aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2018-03-13 20:59:16 -0400
committerDave Airlie <airlied@redhat.com>2018-03-13 20:59:16 -0400
commit0b8eeac5c6ca6dcb19cce04bf8910006ac73dbd3 (patch)
treeb883a42fa60a1a092bf4649051dbc4e3ba9677a2
parent62ccb6533920ce6e8a18ef7c5ee3f98783a1a42a (diff)
parent60beeccc72cabefcb8874fec542b3142e262b6c2 (diff)
Merge tag 'drm-misc-next-2018-03-09-3' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for 4.17: UAPI Changes: plane: Add color encoding/range properties (Jyri) nouveau: Replace iturbt_709 property with color_encoding property (Ville) Core Changes: atomic: Move plane clipping into plane check helper (Ville) property: Multiple new property checks/verification (Ville) Driver Changes: rockchip: Fixes & improvements for rk3399/chromebook plus (various) sun4i: Add H3/H5 HDMI support (Jernej) i915: Add support for limited/full-range ycbcr toggling (Ville) pl111: Add bandwidth checking/limiting (Linus) Cc: Jernej Skrabec <jernej.skrabec@siol.net> Cc: Jyri Sarha <jsarha@ti.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Linus Walleij <linus.walleij@linaro.org> * tag 'drm-misc-next-2018-03-09-3' of git://anongit.freedesktop.org/drm/drm-misc: (85 commits) drm/rockchip: Don't use atomic constructs for psr drm/rockchip: analogix_dp: set psr activate/deactivate when enable/disable bridge drm/rockchip: dw_hdmi: Move HDMI vpll clock enable to bind() drm/rockchip: inno_hdmi: reorder clk_disable_unprepare call in unbind drm/rockchip: inno_hdmi: Fix error handling path. drm/rockchip: dw-mipi-dsi: Fix connector and encoder cleanup. drm/nouveau: Replace the iturbt_709 prop with the standard COLOR_ENCODING prop drm/pl111: Use max memory bandwidth for resolution drm/bridge: sii902x: Retry status read after DDI I2C drm/pl111: Handle the RealView variant separately drm/pl111: Make the default BPP a per-variant variable drm: simple_kms_helper: Fix .mode_valid() documentation bridge: Elaborate a bit on dumb VGA bridges in Kconfig drm/atomic: Add new reverse iterator over all plane state (V2) drm: Reject bad property flag combinations drm: Make property flags u32 drm/uapi: Deprecate DRM_MODE_PROP_PENDING drm: WARN when trying to add enum value > 63 to a bitmask property drm: WARN when trying add enum values to non-enum/bitmask properties drm: Reject replacing property enum values ...
-rw-r--r--Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt6
-rw-r--r--drivers/gpu/drm/arm/hdlcd_crtc.c7
-rw-r--r--drivers/gpu/drm/arm/malidp_planes.c7
-rw-r--r--drivers/gpu/drm/armada/armada_crtc.c9
-rw-r--r--drivers/gpu/drm/armada/armada_overlay.c9
-rw-r--r--drivers/gpu/drm/bridge/Kconfig3
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix_dp_core.c97
-rw-r--r--drivers/gpu/drm/bridge/sii902x.c20
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi.c3
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c10
-rw-r--r--drivers/gpu/drm/drm_atomic.c22
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c12
-rw-r--r--drivers/gpu/drm/drm_color_mgmt.c133
-rw-r--r--drivers/gpu/drm/drm_crtc.c10
-rw-r--r--drivers/gpu/drm/drm_crtc_internal.h6
-rw-r--r--drivers/gpu/drm/drm_drv.c2
-rw-r--r--drivers/gpu/drm/drm_memory.c2
-rw-r--r--drivers/gpu/drm/drm_mm.c9
-rw-r--r--drivers/gpu/drm/drm_modeset_lock.c1
-rw-r--r--drivers/gpu/drm/drm_of.c8
-rw-r--r--drivers/gpu/drm/drm_panel_orientation_quirks.c1
-rw-r--r--drivers/gpu/drm/drm_plane.c33
-rw-r--r--drivers/gpu/drm/drm_plane_helper.c11
-rw-r--r--drivers/gpu/drm/drm_prime.c52
-rw-r--r--drivers/gpu/drm/drm_property.c101
-rw-r--r--drivers/gpu/drm/drm_simple_kms_helper.c34
-rw-r--r--drivers/gpu/drm/drm_vblank.c9
-rw-r--r--drivers/gpu/drm/exynos/exynos_dp.c30
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h24
-rw-r--r--drivers/gpu/drm/i915/intel_display.c45
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h2
-rw-r--r--drivers/gpu/drm/i915/intel_sprite.c134
-rw-r--r--drivers/gpu/drm/imx/ipuv3-plane.c7
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_plane.c7
-rw-r--r--drivers/gpu/drm/meson/meson_plane.c7
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c14
-rw-r--r--drivers/gpu/drm/mxsfb/mxsfb_drv.c54
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/overlay.c26
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c12
-rw-r--r--drivers/gpu/drm/panel/panel-arm-versatile.c8
-rw-r--r--drivers/gpu/drm/pl111/Kconfig1
-rw-r--r--drivers/gpu/drm/pl111/pl111_display.c51
-rw-r--r--drivers/gpu/drm/pl111/pl111_drm.h5
-rw-r--r--drivers/gpu/drm/pl111/pl111_drv.c15
-rw-r--r--drivers/gpu/drm/pl111/pl111_versatile.c32
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_plane.c7
-rw-r--r--drivers/gpu/drm/rockchip/analogix_dp-rockchip.c74
-rw-r--r--drivers/gpu/drm/rockchip/dw-mipi-dsi.c8
-rw-r--r--drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c17
-rw-r--r--drivers/gpu/drm/rockchip/inno_hdmi.c22
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_drv.c25
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_drv.h2
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_psr.c92
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_psr.h4
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop.c16
-rw-r--r--drivers/gpu/drm/stm/drv.c2
-rw-r--r--drivers/gpu/drm/sun4i/Kconfig2
-rw-r--r--drivers/gpu/drm/sun4i/Makefile1
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_backend.c52
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_drv.c1
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_layer.c55
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_layer.h1
-rw-r--r--drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h157
-rw-r--r--drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c369
-rw-r--r--drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c132
-rw-r--r--drivers/gpu/drm/sun4i/sun8i_mixer.c12
-rw-r--r--drivers/gpu/drm/sun4i/sun8i_ui_layer.c7
-rw-r--r--drivers/gpu/drm/sun4i/sun8i_vi_layer.c7
-rw-r--r--drivers/gpu/drm/tegra/plane.c7
-rw-r--r--drivers/gpu/drm/tinydrm/Kconfig2
-rw-r--r--drivers/gpu/drm/tve200/tve200_display.c10
-rw-r--r--drivers/gpu/drm/tve200/tve200_drm.h2
-rw-r--r--drivers/gpu/drm/tve200/tve200_drv.c3
-rw-r--r--drivers/gpu/drm/vc4/vc4_hdmi.c2
-rw-r--r--drivers/gpu/drm/vc4/vc4_kms.c1
-rw-r--r--drivers/gpu/drm/vc4/vc4_plane.c34
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_display.c7
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_drv.c2
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_drv.h8
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_fb.c6
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_gem.c1
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_ioctl.c23
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_prime.c4
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_ttm.c4
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_vq.c13
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c7
-rw-r--r--drivers/gpu/drm/zte/zx_plane.c13
-rw-r--r--include/drm/bridge/analogix_dp.h20
-rw-r--r--include/drm/drm_atomic.h22
-rw-r--r--include/drm/drm_atomic_helper.h1
-rw-r--r--include/drm/drm_color_mgmt.h19
-rw-r--r--include/drm/drm_plane.h32
-rw-r--r--include/drm/drm_plane_helper.h1
-rw-r--r--include/drm/drm_property.h24
-rw-r--r--include/drm/drm_simple_kms_helper.h45
-rw-r--r--include/uapi/drm/drm_mode.h9
96 files changed, 1800 insertions, 678 deletions
diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
index b995bfee734a..8bdef4920edc 100644
--- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
+++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
@@ -102,6 +102,7 @@ DWC HDMI PHY
102Required properties: 102Required properties:
103 - compatible: value must be one of: 103 - compatible: value must be one of:
104 * allwinner,sun8i-a83t-hdmi-phy 104 * allwinner,sun8i-a83t-hdmi-phy
105 * allwinner,sun8i-h3-hdmi-phy
105 - reg: base address and size of memory-mapped region 106 - reg: base address and size of memory-mapped region
106 - clocks: phandles to the clocks feeding the HDMI PHY 107 - clocks: phandles to the clocks feeding the HDMI PHY
107 * bus: the HDMI PHY interface clock 108 * bus: the HDMI PHY interface clock
@@ -110,6 +111,9 @@ Required properties:
110 - resets: phandle to the reset controller driving the PHY 111 - resets: phandle to the reset controller driving the PHY
111 - reset-names: must be "phy" 112 - reset-names: must be "phy"
112 113
114H3 HDMI PHY requires additional clock:
115 - pll-0: parent of phy clock
116
113TV Encoder 117TV Encoder
114---------- 118----------
115 119
@@ -275,6 +279,7 @@ Required properties:
275 - compatible: value must be one of: 279 - compatible: value must be one of:
276 * allwinner,sun8i-a83t-de2-mixer-0 280 * allwinner,sun8i-a83t-de2-mixer-0
277 * allwinner,sun8i-a83t-de2-mixer-1 281 * allwinner,sun8i-a83t-de2-mixer-1
282 * allwinner,sun8i-h3-de2-mixer-0
278 * allwinner,sun8i-v3s-de2-mixer 283 * allwinner,sun8i-v3s-de2-mixer
279 - reg: base address and size of the memory-mapped region. 284 - reg: base address and size of the memory-mapped region.
280 - clocks: phandles to the clocks feeding the mixer 285 - clocks: phandles to the clocks feeding the mixer
@@ -305,6 +310,7 @@ Required properties:
305 * allwinner,sun7i-a20-display-engine 310 * allwinner,sun7i-a20-display-engine
306 * allwinner,sun8i-a33-display-engine 311 * allwinner,sun8i-a33-display-engine
307 * allwinner,sun8i-a83t-display-engine 312 * allwinner,sun8i-a83t-display-engine
313 * allwinner,sun8i-h3-display-engine
308 * allwinner,sun8i-v3s-display-engine 314 * allwinner,sun8i-v3s-display-engine
309 315
310 - allwinner,pipelines: list of phandle to the display engine 316 - allwinner,pipelines: list of phandle to the display engine
diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
index 877647ef35a9..cf5cbd63ecdf 100644
--- a/drivers/gpu/drm/arm/hdlcd_crtc.c
+++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
@@ -229,7 +229,6 @@ static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = {
229static int hdlcd_plane_atomic_check(struct drm_plane *plane, 229static int hdlcd_plane_atomic_check(struct drm_plane *plane,
230 struct drm_plane_state *state) 230 struct drm_plane_state *state)
231{ 231{
232 struct drm_rect clip = { 0 };
233 struct drm_crtc_state *crtc_state; 232 struct drm_crtc_state *crtc_state;
234 u32 src_h = state->src_h >> 16; 233 u32 src_h = state->src_h >> 16;
235 234
@@ -249,11 +248,7 @@ static int hdlcd_plane_atomic_check(struct drm_plane *plane,
249 return -EINVAL; 248 return -EINVAL;
250 } 249 }
251 250
252 if (crtc_state->enable) 251 return drm_atomic_helper_check_plane_state(state, crtc_state,
253 drm_mode_get_hv_timing(&crtc_state->mode,
254 &clip.x2, &clip.y2);
255
256 return drm_atomic_helper_check_plane_state(state, crtc_state, &clip,
257 DRM_PLANE_HELPER_NO_SCALING, 252 DRM_PLANE_HELPER_NO_SCALING,
258 DRM_PLANE_HELPER_NO_SCALING, 253 DRM_PLANE_HELPER_NO_SCALING,
259 false, true); 254 false, true);
diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c
index 2885d69af456..ee32361c87ac 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -141,18 +141,13 @@ static int malidp_se_check_scaling(struct malidp_plane *mp,
141 struct drm_crtc_state *crtc_state = 141 struct drm_crtc_state *crtc_state =
142 drm_atomic_get_existing_crtc_state(state->state, state->crtc); 142 drm_atomic_get_existing_crtc_state(state->state, state->crtc);
143 struct malidp_crtc_state *mc; 143 struct malidp_crtc_state *mc;
144 struct drm_rect clip = { 0 };
145 u32 src_w, src_h; 144 u32 src_w, src_h;
146 int ret; 145 int ret;
147 146
148 if (!crtc_state) 147 if (!crtc_state)
149 return -EINVAL; 148 return -EINVAL;
150 149
151 if (crtc_state->enable) 150 ret = drm_atomic_helper_check_plane_state(state, crtc_state,
152 drm_mode_get_hv_timing(&crtc_state->mode,
153 &clip.x2, &clip.y2);
154
155 ret = drm_atomic_helper_check_plane_state(state, crtc_state, &clip,
156 0, INT_MAX, true, true); 151 0, INT_MAX, true, true);
157 if (ret) 152 if (ret)
158 return ret; 153 return ret;
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index e2adfbef7d6b..03eeee11dd5b 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -1200,13 +1200,14 @@ static int armada_drm_primary_update(struct drm_plane *plane,
1200 .crtc_h = crtc_h, 1200 .crtc_h = crtc_h,
1201 .rotation = DRM_MODE_ROTATE_0, 1201 .rotation = DRM_MODE_ROTATE_0,
1202 }; 1202 };
1203 const struct drm_rect clip = { 1203 struct drm_crtc_state crtc_state = {
1204 .x2 = crtc->mode.hdisplay, 1204 .crtc = crtc,
1205 .y2 = crtc->mode.vdisplay, 1205 .enable = crtc->enabled,
1206 .mode = crtc->mode,
1206 }; 1207 };
1207 int ret; 1208 int ret;
1208 1209
1209 ret = drm_atomic_helper_check_plane_state(&state, crtc->state, &clip, 0, 1210 ret = drm_atomic_helper_check_plane_state(&state, &crtc_state, 0,
1210 INT_MAX, true, false); 1211 INT_MAX, true, false);
1211 if (ret) 1212 if (ret)
1212 return ret; 1213 return ret;
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index 77b55adaa2ac..c391955009d6 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -205,9 +205,10 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
205 .crtc_h = crtc_h, 205 .crtc_h = crtc_h,
206 .rotation = DRM_MODE_ROTATE_0, 206 .rotation = DRM_MODE_ROTATE_0,
207 }; 207 };
208 const struct drm_rect clip = { 208 struct drm_crtc_state crtc_state = {
209 .x2 = crtc->mode.hdisplay, 209 .crtc = crtc,
210 .y2 = crtc->mode.vdisplay, 210 .enable = crtc->enabled,
211 .mode = crtc->mode,
211 }; 212 };
212 int ret; 213 int ret;
213 214
@@ -215,7 +216,7 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
215 crtc_x, crtc_y, crtc_w, crtc_h, 216 crtc_x, crtc_y, crtc_w, crtc_h,
216 src_x, src_y, src_w, src_h); 217 src_x, src_y, src_w, src_h);
217 218
218 ret = drm_atomic_helper_check_plane_state(&state, crtc->state, &clip, 0, 219 ret = drm_atomic_helper_check_plane_state(&state, &crtc_state, 0,
219 INT_MAX, true, false); 220 INT_MAX, true, false);
220 if (ret) 221 if (ret)
221 return ret; 222 return ret;
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 3b99d5a06c16..3aa65bdecb0e 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -30,7 +30,8 @@ config DRM_DUMB_VGA_DAC
30 depends on OF 30 depends on OF
31 select DRM_KMS_HELPER 31 select DRM_KMS_HELPER
32 help 32 help
33 Support for RGB to VGA DAC based bridges 33 Support for non-programmable RGB to VGA DAC bridges, such as ADI
34 ADV7123, TI THS8134 and THS8135 or passive resistor ladder DACs.
34 35
35config DRM_LVDS_ENCODER 36config DRM_LVDS_ENCODER
36 tristate "Transparent parallel to LVDS encoder support" 37 tristate "Transparent parallel to LVDS encoder support"
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index b2756bc4225a..a693ab3078f0 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -98,17 +98,15 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp)
98 return 0; 98 return 0;
99} 99}
100 100
101int analogix_dp_psr_supported(struct device *dev) 101int analogix_dp_psr_supported(struct analogix_dp_device *dp)
102{ 102{
103 struct analogix_dp_device *dp = dev_get_drvdata(dev);
104 103
105 return dp->psr_support; 104 return dp->psr_support;
106} 105}
107EXPORT_SYMBOL_GPL(analogix_dp_psr_supported); 106EXPORT_SYMBOL_GPL(analogix_dp_psr_supported);
108 107
109int analogix_dp_enable_psr(struct device *dev) 108int analogix_dp_enable_psr(struct analogix_dp_device *dp)
110{ 109{
111 struct analogix_dp_device *dp = dev_get_drvdata(dev);
112 struct edp_vsc_psr psr_vsc; 110 struct edp_vsc_psr psr_vsc;
113 111
114 if (!dp->psr_support) 112 if (!dp->psr_support)
@@ -129,9 +127,8 @@ int analogix_dp_enable_psr(struct device *dev)
129} 127}
130EXPORT_SYMBOL_GPL(analogix_dp_enable_psr); 128EXPORT_SYMBOL_GPL(analogix_dp_enable_psr);
131 129
132int analogix_dp_disable_psr(struct device *dev) 130int analogix_dp_disable_psr(struct analogix_dp_device *dp)
133{ 131{
134 struct analogix_dp_device *dp = dev_get_drvdata(dev);
135 struct edp_vsc_psr psr_vsc; 132 struct edp_vsc_psr psr_vsc;
136 int ret; 133 int ret;
137 134
@@ -1015,27 +1012,30 @@ static int analogix_dp_bridge_attach(struct drm_bridge *bridge)
1015{ 1012{
1016 struct analogix_dp_device *dp = bridge->driver_private; 1013 struct analogix_dp_device *dp = bridge->driver_private;
1017 struct drm_encoder *encoder = dp->encoder; 1014 struct drm_encoder *encoder = dp->encoder;
1018 struct drm_connector *connector = &dp->connector; 1015 struct drm_connector *connector = NULL;
1019 int ret; 1016 int ret = 0;
1020 1017
1021 if (!bridge->encoder) { 1018 if (!bridge->encoder) {
1022 DRM_ERROR("Parent encoder object not found"); 1019 DRM_ERROR("Parent encoder object not found");
1023 return -ENODEV; 1020 return -ENODEV;
1024 } 1021 }
1025 1022
1026 connector->polled = DRM_CONNECTOR_POLL_HPD; 1023 if (!dp->plat_data->skip_connector) {
1024 connector = &dp->connector;
1025 connector->polled = DRM_CONNECTOR_POLL_HPD;
1027 1026
1028 ret = drm_connector_init(dp->drm_dev, connector, 1027 ret = drm_connector_init(dp->drm_dev, connector,
1029 &analogix_dp_connector_funcs, 1028 &analogix_dp_connector_funcs,
1030 DRM_MODE_CONNECTOR_eDP); 1029 DRM_MODE_CONNECTOR_eDP);
1031 if (ret) { 1030 if (ret) {
1032 DRM_ERROR("Failed to initialize connector with drm\n"); 1031 DRM_ERROR("Failed to initialize connector with drm\n");
1033 return ret; 1032 return ret;
1034 } 1033 }
1035 1034
1036 drm_connector_helper_add(connector, 1035 drm_connector_helper_add(connector,
1037 &analogix_dp_connector_helper_funcs); 1036 &analogix_dp_connector_helper_funcs);
1038 drm_mode_connector_attach_encoder(connector, encoder); 1037 drm_mode_connector_attach_encoder(connector, encoder);
1038 }
1039 1039
1040 /* 1040 /*
1041 * NOTE: the connector registration is implemented in analogix 1041 * NOTE: the connector registration is implemented in analogix
@@ -1279,8 +1279,9 @@ static ssize_t analogix_dpaux_transfer(struct drm_dp_aux *aux,
1279 return analogix_dp_transfer(dp, msg); 1279 return analogix_dp_transfer(dp, msg);
1280} 1280}
1281 1281
1282int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, 1282struct analogix_dp_device *
1283 struct analogix_dp_plat_data *plat_data) 1283analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
1284 struct analogix_dp_plat_data *plat_data)
1284{ 1285{
1285 struct platform_device *pdev = to_platform_device(dev); 1286 struct platform_device *pdev = to_platform_device(dev);
1286 struct analogix_dp_device *dp; 1287 struct analogix_dp_device *dp;
@@ -1290,14 +1291,12 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
1290 1291
1291 if (!plat_data) { 1292 if (!plat_data) {
1292 dev_err(dev, "Invalided input plat_data\n"); 1293 dev_err(dev, "Invalided input plat_data\n");
1293 return -EINVAL; 1294 return ERR_PTR(-EINVAL);
1294 } 1295 }
1295 1296
1296 dp = devm_kzalloc(dev, sizeof(struct analogix_dp_device), GFP_KERNEL); 1297 dp = devm_kzalloc(dev, sizeof(struct analogix_dp_device), GFP_KERNEL);
1297 if (!dp) 1298 if (!dp)
1298 return -ENOMEM; 1299 return ERR_PTR(-ENOMEM);
1299
1300 dev_set_drvdata(dev, dp);
1301 1300
1302 dp->dev = &pdev->dev; 1301 dp->dev = &pdev->dev;
1303 dp->dpms_mode = DRM_MODE_DPMS_OFF; 1302 dp->dpms_mode = DRM_MODE_DPMS_OFF;
@@ -1314,7 +1313,7 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
1314 1313
1315 ret = analogix_dp_dt_parse_pdata(dp); 1314 ret = analogix_dp_dt_parse_pdata(dp);
1316 if (ret) 1315 if (ret)
1317 return ret; 1316 return ERR_PTR(ret);
1318 1317
1319 dp->phy = devm_phy_get(dp->dev, "dp"); 1318 dp->phy = devm_phy_get(dp->dev, "dp");
1320 if (IS_ERR(dp->phy)) { 1319 if (IS_ERR(dp->phy)) {
@@ -1328,14 +1327,14 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
1328 if (ret == -ENOSYS || ret == -ENODEV) 1327 if (ret == -ENOSYS || ret == -ENODEV)
1329 dp->phy = NULL; 1328 dp->phy = NULL;
1330 else 1329 else
1331 return ret; 1330 return ERR_PTR(ret);
1332 } 1331 }
1333 } 1332 }
1334 1333
1335 dp->clock = devm_clk_get(&pdev->dev, "dp"); 1334 dp->clock = devm_clk_get(&pdev->dev, "dp");
1336 if (IS_ERR(dp->clock)) { 1335 if (IS_ERR(dp->clock)) {
1337 dev_err(&pdev->dev, "failed to get clock\n"); 1336 dev_err(&pdev->dev, "failed to get clock\n");
1338 return PTR_ERR(dp->clock); 1337 return ERR_CAST(dp->clock);
1339 } 1338 }
1340 1339
1341 clk_prepare_enable(dp->clock); 1340 clk_prepare_enable(dp->clock);
@@ -1344,7 +1343,7 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
1344 1343
1345 dp->reg_base = devm_ioremap_resource(&pdev->dev, res); 1344 dp->reg_base = devm_ioremap_resource(&pdev->dev, res);
1346 if (IS_ERR(dp->reg_base)) 1345 if (IS_ERR(dp->reg_base))
1347 return PTR_ERR(dp->reg_base); 1346 return ERR_CAST(dp->reg_base);
1348 1347
1349 dp->force_hpd = of_property_read_bool(dev->of_node, "force-hpd"); 1348 dp->force_hpd = of_property_read_bool(dev->of_node, "force-hpd");
1350 1349
@@ -1365,7 +1364,7 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
1365 "hpd_gpio"); 1364 "hpd_gpio");
1366 if (ret) { 1365 if (ret) {
1367 dev_err(&pdev->dev, "failed to get hpd gpio\n"); 1366 dev_err(&pdev->dev, "failed to get hpd gpio\n");
1368 return ret; 1367 return ERR_PTR(ret);
1369 } 1368 }
1370 dp->irq = gpio_to_irq(dp->hpd_gpio); 1369 dp->irq = gpio_to_irq(dp->hpd_gpio);
1371 irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; 1370 irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
@@ -1377,16 +1376,9 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
1377 1376
1378 if (dp->irq == -ENXIO) { 1377 if (dp->irq == -ENXIO) {
1379 dev_err(&pdev->dev, "failed to get irq\n"); 1378 dev_err(&pdev->dev, "failed to get irq\n");
1380 return -ENODEV; 1379 return ERR_PTR(-ENODEV);
1381 } 1380 }
1382 1381
1383 pm_runtime_enable(dev);
1384
1385 pm_runtime_get_sync(dev);
1386 phy_power_on(dp->phy);
1387
1388 analogix_dp_init_dp(dp);
1389
1390 ret = devm_request_threaded_irq(&pdev->dev, dp->irq, 1382 ret = devm_request_threaded_irq(&pdev->dev, dp->irq,
1391 analogix_dp_hardirq, 1383 analogix_dp_hardirq,
1392 analogix_dp_irq_thread, 1384 analogix_dp_irq_thread,
@@ -1406,38 +1398,30 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
1406 1398
1407 ret = drm_dp_aux_register(&dp->aux); 1399 ret = drm_dp_aux_register(&dp->aux);
1408 if (ret) 1400 if (ret)
1409 goto err_disable_pm_runtime; 1401 return ERR_PTR(ret);
1402
1403 pm_runtime_enable(dev);
1410 1404
1411 ret = analogix_dp_create_bridge(drm_dev, dp); 1405 ret = analogix_dp_create_bridge(drm_dev, dp);
1412 if (ret) { 1406 if (ret) {
1413 DRM_ERROR("failed to create bridge (%d)\n", ret); 1407 DRM_ERROR("failed to create bridge (%d)\n", ret);
1414 drm_encoder_cleanup(dp->encoder);
1415 goto err_disable_pm_runtime; 1408 goto err_disable_pm_runtime;
1416 } 1409 }
1417 1410
1418 phy_power_off(dp->phy); 1411 return dp;
1419 pm_runtime_put(dev);
1420
1421 return 0;
1422 1412
1423err_disable_pm_runtime: 1413err_disable_pm_runtime:
1424 1414
1425 phy_power_off(dp->phy);
1426 pm_runtime_put(dev);
1427 pm_runtime_disable(dev); 1415 pm_runtime_disable(dev);
1428 1416
1429 return ret; 1417 return ERR_PTR(ret);
1430} 1418}
1431EXPORT_SYMBOL_GPL(analogix_dp_bind); 1419EXPORT_SYMBOL_GPL(analogix_dp_bind);
1432 1420
1433void analogix_dp_unbind(struct device *dev, struct device *master, 1421void analogix_dp_unbind(struct analogix_dp_device *dp)
1434 void *data)
1435{ 1422{
1436 struct analogix_dp_device *dp = dev_get_drvdata(dev);
1437
1438 analogix_dp_bridge_disable(dp->bridge); 1423 analogix_dp_bridge_disable(dp->bridge);
1439 dp->connector.funcs->destroy(&dp->connector); 1424 dp->connector.funcs->destroy(&dp->connector);
1440 dp->encoder->funcs->destroy(dp->encoder);
1441 1425
1442 if (dp->plat_data->panel) { 1426 if (dp->plat_data->panel) {
1443 if (drm_panel_unprepare(dp->plat_data->panel)) 1427 if (drm_panel_unprepare(dp->plat_data->panel))
@@ -1447,16 +1431,14 @@ void analogix_dp_unbind(struct device *dev, struct device *master,
1447 } 1431 }
1448 1432
1449 drm_dp_aux_unregister(&dp->aux); 1433 drm_dp_aux_unregister(&dp->aux);
1450 pm_runtime_disable(dev); 1434 pm_runtime_disable(dp->dev);
1451 clk_disable_unprepare(dp->clock); 1435 clk_disable_unprepare(dp->clock);
1452} 1436}
1453EXPORT_SYMBOL_GPL(analogix_dp_unbind); 1437EXPORT_SYMBOL_GPL(analogix_dp_unbind);
1454 1438
1455#ifdef CONFIG_PM 1439#ifdef CONFIG_PM
1456int analogix_dp_suspend(struct device *dev) 1440int analogix_dp_suspend(struct analogix_dp_device *dp)
1457{ 1441{
1458 struct analogix_dp_device *dp = dev_get_drvdata(dev);
1459
1460 clk_disable_unprepare(dp->clock); 1442 clk_disable_unprepare(dp->clock);
1461 1443
1462 if (dp->plat_data->panel) { 1444 if (dp->plat_data->panel) {
@@ -1468,9 +1450,8 @@ int analogix_dp_suspend(struct device *dev)
1468} 1450}
1469EXPORT_SYMBOL_GPL(analogix_dp_suspend); 1451EXPORT_SYMBOL_GPL(analogix_dp_suspend);
1470 1452
1471int analogix_dp_resume(struct device *dev) 1453int analogix_dp_resume(struct analogix_dp_device *dp)
1472{ 1454{
1473 struct analogix_dp_device *dp = dev_get_drvdata(dev);
1474 int ret; 1455 int ret;
1475 1456
1476 ret = clk_prepare_enable(dp->clock); 1457 ret = clk_prepare_enable(dp->clock);
diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c
index b1ab4ab09532..60373d7eb220 100644
--- a/drivers/gpu/drm/bridge/sii902x.c
+++ b/drivers/gpu/drm/bridge/sii902x.c
@@ -137,7 +137,9 @@ static int sii902x_get_modes(struct drm_connector *connector)
137 struct sii902x *sii902x = connector_to_sii902x(connector); 137 struct sii902x *sii902x = connector_to_sii902x(connector);
138 struct regmap *regmap = sii902x->regmap; 138 struct regmap *regmap = sii902x->regmap;
139 u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24; 139 u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
140 struct device *dev = &sii902x->i2c->dev;
140 unsigned long timeout; 141 unsigned long timeout;
142 unsigned int retries;
141 unsigned int status; 143 unsigned int status;
142 struct edid *edid; 144 struct edid *edid;
143 int num = 0; 145 int num = 0;
@@ -159,7 +161,7 @@ static int sii902x_get_modes(struct drm_connector *connector)
159 time_before(jiffies, timeout)); 161 time_before(jiffies, timeout));
160 162
161 if (!(status & SII902X_SYS_CTRL_DDC_BUS_GRTD)) { 163 if (!(status & SII902X_SYS_CTRL_DDC_BUS_GRTD)) {
162 dev_err(&sii902x->i2c->dev, "failed to acquire the i2c bus\n"); 164 dev_err(dev, "failed to acquire the i2c bus\n");
163 return -ETIMEDOUT; 165 return -ETIMEDOUT;
164 } 166 }
165 167
@@ -179,9 +181,19 @@ static int sii902x_get_modes(struct drm_connector *connector)
179 if (ret) 181 if (ret)
180 return ret; 182 return ret;
181 183
182 ret = regmap_read(regmap, SII902X_SYS_CTRL_DATA, &status); 184 /*
185 * Sometimes the I2C bus can stall after failure to use the
186 * EDID channel. Retry a few times to see if things clear
187 * up, else continue anyway.
188 */
189 retries = 5;
190 do {
191 ret = regmap_read(regmap, SII902X_SYS_CTRL_DATA,
192 &status);
193 retries--;
194 } while (ret && retries);
183 if (ret) 195 if (ret)
184 return ret; 196 dev_err(dev, "failed to read status (%d)\n", ret);
185 197
186 ret = regmap_update_bits(regmap, SII902X_SYS_CTRL_DATA, 198 ret = regmap_update_bits(regmap, SII902X_SYS_CTRL_DATA,
187 SII902X_SYS_CTRL_DDC_BUS_REQ | 199 SII902X_SYS_CTRL_DDC_BUS_REQ |
@@ -201,7 +213,7 @@ static int sii902x_get_modes(struct drm_connector *connector)
201 213
202 if (status & (SII902X_SYS_CTRL_DDC_BUS_REQ | 214 if (status & (SII902X_SYS_CTRL_DDC_BUS_REQ |
203 SII902X_SYS_CTRL_DDC_BUS_GRTD)) { 215 SII902X_SYS_CTRL_DDC_BUS_GRTD)) {
204 dev_err(&sii902x->i2c->dev, "failed to release the i2c bus\n"); 216 dev_err(dev, "failed to release the i2c bus\n");
205 return -ETIMEDOUT; 217 return -ETIMEDOUT;
206 } 218 }
207 219
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index f9802399cc0d..53ebbe2904b6 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1654,6 +1654,8 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
1654 * (v1.31a) and multiple Allwinner SoCs (v1.32a) have been identified 1654 * (v1.31a) and multiple Allwinner SoCs (v1.32a) have been identified
1655 * as needing the workaround, with 4 iterations for v1.30a and 1 1655 * as needing the workaround, with 4 iterations for v1.30a and 1
1656 * iteration for others. 1656 * iteration for others.
1657 * The Amlogic Meson GX SoCs (v2.01a) have been identified as needing
1658 * the workaround with a single iteration.
1657 */ 1659 */
1658 1660
1659 switch (hdmi->version) { 1661 switch (hdmi->version) {
@@ -1662,6 +1664,7 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
1662 break; 1664 break;
1663 case 0x131a: 1665 case 0x131a:
1664 case 0x132a: 1666 case 0x132a:
1667 case 0x201a:
1665 count = 1; 1668 count = 1;
1666 break; 1669 break;
1667 default: 1670 default:
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index 7bac101c285c..226171a3ece1 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -342,7 +342,7 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)
342 ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS, 342 ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
343 val, !(val & GEN_CMD_FULL), 1000, 343 val, !(val & GEN_CMD_FULL), 1000,
344 CMD_PKT_STATUS_TIMEOUT_US); 344 CMD_PKT_STATUS_TIMEOUT_US);
345 if (ret < 0) { 345 if (ret) {
346 dev_err(dsi->dev, "failed to get available command FIFO\n"); 346 dev_err(dsi->dev, "failed to get available command FIFO\n");
347 return ret; 347 return ret;
348 } 348 }
@@ -353,7 +353,7 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)
353 ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS, 353 ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
354 val, (val & mask) == mask, 354 val, (val & mask) == mask,
355 1000, CMD_PKT_STATUS_TIMEOUT_US); 355 1000, CMD_PKT_STATUS_TIMEOUT_US);
356 if (ret < 0) { 356 if (ret) {
357 dev_err(dsi->dev, "failed to write command FIFO\n"); 357 dev_err(dsi->dev, "failed to write command FIFO\n");
358 return ret; 358 return ret;
359 } 359 }
@@ -385,7 +385,7 @@ static int dw_mipi_dsi_write(struct dw_mipi_dsi *dsi,
385 ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS, 385 ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
386 val, !(val & GEN_PLD_W_FULL), 1000, 386 val, !(val & GEN_PLD_W_FULL), 1000,
387 CMD_PKT_STATUS_TIMEOUT_US); 387 CMD_PKT_STATUS_TIMEOUT_US);
388 if (ret < 0) { 388 if (ret) {
389 dev_err(dsi->dev, 389 dev_err(dsi->dev,
390 "failed to get available write payload FIFO\n"); 390 "failed to get available write payload FIFO\n");
391 return ret; 391 return ret;
@@ -721,13 +721,13 @@ static void dw_mipi_dsi_dphy_enable(struct dw_mipi_dsi *dsi)
721 721
722 ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS, val, 722 ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS, val,
723 val & PHY_LOCK, 1000, PHY_STATUS_TIMEOUT_US); 723 val & PHY_LOCK, 1000, PHY_STATUS_TIMEOUT_US);
724 if (ret < 0) 724 if (ret)
725 DRM_DEBUG_DRIVER("failed to wait phy lock state\n"); 725 DRM_DEBUG_DRIVER("failed to wait phy lock state\n");
726 726
727 ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS, 727 ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS,
728 val, val & PHY_STOP_STATE_CLK_LANE, 1000, 728 val, val & PHY_STOP_STATE_CLK_LANE, 1000,
729 PHY_STATUS_TIMEOUT_US); 729 PHY_STATUS_TIMEOUT_US);
730 if (ret < 0) 730 if (ret)
731 DRM_DEBUG_DRIVER("failed to wait phy clk lane stop state\n"); 731 DRM_DEBUG_DRIVER("failed to wait phy clk lane stop state\n");
732} 732}
733 733
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 46733d534587..34b7d420e555 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -759,6 +759,10 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
759 state->rotation = val; 759 state->rotation = val;
760 } else if (property == plane->zpos_property) { 760 } else if (property == plane->zpos_property) {
761 state->zpos = val; 761 state->zpos = val;
762 } else if (property == plane->color_encoding_property) {
763 state->color_encoding = val;
764 } else if (property == plane->color_range_property) {
765 state->color_range = val;
762 } else if (plane->funcs->atomic_set_property) { 766 } else if (plane->funcs->atomic_set_property) {
763 return plane->funcs->atomic_set_property(plane, state, 767 return plane->funcs->atomic_set_property(plane, state,
764 property, val); 768 property, val);
@@ -818,6 +822,10 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
818 *val = state->rotation; 822 *val = state->rotation;
819 } else if (property == plane->zpos_property) { 823 } else if (property == plane->zpos_property) {
820 *val = state->zpos; 824 *val = state->zpos;
825 } else if (property == plane->color_encoding_property) {
826 *val = state->color_encoding;
827 } else if (property == plane->color_range_property) {
828 *val = state->color_range;
821 } else if (plane->funcs->atomic_get_property) { 829 } else if (plane->funcs->atomic_get_property) {
822 return plane->funcs->atomic_get_property(plane, state, property, val); 830 return plane->funcs->atomic_get_property(plane, state, property, val);
823 } else { 831 } else {
@@ -882,12 +890,14 @@ static int drm_atomic_plane_check(struct drm_plane *plane,
882 } 890 }
883 891
884 /* Check whether this plane supports the fb pixel format. */ 892 /* Check whether this plane supports the fb pixel format. */
885 ret = drm_plane_check_pixel_format(plane, state->fb->format->format); 893 ret = drm_plane_check_pixel_format(plane, state->fb->format->format,
894 state->fb->modifier);
886 if (ret) { 895 if (ret) {
887 struct drm_format_name_buf format_name; 896 struct drm_format_name_buf format_name;
888 DRM_DEBUG_ATOMIC("Invalid pixel format %s\n", 897 DRM_DEBUG_ATOMIC("Invalid pixel format %s, modifier 0x%llx\n",
889 drm_get_format_name(state->fb->format->format, 898 drm_get_format_name(state->fb->format->format,
890 &format_name)); 899 &format_name),
900 state->fb->modifier);
891 return ret; 901 return ret;
892 } 902 }
893 903
@@ -944,6 +954,10 @@ static void drm_atomic_plane_print_state(struct drm_printer *p,
944 drm_printf(p, "\tcrtc-pos=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&dest)); 954 drm_printf(p, "\tcrtc-pos=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&dest));
945 drm_printf(p, "\tsrc-pos=" DRM_RECT_FP_FMT "\n", DRM_RECT_FP_ARG(&src)); 955 drm_printf(p, "\tsrc-pos=" DRM_RECT_FP_FMT "\n", DRM_RECT_FP_ARG(&src));
946 drm_printf(p, "\trotation=%x\n", state->rotation); 956 drm_printf(p, "\trotation=%x\n", state->rotation);
957 drm_printf(p, "\tcolor-encoding=%s\n",
958 drm_get_color_encoding_name(state->color_encoding));
959 drm_printf(p, "\tcolor-range=%s\n",
960 drm_get_color_range_name(state->color_range));
947 961
948 if (plane->funcs->atomic_print_state) 962 if (plane->funcs->atomic_print_state)
949 plane->funcs->atomic_print_state(p, state); 963 plane->funcs->atomic_print_state(p, state);
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index ae3cbfe9e01c..00c78c1c9681 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -699,7 +699,6 @@ EXPORT_SYMBOL(drm_atomic_helper_check_modeset);
699 * drm_atomic_helper_check_plane_state() - Check plane state for validity 699 * drm_atomic_helper_check_plane_state() - Check plane state for validity
700 * @plane_state: plane state to check 700 * @plane_state: plane state to check
701 * @crtc_state: crtc state to check 701 * @crtc_state: crtc state to check
702 * @clip: integer clipping coordinates
703 * @min_scale: minimum @src:@dest scaling factor in 16.16 fixed point 702 * @min_scale: minimum @src:@dest scaling factor in 16.16 fixed point
704 * @max_scale: maximum @src:@dest scaling factor in 16.16 fixed point 703 * @max_scale: maximum @src:@dest scaling factor in 16.16 fixed point
705 * @can_position: is it legal to position the plane such that it 704 * @can_position: is it legal to position the plane such that it
@@ -719,7 +718,6 @@ EXPORT_SYMBOL(drm_atomic_helper_check_modeset);
719 */ 718 */
720int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state, 719int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state,
721 const struct drm_crtc_state *crtc_state, 720 const struct drm_crtc_state *crtc_state,
722 const struct drm_rect *clip,
723 int min_scale, 721 int min_scale,
724 int max_scale, 722 int max_scale,
725 bool can_position, 723 bool can_position,
@@ -729,6 +727,7 @@ int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state,
729 struct drm_rect *src = &plane_state->src; 727 struct drm_rect *src = &plane_state->src;
730 struct drm_rect *dst = &plane_state->dst; 728 struct drm_rect *dst = &plane_state->dst;
731 unsigned int rotation = plane_state->rotation; 729 unsigned int rotation = plane_state->rotation;
730 struct drm_rect clip = {};
732 int hscale, vscale; 731 int hscale, vscale;
733 732
734 WARN_ON(plane_state->crtc && plane_state->crtc != crtc_state->crtc); 733 WARN_ON(plane_state->crtc && plane_state->crtc != crtc_state->crtc);
@@ -764,7 +763,10 @@ int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state,
764 return -ERANGE; 763 return -ERANGE;
765 } 764 }
766 765
767 plane_state->visible = drm_rect_clip_scaled(src, dst, clip, hscale, vscale); 766 if (crtc_state->enable)
767 drm_mode_get_hv_timing(&crtc_state->mode, &clip.x2, &clip.y2);
768
769 plane_state->visible = drm_rect_clip_scaled(src, dst, &clip, hscale, vscale);
768 770
769 drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, rotation); 771 drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, rotation);
770 772
@@ -778,10 +780,10 @@ int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state,
778 */ 780 */
779 return 0; 781 return 0;
780 782
781 if (!can_position && !drm_rect_equals(dst, clip)) { 783 if (!can_position && !drm_rect_equals(dst, &clip)) {
782 DRM_DEBUG_KMS("Plane must cover entire CRTC\n"); 784 DRM_DEBUG_KMS("Plane must cover entire CRTC\n");
783 drm_rect_debug_print("dst: ", dst, false); 785 drm_rect_debug_print("dst: ", dst, false);
784 drm_rect_debug_print("clip: ", clip, false); 786 drm_rect_debug_print("clip: ", &clip, false);
785 return -EINVAL; 787 return -EINVAL;
786 } 788 }
787 789
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index 0d002b045bd2..4ff064623836 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -88,6 +88,20 @@
88 * drm_mode_crtc_set_gamma_size(). Drivers which support both should use 88 * drm_mode_crtc_set_gamma_size(). Drivers which support both should use
89 * drm_atomic_helper_legacy_gamma_set() to alias the legacy gamma ramp with the 89 * drm_atomic_helper_legacy_gamma_set() to alias the legacy gamma ramp with the
90 * "GAMMA_LUT" property above. 90 * "GAMMA_LUT" property above.
91 *
92 * Support for different non RGB color encodings is controlled through
93 * &drm_plane specific COLOR_ENCODING and COLOR_RANGE properties. They
94 * are set up by calling drm_plane_create_color_properties().
95 *
96 * "COLOR_ENCODING"
97 * Optional plane enum property to support different non RGB
98 * color encodings. The driver can provide a subset of standard
99 * enum values supported by the DRM plane.
100 *
101 * "COLOR_RANGE"
102 * Optional plane enum property to support different non RGB
103 * color parameter ranges. The driver can provide a subset of
104 * standard enum values supported by the DRM plane.
91 */ 105 */
92 106
93/** 107/**
@@ -339,3 +353,122 @@ out:
339 drm_modeset_unlock(&crtc->mutex); 353 drm_modeset_unlock(&crtc->mutex);
340 return ret; 354 return ret;
341} 355}
356
357static const char * const color_encoding_name[] = {
358 [DRM_COLOR_YCBCR_BT601] = "ITU-R BT.601 YCbCr",
359 [DRM_COLOR_YCBCR_BT709] = "ITU-R BT.709 YCbCr",
360 [DRM_COLOR_YCBCR_BT2020] = "ITU-R BT.2020 YCbCr",
361};
362
363static const char * const color_range_name[] = {
364 [DRM_COLOR_YCBCR_FULL_RANGE] = "YCbCr full range",
365 [DRM_COLOR_YCBCR_LIMITED_RANGE] = "YCbCr limited range",
366};
367
368/**
369 * drm_get_color_encoding_name - return a string for color encoding
370 * @encoding: color encoding to compute name of
371 *
372 * In contrast to the other drm_get_*_name functions this one here returns a
373 * const pointer and hence is threadsafe.
374 */
375const char *drm_get_color_encoding_name(enum drm_color_encoding encoding)
376{
377 if (WARN_ON(encoding >= ARRAY_SIZE(color_encoding_name)))
378 return "unknown";
379
380 return color_encoding_name[encoding];
381}
382
383/**
384 * drm_get_color_range_name - return a string for color range
385 * @range: color range to compute name of
386 *
387 * In contrast to the other drm_get_*_name functions this one here returns a
388 * const pointer and hence is threadsafe.
389 */
390const char *drm_get_color_range_name(enum drm_color_range range)
391{
392 if (WARN_ON(range >= ARRAY_SIZE(color_range_name)))
393 return "unknown";
394
395 return color_range_name[range];
396}
397
398/**
399 * drm_plane_create_color_properties - color encoding related plane properties
400 * @plane: plane object
401 * @supported_encodings: bitfield indicating supported color encodings
402 * @supported_ranges: bitfileld indicating supported color ranges
403 * @default_encoding: default color encoding
404 * @default_range: default color range
405 *
406 * Create and attach plane specific COLOR_ENCODING and COLOR_RANGE
407 * properties to @plane. The supported encodings and ranges should
408 * be provided in supported_encodings and supported_ranges bitmasks.
409 * Each bit set in the bitmask indicates that its number as enum
410 * value is supported.
411 */
412int drm_plane_create_color_properties(struct drm_plane *plane,
413 u32 supported_encodings,
414 u32 supported_ranges,
415 enum drm_color_encoding default_encoding,
416 enum drm_color_range default_range)
417{
418 struct drm_device *dev = plane->dev;
419 struct drm_property *prop;
420 struct drm_prop_enum_list enum_list[max(DRM_COLOR_ENCODING_MAX,
421 DRM_COLOR_RANGE_MAX)];
422 int i, len;
423
424 if (WARN_ON(supported_encodings == 0 ||
425 (supported_encodings & -BIT(DRM_COLOR_ENCODING_MAX)) != 0 ||
426 (supported_encodings & BIT(default_encoding)) == 0))
427 return -EINVAL;
428
429 if (WARN_ON(supported_ranges == 0 ||
430 (supported_ranges & -BIT(DRM_COLOR_RANGE_MAX)) != 0 ||
431 (supported_ranges & BIT(default_range)) == 0))
432 return -EINVAL;
433
434 len = 0;
435 for (i = 0; i < DRM_COLOR_ENCODING_MAX; i++) {
436 if ((supported_encodings & BIT(i)) == 0)
437 continue;
438
439 enum_list[len].type = i;
440 enum_list[len].name = color_encoding_name[i];
441 len++;
442 }
443
444 prop = drm_property_create_enum(dev, 0, "COLOR_ENCODING",
445 enum_list, len);
446 if (!prop)
447 return -ENOMEM;
448 plane->color_encoding_property = prop;
449 drm_object_attach_property(&plane->base, prop, default_encoding);
450 if (plane->state)
451 plane->state->color_encoding = default_encoding;
452
453 len = 0;
454 for (i = 0; i < DRM_COLOR_RANGE_MAX; i++) {
455 if ((supported_ranges & BIT(i)) == 0)
456 continue;
457
458 enum_list[len].type = i;
459 enum_list[len].name = color_range_name[i];
460 len++;
461 }
462
463 prop = drm_property_create_enum(dev, 0, "COLOR_RANGE",
464 enum_list, len);
465 if (!prop)
466 return -ENOMEM;
467 plane->color_range_property = prop;
468 drm_object_attach_property(&plane->base, prop, default_range);
469 if (plane->state)
470 plane->state->color_range = default_range;
471
472 return 0;
473}
474EXPORT_SYMBOL(drm_plane_create_color_properties);
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 353e24fcde9e..03583887cfec 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -629,12 +629,14 @@ retry:
629 */ 629 */
630 if (!crtc->primary->format_default) { 630 if (!crtc->primary->format_default) {
631 ret = drm_plane_check_pixel_format(crtc->primary, 631 ret = drm_plane_check_pixel_format(crtc->primary,
632 fb->format->format); 632 fb->format->format,
633 fb->modifier);
633 if (ret) { 634 if (ret) {
634 struct drm_format_name_buf format_name; 635 struct drm_format_name_buf format_name;
635 DRM_DEBUG_KMS("Invalid pixel format %s\n", 636 DRM_DEBUG_KMS("Invalid pixel format %s, modifier 0x%llx\n",
636 drm_get_format_name(fb->format->format, 637 drm_get_format_name(fb->format->format,
637 &format_name)); 638 &format_name),
639 fb->modifier);
638 goto out; 640 goto out;
639 } 641 }
640 } 642 }
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
index af00f42ba269..3c2b82865ad2 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -71,6 +71,8 @@ int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,
71 void *data, struct drm_file *file_priv); 71 void *data, struct drm_file *file_priv);
72 72
73/* drm_color_mgmt.c */ 73/* drm_color_mgmt.c */
74const char *drm_get_color_encoding_name(enum drm_color_encoding encoding);
75const char *drm_get_color_range_name(enum drm_color_range range);
74 76
75/* IOCTLs */ 77/* IOCTLs */
76int drm_mode_gamma_get_ioctl(struct drm_device *dev, 78int drm_mode_gamma_get_ioctl(struct drm_device *dev,
@@ -196,8 +198,8 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
196/* drm_plane.c */ 198/* drm_plane.c */
197int drm_plane_register_all(struct drm_device *dev); 199int drm_plane_register_all(struct drm_device *dev);
198void drm_plane_unregister_all(struct drm_device *dev); 200void drm_plane_unregister_all(struct drm_device *dev);
199int drm_plane_check_pixel_format(const struct drm_plane *plane, 201int drm_plane_check_pixel_format(struct drm_plane *plane,
200 u32 format); 202 u32 format, u64 modifier);
201 203
202/* drm_bridge.c */ 204/* drm_bridge.c */
203void drm_bridge_detach(struct drm_bridge *bridge); 205void drm_bridge_detach(struct drm_bridge *bridge);
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 9acc1e157813..a1b9338736e3 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -99,7 +99,7 @@ static struct drm_minor **drm_minor_get_slot(struct drm_device *dev,
99 case DRM_MINOR_CONTROL: 99 case DRM_MINOR_CONTROL:
100 return &dev->control; 100 return &dev->control;
101 default: 101 default:
102 return NULL; 102 BUG();
103 } 103 }
104} 104}
105 105
diff --git a/drivers/gpu/drm/drm_memory.c b/drivers/gpu/drm/drm_memory.c
index 7ca500b8c399..3c54044214db 100644
--- a/drivers/gpu/drm/drm_memory.c
+++ b/drivers/gpu/drm/drm_memory.c
@@ -153,7 +153,7 @@ EXPORT_SYMBOL(drm_legacy_ioremapfree);
153u64 drm_get_max_iomem(void) 153u64 drm_get_max_iomem(void)
154{ 154{
155 struct resource *tmp; 155 struct resource *tmp;
156 u64 max_iomem = 0; 156 resource_size_t max_iomem = 0;
157 157
158 for (tmp = iomem_resource.child; tmp; tmp = tmp->sibling) { 158 for (tmp = iomem_resource.child; tmp; tmp = tmp->sibling) {
159 max_iomem = max(max_iomem, tmp->end); 159 max_iomem = max(max_iomem, tmp->end);
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 186c4e90cc1c..a351bd888a61 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -180,7 +180,7 @@ static void drm_mm_interval_tree_add_node(struct drm_mm_node *hole_node,
180 struct drm_mm *mm = hole_node->mm; 180 struct drm_mm *mm = hole_node->mm;
181 struct rb_node **link, *rb; 181 struct rb_node **link, *rb;
182 struct drm_mm_node *parent; 182 struct drm_mm_node *parent;
183 bool leftmost = true; 183 bool leftmost;
184 184
185 node->__subtree_last = LAST(node); 185 node->__subtree_last = LAST(node);
186 186
@@ -201,6 +201,7 @@ static void drm_mm_interval_tree_add_node(struct drm_mm_node *hole_node,
201 } else { 201 } else {
202 rb = NULL; 202 rb = NULL;
203 link = &mm->interval_tree.rb_root.rb_node; 203 link = &mm->interval_tree.rb_root.rb_node;
204 leftmost = true;
204 } 205 }
205 206
206 while (*link) { 207 while (*link) {
@@ -208,11 +209,11 @@ static void drm_mm_interval_tree_add_node(struct drm_mm_node *hole_node,
208 parent = rb_entry(rb, struct drm_mm_node, rb); 209 parent = rb_entry(rb, struct drm_mm_node, rb);
209 if (parent->__subtree_last < node->__subtree_last) 210 if (parent->__subtree_last < node->__subtree_last)
210 parent->__subtree_last = node->__subtree_last; 211 parent->__subtree_last = node->__subtree_last;
211 if (node->start < parent->start) 212 if (node->start < parent->start) {
212 link = &parent->rb.rb_left; 213 link = &parent->rb.rb_left;
213 else { 214 } else {
214 link = &parent->rb.rb_right; 215 link = &parent->rb.rb_right;
215 leftmost = true; 216 leftmost = false;
216 } 217 }
217 } 218 }
218 219
diff --git a/drivers/gpu/drm/drm_modeset_lock.c b/drivers/gpu/drm/drm_modeset_lock.c
index 963e23db0fe7..8a5100685875 100644
--- a/drivers/gpu/drm/drm_modeset_lock.c
+++ b/drivers/gpu/drm/drm_modeset_lock.c
@@ -113,6 +113,7 @@ retry:
113 kfree(ctx); 113 kfree(ctx);
114 return; 114 return;
115 } 115 }
116 ww_acquire_done(&ctx->ww_ctx);
116 117
117 WARN_ON(config->acquire_ctx); 118 WARN_ON(config->acquire_ctx);
118 119
diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
index 4c191c050e7d..1fe122461298 100644
--- a/drivers/gpu/drm/drm_of.c
+++ b/drivers/gpu/drm/drm_of.c
@@ -122,12 +122,10 @@ int drm_of_component_probe(struct device *dev,
122 if (!port) 122 if (!port)
123 break; 123 break;
124 124
125 if (!of_device_is_available(port->parent)) { 125 if (of_device_is_available(port->parent))
126 of_node_put(port); 126 drm_of_component_match_add(dev, &match, compare_of,
127 continue; 127 port);
128 }
129 128
130 drm_of_component_match_add(dev, &match, compare_of, port);
131 of_node_put(port); 129 of_node_put(port);
132 } 130 }
133 131
diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c
index 1f2af707ce03..902cc1a71e45 100644
--- a/drivers/gpu/drm/drm_panel_orientation_quirks.c
+++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c
@@ -11,6 +11,7 @@
11#include <linux/dmi.h> 11#include <linux/dmi.h>
12#include <linux/module.h> 12#include <linux/module.h>
13#include <drm/drm_connector.h> 13#include <drm/drm_connector.h>
14#include <drm/drm_utils.h>
14 15
15#ifdef CONFIG_DMI 16#ifdef CONFIG_DMI
16 17
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index 09de6ecb3968..a5d1fc7e8a37 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -549,16 +549,33 @@ int drm_mode_getplane(struct drm_device *dev, void *data,
549 return 0; 549 return 0;
550} 550}
551 551
552int drm_plane_check_pixel_format(const struct drm_plane *plane, u32 format) 552int drm_plane_check_pixel_format(struct drm_plane *plane,
553 u32 format, u64 modifier)
553{ 554{
554 unsigned int i; 555 unsigned int i;
555 556
556 for (i = 0; i < plane->format_count; i++) { 557 for (i = 0; i < plane->format_count; i++) {
557 if (format == plane->format_types[i]) 558 if (format == plane->format_types[i])
558 return 0; 559 break;
560 }
561 if (i == plane->format_count)
562 return -EINVAL;
563
564 if (!plane->modifier_count)
565 return 0;
566
567 for (i = 0; i < plane->modifier_count; i++) {
568 if (modifier == plane->modifiers[i])
569 break;
559 } 570 }
571 if (i == plane->modifier_count)
572 return -EINVAL;
560 573
561 return -EINVAL; 574 if (plane->funcs->format_mod_supported &&
575 !plane->funcs->format_mod_supported(plane, format, modifier))
576 return -EINVAL;
577
578 return 0;
562} 579}
563 580
564/* 581/*
@@ -602,12 +619,14 @@ static int __setplane_internal(struct drm_plane *plane,
602 } 619 }
603 620
604 /* Check whether this plane supports the fb pixel format. */ 621 /* Check whether this plane supports the fb pixel format. */
605 ret = drm_plane_check_pixel_format(plane, fb->format->format); 622 ret = drm_plane_check_pixel_format(plane, fb->format->format,
623 fb->modifier);
606 if (ret) { 624 if (ret) {
607 struct drm_format_name_buf format_name; 625 struct drm_format_name_buf format_name;
608 DRM_DEBUG_KMS("Invalid pixel format %s\n", 626 DRM_DEBUG_KMS("Invalid pixel format %s, modifier 0x%llx\n",
609 drm_get_format_name(fb->format->format, 627 drm_get_format_name(fb->format->format,
610 &format_name)); 628 &format_name),
629 fb->modifier);
611 goto out; 630 goto out;
612 } 631 }
613 632
diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c
index f1be8cd4e387..f88f68161519 100644
--- a/drivers/gpu/drm/drm_plane_helper.c
+++ b/drivers/gpu/drm/drm_plane_helper.c
@@ -106,7 +106,6 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
106 * @fb: framebuffer to flip onto plane 106 * @fb: framebuffer to flip onto plane
107 * @src: source coordinates in 16.16 fixed point 107 * @src: source coordinates in 16.16 fixed point
108 * @dst: integer destination coordinates 108 * @dst: integer destination coordinates
109 * @clip: integer clipping coordinates
110 * @rotation: plane rotation 109 * @rotation: plane rotation
111 * @min_scale: minimum @src:@dest scaling factor in 16.16 fixed point 110 * @min_scale: minimum @src:@dest scaling factor in 16.16 fixed point
112 * @max_scale: maximum @src:@dest scaling factor in 16.16 fixed point 111 * @max_scale: maximum @src:@dest scaling factor in 16.16 fixed point
@@ -131,7 +130,6 @@ int drm_plane_helper_check_update(struct drm_plane *plane,
131 struct drm_framebuffer *fb, 130 struct drm_framebuffer *fb,
132 struct drm_rect *src, 131 struct drm_rect *src,
133 struct drm_rect *dst, 132 struct drm_rect *dst,
134 const struct drm_rect *clip,
135 unsigned int rotation, 133 unsigned int rotation,
136 int min_scale, 134 int min_scale,
137 int max_scale, 135 int max_scale,
@@ -157,11 +155,12 @@ int drm_plane_helper_check_update(struct drm_plane *plane,
157 struct drm_crtc_state crtc_state = { 155 struct drm_crtc_state crtc_state = {
158 .crtc = crtc, 156 .crtc = crtc,
159 .enable = crtc->enabled, 157 .enable = crtc->enabled,
158 .mode = crtc->mode,
160 }; 159 };
161 int ret; 160 int ret;
162 161
163 ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state, 162 ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state,
164 clip, min_scale, max_scale, 163 min_scale, max_scale,
165 can_position, 164 can_position,
166 can_update_disabled); 165 can_update_disabled);
167 if (ret) 166 if (ret)
@@ -239,16 +238,12 @@ int drm_primary_helper_update(struct drm_plane *plane, struct drm_crtc *crtc,
239 .x2 = crtc_x + crtc_w, 238 .x2 = crtc_x + crtc_w,
240 .y2 = crtc_y + crtc_h, 239 .y2 = crtc_y + crtc_h,
241 }; 240 };
242 const struct drm_rect clip = {
243 .x2 = crtc->mode.hdisplay,
244 .y2 = crtc->mode.vdisplay,
245 };
246 struct drm_connector **connector_list; 241 struct drm_connector **connector_list;
247 int num_connectors, ret; 242 int num_connectors, ret;
248 bool visible; 243 bool visible;
249 244
250 ret = drm_plane_helper_check_update(plane, crtc, fb, 245 ret = drm_plane_helper_check_update(plane, crtc, fb,
251 &src, &dest, &clip, 246 &src, &dest,
252 DRM_MODE_ROTATE_0, 247 DRM_MODE_ROTATE_0,
253 DRM_PLANE_HELPER_NO_SCALING, 248 DRM_PLANE_HELPER_NO_SCALING,
254 DRM_PLANE_HELPER_NO_SCALING, 249 DRM_PLANE_HELPER_NO_SCALING,
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index e82a976f0fba..7856a9b3f8a8 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -230,26 +230,26 @@ void drm_gem_map_detach(struct dma_buf *dma_buf,
230 struct drm_prime_attachment *prime_attach = attach->priv; 230 struct drm_prime_attachment *prime_attach = attach->priv;
231 struct drm_gem_object *obj = dma_buf->priv; 231 struct drm_gem_object *obj = dma_buf->priv;
232 struct drm_device *dev = obj->dev; 232 struct drm_device *dev = obj->dev;
233 struct sg_table *sgt;
234 233
235 if (dev->driver->gem_prime_unpin) 234 if (prime_attach) {
236 dev->driver->gem_prime_unpin(obj); 235 struct sg_table *sgt = prime_attach->sgt;
237 236
238 if (!prime_attach) 237 if (sgt) {
239 return; 238 if (prime_attach->dir != DMA_NONE)
240 239 dma_unmap_sg_attrs(attach->dev, sgt->sgl,
241 sgt = prime_attach->sgt; 240 sgt->nents,
242 if (sgt) { 241 prime_attach->dir,
243 if (prime_attach->dir != DMA_NONE) 242 DMA_ATTR_SKIP_CPU_SYNC);
244 dma_unmap_sg_attrs(attach->dev, sgt->sgl, sgt->nents, 243 sg_free_table(sgt);
245 prime_attach->dir, 244 }
246 DMA_ATTR_SKIP_CPU_SYNC); 245
247 sg_free_table(sgt); 246 kfree(sgt);
247 kfree(prime_attach);
248 attach->priv = NULL;
248 } 249 }
249 250
250 kfree(sgt); 251 if (dev->driver->gem_prime_unpin)
251 kfree(prime_attach); 252 dev->driver->gem_prime_unpin(obj);
252 attach->priv = NULL;
253} 253}
254EXPORT_SYMBOL(drm_gem_map_detach); 254EXPORT_SYMBOL(drm_gem_map_detach);
255 255
@@ -922,40 +922,40 @@ EXPORT_SYMBOL(drm_prime_pages_to_sg);
922/** 922/**
923 * drm_prime_sg_to_page_addr_arrays - convert an sg table into a page array 923 * drm_prime_sg_to_page_addr_arrays - convert an sg table into a page array
924 * @sgt: scatter-gather table to convert 924 * @sgt: scatter-gather table to convert
925 * @pages: array of page pointers to store the page array in 925 * @pages: optional array of page pointers to store the page array in
926 * @addrs: optional array to store the dma bus address of each page 926 * @addrs: optional array to store the dma bus address of each page
927 * @max_pages: size of both the passed-in arrays 927 * @max_entries: size of both the passed-in arrays
928 * 928 *
929 * Exports an sg table into an array of pages and addresses. This is currently 929 * Exports an sg table into an array of pages and addresses. This is currently
930 * required by the TTM driver in order to do correct fault handling. 930 * required by the TTM driver in order to do correct fault handling.
931 */ 931 */
932int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages, 932int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages,
933 dma_addr_t *addrs, int max_pages) 933 dma_addr_t *addrs, int max_entries)
934{ 934{
935 unsigned count; 935 unsigned count;
936 struct scatterlist *sg; 936 struct scatterlist *sg;
937 struct page *page; 937 struct page *page;
938 u32 len; 938 u32 len, index;
939 int pg_index;
940 dma_addr_t addr; 939 dma_addr_t addr;
941 940
942 pg_index = 0; 941 index = 0;
943 for_each_sg(sgt->sgl, sg, sgt->nents, count) { 942 for_each_sg(sgt->sgl, sg, sgt->nents, count) {
944 len = sg->length; 943 len = sg->length;
945 page = sg_page(sg); 944 page = sg_page(sg);
946 addr = sg_dma_address(sg); 945 addr = sg_dma_address(sg);
947 946
948 while (len > 0) { 947 while (len > 0) {
949 if (WARN_ON(pg_index >= max_pages)) 948 if (WARN_ON(index >= max_entries))
950 return -1; 949 return -1;
951 pages[pg_index] = page; 950 if (pages)
951 pages[index] = page;
952 if (addrs) 952 if (addrs)
953 addrs[pg_index] = addr; 953 addrs[index] = addr;
954 954
955 page++; 955 page++;
956 addr += PAGE_SIZE; 956 addr += PAGE_SIZE;
957 len -= PAGE_SIZE; 957 len -= PAGE_SIZE;
958 pg_index++; 958 index++;
959 } 959 }
960 } 960 }
961 return 0; 961 return 0;
diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c
index bae50e6b819d..6ac6ee41a6a3 100644
--- a/drivers/gpu/drm/drm_property.c
+++ b/drivers/gpu/drm/drm_property.c
@@ -50,11 +50,27 @@
50 * IOCTL and in the get/set property IOCTL. 50 * IOCTL and in the get/set property IOCTL.
51 */ 51 */
52 52
53static bool drm_property_type_valid(struct drm_property *property) 53static bool drm_property_flags_valid(u32 flags)
54{ 54{
55 if (property->flags & DRM_MODE_PROP_EXTENDED_TYPE) 55 u32 legacy_type = flags & DRM_MODE_PROP_LEGACY_TYPE;
56 return !(property->flags & DRM_MODE_PROP_LEGACY_TYPE); 56 u32 ext_type = flags & DRM_MODE_PROP_EXTENDED_TYPE;
57 return !!(property->flags & DRM_MODE_PROP_LEGACY_TYPE); 57
58 /* Reject undefined/deprecated flags */
59 if (flags & ~(DRM_MODE_PROP_LEGACY_TYPE |
60 DRM_MODE_PROP_EXTENDED_TYPE |
61 DRM_MODE_PROP_IMMUTABLE |
62 DRM_MODE_PROP_ATOMIC))
63 return false;
64
65 /* We want either a legacy type or an extended type, but not both */
66 if (!legacy_type == !ext_type)
67 return false;
68
69 /* Only one legacy type at a time please */
70 if (legacy_type && !is_power_of_2(legacy_type))
71 return false;
72
73 return true;
58} 74}
59 75
60/** 76/**
@@ -72,12 +88,19 @@ static bool drm_property_type_valid(struct drm_property *property)
72 * Returns: 88 * Returns:
73 * A pointer to the newly created property on success, NULL on failure. 89 * A pointer to the newly created property on success, NULL on failure.
74 */ 90 */
75struct drm_property *drm_property_create(struct drm_device *dev, int flags, 91struct drm_property *drm_property_create(struct drm_device *dev,
76 const char *name, int num_values) 92 u32 flags, const char *name,
93 int num_values)
77{ 94{
78 struct drm_property *property = NULL; 95 struct drm_property *property = NULL;
79 int ret; 96 int ret;
80 97
98 if (WARN_ON(!drm_property_flags_valid(flags)))
99 return NULL;
100
101 if (WARN_ON(strlen(name) >= DRM_PROP_NAME_LEN))
102 return NULL;
103
81 property = kzalloc(sizeof(struct drm_property), GFP_KERNEL); 104 property = kzalloc(sizeof(struct drm_property), GFP_KERNEL);
82 if (!property) 105 if (!property)
83 return NULL; 106 return NULL;
@@ -99,15 +122,11 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags,
99 property->num_values = num_values; 122 property->num_values = num_values;
100 INIT_LIST_HEAD(&property->enum_list); 123 INIT_LIST_HEAD(&property->enum_list);
101 124
102 if (name) { 125 strncpy(property->name, name, DRM_PROP_NAME_LEN);
103 strncpy(property->name, name, DRM_PROP_NAME_LEN); 126 property->name[DRM_PROP_NAME_LEN-1] = '\0';
104 property->name[DRM_PROP_NAME_LEN-1] = '\0';
105 }
106 127
107 list_add_tail(&property->head, &dev->mode_config.property_list); 128 list_add_tail(&property->head, &dev->mode_config.property_list);
108 129
109 WARN_ON(!drm_property_type_valid(property));
110
111 return property; 130 return property;
112fail: 131fail:
113 kfree(property->values); 132 kfree(property->values);
@@ -135,10 +154,10 @@ EXPORT_SYMBOL(drm_property_create);
135 * Returns: 154 * Returns:
136 * A pointer to the newly created property on success, NULL on failure. 155 * A pointer to the newly created property on success, NULL on failure.
137 */ 156 */
138struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags, 157struct drm_property *drm_property_create_enum(struct drm_device *dev,
139 const char *name, 158 u32 flags, const char *name,
140 const struct drm_prop_enum_list *props, 159 const struct drm_prop_enum_list *props,
141 int num_values) 160 int num_values)
142{ 161{
143 struct drm_property *property; 162 struct drm_property *property;
144 int i, ret; 163 int i, ret;
@@ -184,10 +203,10 @@ EXPORT_SYMBOL(drm_property_create_enum);
184 * A pointer to the newly created property on success, NULL on failure. 203 * A pointer to the newly created property on success, NULL on failure.
185 */ 204 */
186struct drm_property *drm_property_create_bitmask(struct drm_device *dev, 205struct drm_property *drm_property_create_bitmask(struct drm_device *dev,
187 int flags, const char *name, 206 u32 flags, const char *name,
188 const struct drm_prop_enum_list *props, 207 const struct drm_prop_enum_list *props,
189 int num_props, 208 int num_props,
190 uint64_t supported_bits) 209 uint64_t supported_bits)
191{ 210{
192 struct drm_property *property; 211 struct drm_property *property;
193 int i, ret, index = 0; 212 int i, ret, index = 0;
@@ -221,8 +240,8 @@ struct drm_property *drm_property_create_bitmask(struct drm_device *dev,
221EXPORT_SYMBOL(drm_property_create_bitmask); 240EXPORT_SYMBOL(drm_property_create_bitmask);
222 241
223static struct drm_property *property_create_range(struct drm_device *dev, 242static struct drm_property *property_create_range(struct drm_device *dev,
224 int flags, const char *name, 243 u32 flags, const char *name,
225 uint64_t min, uint64_t max) 244 uint64_t min, uint64_t max)
226{ 245{
227 struct drm_property *property; 246 struct drm_property *property;
228 247
@@ -255,9 +274,9 @@ static struct drm_property *property_create_range(struct drm_device *dev,
255 * Returns: 274 * Returns:
256 * A pointer to the newly created property on success, NULL on failure. 275 * A pointer to the newly created property on success, NULL on failure.
257 */ 276 */
258struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, 277struct drm_property *drm_property_create_range(struct drm_device *dev,
259 const char *name, 278 u32 flags, const char *name,
260 uint64_t min, uint64_t max) 279 uint64_t min, uint64_t max)
261{ 280{
262 return property_create_range(dev, DRM_MODE_PROP_RANGE | flags, 281 return property_create_range(dev, DRM_MODE_PROP_RANGE | flags,
263 name, min, max); 282 name, min, max);
@@ -284,8 +303,8 @@ EXPORT_SYMBOL(drm_property_create_range);
284 * A pointer to the newly created property on success, NULL on failure. 303 * A pointer to the newly created property on success, NULL on failure.
285 */ 304 */
286struct drm_property *drm_property_create_signed_range(struct drm_device *dev, 305struct drm_property *drm_property_create_signed_range(struct drm_device *dev,
287 int flags, const char *name, 306 u32 flags, const char *name,
288 int64_t min, int64_t max) 307 int64_t min, int64_t max)
289{ 308{
290 return property_create_range(dev, DRM_MODE_PROP_SIGNED_RANGE | flags, 309 return property_create_range(dev, DRM_MODE_PROP_SIGNED_RANGE | flags,
291 name, I642U64(min), I642U64(max)); 310 name, I642U64(min), I642U64(max));
@@ -311,7 +330,7 @@ EXPORT_SYMBOL(drm_property_create_signed_range);
311 * A pointer to the newly created property on success, NULL on failure. 330 * A pointer to the newly created property on success, NULL on failure.
312 */ 331 */
313struct drm_property *drm_property_create_object(struct drm_device *dev, 332struct drm_property *drm_property_create_object(struct drm_device *dev,
314 int flags, const char *name, 333 u32 flags, const char *name,
315 uint32_t type) 334 uint32_t type)
316{ 335{
317 struct drm_property *property; 336 struct drm_property *property;
@@ -347,8 +366,8 @@ EXPORT_SYMBOL(drm_property_create_object);
347 * Returns: 366 * Returns:
348 * A pointer to the newly created property on success, NULL on failure. 367 * A pointer to the newly created property on success, NULL on failure.
349 */ 368 */
350struct drm_property *drm_property_create_bool(struct drm_device *dev, int flags, 369struct drm_property *drm_property_create_bool(struct drm_device *dev,
351 const char *name) 370 u32 flags, const char *name)
352{ 371{
353 return drm_property_create_range(dev, flags, name, 0, 1); 372 return drm_property_create_range(dev, flags, name, 0, 1);
354} 373}
@@ -374,26 +393,24 @@ int drm_property_add_enum(struct drm_property *property, int index,
374{ 393{
375 struct drm_property_enum *prop_enum; 394 struct drm_property_enum *prop_enum;
376 395
377 if (!(drm_property_type_is(property, DRM_MODE_PROP_ENUM) || 396 if (WARN_ON(strlen(name) >= DRM_PROP_NAME_LEN))
378 drm_property_type_is(property, DRM_MODE_PROP_BITMASK))) 397 return -EINVAL;
398
399 if (WARN_ON(!drm_property_type_is(property, DRM_MODE_PROP_ENUM) &&
400 !drm_property_type_is(property, DRM_MODE_PROP_BITMASK)))
379 return -EINVAL; 401 return -EINVAL;
380 402
381 /* 403 /*
382 * Bitmask enum properties have the additional constraint of values 404 * Bitmask enum properties have the additional constraint of values
383 * from 0 to 63 405 * from 0 to 63
384 */ 406 */
385 if (drm_property_type_is(property, DRM_MODE_PROP_BITMASK) && 407 if (WARN_ON(drm_property_type_is(property, DRM_MODE_PROP_BITMASK) &&
386 (value > 63)) 408 value > 63))
387 return -EINVAL; 409 return -EINVAL;
388 410
389 if (!list_empty(&property->enum_list)) { 411 list_for_each_entry(prop_enum, &property->enum_list, head) {
390 list_for_each_entry(prop_enum, &property->enum_list, head) { 412 if (WARN_ON(prop_enum->value == value))
391 if (prop_enum->value == value) { 413 return -EINVAL;
392 strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
393 prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
394 return 0;
395 }
396 }
397 } 414 }
398 415
399 prop_enum = kzalloc(sizeof(struct drm_property_enum), GFP_KERNEL); 416 prop_enum = kzalloc(sizeof(struct drm_property_enum), GFP_KERNEL);
diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c b/drivers/gpu/drm/drm_simple_kms_helper.c
index 6c327fdbaaee..987a353c7f72 100644
--- a/drivers/gpu/drm/drm_simple_kms_helper.c
+++ b/drivers/gpu/drm/drm_simple_kms_helper.c
@@ -92,6 +92,28 @@ static const struct drm_crtc_helper_funcs drm_simple_kms_crtc_helper_funcs = {
92 .atomic_disable = drm_simple_kms_crtc_disable, 92 .atomic_disable = drm_simple_kms_crtc_disable,
93}; 93};
94 94
95static int drm_simple_kms_crtc_enable_vblank(struct drm_crtc *crtc)
96{
97 struct drm_simple_display_pipe *pipe;
98
99 pipe = container_of(crtc, struct drm_simple_display_pipe, crtc);
100 if (!pipe->funcs || !pipe->funcs->enable_vblank)
101 return 0;
102
103 return pipe->funcs->enable_vblank(pipe);
104}
105
106static void drm_simple_kms_crtc_disable_vblank(struct drm_crtc *crtc)
107{
108 struct drm_simple_display_pipe *pipe;
109
110 pipe = container_of(crtc, struct drm_simple_display_pipe, crtc);
111 if (!pipe->funcs || !pipe->funcs->disable_vblank)
112 return;
113
114 pipe->funcs->disable_vblank(pipe);
115}
116
95static const struct drm_crtc_funcs drm_simple_kms_crtc_funcs = { 117static const struct drm_crtc_funcs drm_simple_kms_crtc_funcs = {
96 .reset = drm_atomic_helper_crtc_reset, 118 .reset = drm_atomic_helper_crtc_reset,
97 .destroy = drm_crtc_cleanup, 119 .destroy = drm_crtc_cleanup,
@@ -99,12 +121,13 @@ static const struct drm_crtc_funcs drm_simple_kms_crtc_funcs = {
99 .page_flip = drm_atomic_helper_page_flip, 121 .page_flip = drm_atomic_helper_page_flip,
100 .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, 122 .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
101 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, 123 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
124 .enable_vblank = drm_simple_kms_crtc_enable_vblank,
125 .disable_vblank = drm_simple_kms_crtc_disable_vblank,
102}; 126};
103 127
104static int drm_simple_kms_plane_atomic_check(struct drm_plane *plane, 128static int drm_simple_kms_plane_atomic_check(struct drm_plane *plane,
105 struct drm_plane_state *plane_state) 129 struct drm_plane_state *plane_state)
106{ 130{
107 struct drm_rect clip = { 0 };
108 struct drm_simple_display_pipe *pipe; 131 struct drm_simple_display_pipe *pipe;
109 struct drm_crtc_state *crtc_state; 132 struct drm_crtc_state *crtc_state;
110 int ret; 133 int ret;
@@ -112,15 +135,8 @@ static int drm_simple_kms_plane_atomic_check(struct drm_plane *plane,
112 pipe = container_of(plane, struct drm_simple_display_pipe, plane); 135 pipe = container_of(plane, struct drm_simple_display_pipe, plane);
113 crtc_state = drm_atomic_get_new_crtc_state(plane_state->state, 136 crtc_state = drm_atomic_get_new_crtc_state(plane_state->state,
114 &pipe->crtc); 137 &pipe->crtc);
115 if (!crtc_state->enable)
116 return 0; /* nothing to check when disabling or disabled */
117
118 if (crtc_state->enable)
119 drm_mode_get_hv_timing(&crtc_state->mode,
120 &clip.x2, &clip.y2);
121 138
122 ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state, 139 ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state,
123 &clip,
124 DRM_PLANE_HELPER_NO_SCALING, 140 DRM_PLANE_HELPER_NO_SCALING,
125 DRM_PLANE_HELPER_NO_SCALING, 141 DRM_PLANE_HELPER_NO_SCALING,
126 false, true); 142 false, true);
@@ -128,7 +144,7 @@ static int drm_simple_kms_plane_atomic_check(struct drm_plane *plane,
128 return ret; 144 return ret;
129 145
130 if (!plane_state->visible) 146 if (!plane_state->visible)
131 return -EINVAL; 147 return 0;
132 148
133 if (!pipe->funcs || !pipe->funcs->check) 149 if (!pipe->funcs || !pipe->funcs->check)
134 return 0; 150 return 0;
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index c781cb426bf1..e02ddb01917b 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -120,6 +120,9 @@ static u32 __get_vblank_counter(struct drm_device *dev, unsigned int pipe)
120 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 120 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
121 struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe); 121 struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe);
122 122
123 if (WARN_ON(!crtc))
124 return 0;
125
123 if (crtc->funcs->get_vblank_counter) 126 if (crtc->funcs->get_vblank_counter)
124 return crtc->funcs->get_vblank_counter(crtc); 127 return crtc->funcs->get_vblank_counter(crtc);
125 } 128 }
@@ -318,6 +321,9 @@ static void __disable_vblank(struct drm_device *dev, unsigned int pipe)
318 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 321 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
319 struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe); 322 struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe);
320 323
324 if (WARN_ON(!crtc))
325 return;
326
321 if (crtc->funcs->disable_vblank) { 327 if (crtc->funcs->disable_vblank) {
322 crtc->funcs->disable_vblank(crtc); 328 crtc->funcs->disable_vblank(crtc);
323 return; 329 return;
@@ -920,6 +926,9 @@ static int __enable_vblank(struct drm_device *dev, unsigned int pipe)
920 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 926 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
921 struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe); 927 struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe);
922 928
929 if (WARN_ON(!crtc))
930 return 0;
931
923 if (crtc->funcs->enable_vblank) 932 if (crtc->funcs->enable_vblank)
924 return crtc->funcs->enable_vblank(crtc); 933 return crtc->funcs->enable_vblank(crtc);
925 } 934 }
diff --git a/drivers/gpu/drm/exynos/exynos_dp.c b/drivers/gpu/drm/exynos/exynos_dp.c
index 39629e7a80b9..964831dab102 100644
--- a/drivers/gpu/drm/exynos/exynos_dp.c
+++ b/drivers/gpu/drm/exynos/exynos_dp.c
@@ -41,6 +41,7 @@ struct exynos_dp_device {
41 struct device *dev; 41 struct device *dev;
42 42
43 struct videomode vm; 43 struct videomode vm;
44 struct analogix_dp_device *adp;
44 struct analogix_dp_plat_data plat_data; 45 struct analogix_dp_plat_data plat_data;
45}; 46};
46 47
@@ -157,13 +158,6 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
157 struct drm_device *drm_dev = data; 158 struct drm_device *drm_dev = data;
158 int ret; 159 int ret;
159 160
160 /*
161 * Just like the probe function said, we don't need the
162 * device drvrate anymore, we should leave the charge to
163 * analogix dp driver, set the device drvdata to NULL.
164 */
165 dev_set_drvdata(dev, NULL);
166
167 dp->dev = dev; 161 dp->dev = dev;
168 dp->drm_dev = drm_dev; 162 dp->drm_dev = drm_dev;
169 163
@@ -190,13 +184,22 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
190 184
191 dp->plat_data.encoder = encoder; 185 dp->plat_data.encoder = encoder;
192 186
193 return analogix_dp_bind(dev, dp->drm_dev, &dp->plat_data); 187 dp->adp = analogix_dp_bind(dev, dp->drm_dev, &dp->plat_data);
188 if (IS_ERR(dp->adp)) {
189 dp->encoder.funcs->destroy(&dp->encoder);
190 return PTR_ERR(dp->adp);
191 }
192
193 return 0;
194} 194}
195 195
196static void exynos_dp_unbind(struct device *dev, struct device *master, 196static void exynos_dp_unbind(struct device *dev, struct device *master,
197 void *data) 197 void *data)
198{ 198{
199 return analogix_dp_unbind(dev, master, data); 199 struct exynos_dp_device *dp = dev_get_drvdata(dev);
200
201 analogix_dp_unbind(dp->adp);
202 dp->encoder.funcs->destroy(&dp->encoder);
200} 203}
201 204
202static const struct component_ops exynos_dp_ops = { 205static const struct component_ops exynos_dp_ops = {
@@ -241,6 +244,7 @@ static int exynos_dp_probe(struct platform_device *pdev)
241 244
242 /* The remote port can be either a panel or a bridge */ 245 /* The remote port can be either a panel or a bridge */
243 dp->plat_data.panel = panel; 246 dp->plat_data.panel = panel;
247 dp->plat_data.skip_connector = !!bridge;
244 dp->ptn_bridge = bridge; 248 dp->ptn_bridge = bridge;
245 249
246out: 250out:
@@ -257,12 +261,16 @@ static int exynos_dp_remove(struct platform_device *pdev)
257#ifdef CONFIG_PM 261#ifdef CONFIG_PM
258static int exynos_dp_suspend(struct device *dev) 262static int exynos_dp_suspend(struct device *dev)
259{ 263{
260 return analogix_dp_suspend(dev); 264 struct exynos_dp_device *dp = dev_get_drvdata(dev);
265
266 return analogix_dp_suspend(dp->adp);
261} 267}
262 268
263static int exynos_dp_resume(struct device *dev) 269static int exynos_dp_resume(struct device *dev)
264{ 270{
265 return analogix_dp_resume(dev); 271 struct exynos_dp_device *dp = dev_get_drvdata(dev);
272
273 return analogix_dp_resume(dp->adp);
266} 274}
267#endif 275#endif
268 276
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 1412abcb27d4..47ca8b97ce50 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6132,6 +6132,7 @@ enum {
6132#define _DVSACNTR 0x72180 6132#define _DVSACNTR 0x72180
6133#define DVS_ENABLE (1<<31) 6133#define DVS_ENABLE (1<<31)
6134#define DVS_GAMMA_ENABLE (1<<30) 6134#define DVS_GAMMA_ENABLE (1<<30)
6135#define DVS_YUV_RANGE_CORRECTION_DISABLE (1<<27)
6135#define DVS_PIXFORMAT_MASK (3<<25) 6136#define DVS_PIXFORMAT_MASK (3<<25)
6136#define DVS_FORMAT_YUV422 (0<<25) 6137#define DVS_FORMAT_YUV422 (0<<25)
6137#define DVS_FORMAT_RGBX101010 (1<<25) 6138#define DVS_FORMAT_RGBX101010 (1<<25)
@@ -6140,6 +6141,7 @@ enum {
6140#define DVS_PIPE_CSC_ENABLE (1<<24) 6141#define DVS_PIPE_CSC_ENABLE (1<<24)
6141#define DVS_SOURCE_KEY (1<<22) 6142#define DVS_SOURCE_KEY (1<<22)
6142#define DVS_RGB_ORDER_XBGR (1<<20) 6143#define DVS_RGB_ORDER_XBGR (1<<20)
6144#define DVS_YUV_FORMAT_BT709 (1<<18)
6143#define DVS_YUV_BYTE_ORDER_MASK (3<<16) 6145#define DVS_YUV_BYTE_ORDER_MASK (3<<16)
6144#define DVS_YUV_ORDER_YUYV (0<<16) 6146#define DVS_YUV_ORDER_YUYV (0<<16)
6145#define DVS_YUV_ORDER_UYVY (1<<16) 6147#define DVS_YUV_ORDER_UYVY (1<<16)
@@ -6199,6 +6201,7 @@ enum {
6199#define _SPRA_CTL 0x70280 6201#define _SPRA_CTL 0x70280
6200#define SPRITE_ENABLE (1<<31) 6202#define SPRITE_ENABLE (1<<31)
6201#define SPRITE_GAMMA_ENABLE (1<<30) 6203#define SPRITE_GAMMA_ENABLE (1<<30)
6204#define SPRITE_YUV_RANGE_CORRECTION_DISABLE (1<<28)
6202#define SPRITE_PIXFORMAT_MASK (7<<25) 6205#define SPRITE_PIXFORMAT_MASK (7<<25)
6203#define SPRITE_FORMAT_YUV422 (0<<25) 6206#define SPRITE_FORMAT_YUV422 (0<<25)
6204#define SPRITE_FORMAT_RGBX101010 (1<<25) 6207#define SPRITE_FORMAT_RGBX101010 (1<<25)
@@ -6210,7 +6213,7 @@ enum {
6210#define SPRITE_SOURCE_KEY (1<<22) 6213#define SPRITE_SOURCE_KEY (1<<22)
6211#define SPRITE_RGB_ORDER_RGBX (1<<20) /* only for 888 and 161616 */ 6214#define SPRITE_RGB_ORDER_RGBX (1<<20) /* only for 888 and 161616 */
6212#define SPRITE_YUV_TO_RGB_CSC_DISABLE (1<<19) 6215#define SPRITE_YUV_TO_RGB_CSC_DISABLE (1<<19)
6213#define SPRITE_YUV_CSC_FORMAT_BT709 (1<<18) /* 0 is BT601 */ 6216#define SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709 (1<<18) /* 0 is BT601 */
6214#define SPRITE_YUV_BYTE_ORDER_MASK (3<<16) 6217#define SPRITE_YUV_BYTE_ORDER_MASK (3<<16)
6215#define SPRITE_YUV_ORDER_YUYV (0<<16) 6218#define SPRITE_YUV_ORDER_YUYV (0<<16)
6216#define SPRITE_YUV_ORDER_UYVY (1<<16) 6219#define SPRITE_YUV_ORDER_UYVY (1<<16)
@@ -6286,6 +6289,7 @@ enum {
6286#define SP_FORMAT_RGBA8888 (0xf<<26) 6289#define SP_FORMAT_RGBA8888 (0xf<<26)
6287#define SP_ALPHA_PREMULTIPLY (1<<23) /* CHV pipe B */ 6290#define SP_ALPHA_PREMULTIPLY (1<<23) /* CHV pipe B */
6288#define SP_SOURCE_KEY (1<<22) 6291#define SP_SOURCE_KEY (1<<22)
6292#define SP_YUV_FORMAT_BT709 (1<<18)
6289#define SP_YUV_BYTE_ORDER_MASK (3<<16) 6293#define SP_YUV_BYTE_ORDER_MASK (3<<16)
6290#define SP_YUV_ORDER_YUYV (0<<16) 6294#define SP_YUV_ORDER_YUYV (0<<16)
6291#define SP_YUV_ORDER_UYVY (1<<16) 6295#define SP_YUV_ORDER_UYVY (1<<16)
@@ -6305,6 +6309,12 @@ enum {
6305#define _SPATILEOFF (VLV_DISPLAY_BASE + 0x721a4) 6309#define _SPATILEOFF (VLV_DISPLAY_BASE + 0x721a4)
6306#define _SPACONSTALPHA (VLV_DISPLAY_BASE + 0x721a8) 6310#define _SPACONSTALPHA (VLV_DISPLAY_BASE + 0x721a8)
6307#define SP_CONST_ALPHA_ENABLE (1<<31) 6311#define SP_CONST_ALPHA_ENABLE (1<<31)
6312#define _SPACLRC0 (VLV_DISPLAY_BASE + 0x721d0)
6313#define SP_CONTRAST(x) ((x) << 18) /* u3.6 */
6314#define SP_BRIGHTNESS(x) ((x) & 0xff) /* s8 */
6315#define _SPACLRC1 (VLV_DISPLAY_BASE + 0x721d4)
6316#define SP_SH_SIN(x) (((x) & 0x7ff) << 16) /* s4.7 */
6317#define SP_SH_COS(x) (x) /* u3.7 */
6308#define _SPAGAMC (VLV_DISPLAY_BASE + 0x721f4) 6318#define _SPAGAMC (VLV_DISPLAY_BASE + 0x721f4)
6309 6319
6310#define _SPBCNTR (VLV_DISPLAY_BASE + 0x72280) 6320#define _SPBCNTR (VLV_DISPLAY_BASE + 0x72280)
@@ -6318,6 +6328,8 @@ enum {
6318#define _SPBKEYMAXVAL (VLV_DISPLAY_BASE + 0x722a0) 6328#define _SPBKEYMAXVAL (VLV_DISPLAY_BASE + 0x722a0)
6319#define _SPBTILEOFF (VLV_DISPLAY_BASE + 0x722a4) 6329#define _SPBTILEOFF (VLV_DISPLAY_BASE + 0x722a4)
6320#define _SPBCONSTALPHA (VLV_DISPLAY_BASE + 0x722a8) 6330#define _SPBCONSTALPHA (VLV_DISPLAY_BASE + 0x722a8)
6331#define _SPBCLRC0 (VLV_DISPLAY_BASE + 0x722d0)
6332#define _SPBCLRC1 (VLV_DISPLAY_BASE + 0x722d4)
6321#define _SPBGAMC (VLV_DISPLAY_BASE + 0x722f4) 6333#define _SPBGAMC (VLV_DISPLAY_BASE + 0x722f4)
6322 6334
6323#define _MMIO_VLV_SPR(pipe, plane_id, reg_a, reg_b) \ 6335#define _MMIO_VLV_SPR(pipe, plane_id, reg_a, reg_b) \
@@ -6334,6 +6346,8 @@ enum {
6334#define SPKEYMAXVAL(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPAKEYMAXVAL, _SPBKEYMAXVAL) 6346#define SPKEYMAXVAL(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPAKEYMAXVAL, _SPBKEYMAXVAL)
6335#define SPTILEOFF(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPATILEOFF, _SPBTILEOFF) 6347#define SPTILEOFF(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPATILEOFF, _SPBTILEOFF)
6336#define SPCONSTALPHA(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPACONSTALPHA, _SPBCONSTALPHA) 6348#define SPCONSTALPHA(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPACONSTALPHA, _SPBCONSTALPHA)
6349#define SPCLRC0(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPACLRC0, _SPBCLRC0)
6350#define SPCLRC1(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPACLRC1, _SPBCLRC1)
6337#define SPGAMC(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPAGAMC, _SPBGAMC) 6351#define SPGAMC(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPAGAMC, _SPBGAMC)
6338 6352
6339/* 6353/*
@@ -6379,6 +6393,7 @@ enum {
6379#define _PLANE_CTL_3_A 0x70380 6393#define _PLANE_CTL_3_A 0x70380
6380#define PLANE_CTL_ENABLE (1 << 31) 6394#define PLANE_CTL_ENABLE (1 << 31)
6381#define PLANE_CTL_PIPE_GAMMA_ENABLE (1 << 30) /* Pre-GLK */ 6395#define PLANE_CTL_PIPE_GAMMA_ENABLE (1 << 30) /* Pre-GLK */
6396#define PLANE_CTL_YUV_RANGE_CORRECTION_DISABLE (1 << 28)
6382/* 6397/*
6383 * ICL+ uses the same PLANE_CTL_FORMAT bits, but the field definition 6398 * ICL+ uses the same PLANE_CTL_FORMAT bits, but the field definition
6384 * expanded to include bit 23 as well. However, the shift-24 based values 6399 * expanded to include bit 23 as well. However, the shift-24 based values
@@ -6400,6 +6415,7 @@ enum {
6400#define PLANE_CTL_KEY_ENABLE_DESTINATION ( 2 << 21) 6415#define PLANE_CTL_KEY_ENABLE_DESTINATION ( 2 << 21)
6401#define PLANE_CTL_ORDER_BGRX (0 << 20) 6416#define PLANE_CTL_ORDER_BGRX (0 << 20)
6402#define PLANE_CTL_ORDER_RGBX (1 << 20) 6417#define PLANE_CTL_ORDER_RGBX (1 << 20)
6418#define PLANE_CTL_YUV_TO_RGB_CSC_FORMAT_BT709 (1 << 18)
6403#define PLANE_CTL_YUV422_ORDER_MASK (0x3 << 16) 6419#define PLANE_CTL_YUV422_ORDER_MASK (0x3 << 16)
6404#define PLANE_CTL_YUV422_YUYV ( 0 << 16) 6420#define PLANE_CTL_YUV422_YUYV ( 0 << 16)
6405#define PLANE_CTL_YUV422_UYVY ( 1 << 16) 6421#define PLANE_CTL_YUV422_UYVY ( 1 << 16)
@@ -6452,7 +6468,13 @@ enum {
6452#define _PLANE_COLOR_CTL_2_A 0x702CC /* GLK+ */ 6468#define _PLANE_COLOR_CTL_2_A 0x702CC /* GLK+ */
6453#define _PLANE_COLOR_CTL_3_A 0x703CC /* GLK+ */ 6469#define _PLANE_COLOR_CTL_3_A 0x703CC /* GLK+ */
6454#define PLANE_COLOR_PIPE_GAMMA_ENABLE (1 << 30) 6470#define PLANE_COLOR_PIPE_GAMMA_ENABLE (1 << 30)
6471#define PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE (1 << 28)
6455#define PLANE_COLOR_PIPE_CSC_ENABLE (1 << 23) 6472#define PLANE_COLOR_PIPE_CSC_ENABLE (1 << 23)
6473#define PLANE_COLOR_CSC_MODE_BYPASS (0 << 17)
6474#define PLANE_COLOR_CSC_MODE_YUV601_TO_RGB709 (1 << 17)
6475#define PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709 (2 << 17)
6476#define PLANE_COLOR_CSC_MODE_YUV2020_TO_RGB2020 (3 << 17)
6477#define PLANE_COLOR_CSC_MODE_RGB709_TO_RGB2020 (4 << 17)
6456#define PLANE_COLOR_PLANE_GAMMA_DISABLE (1 << 13) 6478#define PLANE_COLOR_PLANE_GAMMA_DISABLE (1 << 13)
6457#define PLANE_COLOR_ALPHA_MASK (0x3 << 4) 6479#define PLANE_COLOR_ALPHA_MASK (0x3 << 4)
6458#define PLANE_COLOR_ALPHA_DISABLE (0 << 4) 6480#define PLANE_COLOR_ALPHA_DISABLE (0 << 4)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 5d46771d58f6..8be9c3371b7e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3083,9 +3083,6 @@ static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
3083 3083
3084static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state) 3084static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state)
3085{ 3085{
3086 struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
3087 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
3088 struct intel_crtc *crtc = to_intel_crtc(plane_state->base.crtc);
3089 const struct drm_framebuffer *fb = plane_state->base.fb; 3086 const struct drm_framebuffer *fb = plane_state->base.fb;
3090 int src_x = plane_state->base.src.x1 >> 16; 3087 int src_x = plane_state->base.src.x1 >> 16;
3091 int src_y = plane_state->base.src.y1 >> 16; 3088 int src_y = plane_state->base.src.y1 >> 16;
@@ -3095,11 +3092,6 @@ static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state)
3095 int y = src_y / vsub; 3092 int y = src_y / vsub;
3096 u32 offset; 3093 u32 offset;
3097 3094
3098 if (!skl_plane_has_ccs(dev_priv, crtc->pipe, plane->id)) {
3099 DRM_DEBUG_KMS("No RC support on %s\n", plane->base.name);
3100 return -EINVAL;
3101 }
3102
3103 if (plane_state->base.rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180)) { 3095 if (plane_state->base.rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180)) {
3104 DRM_DEBUG_KMS("RC support only with 0/180 degree rotation %x\n", 3096 DRM_DEBUG_KMS("RC support only with 0/180 degree rotation %x\n",
3105 plane_state->base.rotation); 3097 plane_state->base.rotation);
@@ -3564,6 +3556,12 @@ u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
3564 PLANE_CTL_PIPE_GAMMA_ENABLE | 3556 PLANE_CTL_PIPE_GAMMA_ENABLE |
3565 PLANE_CTL_PIPE_CSC_ENABLE | 3557 PLANE_CTL_PIPE_CSC_ENABLE |
3566 PLANE_CTL_PLANE_GAMMA_DISABLE; 3558 PLANE_CTL_PLANE_GAMMA_DISABLE;
3559
3560 if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
3561 plane_ctl |= PLANE_CTL_YUV_TO_RGB_CSC_FORMAT_BT709;
3562
3563 if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
3564 plane_ctl |= PLANE_CTL_YUV_RANGE_CORRECTION_DISABLE;
3567 } 3565 }
3568 3566
3569 plane_ctl |= skl_plane_ctl_format(fb->format->format); 3567 plane_ctl |= skl_plane_ctl_format(fb->format->format);
@@ -3593,6 +3591,16 @@ u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state,
3593 plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE; 3591 plane_color_ctl |= PLANE_COLOR_PLANE_GAMMA_DISABLE;
3594 plane_color_ctl |= glk_plane_color_ctl_alpha(fb->format->format); 3592 plane_color_ctl |= glk_plane_color_ctl_alpha(fb->format->format);
3595 3593
3594 if (intel_format_is_yuv(fb->format->format)) {
3595 if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
3596 plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709;
3597 else
3598 plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV601_TO_RGB709;
3599
3600 if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
3601 plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
3602 }
3603
3596 return plane_color_ctl; 3604 return plane_color_ctl;
3597} 3605}
3598 3606
@@ -9389,18 +9397,12 @@ static int intel_check_cursor(struct intel_crtc_state *crtc_state,
9389 struct intel_plane_state *plane_state) 9397 struct intel_plane_state *plane_state)
9390{ 9398{
9391 const struct drm_framebuffer *fb = plane_state->base.fb; 9399 const struct drm_framebuffer *fb = plane_state->base.fb;
9392 struct drm_rect clip = {};
9393 int src_x, src_y; 9400 int src_x, src_y;
9394 u32 offset; 9401 u32 offset;
9395 int ret; 9402 int ret;
9396 9403
9397 if (crtc_state->base.enable)
9398 drm_mode_get_hv_timing(&crtc_state->base.mode,
9399 &clip.x2, &clip.y2);
9400
9401 ret = drm_atomic_helper_check_plane_state(&plane_state->base, 9404 ret = drm_atomic_helper_check_plane_state(&plane_state->base,
9402 &crtc_state->base, 9405 &crtc_state->base,
9403 &clip,
9404 DRM_PLANE_HELPER_NO_SCALING, 9406 DRM_PLANE_HELPER_NO_SCALING,
9405 DRM_PLANE_HELPER_NO_SCALING, 9407 DRM_PLANE_HELPER_NO_SCALING,
9406 true, true); 9408 true, true);
@@ -12839,7 +12841,6 @@ intel_check_primary_plane(struct intel_plane *plane,
12839 int min_scale = DRM_PLANE_HELPER_NO_SCALING; 12841 int min_scale = DRM_PLANE_HELPER_NO_SCALING;
12840 int max_scale = DRM_PLANE_HELPER_NO_SCALING; 12842 int max_scale = DRM_PLANE_HELPER_NO_SCALING;
12841 bool can_position = false; 12843 bool can_position = false;
12842 struct drm_rect clip = {};
12843 int ret; 12844 int ret;
12844 12845
12845 if (INTEL_GEN(dev_priv) >= 9) { 12846 if (INTEL_GEN(dev_priv) >= 9) {
@@ -12851,13 +12852,8 @@ intel_check_primary_plane(struct intel_plane *plane,
12851 can_position = true; 12852 can_position = true;
12852 } 12853 }
12853 12854
12854 if (crtc_state->base.enable)
12855 drm_mode_get_hv_timing(&crtc_state->base.mode,
12856 &clip.x2, &clip.y2);
12857
12858 ret = drm_atomic_helper_check_plane_state(&state->base, 12855 ret = drm_atomic_helper_check_plane_state(&state->base,
12859 &crtc_state->base, 12856 &crtc_state->base,
12860 &clip,
12861 min_scale, max_scale, 12857 min_scale, max_scale,
12862 can_position, true); 12858 can_position, true);
12863 if (ret) 12859 if (ret)
@@ -13338,6 +13334,15 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
13338 DRM_MODE_ROTATE_0, 13334 DRM_MODE_ROTATE_0,
13339 supported_rotations); 13335 supported_rotations);
13340 13336
13337 if (INTEL_GEN(dev_priv) >= 9)
13338 drm_plane_create_color_properties(&primary->base,
13339 BIT(DRM_COLOR_YCBCR_BT601) |
13340 BIT(DRM_COLOR_YCBCR_BT709),
13341 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
13342 BIT(DRM_COLOR_YCBCR_FULL_RANGE),
13343 DRM_COLOR_YCBCR_BT709,
13344 DRM_COLOR_YCBCR_LIMITED_RANGE);
13345
13341 drm_plane_helper_add(&primary->base, &intel_plane_helper_funcs); 13346 drm_plane_helper_add(&primary->base, &intel_plane_helper_funcs);
13342 13347
13343 return primary; 13348 return primary;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 50874f4035cf..24e9caebe463 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1596,6 +1596,7 @@ u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state,
1596 const struct intel_plane_state *plane_state); 1596 const struct intel_plane_state *plane_state);
1597u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state, 1597u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
1598 const struct intel_plane_state *plane_state); 1598 const struct intel_plane_state *plane_state);
1599u32 glk_color_ctl(const struct intel_plane_state *plane_state);
1599u32 skl_plane_stride(const struct drm_framebuffer *fb, int plane, 1600u32 skl_plane_stride(const struct drm_framebuffer *fb, int plane,
1600 unsigned int rotation); 1601 unsigned int rotation);
1601int skl_check_plane_surface(const struct intel_crtc_state *crtc_state, 1602int skl_check_plane_surface(const struct intel_crtc_state *crtc_state,
@@ -2021,6 +2022,7 @@ bool intel_sdvo_init(struct drm_i915_private *dev_priv,
2021 2022
2022 2023
2023/* intel_sprite.c */ 2024/* intel_sprite.c */
2025bool intel_format_is_yuv(u32 format);
2024int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, 2026int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
2025 int usecs); 2027 int usecs);
2026struct intel_plane *intel_sprite_plane_create(struct drm_i915_private *dev_priv, 2028struct intel_plane *intel_sprite_plane_create(struct drm_i915_private *dev_priv,
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index e098e4b2c85c..dbdcf85032df 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -41,8 +41,7 @@
41#include <drm/i915_drm.h> 41#include <drm/i915_drm.h>
42#include "i915_drv.h" 42#include "i915_drv.h"
43 43
44static bool 44bool intel_format_is_yuv(u32 format)
45format_is_yuv(uint32_t format)
46{ 45{
47 switch (format) { 46 switch (format) {
48 case DRM_FORMAT_YUYV: 47 case DRM_FORMAT_YUYV:
@@ -266,6 +265,7 @@ skl_update_plane(struct intel_plane *plane,
266 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) 265 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
267 I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id), 266 I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
268 plane_state->color_ctl); 267 plane_state->color_ctl);
268
269 if (key->flags) { 269 if (key->flags) {
270 I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value); 270 I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
271 I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), key->max_value); 271 I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), key->max_value);
@@ -346,44 +346,103 @@ skl_plane_get_hw_state(struct intel_plane *plane)
346} 346}
347 347
348static void 348static void
349chv_update_csc(struct intel_plane *plane, uint32_t format) 349chv_update_csc(const struct intel_plane_state *plane_state)
350{ 350{
351 struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
351 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 352 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
353 const struct drm_framebuffer *fb = plane_state->base.fb;
352 enum plane_id plane_id = plane->id; 354 enum plane_id plane_id = plane->id;
353
354 /* Seems RGB data bypasses the CSC always */
355 if (!format_is_yuv(format))
356 return;
357
358 /* 355 /*
359 * BT.601 limited range YCbCr -> full range RGB 356 * |r| | c0 c1 c2 | |cr|
357 * |g| = | c3 c4 c5 | x |y |
358 * |b| | c6 c7 c8 | |cb|
360 * 359 *
361 * |r| | 6537 4769 0| |cr | 360 * Coefficients are s3.12.
362 * |g| = |-3330 4769 -1605| x |y-64|
363 * |b| | 0 4769 8263| |cb |
364 * 361 *
365 * Cb and Cr apparently come in as signed already, so no 362 * Cb and Cr apparently come in as signed already, and
366 * need for any offset. For Y we need to remove the offset. 363 * we always get full range data in on account of CLRC0/1.
367 */ 364 */
368 I915_WRITE_FW(SPCSCYGOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(-64)); 365 static const s16 csc_matrix[][9] = {
366 /* BT.601 full range YCbCr -> full range RGB */
367 [DRM_COLOR_YCBCR_BT601] = {
368 5743, 4096, 0,
369 -2925, 4096, -1410,
370 0, 4096, 7258,
371 },
372 /* BT.709 full range YCbCr -> full range RGB */
373 [DRM_COLOR_YCBCR_BT709] = {
374 6450, 4096, 0,
375 -1917, 4096, -767,
376 0, 4096, 7601,
377 },
378 };
379 const s16 *csc = csc_matrix[plane_state->base.color_encoding];
380
381 /* Seems RGB data bypasses the CSC always */
382 if (!intel_format_is_yuv(fb->format->format))
383 return;
384
385 I915_WRITE_FW(SPCSCYGOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
369 I915_WRITE_FW(SPCSCCBOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0)); 386 I915_WRITE_FW(SPCSCCBOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
370 I915_WRITE_FW(SPCSCCROFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0)); 387 I915_WRITE_FW(SPCSCCROFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
371 388
372 I915_WRITE_FW(SPCSCC01(plane_id), SPCSC_C1(4769) | SPCSC_C0(6537)); 389 I915_WRITE_FW(SPCSCC01(plane_id), SPCSC_C1(csc[1]) | SPCSC_C0(csc[0]));
373 I915_WRITE_FW(SPCSCC23(plane_id), SPCSC_C1(-3330) | SPCSC_C0(0)); 390 I915_WRITE_FW(SPCSCC23(plane_id), SPCSC_C1(csc[3]) | SPCSC_C0(csc[2]));
374 I915_WRITE_FW(SPCSCC45(plane_id), SPCSC_C1(-1605) | SPCSC_C0(4769)); 391 I915_WRITE_FW(SPCSCC45(plane_id), SPCSC_C1(csc[5]) | SPCSC_C0(csc[4]));
375 I915_WRITE_FW(SPCSCC67(plane_id), SPCSC_C1(4769) | SPCSC_C0(0)); 392 I915_WRITE_FW(SPCSCC67(plane_id), SPCSC_C1(csc[7]) | SPCSC_C0(csc[6]));
376 I915_WRITE_FW(SPCSCC8(plane_id), SPCSC_C0(8263)); 393 I915_WRITE_FW(SPCSCC8(plane_id), SPCSC_C0(csc[8]));
377 394
378 I915_WRITE_FW(SPCSCYGICLAMP(plane_id), SPCSC_IMAX(940) | SPCSC_IMIN(64)); 395 I915_WRITE_FW(SPCSCYGICLAMP(plane_id), SPCSC_IMAX(1023) | SPCSC_IMIN(0));
379 I915_WRITE_FW(SPCSCCBICLAMP(plane_id), SPCSC_IMAX(448) | SPCSC_IMIN(-448)); 396 I915_WRITE_FW(SPCSCCBICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512));
380 I915_WRITE_FW(SPCSCCRICLAMP(plane_id), SPCSC_IMAX(448) | SPCSC_IMIN(-448)); 397 I915_WRITE_FW(SPCSCCRICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512));
381 398
382 I915_WRITE_FW(SPCSCYGOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 399 I915_WRITE_FW(SPCSCYGOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
383 I915_WRITE_FW(SPCSCCBOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 400 I915_WRITE_FW(SPCSCCBOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
384 I915_WRITE_FW(SPCSCCROCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0)); 401 I915_WRITE_FW(SPCSCCROCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
385} 402}
386 403
404#define SIN_0 0
405#define COS_0 1
406
407static void
408vlv_update_clrc(const struct intel_plane_state *plane_state)
409{
410 struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
411 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
412 const struct drm_framebuffer *fb = plane_state->base.fb;
413 enum pipe pipe = plane->pipe;
414 enum plane_id plane_id = plane->id;
415 int contrast, brightness, sh_scale, sh_sin, sh_cos;
416
417 if (intel_format_is_yuv(fb->format->format) &&
418 plane_state->base.color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) {
419 /*
420 * Expand limited range to full range:
421 * Contrast is applied first and is used to expand Y range.
422 * Brightness is applied second and is used to remove the
423 * offset from Y. Saturation/hue is used to expand CbCr range.
424 */
425 contrast = DIV_ROUND_CLOSEST(255 << 6, 235 - 16);
426 brightness = -DIV_ROUND_CLOSEST(16 * 255, 235 - 16);
427 sh_scale = DIV_ROUND_CLOSEST(128 << 7, 240 - 128);
428 sh_sin = SIN_0 * sh_scale;
429 sh_cos = COS_0 * sh_scale;
430 } else {
431 /* Pass-through everything. */
432 contrast = 1 << 6;
433 brightness = 0;
434 sh_scale = 1 << 7;
435 sh_sin = SIN_0 * sh_scale;
436 sh_cos = COS_0 * sh_scale;
437 }
438
439 /* FIXME these register are single buffered :( */
440 I915_WRITE_FW(SPCLRC0(pipe, plane_id),
441 SP_CONTRAST(contrast) | SP_BRIGHTNESS(brightness));
442 I915_WRITE_FW(SPCLRC1(pipe, plane_id),
443 SP_SH_SIN(sh_sin) | SP_SH_COS(sh_cos));
444}
445
387static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state, 446static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state,
388 const struct intel_plane_state *plane_state) 447 const struct intel_plane_state *plane_state)
389{ 448{
@@ -433,6 +492,9 @@ static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state,
433 return 0; 492 return 0;
434 } 493 }
435 494
495 if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
496 sprctl |= SP_YUV_FORMAT_BT709;
497
436 if (fb->modifier == I915_FORMAT_MOD_X_TILED) 498 if (fb->modifier == I915_FORMAT_MOD_X_TILED)
437 sprctl |= SP_TILED; 499 sprctl |= SP_TILED;
438 500
@@ -477,8 +539,10 @@ vlv_update_plane(struct intel_plane *plane,
477 539
478 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); 540 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
479 541
542 vlv_update_clrc(plane_state);
543
480 if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) 544 if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B)
481 chv_update_csc(plane, fb->format->format); 545 chv_update_csc(plane_state);
482 546
483 if (key->flags) { 547 if (key->flags) {
484 I915_WRITE_FW(SPKEYMINVAL(pipe, plane_id), key->min_value); 548 I915_WRITE_FW(SPKEYMINVAL(pipe, plane_id), key->min_value);
@@ -584,6 +648,12 @@ static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state,
584 return 0; 648 return 0;
585 } 649 }
586 650
651 if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
652 sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709;
653
654 if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
655 sprctl |= SPRITE_YUV_RANGE_CORRECTION_DISABLE;
656
587 if (fb->modifier == I915_FORMAT_MOD_X_TILED) 657 if (fb->modifier == I915_FORMAT_MOD_X_TILED)
588 sprctl |= SPRITE_TILED; 658 sprctl |= SPRITE_TILED;
589 659
@@ -740,6 +810,12 @@ static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state,
740 return 0; 810 return 0;
741 } 811 }
742 812
813 if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
814 dvscntr |= DVS_YUV_FORMAT_BT709;
815
816 if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
817 dvscntr |= DVS_YUV_RANGE_CORRECTION_DISABLE;
818
743 if (fb->modifier == I915_FORMAT_MOD_X_TILED) 819 if (fb->modifier == I915_FORMAT_MOD_X_TILED)
744 dvscntr |= DVS_TILED; 820 dvscntr |= DVS_TILED;
745 821
@@ -979,7 +1055,7 @@ intel_check_sprite_plane(struct intel_plane *plane,
979 src_y = src->y1 >> 16; 1055 src_y = src->y1 >> 16;
980 src_h = drm_rect_height(src) >> 16; 1056 src_h = drm_rect_height(src) >> 16;
981 1057
982 if (format_is_yuv(fb->format->format)) { 1058 if (intel_format_is_yuv(fb->format->format)) {
983 src_x &= ~1; 1059 src_x &= ~1;
984 src_w &= ~1; 1060 src_w &= ~1;
985 1061
@@ -1459,6 +1535,14 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
1459 DRM_MODE_ROTATE_0, 1535 DRM_MODE_ROTATE_0,
1460 supported_rotations); 1536 supported_rotations);
1461 1537
1538 drm_plane_create_color_properties(&intel_plane->base,
1539 BIT(DRM_COLOR_YCBCR_BT601) |
1540 BIT(DRM_COLOR_YCBCR_BT709),
1541 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
1542 BIT(DRM_COLOR_YCBCR_FULL_RANGE),
1543 DRM_COLOR_YCBCR_BT709,
1544 DRM_COLOR_YCBCR_LIMITED_RANGE);
1545
1462 drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs); 1546 drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs);
1463 1547
1464 return intel_plane; 1548 return intel_plane;
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c
index 150628293c51..d7e3583e608e 100644
--- a/drivers/gpu/drm/imx/ipuv3-plane.c
+++ b/drivers/gpu/drm/imx/ipuv3-plane.c
@@ -351,7 +351,6 @@ static int ipu_plane_atomic_check(struct drm_plane *plane,
351 struct drm_framebuffer *old_fb = old_state->fb; 351 struct drm_framebuffer *old_fb = old_state->fb;
352 unsigned long eba, ubo, vbo, old_ubo, old_vbo, alpha_eba; 352 unsigned long eba, ubo, vbo, old_ubo, old_vbo, alpha_eba;
353 bool can_position = (plane->type == DRM_PLANE_TYPE_OVERLAY); 353 bool can_position = (plane->type == DRM_PLANE_TYPE_OVERLAY);
354 struct drm_rect clip = {};
355 int hsub, vsub; 354 int hsub, vsub;
356 int ret; 355 int ret;
357 356
@@ -367,11 +366,7 @@ static int ipu_plane_atomic_check(struct drm_plane *plane,
367 if (WARN_ON(!crtc_state)) 366 if (WARN_ON(!crtc_state))
368 return -EINVAL; 367 return -EINVAL;
369 368
370 if (crtc_state->enable) 369 ret = drm_atomic_helper_check_plane_state(state, crtc_state,
371 drm_mode_get_hv_timing(&crtc_state->mode,
372 &clip.x2, &clip.y2);
373
374 ret = drm_atomic_helper_check_plane_state(state, crtc_state, &clip,
375 DRM_PLANE_HELPER_NO_SCALING, 370 DRM_PLANE_HELPER_NO_SCALING,
376 DRM_PLANE_HELPER_NO_SCALING, 371 DRM_PLANE_HELPER_NO_SCALING,
377 can_position, true); 372 can_position, true);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
index b5c6eec9a584..2f4b0ffee598 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
@@ -91,7 +91,6 @@ static int mtk_plane_atomic_check(struct drm_plane *plane,
91{ 91{
92 struct drm_framebuffer *fb = state->fb; 92 struct drm_framebuffer *fb = state->fb;
93 struct drm_crtc_state *crtc_state; 93 struct drm_crtc_state *crtc_state;
94 struct drm_rect clip = { 0, };
95 94
96 if (!fb) 95 if (!fb)
97 return 0; 96 return 0;
@@ -108,11 +107,7 @@ static int mtk_plane_atomic_check(struct drm_plane *plane,
108 if (IS_ERR(crtc_state)) 107 if (IS_ERR(crtc_state))
109 return PTR_ERR(crtc_state); 108 return PTR_ERR(crtc_state);
110 109
111 if (crtc_state->enable) 110 return drm_atomic_helper_check_plane_state(state, crtc_state,
112 drm_mode_get_hv_timing(&crtc_state->mode,
113 &clip.x2, &clip.y2);
114
115 return drm_atomic_helper_check_plane_state(state, crtc_state, &clip,
116 DRM_PLANE_HELPER_NO_SCALING, 111 DRM_PLANE_HELPER_NO_SCALING,
117 DRM_PLANE_HELPER_NO_SCALING, 112 DRM_PLANE_HELPER_NO_SCALING,
118 true, true); 113 true, true);
diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c
index 3801bee1f9e6..c78a3a59f58c 100644
--- a/drivers/gpu/drm/meson/meson_plane.c
+++ b/drivers/gpu/drm/meson/meson_plane.c
@@ -49,7 +49,6 @@ static int meson_plane_atomic_check(struct drm_plane *plane,
49 struct drm_plane_state *state) 49 struct drm_plane_state *state)
50{ 50{
51 struct drm_crtc_state *crtc_state; 51 struct drm_crtc_state *crtc_state;
52 struct drm_rect clip = { 0, };
53 52
54 if (!state->crtc) 53 if (!state->crtc)
55 return 0; 54 return 0;
@@ -58,11 +57,7 @@ static int meson_plane_atomic_check(struct drm_plane *plane,
58 if (IS_ERR(crtc_state)) 57 if (IS_ERR(crtc_state))
59 return PTR_ERR(crtc_state); 58 return PTR_ERR(crtc_state);
60 59
61 if (crtc_state->enable) 60 return drm_atomic_helper_check_plane_state(state, crtc_state,
62 drm_mode_get_hv_timing(&crtc_state->mode,
63 &clip.x2, &clip.y2);
64
65 return drm_atomic_helper_check_plane_state(state, crtc_state, &clip,
66 DRM_PLANE_HELPER_NO_SCALING, 61 DRM_PLANE_HELPER_NO_SCALING,
67 DRM_PLANE_HELPER_NO_SCALING, 62 DRM_PLANE_HELPER_NO_SCALING,
68 true, true); 63 true, true);
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
index 98d4d7331767..44fc9fe4737a 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
@@ -286,7 +286,6 @@ static int mdp5_plane_atomic_check_with_state(struct drm_crtc_state *crtc_state,
286 uint32_t max_width, max_height; 286 uint32_t max_width, max_height;
287 bool out_of_bounds = false; 287 bool out_of_bounds = false;
288 uint32_t caps = 0; 288 uint32_t caps = 0;
289 struct drm_rect clip = {};
290 int min_scale, max_scale; 289 int min_scale, max_scale;
291 int ret; 290 int ret;
292 291
@@ -323,11 +322,7 @@ static int mdp5_plane_atomic_check_with_state(struct drm_crtc_state *crtc_state,
323 min_scale = FRAC_16_16(1, 8); 322 min_scale = FRAC_16_16(1, 8);
324 max_scale = FRAC_16_16(8, 1); 323 max_scale = FRAC_16_16(8, 1);
325 324
326 if (crtc_state->enable) 325 ret = drm_atomic_helper_check_plane_state(state, crtc_state,
327 drm_mode_get_hv_timing(&crtc_state->mode,
328 &clip.x2, &clip.y2);
329
330 ret = drm_atomic_helper_check_plane_state(state, crtc_state, &clip,
331 min_scale, max_scale, 326 min_scale, max_scale,
332 true, true); 327 true, true);
333 if (ret) 328 if (ret)
@@ -471,7 +466,6 @@ static int mdp5_plane_atomic_async_check(struct drm_plane *plane,
471{ 466{
472 struct mdp5_plane_state *mdp5_state = to_mdp5_plane_state(state); 467 struct mdp5_plane_state *mdp5_state = to_mdp5_plane_state(state);
473 struct drm_crtc_state *crtc_state; 468 struct drm_crtc_state *crtc_state;
474 struct drm_rect clip = {};
475 int min_scale, max_scale; 469 int min_scale, max_scale;
476 int ret; 470 int ret;
477 471
@@ -502,11 +496,7 @@ static int mdp5_plane_atomic_async_check(struct drm_plane *plane,
502 min_scale = FRAC_16_16(1, 8); 496 min_scale = FRAC_16_16(1, 8);
503 max_scale = FRAC_16_16(8, 1); 497 max_scale = FRAC_16_16(8, 1);
504 498
505 if (crtc_state->enable) 499 ret = drm_atomic_helper_check_plane_state(state, crtc_state,
506 drm_mode_get_hv_timing(&crtc_state->mode,
507 &clip.x2, &clip.y2);
508
509 ret = drm_atomic_helper_check_plane_state(state, crtc_state, &clip,
510 min_scale, max_scale, 500 min_scale, max_scale,
511 true, true); 501 true, true);
512 if (ret) 502 if (ret)
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
index 1207ffe36250..5cae8db9dcd4 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
@@ -131,11 +131,37 @@ static int mxsfb_pipe_prepare_fb(struct drm_simple_display_pipe *pipe,
131 return drm_gem_fb_prepare_fb(&pipe->plane, plane_state); 131 return drm_gem_fb_prepare_fb(&pipe->plane, plane_state);
132} 132}
133 133
134static int mxsfb_pipe_enable_vblank(struct drm_simple_display_pipe *pipe)
135{
136 struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe);
137
138 /* Clear and enable VBLANK IRQ */
139 mxsfb_enable_axi_clk(mxsfb);
140 writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
141 writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_SET);
142 mxsfb_disable_axi_clk(mxsfb);
143
144 return 0;
145}
146
147static void mxsfb_pipe_disable_vblank(struct drm_simple_display_pipe *pipe)
148{
149 struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe);
150
151 /* Disable and clear VBLANK IRQ */
152 mxsfb_enable_axi_clk(mxsfb);
153 writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_CLR);
154 writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
155 mxsfb_disable_axi_clk(mxsfb);
156}
157
134static struct drm_simple_display_pipe_funcs mxsfb_funcs = { 158static struct drm_simple_display_pipe_funcs mxsfb_funcs = {
135 .enable = mxsfb_pipe_enable, 159 .enable = mxsfb_pipe_enable,
136 .disable = mxsfb_pipe_disable, 160 .disable = mxsfb_pipe_disable,
137 .update = mxsfb_pipe_update, 161 .update = mxsfb_pipe_update,
138 .prepare_fb = mxsfb_pipe_prepare_fb, 162 .prepare_fb = mxsfb_pipe_prepare_fb,
163 .enable_vblank = mxsfb_pipe_enable_vblank,
164 .disable_vblank = mxsfb_pipe_disable_vblank,
139}; 165};
140 166
141static int mxsfb_load(struct drm_device *drm, unsigned long flags) 167static int mxsfb_load(struct drm_device *drm, unsigned long flags)
@@ -274,33 +300,11 @@ static void mxsfb_lastclose(struct drm_device *drm)
274 drm_fbdev_cma_restore_mode(mxsfb->fbdev); 300 drm_fbdev_cma_restore_mode(mxsfb->fbdev);
275} 301}
276 302
277static int mxsfb_enable_vblank(struct drm_device *drm, unsigned int crtc) 303static void mxsfb_irq_preinstall(struct drm_device *drm)
278{
279 struct mxsfb_drm_private *mxsfb = drm->dev_private;
280
281 /* Clear and enable VBLANK IRQ */
282 mxsfb_enable_axi_clk(mxsfb);
283 writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
284 writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_SET);
285 mxsfb_disable_axi_clk(mxsfb);
286
287 return 0;
288}
289
290static void mxsfb_disable_vblank(struct drm_device *drm, unsigned int crtc)
291{ 304{
292 struct mxsfb_drm_private *mxsfb = drm->dev_private; 305 struct mxsfb_drm_private *mxsfb = drm->dev_private;
293 306
294 /* Disable and clear VBLANK IRQ */ 307 mxsfb_pipe_disable_vblank(&mxsfb->pipe);
295 mxsfb_enable_axi_clk(mxsfb);
296 writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_CLR);
297 writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
298 mxsfb_disable_axi_clk(mxsfb);
299}
300
301static void mxsfb_irq_preinstall(struct drm_device *drm)
302{
303 mxsfb_disable_vblank(drm, 0);
304} 308}
305 309
306static irqreturn_t mxsfb_irq_handler(int irq, void *data) 310static irqreturn_t mxsfb_irq_handler(int irq, void *data)
@@ -333,8 +337,6 @@ static struct drm_driver mxsfb_driver = {
333 .irq_handler = mxsfb_irq_handler, 337 .irq_handler = mxsfb_irq_handler,
334 .irq_preinstall = mxsfb_irq_preinstall, 338 .irq_preinstall = mxsfb_irq_preinstall,
335 .irq_uninstall = mxsfb_irq_preinstall, 339 .irq_uninstall = mxsfb_irq_preinstall,
336 .enable_vblank = mxsfb_enable_vblank,
337 .disable_vblank = mxsfb_disable_vblank,
338 .gem_free_object_unlocked = drm_gem_cma_free_object, 340 .gem_free_object_unlocked = drm_gem_cma_free_object,
339 .gem_vm_ops = &drm_gem_cma_vm_ops, 341 .gem_vm_ops = &drm_gem_cma_vm_ops,
340 .dumb_create = drm_gem_cma_dumb_create, 342 .dumb_create = drm_gem_cma_dumb_create,
diff --git a/drivers/gpu/drm/nouveau/dispnv04/overlay.c b/drivers/gpu/drm/nouveau/dispnv04/overlay.c
index c8c2333f24ee..df4358e31075 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/overlay.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/overlay.c
@@ -46,7 +46,6 @@ struct nouveau_plane {
46 struct drm_property *brightness; 46 struct drm_property *brightness;
47 struct drm_property *hue; 47 struct drm_property *hue;
48 struct drm_property *saturation; 48 struct drm_property *saturation;
49 struct drm_property *iturbt_709;
50 } props; 49 } props;
51 50
52 int colorkey; 51 int colorkey;
@@ -54,7 +53,7 @@ struct nouveau_plane {
54 int brightness; 53 int brightness;
55 int hue; 54 int hue;
56 int saturation; 55 int saturation;
57 int iturbt_709; 56 enum drm_color_encoding color_encoding;
58 57
59 void (*set_params)(struct nouveau_plane *); 58 void (*set_params)(struct nouveau_plane *);
60}; 59};
@@ -166,7 +165,7 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
166 if (fb->format->format == DRM_FORMAT_NV12 || 165 if (fb->format->format == DRM_FORMAT_NV12 ||
167 fb->format->format == DRM_FORMAT_NV21) 166 fb->format->format == DRM_FORMAT_NV21)
168 format |= NV_PVIDEO_FORMAT_PLANAR; 167 format |= NV_PVIDEO_FORMAT_PLANAR;
169 if (nv_plane->iturbt_709) 168 if (nv_plane->color_encoding == DRM_COLOR_YCBCR_BT709)
170 format |= NV_PVIDEO_FORMAT_MATRIX_ITURBT709; 169 format |= NV_PVIDEO_FORMAT_MATRIX_ITURBT709;
171 if (nv_plane->colorkey & (1 << 24)) 170 if (nv_plane->colorkey & (1 << 24))
172 format |= NV_PVIDEO_FORMAT_DISPLAY_COLOR_KEY; 171 format |= NV_PVIDEO_FORMAT_DISPLAY_COLOR_KEY;
@@ -229,7 +228,7 @@ nv10_set_params(struct nouveau_plane *plane)
229 nvif_wr32(dev, NV_PVIDEO_COLOR_KEY, plane->colorkey & 0xffffff); 228 nvif_wr32(dev, NV_PVIDEO_COLOR_KEY, plane->colorkey & 0xffffff);
230 229
231 if (plane->cur) { 230 if (plane->cur) {
232 if (plane->iturbt_709) 231 if (plane->color_encoding == DRM_COLOR_YCBCR_BT709)
233 format |= NV_PVIDEO_FORMAT_MATRIX_ITURBT709; 232 format |= NV_PVIDEO_FORMAT_MATRIX_ITURBT709;
234 if (plane->colorkey & (1 << 24)) 233 if (plane->colorkey & (1 << 24))
235 format |= NV_PVIDEO_FORMAT_DISPLAY_COLOR_KEY; 234 format |= NV_PVIDEO_FORMAT_DISPLAY_COLOR_KEY;
@@ -258,8 +257,8 @@ nv_set_property(struct drm_plane *plane,
258 nv_plane->hue = value; 257 nv_plane->hue = value;
259 else if (property == nv_plane->props.saturation) 258 else if (property == nv_plane->props.saturation)
260 nv_plane->saturation = value; 259 nv_plane->saturation = value;
261 else if (property == nv_plane->props.iturbt_709) 260 else if (property == nv_plane->base.color_encoding_property)
262 nv_plane->iturbt_709 = value; 261 nv_plane->color_encoding = value;
263 else 262 else
264 return -EINVAL; 263 return -EINVAL;
265 264
@@ -313,14 +312,11 @@ nv10_overlay_init(struct drm_device *device)
313 device, 0, "hue", 0, 359); 312 device, 0, "hue", 0, 359);
314 plane->props.saturation = drm_property_create_range( 313 plane->props.saturation = drm_property_create_range(
315 device, 0, "saturation", 0, 8192 - 1); 314 device, 0, "saturation", 0, 8192 - 1);
316 plane->props.iturbt_709 = drm_property_create_range(
317 device, 0, "iturbt_709", 0, 1);
318 if (!plane->props.colorkey || 315 if (!plane->props.colorkey ||
319 !plane->props.contrast || 316 !plane->props.contrast ||
320 !plane->props.brightness || 317 !plane->props.brightness ||
321 !plane->props.hue || 318 !plane->props.hue ||
322 !plane->props.saturation || 319 !plane->props.saturation)
323 !plane->props.iturbt_709)
324 goto cleanup; 320 goto cleanup;
325 321
326 plane->colorkey = 0; 322 plane->colorkey = 0;
@@ -343,9 +339,13 @@ nv10_overlay_init(struct drm_device *device)
343 drm_object_attach_property(&plane->base.base, 339 drm_object_attach_property(&plane->base.base,
344 plane->props.saturation, plane->saturation); 340 plane->props.saturation, plane->saturation);
345 341
346 plane->iturbt_709 = 0; 342 plane->color_encoding = DRM_COLOR_YCBCR_BT601;
347 drm_object_attach_property(&plane->base.base, 343 drm_plane_create_color_properties(&plane->base,
348 plane->props.iturbt_709, plane->iturbt_709); 344 BIT(DRM_COLOR_YCBCR_BT601) |
345 BIT(DRM_COLOR_YCBCR_BT709),
346 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE),
347 DRM_COLOR_YCBCR_BT601,
348 DRM_COLOR_YCBCR_LIMITED_RANGE);
349 349
350 plane->set_params = nv10_set_params; 350 plane->set_params = nv10_set_params;
351 nv10_set_params(plane); 351 nv10_set_params(plane);
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 1f55b3d80a56..6af3bc483c84 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -1143,15 +1143,9 @@ static int
1143nv50_curs_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, 1143nv50_curs_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
1144 struct nv50_head_atom *asyh) 1144 struct nv50_head_atom *asyh)
1145{ 1145{
1146 struct drm_rect clip = {};
1147 int ret; 1146 int ret;
1148 1147
1149 if (asyh->state.enable)
1150 drm_mode_get_hv_timing(&asyh->state.mode,
1151 &clip.x2, &clip.y2);
1152
1153 ret = drm_atomic_helper_check_plane_state(&asyw->state, &asyh->state, 1148 ret = drm_atomic_helper_check_plane_state(&asyw->state, &asyh->state,
1154 &clip,
1155 DRM_PLANE_HELPER_NO_SCALING, 1149 DRM_PLANE_HELPER_NO_SCALING,
1156 DRM_PLANE_HELPER_NO_SCALING, 1150 DRM_PLANE_HELPER_NO_SCALING,
1157 true, true); 1151 true, true);
@@ -1435,18 +1429,12 @@ nv50_base_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
1435 struct nv50_head_atom *asyh) 1429 struct nv50_head_atom *asyh)
1436{ 1430{
1437 const struct drm_framebuffer *fb = asyw->state.fb; 1431 const struct drm_framebuffer *fb = asyw->state.fb;
1438 struct drm_rect clip = {};
1439 int ret; 1432 int ret;
1440 1433
1441 if (!fb->format->depth) 1434 if (!fb->format->depth)
1442 return -EINVAL; 1435 return -EINVAL;
1443 1436
1444 if (asyh->state.enable)
1445 drm_mode_get_hv_timing(&asyh->state.mode,
1446 &clip.x2, &clip.y2);
1447
1448 ret = drm_atomic_helper_check_plane_state(&asyw->state, &asyh->state, 1437 ret = drm_atomic_helper_check_plane_state(&asyw->state, &asyh->state,
1449 &clip,
1450 DRM_PLANE_HELPER_NO_SCALING, 1438 DRM_PLANE_HELPER_NO_SCALING,
1451 DRM_PLANE_HELPER_NO_SCALING, 1439 DRM_PLANE_HELPER_NO_SCALING,
1452 false, true); 1440 false, true);
diff --git a/drivers/gpu/drm/panel/panel-arm-versatile.c b/drivers/gpu/drm/panel/panel-arm-versatile.c
index 3930b4925b15..b428c4678106 100644
--- a/drivers/gpu/drm/panel/panel-arm-versatile.c
+++ b/drivers/gpu/drm/panel/panel-arm-versatile.c
@@ -132,7 +132,7 @@ static const struct versatile_panel_type versatile_panels[] = {
132 .width_mm = 79, 132 .width_mm = 79,
133 .height_mm = 54, 133 .height_mm = 54,
134 .mode = { 134 .mode = {
135 .clock = 10000000, 135 .clock = 10000,
136 .hdisplay = 320, 136 .hdisplay = 320,
137 .hsync_start = 320 + 6, 137 .hsync_start = 320 + 6,
138 .hsync_end = 320 + 6 + 6, 138 .hsync_end = 320 + 6 + 6,
@@ -156,7 +156,7 @@ static const struct versatile_panel_type versatile_panels[] = {
156 .width_mm = 171, 156 .width_mm = 171,
157 .height_mm = 130, 157 .height_mm = 130,
158 .mode = { 158 .mode = {
159 .clock = 25000000, 159 .clock = 25000,
160 .hdisplay = 640, 160 .hdisplay = 640,
161 .hsync_start = 640 + 24, 161 .hsync_start = 640 + 24,
162 .hsync_end = 640 + 24 + 96, 162 .hsync_end = 640 + 24 + 96,
@@ -179,7 +179,7 @@ static const struct versatile_panel_type versatile_panels[] = {
179 .width_mm = 34, 179 .width_mm = 34,
180 .height_mm = 45, 180 .height_mm = 45,
181 .mode = { 181 .mode = {
182 .clock = 625000000, 182 .clock = 62500,
183 .hdisplay = 176, 183 .hdisplay = 176,
184 .hsync_start = 176 + 2, 184 .hsync_start = 176 + 2,
185 .hsync_end = 176 + 2 + 3, 185 .hsync_end = 176 + 2 + 3,
@@ -203,7 +203,7 @@ static const struct versatile_panel_type versatile_panels[] = {
203 .width_mm = 37, 203 .width_mm = 37,
204 .height_mm = 50, 204 .height_mm = 50,
205 .mode = { 205 .mode = {
206 .clock = 5400000, 206 .clock = 5400,
207 .hdisplay = 240, 207 .hdisplay = 240,
208 .hsync_start = 240 + 10, 208 .hsync_start = 240 + 10,
209 .hsync_end = 240 + 10 + 10, 209 .hsync_end = 240 + 10 + 10,
diff --git a/drivers/gpu/drm/pl111/Kconfig b/drivers/gpu/drm/pl111/Kconfig
index 82cb3e60ddc8..e5e2abd66491 100644
--- a/drivers/gpu/drm/pl111/Kconfig
+++ b/drivers/gpu/drm/pl111/Kconfig
@@ -8,7 +8,6 @@ config DRM_PL111
8 select DRM_GEM_CMA_HELPER 8 select DRM_GEM_CMA_HELPER
9 select DRM_BRIDGE 9 select DRM_BRIDGE
10 select DRM_PANEL_BRIDGE 10 select DRM_PANEL_BRIDGE
11 select DRM_DUMB_VGA_DAC
12 select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE 11 select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE
13 help 12 help
14 Choose this option for DRM support for the PL111 CLCD controller. 13 Choose this option for DRM support for the PL111 CLCD controller.
diff --git a/drivers/gpu/drm/pl111/pl111_display.c b/drivers/gpu/drm/pl111/pl111_display.c
index d75923896609..310646427907 100644
--- a/drivers/gpu/drm/pl111/pl111_display.c
+++ b/drivers/gpu/drm/pl111/pl111_display.c
@@ -50,6 +50,41 @@ irqreturn_t pl111_irq(int irq, void *data)
50 return status; 50 return status;
51} 51}
52 52
53static enum drm_mode_status
54pl111_mode_valid(struct drm_crtc *crtc,
55 const struct drm_display_mode *mode)
56{
57 struct drm_device *drm = crtc->dev;
58 struct pl111_drm_dev_private *priv = drm->dev_private;
59 u32 cpp = priv->variant->fb_bpp / 8;
60 u64 bw;
61
62 /*
63 * We use the pixelclock to also account for interlaced modes, the
64 * resulting bandwidth is in bytes per second.
65 */
66 bw = mode->clock * 1000; /* In Hz */
67 bw = bw * mode->hdisplay * mode->vdisplay * cpp;
68 bw = div_u64(bw, mode->htotal * mode->vtotal);
69
70 /*
71 * If no bandwidth constraints, anything goes, else
72 * check if we are too fast.
73 */
74 if (priv->memory_bw && (bw > priv->memory_bw)) {
75 DRM_DEBUG_KMS("%d x %d @ %d Hz, %d cpp, bw %llu too fast\n",
76 mode->hdisplay, mode->vdisplay,
77 mode->clock * 1000, cpp, bw);
78
79 return MODE_BAD;
80 }
81 DRM_DEBUG_KMS("%d x %d @ %d Hz, %d cpp, bw %llu bytes/s OK\n",
82 mode->hdisplay, mode->vdisplay,
83 mode->clock * 1000, cpp, bw);
84
85 return MODE_OK;
86}
87
53static int pl111_display_check(struct drm_simple_display_pipe *pipe, 88static int pl111_display_check(struct drm_simple_display_pipe *pipe,
54 struct drm_plane_state *pstate, 89 struct drm_plane_state *pstate,
55 struct drm_crtc_state *cstate) 90 struct drm_crtc_state *cstate)
@@ -321,8 +356,10 @@ static void pl111_display_update(struct drm_simple_display_pipe *pipe,
321 } 356 }
322} 357}
323 358
324int pl111_enable_vblank(struct drm_device *drm, unsigned int crtc) 359static int pl111_display_enable_vblank(struct drm_simple_display_pipe *pipe)
325{ 360{
361 struct drm_crtc *crtc = &pipe->crtc;
362 struct drm_device *drm = crtc->dev;
326 struct pl111_drm_dev_private *priv = drm->dev_private; 363 struct pl111_drm_dev_private *priv = drm->dev_private;
327 364
328 writel(CLCD_IRQ_NEXTBASE_UPDATE, priv->regs + priv->ienb); 365 writel(CLCD_IRQ_NEXTBASE_UPDATE, priv->regs + priv->ienb);
@@ -330,8 +367,10 @@ int pl111_enable_vblank(struct drm_device *drm, unsigned int crtc)
330 return 0; 367 return 0;
331} 368}
332 369
333void pl111_disable_vblank(struct drm_device *drm, unsigned int crtc) 370static void pl111_display_disable_vblank(struct drm_simple_display_pipe *pipe)
334{ 371{
372 struct drm_crtc *crtc = &pipe->crtc;
373 struct drm_device *drm = crtc->dev;
335 struct pl111_drm_dev_private *priv = drm->dev_private; 374 struct pl111_drm_dev_private *priv = drm->dev_private;
336 375
337 writel(0, priv->regs + priv->ienb); 376 writel(0, priv->regs + priv->ienb);
@@ -343,7 +382,8 @@ static int pl111_display_prepare_fb(struct drm_simple_display_pipe *pipe,
343 return drm_gem_fb_prepare_fb(&pipe->plane, plane_state); 382 return drm_gem_fb_prepare_fb(&pipe->plane, plane_state);
344} 383}
345 384
346static const struct drm_simple_display_pipe_funcs pl111_display_funcs = { 385static struct drm_simple_display_pipe_funcs pl111_display_funcs = {
386 .mode_valid = pl111_mode_valid,
347 .check = pl111_display_check, 387 .check = pl111_display_check,
348 .enable = pl111_display_enable, 388 .enable = pl111_display_enable,
349 .disable = pl111_display_disable, 389 .disable = pl111_display_disable,
@@ -502,6 +542,11 @@ int pl111_display_init(struct drm_device *drm)
502 if (ret) 542 if (ret)
503 return ret; 543 return ret;
504 544
545 if (!priv->variant->broken_vblank) {
546 pl111_display_funcs.enable_vblank = pl111_display_enable_vblank;
547 pl111_display_funcs.disable_vblank = pl111_display_disable_vblank;
548 }
549
505 ret = drm_simple_display_pipe_init(drm, &priv->pipe, 550 ret = drm_simple_display_pipe_init(drm, &priv->pipe,
506 &pl111_display_funcs, 551 &pl111_display_funcs,
507 priv->variant->formats, 552 priv->variant->formats,
diff --git a/drivers/gpu/drm/pl111/pl111_drm.h b/drivers/gpu/drm/pl111/pl111_drm.h
index 6d0e450e51b1..8639b2d4ddf7 100644
--- a/drivers/gpu/drm/pl111/pl111_drm.h
+++ b/drivers/gpu/drm/pl111/pl111_drm.h
@@ -43,6 +43,7 @@ struct drm_minor;
43 * @broken_vblank: the vblank IRQ is broken on this variant 43 * @broken_vblank: the vblank IRQ is broken on this variant
44 * @formats: array of supported pixel formats on this variant 44 * @formats: array of supported pixel formats on this variant
45 * @nformats: the length of the array of supported pixel formats 45 * @nformats: the length of the array of supported pixel formats
46 * @fb_bpp: desired bits per pixel on the default framebuffer
46 */ 47 */
47struct pl111_variant_data { 48struct pl111_variant_data {
48 const char *name; 49 const char *name;
@@ -52,6 +53,7 @@ struct pl111_variant_data {
52 bool broken_vblank; 53 bool broken_vblank;
53 const u32 *formats; 54 const u32 *formats;
54 unsigned int nformats; 55 unsigned int nformats;
56 unsigned int fb_bpp;
55}; 57};
56 58
57struct pl111_drm_dev_private { 59struct pl111_drm_dev_private {
@@ -63,6 +65,7 @@ struct pl111_drm_dev_private {
63 struct drm_simple_display_pipe pipe; 65 struct drm_simple_display_pipe pipe;
64 66
65 void *regs; 67 void *regs;
68 u32 memory_bw;
66 u32 ienb; 69 u32 ienb;
67 u32 ctrl; 70 u32 ctrl;
68 /* The pixel clock (a reference to our clock divider off of CLCDCLK). */ 71 /* The pixel clock (a reference to our clock divider off of CLCDCLK). */
@@ -79,8 +82,6 @@ struct pl111_drm_dev_private {
79}; 82};
80 83
81int pl111_display_init(struct drm_device *dev); 84int pl111_display_init(struct drm_device *dev);
82int pl111_enable_vblank(struct drm_device *drm, unsigned int crtc);
83void pl111_disable_vblank(struct drm_device *drm, unsigned int crtc);
84irqreturn_t pl111_irq(int irq, void *data); 85irqreturn_t pl111_irq(int irq, void *data);
85int pl111_debugfs_init(struct drm_minor *minor); 86int pl111_debugfs_init(struct drm_minor *minor);
86 87
diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c
index 1231905150d0..4621259d5387 100644
--- a/drivers/gpu/drm/pl111/pl111_drv.c
+++ b/drivers/gpu/drm/pl111/pl111_drv.c
@@ -192,7 +192,7 @@ static int pl111_modeset_init(struct drm_device *dev)
192 192
193 drm_mode_config_reset(dev); 193 drm_mode_config_reset(dev);
194 194
195 drm_fb_cma_fbdev_init(dev, 32, 0); 195 drm_fb_cma_fbdev_init(dev, priv->variant->fb_bpp, 0);
196 196
197 drm_kms_helper_poll_init(dev); 197 drm_kms_helper_poll_init(dev);
198 198
@@ -249,11 +249,6 @@ static int pl111_amba_probe(struct amba_device *amba_dev,
249 if (!priv) 249 if (!priv)
250 return -ENOMEM; 250 return -ENOMEM;
251 251
252 if (!variant->broken_vblank) {
253 pl111_drm_driver.enable_vblank = pl111_enable_vblank;
254 pl111_drm_driver.disable_vblank = pl111_disable_vblank;
255 }
256
257 drm = drm_dev_alloc(&pl111_drm_driver, dev); 252 drm = drm_dev_alloc(&pl111_drm_driver, dev);
258 if (IS_ERR(drm)) 253 if (IS_ERR(drm))
259 return PTR_ERR(drm); 254 return PTR_ERR(drm);
@@ -262,6 +257,12 @@ static int pl111_amba_probe(struct amba_device *amba_dev,
262 drm->dev_private = priv; 257 drm->dev_private = priv;
263 priv->variant = variant; 258 priv->variant = variant;
264 259
260 if (of_property_read_u32(dev->of_node, "max-memory-bandwidth",
261 &priv->memory_bw)) {
262 dev_info(dev, "no max memory bandwidth specified, assume unlimited\n");
263 priv->memory_bw = 0;
264 }
265
265 /* The two variants swap this register */ 266 /* The two variants swap this register */
266 if (variant->is_pl110) { 267 if (variant->is_pl110) {
267 priv->ienb = CLCD_PL110_IENB; 268 priv->ienb = CLCD_PL110_IENB;
@@ -341,6 +342,7 @@ static const struct pl111_variant_data pl110_variant = {
341 .is_pl110 = true, 342 .is_pl110 = true,
342 .formats = pl110_pixel_formats, 343 .formats = pl110_pixel_formats,
343 .nformats = ARRAY_SIZE(pl110_pixel_formats), 344 .nformats = ARRAY_SIZE(pl110_pixel_formats),
345 .fb_bpp = 16,
344}; 346};
345 347
346/* RealView, Versatile Express etc use this modern variant */ 348/* RealView, Versatile Express etc use this modern variant */
@@ -365,6 +367,7 @@ static const struct pl111_variant_data pl111_variant = {
365 .name = "PL111", 367 .name = "PL111",
366 .formats = pl111_pixel_formats, 368 .formats = pl111_pixel_formats,
367 .nformats = ARRAY_SIZE(pl111_pixel_formats), 369 .nformats = ARRAY_SIZE(pl111_pixel_formats),
370 .fb_bpp = 32,
368}; 371};
369 372
370static const struct amba_id pl111_id_table[] = { 373static const struct amba_id pl111_id_table[] = {
diff --git a/drivers/gpu/drm/pl111/pl111_versatile.c b/drivers/gpu/drm/pl111/pl111_versatile.c
index 05a4b89e0934..9302f516045e 100644
--- a/drivers/gpu/drm/pl111/pl111_versatile.c
+++ b/drivers/gpu/drm/pl111/pl111_versatile.c
@@ -230,6 +230,23 @@ static const u32 pl110_versatile_pixel_formats[] = {
230 DRM_FORMAT_XRGB1555, 230 DRM_FORMAT_XRGB1555,
231}; 231};
232 232
233static const u32 pl111_realview_pixel_formats[] = {
234 DRM_FORMAT_ABGR8888,
235 DRM_FORMAT_XBGR8888,
236 DRM_FORMAT_ARGB8888,
237 DRM_FORMAT_XRGB8888,
238 DRM_FORMAT_BGR565,
239 DRM_FORMAT_RGB565,
240 DRM_FORMAT_ABGR1555,
241 DRM_FORMAT_XBGR1555,
242 DRM_FORMAT_ARGB1555,
243 DRM_FORMAT_XRGB1555,
244 DRM_FORMAT_ABGR4444,
245 DRM_FORMAT_XBGR4444,
246 DRM_FORMAT_ARGB4444,
247 DRM_FORMAT_XRGB4444,
248};
249
233/* 250/*
234 * The Integrator variant is a PL110 with a bunch of broken, or not 251 * The Integrator variant is a PL110 with a bunch of broken, or not
235 * yet implemented features 252 * yet implemented features
@@ -241,6 +258,7 @@ static const struct pl111_variant_data pl110_integrator = {
241 .broken_vblank = true, 258 .broken_vblank = true,
242 .formats = pl110_integrator_pixel_formats, 259 .formats = pl110_integrator_pixel_formats,
243 .nformats = ARRAY_SIZE(pl110_integrator_pixel_formats), 260 .nformats = ARRAY_SIZE(pl110_integrator_pixel_formats),
261 .fb_bpp = 16,
244}; 262};
245 263
246/* 264/*
@@ -253,6 +271,19 @@ static const struct pl111_variant_data pl110_versatile = {
253 .external_bgr = true, 271 .external_bgr = true,
254 .formats = pl110_versatile_pixel_formats, 272 .formats = pl110_versatile_pixel_formats,
255 .nformats = ARRAY_SIZE(pl110_versatile_pixel_formats), 273 .nformats = ARRAY_SIZE(pl110_versatile_pixel_formats),
274 .fb_bpp = 16,
275};
276
277/*
278 * RealView PL111 variant, the only real difference from the vanilla
279 * PL111 is that we select 16bpp framebuffer by default to be able
280 * to get 1024x768 without saturating the memory bus.
281 */
282static const struct pl111_variant_data pl111_realview = {
283 .name = "PL111 RealView",
284 .formats = pl111_realview_pixel_formats,
285 .nformats = ARRAY_SIZE(pl111_realview_pixel_formats),
286 .fb_bpp = 16,
256}; 287};
257 288
258int pl111_versatile_init(struct device *dev, struct pl111_drm_dev_private *priv) 289int pl111_versatile_init(struct device *dev, struct pl111_drm_dev_private *priv)
@@ -304,6 +335,7 @@ int pl111_versatile_init(struct device *dev, struct pl111_drm_dev_private *priv)
304 case REALVIEW_CLCD_PBA8: 335 case REALVIEW_CLCD_PBA8:
305 case REALVIEW_CLCD_PBX: 336 case REALVIEW_CLCD_PBX:
306 versatile_syscon_map = map; 337 versatile_syscon_map = map;
338 priv->variant = &pl111_realview;
307 priv->variant_display_enable = pl111_realview_clcd_enable; 339 priv->variant_display_enable = pl111_realview_clcd_enable;
308 priv->variant_display_disable = pl111_realview_clcd_disable; 340 priv->variant_display_disable = pl111_realview_clcd_disable;
309 dev_info(dev, "set up callbacks for RealView PL111\n"); 341 dev_info(dev, "set up callbacks for RealView PL111\n");
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
index 5687a94d4cb1..68556bd9dad2 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
@@ -572,7 +572,6 @@ int __rcar_du_plane_atomic_check(struct drm_plane *plane,
572{ 572{
573 struct drm_device *dev = plane->dev; 573 struct drm_device *dev = plane->dev;
574 struct drm_crtc_state *crtc_state; 574 struct drm_crtc_state *crtc_state;
575 struct drm_rect clip = {};
576 int ret; 575 int ret;
577 576
578 if (!state->crtc) { 577 if (!state->crtc) {
@@ -589,11 +588,7 @@ int __rcar_du_plane_atomic_check(struct drm_plane *plane,
589 if (IS_ERR(crtc_state)) 588 if (IS_ERR(crtc_state))
590 return PTR_ERR(crtc_state); 589 return PTR_ERR(crtc_state);
591 590
592 if (crtc_state->enable) 591 ret = drm_atomic_helper_check_plane_state(state, crtc_state,
593 drm_mode_get_hv_timing(&crtc_state->mode,
594 &clip.x2, &clip.y2);
595
596 ret = drm_atomic_helper_check_plane_state(state, crtc_state, &clip,
597 DRM_PLANE_HELPER_NO_SCALING, 592 DRM_PLANE_HELPER_NO_SCALING,
598 DRM_PLANE_HELPER_NO_SCALING, 593 DRM_PLANE_HELPER_NO_SCALING,
599 true, true); 594 true, true);
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 1262120a3834..7d76ff47028d 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -77,6 +77,7 @@ struct rockchip_dp_device {
77 77
78 const struct rockchip_dp_chip_data *data; 78 const struct rockchip_dp_chip_data *data;
79 79
80 struct analogix_dp_device *adp;
80 struct analogix_dp_plat_data plat_data; 81 struct analogix_dp_plat_data plat_data;
81}; 82};
82 83
@@ -84,7 +85,7 @@ static void analogix_dp_psr_set(struct drm_encoder *encoder, bool enabled)
84{ 85{
85 struct rockchip_dp_device *dp = to_dp(encoder); 86 struct rockchip_dp_device *dp = to_dp(encoder);
86 87
87 if (!analogix_dp_psr_supported(dp->dev)) 88 if (!analogix_dp_psr_supported(dp->adp))
88 return; 89 return;
89 90
90 DRM_DEV_DEBUG(dp->dev, "%s PSR...\n", enabled ? "Entry" : "Exit"); 91 DRM_DEV_DEBUG(dp->dev, "%s PSR...\n", enabled ? "Entry" : "Exit");
@@ -114,9 +115,9 @@ static void analogix_dp_psr_work(struct work_struct *work)
114 115
115 mutex_lock(&dp->psr_lock); 116 mutex_lock(&dp->psr_lock);
116 if (dp->psr_state == EDP_VSC_PSR_STATE_ACTIVE) 117 if (dp->psr_state == EDP_VSC_PSR_STATE_ACTIVE)
117 analogix_dp_enable_psr(dp->dev); 118 analogix_dp_enable_psr(dp->adp);
118 else 119 else
119 analogix_dp_disable_psr(dp->dev); 120 analogix_dp_disable_psr(dp->adp);
120 mutex_unlock(&dp->psr_lock); 121 mutex_unlock(&dp->psr_lock);
121} 122}
122 123
@@ -149,12 +150,17 @@ static int rockchip_dp_poweron(struct analogix_dp_plat_data *plat_data)
149 return ret; 150 return ret;
150 } 151 }
151 152
152 return 0; 153 return rockchip_drm_psr_activate(&dp->encoder);
153} 154}
154 155
155static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data) 156static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data)
156{ 157{
157 struct rockchip_dp_device *dp = to_dp(plat_data); 158 struct rockchip_dp_device *dp = to_dp(plat_data);
159 int ret;
160
161 ret = rockchip_drm_psr_deactivate(&dp->encoder);
162 if (ret != 0)
163 return ret;
158 164
159 clk_disable_unprepare(dp->pclk); 165 clk_disable_unprepare(dp->pclk);
160 166
@@ -258,13 +264,8 @@ static struct drm_encoder_helper_funcs rockchip_dp_encoder_helper_funcs = {
258 .atomic_check = rockchip_dp_drm_encoder_atomic_check, 264 .atomic_check = rockchip_dp_drm_encoder_atomic_check,
259}; 265};
260 266
261static void rockchip_dp_drm_encoder_destroy(struct drm_encoder *encoder)
262{
263 drm_encoder_cleanup(encoder);
264}
265
266static struct drm_encoder_funcs rockchip_dp_encoder_funcs = { 267static struct drm_encoder_funcs rockchip_dp_encoder_funcs = {
267 .destroy = rockchip_dp_drm_encoder_destroy, 268 .destroy = drm_encoder_cleanup,
268}; 269};
269 270
270static int rockchip_dp_of_probe(struct rockchip_dp_device *dp) 271static int rockchip_dp_of_probe(struct rockchip_dp_device *dp)
@@ -334,13 +335,6 @@ static int rockchip_dp_bind(struct device *dev, struct device *master,
334 struct drm_device *drm_dev = data; 335 struct drm_device *drm_dev = data;
335 int ret; 336 int ret;
336 337
337 /*
338 * Just like the probe function said, we don't need the
339 * device drvrate anymore, we should leave the charge to
340 * analogix dp driver, set the device drvdata to NULL.
341 */
342 dev_set_drvdata(dev, NULL);
343
344 dp_data = of_device_get_match_data(dev); 338 dp_data = of_device_get_match_data(dev);
345 if (!dp_data) 339 if (!dp_data)
346 return -ENODEV; 340 return -ENODEV;
@@ -365,9 +359,22 @@ static int rockchip_dp_bind(struct device *dev, struct device *master,
365 dp->psr_state = ~EDP_VSC_PSR_STATE_ACTIVE; 359 dp->psr_state = ~EDP_VSC_PSR_STATE_ACTIVE;
366 INIT_WORK(&dp->psr_work, analogix_dp_psr_work); 360 INIT_WORK(&dp->psr_work, analogix_dp_psr_work);
367 361
368 rockchip_drm_psr_register(&dp->encoder, analogix_dp_psr_set); 362 ret = rockchip_drm_psr_register(&dp->encoder, analogix_dp_psr_set);
363 if (ret < 0)
364 goto err_cleanup_encoder;
365
366 dp->adp = analogix_dp_bind(dev, dp->drm_dev, &dp->plat_data);
367 if (IS_ERR(dp->adp)) {
368 ret = PTR_ERR(dp->adp);
369 goto err_unreg_psr;
370 }
369 371
370 return analogix_dp_bind(dev, dp->drm_dev, &dp->plat_data); 372 return 0;
373err_unreg_psr:
374 rockchip_drm_psr_unregister(&dp->encoder);
375err_cleanup_encoder:
376 dp->encoder.funcs->destroy(&dp->encoder);
377 return ret;
371} 378}
372 379
373static void rockchip_dp_unbind(struct device *dev, struct device *master, 380static void rockchip_dp_unbind(struct device *dev, struct device *master,
@@ -375,9 +382,9 @@ static void rockchip_dp_unbind(struct device *dev, struct device *master,
375{ 382{
376 struct rockchip_dp_device *dp = dev_get_drvdata(dev); 383 struct rockchip_dp_device *dp = dev_get_drvdata(dev);
377 384
385 analogix_dp_unbind(dp->adp);
378 rockchip_drm_psr_unregister(&dp->encoder); 386 rockchip_drm_psr_unregister(&dp->encoder);
379 387 dp->encoder.funcs->destroy(&dp->encoder);
380 analogix_dp_unbind(dev, master, data);
381} 388}
382 389
383static const struct component_ops rockchip_dp_component_ops = { 390static const struct component_ops rockchip_dp_component_ops = {
@@ -407,11 +414,6 @@ static int rockchip_dp_probe(struct platform_device *pdev)
407 if (ret < 0) 414 if (ret < 0)
408 return ret; 415 return ret;
409 416
410 /*
411 * We just use the drvdata until driver run into component
412 * add function, and then we would set drvdata to null, so
413 * that analogix dp driver could take charge of the drvdata.
414 */
415 platform_set_drvdata(pdev, dp); 417 platform_set_drvdata(pdev, dp);
416 418
417 return component_add(dev, &rockchip_dp_component_ops); 419 return component_add(dev, &rockchip_dp_component_ops);
@@ -424,10 +426,26 @@ static int rockchip_dp_remove(struct platform_device *pdev)
424 return 0; 426 return 0;
425} 427}
426 428
429#ifdef CONFIG_PM_SLEEP
430static int rockchip_dp_suspend(struct device *dev)
431{
432 struct rockchip_dp_device *dp = dev_get_drvdata(dev);
433
434 return analogix_dp_suspend(dp->adp);
435}
436
437static int rockchip_dp_resume(struct device *dev)
438{
439 struct rockchip_dp_device *dp = dev_get_drvdata(dev);
440
441 return analogix_dp_resume(dp->adp);
442}
443#endif
444
427static const struct dev_pm_ops rockchip_dp_pm_ops = { 445static const struct dev_pm_ops rockchip_dp_pm_ops = {
428#ifdef CONFIG_PM_SLEEP 446#ifdef CONFIG_PM_SLEEP
429 .suspend = analogix_dp_suspend, 447 .suspend = rockchip_dp_suspend,
430 .resume_early = analogix_dp_resume, 448 .resume_early = rockchip_dp_resume,
431#endif 449#endif
432}; 450};
433 451
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 591953cbdd18..d53d5a09547f 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -1302,8 +1302,8 @@ static int dw_mipi_dsi_bind(struct device *dev, struct device *master,
1302err_mipi_dsi_host: 1302err_mipi_dsi_host:
1303 mipi_dsi_host_unregister(&dsi->dsi_host); 1303 mipi_dsi_host_unregister(&dsi->dsi_host);
1304err_cleanup: 1304err_cleanup:
1305 drm_encoder_cleanup(&dsi->encoder); 1305 dsi->connector.funcs->destroy(&dsi->connector);
1306 drm_connector_cleanup(&dsi->connector); 1306 dsi->encoder.funcs->destroy(&dsi->encoder);
1307err_pllref: 1307err_pllref:
1308 clk_disable_unprepare(dsi->pllref_clk); 1308 clk_disable_unprepare(dsi->pllref_clk);
1309 return ret; 1309 return ret;
@@ -1316,6 +1316,10 @@ static void dw_mipi_dsi_unbind(struct device *dev, struct device *master,
1316 1316
1317 mipi_dsi_host_unregister(&dsi->dsi_host); 1317 mipi_dsi_host_unregister(&dsi->dsi_host);
1318 pm_runtime_disable(dev); 1318 pm_runtime_disable(dev);
1319
1320 dsi->connector.funcs->destroy(&dsi->connector);
1321 dsi->encoder.funcs->destroy(&dsi->encoder);
1322
1319 clk_disable_unprepare(dsi->pllref_clk); 1323 clk_disable_unprepare(dsi->pllref_clk);
1320} 1324}
1321 1325
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 3574b0ae2ad1..11309a2a4e43 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -165,7 +165,6 @@ static const struct dw_hdmi_phy_config rockchip_phy_config[] = {
165static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi) 165static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
166{ 166{
167 struct device_node *np = hdmi->dev->of_node; 167 struct device_node *np = hdmi->dev->of_node;
168 int ret;
169 168
170 hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); 169 hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
171 if (IS_ERR(hdmi->regmap)) { 170 if (IS_ERR(hdmi->regmap)) {
@@ -193,13 +192,6 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
193 return PTR_ERR(hdmi->grf_clk); 192 return PTR_ERR(hdmi->grf_clk);
194 } 193 }
195 194
196 ret = clk_prepare_enable(hdmi->vpll_clk);
197 if (ret) {
198 DRM_DEV_ERROR(hdmi->dev,
199 "Failed to enable HDMI vpll: %d\n", ret);
200 return ret;
201 }
202
203 return 0; 195 return 0;
204} 196}
205 197
@@ -374,6 +366,13 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
374 return ret; 366 return ret;
375 } 367 }
376 368
369 ret = clk_prepare_enable(hdmi->vpll_clk);
370 if (ret) {
371 DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI vpll: %d\n",
372 ret);
373 return ret;
374 }
375
377 drm_encoder_helper_add(encoder, &dw_hdmi_rockchip_encoder_helper_funcs); 376 drm_encoder_helper_add(encoder, &dw_hdmi_rockchip_encoder_helper_funcs);
378 drm_encoder_init(drm, encoder, &dw_hdmi_rockchip_encoder_funcs, 377 drm_encoder_init(drm, encoder, &dw_hdmi_rockchip_encoder_funcs,
379 DRM_MODE_ENCODER_TMDS, NULL); 378 DRM_MODE_ENCODER_TMDS, NULL);
@@ -389,6 +388,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
389 if (IS_ERR(hdmi->hdmi)) { 388 if (IS_ERR(hdmi->hdmi)) {
390 ret = PTR_ERR(hdmi->hdmi); 389 ret = PTR_ERR(hdmi->hdmi);
391 drm_encoder_cleanup(encoder); 390 drm_encoder_cleanup(encoder);
391 clk_disable_unprepare(hdmi->vpll_clk);
392 } 392 }
393 393
394 return ret; 394 return ret;
@@ -400,6 +400,7 @@ static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master,
400 struct rockchip_hdmi *hdmi = dev_get_drvdata(dev); 400 struct rockchip_hdmi *hdmi = dev_get_drvdata(dev);
401 401
402 dw_hdmi_unbind(hdmi->hdmi); 402 dw_hdmi_unbind(hdmi->hdmi);
403 clk_disable_unprepare(hdmi->vpll_clk);
403} 404}
404 405
405static const struct component_ops dw_hdmi_rockchip_ops = { 406static const struct component_ops dw_hdmi_rockchip_ops = {
diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index f6ad48766d49..88d0774c97bd 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -849,8 +849,10 @@ static int inno_hdmi_bind(struct device *dev, struct device *master,
849 } 849 }
850 850
851 irq = platform_get_irq(pdev, 0); 851 irq = platform_get_irq(pdev, 0);
852 if (irq < 0) 852 if (irq < 0) {
853 return irq; 853 ret = irq;
854 goto err_disable_clk;
855 }
854 856
855 inno_hdmi_reset(hdmi); 857 inno_hdmi_reset(hdmi);
856 858
@@ -858,7 +860,7 @@ static int inno_hdmi_bind(struct device *dev, struct device *master,
858 if (IS_ERR(hdmi->ddc)) { 860 if (IS_ERR(hdmi->ddc)) {
859 ret = PTR_ERR(hdmi->ddc); 861 ret = PTR_ERR(hdmi->ddc);
860 hdmi->ddc = NULL; 862 hdmi->ddc = NULL;
861 return ret; 863 goto err_disable_clk;
862 } 864 }
863 865
864 /* 866 /*
@@ -872,7 +874,7 @@ static int inno_hdmi_bind(struct device *dev, struct device *master,
872 874
873 ret = inno_hdmi_register(drm, hdmi); 875 ret = inno_hdmi_register(drm, hdmi);
874 if (ret) 876 if (ret)
875 return ret; 877 goto err_put_adapter;
876 878
877 dev_set_drvdata(dev, hdmi); 879 dev_set_drvdata(dev, hdmi);
878 880
@@ -882,7 +884,17 @@ static int inno_hdmi_bind(struct device *dev, struct device *master,
882 ret = devm_request_threaded_irq(dev, irq, inno_hdmi_hardirq, 884 ret = devm_request_threaded_irq(dev, irq, inno_hdmi_hardirq,
883 inno_hdmi_irq, IRQF_SHARED, 885 inno_hdmi_irq, IRQF_SHARED,
884 dev_name(dev), hdmi); 886 dev_name(dev), hdmi);
887 if (ret < 0)
888 goto err_cleanup_hdmi;
885 889
890 return 0;
891err_cleanup_hdmi:
892 hdmi->connector.funcs->destroy(&hdmi->connector);
893 hdmi->encoder.funcs->destroy(&hdmi->encoder);
894err_put_adapter:
895 i2c_put_adapter(hdmi->ddc);
896err_disable_clk:
897 clk_disable_unprepare(hdmi->pclk);
886 return ret; 898 return ret;
887} 899}
888 900
@@ -894,8 +906,8 @@ static void inno_hdmi_unbind(struct device *dev, struct device *master,
894 hdmi->connector.funcs->destroy(&hdmi->connector); 906 hdmi->connector.funcs->destroy(&hdmi->connector);
895 hdmi->encoder.funcs->destroy(&hdmi->encoder); 907 hdmi->encoder.funcs->destroy(&hdmi->encoder);
896 908
897 clk_disable_unprepare(hdmi->pclk);
898 i2c_put_adapter(hdmi->ddc); 909 i2c_put_adapter(hdmi->ddc);
910 clk_disable_unprepare(hdmi->pclk);
899} 911}
900 912
901static const struct component_ops inno_hdmi_ops = { 913static const struct component_ops inno_hdmi_ops = {
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 88084ca15115..f814d37b1db2 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -134,7 +134,7 @@ static int rockchip_drm_bind(struct device *dev)
134 drm_dev->dev_private = private; 134 drm_dev->dev_private = private;
135 135
136 INIT_LIST_HEAD(&private->psr_list); 136 INIT_LIST_HEAD(&private->psr_list);
137 spin_lock_init(&private->psr_list_lock); 137 mutex_init(&private->psr_list_lock);
138 138
139 ret = rockchip_drm_init_iommu(drm_dev); 139 ret = rockchip_drm_init_iommu(drm_dev);
140 if (ret) 140 if (ret)
@@ -314,6 +314,14 @@ static int compare_dev(struct device *dev, void *data)
314 return dev == (struct device *)data; 314 return dev == (struct device *)data;
315} 315}
316 316
317static void rockchip_drm_match_remove(struct device *dev)
318{
319 struct device_link *link;
320
321 list_for_each_entry(link, &dev->links.consumers, s_node)
322 device_link_del(link);
323}
324
317static struct component_match *rockchip_drm_match_add(struct device *dev) 325static struct component_match *rockchip_drm_match_add(struct device *dev)
318{ 326{
319 struct component_match *match = NULL; 327 struct component_match *match = NULL;
@@ -331,10 +339,15 @@ static struct component_match *rockchip_drm_match_add(struct device *dev)
331 339
332 if (!d) 340 if (!d)
333 break; 341 break;
342
343 device_link_add(dev, d, DL_FLAG_STATELESS);
334 component_match_add(dev, &match, compare_dev, d); 344 component_match_add(dev, &match, compare_dev, d);
335 } while (true); 345 } while (true);
336 } 346 }
337 347
348 if (IS_ERR(match))
349 rockchip_drm_match_remove(dev);
350
338 return match ?: ERR_PTR(-ENODEV); 351 return match ?: ERR_PTR(-ENODEV);
339} 352}
340 353
@@ -411,13 +424,21 @@ static int rockchip_drm_platform_probe(struct platform_device *pdev)
411 if (IS_ERR(match)) 424 if (IS_ERR(match))
412 return PTR_ERR(match); 425 return PTR_ERR(match);
413 426
414 return component_master_add_with_match(dev, &rockchip_drm_ops, match); 427 ret = component_master_add_with_match(dev, &rockchip_drm_ops, match);
428 if (ret < 0) {
429 rockchip_drm_match_remove(dev);
430 return ret;
431 }
432
433 return 0;
415} 434}
416 435
417static int rockchip_drm_platform_remove(struct platform_device *pdev) 436static int rockchip_drm_platform_remove(struct platform_device *pdev)
418{ 437{
419 component_master_del(&pdev->dev, &rockchip_drm_ops); 438 component_master_del(&pdev->dev, &rockchip_drm_ops);
420 439
440 rockchip_drm_match_remove(&pdev->dev);
441
421 return 0; 442 return 0;
422} 443}
423 444
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 498dfbc52cec..9c064a40458b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -55,7 +55,7 @@ struct rockchip_drm_private {
55 struct mutex mm_lock; 55 struct mutex mm_lock;
56 struct drm_mm mm; 56 struct drm_mm mm;
57 struct list_head psr_list; 57 struct list_head psr_list;
58 spinlock_t psr_list_lock; 58 struct mutex psr_list_lock;
59}; 59};
60 60
61int rockchip_drm_dma_attach_device(struct drm_device *drm_dev, 61int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
index 3acfd576b7df..b339ca943139 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
@@ -18,7 +18,7 @@
18#include "rockchip_drm_drv.h" 18#include "rockchip_drm_drv.h"
19#include "rockchip_drm_psr.h" 19#include "rockchip_drm_psr.h"
20 20
21#define PSR_FLUSH_TIMEOUT msecs_to_jiffies(100) 21#define PSR_FLUSH_TIMEOUT_MS 100
22 22
23enum psr_state { 23enum psr_state {
24 PSR_FLUSH, 24 PSR_FLUSH,
@@ -30,11 +30,11 @@ struct psr_drv {
30 struct list_head list; 30 struct list_head list;
31 struct drm_encoder *encoder; 31 struct drm_encoder *encoder;
32 32
33 spinlock_t lock; 33 struct mutex lock;
34 bool active; 34 bool active;
35 enum psr_state state; 35 enum psr_state state;
36 36
37 struct timer_list flush_timer; 37 struct delayed_work flush_work;
38 38
39 void (*set)(struct drm_encoder *encoder, bool enable); 39 void (*set)(struct drm_encoder *encoder, bool enable);
40}; 40};
@@ -43,9 +43,8 @@ static struct psr_drv *find_psr_by_crtc(struct drm_crtc *crtc)
43{ 43{
44 struct rockchip_drm_private *drm_drv = crtc->dev->dev_private; 44 struct rockchip_drm_private *drm_drv = crtc->dev->dev_private;
45 struct psr_drv *psr; 45 struct psr_drv *psr;
46 unsigned long flags;
47 46
48 spin_lock_irqsave(&drm_drv->psr_list_lock, flags); 47 mutex_lock(&drm_drv->psr_list_lock);
49 list_for_each_entry(psr, &drm_drv->psr_list, list) { 48 list_for_each_entry(psr, &drm_drv->psr_list, list) {
50 if (psr->encoder->crtc == crtc) 49 if (psr->encoder->crtc == crtc)
51 goto out; 50 goto out;
@@ -53,7 +52,24 @@ static struct psr_drv *find_psr_by_crtc(struct drm_crtc *crtc)
53 psr = ERR_PTR(-ENODEV); 52 psr = ERR_PTR(-ENODEV);
54 53
55out: 54out:
56 spin_unlock_irqrestore(&drm_drv->psr_list_lock, flags); 55 mutex_unlock(&drm_drv->psr_list_lock);
56 return psr;
57}
58
59static struct psr_drv *find_psr_by_encoder(struct drm_encoder *encoder)
60{
61 struct rockchip_drm_private *drm_drv = encoder->dev->dev_private;
62 struct psr_drv *psr;
63
64 mutex_lock(&drm_drv->psr_list_lock);
65 list_for_each_entry(psr, &drm_drv->psr_list, list) {
66 if (psr->encoder == encoder)
67 goto out;
68 }
69 psr = ERR_PTR(-ENODEV);
70
71out:
72 mutex_unlock(&drm_drv->psr_list_lock);
57 return psr; 73 return psr;
58} 74}
59 75
@@ -94,43 +110,40 @@ static void psr_set_state_locked(struct psr_drv *psr, enum psr_state state)
94 110
95static void psr_set_state(struct psr_drv *psr, enum psr_state state) 111static void psr_set_state(struct psr_drv *psr, enum psr_state state)
96{ 112{
97 unsigned long flags; 113 mutex_lock(&psr->lock);
98
99 spin_lock_irqsave(&psr->lock, flags);
100 psr_set_state_locked(psr, state); 114 psr_set_state_locked(psr, state);
101 spin_unlock_irqrestore(&psr->lock, flags); 115 mutex_unlock(&psr->lock);
102} 116}
103 117
104static void psr_flush_handler(struct timer_list *t) 118static void psr_flush_handler(struct work_struct *work)
105{ 119{
106 struct psr_drv *psr = from_timer(psr, t, flush_timer); 120 struct psr_drv *psr = container_of(to_delayed_work(work),
107 unsigned long flags; 121 struct psr_drv, flush_work);
108 122
109 /* If the state has changed since we initiated the flush, do nothing */ 123 /* If the state has changed since we initiated the flush, do nothing */
110 spin_lock_irqsave(&psr->lock, flags); 124 mutex_lock(&psr->lock);
111 if (psr->state == PSR_FLUSH) 125 if (psr->state == PSR_FLUSH)
112 psr_set_state_locked(psr, PSR_ENABLE); 126 psr_set_state_locked(psr, PSR_ENABLE);
113 spin_unlock_irqrestore(&psr->lock, flags); 127 mutex_unlock(&psr->lock);
114} 128}
115 129
116/** 130/**
117 * rockchip_drm_psr_activate - activate PSR on the given pipe 131 * rockchip_drm_psr_activate - activate PSR on the given pipe
118 * @crtc: CRTC to obtain the PSR encoder 132 * @encoder: encoder to obtain the PSR encoder
119 * 133 *
120 * Returns: 134 * Returns:
121 * Zero on success, negative errno on failure. 135 * Zero on success, negative errno on failure.
122 */ 136 */
123int rockchip_drm_psr_activate(struct drm_crtc *crtc) 137int rockchip_drm_psr_activate(struct drm_encoder *encoder)
124{ 138{
125 struct psr_drv *psr = find_psr_by_crtc(crtc); 139 struct psr_drv *psr = find_psr_by_encoder(encoder);
126 unsigned long flags;
127 140
128 if (IS_ERR(psr)) 141 if (IS_ERR(psr))
129 return PTR_ERR(psr); 142 return PTR_ERR(psr);
130 143
131 spin_lock_irqsave(&psr->lock, flags); 144 mutex_lock(&psr->lock);
132 psr->active = true; 145 psr->active = true;
133 spin_unlock_irqrestore(&psr->lock, flags); 146 mutex_unlock(&psr->lock);
134 147
135 return 0; 148 return 0;
136} 149}
@@ -138,23 +151,22 @@ EXPORT_SYMBOL(rockchip_drm_psr_activate);
138 151
139/** 152/**
140 * rockchip_drm_psr_deactivate - deactivate PSR on the given pipe 153 * rockchip_drm_psr_deactivate - deactivate PSR on the given pipe
141 * @crtc: CRTC to obtain the PSR encoder 154 * @encoder: encoder to obtain the PSR encoder
142 * 155 *
143 * Returns: 156 * Returns:
144 * Zero on success, negative errno on failure. 157 * Zero on success, negative errno on failure.
145 */ 158 */
146int rockchip_drm_psr_deactivate(struct drm_crtc *crtc) 159int rockchip_drm_psr_deactivate(struct drm_encoder *encoder)
147{ 160{
148 struct psr_drv *psr = find_psr_by_crtc(crtc); 161 struct psr_drv *psr = find_psr_by_encoder(encoder);
149 unsigned long flags;
150 162
151 if (IS_ERR(psr)) 163 if (IS_ERR(psr))
152 return PTR_ERR(psr); 164 return PTR_ERR(psr);
153 165
154 spin_lock_irqsave(&psr->lock, flags); 166 mutex_lock(&psr->lock);
155 psr->active = false; 167 psr->active = false;
156 spin_unlock_irqrestore(&psr->lock, flags); 168 mutex_unlock(&psr->lock);
157 del_timer_sync(&psr->flush_timer); 169 cancel_delayed_work_sync(&psr->flush_work);
158 170
159 return 0; 171 return 0;
160} 172}
@@ -162,9 +174,8 @@ EXPORT_SYMBOL(rockchip_drm_psr_deactivate);
162 174
163static void rockchip_drm_do_flush(struct psr_drv *psr) 175static void rockchip_drm_do_flush(struct psr_drv *psr)
164{ 176{
165 mod_timer(&psr->flush_timer,
166 round_jiffies_up(jiffies + PSR_FLUSH_TIMEOUT));
167 psr_set_state(psr, PSR_FLUSH); 177 psr_set_state(psr, PSR_FLUSH);
178 mod_delayed_work(system_wq, &psr->flush_work, PSR_FLUSH_TIMEOUT_MS);
168} 179}
169 180
170/** 181/**
@@ -201,12 +212,11 @@ void rockchip_drm_psr_flush_all(struct drm_device *dev)
201{ 212{
202 struct rockchip_drm_private *drm_drv = dev->dev_private; 213 struct rockchip_drm_private *drm_drv = dev->dev_private;
203 struct psr_drv *psr; 214 struct psr_drv *psr;
204 unsigned long flags;
205 215
206 spin_lock_irqsave(&drm_drv->psr_list_lock, flags); 216 mutex_lock(&drm_drv->psr_list_lock);
207 list_for_each_entry(psr, &drm_drv->psr_list, list) 217 list_for_each_entry(psr, &drm_drv->psr_list, list)
208 rockchip_drm_do_flush(psr); 218 rockchip_drm_do_flush(psr);
209 spin_unlock_irqrestore(&drm_drv->psr_list_lock, flags); 219 mutex_unlock(&drm_drv->psr_list_lock);
210} 220}
211EXPORT_SYMBOL(rockchip_drm_psr_flush_all); 221EXPORT_SYMBOL(rockchip_drm_psr_flush_all);
212 222
@@ -223,7 +233,6 @@ int rockchip_drm_psr_register(struct drm_encoder *encoder,
223{ 233{
224 struct rockchip_drm_private *drm_drv = encoder->dev->dev_private; 234 struct rockchip_drm_private *drm_drv = encoder->dev->dev_private;
225 struct psr_drv *psr; 235 struct psr_drv *psr;
226 unsigned long flags;
227 236
228 if (!encoder || !psr_set) 237 if (!encoder || !psr_set)
229 return -EINVAL; 238 return -EINVAL;
@@ -232,17 +241,17 @@ int rockchip_drm_psr_register(struct drm_encoder *encoder,
232 if (!psr) 241 if (!psr)
233 return -ENOMEM; 242 return -ENOMEM;
234 243
235 timer_setup(&psr->flush_timer, psr_flush_handler, 0); 244 INIT_DELAYED_WORK(&psr->flush_work, psr_flush_handler);
236 spin_lock_init(&psr->lock); 245 mutex_init(&psr->lock);
237 246
238 psr->active = true; 247 psr->active = true;
239 psr->state = PSR_DISABLE; 248 psr->state = PSR_DISABLE;
240 psr->encoder = encoder; 249 psr->encoder = encoder;
241 psr->set = psr_set; 250 psr->set = psr_set;
242 251
243 spin_lock_irqsave(&drm_drv->psr_list_lock, flags); 252 mutex_lock(&drm_drv->psr_list_lock);
244 list_add_tail(&psr->list, &drm_drv->psr_list); 253 list_add_tail(&psr->list, &drm_drv->psr_list);
245 spin_unlock_irqrestore(&drm_drv->psr_list_lock, flags); 254 mutex_unlock(&drm_drv->psr_list_lock);
246 255
247 return 0; 256 return 0;
248} 257}
@@ -260,16 +269,15 @@ void rockchip_drm_psr_unregister(struct drm_encoder *encoder)
260{ 269{
261 struct rockchip_drm_private *drm_drv = encoder->dev->dev_private; 270 struct rockchip_drm_private *drm_drv = encoder->dev->dev_private;
262 struct psr_drv *psr, *n; 271 struct psr_drv *psr, *n;
263 unsigned long flags;
264 272
265 spin_lock_irqsave(&drm_drv->psr_list_lock, flags); 273 mutex_lock(&drm_drv->psr_list_lock);
266 list_for_each_entry_safe(psr, n, &drm_drv->psr_list, list) { 274 list_for_each_entry_safe(psr, n, &drm_drv->psr_list, list) {
267 if (psr->encoder == encoder) { 275 if (psr->encoder == encoder) {
268 del_timer(&psr->flush_timer); 276 cancel_delayed_work_sync(&psr->flush_work);
269 list_del(&psr->list); 277 list_del(&psr->list);
270 kfree(psr); 278 kfree(psr);
271 } 279 }
272 } 280 }
273 spin_unlock_irqrestore(&drm_drv->psr_list_lock, flags); 281 mutex_unlock(&drm_drv->psr_list_lock);
274} 282}
275EXPORT_SYMBOL(rockchip_drm_psr_unregister); 283EXPORT_SYMBOL(rockchip_drm_psr_unregister);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.h b/drivers/gpu/drm/rockchip/rockchip_drm_psr.h
index b420cf1bf902..b1ea0155e57c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.h
@@ -18,8 +18,8 @@
18void rockchip_drm_psr_flush_all(struct drm_device *dev); 18void rockchip_drm_psr_flush_all(struct drm_device *dev);
19int rockchip_drm_psr_flush(struct drm_crtc *crtc); 19int rockchip_drm_psr_flush(struct drm_crtc *crtc);
20 20
21int rockchip_drm_psr_activate(struct drm_crtc *crtc); 21int rockchip_drm_psr_activate(struct drm_encoder *encoder);
22int rockchip_drm_psr_deactivate(struct drm_crtc *crtc); 22int rockchip_drm_psr_deactivate(struct drm_encoder *encoder);
23 23
24int rockchip_drm_psr_register(struct drm_encoder *encoder, 24int rockchip_drm_psr_register(struct drm_encoder *encoder,
25 void (*psr_set)(struct drm_encoder *, bool enable)); 25 void (*psr_set)(struct drm_encoder *, bool enable));
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 66736227c96e..158e79e5062e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -256,6 +256,9 @@ static uint16_t scl_vop_cal_scale(enum scale_mode mode, uint32_t src,
256{ 256{
257 uint16_t val = 1 << SCL_FT_DEFAULT_FIXPOINT_SHIFT; 257 uint16_t val = 1 << SCL_FT_DEFAULT_FIXPOINT_SHIFT;
258 258
259 if (vskiplines)
260 *vskiplines = 0;
261
259 if (is_horizontal) { 262 if (is_horizontal) {
260 if (mode == SCALE_UP) 263 if (mode == SCALE_UP)
261 val = GET_SCL_FT_BIC(src, dst); 264 val = GET_SCL_FT_BIC(src, dst);
@@ -296,7 +299,7 @@ static void scl_vop_cal_scl_fac(struct vop *vop, const struct vop_win_data *win,
296 uint16_t vsu_mode; 299 uint16_t vsu_mode;
297 uint16_t lb_mode; 300 uint16_t lb_mode;
298 uint32_t val; 301 uint32_t val;
299 int vskiplines = 0; 302 int vskiplines;
300 303
301 if (dst_w > 3840) { 304 if (dst_w > 3840) {
302 DRM_DEV_ERROR(vop->dev, "Maximum dst width (3840) exceeded\n"); 305 DRM_DEV_ERROR(vop->dev, "Maximum dst width (3840) exceeded\n");
@@ -566,8 +569,6 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
566 569
567 WARN_ON(vop->event); 570 WARN_ON(vop->event);
568 571
569 rockchip_drm_psr_deactivate(&vop->crtc);
570
571 drm_crtc_vblank_off(crtc); 572 drm_crtc_vblank_off(crtc);
572 573
573 /* 574 /*
@@ -627,7 +628,6 @@ static int vop_plane_atomic_check(struct drm_plane *plane,
627 struct vop_win *vop_win = to_vop_win(plane); 628 struct vop_win *vop_win = to_vop_win(plane);
628 const struct vop_win_data *win = vop_win->data; 629 const struct vop_win_data *win = vop_win->data;
629 int ret; 630 int ret;
630 struct drm_rect clip = {};
631 int min_scale = win->phy->scl ? FRAC_16_16(1, 8) : 631 int min_scale = win->phy->scl ? FRAC_16_16(1, 8) :
632 DRM_PLANE_HELPER_NO_SCALING; 632 DRM_PLANE_HELPER_NO_SCALING;
633 int max_scale = win->phy->scl ? FRAC_16_16(8, 1) : 633 int max_scale = win->phy->scl ? FRAC_16_16(8, 1) :
@@ -640,11 +640,7 @@ static int vop_plane_atomic_check(struct drm_plane *plane,
640 if (WARN_ON(!crtc_state)) 640 if (WARN_ON(!crtc_state))
641 return -EINVAL; 641 return -EINVAL;
642 642
643 if (crtc_state->enable) 643 ret = drm_atomic_helper_check_plane_state(state, crtc_state,
644 drm_mode_get_hv_timing(&crtc_state->mode,
645 &clip.x2, &clip.y2);
646
647 ret = drm_atomic_helper_check_plane_state(state, crtc_state, &clip,
648 min_scale, max_scale, 644 min_scale, max_scale,
649 true, true); 645 true, true);
650 if (ret) 646 if (ret)
@@ -939,8 +935,6 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
939 clk_set_rate(vop->dclk, adjusted_mode->clock * 1000); 935 clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
940 936
941 VOP_REG_SET(vop, common, standby, 0); 937 VOP_REG_SET(vop, common, standby, 0);
942
943 rockchip_drm_psr_activate(&vop->crtc);
944} 938}
945 939
946static bool vop_fs_irq_is_pending(struct vop *vop) 940static bool vop_fs_irq_is_pending(struct vop *vop)
diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c
index 8bc7e8418b8d..9ab00a87f7cc 100644
--- a/drivers/gpu/drm/stm/drv.c
+++ b/drivers/gpu/drm/stm/drv.c
@@ -35,7 +35,6 @@ static int stm_gem_cma_dumb_create(struct drm_file *file,
35 struct drm_device *dev, 35 struct drm_device *dev,
36 struct drm_mode_create_dumb *args) 36 struct drm_mode_create_dumb *args)
37{ 37{
38#ifdef CONFIG_MMU
39 unsigned int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8); 38 unsigned int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
40 39
41 /* 40 /*
@@ -44,7 +43,6 @@ static int stm_gem_cma_dumb_create(struct drm_file *file,
44 */ 43 */
45 args->pitch = roundup(min_pitch, 128); 44 args->pitch = roundup(min_pitch, 128);
46 args->height = roundup(args->height, 4); 45 args->height = roundup(args->height, 4);
47#endif
48 46
49 return drm_gem_cma_dumb_create_internal(file, dev, args); 47 return drm_gem_cma_dumb_create_internal(file, dev, args);
50} 48}
diff --git a/drivers/gpu/drm/sun4i/Kconfig b/drivers/gpu/drm/sun4i/Kconfig
index 7327da3bc94f..eee6bc0eaf97 100644
--- a/drivers/gpu/drm/sun4i/Kconfig
+++ b/drivers/gpu/drm/sun4i/Kconfig
@@ -1,6 +1,6 @@
1config DRM_SUN4I 1config DRM_SUN4I
2 tristate "DRM Support for Allwinner A10 Display Engine" 2 tristate "DRM Support for Allwinner A10 Display Engine"
3 depends on DRM && ARM && COMMON_CLK 3 depends on DRM && (ARM || ARM64) && COMMON_CLK
4 depends on ARCH_SUNXI || COMPILE_TEST 4 depends on ARCH_SUNXI || COMPILE_TEST
5 select DRM_GEM_CMA_HELPER 5 select DRM_GEM_CMA_HELPER
6 select DRM_KMS_HELPER 6 select DRM_KMS_HELPER
diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile
index 1610e748119b..330843ce4280 100644
--- a/drivers/gpu/drm/sun4i/Makefile
+++ b/drivers/gpu/drm/sun4i/Makefile
@@ -12,6 +12,7 @@ sun4i-drm-hdmi-y += sun4i_hdmi_tmds_clk.o
12 12
13sun8i-drm-hdmi-y += sun8i_dw_hdmi.o 13sun8i-drm-hdmi-y += sun8i_dw_hdmi.o
14sun8i-drm-hdmi-y += sun8i_hdmi_phy.o 14sun8i-drm-hdmi-y += sun8i_hdmi_phy.o
15sun8i-drm-hdmi-y += sun8i_hdmi_phy_clk.o
15 16
16sun8i-mixer-y += sun8i_mixer.o sun8i_ui_layer.o \ 17sun8i-mixer-y += sun8i_mixer.o sun8i_ui_layer.o \
17 sun8i_vi_layer.o sun8i_ui_scaler.o \ 18 sun8i_vi_layer.o sun8i_ui_scaler.o \
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c
index 245b189fc4d8..092ade4ff6a5 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.c
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.c
@@ -92,13 +92,8 @@ void sun4i_backend_layer_enable(struct sun4i_backend *backend,
92 SUN4I_BACKEND_MODCTL_LAY_EN(layer), val); 92 SUN4I_BACKEND_MODCTL_LAY_EN(layer), val);
93} 93}
94 94
95static int sun4i_backend_drm_format_to_layer(struct drm_plane *plane, 95static int sun4i_backend_drm_format_to_layer(u32 format, u32 *mode)
96 u32 format, u32 *mode)
97{ 96{
98 if (plane && (plane->type == DRM_PLANE_TYPE_PRIMARY) &&
99 (format == DRM_FORMAT_ARGB8888))
100 format = DRM_FORMAT_XRGB8888;
101
102 switch (format) { 97 switch (format) {
103 case DRM_FORMAT_ARGB8888: 98 case DRM_FORMAT_ARGB8888:
104 *mode = SUN4I_BACKEND_LAY_FBFMT_ARGB8888; 99 *mode = SUN4I_BACKEND_LAY_FBFMT_ARGB8888;
@@ -191,8 +186,7 @@ int sun4i_backend_update_layer_formats(struct sun4i_backend *backend,
191 DRM_DEBUG_DRIVER("Switching display backend interlaced mode %s\n", 186 DRM_DEBUG_DRIVER("Switching display backend interlaced mode %s\n",
192 interlaced ? "on" : "off"); 187 interlaced ? "on" : "off");
193 188
194 ret = sun4i_backend_drm_format_to_layer(plane, fb->format->format, 189 ret = sun4i_backend_drm_format_to_layer(fb->format->format, &val);
195 &val);
196 if (ret) { 190 if (ret) {
197 DRM_DEBUG_DRIVER("Invalid format\n"); 191 DRM_DEBUG_DRIVER("Invalid format\n");
198 return ret; 192 return ret;
@@ -211,7 +205,7 @@ int sun4i_backend_update_layer_frontend(struct sun4i_backend *backend,
211 u32 val; 205 u32 val;
212 int ret; 206 int ret;
213 207
214 ret = sun4i_backend_drm_format_to_layer(NULL, fmt, &val); 208 ret = sun4i_backend_drm_format_to_layer(fmt, &val);
215 if (ret) { 209 if (ret) {
216 DRM_DEBUG_DRIVER("Invalid format\n"); 210 DRM_DEBUG_DRIVER("Invalid format\n");
217 return ret; 211 return ret;
@@ -275,12 +269,16 @@ int sun4i_backend_update_layer_zpos(struct sun4i_backend *backend, int layer,
275 struct drm_plane *plane) 269 struct drm_plane *plane)
276{ 270{
277 struct drm_plane_state *state = plane->state; 271 struct drm_plane_state *state = plane->state;
272 struct sun4i_layer_state *p_state = state_to_sun4i_layer_state(state);
278 unsigned int priority = state->normalized_zpos; 273 unsigned int priority = state->normalized_zpos;
274 unsigned int pipe = p_state->pipe;
279 275
280 DRM_DEBUG_DRIVER("Setting layer %d's priority to %d\n", layer, priority); 276 DRM_DEBUG_DRIVER("Setting layer %d's priority to %d and pipe %d\n",
281 277 layer, priority, pipe);
282 regmap_update_bits(backend->engine.regs, SUN4I_BACKEND_ATTCTL_REG0(layer), 278 regmap_update_bits(backend->engine.regs, SUN4I_BACKEND_ATTCTL_REG0(layer),
279 SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL_MASK |
283 SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL_MASK, 280 SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL_MASK,
281 SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL(p_state->pipe) |
284 SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL(priority)); 282 SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL(priority));
285 283
286 return 0; 284 return 0;
@@ -325,12 +323,15 @@ static void sun4i_backend_atomic_begin(struct sunxi_engine *engine,
325static int sun4i_backend_atomic_check(struct sunxi_engine *engine, 323static int sun4i_backend_atomic_check(struct sunxi_engine *engine,
326 struct drm_crtc_state *crtc_state) 324 struct drm_crtc_state *crtc_state)
327{ 325{
326 struct drm_plane_state *plane_states[SUN4I_BACKEND_NUM_LAYERS] = { 0 };
328 struct drm_atomic_state *state = crtc_state->state; 327 struct drm_atomic_state *state = crtc_state->state;
329 struct drm_device *drm = state->dev; 328 struct drm_device *drm = state->dev;
330 struct drm_plane *plane; 329 struct drm_plane *plane;
331 unsigned int num_planes = 0; 330 unsigned int num_planes = 0;
332 unsigned int num_alpha_planes = 0; 331 unsigned int num_alpha_planes = 0;
333 unsigned int num_frontend_planes = 0; 332 unsigned int num_frontend_planes = 0;
333 unsigned int current_pipe = 0;
334 unsigned int i;
334 335
335 DRM_DEBUG_DRIVER("Starting checking our planes\n"); 336 DRM_DEBUG_DRIVER("Starting checking our planes\n");
336 337
@@ -361,9 +362,19 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine,
361 if (fb->format->has_alpha) 362 if (fb->format->has_alpha)
362 num_alpha_planes++; 363 num_alpha_planes++;
363 364
365 DRM_DEBUG_DRIVER("Plane zpos is %d\n",
366 plane_state->normalized_zpos);
367
368 /* Sort our planes by Zpos */
369 plane_states[plane_state->normalized_zpos] = plane_state;
370
364 num_planes++; 371 num_planes++;
365 } 372 }
366 373
374 /* All our planes were disabled, bail out */
375 if (!num_planes)
376 return 0;
377
367 /* 378 /*
368 * The hardware is a bit unusual here. 379 * The hardware is a bit unusual here.
369 * 380 *
@@ -400,6 +411,25 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine,
400 return -EINVAL; 411 return -EINVAL;
401 } 412 }
402 413
414 /* We can't have an alpha plane at the lowest position */
415 if (plane_states[0]->fb->format->has_alpha)
416 return -EINVAL;
417
418 for (i = 1; i < num_planes; i++) {
419 struct drm_plane_state *p_state = plane_states[i];
420 struct drm_framebuffer *fb = p_state->fb;
421 struct sun4i_layer_state *s_state = state_to_sun4i_layer_state(p_state);
422
423 /*
424 * The only alpha position is the lowest plane of the
425 * second pipe.
426 */
427 if (fb->format->has_alpha)
428 current_pipe++;
429
430 s_state->pipe = current_pipe;
431 }
432
403 if (num_frontend_planes > SUN4I_BACKEND_NUM_FRONTEND_LAYERS) { 433 if (num_frontend_planes > SUN4I_BACKEND_NUM_FRONTEND_LAYERS) {
404 DRM_DEBUG_DRIVER("Too many planes going through the frontend, rejecting\n"); 434 DRM_DEBUG_DRIVER("Too many planes going through the frontend, rejecting\n");
405 return -EINVAL; 435 return -EINVAL;
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index 3957c2ff6870..a0f43b81c64c 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -359,6 +359,7 @@ static const struct of_device_id sun4i_drv_of_table[] = {
359 { .compatible = "allwinner,sun7i-a20-display-engine" }, 359 { .compatible = "allwinner,sun7i-a20-display-engine" },
360 { .compatible = "allwinner,sun8i-a33-display-engine" }, 360 { .compatible = "allwinner,sun8i-a33-display-engine" },
361 { .compatible = "allwinner,sun8i-a83t-display-engine" }, 361 { .compatible = "allwinner,sun8i-a83t-display-engine" },
362 { .compatible = "allwinner,sun8i-h3-display-engine" },
362 { .compatible = "allwinner,sun8i-v3s-display-engine" }, 363 { .compatible = "allwinner,sun8i-v3s-display-engine" },
363 { } 364 { }
364}; 365};
diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c
index 19be798e4fac..33ad377569ec 100644
--- a/drivers/gpu/drm/sun4i/sun4i_layer.c
+++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
@@ -19,13 +19,6 @@
19#include "sun4i_layer.h" 19#include "sun4i_layer.h"
20#include "sunxi_engine.h" 20#include "sunxi_engine.h"
21 21
22struct sun4i_plane_desc {
23 enum drm_plane_type type;
24 u8 pipe;
25 const uint32_t *formats;
26 uint32_t nformats;
27};
28
29static void sun4i_backend_layer_reset(struct drm_plane *plane) 22static void sun4i_backend_layer_reset(struct drm_plane *plane)
30{ 23{
31 struct sun4i_layer *layer = plane_to_sun4i_layer(plane); 24 struct sun4i_layer *layer = plane_to_sun4i_layer(plane);
@@ -133,14 +126,7 @@ static const struct drm_plane_funcs sun4i_backend_layer_funcs = {
133 .update_plane = drm_atomic_helper_update_plane, 126 .update_plane = drm_atomic_helper_update_plane,
134}; 127};
135 128
136static const uint32_t sun4i_backend_layer_formats_primary[] = { 129static const uint32_t sun4i_backend_layer_formats[] = {
137 DRM_FORMAT_ARGB8888,
138 DRM_FORMAT_RGB888,
139 DRM_FORMAT_RGB565,
140 DRM_FORMAT_XRGB8888,
141};
142
143static const uint32_t sun4i_backend_layer_formats_overlay[] = {
144 DRM_FORMAT_ARGB8888, 130 DRM_FORMAT_ARGB8888,
145 DRM_FORMAT_ARGB4444, 131 DRM_FORMAT_ARGB4444,
146 DRM_FORMAT_ARGB1555, 132 DRM_FORMAT_ARGB1555,
@@ -151,24 +137,9 @@ static const uint32_t sun4i_backend_layer_formats_overlay[] = {
151 DRM_FORMAT_XRGB8888, 137 DRM_FORMAT_XRGB8888,
152}; 138};
153 139
154static const struct sun4i_plane_desc sun4i_backend_planes[] = {
155 {
156 .type = DRM_PLANE_TYPE_PRIMARY,
157 .pipe = 0,
158 .formats = sun4i_backend_layer_formats_primary,
159 .nformats = ARRAY_SIZE(sun4i_backend_layer_formats_primary),
160 },
161 {
162 .type = DRM_PLANE_TYPE_OVERLAY,
163 .pipe = 1,
164 .formats = sun4i_backend_layer_formats_overlay,
165 .nformats = ARRAY_SIZE(sun4i_backend_layer_formats_overlay),
166 },
167};
168
169static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm, 140static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm,
170 struct sun4i_backend *backend, 141 struct sun4i_backend *backend,
171 const struct sun4i_plane_desc *plane) 142 enum drm_plane_type type)
172{ 143{
173 struct sun4i_layer *layer; 144 struct sun4i_layer *layer;
174 int ret; 145 int ret;
@@ -180,8 +151,9 @@ static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm,
180 /* possible crtcs are set later */ 151 /* possible crtcs are set later */
181 ret = drm_universal_plane_init(drm, &layer->plane, 0, 152 ret = drm_universal_plane_init(drm, &layer->plane, 0,
182 &sun4i_backend_layer_funcs, 153 &sun4i_backend_layer_funcs,
183 plane->formats, plane->nformats, 154 sun4i_backend_layer_formats,
184 NULL, plane->type, NULL); 155 ARRAY_SIZE(sun4i_backend_layer_formats),
156 NULL, type, NULL);
185 if (ret) { 157 if (ret) {
186 dev_err(drm->dev, "Couldn't initialize layer\n"); 158 dev_err(drm->dev, "Couldn't initialize layer\n");
187 return ERR_PTR(ret); 159 return ERR_PTR(ret);
@@ -191,6 +163,9 @@ static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm,
191 &sun4i_backend_layer_helper_funcs); 163 &sun4i_backend_layer_helper_funcs);
192 layer->backend = backend; 164 layer->backend = backend;
193 165
166 drm_plane_create_zpos_property(&layer->plane, 0, 0,
167 SUN4I_BACKEND_NUM_LAYERS - 1);
168
194 return layer; 169 return layer;
195} 170}
196 171
@@ -207,25 +182,17 @@ struct drm_plane **sun4i_layers_init(struct drm_device *drm,
207 if (!planes) 182 if (!planes)
208 return ERR_PTR(-ENOMEM); 183 return ERR_PTR(-ENOMEM);
209 184
210 for (i = 0; i < ARRAY_SIZE(sun4i_backend_planes); i++) { 185 for (i = 0; i < SUN4I_BACKEND_NUM_LAYERS; i++) {
211 const struct sun4i_plane_desc *plane = &sun4i_backend_planes[i]; 186 enum drm_plane_type type = i ? DRM_PLANE_TYPE_OVERLAY : DRM_PLANE_TYPE_PRIMARY;
212 struct sun4i_layer *layer; 187 struct sun4i_layer *layer;
213 188
214 layer = sun4i_layer_init_one(drm, backend, plane); 189 layer = sun4i_layer_init_one(drm, backend, type);
215 if (IS_ERR(layer)) { 190 if (IS_ERR(layer)) {
216 dev_err(drm->dev, "Couldn't initialize %s plane\n", 191 dev_err(drm->dev, "Couldn't initialize %s plane\n",
217 i ? "overlay" : "primary"); 192 i ? "overlay" : "primary");
218 return ERR_CAST(layer); 193 return ERR_CAST(layer);
219 }; 194 };
220 195
221 drm_plane_create_zpos_immutable_property(&layer->plane, i);
222
223 DRM_DEBUG_DRIVER("Assigning %s plane to pipe %d\n",
224 i ? "overlay" : "primary", plane->pipe);
225 regmap_update_bits(engine->regs, SUN4I_BACKEND_ATTCTL_REG0(i),
226 SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL_MASK,
227 SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL(plane->pipe));
228
229 layer->id = i; 196 layer->id = i;
230 planes[i] = &layer->plane; 197 planes[i] = &layer->plane;
231 }; 198 };
diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.h b/drivers/gpu/drm/sun4i/sun4i_layer.h
index 75b4868ba87c..36b20265bd31 100644
--- a/drivers/gpu/drm/sun4i/sun4i_layer.h
+++ b/drivers/gpu/drm/sun4i/sun4i_layer.h
@@ -24,6 +24,7 @@ struct sun4i_layer {
24 24
25struct sun4i_layer_state { 25struct sun4i_layer_state {
26 struct drm_plane_state state; 26 struct drm_plane_state state;
27 unsigned int pipe;
27 bool uses_frontend; 28 bool uses_frontend;
28}; 29};
29 30
diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
index d8d0684fc8aa..79154f0f674a 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
@@ -12,11 +12,158 @@
12#include <linux/regmap.h> 12#include <linux/regmap.h>
13#include <linux/reset.h> 13#include <linux/reset.h>
14 14
15#define SUN8I_HDMI_PHY_DBG_CTRL_REG 0x0000
16#define SUN8I_HDMI_PHY_DBG_CTRL_PX_LOCK BIT(0)
17#define SUN8I_HDMI_PHY_DBG_CTRL_POL_MASK GENMASK(15, 8)
18#define SUN8I_HDMI_PHY_DBG_CTRL_POL_NHSYNC BIT(8)
19#define SUN8I_HDMI_PHY_DBG_CTRL_POL_NVSYNC BIT(9)
20#define SUN8I_HDMI_PHY_DBG_CTRL_ADDR_MASK GENMASK(23, 16)
21#define SUN8I_HDMI_PHY_DBG_CTRL_ADDR(addr) (addr << 16)
22
23#define SUN8I_HDMI_PHY_REXT_CTRL_REG 0x0004
24#define SUN8I_HDMI_PHY_REXT_CTRL_REXT_EN BIT(31)
25
26#define SUN8I_HDMI_PHY_READ_EN_REG 0x0010
27#define SUN8I_HDMI_PHY_READ_EN_MAGIC 0x54524545
28
29#define SUN8I_HDMI_PHY_UNSCRAMBLE_REG 0x0014
30#define SUN8I_HDMI_PHY_UNSCRAMBLE_MAGIC 0x42494E47
31
32#define SUN8I_HDMI_PHY_ANA_CFG1_REG 0x0020
33#define SUN8I_HDMI_PHY_ANA_CFG1_REG_SWI BIT(31)
34#define SUN8I_HDMI_PHY_ANA_CFG1_REG_PWEND BIT(30)
35#define SUN8I_HDMI_PHY_ANA_CFG1_REG_PWENC BIT(29)
36#define SUN8I_HDMI_PHY_ANA_CFG1_REG_CALSW BIT(28)
37#define SUN8I_HDMI_PHY_ANA_CFG1_REG_SVRCAL(x) ((x) << 26)
38#define SUN8I_HDMI_PHY_ANA_CFG1_REG_SVBH(x) ((x) << 24)
39#define SUN8I_HDMI_PHY_ANA_CFG1_AMP_OPT BIT(23)
40#define SUN8I_HDMI_PHY_ANA_CFG1_EMP_OPT BIT(22)
41#define SUN8I_HDMI_PHY_ANA_CFG1_AMPCK_OPT BIT(21)
42#define SUN8I_HDMI_PHY_ANA_CFG1_EMPCK_OPT BIT(20)
43#define SUN8I_HDMI_PHY_ANA_CFG1_ENRCAL BIT(19)
44#define SUN8I_HDMI_PHY_ANA_CFG1_ENCALOG BIT(18)
45#define SUN8I_HDMI_PHY_ANA_CFG1_REG_SCKTMDS BIT(17)
46#define SUN8I_HDMI_PHY_ANA_CFG1_TMDSCLK_EN BIT(16)
47#define SUN8I_HDMI_PHY_ANA_CFG1_TXEN_MASK GENMASK(15, 12)
48#define SUN8I_HDMI_PHY_ANA_CFG1_TXEN_ALL (0xf << 12)
49#define SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDSCLK BIT(11)
50#define SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDS2 BIT(10)
51#define SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDS1 BIT(9)
52#define SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDS0 BIT(8)
53#define SUN8I_HDMI_PHY_ANA_CFG1_ENP2S_TMDSCLK BIT(7)
54#define SUN8I_HDMI_PHY_ANA_CFG1_ENP2S_TMDS2 BIT(6)
55#define SUN8I_HDMI_PHY_ANA_CFG1_ENP2S_TMDS1 BIT(5)
56#define SUN8I_HDMI_PHY_ANA_CFG1_ENP2S_TMDS0 BIT(4)
57#define SUN8I_HDMI_PHY_ANA_CFG1_CKEN BIT(3)
58#define SUN8I_HDMI_PHY_ANA_CFG1_LDOEN BIT(2)
59#define SUN8I_HDMI_PHY_ANA_CFG1_ENVBS BIT(1)
60#define SUN8I_HDMI_PHY_ANA_CFG1_ENBI BIT(0)
61
62#define SUN8I_HDMI_PHY_ANA_CFG2_REG 0x0024
63#define SUN8I_HDMI_PHY_ANA_CFG2_M_EN BIT(31)
64#define SUN8I_HDMI_PHY_ANA_CFG2_PLLDBEN BIT(30)
65#define SUN8I_HDMI_PHY_ANA_CFG2_SEN BIT(29)
66#define SUN8I_HDMI_PHY_ANA_CFG2_REG_HPDPD BIT(28)
67#define SUN8I_HDMI_PHY_ANA_CFG2_REG_HPDEN BIT(27)
68#define SUN8I_HDMI_PHY_ANA_CFG2_REG_PLRCK BIT(26)
69#define SUN8I_HDMI_PHY_ANA_CFG2_REG_PLR(x) ((x) << 23)
70#define SUN8I_HDMI_PHY_ANA_CFG2_REG_DENCK BIT(22)
71#define SUN8I_HDMI_PHY_ANA_CFG2_REG_DEN BIT(21)
72#define SUN8I_HDMI_PHY_ANA_CFG2_REG_CD(x) ((x) << 19)
73#define SUN8I_HDMI_PHY_ANA_CFG2_REG_CKSS(x) ((x) << 17)
74#define SUN8I_HDMI_PHY_ANA_CFG2_REG_BIGSWCK BIT(16)
75#define SUN8I_HDMI_PHY_ANA_CFG2_REG_BIGSW BIT(15)
76#define SUN8I_HDMI_PHY_ANA_CFG2_REG_CSMPS(x) ((x) << 13)
77#define SUN8I_HDMI_PHY_ANA_CFG2_REG_SLV(x) ((x) << 10)
78#define SUN8I_HDMI_PHY_ANA_CFG2_REG_BOOSTCK(x) ((x) << 8)
79#define SUN8I_HDMI_PHY_ANA_CFG2_REG_BOOST(x) ((x) << 6)
80#define SUN8I_HDMI_PHY_ANA_CFG2_REG_RESDI(x) ((x) << 0)
81
82#define SUN8I_HDMI_PHY_ANA_CFG3_REG 0x0028
83#define SUN8I_HDMI_PHY_ANA_CFG3_REG_SLOWCK(x) ((x) << 30)
84#define SUN8I_HDMI_PHY_ANA_CFG3_REG_SLOW(x) ((x) << 28)
85#define SUN8I_HDMI_PHY_ANA_CFG3_REG_WIRE(x) ((x) << 18)
86#define SUN8I_HDMI_PHY_ANA_CFG3_REG_AMPCK(x) ((x) << 14)
87#define SUN8I_HDMI_PHY_ANA_CFG3_REG_EMPCK(x) ((x) << 11)
88#define SUN8I_HDMI_PHY_ANA_CFG3_REG_AMP(x) ((x) << 7)
89#define SUN8I_HDMI_PHY_ANA_CFG3_REG_EMP(x) ((x) << 4)
90#define SUN8I_HDMI_PHY_ANA_CFG3_SDAPD BIT(3)
91#define SUN8I_HDMI_PHY_ANA_CFG3_SDAEN BIT(2)
92#define SUN8I_HDMI_PHY_ANA_CFG3_SCLPD BIT(1)
93#define SUN8I_HDMI_PHY_ANA_CFG3_SCLEN BIT(0)
94
95#define SUN8I_HDMI_PHY_PLL_CFG1_REG 0x002c
96#define SUN8I_HDMI_PHY_PLL_CFG1_REG_OD1 BIT(31)
97#define SUN8I_HDMI_PHY_PLL_CFG1_REG_OD BIT(30)
98#define SUN8I_HDMI_PHY_PLL_CFG1_LDO2_EN BIT(29)
99#define SUN8I_HDMI_PHY_PLL_CFG1_LDO1_EN BIT(28)
100#define SUN8I_HDMI_PHY_PLL_CFG1_HV_IS_33 BIT(27)
101#define SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL BIT(26)
102#define SUN8I_HDMI_PHY_PLL_CFG1_PLLEN BIT(25)
103#define SUN8I_HDMI_PHY_PLL_CFG1_LDO_VSET(x) ((x) << 22)
104#define SUN8I_HDMI_PHY_PLL_CFG1_UNKNOWN(x) ((x) << 20)
105#define SUN8I_HDMI_PHY_PLL_CFG1_PLLDBEN BIT(19)
106#define SUN8I_HDMI_PHY_PLL_CFG1_CS BIT(18)
107#define SUN8I_HDMI_PHY_PLL_CFG1_CP_S(x) ((x) << 13)
108#define SUN8I_HDMI_PHY_PLL_CFG1_CNT_INT(x) ((x) << 7)
109#define SUN8I_HDMI_PHY_PLL_CFG1_BWS BIT(6)
110#define SUN8I_HDMI_PHY_PLL_CFG1_B_IN_MSK GENMASK(5, 0)
111#define SUN8I_HDMI_PHY_PLL_CFG1_B_IN_SHIFT 0
112
113#define SUN8I_HDMI_PHY_PLL_CFG2_REG 0x0030
114#define SUN8I_HDMI_PHY_PLL_CFG2_SV_H BIT(31)
115#define SUN8I_HDMI_PHY_PLL_CFG2_PDCLKSEL(x) ((x) << 29)
116#define SUN8I_HDMI_PHY_PLL_CFG2_CLKSTEP(x) ((x) << 27)
117#define SUN8I_HDMI_PHY_PLL_CFG2_PSET(x) ((x) << 24)
118#define SUN8I_HDMI_PHY_PLL_CFG2_PCLK_SEL BIT(23)
119#define SUN8I_HDMI_PHY_PLL_CFG2_AUTOSYNC_DIS BIT(22)
120#define SUN8I_HDMI_PHY_PLL_CFG2_VREG2_OUT_EN BIT(21)
121#define SUN8I_HDMI_PHY_PLL_CFG2_VREG1_OUT_EN BIT(20)
122#define SUN8I_HDMI_PHY_PLL_CFG2_VCOGAIN_EN BIT(19)
123#define SUN8I_HDMI_PHY_PLL_CFG2_VCOGAIN(x) ((x) << 16)
124#define SUN8I_HDMI_PHY_PLL_CFG2_VCO_S(x) ((x) << 12)
125#define SUN8I_HDMI_PHY_PLL_CFG2_VCO_RST_IN BIT(11)
126#define SUN8I_HDMI_PHY_PLL_CFG2_SINT_FRAC BIT(10)
127#define SUN8I_HDMI_PHY_PLL_CFG2_SDIV2 BIT(9)
128#define SUN8I_HDMI_PHY_PLL_CFG2_S(x) ((x) << 6)
129#define SUN8I_HDMI_PHY_PLL_CFG2_S6P25_7P5 BIT(5)
130#define SUN8I_HDMI_PHY_PLL_CFG2_S5_7 BIT(4)
131#define SUN8I_HDMI_PHY_PLL_CFG2_PREDIV_MSK GENMASK(3, 0)
132#define SUN8I_HDMI_PHY_PLL_CFG2_PREDIV_SHIFT 0
133#define SUN8I_HDMI_PHY_PLL_CFG2_PREDIV(x) (((x) - 1) << 0)
134
135#define SUN8I_HDMI_PHY_PLL_CFG3_REG 0x0034
136#define SUN8I_HDMI_PHY_PLL_CFG3_SOUT_DIV2 BIT(0)
137
138#define SUN8I_HDMI_PHY_ANA_STS_REG 0x0038
139#define SUN8I_HDMI_PHY_ANA_STS_B_OUT_SHIFT 11
140#define SUN8I_HDMI_PHY_ANA_STS_B_OUT_MSK GENMASK(16, 11)
141#define SUN8I_HDMI_PHY_ANA_STS_RCALEND2D BIT(7)
142#define SUN8I_HDMI_PHY_ANA_STS_RCAL_MASK GENMASK(5, 0)
143
144#define SUN8I_HDMI_PHY_CEC_REG 0x003c
145
146struct sun8i_hdmi_phy;
147
148struct sun8i_hdmi_phy_variant {
149 bool has_phy_clk;
150 void (*phy_init)(struct sun8i_hdmi_phy *phy);
151 void (*phy_disable)(struct dw_hdmi *hdmi,
152 struct sun8i_hdmi_phy *phy);
153 int (*phy_config)(struct dw_hdmi *hdmi,
154 struct sun8i_hdmi_phy *phy,
155 unsigned int clk_rate);
156};
157
15struct sun8i_hdmi_phy { 158struct sun8i_hdmi_phy {
16 struct clk *clk_bus; 159 struct clk *clk_bus;
17 struct clk *clk_mod; 160 struct clk *clk_mod;
18 struct regmap *regs; 161 struct clk *clk_phy;
19 struct reset_control *rst_phy; 162 struct clk *clk_pll0;
163 unsigned int rcal;
164 struct regmap *regs;
165 struct reset_control *rst_phy;
166 struct sun8i_hdmi_phy_variant *variant;
20}; 167};
21 168
22struct sun8i_dw_hdmi { 169struct sun8i_dw_hdmi {
@@ -41,4 +188,6 @@ void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi *hdmi);
41void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy); 188void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy);
42const struct dw_hdmi_phy_ops *sun8i_hdmi_phy_get_ops(void); 189const struct dw_hdmi_phy_ops *sun8i_hdmi_phy_get_ops(void);
43 190
191int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev);
192
44#endif /* _SUN8I_DW_HDMI_H_ */ 193#endif /* _SUN8I_DW_HDMI_H_ */
diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
index e5bfcdd43ec9..5a52fc489a9d 100644
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
@@ -3,47 +3,21 @@
3 * Copyright (c) 2018 Jernej Skrabec <jernej.skrabec@siol.net> 3 * Copyright (c) 2018 Jernej Skrabec <jernej.skrabec@siol.net>
4 */ 4 */
5 5
6#include <linux/delay.h>
6#include <linux/of_address.h> 7#include <linux/of_address.h>
7 8
8#include "sun8i_dw_hdmi.h" 9#include "sun8i_dw_hdmi.h"
9 10
10#define SUN8I_HDMI_PHY_DBG_CTRL_REG 0x0000
11#define SUN8I_HDMI_PHY_DBG_CTRL_PX_LOCK BIT(0)
12#define SUN8I_HDMI_PHY_DBG_CTRL_POL_MASK GENMASK(15, 8)
13#define SUN8I_HDMI_PHY_DBG_CTRL_POL(val) (val << 8)
14#define SUN8I_HDMI_PHY_DBG_CTRL_ADDR_MASK GENMASK(23, 16)
15#define SUN8I_HDMI_PHY_DBG_CTRL_ADDR(addr) (addr << 16)
16
17#define SUN8I_HDMI_PHY_REXT_CTRL_REG 0x0004
18#define SUN8I_HDMI_PHY_REXT_CTRL_REXT_EN BIT(31)
19
20#define SUN8I_HDMI_PHY_READ_EN_REG 0x0010
21#define SUN8I_HDMI_PHY_READ_EN_MAGIC 0x54524545
22
23#define SUN8I_HDMI_PHY_UNSCRAMBLE_REG 0x0014
24#define SUN8I_HDMI_PHY_UNSCRAMBLE_MAGIC 0x42494E47
25
26/* 11/*
27 * Address can be actually any value. Here is set to same value as 12 * Address can be actually any value. Here is set to same value as
28 * it is set in BSP driver. 13 * it is set in BSP driver.
29 */ 14 */
30#define I2C_ADDR 0x69 15#define I2C_ADDR 0x69
31 16
32static int sun8i_hdmi_phy_config(struct dw_hdmi *hdmi, void *data, 17static int sun8i_hdmi_phy_config_a83t(struct dw_hdmi *hdmi,
33 struct drm_display_mode *mode) 18 struct sun8i_hdmi_phy *phy,
19 unsigned int clk_rate)
34{ 20{
35 struct sun8i_hdmi_phy *phy = (struct sun8i_hdmi_phy *)data;
36 u32 val = 0;
37
38 if ((mode->flags & DRM_MODE_FLAG_NHSYNC) &&
39 (mode->flags & DRM_MODE_FLAG_NHSYNC)) {
40 val = 0x03;
41 }
42
43 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_DBG_CTRL_REG,
44 SUN8I_HDMI_PHY_DBG_CTRL_POL_MASK,
45 SUN8I_HDMI_PHY_DBG_CTRL_POL(val));
46
47 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_REXT_CTRL_REG, 21 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_REXT_CTRL_REG,
48 SUN8I_HDMI_PHY_REXT_CTRL_REXT_EN, 22 SUN8I_HDMI_PHY_REXT_CTRL_REXT_EN,
49 SUN8I_HDMI_PHY_REXT_CTRL_REXT_EN); 23 SUN8I_HDMI_PHY_REXT_CTRL_REXT_EN);
@@ -63,21 +37,21 @@ static int sun8i_hdmi_phy_config(struct dw_hdmi *hdmi, void *data,
63 * release any documentation, explanation of this values can 37 * release any documentation, explanation of this values can
64 * be found in i.MX 6Dual/6Quad Reference Manual. 38 * be found in i.MX 6Dual/6Quad Reference Manual.
65 */ 39 */
66 if (mode->crtc_clock <= 27000) { 40 if (clk_rate <= 27000000) {
67 dw_hdmi_phy_i2c_write(hdmi, 0x01e0, 0x06); 41 dw_hdmi_phy_i2c_write(hdmi, 0x01e0, 0x06);
68 dw_hdmi_phy_i2c_write(hdmi, 0x0000, 0x15); 42 dw_hdmi_phy_i2c_write(hdmi, 0x0000, 0x15);
69 dw_hdmi_phy_i2c_write(hdmi, 0x08da, 0x10); 43 dw_hdmi_phy_i2c_write(hdmi, 0x08da, 0x10);
70 dw_hdmi_phy_i2c_write(hdmi, 0x0007, 0x19); 44 dw_hdmi_phy_i2c_write(hdmi, 0x0007, 0x19);
71 dw_hdmi_phy_i2c_write(hdmi, 0x0318, 0x0e); 45 dw_hdmi_phy_i2c_write(hdmi, 0x0318, 0x0e);
72 dw_hdmi_phy_i2c_write(hdmi, 0x8009, 0x09); 46 dw_hdmi_phy_i2c_write(hdmi, 0x8009, 0x09);
73 } else if (mode->crtc_clock <= 74250) { 47 } else if (clk_rate <= 74250000) {
74 dw_hdmi_phy_i2c_write(hdmi, 0x0540, 0x06); 48 dw_hdmi_phy_i2c_write(hdmi, 0x0540, 0x06);
75 dw_hdmi_phy_i2c_write(hdmi, 0x0005, 0x15); 49 dw_hdmi_phy_i2c_write(hdmi, 0x0005, 0x15);
76 dw_hdmi_phy_i2c_write(hdmi, 0x0000, 0x10); 50 dw_hdmi_phy_i2c_write(hdmi, 0x0000, 0x10);
77 dw_hdmi_phy_i2c_write(hdmi, 0x0007, 0x19); 51 dw_hdmi_phy_i2c_write(hdmi, 0x0007, 0x19);
78 dw_hdmi_phy_i2c_write(hdmi, 0x02b5, 0x0e); 52 dw_hdmi_phy_i2c_write(hdmi, 0x02b5, 0x0e);
79 dw_hdmi_phy_i2c_write(hdmi, 0x8009, 0x09); 53 dw_hdmi_phy_i2c_write(hdmi, 0x8009, 0x09);
80 } else if (mode->crtc_clock <= 148500) { 54 } else if (clk_rate <= 148500000) {
81 dw_hdmi_phy_i2c_write(hdmi, 0x04a0, 0x06); 55 dw_hdmi_phy_i2c_write(hdmi, 0x04a0, 0x06);
82 dw_hdmi_phy_i2c_write(hdmi, 0x000a, 0x15); 56 dw_hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
83 dw_hdmi_phy_i2c_write(hdmi, 0x0000, 0x10); 57 dw_hdmi_phy_i2c_write(hdmi, 0x0000, 0x10);
@@ -100,12 +74,173 @@ static int sun8i_hdmi_phy_config(struct dw_hdmi *hdmi, void *data,
100 dw_hdmi_phy_gen2_txpwron(hdmi, 1); 74 dw_hdmi_phy_gen2_txpwron(hdmi, 1);
101 75
102 return 0; 76 return 0;
103}; 77}
104 78
105static void sun8i_hdmi_phy_disable(struct dw_hdmi *hdmi, void *data) 79static int sun8i_hdmi_phy_config_h3(struct dw_hdmi *hdmi,
80 struct sun8i_hdmi_phy *phy,
81 unsigned int clk_rate)
82{
83 u32 pll_cfg1_init;
84 u32 pll_cfg2_init;
85 u32 ana_cfg1_end;
86 u32 ana_cfg2_init;
87 u32 ana_cfg3_init;
88 u32 b_offset = 0;
89 u32 val;
90
91 /* bandwidth / frequency independent settings */
92
93 pll_cfg1_init = SUN8I_HDMI_PHY_PLL_CFG1_LDO2_EN |
94 SUN8I_HDMI_PHY_PLL_CFG1_LDO1_EN |
95 SUN8I_HDMI_PHY_PLL_CFG1_LDO_VSET(7) |
96 SUN8I_HDMI_PHY_PLL_CFG1_UNKNOWN(1) |
97 SUN8I_HDMI_PHY_PLL_CFG1_PLLDBEN |
98 SUN8I_HDMI_PHY_PLL_CFG1_CS |
99 SUN8I_HDMI_PHY_PLL_CFG1_CP_S(2) |
100 SUN8I_HDMI_PHY_PLL_CFG1_CNT_INT(63) |
101 SUN8I_HDMI_PHY_PLL_CFG1_BWS;
102
103 pll_cfg2_init = SUN8I_HDMI_PHY_PLL_CFG2_SV_H |
104 SUN8I_HDMI_PHY_PLL_CFG2_VCOGAIN_EN |
105 SUN8I_HDMI_PHY_PLL_CFG2_SDIV2;
106
107 ana_cfg1_end = SUN8I_HDMI_PHY_ANA_CFG1_REG_SVBH(1) |
108 SUN8I_HDMI_PHY_ANA_CFG1_AMP_OPT |
109 SUN8I_HDMI_PHY_ANA_CFG1_EMP_OPT |
110 SUN8I_HDMI_PHY_ANA_CFG1_AMPCK_OPT |
111 SUN8I_HDMI_PHY_ANA_CFG1_EMPCK_OPT |
112 SUN8I_HDMI_PHY_ANA_CFG1_ENRCAL |
113 SUN8I_HDMI_PHY_ANA_CFG1_ENCALOG |
114 SUN8I_HDMI_PHY_ANA_CFG1_REG_SCKTMDS |
115 SUN8I_HDMI_PHY_ANA_CFG1_TMDSCLK_EN |
116 SUN8I_HDMI_PHY_ANA_CFG1_TXEN_MASK |
117 SUN8I_HDMI_PHY_ANA_CFG1_TXEN_ALL |
118 SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDSCLK |
119 SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDS2 |
120 SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDS1 |
121 SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDS0 |
122 SUN8I_HDMI_PHY_ANA_CFG1_ENP2S_TMDS2 |
123 SUN8I_HDMI_PHY_ANA_CFG1_ENP2S_TMDS1 |
124 SUN8I_HDMI_PHY_ANA_CFG1_ENP2S_TMDS0 |
125 SUN8I_HDMI_PHY_ANA_CFG1_CKEN |
126 SUN8I_HDMI_PHY_ANA_CFG1_LDOEN |
127 SUN8I_HDMI_PHY_ANA_CFG1_ENVBS |
128 SUN8I_HDMI_PHY_ANA_CFG1_ENBI;
129
130 ana_cfg2_init = SUN8I_HDMI_PHY_ANA_CFG2_M_EN |
131 SUN8I_HDMI_PHY_ANA_CFG2_REG_DENCK |
132 SUN8I_HDMI_PHY_ANA_CFG2_REG_DEN |
133 SUN8I_HDMI_PHY_ANA_CFG2_REG_CKSS(1) |
134 SUN8I_HDMI_PHY_ANA_CFG2_REG_CSMPS(1);
135
136 ana_cfg3_init = SUN8I_HDMI_PHY_ANA_CFG3_REG_WIRE(0x3e0) |
137 SUN8I_HDMI_PHY_ANA_CFG3_SDAEN |
138 SUN8I_HDMI_PHY_ANA_CFG3_SCLEN;
139
140 /* bandwidth / frequency dependent settings */
141 if (clk_rate <= 27000000) {
142 pll_cfg1_init |= SUN8I_HDMI_PHY_PLL_CFG1_HV_IS_33 |
143 SUN8I_HDMI_PHY_PLL_CFG1_CNT_INT(32);
144 pll_cfg2_init |= SUN8I_HDMI_PHY_PLL_CFG2_VCO_S(4) |
145 SUN8I_HDMI_PHY_PLL_CFG2_S(4);
146 ana_cfg1_end |= SUN8I_HDMI_PHY_ANA_CFG1_REG_CALSW;
147 ana_cfg2_init |= SUN8I_HDMI_PHY_ANA_CFG2_REG_SLV(4) |
148 SUN8I_HDMI_PHY_ANA_CFG2_REG_RESDI(phy->rcal);
149 ana_cfg3_init |= SUN8I_HDMI_PHY_ANA_CFG3_REG_AMPCK(3) |
150 SUN8I_HDMI_PHY_ANA_CFG3_REG_AMP(5);
151 } else if (clk_rate <= 74250000) {
152 pll_cfg1_init |= SUN8I_HDMI_PHY_PLL_CFG1_HV_IS_33 |
153 SUN8I_HDMI_PHY_PLL_CFG1_CNT_INT(32);
154 pll_cfg2_init |= SUN8I_HDMI_PHY_PLL_CFG2_VCO_S(4) |
155 SUN8I_HDMI_PHY_PLL_CFG2_S(5);
156 ana_cfg1_end |= SUN8I_HDMI_PHY_ANA_CFG1_REG_CALSW;
157 ana_cfg2_init |= SUN8I_HDMI_PHY_ANA_CFG2_REG_SLV(4) |
158 SUN8I_HDMI_PHY_ANA_CFG2_REG_RESDI(phy->rcal);
159 ana_cfg3_init |= SUN8I_HDMI_PHY_ANA_CFG3_REG_AMPCK(5) |
160 SUN8I_HDMI_PHY_ANA_CFG3_REG_AMP(7);
161 } else if (clk_rate <= 148500000) {
162 pll_cfg1_init |= SUN8I_HDMI_PHY_PLL_CFG1_HV_IS_33 |
163 SUN8I_HDMI_PHY_PLL_CFG1_CNT_INT(32);
164 pll_cfg2_init |= SUN8I_HDMI_PHY_PLL_CFG2_VCO_S(4) |
165 SUN8I_HDMI_PHY_PLL_CFG2_S(6);
166 ana_cfg2_init |= SUN8I_HDMI_PHY_ANA_CFG2_REG_BIGSWCK |
167 SUN8I_HDMI_PHY_ANA_CFG2_REG_BIGSW |
168 SUN8I_HDMI_PHY_ANA_CFG2_REG_SLV(2);
169 ana_cfg3_init |= SUN8I_HDMI_PHY_ANA_CFG3_REG_AMPCK(7) |
170 SUN8I_HDMI_PHY_ANA_CFG3_REG_AMP(9);
171 } else {
172 b_offset = 2;
173 pll_cfg1_init |= SUN8I_HDMI_PHY_PLL_CFG1_CNT_INT(63);
174 pll_cfg2_init |= SUN8I_HDMI_PHY_PLL_CFG2_VCO_S(6) |
175 SUN8I_HDMI_PHY_PLL_CFG2_S(7);
176 ana_cfg2_init |= SUN8I_HDMI_PHY_ANA_CFG2_REG_BIGSWCK |
177 SUN8I_HDMI_PHY_ANA_CFG2_REG_BIGSW |
178 SUN8I_HDMI_PHY_ANA_CFG2_REG_SLV(4);
179 ana_cfg3_init |= SUN8I_HDMI_PHY_ANA_CFG3_REG_AMPCK(9) |
180 SUN8I_HDMI_PHY_ANA_CFG3_REG_AMP(13);
181 }
182
183 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG,
184 SUN8I_HDMI_PHY_ANA_CFG1_TXEN_MASK, 0);
185
186 regmap_write(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG, pll_cfg1_init);
187 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG2_REG,
188 (u32)~SUN8I_HDMI_PHY_PLL_CFG2_PREDIV_MSK,
189 pll_cfg2_init);
190 usleep_range(10000, 15000);
191 regmap_write(phy->regs, SUN8I_HDMI_PHY_PLL_CFG3_REG,
192 SUN8I_HDMI_PHY_PLL_CFG3_SOUT_DIV2);
193 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG,
194 SUN8I_HDMI_PHY_PLL_CFG1_PLLEN,
195 SUN8I_HDMI_PHY_PLL_CFG1_PLLEN);
196 msleep(100);
197
198 /* get B value */
199 regmap_read(phy->regs, SUN8I_HDMI_PHY_ANA_STS_REG, &val);
200 val = (val & SUN8I_HDMI_PHY_ANA_STS_B_OUT_MSK) >>
201 SUN8I_HDMI_PHY_ANA_STS_B_OUT_SHIFT;
202 val = min(val + b_offset, (u32)0x3f);
203
204 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG,
205 SUN8I_HDMI_PHY_PLL_CFG1_REG_OD1 |
206 SUN8I_HDMI_PHY_PLL_CFG1_REG_OD,
207 SUN8I_HDMI_PHY_PLL_CFG1_REG_OD1 |
208 SUN8I_HDMI_PHY_PLL_CFG1_REG_OD);
209 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG,
210 SUN8I_HDMI_PHY_PLL_CFG1_B_IN_MSK,
211 val << SUN8I_HDMI_PHY_PLL_CFG1_B_IN_SHIFT);
212 msleep(100);
213 regmap_write(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG, ana_cfg1_end);
214 regmap_write(phy->regs, SUN8I_HDMI_PHY_ANA_CFG2_REG, ana_cfg2_init);
215 regmap_write(phy->regs, SUN8I_HDMI_PHY_ANA_CFG3_REG, ana_cfg3_init);
216
217 return 0;
218}
219
220static int sun8i_hdmi_phy_config(struct dw_hdmi *hdmi, void *data,
221 struct drm_display_mode *mode)
106{ 222{
107 struct sun8i_hdmi_phy *phy = (struct sun8i_hdmi_phy *)data; 223 struct sun8i_hdmi_phy *phy = (struct sun8i_hdmi_phy *)data;
224 u32 val = 0;
225
226 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
227 val |= SUN8I_HDMI_PHY_DBG_CTRL_POL_NHSYNC;
228
229 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
230 val |= SUN8I_HDMI_PHY_DBG_CTRL_POL_NVSYNC;
108 231
232 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_DBG_CTRL_REG,
233 SUN8I_HDMI_PHY_DBG_CTRL_POL_MASK, val);
234
235 if (phy->variant->has_phy_clk)
236 clk_set_rate(phy->clk_phy, mode->crtc_clock * 1000);
237
238 return phy->variant->phy_config(hdmi, phy, mode->crtc_clock * 1000);
239};
240
241static void sun8i_hdmi_phy_disable_a83t(struct dw_hdmi *hdmi,
242 struct sun8i_hdmi_phy *phy)
243{
109 dw_hdmi_phy_gen2_txpwron(hdmi, 0); 244 dw_hdmi_phy_gen2_txpwron(hdmi, 0);
110 dw_hdmi_phy_gen2_pddq(hdmi, 1); 245 dw_hdmi_phy_gen2_pddq(hdmi, 1);
111 246
@@ -113,6 +248,23 @@ static void sun8i_hdmi_phy_disable(struct dw_hdmi *hdmi, void *data)
113 SUN8I_HDMI_PHY_REXT_CTRL_REXT_EN, 0); 248 SUN8I_HDMI_PHY_REXT_CTRL_REXT_EN, 0);
114} 249}
115 250
251static void sun8i_hdmi_phy_disable_h3(struct dw_hdmi *hdmi,
252 struct sun8i_hdmi_phy *phy)
253{
254 regmap_write(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG,
255 SUN8I_HDMI_PHY_ANA_CFG1_LDOEN |
256 SUN8I_HDMI_PHY_ANA_CFG1_ENVBS |
257 SUN8I_HDMI_PHY_ANA_CFG1_ENBI);
258 regmap_write(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG, 0);
259}
260
261static void sun8i_hdmi_phy_disable(struct dw_hdmi *hdmi, void *data)
262{
263 struct sun8i_hdmi_phy *phy = (struct sun8i_hdmi_phy *)data;
264
265 phy->variant->phy_disable(hdmi, phy);
266}
267
116static const struct dw_hdmi_phy_ops sun8i_hdmi_phy_ops = { 268static const struct dw_hdmi_phy_ops sun8i_hdmi_phy_ops = {
117 .init = &sun8i_hdmi_phy_config, 269 .init = &sun8i_hdmi_phy_config,
118 .disable = &sun8i_hdmi_phy_disable, 270 .disable = &sun8i_hdmi_phy_disable,
@@ -121,16 +273,8 @@ static const struct dw_hdmi_phy_ops sun8i_hdmi_phy_ops = {
121 .setup_hpd = &dw_hdmi_phy_setup_hpd, 273 .setup_hpd = &dw_hdmi_phy_setup_hpd,
122}; 274};
123 275
124void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy) 276static void sun8i_hdmi_phy_init_a83t(struct sun8i_hdmi_phy *phy)
125{ 277{
126 /* enable read access to HDMI controller */
127 regmap_write(phy->regs, SUN8I_HDMI_PHY_READ_EN_REG,
128 SUN8I_HDMI_PHY_READ_EN_MAGIC);
129
130 /* unscramble register offsets */
131 regmap_write(phy->regs, SUN8I_HDMI_PHY_UNSCRAMBLE_REG,
132 SUN8I_HDMI_PHY_UNSCRAMBLE_MAGIC);
133
134 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_DBG_CTRL_REG, 278 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_DBG_CTRL_REG,
135 SUN8I_HDMI_PHY_DBG_CTRL_PX_LOCK, 279 SUN8I_HDMI_PHY_DBG_CTRL_PX_LOCK,
136 SUN8I_HDMI_PHY_DBG_CTRL_PX_LOCK); 280 SUN8I_HDMI_PHY_DBG_CTRL_PX_LOCK);
@@ -144,6 +288,91 @@ void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy)
144 SUN8I_HDMI_PHY_DBG_CTRL_ADDR(I2C_ADDR)); 288 SUN8I_HDMI_PHY_DBG_CTRL_ADDR(I2C_ADDR));
145} 289}
146 290
291static void sun8i_hdmi_phy_init_h3(struct sun8i_hdmi_phy *phy)
292{
293 unsigned int val;
294
295 regmap_write(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG, 0);
296 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG,
297 SUN8I_HDMI_PHY_ANA_CFG1_ENBI,
298 SUN8I_HDMI_PHY_ANA_CFG1_ENBI);
299 udelay(5);
300 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG,
301 SUN8I_HDMI_PHY_ANA_CFG1_TMDSCLK_EN,
302 SUN8I_HDMI_PHY_ANA_CFG1_TMDSCLK_EN);
303 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG,
304 SUN8I_HDMI_PHY_ANA_CFG1_ENVBS,
305 SUN8I_HDMI_PHY_ANA_CFG1_ENVBS);
306 usleep_range(10, 20);
307 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG,
308 SUN8I_HDMI_PHY_ANA_CFG1_LDOEN,
309 SUN8I_HDMI_PHY_ANA_CFG1_LDOEN);
310 udelay(5);
311 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG,
312 SUN8I_HDMI_PHY_ANA_CFG1_CKEN,
313 SUN8I_HDMI_PHY_ANA_CFG1_CKEN);
314 usleep_range(40, 100);
315 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG,
316 SUN8I_HDMI_PHY_ANA_CFG1_ENRCAL,
317 SUN8I_HDMI_PHY_ANA_CFG1_ENRCAL);
318 usleep_range(100, 200);
319 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG,
320 SUN8I_HDMI_PHY_ANA_CFG1_ENCALOG,
321 SUN8I_HDMI_PHY_ANA_CFG1_ENCALOG);
322 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG,
323 SUN8I_HDMI_PHY_ANA_CFG1_ENP2S_TMDS0 |
324 SUN8I_HDMI_PHY_ANA_CFG1_ENP2S_TMDS1 |
325 SUN8I_HDMI_PHY_ANA_CFG1_ENP2S_TMDS2,
326 SUN8I_HDMI_PHY_ANA_CFG1_ENP2S_TMDS0 |
327 SUN8I_HDMI_PHY_ANA_CFG1_ENP2S_TMDS1 |
328 SUN8I_HDMI_PHY_ANA_CFG1_ENP2S_TMDS2);
329
330 /* wait for calibration to finish */
331 regmap_read_poll_timeout(phy->regs, SUN8I_HDMI_PHY_ANA_STS_REG, val,
332 (val & SUN8I_HDMI_PHY_ANA_STS_RCALEND2D),
333 100, 2000);
334
335 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG,
336 SUN8I_HDMI_PHY_ANA_CFG1_ENP2S_TMDSCLK,
337 SUN8I_HDMI_PHY_ANA_CFG1_ENP2S_TMDSCLK);
338 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG,
339 SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDS0 |
340 SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDS1 |
341 SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDS2 |
342 SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDSCLK,
343 SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDS0 |
344 SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDS1 |
345 SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDS2 |
346 SUN8I_HDMI_PHY_ANA_CFG1_BIASEN_TMDSCLK);
347
348 /* enable DDC communication */
349 regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG3_REG,
350 SUN8I_HDMI_PHY_ANA_CFG3_SCLEN |
351 SUN8I_HDMI_PHY_ANA_CFG3_SDAEN,
352 SUN8I_HDMI_PHY_ANA_CFG3_SCLEN |
353 SUN8I_HDMI_PHY_ANA_CFG3_SDAEN);
354
355 /* set HW control of CEC pins */
356 regmap_write(phy->regs, SUN8I_HDMI_PHY_CEC_REG, 0);
357
358 /* read calibration data */
359 regmap_read(phy->regs, SUN8I_HDMI_PHY_ANA_STS_REG, &val);
360 phy->rcal = (val & SUN8I_HDMI_PHY_ANA_STS_RCAL_MASK) >> 2;
361}
362
363void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy)
364{
365 /* enable read access to HDMI controller */
366 regmap_write(phy->regs, SUN8I_HDMI_PHY_READ_EN_REG,
367 SUN8I_HDMI_PHY_READ_EN_MAGIC);
368
369 /* unscramble register offsets */
370 regmap_write(phy->regs, SUN8I_HDMI_PHY_UNSCRAMBLE_REG,
371 SUN8I_HDMI_PHY_UNSCRAMBLE_MAGIC);
372
373 phy->variant->phy_init(phy);
374}
375
147const struct dw_hdmi_phy_ops *sun8i_hdmi_phy_get_ops(void) 376const struct dw_hdmi_phy_ops *sun8i_hdmi_phy_get_ops(void)
148{ 377{
149 return &sun8i_hdmi_phy_ops; 378 return &sun8i_hdmi_phy_ops;
@@ -153,24 +382,46 @@ static struct regmap_config sun8i_hdmi_phy_regmap_config = {
153 .reg_bits = 32, 382 .reg_bits = 32,
154 .val_bits = 32, 383 .val_bits = 32,
155 .reg_stride = 4, 384 .reg_stride = 4,
156 .max_register = SUN8I_HDMI_PHY_UNSCRAMBLE_REG, 385 .max_register = SUN8I_HDMI_PHY_CEC_REG,
157 .name = "phy" 386 .name = "phy"
158}; 387};
159 388
389static const struct sun8i_hdmi_phy_variant sun8i_a83t_hdmi_phy = {
390 .phy_init = &sun8i_hdmi_phy_init_a83t,
391 .phy_disable = &sun8i_hdmi_phy_disable_a83t,
392 .phy_config = &sun8i_hdmi_phy_config_a83t,
393};
394
395static const struct sun8i_hdmi_phy_variant sun8i_h3_hdmi_phy = {
396 .has_phy_clk = true,
397 .phy_init = &sun8i_hdmi_phy_init_h3,
398 .phy_disable = &sun8i_hdmi_phy_disable_h3,
399 .phy_config = &sun8i_hdmi_phy_config_h3,
400};
401
160static const struct of_device_id sun8i_hdmi_phy_of_table[] = { 402static const struct of_device_id sun8i_hdmi_phy_of_table[] = {
161 { .compatible = "allwinner,sun8i-a83t-hdmi-phy" }, 403 {
404 .compatible = "allwinner,sun8i-a83t-hdmi-phy",
405 .data = &sun8i_a83t_hdmi_phy,
406 },
407 {
408 .compatible = "allwinner,sun8i-h3-hdmi-phy",
409 .data = &sun8i_h3_hdmi_phy,
410 },
162 { /* sentinel */ } 411 { /* sentinel */ }
163}; 412};
164 413
165int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node) 414int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node)
166{ 415{
416 const struct of_device_id *match;
167 struct device *dev = hdmi->dev; 417 struct device *dev = hdmi->dev;
168 struct sun8i_hdmi_phy *phy; 418 struct sun8i_hdmi_phy *phy;
169 struct resource res; 419 struct resource res;
170 void __iomem *regs; 420 void __iomem *regs;
171 int ret; 421 int ret;
172 422
173 if (!of_match_node(sun8i_hdmi_phy_of_table, node)) { 423 match = of_match_node(sun8i_hdmi_phy_of_table, node);
424 if (!match) {
174 dev_err(dev, "Incompatible HDMI PHY\n"); 425 dev_err(dev, "Incompatible HDMI PHY\n");
175 return -EINVAL; 426 return -EINVAL;
176 } 427 }
@@ -179,6 +430,8 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node)
179 if (!phy) 430 if (!phy)
180 return -ENOMEM; 431 return -ENOMEM;
181 432
433 phy->variant = (struct sun8i_hdmi_phy_variant *)match->data;
434
182 ret = of_address_to_resource(node, 0, &res); 435 ret = of_address_to_resource(node, 0, &res);
183 if (ret) { 436 if (ret) {
184 dev_err(dev, "phy: Couldn't get our resources\n"); 437 dev_err(dev, "phy: Couldn't get our resources\n");
@@ -211,11 +464,26 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node)
211 goto err_put_clk_bus; 464 goto err_put_clk_bus;
212 } 465 }
213 466
467 if (phy->variant->has_phy_clk) {
468 phy->clk_pll0 = of_clk_get_by_name(node, "pll-0");
469 if (IS_ERR(phy->clk_pll0)) {
470 dev_err(dev, "Could not get pll-0 clock\n");
471 ret = PTR_ERR(phy->clk_pll0);
472 goto err_put_clk_mod;
473 }
474
475 ret = sun8i_phy_clk_create(phy, dev);
476 if (ret) {
477 dev_err(dev, "Couldn't create the PHY clock\n");
478 goto err_put_clk_pll0;
479 }
480 }
481
214 phy->rst_phy = of_reset_control_get_shared(node, "phy"); 482 phy->rst_phy = of_reset_control_get_shared(node, "phy");
215 if (IS_ERR(phy->rst_phy)) { 483 if (IS_ERR(phy->rst_phy)) {
216 dev_err(dev, "Could not get phy reset control\n"); 484 dev_err(dev, "Could not get phy reset control\n");
217 ret = PTR_ERR(phy->rst_phy); 485 ret = PTR_ERR(phy->rst_phy);
218 goto err_put_clk_mod; 486 goto err_put_clk_pll0;
219 } 487 }
220 488
221 ret = reset_control_deassert(phy->rst_phy); 489 ret = reset_control_deassert(phy->rst_phy);
@@ -246,6 +514,9 @@ err_deassert_rst_phy:
246 reset_control_assert(phy->rst_phy); 514 reset_control_assert(phy->rst_phy);
247err_put_rst_phy: 515err_put_rst_phy:
248 reset_control_put(phy->rst_phy); 516 reset_control_put(phy->rst_phy);
517err_put_clk_pll0:
518 if (phy->variant->has_phy_clk)
519 clk_put(phy->clk_pll0);
249err_put_clk_mod: 520err_put_clk_mod:
250 clk_put(phy->clk_mod); 521 clk_put(phy->clk_mod);
251err_put_clk_bus: 522err_put_clk_bus:
@@ -265,6 +536,8 @@ void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi *hdmi)
265 536
266 reset_control_put(phy->rst_phy); 537 reset_control_put(phy->rst_phy);
267 538
539 if (phy->variant->has_phy_clk)
540 clk_put(phy->clk_pll0);
268 clk_put(phy->clk_mod); 541 clk_put(phy->clk_mod);
269 clk_put(phy->clk_bus); 542 clk_put(phy->clk_bus);
270} 543}
diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c
new file mode 100644
index 000000000000..faea449812f8
--- /dev/null
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c
@@ -0,0 +1,132 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2018 Jernej Skrabec <jernej.skrabec@siol.net>
4 */
5
6#include <linux/clk-provider.h>
7
8#include "sun8i_dw_hdmi.h"
9
10struct sun8i_phy_clk {
11 struct clk_hw hw;
12 struct sun8i_hdmi_phy *phy;
13};
14
15static inline struct sun8i_phy_clk *hw_to_phy_clk(struct clk_hw *hw)
16{
17 return container_of(hw, struct sun8i_phy_clk, hw);
18}
19
20static int sun8i_phy_clk_determine_rate(struct clk_hw *hw,
21 struct clk_rate_request *req)
22{
23 unsigned long rate = req->rate;
24 unsigned long best_rate = 0;
25 struct clk_hw *parent;
26 int best_div = 1;
27 int i;
28
29 parent = clk_hw_get_parent(hw);
30
31 for (i = 1; i <= 16; i++) {
32 unsigned long ideal = rate * i;
33 unsigned long rounded;
34
35 rounded = clk_hw_round_rate(parent, ideal);
36
37 if (rounded == ideal) {
38 best_rate = rounded;
39 best_div = i;
40 break;
41 }
42
43 if (!best_rate ||
44 abs(rate - rounded / i) <
45 abs(rate - best_rate / best_div)) {
46 best_rate = rounded;
47 best_div = i;
48 }
49 }
50
51 req->rate = best_rate / best_div;
52 req->best_parent_rate = best_rate;
53 req->best_parent_hw = parent;
54
55 return 0;
56}
57
58static unsigned long sun8i_phy_clk_recalc_rate(struct clk_hw *hw,
59 unsigned long parent_rate)
60{
61 struct sun8i_phy_clk *priv = hw_to_phy_clk(hw);
62 u32 reg;
63
64 regmap_read(priv->phy->regs, SUN8I_HDMI_PHY_PLL_CFG2_REG, &reg);
65 reg = ((reg >> SUN8I_HDMI_PHY_PLL_CFG2_PREDIV_SHIFT) &
66 SUN8I_HDMI_PHY_PLL_CFG2_PREDIV_MSK) + 1;
67
68 return parent_rate / reg;
69}
70
71static int sun8i_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
72 unsigned long parent_rate)
73{
74 struct sun8i_phy_clk *priv = hw_to_phy_clk(hw);
75 unsigned long best_rate = 0;
76 u8 best_m = 0, m;
77
78 for (m = 1; m <= 16; m++) {
79 unsigned long tmp_rate = parent_rate / m;
80
81 if (tmp_rate > rate)
82 continue;
83
84 if (!best_rate ||
85 (rate - tmp_rate) < (rate - best_rate)) {
86 best_rate = tmp_rate;
87 best_m = m;
88 }
89 }
90
91 regmap_update_bits(priv->phy->regs, SUN8I_HDMI_PHY_PLL_CFG2_REG,
92 SUN8I_HDMI_PHY_PLL_CFG2_PREDIV_MSK,
93 SUN8I_HDMI_PHY_PLL_CFG2_PREDIV(best_m));
94
95 return 0;
96}
97
98static const struct clk_ops sun8i_phy_clk_ops = {
99 .determine_rate = sun8i_phy_clk_determine_rate,
100 .recalc_rate = sun8i_phy_clk_recalc_rate,
101 .set_rate = sun8i_phy_clk_set_rate,
102};
103
104int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev)
105{
106 struct clk_init_data init;
107 struct sun8i_phy_clk *priv;
108 const char *parents[1];
109
110 parents[0] = __clk_get_name(phy->clk_pll0);
111 if (!parents[0])
112 return -ENODEV;
113
114 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
115 if (!priv)
116 return -ENOMEM;
117
118 init.name = "hdmi-phy-clk";
119 init.ops = &sun8i_phy_clk_ops;
120 init.parent_names = parents;
121 init.num_parents = 1;
122 init.flags = CLK_SET_RATE_PARENT;
123
124 priv->phy = phy;
125 priv->hw.init = &init;
126
127 phy->clk_phy = devm_clk_register(dev, &priv->hw);
128 if (IS_ERR(phy->clk_phy))
129 return PTR_ERR(phy->clk_phy);
130
131 return 0;
132}
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index 9b0256d31a61..126899d6f0d3 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -492,6 +492,14 @@ static const struct sun8i_mixer_cfg sun8i_a83t_mixer1_cfg = {
492 .vi_num = 1, 492 .vi_num = 1,
493}; 493};
494 494
495static const struct sun8i_mixer_cfg sun8i_h3_mixer0_cfg = {
496 .ccsc = 0,
497 .mod_rate = 432000000,
498 .scaler_mask = 0xf,
499 .ui_num = 3,
500 .vi_num = 1,
501};
502
495static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = { 503static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = {
496 .vi_num = 2, 504 .vi_num = 2,
497 .ui_num = 1, 505 .ui_num = 1,
@@ -510,6 +518,10 @@ static const struct of_device_id sun8i_mixer_of_table[] = {
510 .data = &sun8i_a83t_mixer1_cfg, 518 .data = &sun8i_a83t_mixer1_cfg,
511 }, 519 },
512 { 520 {
521 .compatible = "allwinner,sun8i-h3-de2-mixer-0",
522 .data = &sun8i_h3_mixer0_cfg,
523 },
524 {
513 .compatible = "allwinner,sun8i-v3s-de2-mixer", 525 .compatible = "allwinner,sun8i-v3s-de2-mixer",
514 .data = &sun8i_v3s_mixer_cfg, 526 .data = &sun8i_v3s_mixer_cfg,
515 }, 527 },
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
index 2f0ccd50b54d..9a540330cb79 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
@@ -211,7 +211,6 @@ static int sun8i_ui_layer_atomic_check(struct drm_plane *plane,
211 struct drm_crtc *crtc = state->crtc; 211 struct drm_crtc *crtc = state->crtc;
212 struct drm_crtc_state *crtc_state; 212 struct drm_crtc_state *crtc_state;
213 int min_scale, max_scale; 213 int min_scale, max_scale;
214 struct drm_rect clip = {};
215 214
216 if (!crtc) 215 if (!crtc)
217 return 0; 216 return 0;
@@ -220,10 +219,6 @@ static int sun8i_ui_layer_atomic_check(struct drm_plane *plane,
220 if (WARN_ON(!crtc_state)) 219 if (WARN_ON(!crtc_state))
221 return -EINVAL; 220 return -EINVAL;
222 221
223 if (crtc_state->enable)
224 drm_mode_get_hv_timing(&crtc_state->mode,
225 &clip.x2, &clip.y2);
226
227 min_scale = DRM_PLANE_HELPER_NO_SCALING; 222 min_scale = DRM_PLANE_HELPER_NO_SCALING;
228 max_scale = DRM_PLANE_HELPER_NO_SCALING; 223 max_scale = DRM_PLANE_HELPER_NO_SCALING;
229 224
@@ -232,7 +227,7 @@ static int sun8i_ui_layer_atomic_check(struct drm_plane *plane,
232 max_scale = SUN8I_UI_SCALER_SCALE_MAX; 227 max_scale = SUN8I_UI_SCALER_SCALE_MAX;
233 } 228 }
234 229
235 return drm_atomic_helper_check_plane_state(state, crtc_state, &clip, 230 return drm_atomic_helper_check_plane_state(state, crtc_state,
236 min_scale, max_scale, 231 min_scale, max_scale,
237 true, true); 232 true, true);
238} 233}
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
index eb3bf2d7291a..5877f8ef5895 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
@@ -239,7 +239,6 @@ static int sun8i_vi_layer_atomic_check(struct drm_plane *plane,
239 struct drm_crtc *crtc = state->crtc; 239 struct drm_crtc *crtc = state->crtc;
240 struct drm_crtc_state *crtc_state; 240 struct drm_crtc_state *crtc_state;
241 int min_scale, max_scale; 241 int min_scale, max_scale;
242 struct drm_rect clip = {};
243 242
244 if (!crtc) 243 if (!crtc)
245 return 0; 244 return 0;
@@ -248,10 +247,6 @@ static int sun8i_vi_layer_atomic_check(struct drm_plane *plane,
248 if (WARN_ON(!crtc_state)) 247 if (WARN_ON(!crtc_state))
249 return -EINVAL; 248 return -EINVAL;
250 249
251 if (crtc_state->enable)
252 drm_mode_get_hv_timing(&crtc_state->mode,
253 &clip.x2, &clip.y2);
254
255 min_scale = DRM_PLANE_HELPER_NO_SCALING; 250 min_scale = DRM_PLANE_HELPER_NO_SCALING;
256 max_scale = DRM_PLANE_HELPER_NO_SCALING; 251 max_scale = DRM_PLANE_HELPER_NO_SCALING;
257 252
@@ -260,7 +255,7 @@ static int sun8i_vi_layer_atomic_check(struct drm_plane *plane,
260 max_scale = SUN8I_VI_SCALER_SCALE_MAX; 255 max_scale = SUN8I_VI_SCALER_SCALE_MAX;
261 } 256 }
262 257
263 return drm_atomic_helper_check_plane_state(state, crtc_state, &clip, 258 return drm_atomic_helper_check_plane_state(state, crtc_state,
264 min_scale, max_scale, 259 min_scale, max_scale,
265 true, true); 260 true, true);
266} 261}
diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c
index 7267a01e6f08..a056fbf83b53 100644
--- a/drivers/gpu/drm/tegra/plane.c
+++ b/drivers/gpu/drm/tegra/plane.c
@@ -82,7 +82,6 @@ int tegra_plane_state_add(struct tegra_plane *plane,
82{ 82{
83 struct drm_crtc_state *crtc_state; 83 struct drm_crtc_state *crtc_state;
84 struct tegra_dc_state *tegra; 84 struct tegra_dc_state *tegra;
85 struct drm_rect clip = {};
86 int err; 85 int err;
87 86
88 /* Propagate errors from allocation or locking failures. */ 87 /* Propagate errors from allocation or locking failures. */
@@ -90,12 +89,8 @@ int tegra_plane_state_add(struct tegra_plane *plane,
90 if (IS_ERR(crtc_state)) 89 if (IS_ERR(crtc_state))
91 return PTR_ERR(crtc_state); 90 return PTR_ERR(crtc_state);
92 91
93 if (crtc_state->enable)
94 drm_mode_get_hv_timing(&crtc_state->mode,
95 &clip.x2, &clip.y2);
96
97 /* Check plane state for visibility and calculate clipping bounds */ 92 /* Check plane state for visibility and calculate clipping bounds */
98 err = drm_atomic_helper_check_plane_state(state, crtc_state, &clip, 93 err = drm_atomic_helper_check_plane_state(state, crtc_state,
99 0, INT_MAX, true, true); 94 0, INT_MAX, true, true);
100 if (err < 0) 95 if (err < 0)
101 return err; 96 return err;
diff --git a/drivers/gpu/drm/tinydrm/Kconfig b/drivers/gpu/drm/tinydrm/Kconfig
index 13339be843bc..4592a5e3f20b 100644
--- a/drivers/gpu/drm/tinydrm/Kconfig
+++ b/drivers/gpu/drm/tinydrm/Kconfig
@@ -23,6 +23,7 @@ config TINYDRM_ILI9225
23config TINYDRM_MI0283QT 23config TINYDRM_MI0283QT
24 tristate "DRM support for MI0283QT" 24 tristate "DRM support for MI0283QT"
25 depends on DRM_TINYDRM && SPI 25 depends on DRM_TINYDRM && SPI
26 depends on BACKLIGHT_CLASS_DEVICE
26 select TINYDRM_MIPI_DBI 27 select TINYDRM_MIPI_DBI
27 help 28 help
28 DRM driver for the Multi-Inno MI0283QT display panel 29 DRM driver for the Multi-Inno MI0283QT display panel
@@ -54,6 +55,7 @@ config TINYDRM_ST7586
54config TINYDRM_ST7735R 55config TINYDRM_ST7735R
55 tristate "DRM support for Sitronix ST7735R display panels" 56 tristate "DRM support for Sitronix ST7735R display panels"
56 depends on DRM_TINYDRM && SPI 57 depends on DRM_TINYDRM && SPI
58 depends on BACKLIGHT_CLASS_DEVICE
57 select TINYDRM_MIPI_DBI 59 select TINYDRM_MIPI_DBI
58 help 60 help
59 DRM driver Sitronix ST7735R with one of the following LCDs: 61 DRM driver Sitronix ST7735R with one of the following LCDs:
diff --git a/drivers/gpu/drm/tve200/tve200_display.c b/drivers/gpu/drm/tve200/tve200_display.c
index 2c668bd6d997..db397fcb345a 100644
--- a/drivers/gpu/drm/tve200/tve200_display.c
+++ b/drivers/gpu/drm/tve200/tve200_display.c
@@ -273,16 +273,20 @@ static void tve200_display_update(struct drm_simple_display_pipe *pipe,
273 } 273 }
274} 274}
275 275
276int tve200_enable_vblank(struct drm_device *drm, unsigned int crtc) 276static int tve200_display_enable_vblank(struct drm_simple_display_pipe *pipe)
277{ 277{
278 struct drm_crtc *crtc = &pipe->crtc;
279 struct drm_device *drm = crtc->dev;
278 struct tve200_drm_dev_private *priv = drm->dev_private; 280 struct tve200_drm_dev_private *priv = drm->dev_private;
279 281
280 writel(TVE200_INT_V_STATUS, priv->regs + TVE200_INT_EN); 282 writel(TVE200_INT_V_STATUS, priv->regs + TVE200_INT_EN);
281 return 0; 283 return 0;
282} 284}
283 285
284void tve200_disable_vblank(struct drm_device *drm, unsigned int crtc) 286static void tve200_display_disable_vblank(struct drm_simple_display_pipe *pipe)
285{ 287{
288 struct drm_crtc *crtc = &pipe->crtc;
289 struct drm_device *drm = crtc->dev;
286 struct tve200_drm_dev_private *priv = drm->dev_private; 290 struct tve200_drm_dev_private *priv = drm->dev_private;
287 291
288 writel(0, priv->regs + TVE200_INT_EN); 292 writel(0, priv->regs + TVE200_INT_EN);
@@ -300,6 +304,8 @@ static const struct drm_simple_display_pipe_funcs tve200_display_funcs = {
300 .disable = tve200_display_disable, 304 .disable = tve200_display_disable,
301 .update = tve200_display_update, 305 .update = tve200_display_update,
302 .prepare_fb = tve200_display_prepare_fb, 306 .prepare_fb = tve200_display_prepare_fb,
307 .enable_vblank = tve200_display_enable_vblank,
308 .disable_vblank = tve200_display_disable_vblank,
303}; 309};
304 310
305int tve200_display_init(struct drm_device *drm) 311int tve200_display_init(struct drm_device *drm)
diff --git a/drivers/gpu/drm/tve200/tve200_drm.h b/drivers/gpu/drm/tve200/tve200_drm.h
index 5c270055bd58..1ba4380f489b 100644
--- a/drivers/gpu/drm/tve200/tve200_drm.h
+++ b/drivers/gpu/drm/tve200/tve200_drm.h
@@ -113,8 +113,6 @@ struct tve200_drm_dev_private {
113 container_of(x, struct tve200_drm_connector, connector) 113 container_of(x, struct tve200_drm_connector, connector)
114 114
115int tve200_display_init(struct drm_device *dev); 115int tve200_display_init(struct drm_device *dev);
116int tve200_enable_vblank(struct drm_device *drm, unsigned int crtc);
117void tve200_disable_vblank(struct drm_device *drm, unsigned int crtc);
118irqreturn_t tve200_irq(int irq, void *data); 116irqreturn_t tve200_irq(int irq, void *data);
119int tve200_connector_init(struct drm_device *dev); 117int tve200_connector_init(struct drm_device *dev);
120int tve200_encoder_init(struct drm_device *dev); 118int tve200_encoder_init(struct drm_device *dev);
diff --git a/drivers/gpu/drm/tve200/tve200_drv.c b/drivers/gpu/drm/tve200/tve200_drv.c
index 44911d921864..ac344ddb23bc 100644
--- a/drivers/gpu/drm/tve200/tve200_drv.c
+++ b/drivers/gpu/drm/tve200/tve200_drv.c
@@ -162,9 +162,6 @@ static struct drm_driver tve200_drm_driver = {
162 .gem_free_object_unlocked = drm_gem_cma_free_object, 162 .gem_free_object_unlocked = drm_gem_cma_free_object,
163 .gem_vm_ops = &drm_gem_cma_vm_ops, 163 .gem_vm_ops = &drm_gem_cma_vm_ops,
164 164
165 .enable_vblank = tve200_enable_vblank,
166 .disable_vblank = tve200_disable_vblank,
167
168 .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 165 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
169 .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 166 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
170 .gem_prime_import = drm_gem_prime_import, 167 .gem_prime_import = drm_gem_prime_import,
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 984501e3f0b0..1a6db291d48b 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -681,7 +681,7 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
681 drift & ~VC4_HDMI_FIFO_CTL_RECENTER); 681 drift & ~VC4_HDMI_FIFO_CTL_RECENTER);
682 HDMI_WRITE(VC4_HDMI_FIFO_CTL, 682 HDMI_WRITE(VC4_HDMI_FIFO_CTL,
683 drift | VC4_HDMI_FIFO_CTL_RECENTER); 683 drift | VC4_HDMI_FIFO_CTL_RECENTER);
684 udelay(1000); 684 usleep_range(1000, 1100);
685 HDMI_WRITE(VC4_HDMI_FIFO_CTL, 685 HDMI_WRITE(VC4_HDMI_FIFO_CTL,
686 drift & ~VC4_HDMI_FIFO_CTL_RECENTER); 686 drift & ~VC4_HDMI_FIFO_CTL_RECENTER);
687 HDMI_WRITE(VC4_HDMI_FIFO_CTL, 687 HDMI_WRITE(VC4_HDMI_FIFO_CTL,
diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index 4256f294c346..ba60153dddb5 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -215,6 +215,7 @@ int vc4_kms_load(struct drm_device *dev)
215 dev->mode_config.funcs = &vc4_mode_funcs; 215 dev->mode_config.funcs = &vc4_mode_funcs;
216 dev->mode_config.preferred_depth = 24; 216 dev->mode_config.preferred_depth = 24;
217 dev->mode_config.async_page_flip = true; 217 dev->mode_config.async_page_flip = true;
218 dev->mode_config.allow_fb_modifiers = true;
218 219
219 drm_mode_config_reset(dev); 220 drm_mode_config_reset(dev);
220 221
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index 61ad955645a5..c4c7af11fec5 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -906,6 +906,32 @@ out:
906 ctx); 906 ctx);
907} 907}
908 908
909static bool vc4_format_mod_supported(struct drm_plane *plane,
910 uint32_t format,
911 uint64_t modifier)
912{
913 /* Support T_TILING for RGB formats only. */
914 switch (format) {
915 case DRM_FORMAT_XRGB8888:
916 case DRM_FORMAT_ARGB8888:
917 case DRM_FORMAT_ABGR8888:
918 case DRM_FORMAT_XBGR8888:
919 case DRM_FORMAT_RGB565:
920 case DRM_FORMAT_BGR565:
921 case DRM_FORMAT_ARGB1555:
922 case DRM_FORMAT_XRGB1555:
923 return true;
924 case DRM_FORMAT_YUV422:
925 case DRM_FORMAT_YVU422:
926 case DRM_FORMAT_YUV420:
927 case DRM_FORMAT_YVU420:
928 case DRM_FORMAT_NV12:
929 case DRM_FORMAT_NV16:
930 default:
931 return (modifier == DRM_FORMAT_MOD_LINEAR);
932 }
933}
934
909static const struct drm_plane_funcs vc4_plane_funcs = { 935static const struct drm_plane_funcs vc4_plane_funcs = {
910 .update_plane = vc4_update_plane, 936 .update_plane = vc4_update_plane,
911 .disable_plane = drm_atomic_helper_disable_plane, 937 .disable_plane = drm_atomic_helper_disable_plane,
@@ -914,6 +940,7 @@ static const struct drm_plane_funcs vc4_plane_funcs = {
914 .reset = vc4_plane_reset, 940 .reset = vc4_plane_reset,
915 .atomic_duplicate_state = vc4_plane_duplicate_state, 941 .atomic_duplicate_state = vc4_plane_duplicate_state,
916 .atomic_destroy_state = vc4_plane_destroy_state, 942 .atomic_destroy_state = vc4_plane_destroy_state,
943 .format_mod_supported = vc4_format_mod_supported,
917}; 944};
918 945
919struct drm_plane *vc4_plane_init(struct drm_device *dev, 946struct drm_plane *vc4_plane_init(struct drm_device *dev,
@@ -925,6 +952,11 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev,
925 u32 num_formats = 0; 952 u32 num_formats = 0;
926 int ret = 0; 953 int ret = 0;
927 unsigned i; 954 unsigned i;
955 static const uint64_t modifiers[] = {
956 DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED,
957 DRM_FORMAT_MOD_LINEAR,
958 DRM_FORMAT_MOD_INVALID
959 };
928 960
929 vc4_plane = devm_kzalloc(dev->dev, sizeof(*vc4_plane), 961 vc4_plane = devm_kzalloc(dev->dev, sizeof(*vc4_plane),
930 GFP_KERNEL); 962 GFP_KERNEL);
@@ -945,7 +977,7 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev,
945 ret = drm_universal_plane_init(dev, plane, 0, 977 ret = drm_universal_plane_init(dev, plane, 0,
946 &vc4_plane_funcs, 978 &vc4_plane_funcs,
947 formats, num_formats, 979 formats, num_formats,
948 NULL, type, NULL); 980 modifiers, type, NULL);
949 981
950 drm_plane_helper_add(plane, &vc4_plane_helper_funcs); 982 drm_plane_helper_add(plane, &vc4_plane_helper_funcs);
951 983
diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c
index 19114a3c5ee4..8cc8c34d67f5 100644
--- a/drivers/gpu/drm/virtio/virtgpu_display.c
+++ b/drivers/gpu/drm/virtio/virtgpu_display.c
@@ -61,9 +61,9 @@ static void virtio_gpu_user_framebuffer_destroy(struct drm_framebuffer *fb)
61static int 61static int
62virtio_gpu_framebuffer_surface_dirty(struct drm_framebuffer *fb, 62virtio_gpu_framebuffer_surface_dirty(struct drm_framebuffer *fb,
63 struct drm_file *file_priv, 63 struct drm_file *file_priv,
64 unsigned flags, unsigned color, 64 unsigned int flags, unsigned int color,
65 struct drm_clip_rect *clips, 65 struct drm_clip_rect *clips,
66 unsigned num_clips) 66 unsigned int num_clips)
67{ 67{
68 struct virtio_gpu_framebuffer *virtio_gpu_fb 68 struct virtio_gpu_framebuffer *virtio_gpu_fb
69 = to_virtio_gpu_framebuffer(fb); 69 = to_virtio_gpu_framebuffer(fb);
@@ -96,6 +96,7 @@ virtio_gpu_framebuffer_init(struct drm_device *dev,
96{ 96{
97 int ret; 97 int ret;
98 struct virtio_gpu_object *bo; 98 struct virtio_gpu_object *bo;
99
99 vgfb->obj = obj; 100 vgfb->obj = obj;
100 101
101 bo = gem_to_virtio_gpu_obj(obj); 102 bo = gem_to_virtio_gpu_obj(obj);
@@ -387,7 +388,7 @@ int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev)
387 for (i = 0 ; i < vgdev->num_scanouts; ++i) 388 for (i = 0 ; i < vgdev->num_scanouts; ++i)
388 vgdev_output_init(vgdev, i); 389 vgdev_output_init(vgdev, i);
389 390
390 drm_mode_config_reset(vgdev->ddev); 391 drm_mode_config_reset(vgdev->ddev);
391 return 0; 392 return 0;
392} 393}
393 394
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c
index 49a3d8d5a249..d9287c144fe5 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.c
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
@@ -54,6 +54,7 @@ static int virtio_gpu_probe(struct virtio_device *vdev)
54static void virtio_gpu_remove(struct virtio_device *vdev) 54static void virtio_gpu_remove(struct virtio_device *vdev)
55{ 55{
56 struct drm_device *dev = vdev->priv; 56 struct drm_device *dev = vdev->priv;
57
57 drm_put_dev(dev); 58 drm_put_dev(dev);
58} 59}
59 60
@@ -112,7 +113,6 @@ static const struct file_operations virtio_gpu_driver_fops = {
112 .llseek = noop_llseek, 113 .llseek = noop_llseek,
113}; 114};
114 115
115
116static struct drm_driver driver = { 116static struct drm_driver driver = {
117 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_RENDER | DRIVER_ATOMIC, 117 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_RENDER | DRIVER_ATOMIC,
118 .load = virtio_gpu_driver_load, 118 .load = virtio_gpu_driver_load,
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
index da2fb585fea4..d25c8ca224aa 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -246,7 +246,7 @@ int virtio_gpu_fbdev_init(struct virtio_gpu_device *vgdev);
246void virtio_gpu_fbdev_fini(struct virtio_gpu_device *vgdev); 246void virtio_gpu_fbdev_fini(struct virtio_gpu_device *vgdev);
247int virtio_gpu_surface_dirty(struct virtio_gpu_framebuffer *qfb, 247int virtio_gpu_surface_dirty(struct virtio_gpu_framebuffer *qfb,
248 struct drm_clip_rect *clips, 248 struct drm_clip_rect *clips,
249 unsigned num_clips); 249 unsigned int num_clips);
250/* virtio vg */ 250/* virtio vg */
251int virtio_gpu_alloc_vbufs(struct virtio_gpu_device *vgdev); 251int virtio_gpu_alloc_vbufs(struct virtio_gpu_device *vgdev);
252void virtio_gpu_free_vbufs(struct virtio_gpu_device *vgdev); 252void virtio_gpu_free_vbufs(struct virtio_gpu_device *vgdev);
@@ -363,12 +363,12 @@ int virtgpu_gem_prime_pin(struct drm_gem_object *obj);
363void virtgpu_gem_prime_unpin(struct drm_gem_object *obj); 363void virtgpu_gem_prime_unpin(struct drm_gem_object *obj);
364struct sg_table *virtgpu_gem_prime_get_sg_table(struct drm_gem_object *obj); 364struct sg_table *virtgpu_gem_prime_get_sg_table(struct drm_gem_object *obj);
365struct drm_gem_object *virtgpu_gem_prime_import_sg_table( 365struct drm_gem_object *virtgpu_gem_prime_import_sg_table(
366 struct drm_device *dev, struct dma_buf_attachment *attach, 366 struct drm_device *dev, struct dma_buf_attachment *attach,
367 struct sg_table *sgt); 367 struct sg_table *sgt);
368void *virtgpu_gem_prime_vmap(struct drm_gem_object *obj); 368void *virtgpu_gem_prime_vmap(struct drm_gem_object *obj);
369void virtgpu_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr); 369void virtgpu_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
370int virtgpu_gem_prime_mmap(struct drm_gem_object *obj, 370int virtgpu_gem_prime_mmap(struct drm_gem_object *obj,
371 struct vm_area_struct *vma); 371 struct vm_area_struct *vma);
372 372
373static inline struct virtio_gpu_object* 373static inline struct virtio_gpu_object*
374virtio_gpu_object_ref(struct virtio_gpu_object *bo) 374virtio_gpu_object_ref(struct virtio_gpu_object *bo)
diff --git a/drivers/gpu/drm/virtio/virtgpu_fb.c b/drivers/gpu/drm/virtio/virtgpu_fb.c
index 15d18fd0c64b..8af69ab58b89 100644
--- a/drivers/gpu/drm/virtio/virtgpu_fb.c
+++ b/drivers/gpu/drm/virtio/virtgpu_fb.c
@@ -118,7 +118,7 @@ static int virtio_gpu_dirty_update(struct virtio_gpu_framebuffer *fb,
118 118
119int virtio_gpu_surface_dirty(struct virtio_gpu_framebuffer *vgfb, 119int virtio_gpu_surface_dirty(struct virtio_gpu_framebuffer *vgfb,
120 struct drm_clip_rect *clips, 120 struct drm_clip_rect *clips,
121 unsigned num_clips) 121 unsigned int num_clips)
122{ 122{
123 struct virtio_gpu_device *vgdev = vgfb->base.dev->dev_private; 123 struct virtio_gpu_device *vgdev = vgfb->base.dev->dev_private;
124 struct virtio_gpu_object *obj = gem_to_virtio_gpu_obj(vgfb->obj); 124 struct virtio_gpu_object *obj = gem_to_virtio_gpu_obj(vgfb->obj);
@@ -127,6 +127,7 @@ int virtio_gpu_surface_dirty(struct virtio_gpu_framebuffer *vgfb,
127 int left, right, top, bottom; 127 int left, right, top, bottom;
128 int i; 128 int i;
129 int inc = 1; 129 int inc = 1;
130
130 if (!num_clips) { 131 if (!num_clips) {
131 num_clips = 1; 132 num_clips = 1;
132 clips = &norect; 133 clips = &norect;
@@ -172,6 +173,7 @@ static void virtio_gpu_3d_fillrect(struct fb_info *info,
172 const struct fb_fillrect *rect) 173 const struct fb_fillrect *rect)
173{ 174{
174 struct virtio_gpu_fbdev *vfbdev = info->par; 175 struct virtio_gpu_fbdev *vfbdev = info->par;
176
175 drm_fb_helper_sys_fillrect(info, rect); 177 drm_fb_helper_sys_fillrect(info, rect);
176 virtio_gpu_dirty_update(&vfbdev->vgfb, true, rect->dx, rect->dy, 178 virtio_gpu_dirty_update(&vfbdev->vgfb, true, rect->dx, rect->dy,
177 rect->width, rect->height); 179 rect->width, rect->height);
@@ -182,6 +184,7 @@ static void virtio_gpu_3d_copyarea(struct fb_info *info,
182 const struct fb_copyarea *area) 184 const struct fb_copyarea *area)
183{ 185{
184 struct virtio_gpu_fbdev *vfbdev = info->par; 186 struct virtio_gpu_fbdev *vfbdev = info->par;
187
185 drm_fb_helper_sys_copyarea(info, area); 188 drm_fb_helper_sys_copyarea(info, area);
186 virtio_gpu_dirty_update(&vfbdev->vgfb, true, area->dx, area->dy, 189 virtio_gpu_dirty_update(&vfbdev->vgfb, true, area->dx, area->dy,
187 area->width, area->height); 190 area->width, area->height);
@@ -192,6 +195,7 @@ static void virtio_gpu_3d_imageblit(struct fb_info *info,
192 const struct fb_image *image) 195 const struct fb_image *image)
193{ 196{
194 struct virtio_gpu_fbdev *vfbdev = info->par; 197 struct virtio_gpu_fbdev *vfbdev = info->par;
198
195 drm_fb_helper_sys_imageblit(info, image); 199 drm_fb_helper_sys_imageblit(info, image);
196 virtio_gpu_dirty_update(&vfbdev->vgfb, true, image->dx, image->dy, 200 virtio_gpu_dirty_update(&vfbdev->vgfb, true, image->dx, image->dy,
197 image->width, image->height); 201 image->width, image->height);
diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c
index 92fb27753b9e..0f2768eacaee 100644
--- a/drivers/gpu/drm/virtio/virtgpu_gem.c
+++ b/drivers/gpu/drm/virtio/virtgpu_gem.c
@@ -124,6 +124,7 @@ int virtio_gpu_mode_dumb_mmap(struct drm_file *file_priv,
124{ 124{
125 struct drm_gem_object *gobj; 125 struct drm_gem_object *gobj;
126 struct virtio_gpu_object *obj; 126 struct virtio_gpu_object *obj;
127
127 BUG_ON(!offset_p); 128 BUG_ON(!offset_p);
128 gobj = drm_gem_object_lookup(file_priv, handle); 129 gobj = drm_gem_object_lookup(file_priv, handle);
129 if (gobj == NULL) 130 if (gobj == NULL)
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index 355569a9b5cb..a14e8a2ec682 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -83,6 +83,7 @@ static void virtio_gpu_unref_list(struct list_head *head)
83 struct ttm_validate_buffer *buf; 83 struct ttm_validate_buffer *buf;
84 struct ttm_buffer_object *bo; 84 struct ttm_buffer_object *bo;
85 struct virtio_gpu_object *qobj; 85 struct virtio_gpu_object *qobj;
86
86 list_for_each_entry(buf, head, head) { 87 list_for_each_entry(buf, head, head) {
87 bo = buf->bo; 88 bo = buf->bo;
88 qobj = container_of(bo, struct virtio_gpu_object, tbo); 89 qobj = container_of(bo, struct virtio_gpu_object, tbo);
@@ -478,6 +479,7 @@ static int virtio_gpu_get_caps_ioctl(struct drm_device *dev,
478 int ret; 479 int ret;
479 struct virtio_gpu_drv_cap_cache *cache_ent; 480 struct virtio_gpu_drv_cap_cache *cache_ent;
480 void *ptr; 481 void *ptr;
482
481 if (vgdev->num_capsets == 0) 483 if (vgdev->num_capsets == 0)
482 return -ENOSYS; 484 return -ENOSYS;
483 485
@@ -532,33 +534,34 @@ copy_exit:
532 534
533struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS] = { 535struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS] = {
534 DRM_IOCTL_DEF_DRV(VIRTGPU_MAP, virtio_gpu_map_ioctl, 536 DRM_IOCTL_DEF_DRV(VIRTGPU_MAP, virtio_gpu_map_ioctl,
535 DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), 537 DRM_AUTH | DRM_UNLOCKED | DRM_RENDER_ALLOW),
536 538
537 DRM_IOCTL_DEF_DRV(VIRTGPU_EXECBUFFER, virtio_gpu_execbuffer_ioctl, 539 DRM_IOCTL_DEF_DRV(VIRTGPU_EXECBUFFER, virtio_gpu_execbuffer_ioctl,
538 DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), 540 DRM_AUTH | DRM_UNLOCKED | DRM_RENDER_ALLOW),
539 541
540 DRM_IOCTL_DEF_DRV(VIRTGPU_GETPARAM, virtio_gpu_getparam_ioctl, 542 DRM_IOCTL_DEF_DRV(VIRTGPU_GETPARAM, virtio_gpu_getparam_ioctl,
541 DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), 543 DRM_AUTH | DRM_UNLOCKED | DRM_RENDER_ALLOW),
542 544
543 DRM_IOCTL_DEF_DRV(VIRTGPU_RESOURCE_CREATE, 545 DRM_IOCTL_DEF_DRV(VIRTGPU_RESOURCE_CREATE,
544 virtio_gpu_resource_create_ioctl, 546 virtio_gpu_resource_create_ioctl,
545 DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), 547 DRM_AUTH | DRM_UNLOCKED | DRM_RENDER_ALLOW),
546 548
547 DRM_IOCTL_DEF_DRV(VIRTGPU_RESOURCE_INFO, virtio_gpu_resource_info_ioctl, 549 DRM_IOCTL_DEF_DRV(VIRTGPU_RESOURCE_INFO, virtio_gpu_resource_info_ioctl,
548 DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), 550 DRM_AUTH | DRM_UNLOCKED | DRM_RENDER_ALLOW),
549 551
550 /* make transfer async to the main ring? - no sure, can we 552 /* make transfer async to the main ring? - no sure, can we
551 thread these in the underlying GL */ 553 * thread these in the underlying GL
554 */
552 DRM_IOCTL_DEF_DRV(VIRTGPU_TRANSFER_FROM_HOST, 555 DRM_IOCTL_DEF_DRV(VIRTGPU_TRANSFER_FROM_HOST,
553 virtio_gpu_transfer_from_host_ioctl, 556 virtio_gpu_transfer_from_host_ioctl,
554 DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), 557 DRM_AUTH | DRM_UNLOCKED | DRM_RENDER_ALLOW),
555 DRM_IOCTL_DEF_DRV(VIRTGPU_TRANSFER_TO_HOST, 558 DRM_IOCTL_DEF_DRV(VIRTGPU_TRANSFER_TO_HOST,
556 virtio_gpu_transfer_to_host_ioctl, 559 virtio_gpu_transfer_to_host_ioctl,
557 DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), 560 DRM_AUTH | DRM_UNLOCKED | DRM_RENDER_ALLOW),
558 561
559 DRM_IOCTL_DEF_DRV(VIRTGPU_WAIT, virtio_gpu_wait_ioctl, 562 DRM_IOCTL_DEF_DRV(VIRTGPU_WAIT, virtio_gpu_wait_ioctl,
560 DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), 563 DRM_AUTH | DRM_UNLOCKED | DRM_RENDER_ALLOW),
561 564
562 DRM_IOCTL_DEF_DRV(VIRTGPU_GET_CAPS, virtio_gpu_get_caps_ioctl, 565 DRM_IOCTL_DEF_DRV(VIRTGPU_GET_CAPS, virtio_gpu_get_caps_ioctl,
563 DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), 566 DRM_AUTH | DRM_UNLOCKED | DRM_RENDER_ALLOW),
564}; 567};
diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c
index 385e0eb9826a..d27a1688714f 100644
--- a/drivers/gpu/drm/virtio/virtgpu_prime.c
+++ b/drivers/gpu/drm/virtio/virtgpu_prime.c
@@ -25,7 +25,8 @@
25#include "virtgpu_drv.h" 25#include "virtgpu_drv.h"
26 26
27/* Empty Implementations as there should not be any other driver for a virtual 27/* Empty Implementations as there should not be any other driver for a virtual
28 * device that might share buffers with virtgpu */ 28 * device that might share buffers with virtgpu
29 */
29 30
30int virtgpu_gem_prime_pin(struct drm_gem_object *obj) 31int virtgpu_gem_prime_pin(struct drm_gem_object *obj)
31{ 32{
@@ -38,7 +39,6 @@ void virtgpu_gem_prime_unpin(struct drm_gem_object *obj)
38 WARN_ONCE(1, "not implemented"); 39 WARN_ONCE(1, "not implemented");
39} 40}
40 41
41
42struct sg_table *virtgpu_gem_prime_get_sg_table(struct drm_gem_object *obj) 42struct sg_table *virtgpu_gem_prime_get_sg_table(struct drm_gem_object *obj)
43{ 43{
44 WARN_ONCE(1, "not implemented"); 44 WARN_ONCE(1, "not implemented");
diff --git a/drivers/gpu/drm/virtio/virtgpu_ttm.c b/drivers/gpu/drm/virtio/virtgpu_ttm.c
index ee9839fbae66..fd5d9450878e 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ttm.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ttm.c
@@ -177,7 +177,6 @@ static void ttm_bo_man_put_node(struct ttm_mem_type_manager *man,
177 struct ttm_mem_reg *mem) 177 struct ttm_mem_reg *mem)
178{ 178{
179 mem->mm_node = (void *)NULL; 179 mem->mm_node = (void *)NULL;
180 return;
181} 180}
182 181
183static int ttm_bo_man_init(struct ttm_mem_type_manager *man, 182static int ttm_bo_man_init(struct ttm_mem_type_manager *man,
@@ -225,7 +224,7 @@ static int virtio_gpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
225 man->default_caching = TTM_PL_FLAG_CACHED; 224 man->default_caching = TTM_PL_FLAG_CACHED;
226 break; 225 break;
227 default: 226 default:
228 DRM_ERROR("Unsupported memory type %u\n", (unsigned)type); 227 DRM_ERROR("Unsupported memory type %u\n", (unsigned int)type);
229 return -EINVAL; 228 return -EINVAL;
230 } 229 }
231 return 0; 230 return 0;
@@ -244,7 +243,6 @@ static void virtio_gpu_evict_flags(struct ttm_buffer_object *bo,
244 placement->busy_placement = &placements; 243 placement->busy_placement = &placements;
245 placement->num_placement = 1; 244 placement->num_placement = 1;
246 placement->num_busy_placement = 1; 245 placement->num_busy_placement = 1;
247 return;
248} 246}
249 247
250static int virtio_gpu_verify_access(struct ttm_buffer_object *bo, 248static int virtio_gpu_verify_access(struct ttm_buffer_object *bo,
diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
index 9eb96fb2c147..48e4f1df6e5d 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
@@ -62,6 +62,7 @@ void virtio_gpu_ctrl_ack(struct virtqueue *vq)
62{ 62{
63 struct drm_device *dev = vq->vdev->priv; 63 struct drm_device *dev = vq->vdev->priv;
64 struct virtio_gpu_device *vgdev = dev->dev_private; 64 struct virtio_gpu_device *vgdev = dev->dev_private;
65
65 schedule_work(&vgdev->ctrlq.dequeue_work); 66 schedule_work(&vgdev->ctrlq.dequeue_work);
66} 67}
67 68
@@ -69,6 +70,7 @@ void virtio_gpu_cursor_ack(struct virtqueue *vq)
69{ 70{
70 struct drm_device *dev = vq->vdev->priv; 71 struct drm_device *dev = vq->vdev->priv;
71 struct virtio_gpu_device *vgdev = dev->dev_private; 72 struct virtio_gpu_device *vgdev = dev->dev_private;
73
72 schedule_work(&vgdev->cursorq.dequeue_work); 74 schedule_work(&vgdev->cursorq.dequeue_work);
73} 75}
74 76
@@ -272,7 +274,7 @@ static int virtio_gpu_queue_ctrl_buffer_locked(struct virtio_gpu_device *vgdev,
272 return -ENODEV; 274 return -ENODEV;
273 275
274 sg_init_one(&vcmd, vbuf->buf, vbuf->size); 276 sg_init_one(&vcmd, vbuf->buf, vbuf->size);
275 sgs[outcnt+incnt] = &vcmd; 277 sgs[outcnt + incnt] = &vcmd;
276 outcnt++; 278 outcnt++;
277 279
278 if (vbuf->data_size) { 280 if (vbuf->data_size) {
@@ -381,7 +383,8 @@ retry:
381} 383}
382 384
383/* just create gem objects for userspace and long lived objects, 385/* just create gem objects for userspace and long lived objects,
384 just use dma_alloced pages for the queue objects? */ 386 * just use dma_alloced pages for the queue objects?
387 */
385 388
386/* create a basic resource */ 389/* create a basic resource */
387void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev, 390void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev,
@@ -593,7 +596,6 @@ static void virtio_gpu_cmd_capset_cb(struct virtio_gpu_device *vgdev,
593 wake_up(&vgdev->resp_wq); 596 wake_up(&vgdev->resp_wq);
594} 597}
595 598
596
597int virtio_gpu_cmd_get_display_info(struct virtio_gpu_device *vgdev) 599int virtio_gpu_cmd_get_display_info(struct virtio_gpu_device *vgdev)
598{ 600{
599 struct virtio_gpu_ctrl_hdr *cmd_p; 601 struct virtio_gpu_ctrl_hdr *cmd_p;
@@ -707,8 +709,8 @@ void virtio_gpu_cmd_context_create(struct virtio_gpu_device *vgdev, uint32_t id,
707 cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_CTX_CREATE); 709 cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_CTX_CREATE);
708 cmd_p->hdr.ctx_id = cpu_to_le32(id); 710 cmd_p->hdr.ctx_id = cpu_to_le32(id);
709 cmd_p->nlen = cpu_to_le32(nlen); 711 cmd_p->nlen = cpu_to_le32(nlen);
710 strncpy(cmd_p->debug_name, name, sizeof(cmd_p->debug_name)-1); 712 strncpy(cmd_p->debug_name, name, sizeof(cmd_p->debug_name) - 1);
711 cmd_p->debug_name[sizeof(cmd_p->debug_name)-1] = 0; 713 cmd_p->debug_name[sizeof(cmd_p->debug_name) - 1] = 0;
712 virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); 714 virtio_gpu_queue_ctrl_buffer(vgdev, vbuf);
713} 715}
714 716
@@ -852,6 +854,7 @@ int virtio_gpu_object_attach(struct virtio_gpu_device *vgdev,
852 854
853 if (!obj->pages) { 855 if (!obj->pages) {
854 int ret; 856 int ret;
857
855 ret = virtio_gpu_object_get_sg_table(vgdev, obj); 858 ret = virtio_gpu_object_get_sg_table(vgdev, obj);
856 if (ret) 859 if (ret)
857 return ret; 860 return ret;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 1107d6d03506..34ecc27fc30a 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -443,17 +443,12 @@ int vmw_du_primary_plane_atomic_check(struct drm_plane *plane,
443{ 443{
444 struct drm_crtc_state *crtc_state = NULL; 444 struct drm_crtc_state *crtc_state = NULL;
445 struct drm_framebuffer *new_fb = state->fb; 445 struct drm_framebuffer *new_fb = state->fb;
446 struct drm_rect clip = {};
447 int ret; 446 int ret;
448 447
449 if (state->crtc) 448 if (state->crtc)
450 crtc_state = drm_atomic_get_new_crtc_state(state->state, state->crtc); 449 crtc_state = drm_atomic_get_new_crtc_state(state->state, state->crtc);
451 450
452 if (crtc_state && crtc_state->enable) 451 ret = drm_atomic_helper_check_plane_state(state, crtc_state,
453 drm_mode_get_hv_timing(&crtc_state->mode,
454 &clip.x2, &clip.y2);
455
456 ret = drm_atomic_helper_check_plane_state(state, crtc_state, &clip,
457 DRM_PLANE_HELPER_NO_SCALING, 452 DRM_PLANE_HELPER_NO_SCALING,
458 DRM_PLANE_HELPER_NO_SCALING, 453 DRM_PLANE_HELPER_NO_SCALING,
459 false, true); 454 false, true);
diff --git a/drivers/gpu/drm/zte/zx_plane.c b/drivers/gpu/drm/zte/zx_plane.c
index 8e1f34274e24..94545adac50d 100644
--- a/drivers/gpu/drm/zte/zx_plane.c
+++ b/drivers/gpu/drm/zte/zx_plane.c
@@ -55,7 +55,6 @@ static int zx_vl_plane_atomic_check(struct drm_plane *plane,
55 struct drm_framebuffer *fb = plane_state->fb; 55 struct drm_framebuffer *fb = plane_state->fb;
56 struct drm_crtc *crtc = plane_state->crtc; 56 struct drm_crtc *crtc = plane_state->crtc;
57 struct drm_crtc_state *crtc_state; 57 struct drm_crtc_state *crtc_state;
58 struct drm_rect clip = {};
59 int min_scale = FRAC_16_16(1, 8); 58 int min_scale = FRAC_16_16(1, 8);
60 int max_scale = FRAC_16_16(8, 1); 59 int max_scale = FRAC_16_16(8, 1);
61 60
@@ -75,12 +74,8 @@ static int zx_vl_plane_atomic_check(struct drm_plane *plane,
75 if (!plane_state->crtc) 74 if (!plane_state->crtc)
76 return -EINVAL; 75 return -EINVAL;
77 76
78 if (crtc_state->enable)
79 drm_mode_get_hv_timing(&crtc_state->mode,
80 &clip.x2, &clip.y2);
81
82 return drm_atomic_helper_check_plane_state(plane_state, crtc_state, 77 return drm_atomic_helper_check_plane_state(plane_state, crtc_state,
83 &clip, min_scale, max_scale, 78 min_scale, max_scale,
84 true, true); 79 true, true);
85} 80}
86 81
@@ -291,7 +286,6 @@ static int zx_gl_plane_atomic_check(struct drm_plane *plane,
291 struct drm_framebuffer *fb = plane_state->fb; 286 struct drm_framebuffer *fb = plane_state->fb;
292 struct drm_crtc *crtc = plane_state->crtc; 287 struct drm_crtc *crtc = plane_state->crtc;
293 struct drm_crtc_state *crtc_state; 288 struct drm_crtc_state *crtc_state;
294 struct drm_rect clip = {};
295 289
296 if (!crtc || !fb) 290 if (!crtc || !fb)
297 return 0; 291 return 0;
@@ -309,12 +303,7 @@ static int zx_gl_plane_atomic_check(struct drm_plane *plane,
309 if (!plane_state->crtc) 303 if (!plane_state->crtc)
310 return -EINVAL; 304 return -EINVAL;
311 305
312 if (crtc_state->enable)
313 drm_mode_get_hv_timing(&crtc_state->mode,
314 &clip.x2, &clip.y2);
315
316 return drm_atomic_helper_check_plane_state(plane_state, crtc_state, 306 return drm_atomic_helper_check_plane_state(plane_state, crtc_state,
317 &clip,
318 DRM_PLANE_HELPER_NO_SCALING, 307 DRM_PLANE_HELPER_NO_SCALING,
319 DRM_PLANE_HELPER_NO_SCALING, 308 DRM_PLANE_HELPER_NO_SCALING,
320 false, true); 309 false, true);
diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h
index c99d6eaef1ac..711fff9b6803 100644
--- a/include/drm/bridge/analogix_dp.h
+++ b/include/drm/bridge/analogix_dp.h
@@ -13,6 +13,8 @@
13 13
14#include <drm/drm_crtc.h> 14#include <drm/drm_crtc.h>
15 15
16struct analogix_dp_device;
17
16enum analogix_dp_devtype { 18enum analogix_dp_devtype {
17 EXYNOS_DP, 19 EXYNOS_DP,
18 RK3288_DP, 20 RK3288_DP,
@@ -29,6 +31,7 @@ struct analogix_dp_plat_data {
29 struct drm_panel *panel; 31 struct drm_panel *panel;
30 struct drm_encoder *encoder; 32 struct drm_encoder *encoder;
31 struct drm_connector *connector; 33 struct drm_connector *connector;
34 bool skip_connector;
32 35
33 int (*power_on)(struct analogix_dp_plat_data *); 36 int (*power_on)(struct analogix_dp_plat_data *);
34 int (*power_off)(struct analogix_dp_plat_data *); 37 int (*power_off)(struct analogix_dp_plat_data *);
@@ -38,16 +41,17 @@ struct analogix_dp_plat_data {
38 struct drm_connector *); 41 struct drm_connector *);
39}; 42};
40 43
41int analogix_dp_psr_supported(struct device *dev); 44int analogix_dp_psr_supported(struct analogix_dp_device *dp);
42int analogix_dp_enable_psr(struct device *dev); 45int analogix_dp_enable_psr(struct analogix_dp_device *dp);
43int analogix_dp_disable_psr(struct device *dev); 46int analogix_dp_disable_psr(struct analogix_dp_device *dp);
44 47
45int analogix_dp_resume(struct device *dev); 48int analogix_dp_resume(struct analogix_dp_device *dp);
46int analogix_dp_suspend(struct device *dev); 49int analogix_dp_suspend(struct analogix_dp_device *dp);
47 50
48int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, 51struct analogix_dp_device *
49 struct analogix_dp_plat_data *plat_data); 52analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
50void analogix_dp_unbind(struct device *dev, struct device *master, void *data); 53 struct analogix_dp_plat_data *plat_data);
54void analogix_dp_unbind(struct analogix_dp_device *dp);
51 55
52int analogix_dp_start_crc(struct drm_connector *connector); 56int analogix_dp_start_crc(struct drm_connector *connector);
53int analogix_dp_stop_crc(struct drm_connector *connector); 57int analogix_dp_stop_crc(struct drm_connector *connector);
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 2c711a24c80c..a57a8aa90ffb 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -754,6 +754,28 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
754 (new_plane_state) = (__state)->planes[__i].new_state, 1)) 754 (new_plane_state) = (__state)->planes[__i].new_state, 1))
755 755
756/** 756/**
757 * for_each_oldnew_plane_in_state_reverse - iterate over all planes in an atomic
758 * update in reverse order
759 * @__state: &struct drm_atomic_state pointer
760 * @plane: &struct drm_plane iteration cursor
761 * @old_plane_state: &struct drm_plane_state iteration cursor for the old state
762 * @new_plane_state: &struct drm_plane_state iteration cursor for the new state
763 * @__i: int iteration cursor, for macro-internal use
764 *
765 * This iterates over all planes in an atomic update in reverse order,
766 * tracking both old and new state. This is useful in places where the
767 * state delta needs to be considered, for example in atomic check functions.
768 */
769#define for_each_oldnew_plane_in_state_reverse(__state, plane, old_plane_state, new_plane_state, __i) \
770 for ((__i) = ((__state)->dev->mode_config.num_total_plane - 1); \
771 (__i) >= 0; \
772 (__i)--) \
773 for_each_if ((__state)->planes[__i].ptr && \
774 ((plane) = (__state)->planes[__i].ptr, \
775 (old_plane_state) = (__state)->planes[__i].old_state,\
776 (new_plane_state) = (__state)->planes[__i].new_state, 1))
777
778/**
757 * for_each_old_plane_in_state - iterate over all planes in an atomic update 779 * for_each_old_plane_in_state - iterate over all planes in an atomic update
758 * @__state: &struct drm_atomic_state pointer 780 * @__state: &struct drm_atomic_state pointer
759 * @plane: &struct drm_plane iteration cursor 781 * @plane: &struct drm_plane iteration cursor
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index 4842ee9485ce..26aaba58d6ce 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -40,7 +40,6 @@ int drm_atomic_helper_check_modeset(struct drm_device *dev,
40 struct drm_atomic_state *state); 40 struct drm_atomic_state *state);
41int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state, 41int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state,
42 const struct drm_crtc_state *crtc_state, 42 const struct drm_crtc_state *crtc_state,
43 const struct drm_rect *clip,
44 int min_scale, 43 int min_scale,
45 int max_scale, 44 int max_scale,
46 bool can_position, 45 bool can_position,
diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h
index 03a59cbce621..b3b6d302ca8c 100644
--- a/include/drm/drm_color_mgmt.h
+++ b/include/drm/drm_color_mgmt.h
@@ -26,6 +26,7 @@
26#include <linux/ctype.h> 26#include <linux/ctype.h>
27 27
28struct drm_crtc; 28struct drm_crtc;
29struct drm_plane;
29 30
30uint32_t drm_color_lut_extract(uint32_t user_input, uint32_t bit_precision); 31uint32_t drm_color_lut_extract(uint32_t user_input, uint32_t bit_precision);
31 32
@@ -37,4 +38,22 @@ void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc,
37int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, 38int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
38 int gamma_size); 39 int gamma_size);
39 40
41enum drm_color_encoding {
42 DRM_COLOR_YCBCR_BT601,
43 DRM_COLOR_YCBCR_BT709,
44 DRM_COLOR_YCBCR_BT2020,
45 DRM_COLOR_ENCODING_MAX,
46};
47
48enum drm_color_range {
49 DRM_COLOR_YCBCR_LIMITED_RANGE,
50 DRM_COLOR_YCBCR_FULL_RANGE,
51 DRM_COLOR_RANGE_MAX,
52};
53
54int drm_plane_create_color_properties(struct drm_plane *plane,
55 u32 supported_encodings,
56 u32 supported_ranges,
57 enum drm_color_encoding default_encoding,
58 enum drm_color_range default_range);
40#endif 59#endif
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 8185e3468a23..f7bf4a48b1c3 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -26,6 +26,7 @@
26#include <linux/list.h> 26#include <linux/list.h>
27#include <linux/ctype.h> 27#include <linux/ctype.h>
28#include <drm/drm_mode_object.h> 28#include <drm/drm_mode_object.h>
29#include <drm/drm_color_mgmt.h>
29 30
30struct drm_crtc; 31struct drm_crtc;
31struct drm_printer; 32struct drm_printer;
@@ -112,6 +113,20 @@ struct drm_plane_state {
112 unsigned int zpos; 113 unsigned int zpos;
113 unsigned int normalized_zpos; 114 unsigned int normalized_zpos;
114 115
116 /**
117 * @color_encoding:
118 *
119 * Color encoding for non RGB formats
120 */
121 enum drm_color_encoding color_encoding;
122
123 /**
124 * @color_range:
125 *
126 * Color range for non RGB formats
127 */
128 enum drm_color_range color_range;
129
115 /* Clipped coordinates */ 130 /* Clipped coordinates */
116 struct drm_rect src, dst; 131 struct drm_rect src, dst;
117 132
@@ -558,6 +573,23 @@ struct drm_plane {
558 573
559 struct drm_property *zpos_property; 574 struct drm_property *zpos_property;
560 struct drm_property *rotation_property; 575 struct drm_property *rotation_property;
576
577 /**
578 * @color_encoding_property:
579 *
580 * Optional "COLOR_ENCODING" enum property for specifying
581 * color encoding for non RGB formats.
582 * See drm_plane_create_color_properties().
583 */
584 struct drm_property *color_encoding_property;
585 /**
586 * @color_range_property:
587 *
588 * Optional "COLOR_RANGE" enum property for specifying
589 * color range for non RGB formats.
590 * See drm_plane_create_color_properties().
591 */
592 struct drm_property *color_range_property;
561}; 593};
562 594
563#define obj_to_plane(x) container_of(x, struct drm_plane, base) 595#define obj_to_plane(x) container_of(x, struct drm_plane, base)
diff --git a/include/drm/drm_plane_helper.h b/include/drm/drm_plane_helper.h
index 8aa49c0ecd4d..28d7ce620729 100644
--- a/include/drm/drm_plane_helper.h
+++ b/include/drm/drm_plane_helper.h
@@ -43,7 +43,6 @@ int drm_plane_helper_check_update(struct drm_plane *plane,
43 struct drm_framebuffer *fb, 43 struct drm_framebuffer *fb,
44 struct drm_rect *src, 44 struct drm_rect *src,
45 struct drm_rect *dest, 45 struct drm_rect *dest,
46 const struct drm_rect *clip,
47 unsigned int rotation, 46 unsigned int rotation,
48 int min_scale, 47 int min_scale,
49 int max_scale, 48 int max_scale,
diff --git a/include/drm/drm_property.h b/include/drm/drm_property.h
index 8a522b4bed40..937757a8a568 100644
--- a/include/drm/drm_property.h
+++ b/include/drm/drm_property.h
@@ -237,27 +237,29 @@ static inline bool drm_property_type_is(struct drm_property *property,
237 return property->flags & type; 237 return property->flags & type;
238} 238}
239 239
240struct drm_property *drm_property_create(struct drm_device *dev, int flags, 240struct drm_property *drm_property_create(struct drm_device *dev,
241 const char *name, int num_values); 241 u32 flags, const char *name,
242struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags, 242 int num_values);
243 const char *name, 243struct drm_property *drm_property_create_enum(struct drm_device *dev,
244 u32 flags, const char *name,
244 const struct drm_prop_enum_list *props, 245 const struct drm_prop_enum_list *props,
245 int num_values); 246 int num_values);
246struct drm_property *drm_property_create_bitmask(struct drm_device *dev, 247struct drm_property *drm_property_create_bitmask(struct drm_device *dev,
247 int flags, const char *name, 248 u32 flags, const char *name,
248 const struct drm_prop_enum_list *props, 249 const struct drm_prop_enum_list *props,
249 int num_props, 250 int num_props,
250 uint64_t supported_bits); 251 uint64_t supported_bits);
251struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, 252struct drm_property *drm_property_create_range(struct drm_device *dev,
252 const char *name, 253 u32 flags, const char *name,
253 uint64_t min, uint64_t max); 254 uint64_t min, uint64_t max);
254struct drm_property *drm_property_create_signed_range(struct drm_device *dev, 255struct drm_property *drm_property_create_signed_range(struct drm_device *dev,
255 int flags, const char *name, 256 u32 flags, const char *name,
256 int64_t min, int64_t max); 257 int64_t min, int64_t max);
257struct drm_property *drm_property_create_object(struct drm_device *dev, 258struct drm_property *drm_property_create_object(struct drm_device *dev,
258 int flags, const char *name, uint32_t type); 259 u32 flags, const char *name,
259struct drm_property *drm_property_create_bool(struct drm_device *dev, int flags, 260 uint32_t type);
260 const char *name); 261struct drm_property *drm_property_create_bool(struct drm_device *dev,
262 u32 flags, const char *name);
261int drm_property_add_enum(struct drm_property *property, int index, 263int drm_property_add_enum(struct drm_property *property, int index,
262 uint64_t value, const char *name); 264 uint64_t value, const char *name);
263void drm_property_destroy(struct drm_device *dev, struct drm_property *property); 265void drm_property_destroy(struct drm_device *dev, struct drm_property *property);
diff --git a/include/drm/drm_simple_kms_helper.h b/include/drm/drm_simple_kms_helper.h
index d9e4c3c3f009..1b4e352143fd 100644
--- a/include/drm/drm_simple_kms_helper.h
+++ b/include/drm/drm_simple_kms_helper.h
@@ -24,9 +24,30 @@ struct drm_simple_display_pipe_funcs {
24 /** 24 /**
25 * @mode_valid: 25 * @mode_valid:
26 * 26 *
27 * This function is called to filter out valid modes from the 27 * This callback is used to check if a specific mode is valid in the
28 * suggestions suggested by the bridge or display. This optional 28 * crtc used in this simple display pipe. This should be implemented
29 * hook is passed in when initializing the pipeline. 29 * if the display pipe has some sort of restriction in the modes
30 * it can display. For example, a given display pipe may be responsible
31 * to set a clock value. If the clock can not produce all the values
32 * for the available modes then this callback can be used to restrict
33 * the number of modes to only the ones that can be displayed. Another
34 * reason can be bandwidth mitigation: the memory port on the display
35 * controller can have bandwidth limitations not allowing pixel data
36 * to be fetched at any rate.
37 *
38 * This hook is used by the probe helpers to filter the mode list in
39 * drm_helper_probe_single_connector_modes(), and it is used by the
40 * atomic helpers to validate modes supplied by userspace in
41 * drm_atomic_helper_check_modeset().
42 *
43 * This function is optional.
44 *
45 * NOTE:
46 *
47 * Since this function is both called from the check phase of an atomic
48 * commit, and the mode validation in the probe paths it is not allowed
49 * to look at anything else but the passed-in mode, and validate it
50 * against configuration-invariant hardware constraints.
30 * 51 *
31 * RETURNS: 52 * RETURNS:
32 * 53 *
@@ -107,6 +128,24 @@ struct drm_simple_display_pipe_funcs {
107 */ 128 */
108 void (*cleanup_fb)(struct drm_simple_display_pipe *pipe, 129 void (*cleanup_fb)(struct drm_simple_display_pipe *pipe,
109 struct drm_plane_state *plane_state); 130 struct drm_plane_state *plane_state);
131
132 /**
133 * @enable_vblank:
134 *
135 * Optional, called by &drm_crtc_funcs.enable_vblank. Please read
136 * the documentation for the &drm_crtc_funcs.enable_vblank hook for
137 * more details.
138 */
139 int (*enable_vblank)(struct drm_simple_display_pipe *pipe);
140
141 /**
142 * @disable_vblank:
143 *
144 * Optional, called by &drm_crtc_funcs.disable_vblank. Please read
145 * the documentation for the &drm_crtc_funcs.disable_vblank hook for
146 * more details.
147 */
148 void (*disable_vblank)(struct drm_simple_display_pipe *pipe);
110}; 149};
111 150
112/** 151/**
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 2c575794fb52..50bcf4214ff9 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -363,7 +363,7 @@ struct drm_mode_get_connector {
363 __u32 pad; 363 __u32 pad;
364}; 364};
365 365
366#define DRM_MODE_PROP_PENDING (1<<0) 366#define DRM_MODE_PROP_PENDING (1<<0) /* deprecated, do not use */
367#define DRM_MODE_PROP_RANGE (1<<1) 367#define DRM_MODE_PROP_RANGE (1<<1)
368#define DRM_MODE_PROP_IMMUTABLE (1<<2) 368#define DRM_MODE_PROP_IMMUTABLE (1<<2)
369#define DRM_MODE_PROP_ENUM (1<<3) /* enumerated type with text strings */ 369#define DRM_MODE_PROP_ENUM (1<<3) /* enumerated type with text strings */
@@ -598,8 +598,11 @@ struct drm_mode_crtc_lut {
598}; 598};
599 599
600struct drm_color_ctm { 600struct drm_color_ctm {
601 /* Conversion matrix in S31.32 format. */ 601 /*
602 __s64 matrix[9]; 602 * Conversion matrix in S31.32 sign-magnitude
603 * (not two's complement!) format.
604 */
605 __u64 matrix[9];
603}; 606};
604 607
605struct drm_color_lut { 608struct drm_color_lut {