aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c2
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix_dp_core.c151
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix_dp_core.h11
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c38
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi.c9
-rw-r--r--drivers/gpu/drm/drm_atomic.c42
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c2
-rw-r--r--drivers/gpu/drm/drm_bufs.c16
-rw-r--r--drivers/gpu/drm/drm_edid.c3
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c2
-rw-r--r--drivers/gpu/drm/drm_framebuffer.c5
-rw-r--r--drivers/gpu/drm/drm_modes.c34
-rw-r--r--drivers/gpu/drm/drm_plane.c2
-rw-r--r--drivers/gpu/drm/drm_print.c65
-rw-r--r--drivers/gpu/drm/drm_property.c1
-rw-r--r--drivers/gpu/drm/i915/intel_color.c32
-rw-r--r--drivers/gpu/drm/i915/intel_display.c15
-rw-r--r--drivers/gpu/drm/meson/meson_drv.c37
-rw-r--r--drivers/gpu/drm/meson/meson_dw_hdmi.c22
-rw-r--r--drivers/gpu/drm/meson/meson_vclk.c219
-rw-r--r--drivers/gpu/drm/meson/meson_venc.c347
-rw-r--r--drivers/gpu/drm/meson/meson_venc.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c46
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h1
-rw-r--r--drivers/gpu/drm/panel/Kconfig9
-rw-r--r--drivers/gpu/drm/panel/Makefile1
-rw-r--r--drivers/gpu/drm/panel/panel-ilitek-ili9322.c4
-rw-r--r--drivers/gpu/drm/panel/panel-lvds.c2
-rw-r--r--drivers/gpu/drm/panel/panel-orisetech-otm8009a.c21
-rw-r--r--drivers/gpu/drm/panel/panel-raydium-rm68200.c448
-rw-r--r--drivers/gpu/drm/panel/panel-simple.c82
-rw-r--r--drivers/gpu/drm/qxl/qxl_display.c4
-rw-r--r--drivers/gpu/drm/qxl/qxl_dumb.c2
-rw-r--r--drivers/gpu/drm/qxl/qxl_fb.c6
-rw-r--r--drivers/gpu/drm/qxl/qxl_gem.c2
-rw-r--r--drivers/gpu/drm/qxl/qxl_ioctl.c4
-rw-r--r--drivers/gpu/drm/qxl/qxl_object.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c2
-rw-r--r--drivers/gpu/drm/rockchip/analogix_dp-rockchip.c33
-rw-r--r--drivers/gpu/drm/rockchip/cdn-dp-core.c7
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop.c74
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_backend.c154
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_backend.h18
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_drv.c12
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_layer.c4
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_lvds.c55
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_rgb.c8
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_tcon.c52
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_tcon.h1
-rw-r--r--drivers/gpu/drm/sun4i/sun6i_drc.c1
-rw-r--r--drivers/gpu/drm/vc4/vc4_crtc.c25
-rw-r--r--drivers/gpu/drm/vc4/vc4_drv.h60
-rw-r--r--drivers/gpu/drm/vc4/vc4_plane.c68
-rw-r--r--drivers/gpu/drm/vc4/vc4_regs.h1
-rw-r--r--drivers/gpu/drm/vc4/vc4_validate.c2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fb.c2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c4
-rw-r--r--drivers/gpu/vga/vga_switcheroo.c152
-rw-r--r--drivers/pci/pci-driver.c17
-rw-r--r--drivers/pci/pci.c8
-rw-r--r--drivers/pci/quirks.c39
61 files changed, 1982 insertions, 511 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index e6709362994a..2337d4bfd85c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -738,7 +738,6 @@ static int amdgpu_pmops_runtime_suspend(struct device *dev)
738 738
739 drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; 739 drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
740 drm_kms_helper_poll_disable(drm_dev); 740 drm_kms_helper_poll_disable(drm_dev);
741 vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF);
742 741
743 ret = amdgpu_device_suspend(drm_dev, false, false); 742 ret = amdgpu_device_suspend(drm_dev, false, false);
744 pci_save_state(pdev); 743 pci_save_state(pdev);
@@ -775,7 +774,6 @@ static int amdgpu_pmops_runtime_resume(struct device *dev)
775 774
776 ret = amdgpu_device_resume(drm_dev, false, false); 775 ret = amdgpu_device_resume(drm_dev, false, false);
777 drm_kms_helper_poll_enable(drm_dev); 776 drm_kms_helper_poll_enable(drm_dev);
778 vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_ON);
779 drm_dev->switch_power_state = DRM_SWITCH_POWER_ON; 777 drm_dev->switch_power_state = DRM_SWITCH_POWER_ON;
780 return 0; 778 return 0;
781} 779}
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index a693ab3078f0..5c52307146c7 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -15,6 +15,7 @@
15#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/clk.h> 16#include <linux/clk.h>
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/iopoll.h>
18#include <linux/interrupt.h> 19#include <linux/interrupt.h>
19#include <linux/of.h> 20#include <linux/of.h>
20#include <linux/of_gpio.h> 21#include <linux/of_gpio.h>
@@ -35,6 +36,8 @@
35 36
36#define to_dp(nm) container_of(nm, struct analogix_dp_device, nm) 37#define to_dp(nm) container_of(nm, struct analogix_dp_device, nm)
37 38
39static const bool verify_fast_training;
40
38struct bridge_init { 41struct bridge_init {
39 struct i2c_client *client; 42 struct i2c_client *client;
40 struct device_node *node; 43 struct device_node *node;
@@ -98,18 +101,18 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp)
98 return 0; 101 return 0;
99} 102}
100 103
101int analogix_dp_psr_supported(struct analogix_dp_device *dp) 104int analogix_dp_psr_enabled(struct analogix_dp_device *dp)
102{ 105{
103 106
104 return dp->psr_support; 107 return dp->psr_enable;
105} 108}
106EXPORT_SYMBOL_GPL(analogix_dp_psr_supported); 109EXPORT_SYMBOL_GPL(analogix_dp_psr_enabled);
107 110
108int analogix_dp_enable_psr(struct analogix_dp_device *dp) 111int analogix_dp_enable_psr(struct analogix_dp_device *dp)
109{ 112{
110 struct edp_vsc_psr psr_vsc; 113 struct edp_vsc_psr psr_vsc;
111 114
112 if (!dp->psr_support) 115 if (!dp->psr_enable)
113 return 0; 116 return 0;
114 117
115 /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ 118 /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
@@ -122,8 +125,7 @@ int analogix_dp_enable_psr(struct analogix_dp_device *dp)
122 psr_vsc.DB0 = 0; 125 psr_vsc.DB0 = 0;
123 psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID; 126 psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID;
124 127
125 analogix_dp_send_psr_spd(dp, &psr_vsc); 128 return analogix_dp_send_psr_spd(dp, &psr_vsc, true);
126 return 0;
127} 129}
128EXPORT_SYMBOL_GPL(analogix_dp_enable_psr); 130EXPORT_SYMBOL_GPL(analogix_dp_enable_psr);
129 131
@@ -132,7 +134,7 @@ int analogix_dp_disable_psr(struct analogix_dp_device *dp)
132 struct edp_vsc_psr psr_vsc; 134 struct edp_vsc_psr psr_vsc;
133 int ret; 135 int ret;
134 136
135 if (!dp->psr_support) 137 if (!dp->psr_enable)
136 return 0; 138 return 0;
137 139
138 /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ 140 /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
@@ -149,8 +151,7 @@ int analogix_dp_disable_psr(struct analogix_dp_device *dp)
149 if (ret != 1) 151 if (ret != 1)
150 dev_err(dp->dev, "Failed to set DP Power0 %d\n", ret); 152 dev_err(dp->dev, "Failed to set DP Power0 %d\n", ret);
151 153
152 analogix_dp_send_psr_spd(dp, &psr_vsc); 154 return analogix_dp_send_psr_spd(dp, &psr_vsc, false);
153 return 0;
154} 155}
155EXPORT_SYMBOL_GPL(analogix_dp_disable_psr); 156EXPORT_SYMBOL_GPL(analogix_dp_disable_psr);
156 157
@@ -530,7 +531,7 @@ static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp)
530{ 531{
531 int lane, lane_count, retval; 532 int lane, lane_count, retval;
532 u32 reg; 533 u32 reg;
533 u8 link_align, link_status[2], adjust_request[2]; 534 u8 link_align, link_status[2], adjust_request[2], spread;
534 535
535 usleep_range(400, 401); 536 usleep_range(400, 401);
536 537
@@ -573,6 +574,20 @@ static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp)
573 dev_dbg(dp->dev, "final lane count = %.2x\n", 574 dev_dbg(dp->dev, "final lane count = %.2x\n",
574 dp->link_train.lane_count); 575 dp->link_train.lane_count);
575 576
577 retval = drm_dp_dpcd_readb(&dp->aux, DP_MAX_DOWNSPREAD,
578 &spread);
579 if (retval != 1) {
580 dev_err(dp->dev, "failed to read downspread %d\n",
581 retval);
582 dp->fast_train_support = false;
583 } else {
584 dp->fast_train_support =
585 (spread & DP_NO_AUX_HANDSHAKE_LINK_TRAINING) ?
586 true : false;
587 }
588 dev_dbg(dp->dev, "fast link training %s\n",
589 dp->fast_train_support ? "supported" : "unsupported");
590
576 /* set enhanced mode if available */ 591 /* set enhanced mode if available */
577 analogix_dp_set_enhanced_mode(dp); 592 analogix_dp_set_enhanced_mode(dp);
578 dp->link_train.lt_state = FINISHED; 593 dp->link_train.lt_state = FINISHED;
@@ -629,10 +644,12 @@ static void analogix_dp_get_max_rx_lane_count(struct analogix_dp_device *dp,
629 *lane_count = DPCD_MAX_LANE_COUNT(data); 644 *lane_count = DPCD_MAX_LANE_COUNT(data);
630} 645}
631 646
632static void analogix_dp_init_training(struct analogix_dp_device *dp, 647static int analogix_dp_full_link_train(struct analogix_dp_device *dp,
633 enum link_lane_count_type max_lane, 648 u32 max_lanes, u32 max_rate)
634 int max_rate)
635{ 649{
650 int retval = 0;
651 bool training_finished = false;
652
636 /* 653 /*
637 * MACRO_RST must be applied after the PLL_LOCK to avoid 654 * MACRO_RST must be applied after the PLL_LOCK to avoid
638 * the DP inter pair skew issue for at least 10 us 655 * the DP inter pair skew issue for at least 10 us
@@ -658,18 +675,13 @@ static void analogix_dp_init_training(struct analogix_dp_device *dp,
658 } 675 }
659 676
660 /* Setup TX lane count & rate */ 677 /* Setup TX lane count & rate */
661 if (dp->link_train.lane_count > max_lane) 678 if (dp->link_train.lane_count > max_lanes)
662 dp->link_train.lane_count = max_lane; 679 dp->link_train.lane_count = max_lanes;
663 if (dp->link_train.link_rate > max_rate) 680 if (dp->link_train.link_rate > max_rate)
664 dp->link_train.link_rate = max_rate; 681 dp->link_train.link_rate = max_rate;
665 682
666 /* All DP analog module power up */ 683 /* All DP analog module power up */
667 analogix_dp_set_analog_power_down(dp, POWER_ALL, 0); 684 analogix_dp_set_analog_power_down(dp, POWER_ALL, 0);
668}
669
670static int analogix_dp_sw_link_training(struct analogix_dp_device *dp)
671{
672 int retval = 0, training_finished = 0;
673 685
674 dp->link_train.lt_state = START; 686 dp->link_train.lt_state = START;
675 687
@@ -704,22 +716,88 @@ static int analogix_dp_sw_link_training(struct analogix_dp_device *dp)
704 return retval; 716 return retval;
705} 717}
706 718
707static int analogix_dp_set_link_train(struct analogix_dp_device *dp, 719static int analogix_dp_fast_link_train(struct analogix_dp_device *dp)
708 u32 count, u32 bwtype)
709{ 720{
710 int i; 721 int i, ret;
711 int retval; 722 u8 link_align, link_status[2];
723 enum pll_status status;
712 724
713 for (i = 0; i < DP_TIMEOUT_LOOP_COUNT; i++) { 725 analogix_dp_reset_macro(dp);
714 analogix_dp_init_training(dp, count, bwtype); 726
715 retval = analogix_dp_sw_link_training(dp); 727 analogix_dp_set_link_bandwidth(dp, dp->link_train.link_rate);
716 if (retval == 0) 728 analogix_dp_set_lane_count(dp, dp->link_train.lane_count);
717 break;
718 729
719 usleep_range(100, 110); 730 for (i = 0; i < dp->link_train.lane_count; i++) {
731 analogix_dp_set_lane_link_training(dp,
732 dp->link_train.training_lane[i], i);
720 } 733 }
721 734
722 return retval; 735 ret = readx_poll_timeout(analogix_dp_get_pll_lock_status, dp, status,
736 status != PLL_UNLOCKED, 120,
737 120 * DP_TIMEOUT_LOOP_COUNT);
738 if (ret) {
739 DRM_DEV_ERROR(dp->dev, "Wait for pll lock failed %d\n", ret);
740 return ret;
741 }
742
743 /* source Set training pattern 1 */
744 analogix_dp_set_training_pattern(dp, TRAINING_PTN1);
745 /* From DP spec, pattern must be on-screen for a minimum 500us */
746 usleep_range(500, 600);
747
748 analogix_dp_set_training_pattern(dp, TRAINING_PTN2);
749 /* From DP spec, pattern must be on-screen for a minimum 500us */
750 usleep_range(500, 600);
751
752 /* TODO: enhanced_mode?*/
753 analogix_dp_set_training_pattern(dp, DP_NONE);
754
755 /*
756 * Useful for debugging issues with fast link training, disable for more
757 * speed
758 */
759 if (verify_fast_training) {
760 ret = drm_dp_dpcd_readb(&dp->aux, DP_LANE_ALIGN_STATUS_UPDATED,
761 &link_align);
762 if (ret < 0) {
763 DRM_DEV_ERROR(dp->dev, "Read align status failed %d\n",
764 ret);
765 return ret;
766 }
767
768 ret = drm_dp_dpcd_read(&dp->aux, DP_LANE0_1_STATUS, link_status,
769 2);
770 if (ret < 0) {
771 DRM_DEV_ERROR(dp->dev, "Read link status failed %d\n",
772 ret);
773 return ret;
774 }
775
776 if (analogix_dp_clock_recovery_ok(link_status,
777 dp->link_train.lane_count)) {
778 DRM_DEV_ERROR(dp->dev, "Clock recovery failed\n");
779 analogix_dp_reduce_link_rate(dp);
780 return -EIO;
781 }
782
783 if (analogix_dp_channel_eq_ok(link_status, link_align,
784 dp->link_train.lane_count)) {
785 DRM_DEV_ERROR(dp->dev, "Channel EQ failed\n");
786 analogix_dp_reduce_link_rate(dp);
787 return -EIO;
788 }
789 }
790
791 return 0;
792}
793
794static int analogix_dp_train_link(struct analogix_dp_device *dp)
795{
796 if (dp->fast_train_support)
797 return analogix_dp_fast_link_train(dp);
798
799 return analogix_dp_full_link_train(dp, dp->video_info.max_lane_count,
800 dp->video_info.max_link_rate);
723} 801}
724 802
725static int analogix_dp_config_video(struct analogix_dp_device *dp) 803static int analogix_dp_config_video(struct analogix_dp_device *dp)
@@ -848,10 +926,10 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
848 DRM_ERROR("failed to disable the panel\n"); 926 DRM_ERROR("failed to disable the panel\n");
849 } 927 }
850 928
851 ret = analogix_dp_set_link_train(dp, dp->video_info.max_lane_count, 929 ret = readx_poll_timeout(analogix_dp_train_link, dp, ret, !ret, 100,
852 dp->video_info.max_link_rate); 930 DP_TIMEOUT_TRAINING_US * 5);
853 if (ret) { 931 if (ret) {
854 dev_err(dp->dev, "unable to do link train\n"); 932 dev_err(dp->dev, "unable to do link train, ret=%d\n", ret);
855 return; 933 return;
856 } 934 }
857 935
@@ -873,8 +951,8 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
873 /* Enable video */ 951 /* Enable video */
874 analogix_dp_start_video(dp); 952 analogix_dp_start_video(dp);
875 953
876 dp->psr_support = analogix_dp_detect_sink_psr(dp); 954 dp->psr_enable = analogix_dp_detect_sink_psr(dp);
877 if (dp->psr_support) 955 if (dp->psr_enable)
878 analogix_dp_enable_sink_psr(dp); 956 analogix_dp_enable_sink_psr(dp);
879} 957}
880 958
@@ -1119,6 +1197,7 @@ static void analogix_dp_bridge_disable(struct drm_bridge *bridge)
1119 if (ret) 1197 if (ret)
1120 DRM_ERROR("failed to setup the panel ret = %d\n", ret); 1198 DRM_ERROR("failed to setup the panel ret = %d\n", ret);
1121 1199
1200 dp->psr_enable = false;
1122 dp->dpms_mode = DRM_MODE_DPMS_OFF; 1201 dp->dpms_mode = DRM_MODE_DPMS_OFF;
1123} 1202}
1124 1203
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
index 5c6a28806129..6a96ef7e6934 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
@@ -20,6 +20,10 @@
20#define MAX_CR_LOOP 5 20#define MAX_CR_LOOP 5
21#define MAX_EQ_LOOP 5 21#define MAX_EQ_LOOP 5
22 22
23/* Training takes 22ms if AUX channel comm fails. Use this as retry interval */
24#define DP_TIMEOUT_TRAINING_US 22000
25#define DP_TIMEOUT_PSR_LOOP_MS 300
26
23/* DP_MAX_LANE_COUNT */ 27/* DP_MAX_LANE_COUNT */
24#define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1) 28#define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1)
25#define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f) 29#define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f)
@@ -168,7 +172,8 @@ struct analogix_dp_device {
168 int dpms_mode; 172 int dpms_mode;
169 int hpd_gpio; 173 int hpd_gpio;
170 bool force_hpd; 174 bool force_hpd;
171 bool psr_support; 175 bool psr_enable;
176 bool fast_train_support;
172 177
173 struct mutex panel_lock; 178 struct mutex panel_lock;
174 bool panel_is_modeset; 179 bool panel_is_modeset;
@@ -247,8 +252,8 @@ void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp);
247void analogix_dp_enable_scrambling(struct analogix_dp_device *dp); 252void analogix_dp_enable_scrambling(struct analogix_dp_device *dp);
248void analogix_dp_disable_scrambling(struct analogix_dp_device *dp); 253void analogix_dp_disable_scrambling(struct analogix_dp_device *dp);
249void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp); 254void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp);
250void analogix_dp_send_psr_spd(struct analogix_dp_device *dp, 255int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
251 struct edp_vsc_psr *vsc); 256 struct edp_vsc_psr *vsc, bool blocking);
252ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, 257ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
253 struct drm_dp_aux_msg *msg); 258 struct drm_dp_aux_msg *msg);
254 259
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 303083ad28e3..9df2f3ef000c 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -10,10 +10,11 @@
10 * option) any later version. 10 * option) any later version.
11 */ 11 */
12 12
13#include <linux/device.h>
14#include <linux/io.h>
15#include <linux/delay.h> 13#include <linux/delay.h>
14#include <linux/device.h>
16#include <linux/gpio.h> 15#include <linux/gpio.h>
16#include <linux/io.h>
17#include <linux/iopoll.h>
17 18
18#include <drm/bridge/analogix_dp.h> 19#include <drm/bridge/analogix_dp.h>
19 20
@@ -992,10 +993,25 @@ void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp)
992 writel(PSR_VID_CRC_ENABLE, dp->reg_base + ANALOGIX_DP_CRC_CON); 993 writel(PSR_VID_CRC_ENABLE, dp->reg_base + ANALOGIX_DP_CRC_CON);
993} 994}
994 995
995void analogix_dp_send_psr_spd(struct analogix_dp_device *dp, 996static ssize_t analogix_dp_get_psr_status(struct analogix_dp_device *dp)
996 struct edp_vsc_psr *vsc) 997{
998 ssize_t val;
999 u8 status;
1000
1001 val = drm_dp_dpcd_readb(&dp->aux, DP_PSR_STATUS, &status);
1002 if (val < 0) {
1003 dev_err(dp->dev, "PSR_STATUS read failed ret=%zd", val);
1004 return val;
1005 }
1006 return status;
1007}
1008
1009int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
1010 struct edp_vsc_psr *vsc, bool blocking)
997{ 1011{
998 unsigned int val; 1012 unsigned int val;
1013 int ret;
1014 ssize_t psr_status;
999 1015
1000 /* don't send info frame */ 1016 /* don't send info frame */
1001 val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); 1017 val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
@@ -1036,6 +1052,20 @@ void analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
1036 val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); 1052 val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
1037 val |= IF_EN; 1053 val |= IF_EN;
1038 writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); 1054 writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
1055
1056 if (!blocking)
1057 return 0;
1058
1059 ret = readx_poll_timeout(analogix_dp_get_psr_status, dp, psr_status,
1060 psr_status >= 0 &&
1061 ((vsc->DB1 && psr_status == DP_PSR_SINK_ACTIVE_RFB) ||
1062 (!vsc->DB1 && psr_status == DP_PSR_SINK_INACTIVE)), 1500,
1063 DP_TIMEOUT_PSR_LOOP_MS * 1000);
1064 if (ret) {
1065 dev_warn(dp->dev, "Failed to apply PSR %d\n", ret);
1066 return ret;
1067 }
1068 return 0;
1039} 1069}
1040 1070
1041ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, 1071ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 53ebbe2904b6..ec8d0006ef7c 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -147,7 +147,6 @@ struct dw_hdmi {
147 int vic; 147 int vic;
148 148
149 u8 edid[HDMI_EDID_LEN]; 149 u8 edid[HDMI_EDID_LEN];
150 bool cable_plugin;
151 150
152 struct { 151 struct {
153 const struct dw_hdmi_phy_ops *ops; 152 const struct dw_hdmi_phy_ops *ops;
@@ -1679,12 +1678,6 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
1679 hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF); 1678 hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
1680} 1679}
1681 1680
1682static void hdmi_enable_overflow_interrupts(struct dw_hdmi *hdmi)
1683{
1684 hdmi_writeb(hdmi, 0, HDMI_FC_MASK2);
1685 hdmi_writeb(hdmi, 0, HDMI_IH_MUTE_FC_STAT2);
1686}
1687
1688static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi) 1681static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi)
1689{ 1682{
1690 hdmi_writeb(hdmi, HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK, 1683 hdmi_writeb(hdmi, HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK,
@@ -1774,8 +1767,6 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
1774 hdmi_tx_hdcp_config(hdmi); 1767 hdmi_tx_hdcp_config(hdmi);
1775 1768
1776 dw_hdmi_clear_overflow(hdmi); 1769 dw_hdmi_clear_overflow(hdmi);
1777 if (hdmi->cable_plugin && hdmi->sink_is_hdmi)
1778 hdmi_enable_overflow_interrupts(hdmi);
1779 1770
1780 return 0; 1771 return 0;
1781} 1772}
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 34b7d420e555..7d25c42f22db 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -391,8 +391,7 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state,
391 if (blob) { 391 if (blob) {
392 if (blob->length != sizeof(struct drm_mode_modeinfo) || 392 if (blob->length != sizeof(struct drm_mode_modeinfo) ||
393 drm_mode_convert_umode(state->crtc->dev, &state->mode, 393 drm_mode_convert_umode(state->crtc->dev, &state->mode,
394 (const struct drm_mode_modeinfo *) 394 blob->data))
395 blob->data))
396 return -EINVAL; 395 return -EINVAL;
397 396
398 state->mode_blob = drm_property_blob_get(blob); 397 state->mode_blob = drm_property_blob_get(blob);
@@ -409,11 +408,36 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state,
409} 408}
410EXPORT_SYMBOL(drm_atomic_set_mode_prop_for_crtc); 409EXPORT_SYMBOL(drm_atomic_set_mode_prop_for_crtc);
411 410
411/**
412 * drm_atomic_replace_property_blob_from_id - lookup the new blob and replace the old one with it
413 * @dev: DRM device
414 * @blob: a pointer to the member blob to be replaced
415 * @blob_id: ID of the new blob
416 * @expected_size: total expected size of the blob data (in bytes)
417 * @expected_elem_size: expected element size of the blob data (in bytes)
418 * @replaced: did the blob get replaced?
419 *
420 * Replace @blob with another blob with the ID @blob_id. If @blob_id is zero
421 * @blob becomes NULL.
422 *
423 * If @expected_size is positive the new blob length is expected to be equal
424 * to @expected_size bytes. If @expected_elem_size is positive the new blob
425 * length is expected to be a multiple of @expected_elem_size bytes. Otherwise
426 * an error is returned.
427 *
428 * @replaced will indicate to the caller whether the blob was replaced or not.
429 * If the old and new blobs were in fact the same blob @replaced will be false
430 * otherwise it will be true.
431 *
432 * RETURNS:
433 * Zero on success, error code on failure.
434 */
412static int 435static int
413drm_atomic_replace_property_blob_from_id(struct drm_device *dev, 436drm_atomic_replace_property_blob_from_id(struct drm_device *dev,
414 struct drm_property_blob **blob, 437 struct drm_property_blob **blob,
415 uint64_t blob_id, 438 uint64_t blob_id,
416 ssize_t expected_size, 439 ssize_t expected_size,
440 ssize_t expected_elem_size,
417 bool *replaced) 441 bool *replaced)
418{ 442{
419 struct drm_property_blob *new_blob = NULL; 443 struct drm_property_blob *new_blob = NULL;
@@ -423,7 +447,13 @@ drm_atomic_replace_property_blob_from_id(struct drm_device *dev,
423 if (new_blob == NULL) 447 if (new_blob == NULL)
424 return -EINVAL; 448 return -EINVAL;
425 449
426 if (expected_size > 0 && expected_size != new_blob->length) { 450 if (expected_size > 0 &&
451 new_blob->length != expected_size) {
452 drm_property_blob_put(new_blob);
453 return -EINVAL;
454 }
455 if (expected_elem_size > 0 &&
456 new_blob->length % expected_elem_size != 0) {
427 drm_property_blob_put(new_blob); 457 drm_property_blob_put(new_blob);
428 return -EINVAL; 458 return -EINVAL;
429 } 459 }
@@ -471,7 +501,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
471 ret = drm_atomic_replace_property_blob_from_id(dev, 501 ret = drm_atomic_replace_property_blob_from_id(dev,
472 &state->degamma_lut, 502 &state->degamma_lut,
473 val, 503 val,
474 -1, 504 -1, sizeof(struct drm_color_lut),
475 &replaced); 505 &replaced);
476 state->color_mgmt_changed |= replaced; 506 state->color_mgmt_changed |= replaced;
477 return ret; 507 return ret;
@@ -479,7 +509,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
479 ret = drm_atomic_replace_property_blob_from_id(dev, 509 ret = drm_atomic_replace_property_blob_from_id(dev,
480 &state->ctm, 510 &state->ctm,
481 val, 511 val,
482 sizeof(struct drm_color_ctm), 512 sizeof(struct drm_color_ctm), -1,
483 &replaced); 513 &replaced);
484 state->color_mgmt_changed |= replaced; 514 state->color_mgmt_changed |= replaced;
485 return ret; 515 return ret;
@@ -487,7 +517,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
487 ret = drm_atomic_replace_property_blob_from_id(dev, 517 ret = drm_atomic_replace_property_blob_from_id(dev,
488 &state->gamma_lut, 518 &state->gamma_lut,
489 val, 519 val,
490 -1, 520 -1, sizeof(struct drm_color_lut),
491 &replaced); 521 &replaced);
492 state->color_mgmt_changed |= replaced; 522 state->color_mgmt_changed |= replaced;
493 return ret; 523 return ret;
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 00c78c1c9681..c35654591c12 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3818,7 +3818,7 @@ int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
3818 } 3818 }
3819 3819
3820 /* Prepare GAMMA_LUT with the legacy values. */ 3820 /* Prepare GAMMA_LUT with the legacy values. */
3821 blob_data = (struct drm_color_lut *) blob->data; 3821 blob_data = blob->data;
3822 for (i = 0; i < size; i++) { 3822 for (i = 0; i < size; i++) {
3823 blob_data[i].red = red[i]; 3823 blob_data[i].red = red[i];
3824 blob_data[i].green = green[i]; 3824 blob_data[i].green = green[i];
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
index 1ee84dd802d4..ba8cfe65c65b 100644
--- a/drivers/gpu/drm/drm_bufs.c
+++ b/drivers/gpu/drm/drm_bufs.c
@@ -129,10 +129,10 @@ static int drm_map_handle(struct drm_device *dev, struct drm_hash_item *hash,
129 * type. Adds the map to the map list drm_device::maplist. Adds MTRR's where 129 * type. Adds the map to the map list drm_device::maplist. Adds MTRR's where
130 * applicable and if supported by the kernel. 130 * applicable and if supported by the kernel.
131 */ 131 */
132static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, 132static int drm_addmap_core(struct drm_device *dev, resource_size_t offset,
133 unsigned int size, enum drm_map_type type, 133 unsigned int size, enum drm_map_type type,
134 enum drm_map_flags flags, 134 enum drm_map_flags flags,
135 struct drm_map_list ** maplist) 135 struct drm_map_list **maplist)
136{ 136{
137 struct drm_local_map *map; 137 struct drm_local_map *map;
138 struct drm_map_list *list; 138 struct drm_map_list *list;
@@ -224,7 +224,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset,
224 case _DRM_SHM: 224 case _DRM_SHM:
225 list = drm_find_matching_map(dev, map); 225 list = drm_find_matching_map(dev, map);
226 if (list != NULL) { 226 if (list != NULL) {
227 if(list->map->size != map->size) { 227 if (list->map->size != map->size) {
228 DRM_DEBUG("Matching maps of type %d with " 228 DRM_DEBUG("Matching maps of type %d with "
229 "mismatched sizes, (%ld vs %ld)\n", 229 "mismatched sizes, (%ld vs %ld)\n",
230 map->type, map->size, list->map->size); 230 map->type, map->size, list->map->size);
@@ -361,7 +361,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset,
361 return 0; 361 return 0;
362} 362}
363 363
364int drm_legacy_addmap(struct drm_device * dev, resource_size_t offset, 364int drm_legacy_addmap(struct drm_device *dev, resource_size_t offset,
365 unsigned int size, enum drm_map_type type, 365 unsigned int size, enum drm_map_type type,
366 enum drm_map_flags flags, struct drm_local_map **map_ptr) 366 enum drm_map_flags flags, struct drm_local_map **map_ptr)
367{ 367{
@@ -637,8 +637,8 @@ int drm_legacy_rmmap_ioctl(struct drm_device *dev, void *data,
637 * 637 *
638 * Frees any pages and buffers associated with the given entry. 638 * Frees any pages and buffers associated with the given entry.
639 */ 639 */
640static void drm_cleanup_buf_error(struct drm_device * dev, 640static void drm_cleanup_buf_error(struct drm_device *dev,
641 struct drm_buf_entry * entry) 641 struct drm_buf_entry *entry)
642{ 642{
643 int i; 643 int i;
644 644
@@ -1446,8 +1446,8 @@ int drm_legacy_freebufs(struct drm_device *dev, void *data,
1446int __drm_legacy_mapbufs(struct drm_device *dev, void *data, int *p, 1446int __drm_legacy_mapbufs(struct drm_device *dev, void *data, int *p,
1447 void __user **v, 1447 void __user **v,
1448 int (*f)(void *, int, unsigned long, 1448 int (*f)(void *, int, unsigned long,
1449 struct drm_buf *), 1449 struct drm_buf *),
1450 struct drm_file *file_priv) 1450 struct drm_file *file_priv)
1451{ 1451{
1452 struct drm_device_dma *dma = dev->dma; 1452 struct drm_device_dma *dma = dev->dma;
1453 int retcode = 0; 1453 int retcode = 0;
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index a797bbf1cab8..49147b2aa288 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1554,8 +1554,7 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
1554 struct edid *override = NULL; 1554 struct edid *override = NULL;
1555 1555
1556 if (connector->override_edid) 1556 if (connector->override_edid)
1557 override = drm_edid_duplicate((const struct edid *) 1557 override = drm_edid_duplicate(connector->edid_blob_ptr->data);
1558 connector->edid_blob_ptr->data);
1559 1558
1560 if (!override) 1559 if (!override)
1561 override = drm_load_edid_firmware(connector); 1560 override = drm_load_edid_firmware(connector);
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 035784ddd133..0646b108030b 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -1351,7 +1351,7 @@ static struct drm_property_blob *setcmap_new_gamma_lut(struct drm_crtc *crtc,
1351 if (IS_ERR(gamma_lut)) 1351 if (IS_ERR(gamma_lut))
1352 return gamma_lut; 1352 return gamma_lut;
1353 1353
1354 lut = (struct drm_color_lut *)gamma_lut->data; 1354 lut = gamma_lut->data;
1355 if (cmap->start || cmap->len != size) { 1355 if (cmap->start || cmap->len != size) {
1356 u16 *r = crtc->gamma_store; 1356 u16 *r = crtc->gamma_store;
1357 u16 *g = r + crtc->gamma_size; 1357 u16 *g = r + crtc->gamma_size;
diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index 5a13ff29f4f0..0eebe8ba8a2c 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -158,9 +158,10 @@ static int framebuffer_check(struct drm_device *dev,
158 info = __drm_format_info(r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN); 158 info = __drm_format_info(r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN);
159 if (!info) { 159 if (!info) {
160 struct drm_format_name_buf format_name; 160 struct drm_format_name_buf format_name;
161
161 DRM_DEBUG_KMS("bad framebuffer format %s\n", 162 DRM_DEBUG_KMS("bad framebuffer format %s\n",
162 drm_get_format_name(r->pixel_format, 163 drm_get_format_name(r->pixel_format,
163 &format_name)); 164 &format_name));
164 return -EINVAL; 165 return -EINVAL;
165 } 166 }
166 167
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 5a8033fda4e3..f6b7c0e36a1a 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -773,24 +773,23 @@ EXPORT_SYMBOL(drm_mode_hsync);
773int drm_mode_vrefresh(const struct drm_display_mode *mode) 773int drm_mode_vrefresh(const struct drm_display_mode *mode)
774{ 774{
775 int refresh = 0; 775 int refresh = 0;
776 unsigned int calc_val;
777 776
778 if (mode->vrefresh > 0) 777 if (mode->vrefresh > 0)
779 refresh = mode->vrefresh; 778 refresh = mode->vrefresh;
780 else if (mode->htotal > 0 && mode->vtotal > 0) { 779 else if (mode->htotal > 0 && mode->vtotal > 0) {
781 int vtotal; 780 unsigned int num, den;
782 vtotal = mode->vtotal; 781
783 /* work out vrefresh the value will be x1000 */ 782 num = mode->clock * 1000;
784 calc_val = (mode->clock * 1000); 783 den = mode->htotal * mode->vtotal;
785 calc_val /= mode->htotal;
786 refresh = (calc_val + vtotal / 2) / vtotal;
787 784
788 if (mode->flags & DRM_MODE_FLAG_INTERLACE) 785 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
789 refresh *= 2; 786 num *= 2;
790 if (mode->flags & DRM_MODE_FLAG_DBLSCAN) 787 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
791 refresh /= 2; 788 den *= 2;
792 if (mode->vscan > 1) 789 if (mode->vscan > 1)
793 refresh /= mode->vscan; 790 den *= mode->vscan;
791
792 refresh = DIV_ROUND_CLOSEST(num, den);
794 } 793 }
795 return refresh; 794 return refresh;
796} 795}
@@ -1596,12 +1595,8 @@ int drm_mode_convert_umode(struct drm_device *dev,
1596 struct drm_display_mode *out, 1595 struct drm_display_mode *out,
1597 const struct drm_mode_modeinfo *in) 1596 const struct drm_mode_modeinfo *in)
1598{ 1597{
1599 int ret = -EINVAL; 1598 if (in->clock > INT_MAX || in->vrefresh > INT_MAX)
1600 1599 return -ERANGE;
1601 if (in->clock > INT_MAX || in->vrefresh > INT_MAX) {
1602 ret = -ERANGE;
1603 goto out;
1604 }
1605 1600
1606 out->clock = in->clock; 1601 out->clock = in->clock;
1607 out->hdisplay = in->hdisplay; 1602 out->hdisplay = in->hdisplay;
@@ -1622,14 +1617,11 @@ int drm_mode_convert_umode(struct drm_device *dev,
1622 1617
1623 out->status = drm_mode_validate_driver(dev, out); 1618 out->status = drm_mode_validate_driver(dev, out);
1624 if (out->status != MODE_OK) 1619 if (out->status != MODE_OK)
1625 goto out; 1620 return -EINVAL;
1626 1621
1627 drm_mode_set_crtcinfo(out, CRTC_INTERLACE_HALVE_V); 1622 drm_mode_set_crtcinfo(out, CRTC_INTERLACE_HALVE_V);
1628 1623
1629 ret = 0; 1624 return 0;
1630
1631out:
1632 return ret;
1633} 1625}
1634 1626
1635/** 1627/**
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index a5d1fc7e8a37..6d2a6e428a3e 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -104,7 +104,7 @@ static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane
104 if (IS_ERR(blob)) 104 if (IS_ERR(blob))
105 return -1; 105 return -1;
106 106
107 blob_data = (struct drm_format_modifier_blob *)blob->data; 107 blob_data = blob->data;
108 blob_data->version = FORMAT_BLOB_CURRENT; 108 blob_data->version = FORMAT_BLOB_CURRENT;
109 blob_data->count_formats = plane->format_count; 109 blob_data->count_formats = plane->format_count;
110 blob_data->formats_offset = sizeof(struct drm_format_modifier_blob); 110 blob_data->formats_offset = sizeof(struct drm_format_modifier_blob);
diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 781518fd88e3..b25f98f33f6c 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -63,16 +63,34 @@ void drm_printf(struct drm_printer *p, const char *f, ...)
63} 63}
64EXPORT_SYMBOL(drm_printf); 64EXPORT_SYMBOL(drm_printf);
65 65
66#define DRM_PRINTK_FMT "[" DRM_NAME ":%s]%s %pV"
67
68void drm_dev_printk(const struct device *dev, const char *level, 66void drm_dev_printk(const struct device *dev, const char *level,
69 unsigned int category, const char *function_name, 67 const char *format, ...)
70 const char *prefix, const char *format, ...)
71{ 68{
72 struct va_format vaf; 69 struct va_format vaf;
73 va_list args; 70 va_list args;
74 71
75 if (category != DRM_UT_NONE && !(drm_debug & category)) 72 va_start(args, format);
73 vaf.fmt = format;
74 vaf.va = &args;
75
76 if (dev)
77 dev_printk(level, dev, "[" DRM_NAME ":%ps] %pV",
78 __builtin_return_address(0), &vaf);
79 else
80 printk("%s" "[" DRM_NAME ":%ps] %pV",
81 level, __builtin_return_address(0), &vaf);
82
83 va_end(args);
84}
85EXPORT_SYMBOL(drm_dev_printk);
86
87void drm_dev_dbg(const struct device *dev, unsigned int category,
88 const char *format, ...)
89{
90 struct va_format vaf;
91 va_list args;
92
93 if (!(drm_debug & category))
76 return; 94 return;
77 95
78 va_start(args, format); 96 va_start(args, format);
@@ -80,32 +98,47 @@ void drm_dev_printk(const struct device *dev, const char *level,
80 vaf.va = &args; 98 vaf.va = &args;
81 99
82 if (dev) 100 if (dev)
83 dev_printk(level, dev, DRM_PRINTK_FMT, function_name, prefix, 101 dev_printk(KERN_DEBUG, dev, "[" DRM_NAME ":%ps] %pV",
84 &vaf); 102 __builtin_return_address(0), &vaf);
85 else 103 else
86 printk("%s" DRM_PRINTK_FMT, level, function_name, prefix, &vaf); 104 printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV",
105 __builtin_return_address(0), &vaf);
87 106
88 va_end(args); 107 va_end(args);
89} 108}
90EXPORT_SYMBOL(drm_dev_printk); 109EXPORT_SYMBOL(drm_dev_dbg);
91 110
92void drm_printk(const char *level, unsigned int category, 111void drm_dbg(unsigned int category, const char *format, ...)
93 const char *format, ...)
94{ 112{
95 struct va_format vaf; 113 struct va_format vaf;
96 va_list args; 114 va_list args;
97 115
98 if (category != DRM_UT_NONE && !(drm_debug & category)) 116 if (!(drm_debug & category))
99 return; 117 return;
100 118
101 va_start(args, format); 119 va_start(args, format);
102 vaf.fmt = format; 120 vaf.fmt = format;
103 vaf.va = &args; 121 vaf.va = &args;
104 122
105 printk("%s" "[" DRM_NAME ":%ps]%s %pV", 123 printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV",
106 level, __builtin_return_address(0), 124 __builtin_return_address(0), &vaf);
107 strcmp(level, KERN_ERR) == 0 ? " *ERROR*" : "", &vaf); 125
126 va_end(args);
127}
128EXPORT_SYMBOL(drm_dbg);
129
130void drm_err(const char *format, ...)
131{
132 struct va_format vaf;
133 va_list args;
134
135 va_start(args, format);
136 vaf.fmt = format;
137 vaf.va = &args;
138
139 printk(KERN_ERR "[" DRM_NAME ":%ps] *ERROR* %pV",
140 __builtin_return_address(0), &vaf);
108 141
109 va_end(args); 142 va_end(args);
110} 143}
111EXPORT_SYMBOL(drm_printk); 144EXPORT_SYMBOL(drm_err);
diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c
index 6ac6ee41a6a3..8f4672daac7f 100644
--- a/drivers/gpu/drm/drm_property.c
+++ b/drivers/gpu/drm/drm_property.c
@@ -567,6 +567,7 @@ drm_property_create_blob(struct drm_device *dev, size_t length,
567 /* This must be explicitly initialised, so we can safely call list_del 567 /* This must be explicitly initialised, so we can safely call list_del
568 * on it in the removal handler, even if it isn't in a file list. */ 568 * on it in the removal handler, even if it isn't in a file list. */
569 INIT_LIST_HEAD(&blob->head_file); 569 INIT_LIST_HEAD(&blob->head_file);
570 blob->data = (void *)blob + sizeof(*blob);
570 blob->length = length; 571 blob->length = length;
571 blob->dev = dev; 572 blob->dev = dev;
572 573
diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c
index 89ab0f70aa22..c6a7beabd58d 100644
--- a/drivers/gpu/drm/i915/intel_color.c
+++ b/drivers/gpu/drm/i915/intel_color.c
@@ -39,7 +39,7 @@
39#define CTM_COEFF_NEGATIVE(coeff) (((coeff) & CTM_COEFF_SIGN) != 0) 39#define CTM_COEFF_NEGATIVE(coeff) (((coeff) & CTM_COEFF_SIGN) != 0)
40#define CTM_COEFF_ABS(coeff) ((coeff) & (CTM_COEFF_SIGN - 1)) 40#define CTM_COEFF_ABS(coeff) ((coeff) & (CTM_COEFF_SIGN - 1))
41 41
42#define LEGACY_LUT_LENGTH (sizeof(struct drm_color_lut) * 256) 42#define LEGACY_LUT_LENGTH 256
43 43
44/* Post offset values for RGB->YCBCR conversion */ 44/* Post offset values for RGB->YCBCR conversion */
45#define POSTOFF_RGB_TO_YUV_HI 0x800 45#define POSTOFF_RGB_TO_YUV_HI 0x800
@@ -79,7 +79,7 @@ static bool crtc_state_is_legacy_gamma(struct drm_crtc_state *state)
79 return !state->degamma_lut && 79 return !state->degamma_lut &&
80 !state->ctm && 80 !state->ctm &&
81 state->gamma_lut && 81 state->gamma_lut &&
82 state->gamma_lut->length == LEGACY_LUT_LENGTH; 82 drm_color_lut_size(state->gamma_lut) == LEGACY_LUT_LENGTH;
83} 83}
84 84
85/* 85/*
@@ -153,8 +153,7 @@ static void ilk_load_csc_matrix(struct drm_crtc_state *crtc_state)
153 ilk_load_ycbcr_conversion_matrix(intel_crtc); 153 ilk_load_ycbcr_conversion_matrix(intel_crtc);
154 return; 154 return;
155 } else if (crtc_state->ctm) { 155 } else if (crtc_state->ctm) {
156 struct drm_color_ctm *ctm = 156 struct drm_color_ctm *ctm = crtc_state->ctm->data;
157 (struct drm_color_ctm *)crtc_state->ctm->data;
158 const u64 *input; 157 const u64 *input;
159 u64 temp[9]; 158 u64 temp[9];
160 159
@@ -262,8 +261,7 @@ static void cherryview_load_csc_matrix(struct drm_crtc_state *state)
262 uint32_t mode; 261 uint32_t mode;
263 262
264 if (state->ctm) { 263 if (state->ctm) {
265 struct drm_color_ctm *ctm = 264 struct drm_color_ctm *ctm = state->ctm->data;
266 (struct drm_color_ctm *) state->ctm->data;
267 uint16_t coeffs[9] = { 0, }; 265 uint16_t coeffs[9] = { 0, };
268 int i; 266 int i;
269 267
@@ -330,7 +328,7 @@ static void i9xx_load_luts_internal(struct drm_crtc *crtc,
330 } 328 }
331 329
332 if (blob) { 330 if (blob) {
333 struct drm_color_lut *lut = (struct drm_color_lut *) blob->data; 331 struct drm_color_lut *lut = blob->data;
334 for (i = 0; i < 256; i++) { 332 for (i = 0; i < 256; i++) {
335 uint32_t word = 333 uint32_t word =
336 (drm_color_lut_extract(lut[i].red, 8) << 16) | 334 (drm_color_lut_extract(lut[i].red, 8) << 16) |
@@ -400,8 +398,7 @@ static void bdw_load_degamma_lut(struct drm_crtc_state *state)
400 PAL_PREC_SPLIT_MODE | PAL_PREC_AUTO_INCREMENT); 398 PAL_PREC_SPLIT_MODE | PAL_PREC_AUTO_INCREMENT);
401 399
402 if (state->degamma_lut) { 400 if (state->degamma_lut) {
403 struct drm_color_lut *lut = 401 struct drm_color_lut *lut = state->degamma_lut->data;
404 (struct drm_color_lut *) state->degamma_lut->data;
405 402
406 for (i = 0; i < lut_size; i++) { 403 for (i = 0; i < lut_size; i++) {
407 uint32_t word = 404 uint32_t word =
@@ -435,8 +432,7 @@ static void bdw_load_gamma_lut(struct drm_crtc_state *state, u32 offset)
435 offset); 432 offset);
436 433
437 if (state->gamma_lut) { 434 if (state->gamma_lut) {
438 struct drm_color_lut *lut = 435 struct drm_color_lut *lut = state->gamma_lut->data;
439 (struct drm_color_lut *) state->gamma_lut->data;
440 436
441 for (i = 0; i < lut_size; i++) { 437 for (i = 0; i < lut_size; i++) {
442 uint32_t word = 438 uint32_t word =
@@ -568,7 +564,7 @@ static void cherryview_load_luts(struct drm_crtc_state *state)
568 } 564 }
569 565
570 if (state->degamma_lut) { 566 if (state->degamma_lut) {
571 lut = (struct drm_color_lut *) state->degamma_lut->data; 567 lut = state->degamma_lut->data;
572 lut_size = INTEL_INFO(dev_priv)->color.degamma_lut_size; 568 lut_size = INTEL_INFO(dev_priv)->color.degamma_lut_size;
573 for (i = 0; i < lut_size; i++) { 569 for (i = 0; i < lut_size; i++) {
574 /* Write LUT in U0.14 format. */ 570 /* Write LUT in U0.14 format. */
@@ -583,7 +579,7 @@ static void cherryview_load_luts(struct drm_crtc_state *state)
583 } 579 }
584 580
585 if (state->gamma_lut) { 581 if (state->gamma_lut) {
586 lut = (struct drm_color_lut *) state->gamma_lut->data; 582 lut = state->gamma_lut->data;
587 lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size; 583 lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size;
588 for (i = 0; i < lut_size; i++) { 584 for (i = 0; i < lut_size; i++) {
589 /* Write LUT in U0.10 format. */ 585 /* Write LUT in U0.10 format. */
@@ -623,19 +619,17 @@ int intel_color_check(struct drm_crtc *crtc,
623 struct drm_i915_private *dev_priv = to_i915(crtc->dev); 619 struct drm_i915_private *dev_priv = to_i915(crtc->dev);
624 size_t gamma_length, degamma_length; 620 size_t gamma_length, degamma_length;
625 621
626 degamma_length = INTEL_INFO(dev_priv)->color.degamma_lut_size * 622 degamma_length = INTEL_INFO(dev_priv)->color.degamma_lut_size;
627 sizeof(struct drm_color_lut); 623 gamma_length = INTEL_INFO(dev_priv)->color.gamma_lut_size;
628 gamma_length = INTEL_INFO(dev_priv)->color.gamma_lut_size *
629 sizeof(struct drm_color_lut);
630 624
631 /* 625 /*
632 * We allow both degamma & gamma luts at the right size or 626 * We allow both degamma & gamma luts at the right size or
633 * NULL. 627 * NULL.
634 */ 628 */
635 if ((!crtc_state->degamma_lut || 629 if ((!crtc_state->degamma_lut ||
636 crtc_state->degamma_lut->length == degamma_length) && 630 drm_color_lut_size(crtc_state->degamma_lut) == degamma_length) &&
637 (!crtc_state->gamma_lut || 631 (!crtc_state->gamma_lut ||
638 crtc_state->gamma_lut->length == gamma_length)) 632 drm_color_lut_size(crtc_state->gamma_lut) == gamma_length))
639 return 0; 633 return 0;
640 634
641 /* 635 /*
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 331084082545..3b48fd2561fe 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11059,24 +11059,17 @@ intel_compare_link_m_n(const struct intel_link_m_n *m_n,
11059static void __printf(3, 4) 11059static void __printf(3, 4)
11060pipe_config_err(bool adjust, const char *name, const char *format, ...) 11060pipe_config_err(bool adjust, const char *name, const char *format, ...)
11061{ 11061{
11062 char *level;
11063 unsigned int category;
11064 struct va_format vaf; 11062 struct va_format vaf;
11065 va_list args; 11063 va_list args;
11066 11064
11067 if (adjust) {
11068 level = KERN_DEBUG;
11069 category = DRM_UT_KMS;
11070 } else {
11071 level = KERN_ERR;
11072 category = DRM_UT_NONE;
11073 }
11074
11075 va_start(args, format); 11065 va_start(args, format);
11076 vaf.fmt = format; 11066 vaf.fmt = format;
11077 vaf.va = &args; 11067 vaf.va = &args;
11078 11068
11079 drm_printk(level, category, "mismatch in %s %pV", name, &vaf); 11069 if (adjust)
11070 drm_dbg(DRM_UT_KMS, "mismatch in %s %pV", name, &vaf);
11071 else
11072 drm_err("mismatch in %s %pV", name, &vaf);
11080 11073
11081 va_end(args); 11074 va_end(args);
11082} 11075}
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
index f9ad0e960263..32b1a6cdecfc 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -189,40 +189,55 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
189 189
190 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpu"); 190 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpu");
191 regs = devm_ioremap_resource(dev, res); 191 regs = devm_ioremap_resource(dev, res);
192 if (IS_ERR(regs)) 192 if (IS_ERR(regs)) {
193 return PTR_ERR(regs); 193 ret = PTR_ERR(regs);
194 goto free_drm;
195 }
194 196
195 priv->io_base = regs; 197 priv->io_base = regs;
196 198
197 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hhi"); 199 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hhi");
200 if (!res)
201 return -EINVAL;
198 /* Simply ioremap since it may be a shared register zone */ 202 /* Simply ioremap since it may be a shared register zone */
199 regs = devm_ioremap(dev, res->start, resource_size(res)); 203 regs = devm_ioremap(dev, res->start, resource_size(res));
200 if (!regs) 204 if (!regs) {
201 return -EADDRNOTAVAIL; 205 ret = -EADDRNOTAVAIL;
206 goto free_drm;
207 }
202 208
203 priv->hhi = devm_regmap_init_mmio(dev, regs, 209 priv->hhi = devm_regmap_init_mmio(dev, regs,
204 &meson_regmap_config); 210 &meson_regmap_config);
205 if (IS_ERR(priv->hhi)) { 211 if (IS_ERR(priv->hhi)) {
206 dev_err(&pdev->dev, "Couldn't create the HHI regmap\n"); 212 dev_err(&pdev->dev, "Couldn't create the HHI regmap\n");
207 return PTR_ERR(priv->hhi); 213 ret = PTR_ERR(priv->hhi);
214 goto free_drm;
208 } 215 }
209 216
210 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dmc"); 217 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dmc");
218 if (!res)
219 return -EINVAL;
211 /* Simply ioremap since it may be a shared register zone */ 220 /* Simply ioremap since it may be a shared register zone */
212 regs = devm_ioremap(dev, res->start, resource_size(res)); 221 regs = devm_ioremap(dev, res->start, resource_size(res));
213 if (!regs) 222 if (!regs) {
214 return -EADDRNOTAVAIL; 223 ret = -EADDRNOTAVAIL;
224 goto free_drm;
225 }
215 226
216 priv->dmc = devm_regmap_init_mmio(dev, regs, 227 priv->dmc = devm_regmap_init_mmio(dev, regs,
217 &meson_regmap_config); 228 &meson_regmap_config);
218 if (IS_ERR(priv->dmc)) { 229 if (IS_ERR(priv->dmc)) {
219 dev_err(&pdev->dev, "Couldn't create the DMC regmap\n"); 230 dev_err(&pdev->dev, "Couldn't create the DMC regmap\n");
220 return PTR_ERR(priv->dmc); 231 ret = PTR_ERR(priv->dmc);
232 goto free_drm;
221 } 233 }
222 234
223 priv->vsync_irq = platform_get_irq(pdev, 0); 235 priv->vsync_irq = platform_get_irq(pdev, 0);
224 236
225 drm_vblank_init(drm, 1); 237 ret = drm_vblank_init(drm, 1);
238 if (ret)
239 goto free_drm;
240
226 drm_mode_config_init(drm); 241 drm_mode_config_init(drm);
227 drm->mode_config.max_width = 3840; 242 drm->mode_config.max_width = 3840;
228 drm->mode_config.max_height = 2160; 243 drm->mode_config.max_height = 2160;
@@ -281,7 +296,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
281 return 0; 296 return 0;
282 297
283free_drm: 298free_drm:
284 drm_dev_unref(drm); 299 drm_dev_put(drm);
285 300
286 return ret; 301 return ret;
287} 302}
@@ -300,7 +315,7 @@ static void meson_drv_unbind(struct device *dev)
300 drm_kms_helper_poll_fini(drm); 315 drm_kms_helper_poll_fini(drm);
301 drm_fbdev_cma_fini(priv->fbdev); 316 drm_fbdev_cma_fini(priv->fbdev);
302 drm_mode_config_cleanup(drm); 317 drm_mode_config_cleanup(drm);
303 drm_dev_unref(drm); 318 drm_dev_put(drm);
304 319
305} 320}
306 321
diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
index d49af17310c9..a393095aac1a 100644
--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
@@ -538,7 +538,6 @@ static irqreturn_t dw_hdmi_top_thread_irq(int irq, void *dev_id)
538 return IRQ_HANDLED; 538 return IRQ_HANDLED;
539} 539}
540 540
541/* TOFIX Enable support for non-vic modes */
542static enum drm_mode_status 541static enum drm_mode_status
543dw_hdmi_mode_valid(struct drm_connector *connector, 542dw_hdmi_mode_valid(struct drm_connector *connector,
544 const struct drm_display_mode *mode) 543 const struct drm_display_mode *mode)
@@ -555,12 +554,12 @@ dw_hdmi_mode_valid(struct drm_connector *connector,
555 mode->vdisplay, mode->vsync_start, 554 mode->vdisplay, mode->vsync_start,
556 mode->vsync_end, mode->vtotal, mode->type, mode->flags); 555 mode->vsync_end, mode->vtotal, mode->type, mode->flags);
557 556
558 /* For now, only accept VIC modes */ 557 /* Check against non-VIC supported modes */
559 if (!vic) 558 if (!vic) {
560 return MODE_BAD; 559 if (!meson_venc_hdmi_supported_mode(mode))
561 560 return MODE_BAD;
562 /* For now, filter by supported VIC modes */ 561 /* Check against supported VIC modes */
563 if (!meson_venc_hdmi_supported_vic(vic)) 562 } else if (!meson_venc_hdmi_supported_vic(vic))
564 return MODE_BAD; 563 return MODE_BAD;
565 564
566 vclk_freq = mode->clock; 565 vclk_freq = mode->clock;
@@ -586,9 +585,14 @@ dw_hdmi_mode_valid(struct drm_connector *connector,
586 585
587 /* Finally filter by configurable vclk frequencies */ 586 /* Finally filter by configurable vclk frequencies */
588 switch (vclk_freq) { 587 switch (vclk_freq) {
588 case 25175:
589 case 40000:
589 case 54000: 590 case 54000:
591 case 65000:
590 case 74250: 592 case 74250:
593 case 108000:
591 case 148500: 594 case 148500:
595 case 162000:
592 case 297000: 596 case 297000:
593 case 594000: 597 case 594000:
594 return MODE_OK; 598 return MODE_OK;
@@ -653,10 +657,6 @@ static void meson_venc_hdmi_encoder_mode_set(struct drm_encoder *encoder,
653 DRM_DEBUG_DRIVER("%d:\"%s\" vic %d\n", 657 DRM_DEBUG_DRIVER("%d:\"%s\" vic %d\n",
654 mode->base.id, mode->name, vic); 658 mode->base.id, mode->name, vic);
655 659
656 /* Should have been filtered */
657 if (!vic)
658 return;
659
660 /* VENC + VENC-DVI Mode setup */ 660 /* VENC + VENC-DVI Mode setup */
661 meson_venc_hdmi_mode_set(priv, vic, mode); 661 meson_venc_hdmi_mode_set(priv, vic, mode);
662 662
diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c
index 47677047e42d..f0511220317f 100644
--- a/drivers/gpu/drm/meson/meson_vclk.c
+++ b/drivers/gpu/drm/meson/meson_vclk.c
@@ -328,14 +328,24 @@ static void meson_venci_cvbs_clock_config(struct meson_drm *priv)
328#define MESON_VCLK_HDMI_DDR_54000 2 328#define MESON_VCLK_HDMI_DDR_54000 2
329/* 2970 /4 /1 /1 /5 /1 => /1 /2 */ 329/* 2970 /4 /1 /1 /5 /1 => /1 /2 */
330#define MESON_VCLK_HDMI_DDR_148500 3 330#define MESON_VCLK_HDMI_DDR_148500 3
331/* 4028 /4 /4 /1 /5 /2 => /1 /1 */
332#define MESON_VCLK_HDMI_25175 4
333/* 3200 /4 /2 /1 /5 /2 => /1 /1 */
334#define MESON_VCLK_HDMI_40000 5
335/* 5200 /4 /2 /1 /5 /2 => /1 /1 */
336#define MESON_VCLK_HDMI_65000 6
331/* 2970 /2 /2 /2 /5 /1 => /1 /1 */ 337/* 2970 /2 /2 /2 /5 /1 => /1 /1 */
332#define MESON_VCLK_HDMI_74250 4 338#define MESON_VCLK_HDMI_74250 7
339/* 4320 /4 /1 /1 /5 /2 => /1 /1 */
340#define MESON_VCLK_HDMI_108000 8
333/* 2970 /1 /2 /2 /5 /1 => /1 /1 */ 341/* 2970 /1 /2 /2 /5 /1 => /1 /1 */
334#define MESON_VCLK_HDMI_148500 5 342#define MESON_VCLK_HDMI_148500 9
343/* 3240 /2 /1 /1 /5 /2 => /1 /1 */
344#define MESON_VCLK_HDMI_162000 10
335/* 2970 /1 /1 /1 /5 /2 => /1 /1 */ 345/* 2970 /1 /1 /1 /5 /2 => /1 /1 */
336#define MESON_VCLK_HDMI_297000 6 346#define MESON_VCLK_HDMI_297000 11
337/* 5940 /1 /1 /2 /5 /1 => /1 /1 */ 347/* 5940 /1 /1 /2 /5 /1 => /1 /1 */
338#define MESON_VCLK_HDMI_594000 7 348#define MESON_VCLK_HDMI_594000 12
339 349
340struct meson_vclk_params { 350struct meson_vclk_params {
341 unsigned int pll_base_freq; 351 unsigned int pll_base_freq;
@@ -401,6 +411,46 @@ struct meson_vclk_params {
401 .vid_pll_div = VID_PLL_DIV_5, 411 .vid_pll_div = VID_PLL_DIV_5,
402 .vclk_div = 1, 412 .vclk_div = 1,
403 }, 413 },
414 [MESON_VCLK_HDMI_25175] = {
415 .pll_base_freq = 4028000,
416 .pll_od1 = 4,
417 .pll_od2 = 4,
418 .pll_od3 = 1,
419 .vid_pll_div = VID_PLL_DIV_5,
420 .vclk_div = 2,
421 },
422 [MESON_VCLK_HDMI_40000] = {
423 .pll_base_freq = 3200000,
424 .pll_od1 = 4,
425 .pll_od2 = 2,
426 .pll_od3 = 1,
427 .vid_pll_div = VID_PLL_DIV_5,
428 .vclk_div = 2,
429 },
430 [MESON_VCLK_HDMI_65000] = {
431 .pll_base_freq = 5200000,
432 .pll_od1 = 4,
433 .pll_od2 = 2,
434 .pll_od3 = 1,
435 .vid_pll_div = VID_PLL_DIV_5,
436 .vclk_div = 2,
437 },
438 [MESON_VCLK_HDMI_108000] = {
439 .pll_base_freq = 4320000,
440 .pll_od1 = 4,
441 .pll_od2 = 1,
442 .pll_od3 = 1,
443 .vid_pll_div = VID_PLL_DIV_5,
444 .vclk_div = 2,
445 },
446 [MESON_VCLK_HDMI_162000] = {
447 .pll_base_freq = 3240000,
448 .pll_od1 = 2,
449 .pll_od2 = 1,
450 .pll_od3 = 1,
451 .vid_pll_div = VID_PLL_DIV_5,
452 .vclk_div = 2,
453 },
404}; 454};
405 455
406static inline unsigned int pll_od_to_reg(unsigned int od) 456static inline unsigned int pll_od_to_reg(unsigned int od)
@@ -451,6 +501,90 @@ void meson_hdmi_pll_set(struct meson_drm *priv,
451 0xFFFF, 0x4e00); 501 0xFFFF, 0x4e00);
452 break; 502 break;
453 503
504 case 3200000:
505 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000242);
506 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
507 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
508 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
509 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
510 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
511
512 /* unreset */
513 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
514 BIT(28), 0);
515
516 /* Poll for lock bit */
517 regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
518 val, (val & HDMI_PLL_LOCK), 10, 0);
519
520 /* div_frac */
521 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
522 0xFFFF, 0x4aab);
523 break;
524
525 case 3240000:
526 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000243);
527 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
528 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
529 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
530 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
531 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
532
533 /* unreset */
534 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
535 BIT(28), 0);
536
537 /* Poll for lock bit */
538 regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
539 val, (val & HDMI_PLL_LOCK), 10, 0);
540
541 /* div_frac */
542 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
543 0xFFFF, 0x4800);
544 break;
545
546 case 3865000:
547 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000250);
548 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
549 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
550 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
551 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
552 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
553
554 /* unreset */
555 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
556 BIT(28), 0);
557
558 /* Poll for lock bit */
559 regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
560 val, (val & HDMI_PLL_LOCK), 10, 0);
561
562 /* div_frac */
563 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
564 0xFFFF, 0x4855);
565 break;
566
567 case 4028000:
568 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000253);
569 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
570 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
571 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
572 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
573 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
574
575 /* unreset */
576 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
577 BIT(28), 0);
578
579 /* Poll for lock bit */
580 regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
581 val, (val & HDMI_PLL_LOCK), 10, 0);
582
583 /* div_frac */
584 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
585 0xFFFF, 0x4eab);
586 break;
587
454 case 4320000: 588 case 4320000:
455 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800025a); 589 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800025a);
456 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000); 590 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
@@ -485,6 +619,23 @@ void meson_hdmi_pll_set(struct meson_drm *priv,
485 regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, 619 regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
486 val, (val & HDMI_PLL_LOCK), 10, 0); 620 val, (val & HDMI_PLL_LOCK), 10, 0);
487 break; 621 break;
622
623 case 5200000:
624 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800026c);
625 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
626 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x135c5091);
627 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
628 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
629 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
630
631 /* unreset */
632 regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
633 BIT(28), 0);
634
635 /* Poll for lock bit */
636 regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
637 val, (val & HDMI_PLL_LOCK), 10, 0);
638 break;
488 }; 639 };
489 } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") || 640 } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
490 meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) { 641 meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) {
@@ -498,6 +649,42 @@ void meson_hdmi_pll_set(struct meson_drm *priv,
498 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); 649 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
499 break; 650 break;
500 651
652 case 3200000:
653 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000285);
654 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb155);
655 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
656 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
657 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
658 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
659 break;
660
661 case 3240000:
662 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000287);
663 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000);
664 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
665 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
666 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
667 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
668 break;
669
670 case 3865000:
671 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002a1);
672 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb02b);
673 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
674 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
675 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
676 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
677 break;
678
679 case 4028000:
680 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002a7);
681 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb355);
682 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
683 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
684 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
685 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
686 break;
687
501 case 4320000: 688 case 4320000:
502 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002b4); 689 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002b4);
503 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000); 690 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000);
@@ -516,6 +703,15 @@ void meson_hdmi_pll_set(struct meson_drm *priv,
516 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500); 703 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
517 break; 704 break;
518 705
706 case 5200000:
707 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002d8);
708 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb2ab);
709 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
710 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
711 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
712 regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
713 break;
714
519 }; 715 };
520 716
521 /* Reset PLL */ 717 /* Reset PLL */
@@ -590,15 +786,30 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
590 else 786 else
591 freq = MESON_VCLK_HDMI_DDR_54000; 787 freq = MESON_VCLK_HDMI_DDR_54000;
592 break; 788 break;
789 case 25175:
790 freq = MESON_VCLK_HDMI_25175;
791 break;
792 case 40000:
793 freq = MESON_VCLK_HDMI_40000;
794 break;
795 case 65000:
796 freq = MESON_VCLK_HDMI_65000;
797 break;
593 case 74250: 798 case 74250:
594 freq = MESON_VCLK_HDMI_74250; 799 freq = MESON_VCLK_HDMI_74250;
595 break; 800 break;
801 case 108000:
802 freq = MESON_VCLK_HDMI_108000;
803 break;
596 case 148500: 804 case 148500:
597 if (dac_freq != 148500) 805 if (dac_freq != 148500)
598 freq = MESON_VCLK_HDMI_DDR_148500; 806 freq = MESON_VCLK_HDMI_DDR_148500;
599 else 807 else
600 freq = MESON_VCLK_HDMI_148500; 808 freq = MESON_VCLK_HDMI_148500;
601 break; 809 break;
810 case 162000:
811 freq = MESON_VCLK_HDMI_162000;
812 break;
602 case 297000: 813 case 297000:
603 freq = MESON_VCLK_HDMI_297000; 814 freq = MESON_VCLK_HDMI_297000;
604 break; 815 break;
diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c
index 9509017dbded..6e2701389801 100644
--- a/drivers/gpu/drm/meson/meson_venc.c
+++ b/drivers/gpu/drm/meson/meson_venc.c
@@ -697,6 +697,314 @@ union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p60 = {
697 }, 697 },
698}; 698};
699 699
700union meson_hdmi_venc_mode meson_hdmi_encp_mode_640x480_60 = {
701 .encp = {
702 .dvi_settings = 0x21,
703 .video_mode = 0x4040,
704 .video_mode_adv = 0x18,
705 /* video_prog_mode */
706 /* video_sync_mode */
707 /* video_yc_dly */
708 /* video_rgb_ctrl */
709 /* video_filt_ctrl */
710 /* video_ofld_voav_ofst */
711 /* yfp1_htime */
712 /* yfp2_htime */
713 .max_pxcnt = 0x31f,
714 /* hspuls_begin */
715 /* hspuls_end */
716 /* hspuls_switch */
717 /* vspuls_begin */
718 /* vspuls_end */
719 /* vspuls_bline */
720 /* vspuls_eline */
721 .havon_begin = 0x90,
722 .havon_end = 0x30f,
723 .vavon_bline = 0x23,
724 .vavon_eline = 0x202,
725 /* eqpuls_begin */
726 /* eqpuls_end */
727 /* eqpuls_bline */
728 /* eqpuls_eline */
729 .hso_begin = 0,
730 .hso_end = 0x60,
731 .vso_begin = 0x1e,
732 .vso_end = 0x32,
733 .vso_bline = 0,
734 .vso_eline = 2,
735 .vso_eline_present = true,
736 /* sy_val */
737 /* sy2_val */
738 .max_lncnt = 0x20c,
739 },
740};
741
742union meson_hdmi_venc_mode meson_hdmi_encp_mode_800x600_60 = {
743 .encp = {
744 .dvi_settings = 0x21,
745 .video_mode = 0x4040,
746 .video_mode_adv = 0x18,
747 /* video_prog_mode */
748 /* video_sync_mode */
749 /* video_yc_dly */
750 /* video_rgb_ctrl */
751 /* video_filt_ctrl */
752 /* video_ofld_voav_ofst */
753 /* yfp1_htime */
754 /* yfp2_htime */
755 .max_pxcnt = 0x41f,
756 /* hspuls_begin */
757 /* hspuls_end */
758 /* hspuls_switch */
759 /* vspuls_begin */
760 /* vspuls_end */
761 /* vspuls_bline */
762 /* vspuls_eline */
763 .havon_begin = 0xD8,
764 .havon_end = 0x3f7,
765 .vavon_bline = 0x1b,
766 .vavon_eline = 0x272,
767 /* eqpuls_begin */
768 /* eqpuls_end */
769 /* eqpuls_bline */
770 /* eqpuls_eline */
771 .hso_begin = 0,
772 .hso_end = 0x80,
773 .vso_begin = 0x1e,
774 .vso_end = 0x32,
775 .vso_bline = 0,
776 .vso_eline = 4,
777 .vso_eline_present = true,
778 /* sy_val */
779 /* sy2_val */
780 .max_lncnt = 0x273,
781 },
782};
783
784union meson_hdmi_venc_mode meson_hdmi_encp_mode_1024x768_60 = {
785 .encp = {
786 .dvi_settings = 0x21,
787 .video_mode = 0x4040,
788 .video_mode_adv = 0x18,
789 /* video_prog_mode */
790 /* video_sync_mode */
791 /* video_yc_dly */
792 /* video_rgb_ctrl */
793 /* video_filt_ctrl */
794 /* video_ofld_voav_ofst */
795 /* yfp1_htime */
796 /* yfp2_htime */
797 .max_pxcnt = 1343,
798 /* hspuls_begin */
799 /* hspuls_end */
800 /* hspuls_switch */
801 /* vspuls_begin */
802 /* vspuls_end */
803 /* vspuls_bline */
804 /* vspuls_eline */
805 .havon_begin = 296,
806 .havon_end = 1319,
807 .vavon_bline = 35,
808 .vavon_eline = 802,
809 /* eqpuls_begin */
810 /* eqpuls_end */
811 /* eqpuls_bline */
812 /* eqpuls_eline */
813 .hso_begin = 0,
814 .hso_end = 136,
815 .vso_begin = 30,
816 .vso_end = 50,
817 .vso_bline = 0,
818 .vso_eline = 6,
819 .vso_eline_present = true,
820 /* sy_val */
821 /* sy2_val */
822 .max_lncnt = 805,
823 },
824};
825
826union meson_hdmi_venc_mode meson_hdmi_encp_mode_1152x864_75 = {
827 .encp = {
828 .dvi_settings = 0x21,
829 .video_mode = 0x4040,
830 .video_mode_adv = 0x18,
831 /* video_prog_mode */
832 /* video_sync_mode */
833 /* video_yc_dly */
834 /* video_rgb_ctrl */
835 /* video_filt_ctrl */
836 /* video_ofld_voav_ofst */
837 /* yfp1_htime */
838 /* yfp2_htime */
839 .max_pxcnt = 0x63f,
840 /* hspuls_begin */
841 /* hspuls_end */
842 /* hspuls_switch */
843 /* vspuls_begin */
844 /* vspuls_end */
845 /* vspuls_bline */
846 /* vspuls_eline */
847 .havon_begin = 0x180,
848 .havon_end = 0x5ff,
849 .vavon_bline = 0x23,
850 .vavon_eline = 0x382,
851 /* eqpuls_begin */
852 /* eqpuls_end */
853 /* eqpuls_bline */
854 /* eqpuls_eline */
855 .hso_begin = 0,
856 .hso_end = 0x80,
857 .vso_begin = 0x1e,
858 .vso_end = 0x32,
859 .vso_bline = 0,
860 .vso_eline = 3,
861 .vso_eline_present = true,
862 /* sy_val */
863 /* sy2_val */
864 .max_lncnt = 0x383,
865 },
866};
867
868union meson_hdmi_venc_mode meson_hdmi_encp_mode_1280x1024_60 = {
869 .encp = {
870 .dvi_settings = 0x21,
871 .video_mode = 0x4040,
872 .video_mode_adv = 0x18,
873 /* video_prog_mode */
874 /* video_sync_mode */
875 /* video_yc_dly */
876 /* video_rgb_ctrl */
877 /* video_filt_ctrl */
878 /* video_ofld_voav_ofst */
879 /* yfp1_htime */
880 /* yfp2_htime */
881 .max_pxcnt = 0x697,
882 /* hspuls_begin */
883 /* hspuls_end */
884 /* hspuls_switch */
885 /* vspuls_begin */
886 /* vspuls_end */
887 /* vspuls_bline */
888 /* vspuls_eline */
889 .havon_begin = 0x168,
890 .havon_end = 0x667,
891 .vavon_bline = 0x29,
892 .vavon_eline = 0x428,
893 /* eqpuls_begin */
894 /* eqpuls_end */
895 /* eqpuls_bline */
896 /* eqpuls_eline */
897 .hso_begin = 0,
898 .hso_end = 0x70,
899 .vso_begin = 0x1e,
900 .vso_end = 0x32,
901 .vso_bline = 0,
902 .vso_eline = 3,
903 .vso_eline_present = true,
904 /* sy_val */
905 /* sy2_val */
906 .max_lncnt = 0x429,
907 },
908};
909
910union meson_hdmi_venc_mode meson_hdmi_encp_mode_1600x1200_60 = {
911 .encp = {
912 .dvi_settings = 0x21,
913 .video_mode = 0x4040,
914 .video_mode_adv = 0x18,
915 /* video_prog_mode */
916 /* video_sync_mode */
917 /* video_yc_dly */
918 /* video_rgb_ctrl */
919 /* video_filt_ctrl */
920 /* video_ofld_voav_ofst */
921 /* yfp1_htime */
922 /* yfp2_htime */
923 .max_pxcnt = 0x86f,
924 /* hspuls_begin */
925 /* hspuls_end */
926 /* hspuls_switch */
927 /* vspuls_begin */
928 /* vspuls_end */
929 /* vspuls_bline */
930 /* vspuls_eline */
931 .havon_begin = 0x1f0,
932 .havon_end = 0x82f,
933 .vavon_bline = 0x31,
934 .vavon_eline = 0x4e0,
935 /* eqpuls_begin */
936 /* eqpuls_end */
937 /* eqpuls_bline */
938 /* eqpuls_eline */
939 .hso_begin = 0,
940 .hso_end = 0xc0,
941 .vso_begin = 0x1e,
942 .vso_end = 0x32,
943 .vso_bline = 0,
944 .vso_eline = 3,
945 .vso_eline_present = true,
946 /* sy_val */
947 /* sy2_val */
948 .max_lncnt = 0x4e1,
949 },
950};
951
952struct meson_hdmi_venc_dmt_mode {
953 struct drm_display_mode drm_mode;
954 union meson_hdmi_venc_mode *mode;
955} meson_hdmi_venc_dmt_modes[] = {
956 /* 640x480@60Hz */
957 {
958 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
959 752, 800, 0, 480, 490, 492, 525, 0,
960 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
961 &meson_hdmi_encp_mode_640x480_60,
962 },
963 /* 800x600@60Hz */
964 {
965 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
966 968, 1056, 0, 600, 601, 605, 628, 0,
967 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
968 &meson_hdmi_encp_mode_800x600_60,
969 },
970 /* 1024x768@60Hz */
971 {
972 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024,
973 1048, 1184, 1344, 0, 768, 771, 777, 806, 0,
974 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
975 &meson_hdmi_encp_mode_1024x768_60,
976 },
977 /* 1152x864@75Hz */
978 {
979 { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152,
980 1216, 1344, 1600, 0, 864, 865, 868, 900, 0,
981 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
982 &meson_hdmi_encp_mode_1152x864_75,
983 },
984 /* 1280x1024@60Hz */
985 {
986 { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280,
987 1328, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
988 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
989 &meson_hdmi_encp_mode_1280x1024_60,
990 },
991 /* 1600x1200@60Hz */
992 {
993 { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600,
994 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
995 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
996 &meson_hdmi_encp_mode_1600x1200_60,
997 },
998 /* 1920x1080@60Hz */
999 {
1000 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920,
1001 2008, 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
1002 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
1003 &meson_hdmi_encp_mode_1080p60
1004 },
1005 { }, /* sentinel */
1006};
1007
700struct meson_hdmi_venc_vic_mode { 1008struct meson_hdmi_venc_vic_mode {
701 unsigned int vic; 1009 unsigned int vic;
702 union meson_hdmi_venc_mode *mode; 1010 union meson_hdmi_venc_mode *mode;
@@ -736,6 +1044,20 @@ static unsigned long modulo(unsigned long a, unsigned long b)
736 return a; 1044 return a;
737} 1045}
738 1046
1047bool meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode)
1048{
1049 struct meson_hdmi_venc_dmt_mode *vmode = meson_hdmi_venc_dmt_modes;
1050
1051 while (vmode->mode) {
1052 if (drm_mode_equal(&vmode->drm_mode, mode))
1053 return true;
1054 vmode++;
1055 }
1056
1057 return false;
1058}
1059EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_mode);
1060
739bool meson_venc_hdmi_supported_vic(int vic) 1061bool meson_venc_hdmi_supported_vic(int vic)
740{ 1062{
741 struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes; 1063 struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes;
@@ -750,6 +1072,20 @@ bool meson_venc_hdmi_supported_vic(int vic)
750} 1072}
751EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_vic); 1073EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_vic);
752 1074
1075static union meson_hdmi_venc_mode
1076*meson_venc_hdmi_get_dmt_vmode(const struct drm_display_mode *mode)
1077{
1078 struct meson_hdmi_venc_dmt_mode *vmode = meson_hdmi_venc_dmt_modes;
1079
1080 while (vmode->mode) {
1081 if (drm_mode_equal(&vmode->drm_mode, mode))
1082 return vmode->mode;
1083 vmode++;
1084 }
1085
1086 return NULL;
1087}
1088
753static union meson_hdmi_venc_mode *meson_venc_hdmi_get_vic_vmode(int vic) 1089static union meson_hdmi_venc_mode *meson_venc_hdmi_get_vic_vmode(int vic)
754{ 1090{
755 struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes; 1091 struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes;
@@ -811,10 +1147,13 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
811 unsigned int sof_lines; 1147 unsigned int sof_lines;
812 unsigned int vsync_lines; 1148 unsigned int vsync_lines;
813 1149
814 vmode = meson_venc_hdmi_get_vic_vmode(vic); 1150 if (meson_venc_hdmi_supported_vic(vic))
1151 vmode = meson_venc_hdmi_get_vic_vmode(vic);
1152 else
1153 vmode = meson_venc_hdmi_get_dmt_vmode(mode);
815 if (!vmode) { 1154 if (!vmode) {
816 dev_err(priv->dev, "%s: Fatal Error, unsupported vic %d\n", 1155 dev_err(priv->dev, "%s: Fatal Error, unsupported mode "
817 __func__, vic); 1156 DRM_MODE_FMT "\n", __func__, DRM_MODE_ARG(mode));
818 return; 1157 return;
819 } 1158 }
820 1159
@@ -864,7 +1203,7 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
864 hsync_pixels_venc *= 2; 1203 hsync_pixels_venc *= 2;
865 1204
866 /* Disable VDACs */ 1205 /* Disable VDACs */
867 writel_bits_relaxed(0x1f, 0x1f, 1206 writel_bits_relaxed(0xff, 0xff,
868 priv->io_base + _REG(VENC_VDAC_SETTING)); 1207 priv->io_base + _REG(VENC_VDAC_SETTING));
869 1208
870 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN)); 1209 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN));
diff --git a/drivers/gpu/drm/meson/meson_venc.h b/drivers/gpu/drm/meson/meson_venc.h
index a1b96e898c14..7c18a36a0dd0 100644
--- a/drivers/gpu/drm/meson/meson_venc.h
+++ b/drivers/gpu/drm/meson/meson_venc.h
@@ -58,6 +58,7 @@ struct meson_cvbs_enci_mode {
58}; 58};
59 59
60/* HDMI Clock parameters */ 60/* HDMI Clock parameters */
61bool meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode);
61bool meson_venc_hdmi_supported_vic(int vic); 62bool meson_venc_hdmi_supported_vic(int vic);
62bool meson_venc_hdmi_venc_repeat(int vic); 63bool meson_venc_hdmi_venc_repeat(int vic);
63 64
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 3e293029e3a6..bbbf353682e1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -510,37 +510,6 @@ static int nouveau_drm_probe(struct pci_dev *pdev,
510 return 0; 510 return 0;
511} 511}
512 512
513#define PCI_CLASS_MULTIMEDIA_HD_AUDIO 0x0403
514
515static void
516nouveau_get_hdmi_dev(struct nouveau_drm *drm)
517{
518 struct pci_dev *pdev = drm->dev->pdev;
519
520 if (!pdev) {
521 NV_DEBUG(drm, "not a PCI device; no HDMI\n");
522 drm->hdmi_device = NULL;
523 return;
524 }
525
526 /* subfunction one is a hdmi audio device? */
527 drm->hdmi_device = pci_get_domain_bus_and_slot(pci_domain_nr(pdev->bus),
528 (unsigned int)pdev->bus->number,
529 PCI_DEVFN(PCI_SLOT(pdev->devfn), 1));
530
531 if (!drm->hdmi_device) {
532 NV_DEBUG(drm, "hdmi device not found %d %d %d\n", pdev->bus->number, PCI_SLOT(pdev->devfn), 1);
533 return;
534 }
535
536 if ((drm->hdmi_device->class >> 8) != PCI_CLASS_MULTIMEDIA_HD_AUDIO) {
537 NV_DEBUG(drm, "possible hdmi device not audio %d\n", drm->hdmi_device->class);
538 pci_dev_put(drm->hdmi_device);
539 drm->hdmi_device = NULL;
540 return;
541 }
542}
543
544static int 513static int
545nouveau_drm_load(struct drm_device *dev, unsigned long flags) 514nouveau_drm_load(struct drm_device *dev, unsigned long flags)
546{ 515{
@@ -568,8 +537,6 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
568 INIT_LIST_HEAD(&drm->clients); 537 INIT_LIST_HEAD(&drm->clients);
569 spin_lock_init(&drm->tile.lock); 538 spin_lock_init(&drm->tile.lock);
570 539
571 nouveau_get_hdmi_dev(drm);
572
573 /* workaround an odd issue on nvc1 by disabling the device's 540 /* workaround an odd issue on nvc1 by disabling the device's
574 * nosnoop capability. hopefully won't cause issues until a 541 * nosnoop capability. hopefully won't cause issues until a
575 * better fix is found - assuming there is one... 542 * better fix is found - assuming there is one...
@@ -655,8 +622,6 @@ nouveau_drm_unload(struct drm_device *dev)
655 nouveau_ttm_fini(drm); 622 nouveau_ttm_fini(drm);
656 nouveau_vga_fini(drm); 623 nouveau_vga_fini(drm);
657 624
658 if (drm->hdmi_device)
659 pci_dev_put(drm->hdmi_device);
660 nouveau_cli_fini(&drm->client); 625 nouveau_cli_fini(&drm->client);
661 nouveau_cli_fini(&drm->master); 626 nouveau_cli_fini(&drm->master);
662 kfree(drm); 627 kfree(drm);
@@ -856,7 +821,6 @@ nouveau_pmops_runtime_suspend(struct device *dev)
856 } 821 }
857 822
858 drm_kms_helper_poll_disable(drm_dev); 823 drm_kms_helper_poll_disable(drm_dev);
859 vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF);
860 nouveau_switcheroo_optimus_dsm(); 824 nouveau_switcheroo_optimus_dsm();
861 ret = nouveau_do_suspend(drm_dev, true); 825 ret = nouveau_do_suspend(drm_dev, true);
862 pci_save_state(pdev); 826 pci_save_state(pdev);
@@ -891,7 +855,6 @@ nouveau_pmops_runtime_resume(struct device *dev)
891 855
892 /* do magic */ 856 /* do magic */
893 nvif_mask(&device->object, 0x088488, (1 << 25), (1 << 25)); 857 nvif_mask(&device->object, 0x088488, (1 << 25), (1 << 25));
894 vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_ON);
895 drm_dev->switch_power_state = DRM_SWITCH_POWER_ON; 858 drm_dev->switch_power_state = DRM_SWITCH_POWER_ON;
896 859
897 /* Monitors may have been connected / disconnected during suspend */ 860 /* Monitors may have been connected / disconnected during suspend */
@@ -913,15 +876,6 @@ nouveau_pmops_runtime_idle(struct device *dev)
913 return -EBUSY; 876 return -EBUSY;
914 } 877 }
915 878
916 /* if we have a hdmi audio device - make sure it has a driver loaded */
917 if (drm->hdmi_device) {
918 if (!drm->hdmi_device->driver) {
919 DRM_DEBUG_DRIVER("failing to power off - no HDMI audio driver loaded\n");
920 pm_runtime_mark_last_busy(dev);
921 return -EBUSY;
922 }
923 }
924
925 list_for_each_entry(crtc, &drm->dev->mode_config.crtc_list, head) { 879 list_for_each_entry(crtc, &drm->dev->mode_config.crtc_list, head) {
926 if (crtc->enabled) { 880 if (crtc->enabled) {
927 DRM_DEBUG_DRIVER("failing to power off - crtc active\n"); 881 DRM_DEBUG_DRIVER("failing to power off - crtc active\n");
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 96f6bd8aee5d..881b44b89a01 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -208,7 +208,6 @@ struct nouveau_drm {
208 bool have_disp_power_ref; 208 bool have_disp_power_ref;
209 209
210 struct dev_pm_domain vga_pm_domain; 210 struct dev_pm_domain vga_pm_domain;
211 struct pci_dev *hdmi_device;
212}; 211};
213 212
214static inline struct nouveau_drm * 213static inline struct nouveau_drm *
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 988048ebcc22..25682ff3449a 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -108,6 +108,15 @@ config DRM_PANEL_RASPBERRYPI_TOUCHSCREEN
108 Pi 7" Touchscreen. To compile this driver as a module, 108 Pi 7" Touchscreen. To compile this driver as a module,
109 choose M here. 109 choose M here.
110 110
111config DRM_PANEL_RAYDIUM_RM68200
112 tristate "Raydium RM68200 720x1280 DSI video mode panel"
113 depends on OF
114 depends on DRM_MIPI_DSI
115 depends on BACKLIGHT_CLASS_DEVICE
116 help
117 Say Y here if you want to enable support for Raydium RM68200
118 720x1280 DSI video mode panel.
119
111config DRM_PANEL_SAMSUNG_S6E3HA2 120config DRM_PANEL_SAMSUNG_S6E3HA2
112 tristate "Samsung S6E3HA2 DSI video mode panel" 121 tristate "Samsung S6E3HA2 DSI video mode panel"
113 depends on OF 122 depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 3d2a88d0e965..f26efc11d746 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
9obj-$(CONFIG_DRM_PANEL_ORISETECH_OTM8009A) += panel-orisetech-otm8009a.o 9obj-$(CONFIG_DRM_PANEL_ORISETECH_OTM8009A) += panel-orisetech-otm8009a.o
10obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o 10obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o
11obj-$(CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN) += panel-raspberrypi-touchscreen.o 11obj-$(CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN) += panel-raspberrypi-touchscreen.o
12obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM68200) += panel-raydium-rm68200.o
12obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o 13obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o
13obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o 14obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o
14obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03) += panel-samsung-s6e63j0x03.o 15obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03) += panel-samsung-s6e63j0x03.o
diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9322.c b/drivers/gpu/drm/panel/panel-ilitek-ili9322.c
index b4ec0ecff807..bd38bf4f1ba6 100644
--- a/drivers/gpu/drm/panel/panel-ilitek-ili9322.c
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9322.c
@@ -179,7 +179,7 @@ enum ili9322_input {
179 ILI9322_INPUT_UNKNOWN = 0xc, 179 ILI9322_INPUT_UNKNOWN = 0xc,
180}; 180};
181 181
182const char *ili9322_inputs[] = { 182static const char * const ili9322_inputs[] = {
183 "8 bit serial RGB through", 183 "8 bit serial RGB through",
184 "8 bit serial RGB aligned", 184 "8 bit serial RGB aligned",
185 "8 bit serial RGB dummy 320x240", 185 "8 bit serial RGB dummy 320x240",
@@ -340,7 +340,7 @@ static bool ili9322_writeable_reg(struct device *dev, unsigned int reg)
340 return true; 340 return true;
341} 341}
342 342
343const struct regmap_config ili9322_regmap_config = { 343static const struct regmap_config ili9322_regmap_config = {
344 .reg_bits = 8, 344 .reg_bits = 8,
345 .val_bits = 8, 345 .val_bits = 8,
346 .max_register = 0x44, 346 .max_register = 0x44,
diff --git a/drivers/gpu/drm/panel/panel-lvds.c b/drivers/gpu/drm/panel/panel-lvds.c
index b5e3994f0aa8..5185819c5b79 100644
--- a/drivers/gpu/drm/panel/panel-lvds.c
+++ b/drivers/gpu/drm/panel/panel-lvds.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * rcar_du_crtc.c -- R-Car Display Unit CRTCs 2 * Generic LVDS panel driver
3 * 3 *
4 * Copyright (C) 2016 Laurent Pinchart 4 * Copyright (C) 2016 Laurent Pinchart
5 * Copyright (C) 2016 Renesas Electronics Corporation 5 * Copyright (C) 2016 Renesas Electronics Corporation
diff --git a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c
index c189cd6329c8..90f1ae4af93c 100644
--- a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c
+++ b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c
@@ -1,16 +1,17 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Copyright (C) STMicroelectronics SA 2017 3 * Copyright (C) STMicroelectronics SA 2017
3 * 4 *
4 * Authors: Philippe Cornu <philippe.cornu@st.com> 5 * Authors: Philippe Cornu <philippe.cornu@st.com>
5 * Yannick Fertre <yannick.fertre@st.com> 6 * Yannick Fertre <yannick.fertre@st.com>
6 *
7 * License terms: GNU General Public License (GPL), version 2
8 */ 7 */
8
9#include <drm/drmP.h> 9#include <drm/drmP.h>
10#include <drm/drm_mipi_dsi.h> 10#include <drm/drm_mipi_dsi.h>
11#include <drm/drm_panel.h> 11#include <drm/drm_panel.h>
12#include <linux/backlight.h> 12#include <linux/backlight.h>
13#include <linux/gpio/consumer.h> 13#include <linux/gpio/consumer.h>
14#include <linux/regulator/consumer.h>
14#include <video/mipi_display.h> 15#include <video/mipi_display.h>
15 16
16#define DRV_NAME "orisetech_otm8009a" 17#define DRV_NAME "orisetech_otm8009a"
@@ -62,6 +63,7 @@ struct otm8009a {
62 struct drm_panel panel; 63 struct drm_panel panel;
63 struct backlight_device *bl_dev; 64 struct backlight_device *bl_dev;
64 struct gpio_desc *reset_gpio; 65 struct gpio_desc *reset_gpio;
66 struct regulator *supply;
65 bool prepared; 67 bool prepared;
66 bool enabled; 68 bool enabled;
67}; 69};
@@ -279,6 +281,8 @@ static int otm8009a_unprepare(struct drm_panel *panel)
279 msleep(20); 281 msleep(20);
280 } 282 }
281 283
284 regulator_disable(ctx->supply);
285
282 ctx->prepared = false; 286 ctx->prepared = false;
283 287
284 return 0; 288 return 0;
@@ -292,6 +296,12 @@ static int otm8009a_prepare(struct drm_panel *panel)
292 if (ctx->prepared) 296 if (ctx->prepared)
293 return 0; 297 return 0;
294 298
299 ret = regulator_enable(ctx->supply);
300 if (ret < 0) {
301 DRM_ERROR("failed to enable supply: %d\n", ret);
302 return ret;
303 }
304
295 if (ctx->reset_gpio) { 305 if (ctx->reset_gpio) {
296 gpiod_set_value_cansleep(ctx->reset_gpio, 0); 306 gpiod_set_value_cansleep(ctx->reset_gpio, 0);
297 gpiod_set_value_cansleep(ctx->reset_gpio, 1); 307 gpiod_set_value_cansleep(ctx->reset_gpio, 1);
@@ -414,6 +424,13 @@ static int otm8009a_probe(struct mipi_dsi_device *dsi)
414 return PTR_ERR(ctx->reset_gpio); 424 return PTR_ERR(ctx->reset_gpio);
415 } 425 }
416 426
427 ctx->supply = devm_regulator_get(dev, "power");
428 if (IS_ERR(ctx->supply)) {
429 ret = PTR_ERR(ctx->supply);
430 dev_err(dev, "failed to request regulator: %d\n", ret);
431 return ret;
432 }
433
417 mipi_dsi_set_drvdata(dsi, ctx); 434 mipi_dsi_set_drvdata(dsi, ctx);
418 435
419 ctx->dev = dev; 436 ctx->dev = dev;
diff --git a/drivers/gpu/drm/panel/panel-raydium-rm68200.c b/drivers/gpu/drm/panel/panel-raydium-rm68200.c
new file mode 100644
index 000000000000..77593533abcd
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-raydium-rm68200.c
@@ -0,0 +1,448 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) STMicroelectronics SA 2017
4 *
5 * Authors: Philippe Cornu <philippe.cornu@st.com>
6 * Yannick Fertre <yannick.fertre@st.com>
7 */
8
9#include <linux/backlight.h>
10#include <linux/gpio/consumer.h>
11#include <linux/regulator/consumer.h>
12
13#include <video/mipi_display.h>
14
15#include <drm/drmP.h>
16#include <drm/drm_mipi_dsi.h>
17#include <drm/drm_panel.h>
18
19/*** Manufacturer Command Set ***/
20#define MCS_CMD_MODE_SW 0xFE /* CMD Mode Switch */
21#define MCS_CMD1_UCS 0x00 /* User Command Set (UCS = CMD1) */
22#define MCS_CMD2_P0 0x01 /* Manufacture Command Set Page0 (CMD2 P0) */
23#define MCS_CMD2_P1 0x02 /* Manufacture Command Set Page1 (CMD2 P1) */
24#define MCS_CMD2_P2 0x03 /* Manufacture Command Set Page2 (CMD2 P2) */
25#define MCS_CMD2_P3 0x04 /* Manufacture Command Set Page3 (CMD2 P3) */
26
27/* CMD2 P0 commands (Display Options and Power) */
28#define MCS_STBCTR 0x12 /* TE1 Output Setting Zig-Zag Connection */
29#define MCS_SGOPCTR 0x16 /* Source Bias Current */
30#define MCS_SDCTR 0x1A /* Source Output Delay Time */
31#define MCS_INVCTR 0x1B /* Inversion Type */
32#define MCS_EXT_PWR_IC 0x24 /* External PWR IC Control */
33#define MCS_SETAVDD 0x27 /* PFM Control for AVDD Output */
34#define MCS_SETAVEE 0x29 /* PFM Control for AVEE Output */
35#define MCS_BT2CTR 0x2B /* DDVDL Charge Pump Control */
36#define MCS_BT3CTR 0x2F /* VGH Charge Pump Control */
37#define MCS_BT4CTR 0x34 /* VGL Charge Pump Control */
38#define MCS_VCMCTR 0x46 /* VCOM Output Level Control */
39#define MCS_SETVGN 0x52 /* VG M/S N Control */
40#define MCS_SETVGP 0x54 /* VG M/S P Control */
41#define MCS_SW_CTRL 0x5F /* Interface Control for PFM and MIPI */
42
43/* CMD2 P2 commands (GOA Timing Control) - no description in datasheet */
44#define GOA_VSTV1 0x00
45#define GOA_VSTV2 0x07
46#define GOA_VCLK1 0x0E
47#define GOA_VCLK2 0x17
48#define GOA_VCLK_OPT1 0x20
49#define GOA_BICLK1 0x2A
50#define GOA_BICLK2 0x37
51#define GOA_BICLK3 0x44
52#define GOA_BICLK4 0x4F
53#define GOA_BICLK_OPT1 0x5B
54#define GOA_BICLK_OPT2 0x60
55#define MCS_GOA_GPO1 0x6D
56#define MCS_GOA_GPO2 0x71
57#define MCS_GOA_EQ 0x74
58#define MCS_GOA_CLK_GALLON 0x7C
59#define MCS_GOA_FS_SEL0 0x7E
60#define MCS_GOA_FS_SEL1 0x87
61#define MCS_GOA_FS_SEL2 0x91
62#define MCS_GOA_FS_SEL3 0x9B
63#define MCS_GOA_BS_SEL0 0xAC
64#define MCS_GOA_BS_SEL1 0xB5
65#define MCS_GOA_BS_SEL2 0xBF
66#define MCS_GOA_BS_SEL3 0xC9
67#define MCS_GOA_BS_SEL4 0xD3
68
69/* CMD2 P3 commands (Gamma) */
70#define MCS_GAMMA_VP 0x60 /* Gamma VP1~VP16 */
71#define MCS_GAMMA_VN 0x70 /* Gamma VN1~VN16 */
72
73struct rm68200 {
74 struct device *dev;
75 struct drm_panel panel;
76 struct gpio_desc *reset_gpio;
77 struct regulator *supply;
78 struct backlight_device *backlight;
79 bool prepared;
80 bool enabled;
81};
82
83static const struct drm_display_mode default_mode = {
84 .clock = 52582,
85 .hdisplay = 720,
86 .hsync_start = 720 + 38,
87 .hsync_end = 720 + 38 + 8,
88 .htotal = 720 + 38 + 8 + 38,
89 .vdisplay = 1280,
90 .vsync_start = 1280 + 12,
91 .vsync_end = 1280 + 12 + 4,
92 .vtotal = 1280 + 12 + 4 + 12,
93 .vrefresh = 50,
94 .flags = 0,
95 .width_mm = 68,
96 .height_mm = 122,
97};
98
99static inline struct rm68200 *panel_to_rm68200(struct drm_panel *panel)
100{
101 return container_of(panel, struct rm68200, panel);
102}
103
104static void rm68200_dcs_write_buf(struct rm68200 *ctx, const void *data,
105 size_t len)
106{
107 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
108 int err;
109
110 err = mipi_dsi_dcs_write_buffer(dsi, data, len);
111 if (err < 0)
112 DRM_ERROR_RATELIMITED("MIPI DSI DCS write buffer failed: %d\n",
113 err);
114}
115
116static void rm68200_dcs_write_cmd(struct rm68200 *ctx, u8 cmd, u8 value)
117{
118 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
119 int err;
120
121 err = mipi_dsi_dcs_write(dsi, cmd, &value, 1);
122 if (err < 0)
123 DRM_ERROR_RATELIMITED("MIPI DSI DCS write failed: %d\n", err);
124}
125
126#define dcs_write_seq(ctx, seq...) \
127({ \
128 static const u8 d[] = { seq }; \
129 \
130 rm68200_dcs_write_buf(ctx, d, ARRAY_SIZE(d)); \
131})
132
133/*
134 * This panel is not able to auto-increment all cmd addresses so for some of
135 * them, we need to send them one by one...
136 */
137#define dcs_write_cmd_seq(ctx, cmd, seq...) \
138({ \
139 static const u8 d[] = { seq }; \
140 unsigned int i; \
141 \
142 for (i = 0; i < ARRAY_SIZE(d) ; i++) \
143 rm68200_dcs_write_cmd(ctx, cmd + i, d[i]); \
144})
145
146static void rm68200_init_sequence(struct rm68200 *ctx)
147{
148 /* Enter CMD2 with page 0 */
149 dcs_write_seq(ctx, MCS_CMD_MODE_SW, MCS_CMD2_P0);
150 dcs_write_cmd_seq(ctx, MCS_EXT_PWR_IC, 0xC0, 0x53, 0x00);
151 dcs_write_seq(ctx, MCS_BT2CTR, 0xE5);
152 dcs_write_seq(ctx, MCS_SETAVDD, 0x0A);
153 dcs_write_seq(ctx, MCS_SETAVEE, 0x0A);
154 dcs_write_seq(ctx, MCS_SGOPCTR, 0x52);
155 dcs_write_seq(ctx, MCS_BT3CTR, 0x53);
156 dcs_write_seq(ctx, MCS_BT4CTR, 0x5A);
157 dcs_write_seq(ctx, MCS_INVCTR, 0x00);
158 dcs_write_seq(ctx, MCS_STBCTR, 0x0A);
159 dcs_write_seq(ctx, MCS_SDCTR, 0x06);
160 dcs_write_seq(ctx, MCS_VCMCTR, 0x56);
161 dcs_write_seq(ctx, MCS_SETVGN, 0xA0, 0x00);
162 dcs_write_seq(ctx, MCS_SETVGP, 0xA0, 0x00);
163 dcs_write_seq(ctx, MCS_SW_CTRL, 0x11); /* 2 data lanes, see doc */
164
165 dcs_write_seq(ctx, MCS_CMD_MODE_SW, MCS_CMD2_P2);
166 dcs_write_seq(ctx, GOA_VSTV1, 0x05);
167 dcs_write_seq(ctx, 0x02, 0x0B);
168 dcs_write_seq(ctx, 0x03, 0x0F);
169 dcs_write_seq(ctx, 0x04, 0x7D, 0x00, 0x50);
170 dcs_write_cmd_seq(ctx, GOA_VSTV2, 0x05, 0x16, 0x0D, 0x11, 0x7D, 0x00,
171 0x50);
172 dcs_write_cmd_seq(ctx, GOA_VCLK1, 0x07, 0x08, 0x01, 0x02, 0x00, 0x7D,
173 0x00, 0x85, 0x08);
174 dcs_write_cmd_seq(ctx, GOA_VCLK2, 0x03, 0x04, 0x05, 0x06, 0x00, 0x7D,
175 0x00, 0x85, 0x08);
176 dcs_write_seq(ctx, GOA_VCLK_OPT1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
177 0x00, 0x00, 0x00, 0x00);
178 dcs_write_cmd_seq(ctx, GOA_BICLK1, 0x07, 0x08);
179 dcs_write_seq(ctx, 0x2D, 0x01);
180 dcs_write_seq(ctx, 0x2F, 0x02, 0x00, 0x40, 0x05, 0x08, 0x54, 0x7D,
181 0x00);
182 dcs_write_cmd_seq(ctx, GOA_BICLK2, 0x03, 0x04, 0x05, 0x06, 0x00);
183 dcs_write_seq(ctx, 0x3D, 0x40);
184 dcs_write_seq(ctx, 0x3F, 0x05, 0x08, 0x54, 0x7D, 0x00);
185 dcs_write_seq(ctx, GOA_BICLK3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
186 0x00, 0x00, 0x00, 0x00, 0x00);
187 dcs_write_seq(ctx, GOA_BICLK4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
188 0x00, 0x00);
189 dcs_write_seq(ctx, 0x58, 0x00, 0x00, 0x00);
190 dcs_write_seq(ctx, GOA_BICLK_OPT1, 0x00, 0x00, 0x00, 0x00, 0x00);
191 dcs_write_seq(ctx, GOA_BICLK_OPT2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
192 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
193 dcs_write_seq(ctx, MCS_GOA_GPO1, 0x00, 0x00, 0x00, 0x00);
194 dcs_write_seq(ctx, MCS_GOA_GPO2, 0x00, 0x20, 0x00);
195 dcs_write_seq(ctx, MCS_GOA_EQ, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
196 0x00, 0x00);
197 dcs_write_seq(ctx, MCS_GOA_CLK_GALLON, 0x00, 0x00);
198 dcs_write_cmd_seq(ctx, MCS_GOA_FS_SEL0, 0xBF, 0x02, 0x06, 0x14, 0x10,
199 0x16, 0x12, 0x08, 0x3F);
200 dcs_write_cmd_seq(ctx, MCS_GOA_FS_SEL1, 0x3F, 0x3F, 0x3F, 0x3F, 0x0C,
201 0x0A, 0x0E, 0x3F, 0x3F, 0x00);
202 dcs_write_cmd_seq(ctx, MCS_GOA_FS_SEL2, 0x04, 0x3F, 0x3F, 0x3F, 0x3F,
203 0x05, 0x01, 0x3F, 0x3F, 0x0F);
204 dcs_write_cmd_seq(ctx, MCS_GOA_FS_SEL3, 0x0B, 0x0D, 0x3F, 0x3F, 0x3F,
205 0x3F);
206 dcs_write_cmd_seq(ctx, 0xA2, 0x3F, 0x09, 0x13, 0x17, 0x11, 0x15);
207 dcs_write_cmd_seq(ctx, 0xA9, 0x07, 0x03, 0x3F);
208 dcs_write_cmd_seq(ctx, MCS_GOA_BS_SEL0, 0x3F, 0x05, 0x01, 0x17, 0x13,
209 0x15, 0x11, 0x0F, 0x3F);
210 dcs_write_cmd_seq(ctx, MCS_GOA_BS_SEL1, 0x3F, 0x3F, 0x3F, 0x3F, 0x0B,
211 0x0D, 0x09, 0x3F, 0x3F, 0x07);
212 dcs_write_cmd_seq(ctx, MCS_GOA_BS_SEL2, 0x03, 0x3F, 0x3F, 0x3F, 0x3F,
213 0x02, 0x06, 0x3F, 0x3F, 0x08);
214 dcs_write_cmd_seq(ctx, MCS_GOA_BS_SEL3, 0x0C, 0x0A, 0x3F, 0x3F, 0x3F,
215 0x3F, 0x3F, 0x0E, 0x10, 0x14);
216 dcs_write_cmd_seq(ctx, MCS_GOA_BS_SEL4, 0x12, 0x16, 0x00, 0x04, 0x3F);
217 dcs_write_seq(ctx, 0xDC, 0x02);
218 dcs_write_seq(ctx, 0xDE, 0x12);
219
220 dcs_write_seq(ctx, MCS_CMD_MODE_SW, 0x0E); /* No documentation */
221 dcs_write_seq(ctx, 0x01, 0x75);
222
223 dcs_write_seq(ctx, MCS_CMD_MODE_SW, MCS_CMD2_P3);
224 dcs_write_cmd_seq(ctx, MCS_GAMMA_VP, 0x00, 0x0C, 0x12, 0x0E, 0x06,
225 0x12, 0x0E, 0x0B, 0x15, 0x0B, 0x10, 0x07, 0x0F,
226 0x12, 0x0C, 0x00);
227 dcs_write_cmd_seq(ctx, MCS_GAMMA_VN, 0x00, 0x0C, 0x12, 0x0E, 0x06,
228 0x12, 0x0E, 0x0B, 0x15, 0x0B, 0x10, 0x07, 0x0F,
229 0x12, 0x0C, 0x00);
230
231 /* Exit CMD2 */
232 dcs_write_seq(ctx, MCS_CMD_MODE_SW, MCS_CMD1_UCS);
233}
234
235static int rm68200_disable(struct drm_panel *panel)
236{
237 struct rm68200 *ctx = panel_to_rm68200(panel);
238
239 if (!ctx->enabled)
240 return 0;
241
242 backlight_disable(ctx->backlight);
243
244 ctx->enabled = false;
245
246 return 0;
247}
248
249static int rm68200_unprepare(struct drm_panel *panel)
250{
251 struct rm68200 *ctx = panel_to_rm68200(panel);
252 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
253 int ret;
254
255 if (!ctx->prepared)
256 return 0;
257
258 ret = mipi_dsi_dcs_set_display_off(dsi);
259 if (ret)
260 DRM_WARN("failed to set display off: %d\n", ret);
261
262 ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
263 if (ret)
264 DRM_WARN("failed to enter sleep mode: %d\n", ret);
265
266 msleep(120);
267
268 if (ctx->reset_gpio) {
269 gpiod_set_value_cansleep(ctx->reset_gpio, 1);
270 msleep(20);
271 }
272
273 regulator_disable(ctx->supply);
274
275 ctx->prepared = false;
276
277 return 0;
278}
279
280static int rm68200_prepare(struct drm_panel *panel)
281{
282 struct rm68200 *ctx = panel_to_rm68200(panel);
283 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
284 int ret;
285
286 if (ctx->prepared)
287 return 0;
288
289 ret = regulator_enable(ctx->supply);
290 if (ret < 0) {
291 DRM_ERROR("failed to enable supply: %d\n", ret);
292 return ret;
293 }
294
295 if (ctx->reset_gpio) {
296 gpiod_set_value_cansleep(ctx->reset_gpio, 1);
297 msleep(20);
298 gpiod_set_value_cansleep(ctx->reset_gpio, 0);
299 msleep(100);
300 }
301
302 rm68200_init_sequence(ctx);
303
304 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
305 if (ret)
306 return ret;
307
308 msleep(125);
309
310 ret = mipi_dsi_dcs_set_display_on(dsi);
311 if (ret)
312 return ret;
313
314 msleep(20);
315
316 ctx->prepared = true;
317
318 return 0;
319}
320
321static int rm68200_enable(struct drm_panel *panel)
322{
323 struct rm68200 *ctx = panel_to_rm68200(panel);
324
325 if (ctx->enabled)
326 return 0;
327
328 backlight_enable(ctx->backlight);
329
330 ctx->enabled = true;
331
332 return 0;
333}
334
335static int rm68200_get_modes(struct drm_panel *panel)
336{
337 struct drm_display_mode *mode;
338
339 mode = drm_mode_duplicate(panel->drm, &default_mode);
340 if (!mode) {
341 DRM_ERROR("failed to add mode %ux%ux@%u\n",
342 default_mode.hdisplay, default_mode.vdisplay,
343 default_mode.vrefresh);
344 return -ENOMEM;
345 }
346
347 drm_mode_set_name(mode);
348
349 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
350 drm_mode_probed_add(panel->connector, mode);
351
352 panel->connector->display_info.width_mm = mode->width_mm;
353 panel->connector->display_info.height_mm = mode->height_mm;
354
355 return 1;
356}
357
358static const struct drm_panel_funcs rm68200_drm_funcs = {
359 .disable = rm68200_disable,
360 .unprepare = rm68200_unprepare,
361 .prepare = rm68200_prepare,
362 .enable = rm68200_enable,
363 .get_modes = rm68200_get_modes,
364};
365
366static int rm68200_probe(struct mipi_dsi_device *dsi)
367{
368 struct device *dev = &dsi->dev;
369 struct rm68200 *ctx;
370 int ret;
371
372 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
373 if (!ctx)
374 return -ENOMEM;
375
376 ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
377 if (IS_ERR(ctx->reset_gpio)) {
378 ret = PTR_ERR(ctx->reset_gpio);
379 dev_err(dev, "cannot get reset GPIO: %d\n", ret);
380 return ret;
381 }
382
383 ctx->supply = devm_regulator_get(dev, "power");
384 if (IS_ERR(ctx->supply)) {
385 ret = PTR_ERR(ctx->supply);
386 dev_err(dev, "cannot get regulator: %d\n", ret);
387 return ret;
388 }
389
390 ctx->backlight = devm_of_find_backlight(dev);
391 if (IS_ERR(ctx->backlight))
392 return PTR_ERR(ctx->backlight);
393
394 mipi_dsi_set_drvdata(dsi, ctx);
395
396 ctx->dev = dev;
397
398 dsi->lanes = 2;
399 dsi->format = MIPI_DSI_FMT_RGB888;
400 dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
401 MIPI_DSI_MODE_LPM;
402
403 drm_panel_init(&ctx->panel);
404 ctx->panel.dev = dev;
405 ctx->panel.funcs = &rm68200_drm_funcs;
406
407 drm_panel_add(&ctx->panel);
408
409 ret = mipi_dsi_attach(dsi);
410 if (ret < 0) {
411 dev_err(dev, "mipi_dsi_attach() failed: %d\n", ret);
412 drm_panel_remove(&ctx->panel);
413 return ret;
414 }
415
416 return 0;
417}
418
419static int rm68200_remove(struct mipi_dsi_device *dsi)
420{
421 struct rm68200 *ctx = mipi_dsi_get_drvdata(dsi);
422
423 mipi_dsi_detach(dsi);
424 drm_panel_remove(&ctx->panel);
425
426 return 0;
427}
428
429static const struct of_device_id raydium_rm68200_of_match[] = {
430 { .compatible = "raydium,rm68200" },
431 { }
432};
433MODULE_DEVICE_TABLE(of, raydium_rm68200_of_match);
434
435static struct mipi_dsi_driver raydium_rm68200_driver = {
436 .probe = rm68200_probe,
437 .remove = rm68200_remove,
438 .driver = {
439 .name = "panel-raydium-rm68200",
440 .of_match_table = raydium_rm68200_of_match,
441 },
442};
443module_mipi_dsi_driver(raydium_rm68200_driver);
444
445MODULE_AUTHOR("Philippe Cornu <philippe.cornu@st.com>");
446MODULE_AUTHOR("Yannick Fertre <yannick.fertre@st.com>");
447MODULE_DESCRIPTION("DRM Driver for Raydium RM68200 MIPI DSI panel");
448MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index 5591984a392b..cbf1ab404ee7 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -581,6 +581,29 @@ static const struct panel_desc auo_b133htn01 = {
581 }, 581 },
582}; 582};
583 583
584static const struct drm_display_mode auo_g104sn02_mode = {
585 .clock = 40000,
586 .hdisplay = 800,
587 .hsync_start = 800 + 40,
588 .hsync_end = 800 + 40 + 216,
589 .htotal = 800 + 40 + 216 + 128,
590 .vdisplay = 600,
591 .vsync_start = 600 + 10,
592 .vsync_end = 600 + 10 + 35,
593 .vtotal = 600 + 10 + 35 + 2,
594 .vrefresh = 60,
595};
596
597static const struct panel_desc auo_g104sn02 = {
598 .modes = &auo_g104sn02_mode,
599 .num_modes = 1,
600 .bpc = 8,
601 .size = {
602 .width = 211,
603 .height = 158,
604 },
605};
606
584static const struct display_timing auo_g133han01_timings = { 607static const struct display_timing auo_g133han01_timings = {
585 .pixelclock = { 134000000, 141200000, 149000000 }, 608 .pixelclock = { 134000000, 141200000, 149000000 },
586 .hactive = { 1920, 1920, 1920 }, 609 .hactive = { 1920, 1920, 1920 },
@@ -1217,6 +1240,30 @@ static const struct panel_desc innolux_zj070na_01p = {
1217 }, 1240 },
1218}; 1241};
1219 1242
1243static const struct display_timing koe_tx31d200vm0baa_timing = {
1244 .pixelclock = { 39600000, 43200000, 48000000 },
1245 .hactive = { 1280, 1280, 1280 },
1246 .hfront_porch = { 16, 36, 56 },
1247 .hback_porch = { 16, 36, 56 },
1248 .hsync_len = { 8, 8, 8 },
1249 .vactive = { 480, 480, 480 },
1250 .vfront_porch = { 6, 21, 33.5 },
1251 .vback_porch = { 6, 21, 33.5 },
1252 .vsync_len = { 8, 8, 8 },
1253 .flags = DISPLAY_FLAGS_DE_HIGH,
1254};
1255
1256static const struct panel_desc koe_tx31d200vm0baa = {
1257 .timings = &koe_tx31d200vm0baa_timing,
1258 .num_timings = 1,
1259 .bpc = 6,
1260 .size = {
1261 .width = 292,
1262 .height = 109,
1263 },
1264 .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
1265};
1266
1220static const struct display_timing kyo_tcg121xglp_timing = { 1267static const struct display_timing kyo_tcg121xglp_timing = {
1221 .pixelclock = { 52000000, 65000000, 71000000 }, 1268 .pixelclock = { 52000000, 65000000, 71000000 },
1222 .hactive = { 1024, 1024, 1024 }, 1269 .hactive = { 1024, 1024, 1024 },
@@ -1597,7 +1644,7 @@ static const struct panel_desc ontat_yx700wv03 = {
1597 .width = 154, 1644 .width = 154,
1598 .height = 83, 1645 .height = 83,
1599 }, 1646 },
1600 .bus_format = MEDIA_BUS_FMT_RGB888_1X24, 1647 .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
1601}; 1648};
1602 1649
1603static const struct drm_display_mode ortustech_com43h4m85ulc_mode = { 1650static const struct drm_display_mode ortustech_com43h4m85ulc_mode = {
@@ -1741,23 +1788,22 @@ static const struct panel_desc sharp_lq101k1ly04 = {
1741 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, 1788 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
1742}; 1789};
1743 1790
1744static const struct drm_display_mode sharp_lq123p1jx31_mode = { 1791static const struct display_timing sharp_lq123p1jx31_timing = {
1745 .clock = 252750, 1792 .pixelclock = { 252750000, 252750000, 266604720 },
1746 .hdisplay = 2400, 1793 .hactive = { 2400, 2400, 2400 },
1747 .hsync_start = 2400 + 48, 1794 .hfront_porch = { 48, 48, 48 },
1748 .hsync_end = 2400 + 48 + 32, 1795 .hback_porch = { 80, 80, 84 },
1749 .htotal = 2400 + 48 + 32 + 80, 1796 .hsync_len = { 32, 32, 32 },
1750 .vdisplay = 1600, 1797 .vactive = { 1600, 1600, 1600 },
1751 .vsync_start = 1600 + 3, 1798 .vfront_porch = { 3, 3, 3 },
1752 .vsync_end = 1600 + 3 + 10, 1799 .vback_porch = { 33, 33, 120 },
1753 .vtotal = 1600 + 3 + 10 + 33, 1800 .vsync_len = { 10, 10, 10 },
1754 .vrefresh = 60, 1801 .flags = DISPLAY_FLAGS_VSYNC_LOW | DISPLAY_FLAGS_HSYNC_LOW,
1755 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
1756}; 1802};
1757 1803
1758static const struct panel_desc sharp_lq123p1jx31 = { 1804static const struct panel_desc sharp_lq123p1jx31 = {
1759 .modes = &sharp_lq123p1jx31_mode, 1805 .timings = &sharp_lq123p1jx31_timing,
1760 .num_modes = 1, 1806 .num_timings = 1,
1761 .bpc = 8, 1807 .bpc = 8,
1762 .size = { 1808 .size = {
1763 .width = 259, 1809 .width = 259,
@@ -2049,6 +2095,9 @@ static const struct of_device_id platform_of_match[] = {
2049 .compatible = "auo,b133xtn01", 2095 .compatible = "auo,b133xtn01",
2050 .data = &auo_b133xtn01, 2096 .data = &auo_b133xtn01,
2051 }, { 2097 }, {
2098 .compatible = "auo,g104sn02",
2099 .data = &auo_g104sn02,
2100 }, {
2052 .compatible = "auo,g133han01", 2101 .compatible = "auo,g133han01",
2053 .data = &auo_g133han01, 2102 .data = &auo_g133han01,
2054 }, { 2103 }, {
@@ -2124,6 +2173,9 @@ static const struct of_device_id platform_of_match[] = {
2124 .compatible = "innolux,zj070na-01p", 2173 .compatible = "innolux,zj070na-01p",
2125 .data = &innolux_zj070na_01p, 2174 .data = &innolux_zj070na_01p,
2126 }, { 2175 }, {
2176 .compatible = "koe,tx31d200vm0baa",
2177 .data = &koe_tx31d200vm0baa,
2178 }, {
2127 .compatible = "kyo,tcg121xglp", 2179 .compatible = "kyo,tcg121xglp",
2128 .data = &kyo_tcg121xglp, 2180 .data = &kyo_tcg121xglp,
2129 }, { 2181 }, {
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c
index 9a9214ae0fb5..ecb35ed0eac8 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -309,7 +309,7 @@ void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb)
309 struct qxl_bo *bo = gem_to_qxl_bo(qxl_fb->obj); 309 struct qxl_bo *bo = gem_to_qxl_bo(qxl_fb->obj);
310 310
311 WARN_ON(bo->shadow); 311 WARN_ON(bo->shadow);
312 drm_gem_object_unreference_unlocked(qxl_fb->obj); 312 drm_gem_object_put_unlocked(qxl_fb->obj);
313 drm_framebuffer_cleanup(fb); 313 drm_framebuffer_cleanup(fb);
314 kfree(qxl_fb); 314 kfree(qxl_fb);
315} 315}
@@ -1215,7 +1215,7 @@ qxl_user_framebuffer_create(struct drm_device *dev,
1215 ret = qxl_framebuffer_init(dev, qxl_fb, mode_cmd, obj, &qxl_fb_funcs); 1215 ret = qxl_framebuffer_init(dev, qxl_fb, mode_cmd, obj, &qxl_fb_funcs);
1216 if (ret) { 1216 if (ret) {
1217 kfree(qxl_fb); 1217 kfree(qxl_fb);
1218 drm_gem_object_unreference_unlocked(obj); 1218 drm_gem_object_put_unlocked(obj);
1219 return NULL; 1219 return NULL;
1220 } 1220 }
1221 1221
diff --git a/drivers/gpu/drm/qxl/qxl_dumb.c b/drivers/gpu/drm/qxl/qxl_dumb.c
index 11085ab01374..c666b89eed5d 100644
--- a/drivers/gpu/drm/qxl/qxl_dumb.c
+++ b/drivers/gpu/drm/qxl/qxl_dumb.c
@@ -82,6 +82,6 @@ int qxl_mode_dumb_mmap(struct drm_file *file_priv,
82 return -ENOENT; 82 return -ENOENT;
83 qobj = gem_to_qxl_bo(gobj); 83 qobj = gem_to_qxl_bo(gobj);
84 *offset_p = qxl_bo_mmap_offset(qobj); 84 *offset_p = qxl_bo_mmap_offset(qobj);
85 drm_gem_object_unreference_unlocked(gobj); 85 drm_gem_object_put_unlocked(gobj);
86 return 0; 86 return 0;
87} 87}
diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c
index 23af3e352673..338891401f35 100644
--- a/drivers/gpu/drm/qxl/qxl_fb.c
+++ b/drivers/gpu/drm/qxl/qxl_fb.c
@@ -95,7 +95,7 @@ static void qxlfb_destroy_pinned_object(struct drm_gem_object *gobj)
95 qxl_bo_kunmap(qbo); 95 qxl_bo_kunmap(qbo);
96 qxl_bo_unpin(qbo); 96 qxl_bo_unpin(qbo);
97 97
98 drm_gem_object_unreference_unlocked(gobj); 98 drm_gem_object_put_unlocked(gobj);
99} 99}
100 100
101int qxl_get_handle_for_primary_fb(struct qxl_device *qdev, 101int qxl_get_handle_for_primary_fb(struct qxl_device *qdev,
@@ -316,11 +316,11 @@ out_unref:
316 qxl_bo_unpin(qbo); 316 qxl_bo_unpin(qbo);
317 } 317 }
318 if (fb && ret) { 318 if (fb && ret) {
319 drm_gem_object_unreference_unlocked(gobj); 319 drm_gem_object_put_unlocked(gobj);
320 drm_framebuffer_cleanup(fb); 320 drm_framebuffer_cleanup(fb);
321 kfree(fb); 321 kfree(fb);
322 } 322 }
323 drm_gem_object_unreference_unlocked(gobj); 323 drm_gem_object_put_unlocked(gobj);
324 return ret; 324 return ret;
325} 325}
326 326
diff --git a/drivers/gpu/drm/qxl/qxl_gem.c b/drivers/gpu/drm/qxl/qxl_gem.c
index 85f546719adb..f5c1e7872e92 100644
--- a/drivers/gpu/drm/qxl/qxl_gem.c
+++ b/drivers/gpu/drm/qxl/qxl_gem.c
@@ -98,7 +98,7 @@ int qxl_gem_object_create_with_handle(struct qxl_device *qdev,
98 return r; 98 return r;
99 /* drop reference from allocate - handle holds it now */ 99 /* drop reference from allocate - handle holds it now */
100 *qobj = gem_to_qxl_bo(gobj); 100 *qobj = gem_to_qxl_bo(gobj);
101 drm_gem_object_unreference_unlocked(gobj); 101 drm_gem_object_put_unlocked(gobj);
102 return 0; 102 return 0;
103} 103}
104 104
diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c
index e8c0b1037230..e238a1a2eca1 100644
--- a/drivers/gpu/drm/qxl/qxl_ioctl.c
+++ b/drivers/gpu/drm/qxl/qxl_ioctl.c
@@ -121,7 +121,7 @@ static int qxlhw_handle_to_bo(struct drm_file *file_priv, uint64_t handle,
121 qobj = gem_to_qxl_bo(gobj); 121 qobj = gem_to_qxl_bo(gobj);
122 122
123 ret = qxl_release_list_add(release, qobj); 123 ret = qxl_release_list_add(release, qobj);
124 drm_gem_object_unreference_unlocked(gobj); 124 drm_gem_object_put_unlocked(gobj);
125 if (ret) 125 if (ret)
126 return ret; 126 return ret;
127 127
@@ -343,7 +343,7 @@ out2:
343 qxl_bo_unreserve(qobj); 343 qxl_bo_unreserve(qobj);
344 344
345out: 345out:
346 drm_gem_object_unreference_unlocked(gobj); 346 drm_gem_object_put_unlocked(gobj);
347 return ret; 347 return ret;
348} 348}
349 349
diff --git a/drivers/gpu/drm/qxl/qxl_object.c b/drivers/gpu/drm/qxl/qxl_object.c
index af62824ed4cc..6a30196e9d6c 100644
--- a/drivers/gpu/drm/qxl/qxl_object.c
+++ b/drivers/gpu/drm/qxl/qxl_object.c
@@ -211,13 +211,13 @@ void qxl_bo_unref(struct qxl_bo **bo)
211 if ((*bo) == NULL) 211 if ((*bo) == NULL)
212 return; 212 return;
213 213
214 drm_gem_object_unreference_unlocked(&(*bo)->gem_base); 214 drm_gem_object_put_unlocked(&(*bo)->gem_base);
215 *bo = NULL; 215 *bo = NULL;
216} 216}
217 217
218struct qxl_bo *qxl_bo_ref(struct qxl_bo *bo) 218struct qxl_bo *qxl_bo_ref(struct qxl_bo *bo)
219{ 219{
220 drm_gem_object_reference(&bo->gem_base); 220 drm_gem_object_get(&bo->gem_base);
221 return bo; 221 return bo;
222} 222}
223 223
@@ -318,7 +318,7 @@ void qxl_bo_force_delete(struct qxl_device *qdev)
318 list_del_init(&bo->list); 318 list_del_init(&bo->list);
319 mutex_unlock(&qdev->gem.mutex); 319 mutex_unlock(&qdev->gem.mutex);
320 /* this should unref the ttm bo */ 320 /* this should unref the ttm bo */
321 drm_gem_object_unreference_unlocked(&bo->gem_base); 321 drm_gem_object_put_unlocked(&bo->gem_base);
322 } 322 }
323} 323}
324 324
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 31dd04f6baa1..b28288a781ef 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -415,7 +415,6 @@ static int radeon_pmops_runtime_suspend(struct device *dev)
415 415
416 drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; 416 drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
417 drm_kms_helper_poll_disable(drm_dev); 417 drm_kms_helper_poll_disable(drm_dev);
418 vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF);
419 418
420 ret = radeon_suspend_kms(drm_dev, false, false, false); 419 ret = radeon_suspend_kms(drm_dev, false, false, false);
421 pci_save_state(pdev); 420 pci_save_state(pdev);
@@ -452,7 +451,6 @@ static int radeon_pmops_runtime_resume(struct device *dev)
452 451
453 ret = radeon_resume_kms(drm_dev, false, false); 452 ret = radeon_resume_kms(drm_dev, false, false);
454 drm_kms_helper_poll_enable(drm_dev); 453 drm_kms_helper_poll_enable(drm_dev);
455 vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_ON);
456 drm_dev->switch_power_state = DRM_SWITCH_POWER_ON; 454 drm_dev->switch_power_state = DRM_SWITCH_POWER_ON;
457 return 0; 455 return 0;
458} 456}
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 7d76ff47028d..3e8bf79bea58 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -71,10 +71,6 @@ struct rockchip_dp_device {
71 struct regmap *grf; 71 struct regmap *grf;
72 struct reset_control *rst; 72 struct reset_control *rst;
73 73
74 struct work_struct psr_work;
75 struct mutex psr_lock;
76 unsigned int psr_state;
77
78 const struct rockchip_dp_chip_data *data; 74 const struct rockchip_dp_chip_data *data;
79 75
80 struct analogix_dp_device *adp; 76 struct analogix_dp_device *adp;
@@ -84,28 +80,13 @@ struct rockchip_dp_device {
84static void analogix_dp_psr_set(struct drm_encoder *encoder, bool enabled) 80static void analogix_dp_psr_set(struct drm_encoder *encoder, bool enabled)
85{ 81{
86 struct rockchip_dp_device *dp = to_dp(encoder); 82 struct rockchip_dp_device *dp = to_dp(encoder);
83 int ret;
87 84
88 if (!analogix_dp_psr_supported(dp->adp)) 85 if (!analogix_dp_psr_enabled(dp->adp))
89 return; 86 return;
90 87
91 DRM_DEV_DEBUG(dp->dev, "%s PSR...\n", enabled ? "Entry" : "Exit"); 88 DRM_DEV_DEBUG(dp->dev, "%s PSR...\n", enabled ? "Entry" : "Exit");
92 89
93 mutex_lock(&dp->psr_lock);
94 if (enabled)
95 dp->psr_state = EDP_VSC_PSR_STATE_ACTIVE;
96 else
97 dp->psr_state = ~EDP_VSC_PSR_STATE_ACTIVE;
98
99 schedule_work(&dp->psr_work);
100 mutex_unlock(&dp->psr_lock);
101}
102
103static void analogix_dp_psr_work(struct work_struct *work)
104{
105 struct rockchip_dp_device *dp =
106 container_of(work, typeof(*dp), psr_work);
107 int ret;
108
109 ret = rockchip_drm_wait_vact_end(dp->encoder.crtc, 90 ret = rockchip_drm_wait_vact_end(dp->encoder.crtc,
110 PSR_WAIT_LINE_FLAG_TIMEOUT_MS); 91 PSR_WAIT_LINE_FLAG_TIMEOUT_MS);
111 if (ret) { 92 if (ret) {
@@ -113,12 +94,10 @@ static void analogix_dp_psr_work(struct work_struct *work)
113 return; 94 return;
114 } 95 }
115 96
116 mutex_lock(&dp->psr_lock); 97 if (enabled)
117 if (dp->psr_state == EDP_VSC_PSR_STATE_ACTIVE)
118 analogix_dp_enable_psr(dp->adp); 98 analogix_dp_enable_psr(dp->adp);
119 else 99 else
120 analogix_dp_disable_psr(dp->adp); 100 analogix_dp_disable_psr(dp->adp);
121 mutex_unlock(&dp->psr_lock);
122} 101}
123 102
124static int rockchip_dp_pre_init(struct rockchip_dp_device *dp) 103static int rockchip_dp_pre_init(struct rockchip_dp_device *dp)
@@ -135,8 +114,6 @@ static int rockchip_dp_poweron(struct analogix_dp_plat_data *plat_data)
135 struct rockchip_dp_device *dp = to_dp(plat_data); 114 struct rockchip_dp_device *dp = to_dp(plat_data);
136 int ret; 115 int ret;
137 116
138 cancel_work_sync(&dp->psr_work);
139
140 ret = clk_prepare_enable(dp->pclk); 117 ret = clk_prepare_enable(dp->pclk);
141 if (ret < 0) { 118 if (ret < 0) {
142 DRM_DEV_ERROR(dp->dev, "failed to enable pclk %d\n", ret); 119 DRM_DEV_ERROR(dp->dev, "failed to enable pclk %d\n", ret);
@@ -355,10 +332,6 @@ static int rockchip_dp_bind(struct device *dev, struct device *master,
355 dp->plat_data.power_off = rockchip_dp_powerdown; 332 dp->plat_data.power_off = rockchip_dp_powerdown;
356 dp->plat_data.get_modes = rockchip_dp_get_modes; 333 dp->plat_data.get_modes = rockchip_dp_get_modes;
357 334
358 mutex_init(&dp->psr_lock);
359 dp->psr_state = ~EDP_VSC_PSR_STATE_ACTIVE;
360 INIT_WORK(&dp->psr_work, analogix_dp_psr_work);
361
362 ret = rockchip_drm_psr_register(&dp->encoder, analogix_dp_psr_set); 335 ret = rockchip_drm_psr_register(&dp->encoder, analogix_dp_psr_set);
363 if (ret < 0) 336 if (ret < 0)
364 goto err_cleanup_encoder; 337 goto err_cleanup_encoder;
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index ec999d9f15f6..c6fbdcd87c16 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -43,8 +43,6 @@
43#define GRF_SOC_CON9 0x6224 43#define GRF_SOC_CON9 0x6224
44#define DP_SEL_VOP_LIT BIT(12) 44#define DP_SEL_VOP_LIT BIT(12)
45#define GRF_SOC_CON26 0x6268 45#define GRF_SOC_CON26 0x6268
46#define UPHY_SEL_BIT 3
47#define UPHY_SEL_MASK BIT(19)
48#define DPTX_HPD_SEL (3 << 12) 46#define DPTX_HPD_SEL (3 << 12)
49#define DPTX_HPD_DEL (2 << 12) 47#define DPTX_HPD_DEL (2 << 12)
50#define DPTX_HPD_SEL_MASK (3 << 28) 48#define DPTX_HPD_SEL_MASK (3 << 28)
@@ -394,11 +392,6 @@ static int cdn_dp_enable_phy(struct cdn_dp_device *dp, struct cdn_dp_port *port)
394 union extcon_property_value property; 392 union extcon_property_value property;
395 int ret; 393 int ret;
396 394
397 ret = cdn_dp_grf_write(dp, GRF_SOC_CON26,
398 (port->id << UPHY_SEL_BIT) | UPHY_SEL_MASK);
399 if (ret)
400 return ret;
401
402 if (!port->phy_enabled) { 395 if (!port->phy_enabled) {
403 ret = phy_power_on(port->phy); 396 ret = phy_power_on(port->phy);
404 if (ret) { 397 if (ret) {
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 158e79e5062e..53d4afe15278 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -117,6 +117,8 @@ struct vop {
117 spinlock_t reg_lock; 117 spinlock_t reg_lock;
118 /* lock vop irq reg */ 118 /* lock vop irq reg */
119 spinlock_t irq_lock; 119 spinlock_t irq_lock;
120 /* protects crtc enable/disable */
121 struct mutex vop_lock;
120 122
121 unsigned int irq; 123 unsigned int irq;
122 124
@@ -517,7 +519,10 @@ static int vop_enable(struct drm_crtc *crtc)
517 goto err_disable_aclk; 519 goto err_disable_aclk;
518 } 520 }
519 521
520 memcpy(vop->regs, vop->regsbak, vop->len); 522 spin_lock(&vop->reg_lock);
523 for (i = 0; i < vop->len; i += 4)
524 writel_relaxed(vop->regsbak[i / 4], vop->regs + i);
525
521 /* 526 /*
522 * We need to make sure that all windows are disabled before we 527 * We need to make sure that all windows are disabled before we
523 * enable the crtc. Otherwise we might try to scan from a destroyed 528 * enable the crtc. Otherwise we might try to scan from a destroyed
@@ -527,10 +532,9 @@ static int vop_enable(struct drm_crtc *crtc)
527 struct vop_win *vop_win = &vop->win[i]; 532 struct vop_win *vop_win = &vop->win[i];
528 const struct vop_win_data *win = vop_win->data; 533 const struct vop_win_data *win = vop_win->data;
529 534
530 spin_lock(&vop->reg_lock);
531 VOP_WIN_SET(vop, win, enable, 0); 535 VOP_WIN_SET(vop, win, enable, 0);
532 spin_unlock(&vop->reg_lock);
533 } 536 }
537 spin_unlock(&vop->reg_lock);
534 538
535 vop_cfg_done(vop); 539 vop_cfg_done(vop);
536 540
@@ -569,6 +573,7 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
569 573
570 WARN_ON(vop->event); 574 WARN_ON(vop->event);
571 575
576 mutex_lock(&vop->vop_lock);
572 drm_crtc_vblank_off(crtc); 577 drm_crtc_vblank_off(crtc);
573 578
574 /* 579 /*
@@ -604,6 +609,7 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
604 clk_disable(vop->aclk); 609 clk_disable(vop->aclk);
605 clk_disable(vop->hclk); 610 clk_disable(vop->hclk);
606 pm_runtime_put(vop->dev); 611 pm_runtime_put(vop->dev);
612 mutex_unlock(&vop->vop_lock);
607 613
608 if (crtc->state->event && !crtc->state->active) { 614 if (crtc->state->event && !crtc->state->active) {
609 spin_lock_irq(&crtc->dev->event_lock); 615 spin_lock_irq(&crtc->dev->event_lock);
@@ -868,10 +874,13 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
868 uint32_t pin_pol, val; 874 uint32_t pin_pol, val;
869 int ret; 875 int ret;
870 876
877 mutex_lock(&vop->vop_lock);
878
871 WARN_ON(vop->event); 879 WARN_ON(vop->event);
872 880
873 ret = vop_enable(crtc); 881 ret = vop_enable(crtc);
874 if (ret) { 882 if (ret) {
883 mutex_unlock(&vop->vop_lock);
875 DRM_DEV_ERROR(vop->dev, "Failed to enable vop (%d)\n", ret); 884 DRM_DEV_ERROR(vop->dev, "Failed to enable vop (%d)\n", ret);
876 return; 885 return;
877 } 886 }
@@ -935,6 +944,7 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
935 clk_set_rate(vop->dclk, adjusted_mode->clock * 1000); 944 clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
936 945
937 VOP_REG_SET(vop, common, standby, 0); 946 VOP_REG_SET(vop, common, standby, 0);
947 mutex_unlock(&vop->vop_lock);
938} 948}
939 949
940static bool vop_fs_irq_is_pending(struct vop *vop) 950static bool vop_fs_irq_is_pending(struct vop *vop)
@@ -1137,15 +1147,14 @@ static void vop_handle_vblank(struct vop *vop)
1137{ 1147{
1138 struct drm_device *drm = vop->drm_dev; 1148 struct drm_device *drm = vop->drm_dev;
1139 struct drm_crtc *crtc = &vop->crtc; 1149 struct drm_crtc *crtc = &vop->crtc;
1140 unsigned long flags;
1141 1150
1142 spin_lock_irqsave(&drm->event_lock, flags); 1151 spin_lock(&drm->event_lock);
1143 if (vop->event) { 1152 if (vop->event) {
1144 drm_crtc_send_vblank_event(crtc, vop->event); 1153 drm_crtc_send_vblank_event(crtc, vop->event);
1145 drm_crtc_vblank_put(crtc); 1154 drm_crtc_vblank_put(crtc);
1146 vop->event = NULL; 1155 vop->event = NULL;
1147 } 1156 }
1148 spin_unlock_irqrestore(&drm->event_lock, flags); 1157 spin_unlock(&drm->event_lock);
1149 1158
1150 if (test_and_clear_bit(VOP_PENDING_FB_UNREF, &vop->pending)) 1159 if (test_and_clear_bit(VOP_PENDING_FB_UNREF, &vop->pending))
1151 drm_flip_work_commit(&vop->fb_unref_work, system_unbound_wq); 1160 drm_flip_work_commit(&vop->fb_unref_work, system_unbound_wq);
@@ -1156,21 +1165,20 @@ static irqreturn_t vop_isr(int irq, void *data)
1156 struct vop *vop = data; 1165 struct vop *vop = data;
1157 struct drm_crtc *crtc = &vop->crtc; 1166 struct drm_crtc *crtc = &vop->crtc;
1158 uint32_t active_irqs; 1167 uint32_t active_irqs;
1159 unsigned long flags;
1160 int ret = IRQ_NONE; 1168 int ret = IRQ_NONE;
1161 1169
1162 /* 1170 /*
1163 * interrupt register has interrupt status, enable and clear bits, we 1171 * interrupt register has interrupt status, enable and clear bits, we
1164 * must hold irq_lock to avoid a race with enable/disable_vblank(). 1172 * must hold irq_lock to avoid a race with enable/disable_vblank().
1165 */ 1173 */
1166 spin_lock_irqsave(&vop->irq_lock, flags); 1174 spin_lock(&vop->irq_lock);
1167 1175
1168 active_irqs = VOP_INTR_GET_TYPE(vop, status, INTR_MASK); 1176 active_irqs = VOP_INTR_GET_TYPE(vop, status, INTR_MASK);
1169 /* Clear all active interrupt sources */ 1177 /* Clear all active interrupt sources */
1170 if (active_irqs) 1178 if (active_irqs)
1171 VOP_INTR_SET_TYPE(vop, clear, active_irqs, 1); 1179 VOP_INTR_SET_TYPE(vop, clear, active_irqs, 1);
1172 1180
1173 spin_unlock_irqrestore(&vop->irq_lock, flags); 1181 spin_unlock(&vop->irq_lock);
1174 1182
1175 /* This is expected for vop iommu irqs, since the irq is shared */ 1183 /* This is expected for vop iommu irqs, since the irq is shared */
1176 if (!active_irqs) 1184 if (!active_irqs)
@@ -1393,7 +1401,11 @@ static int vop_initial(struct vop *vop)
1393 usleep_range(10, 20); 1401 usleep_range(10, 20);
1394 reset_control_deassert(ahb_rst); 1402 reset_control_deassert(ahb_rst);
1395 1403
1396 memcpy(vop->regsbak, vop->regs, vop->len); 1404 VOP_INTR_SET_TYPE(vop, clear, INTR_MASK, 1);
1405 VOP_INTR_SET_TYPE(vop, enable, INTR_MASK, 0);
1406
1407 for (i = 0; i < vop->len; i += sizeof(u32))
1408 vop->regsbak[i / 4] = readl_relaxed(vop->regs + i);
1397 1409
1398 VOP_REG_SET(vop, misc, global_regdone_en, 1); 1410 VOP_REG_SET(vop, misc, global_regdone_en, 1);
1399 VOP_REG_SET(vop, common, dsp_blank, 0); 1411 VOP_REG_SET(vop, common, dsp_blank, 0);
@@ -1473,15 +1485,21 @@ int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout)
1473{ 1485{
1474 struct vop *vop = to_vop(crtc); 1486 struct vop *vop = to_vop(crtc);
1475 unsigned long jiffies_left; 1487 unsigned long jiffies_left;
1488 int ret = 0;
1476 1489
1477 if (!crtc || !vop->is_enabled) 1490 if (!crtc || !vop->is_enabled)
1478 return -ENODEV; 1491 return -ENODEV;
1479 1492
1480 if (mstimeout <= 0) 1493 mutex_lock(&vop->vop_lock);
1481 return -EINVAL; 1494 if (mstimeout <= 0) {
1495 ret = -EINVAL;
1496 goto out;
1497 }
1482 1498
1483 if (vop_line_flag_irq_is_enabled(vop)) 1499 if (vop_line_flag_irq_is_enabled(vop)) {
1484 return -EBUSY; 1500 ret = -EBUSY;
1501 goto out;
1502 }
1485 1503
1486 reinit_completion(&vop->line_flag_completion); 1504 reinit_completion(&vop->line_flag_completion);
1487 vop_line_flag_irq_enable(vop); 1505 vop_line_flag_irq_enable(vop);
@@ -1492,10 +1510,13 @@ int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout)
1492 1510
1493 if (jiffies_left == 0) { 1511 if (jiffies_left == 0) {
1494 DRM_DEV_ERROR(vop->dev, "Timeout waiting for IRQ\n"); 1512 DRM_DEV_ERROR(vop->dev, "Timeout waiting for IRQ\n");
1495 return -ETIMEDOUT; 1513 ret = -ETIMEDOUT;
1514 goto out;
1496 } 1515 }
1497 1516
1498 return 0; 1517out:
1518 mutex_unlock(&vop->vop_lock);
1519 return ret;
1499} 1520}
1500EXPORT_SYMBOL(rockchip_drm_wait_vact_end); 1521EXPORT_SYMBOL(rockchip_drm_wait_vact_end);
1501 1522
@@ -1545,18 +1566,11 @@ static int vop_bind(struct device *dev, struct device *master, void *data)
1545 1566
1546 spin_lock_init(&vop->reg_lock); 1567 spin_lock_init(&vop->reg_lock);
1547 spin_lock_init(&vop->irq_lock); 1568 spin_lock_init(&vop->irq_lock);
1548 1569 mutex_init(&vop->vop_lock);
1549 ret = devm_request_irq(dev, vop->irq, vop_isr,
1550 IRQF_SHARED, dev_name(dev), vop);
1551 if (ret)
1552 return ret;
1553
1554 /* IRQ is initially disabled; it gets enabled in power_on */
1555 disable_irq(vop->irq);
1556 1570
1557 ret = vop_create_crtc(vop); 1571 ret = vop_create_crtc(vop);
1558 if (ret) 1572 if (ret)
1559 goto err_enable_irq; 1573 return ret;
1560 1574
1561 pm_runtime_enable(&pdev->dev); 1575 pm_runtime_enable(&pdev->dev);
1562 1576
@@ -1567,13 +1581,19 @@ static int vop_bind(struct device *dev, struct device *master, void *data)
1567 goto err_disable_pm_runtime; 1581 goto err_disable_pm_runtime;
1568 } 1582 }
1569 1583
1584 ret = devm_request_irq(dev, vop->irq, vop_isr,
1585 IRQF_SHARED, dev_name(dev), vop);
1586 if (ret)
1587 goto err_disable_pm_runtime;
1588
1589 /* IRQ is initially disabled; it gets enabled in power_on */
1590 disable_irq(vop->irq);
1591
1570 return 0; 1592 return 0;
1571 1593
1572err_disable_pm_runtime: 1594err_disable_pm_runtime:
1573 pm_runtime_disable(&pdev->dev); 1595 pm_runtime_disable(&pdev->dev);
1574 vop_destroy_crtc(vop); 1596 vop_destroy_crtc(vop);
1575err_enable_irq:
1576 enable_irq(vop->irq); /* To balance out the disable_irq above */
1577 return ret; 1597 return ret;
1578} 1598}
1579 1599
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c
index 092ade4ff6a5..9bad54f3de38 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.c
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.c
@@ -42,6 +42,56 @@ static const u32 sunxi_rgb2yuv_coef[12] = {
42 0x000001c1, 0x00003e88, 0x00003fb8, 0x00000808 42 0x000001c1, 0x00003e88, 0x00003fb8, 0x00000808
43}; 43};
44 44
45/*
46 * These coefficients are taken from the A33 BSP from Allwinner.
47 *
48 * The formula is for each component, each coefficient being multiplied by
49 * 1024 and each constant being multiplied by 16:
50 * G = 1.164 * Y - 0.391 * U - 0.813 * V + 135
51 * R = 1.164 * Y + 1.596 * V - 222
52 * B = 1.164 * Y + 2.018 * U + 276
53 *
54 * This seems to be a conversion from Y[16:235] UV[16:240] to RGB[0:255],
55 * following the BT601 spec.
56 */
57static const u32 sunxi_bt601_yuv2rgb_coef[12] = {
58 0x000004a7, 0x00001e6f, 0x00001cbf, 0x00000877,
59 0x000004a7, 0x00000000, 0x00000662, 0x00003211,
60 0x000004a7, 0x00000812, 0x00000000, 0x00002eb1,
61};
62
63static inline bool sun4i_backend_format_is_planar_yuv(uint32_t format)
64{
65 switch (format) {
66 case DRM_FORMAT_YUV411:
67 case DRM_FORMAT_YUV422:
68 case DRM_FORMAT_YUV444:
69 return true;
70 default:
71 return false;
72 }
73}
74
75static inline bool sun4i_backend_format_is_packed_yuv422(uint32_t format)
76{
77 switch (format) {
78 case DRM_FORMAT_YUYV:
79 case DRM_FORMAT_YVYU:
80 case DRM_FORMAT_UYVY:
81 case DRM_FORMAT_VYUY:
82 return true;
83
84 default:
85 return false;
86 }
87}
88
89static inline bool sun4i_backend_format_is_yuv(uint32_t format)
90{
91 return sun4i_backend_format_is_planar_yuv(format) ||
92 sun4i_backend_format_is_packed_yuv422(format);
93}
94
45static void sun4i_backend_apply_color_correction(struct sunxi_engine *engine) 95static void sun4i_backend_apply_color_correction(struct sunxi_engine *engine)
46{ 96{
47 int i; 97 int i;
@@ -166,6 +216,61 @@ int sun4i_backend_update_layer_coord(struct sun4i_backend *backend,
166 return 0; 216 return 0;
167} 217}
168 218
219static int sun4i_backend_update_yuv_format(struct sun4i_backend *backend,
220 int layer, struct drm_plane *plane)
221{
222 struct drm_plane_state *state = plane->state;
223 struct drm_framebuffer *fb = state->fb;
224 uint32_t format = fb->format->format;
225 u32 val = SUN4I_BACKEND_IYUVCTL_EN;
226 int i;
227
228 for (i = 0; i < ARRAY_SIZE(sunxi_bt601_yuv2rgb_coef); i++)
229 regmap_write(backend->engine.regs,
230 SUN4I_BACKEND_YGCOEF_REG(i),
231 sunxi_bt601_yuv2rgb_coef[i]);
232
233 /*
234 * We should do that only for a single plane, but the
235 * framebuffer's atomic_check has our back on this.
236 */
237 regmap_update_bits(backend->engine.regs, SUN4I_BACKEND_ATTCTL_REG0(layer),
238 SUN4I_BACKEND_ATTCTL_REG0_LAY_YUVEN,
239 SUN4I_BACKEND_ATTCTL_REG0_LAY_YUVEN);
240
241 /* TODO: Add support for the multi-planar YUV formats */
242 if (sun4i_backend_format_is_packed_yuv422(format))
243 val |= SUN4I_BACKEND_IYUVCTL_FBFMT_PACKED_YUV422;
244 else
245 DRM_DEBUG_DRIVER("Unsupported YUV format (0x%x)\n", format);
246
247 /*
248 * Allwinner seems to list the pixel sequence from right to left, while
249 * DRM lists it from left to right.
250 */
251 switch (format) {
252 case DRM_FORMAT_YUYV:
253 val |= SUN4I_BACKEND_IYUVCTL_FBPS_VYUY;
254 break;
255 case DRM_FORMAT_YVYU:
256 val |= SUN4I_BACKEND_IYUVCTL_FBPS_UYVY;
257 break;
258 case DRM_FORMAT_UYVY:
259 val |= SUN4I_BACKEND_IYUVCTL_FBPS_YVYU;
260 break;
261 case DRM_FORMAT_VYUY:
262 val |= SUN4I_BACKEND_IYUVCTL_FBPS_YUYV;
263 break;
264 default:
265 DRM_DEBUG_DRIVER("Unsupported YUV pixel sequence (0x%x)\n",
266 format);
267 }
268
269 regmap_write(backend->engine.regs, SUN4I_BACKEND_IYUVCTL_REG, val);
270
271 return 0;
272}
273
169int sun4i_backend_update_layer_formats(struct sun4i_backend *backend, 274int sun4i_backend_update_layer_formats(struct sun4i_backend *backend,
170 int layer, struct drm_plane *plane) 275 int layer, struct drm_plane *plane)
171{ 276{
@@ -175,6 +280,10 @@ int sun4i_backend_update_layer_formats(struct sun4i_backend *backend,
175 u32 val; 280 u32 val;
176 int ret; 281 int ret;
177 282
283 /* Clear the YUV mode */
284 regmap_update_bits(backend->engine.regs, SUN4I_BACKEND_ATTCTL_REG0(layer),
285 SUN4I_BACKEND_ATTCTL_REG0_LAY_YUVEN, 0);
286
178 if (plane->state->crtc) 287 if (plane->state->crtc)
179 interlaced = plane->state->crtc->state->adjusted_mode.flags 288 interlaced = plane->state->crtc->state->adjusted_mode.flags
180 & DRM_MODE_FLAG_INTERLACE; 289 & DRM_MODE_FLAG_INTERLACE;
@@ -186,6 +295,9 @@ int sun4i_backend_update_layer_formats(struct sun4i_backend *backend,
186 DRM_DEBUG_DRIVER("Switching display backend interlaced mode %s\n", 295 DRM_DEBUG_DRIVER("Switching display backend interlaced mode %s\n",
187 interlaced ? "on" : "off"); 296 interlaced ? "on" : "off");
188 297
298 if (sun4i_backend_format_is_yuv(fb->format->format))
299 return sun4i_backend_update_yuv_format(backend, layer, plane);
300
189 ret = sun4i_backend_drm_format_to_layer(fb->format->format, &val); 301 ret = sun4i_backend_drm_format_to_layer(fb->format->format, &val);
190 if (ret) { 302 if (ret) {
191 DRM_DEBUG_DRIVER("Invalid format\n"); 303 DRM_DEBUG_DRIVER("Invalid format\n");
@@ -223,6 +335,21 @@ int sun4i_backend_update_layer_frontend(struct sun4i_backend *backend,
223 return 0; 335 return 0;
224} 336}
225 337
338static int sun4i_backend_update_yuv_buffer(struct sun4i_backend *backend,
339 struct drm_framebuffer *fb,
340 dma_addr_t paddr)
341{
342 /* TODO: Add support for the multi-planar YUV formats */
343 DRM_DEBUG_DRIVER("Setting packed YUV buffer address to %pad\n", &paddr);
344 regmap_write(backend->engine.regs, SUN4I_BACKEND_IYUVADD_REG(0), paddr);
345
346 DRM_DEBUG_DRIVER("Layer line width: %d bits\n", fb->pitches[0] * 8);
347 regmap_write(backend->engine.regs, SUN4I_BACKEND_IYUVLINEWIDTH_REG(0),
348 fb->pitches[0] * 8);
349
350 return 0;
351}
352
226int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend, 353int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend,
227 int layer, struct drm_plane *plane) 354 int layer, struct drm_plane *plane)
228{ 355{
@@ -248,6 +375,9 @@ int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend,
248 */ 375 */
249 paddr -= PHYS_OFFSET; 376 paddr -= PHYS_OFFSET;
250 377
378 if (sun4i_backend_format_is_yuv(fb->format->format))
379 return sun4i_backend_update_yuv_buffer(backend, fb, paddr);
380
251 /* Write the 32 lower bits of the address (in bits) */ 381 /* Write the 32 lower bits of the address (in bits) */
252 lo_paddr = paddr << 3; 382 lo_paddr = paddr << 3;
253 DRM_DEBUG_DRIVER("Setting address lower bits to 0x%x\n", lo_paddr); 383 DRM_DEBUG_DRIVER("Setting address lower bits to 0x%x\n", lo_paddr);
@@ -330,6 +460,7 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine,
330 unsigned int num_planes = 0; 460 unsigned int num_planes = 0;
331 unsigned int num_alpha_planes = 0; 461 unsigned int num_alpha_planes = 0;
332 unsigned int num_frontend_planes = 0; 462 unsigned int num_frontend_planes = 0;
463 unsigned int num_yuv_planes = 0;
333 unsigned int current_pipe = 0; 464 unsigned int current_pipe = 0;
334 unsigned int i; 465 unsigned int i;
335 466
@@ -362,6 +493,11 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine,
362 if (fb->format->has_alpha) 493 if (fb->format->has_alpha)
363 num_alpha_planes++; 494 num_alpha_planes++;
364 495
496 if (sun4i_backend_format_is_yuv(fb->format->format)) {
497 DRM_DEBUG_DRIVER("Plane FB format is YUV\n");
498 num_yuv_planes++;
499 }
500
365 DRM_DEBUG_DRIVER("Plane zpos is %d\n", 501 DRM_DEBUG_DRIVER("Plane zpos is %d\n",
366 plane_state->normalized_zpos); 502 plane_state->normalized_zpos);
367 503
@@ -430,13 +566,20 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine,
430 s_state->pipe = current_pipe; 566 s_state->pipe = current_pipe;
431 } 567 }
432 568
569 /* We can only have a single YUV plane at a time */
570 if (num_yuv_planes > SUN4I_BACKEND_NUM_YUV_PLANES) {
571 DRM_DEBUG_DRIVER("Too many planes with YUV, rejecting...\n");
572 return -EINVAL;
573 }
574
433 if (num_frontend_planes > SUN4I_BACKEND_NUM_FRONTEND_LAYERS) { 575 if (num_frontend_planes > SUN4I_BACKEND_NUM_FRONTEND_LAYERS) {
434 DRM_DEBUG_DRIVER("Too many planes going through the frontend, rejecting\n"); 576 DRM_DEBUG_DRIVER("Too many planes going through the frontend, rejecting\n");
435 return -EINVAL; 577 return -EINVAL;
436 } 578 }
437 579
438 DRM_DEBUG_DRIVER("State valid with %u planes, %u alpha, %u video\n", 580 DRM_DEBUG_DRIVER("State valid with %u planes, %u alpha, %u video, %u YUV\n",
439 num_planes, num_alpha_planes, num_frontend_planes); 581 num_planes, num_alpha_planes, num_frontend_planes,
582 num_yuv_planes);
440 583
441 return 0; 584 return 0;
442} 585}
@@ -793,6 +936,9 @@ static const struct sun4i_backend_quirks sun7i_backend_quirks = {
793static const struct sun4i_backend_quirks sun8i_a33_backend_quirks = { 936static const struct sun4i_backend_quirks sun8i_a33_backend_quirks = {
794}; 937};
795 938
939static const struct sun4i_backend_quirks sun9i_backend_quirks = {
940};
941
796static const struct of_device_id sun4i_backend_of_table[] = { 942static const struct of_device_id sun4i_backend_of_table[] = {
797 { 943 {
798 .compatible = "allwinner,sun4i-a10-display-backend", 944 .compatible = "allwinner,sun4i-a10-display-backend",
@@ -814,6 +960,10 @@ static const struct of_device_id sun4i_backend_of_table[] = {
814 .compatible = "allwinner,sun8i-a33-display-backend", 960 .compatible = "allwinner,sun8i-a33-display-backend",
815 .data = &sun8i_a33_backend_quirks, 961 .data = &sun8i_a33_backend_quirks,
816 }, 962 },
963 {
964 .compatible = "allwinner,sun9i-a80-display-backend",
965 .data = &sun9i_backend_quirks,
966 },
817 { } 967 { }
818}; 968};
819MODULE_DEVICE_TABLE(of, sun4i_backend_of_table); 969MODULE_DEVICE_TABLE(of, sun4i_backend_of_table);
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.h b/drivers/gpu/drm/sun4i/sun4i_backend.h
index 52e77591186a..316f2179e9e1 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.h
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.h
@@ -72,6 +72,7 @@
72#define SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL(x) ((x) << 15) 72#define SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL(x) ((x) << 15)
73#define SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL_MASK GENMASK(11, 10) 73#define SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL_MASK GENMASK(11, 10)
74#define SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL(x) ((x) << 10) 74#define SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL(x) ((x) << 10)
75#define SUN4I_BACKEND_ATTCTL_REG0_LAY_YUVEN BIT(2)
75#define SUN4I_BACKEND_ATTCTL_REG0_LAY_VDOEN BIT(1) 76#define SUN4I_BACKEND_ATTCTL_REG0_LAY_VDOEN BIT(1)
76 77
77#define SUN4I_BACKEND_ATTCTL_REG1(l) (0x8a0 + (0x4 * (l))) 78#define SUN4I_BACKEND_ATTCTL_REG1(l) (0x8a0 + (0x4 * (l)))
@@ -110,7 +111,23 @@
110#define SUN4I_BACKEND_SPREN_REG 0x900 111#define SUN4I_BACKEND_SPREN_REG 0x900
111#define SUN4I_BACKEND_SPRFMTCTL_REG 0x908 112#define SUN4I_BACKEND_SPRFMTCTL_REG 0x908
112#define SUN4I_BACKEND_SPRALPHACTL_REG 0x90c 113#define SUN4I_BACKEND_SPRALPHACTL_REG 0x90c
114
113#define SUN4I_BACKEND_IYUVCTL_REG 0x920 115#define SUN4I_BACKEND_IYUVCTL_REG 0x920
116#define SUN4I_BACKEND_IYUVCTL_FBFMT_MASK GENMASK(14, 12)
117#define SUN4I_BACKEND_IYUVCTL_FBFMT_PACKED_YUV444 (4 << 12)
118#define SUN4I_BACKEND_IYUVCTL_FBFMT_PACKED_YUV422 (3 << 12)
119#define SUN4I_BACKEND_IYUVCTL_FBFMT_PLANAR_YUV444 (2 << 12)
120#define SUN4I_BACKEND_IYUVCTL_FBFMT_PLANAR_YUV222 (1 << 12)
121#define SUN4I_BACKEND_IYUVCTL_FBFMT_PLANAR_YUV111 (0 << 12)
122#define SUN4I_BACKEND_IYUVCTL_FBPS_MASK GENMASK(9, 8)
123#define SUN4I_BACKEND_IYUVCTL_FBPS_YVYU (3 << 8)
124#define SUN4I_BACKEND_IYUVCTL_FBPS_VYUY (2 << 8)
125#define SUN4I_BACKEND_IYUVCTL_FBPS_YUYV (1 << 8)
126#define SUN4I_BACKEND_IYUVCTL_FBPS_UYVY (0 << 8)
127#define SUN4I_BACKEND_IYUVCTL_FBPS_VUYA (1 << 8)
128#define SUN4I_BACKEND_IYUVCTL_FBPS_AYUV (0 << 8)
129#define SUN4I_BACKEND_IYUVCTL_EN BIT(0)
130
114#define SUN4I_BACKEND_IYUVADD_REG(c) (0x930 + (0x4 * (c))) 131#define SUN4I_BACKEND_IYUVADD_REG(c) (0x930 + (0x4 * (c)))
115 132
116#define SUN4I_BACKEND_IYUVLINEWIDTH_REG(c) (0x940 + (0x4 * (c))) 133#define SUN4I_BACKEND_IYUVLINEWIDTH_REG(c) (0x940 + (0x4 * (c)))
@@ -149,6 +166,7 @@
149#define SUN4I_BACKEND_NUM_LAYERS 4 166#define SUN4I_BACKEND_NUM_LAYERS 4
150#define SUN4I_BACKEND_NUM_ALPHA_LAYERS 1 167#define SUN4I_BACKEND_NUM_ALPHA_LAYERS 1
151#define SUN4I_BACKEND_NUM_FRONTEND_LAYERS 1 168#define SUN4I_BACKEND_NUM_FRONTEND_LAYERS 1
169#define SUN4I_BACKEND_NUM_YUV_PLANES 1
152 170
153struct sun4i_backend { 171struct sun4i_backend {
154 struct sunxi_engine engine; 172 struct sunxi_engine engine;
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index a0f43b81c64c..7f0705ef9f4e 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -176,7 +176,13 @@ static bool sun4i_drv_node_is_frontend(struct device_node *node)
176 of_device_is_compatible(node, "allwinner,sun5i-a13-display-frontend") || 176 of_device_is_compatible(node, "allwinner,sun5i-a13-display-frontend") ||
177 of_device_is_compatible(node, "allwinner,sun6i-a31-display-frontend") || 177 of_device_is_compatible(node, "allwinner,sun6i-a31-display-frontend") ||
178 of_device_is_compatible(node, "allwinner,sun7i-a20-display-frontend") || 178 of_device_is_compatible(node, "allwinner,sun7i-a20-display-frontend") ||
179 of_device_is_compatible(node, "allwinner,sun8i-a33-display-frontend"); 179 of_device_is_compatible(node, "allwinner,sun8i-a33-display-frontend") ||
180 of_device_is_compatible(node, "allwinner,sun9i-a80-display-frontend");
181}
182
183static bool sun4i_drv_node_is_deu(struct device_node *node)
184{
185 return of_device_is_compatible(node, "allwinner,sun9i-a80-deu");
180} 186}
181 187
182static bool sun4i_drv_node_is_supported_frontend(struct device_node *node) 188static bool sun4i_drv_node_is_supported_frontend(struct device_node *node)
@@ -257,7 +263,8 @@ static int sun4i_drv_add_endpoints(struct device *dev,
257 * enabled frontend supported by the driver, we add it to our 263 * enabled frontend supported by the driver, we add it to our
258 * component list. 264 * component list.
259 */ 265 */
260 if (!sun4i_drv_node_is_frontend(node) || 266 if (!(sun4i_drv_node_is_frontend(node) ||
267 sun4i_drv_node_is_deu(node)) ||
261 (sun4i_drv_node_is_supported_frontend(node) && 268 (sun4i_drv_node_is_supported_frontend(node) &&
262 of_device_is_available(node))) { 269 of_device_is_available(node))) {
263 /* Add current component */ 270 /* Add current component */
@@ -361,6 +368,7 @@ static const struct of_device_id sun4i_drv_of_table[] = {
361 { .compatible = "allwinner,sun8i-a83t-display-engine" }, 368 { .compatible = "allwinner,sun8i-a83t-display-engine" },
362 { .compatible = "allwinner,sun8i-h3-display-engine" }, 369 { .compatible = "allwinner,sun8i-h3-display-engine" },
363 { .compatible = "allwinner,sun8i-v3s-display-engine" }, 370 { .compatible = "allwinner,sun8i-v3s-display-engine" },
371 { .compatible = "allwinner,sun9i-a80-display-engine" },
364 { } 372 { }
365}; 373};
366MODULE_DEVICE_TABLE(of, sun4i_drv_of_table); 374MODULE_DEVICE_TABLE(of, sun4i_drv_of_table);
diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c
index 33ad377569ec..2949a3c912c1 100644
--- a/drivers/gpu/drm/sun4i/sun4i_layer.c
+++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
@@ -134,7 +134,11 @@ static const uint32_t sun4i_backend_layer_formats[] = {
134 DRM_FORMAT_RGBA4444, 134 DRM_FORMAT_RGBA4444,
135 DRM_FORMAT_RGB888, 135 DRM_FORMAT_RGB888,
136 DRM_FORMAT_RGB565, 136 DRM_FORMAT_RGB565,
137 DRM_FORMAT_UYVY,
138 DRM_FORMAT_VYUY,
137 DRM_FORMAT_XRGB8888, 139 DRM_FORMAT_XRGB8888,
140 DRM_FORMAT_YUYV,
141 DRM_FORMAT_YVYU,
138}; 142};
139 143
140static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm, 144static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm,
diff --git a/drivers/gpu/drm/sun4i/sun4i_lvds.c b/drivers/gpu/drm/sun4i/sun4i_lvds.c
index be3f14d7746d..bffff4c9fbf5 100644
--- a/drivers/gpu/drm/sun4i/sun4i_lvds.c
+++ b/drivers/gpu/drm/sun4i/sun4i_lvds.c
@@ -94,9 +94,64 @@ static void sun4i_lvds_encoder_disable(struct drm_encoder *encoder)
94 } 94 }
95} 95}
96 96
97static enum drm_mode_status sun4i_lvds_encoder_mode_valid(struct drm_encoder *crtc,
98 const struct drm_display_mode *mode)
99{
100 struct sun4i_lvds *lvds = drm_encoder_to_sun4i_lvds(crtc);
101 struct sun4i_tcon *tcon = lvds->tcon;
102 u32 hsync = mode->hsync_end - mode->hsync_start;
103 u32 vsync = mode->vsync_end - mode->vsync_start;
104 unsigned long rate = mode->clock * 1000;
105 long rounded_rate;
106
107 DRM_DEBUG_DRIVER("Validating modes...\n");
108
109 if (hsync < 1)
110 return MODE_HSYNC_NARROW;
111
112 if (hsync > 0x3ff)
113 return MODE_HSYNC_WIDE;
114
115 if ((mode->hdisplay < 1) || (mode->htotal < 1))
116 return MODE_H_ILLEGAL;
117
118 if ((mode->hdisplay > 0x7ff) || (mode->htotal > 0xfff))
119 return MODE_BAD_HVALUE;
120
121 DRM_DEBUG_DRIVER("Horizontal parameters OK\n");
122
123 if (vsync < 1)
124 return MODE_VSYNC_NARROW;
125
126 if (vsync > 0x3ff)
127 return MODE_VSYNC_WIDE;
128
129 if ((mode->vdisplay < 1) || (mode->vtotal < 1))
130 return MODE_V_ILLEGAL;
131
132 if ((mode->vdisplay > 0x7ff) || (mode->vtotal > 0xfff))
133 return MODE_BAD_VVALUE;
134
135 DRM_DEBUG_DRIVER("Vertical parameters OK\n");
136
137 tcon->dclk_min_div = 7;
138 tcon->dclk_max_div = 7;
139 rounded_rate = clk_round_rate(tcon->dclk, rate);
140 if (rounded_rate < rate)
141 return MODE_CLOCK_LOW;
142
143 if (rounded_rate > rate)
144 return MODE_CLOCK_HIGH;
145
146 DRM_DEBUG_DRIVER("Clock rate OK\n");
147
148 return MODE_OK;
149}
150
97static const struct drm_encoder_helper_funcs sun4i_lvds_enc_helper_funcs = { 151static const struct drm_encoder_helper_funcs sun4i_lvds_enc_helper_funcs = {
98 .disable = sun4i_lvds_encoder_disable, 152 .disable = sun4i_lvds_encoder_disable,
99 .enable = sun4i_lvds_encoder_enable, 153 .enable = sun4i_lvds_encoder_enable,
154 .mode_valid = sun4i_lvds_encoder_mode_valid,
100}; 155};
101 156
102static const struct drm_encoder_funcs sun4i_lvds_enc_funcs = { 157static const struct drm_encoder_funcs sun4i_lvds_enc_funcs = {
diff --git a/drivers/gpu/drm/sun4i/sun4i_rgb.c b/drivers/gpu/drm/sun4i/sun4i_rgb.c
index 832f8f9bc47f..a2a697a099e6 100644
--- a/drivers/gpu/drm/sun4i/sun4i_rgb.c
+++ b/drivers/gpu/drm/sun4i/sun4i_rgb.c
@@ -52,10 +52,10 @@ static int sun4i_rgb_get_modes(struct drm_connector *connector)
52 return drm_panel_get_modes(tcon->panel); 52 return drm_panel_get_modes(tcon->panel);
53} 53}
54 54
55static int sun4i_rgb_mode_valid(struct drm_connector *connector, 55static enum drm_mode_status sun4i_rgb_mode_valid(struct drm_encoder *crtc,
56 struct drm_display_mode *mode) 56 const struct drm_display_mode *mode)
57{ 57{
58 struct sun4i_rgb *rgb = drm_connector_to_sun4i_rgb(connector); 58 struct sun4i_rgb *rgb = drm_encoder_to_sun4i_rgb(crtc);
59 struct sun4i_tcon *tcon = rgb->tcon; 59 struct sun4i_tcon *tcon = rgb->tcon;
60 u32 hsync = mode->hsync_end - mode->hsync_start; 60 u32 hsync = mode->hsync_end - mode->hsync_start;
61 u32 vsync = mode->vsync_end - mode->vsync_start; 61 u32 vsync = mode->vsync_end - mode->vsync_start;
@@ -106,7 +106,6 @@ static int sun4i_rgb_mode_valid(struct drm_connector *connector,
106 106
107static struct drm_connector_helper_funcs sun4i_rgb_con_helper_funcs = { 107static struct drm_connector_helper_funcs sun4i_rgb_con_helper_funcs = {
108 .get_modes = sun4i_rgb_get_modes, 108 .get_modes = sun4i_rgb_get_modes,
109 .mode_valid = sun4i_rgb_mode_valid,
110}; 109};
111 110
112static void 111static void
@@ -156,6 +155,7 @@ static void sun4i_rgb_encoder_disable(struct drm_encoder *encoder)
156static struct drm_encoder_helper_funcs sun4i_rgb_enc_helper_funcs = { 155static struct drm_encoder_helper_funcs sun4i_rgb_enc_helper_funcs = {
157 .disable = sun4i_rgb_encoder_disable, 156 .disable = sun4i_rgb_encoder_disable,
158 .enable = sun4i_rgb_encoder_enable, 157 .enable = sun4i_rgb_encoder_enable,
158 .mode_valid = sun4i_rgb_mode_valid,
159}; 159};
160 160
161static void sun4i_rgb_enc_destroy(struct drm_encoder *encoder) 161static void sun4i_rgb_enc_destroy(struct drm_encoder *encoder)
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 0d6c5ed44795..1a114e380f13 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -17,6 +17,7 @@
17#include <drm/drm_encoder.h> 17#include <drm/drm_encoder.h>
18#include <drm/drm_modes.h> 18#include <drm/drm_modes.h>
19#include <drm/drm_of.h> 19#include <drm/drm_of.h>
20#include <drm/drm_panel.h>
20 21
21#include <uapi/drm/drm_mode.h> 22#include <uapi/drm/drm_mode.h>
22 23
@@ -343,6 +344,9 @@ static void sun4i_tcon0_mode_set_lvds(struct sun4i_tcon *tcon,
343static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon, 344static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon,
344 const struct drm_display_mode *mode) 345 const struct drm_display_mode *mode)
345{ 346{
347 struct drm_panel *panel = tcon->panel;
348 struct drm_connector *connector = panel->connector;
349 struct drm_display_info display_info = connector->display_info;
346 unsigned int bp, hsync, vsync; 350 unsigned int bp, hsync, vsync;
347 u8 clk_delay; 351 u8 clk_delay;
348 u32 val = 0; 352 u32 val = 0;
@@ -400,6 +404,27 @@ static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon,
400 if (mode->flags & DRM_MODE_FLAG_PVSYNC) 404 if (mode->flags & DRM_MODE_FLAG_PVSYNC)
401 val |= SUN4I_TCON0_IO_POL_VSYNC_POSITIVE; 405 val |= SUN4I_TCON0_IO_POL_VSYNC_POSITIVE;
402 406
407 /*
408 * On A20 and similar SoCs, the only way to achieve Positive Edge
409 * (Rising Edge), is setting dclk clock phase to 2/3(240°).
410 * By default TCON works in Negative Edge(Falling Edge),
411 * this is why phase is set to 0 in that case.
412 * Unfortunately there's no way to logically invert dclk through
413 * IO_POL register.
414 * The only acceptable way to work, triple checked with scope,
415 * is using clock phase set to 0° for Negative Edge and set to 240°
416 * for Positive Edge.
417 * On A33 and similar SoCs there would be a 90° phase option,
418 * but it divides also dclk by 2.
419 * Following code is a way to avoid quirks all around TCON
420 * and DOTCLOCK drivers.
421 */
422 if (display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_POSEDGE)
423 clk_set_phase(tcon->dclk, 240);
424
425 if (display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_NEGEDGE)
426 clk_set_phase(tcon->dclk, 0);
427
403 regmap_update_bits(tcon->regs, SUN4I_TCON0_IO_POL_REG, 428 regmap_update_bits(tcon->regs, SUN4I_TCON0_IO_POL_REG,
404 SUN4I_TCON0_IO_POL_HSYNC_POSITIVE | SUN4I_TCON0_IO_POL_VSYNC_POSITIVE, 429 SUN4I_TCON0_IO_POL_HSYNC_POSITIVE | SUN4I_TCON0_IO_POL_VSYNC_POSITIVE,
405 val); 430 val);
@@ -850,6 +875,7 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
850 struct sunxi_engine *engine; 875 struct sunxi_engine *engine;
851 struct device_node *remote; 876 struct device_node *remote;
852 struct sun4i_tcon *tcon; 877 struct sun4i_tcon *tcon;
878 struct reset_control *edp_rstc;
853 bool has_lvds_rst, has_lvds_alt, can_lvds; 879 bool has_lvds_rst, has_lvds_alt, can_lvds;
854 int ret; 880 int ret;
855 881
@@ -874,6 +900,20 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
874 return PTR_ERR(tcon->lcd_rst); 900 return PTR_ERR(tcon->lcd_rst);
875 } 901 }
876 902
903 if (tcon->quirks->needs_edp_reset) {
904 edp_rstc = devm_reset_control_get_shared(dev, "edp");
905 if (IS_ERR(edp_rstc)) {
906 dev_err(dev, "Couldn't get edp reset line\n");
907 return PTR_ERR(edp_rstc);
908 }
909
910 ret = reset_control_deassert(edp_rstc);
911 if (ret) {
912 dev_err(dev, "Couldn't deassert edp reset line\n");
913 return ret;
914 }
915 }
916
877 /* Make sure our TCON is reset */ 917 /* Make sure our TCON is reset */
878 ret = reset_control_reset(tcon->lcd_rst); 918 ret = reset_control_reset(tcon->lcd_rst);
879 if (ret) { 919 if (ret) {
@@ -1166,6 +1206,16 @@ static const struct sun4i_tcon_quirks sun8i_v3s_quirks = {
1166 .has_channel_0 = true, 1206 .has_channel_0 = true,
1167}; 1207};
1168 1208
1209static const struct sun4i_tcon_quirks sun9i_a80_tcon_lcd_quirks = {
1210 .has_channel_0 = true,
1211 .needs_edp_reset = true,
1212};
1213
1214static const struct sun4i_tcon_quirks sun9i_a80_tcon_tv_quirks = {
1215 .has_channel_1 = true,
1216 .needs_edp_reset = true,
1217};
1218
1169/* sun4i_drv uses this list to check if a device node is a TCON */ 1219/* sun4i_drv uses this list to check if a device node is a TCON */
1170const struct of_device_id sun4i_tcon_of_table[] = { 1220const struct of_device_id sun4i_tcon_of_table[] = {
1171 { .compatible = "allwinner,sun4i-a10-tcon", .data = &sun4i_a10_quirks }, 1221 { .compatible = "allwinner,sun4i-a10-tcon", .data = &sun4i_a10_quirks },
@@ -1177,6 +1227,8 @@ const struct of_device_id sun4i_tcon_of_table[] = {
1177 { .compatible = "allwinner,sun8i-a83t-tcon-lcd", .data = &sun8i_a83t_lcd_quirks }, 1227 { .compatible = "allwinner,sun8i-a83t-tcon-lcd", .data = &sun8i_a83t_lcd_quirks },
1178 { .compatible = "allwinner,sun8i-a83t-tcon-tv", .data = &sun8i_a83t_tv_quirks }, 1228 { .compatible = "allwinner,sun8i-a83t-tcon-tv", .data = &sun8i_a83t_tv_quirks },
1179 { .compatible = "allwinner,sun8i-v3s-tcon", .data = &sun8i_v3s_quirks }, 1229 { .compatible = "allwinner,sun8i-v3s-tcon", .data = &sun8i_v3s_quirks },
1230 { .compatible = "allwinner,sun9i-a80-tcon-lcd", .data = &sun9i_a80_tcon_lcd_quirks },
1231 { .compatible = "allwinner,sun9i-a80-tcon-tv", .data = &sun9i_a80_tcon_tv_quirks },
1180 { } 1232 { }
1181}; 1233};
1182MODULE_DEVICE_TABLE(of, sun4i_tcon_of_table); 1234MODULE_DEVICE_TABLE(of, sun4i_tcon_of_table);
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h
index 78d55e7cd2b3..d3a945b7bb60 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
@@ -176,6 +176,7 @@ struct sun4i_tcon_quirks {
176 bool has_channel_1; /* a33 does not have channel 1 */ 176 bool has_channel_1; /* a33 does not have channel 1 */
177 bool has_lvds_alt; /* Does the LVDS clock have a parent other than the TCON clock? */ 177 bool has_lvds_alt; /* Does the LVDS clock have a parent other than the TCON clock? */
178 bool needs_de_be_mux; /* sun6i needs mux to select backend */ 178 bool needs_de_be_mux; /* sun6i needs mux to select backend */
179 bool needs_edp_reset; /* a80 edp reset needed for tcon0 access */
179 180
180 /* callback to handle tcon muxing options */ 181 /* callback to handle tcon muxing options */
181 int (*set_mux)(struct sun4i_tcon *, const struct drm_encoder *); 182 int (*set_mux)(struct sun4i_tcon *, const struct drm_encoder *);
diff --git a/drivers/gpu/drm/sun4i/sun6i_drc.c b/drivers/gpu/drm/sun4i/sun6i_drc.c
index 09bba853e2a4..b5e071a49045 100644
--- a/drivers/gpu/drm/sun4i/sun6i_drc.c
+++ b/drivers/gpu/drm/sun4i/sun6i_drc.c
@@ -101,6 +101,7 @@ static const struct of_device_id sun6i_drc_of_table[] = {
101 { .compatible = "allwinner,sun6i-a31-drc" }, 101 { .compatible = "allwinner,sun6i-a31-drc" },
102 { .compatible = "allwinner,sun6i-a31s-drc" }, 102 { .compatible = "allwinner,sun6i-a31s-drc" },
103 { .compatible = "allwinner,sun8i-a33-drc" }, 103 { .compatible = "allwinner,sun8i-a33-drc" },
104 { .compatible = "allwinner,sun9i-a80-drc" },
104 { } 105 { }
105}; 106};
106MODULE_DEVICE_TABLE(of, sun6i_drc_of_table); 107MODULE_DEVICE_TABLE(of, sun6i_drc_of_table);
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index ce1e3b9e14c9..bf4667481935 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -643,9 +643,12 @@ static void vc4_crtc_atomic_flush(struct drm_crtc *crtc,
643{ 643{
644 struct drm_device *dev = crtc->dev; 644 struct drm_device *dev = crtc->dev;
645 struct vc4_dev *vc4 = to_vc4_dev(dev); 645 struct vc4_dev *vc4 = to_vc4_dev(dev);
646 struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
646 struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); 647 struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
647 struct drm_plane *plane; 648 struct drm_plane *plane;
649 struct vc4_plane_state *vc4_plane_state;
648 bool debug_dump_regs = false; 650 bool debug_dump_regs = false;
651 bool enable_bg_fill = false;
649 u32 __iomem *dlist_start = vc4->hvs->dlist + vc4_state->mm.start; 652 u32 __iomem *dlist_start = vc4->hvs->dlist + vc4_state->mm.start;
650 u32 __iomem *dlist_next = dlist_start; 653 u32 __iomem *dlist_next = dlist_start;
651 654
@@ -656,6 +659,20 @@ static void vc4_crtc_atomic_flush(struct drm_crtc *crtc,
656 659
657 /* Copy all the active planes' dlist contents to the hardware dlist. */ 660 /* Copy all the active planes' dlist contents to the hardware dlist. */
658 drm_atomic_crtc_for_each_plane(plane, crtc) { 661 drm_atomic_crtc_for_each_plane(plane, crtc) {
662 /* Is this the first active plane? */
663 if (dlist_next == dlist_start) {
664 /* We need to enable background fill when a plane
665 * could be alpha blending from the background, i.e.
666 * where no other plane is underneath. It suffices to
667 * consider the first active plane here since we set
668 * needs_bg_fill such that either the first plane
669 * already needs it or all planes on top blend from
670 * the first or a lower plane.
671 */
672 vc4_plane_state = to_vc4_plane_state(plane->state);
673 enable_bg_fill = vc4_plane_state->needs_bg_fill;
674 }
675
659 dlist_next += vc4_plane_write_dlist(plane, dlist_next); 676 dlist_next += vc4_plane_write_dlist(plane, dlist_next);
660 } 677 }
661 678
@@ -664,6 +681,14 @@ static void vc4_crtc_atomic_flush(struct drm_crtc *crtc,
664 681
665 WARN_ON_ONCE(dlist_next - dlist_start != vc4_state->mm.size); 682 WARN_ON_ONCE(dlist_next - dlist_start != vc4_state->mm.size);
666 683
684 if (enable_bg_fill)
685 /* This sets a black background color fill, as is the case
686 * with other DRM drivers.
687 */
688 HVS_WRITE(SCALER_DISPBKGNDX(vc4_crtc->channel),
689 HVS_READ(SCALER_DISPBKGNDX(vc4_crtc->channel)) |
690 SCALER_DISPBKGND_FILL);
691
667 /* Only update DISPLIST if the CRTC was already running and is not 692 /* Only update DISPLIST if the CRTC was already running and is not
668 * being disabled. 693 * being disabled.
669 * vc4_crtc_enable() takes care of updating the dlist just after 694 * vc4_crtc_enable() takes care of updating the dlist just after
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index fefa1664a9f5..1b4cd1fabf56 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -310,6 +310,66 @@ to_vc4_plane(struct drm_plane *plane)
310 return (struct vc4_plane *)plane; 310 return (struct vc4_plane *)plane;
311} 311}
312 312
313enum vc4_scaling_mode {
314 VC4_SCALING_NONE,
315 VC4_SCALING_TPZ,
316 VC4_SCALING_PPF,
317};
318
319struct vc4_plane_state {
320 struct drm_plane_state base;
321 /* System memory copy of the display list for this element, computed
322 * at atomic_check time.
323 */
324 u32 *dlist;
325 u32 dlist_size; /* Number of dwords allocated for the display list */
326 u32 dlist_count; /* Number of used dwords in the display list. */
327
328 /* Offset in the dlist to various words, for pageflip or
329 * cursor updates.
330 */
331 u32 pos0_offset;
332 u32 pos2_offset;
333 u32 ptr0_offset;
334
335 /* Offset where the plane's dlist was last stored in the
336 * hardware at vc4_crtc_atomic_flush() time.
337 */
338 u32 __iomem *hw_dlist;
339
340 /* Clipped coordinates of the plane on the display. */
341 int crtc_x, crtc_y, crtc_w, crtc_h;
342 /* Clipped area being scanned from in the FB. */
343 u32 src_x, src_y;
344
345 u32 src_w[2], src_h[2];
346
347 /* Scaling selection for the RGB/Y plane and the Cb/Cr planes. */
348 enum vc4_scaling_mode x_scaling[2], y_scaling[2];
349 bool is_unity;
350 bool is_yuv;
351
352 /* Offset to start scanning out from the start of the plane's
353 * BO.
354 */
355 u32 offsets[3];
356
357 /* Our allocation in LBM for temporary storage during scaling. */
358 struct drm_mm_node lbm;
359
360 /* Set when the plane has per-pixel alpha content or does not cover
361 * the entire screen. This is a hint to the CRTC that it might need
362 * to enable background color fill.
363 */
364 bool needs_bg_fill;
365};
366
367static inline struct vc4_plane_state *
368to_vc4_plane_state(struct drm_plane_state *state)
369{
370 return (struct vc4_plane_state *)state;
371}
372
313enum vc4_encoder_type { 373enum vc4_encoder_type {
314 VC4_ENCODER_TYPE_NONE, 374 VC4_ENCODER_TYPE_NONE,
315 VC4_ENCODER_TYPE_HDMI, 375 VC4_ENCODER_TYPE_HDMI,
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index c4c7af11fec5..ce39390be389 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -27,60 +27,6 @@
27#include "vc4_drv.h" 27#include "vc4_drv.h"
28#include "vc4_regs.h" 28#include "vc4_regs.h"
29 29
30enum vc4_scaling_mode {
31 VC4_SCALING_NONE,
32 VC4_SCALING_TPZ,
33 VC4_SCALING_PPF,
34};
35
36struct vc4_plane_state {
37 struct drm_plane_state base;
38 /* System memory copy of the display list for this element, computed
39 * at atomic_check time.
40 */
41 u32 *dlist;
42 u32 dlist_size; /* Number of dwords allocated for the display list */
43 u32 dlist_count; /* Number of used dwords in the display list. */
44
45 /* Offset in the dlist to various words, for pageflip or
46 * cursor updates.
47 */
48 u32 pos0_offset;
49 u32 pos2_offset;
50 u32 ptr0_offset;
51
52 /* Offset where the plane's dlist was last stored in the
53 * hardware at vc4_crtc_atomic_flush() time.
54 */
55 u32 __iomem *hw_dlist;
56
57 /* Clipped coordinates of the plane on the display. */
58 int crtc_x, crtc_y, crtc_w, crtc_h;
59 /* Clipped area being scanned from in the FB. */
60 u32 src_x, src_y;
61
62 u32 src_w[2], src_h[2];
63
64 /* Scaling selection for the RGB/Y plane and the Cb/Cr planes. */
65 enum vc4_scaling_mode x_scaling[2], y_scaling[2];
66 bool is_unity;
67 bool is_yuv;
68
69 /* Offset to start scanning out from the start of the plane's
70 * BO.
71 */
72 u32 offsets[3];
73
74 /* Our allocation in LBM for temporary storage during scaling. */
75 struct drm_mm_node lbm;
76};
77
78static inline struct vc4_plane_state *
79to_vc4_plane_state(struct drm_plane_state *state)
80{
81 return (struct vc4_plane_state *)state;
82}
83
84static const struct hvs_format { 30static const struct hvs_format {
85 u32 drm; /* DRM_FORMAT_* */ 31 u32 drm; /* DRM_FORMAT_* */
86 u32 hvs; /* HVS_FORMAT_* */ 32 u32 hvs; /* HVS_FORMAT_* */
@@ -521,6 +467,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
521 u32 ctl0_offset = vc4_state->dlist_count; 467 u32 ctl0_offset = vc4_state->dlist_count;
522 const struct hvs_format *format = vc4_get_hvs_format(fb->format->format); 468 const struct hvs_format *format = vc4_get_hvs_format(fb->format->format);
523 int num_planes = drm_format_num_planes(format->drm); 469 int num_planes = drm_format_num_planes(format->drm);
470 bool covers_screen;
524 u32 scl0, scl1, pitch0; 471 u32 scl0, scl1, pitch0;
525 u32 lbm_size, tiling; 472 u32 lbm_size, tiling;
526 unsigned long irqflags; 473 unsigned long irqflags;
@@ -618,13 +565,14 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
618 SCALER_POS1_SCL_HEIGHT)); 565 SCALER_POS1_SCL_HEIGHT));
619 } 566 }
620 567
621 /* Position Word 2: Source Image Size, Alpha Mode */ 568 /* Position Word 2: Source Image Size, Alpha */
622 vc4_state->pos2_offset = vc4_state->dlist_count; 569 vc4_state->pos2_offset = vc4_state->dlist_count;
623 vc4_dlist_write(vc4_state, 570 vc4_dlist_write(vc4_state,
624 VC4_SET_FIELD(fb->format->has_alpha ? 571 VC4_SET_FIELD(fb->format->has_alpha ?
625 SCALER_POS2_ALPHA_MODE_PIPELINE : 572 SCALER_POS2_ALPHA_MODE_PIPELINE :
626 SCALER_POS2_ALPHA_MODE_FIXED, 573 SCALER_POS2_ALPHA_MODE_FIXED,
627 SCALER_POS2_ALPHA_MODE) | 574 SCALER_POS2_ALPHA_MODE) |
575 (fb->format->has_alpha ? SCALER_POS2_ALPHA_PREMULT : 0) |
628 VC4_SET_FIELD(vc4_state->src_w[0], SCALER_POS2_WIDTH) | 576 VC4_SET_FIELD(vc4_state->src_w[0], SCALER_POS2_WIDTH) |
629 VC4_SET_FIELD(vc4_state->src_h[0], SCALER_POS2_HEIGHT)); 577 VC4_SET_FIELD(vc4_state->src_h[0], SCALER_POS2_HEIGHT));
630 578
@@ -700,6 +648,16 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
700 vc4_state->dlist[ctl0_offset] |= 648 vc4_state->dlist[ctl0_offset] |=
701 VC4_SET_FIELD(vc4_state->dlist_count, SCALER_CTL0_SIZE); 649 VC4_SET_FIELD(vc4_state->dlist_count, SCALER_CTL0_SIZE);
702 650
651 /* crtc_* are already clipped coordinates. */
652 covers_screen = vc4_state->crtc_x == 0 && vc4_state->crtc_y == 0 &&
653 vc4_state->crtc_w == state->crtc->mode.hdisplay &&
654 vc4_state->crtc_h == state->crtc->mode.vdisplay;
655 /* Background fill might be necessary when the plane has per-pixel
656 * alpha content and blends from the background or does not cover
657 * the entire screen.
658 */
659 vc4_state->needs_bg_fill = fb->format->has_alpha || !covers_screen;
660
703 return 0; 661 return 0;
704} 662}
705 663
diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
index b9749cb24063..a141496104a6 100644
--- a/drivers/gpu/drm/vc4/vc4_regs.h
+++ b/drivers/gpu/drm/vc4/vc4_regs.h
@@ -848,6 +848,7 @@ enum hvs_pixel_format {
848#define SCALER_POS2_ALPHA_MODE_FIXED 1 848#define SCALER_POS2_ALPHA_MODE_FIXED 1
849#define SCALER_POS2_ALPHA_MODE_FIXED_NONZERO 2 849#define SCALER_POS2_ALPHA_MODE_FIXED_NONZERO 2
850#define SCALER_POS2_ALPHA_MODE_FIXED_OVER_0x07 3 850#define SCALER_POS2_ALPHA_MODE_FIXED_OVER_0x07 3
851#define SCALER_POS2_ALPHA_PREMULT BIT(29)
851 852
852#define SCALER_POS2_HEIGHT_MASK VC4_MASK(27, 16) 853#define SCALER_POS2_HEIGHT_MASK VC4_MASK(27, 16)
853#define SCALER_POS2_HEIGHT_SHIFT 16 854#define SCALER_POS2_HEIGHT_SHIFT 16
diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c
index 2db485abb186..eec76af49f04 100644
--- a/drivers/gpu/drm/vc4/vc4_validate.c
+++ b/drivers/gpu/drm/vc4/vc4_validate.c
@@ -753,7 +753,7 @@ validate_gl_shader_rec(struct drm_device *dev,
753 28, /* cs */ 753 28, /* cs */
754 }; 754 };
755 uint32_t shader_reloc_count = ARRAY_SIZE(shader_reloc_offsets); 755 uint32_t shader_reloc_count = ARRAY_SIZE(shader_reloc_offsets);
756 struct drm_gem_cma_object *bo[shader_reloc_count + 8]; 756 struct drm_gem_cma_object *bo[ARRAY_SIZE(shader_reloc_offsets) + 8];
757 uint32_t nr_attributes, nr_relocs, packet_size; 757 uint32_t nr_attributes, nr_relocs, packet_size;
758 int i; 758 int i;
759 759
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
index d23a18aae476..be7d7fb1b44b 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
@@ -500,7 +500,7 @@ static int vmw_fb_kms_detach(struct vmw_fb_par *par,
500 } 500 }
501 501
502 if (cur_fb) { 502 if (cur_fb) {
503 drm_framebuffer_unreference(cur_fb); 503 drm_framebuffer_put(cur_fb);
504 par->set_fb = NULL; 504 par->set_fb = NULL;
505 } 505 }
506 506
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
index 67f844678ac8..c5e8eae0dbe2 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
@@ -316,7 +316,7 @@ int vmw_present_ioctl(struct drm_device *dev, void *data,
316out_no_surface: 316out_no_surface:
317 ttm_read_unlock(&dev_priv->reservation_sem); 317 ttm_read_unlock(&dev_priv->reservation_sem);
318out_no_ttm_lock: 318out_no_ttm_lock:
319 drm_framebuffer_unreference(fb); 319 drm_framebuffer_put(fb);
320out_no_fb: 320out_no_fb:
321 drm_modeset_unlock_all(dev); 321 drm_modeset_unlock_all(dev);
322out_no_copy: 322out_no_copy:
@@ -393,7 +393,7 @@ int vmw_present_readback_ioctl(struct drm_device *dev, void *data,
393 393
394 ttm_read_unlock(&dev_priv->reservation_sem); 394 ttm_read_unlock(&dev_priv->reservation_sem);
395out_no_ttm_lock: 395out_no_ttm_lock:
396 drm_framebuffer_unreference(fb); 396 drm_framebuffer_put(fb);
397out_no_fb: 397out_no_fb:
398 drm_modeset_unlock_all(dev); 398 drm_modeset_unlock_all(dev);
399out_no_copy: 399out_no_copy:
diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c
index 3cd153c6d271..fc4adf3d34e8 100644
--- a/drivers/gpu/vga/vga_switcheroo.c
+++ b/drivers/gpu/vga/vga_switcheroo.c
@@ -92,7 +92,8 @@
92 * struct vga_switcheroo_client - registered client 92 * struct vga_switcheroo_client - registered client
93 * @pdev: client pci device 93 * @pdev: client pci device
94 * @fb_info: framebuffer to which console is remapped on switching 94 * @fb_info: framebuffer to which console is remapped on switching
95 * @pwr_state: current power state 95 * @pwr_state: current power state if manual power control is used.
96 * For driver power control, call vga_switcheroo_pwr_state().
96 * @ops: client callbacks 97 * @ops: client callbacks
97 * @id: client identifier. Determining the id requires the handler, 98 * @id: client identifier. Determining the id requires the handler,
98 * so gpus are initially assigned VGA_SWITCHEROO_UNKNOWN_ID 99 * so gpus are initially assigned VGA_SWITCHEROO_UNKNOWN_ID
@@ -104,8 +105,7 @@
104 * @list: client list 105 * @list: client list
105 * 106 *
106 * Registered client. A client can be either a GPU or an audio device on a GPU. 107 * Registered client. A client can be either a GPU or an audio device on a GPU.
107 * For audio clients, the @fb_info, @active and @driver_power_control members 108 * For audio clients, the @fb_info and @active members are bogus.
108 * are bogus.
109 */ 109 */
110struct vga_switcheroo_client { 110struct vga_switcheroo_client {
111 struct pci_dev *pdev; 111 struct pci_dev *pdev;
@@ -331,8 +331,8 @@ EXPORT_SYMBOL(vga_switcheroo_register_client);
331 * @ops: client callbacks 331 * @ops: client callbacks
332 * @id: client identifier 332 * @id: client identifier
333 * 333 *
334 * Register audio client (audio device on a GPU). The power state of the 334 * Register audio client (audio device on a GPU). The client is assumed
335 * client is assumed to be ON. Beforehand, vga_switcheroo_client_probe_defer() 335 * to use runtime PM. Beforehand, vga_switcheroo_client_probe_defer()
336 * shall be called to ensure that all prerequisites are met. 336 * shall be called to ensure that all prerequisites are met.
337 * 337 *
338 * Return: 0 on success, -ENOMEM on memory allocation error. 338 * Return: 0 on success, -ENOMEM on memory allocation error.
@@ -341,7 +341,7 @@ int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
341 const struct vga_switcheroo_client_ops *ops, 341 const struct vga_switcheroo_client_ops *ops,
342 enum vga_switcheroo_client_id id) 342 enum vga_switcheroo_client_id id)
343{ 343{
344 return register_client(pdev, ops, id | ID_BIT_AUDIO, false, false); 344 return register_client(pdev, ops, id | ID_BIT_AUDIO, false, true);
345} 345}
346EXPORT_SYMBOL(vga_switcheroo_register_audio_client); 346EXPORT_SYMBOL(vga_switcheroo_register_audio_client);
347 347
@@ -406,6 +406,19 @@ bool vga_switcheroo_client_probe_defer(struct pci_dev *pdev)
406} 406}
407EXPORT_SYMBOL(vga_switcheroo_client_probe_defer); 407EXPORT_SYMBOL(vga_switcheroo_client_probe_defer);
408 408
409static enum vga_switcheroo_state
410vga_switcheroo_pwr_state(struct vga_switcheroo_client *client)
411{
412 if (client->driver_power_control)
413 if (pm_runtime_enabled(&client->pdev->dev) &&
414 pm_runtime_active(&client->pdev->dev))
415 return VGA_SWITCHEROO_ON;
416 else
417 return VGA_SWITCHEROO_OFF;
418 else
419 return client->pwr_state;
420}
421
409/** 422/**
410 * vga_switcheroo_get_client_state() - obtain power state of a given client 423 * vga_switcheroo_get_client_state() - obtain power state of a given client
411 * @pdev: client pci device 424 * @pdev: client pci device
@@ -425,7 +438,7 @@ enum vga_switcheroo_state vga_switcheroo_get_client_state(struct pci_dev *pdev)
425 if (!client) 438 if (!client)
426 ret = VGA_SWITCHEROO_NOT_FOUND; 439 ret = VGA_SWITCHEROO_NOT_FOUND;
427 else 440 else
428 ret = client->pwr_state; 441 ret = vga_switcheroo_pwr_state(client);
429 mutex_unlock(&vgasr_mutex); 442 mutex_unlock(&vgasr_mutex);
430 return ret; 443 return ret;
431} 444}
@@ -598,7 +611,7 @@ static int vga_switcheroo_show(struct seq_file *m, void *v)
598 client_is_vga(client) ? "" : "-Audio", 611 client_is_vga(client) ? "" : "-Audio",
599 client->active ? '+' : ' ', 612 client->active ? '+' : ' ',
600 client->driver_power_control ? "Dyn" : "", 613 client->driver_power_control ? "Dyn" : "",
601 client->pwr_state ? "Pwr" : "Off", 614 vga_switcheroo_pwr_state(client) ? "Pwr" : "Off",
602 pci_name(client->pdev)); 615 pci_name(client->pdev));
603 i++; 616 i++;
604 } 617 }
@@ -641,10 +654,8 @@ static void set_audio_state(enum vga_switcheroo_client_id id,
641 struct vga_switcheroo_client *client; 654 struct vga_switcheroo_client *client;
642 655
643 client = find_client_from_id(&vgasr_priv.clients, id | ID_BIT_AUDIO); 656 client = find_client_from_id(&vgasr_priv.clients, id | ID_BIT_AUDIO);
644 if (client && client->pwr_state != state) { 657 if (client)
645 client->ops->set_gpu_state(client->pdev, state); 658 client->ops->set_gpu_state(client->pdev, state);
646 client->pwr_state = state;
647 }
648} 659}
649 660
650/* stage one happens before delay */ 661/* stage one happens before delay */
@@ -656,7 +667,7 @@ static int vga_switchto_stage1(struct vga_switcheroo_client *new_client)
656 if (!active) 667 if (!active)
657 return 0; 668 return 0;
658 669
659 if (new_client->pwr_state == VGA_SWITCHEROO_OFF) 670 if (vga_switcheroo_pwr_state(new_client) == VGA_SWITCHEROO_OFF)
660 vga_switchon(new_client); 671 vga_switchon(new_client);
661 672
662 vga_set_default_device(new_client->pdev); 673 vga_set_default_device(new_client->pdev);
@@ -675,7 +686,9 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client)
675 686
676 active->active = false; 687 active->active = false;
677 688
678 set_audio_state(active->id, VGA_SWITCHEROO_OFF); 689 /* let HDA controller autosuspend if GPU uses driver power control */
690 if (!active->driver_power_control)
691 set_audio_state(active->id, VGA_SWITCHEROO_OFF);
679 692
680 if (new_client->fb_info) { 693 if (new_client->fb_info) {
681 struct fb_event event; 694 struct fb_event event;
@@ -695,10 +708,12 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client)
695 if (new_client->ops->reprobe) 708 if (new_client->ops->reprobe)
696 new_client->ops->reprobe(new_client->pdev); 709 new_client->ops->reprobe(new_client->pdev);
697 710
698 if (active->pwr_state == VGA_SWITCHEROO_ON) 711 if (vga_switcheroo_pwr_state(active) == VGA_SWITCHEROO_ON)
699 vga_switchoff(active); 712 vga_switchoff(active);
700 713
701 set_audio_state(new_client->id, VGA_SWITCHEROO_ON); 714 /* let HDA controller autoresume if GPU uses driver power control */
715 if (!new_client->driver_power_control)
716 set_audio_state(new_client->id, VGA_SWITCHEROO_ON);
702 717
703 new_client->active = true; 718 new_client->active = true;
704 return 0; 719 return 0;
@@ -939,11 +954,6 @@ EXPORT_SYMBOL(vga_switcheroo_process_delayed_switch);
939 * Specifying nouveau.runpm=0, radeon.runpm=0 or amdgpu.runpm=0 on the kernel 954 * Specifying nouveau.runpm=0, radeon.runpm=0 or amdgpu.runpm=0 on the kernel
940 * command line disables it. 955 * command line disables it.
941 * 956 *
942 * When the driver decides to power up or down, it notifies vga_switcheroo
943 * thereof so that it can (a) power the audio device on the GPU up or down,
944 * and (b) update its internal power state representation for the device.
945 * This is achieved by vga_switcheroo_set_dynamic_switch().
946 *
947 * After the GPU has been suspended, the handler needs to be called to cut 957 * After the GPU has been suspended, the handler needs to be called to cut
948 * power to the GPU. Likewise it needs to reinstate power before the GPU 958 * power to the GPU. Likewise it needs to reinstate power before the GPU
949 * can resume. This is achieved by vga_switcheroo_init_domain_pm_ops(), 959 * can resume. This is achieved by vga_switcheroo_init_domain_pm_ops(),
@@ -951,8 +961,9 @@ EXPORT_SYMBOL(vga_switcheroo_process_delayed_switch);
951 * calls to the handler. 961 * calls to the handler.
952 * 962 *
953 * When the audio device resumes, the GPU needs to be woken. This is achieved 963 * When the audio device resumes, the GPU needs to be woken. This is achieved
954 * by vga_switcheroo_init_domain_pm_optimus_hdmi_audio(), which augments the 964 * by a PCI quirk which calls device_link_add() to declare a dependency on the
955 * audio device's resume function. 965 * GPU. That way, the GPU is kept awake whenever and as long as the audio
966 * device is in use.
956 * 967 *
957 * On muxed machines, if the mux is initially switched to the discrete GPU, 968 * On muxed machines, if the mux is initially switched to the discrete GPU,
958 * the user ends up with a black screen when the GPU powers down after boot. 969 * the user ends up with a black screen when the GPU powers down after boot.
@@ -978,35 +989,6 @@ static void vga_switcheroo_power_switch(struct pci_dev *pdev,
978 vgasr_priv.handler->power_state(client->id, state); 989 vgasr_priv.handler->power_state(client->id, state);
979} 990}
980 991
981/**
982 * vga_switcheroo_set_dynamic_switch() - helper for driver power control
983 * @pdev: client pci device
984 * @dynamic: new power state
985 *
986 * Helper for GPUs whose power state is controlled by the driver's runtime pm.
987 * When the driver decides to power up or down, it notifies vga_switcheroo
988 * thereof using this helper so that it can (a) power the audio device on
989 * the GPU up or down, and (b) update its internal power state representation
990 * for the device.
991 */
992void vga_switcheroo_set_dynamic_switch(struct pci_dev *pdev,
993 enum vga_switcheroo_state dynamic)
994{
995 struct vga_switcheroo_client *client;
996
997 mutex_lock(&vgasr_mutex);
998 client = find_client_from_pci(&vgasr_priv.clients, pdev);
999 if (!client || !client->driver_power_control) {
1000 mutex_unlock(&vgasr_mutex);
1001 return;
1002 }
1003
1004 client->pwr_state = dynamic;
1005 set_audio_state(client->id, dynamic);
1006 mutex_unlock(&vgasr_mutex);
1007}
1008EXPORT_SYMBOL(vga_switcheroo_set_dynamic_switch);
1009
1010/* switcheroo power domain */ 992/* switcheroo power domain */
1011static int vga_switcheroo_runtime_suspend(struct device *dev) 993static int vga_switcheroo_runtime_suspend(struct device *dev)
1012{ 994{
@@ -1022,6 +1004,7 @@ static int vga_switcheroo_runtime_suspend(struct device *dev)
1022 vgasr_priv.handler->switchto(VGA_SWITCHEROO_IGD); 1004 vgasr_priv.handler->switchto(VGA_SWITCHEROO_IGD);
1023 mutex_unlock(&vgasr_priv.mux_hw_lock); 1005 mutex_unlock(&vgasr_priv.mux_hw_lock);
1024 } 1006 }
1007 pci_bus_set_current_state(pdev->bus, PCI_D3cold);
1025 vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_OFF); 1008 vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_OFF);
1026 mutex_unlock(&vgasr_mutex); 1009 mutex_unlock(&vgasr_mutex);
1027 return 0; 1010 return 0;
@@ -1035,6 +1018,7 @@ static int vga_switcheroo_runtime_resume(struct device *dev)
1035 mutex_lock(&vgasr_mutex); 1018 mutex_lock(&vgasr_mutex);
1036 vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_ON); 1019 vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_ON);
1037 mutex_unlock(&vgasr_mutex); 1020 mutex_unlock(&vgasr_mutex);
1021 pci_wakeup_bus(pdev->bus);
1038 ret = dev->bus->pm->runtime_resume(dev); 1022 ret = dev->bus->pm->runtime_resume(dev);
1039 if (ret) 1023 if (ret)
1040 return ret; 1024 return ret;
@@ -1076,69 +1060,3 @@ void vga_switcheroo_fini_domain_pm_ops(struct device *dev)
1076 dev_pm_domain_set(dev, NULL); 1060 dev_pm_domain_set(dev, NULL);
1077} 1061}
1078EXPORT_SYMBOL(vga_switcheroo_fini_domain_pm_ops); 1062EXPORT_SYMBOL(vga_switcheroo_fini_domain_pm_ops);
1079
1080static int vga_switcheroo_runtime_resume_hdmi_audio(struct device *dev)
1081{
1082 struct pci_dev *pdev = to_pci_dev(dev);
1083 struct vga_switcheroo_client *client;
1084 struct device *video_dev = NULL;
1085 int ret;
1086
1087 /* we need to check if we have to switch back on the video
1088 * device so the audio device can come back
1089 */
1090 mutex_lock(&vgasr_mutex);
1091 list_for_each_entry(client, &vgasr_priv.clients, list) {
1092 if (PCI_SLOT(client->pdev->devfn) == PCI_SLOT(pdev->devfn) &&
1093 client_is_vga(client)) {
1094 video_dev = &client->pdev->dev;
1095 break;
1096 }
1097 }
1098 mutex_unlock(&vgasr_mutex);
1099
1100 if (video_dev) {
1101 ret = pm_runtime_get_sync(video_dev);
1102 if (ret && ret != 1)
1103 return ret;
1104 }
1105 ret = dev->bus->pm->runtime_resume(dev);
1106
1107 /* put the reference for the gpu */
1108 if (video_dev) {
1109 pm_runtime_mark_last_busy(video_dev);
1110 pm_runtime_put_autosuspend(video_dev);
1111 }
1112 return ret;
1113}
1114
1115/**
1116 * vga_switcheroo_init_domain_pm_optimus_hdmi_audio() - helper for driver
1117 * power control
1118 * @dev: audio client device
1119 * @domain: power domain
1120 *
1121 * Helper for GPUs whose power state is controlled by the driver's runtime pm.
1122 * When the audio device resumes, the GPU needs to be woken. This helper
1123 * augments the audio device's resume function to do that.
1124 *
1125 * Return: 0 on success, -EINVAL if no power management operations are
1126 * defined for this device.
1127 */
1128int
1129vga_switcheroo_init_domain_pm_optimus_hdmi_audio(struct device *dev,
1130 struct dev_pm_domain *domain)
1131{
1132 /* copy over all the bus versions */
1133 if (dev->bus && dev->bus->pm) {
1134 domain->ops = *dev->bus->pm;
1135 domain->ops.runtime_resume =
1136 vga_switcheroo_runtime_resume_hdmi_audio;
1137
1138 dev_pm_domain_set(dev, domain);
1139 return 0;
1140 }
1141 dev_pm_domain_set(dev, NULL);
1142 return -EINVAL;
1143}
1144EXPORT_SYMBOL(vga_switcheroo_init_domain_pm_optimus_hdmi_audio);
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 3bed6beda051..6a67cdbd0e6a 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -1224,11 +1224,14 @@ static int pci_pm_runtime_suspend(struct device *dev)
1224 int error; 1224 int error;
1225 1225
1226 /* 1226 /*
1227 * If pci_dev->driver is not set (unbound), the device should 1227 * If pci_dev->driver is not set (unbound), we leave the device in D0,
1228 * always remain in D0 regardless of the runtime PM status 1228 * but it may go to D3cold when the bridge above it runtime suspends.
1229 * Save its config space in case that happens.
1229 */ 1230 */
1230 if (!pci_dev->driver) 1231 if (!pci_dev->driver) {
1232 pci_save_state(pci_dev);
1231 return 0; 1233 return 0;
1234 }
1232 1235
1233 if (!pm || !pm->runtime_suspend) 1236 if (!pm || !pm->runtime_suspend)
1234 return -ENOSYS; 1237 return -ENOSYS;
@@ -1276,16 +1279,18 @@ static int pci_pm_runtime_resume(struct device *dev)
1276 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 1279 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
1277 1280
1278 /* 1281 /*
1279 * If pci_dev->driver is not set (unbound), the device should 1282 * Restoring config space is necessary even if the device is not bound
1280 * always remain in D0 regardless of the runtime PM status 1283 * to a driver because although we left it in D0, it may have gone to
1284 * D3cold when the bridge above it runtime suspended.
1281 */ 1285 */
1286 pci_restore_standard_config(pci_dev);
1287
1282 if (!pci_dev->driver) 1288 if (!pci_dev->driver)
1283 return 0; 1289 return 0;
1284 1290
1285 if (!pm || !pm->runtime_resume) 1291 if (!pm || !pm->runtime_resume)
1286 return -ENOSYS; 1292 return -ENOSYS;
1287 1293
1288 pci_restore_standard_config(pci_dev);
1289 pci_fixup_device(pci_fixup_resume_early, pci_dev); 1294 pci_fixup_device(pci_fixup_resume_early, pci_dev);
1290 pci_enable_wake(pci_dev, PCI_D0, false); 1295 pci_enable_wake(pci_dev, PCI_D0, false);
1291 pci_fixup_device(pci_fixup_resume, pci_dev); 1296 pci_fixup_device(pci_fixup_resume, pci_dev);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index f6a4dd10d9b0..bd6f156dc3cf 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -800,7 +800,7 @@ static int pci_wakeup(struct pci_dev *pci_dev, void *ign)
800 * pci_wakeup_bus - Walk given bus and wake up devices on it 800 * pci_wakeup_bus - Walk given bus and wake up devices on it
801 * @bus: Top bus of the subtree to walk. 801 * @bus: Top bus of the subtree to walk.
802 */ 802 */
803static void pci_wakeup_bus(struct pci_bus *bus) 803void pci_wakeup_bus(struct pci_bus *bus)
804{ 804{
805 if (bus) 805 if (bus)
806 pci_walk_bus(bus, pci_wakeup, NULL); 806 pci_walk_bus(bus, pci_wakeup, NULL);
@@ -850,11 +850,11 @@ static int __pci_dev_set_current_state(struct pci_dev *dev, void *data)
850} 850}
851 851
852/** 852/**
853 * __pci_bus_set_current_state - Walk given bus and set current state of devices 853 * pci_bus_set_current_state - Walk given bus and set current state of devices
854 * @bus: Top bus of the subtree to walk. 854 * @bus: Top bus of the subtree to walk.
855 * @state: state to be set 855 * @state: state to be set
856 */ 856 */
857static void __pci_bus_set_current_state(struct pci_bus *bus, pci_power_t state) 857void pci_bus_set_current_state(struct pci_bus *bus, pci_power_t state)
858{ 858{
859 if (bus) 859 if (bus)
860 pci_walk_bus(bus, __pci_dev_set_current_state, &state); 860 pci_walk_bus(bus, __pci_dev_set_current_state, &state);
@@ -876,7 +876,7 @@ int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state)
876 ret = pci_platform_power_transition(dev, state); 876 ret = pci_platform_power_transition(dev, state);
877 /* Power off the bridge may power off the whole hierarchy */ 877 /* Power off the bridge may power off the whole hierarchy */
878 if (!ret && state == PCI_D3cold) 878 if (!ret && state == PCI_D3cold)
879 __pci_bus_set_current_state(dev->subordinate, PCI_D3cold); 879 pci_bus_set_current_state(dev->subordinate, PCI_D3cold);
880 return ret; 880 return ret;
881} 881}
882EXPORT_SYMBOL_GPL(__pci_complete_power_transition); 882EXPORT_SYMBOL_GPL(__pci_complete_power_transition);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index fc734014206f..ec582d37c189 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -26,6 +26,7 @@
26#include <linux/ktime.h> 26#include <linux/ktime.h>
27#include <linux/mm.h> 27#include <linux/mm.h>
28#include <linux/platform_data/x86/apple.h> 28#include <linux/platform_data/x86/apple.h>
29#include <linux/pm_runtime.h>
29#include <asm/dma.h> /* isa_dma_bridge_buggy */ 30#include <asm/dma.h> /* isa_dma_bridge_buggy */
30#include "pci.h" 31#include "pci.h"
31 32
@@ -4832,3 +4833,41 @@ static void quirk_fsl_no_msi(struct pci_dev *pdev)
4832 pdev->no_msi = 1; 4833 pdev->no_msi = 1;
4833} 4834}
4834DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, quirk_fsl_no_msi); 4835DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, quirk_fsl_no_msi);
4836
4837/*
4838 * GPUs with integrated HDA controller for streaming audio to attached displays
4839 * need a device link from the HDA controller (consumer) to the GPU (supplier)
4840 * so that the GPU is powered up whenever the HDA controller is accessed.
4841 * The GPU and HDA controller are functions 0 and 1 of the same PCI device.
4842 * The device link stays in place until shutdown (or removal of the PCI device
4843 * if it's hotplugged). Runtime PM is allowed by default on the HDA controller
4844 * to prevent it from permanently keeping the GPU awake.
4845 */
4846static void quirk_gpu_hda(struct pci_dev *hda)
4847{
4848 struct pci_dev *gpu;
4849
4850 if (PCI_FUNC(hda->devfn) != 1)
4851 return;
4852
4853 gpu = pci_get_domain_bus_and_slot(pci_domain_nr(hda->bus),
4854 hda->bus->number,
4855 PCI_DEVFN(PCI_SLOT(hda->devfn), 0));
4856 if (!gpu || (gpu->class >> 16) != PCI_BASE_CLASS_DISPLAY) {
4857 pci_dev_put(gpu);
4858 return;
4859 }
4860
4861 if (!device_link_add(&hda->dev, &gpu->dev,
4862 DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME))
4863 pci_err(hda, "cannot link HDA to GPU %s\n", pci_name(gpu));
4864
4865 pm_runtime_allow(&hda->dev);
4866 pci_dev_put(gpu);
4867}
4868DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_ATI, PCI_ANY_ID,
4869 PCI_CLASS_MULTIMEDIA_HD_AUDIO, 8, quirk_gpu_hda);
4870DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_AMD, PCI_ANY_ID,
4871 PCI_CLASS_MULTIMEDIA_HD_AUDIO, 8, quirk_gpu_hda);
4872DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
4873 PCI_CLASS_MULTIMEDIA_HD_AUDIO, 8, quirk_gpu_hda);