aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2017-08-09 20:47:33 -0400
committerDave Airlie <airlied@redhat.com>2017-08-09 20:47:33 -0400
commit09ef2378dc42339f3871584dc26d27da220277cb (patch)
treebd7d8e982c457767f50e3129b09b5f7d9e36a9d1
parentd720661291fc2b261311c8425b8ca0e2a21c264b (diff)
parent16fece0153d5b6573c3fcb8cfbe483f83ca8eb01 (diff)
Merge tag 'drm-misc-next-2017-08-08' of git://anongit.freedesktop.org/git/drm-misc into drm-next
UAPI Changes: - vc4: Add ioctl to allow attaching a label to a bo (Eric) - Add new format/modifier blob plane property (Ben) - armada: Use __u32/__u64 instead of uint32_t/uint64_t (Mikko) - [kinda uapi] fb_helper: Expose display_info size via fb_info (David) Core Changes: - Default gem_dumb_[map_offset|destroy] as mmap/destroy implementations (Noralf) - Simplify atomic properties by removing the helpers and handling in core (Daniel) Driver Changes: - stm: Add STM32 DSI controller driver (Phillipe) - vc4: Add HDMI CEC support (Hans) - rockchip: Refactor register init & soc version handling (Mark) - misc: Remove .load_lut, .gamma_set, .gamma_get dead code (Peter) - dw-hdmi: Add HDMI CEC support (Russell) Cc: Philippe CORNU <philippe.cornu@st.com> Cc: Hans Verkuil <hans.verkuil@cisco.com> Cc: Eric Anholt <eric@anholt.net> Cc: Noralf Trønnes <noralf@tronnes.org> Cc: Ben Widawsky <ben@bwidawsk.net> Cc: Mark yao <mark.yao@rock-chips.com> Cc: Peter Rosin <peda@axentia.se> Cc: Russell King <rmk+kernel@armlinux.org.uk> Cc: Mikko Rapeli <mikko.rapeli@iki.fi> Cc: David Lechner <david@lechnology.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> * tag 'drm-misc-next-2017-08-08' of git://anongit.freedesktop.org/git/drm-misc: (107 commits) drm: Nuke drm_atomic_legacy_backoff drm: Nuke drm_atomic_helper_connector_dpms drm: Nuke drm_atomic_helper_connector_set_property drm: Nuke drm_atomic_helper_plane_set_property drm: Nuke drm_atomic_helper_crtc_set_property drm: Handle properties in the core for atomic drivers drm: Don't update property values for atomic drivers drm/omap: Rework the rotation-on-crtc hack drm/radeon: Use the drm_driver.dumb_destroy default drm/i915: Use the drm_driver.dumb_destroy default drm/sti: Use .dumb_map_offset and .dumb_destroy defaults drm: bridge: synopsys/dw-hdmi: Provide default configuration function for HDMI 2.0 PHY drm/fb-helper: pass physical dimensions to fbdev uapi drm/armada_drm.h: use __u32 and __u64 instead of uint32_t and uint64_t drm/bridge: dw-hdmi: remove CEC engine register definitions drm/bridge: dw-hdmi: add cec driver drm/bridge: dw-hdmi: add missing cec_notifier_put drm: remove unused and redundant callbacks staging: vboxvideo: remove dead gamma lut code drm: dw-hdmi-i2s: add missing company name on Copyright ...
-rw-r--r--Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt4
-rw-r--r--Documentation/devicetree/bindings/display/st,stm32-ltdc.txt105
-rw-r--r--Documentation/gpu/todo.rst4
-rw-r--r--drivers/dma-buf/sw_sync.c150
-rw-r--r--drivers/dma-buf/sync_file.c5
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c24
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v10_0.c27
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v11_0.c27
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v6_0.c27
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v8_0.c27
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_virtual.c23
-rw-r--r--drivers/gpu/drm/arc/arcpgu_crtc.c1
-rw-r--r--drivers/gpu/drm/arc/arcpgu_drv.c2
-rw-r--r--drivers/gpu/drm/arm/hdlcd_crtc.c1
-rw-r--r--drivers/gpu/drm/arm/hdlcd_drv.c2
-rw-r--r--drivers/gpu/drm/arm/malidp_drv.c2
-rw-r--r--drivers/gpu/drm/arm/malidp_planes.c3
-rw-r--r--drivers/gpu/drm/armada/armada_crtc.c11
-rw-r--r--drivers/gpu/drm/armada/armada_crtc.h2
-rw-r--r--drivers/gpu/drm/armada/armada_fbdev.c2
-rw-r--r--drivers/gpu/drm/armada/armada_overlay.c1
-rw-r--r--drivers/gpu/drm/ast/ast_drv.h1
-rw-r--r--drivers/gpu/drm/ast/ast_fb.c20
-rw-r--r--drivers/gpu/drm/ast/ast_mode.c26
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c1
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c2
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c16
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7511_drv.c1
-rw-r--r--drivers/gpu/drm/bridge/analogix-anx78xx.c1
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix_dp_core.c1
-rw-r--r--drivers/gpu/drm/bridge/dumb-vga-dac.c1
-rw-r--r--drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c1
-rw-r--r--drivers/gpu/drm/bridge/nxp-ptn3460.c1
-rw-r--r--drivers/gpu/drm/bridge/panel.c31
-rw-r--r--drivers/gpu/drm/bridge/parade-ps8622.c1
-rw-r--r--drivers/gpu/drm/bridge/sii902x.c1
-rw-r--r--drivers/gpu/drm/bridge/synopsys/Kconfig10
-rw-r--r--drivers/gpu/drm/bridge/synopsys/Makefile1
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c327
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h19
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c3
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi.c98
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi.h46
-rw-r--r--drivers/gpu/drm/bridge/tc358767.c1
-rw-r--r--drivers/gpu/drm/bridge/ti-tfp410.c1
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_drv.h8
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_fbdev.c2
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_mode.c71
-rw-r--r--drivers/gpu/drm/drm_atomic.c98
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c250
-rw-r--r--drivers/gpu/drm/drm_connector.c7
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c3
-rw-r--r--drivers/gpu/drm/drm_crtc_internal.h7
-rw-r--r--drivers/gpu/drm/drm_dumb_buffers.c26
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c49
-rw-r--r--drivers/gpu/drm/drm_gem.c35
-rw-r--r--drivers/gpu/drm/drm_mode_config.c7
-rw-r--r--drivers/gpu/drm/drm_mode_object.c159
-rw-r--r--drivers/gpu/drm/drm_modes.c2
-rw-r--r--drivers/gpu/drm/drm_modeset_helper.c1
-rw-r--r--drivers/gpu/drm/drm_plane.c120
-rw-r--r--drivers/gpu/drm/drm_scdc_helper.c33
-rw-r--r--drivers/gpu/drm/drm_simple_kms_helper.c3
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dpi.c1
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dsi.c1
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_plane.c3
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_vidi.c1
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.c1
-rw-r--r--drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c2
-rw-r--r--drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c2
-rw-r--r--drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c1
-rw-r--r--drivers/gpu/drm/gma500/framebuffer.c22
-rw-r--r--drivers/gpu/drm/gma500/gma_display.c32
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_display.c7
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_drv.h1
-rw-r--r--drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c2
-rw-r--r--drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c1
-rw-r--r--drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c1
-rw-r--r--drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c4
-rw-r--r--drivers/gpu/drm/i2c/tda998x_drv.c10
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c1
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c2
-rw-r--r--drivers/gpu/drm/i915/intel_display.c8
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c2
-rw-r--r--drivers/gpu/drm/i915/intel_dp_mst.c2
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h1
-rw-r--r--drivers/gpu/drm/i915/intel_dsi.c2
-rw-r--r--drivers/gpu/drm/i915/intel_dvo.c2
-rw-r--r--drivers/gpu/drm/i915/intel_fbdev.c31
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c2
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c2
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c2
-rw-r--r--drivers/gpu/drm/i915/intel_sprite.c4
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c2
-rw-r--r--drivers/gpu/drm/imx/imx-drm-core.c2
-rw-r--r--drivers/gpu/drm/imx/imx-ldb.c1
-rw-r--r--drivers/gpu/drm/imx/imx-tve.c1
-rw-r--r--drivers/gpu/drm/imx/ipuv3-plane.c4
-rw-r--r--drivers/gpu/drm/imx/parallel-display.c1
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_drv.c2
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_gem.c25
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_gem.h3
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_plane.c2
-rw-r--r--drivers/gpu/drm/mediatek/mtk_dsi.c1
-rw-r--r--drivers/gpu/drm/mediatek/mtk_hdmi.c1
-rw-r--r--drivers/gpu/drm/meson/meson_plane.c1
-rw-r--r--drivers/gpu/drm/meson/meson_venc_cvbs.c1
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_drv.h5
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_fb.c2
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_mode.c62
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_manager.c1
-rw-r--r--drivers/gpu/drm/msm/edp/edp_connector.c1
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi_connector.c1
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c1
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c4
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c1
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c2
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c2
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c6
-rw-r--r--drivers/gpu/drm/msm/msm_atomic.c18
-rw-r--r--drivers/gpu/drm/mxsfb/mxsfb_drv.c2
-rw-r--r--drivers/gpu/drm/mxsfb/mxsfb_out.c1
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/crtc.c26
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c15
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_crtc.h3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.c22
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c121
-rw-r--r--drivers/gpu/drm/omapdrm/omap_connector.c1
-rw-r--r--drivers/gpu/drm/omapdrm/omap_crtc.c125
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.c7
-rw-r--r--drivers/gpu/drm/omapdrm/omap_plane.c3
-rw-r--r--drivers/gpu/drm/pl111/pl111_connector.c1
-rw-r--r--drivers/gpu/drm/pl111/pl111_display.c2
-rw-r--r--drivers/gpu/drm/pl111/pl111_drv.c2
-rw-r--r--drivers/gpu/drm/qxl/qxl_display.c2
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c7
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c71
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_fb.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_crtc.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h4
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_drv.c2
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c1
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_plane.c5
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_vsp.c5
-rw-r--r--drivers/gpu/drm/rockchip/cdn-dp-core.c1
-rw-r--r--drivers/gpu/drm/rockchip/dw-mipi-dsi.c1
-rw-r--r--drivers/gpu/drm/rockchip/inno_hdmi.c1
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_drv.c15
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_gem.c26
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_gem.h3
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop.c190
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop.h84
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_vop_reg.c375
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_vop_reg.h905
-rw-r--r--drivers/gpu/drm/shmobile/shmob_drm_drv.c2
-rw-r--r--drivers/gpu/drm/sti/sti_cursor.c3
-rw-r--r--drivers/gpu/drm/sti/sti_drv.c2
-rw-r--r--drivers/gpu/drm/sti/sti_dvo.c1
-rw-r--r--drivers/gpu/drm/sti/sti_gdp.c3
-rw-r--r--drivers/gpu/drm/sti/sti_hda.c1
-rw-r--r--drivers/gpu/drm/sti/sti_hdmi.c2
-rw-r--r--drivers/gpu/drm/sti/sti_hqvdp.c3
-rw-r--r--drivers/gpu/drm/stm/Kconfig8
-rw-r--r--drivers/gpu/drm/stm/Makefile2
-rw-r--r--drivers/gpu/drm/stm/drv.c23
-rw-r--r--drivers/gpu/drm/stm/dw_mipi_dsi-stm.c352
-rw-r--r--drivers/gpu/drm/stm/ltdc.c240
-rw-r--r--drivers/gpu/drm/stm/ltdc.h1
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_drv.c2
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c1
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_layer.c2
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_rgb.c1
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_tv.c1
-rw-r--r--drivers/gpu/drm/sun4i/sun8i_layer.c2
-rw-r--r--drivers/gpu/drm/tegra/dc.c12
-rw-r--r--drivers/gpu/drm/tegra/dsi.c1
-rw-r--r--drivers/gpu/drm/tegra/hdmi.c1
-rw-r--r--drivers/gpu/drm/tegra/rgb.c1
-rw-r--r--drivers/gpu/drm/tegra/sor.c1
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_drv.c2
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_panel.c1
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_plane.c1
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_tfp410.c1
-rw-r--r--drivers/gpu/drm/tinydrm/Kconfig1
-rw-r--r--drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c3
-rw-r--r--drivers/gpu/drm/tinydrm/mi0283qt.c8
-rw-r--r--drivers/gpu/drm/tinydrm/mipi-dbi.c17
-rw-r--r--drivers/gpu/drm/vc4/Kconfig8
-rw-r--r--drivers/gpu/drm/vc4/vc4_bo.c265
-rw-r--r--drivers/gpu/drm/vc4/vc4_drv.c10
-rw-r--r--drivers/gpu/drm/vc4/vc4_drv.h39
-rw-r--r--drivers/gpu/drm/vc4/vc4_gem.c13
-rw-r--r--drivers/gpu/drm/vc4/vc4_hdmi.c288
-rw-r--r--drivers/gpu/drm/vc4/vc4_plane.c2
-rw-r--r--drivers/gpu/drm/vc4/vc4_regs.h113
-rw-r--r--drivers/gpu/drm/vc4/vc4_render_cl.c2
-rw-r--r--drivers/gpu/drm/vc4/vc4_v3d.c3
-rw-r--r--drivers/gpu/drm/vc4/vc4_vec.c2
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_display.c1
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_plane.c2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c4
-rw-r--r--drivers/gpu/drm/zte/zx_drm_drv.c2
-rw-r--r--drivers/gpu/drm/zte/zx_hdmi.c1
-rw-r--r--drivers/gpu/drm/zte/zx_plane.c2
-rw-r--r--drivers/gpu/drm/zte/zx_tvenc.c1
-rw-r--r--drivers/gpu/drm/zte/zx_vga.c1
-rw-r--r--drivers/gpu/host1x/bus.c1
-rw-r--r--drivers/staging/vboxvideo/vbox_fb.c15
-rw-r--r--drivers/staging/vboxvideo/vbox_mode.c5
-rw-r--r--include/drm/drm_atomic.h10
-rw-r--r--include/drm/drm_atomic_helper.h11
-rw-r--r--include/drm/drm_bridge.h3
-rw-r--r--include/drm/drm_connector.h10
-rw-r--r--include/drm/drm_crtc.h14
-rw-r--r--include/drm/drm_drv.h52
-rw-r--r--include/drm/drm_fb_helper.h32
-rw-r--r--include/drm/drm_gem.h2
-rw-r--r--include/drm/drm_mode_config.h6
-rw-r--r--include/drm/drm_modeset_helper_vtables.h22
-rw-r--r--include/drm/drm_plane.h28
-rw-r--r--include/drm/drm_scdc_helper.h25
-rw-r--r--include/drm/drm_simple_kms_helper.h1
-rw-r--r--include/drm/tinydrm/mipi-dbi.h6
-rw-r--r--include/drm/tinydrm/tinydrm.h4
-rw-r--r--include/linux/sync_file.h3
-rw-r--r--include/uapi/drm/armada_drm.h22
-rw-r--r--include/uapi/drm/drm_fourcc.h11
-rw-r--r--include/uapi/drm/drm_mode.h50
-rw-r--r--include/uapi/drm/vc4_drm.h11
236 files changed, 3820 insertions, 2278 deletions
diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt
index 9eb3f0a2a078..5d835d9c1ba8 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt
@@ -8,8 +8,12 @@ Required properties:
8- compatible: value should be one of the following 8- compatible: value should be one of the following
9 "rockchip,rk3036-vop"; 9 "rockchip,rk3036-vop";
10 "rockchip,rk3288-vop"; 10 "rockchip,rk3288-vop";
11 "rockchip,rk3368-vop";
12 "rockchip,rk3366-vop";
11 "rockchip,rk3399-vop-big"; 13 "rockchip,rk3399-vop-big";
12 "rockchip,rk3399-vop-lit"; 14 "rockchip,rk3399-vop-lit";
15 "rockchip,rk3228-vop";
16 "rockchip,rk3328-vop";
13 17
14- interrupts: should contain a list of all VOP IP block interrupts in the 18- interrupts: should contain a list of all VOP IP block interrupts in the
15 order: VSYNC, LCD_SYSTEM. The interrupt specifier 19 order: VSYNC, LCD_SYSTEM. The interrupt specifier
diff --git a/Documentation/devicetree/bindings/display/st,stm32-ltdc.txt b/Documentation/devicetree/bindings/display/st,stm32-ltdc.txt
index 8e1476941c0f..74b5ac7b26d6 100644
--- a/Documentation/devicetree/bindings/display/st,stm32-ltdc.txt
+++ b/Documentation/devicetree/bindings/display/st,stm32-ltdc.txt
@@ -1,7 +1,6 @@
1* STMicroelectronics STM32 lcd-tft display controller 1* STMicroelectronics STM32 lcd-tft display controller
2 2
3- ltdc: lcd-tft display controller host 3- ltdc: lcd-tft display controller host
4 must be a sub-node of st-display-subsystem
5 Required properties: 4 Required properties:
6 - compatible: "st,stm32-ltdc" 5 - compatible: "st,stm32-ltdc"
7 - reg: Physical base address of the IP registers and length of memory mapped region. 6 - reg: Physical base address of the IP registers and length of memory mapped region.
@@ -13,8 +12,40 @@
13 Required nodes: 12 Required nodes:
14 - Video port for RGB output. 13 - Video port for RGB output.
15 14
16Example: 15* STMicroelectronics STM32 DSI controller specific extensions to Synopsys
16 DesignWare MIPI DSI host controller
17 17
18The STMicroelectronics STM32 DSI controller uses the Synopsys DesignWare MIPI
19DSI host controller. For all mandatory properties & nodes, please refer
20to the related documentation in [5].
21
22Mandatory properties specific to STM32 DSI:
23- #address-cells: Should be <1>.
24- #size-cells: Should be <0>.
25- compatible: "st,stm32-dsi".
26- clock-names:
27 - phy pll reference clock string name, must be "ref".
28- resets: see [5].
29- reset-names: see [5].
30
31Mandatory nodes specific to STM32 DSI:
32- ports: A node containing DSI input & output port nodes with endpoint
33 definitions as documented in [3] & [4].
34 - port@0: DSI input port node, connected to the ltdc rgb output port.
35 - port@1: DSI output port node, connected to a panel or a bridge input port.
36- panel or bridge node: A node containing the panel or bridge description as
37 documented in [6].
38 - port: panel or bridge port node, connected to the DSI output port (port@1).
39
40Note: You can find more documentation in the following references
41[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
42[2] Documentation/devicetree/bindings/reset/reset.txt
43[3] Documentation/devicetree/bindings/media/video-interfaces.txt
44[4] Documentation/devicetree/bindings/graph.txt
45[5] Documentation/devicetree/bindings/display/bridge/dw_mipi_dsi.txt
46[6] Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
47
48Example 1: RGB panel
18/ { 49/ {
19 ... 50 ...
20 soc { 51 soc {
@@ -34,3 +65,73 @@ Example:
34 }; 65 };
35 }; 66 };
36}; 67};
68
69Example 2: DSI panel
70
71/ {
72 ...
73 soc {
74 ...
75 ltdc: display-controller@40016800 {
76 compatible = "st,stm32-ltdc";
77 reg = <0x40016800 0x200>;
78 interrupts = <88>, <89>;
79 resets = <&rcc STM32F4_APB2_RESET(LTDC)>;
80 clocks = <&rcc 1 CLK_LCD>;
81 clock-names = "lcd";
82
83 port {
84 ltdc_out_dsi: endpoint {
85 remote-endpoint = <&dsi_in>;
86 };
87 };
88 };
89
90
91 dsi: dsi@40016c00 {
92 #address-cells = <1>;
93 #size-cells = <0>;
94 compatible = "st,stm32-dsi";
95 reg = <0x40016c00 0x800>;
96 clocks = <&rcc 1 CLK_F469_DSI>, <&clk_hse>;
97 clock-names = "ref", "pclk";
98 resets = <&rcc STM32F4_APB2_RESET(DSI)>;
99 reset-names = "apb";
100
101 ports {
102 #address-cells = <1>;
103 #size-cells = <0>;
104
105 port@0 {
106 reg = <0>;
107 dsi_in: endpoint {
108 remote-endpoint = <&ltdc_out_dsi>;
109 };
110 };
111
112 port@1 {
113 reg = <1>;
114 dsi_out: endpoint {
115 remote-endpoint = <&dsi_in_panel>;
116 };
117 };
118
119 };
120
121 panel-dsi@0 {
122 reg = <0>; /* dsi virtual channel (0..3) */
123 compatible = ...;
124 enable-gpios = ...;
125
126 port {
127 dsi_in_panel: endpoint {
128 remote-endpoint = <&dsi_out>;
129 };
130 };
131
132 };
133
134 };
135
136 };
137};
diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index 1ae42006deea..22af55d06ab8 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -108,8 +108,8 @@ This would be especially useful for tinydrm:
108 crtc state, clear that to the max values, x/y = 0 and w/h = MAX_INT, in 108 crtc state, clear that to the max values, x/y = 0 and w/h = MAX_INT, in
109 __drm_atomic_helper_crtc_duplicate_state(). 109 __drm_atomic_helper_crtc_duplicate_state().
110 110
111- Move tinydrm_merge_clips into drm_framebuffer.c, dropping the tinydrm_ 111- Move tinydrm_merge_clips into drm_framebuffer.c, dropping the tinydrm\_
112 prefix ofc and using drm_fb_. drm_framebuffer.c makes sense since this 112 prefix ofc and using drm_fb\_. drm_framebuffer.c makes sense since this
113 is a function useful to implement the fb->dirty function. 113 is a function useful to implement the fb->dirty function.
114 114
115- Create a new drm_fb_dirty function which does essentially what e.g. 115- Create a new drm_fb_dirty function which does essentially what e.g.
diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
index af1bc84802e5..38cc7389a6c1 100644
--- a/drivers/dma-buf/sw_sync.c
+++ b/drivers/dma-buf/sw_sync.c
@@ -125,6 +125,75 @@ static void sync_timeline_put(struct sync_timeline *obj)
125 kref_put(&obj->kref, sync_timeline_free); 125 kref_put(&obj->kref, sync_timeline_free);
126} 126}
127 127
128static const char *timeline_fence_get_driver_name(struct dma_fence *fence)
129{
130 return "sw_sync";
131}
132
133static const char *timeline_fence_get_timeline_name(struct dma_fence *fence)
134{
135 struct sync_timeline *parent = dma_fence_parent(fence);
136
137 return parent->name;
138}
139
140static void timeline_fence_release(struct dma_fence *fence)
141{
142 struct sync_pt *pt = dma_fence_to_sync_pt(fence);
143 struct sync_timeline *parent = dma_fence_parent(fence);
144
145 if (!list_empty(&pt->link)) {
146 unsigned long flags;
147
148 spin_lock_irqsave(fence->lock, flags);
149 if (!list_empty(&pt->link)) {
150 list_del(&pt->link);
151 rb_erase(&pt->node, &parent->pt_tree);
152 }
153 spin_unlock_irqrestore(fence->lock, flags);
154 }
155
156 sync_timeline_put(parent);
157 dma_fence_free(fence);
158}
159
160static bool timeline_fence_signaled(struct dma_fence *fence)
161{
162 struct sync_timeline *parent = dma_fence_parent(fence);
163
164 return !__dma_fence_is_later(fence->seqno, parent->value);
165}
166
167static bool timeline_fence_enable_signaling(struct dma_fence *fence)
168{
169 return true;
170}
171
172static void timeline_fence_value_str(struct dma_fence *fence,
173 char *str, int size)
174{
175 snprintf(str, size, "%d", fence->seqno);
176}
177
178static void timeline_fence_timeline_value_str(struct dma_fence *fence,
179 char *str, int size)
180{
181 struct sync_timeline *parent = dma_fence_parent(fence);
182
183 snprintf(str, size, "%d", parent->value);
184}
185
186static const struct dma_fence_ops timeline_fence_ops = {
187 .get_driver_name = timeline_fence_get_driver_name,
188 .get_timeline_name = timeline_fence_get_timeline_name,
189 .enable_signaling = timeline_fence_enable_signaling,
190 .signaled = timeline_fence_signaled,
191 .wait = dma_fence_default_wait,
192 .release = timeline_fence_release,
193 .fence_value_str = timeline_fence_value_str,
194 .timeline_value_str = timeline_fence_timeline_value_str,
195};
196
128/** 197/**
129 * sync_timeline_signal() - signal a status change on a sync_timeline 198 * sync_timeline_signal() - signal a status change on a sync_timeline
130 * @obj: sync_timeline to signal 199 * @obj: sync_timeline to signal
@@ -144,11 +213,21 @@ static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc)
144 obj->value += inc; 213 obj->value += inc;
145 214
146 list_for_each_entry_safe(pt, next, &obj->pt_list, link) { 215 list_for_each_entry_safe(pt, next, &obj->pt_list, link) {
147 if (!dma_fence_is_signaled_locked(&pt->base)) 216 if (!timeline_fence_signaled(&pt->base))
148 break; 217 break;
149 218
150 list_del_init(&pt->link); 219 list_del_init(&pt->link);
151 rb_erase(&pt->node, &obj->pt_tree); 220 rb_erase(&pt->node, &obj->pt_tree);
221
222 /*
223 * A signal callback may release the last reference to this
224 * fence, causing it to be freed. That operation has to be
225 * last to avoid a use after free inside this loop, and must
226 * be after we remove the fence from the timeline in order to
227 * prevent deadlocking on timeline->lock inside
228 * timeline_fence_release().
229 */
230 dma_fence_signal_locked(&pt->base);
152 } 231 }
153 232
154 spin_unlock_irq(&obj->lock); 233 spin_unlock_irq(&obj->lock);
@@ -216,75 +295,6 @@ unlock:
216 return pt; 295 return pt;
217} 296}
218 297
219static const char *timeline_fence_get_driver_name(struct dma_fence *fence)
220{
221 return "sw_sync";
222}
223
224static const char *timeline_fence_get_timeline_name(struct dma_fence *fence)
225{
226 struct sync_timeline *parent = dma_fence_parent(fence);
227
228 return parent->name;
229}
230
231static void timeline_fence_release(struct dma_fence *fence)
232{
233 struct sync_pt *pt = dma_fence_to_sync_pt(fence);
234 struct sync_timeline *parent = dma_fence_parent(fence);
235
236 if (!list_empty(&pt->link)) {
237 unsigned long flags;
238
239 spin_lock_irqsave(fence->lock, flags);
240 if (!list_empty(&pt->link)) {
241 list_del(&pt->link);
242 rb_erase(&pt->node, &parent->pt_tree);
243 }
244 spin_unlock_irqrestore(fence->lock, flags);
245 }
246
247 sync_timeline_put(parent);
248 dma_fence_free(fence);
249}
250
251static bool timeline_fence_signaled(struct dma_fence *fence)
252{
253 struct sync_timeline *parent = dma_fence_parent(fence);
254
255 return !__dma_fence_is_later(fence->seqno, parent->value);
256}
257
258static bool timeline_fence_enable_signaling(struct dma_fence *fence)
259{
260 return true;
261}
262
263static void timeline_fence_value_str(struct dma_fence *fence,
264 char *str, int size)
265{
266 snprintf(str, size, "%d", fence->seqno);
267}
268
269static void timeline_fence_timeline_value_str(struct dma_fence *fence,
270 char *str, int size)
271{
272 struct sync_timeline *parent = dma_fence_parent(fence);
273
274 snprintf(str, size, "%d", parent->value);
275}
276
277static const struct dma_fence_ops timeline_fence_ops = {
278 .get_driver_name = timeline_fence_get_driver_name,
279 .get_timeline_name = timeline_fence_get_timeline_name,
280 .enable_signaling = timeline_fence_enable_signaling,
281 .signaled = timeline_fence_signaled,
282 .wait = dma_fence_default_wait,
283 .release = timeline_fence_release,
284 .fence_value_str = timeline_fence_value_str,
285 .timeline_value_str = timeline_fence_timeline_value_str,
286};
287
288/* 298/*
289 * *WARNING* 299 * *WARNING*
290 * 300 *
diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c
index d7e219d2669d..66fb40d0ebdb 100644
--- a/drivers/dma-buf/sync_file.c
+++ b/drivers/dma-buf/sync_file.c
@@ -304,7 +304,7 @@ static int sync_file_release(struct inode *inode, struct file *file)
304{ 304{
305 struct sync_file *sync_file = file->private_data; 305 struct sync_file *sync_file = file->private_data;
306 306
307 if (test_bit(POLL_ENABLED, &sync_file->fence->flags)) 307 if (test_bit(POLL_ENABLED, &sync_file->flags))
308 dma_fence_remove_callback(sync_file->fence, &sync_file->cb); 308 dma_fence_remove_callback(sync_file->fence, &sync_file->cb);
309 dma_fence_put(sync_file->fence); 309 dma_fence_put(sync_file->fence);
310 kfree(sync_file); 310 kfree(sync_file);
@@ -318,7 +318,8 @@ static unsigned int sync_file_poll(struct file *file, poll_table *wait)
318 318
319 poll_wait(file, &sync_file->wq, wait); 319 poll_wait(file, &sync_file->wq, wait);
320 320
321 if (!test_and_set_bit(POLL_ENABLED, &sync_file->fence->flags)) { 321 if (list_empty(&sync_file->cb.node) &&
322 !test_and_set_bit(POLL_ENABLED, &sync_file->flags)) {
322 if (dma_fence_add_callback(sync_file->fence, &sync_file->cb, 323 if (dma_fence_add_callback(sync_file->fence, &sync_file->cb,
323 fence_check_cb_func) < 0) 324 fence_check_cb_func) < 0)
324 wake_up_all(&sync_file->wq); 325 wake_up_all(&sync_file->wq);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index aa53a860c904..5e9ce8a29669 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -834,7 +834,6 @@ static struct drm_driver kms_driver = {
834 .gem_close_object = amdgpu_gem_object_close, 834 .gem_close_object = amdgpu_gem_object_close,
835 .dumb_create = amdgpu_mode_dumb_create, 835 .dumb_create = amdgpu_mode_dumb_create,
836 .dumb_map_offset = amdgpu_mode_dumb_mmap, 836 .dumb_map_offset = amdgpu_mode_dumb_mmap,
837 .dumb_destroy = drm_gem_dumb_destroy,
838 .fops = &amdgpu_driver_kms_fops, 837 .fops = &amdgpu_driver_kms_fops,
839 838
840 .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 839 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
index 1c57fefc364c..0a8ee2411180 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
@@ -311,31 +311,7 @@ static int amdgpu_fbdev_destroy(struct drm_device *dev, struct amdgpu_fbdev *rfb
311 return 0; 311 return 0;
312} 312}
313 313
314/** Sets the color ramps on behalf of fbcon */
315static void amdgpu_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
316 u16 blue, int regno)
317{
318 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
319
320 amdgpu_crtc->lut_r[regno] = red >> 6;
321 amdgpu_crtc->lut_g[regno] = green >> 6;
322 amdgpu_crtc->lut_b[regno] = blue >> 6;
323}
324
325/** Gets the color ramps on behalf of fbcon */
326static void amdgpu_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
327 u16 *blue, int regno)
328{
329 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
330
331 *red = amdgpu_crtc->lut_r[regno] << 6;
332 *green = amdgpu_crtc->lut_g[regno] << 6;
333 *blue = amdgpu_crtc->lut_b[regno] << 6;
334}
335
336static const struct drm_fb_helper_funcs amdgpu_fb_helper_funcs = { 314static const struct drm_fb_helper_funcs amdgpu_fb_helper_funcs = {
337 .gamma_set = amdgpu_crtc_fb_gamma_set,
338 .gamma_get = amdgpu_crtc_fb_gamma_get,
339 .fb_probe = amdgpufb_create, 315 .fb_probe = amdgpufb_create,
340}; 316};
341 317
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index b8abd4e18d51..2af2678ddaf6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -357,7 +357,6 @@ struct amdgpu_atom_ss {
357struct amdgpu_crtc { 357struct amdgpu_crtc {
358 struct drm_crtc base; 358 struct drm_crtc base;
359 int crtc_id; 359 int crtc_id;
360 u16 lut_r[256], lut_g[256], lut_b[256];
361 bool enabled; 360 bool enabled;
362 bool can_tile; 361 bool can_tile;
363 uint32_t crtc_offset; 362 uint32_t crtc_offset;
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
index 4b6e2f7bfec9..490e84944851 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
@@ -2139,6 +2139,7 @@ static void dce_v10_0_crtc_load_lut(struct drm_crtc *crtc)
2139 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); 2139 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
2140 struct drm_device *dev = crtc->dev; 2140 struct drm_device *dev = crtc->dev;
2141 struct amdgpu_device *adev = dev->dev_private; 2141 struct amdgpu_device *adev = dev->dev_private;
2142 u16 *r, *g, *b;
2142 int i; 2143 int i;
2143 u32 tmp; 2144 u32 tmp;
2144 2145
@@ -2176,11 +2177,14 @@ static void dce_v10_0_crtc_load_lut(struct drm_crtc *crtc)
2176 WREG32(mmDC_LUT_WRITE_EN_MASK + amdgpu_crtc->crtc_offset, 0x00000007); 2177 WREG32(mmDC_LUT_WRITE_EN_MASK + amdgpu_crtc->crtc_offset, 0x00000007);
2177 2178
2178 WREG32(mmDC_LUT_RW_INDEX + amdgpu_crtc->crtc_offset, 0); 2179 WREG32(mmDC_LUT_RW_INDEX + amdgpu_crtc->crtc_offset, 0);
2180 r = crtc->gamma_store;
2181 g = r + crtc->gamma_size;
2182 b = g + crtc->gamma_size;
2179 for (i = 0; i < 256; i++) { 2183 for (i = 0; i < 256; i++) {
2180 WREG32(mmDC_LUT_30_COLOR + amdgpu_crtc->crtc_offset, 2184 WREG32(mmDC_LUT_30_COLOR + amdgpu_crtc->crtc_offset,
2181 (amdgpu_crtc->lut_r[i] << 20) | 2185 ((*r++ & 0xffc0) << 14) |
2182 (amdgpu_crtc->lut_g[i] << 10) | 2186 ((*g++ & 0xffc0) << 4) |
2183 (amdgpu_crtc->lut_b[i] << 0)); 2187 (*b++ >> 6));
2184 } 2188 }
2185 2189
2186 tmp = RREG32(mmDEGAMMA_CONTROL + amdgpu_crtc->crtc_offset); 2190 tmp = RREG32(mmDEGAMMA_CONTROL + amdgpu_crtc->crtc_offset);
@@ -2496,15 +2500,6 @@ static int dce_v10_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
2496 u16 *blue, uint32_t size, 2500 u16 *blue, uint32_t size,
2497 struct drm_modeset_acquire_ctx *ctx) 2501 struct drm_modeset_acquire_ctx *ctx)
2498{ 2502{
2499 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
2500 int i;
2501
2502 /* userspace palettes are always correct as is */
2503 for (i = 0; i < size; i++) {
2504 amdgpu_crtc->lut_r[i] = red[i] >> 6;
2505 amdgpu_crtc->lut_g[i] = green[i] >> 6;
2506 amdgpu_crtc->lut_b[i] = blue[i] >> 6;
2507 }
2508 dce_v10_0_crtc_load_lut(crtc); 2503 dce_v10_0_crtc_load_lut(crtc);
2509 2504
2510 return 0; 2505 return 0;
@@ -2716,14 +2711,12 @@ static const struct drm_crtc_helper_funcs dce_v10_0_crtc_helper_funcs = {
2716 .mode_set_base_atomic = dce_v10_0_crtc_set_base_atomic, 2711 .mode_set_base_atomic = dce_v10_0_crtc_set_base_atomic,
2717 .prepare = dce_v10_0_crtc_prepare, 2712 .prepare = dce_v10_0_crtc_prepare,
2718 .commit = dce_v10_0_crtc_commit, 2713 .commit = dce_v10_0_crtc_commit,
2719 .load_lut = dce_v10_0_crtc_load_lut,
2720 .disable = dce_v10_0_crtc_disable, 2714 .disable = dce_v10_0_crtc_disable,
2721}; 2715};
2722 2716
2723static int dce_v10_0_crtc_init(struct amdgpu_device *adev, int index) 2717static int dce_v10_0_crtc_init(struct amdgpu_device *adev, int index)
2724{ 2718{
2725 struct amdgpu_crtc *amdgpu_crtc; 2719 struct amdgpu_crtc *amdgpu_crtc;
2726 int i;
2727 2720
2728 amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) + 2721 amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) +
2729 (AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL); 2722 (AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
@@ -2741,12 +2734,6 @@ static int dce_v10_0_crtc_init(struct amdgpu_device *adev, int index)
2741 adev->ddev->mode_config.cursor_width = amdgpu_crtc->max_cursor_width; 2734 adev->ddev->mode_config.cursor_width = amdgpu_crtc->max_cursor_width;
2742 adev->ddev->mode_config.cursor_height = amdgpu_crtc->max_cursor_height; 2735 adev->ddev->mode_config.cursor_height = amdgpu_crtc->max_cursor_height;
2743 2736
2744 for (i = 0; i < 256; i++) {
2745 amdgpu_crtc->lut_r[i] = i << 2;
2746 amdgpu_crtc->lut_g[i] = i << 2;
2747 amdgpu_crtc->lut_b[i] = i << 2;
2748 }
2749
2750 switch (amdgpu_crtc->crtc_id) { 2737 switch (amdgpu_crtc->crtc_id) {
2751 case 0: 2738 case 0:
2752 default: 2739 default:
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
index 6af489872ffd..921c6f772f11 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
@@ -2178,6 +2178,7 @@ static void dce_v11_0_crtc_load_lut(struct drm_crtc *crtc)
2178 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); 2178 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
2179 struct drm_device *dev = crtc->dev; 2179 struct drm_device *dev = crtc->dev;
2180 struct amdgpu_device *adev = dev->dev_private; 2180 struct amdgpu_device *adev = dev->dev_private;
2181 u16 *r, *g, *b;
2181 int i; 2182 int i;
2182 u32 tmp; 2183 u32 tmp;
2183 2184
@@ -2209,11 +2210,14 @@ static void dce_v11_0_crtc_load_lut(struct drm_crtc *crtc)
2209 WREG32(mmDC_LUT_WRITE_EN_MASK + amdgpu_crtc->crtc_offset, 0x00000007); 2210 WREG32(mmDC_LUT_WRITE_EN_MASK + amdgpu_crtc->crtc_offset, 0x00000007);
2210 2211
2211 WREG32(mmDC_LUT_RW_INDEX + amdgpu_crtc->crtc_offset, 0); 2212 WREG32(mmDC_LUT_RW_INDEX + amdgpu_crtc->crtc_offset, 0);
2213 r = crtc->gamma_store;
2214 g = r + crtc->gamma_size;
2215 b = g + crtc->gamma_size;
2212 for (i = 0; i < 256; i++) { 2216 for (i = 0; i < 256; i++) {
2213 WREG32(mmDC_LUT_30_COLOR + amdgpu_crtc->crtc_offset, 2217 WREG32(mmDC_LUT_30_COLOR + amdgpu_crtc->crtc_offset,
2214 (amdgpu_crtc->lut_r[i] << 20) | 2218 ((*r++ & 0xffc0) << 14) |
2215 (amdgpu_crtc->lut_g[i] << 10) | 2219 ((*g++ & 0xffc0) << 4) |
2216 (amdgpu_crtc->lut_b[i] << 0)); 2220 (*b++ >> 6));
2217 } 2221 }
2218 2222
2219 tmp = RREG32(mmDEGAMMA_CONTROL + amdgpu_crtc->crtc_offset); 2223 tmp = RREG32(mmDEGAMMA_CONTROL + amdgpu_crtc->crtc_offset);
@@ -2571,15 +2575,6 @@ static int dce_v11_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
2571 u16 *blue, uint32_t size, 2575 u16 *blue, uint32_t size,
2572 struct drm_modeset_acquire_ctx *ctx) 2576 struct drm_modeset_acquire_ctx *ctx)
2573{ 2577{
2574 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
2575 int i;
2576
2577 /* userspace palettes are always correct as is */
2578 for (i = 0; i < size; i++) {
2579 amdgpu_crtc->lut_r[i] = red[i] >> 6;
2580 amdgpu_crtc->lut_g[i] = green[i] >> 6;
2581 amdgpu_crtc->lut_b[i] = blue[i] >> 6;
2582 }
2583 dce_v11_0_crtc_load_lut(crtc); 2578 dce_v11_0_crtc_load_lut(crtc);
2584 2579
2585 return 0; 2580 return 0;
@@ -2819,14 +2814,12 @@ static const struct drm_crtc_helper_funcs dce_v11_0_crtc_helper_funcs = {
2819 .mode_set_base_atomic = dce_v11_0_crtc_set_base_atomic, 2814 .mode_set_base_atomic = dce_v11_0_crtc_set_base_atomic,
2820 .prepare = dce_v11_0_crtc_prepare, 2815 .prepare = dce_v11_0_crtc_prepare,
2821 .commit = dce_v11_0_crtc_commit, 2816 .commit = dce_v11_0_crtc_commit,
2822 .load_lut = dce_v11_0_crtc_load_lut,
2823 .disable = dce_v11_0_crtc_disable, 2817 .disable = dce_v11_0_crtc_disable,
2824}; 2818};
2825 2819
2826static int dce_v11_0_crtc_init(struct amdgpu_device *adev, int index) 2820static int dce_v11_0_crtc_init(struct amdgpu_device *adev, int index)
2827{ 2821{
2828 struct amdgpu_crtc *amdgpu_crtc; 2822 struct amdgpu_crtc *amdgpu_crtc;
2829 int i;
2830 2823
2831 amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) + 2824 amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) +
2832 (AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL); 2825 (AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
@@ -2844,12 +2837,6 @@ static int dce_v11_0_crtc_init(struct amdgpu_device *adev, int index)
2844 adev->ddev->mode_config.cursor_width = amdgpu_crtc->max_cursor_width; 2837 adev->ddev->mode_config.cursor_width = amdgpu_crtc->max_cursor_width;
2845 adev->ddev->mode_config.cursor_height = amdgpu_crtc->max_cursor_height; 2838 adev->ddev->mode_config.cursor_height = amdgpu_crtc->max_cursor_height;
2846 2839
2847 for (i = 0; i < 256; i++) {
2848 amdgpu_crtc->lut_r[i] = i << 2;
2849 amdgpu_crtc->lut_g[i] = i << 2;
2850 amdgpu_crtc->lut_b[i] = i << 2;
2851 }
2852
2853 switch (amdgpu_crtc->crtc_id) { 2840 switch (amdgpu_crtc->crtc_id) {
2854 case 0: 2841 case 0:
2855 default: 2842 default:
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
index 126c5e4e7733..bcd9521237f4 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
@@ -2071,6 +2071,7 @@ static void dce_v6_0_crtc_load_lut(struct drm_crtc *crtc)
2071 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); 2071 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
2072 struct drm_device *dev = crtc->dev; 2072 struct drm_device *dev = crtc->dev;
2073 struct amdgpu_device *adev = dev->dev_private; 2073 struct amdgpu_device *adev = dev->dev_private;
2074 u16 *r, *g, *b;
2074 int i; 2075 int i;
2075 2076
2076 DRM_DEBUG_KMS("%d\n", amdgpu_crtc->crtc_id); 2077 DRM_DEBUG_KMS("%d\n", amdgpu_crtc->crtc_id);
@@ -2100,11 +2101,14 @@ static void dce_v6_0_crtc_load_lut(struct drm_crtc *crtc)
2100 WREG32(mmDC_LUT_WRITE_EN_MASK + amdgpu_crtc->crtc_offset, 0x00000007); 2101 WREG32(mmDC_LUT_WRITE_EN_MASK + amdgpu_crtc->crtc_offset, 0x00000007);
2101 2102
2102 WREG32(mmDC_LUT_RW_INDEX + amdgpu_crtc->crtc_offset, 0); 2103 WREG32(mmDC_LUT_RW_INDEX + amdgpu_crtc->crtc_offset, 0);
2104 r = crtc->gamma_store;
2105 g = r + crtc->gamma_size;
2106 b = g + crtc->gamma_size;
2103 for (i = 0; i < 256; i++) { 2107 for (i = 0; i < 256; i++) {
2104 WREG32(mmDC_LUT_30_COLOR + amdgpu_crtc->crtc_offset, 2108 WREG32(mmDC_LUT_30_COLOR + amdgpu_crtc->crtc_offset,
2105 (amdgpu_crtc->lut_r[i] << 20) | 2109 ((*r++ & 0xffc0) << 14) |
2106 (amdgpu_crtc->lut_g[i] << 10) | 2110 ((*g++ & 0xffc0) << 4) |
2107 (amdgpu_crtc->lut_b[i] << 0)); 2111 (*b++ >> 6));
2108 } 2112 }
2109 2113
2110 WREG32(mmDEGAMMA_CONTROL + amdgpu_crtc->crtc_offset, 2114 WREG32(mmDEGAMMA_CONTROL + amdgpu_crtc->crtc_offset,
@@ -2385,15 +2389,6 @@ static int dce_v6_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
2385 u16 *blue, uint32_t size, 2389 u16 *blue, uint32_t size,
2386 struct drm_modeset_acquire_ctx *ctx) 2390 struct drm_modeset_acquire_ctx *ctx)
2387{ 2391{
2388 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
2389 int i;
2390
2391 /* userspace palettes are always correct as is */
2392 for (i = 0; i < size; i++) {
2393 amdgpu_crtc->lut_r[i] = red[i] >> 6;
2394 amdgpu_crtc->lut_g[i] = green[i] >> 6;
2395 amdgpu_crtc->lut_b[i] = blue[i] >> 6;
2396 }
2397 dce_v6_0_crtc_load_lut(crtc); 2392 dce_v6_0_crtc_load_lut(crtc);
2398 2393
2399 return 0; 2394 return 0;
@@ -2601,14 +2596,12 @@ static const struct drm_crtc_helper_funcs dce_v6_0_crtc_helper_funcs = {
2601 .mode_set_base_atomic = dce_v6_0_crtc_set_base_atomic, 2596 .mode_set_base_atomic = dce_v6_0_crtc_set_base_atomic,
2602 .prepare = dce_v6_0_crtc_prepare, 2597 .prepare = dce_v6_0_crtc_prepare,
2603 .commit = dce_v6_0_crtc_commit, 2598 .commit = dce_v6_0_crtc_commit,
2604 .load_lut = dce_v6_0_crtc_load_lut,
2605 .disable = dce_v6_0_crtc_disable, 2599 .disable = dce_v6_0_crtc_disable,
2606}; 2600};
2607 2601
2608static int dce_v6_0_crtc_init(struct amdgpu_device *adev, int index) 2602static int dce_v6_0_crtc_init(struct amdgpu_device *adev, int index)
2609{ 2603{
2610 struct amdgpu_crtc *amdgpu_crtc; 2604 struct amdgpu_crtc *amdgpu_crtc;
2611 int i;
2612 2605
2613 amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) + 2606 amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) +
2614 (AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL); 2607 (AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
@@ -2626,12 +2619,6 @@ static int dce_v6_0_crtc_init(struct amdgpu_device *adev, int index)
2626 adev->ddev->mode_config.cursor_width = amdgpu_crtc->max_cursor_width; 2619 adev->ddev->mode_config.cursor_width = amdgpu_crtc->max_cursor_width;
2627 adev->ddev->mode_config.cursor_height = amdgpu_crtc->max_cursor_height; 2620 adev->ddev->mode_config.cursor_height = amdgpu_crtc->max_cursor_height;
2628 2621
2629 for (i = 0; i < 256; i++) {
2630 amdgpu_crtc->lut_r[i] = i << 2;
2631 amdgpu_crtc->lut_g[i] = i << 2;
2632 amdgpu_crtc->lut_b[i] = i << 2;
2633 }
2634
2635 amdgpu_crtc->crtc_offset = crtc_offsets[amdgpu_crtc->crtc_id]; 2622 amdgpu_crtc->crtc_offset = crtc_offsets[amdgpu_crtc->crtc_id];
2636 2623
2637 amdgpu_crtc->pll_id = ATOM_PPLL_INVALID; 2624 amdgpu_crtc->pll_id = ATOM_PPLL_INVALID;
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
index c0740adee46f..609438fe8584 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
@@ -2049,6 +2049,7 @@ static void dce_v8_0_crtc_load_lut(struct drm_crtc *crtc)
2049 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); 2049 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
2050 struct drm_device *dev = crtc->dev; 2050 struct drm_device *dev = crtc->dev;
2051 struct amdgpu_device *adev = dev->dev_private; 2051 struct amdgpu_device *adev = dev->dev_private;
2052 u16 *r, *g, *b;
2052 int i; 2053 int i;
2053 2054
2054 DRM_DEBUG_KMS("%d\n", amdgpu_crtc->crtc_id); 2055 DRM_DEBUG_KMS("%d\n", amdgpu_crtc->crtc_id);
@@ -2078,11 +2079,14 @@ static void dce_v8_0_crtc_load_lut(struct drm_crtc *crtc)
2078 WREG32(mmDC_LUT_WRITE_EN_MASK + amdgpu_crtc->crtc_offset, 0x00000007); 2079 WREG32(mmDC_LUT_WRITE_EN_MASK + amdgpu_crtc->crtc_offset, 0x00000007);
2079 2080
2080 WREG32(mmDC_LUT_RW_INDEX + amdgpu_crtc->crtc_offset, 0); 2081 WREG32(mmDC_LUT_RW_INDEX + amdgpu_crtc->crtc_offset, 0);
2082 r = crtc->gamma_store;
2083 g = r + crtc->gamma_size;
2084 b = g + crtc->gamma_size;
2081 for (i = 0; i < 256; i++) { 2085 for (i = 0; i < 256; i++) {
2082 WREG32(mmDC_LUT_30_COLOR + amdgpu_crtc->crtc_offset, 2086 WREG32(mmDC_LUT_30_COLOR + amdgpu_crtc->crtc_offset,
2083 (amdgpu_crtc->lut_r[i] << 20) | 2087 ((*r++ & 0xffc0) << 14) |
2084 (amdgpu_crtc->lut_g[i] << 10) | 2088 ((*g++ & 0xffc0) << 4) |
2085 (amdgpu_crtc->lut_b[i] << 0)); 2089 (*b++ >> 6));
2086 } 2090 }
2087 2091
2088 WREG32(mmDEGAMMA_CONTROL + amdgpu_crtc->crtc_offset, 2092 WREG32(mmDEGAMMA_CONTROL + amdgpu_crtc->crtc_offset,
@@ -2400,15 +2404,6 @@ static int dce_v8_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
2400 u16 *blue, uint32_t size, 2404 u16 *blue, uint32_t size,
2401 struct drm_modeset_acquire_ctx *ctx) 2405 struct drm_modeset_acquire_ctx *ctx)
2402{ 2406{
2403 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
2404 int i;
2405
2406 /* userspace palettes are always correct as is */
2407 for (i = 0; i < size; i++) {
2408 amdgpu_crtc->lut_r[i] = red[i] >> 6;
2409 amdgpu_crtc->lut_g[i] = green[i] >> 6;
2410 amdgpu_crtc->lut_b[i] = blue[i] >> 6;
2411 }
2412 dce_v8_0_crtc_load_lut(crtc); 2407 dce_v8_0_crtc_load_lut(crtc);
2413 2408
2414 return 0; 2409 return 0;
@@ -2627,14 +2622,12 @@ static const struct drm_crtc_helper_funcs dce_v8_0_crtc_helper_funcs = {
2627 .mode_set_base_atomic = dce_v8_0_crtc_set_base_atomic, 2622 .mode_set_base_atomic = dce_v8_0_crtc_set_base_atomic,
2628 .prepare = dce_v8_0_crtc_prepare, 2623 .prepare = dce_v8_0_crtc_prepare,
2629 .commit = dce_v8_0_crtc_commit, 2624 .commit = dce_v8_0_crtc_commit,
2630 .load_lut = dce_v8_0_crtc_load_lut,
2631 .disable = dce_v8_0_crtc_disable, 2625 .disable = dce_v8_0_crtc_disable,
2632}; 2626};
2633 2627
2634static int dce_v8_0_crtc_init(struct amdgpu_device *adev, int index) 2628static int dce_v8_0_crtc_init(struct amdgpu_device *adev, int index)
2635{ 2629{
2636 struct amdgpu_crtc *amdgpu_crtc; 2630 struct amdgpu_crtc *amdgpu_crtc;
2637 int i;
2638 2631
2639 amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) + 2632 amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) +
2640 (AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL); 2633 (AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
@@ -2652,12 +2645,6 @@ static int dce_v8_0_crtc_init(struct amdgpu_device *adev, int index)
2652 adev->ddev->mode_config.cursor_width = amdgpu_crtc->max_cursor_width; 2645 adev->ddev->mode_config.cursor_width = amdgpu_crtc->max_cursor_width;
2653 adev->ddev->mode_config.cursor_height = amdgpu_crtc->max_cursor_height; 2646 adev->ddev->mode_config.cursor_height = amdgpu_crtc->max_cursor_height;
2654 2647
2655 for (i = 0; i < 256; i++) {
2656 amdgpu_crtc->lut_r[i] = i << 2;
2657 amdgpu_crtc->lut_g[i] = i << 2;
2658 amdgpu_crtc->lut_b[i] = i << 2;
2659 }
2660
2661 amdgpu_crtc->crtc_offset = crtc_offsets[amdgpu_crtc->crtc_id]; 2648 amdgpu_crtc->crtc_offset = crtc_offsets[amdgpu_crtc->crtc_id];
2662 2649
2663 amdgpu_crtc->pll_id = ATOM_PPLL_INVALID; 2650 amdgpu_crtc->pll_id = ATOM_PPLL_INVALID;
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
index 0d2f060206dc..5ed919e45351 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
@@ -112,16 +112,6 @@ static int dce_virtual_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
112 u16 *green, u16 *blue, uint32_t size, 112 u16 *green, u16 *blue, uint32_t size,
113 struct drm_modeset_acquire_ctx *ctx) 113 struct drm_modeset_acquire_ctx *ctx)
114{ 114{
115 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
116 int i;
117
118 /* userspace palettes are always correct as is */
119 for (i = 0; i < size; i++) {
120 amdgpu_crtc->lut_r[i] = red[i] >> 6;
121 amdgpu_crtc->lut_g[i] = green[i] >> 6;
122 amdgpu_crtc->lut_b[i] = blue[i] >> 6;
123 }
124
125 return 0; 115 return 0;
126} 116}
127 117
@@ -233,11 +223,6 @@ static int dce_virtual_crtc_set_base(struct drm_crtc *crtc, int x, int y,
233 return 0; 223 return 0;
234} 224}
235 225
236static void dce_virtual_crtc_load_lut(struct drm_crtc *crtc)
237{
238 return;
239}
240
241static int dce_virtual_crtc_set_base_atomic(struct drm_crtc *crtc, 226static int dce_virtual_crtc_set_base_atomic(struct drm_crtc *crtc,
242 struct drm_framebuffer *fb, 227 struct drm_framebuffer *fb,
243 int x, int y, enum mode_set_atomic state) 228 int x, int y, enum mode_set_atomic state)
@@ -253,14 +238,12 @@ static const struct drm_crtc_helper_funcs dce_virtual_crtc_helper_funcs = {
253 .mode_set_base_atomic = dce_virtual_crtc_set_base_atomic, 238 .mode_set_base_atomic = dce_virtual_crtc_set_base_atomic,
254 .prepare = dce_virtual_crtc_prepare, 239 .prepare = dce_virtual_crtc_prepare,
255 .commit = dce_virtual_crtc_commit, 240 .commit = dce_virtual_crtc_commit,
256 .load_lut = dce_virtual_crtc_load_lut,
257 .disable = dce_virtual_crtc_disable, 241 .disable = dce_virtual_crtc_disable,
258}; 242};
259 243
260static int dce_virtual_crtc_init(struct amdgpu_device *adev, int index) 244static int dce_virtual_crtc_init(struct amdgpu_device *adev, int index)
261{ 245{
262 struct amdgpu_crtc *amdgpu_crtc; 246 struct amdgpu_crtc *amdgpu_crtc;
263 int i;
264 247
265 amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) + 248 amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) +
266 (AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL); 249 (AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
@@ -273,12 +256,6 @@ static int dce_virtual_crtc_init(struct amdgpu_device *adev, int index)
273 amdgpu_crtc->crtc_id = index; 256 amdgpu_crtc->crtc_id = index;
274 adev->mode_info.crtcs[index] = amdgpu_crtc; 257 adev->mode_info.crtcs[index] = amdgpu_crtc;
275 258
276 for (i = 0; i < 256; i++) {
277 amdgpu_crtc->lut_r[i] = i << 2;
278 amdgpu_crtc->lut_g[i] = i << 2;
279 amdgpu_crtc->lut_b[i] = i << 2;
280 }
281
282 amdgpu_crtc->pll_id = ATOM_PPLL_INVALID; 259 amdgpu_crtc->pll_id = ATOM_PPLL_INVALID;
283 amdgpu_crtc->encoder = NULL; 260 amdgpu_crtc->encoder = NULL;
284 amdgpu_crtc->connector = NULL; 261 amdgpu_crtc->connector = NULL;
diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c
index 55c5d5bd74e1..16903dc7fe0d 100644
--- a/drivers/gpu/drm/arc/arcpgu_crtc.c
+++ b/drivers/gpu/drm/arc/arcpgu_crtc.c
@@ -218,6 +218,7 @@ static struct drm_plane *arc_pgu_plane_init(struct drm_device *drm)
218 218
219 ret = drm_universal_plane_init(drm, plane, 0xff, &arc_pgu_plane_funcs, 219 ret = drm_universal_plane_init(drm, plane, 0xff, &arc_pgu_plane_funcs,
220 formats, ARRAY_SIZE(formats), 220 formats, ARRAY_SIZE(formats),
221 NULL,
221 DRM_PLANE_TYPE_PRIMARY, NULL); 222 DRM_PLANE_TYPE_PRIMARY, NULL);
222 if (ret) 223 if (ret)
223 return ERR_PTR(ret); 224 return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c
index 69d0ef684f7b..e3c13aa202b8 100644
--- a/drivers/gpu/drm/arc/arcpgu_drv.c
+++ b/drivers/gpu/drm/arc/arcpgu_drv.c
@@ -176,8 +176,6 @@ static struct drm_driver arcpgu_drm_driver = {
176 .patchlevel = 0, 176 .patchlevel = 0,
177 .fops = &arcpgu_drm_ops, 177 .fops = &arcpgu_drm_ops,
178 .dumb_create = drm_gem_cma_dumb_create, 178 .dumb_create = drm_gem_cma_dumb_create,
179 .dumb_map_offset = drm_gem_cma_dumb_map_offset,
180 .dumb_destroy = drm_gem_dumb_destroy,
181 .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 179 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
182 .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 180 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
183 .gem_free_object_unlocked = drm_gem_cma_free_object, 181 .gem_free_object_unlocked = drm_gem_cma_free_object,
diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
index 16e1e20cf04c..72b22b805412 100644
--- a/drivers/gpu/drm/arm/hdlcd_crtc.c
+++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
@@ -315,6 +315,7 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm)
315 315
316 ret = drm_universal_plane_init(drm, plane, 0xff, &hdlcd_plane_funcs, 316 ret = drm_universal_plane_init(drm, plane, 0xff, &hdlcd_plane_funcs,
317 formats, ARRAY_SIZE(formats), 317 formats, ARRAY_SIZE(formats),
318 NULL,
318 DRM_PLANE_TYPE_PRIMARY, NULL); 319 DRM_PLANE_TYPE_PRIMARY, NULL);
319 if (ret) { 320 if (ret) {
320 return ERR_PTR(ret); 321 return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index 90bd97bf0013..f9bda7b0d2ec 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -253,8 +253,6 @@ static struct drm_driver hdlcd_driver = {
253 .gem_free_object_unlocked = drm_gem_cma_free_object, 253 .gem_free_object_unlocked = drm_gem_cma_free_object,
254 .gem_vm_ops = &drm_gem_cma_vm_ops, 254 .gem_vm_ops = &drm_gem_cma_vm_ops,
255 .dumb_create = drm_gem_cma_dumb_create, 255 .dumb_create = drm_gem_cma_dumb_create,
256 .dumb_map_offset = drm_gem_cma_dumb_map_offset,
257 .dumb_destroy = drm_gem_dumb_destroy,
258 .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 256 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
259 .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 257 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
260 .gem_prime_export = drm_gem_prime_export, 258 .gem_prime_export = drm_gem_prime_export,
diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index a6a05a768dd1..1a57cc28955e 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -331,8 +331,6 @@ static struct drm_driver malidp_driver = {
331 .gem_free_object_unlocked = drm_gem_cma_free_object, 331 .gem_free_object_unlocked = drm_gem_cma_free_object,
332 .gem_vm_ops = &drm_gem_cma_vm_ops, 332 .gem_vm_ops = &drm_gem_cma_vm_ops,
333 .dumb_create = drm_gem_cma_dumb_create, 333 .dumb_create = drm_gem_cma_dumb_create,
334 .dumb_map_offset = drm_gem_cma_dumb_map_offset,
335 .dumb_destroy = drm_gem_dumb_destroy,
336 .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 334 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
337 .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 335 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
338 .gem_prime_export = drm_gem_prime_export, 336 .gem_prime_export = drm_gem_prime_export,
diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c
index 600fa7bd7f52..94e7e3fa3408 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -128,7 +128,6 @@ static void malidp_plane_atomic_print_state(struct drm_printer *p,
128static const struct drm_plane_funcs malidp_de_plane_funcs = { 128static const struct drm_plane_funcs malidp_de_plane_funcs = {
129 .update_plane = drm_atomic_helper_update_plane, 129 .update_plane = drm_atomic_helper_update_plane,
130 .disable_plane = drm_atomic_helper_disable_plane, 130 .disable_plane = drm_atomic_helper_disable_plane,
131 .set_property = drm_atomic_helper_plane_set_property,
132 .destroy = malidp_de_plane_destroy, 131 .destroy = malidp_de_plane_destroy,
133 .reset = malidp_plane_reset, 132 .reset = malidp_plane_reset,
134 .atomic_duplicate_state = malidp_duplicate_plane_state, 133 .atomic_duplicate_state = malidp_duplicate_plane_state,
@@ -398,7 +397,7 @@ int malidp_de_planes_init(struct drm_device *drm)
398 DRM_PLANE_TYPE_OVERLAY; 397 DRM_PLANE_TYPE_OVERLAY;
399 ret = drm_universal_plane_init(drm, &plane->base, crtcs, 398 ret = drm_universal_plane_init(drm, &plane->base, crtcs,
400 &malidp_de_plane_funcs, formats, 399 &malidp_de_plane_funcs, formats,
401 n, plane_type, NULL); 400 n, NULL, plane_type, NULL);
402 if (ret < 0) 401 if (ret < 0)
403 goto cleanup; 402 goto cleanup;
404 403
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 1ffba91fbaae..2a4d163ac76f 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -334,16 +334,6 @@ static void armada_drm_vblank_off(struct armada_crtc *dcrtc)
334 armada_drm_plane_work_run(dcrtc, dcrtc->crtc.primary); 334 armada_drm_plane_work_run(dcrtc, dcrtc->crtc.primary);
335} 335}
336 336
337void armada_drm_crtc_gamma_set(struct drm_crtc *crtc, u16 r, u16 g, u16 b,
338 int idx)
339{
340}
341
342void armada_drm_crtc_gamma_get(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
343 int idx)
344{
345}
346
347/* The mode_config.mutex will be held for this call */ 337/* The mode_config.mutex will be held for this call */
348static void armada_drm_crtc_dpms(struct drm_crtc *crtc, int dpms) 338static void armada_drm_crtc_dpms(struct drm_crtc *crtc, int dpms)
349{ 339{
@@ -1269,6 +1259,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
1269 &armada_primary_plane_funcs, 1259 &armada_primary_plane_funcs,
1270 armada_primary_formats, 1260 armada_primary_formats,
1271 ARRAY_SIZE(armada_primary_formats), 1261 ARRAY_SIZE(armada_primary_formats),
1262 NULL,
1272 DRM_PLANE_TYPE_PRIMARY, NULL); 1263 DRM_PLANE_TYPE_PRIMARY, NULL);
1273 if (ret) { 1264 if (ret) {
1274 kfree(primary); 1265 kfree(primary);
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index 7e8906d3ae26..bab11f483575 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -102,8 +102,6 @@ struct armada_crtc {
102}; 102};
103#define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc) 103#define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc)
104 104
105void armada_drm_crtc_gamma_set(struct drm_crtc *, u16, u16, u16, int);
106void armada_drm_crtc_gamma_get(struct drm_crtc *, u16 *, u16 *, u16 *, int);
107void armada_drm_crtc_update_regs(struct armada_crtc *, struct armada_regs *); 105void armada_drm_crtc_update_regs(struct armada_crtc *, struct armada_regs *);
108 106
109void armada_drm_crtc_plane_disable(struct armada_crtc *dcrtc, 107void armada_drm_crtc_plane_disable(struct armada_crtc *dcrtc,
diff --git a/drivers/gpu/drm/armada/armada_fbdev.c b/drivers/gpu/drm/armada/armada_fbdev.c
index 5b479b0ed06c..29c7d047b152 100644
--- a/drivers/gpu/drm/armada/armada_fbdev.c
+++ b/drivers/gpu/drm/armada/armada_fbdev.c
@@ -117,8 +117,6 @@ static int armada_fb_probe(struct drm_fb_helper *fbh,
117} 117}
118 118
119static const struct drm_fb_helper_funcs armada_fb_helper_funcs = { 119static const struct drm_fb_helper_funcs armada_fb_helper_funcs = {
120 .gamma_set = armada_drm_crtc_gamma_set,
121 .gamma_get = armada_drm_crtc_gamma_get,
122 .fb_probe = armada_fb_probe, 120 .fb_probe = armada_fb_probe,
123}; 121};
124 122
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index 677b44f3534b..edc44910d79f 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -460,6 +460,7 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
460 &armada_ovl_plane_funcs, 460 &armada_ovl_plane_funcs,
461 armada_ovl_formats, 461 armada_ovl_formats,
462 ARRAY_SIZE(armada_ovl_formats), 462 ARRAY_SIZE(armada_ovl_formats),
463 NULL,
463 DRM_PLANE_TYPE_OVERLAY, NULL); 464 DRM_PLANE_TYPE_OVERLAY, NULL);
464 if (ret) { 465 if (ret) {
465 kfree(dplane); 466 kfree(dplane);
diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index 7ded3b84237f..e6c4cd3dc50e 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -245,7 +245,6 @@ struct ast_connector {
245 245
246struct ast_crtc { 246struct ast_crtc {
247 struct drm_crtc base; 247 struct drm_crtc base;
248 u8 lut_r[256], lut_g[256], lut_b[256];
249 struct drm_gem_object *cursor_bo; 248 struct drm_gem_object *cursor_bo;
250 uint64_t cursor_addr; 249 uint64_t cursor_addr;
251 int cursor_width, cursor_height; 250 int cursor_width, cursor_height;
diff --git a/drivers/gpu/drm/ast/ast_fb.c b/drivers/gpu/drm/ast/ast_fb.c
index 53ca6d099234..9052ebeae8d0 100644
--- a/drivers/gpu/drm/ast/ast_fb.c
+++ b/drivers/gpu/drm/ast/ast_fb.c
@@ -254,27 +254,7 @@ out:
254 return ret; 254 return ret;
255} 255}
256 256
257static void ast_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
258 u16 blue, int regno)
259{
260 struct ast_crtc *ast_crtc = to_ast_crtc(crtc);
261 ast_crtc->lut_r[regno] = red >> 8;
262 ast_crtc->lut_g[regno] = green >> 8;
263 ast_crtc->lut_b[regno] = blue >> 8;
264}
265
266static void ast_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
267 u16 *blue, int regno)
268{
269 struct ast_crtc *ast_crtc = to_ast_crtc(crtc);
270 *red = ast_crtc->lut_r[regno] << 8;
271 *green = ast_crtc->lut_g[regno] << 8;
272 *blue = ast_crtc->lut_b[regno] << 8;
273}
274
275static const struct drm_fb_helper_funcs ast_fb_helper_funcs = { 257static const struct drm_fb_helper_funcs ast_fb_helper_funcs = {
276 .gamma_set = ast_fb_gamma_set,
277 .gamma_get = ast_fb_gamma_get,
278 .fb_probe = astfb_create, 258 .fb_probe = astfb_create,
279}; 259};
280 260
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index 3549a3356afe..43245229f437 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -63,15 +63,18 @@ static inline void ast_load_palette_index(struct ast_private *ast,
63static void ast_crtc_load_lut(struct drm_crtc *crtc) 63static void ast_crtc_load_lut(struct drm_crtc *crtc)
64{ 64{
65 struct ast_private *ast = crtc->dev->dev_private; 65 struct ast_private *ast = crtc->dev->dev_private;
66 struct ast_crtc *ast_crtc = to_ast_crtc(crtc); 66 u16 *r, *g, *b;
67 int i; 67 int i;
68 68
69 if (!crtc->enabled) 69 if (!crtc->enabled)
70 return; 70 return;
71 71
72 r = crtc->gamma_store;
73 g = r + crtc->gamma_size;
74 b = g + crtc->gamma_size;
75
72 for (i = 0; i < 256; i++) 76 for (i = 0; i < 256; i++)
73 ast_load_palette_index(ast, i, ast_crtc->lut_r[i], 77 ast_load_palette_index(ast, i, *r++ >> 8, *g++ >> 8, *b++ >> 8);
74 ast_crtc->lut_g[i], ast_crtc->lut_b[i]);
75} 78}
76 79
77static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mode *mode, 80static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mode *mode,
@@ -649,7 +652,6 @@ static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = {
649 .mode_set = ast_crtc_mode_set, 652 .mode_set = ast_crtc_mode_set,
650 .mode_set_base = ast_crtc_mode_set_base, 653 .mode_set_base = ast_crtc_mode_set_base,
651 .disable = ast_crtc_disable, 654 .disable = ast_crtc_disable,
652 .load_lut = ast_crtc_load_lut,
653 .prepare = ast_crtc_prepare, 655 .prepare = ast_crtc_prepare,
654 .commit = ast_crtc_commit, 656 .commit = ast_crtc_commit,
655 657
@@ -664,15 +666,6 @@ static int ast_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
664 u16 *blue, uint32_t size, 666 u16 *blue, uint32_t size,
665 struct drm_modeset_acquire_ctx *ctx) 667 struct drm_modeset_acquire_ctx *ctx)
666{ 668{
667 struct ast_crtc *ast_crtc = to_ast_crtc(crtc);
668 int i;
669
670 /* userspace palettes are always correct as is */
671 for (i = 0; i < size; i++) {
672 ast_crtc->lut_r[i] = red[i] >> 8;
673 ast_crtc->lut_g[i] = green[i] >> 8;
674 ast_crtc->lut_b[i] = blue[i] >> 8;
675 }
676 ast_crtc_load_lut(crtc); 669 ast_crtc_load_lut(crtc);
677 670
678 return 0; 671 return 0;
@@ -697,7 +690,6 @@ static const struct drm_crtc_funcs ast_crtc_funcs = {
697static int ast_crtc_init(struct drm_device *dev) 690static int ast_crtc_init(struct drm_device *dev)
698{ 691{
699 struct ast_crtc *crtc; 692 struct ast_crtc *crtc;
700 int i;
701 693
702 crtc = kzalloc(sizeof(struct ast_crtc), GFP_KERNEL); 694 crtc = kzalloc(sizeof(struct ast_crtc), GFP_KERNEL);
703 if (!crtc) 695 if (!crtc)
@@ -706,12 +698,6 @@ static int ast_crtc_init(struct drm_device *dev)
706 drm_crtc_init(dev, &crtc->base, &ast_crtc_funcs); 698 drm_crtc_init(dev, &crtc->base, &ast_crtc_funcs);
707 drm_mode_crtc_set_gamma_size(&crtc->base, 256); 699 drm_mode_crtc_set_gamma_size(&crtc->base, 256);
708 drm_crtc_helper_add(&crtc->base, &ast_crtc_helper_funcs); 700 drm_crtc_helper_add(&crtc->base, &ast_crtc_helper_funcs);
709
710 for (i = 0; i < 256; i++) {
711 crtc->lut_r[i] = i;
712 crtc->lut_g[i] = i;
713 crtc->lut_b[i] = i;
714 }
715 return 0; 701 return 0;
716} 702}
717 703
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
index 4fbbeab5c5d4..d73281095fac 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
@@ -431,7 +431,6 @@ static const struct drm_crtc_funcs atmel_hlcdc_crtc_funcs = {
431 .atomic_destroy_state = atmel_hlcdc_crtc_destroy_state, 431 .atomic_destroy_state = atmel_hlcdc_crtc_destroy_state,
432 .enable_vblank = atmel_hlcdc_crtc_enable_vblank, 432 .enable_vblank = atmel_hlcdc_crtc_enable_vblank,
433 .disable_vblank = atmel_hlcdc_crtc_disable_vblank, 433 .disable_vblank = atmel_hlcdc_crtc_disable_vblank,
434 .set_property = drm_atomic_helper_crtc_set_property,
435 .gamma_set = drm_atomic_helper_legacy_gamma_set, 434 .gamma_set = drm_atomic_helper_legacy_gamma_set,
436}; 435};
437 436
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
index 64f54dc7dd68..74d66e11f688 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
@@ -761,8 +761,6 @@ static struct drm_driver atmel_hlcdc_dc_driver = {
761 .gem_prime_vunmap = drm_gem_cma_prime_vunmap, 761 .gem_prime_vunmap = drm_gem_cma_prime_vunmap,
762 .gem_prime_mmap = drm_gem_cma_prime_mmap, 762 .gem_prime_mmap = drm_gem_cma_prime_mmap,
763 .dumb_create = drm_gem_cma_dumb_create, 763 .dumb_create = drm_gem_cma_dumb_create,
764 .dumb_map_offset = drm_gem_cma_dumb_map_offset,
765 .dumb_destroy = drm_gem_dumb_destroy,
766 .fops = &fops, 764 .fops = &fops,
767 .name = "atmel-hlcdc", 765 .name = "atmel-hlcdc",
768 .desc = "Atmel HLCD Controller DRM", 766 .desc = "Atmel HLCD Controller DRM",
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
index b5bd9b005225..703c2d13603f 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
@@ -838,7 +838,7 @@ static void atmel_hlcdc_plane_destroy(struct drm_plane *p)
838 struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p); 838 struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
839 839
840 if (plane->base.fb) 840 if (plane->base.fb)
841 drm_framebuffer_unreference(plane->base.fb); 841 drm_framebuffer_put(plane->base.fb);
842 842
843 drm_plane_cleanup(p); 843 drm_plane_cleanup(p);
844} 844}
@@ -940,7 +940,7 @@ void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane)
940 desc->name); 940 desc->name);
941} 941}
942 942
943static struct drm_plane_helper_funcs atmel_hlcdc_layer_plane_helper_funcs = { 943static const struct drm_plane_helper_funcs atmel_hlcdc_layer_plane_helper_funcs = {
944 .atomic_check = atmel_hlcdc_plane_atomic_check, 944 .atomic_check = atmel_hlcdc_plane_atomic_check,
945 .atomic_update = atmel_hlcdc_plane_atomic_update, 945 .atomic_update = atmel_hlcdc_plane_atomic_update,
946 .atomic_disable = atmel_hlcdc_plane_atomic_disable, 946 .atomic_disable = atmel_hlcdc_plane_atomic_disable,
@@ -987,7 +987,7 @@ static void atmel_hlcdc_plane_reset(struct drm_plane *p)
987 state = drm_plane_state_to_atmel_hlcdc_plane_state(p->state); 987 state = drm_plane_state_to_atmel_hlcdc_plane_state(p->state);
988 988
989 if (state->base.fb) 989 if (state->base.fb)
990 drm_framebuffer_unreference(state->base.fb); 990 drm_framebuffer_put(state->base.fb);
991 991
992 kfree(state); 992 kfree(state);
993 p->state = NULL; 993 p->state = NULL;
@@ -1025,7 +1025,7 @@ atmel_hlcdc_plane_atomic_duplicate_state(struct drm_plane *p)
1025 } 1025 }
1026 1026
1027 if (copy->base.fb) 1027 if (copy->base.fb)
1028 drm_framebuffer_reference(copy->base.fb); 1028 drm_framebuffer_get(copy->base.fb);
1029 1029
1030 return &copy->base; 1030 return &copy->base;
1031} 1031}
@@ -1044,15 +1044,14 @@ static void atmel_hlcdc_plane_atomic_destroy_state(struct drm_plane *p,
1044 } 1044 }
1045 1045
1046 if (s->fb) 1046 if (s->fb)
1047 drm_framebuffer_unreference(s->fb); 1047 drm_framebuffer_put(s->fb);
1048 1048
1049 kfree(state); 1049 kfree(state);
1050} 1050}
1051 1051
1052static struct drm_plane_funcs layer_plane_funcs = { 1052static const struct drm_plane_funcs layer_plane_funcs = {
1053 .update_plane = drm_atomic_helper_update_plane, 1053 .update_plane = drm_atomic_helper_update_plane,
1054 .disable_plane = drm_atomic_helper_disable_plane, 1054 .disable_plane = drm_atomic_helper_disable_plane,
1055 .set_property = drm_atomic_helper_plane_set_property,
1056 .destroy = atmel_hlcdc_plane_destroy, 1055 .destroy = atmel_hlcdc_plane_destroy,
1057 .reset = atmel_hlcdc_plane_reset, 1056 .reset = atmel_hlcdc_plane_reset,
1058 .atomic_duplicate_state = atmel_hlcdc_plane_atomic_duplicate_state, 1057 .atomic_duplicate_state = atmel_hlcdc_plane_atomic_duplicate_state,
@@ -1087,7 +1086,8 @@ static int atmel_hlcdc_plane_create(struct drm_device *dev,
1087 ret = drm_universal_plane_init(dev, &plane->base, 0, 1086 ret = drm_universal_plane_init(dev, &plane->base, 0,
1088 &layer_plane_funcs, 1087 &layer_plane_funcs,
1089 desc->formats->formats, 1088 desc->formats->formats,
1090 desc->formats->nformats, type, NULL); 1089 desc->formats->nformats,
1090 NULL, type, NULL);
1091 if (ret) 1091 if (ret)
1092 return ret; 1092 return ret;
1093 1093
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index ff9792d350c8..682c090fa3ed 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -786,7 +786,6 @@ adv7511_connector_detect(struct drm_connector *connector, bool force)
786} 786}
787 787
788static struct drm_connector_funcs adv7511_connector_funcs = { 788static struct drm_connector_funcs adv7511_connector_funcs = {
789 .dpms = drm_atomic_helper_connector_dpms,
790 .fill_modes = drm_helper_probe_single_connector_modes, 789 .fill_modes = drm_helper_probe_single_connector_modes,
791 .detect = adv7511_connector_detect, 790 .detect = adv7511_connector_detect,
792 .destroy = drm_connector_cleanup, 791 .destroy = drm_connector_cleanup,
diff --git a/drivers/gpu/drm/bridge/analogix-anx78xx.c b/drivers/gpu/drm/bridge/analogix-anx78xx.c
index dc045e0c32fc..9385eb0b1ee4 100644
--- a/drivers/gpu/drm/bridge/analogix-anx78xx.c
+++ b/drivers/gpu/drm/bridge/analogix-anx78xx.c
@@ -1002,7 +1002,6 @@ static enum drm_connector_status anx78xx_detect(struct drm_connector *connector,
1002} 1002}
1003 1003
1004static const struct drm_connector_funcs anx78xx_connector_funcs = { 1004static const struct drm_connector_funcs anx78xx_connector_funcs = {
1005 .dpms = drm_atomic_helper_connector_dpms,
1006 .fill_modes = drm_helper_probe_single_connector_modes, 1005 .fill_modes = drm_helper_probe_single_connector_modes,
1007 .detect = anx78xx_detect, 1006 .detect = anx78xx_detect,
1008 .destroy = drm_connector_cleanup, 1007 .destroy = drm_connector_cleanup,
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 4c758ed51939..5dd3f1cd074a 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1005,7 +1005,6 @@ analogix_dp_detect(struct drm_connector *connector, bool force)
1005} 1005}
1006 1006
1007static const struct drm_connector_funcs analogix_dp_connector_funcs = { 1007static const struct drm_connector_funcs analogix_dp_connector_funcs = {
1008 .dpms = drm_atomic_helper_connector_dpms,
1009 .fill_modes = drm_helper_probe_single_connector_modes, 1008 .fill_modes = drm_helper_probe_single_connector_modes,
1010 .detect = analogix_dp_detect, 1009 .detect = analogix_dp_detect,
1011 .destroy = drm_connector_cleanup, 1010 .destroy = drm_connector_cleanup,
diff --git a/drivers/gpu/drm/bridge/dumb-vga-dac.c b/drivers/gpu/drm/bridge/dumb-vga-dac.c
index 8a52539e618e..de5e7dee7ad6 100644
--- a/drivers/gpu/drm/bridge/dumb-vga-dac.c
+++ b/drivers/gpu/drm/bridge/dumb-vga-dac.c
@@ -92,7 +92,6 @@ dumb_vga_connector_detect(struct drm_connector *connector, bool force)
92} 92}
93 93
94static const struct drm_connector_funcs dumb_vga_con_funcs = { 94static const struct drm_connector_funcs dumb_vga_con_funcs = {
95 .dpms = drm_atomic_helper_connector_dpms,
96 .detect = dumb_vga_connector_detect, 95 .detect = dumb_vga_connector_detect,
97 .fill_modes = drm_helper_probe_single_connector_modes, 96 .fill_modes = drm_helper_probe_single_connector_modes,
98 .destroy = drm_connector_cleanup, 97 .destroy = drm_connector_cleanup,
diff --git a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
index 11f11086a68f..7ccadba7c98c 100644
--- a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
+++ b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
@@ -193,7 +193,6 @@ static enum drm_connector_status ge_b850v3_lvds_detect(
193} 193}
194 194
195static const struct drm_connector_funcs ge_b850v3_lvds_connector_funcs = { 195static const struct drm_connector_funcs ge_b850v3_lvds_connector_funcs = {
196 .dpms = drm_atomic_helper_connector_dpms,
197 .fill_modes = drm_helper_probe_single_connector_modes, 196 .fill_modes = drm_helper_probe_single_connector_modes,
198 .detect = ge_b850v3_lvds_detect, 197 .detect = ge_b850v3_lvds_detect,
199 .destroy = drm_connector_cleanup, 198 .destroy = drm_connector_cleanup,
diff --git a/drivers/gpu/drm/bridge/nxp-ptn3460.c b/drivers/gpu/drm/bridge/nxp-ptn3460.c
index f0b5d0fc8594..d64a3283822a 100644
--- a/drivers/gpu/drm/bridge/nxp-ptn3460.c
+++ b/drivers/gpu/drm/bridge/nxp-ptn3460.c
@@ -238,7 +238,6 @@ static const struct drm_connector_helper_funcs ptn3460_connector_helper_funcs =
238}; 238};
239 239
240static const struct drm_connector_funcs ptn3460_connector_funcs = { 240static const struct drm_connector_funcs ptn3460_connector_funcs = {
241 .dpms = drm_atomic_helper_connector_dpms,
242 .fill_modes = drm_helper_probe_single_connector_modes, 241 .fill_modes = drm_helper_probe_single_connector_modes,
243 .destroy = drm_connector_cleanup, 242 .destroy = drm_connector_cleanup,
244 .reset = drm_atomic_helper_connector_reset, 243 .reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c
index 685c1a480201..e0cca19b4044 100644
--- a/drivers/gpu/drm/bridge/panel.c
+++ b/drivers/gpu/drm/bridge/panel.c
@@ -50,7 +50,6 @@ panel_bridge_connector_helper_funcs = {
50}; 50};
51 51
52static const struct drm_connector_funcs panel_bridge_connector_funcs = { 52static const struct drm_connector_funcs panel_bridge_connector_funcs = {
53 .dpms = drm_atomic_helper_connector_dpms,
54 .reset = drm_atomic_helper_connector_reset, 53 .reset = drm_atomic_helper_connector_reset,
55 .fill_modes = drm_helper_probe_single_connector_modes, 54 .fill_modes = drm_helper_probe_single_connector_modes,
56 .destroy = drm_connector_cleanup, 55 .destroy = drm_connector_cleanup,
@@ -195,3 +194,33 @@ void drm_panel_bridge_remove(struct drm_bridge *bridge)
195 devm_kfree(panel_bridge->panel->dev, bridge); 194 devm_kfree(panel_bridge->panel->dev, bridge);
196} 195}
197EXPORT_SYMBOL(drm_panel_bridge_remove); 196EXPORT_SYMBOL(drm_panel_bridge_remove);
197
198static void devm_drm_panel_bridge_release(struct device *dev, void *res)
199{
200 struct drm_bridge **bridge = res;
201
202 drm_panel_bridge_remove(*bridge);
203}
204
205struct drm_bridge *devm_drm_panel_bridge_add(struct device *dev,
206 struct drm_panel *panel,
207 u32 connector_type)
208{
209 struct drm_bridge **ptr, *bridge;
210
211 ptr = devres_alloc(devm_drm_panel_bridge_release, sizeof(*ptr),
212 GFP_KERNEL);
213 if (!ptr)
214 return ERR_PTR(-ENOMEM);
215
216 bridge = drm_panel_bridge_add(panel, connector_type);
217 if (!IS_ERR(bridge)) {
218 *ptr = bridge;
219 devres_add(dev, ptr);
220 } else {
221 devres_free(ptr);
222 }
223
224 return bridge;
225}
226EXPORT_SYMBOL(devm_drm_panel_bridge_add);
diff --git a/drivers/gpu/drm/bridge/parade-ps8622.c b/drivers/gpu/drm/bridge/parade-ps8622.c
index 4f7725d4a309..81198f5e9afa 100644
--- a/drivers/gpu/drm/bridge/parade-ps8622.c
+++ b/drivers/gpu/drm/bridge/parade-ps8622.c
@@ -476,7 +476,6 @@ static const struct drm_connector_helper_funcs ps8622_connector_helper_funcs = {
476}; 476};
477 477
478static const struct drm_connector_funcs ps8622_connector_funcs = { 478static const struct drm_connector_funcs ps8622_connector_funcs = {
479 .dpms = drm_atomic_helper_connector_dpms,
480 .fill_modes = drm_helper_probe_single_connector_modes, 479 .fill_modes = drm_helper_probe_single_connector_modes,
481 .destroy = drm_connector_cleanup, 480 .destroy = drm_connector_cleanup,
482 .reset = drm_atomic_helper_connector_reset, 481 .reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c
index 9efb7b8fad57..b1ab4ab09532 100644
--- a/drivers/gpu/drm/bridge/sii902x.c
+++ b/drivers/gpu/drm/bridge/sii902x.c
@@ -124,7 +124,6 @@ sii902x_connector_detect(struct drm_connector *connector, bool force)
124} 124}
125 125
126static const struct drm_connector_funcs sii902x_connector_funcs = { 126static const struct drm_connector_funcs sii902x_connector_funcs = {
127 .dpms = drm_atomic_helper_connector_dpms,
128 .detect = sii902x_connector_detect, 127 .detect = sii902x_connector_detect,
129 .fill_modes = drm_helper_probe_single_connector_modes, 128 .fill_modes = drm_helper_probe_single_connector_modes,
130 .destroy = drm_connector_cleanup, 129 .destroy = drm_connector_cleanup,
diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig
index a2fb939c4e13..3cc53b44186e 100644
--- a/drivers/gpu/drm/bridge/synopsys/Kconfig
+++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
@@ -2,6 +2,7 @@ config DRM_DW_HDMI
2 tristate 2 tristate
3 select DRM_KMS_HELPER 3 select DRM_KMS_HELPER
4 select REGMAP_MMIO 4 select REGMAP_MMIO
5 select CEC_CORE if CEC_NOTIFIER
5 6
6config DRM_DW_HDMI_AHB_AUDIO 7config DRM_DW_HDMI_AHB_AUDIO
7 tristate "Synopsys Designware AHB Audio interface" 8 tristate "Synopsys Designware AHB Audio interface"
@@ -23,6 +24,15 @@ config DRM_DW_HDMI_I2S_AUDIO
23 Support the I2S Audio interface which is part of the Synopsys 24 Support the I2S Audio interface which is part of the Synopsys
24 Designware HDMI block. 25 Designware HDMI block.
25 26
27config DRM_DW_HDMI_CEC
28 tristate "Synopsis Designware CEC interface"
29 depends on DRM_DW_HDMI
30 select CEC_CORE
31 select CEC_NOTIFIER
32 help
33 Support the CE interface which is part of the Synopsys
34 Designware HDMI block.
35
26config DRM_DW_MIPI_DSI 36config DRM_DW_MIPI_DSI
27 tristate 37 tristate
28 select DRM_KMS_HELPER 38 select DRM_KMS_HELPER
diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile b/drivers/gpu/drm/bridge/synopsys/Makefile
index 5f57d366cc86..5dad97d920be 100644
--- a/drivers/gpu/drm/bridge/synopsys/Makefile
+++ b/drivers/gpu/drm/bridge/synopsys/Makefile
@@ -3,5 +3,6 @@
3obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o 3obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
4obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o 4obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
5obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o 5obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
6obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
6 7
7obj-$(CONFIG_DRM_DW_MIPI_DSI) += dw-mipi-dsi.o 8obj-$(CONFIG_DRM_DW_MIPI_DSI) += dw-mipi-dsi.o
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
new file mode 100644
index 000000000000..6c323510f128
--- /dev/null
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
@@ -0,0 +1,327 @@
1/*
2 * Designware HDMI CEC driver
3 *
4 * Copyright (C) 2015-2017 Russell King.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/interrupt.h>
11#include <linux/io.h>
12#include <linux/module.h>
13#include <linux/platform_device.h>
14#include <linux/sched.h>
15#include <linux/slab.h>
16
17#include <drm/drm_edid.h>
18
19#include <media/cec.h>
20#include <media/cec-notifier.h>
21
22#include "dw-hdmi-cec.h"
23
24enum {
25 HDMI_IH_CEC_STAT0 = 0x0106,
26 HDMI_IH_MUTE_CEC_STAT0 = 0x0186,
27
28 HDMI_CEC_CTRL = 0x7d00,
29 CEC_CTRL_START = BIT(0),
30 CEC_CTRL_FRAME_TYP = 3 << 1,
31 CEC_CTRL_RETRY = 0 << 1,
32 CEC_CTRL_NORMAL = 1 << 1,
33 CEC_CTRL_IMMED = 2 << 1,
34
35 HDMI_CEC_STAT = 0x7d01,
36 CEC_STAT_DONE = BIT(0),
37 CEC_STAT_EOM = BIT(1),
38 CEC_STAT_NACK = BIT(2),
39 CEC_STAT_ARBLOST = BIT(3),
40 CEC_STAT_ERROR_INIT = BIT(4),
41 CEC_STAT_ERROR_FOLL = BIT(5),
42 CEC_STAT_WAKEUP = BIT(6),
43
44 HDMI_CEC_MASK = 0x7d02,
45 HDMI_CEC_POLARITY = 0x7d03,
46 HDMI_CEC_INT = 0x7d04,
47 HDMI_CEC_ADDR_L = 0x7d05,
48 HDMI_CEC_ADDR_H = 0x7d06,
49 HDMI_CEC_TX_CNT = 0x7d07,
50 HDMI_CEC_RX_CNT = 0x7d08,
51 HDMI_CEC_TX_DATA0 = 0x7d10,
52 HDMI_CEC_RX_DATA0 = 0x7d20,
53 HDMI_CEC_LOCK = 0x7d30,
54 HDMI_CEC_WKUPCTRL = 0x7d31,
55};
56
57struct dw_hdmi_cec {
58 struct dw_hdmi *hdmi;
59 const struct dw_hdmi_cec_ops *ops;
60 u32 addresses;
61 struct cec_adapter *adap;
62 struct cec_msg rx_msg;
63 unsigned int tx_status;
64 bool tx_done;
65 bool rx_done;
66 struct cec_notifier *notify;
67 int irq;
68};
69
70static void dw_hdmi_write(struct dw_hdmi_cec *cec, u8 val, int offset)
71{
72 cec->ops->write(cec->hdmi, val, offset);
73}
74
75static u8 dw_hdmi_read(struct dw_hdmi_cec *cec, int offset)
76{
77 return cec->ops->read(cec->hdmi, offset);
78}
79
80static int dw_hdmi_cec_log_addr(struct cec_adapter *adap, u8 logical_addr)
81{
82 struct dw_hdmi_cec *cec = cec_get_drvdata(adap);
83
84 if (logical_addr == CEC_LOG_ADDR_INVALID)
85 cec->addresses = 0;
86 else
87 cec->addresses |= BIT(logical_addr) | BIT(15);
88
89 dw_hdmi_write(cec, cec->addresses & 255, HDMI_CEC_ADDR_L);
90 dw_hdmi_write(cec, cec->addresses >> 8, HDMI_CEC_ADDR_H);
91
92 return 0;
93}
94
95static int dw_hdmi_cec_transmit(struct cec_adapter *adap, u8 attempts,
96 u32 signal_free_time, struct cec_msg *msg)
97{
98 struct dw_hdmi_cec *cec = cec_get_drvdata(adap);
99 unsigned int i, ctrl;
100
101 switch (signal_free_time) {
102 case CEC_SIGNAL_FREE_TIME_RETRY:
103 ctrl = CEC_CTRL_RETRY;
104 break;
105 case CEC_SIGNAL_FREE_TIME_NEW_INITIATOR:
106 default:
107 ctrl = CEC_CTRL_NORMAL;
108 break;
109 case CEC_SIGNAL_FREE_TIME_NEXT_XFER:
110 ctrl = CEC_CTRL_IMMED;
111 break;
112 }
113
114 for (i = 0; i < msg->len; i++)
115 dw_hdmi_write(cec, msg->msg[i], HDMI_CEC_TX_DATA0 + i);
116
117 dw_hdmi_write(cec, msg->len, HDMI_CEC_TX_CNT);
118 dw_hdmi_write(cec, ctrl | CEC_CTRL_START, HDMI_CEC_CTRL);
119
120 return 0;
121}
122
123static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data)
124{
125 struct cec_adapter *adap = data;
126 struct dw_hdmi_cec *cec = cec_get_drvdata(adap);
127 unsigned int stat = dw_hdmi_read(cec, HDMI_IH_CEC_STAT0);
128 irqreturn_t ret = IRQ_HANDLED;
129
130 if (stat == 0)
131 return IRQ_NONE;
132
133 dw_hdmi_write(cec, stat, HDMI_IH_CEC_STAT0);
134
135 if (stat & CEC_STAT_ERROR_INIT) {
136 cec->tx_status = CEC_TX_STATUS_ERROR;
137 cec->tx_done = true;
138 ret = IRQ_WAKE_THREAD;
139 } else if (stat & CEC_STAT_DONE) {
140 cec->tx_status = CEC_TX_STATUS_OK;
141 cec->tx_done = true;
142 ret = IRQ_WAKE_THREAD;
143 } else if (stat & CEC_STAT_NACK) {
144 cec->tx_status = CEC_TX_STATUS_NACK;
145 cec->tx_done = true;
146 ret = IRQ_WAKE_THREAD;
147 }
148
149 if (stat & CEC_STAT_EOM) {
150 unsigned int len, i;
151
152 len = dw_hdmi_read(cec, HDMI_CEC_RX_CNT);
153 if (len > sizeof(cec->rx_msg.msg))
154 len = sizeof(cec->rx_msg.msg);
155
156 for (i = 0; i < len; i++)
157 cec->rx_msg.msg[i] =
158 dw_hdmi_read(cec, HDMI_CEC_RX_DATA0 + i);
159
160 dw_hdmi_write(cec, 0, HDMI_CEC_LOCK);
161
162 cec->rx_msg.len = len;
163 smp_wmb();
164 cec->rx_done = true;
165
166 ret = IRQ_WAKE_THREAD;
167 }
168
169 return ret;
170}
171
172static irqreturn_t dw_hdmi_cec_thread(int irq, void *data)
173{
174 struct cec_adapter *adap = data;
175 struct dw_hdmi_cec *cec = cec_get_drvdata(adap);
176
177 if (cec->tx_done) {
178 cec->tx_done = false;
179 cec_transmit_attempt_done(adap, cec->tx_status);
180 }
181 if (cec->rx_done) {
182 cec->rx_done = false;
183 smp_rmb();
184 cec_received_msg(adap, &cec->rx_msg);
185 }
186 return IRQ_HANDLED;
187}
188
189static int dw_hdmi_cec_enable(struct cec_adapter *adap, bool enable)
190{
191 struct dw_hdmi_cec *cec = cec_get_drvdata(adap);
192
193 if (!enable) {
194 dw_hdmi_write(cec, ~0, HDMI_CEC_MASK);
195 dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0);
196 dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY);
197
198 cec->ops->disable(cec->hdmi);
199 } else {
200 unsigned int irqs;
201
202 dw_hdmi_write(cec, 0, HDMI_CEC_CTRL);
203 dw_hdmi_write(cec, ~0, HDMI_IH_CEC_STAT0);
204 dw_hdmi_write(cec, 0, HDMI_CEC_LOCK);
205
206 dw_hdmi_cec_log_addr(cec->adap, CEC_LOG_ADDR_INVALID);
207
208 cec->ops->enable(cec->hdmi);
209
210 irqs = CEC_STAT_ERROR_INIT | CEC_STAT_NACK | CEC_STAT_EOM |
211 CEC_STAT_DONE;
212 dw_hdmi_write(cec, irqs, HDMI_CEC_POLARITY);
213 dw_hdmi_write(cec, ~irqs, HDMI_CEC_MASK);
214 dw_hdmi_write(cec, ~irqs, HDMI_IH_MUTE_CEC_STAT0);
215 }
216 return 0;
217}
218
219static const struct cec_adap_ops dw_hdmi_cec_ops = {
220 .adap_enable = dw_hdmi_cec_enable,
221 .adap_log_addr = dw_hdmi_cec_log_addr,
222 .adap_transmit = dw_hdmi_cec_transmit,
223};
224
225static void dw_hdmi_cec_del(void *data)
226{
227 struct dw_hdmi_cec *cec = data;
228
229 cec_delete_adapter(cec->adap);
230}
231
232static int dw_hdmi_cec_probe(struct platform_device *pdev)
233{
234 struct dw_hdmi_cec_data *data = dev_get_platdata(&pdev->dev);
235 struct dw_hdmi_cec *cec;
236 int ret;
237
238 if (!data)
239 return -ENXIO;
240
241 /*
242 * Our device is just a convenience - we want to link to the real
243 * hardware device here, so that userspace can see the association
244 * between the HDMI hardware and its associated CEC chardev.
245 */
246 cec = devm_kzalloc(&pdev->dev, sizeof(*cec), GFP_KERNEL);
247 if (!cec)
248 return -ENOMEM;
249
250 cec->irq = data->irq;
251 cec->ops = data->ops;
252 cec->hdmi = data->hdmi;
253
254 platform_set_drvdata(pdev, cec);
255
256 dw_hdmi_write(cec, 0, HDMI_CEC_TX_CNT);
257 dw_hdmi_write(cec, ~0, HDMI_CEC_MASK);
258 dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0);
259 dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY);
260
261 cec->adap = cec_allocate_adapter(&dw_hdmi_cec_ops, cec, "dw_hdmi",
262 CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT |
263 CEC_CAP_RC | CEC_CAP_PASSTHROUGH,
264 CEC_MAX_LOG_ADDRS);
265 if (IS_ERR(cec->adap))
266 return PTR_ERR(cec->adap);
267
268 /* override the module pointer */
269 cec->adap->owner = THIS_MODULE;
270
271 ret = devm_add_action(&pdev->dev, dw_hdmi_cec_del, cec);
272 if (ret) {
273 cec_delete_adapter(cec->adap);
274 return ret;
275 }
276
277 ret = devm_request_threaded_irq(&pdev->dev, cec->irq,
278 dw_hdmi_cec_hardirq,
279 dw_hdmi_cec_thread, IRQF_SHARED,
280 "dw-hdmi-cec", cec->adap);
281 if (ret < 0)
282 return ret;
283
284 cec->notify = cec_notifier_get(pdev->dev.parent);
285 if (!cec->notify)
286 return -ENOMEM;
287
288 ret = cec_register_adapter(cec->adap, pdev->dev.parent);
289 if (ret < 0) {
290 cec_notifier_put(cec->notify);
291 return ret;
292 }
293
294 /*
295 * CEC documentation says we must not call cec_delete_adapter
296 * after a successful call to cec_register_adapter().
297 */
298 devm_remove_action(&pdev->dev, dw_hdmi_cec_del, cec);
299
300 cec_register_cec_notifier(cec->adap, cec->notify);
301
302 return 0;
303}
304
305static int dw_hdmi_cec_remove(struct platform_device *pdev)
306{
307 struct dw_hdmi_cec *cec = platform_get_drvdata(pdev);
308
309 cec_unregister_adapter(cec->adap);
310 cec_notifier_put(cec->notify);
311
312 return 0;
313}
314
315static struct platform_driver dw_hdmi_cec_driver = {
316 .probe = dw_hdmi_cec_probe,
317 .remove = dw_hdmi_cec_remove,
318 .driver = {
319 .name = "dw-hdmi-cec",
320 },
321};
322module_platform_driver(dw_hdmi_cec_driver);
323
324MODULE_AUTHOR("Russell King <rmk+kernel@armlinux.org.uk>");
325MODULE_DESCRIPTION("Synopsys Designware HDMI CEC driver for i.MX");
326MODULE_LICENSE("GPL");
327MODULE_ALIAS(PLATFORM_MODULE_PREFIX "dw-hdmi-cec");
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
new file mode 100644
index 000000000000..cf4dc121a2c4
--- /dev/null
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
@@ -0,0 +1,19 @@
1#ifndef DW_HDMI_CEC_H
2#define DW_HDMI_CEC_H
3
4struct dw_hdmi;
5
6struct dw_hdmi_cec_ops {
7 void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
8 u8 (*read)(struct dw_hdmi *hdmi, int offset);
9 void (*enable)(struct dw_hdmi *hdmi);
10 void (*disable)(struct dw_hdmi *hdmi);
11};
12
13struct dw_hdmi_cec_data {
14 struct dw_hdmi *hdmi;
15 const struct dw_hdmi_cec_ops *ops;
16 int irq;
17};
18
19#endif
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
index b2cf59f54c88..3b7e5c59a5e9 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
@@ -1,7 +1,8 @@
1/* 1/*
2 * dw-hdmi-i2s-audio.c 2 * dw-hdmi-i2s-audio.c
3 * 3 *
4 * Copyright (c) 2016 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> 4 * Copyright (c) 2017 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
5 * 6 *
6 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 60faf2d2bc6b..bf14214fa464 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -35,8 +35,12 @@
35 35
36#include "dw-hdmi.h" 36#include "dw-hdmi.h"
37#include "dw-hdmi-audio.h" 37#include "dw-hdmi-audio.h"
38#include "dw-hdmi-cec.h"
39
40#include <media/cec-notifier.h>
38 41
39#define DDC_SEGMENT_ADDR 0x30 42#define DDC_SEGMENT_ADDR 0x30
43
40#define HDMI_EDID_LEN 512 44#define HDMI_EDID_LEN 512
41 45
42enum hdmi_datamap { 46enum hdmi_datamap {
@@ -130,6 +134,7 @@ struct dw_hdmi {
130 unsigned int version; 134 unsigned int version;
131 135
132 struct platform_device *audio; 136 struct platform_device *audio;
137 struct platform_device *cec;
133 struct device *dev; 138 struct device *dev;
134 struct clk *isfr_clk; 139 struct clk *isfr_clk;
135 struct clk *iahb_clk; 140 struct clk *iahb_clk;
@@ -163,6 +168,7 @@ struct dw_hdmi {
163 bool bridge_is_on; /* indicates the bridge is on */ 168 bool bridge_is_on; /* indicates the bridge is on */
164 bool rxsense; /* rxsense state */ 169 bool rxsense; /* rxsense state */
165 u8 phy_mask; /* desired phy int mask settings */ 170 u8 phy_mask; /* desired phy int mask settings */
171 u8 mc_clkdis; /* clock disable register */
166 172
167 spinlock_t audio_lock; 173 spinlock_t audio_lock;
168 struct mutex audio_mutex; 174 struct mutex audio_mutex;
@@ -175,6 +181,8 @@ struct dw_hdmi {
175 struct regmap *regm; 181 struct regmap *regm;
176 void (*enable_audio)(struct dw_hdmi *hdmi); 182 void (*enable_audio)(struct dw_hdmi *hdmi);
177 void (*disable_audio)(struct dw_hdmi *hdmi); 183 void (*disable_audio)(struct dw_hdmi *hdmi);
184
185 struct cec_notifier *cec_notifier;
178}; 186};
179 187
180#define HDMI_IH_PHY_STAT0_RX_SENSE \ 188#define HDMI_IH_PHY_STAT0_RX_SENSE \
@@ -546,8 +554,11 @@ EXPORT_SYMBOL_GPL(dw_hdmi_set_sample_rate);
546 554
547static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi, bool enable) 555static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi, bool enable)
548{ 556{
549 hdmi_modb(hdmi, enable ? 0 : HDMI_MC_CLKDIS_AUDCLK_DISABLE, 557 if (enable)
550 HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS); 558 hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE;
559 else
560 hdmi->mc_clkdis |= HDMI_MC_CLKDIS_AUDCLK_DISABLE;
561 hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
551} 562}
552 563
553static void dw_hdmi_ahb_audio_enable(struct dw_hdmi *hdmi) 564static void dw_hdmi_ahb_audio_enable(struct dw_hdmi *hdmi)
@@ -1569,8 +1580,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
1569/* HDMI Initialization Step B.4 */ 1580/* HDMI Initialization Step B.4 */
1570static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi) 1581static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
1571{ 1582{
1572 u8 clkdis;
1573
1574 /* control period minimum duration */ 1583 /* control period minimum duration */
1575 hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR); 1584 hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR);
1576 hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR); 1585 hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR);
@@ -1582,17 +1591,21 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
1582 hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM); 1591 hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM);
1583 1592
1584 /* Enable pixel clock and tmds data path */ 1593 /* Enable pixel clock and tmds data path */
1585 clkdis = 0x7F; 1594 hdmi->mc_clkdis |= HDMI_MC_CLKDIS_HDCPCLK_DISABLE |
1586 clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE; 1595 HDMI_MC_CLKDIS_CSCCLK_DISABLE |
1587 hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); 1596 HDMI_MC_CLKDIS_AUDCLK_DISABLE |
1597 HDMI_MC_CLKDIS_PREPCLK_DISABLE |
1598 HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
1599 hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
1600 hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
1588 1601
1589 clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE; 1602 hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
1590 hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); 1603 hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
1591 1604
1592 /* Enable csc path */ 1605 /* Enable csc path */
1593 if (is_color_space_conversion(hdmi)) { 1606 if (is_color_space_conversion(hdmi)) {
1594 clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE; 1607 hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
1595 hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); 1608 hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
1596 } 1609 }
1597 1610
1598 /* Enable color space conversion if needed */ 1611 /* Enable color space conversion if needed */
@@ -1783,7 +1796,6 @@ static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
1783 hdmi_writeb(hdmi, 0xff, HDMI_AUD_HBR_MASK); 1796 hdmi_writeb(hdmi, 0xff, HDMI_AUD_HBR_MASK);
1784 hdmi_writeb(hdmi, 0xff, HDMI_GP_MASK); 1797 hdmi_writeb(hdmi, 0xff, HDMI_GP_MASK);
1785 hdmi_writeb(hdmi, 0xff, HDMI_A_APIINTMSK); 1798 hdmi_writeb(hdmi, 0xff, HDMI_A_APIINTMSK);
1786 hdmi_writeb(hdmi, 0xff, HDMI_CEC_MASK);
1787 hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT); 1799 hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT);
1788 hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT); 1800 hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT);
1789 1801
@@ -1896,6 +1908,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
1896 hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid); 1908 hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
1897 hdmi->sink_has_audio = drm_detect_monitor_audio(edid); 1909 hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
1898 drm_mode_connector_update_edid_property(connector, edid); 1910 drm_mode_connector_update_edid_property(connector, edid);
1911 cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
1899 ret = drm_add_edid_modes(connector, edid); 1912 ret = drm_add_edid_modes(connector, edid);
1900 /* Store the ELD */ 1913 /* Store the ELD */
1901 drm_edid_to_eld(connector, edid); 1914 drm_edid_to_eld(connector, edid);
@@ -1920,7 +1933,6 @@ static void dw_hdmi_connector_force(struct drm_connector *connector)
1920} 1933}
1921 1934
1922static const struct drm_connector_funcs dw_hdmi_connector_funcs = { 1935static const struct drm_connector_funcs dw_hdmi_connector_funcs = {
1923 .dpms = drm_atomic_helper_connector_dpms,
1924 .fill_modes = drm_helper_probe_single_connector_modes, 1936 .fill_modes = drm_helper_probe_single_connector_modes,
1925 .detect = dw_hdmi_connector_detect, 1937 .detect = dw_hdmi_connector_detect,
1926 .destroy = drm_connector_cleanup, 1938 .destroy = drm_connector_cleanup,
@@ -2119,11 +2131,16 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
2119 * ask the source to re-read the EDID. 2131 * ask the source to re-read the EDID.
2120 */ 2132 */
2121 if (intr_stat & 2133 if (intr_stat &
2122 (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) 2134 (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
2123 __dw_hdmi_setup_rx_sense(hdmi, 2135 __dw_hdmi_setup_rx_sense(hdmi,
2124 phy_stat & HDMI_PHY_HPD, 2136 phy_stat & HDMI_PHY_HPD,
2125 phy_stat & HDMI_PHY_RX_SENSE); 2137 phy_stat & HDMI_PHY_RX_SENSE);
2126 2138
2139 if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
2140 cec_notifier_set_phys_addr(hdmi->cec_notifier,
2141 CEC_PHYS_ADDR_INVALID);
2142 }
2143
2127 if (intr_stat & HDMI_IH_PHY_STAT0_HPD) { 2144 if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
2128 dev_dbg(hdmi->dev, "EVENT=%s\n", 2145 dev_dbg(hdmi->dev, "EVENT=%s\n",
2129 phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout"); 2146 phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
@@ -2170,6 +2187,7 @@ static const struct dw_hdmi_phy_data dw_hdmi_phys[] = {
2170 .name = "DWC HDMI 2.0 TX PHY", 2187 .name = "DWC HDMI 2.0 TX PHY",
2171 .gen = 2, 2188 .gen = 2,
2172 .has_svsret = true, 2189 .has_svsret = true,
2190 .configure = hdmi_phy_configure_dwc_hdmi_3d_tx,
2173 }, { 2191 }, {
2174 .type = DW_HDMI_PHY_VENDOR_PHY, 2192 .type = DW_HDMI_PHY_VENDOR_PHY,
2175 .name = "Vendor PHY", 2193 .name = "Vendor PHY",
@@ -2219,6 +2237,29 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
2219 return -ENODEV; 2237 return -ENODEV;
2220} 2238}
2221 2239
2240static void dw_hdmi_cec_enable(struct dw_hdmi *hdmi)
2241{
2242 mutex_lock(&hdmi->mutex);
2243 hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
2244 hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
2245 mutex_unlock(&hdmi->mutex);
2246}
2247
2248static void dw_hdmi_cec_disable(struct dw_hdmi *hdmi)
2249{
2250 mutex_lock(&hdmi->mutex);
2251 hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
2252 hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
2253 mutex_unlock(&hdmi->mutex);
2254}
2255
2256static const struct dw_hdmi_cec_ops dw_hdmi_cec_ops = {
2257 .write = hdmi_writeb,
2258 .read = hdmi_readb,
2259 .enable = dw_hdmi_cec_enable,
2260 .disable = dw_hdmi_cec_disable,
2261};
2262
2222static const struct regmap_config hdmi_regmap_8bit_config = { 2263static const struct regmap_config hdmi_regmap_8bit_config = {
2223 .reg_bits = 32, 2264 .reg_bits = 32,
2224 .val_bits = 8, 2265 .val_bits = 8,
@@ -2241,6 +2282,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
2241 struct device_node *np = dev->of_node; 2282 struct device_node *np = dev->of_node;
2242 struct platform_device_info pdevinfo; 2283 struct platform_device_info pdevinfo;
2243 struct device_node *ddc_node; 2284 struct device_node *ddc_node;
2285 struct dw_hdmi_cec_data cec;
2244 struct dw_hdmi *hdmi; 2286 struct dw_hdmi *hdmi;
2245 struct resource *iores = NULL; 2287 struct resource *iores = NULL;
2246 int irq; 2288 int irq;
@@ -2261,6 +2303,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
2261 hdmi->disabled = true; 2303 hdmi->disabled = true;
2262 hdmi->rxsense = true; 2304 hdmi->rxsense = true;
2263 hdmi->phy_mask = (u8)~(HDMI_PHY_HPD | HDMI_PHY_RX_SENSE); 2305 hdmi->phy_mask = (u8)~(HDMI_PHY_HPD | HDMI_PHY_RX_SENSE);
2306 hdmi->mc_clkdis = 0x7f;
2264 2307
2265 mutex_init(&hdmi->mutex); 2308 mutex_init(&hdmi->mutex);
2266 mutex_init(&hdmi->audio_mutex); 2309 mutex_init(&hdmi->audio_mutex);
@@ -2376,6 +2419,12 @@ __dw_hdmi_probe(struct platform_device *pdev,
2376 if (ret) 2419 if (ret)
2377 goto err_iahb; 2420 goto err_iahb;
2378 2421
2422 hdmi->cec_notifier = cec_notifier_get(dev);
2423 if (!hdmi->cec_notifier) {
2424 ret = -ENOMEM;
2425 goto err_iahb;
2426 }
2427
2379 /* 2428 /*
2380 * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator 2429 * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
2381 * N and cts values before enabling phy 2430 * N and cts values before enabling phy
@@ -2438,6 +2487,19 @@ __dw_hdmi_probe(struct platform_device *pdev,
2438 hdmi->audio = platform_device_register_full(&pdevinfo); 2487 hdmi->audio = platform_device_register_full(&pdevinfo);
2439 } 2488 }
2440 2489
2490 if (config0 & HDMI_CONFIG0_CEC) {
2491 cec.hdmi = hdmi;
2492 cec.ops = &dw_hdmi_cec_ops;
2493 cec.irq = irq;
2494
2495 pdevinfo.name = "dw-hdmi-cec";
2496 pdevinfo.data = &cec;
2497 pdevinfo.size_data = sizeof(cec);
2498 pdevinfo.dma_mask = 0;
2499
2500 hdmi->cec = platform_device_register_full(&pdevinfo);
2501 }
2502
2441 /* Reset HDMI DDC I2C master controller and mute I2CM interrupts */ 2503 /* Reset HDMI DDC I2C master controller and mute I2CM interrupts */
2442 if (hdmi->i2c) 2504 if (hdmi->i2c)
2443 dw_hdmi_i2c_init(hdmi); 2505 dw_hdmi_i2c_init(hdmi);
@@ -2452,6 +2514,9 @@ err_iahb:
2452 hdmi->ddc = NULL; 2514 hdmi->ddc = NULL;
2453 } 2515 }
2454 2516
2517 if (hdmi->cec_notifier)
2518 cec_notifier_put(hdmi->cec_notifier);
2519
2455 clk_disable_unprepare(hdmi->iahb_clk); 2520 clk_disable_unprepare(hdmi->iahb_clk);
2456err_isfr: 2521err_isfr:
2457 clk_disable_unprepare(hdmi->isfr_clk); 2522 clk_disable_unprepare(hdmi->isfr_clk);
@@ -2465,10 +2530,15 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
2465{ 2530{
2466 if (hdmi->audio && !IS_ERR(hdmi->audio)) 2531 if (hdmi->audio && !IS_ERR(hdmi->audio))
2467 platform_device_unregister(hdmi->audio); 2532 platform_device_unregister(hdmi->audio);
2533 if (!IS_ERR(hdmi->cec))
2534 platform_device_unregister(hdmi->cec);
2468 2535
2469 /* Disable all interrupts */ 2536 /* Disable all interrupts */
2470 hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0); 2537 hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
2471 2538
2539 if (hdmi->cec_notifier)
2540 cec_notifier_put(hdmi->cec_notifier);
2541
2472 clk_disable_unprepare(hdmi->iahb_clk); 2542 clk_disable_unprepare(hdmi->iahb_clk);
2473 clk_disable_unprepare(hdmi->isfr_clk); 2543 clk_disable_unprepare(hdmi->isfr_clk);
2474 2544
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
index c59f87e1483e..9d90eb9c46e5 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
@@ -478,51 +478,6 @@
478#define HDMI_A_PRESETUP 0x501A 478#define HDMI_A_PRESETUP 0x501A
479#define HDMI_A_SRM_BASE 0x5020 479#define HDMI_A_SRM_BASE 0x5020
480 480
481/* CEC Engine Registers */
482#define HDMI_CEC_CTRL 0x7D00
483#define HDMI_CEC_STAT 0x7D01
484#define HDMI_CEC_MASK 0x7D02
485#define HDMI_CEC_POLARITY 0x7D03
486#define HDMI_CEC_INT 0x7D04
487#define HDMI_CEC_ADDR_L 0x7D05
488#define HDMI_CEC_ADDR_H 0x7D06
489#define HDMI_CEC_TX_CNT 0x7D07
490#define HDMI_CEC_RX_CNT 0x7D08
491#define HDMI_CEC_TX_DATA0 0x7D10
492#define HDMI_CEC_TX_DATA1 0x7D11
493#define HDMI_CEC_TX_DATA2 0x7D12
494#define HDMI_CEC_TX_DATA3 0x7D13
495#define HDMI_CEC_TX_DATA4 0x7D14
496#define HDMI_CEC_TX_DATA5 0x7D15
497#define HDMI_CEC_TX_DATA6 0x7D16
498#define HDMI_CEC_TX_DATA7 0x7D17
499#define HDMI_CEC_TX_DATA8 0x7D18
500#define HDMI_CEC_TX_DATA9 0x7D19
501#define HDMI_CEC_TX_DATA10 0x7D1a
502#define HDMI_CEC_TX_DATA11 0x7D1b
503#define HDMI_CEC_TX_DATA12 0x7D1c
504#define HDMI_CEC_TX_DATA13 0x7D1d
505#define HDMI_CEC_TX_DATA14 0x7D1e
506#define HDMI_CEC_TX_DATA15 0x7D1f
507#define HDMI_CEC_RX_DATA0 0x7D20
508#define HDMI_CEC_RX_DATA1 0x7D21
509#define HDMI_CEC_RX_DATA2 0x7D22
510#define HDMI_CEC_RX_DATA3 0x7D23
511#define HDMI_CEC_RX_DATA4 0x7D24
512#define HDMI_CEC_RX_DATA5 0x7D25
513#define HDMI_CEC_RX_DATA6 0x7D26
514#define HDMI_CEC_RX_DATA7 0x7D27
515#define HDMI_CEC_RX_DATA8 0x7D28
516#define HDMI_CEC_RX_DATA9 0x7D29
517#define HDMI_CEC_RX_DATA10 0x7D2a
518#define HDMI_CEC_RX_DATA11 0x7D2b
519#define HDMI_CEC_RX_DATA12 0x7D2c
520#define HDMI_CEC_RX_DATA13 0x7D2d
521#define HDMI_CEC_RX_DATA14 0x7D2e
522#define HDMI_CEC_RX_DATA15 0x7D2f
523#define HDMI_CEC_LOCK 0x7D30
524#define HDMI_CEC_WKUPCTRL 0x7D31
525
526/* I2C Master Registers (E-DDC) */ 481/* I2C Master Registers (E-DDC) */
527#define HDMI_I2CM_SLAVE 0x7E00 482#define HDMI_I2CM_SLAVE 0x7E00
528#define HDMI_I2CM_ADDRESS 0x7E01 483#define HDMI_I2CM_ADDRESS 0x7E01
@@ -555,6 +510,7 @@ enum {
555 510
556/* CONFIG0_ID field values */ 511/* CONFIG0_ID field values */
557 HDMI_CONFIG0_I2S = 0x10, 512 HDMI_CONFIG0_I2S = 0x10,
513 HDMI_CONFIG0_CEC = 0x02,
558 514
559/* CONFIG1_ID field values */ 515/* CONFIG1_ID field values */
560 HDMI_CONFIG1_AHB = 0x01, 516 HDMI_CONFIG1_AHB = 0x01,
diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
index 12a35f9c3adc..503252d6a74d 100644
--- a/drivers/gpu/drm/bridge/tc358767.c
+++ b/drivers/gpu/drm/bridge/tc358767.c
@@ -1160,7 +1160,6 @@ static const struct drm_connector_helper_funcs tc_connector_helper_funcs = {
1160}; 1160};
1161 1161
1162static const struct drm_connector_funcs tc_connector_funcs = { 1162static const struct drm_connector_funcs tc_connector_funcs = {
1163 .dpms = drm_atomic_helper_connector_dpms,
1164 .fill_modes = drm_helper_probe_single_connector_modes, 1163 .fill_modes = drm_helper_probe_single_connector_modes,
1165 .destroy = drm_connector_cleanup, 1164 .destroy = drm_connector_cleanup,
1166 .reset = drm_atomic_helper_connector_reset, 1165 .reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c b/drivers/gpu/drm/bridge/ti-tfp410.c
index 7ea2a15e8807..acb857030951 100644
--- a/drivers/gpu/drm/bridge/ti-tfp410.c
+++ b/drivers/gpu/drm/bridge/ti-tfp410.c
@@ -102,7 +102,6 @@ tfp410_connector_detect(struct drm_connector *connector, bool force)
102} 102}
103 103
104static const struct drm_connector_funcs tfp410_con_funcs = { 104static const struct drm_connector_funcs tfp410_con_funcs = {
105 .dpms = drm_atomic_helper_connector_dpms,
106 .detect = tfp410_connector_detect, 105 .detect = tfp410_connector_detect,
107 .fill_modes = drm_helper_probe_single_connector_modes, 106 .fill_modes = drm_helper_probe_single_connector_modes,
108 .destroy = drm_connector_cleanup, 107 .destroy = drm_connector_cleanup,
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.h b/drivers/gpu/drm/cirrus/cirrus_drv.h
index 8690352d96f7..be2d7e488062 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.h
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.h
@@ -96,7 +96,6 @@
96 96
97struct cirrus_crtc { 97struct cirrus_crtc {
98 struct drm_crtc base; 98 struct drm_crtc base;
99 u8 lut_r[256], lut_g[256], lut_b[256];
100 int last_dpms; 99 int last_dpms;
101 bool enabled; 100 bool enabled;
102}; 101};
@@ -180,13 +179,6 @@ cirrus_bo(struct ttm_buffer_object *bo)
180#define to_cirrus_obj(x) container_of(x, struct cirrus_gem_object, base) 179#define to_cirrus_obj(x) container_of(x, struct cirrus_gem_object, base)
181#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT) 180#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
182 181
183 /* cirrus_mode.c */
184void cirrus_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
185 u16 blue, int regno);
186void cirrus_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
187 u16 *blue, int regno);
188
189
190 /* cirrus_main.c */ 182 /* cirrus_main.c */
191int cirrus_device_init(struct cirrus_device *cdev, 183int cirrus_device_init(struct cirrus_device *cdev,
192 struct drm_device *ddev, 184 struct drm_device *ddev,
diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
index c69586163d92..0f6815f35ad2 100644
--- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c
+++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
@@ -264,8 +264,6 @@ static int cirrus_fbdev_destroy(struct drm_device *dev,
264} 264}
265 265
266static const struct drm_fb_helper_funcs cirrus_fb_helper_funcs = { 266static const struct drm_fb_helper_funcs cirrus_fb_helper_funcs = {
267 .gamma_set = cirrus_crtc_fb_gamma_set,
268 .gamma_get = cirrus_crtc_fb_gamma_get,
269 .fb_probe = cirrusfb_create, 267 .fb_probe = cirrusfb_create,
270}; 268};
271 269
diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
index 53f6f0f84206..a4c4a465b385 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -31,25 +31,6 @@
31 * This file contains setup code for the CRTC. 31 * This file contains setup code for the CRTC.
32 */ 32 */
33 33
34static void cirrus_crtc_load_lut(struct drm_crtc *crtc)
35{
36 struct cirrus_crtc *cirrus_crtc = to_cirrus_crtc(crtc);
37 struct drm_device *dev = crtc->dev;
38 struct cirrus_device *cdev = dev->dev_private;
39 int i;
40
41 if (!crtc->enabled)
42 return;
43
44 for (i = 0; i < CIRRUS_LUT_SIZE; i++) {
45 /* VGA registers */
46 WREG8(PALETTE_INDEX, i);
47 WREG8(PALETTE_DATA, cirrus_crtc->lut_r[i]);
48 WREG8(PALETTE_DATA, cirrus_crtc->lut_g[i]);
49 WREG8(PALETTE_DATA, cirrus_crtc->lut_b[i]);
50 }
51}
52
53/* 34/*
54 * The DRM core requires DPMS functions, but they make little sense in our 35 * The DRM core requires DPMS functions, but they make little sense in our
55 * case and so are just stubs 36 * case and so are just stubs
@@ -330,15 +311,25 @@ static int cirrus_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
330 u16 *blue, uint32_t size, 311 u16 *blue, uint32_t size,
331 struct drm_modeset_acquire_ctx *ctx) 312 struct drm_modeset_acquire_ctx *ctx)
332{ 313{
333 struct cirrus_crtc *cirrus_crtc = to_cirrus_crtc(crtc); 314 struct drm_device *dev = crtc->dev;
315 struct cirrus_device *cdev = dev->dev_private;
316 u16 *r, *g, *b;
334 int i; 317 int i;
335 318
336 for (i = 0; i < size; i++) { 319 if (!crtc->enabled)
337 cirrus_crtc->lut_r[i] = red[i]; 320 return 0;
338 cirrus_crtc->lut_g[i] = green[i]; 321
339 cirrus_crtc->lut_b[i] = blue[i]; 322 r = crtc->gamma_store;
323 g = r + crtc->gamma_size;
324 b = g + crtc->gamma_size;
325
326 for (i = 0; i < CIRRUS_LUT_SIZE; i++) {
327 /* VGA registers */
328 WREG8(PALETTE_INDEX, i);
329 WREG8(PALETTE_DATA, *r++ >> 8);
330 WREG8(PALETTE_DATA, *g++ >> 8);
331 WREG8(PALETTE_DATA, *b++ >> 8);
340 } 332 }
341 cirrus_crtc_load_lut(crtc);
342 333
343 return 0; 334 return 0;
344} 335}
@@ -365,7 +356,6 @@ static const struct drm_crtc_helper_funcs cirrus_helper_funcs = {
365 .mode_set_base = cirrus_crtc_mode_set_base, 356 .mode_set_base = cirrus_crtc_mode_set_base,
366 .prepare = cirrus_crtc_prepare, 357 .prepare = cirrus_crtc_prepare,
367 .commit = cirrus_crtc_commit, 358 .commit = cirrus_crtc_commit,
368 .load_lut = cirrus_crtc_load_lut,
369}; 359};
370 360
371/* CRTC setup */ 361/* CRTC setup */
@@ -373,7 +363,6 @@ static void cirrus_crtc_init(struct drm_device *dev)
373{ 363{
374 struct cirrus_device *cdev = dev->dev_private; 364 struct cirrus_device *cdev = dev->dev_private;
375 struct cirrus_crtc *cirrus_crtc; 365 struct cirrus_crtc *cirrus_crtc;
376 int i;
377 366
378 cirrus_crtc = kzalloc(sizeof(struct cirrus_crtc) + 367 cirrus_crtc = kzalloc(sizeof(struct cirrus_crtc) +
379 (CIRRUSFB_CONN_LIMIT * sizeof(struct drm_connector *)), 368 (CIRRUSFB_CONN_LIMIT * sizeof(struct drm_connector *)),
@@ -387,37 +376,9 @@ static void cirrus_crtc_init(struct drm_device *dev)
387 drm_mode_crtc_set_gamma_size(&cirrus_crtc->base, CIRRUS_LUT_SIZE); 376 drm_mode_crtc_set_gamma_size(&cirrus_crtc->base, CIRRUS_LUT_SIZE);
388 cdev->mode_info.crtc = cirrus_crtc; 377 cdev->mode_info.crtc = cirrus_crtc;
389 378
390 for (i = 0; i < CIRRUS_LUT_SIZE; i++) {
391 cirrus_crtc->lut_r[i] = i;
392 cirrus_crtc->lut_g[i] = i;
393 cirrus_crtc->lut_b[i] = i;
394 }
395
396 drm_crtc_helper_add(&cirrus_crtc->base, &cirrus_helper_funcs); 379 drm_crtc_helper_add(&cirrus_crtc->base, &cirrus_helper_funcs);
397} 380}
398 381
399/** Sets the color ramps on behalf of fbcon */
400void cirrus_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
401 u16 blue, int regno)
402{
403 struct cirrus_crtc *cirrus_crtc = to_cirrus_crtc(crtc);
404
405 cirrus_crtc->lut_r[regno] = red;
406 cirrus_crtc->lut_g[regno] = green;
407 cirrus_crtc->lut_b[regno] = blue;
408}
409
410/** Gets the color ramps on behalf of fbcon */
411void cirrus_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
412 u16 *blue, int regno)
413{
414 struct cirrus_crtc *cirrus_crtc = to_cirrus_crtc(crtc);
415
416 *red = cirrus_crtc->lut_r[regno];
417 *green = cirrus_crtc->lut_g[regno];
418 *blue = cirrus_crtc->lut_b[regno];
419}
420
421static void cirrus_encoder_mode_set(struct drm_encoder *encoder, 382static void cirrus_encoder_mode_set(struct drm_encoder *encoder,
422 struct drm_display_mode *mode, 383 struct drm_display_mode *mode,
423 struct drm_display_mode *adjusted_mode) 384 struct drm_display_mode *adjusted_mode)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 01192dd3ed79..1b755439f591 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -713,7 +713,7 @@ EXPORT_SYMBOL(drm_atomic_get_plane_state);
713 * RETURNS: 713 * RETURNS:
714 * Zero on success, error code on failure 714 * Zero on success, error code on failure
715 */ 715 */
716int drm_atomic_plane_set_property(struct drm_plane *plane, 716static int drm_atomic_plane_set_property(struct drm_plane *plane,
717 struct drm_plane_state *state, struct drm_property *property, 717 struct drm_plane_state *state, struct drm_property *property,
718 uint64_t val) 718 uint64_t val)
719{ 719{
@@ -770,7 +770,6 @@ int drm_atomic_plane_set_property(struct drm_plane *plane,
770 770
771 return 0; 771 return 0;
772} 772}
773EXPORT_SYMBOL(drm_atomic_plane_set_property);
774 773
775/** 774/**
776 * drm_atomic_plane_get_property - get property value from plane state 775 * drm_atomic_plane_get_property - get property value from plane state
@@ -1145,7 +1144,7 @@ EXPORT_SYMBOL(drm_atomic_get_connector_state);
1145 * RETURNS: 1144 * RETURNS:
1146 * Zero on success, error code on failure 1145 * Zero on success, error code on failure
1147 */ 1146 */
1148int drm_atomic_connector_set_property(struct drm_connector *connector, 1147static int drm_atomic_connector_set_property(struct drm_connector *connector,
1149 struct drm_connector_state *state, struct drm_property *property, 1148 struct drm_connector_state *state, struct drm_property *property,
1150 uint64_t val) 1149 uint64_t val)
1151{ 1150{
@@ -1212,7 +1211,6 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
1212 1211
1213 return 0; 1212 return 0;
1214} 1213}
1215EXPORT_SYMBOL(drm_atomic_connector_set_property);
1216 1214
1217static void drm_atomic_connector_print_state(struct drm_printer *p, 1215static void drm_atomic_connector_print_state(struct drm_printer *p,
1218 const struct drm_connector_state *state) 1216 const struct drm_connector_state *state)
@@ -1590,38 +1588,6 @@ drm_atomic_add_affected_planes(struct drm_atomic_state *state,
1590EXPORT_SYMBOL(drm_atomic_add_affected_planes); 1588EXPORT_SYMBOL(drm_atomic_add_affected_planes);
1591 1589
1592/** 1590/**
1593 * drm_atomic_legacy_backoff - locking backoff for legacy ioctls
1594 * @state: atomic state
1595 *
1596 * This function should be used by legacy entry points which don't understand
1597 * -EDEADLK semantics. For simplicity this one will grab all modeset locks after
1598 * the slowpath completed.
1599 */
1600void drm_atomic_legacy_backoff(struct drm_atomic_state *state)
1601{
1602 struct drm_device *dev = state->dev;
1603 int ret;
1604 bool global = false;
1605
1606 if (WARN_ON(dev->mode_config.acquire_ctx == state->acquire_ctx)) {
1607 global = true;
1608
1609 dev->mode_config.acquire_ctx = NULL;
1610 }
1611
1612retry:
1613 drm_modeset_backoff(state->acquire_ctx);
1614
1615 ret = drm_modeset_lock_all_ctx(dev, state->acquire_ctx);
1616 if (ret)
1617 goto retry;
1618
1619 if (global)
1620 dev->mode_config.acquire_ctx = state->acquire_ctx;
1621}
1622EXPORT_SYMBOL(drm_atomic_legacy_backoff);
1623
1624/**
1625 * drm_atomic_check_only - check whether a given config would work 1591 * drm_atomic_check_only - check whether a given config would work
1626 * @state: atomic configuration to check 1592 * @state: atomic configuration to check
1627 * 1593 *
@@ -1864,9 +1830,60 @@ static struct drm_pending_vblank_event *create_vblank_event(
1864 return e; 1830 return e;
1865} 1831}
1866 1832
1867static int atomic_set_prop(struct drm_atomic_state *state, 1833int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state,
1868 struct drm_mode_object *obj, struct drm_property *prop, 1834 struct drm_connector *connector,
1869 uint64_t prop_value) 1835 int mode)
1836{
1837 struct drm_connector *tmp_connector;
1838 struct drm_connector_state *new_conn_state;
1839 struct drm_crtc *crtc;
1840 struct drm_crtc_state *crtc_state;
1841 int i, ret, old_mode = connector->dpms;
1842 bool active = false;
1843
1844 ret = drm_modeset_lock(&state->dev->mode_config.connection_mutex,
1845 state->acquire_ctx);
1846 if (ret)
1847 return ret;
1848
1849 if (mode != DRM_MODE_DPMS_ON)
1850 mode = DRM_MODE_DPMS_OFF;
1851 connector->dpms = mode;
1852
1853 crtc = connector->state->crtc;
1854 if (!crtc)
1855 goto out;
1856 ret = drm_atomic_add_affected_connectors(state, crtc);
1857 if (ret)
1858 goto out;
1859
1860 crtc_state = drm_atomic_get_crtc_state(state, crtc);
1861 if (IS_ERR(crtc_state)) {
1862 ret = PTR_ERR(crtc_state);
1863 goto out;
1864 }
1865
1866 for_each_new_connector_in_state(state, tmp_connector, new_conn_state, i) {
1867 if (new_conn_state->crtc != crtc)
1868 continue;
1869 if (tmp_connector->dpms == DRM_MODE_DPMS_ON) {
1870 active = true;
1871 break;
1872 }
1873 }
1874
1875 crtc_state->active = active;
1876 ret = drm_atomic_commit(state);
1877out:
1878 if (ret != 0)
1879 connector->dpms = old_mode;
1880 return ret;
1881}
1882
1883int drm_atomic_set_property(struct drm_atomic_state *state,
1884 struct drm_mode_object *obj,
1885 struct drm_property *prop,
1886 uint64_t prop_value)
1870{ 1887{
1871 struct drm_mode_object *ref; 1888 struct drm_mode_object *ref;
1872 int ret; 1889 int ret;
@@ -2286,7 +2303,8 @@ retry:
2286 goto out; 2303 goto out;
2287 } 2304 }
2288 2305
2289 ret = atomic_set_prop(state, obj, prop, prop_value); 2306 ret = drm_atomic_set_property(state, obj, prop,
2307 prop_value);
2290 if (ret) { 2308 if (ret) {
2291 drm_mode_object_put(obj); 2309 drm_mode_object_put(obj);
2292 goto out; 2310 goto out;
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 41f9d47d2bf6..1bc32cd74d78 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -921,16 +921,12 @@ drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev,
921 crtc = new_conn_state->crtc; 921 crtc = new_conn_state->crtc;
922 if ((!crtc && old_conn_state->crtc) || 922 if ((!crtc && old_conn_state->crtc) ||
923 (crtc && drm_atomic_crtc_needs_modeset(crtc->state))) { 923 (crtc && drm_atomic_crtc_needs_modeset(crtc->state))) {
924 struct drm_property *dpms_prop =
925 dev->mode_config.dpms_property;
926 int mode = DRM_MODE_DPMS_OFF; 924 int mode = DRM_MODE_DPMS_OFF;
927 925
928 if (crtc && crtc->state->active) 926 if (crtc && crtc->state->active)
929 mode = DRM_MODE_DPMS_ON; 927 mode = DRM_MODE_DPMS_ON;
930 928
931 connector->dpms = mode; 929 connector->dpms = mode;
932 drm_object_property_set_value(&connector->base,
933 dpms_prop, mode);
934 } 930 }
935 } 931 }
936 932
@@ -1270,7 +1266,7 @@ void drm_atomic_helper_wait_for_flip_done(struct drm_device *dev,
1270 struct drm_crtc *crtc; 1266 struct drm_crtc *crtc;
1271 int i; 1267 int i;
1272 1268
1273 for_each_crtc_in_state(old_state, crtc, unused, i) { 1269 for_each_new_crtc_in_state(old_state, crtc, unused, i) {
1274 struct drm_crtc_commit *commit = old_state->crtcs[i].commit; 1270 struct drm_crtc_commit *commit = old_state->crtcs[i].commit;
1275 int ret; 1271 int ret;
1276 1272
@@ -2957,171 +2953,6 @@ out:
2957} 2953}
2958EXPORT_SYMBOL(drm_atomic_helper_resume); 2954EXPORT_SYMBOL(drm_atomic_helper_resume);
2959 2955
2960/**
2961 * drm_atomic_helper_crtc_set_property - helper for crtc properties
2962 * @crtc: DRM crtc
2963 * @property: DRM property
2964 * @val: value of property
2965 *
2966 * Provides a default crtc set_property handler using the atomic driver
2967 * interface.
2968 *
2969 * RETURNS:
2970 * Zero on success, error code on failure
2971 */
2972int
2973drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc,
2974 struct drm_property *property,
2975 uint64_t val)
2976{
2977 struct drm_atomic_state *state;
2978 struct drm_crtc_state *crtc_state;
2979 int ret = 0;
2980
2981 state = drm_atomic_state_alloc(crtc->dev);
2982 if (!state)
2983 return -ENOMEM;
2984
2985 /* ->set_property is always called with all locks held. */
2986 state->acquire_ctx = crtc->dev->mode_config.acquire_ctx;
2987retry:
2988 crtc_state = drm_atomic_get_crtc_state(state, crtc);
2989 if (IS_ERR(crtc_state)) {
2990 ret = PTR_ERR(crtc_state);
2991 goto fail;
2992 }
2993
2994 ret = drm_atomic_crtc_set_property(crtc, crtc_state,
2995 property, val);
2996 if (ret)
2997 goto fail;
2998
2999 ret = drm_atomic_commit(state);
3000fail:
3001 if (ret == -EDEADLK)
3002 goto backoff;
3003
3004 drm_atomic_state_put(state);
3005 return ret;
3006
3007backoff:
3008 drm_atomic_state_clear(state);
3009 drm_atomic_legacy_backoff(state);
3010
3011 goto retry;
3012}
3013EXPORT_SYMBOL(drm_atomic_helper_crtc_set_property);
3014
3015/**
3016 * drm_atomic_helper_plane_set_property - helper for plane properties
3017 * @plane: DRM plane
3018 * @property: DRM property
3019 * @val: value of property
3020 *
3021 * Provides a default plane set_property handler using the atomic driver
3022 * interface.
3023 *
3024 * RETURNS:
3025 * Zero on success, error code on failure
3026 */
3027int
3028drm_atomic_helper_plane_set_property(struct drm_plane *plane,
3029 struct drm_property *property,
3030 uint64_t val)
3031{
3032 struct drm_atomic_state *state;
3033 struct drm_plane_state *plane_state;
3034 int ret = 0;
3035
3036 state = drm_atomic_state_alloc(plane->dev);
3037 if (!state)
3038 return -ENOMEM;
3039
3040 /* ->set_property is always called with all locks held. */
3041 state->acquire_ctx = plane->dev->mode_config.acquire_ctx;
3042retry:
3043 plane_state = drm_atomic_get_plane_state(state, plane);
3044 if (IS_ERR(plane_state)) {
3045 ret = PTR_ERR(plane_state);
3046 goto fail;
3047 }
3048
3049 ret = drm_atomic_plane_set_property(plane, plane_state,
3050 property, val);
3051 if (ret)
3052 goto fail;
3053
3054 ret = drm_atomic_commit(state);
3055fail:
3056 if (ret == -EDEADLK)
3057 goto backoff;
3058
3059 drm_atomic_state_put(state);
3060 return ret;
3061
3062backoff:
3063 drm_atomic_state_clear(state);
3064 drm_atomic_legacy_backoff(state);
3065
3066 goto retry;
3067}
3068EXPORT_SYMBOL(drm_atomic_helper_plane_set_property);
3069
3070/**
3071 * drm_atomic_helper_connector_set_property - helper for connector properties
3072 * @connector: DRM connector
3073 * @property: DRM property
3074 * @val: value of property
3075 *
3076 * Provides a default connector set_property handler using the atomic driver
3077 * interface.
3078 *
3079 * RETURNS:
3080 * Zero on success, error code on failure
3081 */
3082int
3083drm_atomic_helper_connector_set_property(struct drm_connector *connector,
3084 struct drm_property *property,
3085 uint64_t val)
3086{
3087 struct drm_atomic_state *state;
3088 struct drm_connector_state *connector_state;
3089 int ret = 0;
3090
3091 state = drm_atomic_state_alloc(connector->dev);
3092 if (!state)
3093 return -ENOMEM;
3094
3095 /* ->set_property is always called with all locks held. */
3096 state->acquire_ctx = connector->dev->mode_config.acquire_ctx;
3097retry:
3098 connector_state = drm_atomic_get_connector_state(state, connector);
3099 if (IS_ERR(connector_state)) {
3100 ret = PTR_ERR(connector_state);
3101 goto fail;
3102 }
3103
3104 ret = drm_atomic_connector_set_property(connector, connector_state,
3105 property, val);
3106 if (ret)
3107 goto fail;
3108
3109 ret = drm_atomic_commit(state);
3110fail:
3111 if (ret == -EDEADLK)
3112 goto backoff;
3113
3114 drm_atomic_state_put(state);
3115 return ret;
3116
3117backoff:
3118 drm_atomic_state_clear(state);
3119 drm_atomic_legacy_backoff(state);
3120
3121 goto retry;
3122}
3123EXPORT_SYMBOL(drm_atomic_helper_connector_set_property);
3124
3125static int page_flip_common(struct drm_atomic_state *state, 2956static int page_flip_common(struct drm_atomic_state *state,
3126 struct drm_crtc *crtc, 2957 struct drm_crtc *crtc,
3127 struct drm_framebuffer *fb, 2958 struct drm_framebuffer *fb,
@@ -3257,85 +3088,6 @@ fail:
3257EXPORT_SYMBOL(drm_atomic_helper_page_flip_target); 3088EXPORT_SYMBOL(drm_atomic_helper_page_flip_target);
3258 3089
3259/** 3090/**
3260 * drm_atomic_helper_connector_dpms() - connector dpms helper implementation
3261 * @connector: affected connector
3262 * @mode: DPMS mode
3263 *
3264 * This is the main helper function provided by the atomic helper framework for
3265 * implementing the legacy DPMS connector interface. It computes the new desired
3266 * &drm_crtc_state.active state for the corresponding CRTC (if the connector is
3267 * enabled) and updates it.
3268 *
3269 * Returns:
3270 * Returns 0 on success, negative errno numbers on failure.
3271 */
3272int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
3273 int mode)
3274{
3275 struct drm_mode_config *config = &connector->dev->mode_config;
3276 struct drm_atomic_state *state;
3277 struct drm_crtc_state *crtc_state;
3278 struct drm_crtc *crtc;
3279 struct drm_connector *tmp_connector;
3280 struct drm_connector_list_iter conn_iter;
3281 int ret;
3282 bool active = false;
3283 int old_mode = connector->dpms;
3284
3285 if (mode != DRM_MODE_DPMS_ON)
3286 mode = DRM_MODE_DPMS_OFF;
3287
3288 connector->dpms = mode;
3289 crtc = connector->state->crtc;
3290
3291 if (!crtc)
3292 return 0;
3293
3294 state = drm_atomic_state_alloc(connector->dev);
3295 if (!state)
3296 return -ENOMEM;
3297
3298 state->acquire_ctx = crtc->dev->mode_config.acquire_ctx;
3299retry:
3300 crtc_state = drm_atomic_get_crtc_state(state, crtc);
3301 if (IS_ERR(crtc_state)) {
3302 ret = PTR_ERR(crtc_state);
3303 goto fail;
3304 }
3305
3306 WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
3307
3308 drm_connector_list_iter_begin(connector->dev, &conn_iter);
3309 drm_for_each_connector_iter(tmp_connector, &conn_iter) {
3310 if (tmp_connector->state->crtc != crtc)
3311 continue;
3312
3313 if (tmp_connector->dpms == DRM_MODE_DPMS_ON) {
3314 active = true;
3315 break;
3316 }
3317 }
3318 drm_connector_list_iter_end(&conn_iter);
3319 crtc_state->active = active;
3320
3321 ret = drm_atomic_commit(state);
3322fail:
3323 if (ret == -EDEADLK)
3324 goto backoff;
3325 if (ret != 0)
3326 connector->dpms = old_mode;
3327 drm_atomic_state_put(state);
3328 return ret;
3329
3330backoff:
3331 drm_atomic_state_clear(state);
3332 drm_atomic_legacy_backoff(state);
3333
3334 goto retry;
3335}
3336EXPORT_SYMBOL(drm_atomic_helper_connector_dpms);
3337
3338/**
3339 * drm_atomic_helper_best_encoder - Helper for 3091 * drm_atomic_helper_best_encoder - Helper for
3340 * &drm_connector_helper_funcs.best_encoder callback 3092 * &drm_connector_helper_funcs.best_encoder callback
3341 * @connector: Connector control structure 3093 * @connector: Connector control structure
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 8072e6e4c62c..ba9f36cef68c 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -717,9 +717,9 @@ DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
717 * drivers, it remaps to controlling the "ACTIVE" property on the CRTC the 717 * drivers, it remaps to controlling the "ACTIVE" property on the CRTC the
718 * connector is linked to. Drivers should never set this property directly, 718 * connector is linked to. Drivers should never set this property directly,
719 * it is handled by the DRM core by calling the &drm_connector_funcs.dpms 719 * it is handled by the DRM core by calling the &drm_connector_funcs.dpms
720 * callback. Atomic drivers should implement this hook using 720 * callback. For atomic drivers the remapping to the "ACTIVE" property is
721 * drm_atomic_helper_connector_dpms(). This is the only property standard 721 * implemented in the DRM core. This is the only standard connector
722 * connector property that userspace can change. 722 * property that userspace can change.
723 * PATH: 723 * PATH:
724 * Connector path property to identify how this sink is physically 724 * Connector path property to identify how this sink is physically
725 * connected. Used by DP MST. This should be set by calling 725 * connected. Used by DP MST. This should be set by calling
@@ -1225,7 +1225,6 @@ int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
1225 } else if (connector->funcs->set_property) 1225 } else if (connector->funcs->set_property)
1226 ret = connector->funcs->set_property(connector, property, value); 1226 ret = connector->funcs->set_property(connector, property, value);
1227 1227
1228 /* store the property value if successful */
1229 if (!ret) 1228 if (!ret)
1230 drm_object_property_set_value(&connector->base, property, value); 1229 drm_object_property_set_value(&connector->base, property, value);
1231 return ret; 1230 return ret;
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 4afdf7902eda..eab36a460638 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -863,8 +863,7 @@ static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
863 * provided by the driver. 863 * provided by the driver.
864 * 864 *
865 * This function is deprecated. New drivers must implement atomic modeset 865 * This function is deprecated. New drivers must implement atomic modeset
866 * support, for which this function is unsuitable. Instead drivers should use 866 * support, where DPMS is handled in the DRM core.
867 * drm_atomic_helper_connector_dpms().
868 * 867 *
869 * Returns: 868 * Returns:
870 * Always returns 0. 869 * Always returns 0.
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
index d077c5490041..a43582076b20 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -178,6 +178,13 @@ struct drm_minor;
178int drm_atomic_debugfs_init(struct drm_minor *minor); 178int drm_atomic_debugfs_init(struct drm_minor *minor);
179#endif 179#endif
180 180
181int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state,
182 struct drm_connector *connector,
183 int mode);
184int drm_atomic_set_property(struct drm_atomic_state *state,
185 struct drm_mode_object *obj,
186 struct drm_property *prop,
187 uint64_t prop_value);
181int drm_atomic_get_property(struct drm_mode_object *obj, 188int drm_atomic_get_property(struct drm_mode_object *obj,
182 struct drm_property *property, uint64_t *val); 189 struct drm_property *property, uint64_t *val);
183int drm_mode_atomic_ioctl(struct drm_device *dev, 190int drm_mode_atomic_ioctl(struct drm_device *dev,
diff --git a/drivers/gpu/drm/drm_dumb_buffers.c b/drivers/gpu/drm/drm_dumb_buffers.c
index 10307cc16d75..39ac15ce4702 100644
--- a/drivers/gpu/drm/drm_dumb_buffers.c
+++ b/drivers/gpu/drm/drm_dumb_buffers.c
@@ -24,6 +24,7 @@
24 */ 24 */
25 25
26#include <drm/drmP.h> 26#include <drm/drmP.h>
27#include <drm/drm_gem.h>
27 28
28#include "drm_crtc_internal.h" 29#include "drm_crtc_internal.h"
29 30
@@ -42,9 +43,10 @@
42 * create dumb buffers suitable for scanout, which can then be used to create 43 * create dumb buffers suitable for scanout, which can then be used to create
43 * KMS frame buffers. 44 * KMS frame buffers.
44 * 45 *
45 * To support dumb objects drivers must implement the &drm_driver.dumb_create, 46 * To support dumb objects drivers must implement the &drm_driver.dumb_create
46 * &drm_driver.dumb_destroy and &drm_driver.dumb_map_offset operations. See 47 * operation. &drm_driver.dumb_destroy defaults to drm_gem_dumb_destroy() if
47 * there for further details. 48 * not set and &drm_driver.dumb_map_offset defaults to
49 * drm_gem_dumb_map_offset(). See the callbacks for further details.
48 * 50 *
49 * Note that dumb objects may not be used for gpu acceleration, as has been 51 * Note that dumb objects may not be used for gpu acceleration, as has been
50 * attempted on some ARM embedded platforms. Such drivers really must have 52 * attempted on some ARM embedded platforms. Such drivers really must have
@@ -108,11 +110,16 @@ int drm_mode_mmap_dumb_ioctl(struct drm_device *dev,
108{ 110{
109 struct drm_mode_map_dumb *args = data; 111 struct drm_mode_map_dumb *args = data;
110 112
111 /* call driver ioctl to get mmap offset */ 113 if (!dev->driver->dumb_create)
112 if (!dev->driver->dumb_map_offset)
113 return -ENOSYS; 114 return -ENOSYS;
114 115
115 return dev->driver->dumb_map_offset(file_priv, dev, args->handle, &args->offset); 116 if (dev->driver->dumb_map_offset)
117 return dev->driver->dumb_map_offset(file_priv, dev,
118 args->handle,
119 &args->offset);
120 else
121 return drm_gem_dumb_map_offset(file_priv, dev, args->handle,
122 &args->offset);
116} 123}
117 124
118int drm_mode_destroy_dumb_ioctl(struct drm_device *dev, 125int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,
@@ -120,9 +127,12 @@ int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,
120{ 127{
121 struct drm_mode_destroy_dumb *args = data; 128 struct drm_mode_destroy_dumb *args = data;
122 129
123 if (!dev->driver->dumb_destroy) 130 if (!dev->driver->dumb_create)
124 return -ENOSYS; 131 return -ENOSYS;
125 132
126 return dev->driver->dumb_destroy(file_priv, dev, args->handle); 133 if (dev->driver->dumb_destroy)
134 return dev->driver->dumb_destroy(file_priv, dev, args->handle);
135 else
136 return drm_gem_dumb_destroy(file_priv, dev, args->handle);
127} 137}
128 138
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 4b968f5b9c85..1b8f013ffa65 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -1821,17 +1821,6 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
1821 if (ret < 0) 1821 if (ret < 0)
1822 return ret; 1822 return ret;
1823 1823
1824 /*
1825 * Set the fb pointer - usually drm_setup_crtcs does this for hotplug
1826 * events, but at init time drm_setup_crtcs needs to be called before
1827 * the fb is allocated (since we need to figure out the desired size of
1828 * the fb before we can allocate it ...). Hence we need to fix things up
1829 * here again.
1830 */
1831 for (i = 0; i < fb_helper->crtc_count; i++)
1832 if (fb_helper->crtc_info[i].mode_set.num_connectors)
1833 fb_helper->crtc_info[i].mode_set.fb = fb_helper->fb;
1834
1835 return 0; 1824 return 0;
1836} 1825}
1837 1826
@@ -1893,8 +1882,6 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helpe
1893 info->var.xoffset = 0; 1882 info->var.xoffset = 0;
1894 info->var.yoffset = 0; 1883 info->var.yoffset = 0;
1895 info->var.activate = FB_ACTIVATE_NOW; 1884 info->var.activate = FB_ACTIVATE_NOW;
1896 info->var.height = -1;
1897 info->var.width = -1;
1898 1885
1899 switch (fb->format->depth) { 1886 switch (fb->format->depth) {
1900 case 8: 1887 case 8:
@@ -2410,9 +2397,9 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
2410 struct drm_display_mode *mode = modes[i]; 2397 struct drm_display_mode *mode = modes[i];
2411 struct drm_fb_helper_crtc *fb_crtc = crtcs[i]; 2398 struct drm_fb_helper_crtc *fb_crtc = crtcs[i];
2412 struct drm_fb_offset *offset = &offsets[i]; 2399 struct drm_fb_offset *offset = &offsets[i];
2413 struct drm_mode_set *modeset = &fb_crtc->mode_set;
2414 2400
2415 if (mode && fb_crtc) { 2401 if (mode && fb_crtc) {
2402 struct drm_mode_set *modeset = &fb_crtc->mode_set;
2416 struct drm_connector *connector = 2403 struct drm_connector *connector =
2417 fb_helper->connector_info[i]->connector; 2404 fb_helper->connector_info[i]->connector;
2418 2405
@@ -2426,7 +2413,6 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
2426 fb_crtc->desired_mode); 2413 fb_crtc->desired_mode);
2427 drm_connector_get(connector); 2414 drm_connector_get(connector);
2428 modeset->connectors[modeset->num_connectors++] = connector; 2415 modeset->connectors[modeset->num_connectors++] = connector;
2429 modeset->fb = fb_helper->fb;
2430 modeset->x = offset->x; 2416 modeset->x = offset->x;
2431 modeset->y = offset->y; 2417 modeset->y = offset->y;
2432 } 2418 }
@@ -2438,6 +2424,37 @@ out:
2438 kfree(enabled); 2424 kfree(enabled);
2439} 2425}
2440 2426
2427/*
2428 * This is a continuation of drm_setup_crtcs() that sets up anything related
2429 * to the framebuffer. During initialization, drm_setup_crtcs() is called before
2430 * the framebuffer has been allocated (fb_helper->fb and fb_helper->fbdev).
2431 * So, any setup that touches those fields needs to be done here instead of in
2432 * drm_setup_crtcs().
2433 */
2434static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper)
2435{
2436 struct fb_info *info = fb_helper->fbdev;
2437 int i;
2438
2439 for (i = 0; i < fb_helper->crtc_count; i++)
2440 if (fb_helper->crtc_info[i].mode_set.num_connectors)
2441 fb_helper->crtc_info[i].mode_set.fb = fb_helper->fb;
2442
2443 mutex_lock(&fb_helper->dev->mode_config.mutex);
2444 drm_fb_helper_for_each_connector(fb_helper, i) {
2445 struct drm_connector *connector =
2446 fb_helper->connector_info[i]->connector;
2447
2448 /* use first connected connector for the physical dimensions */
2449 if (connector->status == connector_status_connected) {
2450 info->var.width = connector->display_info.width_mm;
2451 info->var.height = connector->display_info.height_mm;
2452 break;
2453 }
2454 }
2455 mutex_unlock(&fb_helper->dev->mode_config.mutex);
2456}
2457
2441/* Note: Drops fb_helper->lock before returning. */ 2458/* Note: Drops fb_helper->lock before returning. */
2442static int 2459static int
2443__drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper, 2460__drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper,
@@ -2463,6 +2480,7 @@ __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper,
2463 2480
2464 return ret; 2481 return ret;
2465 } 2482 }
2483 drm_setup_crtcs_fb(fb_helper);
2466 2484
2467 fb_helper->deferred_setup = false; 2485 fb_helper->deferred_setup = false;
2468 2486
@@ -2591,6 +2609,7 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
2591 DRM_DEBUG_KMS("\n"); 2609 DRM_DEBUG_KMS("\n");
2592 2610
2593 drm_setup_crtcs(fb_helper, fb_helper->fb->width, fb_helper->fb->height); 2611 drm_setup_crtcs(fb_helper, fb_helper->fb->width, fb_helper->fb->height);
2612 drm_setup_crtcs_fb(fb_helper);
2594 mutex_unlock(&fb_helper->lock); 2613 mutex_unlock(&fb_helper->lock);
2595 2614
2596 drm_fb_helper_set_par(fb_helper->fbdev); 2615 drm_fb_helper_set_par(fb_helper->fbdev);
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 5df028a6dd9f..a8d396bed6a4 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -311,6 +311,41 @@ drm_gem_handle_delete(struct drm_file *filp, u32 handle)
311EXPORT_SYMBOL(drm_gem_handle_delete); 311EXPORT_SYMBOL(drm_gem_handle_delete);
312 312
313/** 313/**
314 * drm_gem_dumb_map_offset - return the fake mmap offset for a gem object
315 * @file: drm file-private structure containing the gem object
316 * @dev: corresponding drm_device
317 * @handle: gem object handle
318 * @offset: return location for the fake mmap offset
319 *
320 * This implements the &drm_driver.dumb_map_offset kms driver callback for
321 * drivers which use gem to manage their backing storage.
322 *
323 * Returns:
324 * 0 on success or a negative error code on failure.
325 */
326int drm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
327 u32 handle, u64 *offset)
328{
329 struct drm_gem_object *obj;
330 int ret;
331
332 obj = drm_gem_object_lookup(file, handle);
333 if (!obj)
334 return -ENOENT;
335
336 ret = drm_gem_create_mmap_offset(obj);
337 if (ret)
338 goto out;
339
340 *offset = drm_vma_node_offset_addr(&obj->vma_node);
341out:
342 drm_gem_object_put_unlocked(obj);
343
344 return ret;
345}
346EXPORT_SYMBOL_GPL(drm_gem_dumb_map_offset);
347
348/**
314 * drm_gem_dumb_destroy - dumb fb callback helper for gem based drivers 349 * drm_gem_dumb_destroy - dumb fb callback helper for gem based drivers
315 * @file: drm file-private structure to remove the dumb handle from 350 * @file: drm file-private structure to remove the dumb handle from
316 * @dev: corresponding drm_device 351 * @dev: corresponding drm_device
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index d9862259a2a7..74f6ff5df656 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -337,6 +337,13 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)
337 return -ENOMEM; 337 return -ENOMEM;
338 dev->mode_config.gamma_lut_size_property = prop; 338 dev->mode_config.gamma_lut_size_property = prop;
339 339
340 prop = drm_property_create(dev,
341 DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB,
342 "IN_FORMATS", 0);
343 if (!prop)
344 return -ENOMEM;
345 dev->mode_config.modifiers_property = prop;
346
340 return 0; 347 return 0;
341} 348}
342 349
diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c
index da9a9adbcc98..1055533792f3 100644
--- a/drivers/gpu/drm/drm_mode_object.c
+++ b/drivers/gpu/drm/drm_mode_object.c
@@ -233,6 +233,9 @@ int drm_object_property_set_value(struct drm_mode_object *obj,
233{ 233{
234 int i; 234 int i;
235 235
236 WARN_ON(drm_drv_uses_atomic_modeset(property->dev) &&
237 !(property->flags & DRM_MODE_PROP_IMMUTABLE));
238
236 for (i = 0; i < obj->properties->count; i++) { 239 for (i = 0; i < obj->properties->count; i++) {
237 if (obj->properties->properties[i] == property) { 240 if (obj->properties->properties[i] == property) {
238 obj->properties->values[i] = val; 241 obj->properties->values[i] = val;
@@ -244,24 +247,7 @@ int drm_object_property_set_value(struct drm_mode_object *obj,
244} 247}
245EXPORT_SYMBOL(drm_object_property_set_value); 248EXPORT_SYMBOL(drm_object_property_set_value);
246 249
247/** 250int __drm_object_property_get_value(struct drm_mode_object *obj,
248 * drm_object_property_get_value - retrieve the value of a property
249 * @obj: drm mode object to get property value from
250 * @property: property to retrieve
251 * @val: storage for the property value
252 *
253 * This function retrieves the softare state of the given property for the given
254 * property. Since there is no driver callback to retrieve the current property
255 * value this might be out of sync with the hardware, depending upon the driver
256 * and property.
257 *
258 * Atomic drivers should never call this function directly, the core will read
259 * out property values through the various ->atomic_get_property callbacks.
260 *
261 * Returns:
262 * Zero on success, error code on failure.
263 */
264int drm_object_property_get_value(struct drm_mode_object *obj,
265 struct drm_property *property, uint64_t *val) 251 struct drm_property *property, uint64_t *val)
266{ 252{
267 int i; 253 int i;
@@ -284,6 +270,31 @@ int drm_object_property_get_value(struct drm_mode_object *obj,
284 270
285 return -EINVAL; 271 return -EINVAL;
286} 272}
273
274/**
275 * drm_object_property_get_value - retrieve the value of a property
276 * @obj: drm mode object to get property value from
277 * @property: property to retrieve
278 * @val: storage for the property value
279 *
280 * This function retrieves the softare state of the given property for the given
281 * property. Since there is no driver callback to retrieve the current property
282 * value this might be out of sync with the hardware, depending upon the driver
283 * and property.
284 *
285 * Atomic drivers should never call this function directly, the core will read
286 * out property values through the various ->atomic_get_property callbacks.
287 *
288 * Returns:
289 * Zero on success, error code on failure.
290 */
291int drm_object_property_get_value(struct drm_mode_object *obj,
292 struct drm_property *property, uint64_t *val)
293{
294 WARN_ON(drm_drv_uses_atomic_modeset(property->dev));
295
296 return __drm_object_property_get_value(obj, property, val);
297}
287EXPORT_SYMBOL(drm_object_property_get_value); 298EXPORT_SYMBOL(drm_object_property_get_value);
288 299
289/* helper for getconnector and getproperties ioctls */ 300/* helper for getconnector and getproperties ioctls */
@@ -302,7 +313,7 @@ int drm_mode_object_get_properties(struct drm_mode_object *obj, bool atomic,
302 continue; 313 continue;
303 314
304 if (*arg_count_props > count) { 315 if (*arg_count_props > count) {
305 ret = drm_object_property_get_value(obj, prop, &val); 316 ret = __drm_object_property_get_value(obj, prop, &val);
306 if (ret) 317 if (ret)
307 return ret; 318 return ret;
308 319
@@ -381,6 +392,83 @@ struct drm_property *drm_mode_obj_find_prop_id(struct drm_mode_object *obj,
381 return NULL; 392 return NULL;
382} 393}
383 394
395static int set_property_legacy(struct drm_mode_object *obj,
396 struct drm_property *prop,
397 uint64_t prop_value)
398{
399 struct drm_device *dev = prop->dev;
400 struct drm_mode_object *ref;
401 int ret = -EINVAL;
402
403 if (!drm_property_change_valid_get(prop, prop_value, &ref))
404 return -EINVAL;
405
406 drm_modeset_lock_all(dev);
407 switch (obj->type) {
408 case DRM_MODE_OBJECT_CONNECTOR:
409 ret = drm_mode_connector_set_obj_prop(obj, prop,
410 prop_value);
411 break;
412 case DRM_MODE_OBJECT_CRTC:
413 ret = drm_mode_crtc_set_obj_prop(obj, prop, prop_value);
414 break;
415 case DRM_MODE_OBJECT_PLANE:
416 ret = drm_mode_plane_set_obj_prop(obj_to_plane(obj),
417 prop, prop_value);
418 break;
419 }
420 drm_property_change_valid_put(prop, ref);
421 drm_modeset_unlock_all(dev);
422
423 return ret;
424}
425
426static int set_property_atomic(struct drm_mode_object *obj,
427 struct drm_property *prop,
428 uint64_t prop_value)
429{
430 struct drm_device *dev = prop->dev;
431 struct drm_atomic_state *state;
432 struct drm_modeset_acquire_ctx ctx;
433 int ret;
434
435 drm_modeset_acquire_init(&ctx, 0);
436
437 state = drm_atomic_state_alloc(dev);
438 if (!state)
439 return -ENOMEM;
440 state->acquire_ctx = &ctx;
441retry:
442 if (prop == state->dev->mode_config.dpms_property) {
443 if (obj->type != DRM_MODE_OBJECT_CONNECTOR) {
444 ret = -EINVAL;
445 goto out;
446 }
447
448 ret = drm_atomic_connector_commit_dpms(state,
449 obj_to_connector(obj),
450 prop_value);
451 } else {
452 ret = drm_atomic_set_property(state, obj, prop, prop_value);
453 if (ret)
454 goto out;
455 ret = drm_atomic_commit(state);
456 }
457out:
458 if (ret == -EDEADLK) {
459 drm_atomic_state_clear(state);
460 drm_modeset_backoff(&ctx);
461 goto retry;
462 }
463
464 drm_atomic_state_put(state);
465
466 drm_modeset_drop_locks(&ctx);
467 drm_modeset_acquire_fini(&ctx);
468
469 return ret;
470}
471
384int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data, 472int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
385 struct drm_file *file_priv) 473 struct drm_file *file_priv)
386{ 474{
@@ -388,18 +476,13 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
388 struct drm_mode_object *arg_obj; 476 struct drm_mode_object *arg_obj;
389 struct drm_property *property; 477 struct drm_property *property;
390 int ret = -EINVAL; 478 int ret = -EINVAL;
391 struct drm_mode_object *ref;
392 479
393 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 480 if (!drm_core_check_feature(dev, DRIVER_MODESET))
394 return -EINVAL; 481 return -EINVAL;
395 482
396 drm_modeset_lock_all(dev);
397
398 arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type); 483 arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
399 if (!arg_obj) { 484 if (!arg_obj)
400 ret = -ENOENT; 485 return -ENOENT;
401 goto out;
402 }
403 486
404 if (!arg_obj->properties) 487 if (!arg_obj->properties)
405 goto out_unref; 488 goto out_unref;
@@ -408,28 +491,12 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
408 if (!property) 491 if (!property)
409 goto out_unref; 492 goto out_unref;
410 493
411 if (!drm_property_change_valid_get(property, arg->value, &ref)) 494 if (drm_drv_uses_atomic_modeset(property->dev))
412 goto out_unref; 495 ret = set_property_atomic(arg_obj, property, arg->value);
413 496 else
414 switch (arg_obj->type) { 497 ret = set_property_legacy(arg_obj, property, arg->value);
415 case DRM_MODE_OBJECT_CONNECTOR:
416 ret = drm_mode_connector_set_obj_prop(arg_obj, property,
417 arg->value);
418 break;
419 case DRM_MODE_OBJECT_CRTC:
420 ret = drm_mode_crtc_set_obj_prop(arg_obj, property, arg->value);
421 break;
422 case DRM_MODE_OBJECT_PLANE:
423 ret = drm_mode_plane_set_obj_prop(obj_to_plane(arg_obj),
424 property, arg->value);
425 break;
426 }
427
428 drm_property_change_valid_put(property, ref);
429 498
430out_unref: 499out_unref:
431 drm_mode_object_put(arg_obj); 500 drm_mode_object_put(arg_obj);
432out:
433 drm_modeset_unlock_all(dev);
434 return ret; 501 return ret;
435} 502}
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index d52f0a17a66b..4a3f68a33844 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -1610,7 +1610,7 @@ out:
1610 * drm_mode_is_420_only - if a given videomode can be only supported in YCBCR420 1610 * drm_mode_is_420_only - if a given videomode can be only supported in YCBCR420
1611 * output format 1611 * output format
1612 * 1612 *
1613 * @connector: drm connector under action. 1613 * @display: display under action
1614 * @mode: video mode to be tested. 1614 * @mode: video mode to be tested.
1615 * 1615 *
1616 * Returns: 1616 * Returns:
diff --git a/drivers/gpu/drm/drm_modeset_helper.c b/drivers/gpu/drm/drm_modeset_helper.c
index 2b33825f2f93..9cb1eede0b4d 100644
--- a/drivers/gpu/drm/drm_modeset_helper.c
+++ b/drivers/gpu/drm/drm_modeset_helper.c
@@ -124,6 +124,7 @@ static struct drm_plane *create_primary_plane(struct drm_device *dev)
124 &drm_primary_helper_funcs, 124 &drm_primary_helper_funcs,
125 safe_modeset_formats, 125 safe_modeset_formats,
126 ARRAY_SIZE(safe_modeset_formats), 126 ARRAY_SIZE(safe_modeset_formats),
127 NULL,
127 DRM_PLANE_TYPE_PRIMARY, NULL); 128 DRM_PLANE_TYPE_PRIMARY, NULL);
128 if (ret) { 129 if (ret) {
129 kfree(primary); 130 kfree(primary);
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index 5dc8c4350602..5c14beee52ff 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -62,6 +62,87 @@ static unsigned int drm_num_planes(struct drm_device *dev)
62 return num; 62 return num;
63} 63}
64 64
65static inline u32 *
66formats_ptr(struct drm_format_modifier_blob *blob)
67{
68 return (u32 *)(((char *)blob) + blob->formats_offset);
69}
70
71static inline struct drm_format_modifier *
72modifiers_ptr(struct drm_format_modifier_blob *blob)
73{
74 return (struct drm_format_modifier *)(((char *)blob) + blob->modifiers_offset);
75}
76
77static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane)
78{
79 const struct drm_mode_config *config = &dev->mode_config;
80 struct drm_property_blob *blob;
81 struct drm_format_modifier *mod;
82 size_t blob_size, formats_size, modifiers_size;
83 struct drm_format_modifier_blob *blob_data;
84 unsigned int i, j;
85
86 formats_size = sizeof(__u32) * plane->format_count;
87 if (WARN_ON(!formats_size)) {
88 /* 0 formats are never expected */
89 return 0;
90 }
91
92 modifiers_size =
93 sizeof(struct drm_format_modifier) * plane->modifier_count;
94
95 blob_size = sizeof(struct drm_format_modifier_blob);
96 /* Modifiers offset is a pointer to a struct with a 64 bit field so it
97 * should be naturally aligned to 8B.
98 */
99 BUILD_BUG_ON(sizeof(struct drm_format_modifier_blob) % 8);
100 blob_size += ALIGN(formats_size, 8);
101 blob_size += modifiers_size;
102
103 blob = drm_property_create_blob(dev, blob_size, NULL);
104 if (IS_ERR(blob))
105 return -1;
106
107 blob_data = (struct drm_format_modifier_blob *)blob->data;
108 blob_data->version = FORMAT_BLOB_CURRENT;
109 blob_data->count_formats = plane->format_count;
110 blob_data->formats_offset = sizeof(struct drm_format_modifier_blob);
111 blob_data->count_modifiers = plane->modifier_count;
112
113 blob_data->modifiers_offset =
114 ALIGN(blob_data->formats_offset + formats_size, 8);
115
116 memcpy(formats_ptr(blob_data), plane->format_types, formats_size);
117
118 /* If we can't determine support, just bail */
119 if (!plane->funcs->format_mod_supported)
120 goto done;
121
122 mod = modifiers_ptr(blob_data);
123 for (i = 0; i < plane->modifier_count; i++) {
124 for (j = 0; j < plane->format_count; j++) {
125 if (plane->funcs->format_mod_supported(plane,
126 plane->format_types[j],
127 plane->modifiers[i])) {
128
129 mod->formats |= 1 << j;
130 }
131 }
132
133 mod->modifier = plane->modifiers[i];
134 mod->offset = 0;
135 mod->pad = 0;
136 mod++;
137 }
138
139done:
140 drm_object_attach_property(&plane->base, config->modifiers_property,
141 blob->base.id);
142
143 return 0;
144}
145
65/** 146/**
66 * drm_universal_plane_init - Initialize a new universal plane object 147 * drm_universal_plane_init - Initialize a new universal plane object
67 * @dev: DRM device 148 * @dev: DRM device
@@ -70,6 +151,8 @@ static unsigned int drm_num_planes(struct drm_device *dev)
70 * @funcs: callbacks for the new plane 151 * @funcs: callbacks for the new plane
71 * @formats: array of supported formats (DRM_FORMAT\_\*) 152 * @formats: array of supported formats (DRM_FORMAT\_\*)
72 * @format_count: number of elements in @formats 153 * @format_count: number of elements in @formats
154 * @format_modifiers: array of struct drm_format modifiers terminated by
155 * DRM_FORMAT_MOD_INVALID
73 * @type: type of plane (overlay, primary, cursor) 156 * @type: type of plane (overlay, primary, cursor)
74 * @name: printf style format string for the plane name, or NULL for default name 157 * @name: printf style format string for the plane name, or NULL for default name
75 * 158 *
@@ -82,10 +165,12 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
82 uint32_t possible_crtcs, 165 uint32_t possible_crtcs,
83 const struct drm_plane_funcs *funcs, 166 const struct drm_plane_funcs *funcs,
84 const uint32_t *formats, unsigned int format_count, 167 const uint32_t *formats, unsigned int format_count,
168 const uint64_t *format_modifiers,
85 enum drm_plane_type type, 169 enum drm_plane_type type,
86 const char *name, ...) 170 const char *name, ...)
87{ 171{
88 struct drm_mode_config *config = &dev->mode_config; 172 struct drm_mode_config *config = &dev->mode_config;
173 unsigned int format_modifier_count = 0;
89 int ret; 174 int ret;
90 175
91 ret = drm_mode_object_add(dev, &plane->base, DRM_MODE_OBJECT_PLANE); 176 ret = drm_mode_object_add(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
@@ -105,6 +190,31 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
105 return -ENOMEM; 190 return -ENOMEM;
106 } 191 }
107 192
193 /*
194 * First driver to need more than 64 formats needs to fix this. Each
195 * format is encoded as a bit and the current code only supports a u64.
196 */
197 if (WARN_ON(format_count > 64))
198 return -EINVAL;
199
200 if (format_modifiers) {
201 const uint64_t *temp_modifiers = format_modifiers;
202 while (*temp_modifiers++ != DRM_FORMAT_MOD_INVALID)
203 format_modifier_count++;
204 }
205
206 plane->modifier_count = format_modifier_count;
207 plane->modifiers = kmalloc_array(format_modifier_count,
208 sizeof(format_modifiers[0]),
209 GFP_KERNEL);
210
211 if (format_modifier_count && !plane->modifiers) {
212 DRM_DEBUG_KMS("out of memory when allocating plane\n");
213 kfree(plane->format_types);
214 drm_mode_object_unregister(dev, &plane->base);
215 return -ENOMEM;
216 }
217
108 if (name) { 218 if (name) {
109 va_list ap; 219 va_list ap;
110 220
@@ -117,12 +227,15 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
117 } 227 }
118 if (!plane->name) { 228 if (!plane->name) {
119 kfree(plane->format_types); 229 kfree(plane->format_types);
230 kfree(plane->modifiers);
120 drm_mode_object_unregister(dev, &plane->base); 231 drm_mode_object_unregister(dev, &plane->base);
121 return -ENOMEM; 232 return -ENOMEM;
122 } 233 }
123 234
124 memcpy(plane->format_types, formats, format_count * sizeof(uint32_t)); 235 memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));
125 plane->format_count = format_count; 236 plane->format_count = format_count;
237 memcpy(plane->modifiers, format_modifiers,
238 format_modifier_count * sizeof(format_modifiers[0]));
126 plane->possible_crtcs = possible_crtcs; 239 plane->possible_crtcs = possible_crtcs;
127 plane->type = type; 240 plane->type = type;
128 241
@@ -149,6 +262,9 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
149 drm_object_attach_property(&plane->base, config->prop_src_h, 0); 262 drm_object_attach_property(&plane->base, config->prop_src_h, 0);
150 } 263 }
151 264
265 if (config->allow_fb_modifiers)
266 create_in_format_blob(dev, plane);
267
152 return 0; 268 return 0;
153} 269}
154EXPORT_SYMBOL(drm_universal_plane_init); 270EXPORT_SYMBOL(drm_universal_plane_init);
@@ -205,7 +321,8 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
205 321
206 type = is_primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; 322 type = is_primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
207 return drm_universal_plane_init(dev, plane, possible_crtcs, funcs, 323 return drm_universal_plane_init(dev, plane, possible_crtcs, funcs,
208 formats, format_count, type, NULL); 324 formats, format_count,
325 NULL, type, NULL);
209} 326}
210EXPORT_SYMBOL(drm_plane_init); 327EXPORT_SYMBOL(drm_plane_init);
211 328
@@ -224,6 +341,7 @@ void drm_plane_cleanup(struct drm_plane *plane)
224 drm_modeset_lock_fini(&plane->mutex); 341 drm_modeset_lock_fini(&plane->mutex);
225 342
226 kfree(plane->format_types); 343 kfree(plane->format_types);
344 kfree(plane->modifiers);
227 drm_mode_object_unregister(dev, &plane->base); 345 drm_mode_object_unregister(dev, &plane->base);
228 346
229 BUG_ON(list_empty(&plane->head)); 347 BUG_ON(list_empty(&plane->head));
diff --git a/drivers/gpu/drm/drm_scdc_helper.c b/drivers/gpu/drm/drm_scdc_helper.c
index 3cd96a95736d..7d1b0f011d33 100644
--- a/drivers/gpu/drm/drm_scdc_helper.c
+++ b/drivers/gpu/drm/drm_scdc_helper.c
@@ -194,19 +194,26 @@ EXPORT_SYMBOL(drm_scdc_set_scrambling);
194 * @adapter: I2C adapter for DDC channel 194 * @adapter: I2C adapter for DDC channel
195 * @set: ret or reset the high clock ratio 195 * @set: ret or reset the high clock ratio
196 * 196 *
197 * TMDS clock ratio calculations go like this: 197 *
198 * TMDS character = 10 bit TMDS encoded value 198 * TMDS clock ratio calculations go like this:
199 * TMDS character rate = The rate at which TMDS characters are transmitted(Mcsc) 199 * TMDS character = 10 bit TMDS encoded value
200 * TMDS bit rate = 10x TMDS character rate 200 *
201 * As per the spec: 201 * TMDS character rate = The rate at which TMDS characters are
202 * TMDS clock rate for pixel clock < 340 MHz = 1x the character rate 202 * transmitted (Mcsc)
203 * = 1/10 pixel clock rate 203 *
204 * TMDS clock rate for pixel clock > 340 MHz = 0.25x the character rate 204 * TMDS bit rate = 10x TMDS character rate
205 * = 1/40 pixel clock rate 205 *
206 * 206 * As per the spec:
207 * Writes to the TMDS config register over SCDC channel, and: 207 * TMDS clock rate for pixel clock < 340 MHz = 1x the character
208 * sets TMDS clock ratio to 1/40 when set = 1 208 * rate = 1/10 pixel clock rate
209 * sets TMDS clock ratio to 1/10 when set = 0 209 *
210 * TMDS clock rate for pixel clock > 340 MHz = 0.25x the character
211 * rate = 1/40 pixel clock rate
212 *
213 * Writes to the TMDS config register over SCDC channel, and:
214 * sets TMDS clock ratio to 1/40 when set = 1
215 *
216 * sets TMDS clock ratio to 1/10 when set = 0
210 * 217 *
211 * Returns: 218 * Returns:
212 * True if write is successful, false otherwise. 219 * True if write is successful, false otherwise.
diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c b/drivers/gpu/drm/drm_simple_kms_helper.c
index 39c203ad59db..dc9fd109de14 100644
--- a/drivers/gpu/drm/drm_simple_kms_helper.c
+++ b/drivers/gpu/drm/drm_simple_kms_helper.c
@@ -199,6 +199,7 @@ EXPORT_SYMBOL(drm_simple_display_pipe_attach_bridge);
199 * @funcs: callbacks for the display pipe (optional) 199 * @funcs: callbacks for the display pipe (optional)
200 * @formats: array of supported formats (DRM_FORMAT\_\*) 200 * @formats: array of supported formats (DRM_FORMAT\_\*)
201 * @format_count: number of elements in @formats 201 * @format_count: number of elements in @formats
202 * @format_modifiers: array of formats modifiers
202 * @connector: connector to attach and register (optional) 203 * @connector: connector to attach and register (optional)
203 * 204 *
204 * Sets up a display pipeline which consist of a really simple 205 * Sets up a display pipeline which consist of a really simple
@@ -219,6 +220,7 @@ int drm_simple_display_pipe_init(struct drm_device *dev,
219 struct drm_simple_display_pipe *pipe, 220 struct drm_simple_display_pipe *pipe,
220 const struct drm_simple_display_pipe_funcs *funcs, 221 const struct drm_simple_display_pipe_funcs *funcs,
221 const uint32_t *formats, unsigned int format_count, 222 const uint32_t *formats, unsigned int format_count,
223 const uint64_t *format_modifiers,
222 struct drm_connector *connector) 224 struct drm_connector *connector)
223{ 225{
224 struct drm_encoder *encoder = &pipe->encoder; 226 struct drm_encoder *encoder = &pipe->encoder;
@@ -233,6 +235,7 @@ int drm_simple_display_pipe_init(struct drm_device *dev,
233 ret = drm_universal_plane_init(dev, plane, 0, 235 ret = drm_universal_plane_init(dev, plane, 0,
234 &drm_simple_kms_plane_funcs, 236 &drm_simple_kms_plane_funcs,
235 formats, format_count, 237 formats, format_count,
238 format_modifiers,
236 DRM_PLANE_TYPE_PRIMARY, NULL); 239 DRM_PLANE_TYPE_PRIMARY, NULL);
237 if (ret) 240 if (ret)
238 return ret; 241 return ret;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
index 63abcd280fa0..76d80e5de521 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
@@ -59,7 +59,6 @@ static void exynos_dpi_connector_destroy(struct drm_connector *connector)
59} 59}
60 60
61static const struct drm_connector_funcs exynos_dpi_connector_funcs = { 61static const struct drm_connector_funcs exynos_dpi_connector_funcs = {
62 .dpms = drm_atomic_helper_connector_dpms,
63 .detect = exynos_dpi_detect, 62 .detect = exynos_dpi_detect,
64 .fill_modes = drm_helper_probe_single_connector_modes, 63 .fill_modes = drm_helper_probe_single_connector_modes,
65 .destroy = exynos_dpi_connector_destroy, 64 .destroy = exynos_dpi_connector_destroy,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index f580be170089..4ea7cc7cb3de 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1537,7 +1537,6 @@ static void exynos_dsi_connector_destroy(struct drm_connector *connector)
1537} 1537}
1538 1538
1539static const struct drm_connector_funcs exynos_dsi_connector_funcs = { 1539static const struct drm_connector_funcs exynos_dsi_connector_funcs = {
1540 .dpms = drm_atomic_helper_connector_dpms,
1541 .detect = exynos_dsi_detect, 1540 .detect = exynos_dsi_detect,
1542 .fill_modes = drm_helper_probe_single_connector_modes, 1541 .fill_modes = drm_helper_probe_single_connector_modes,
1543 .destroy = exynos_dsi_connector_destroy, 1542 .destroy = exynos_dsi_connector_destroy,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index 611b6fd65433..8de74009dee4 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -173,7 +173,6 @@ static struct drm_plane_funcs exynos_plane_funcs = {
173 .update_plane = drm_atomic_helper_update_plane, 173 .update_plane = drm_atomic_helper_update_plane,
174 .disable_plane = drm_atomic_helper_disable_plane, 174 .disable_plane = drm_atomic_helper_disable_plane,
175 .destroy = drm_plane_cleanup, 175 .destroy = drm_plane_cleanup,
176 .set_property = drm_atomic_helper_plane_set_property,
177 .reset = exynos_drm_plane_reset, 176 .reset = exynos_drm_plane_reset,
178 .atomic_duplicate_state = exynos_drm_plane_duplicate_state, 177 .atomic_duplicate_state = exynos_drm_plane_duplicate_state,
179 .atomic_destroy_state = exynos_drm_plane_destroy_state, 178 .atomic_destroy_state = exynos_drm_plane_destroy_state,
@@ -283,7 +282,7 @@ int exynos_plane_init(struct drm_device *dev,
283 &exynos_plane_funcs, 282 &exynos_plane_funcs,
284 config->pixel_formats, 283 config->pixel_formats,
285 config->num_pixel_formats, 284 config->num_pixel_formats,
286 config->type, NULL); 285 NULL, config->type, NULL);
287 if (err) { 286 if (err) {
288 DRM_ERROR("failed to initialize plane\n"); 287 DRM_ERROR("failed to initialize plane\n");
289 return err; 288 return err;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index cb8a72842537..9186a654c3b5 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -289,7 +289,6 @@ static void vidi_connector_destroy(struct drm_connector *connector)
289} 289}
290 290
291static const struct drm_connector_funcs vidi_connector_funcs = { 291static const struct drm_connector_funcs vidi_connector_funcs = {
292 .dpms = drm_atomic_helper_connector_dpms,
293 .fill_modes = drm_helper_probe_single_connector_modes, 292 .fill_modes = drm_helper_probe_single_connector_modes,
294 .detect = vidi_detect, 293 .detect = vidi_detect,
295 .destroy = vidi_connector_destroy, 294 .destroy = vidi_connector_destroy,
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index c953927fb0cb..0e2a472c3021 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -835,7 +835,6 @@ static void hdmi_connector_destroy(struct drm_connector *connector)
835} 835}
836 836
837static const struct drm_connector_funcs hdmi_connector_funcs = { 837static const struct drm_connector_funcs hdmi_connector_funcs = {
838 .dpms = drm_atomic_helper_connector_dpms,
839 .fill_modes = drm_helper_probe_single_connector_modes, 838 .fill_modes = drm_helper_probe_single_connector_modes,
840 .detect = hdmi_detect, 839 .detect = hdmi_detect,
841 .destroy = hdmi_connector_destroy, 840 .destroy = hdmi_connector_destroy,
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
index 5cbde196895a..58e9e0601a61 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
@@ -176,8 +176,6 @@ static struct drm_driver fsl_dcu_drm_driver = {
176 .gem_prime_vunmap = drm_gem_cma_prime_vunmap, 176 .gem_prime_vunmap = drm_gem_cma_prime_vunmap,
177 .gem_prime_mmap = drm_gem_cma_prime_mmap, 177 .gem_prime_mmap = drm_gem_cma_prime_mmap,
178 .dumb_create = drm_gem_cma_dumb_create, 178 .dumb_create = drm_gem_cma_dumb_create,
179 .dumb_map_offset = drm_gem_cma_dumb_map_offset,
180 .dumb_destroy = drm_gem_dumb_destroy,
181 .fops = &fsl_dcu_drm_fops, 179 .fops = &fsl_dcu_drm_fops,
182 .name = "fsl-dcu-drm", 180 .name = "fsl-dcu-drm",
183 .desc = "Freescale DCU DRM", 181 .desc = "Freescale DCU DRM",
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c
index 0a20723aa6e1..9554b245746e 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c
@@ -224,7 +224,7 @@ struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device *dev)
224 &fsl_dcu_drm_plane_funcs, 224 &fsl_dcu_drm_plane_funcs,
225 fsl_dcu_drm_plane_formats, 225 fsl_dcu_drm_plane_formats,
226 ARRAY_SIZE(fsl_dcu_drm_plane_formats), 226 ARRAY_SIZE(fsl_dcu_drm_plane_formats),
227 DRM_PLANE_TYPE_PRIMARY, NULL); 227 NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
228 if (ret) { 228 if (ret) {
229 kfree(primary); 229 kfree(primary);
230 primary = NULL; 230 primary = NULL;
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
index dcbf3c06e1d8..edd7d8127d19 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
@@ -63,7 +63,6 @@ static const struct drm_connector_funcs fsl_dcu_drm_connector_funcs = {
63 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 63 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
64 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 64 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
65 .destroy = fsl_dcu_drm_connector_destroy, 65 .destroy = fsl_dcu_drm_connector_destroy,
66 .dpms = drm_atomic_helper_connector_dpms,
67 .fill_modes = drm_helper_probe_single_connector_modes, 66 .fill_modes = drm_helper_probe_single_connector_modes,
68 .reset = drm_atomic_helper_connector_reset, 67 .reset = drm_atomic_helper_connector_reset,
69}; 68};
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index 7da70b6c83f0..2570c7f647a6 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -479,26 +479,6 @@ static struct drm_framebuffer *psb_user_framebuffer_create
479 return psb_framebuffer_create(dev, cmd, r); 479 return psb_framebuffer_create(dev, cmd, r);
480} 480}
481 481
482static void psbfb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
483 u16 blue, int regno)
484{
485 struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
486
487 gma_crtc->lut_r[regno] = red >> 8;
488 gma_crtc->lut_g[regno] = green >> 8;
489 gma_crtc->lut_b[regno] = blue >> 8;
490}
491
492static void psbfb_gamma_get(struct drm_crtc *crtc, u16 *red,
493 u16 *green, u16 *blue, int regno)
494{
495 struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
496
497 *red = gma_crtc->lut_r[regno] << 8;
498 *green = gma_crtc->lut_g[regno] << 8;
499 *blue = gma_crtc->lut_b[regno] << 8;
500}
501
502static int psbfb_probe(struct drm_fb_helper *helper, 482static int psbfb_probe(struct drm_fb_helper *helper,
503 struct drm_fb_helper_surface_size *sizes) 483 struct drm_fb_helper_surface_size *sizes)
504{ 484{
@@ -525,8 +505,6 @@ static int psbfb_probe(struct drm_fb_helper *helper,
525} 505}
526 506
527static const struct drm_fb_helper_funcs psb_fb_helper_funcs = { 507static const struct drm_fb_helper_funcs psb_fb_helper_funcs = {
528 .gamma_set = psbfb_gamma_set,
529 .gamma_get = psbfb_gamma_get,
530 .fb_probe = psbfb_probe, 508 .fb_probe = psbfb_probe,
531}; 509};
532 510
diff --git a/drivers/gpu/drm/gma500/gma_display.c b/drivers/gpu/drm/gma500/gma_display.c
index e7fd356acf2e..f3c48a2be71b 100644
--- a/drivers/gpu/drm/gma500/gma_display.c
+++ b/drivers/gpu/drm/gma500/gma_display.c
@@ -144,33 +144,32 @@ void gma_crtc_load_lut(struct drm_crtc *crtc)
144 struct gma_crtc *gma_crtc = to_gma_crtc(crtc); 144 struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
145 const struct psb_offset *map = &dev_priv->regmap[gma_crtc->pipe]; 145 const struct psb_offset *map = &dev_priv->regmap[gma_crtc->pipe];
146 int palreg = map->palette; 146 int palreg = map->palette;
147 u16 *r, *g, *b;
147 int i; 148 int i;
148 149
149 /* The clocks have to be on to load the palette. */ 150 /* The clocks have to be on to load the palette. */
150 if (!crtc->enabled) 151 if (!crtc->enabled)
151 return; 152 return;
152 153
154 r = crtc->gamma_store;
155 g = r + crtc->gamma_size;
156 b = g + crtc->gamma_size;
157
153 if (gma_power_begin(dev, false)) { 158 if (gma_power_begin(dev, false)) {
154 for (i = 0; i < 256; i++) { 159 for (i = 0; i < 256; i++) {
155 REG_WRITE(palreg + 4 * i, 160 REG_WRITE(palreg + 4 * i,
156 ((gma_crtc->lut_r[i] + 161 (((*r++ >> 8) + gma_crtc->lut_adj[i]) << 16) |
157 gma_crtc->lut_adj[i]) << 16) | 162 (((*g++ >> 8) + gma_crtc->lut_adj[i]) << 8) |
158 ((gma_crtc->lut_g[i] + 163 ((*b++ >> 8) + gma_crtc->lut_adj[i]));
159 gma_crtc->lut_adj[i]) << 8) |
160 (gma_crtc->lut_b[i] +
161 gma_crtc->lut_adj[i]));
162 } 164 }
163 gma_power_end(dev); 165 gma_power_end(dev);
164 } else { 166 } else {
165 for (i = 0; i < 256; i++) { 167 for (i = 0; i < 256; i++) {
166 /* FIXME: Why pipe[0] and not pipe[..._crtc->pipe]? */ 168 /* FIXME: Why pipe[0] and not pipe[..._crtc->pipe]? */
167 dev_priv->regs.pipe[0].palette[i] = 169 dev_priv->regs.pipe[0].palette[i] =
168 ((gma_crtc->lut_r[i] + 170 (((*r++ >> 8) + gma_crtc->lut_adj[i]) << 16) |
169 gma_crtc->lut_adj[i]) << 16) | 171 (((*g++ >> 8) + gma_crtc->lut_adj[i]) << 8) |
170 ((gma_crtc->lut_g[i] + 172 ((*b++ >> 8) + gma_crtc->lut_adj[i]);
171 gma_crtc->lut_adj[i]) << 8) |
172 (gma_crtc->lut_b[i] +
173 gma_crtc->lut_adj[i]);
174 } 173 }
175 174
176 } 175 }
@@ -180,15 +179,6 @@ int gma_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, u16 *blue,
180 u32 size, 179 u32 size,
181 struct drm_modeset_acquire_ctx *ctx) 180 struct drm_modeset_acquire_ctx *ctx)
182{ 181{
183 struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
184 int i;
185
186 for (i = 0; i < size; i++) {
187 gma_crtc->lut_r[i] = red[i] >> 8;
188 gma_crtc->lut_g[i] = green[i] >> 8;
189 gma_crtc->lut_b[i] = blue[i] >> 8;
190 }
191
192 gma_crtc_load_lut(crtc); 182 gma_crtc_load_lut(crtc);
193 183
194 return 0; 184 return 0;
diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c
index 7b6c84925098..8762efaef283 100644
--- a/drivers/gpu/drm/gma500/psb_intel_display.c
+++ b/drivers/gpu/drm/gma500/psb_intel_display.c
@@ -518,13 +518,8 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe,
518 gma_crtc->pipe = pipe; 518 gma_crtc->pipe = pipe;
519 gma_crtc->plane = pipe; 519 gma_crtc->plane = pipe;
520 520
521 for (i = 0; i < 256; i++) { 521 for (i = 0; i < 256; i++)
522 gma_crtc->lut_r[i] = i;
523 gma_crtc->lut_g[i] = i;
524 gma_crtc->lut_b[i] = i;
525
526 gma_crtc->lut_adj[i] = 0; 522 gma_crtc->lut_adj[i] = 0;
527 }
528 523
529 gma_crtc->mode_dev = mode_dev; 524 gma_crtc->mode_dev = mode_dev;
530 gma_crtc->cursor_addr = 0; 525 gma_crtc->cursor_addr = 0;
diff --git a/drivers/gpu/drm/gma500/psb_intel_drv.h b/drivers/gpu/drm/gma500/psb_intel_drv.h
index 6a10215fc42d..e8e4ea14b12b 100644
--- a/drivers/gpu/drm/gma500/psb_intel_drv.h
+++ b/drivers/gpu/drm/gma500/psb_intel_drv.h
@@ -172,7 +172,6 @@ struct gma_crtc {
172 int plane; 172 int plane;
173 uint32_t cursor_addr; 173 uint32_t cursor_addr;
174 struct gtt_range *cursor_gt; 174 struct gtt_range *cursor_gt;
175 u8 lut_r[256], lut_g[256], lut_b[256];
176 u8 lut_adj[256]; 175 u8 lut_adj[256];
177 struct psb_intel_framebuffer *fbdev_fb; 176 struct psb_intel_framebuffer *fbdev_fb;
178 /* a mode_set for fbdev users on this crtc */ 177 /* a mode_set for fbdev users on this crtc */
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
index 54a4542a40f1..a956545774a3 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
@@ -150,7 +150,6 @@ static const u32 channel_formats1[] = {
150static struct drm_plane_funcs hibmc_plane_funcs = { 150static struct drm_plane_funcs hibmc_plane_funcs = {
151 .update_plane = drm_atomic_helper_update_plane, 151 .update_plane = drm_atomic_helper_update_plane,
152 .disable_plane = drm_atomic_helper_disable_plane, 152 .disable_plane = drm_atomic_helper_disable_plane,
153 .set_property = drm_atomic_helper_plane_set_property,
154 .destroy = drm_plane_cleanup, 153 .destroy = drm_plane_cleanup,
155 .reset = drm_atomic_helper_plane_reset, 154 .reset = drm_atomic_helper_plane_reset,
156 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 155 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
@@ -181,6 +180,7 @@ static struct drm_plane *hibmc_plane_init(struct hibmc_drm_private *priv)
181 ret = drm_universal_plane_init(dev, plane, 1, &hibmc_plane_funcs, 180 ret = drm_universal_plane_init(dev, plane, 1, &hibmc_plane_funcs,
182 channel_formats1, 181 channel_formats1,
183 ARRAY_SIZE(channel_formats1), 182 ARRAY_SIZE(channel_formats1),
183 NULL,
184 DRM_PLANE_TYPE_PRIMARY, 184 DRM_PLANE_TYPE_PRIMARY,
185 NULL); 185 NULL);
186 if (ret) { 186 if (ret) {
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
index 4d018ca98581..d4f6f1f9df5b 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
@@ -67,7 +67,6 @@ static struct drm_driver hibmc_driver = {
67 .gem_free_object_unlocked = hibmc_gem_free_object, 67 .gem_free_object_unlocked = hibmc_gem_free_object,
68 .dumb_create = hibmc_dumb_create, 68 .dumb_create = hibmc_dumb_create,
69 .dumb_map_offset = hibmc_dumb_mmap_offset, 69 .dumb_map_offset = hibmc_dumb_mmap_offset,
70 .dumb_destroy = drm_gem_dumb_destroy,
71 .irq_handler = hibmc_drm_interrupt, 70 .irq_handler = hibmc_drm_interrupt,
72}; 71};
73 72
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
index 12a18557c5fd..ec4dd9df9150 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
@@ -47,7 +47,6 @@ static const struct drm_connector_helper_funcs
47}; 47};
48 48
49static const struct drm_connector_funcs hibmc_connector_funcs = { 49static const struct drm_connector_funcs hibmc_connector_funcs = {
50 .dpms = drm_atomic_helper_connector_dpms,
51 .fill_modes = drm_helper_probe_single_connector_modes, 50 .fill_modes = drm_helper_probe_single_connector_modes,
52 .destroy = drm_connector_cleanup, 51 .destroy = drm_connector_cleanup,
53 .reset = drm_atomic_helper_connector_reset, 52 .reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
index 706efd0c4190..39f7d15673ed 100644
--- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
+++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
@@ -567,7 +567,6 @@ static const struct drm_crtc_funcs ade_crtc_funcs = {
567 .set_config = drm_atomic_helper_set_config, 567 .set_config = drm_atomic_helper_set_config,
568 .page_flip = drm_atomic_helper_page_flip, 568 .page_flip = drm_atomic_helper_page_flip,
569 .reset = drm_atomic_helper_crtc_reset, 569 .reset = drm_atomic_helper_crtc_reset,
570 .set_property = drm_atomic_helper_crtc_set_property,
571 .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, 570 .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
572 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, 571 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
573 .enable_vblank = ade_crtc_enable_vblank, 572 .enable_vblank = ade_crtc_enable_vblank,
@@ -890,7 +889,6 @@ static const struct drm_plane_helper_funcs ade_plane_helper_funcs = {
890static struct drm_plane_funcs ade_plane_funcs = { 889static struct drm_plane_funcs ade_plane_funcs = {
891 .update_plane = drm_atomic_helper_update_plane, 890 .update_plane = drm_atomic_helper_update_plane,
892 .disable_plane = drm_atomic_helper_disable_plane, 891 .disable_plane = drm_atomic_helper_disable_plane,
893 .set_property = drm_atomic_helper_plane_set_property,
894 .destroy = drm_plane_cleanup, 892 .destroy = drm_plane_cleanup,
895 .reset = drm_atomic_helper_plane_reset, 893 .reset = drm_atomic_helper_plane_reset,
896 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 894 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
@@ -910,7 +908,7 @@ static int ade_plane_init(struct drm_device *dev, struct ade_plane *aplane,
910 return ret; 908 return ret;
911 909
912 ret = drm_universal_plane_init(dev, &aplane->base, 1, &ade_plane_funcs, 910 ret = drm_universal_plane_init(dev, &aplane->base, 1, &ade_plane_funcs,
913 fmts, fmts_cnt, type, NULL); 911 fmts, fmts_cnt, NULL, type, NULL);
914 if (ret) { 912 if (ret) {
915 DRM_ERROR("fail to init plane, ch=%d\n", aplane->ch); 913 DRM_ERROR("fail to init plane, ch=%d\n", aplane->ch);
916 return ret; 914 return ret;
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index d1e7ac540199..54e3255dde13 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -969,14 +969,6 @@ static int tda998x_audio_codec_init(struct tda998x_priv *priv,
969 969
970/* DRM connector functions */ 970/* DRM connector functions */
971 971
972static int tda998x_connector_dpms(struct drm_connector *connector, int mode)
973{
974 if (drm_core_check_feature(connector->dev, DRIVER_ATOMIC))
975 return drm_atomic_helper_connector_dpms(connector, mode);
976 else
977 return drm_helper_connector_dpms(connector, mode);
978}
979
980static int tda998x_connector_fill_modes(struct drm_connector *connector, 972static int tda998x_connector_fill_modes(struct drm_connector *connector,
981 uint32_t maxX, uint32_t maxY) 973 uint32_t maxX, uint32_t maxY)
982{ 974{
@@ -1014,7 +1006,7 @@ static void tda998x_connector_destroy(struct drm_connector *connector)
1014} 1006}
1015 1007
1016static const struct drm_connector_funcs tda998x_connector_funcs = { 1008static const struct drm_connector_funcs tda998x_connector_funcs = {
1017 .dpms = tda998x_connector_dpms, 1009 .dpms = drm_helper_connector_dpms,
1018 .reset = drm_atomic_helper_connector_reset, 1010 .reset = drm_atomic_helper_connector_reset,
1019 .fill_modes = tda998x_connector_fill_modes, 1011 .fill_modes = tda998x_connector_fill_modes,
1020 .detect = tda998x_connector_detect, 1012 .detect = tda998x_connector_detect,
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index d310d8245dca..4c96a7214482 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2755,7 +2755,6 @@ static struct drm_driver driver = {
2755 2755
2756 .dumb_create = i915_gem_dumb_create, 2756 .dumb_create = i915_gem_dumb_create,
2757 .dumb_map_offset = i915_gem_mmap_gtt, 2757 .dumb_map_offset = i915_gem_mmap_gtt,
2758 .dumb_destroy = drm_gem_dumb_destroy,
2759 .ioctls = i915_ioctls, 2758 .ioctls = i915_ioctls,
2760 .num_ioctls = ARRAY_SIZE(i915_ioctls), 2759 .num_ioctls = ARRAY_SIZE(i915_ioctls),
2761 .fops = &i915_driver_fops, 2760 .fops = &i915_driver_fops,
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 84a1f5e85153..70e0ff41070c 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -802,12 +802,10 @@ void intel_crt_reset(struct drm_encoder *encoder)
802 */ 802 */
803 803
804static const struct drm_connector_funcs intel_crt_connector_funcs = { 804static const struct drm_connector_funcs intel_crt_connector_funcs = {
805 .dpms = drm_atomic_helper_connector_dpms,
806 .fill_modes = drm_helper_probe_single_connector_modes, 805 .fill_modes = drm_helper_probe_single_connector_modes,
807 .late_register = intel_connector_register, 806 .late_register = intel_connector_register,
808 .early_unregister = intel_connector_unregister, 807 .early_unregister = intel_connector_unregister,
809 .destroy = intel_crt_destroy, 808 .destroy = intel_crt_destroy,
810 .set_property = drm_atomic_helper_connector_set_property,
811 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 809 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
812 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 810 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
813}; 811};
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e92fd14c06c7..684d653bfddb 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13323,7 +13323,6 @@ static int intel_atomic_commit(struct drm_device *dev,
13323static const struct drm_crtc_funcs intel_crtc_funcs = { 13323static const struct drm_crtc_funcs intel_crtc_funcs = {
13324 .gamma_set = drm_atomic_helper_legacy_gamma_set, 13324 .gamma_set = drm_atomic_helper_legacy_gamma_set,
13325 .set_config = drm_atomic_helper_set_config, 13325 .set_config = drm_atomic_helper_set_config,
13326 .set_property = drm_atomic_helper_crtc_set_property,
13327 .destroy = intel_crtc_destroy, 13326 .destroy = intel_crtc_destroy,
13328 .page_flip = drm_atomic_helper_page_flip, 13327 .page_flip = drm_atomic_helper_page_flip,
13329 .atomic_duplicate_state = intel_crtc_duplicate_state, 13328 .atomic_duplicate_state = intel_crtc_duplicate_state,
@@ -13600,7 +13599,6 @@ const struct drm_plane_funcs intel_plane_funcs = {
13600 .update_plane = drm_atomic_helper_update_plane, 13599 .update_plane = drm_atomic_helper_update_plane,
13601 .disable_plane = drm_atomic_helper_disable_plane, 13600 .disable_plane = drm_atomic_helper_disable_plane,
13602 .destroy = intel_plane_destroy, 13601 .destroy = intel_plane_destroy,
13603 .set_property = drm_atomic_helper_plane_set_property,
13604 .atomic_get_property = intel_plane_atomic_get_property, 13602 .atomic_get_property = intel_plane_atomic_get_property,
13605 .atomic_set_property = intel_plane_atomic_set_property, 13603 .atomic_set_property = intel_plane_atomic_set_property,
13606 .atomic_duplicate_state = intel_plane_duplicate_state, 13604 .atomic_duplicate_state = intel_plane_duplicate_state,
@@ -13735,7 +13733,6 @@ static const struct drm_plane_funcs intel_cursor_plane_funcs = {
13735 .update_plane = intel_legacy_cursor_update, 13733 .update_plane = intel_legacy_cursor_update,
13736 .disable_plane = drm_atomic_helper_disable_plane, 13734 .disable_plane = drm_atomic_helper_disable_plane,
13737 .destroy = intel_plane_destroy, 13735 .destroy = intel_plane_destroy,
13738 .set_property = drm_atomic_helper_plane_set_property,
13739 .atomic_get_property = intel_plane_atomic_get_property, 13736 .atomic_get_property = intel_plane_atomic_get_property,
13740 .atomic_set_property = intel_plane_atomic_set_property, 13737 .atomic_set_property = intel_plane_atomic_set_property,
13741 .atomic_duplicate_state = intel_plane_duplicate_state, 13738 .atomic_duplicate_state = intel_plane_duplicate_state,
@@ -13809,18 +13806,21 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
13809 ret = drm_universal_plane_init(&dev_priv->drm, &primary->base, 13806 ret = drm_universal_plane_init(&dev_priv->drm, &primary->base,
13810 0, &intel_plane_funcs, 13807 0, &intel_plane_funcs,
13811 intel_primary_formats, num_formats, 13808 intel_primary_formats, num_formats,
13809 NULL,
13812 DRM_PLANE_TYPE_PRIMARY, 13810 DRM_PLANE_TYPE_PRIMARY,
13813 "plane 1%c", pipe_name(pipe)); 13811 "plane 1%c", pipe_name(pipe));
13814 else if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv)) 13812 else if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv))
13815 ret = drm_universal_plane_init(&dev_priv->drm, &primary->base, 13813 ret = drm_universal_plane_init(&dev_priv->drm, &primary->base,
13816 0, &intel_plane_funcs, 13814 0, &intel_plane_funcs,
13817 intel_primary_formats, num_formats, 13815 intel_primary_formats, num_formats,
13816 NULL,
13818 DRM_PLANE_TYPE_PRIMARY, 13817 DRM_PLANE_TYPE_PRIMARY,
13819 "primary %c", pipe_name(pipe)); 13818 "primary %c", pipe_name(pipe));
13820 else 13819 else
13821 ret = drm_universal_plane_init(&dev_priv->drm, &primary->base, 13820 ret = drm_universal_plane_init(&dev_priv->drm, &primary->base,
13822 0, &intel_plane_funcs, 13821 0, &intel_plane_funcs,
13823 intel_primary_formats, num_formats, 13822 intel_primary_formats, num_formats,
13823 NULL,
13824 DRM_PLANE_TYPE_PRIMARY, 13824 DRM_PLANE_TYPE_PRIMARY,
13825 "plane %c", plane_name(primary->plane)); 13825 "plane %c", plane_name(primary->plane));
13826 if (ret) 13826 if (ret)
@@ -13906,7 +13906,7 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv,
13906 0, &intel_cursor_plane_funcs, 13906 0, &intel_cursor_plane_funcs,
13907 intel_cursor_formats, 13907 intel_cursor_formats,
13908 ARRAY_SIZE(intel_cursor_formats), 13908 ARRAY_SIZE(intel_cursor_formats),
13909 DRM_PLANE_TYPE_CURSOR, 13909 NULL, DRM_PLANE_TYPE_CURSOR,
13910 "cursor %c", pipe_name(pipe)); 13910 "cursor %c", pipe_name(pipe));
13911 if (ret) 13911 if (ret)
13912 goto fail; 13912 goto fail;
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 2d42d09428c9..76c8a0bd17f9 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -5007,10 +5007,8 @@ void intel_dp_encoder_reset(struct drm_encoder *encoder)
5007} 5007}
5008 5008
5009static const struct drm_connector_funcs intel_dp_connector_funcs = { 5009static const struct drm_connector_funcs intel_dp_connector_funcs = {
5010 .dpms = drm_atomic_helper_connector_dpms,
5011 .force = intel_dp_force, 5010 .force = intel_dp_force,
5012 .fill_modes = drm_helper_probe_single_connector_modes, 5011 .fill_modes = drm_helper_probe_single_connector_modes,
5013 .set_property = drm_atomic_helper_connector_set_property,
5014 .atomic_get_property = intel_digital_connector_atomic_get_property, 5012 .atomic_get_property = intel_digital_connector_atomic_get_property,
5015 .atomic_set_property = intel_digital_connector_atomic_set_property, 5013 .atomic_set_property = intel_digital_connector_atomic_set_property,
5016 .late_register = intel_dp_connector_register, 5014 .late_register = intel_dp_connector_register,
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index e4ea968b1d6b..58568559711a 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -346,10 +346,8 @@ intel_dp_mst_connector_destroy(struct drm_connector *connector)
346} 346}
347 347
348static const struct drm_connector_funcs intel_dp_mst_connector_funcs = { 348static const struct drm_connector_funcs intel_dp_mst_connector_funcs = {
349 .dpms = drm_atomic_helper_connector_dpms,
350 .detect = intel_dp_mst_detect, 349 .detect = intel_dp_mst_detect,
351 .fill_modes = drm_helper_probe_single_connector_modes, 350 .fill_modes = drm_helper_probe_single_connector_modes,
352 .set_property = drm_atomic_helper_connector_set_property,
353 .late_register = intel_connector_register, 351 .late_register = intel_connector_register,
354 .early_unregister = intel_connector_unregister, 352 .early_unregister = intel_connector_unregister,
355 .destroy = intel_dp_mst_connector_destroy, 353 .destroy = intel_dp_mst_connector_destroy,
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d17a32437f07..210a8c63bde8 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -786,7 +786,6 @@ struct intel_crtc {
786 struct drm_crtc base; 786 struct drm_crtc base;
787 enum pipe pipe; 787 enum pipe pipe;
788 enum plane plane; 788 enum plane plane;
789 u8 lut_r[256], lut_g[256], lut_b[256];
790 /* 789 /*
791 * Whether the crtc and the connected output pipeline is active. Implies 790 * Whether the crtc and the connected output pipeline is active. Implies
792 * that crtc->enabled is set, i.e. the current mode configuration has 791 * that crtc->enabled is set, i.e. the current mode configuration has
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 50ec836da8b1..b0b3adf016f8 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -1653,12 +1653,10 @@ static const struct drm_connector_helper_funcs intel_dsi_connector_helper_funcs
1653}; 1653};
1654 1654
1655static const struct drm_connector_funcs intel_dsi_connector_funcs = { 1655static const struct drm_connector_funcs intel_dsi_connector_funcs = {
1656 .dpms = drm_atomic_helper_connector_dpms,
1657 .late_register = intel_connector_register, 1656 .late_register = intel_connector_register,
1658 .early_unregister = intel_connector_unregister, 1657 .early_unregister = intel_connector_unregister,
1659 .destroy = intel_dsi_connector_destroy, 1658 .destroy = intel_dsi_connector_destroy,
1660 .fill_modes = drm_helper_probe_single_connector_modes, 1659 .fill_modes = drm_helper_probe_single_connector_modes,
1661 .set_property = drm_atomic_helper_connector_set_property,
1662 .atomic_get_property = intel_digital_connector_atomic_get_property, 1660 .atomic_get_property = intel_digital_connector_atomic_get_property,
1663 .atomic_set_property = intel_digital_connector_atomic_set_property, 1661 .atomic_set_property = intel_digital_connector_atomic_set_property,
1664 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 1662 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
index c1544a53095d..baf369d2de30 100644
--- a/drivers/gpu/drm/i915/intel_dvo.c
+++ b/drivers/gpu/drm/i915/intel_dvo.c
@@ -344,13 +344,11 @@ static void intel_dvo_destroy(struct drm_connector *connector)
344} 344}
345 345
346static const struct drm_connector_funcs intel_dvo_connector_funcs = { 346static const struct drm_connector_funcs intel_dvo_connector_funcs = {
347 .dpms = drm_atomic_helper_connector_dpms,
348 .detect = intel_dvo_detect, 347 .detect = intel_dvo_detect,
349 .late_register = intel_connector_register, 348 .late_register = intel_connector_register,
350 .early_unregister = intel_connector_unregister, 349 .early_unregister = intel_connector_unregister,
351 .destroy = intel_dvo_destroy, 350 .destroy = intel_dvo_destroy,
352 .fill_modes = drm_helper_probe_single_connector_modes, 351 .fill_modes = drm_helper_probe_single_connector_modes,
353 .set_property = drm_atomic_helper_connector_set_property,
354 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 352 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
355 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 353 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
356}; 354};
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c
index b953365a3eec..0986ca4f16f1 100644
--- a/drivers/gpu/drm/i915/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/intel_fbdev.c
@@ -280,27 +280,6 @@ out_unlock:
280 return ret; 280 return ret;
281} 281}
282 282
283/** Sets the color ramps on behalf of RandR */
284static void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
285 u16 blue, int regno)
286{
287 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
288
289 intel_crtc->lut_r[regno] = red >> 8;
290 intel_crtc->lut_g[regno] = green >> 8;
291 intel_crtc->lut_b[regno] = blue >> 8;
292}
293
294static void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
295 u16 *blue, int regno)
296{
297 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
298
299 *red = intel_crtc->lut_r[regno] << 8;
300 *green = intel_crtc->lut_g[regno] << 8;
301 *blue = intel_crtc->lut_b[regno] << 8;
302}
303
304static struct drm_fb_helper_crtc * 283static struct drm_fb_helper_crtc *
305intel_fb_helper_crtc(struct drm_fb_helper *fb_helper, struct drm_crtc *crtc) 284intel_fb_helper_crtc(struct drm_fb_helper *fb_helper, struct drm_crtc *crtc)
306{ 285{
@@ -375,7 +354,6 @@ retry:
375 struct drm_connector *connector; 354 struct drm_connector *connector;
376 struct drm_encoder *encoder; 355 struct drm_encoder *encoder;
377 struct drm_fb_helper_crtc *new_crtc; 356 struct drm_fb_helper_crtc *new_crtc;
378 struct intel_crtc *intel_crtc;
379 357
380 fb_conn = fb_helper->connector_info[i]; 358 fb_conn = fb_helper->connector_info[i];
381 connector = fb_conn->connector; 359 connector = fb_conn->connector;
@@ -417,13 +395,6 @@ retry:
417 395
418 num_connectors_enabled++; 396 num_connectors_enabled++;
419 397
420 intel_crtc = to_intel_crtc(connector->state->crtc);
421 for (j = 0; j < 256; j++) {
422 intel_crtc->lut_r[j] = j;
423 intel_crtc->lut_g[j] = j;
424 intel_crtc->lut_b[j] = j;
425 }
426
427 new_crtc = intel_fb_helper_crtc(fb_helper, 398 new_crtc = intel_fb_helper_crtc(fb_helper,
428 connector->state->crtc); 399 connector->state->crtc);
429 400
@@ -526,8 +497,6 @@ bail:
526 497
527static const struct drm_fb_helper_funcs intel_fb_helper_funcs = { 498static const struct drm_fb_helper_funcs intel_fb_helper_funcs = {
528 .initial_config = intel_fb_initial_config, 499 .initial_config = intel_fb_initial_config,
529 .gamma_set = intel_crtc_fb_gamma_set,
530 .gamma_get = intel_crtc_fb_gamma_get,
531 .fb_probe = intelfb_create, 500 .fb_probe = intelfb_create,
532}; 501};
533 502
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 2f831cfdd243..eb0c559b66c1 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1706,11 +1706,9 @@ static void intel_hdmi_destroy(struct drm_connector *connector)
1706} 1706}
1707 1707
1708static const struct drm_connector_funcs intel_hdmi_connector_funcs = { 1708static const struct drm_connector_funcs intel_hdmi_connector_funcs = {
1709 .dpms = drm_atomic_helper_connector_dpms,
1710 .detect = intel_hdmi_detect, 1709 .detect = intel_hdmi_detect,
1711 .force = intel_hdmi_force, 1710 .force = intel_hdmi_force,
1712 .fill_modes = drm_helper_probe_single_connector_modes, 1711 .fill_modes = drm_helper_probe_single_connector_modes,
1713 .set_property = drm_atomic_helper_connector_set_property,
1714 .atomic_get_property = intel_digital_connector_atomic_get_property, 1712 .atomic_get_property = intel_digital_connector_atomic_get_property,
1715 .atomic_set_property = intel_digital_connector_atomic_set_property, 1713 .atomic_set_property = intel_digital_connector_atomic_set_property,
1716 .late_register = intel_connector_register, 1714 .late_register = intel_connector_register,
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 6fe5d7c3bc23..61d557948e21 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -595,10 +595,8 @@ static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs
595}; 595};
596 596
597static const struct drm_connector_funcs intel_lvds_connector_funcs = { 597static const struct drm_connector_funcs intel_lvds_connector_funcs = {
598 .dpms = drm_atomic_helper_connector_dpms,
599 .detect = intel_lvds_detect, 598 .detect = intel_lvds_detect,
600 .fill_modes = drm_helper_probe_single_connector_modes, 599 .fill_modes = drm_helper_probe_single_connector_modes,
601 .set_property = drm_atomic_helper_connector_set_property,
602 .atomic_get_property = intel_digital_connector_atomic_get_property, 600 .atomic_get_property = intel_digital_connector_atomic_get_property,
603 .atomic_set_property = intel_digital_connector_atomic_set_property, 601 .atomic_set_property = intel_digital_connector_atomic_set_property,
604 .late_register = intel_connector_register, 602 .late_register = intel_connector_register,
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index e58a47db9a9d..bea8152ae859 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -2193,10 +2193,8 @@ intel_sdvo_connector_duplicate_state(struct drm_connector *connector)
2193} 2193}
2194 2194
2195static const struct drm_connector_funcs intel_sdvo_connector_funcs = { 2195static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
2196 .dpms = drm_atomic_helper_connector_dpms,
2197 .detect = intel_sdvo_detect, 2196 .detect = intel_sdvo_detect,
2198 .fill_modes = drm_helper_probe_single_connector_modes, 2197 .fill_modes = drm_helper_probe_single_connector_modes,
2199 .set_property = drm_atomic_helper_connector_set_property,
2200 .atomic_get_property = intel_sdvo_connector_atomic_get_property, 2198 .atomic_get_property = intel_sdvo_connector_atomic_get_property,
2201 .atomic_set_property = intel_sdvo_connector_atomic_set_property, 2199 .atomic_set_property = intel_sdvo_connector_atomic_set_property,
2202 .late_register = intel_sdvo_connector_register, 2200 .late_register = intel_sdvo_connector_register,
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 94f9a1332dbf..4c6b387fa9dc 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -1171,13 +1171,13 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
1171 ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base, 1171 ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base,
1172 possible_crtcs, &intel_plane_funcs, 1172 possible_crtcs, &intel_plane_funcs,
1173 plane_formats, num_plane_formats, 1173 plane_formats, num_plane_formats,
1174 DRM_PLANE_TYPE_OVERLAY, 1174 NULL, DRM_PLANE_TYPE_OVERLAY,
1175 "plane %d%c", plane + 2, pipe_name(pipe)); 1175 "plane %d%c", plane + 2, pipe_name(pipe));
1176 else 1176 else
1177 ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base, 1177 ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base,
1178 possible_crtcs, &intel_plane_funcs, 1178 possible_crtcs, &intel_plane_funcs,
1179 plane_formats, num_plane_formats, 1179 plane_formats, num_plane_formats,
1180 DRM_PLANE_TYPE_OVERLAY, 1180 NULL, DRM_PLANE_TYPE_OVERLAY,
1181 "sprite %c", sprite_name(pipe, plane)); 1181 "sprite %c", sprite_name(pipe, plane));
1182 if (ret) 1182 if (ret)
1183 goto fail; 1183 goto fail;
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 784df024e230..906893c006d8 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1407,11 +1407,9 @@ intel_tv_destroy(struct drm_connector *connector)
1407} 1407}
1408 1408
1409static const struct drm_connector_funcs intel_tv_connector_funcs = { 1409static const struct drm_connector_funcs intel_tv_connector_funcs = {
1410 .dpms = drm_atomic_helper_connector_dpms,
1411 .late_register = intel_connector_register, 1410 .late_register = intel_connector_register,
1412 .early_unregister = intel_connector_unregister, 1411 .early_unregister = intel_connector_unregister,
1413 .destroy = intel_tv_destroy, 1412 .destroy = intel_tv_destroy,
1414 .set_property = drm_atomic_helper_connector_set_property,
1415 .fill_modes = drm_helper_probe_single_connector_modes, 1413 .fill_modes = drm_helper_probe_single_connector_modes,
1416 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 1414 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1417 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 1415 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
index f5c621219113..f91cb72d0830 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -182,8 +182,6 @@ static struct drm_driver imx_drm_driver = {
182 .gem_free_object_unlocked = drm_gem_cma_free_object, 182 .gem_free_object_unlocked = drm_gem_cma_free_object,
183 .gem_vm_ops = &drm_gem_cma_vm_ops, 183 .gem_vm_ops = &drm_gem_cma_vm_ops,
184 .dumb_create = drm_gem_cma_dumb_create, 184 .dumb_create = drm_gem_cma_dumb_create,
185 .dumb_map_offset = drm_gem_cma_dumb_map_offset,
186 .dumb_destroy = drm_gem_dumb_destroy,
187 185
188 .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 186 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
189 .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 187 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
index 8b05ecb8fdef..56dd7a9a8e25 100644
--- a/drivers/gpu/drm/imx/imx-ldb.c
+++ b/drivers/gpu/drm/imx/imx-ldb.c
@@ -389,7 +389,6 @@ static int imx_ldb_encoder_atomic_check(struct drm_encoder *encoder,
389 389
390 390
391static const struct drm_connector_funcs imx_ldb_connector_funcs = { 391static const struct drm_connector_funcs imx_ldb_connector_funcs = {
392 .dpms = drm_atomic_helper_connector_dpms,
393 .fill_modes = drm_helper_probe_single_connector_modes, 392 .fill_modes = drm_helper_probe_single_connector_modes,
394 .destroy = imx_drm_connector_destroy, 393 .destroy = imx_drm_connector_destroy,
395 .reset = drm_atomic_helper_connector_reset, 394 .reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c
index 4826bb781723..bc27c2699464 100644
--- a/drivers/gpu/drm/imx/imx-tve.c
+++ b/drivers/gpu/drm/imx/imx-tve.c
@@ -341,7 +341,6 @@ static int imx_tve_atomic_check(struct drm_encoder *encoder,
341} 341}
342 342
343static const struct drm_connector_funcs imx_tve_connector_funcs = { 343static const struct drm_connector_funcs imx_tve_connector_funcs = {
344 .dpms = drm_atomic_helper_connector_dpms,
345 .fill_modes = drm_helper_probe_single_connector_modes, 344 .fill_modes = drm_helper_probe_single_connector_modes,
346 .destroy = imx_drm_connector_destroy, 345 .destroy = imx_drm_connector_destroy,
347 .reset = drm_atomic_helper_connector_reset, 346 .reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c
index 0847cc0d96a4..debde2dae7bf 100644
--- a/drivers/gpu/drm/imx/ipuv3-plane.c
+++ b/drivers/gpu/drm/imx/ipuv3-plane.c
@@ -718,8 +718,8 @@ struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
718 718
719 ret = drm_universal_plane_init(dev, &ipu_plane->base, possible_crtcs, 719 ret = drm_universal_plane_init(dev, &ipu_plane->base, possible_crtcs,
720 &ipu_plane_funcs, ipu_plane_formats, 720 &ipu_plane_funcs, ipu_plane_formats,
721 ARRAY_SIZE(ipu_plane_formats), type, 721 ARRAY_SIZE(ipu_plane_formats),
722 NULL); 722 NULL, type, NULL);
723 if (ret) { 723 if (ret) {
724 DRM_ERROR("failed to initialize plane\n"); 724 DRM_ERROR("failed to initialize plane\n");
725 kfree(ipu_plane); 725 kfree(ipu_plane);
diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c
index 8aca20209cb8..8def97d75030 100644
--- a/drivers/gpu/drm/imx/parallel-display.c
+++ b/drivers/gpu/drm/imx/parallel-display.c
@@ -135,7 +135,6 @@ static int imx_pd_encoder_atomic_check(struct drm_encoder *encoder,
135} 135}
136 136
137static const struct drm_connector_funcs imx_pd_connector_funcs = { 137static const struct drm_connector_funcs imx_pd_connector_funcs = {
138 .dpms = drm_atomic_helper_connector_dpms,
139 .fill_modes = drm_helper_probe_single_connector_modes, 138 .fill_modes = drm_helper_probe_single_connector_modes,
140 .destroy = imx_drm_connector_destroy, 139 .destroy = imx_drm_connector_destroy,
141 .reset = drm_atomic_helper_connector_reset, 140 .reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index f0cb2765e212..a2ca90fc403c 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -293,8 +293,6 @@ static struct drm_driver mtk_drm_driver = {
293 .gem_free_object_unlocked = mtk_drm_gem_free_object, 293 .gem_free_object_unlocked = mtk_drm_gem_free_object,
294 .gem_vm_ops = &drm_gem_cma_vm_ops, 294 .gem_vm_ops = &drm_gem_cma_vm_ops,
295 .dumb_create = mtk_drm_gem_dumb_create, 295 .dumb_create = mtk_drm_gem_dumb_create,
296 .dumb_map_offset = mtk_drm_gem_dumb_map_offset,
297 .dumb_destroy = drm_gem_dumb_destroy,
298 296
299 .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 297 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
300 .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 298 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
index 7abc550ebc00..8ec963fff8b1 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
@@ -131,31 +131,6 @@ err_handle_create:
131 return ret; 131 return ret;
132} 132}
133 133
134int mtk_drm_gem_dumb_map_offset(struct drm_file *file_priv,
135 struct drm_device *dev, uint32_t handle,
136 uint64_t *offset)
137{
138 struct drm_gem_object *obj;
139 int ret;
140
141 obj = drm_gem_object_lookup(file_priv, handle);
142 if (!obj) {
143 DRM_ERROR("failed to lookup gem object.\n");
144 return -EINVAL;
145 }
146
147 ret = drm_gem_create_mmap_offset(obj);
148 if (ret)
149 goto out;
150
151 *offset = drm_vma_node_offset_addr(&obj->vma_node);
152 DRM_DEBUG_KMS("offset = 0x%llx\n", *offset);
153
154out:
155 drm_gem_object_unreference_unlocked(obj);
156 return ret;
157}
158
159static int mtk_drm_gem_object_mmap(struct drm_gem_object *obj, 134static int mtk_drm_gem_object_mmap(struct drm_gem_object *obj,
160 struct vm_area_struct *vma) 135 struct vm_area_struct *vma)
161 136
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.h b/drivers/gpu/drm/mediatek/mtk_drm_gem.h
index 2752718fa5b2..534639b43a1c 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_gem.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.h
@@ -46,9 +46,6 @@ struct mtk_drm_gem_obj *mtk_drm_gem_create(struct drm_device *dev, size_t size,
46 bool alloc_kmap); 46 bool alloc_kmap);
47int mtk_drm_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev, 47int mtk_drm_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
48 struct drm_mode_create_dumb *args); 48 struct drm_mode_create_dumb *args);
49int mtk_drm_gem_dumb_map_offset(struct drm_file *file_priv,
50 struct drm_device *dev, uint32_t handle,
51 uint64_t *offset);
52int mtk_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); 49int mtk_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
53int mtk_drm_gem_mmap_buf(struct drm_gem_object *obj, 50int mtk_drm_gem_mmap_buf(struct drm_gem_object *obj,
54 struct vm_area_struct *vma); 51 struct vm_area_struct *vma);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
index 1a59b9ab4aa8..6f121891430f 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
@@ -175,7 +175,7 @@ int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
175 175
176 err = drm_universal_plane_init(dev, plane, possible_crtcs, 176 err = drm_universal_plane_init(dev, plane, possible_crtcs,
177 &mtk_plane_funcs, formats, 177 &mtk_plane_funcs, formats,
178 ARRAY_SIZE(formats), type, NULL); 178 ARRAY_SIZE(formats), NULL, type, NULL);
179 if (err) { 179 if (err) {
180 DRM_ERROR("failed to initialize plane\n"); 180 DRM_ERROR("failed to initialize plane\n");
181 return err; 181 return err;
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index a31bd2a82de5..7e5e24c2152a 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -766,7 +766,6 @@ static const struct drm_encoder_helper_funcs mtk_dsi_encoder_helper_funcs = {
766}; 766};
767 767
768static const struct drm_connector_funcs mtk_dsi_connector_funcs = { 768static const struct drm_connector_funcs mtk_dsi_connector_funcs = {
769 .dpms = drm_atomic_helper_connector_dpms,
770 .fill_modes = drm_helper_probe_single_connector_modes, 769 .fill_modes = drm_helper_probe_single_connector_modes,
771 .destroy = drm_connector_cleanup, 770 .destroy = drm_connector_cleanup,
772 .reset = drm_atomic_helper_connector_reset, 771 .reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index f2437cd1e0f9..690c67507cbc 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1261,7 +1261,6 @@ static struct drm_encoder *mtk_hdmi_conn_best_enc(struct drm_connector *conn)
1261} 1261}
1262 1262
1263static const struct drm_connector_funcs mtk_hdmi_connector_funcs = { 1263static const struct drm_connector_funcs mtk_hdmi_connector_funcs = {
1264 .dpms = drm_atomic_helper_connector_dpms,
1265 .detect = hdmi_conn_detect, 1264 .detect = hdmi_conn_detect,
1266 .fill_modes = drm_helper_probe_single_connector_modes, 1265 .fill_modes = drm_helper_probe_single_connector_modes,
1267 .destroy = hdmi_conn_destroy, 1266 .destroy = hdmi_conn_destroy,
diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c
index a32d3b6e2e12..17e96fa47868 100644
--- a/drivers/gpu/drm/meson/meson_plane.c
+++ b/drivers/gpu/drm/meson/meson_plane.c
@@ -223,6 +223,7 @@ int meson_plane_create(struct meson_drm *priv)
223 &meson_plane_funcs, 223 &meson_plane_funcs,
224 supported_drm_formats, 224 supported_drm_formats,
225 ARRAY_SIZE(supported_drm_formats), 225 ARRAY_SIZE(supported_drm_formats),
226 NULL,
226 DRM_PLANE_TYPE_PRIMARY, "meson_primary_plane"); 227 DRM_PLANE_TYPE_PRIMARY, "meson_primary_plane");
227 228
228 drm_plane_helper_add(plane, &meson_plane_helper_funcs); 229 drm_plane_helper_add(plane, &meson_plane_helper_funcs);
diff --git a/drivers/gpu/drm/meson/meson_venc_cvbs.c b/drivers/gpu/drm/meson/meson_venc_cvbs.c
index 00775b397dba..79d95ca8a0c0 100644
--- a/drivers/gpu/drm/meson/meson_venc_cvbs.c
+++ b/drivers/gpu/drm/meson/meson_venc_cvbs.c
@@ -118,7 +118,6 @@ static int meson_cvbs_connector_mode_valid(struct drm_connector *connector,
118} 118}
119 119
120static const struct drm_connector_funcs meson_cvbs_connector_funcs = { 120static const struct drm_connector_funcs meson_cvbs_connector_funcs = {
121 .dpms = drm_atomic_helper_connector_dpms,
122 .detect = meson_cvbs_connector_detect, 121 .detect = meson_cvbs_connector_detect,
123 .fill_modes = drm_helper_probe_single_connector_modes, 122 .fill_modes = drm_helper_probe_single_connector_modes,
124 .destroy = meson_cvbs_connector_destroy, 123 .destroy = meson_cvbs_connector_destroy,
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index c88b6ec88dd2..04f1dfba12e5 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -237,11 +237,6 @@ mgag200_bo(struct ttm_buffer_object *bo)
237{ 237{
238 return container_of(bo, struct mgag200_bo, bo); 238 return container_of(bo, struct mgag200_bo, bo);
239} 239}
240 /* mgag200_crtc.c */
241void mga_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
242 u16 blue, int regno);
243void mga_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
244 u16 *blue, int regno);
245 240
246 /* mgag200_mode.c */ 241 /* mgag200_mode.c */
247int mgag200_modeset_init(struct mga_device *mdev); 242int mgag200_modeset_init(struct mga_device *mdev);
diff --git a/drivers/gpu/drm/mgag200/mgag200_fb.c b/drivers/gpu/drm/mgag200/mgag200_fb.c
index e94d78a32fe0..9d914ca69996 100644
--- a/drivers/gpu/drm/mgag200/mgag200_fb.c
+++ b/drivers/gpu/drm/mgag200/mgag200_fb.c
@@ -257,8 +257,6 @@ static int mga_fbdev_destroy(struct drm_device *dev,
257} 257}
258 258
259static const struct drm_fb_helper_funcs mga_fb_helper_funcs = { 259static const struct drm_fb_helper_funcs mga_fb_helper_funcs = {
260 .gamma_set = mga_crtc_fb_gamma_set,
261 .gamma_get = mga_crtc_fb_gamma_get,
262 .fb_probe = mgag200fb_create, 260 .fb_probe = mgag200fb_create,
263}; 261};
264 262
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index f4b53588e071..5e9cd4c0e8b6 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -27,15 +27,19 @@
27 27
28static void mga_crtc_load_lut(struct drm_crtc *crtc) 28static void mga_crtc_load_lut(struct drm_crtc *crtc)
29{ 29{
30 struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
31 struct drm_device *dev = crtc->dev; 30 struct drm_device *dev = crtc->dev;
32 struct mga_device *mdev = dev->dev_private; 31 struct mga_device *mdev = dev->dev_private;
33 struct drm_framebuffer *fb = crtc->primary->fb; 32 struct drm_framebuffer *fb = crtc->primary->fb;
33 u16 *r_ptr, *g_ptr, *b_ptr;
34 int i; 34 int i;
35 35
36 if (!crtc->enabled) 36 if (!crtc->enabled)
37 return; 37 return;
38 38
39 r_ptr = crtc->gamma_store;
40 g_ptr = r_ptr + crtc->gamma_size;
41 b_ptr = g_ptr + crtc->gamma_size;
42
39 WREG8(DAC_INDEX + MGA1064_INDEX, 0); 43 WREG8(DAC_INDEX + MGA1064_INDEX, 0);
40 44
41 if (fb && fb->format->cpp[0] * 8 == 16) { 45 if (fb && fb->format->cpp[0] * 8 == 16) {
@@ -46,25 +50,27 @@ static void mga_crtc_load_lut(struct drm_crtc *crtc)
46 if (i > (MGAG200_LUT_SIZE >> 1)) { 50 if (i > (MGAG200_LUT_SIZE >> 1)) {
47 r = b = 0; 51 r = b = 0;
48 } else { 52 } else {
49 r = mga_crtc->lut_r[i << 1]; 53 r = *r_ptr++ >> 8;
50 b = mga_crtc->lut_b[i << 1]; 54 b = *b_ptr++ >> 8;
55 r_ptr++;
56 b_ptr++;
51 } 57 }
52 } else { 58 } else {
53 r = mga_crtc->lut_r[i]; 59 r = *r_ptr++ >> 8;
54 b = mga_crtc->lut_b[i]; 60 b = *b_ptr++ >> 8;
55 } 61 }
56 /* VGA registers */ 62 /* VGA registers */
57 WREG8(DAC_INDEX + MGA1064_COL_PAL, r); 63 WREG8(DAC_INDEX + MGA1064_COL_PAL, r);
58 WREG8(DAC_INDEX + MGA1064_COL_PAL, mga_crtc->lut_g[i]); 64 WREG8(DAC_INDEX + MGA1064_COL_PAL, *g_ptr++ >> 8);
59 WREG8(DAC_INDEX + MGA1064_COL_PAL, b); 65 WREG8(DAC_INDEX + MGA1064_COL_PAL, b);
60 } 66 }
61 return; 67 return;
62 } 68 }
63 for (i = 0; i < MGAG200_LUT_SIZE; i++) { 69 for (i = 0; i < MGAG200_LUT_SIZE; i++) {
64 /* VGA registers */ 70 /* VGA registers */
65 WREG8(DAC_INDEX + MGA1064_COL_PAL, mga_crtc->lut_r[i]); 71 WREG8(DAC_INDEX + MGA1064_COL_PAL, *r_ptr++ >> 8);
66 WREG8(DAC_INDEX + MGA1064_COL_PAL, mga_crtc->lut_g[i]); 72 WREG8(DAC_INDEX + MGA1064_COL_PAL, *g_ptr++ >> 8);
67 WREG8(DAC_INDEX + MGA1064_COL_PAL, mga_crtc->lut_b[i]); 73 WREG8(DAC_INDEX + MGA1064_COL_PAL, *b_ptr++ >> 8);
68 } 74 }
69} 75}
70 76
@@ -1399,14 +1405,6 @@ static int mga_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
1399 u16 *blue, uint32_t size, 1405 u16 *blue, uint32_t size,
1400 struct drm_modeset_acquire_ctx *ctx) 1406 struct drm_modeset_acquire_ctx *ctx)
1401{ 1407{
1402 struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1403 int i;
1404
1405 for (i = 0; i < size; i++) {
1406 mga_crtc->lut_r[i] = red[i] >> 8;
1407 mga_crtc->lut_g[i] = green[i] >> 8;
1408 mga_crtc->lut_b[i] = blue[i] >> 8;
1409 }
1410 mga_crtc_load_lut(crtc); 1408 mga_crtc_load_lut(crtc);
1411 1409
1412 return 0; 1410 return 0;
@@ -1455,14 +1453,12 @@ static const struct drm_crtc_helper_funcs mga_helper_funcs = {
1455 .mode_set_base = mga_crtc_mode_set_base, 1453 .mode_set_base = mga_crtc_mode_set_base,
1456 .prepare = mga_crtc_prepare, 1454 .prepare = mga_crtc_prepare,
1457 .commit = mga_crtc_commit, 1455 .commit = mga_crtc_commit,
1458 .load_lut = mga_crtc_load_lut,
1459}; 1456};
1460 1457
1461/* CRTC setup */ 1458/* CRTC setup */
1462static void mga_crtc_init(struct mga_device *mdev) 1459static void mga_crtc_init(struct mga_device *mdev)
1463{ 1460{
1464 struct mga_crtc *mga_crtc; 1461 struct mga_crtc *mga_crtc;
1465 int i;
1466 1462
1467 mga_crtc = kzalloc(sizeof(struct mga_crtc) + 1463 mga_crtc = kzalloc(sizeof(struct mga_crtc) +
1468 (MGAG200FB_CONN_LIMIT * sizeof(struct drm_connector *)), 1464 (MGAG200FB_CONN_LIMIT * sizeof(struct drm_connector *)),
@@ -1476,37 +1472,9 @@ static void mga_crtc_init(struct mga_device *mdev)
1476 drm_mode_crtc_set_gamma_size(&mga_crtc->base, MGAG200_LUT_SIZE); 1472 drm_mode_crtc_set_gamma_size(&mga_crtc->base, MGAG200_LUT_SIZE);
1477 mdev->mode_info.crtc = mga_crtc; 1473 mdev->mode_info.crtc = mga_crtc;
1478 1474
1479 for (i = 0; i < MGAG200_LUT_SIZE; i++) {
1480 mga_crtc->lut_r[i] = i;
1481 mga_crtc->lut_g[i] = i;
1482 mga_crtc->lut_b[i] = i;
1483 }
1484
1485 drm_crtc_helper_add(&mga_crtc->base, &mga_helper_funcs); 1475 drm_crtc_helper_add(&mga_crtc->base, &mga_helper_funcs);
1486} 1476}
1487 1477
1488/** Sets the color ramps on behalf of fbcon */
1489void mga_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
1490 u16 blue, int regno)
1491{
1492 struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1493
1494 mga_crtc->lut_r[regno] = red >> 8;
1495 mga_crtc->lut_g[regno] = green >> 8;
1496 mga_crtc->lut_b[regno] = blue >> 8;
1497}
1498
1499/** Gets the color ramps on behalf of fbcon */
1500void mga_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
1501 u16 *blue, int regno)
1502{
1503 struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1504
1505 *red = (u16)mga_crtc->lut_r[regno] << 8;
1506 *green = (u16)mga_crtc->lut_g[regno] << 8;
1507 *blue = (u16)mga_crtc->lut_b[regno] << 8;
1508}
1509
1510/* 1478/*
1511 * The encoder comes after the CRTC in the output pipeline, but before 1479 * The encoder comes after the CRTC in the output pipeline, but before
1512 * the connector. It's responsible for ensuring that the digital 1480 * the connector. It's responsible for ensuring that the digital
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c
index a879ffa534b4..855248132b2b 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -626,7 +626,6 @@ static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge,
626} 626}
627 627
628static const struct drm_connector_funcs dsi_mgr_connector_funcs = { 628static const struct drm_connector_funcs dsi_mgr_connector_funcs = {
629 .dpms = drm_atomic_helper_connector_dpms,
630 .detect = dsi_mgr_connector_detect, 629 .detect = dsi_mgr_connector_detect,
631 .fill_modes = drm_helper_probe_single_connector_modes, 630 .fill_modes = drm_helper_probe_single_connector_modes,
632 .destroy = dsi_mgr_connector_destroy, 631 .destroy = dsi_mgr_connector_destroy,
diff --git a/drivers/gpu/drm/msm/edp/edp_connector.c b/drivers/gpu/drm/msm/edp/edp_connector.c
index 5960628ceb93..6f3fc6b0f0a3 100644
--- a/drivers/gpu/drm/msm/edp/edp_connector.c
+++ b/drivers/gpu/drm/msm/edp/edp_connector.c
@@ -92,7 +92,6 @@ static int edp_connector_mode_valid(struct drm_connector *connector,
92} 92}
93 93
94static const struct drm_connector_funcs edp_connector_funcs = { 94static const struct drm_connector_funcs edp_connector_funcs = {
95 .dpms = drm_atomic_helper_connector_dpms,
96 .detect = edp_connector_detect, 95 .detect = edp_connector_detect,
97 .fill_modes = drm_helper_probe_single_connector_modes, 96 .fill_modes = drm_helper_probe_single_connector_modes,
98 .destroy = edp_connector_destroy, 97 .destroy = edp_connector_destroy,
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c
index a2515b466ce5..71536d9c7fe8 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c
@@ -407,7 +407,6 @@ static int msm_hdmi_connector_mode_valid(struct drm_connector *connector,
407} 407}
408 408
409static const struct drm_connector_funcs hdmi_connector_funcs = { 409static const struct drm_connector_funcs hdmi_connector_funcs = {
410 .dpms = drm_atomic_helper_connector_dpms,
411 .detect = hdmi_connector_detect, 410 .detect = hdmi_connector_detect,
412 .fill_modes = drm_helper_probe_single_connector_modes, 411 .fill_modes = drm_helper_probe_single_connector_modes,
413 .destroy = hdmi_connector_destroy, 412 .destroy = hdmi_connector_destroy,
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c
index 3c7a9d343e05..47fa2aba1983 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c
@@ -484,7 +484,6 @@ static const struct drm_crtc_funcs mdp4_crtc_funcs = {
484 .set_config = drm_atomic_helper_set_config, 484 .set_config = drm_atomic_helper_set_config,
485 .destroy = mdp4_crtc_destroy, 485 .destroy = mdp4_crtc_destroy,
486 .page_flip = drm_atomic_helper_page_flip, 486 .page_flip = drm_atomic_helper_page_flip,
487 .set_property = drm_atomic_helper_crtc_set_property,
488 .cursor_set = mdp4_crtc_cursor_set, 487 .cursor_set = mdp4_crtc_cursor_set,
489 .cursor_move = mdp4_crtc_cursor_move, 488 .cursor_move = mdp4_crtc_cursor_move,
490 .reset = drm_atomic_helper_crtc_reset, 489 .reset = drm_atomic_helper_crtc_reset,
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
index bcd1f5cac72c..f7f087419ed8 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
@@ -114,7 +114,7 @@ static void mdp4_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *st
114 mdp4_enable(mdp4_kms); 114 mdp4_enable(mdp4_kms);
115 115
116 /* see 119ecb7fd */ 116 /* see 119ecb7fd */
117 for_each_crtc_in_state(state, crtc, crtc_state, i) 117 for_each_new_crtc_in_state(state, crtc, crtc_state, i)
118 drm_crtc_vblank_get(crtc); 118 drm_crtc_vblank_get(crtc);
119} 119}
120 120
@@ -126,7 +126,7 @@ static void mdp4_complete_commit(struct msm_kms *kms, struct drm_atomic_state *s
126 struct drm_crtc_state *crtc_state; 126 struct drm_crtc_state *crtc_state;
127 127
128 /* see 119ecb7fd */ 128 /* see 119ecb7fd */
129 for_each_crtc_in_state(state, crtc, crtc_state, i) 129 for_each_new_crtc_in_state(state, crtc, crtc_state, i)
130 drm_crtc_vblank_put(crtc); 130 drm_crtc_vblank_put(crtc);
131 131
132 mdp4_disable(mdp4_kms); 132 mdp4_disable(mdp4_kms);
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c
index 353429b05733..e3b1c86b7aae 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c
@@ -91,7 +91,6 @@ static int mdp4_lvds_connector_mode_valid(struct drm_connector *connector,
91} 91}
92 92
93static const struct drm_connector_funcs mdp4_lvds_connector_funcs = { 93static const struct drm_connector_funcs mdp4_lvds_connector_funcs = {
94 .dpms = drm_atomic_helper_connector_dpms,
95 .detect = mdp4_lvds_connector_detect, 94 .detect = mdp4_lvds_connector_detect,
96 .fill_modes = drm_helper_probe_single_connector_modes, 95 .fill_modes = drm_helper_probe_single_connector_modes,
97 .destroy = mdp4_lvds_connector_destroy, 96 .destroy = mdp4_lvds_connector_destroy,
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c
index a20e3d644523..7a1ad3af08e3 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c
@@ -401,7 +401,7 @@ struct drm_plane *mdp4_plane_init(struct drm_device *dev,
401 type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; 401 type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
402 ret = drm_universal_plane_init(dev, plane, 0xff, &mdp4_plane_funcs, 402 ret = drm_universal_plane_init(dev, plane, 0xff, &mdp4_plane_funcs,
403 mdp4_plane->formats, mdp4_plane->nformats, 403 mdp4_plane->formats, mdp4_plane->nformats,
404 type, NULL); 404 NULL, type, NULL);
405 if (ret) 405 if (ret)
406 goto fail; 406 goto fail;
407 407
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
index 4322a502555a..5e3bc7224eee 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
@@ -919,7 +919,6 @@ static const struct drm_crtc_funcs mdp5_crtc_funcs = {
919 .set_config = drm_atomic_helper_set_config, 919 .set_config = drm_atomic_helper_set_config,
920 .destroy = mdp5_crtc_destroy, 920 .destroy = mdp5_crtc_destroy,
921 .page_flip = drm_atomic_helper_page_flip, 921 .page_flip = drm_atomic_helper_page_flip,
922 .set_property = drm_atomic_helper_crtc_set_property,
923 .reset = mdp5_crtc_reset, 922 .reset = mdp5_crtc_reset,
924 .atomic_duplicate_state = mdp5_crtc_duplicate_state, 923 .atomic_duplicate_state = mdp5_crtc_duplicate_state,
925 .atomic_destroy_state = mdp5_crtc_destroy_state, 924 .atomic_destroy_state = mdp5_crtc_destroy_state,
@@ -932,7 +931,6 @@ static const struct drm_crtc_funcs mdp5_crtc_no_lm_cursor_funcs = {
932 .set_config = drm_atomic_helper_set_config, 931 .set_config = drm_atomic_helper_set_config,
933 .destroy = mdp5_crtc_destroy, 932 .destroy = mdp5_crtc_destroy,
934 .page_flip = drm_atomic_helper_page_flip, 933 .page_flip = drm_atomic_helper_page_flip,
935 .set_property = drm_atomic_helper_crtc_set_property,
936 .reset = mdp5_crtc_reset, 934 .reset = mdp5_crtc_reset,
937 .atomic_duplicate_state = mdp5_crtc_duplicate_state, 935 .atomic_duplicate_state = mdp5_crtc_duplicate_state,
938 .atomic_destroy_state = mdp5_crtc_destroy_state, 936 .atomic_destroy_state = mdp5_crtc_destroy_state,
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
index fe3a4de1a433..818244ac4a4b 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
@@ -246,7 +246,6 @@ static const struct drm_plane_funcs mdp5_plane_funcs = {
246 .update_plane = drm_atomic_helper_update_plane, 246 .update_plane = drm_atomic_helper_update_plane,
247 .disable_plane = drm_atomic_helper_disable_plane, 247 .disable_plane = drm_atomic_helper_disable_plane,
248 .destroy = mdp5_plane_destroy, 248 .destroy = mdp5_plane_destroy,
249 .set_property = drm_atomic_helper_plane_set_property,
250 .atomic_set_property = mdp5_plane_atomic_set_property, 249 .atomic_set_property = mdp5_plane_atomic_set_property,
251 .atomic_get_property = mdp5_plane_atomic_get_property, 250 .atomic_get_property = mdp5_plane_atomic_get_property,
252 .reset = mdp5_plane_reset, 251 .reset = mdp5_plane_reset,
@@ -259,7 +258,6 @@ static const struct drm_plane_funcs mdp5_cursor_plane_funcs = {
259 .update_plane = mdp5_update_cursor_plane_legacy, 258 .update_plane = mdp5_update_cursor_plane_legacy,
260 .disable_plane = drm_atomic_helper_disable_plane, 259 .disable_plane = drm_atomic_helper_disable_plane,
261 .destroy = mdp5_plane_destroy, 260 .destroy = mdp5_plane_destroy,
262 .set_property = drm_atomic_helper_plane_set_property,
263 .atomic_set_property = mdp5_plane_atomic_set_property, 261 .atomic_set_property = mdp5_plane_atomic_set_property,
264 .atomic_get_property = mdp5_plane_atomic_get_property, 262 .atomic_get_property = mdp5_plane_atomic_get_property,
265 .reset = mdp5_plane_reset, 263 .reset = mdp5_plane_reset,
@@ -1139,12 +1137,12 @@ struct drm_plane *mdp5_plane_init(struct drm_device *dev,
1139 ret = drm_universal_plane_init(dev, plane, 0xff, 1137 ret = drm_universal_plane_init(dev, plane, 0xff,
1140 &mdp5_cursor_plane_funcs, 1138 &mdp5_cursor_plane_funcs,
1141 mdp5_plane->formats, mdp5_plane->nformats, 1139 mdp5_plane->formats, mdp5_plane->nformats,
1142 type, NULL); 1140 NULL, type, NULL);
1143 else 1141 else
1144 ret = drm_universal_plane_init(dev, plane, 0xff, 1142 ret = drm_universal_plane_init(dev, plane, 0xff,
1145 &mdp5_plane_funcs, 1143 &mdp5_plane_funcs,
1146 mdp5_plane->formats, mdp5_plane->nformats, 1144 mdp5_plane->formats, mdp5_plane->nformats,
1147 type, NULL); 1145 NULL, type, NULL);
1148 if (ret) 1146 if (ret)
1149 goto fail; 1147 goto fail;
1150 1148
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
index badfa8717317..025d454163b0 100644
--- a/drivers/gpu/drm/msm/msm_atomic.c
+++ b/drivers/gpu/drm/msm/msm_atomic.c
@@ -84,13 +84,13 @@ static void msm_atomic_wait_for_commit_done(struct drm_device *dev,
84 struct drm_atomic_state *old_state) 84 struct drm_atomic_state *old_state)
85{ 85{
86 struct drm_crtc *crtc; 86 struct drm_crtc *crtc;
87 struct drm_crtc_state *crtc_state; 87 struct drm_crtc_state *new_crtc_state;
88 struct msm_drm_private *priv = old_state->dev->dev_private; 88 struct msm_drm_private *priv = old_state->dev->dev_private;
89 struct msm_kms *kms = priv->kms; 89 struct msm_kms *kms = priv->kms;
90 int i; 90 int i;
91 91
92 for_each_crtc_in_state(old_state, crtc, crtc_state, i) { 92 for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
93 if (!crtc->state->enable) 93 if (!new_crtc_state->active)
94 continue; 94 continue;
95 95
96 kms->funcs->wait_for_crtc_commit_done(kms, crtc); 96 kms->funcs->wait_for_crtc_commit_done(kms, crtc);
@@ -195,7 +195,7 @@ int msm_atomic_commit(struct drm_device *dev,
195 struct drm_crtc *crtc; 195 struct drm_crtc *crtc;
196 struct drm_crtc_state *crtc_state; 196 struct drm_crtc_state *crtc_state;
197 struct drm_plane *plane; 197 struct drm_plane *plane;
198 struct drm_plane_state *plane_state; 198 struct drm_plane_state *old_plane_state, *new_plane_state;
199 int i, ret; 199 int i, ret;
200 200
201 ret = drm_atomic_helper_prepare_planes(dev, state); 201 ret = drm_atomic_helper_prepare_planes(dev, state);
@@ -211,19 +211,19 @@ int msm_atomic_commit(struct drm_device *dev,
211 /* 211 /*
212 * Figure out what crtcs we have: 212 * Figure out what crtcs we have:
213 */ 213 */
214 for_each_crtc_in_state(state, crtc, crtc_state, i) 214 for_each_new_crtc_in_state(state, crtc, crtc_state, i)
215 c->crtc_mask |= drm_crtc_mask(crtc); 215 c->crtc_mask |= drm_crtc_mask(crtc);
216 216
217 /* 217 /*
218 * Figure out what fence to wait for: 218 * Figure out what fence to wait for:
219 */ 219 */
220 for_each_plane_in_state(state, plane, plane_state, i) { 220 for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
221 if ((plane->state->fb != plane_state->fb) && plane_state->fb) { 221 if ((new_plane_state->fb != old_plane_state->fb) && new_plane_state->fb) {
222 struct drm_gem_object *obj = msm_framebuffer_bo(plane_state->fb, 0); 222 struct drm_gem_object *obj = msm_framebuffer_bo(new_plane_state->fb, 0);
223 struct msm_gem_object *msm_obj = to_msm_bo(obj); 223 struct msm_gem_object *msm_obj = to_msm_bo(obj);
224 struct dma_fence *fence = reservation_object_get_excl_rcu(msm_obj->resv); 224 struct dma_fence *fence = reservation_object_get_excl_rcu(msm_obj->resv);
225 225
226 drm_atomic_set_fence_for_plane(plane_state, fence); 226 drm_atomic_set_fence_for_plane(new_plane_state, fence);
227 } 227 }
228 } 228 }
229 229
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
index a34f41ce3599..93c38eb6d187 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
@@ -190,7 +190,7 @@ static int mxsfb_load(struct drm_device *drm, unsigned long flags)
190 } 190 }
191 191
192 ret = drm_simple_display_pipe_init(drm, &mxsfb->pipe, &mxsfb_funcs, 192 ret = drm_simple_display_pipe_init(drm, &mxsfb->pipe, &mxsfb_funcs,
193 mxsfb_formats, ARRAY_SIZE(mxsfb_formats), 193 mxsfb_formats, ARRAY_SIZE(mxsfb_formats), NULL,
194 &mxsfb->connector); 194 &mxsfb->connector);
195 if (ret < 0) { 195 if (ret < 0) {
196 dev_err(drm->dev, "Cannot setup simple display pipe\n"); 196 dev_err(drm->dev, "Cannot setup simple display pipe\n");
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_out.c b/drivers/gpu/drm/mxsfb/mxsfb_out.c
index f7d729aa09bd..e5edf016a439 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_out.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_out.c
@@ -74,7 +74,6 @@ static void mxsfb_panel_connector_destroy(struct drm_connector *connector)
74} 74}
75 75
76static const struct drm_connector_funcs mxsfb_panel_connector_funcs = { 76static const struct drm_connector_funcs mxsfb_panel_connector_funcs = {
77 .dpms = drm_atomic_helper_connector_dpms,
78 .detect = mxsfb_panel_connector_detect, 77 .detect = mxsfb_panel_connector_detect,
79 .fill_modes = drm_helper_probe_single_connector_modes, 78 .fill_modes = drm_helper_probe_single_connector_modes,
80 .destroy = mxsfb_panel_connector_destroy, 79 .destroy = mxsfb_panel_connector_destroy,
diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
index 4b4b0b496262..8f689f1f6122 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
@@ -764,13 +764,18 @@ nv_crtc_gamma_load(struct drm_crtc *crtc)
764 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 764 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
765 struct drm_device *dev = nv_crtc->base.dev; 765 struct drm_device *dev = nv_crtc->base.dev;
766 struct rgb { uint8_t r, g, b; } __attribute__((packed)) *rgbs; 766 struct rgb { uint8_t r, g, b; } __attribute__((packed)) *rgbs;
767 u16 *r, *g, *b;
767 int i; 768 int i;
768 769
769 rgbs = (struct rgb *)nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index].DAC; 770 rgbs = (struct rgb *)nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index].DAC;
771 r = crtc->gamma_store;
772 g = r + crtc->gamma_size;
773 b = g + crtc->gamma_size;
774
770 for (i = 0; i < 256; i++) { 775 for (i = 0; i < 256; i++) {
771 rgbs[i].r = nv_crtc->lut.r[i] >> 8; 776 rgbs[i].r = *r++ >> 8;
772 rgbs[i].g = nv_crtc->lut.g[i] >> 8; 777 rgbs[i].g = *g++ >> 8;
773 rgbs[i].b = nv_crtc->lut.b[i] >> 8; 778 rgbs[i].b = *b++ >> 8;
774 } 779 }
775 780
776 nouveau_hw_load_state_palette(dev, nv_crtc->index, &nv04_display(dev)->mode_reg); 781 nouveau_hw_load_state_palette(dev, nv_crtc->index, &nv04_display(dev)->mode_reg);
@@ -792,13 +797,6 @@ nv_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
792 struct drm_modeset_acquire_ctx *ctx) 797 struct drm_modeset_acquire_ctx *ctx)
793{ 798{
794 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 799 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
795 int i;
796
797 for (i = 0; i < size; i++) {
798 nv_crtc->lut.r[i] = r[i];
799 nv_crtc->lut.g[i] = g[i];
800 nv_crtc->lut.b[i] = b[i];
801 }
802 800
803 /* We need to know the depth before we upload, but it's possible to 801 /* We need to know the depth before we upload, but it's possible to
804 * get called before a framebuffer is bound. If this is the case, 802 * get called before a framebuffer is bound. If this is the case,
@@ -1095,7 +1093,6 @@ static const struct drm_crtc_helper_funcs nv04_crtc_helper_funcs = {
1095 .mode_set = nv_crtc_mode_set, 1093 .mode_set = nv_crtc_mode_set,
1096 .mode_set_base = nv04_crtc_mode_set_base, 1094 .mode_set_base = nv04_crtc_mode_set_base,
1097 .mode_set_base_atomic = nv04_crtc_mode_set_base_atomic, 1095 .mode_set_base_atomic = nv04_crtc_mode_set_base_atomic,
1098 .load_lut = nv_crtc_gamma_load,
1099 .disable = nv_crtc_disable, 1096 .disable = nv_crtc_disable,
1100}; 1097};
1101 1098
@@ -1103,17 +1100,12 @@ int
1103nv04_crtc_create(struct drm_device *dev, int crtc_num) 1100nv04_crtc_create(struct drm_device *dev, int crtc_num)
1104{ 1101{
1105 struct nouveau_crtc *nv_crtc; 1102 struct nouveau_crtc *nv_crtc;
1106 int ret, i; 1103 int ret;
1107 1104
1108 nv_crtc = kzalloc(sizeof(*nv_crtc), GFP_KERNEL); 1105 nv_crtc = kzalloc(sizeof(*nv_crtc), GFP_KERNEL);
1109 if (!nv_crtc) 1106 if (!nv_crtc)
1110 return -ENOMEM; 1107 return -ENOMEM;
1111 1108
1112 for (i = 0; i < 256; i++) {
1113 nv_crtc->lut.r[i] = i << 8;
1114 nv_crtc->lut.g[i] = i << 8;
1115 nv_crtc->lut.b[i] = i << 8;
1116 }
1117 nv_crtc->lut.depth = 0; 1109 nv_crtc->lut.depth = 0;
1118 1110
1119 nv_crtc->index = crtc_num; 1111 nv_crtc->index = crtc_num;
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 147b22163f9f..196eb668d30d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -770,9 +770,6 @@ nouveau_connector_set_property(struct drm_connector *connector,
770 struct drm_encoder *encoder = to_drm_encoder(nv_encoder); 770 struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
771 int ret; 771 int ret;
772 772
773 if (drm_drv_uses_atomic_modeset(connector->dev))
774 return drm_atomic_helper_connector_set_property(connector, property, value);
775
776 ret = connector->funcs->atomic_set_property(&nv_connector->base, 773 ret = connector->funcs->atomic_set_property(&nv_connector->base,
777 &asyc->state, 774 &asyc->state,
778 property, value); 775 property, value);
@@ -1075,17 +1072,9 @@ nouveau_connector_helper_funcs = {
1075 .best_encoder = nouveau_connector_best_encoder, 1072 .best_encoder = nouveau_connector_best_encoder,
1076}; 1073};
1077 1074
1078static int
1079nouveau_connector_dpms(struct drm_connector *connector, int mode)
1080{
1081 if (drm_drv_uses_atomic_modeset(connector->dev))
1082 return drm_atomic_helper_connector_dpms(connector, mode);
1083 return drm_helper_connector_dpms(connector, mode);
1084}
1085
1086static const struct drm_connector_funcs 1075static const struct drm_connector_funcs
1087nouveau_connector_funcs = { 1076nouveau_connector_funcs = {
1088 .dpms = nouveau_connector_dpms, 1077 .dpms = drm_helper_connector_dpms,
1089 .reset = nouveau_conn_reset, 1078 .reset = nouveau_conn_reset,
1090 .detect = nouveau_connector_detect, 1079 .detect = nouveau_connector_detect,
1091 .force = nouveau_connector_force, 1080 .force = nouveau_connector_force,
@@ -1100,7 +1089,7 @@ nouveau_connector_funcs = {
1100 1089
1101static const struct drm_connector_funcs 1090static const struct drm_connector_funcs
1102nouveau_connector_funcs_lvds = { 1091nouveau_connector_funcs_lvds = {
1103 .dpms = nouveau_connector_dpms, 1092 .dpms = drm_helper_connector_dpms,
1104 .reset = nouveau_conn_reset, 1093 .reset = nouveau_conn_reset,
1105 .detect = nouveau_connector_detect_lvds, 1094 .detect = nouveau_connector_detect_lvds,
1106 .force = nouveau_connector_force, 1095 .force = nouveau_connector_force,
diff --git a/drivers/gpu/drm/nouveau/nouveau_crtc.h b/drivers/gpu/drm/nouveau/nouveau_crtc.h
index 050fcf30a0d2..b7a18fbee6dc 100644
--- a/drivers/gpu/drm/nouveau/nouveau_crtc.h
+++ b/drivers/gpu/drm/nouveau/nouveau_crtc.h
@@ -61,9 +61,6 @@ struct nouveau_crtc {
61 61
62 struct { 62 struct {
63 struct nouveau_bo *nvbo; 63 struct nouveau_bo *nvbo;
64 uint16_t r[256];
65 uint16_t g[256];
66 uint16_t b[256];
67 int depth; 64 int depth;
68 } lut; 65 } lut;
69 66
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 2600b3b9f2e7..df7e2037031a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -998,7 +998,6 @@ driver_stub = {
998 998
999 .dumb_create = nouveau_display_dumb_create, 999 .dumb_create = nouveau_display_dumb_create,
1000 .dumb_map_offset = nouveau_display_dumb_map_offset, 1000 .dumb_map_offset = nouveau_display_dumb_map_offset,
1001 .dumb_destroy = drm_gem_dumb_destroy,
1002 1001
1003 .name = DRIVER_NAME, 1002 .name = DRIVER_NAME,
1004 .desc = DRIVER_DESC, 1003 .desc = DRIVER_DESC,
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index 2665a078b6da..f7707849bb53 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -278,26 +278,6 @@ nouveau_fbcon_accel_init(struct drm_device *dev)
278 info->fbops = &nouveau_fbcon_ops; 278 info->fbops = &nouveau_fbcon_ops;
279} 279}
280 280
281static void nouveau_fbcon_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
282 u16 blue, int regno)
283{
284 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
285
286 nv_crtc->lut.r[regno] = red;
287 nv_crtc->lut.g[regno] = green;
288 nv_crtc->lut.b[regno] = blue;
289}
290
291static void nouveau_fbcon_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
292 u16 *blue, int regno)
293{
294 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
295
296 *red = nv_crtc->lut.r[regno];
297 *green = nv_crtc->lut.g[regno];
298 *blue = nv_crtc->lut.b[regno];
299}
300
301static void 281static void
302nouveau_fbcon_zfill(struct drm_device *dev, struct nouveau_fbdev *fbcon) 282nouveau_fbcon_zfill(struct drm_device *dev, struct nouveau_fbdev *fbcon)
303{ 283{
@@ -467,8 +447,6 @@ void nouveau_fbcon_gpu_lockup(struct fb_info *info)
467} 447}
468 448
469static const struct drm_fb_helper_funcs nouveau_fbcon_helper_funcs = { 449static const struct drm_fb_helper_funcs nouveau_fbcon_helper_funcs = {
470 .gamma_set = nouveau_fbcon_gamma_set,
471 .gamma_get = nouveau_fbcon_gamma_get,
472 .fb_probe = nouveau_fbcon_create, 450 .fb_probe = nouveau_fbcon_create,
473}; 451};
474 452
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 747c99c1e474..6dee4071bb3f 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -1055,7 +1055,6 @@ nv50_wndw = {
1055 .disable_plane = drm_atomic_helper_disable_plane, 1055 .disable_plane = drm_atomic_helper_disable_plane,
1056 .destroy = nv50_wndw_destroy, 1056 .destroy = nv50_wndw_destroy,
1057 .reset = nv50_wndw_reset, 1057 .reset = nv50_wndw_reset,
1058 .set_property = drm_atomic_helper_plane_set_property,
1059 .atomic_duplicate_state = nv50_wndw_atomic_duplicate_state, 1058 .atomic_duplicate_state = nv50_wndw_atomic_duplicate_state,
1060 .atomic_destroy_state = nv50_wndw_atomic_destroy_state, 1059 .atomic_destroy_state = nv50_wndw_atomic_destroy_state,
1061}; 1060};
@@ -1083,8 +1082,9 @@ nv50_wndw_ctor(const struct nv50_wndw_func *func, struct drm_device *dev,
1083 wndw->func = func; 1082 wndw->func = func;
1084 wndw->dmac = dmac; 1083 wndw->dmac = dmac;
1085 1084
1086 ret = drm_universal_plane_init(dev, &wndw->plane, 0, &nv50_wndw, format, 1085 ret = drm_universal_plane_init(dev, &wndw->plane, 0, &nv50_wndw,
1087 nformat, type, "%s-%d", name, index); 1086 format, nformat, NULL,
1087 type, "%s-%d", name, index);
1088 if (ret) 1088 if (ret)
1089 return ret; 1089 return ret;
1090 1090
@@ -2103,7 +2103,7 @@ nv50_head_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state)
2103 2103
2104 NV_ATOMIC(drm, "%s atomic_check %d\n", crtc->name, asyh->state.active); 2104 NV_ATOMIC(drm, "%s atomic_check %d\n", crtc->name, asyh->state.active);
2105 if (asyh->state.active) { 2105 if (asyh->state.active) {
2106 for_each_connector_in_state(asyh->state.state, conn, conns, i) { 2106 for_each_new_connector_in_state(asyh->state.state, conn, conns, i) {
2107 if (conns->crtc == crtc) { 2107 if (conns->crtc == crtc) {
2108 asyc = nouveau_conn_atom(conns); 2108 asyc = nouveau_conn_atom(conns);
2109 break; 2109 break;
@@ -2204,28 +2204,29 @@ nv50_head_lut_load(struct drm_crtc *crtc)
2204 struct nv50_disp *disp = nv50_disp(crtc->dev); 2204 struct nv50_disp *disp = nv50_disp(crtc->dev);
2205 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 2205 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
2206 void __iomem *lut = nvbo_kmap_obj_iovirtual(nv_crtc->lut.nvbo); 2206 void __iomem *lut = nvbo_kmap_obj_iovirtual(nv_crtc->lut.nvbo);
2207 u16 *r, *g, *b;
2207 int i; 2208 int i;
2208 2209
2209 for (i = 0; i < 256; i++) { 2210 r = crtc->gamma_store;
2210 u16 r = nv_crtc->lut.r[i] >> 2; 2211 g = r + crtc->gamma_size;
2211 u16 g = nv_crtc->lut.g[i] >> 2; 2212 b = g + crtc->gamma_size;
2212 u16 b = nv_crtc->lut.b[i] >> 2;
2213 2213
2214 for (i = 0; i < 256; i++) {
2214 if (disp->disp->oclass < GF110_DISP) { 2215 if (disp->disp->oclass < GF110_DISP) {
2215 writew(r + 0x0000, lut + (i * 0x08) + 0); 2216 writew((*r++ >> 2) + 0x0000, lut + (i * 0x08) + 0);
2216 writew(g + 0x0000, lut + (i * 0x08) + 2); 2217 writew((*g++ >> 2) + 0x0000, lut + (i * 0x08) + 2);
2217 writew(b + 0x0000, lut + (i * 0x08) + 4); 2218 writew((*b++ >> 2) + 0x0000, lut + (i * 0x08) + 4);
2218 } else { 2219 } else {
2219 writew(r + 0x6000, lut + (i * 0x20) + 0); 2220 /* 0x6000 interferes with the 14-bit color??? */
2220 writew(g + 0x6000, lut + (i * 0x20) + 2); 2221 writew((*r++ >> 2) + 0x6000, lut + (i * 0x20) + 0);
2221 writew(b + 0x6000, lut + (i * 0x20) + 4); 2222 writew((*g++ >> 2) + 0x6000, lut + (i * 0x20) + 2);
2223 writew((*b++ >> 2) + 0x6000, lut + (i * 0x20) + 4);
2222 } 2224 }
2223 } 2225 }
2224} 2226}
2225 2227
2226static const struct drm_crtc_helper_funcs 2228static const struct drm_crtc_helper_funcs
2227nv50_head_help = { 2229nv50_head_help = {
2228 .load_lut = nv50_head_lut_load,
2229 .atomic_check = nv50_head_atomic_check, 2230 .atomic_check = nv50_head_atomic_check,
2230}; 2231};
2231 2232
@@ -2234,15 +2235,6 @@ nv50_head_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
2234 uint32_t size, 2235 uint32_t size,
2235 struct drm_modeset_acquire_ctx *ctx) 2236 struct drm_modeset_acquire_ctx *ctx)
2236{ 2237{
2237 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
2238 u32 i;
2239
2240 for (i = 0; i < size; i++) {
2241 nv_crtc->lut.r[i] = r[i];
2242 nv_crtc->lut.g[i] = g[i];
2243 nv_crtc->lut.b[i] = b[i];
2244 }
2245
2246 nv50_head_lut_load(crtc); 2238 nv50_head_lut_load(crtc);
2247 return 0; 2239 return 0;
2248} 2240}
@@ -2325,7 +2317,6 @@ nv50_head_func = {
2325 .destroy = nv50_head_destroy, 2317 .destroy = nv50_head_destroy,
2326 .set_config = drm_atomic_helper_set_config, 2318 .set_config = drm_atomic_helper_set_config,
2327 .page_flip = drm_atomic_helper_page_flip, 2319 .page_flip = drm_atomic_helper_page_flip,
2328 .set_property = drm_atomic_helper_crtc_set_property,
2329 .atomic_duplicate_state = nv50_head_atomic_duplicate_state, 2320 .atomic_duplicate_state = nv50_head_atomic_duplicate_state,
2330 .atomic_destroy_state = nv50_head_atomic_destroy_state, 2321 .atomic_destroy_state = nv50_head_atomic_destroy_state,
2331}; 2322};
@@ -2340,19 +2331,13 @@ nv50_head_create(struct drm_device *dev, int index)
2340 struct nv50_base *base; 2331 struct nv50_base *base;
2341 struct nv50_curs *curs; 2332 struct nv50_curs *curs;
2342 struct drm_crtc *crtc; 2333 struct drm_crtc *crtc;
2343 int ret, i; 2334 int ret;
2344 2335
2345 head = kzalloc(sizeof(*head), GFP_KERNEL); 2336 head = kzalloc(sizeof(*head), GFP_KERNEL);
2346 if (!head) 2337 if (!head)
2347 return -ENOMEM; 2338 return -ENOMEM;
2348 2339
2349 head->base.index = index; 2340 head->base.index = index;
2350 for (i = 0; i < 256; i++) {
2351 head->base.lut.r[i] = i << 8;
2352 head->base.lut.g[i] = i << 8;
2353 head->base.lut.b[i] = i << 8;
2354 }
2355
2356 ret = nv50_base_new(drm, head, &base); 2341 ret = nv50_base_new(drm, head, &base);
2357 if (ret == 0) 2342 if (ret == 0)
2358 ret = nv50_curs_new(drm, head, &curs); 2343 ret = nv50_curs_new(drm, head, &curs);
@@ -3120,11 +3105,9 @@ nv50_mstc_destroy(struct drm_connector *connector)
3120 3105
3121static const struct drm_connector_funcs 3106static const struct drm_connector_funcs
3122nv50_mstc = { 3107nv50_mstc = {
3123 .dpms = drm_atomic_helper_connector_dpms,
3124 .reset = nouveau_conn_reset, 3108 .reset = nouveau_conn_reset,
3125 .detect = nv50_mstc_detect, 3109 .detect = nv50_mstc_detect,
3126 .fill_modes = drm_helper_probe_single_connector_modes, 3110 .fill_modes = drm_helper_probe_single_connector_modes,
3127 .set_property = drm_atomic_helper_connector_set_property,
3128 .destroy = nv50_mstc_destroy, 3111 .destroy = nv50_mstc_destroy,
3129 .atomic_duplicate_state = nouveau_conn_atomic_duplicate_state, 3112 .atomic_duplicate_state = nouveau_conn_atomic_duplicate_state,
3130 .atomic_destroy_state = nouveau_conn_atomic_destroy_state, 3113 .atomic_destroy_state = nouveau_conn_atomic_destroy_state,
@@ -3905,9 +3888,9 @@ static void
3905nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) 3888nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
3906{ 3889{
3907 struct drm_device *dev = state->dev; 3890 struct drm_device *dev = state->dev;
3908 struct drm_crtc_state *crtc_state; 3891 struct drm_crtc_state *new_crtc_state;
3909 struct drm_crtc *crtc; 3892 struct drm_crtc *crtc;
3910 struct drm_plane_state *plane_state; 3893 struct drm_plane_state *new_plane_state;
3911 struct drm_plane *plane; 3894 struct drm_plane *plane;
3912 struct nouveau_drm *drm = nouveau_drm(dev); 3895 struct nouveau_drm *drm = nouveau_drm(dev);
3913 struct nv50_disp *disp = nv50_disp(dev); 3896 struct nv50_disp *disp = nv50_disp(dev);
@@ -3926,8 +3909,8 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
3926 mutex_lock(&disp->mutex); 3909 mutex_lock(&disp->mutex);
3927 3910
3928 /* Disable head(s). */ 3911 /* Disable head(s). */
3929 for_each_crtc_in_state(state, crtc, crtc_state, i) { 3912 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
3930 struct nv50_head_atom *asyh = nv50_head_atom(crtc->state); 3913 struct nv50_head_atom *asyh = nv50_head_atom(new_crtc_state);
3931 struct nv50_head *head = nv50_head(crtc); 3914 struct nv50_head *head = nv50_head(crtc);
3932 3915
3933 NV_ATOMIC(drm, "%s: clr %04x (set %04x)\n", crtc->name, 3916 NV_ATOMIC(drm, "%s: clr %04x (set %04x)\n", crtc->name,
@@ -3940,8 +3923,8 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
3940 } 3923 }
3941 3924
3942 /* Disable plane(s). */ 3925 /* Disable plane(s). */
3943 for_each_plane_in_state(state, plane, plane_state, i) { 3926 for_each_new_plane_in_state(state, plane, new_plane_state, i) {
3944 struct nv50_wndw_atom *asyw = nv50_wndw_atom(plane->state); 3927 struct nv50_wndw_atom *asyw = nv50_wndw_atom(new_plane_state);
3945 struct nv50_wndw *wndw = nv50_wndw(plane); 3928 struct nv50_wndw *wndw = nv50_wndw(plane);
3946 3929
3947 NV_ATOMIC(drm, "%s: clr %02x (set %02x)\n", plane->name, 3930 NV_ATOMIC(drm, "%s: clr %02x (set %02x)\n", plane->name,
@@ -4006,8 +3989,8 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
4006 } 3989 }
4007 3990
4008 /* Update head(s). */ 3991 /* Update head(s). */
4009 for_each_crtc_in_state(state, crtc, crtc_state, i) { 3992 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
4010 struct nv50_head_atom *asyh = nv50_head_atom(crtc->state); 3993 struct nv50_head_atom *asyh = nv50_head_atom(new_crtc_state);
4011 struct nv50_head *head = nv50_head(crtc); 3994 struct nv50_head *head = nv50_head(crtc);
4012 3995
4013 NV_ATOMIC(drm, "%s: set %04x (clr %04x)\n", crtc->name, 3996 NV_ATOMIC(drm, "%s: set %04x (clr %04x)\n", crtc->name,
@@ -4019,14 +4002,14 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
4019 } 4002 }
4020 } 4003 }
4021 4004
4022 for_each_crtc_in_state(state, crtc, crtc_state, i) { 4005 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
4023 if (crtc->state->event) 4006 if (new_crtc_state->event)
4024 drm_crtc_vblank_get(crtc); 4007 drm_crtc_vblank_get(crtc);
4025 } 4008 }
4026 4009
4027 /* Update plane(s). */ 4010 /* Update plane(s). */
4028 for_each_plane_in_state(state, plane, plane_state, i) { 4011 for_each_new_plane_in_state(state, plane, new_plane_state, i) {
4029 struct nv50_wndw_atom *asyw = nv50_wndw_atom(plane->state); 4012 struct nv50_wndw_atom *asyw = nv50_wndw_atom(new_plane_state);
4030 struct nv50_wndw *wndw = nv50_wndw(plane); 4013 struct nv50_wndw *wndw = nv50_wndw(plane);
4031 4014
4032 NV_ATOMIC(drm, "%s: set %02x (clr %02x)\n", plane->name, 4015 NV_ATOMIC(drm, "%s: set %02x (clr %02x)\n", plane->name,
@@ -4056,23 +4039,23 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
4056 mutex_unlock(&disp->mutex); 4039 mutex_unlock(&disp->mutex);
4057 4040
4058 /* Wait for HW to signal completion. */ 4041 /* Wait for HW to signal completion. */
4059 for_each_plane_in_state(state, plane, plane_state, i) { 4042 for_each_new_plane_in_state(state, plane, new_plane_state, i) {
4060 struct nv50_wndw_atom *asyw = nv50_wndw_atom(plane->state); 4043 struct nv50_wndw_atom *asyw = nv50_wndw_atom(new_plane_state);
4061 struct nv50_wndw *wndw = nv50_wndw(plane); 4044 struct nv50_wndw *wndw = nv50_wndw(plane);
4062 int ret = nv50_wndw_wait_armed(wndw, asyw); 4045 int ret = nv50_wndw_wait_armed(wndw, asyw);
4063 if (ret) 4046 if (ret)
4064 NV_ERROR(drm, "%s: timeout\n", plane->name); 4047 NV_ERROR(drm, "%s: timeout\n", plane->name);
4065 } 4048 }
4066 4049
4067 for_each_crtc_in_state(state, crtc, crtc_state, i) { 4050 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
4068 if (crtc->state->event) { 4051 if (new_crtc_state->event) {
4069 unsigned long flags; 4052 unsigned long flags;
4070 /* Get correct count/ts if racing with vblank irq */ 4053 /* Get correct count/ts if racing with vblank irq */
4071 drm_crtc_accurate_vblank_count(crtc); 4054 drm_crtc_accurate_vblank_count(crtc);
4072 spin_lock_irqsave(&crtc->dev->event_lock, flags); 4055 spin_lock_irqsave(&crtc->dev->event_lock, flags);
4073 drm_crtc_send_vblank_event(crtc, crtc->state->event); 4056 drm_crtc_send_vblank_event(crtc, new_crtc_state->event);
4074 spin_unlock_irqrestore(&crtc->dev->event_lock, flags); 4057 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
4075 crtc->state->event = NULL; 4058 new_crtc_state->event = NULL;
4076 drm_crtc_vblank_put(crtc); 4059 drm_crtc_vblank_put(crtc);
4077 } 4060 }
4078 } 4061 }
@@ -4097,7 +4080,7 @@ nv50_disp_atomic_commit(struct drm_device *dev,
4097{ 4080{
4098 struct nouveau_drm *drm = nouveau_drm(dev); 4081 struct nouveau_drm *drm = nouveau_drm(dev);
4099 struct nv50_disp *disp = nv50_disp(dev); 4082 struct nv50_disp *disp = nv50_disp(dev);
4100 struct drm_plane_state *plane_state; 4083 struct drm_plane_state *old_plane_state;
4101 struct drm_plane *plane; 4084 struct drm_plane *plane;
4102 struct drm_crtc *crtc; 4085 struct drm_crtc *crtc;
4103 bool active = false; 4086 bool active = false;
@@ -4127,9 +4110,10 @@ nv50_disp_atomic_commit(struct drm_device *dev,
4127 if (ret) 4110 if (ret)
4128 goto err_cleanup; 4111 goto err_cleanup;
4129 4112
4130 for_each_plane_in_state(state, plane, plane_state, i) { 4113 for_each_old_plane_in_state(state, plane, old_plane_state, i) {
4131 struct nv50_wndw_atom *asyw = nv50_wndw_atom(plane_state); 4114 struct nv50_wndw_atom *asyw = nv50_wndw_atom(old_plane_state);
4132 struct nv50_wndw *wndw = nv50_wndw(plane); 4115 struct nv50_wndw *wndw = nv50_wndw(plane);
4116
4133 if (asyw->set.image) { 4117 if (asyw->set.image) {
4134 asyw->ntfy.handle = wndw->dmac->sync.handle; 4118 asyw->ntfy.handle = wndw->dmac->sync.handle;
4135 asyw->ntfy.offset = wndw->ntfy; 4119 asyw->ntfy.offset = wndw->ntfy;
@@ -4192,18 +4176,19 @@ nv50_disp_outp_atomic_add(struct nv50_atom *atom, struct drm_encoder *encoder)
4192 4176
4193static int 4177static int
4194nv50_disp_outp_atomic_check_clr(struct nv50_atom *atom, 4178nv50_disp_outp_atomic_check_clr(struct nv50_atom *atom,
4195 struct drm_connector *connector) 4179 struct drm_connector_state *old_connector_state)
4196{ 4180{
4197 struct drm_encoder *encoder = connector->state->best_encoder; 4181 struct drm_encoder *encoder = old_connector_state->best_encoder;
4198 struct drm_crtc_state *crtc_state; 4182 struct drm_crtc_state *old_crtc_state, *new_crtc_state;
4199 struct drm_crtc *crtc; 4183 struct drm_crtc *crtc;
4200 struct nv50_outp_atom *outp; 4184 struct nv50_outp_atom *outp;
4201 4185
4202 if (!(crtc = connector->state->crtc)) 4186 if (!(crtc = old_connector_state->crtc))
4203 return 0; 4187 return 0;
4204 4188
4205 crtc_state = drm_atomic_get_existing_crtc_state(&atom->state, crtc); 4189 old_crtc_state = drm_atomic_get_old_crtc_state(&atom->state, crtc);
4206 if (crtc->state->active && drm_atomic_crtc_needs_modeset(crtc_state)) { 4190 new_crtc_state = drm_atomic_get_new_crtc_state(&atom->state, crtc);
4191 if (old_crtc_state->active && drm_atomic_crtc_needs_modeset(new_crtc_state)) {
4207 outp = nv50_disp_outp_atomic_add(atom, encoder); 4192 outp = nv50_disp_outp_atomic_add(atom, encoder);
4208 if (IS_ERR(outp)) 4193 if (IS_ERR(outp))
4209 return PTR_ERR(outp); 4194 return PTR_ERR(outp);
@@ -4224,15 +4209,15 @@ nv50_disp_outp_atomic_check_set(struct nv50_atom *atom,
4224 struct drm_connector_state *connector_state) 4209 struct drm_connector_state *connector_state)
4225{ 4210{
4226 struct drm_encoder *encoder = connector_state->best_encoder; 4211 struct drm_encoder *encoder = connector_state->best_encoder;
4227 struct drm_crtc_state *crtc_state; 4212 struct drm_crtc_state *new_crtc_state;
4228 struct drm_crtc *crtc; 4213 struct drm_crtc *crtc;
4229 struct nv50_outp_atom *outp; 4214 struct nv50_outp_atom *outp;
4230 4215
4231 if (!(crtc = connector_state->crtc)) 4216 if (!(crtc = connector_state->crtc))
4232 return 0; 4217 return 0;
4233 4218
4234 crtc_state = drm_atomic_get_existing_crtc_state(&atom->state, crtc); 4219 new_crtc_state = drm_atomic_get_new_crtc_state(&atom->state, crtc);
4235 if (crtc_state->active && drm_atomic_crtc_needs_modeset(crtc_state)) { 4220 if (new_crtc_state->active && drm_atomic_crtc_needs_modeset(new_crtc_state)) {
4236 outp = nv50_disp_outp_atomic_add(atom, encoder); 4221 outp = nv50_disp_outp_atomic_add(atom, encoder);
4237 if (IS_ERR(outp)) 4222 if (IS_ERR(outp))
4238 return PTR_ERR(outp); 4223 return PTR_ERR(outp);
@@ -4248,7 +4233,7 @@ static int
4248nv50_disp_atomic_check(struct drm_device *dev, struct drm_atomic_state *state) 4233nv50_disp_atomic_check(struct drm_device *dev, struct drm_atomic_state *state)
4249{ 4234{
4250 struct nv50_atom *atom = nv50_atom(state); 4235 struct nv50_atom *atom = nv50_atom(state);
4251 struct drm_connector_state *connector_state; 4236 struct drm_connector_state *old_connector_state, *new_connector_state;
4252 struct drm_connector *connector; 4237 struct drm_connector *connector;
4253 int ret, i; 4238 int ret, i;
4254 4239
@@ -4256,12 +4241,12 @@ nv50_disp_atomic_check(struct drm_device *dev, struct drm_atomic_state *state)
4256 if (ret) 4241 if (ret)
4257 return ret; 4242 return ret;
4258 4243
4259 for_each_connector_in_state(state, connector, connector_state, i) { 4244 for_each_oldnew_connector_in_state(state, connector, old_connector_state, new_connector_state, i) {
4260 ret = nv50_disp_outp_atomic_check_clr(atom, connector); 4245 ret = nv50_disp_outp_atomic_check_clr(atom, old_connector_state);
4261 if (ret) 4246 if (ret)
4262 return ret; 4247 return ret;
4263 4248
4264 ret = nv50_disp_outp_atomic_check_set(atom, connector_state); 4249 ret = nv50_disp_outp_atomic_check_set(atom, new_connector_state);
4265 if (ret) 4250 if (ret)
4266 return ret; 4251 return ret;
4267 } 4252 }
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c
index c24b6b783e9a..d1ec76ef5cc6 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -195,7 +195,6 @@ static int omap_connector_mode_valid(struct drm_connector *connector,
195} 195}
196 196
197static const struct drm_connector_funcs omap_connector_funcs = { 197static const struct drm_connector_funcs omap_connector_funcs = {
198 .dpms = drm_atomic_helper_connector_dpms,
199 .reset = drm_atomic_helper_connector_reset, 198 .reset = drm_atomic_helper_connector_reset,
200 .detect = omap_connector_detect, 199 .detect = omap_connector_detect,
201 .fill_modes = drm_helper_probe_single_connector_modes, 200 .fill_modes = drm_helper_probe_single_connector_modes,
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 14e8a7738b06..400d0d2f6790 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -26,6 +26,16 @@
26 26
27#include "omap_drv.h" 27#include "omap_drv.h"
28 28
29#define to_omap_crtc_state(x) container_of(x, struct omap_crtc_state, base)
30
31struct omap_crtc_state {
32 /* Must be first. */
33 struct drm_crtc_state base;
34 /* Shadow values for legacy userspace support. */
35 unsigned int rotation;
36 unsigned int zpos;
37};
38
29#define to_omap_crtc(x) container_of(x, struct omap_crtc, base) 39#define to_omap_crtc(x) container_of(x, struct omap_crtc, base)
30 40
31struct omap_crtc { 41struct omap_crtc {
@@ -445,6 +455,8 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
445static int omap_crtc_atomic_check(struct drm_crtc *crtc, 455static int omap_crtc_atomic_check(struct drm_crtc *crtc,
446 struct drm_crtc_state *state) 456 struct drm_crtc_state *state)
447{ 457{
458 struct drm_plane_state *pri_state;
459
448 if (state->color_mgmt_changed && state->gamma_lut) { 460 if (state->color_mgmt_changed && state->gamma_lut) {
449 uint length = state->gamma_lut->length / 461 uint length = state->gamma_lut->length /
450 sizeof(struct drm_color_lut); 462 sizeof(struct drm_color_lut);
@@ -453,6 +465,16 @@ static int omap_crtc_atomic_check(struct drm_crtc *crtc,
453 return -EINVAL; 465 return -EINVAL;
454 } 466 }
455 467
468 pri_state = drm_atomic_get_new_plane_state(state->state, crtc->primary);
469 if (pri_state) {
470 struct omap_crtc_state *omap_crtc_state =
471 to_omap_crtc_state(state);
472
473 /* Mirror new values for zpos and rotation in omap_crtc_state */
474 omap_crtc_state->zpos = pri_state->zpos;
475 omap_crtc_state->rotation = pri_state->rotation;
476 }
477
456 return 0; 478 return 0;
457} 479}
458 480
@@ -498,39 +520,32 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc,
498 spin_unlock_irq(&crtc->dev->event_lock); 520 spin_unlock_irq(&crtc->dev->event_lock);
499} 521}
500 522
501static bool omap_crtc_is_plane_prop(struct drm_crtc *crtc,
502 struct drm_property *property)
503{
504 struct drm_device *dev = crtc->dev;
505 struct omap_drm_private *priv = dev->dev_private;
506
507 return property == priv->zorder_prop ||
508 property == crtc->primary->rotation_property;
509}
510
511static int omap_crtc_atomic_set_property(struct drm_crtc *crtc, 523static int omap_crtc_atomic_set_property(struct drm_crtc *crtc,
512 struct drm_crtc_state *state, 524 struct drm_crtc_state *state,
513 struct drm_property *property, 525 struct drm_property *property,
514 uint64_t val) 526 uint64_t val)
515{ 527{
516 if (omap_crtc_is_plane_prop(crtc, property)) { 528 struct omap_drm_private *priv = crtc->dev->dev_private;
517 struct drm_plane_state *plane_state; 529 struct drm_plane_state *plane_state;
518 struct drm_plane *plane = crtc->primary;
519
520 /*
521 * Delegate property set to the primary plane. Get the plane
522 * state and set the property directly.
523 */
524
525 plane_state = drm_atomic_get_plane_state(state->state, plane);
526 if (IS_ERR(plane_state))
527 return PTR_ERR(plane_state);
528 530
529 return drm_atomic_plane_set_property(plane, plane_state, 531 /*
530 property, val); 532 * Delegate property set to the primary plane. Get the plane state and
531 } 533 * set the property directly, the shadow copy will be assigned in the
534 * omap_crtc_atomic_check callback. This way updates to plane state will
535 * always be mirrored in the crtc state correctly.
536 */
537 plane_state = drm_atomic_get_plane_state(state->state, crtc->primary);
538 if (IS_ERR(plane_state))
539 return PTR_ERR(plane_state);
540
541 if (property == crtc->primary->rotation_property)
542 plane_state->rotation = val;
543 else if (property == priv->zorder_prop)
544 plane_state->zpos = val;
545 else
546 return -EINVAL;
532 547
533 return -EINVAL; 548 return 0;
534} 549}
535 550
536static int omap_crtc_atomic_get_property(struct drm_crtc *crtc, 551static int omap_crtc_atomic_get_property(struct drm_crtc *crtc,
@@ -538,28 +553,58 @@ static int omap_crtc_atomic_get_property(struct drm_crtc *crtc,
538 struct drm_property *property, 553 struct drm_property *property,
539 uint64_t *val) 554 uint64_t *val)
540{ 555{
541 if (omap_crtc_is_plane_prop(crtc, property)) { 556 struct omap_drm_private *priv = crtc->dev->dev_private;
542 /* 557 struct omap_crtc_state *omap_state = to_omap_crtc_state(state);
543 * Delegate property get to the primary plane. The 558
544 * drm_atomic_plane_get_property() function isn't exported, but 559 if (property == crtc->primary->rotation_property)
545 * can be called through drm_object_property_get_value() as that 560 *val = omap_state->rotation;
546 * will call drm_atomic_get_property() for atomic drivers. 561 else if (property == priv->zorder_prop)
547 */ 562 *val = omap_state->zpos;
548 return drm_object_property_get_value(&crtc->primary->base, 563 else
549 property, val); 564 return -EINVAL;
550 } 565
566 return 0;
567}
568
569static void omap_crtc_reset(struct drm_crtc *crtc)
570{
571 if (crtc->state)
572 __drm_atomic_helper_crtc_destroy_state(crtc->state);
573
574 kfree(crtc->state);
575 crtc->state = kzalloc(sizeof(struct omap_crtc_state), GFP_KERNEL);
576
577 if (crtc->state)
578 crtc->state->crtc = crtc;
579}
580
581static struct drm_crtc_state *
582omap_crtc_duplicate_state(struct drm_crtc *crtc)
583{
584 struct omap_crtc_state *state, *current_state;
585
586 if (WARN_ON(!crtc->state))
587 return NULL;
588
589 current_state = to_omap_crtc_state(crtc->state);
590
591 state = kmalloc(sizeof(*state), GFP_KERNEL);
592 if (state)
593 __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base);
594
595 state->zpos = current_state->zpos;
596 state->rotation = current_state->rotation;
551 597
552 return -EINVAL; 598 return &state->base;
553} 599}
554 600
555static const struct drm_crtc_funcs omap_crtc_funcs = { 601static const struct drm_crtc_funcs omap_crtc_funcs = {
556 .reset = drm_atomic_helper_crtc_reset, 602 .reset = omap_crtc_reset,
557 .set_config = drm_atomic_helper_set_config, 603 .set_config = drm_atomic_helper_set_config,
558 .destroy = omap_crtc_destroy, 604 .destroy = omap_crtc_destroy,
559 .page_flip = drm_atomic_helper_page_flip, 605 .page_flip = drm_atomic_helper_page_flip,
560 .gamma_set = drm_atomic_helper_legacy_gamma_set, 606 .gamma_set = drm_atomic_helper_legacy_gamma_set,
561 .set_property = drm_atomic_helper_crtc_set_property, 607 .atomic_duplicate_state = omap_crtc_duplicate_state,
562 .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
563 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, 608 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
564 .atomic_set_property = omap_crtc_atomic_set_property, 609 .atomic_set_property = omap_crtc_atomic_set_property,
565 .atomic_get_property = omap_crtc_atomic_get_property, 610 .atomic_get_property = omap_crtc_atomic_get_property,
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 022029ea6972..721a358531b0 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -57,13 +57,13 @@ static void omap_fb_output_poll_changed(struct drm_device *dev)
57static void omap_atomic_wait_for_completion(struct drm_device *dev, 57static void omap_atomic_wait_for_completion(struct drm_device *dev,
58 struct drm_atomic_state *old_state) 58 struct drm_atomic_state *old_state)
59{ 59{
60 struct drm_crtc_state *old_crtc_state; 60 struct drm_crtc_state *new_crtc_state;
61 struct drm_crtc *crtc; 61 struct drm_crtc *crtc;
62 unsigned int i; 62 unsigned int i;
63 int ret; 63 int ret;
64 64
65 for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) { 65 for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
66 if (!crtc->state->enable) 66 if (!new_crtc_state->active)
67 continue; 67 continue;
68 68
69 ret = omap_crtc_wait_pending(crtc); 69 ret = omap_crtc_wait_pending(crtc);
@@ -517,7 +517,6 @@ static struct drm_driver omap_drm_driver = {
517 .gem_vm_ops = &omap_gem_vm_ops, 517 .gem_vm_ops = &omap_gem_vm_ops,
518 .dumb_create = omap_gem_dumb_create, 518 .dumb_create = omap_gem_dumb_create,
519 .dumb_map_offset = omap_gem_dumb_map_offset, 519 .dumb_map_offset = omap_gem_dumb_map_offset,
520 .dumb_destroy = drm_gem_dumb_destroy,
521 .ioctls = ioctls, 520 .ioctls = ioctls,
522 .num_ioctls = DRM_OMAP_NUM_IOCTLS, 521 .num_ioctls = DRM_OMAP_NUM_IOCTLS,
523 .fops = &omapdriver_fops, 522 .fops = &omapdriver_fops,
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index 2160f64548e0..15e5d5d325c6 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -235,7 +235,6 @@ static const struct drm_plane_funcs omap_plane_funcs = {
235 .disable_plane = drm_atomic_helper_disable_plane, 235 .disable_plane = drm_atomic_helper_disable_plane,
236 .reset = omap_plane_reset, 236 .reset = omap_plane_reset,
237 .destroy = omap_plane_destroy, 237 .destroy = omap_plane_destroy,
238 .set_property = drm_atomic_helper_plane_set_property,
239 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 238 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
240 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 239 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
241 .atomic_set_property = omap_plane_atomic_set_property, 240 .atomic_set_property = omap_plane_atomic_set_property,
@@ -291,7 +290,7 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
291 290
292 ret = drm_universal_plane_init(dev, plane, possible_crtcs, 291 ret = drm_universal_plane_init(dev, plane, possible_crtcs,
293 &omap_plane_funcs, formats, 292 &omap_plane_funcs, formats,
294 nformats, type, NULL); 293 nformats, NULL, type, NULL);
295 if (ret < 0) 294 if (ret < 0)
296 goto error; 295 goto error;
297 296
diff --git a/drivers/gpu/drm/pl111/pl111_connector.c b/drivers/gpu/drm/pl111/pl111_connector.c
index 3f213d7e7692..d335f9a29ce4 100644
--- a/drivers/gpu/drm/pl111/pl111_connector.c
+++ b/drivers/gpu/drm/pl111/pl111_connector.c
@@ -69,7 +69,6 @@ const struct drm_connector_funcs connector_funcs = {
69 .fill_modes = drm_helper_probe_single_connector_modes, 69 .fill_modes = drm_helper_probe_single_connector_modes,
70 .destroy = pl111_connector_destroy, 70 .destroy = pl111_connector_destroy,
71 .detect = pl111_connector_detect, 71 .detect = pl111_connector_detect,
72 .dpms = drm_atomic_helper_connector_dpms,
73 .reset = drm_atomic_helper_connector_reset, 72 .reset = drm_atomic_helper_connector_reset,
74 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 73 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
75 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 74 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
diff --git a/drivers/gpu/drm/pl111/pl111_display.c b/drivers/gpu/drm/pl111/pl111_display.c
index c6ca4f1bbd49..f0139fa58d55 100644
--- a/drivers/gpu/drm/pl111/pl111_display.c
+++ b/drivers/gpu/drm/pl111/pl111_display.c
@@ -457,7 +457,7 @@ int pl111_display_init(struct drm_device *drm)
457 ret = drm_simple_display_pipe_init(drm, &priv->pipe, 457 ret = drm_simple_display_pipe_init(drm, &priv->pipe,
458 &pl111_display_funcs, 458 &pl111_display_funcs,
459 formats, ARRAY_SIZE(formats), 459 formats, ARRAY_SIZE(formats),
460 &priv->connector.connector); 460 NULL, &priv->connector.connector);
461 if (ret) 461 if (ret)
462 return ret; 462 return ret;
463 463
diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c
index 8907bc261ab2..29653fe5285c 100644
--- a/drivers/gpu/drm/pl111/pl111_drv.c
+++ b/drivers/gpu/drm/pl111/pl111_drv.c
@@ -159,8 +159,6 @@ static struct drm_driver pl111_drm_driver = {
159 .minor = 0, 159 .minor = 0,
160 .patchlevel = 0, 160 .patchlevel = 0,
161 .dumb_create = drm_gem_cma_dumb_create, 161 .dumb_create = drm_gem_cma_dumb_create,
162 .dumb_destroy = drm_gem_dumb_destroy,
163 .dumb_map_offset = drm_gem_cma_dumb_map_offset,
164 .gem_free_object_unlocked = drm_gem_cma_free_object, 162 .gem_free_object_unlocked = drm_gem_cma_free_object,
165 .gem_vm_ops = &drm_gem_cma_vm_ops, 163 .gem_vm_ops = &drm_gem_cma_vm_ops,
166 164
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c
index 5eeae89c138d..14c5613b4388 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -784,7 +784,7 @@ static struct drm_plane *qxl_create_plane(struct qxl_device *qdev,
784 784
785 err = drm_universal_plane_init(&qdev->ddev, plane, possible_crtcs, 785 err = drm_universal_plane_init(&qdev->ddev, plane, possible_crtcs,
786 funcs, formats, num_formats, 786 funcs, formats, num_formats,
787 type, NULL); 787 NULL, type, NULL);
788 if (err) 788 if (err)
789 goto free_plane; 789 goto free_plane;
790 790
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 3c492a0aa6bd..02baaaf20e9d 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -2217,7 +2217,6 @@ static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
2217 .mode_set_base_atomic = atombios_crtc_set_base_atomic, 2217 .mode_set_base_atomic = atombios_crtc_set_base_atomic,
2218 .prepare = atombios_crtc_prepare, 2218 .prepare = atombios_crtc_prepare,
2219 .commit = atombios_crtc_commit, 2219 .commit = atombios_crtc_commit,
2220 .load_lut = radeon_crtc_load_lut,
2221 .disable = atombios_crtc_disable, 2220 .disable = atombios_crtc_disable,
2222}; 2221};
2223 2222
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 27affbde058c..2f642cbefd8e 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -773,12 +773,15 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct
773 773
774 if (connector->encoder->crtc) { 774 if (connector->encoder->crtc) {
775 struct drm_crtc *crtc = connector->encoder->crtc; 775 struct drm_crtc *crtc = connector->encoder->crtc;
776 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
777 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 776 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
778 777
779 radeon_crtc->output_csc = radeon_encoder->output_csc; 778 radeon_crtc->output_csc = radeon_encoder->output_csc;
780 779
781 (*crtc_funcs->load_lut)(crtc); 780 /*
781 * Our .gamma_set assumes the .gamma_store has been
782 * prefilled and don't care about its arguments.
783 */
784 crtc->funcs->gamma_set(crtc, NULL, NULL, NULL, 0, NULL);
782 } 785 }
783 } 786 }
784 787
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index f339c1c10fa1..ee274c6e374d 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -42,6 +42,7 @@ static void avivo_crtc_load_lut(struct drm_crtc *crtc)
42 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 42 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
43 struct drm_device *dev = crtc->dev; 43 struct drm_device *dev = crtc->dev;
44 struct radeon_device *rdev = dev->dev_private; 44 struct radeon_device *rdev = dev->dev_private;
45 u16 *r, *g, *b;
45 int i; 46 int i;
46 47
47 DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id); 48 DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id);
@@ -60,11 +61,14 @@ static void avivo_crtc_load_lut(struct drm_crtc *crtc)
60 WREG32(AVIVO_DC_LUT_WRITE_EN_MASK, 0x0000003f); 61 WREG32(AVIVO_DC_LUT_WRITE_EN_MASK, 0x0000003f);
61 62
62 WREG8(AVIVO_DC_LUT_RW_INDEX, 0); 63 WREG8(AVIVO_DC_LUT_RW_INDEX, 0);
64 r = crtc->gamma_store;
65 g = r + crtc->gamma_size;
66 b = g + crtc->gamma_size;
63 for (i = 0; i < 256; i++) { 67 for (i = 0; i < 256; i++) {
64 WREG32(AVIVO_DC_LUT_30_COLOR, 68 WREG32(AVIVO_DC_LUT_30_COLOR,
65 (radeon_crtc->lut_r[i] << 20) | 69 ((*r++ & 0xffc0) << 14) |
66 (radeon_crtc->lut_g[i] << 10) | 70 ((*g++ & 0xffc0) << 4) |
67 (radeon_crtc->lut_b[i] << 0)); 71 (*b++ >> 6));
68 } 72 }
69 73
70 /* Only change bit 0 of LUT_SEL, other bits are set elsewhere */ 74 /* Only change bit 0 of LUT_SEL, other bits are set elsewhere */
@@ -76,6 +80,7 @@ static void dce4_crtc_load_lut(struct drm_crtc *crtc)
76 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 80 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
77 struct drm_device *dev = crtc->dev; 81 struct drm_device *dev = crtc->dev;
78 struct radeon_device *rdev = dev->dev_private; 82 struct radeon_device *rdev = dev->dev_private;
83 u16 *r, *g, *b;
79 int i; 84 int i;
80 85
81 DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id); 86 DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id);
@@ -93,11 +98,14 @@ static void dce4_crtc_load_lut(struct drm_crtc *crtc)
93 WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007); 98 WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007);
94 99
95 WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0); 100 WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0);
101 r = crtc->gamma_store;
102 g = r + crtc->gamma_size;
103 b = g + crtc->gamma_size;
96 for (i = 0; i < 256; i++) { 104 for (i = 0; i < 256; i++) {
97 WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset, 105 WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset,
98 (radeon_crtc->lut_r[i] << 20) | 106 ((*r++ & 0xffc0) << 14) |
99 (radeon_crtc->lut_g[i] << 10) | 107 ((*g++ & 0xffc0) << 4) |
100 (radeon_crtc->lut_b[i] << 0)); 108 (*b++ >> 6));
101 } 109 }
102} 110}
103 111
@@ -106,6 +114,7 @@ static void dce5_crtc_load_lut(struct drm_crtc *crtc)
106 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 114 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
107 struct drm_device *dev = crtc->dev; 115 struct drm_device *dev = crtc->dev;
108 struct radeon_device *rdev = dev->dev_private; 116 struct radeon_device *rdev = dev->dev_private;
117 u16 *r, *g, *b;
109 int i; 118 int i;
110 119
111 DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id); 120 DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id);
@@ -135,11 +144,14 @@ static void dce5_crtc_load_lut(struct drm_crtc *crtc)
135 WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007); 144 WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007);
136 145
137 WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0); 146 WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0);
147 r = crtc->gamma_store;
148 g = r + crtc->gamma_size;
149 b = g + crtc->gamma_size;
138 for (i = 0; i < 256; i++) { 150 for (i = 0; i < 256; i++) {
139 WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset, 151 WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset,
140 (radeon_crtc->lut_r[i] << 20) | 152 ((*r++ & 0xffc0) << 14) |
141 (radeon_crtc->lut_g[i] << 10) | 153 ((*g++ & 0xffc0) << 4) |
142 (radeon_crtc->lut_b[i] << 0)); 154 (*b++ >> 6));
143 } 155 }
144 156
145 WREG32(NI_DEGAMMA_CONTROL + radeon_crtc->crtc_offset, 157 WREG32(NI_DEGAMMA_CONTROL + radeon_crtc->crtc_offset,
@@ -172,6 +184,7 @@ static void legacy_crtc_load_lut(struct drm_crtc *crtc)
172 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 184 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
173 struct drm_device *dev = crtc->dev; 185 struct drm_device *dev = crtc->dev;
174 struct radeon_device *rdev = dev->dev_private; 186 struct radeon_device *rdev = dev->dev_private;
187 u16 *r, *g, *b;
175 int i; 188 int i;
176 uint32_t dac2_cntl; 189 uint32_t dac2_cntl;
177 190
@@ -183,11 +196,14 @@ static void legacy_crtc_load_lut(struct drm_crtc *crtc)
183 WREG32(RADEON_DAC_CNTL2, dac2_cntl); 196 WREG32(RADEON_DAC_CNTL2, dac2_cntl);
184 197
185 WREG8(RADEON_PALETTE_INDEX, 0); 198 WREG8(RADEON_PALETTE_INDEX, 0);
199 r = crtc->gamma_store;
200 g = r + crtc->gamma_size;
201 b = g + crtc->gamma_size;
186 for (i = 0; i < 256; i++) { 202 for (i = 0; i < 256; i++) {
187 WREG32(RADEON_PALETTE_30_DATA, 203 WREG32(RADEON_PALETTE_30_DATA,
188 (radeon_crtc->lut_r[i] << 20) | 204 ((*r++ & 0xffc0) << 14) |
189 (radeon_crtc->lut_g[i] << 10) | 205 ((*g++ & 0xffc0) << 4) |
190 (radeon_crtc->lut_b[i] << 0)); 206 (*b++ >> 6));
191 } 207 }
192} 208}
193 209
@@ -209,41 +225,10 @@ void radeon_crtc_load_lut(struct drm_crtc *crtc)
209 legacy_crtc_load_lut(crtc); 225 legacy_crtc_load_lut(crtc);
210} 226}
211 227
212/** Sets the color ramps on behalf of fbcon */
213void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
214 u16 blue, int regno)
215{
216 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
217
218 radeon_crtc->lut_r[regno] = red >> 6;
219 radeon_crtc->lut_g[regno] = green >> 6;
220 radeon_crtc->lut_b[regno] = blue >> 6;
221}
222
223/** Gets the color ramps on behalf of fbcon */
224void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
225 u16 *blue, int regno)
226{
227 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
228
229 *red = radeon_crtc->lut_r[regno] << 6;
230 *green = radeon_crtc->lut_g[regno] << 6;
231 *blue = radeon_crtc->lut_b[regno] << 6;
232}
233
234static int radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, 228static int radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
235 u16 *blue, uint32_t size, 229 u16 *blue, uint32_t size,
236 struct drm_modeset_acquire_ctx *ctx) 230 struct drm_modeset_acquire_ctx *ctx)
237{ 231{
238 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
239 int i;
240
241 /* userspace palettes are always correct as is */
242 for (i = 0; i < size; i++) {
243 radeon_crtc->lut_r[i] = red[i] >> 6;
244 radeon_crtc->lut_g[i] = green[i] >> 6;
245 radeon_crtc->lut_b[i] = blue[i] >> 6;
246 }
247 radeon_crtc_load_lut(crtc); 232 radeon_crtc_load_lut(crtc);
248 233
249 return 0; 234 return 0;
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index b401f1689bc1..f4becad0a78c 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -583,7 +583,6 @@ static struct drm_driver kms_driver = {
583 .gem_close_object = radeon_gem_object_close, 583 .gem_close_object = radeon_gem_object_close,
584 .dumb_create = radeon_mode_dumb_create, 584 .dumb_create = radeon_mode_dumb_create,
585 .dumb_map_offset = radeon_mode_dumb_mmap, 585 .dumb_map_offset = radeon_mode_dumb_mmap,
586 .dumb_destroy = drm_gem_dumb_destroy,
587 .fops = &radeon_driver_kms_fops, 586 .fops = &radeon_driver_kms_fops,
588 587
589 .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 588 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index 7fc63fecb8c1..af6ee7d9b465 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -331,8 +331,6 @@ static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfb
331} 331}
332 332
333static const struct drm_fb_helper_funcs radeon_fb_helper_funcs = { 333static const struct drm_fb_helper_funcs radeon_fb_helper_funcs = {
334 .gamma_set = radeon_crtc_fb_gamma_set,
335 .gamma_get = radeon_crtc_fb_gamma_get,
336 .fb_probe = radeonfb_create, 334 .fb_probe = radeonfb_create,
337}; 335};
338 336
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
index ce6cb6666212..1f1856e0b1e0 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
@@ -1116,7 +1116,6 @@ static const struct drm_crtc_helper_funcs legacy_helper_funcs = {
1116 .mode_set_base_atomic = radeon_crtc_set_base_atomic, 1116 .mode_set_base_atomic = radeon_crtc_set_base_atomic,
1117 .prepare = radeon_crtc_prepare, 1117 .prepare = radeon_crtc_prepare,
1118 .commit = radeon_crtc_commit, 1118 .commit = radeon_crtc_commit,
1119 .load_lut = radeon_crtc_load_lut,
1120 .disable = radeon_crtc_disable 1119 .disable = radeon_crtc_disable
1121}; 1120};
1122 1121
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 00f5ec5c12c7..da44ac234f64 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -935,10 +935,6 @@ extern void
935radeon_combios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc); 935radeon_combios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc);
936extern void 936extern void
937radeon_combios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on); 937radeon_combios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on);
938extern void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
939 u16 blue, int regno);
940extern void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
941 u16 *blue, int regno);
942int radeon_framebuffer_init(struct drm_device *dev, 938int radeon_framebuffer_init(struct drm_device *dev,
943 struct radeon_framebuffer *rfb, 939 struct radeon_framebuffer *rfb,
944 const struct drm_mode_fb_cmd2 *mode_cmd, 940 const struct drm_mode_fb_cmd2 *mode_cmd,
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index da3020b622ab..d2f29e6b1112 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -249,8 +249,6 @@ static struct drm_driver rcar_du_driver = {
249 .gem_prime_vunmap = drm_gem_cma_prime_vunmap, 249 .gem_prime_vunmap = drm_gem_cma_prime_vunmap,
250 .gem_prime_mmap = drm_gem_cma_prime_mmap, 250 .gem_prime_mmap = drm_gem_cma_prime_mmap,
251 .dumb_create = rcar_du_dumb_create, 251 .dumb_create = rcar_du_dumb_create,
252 .dumb_map_offset = drm_gem_cma_dumb_map_offset,
253 .dumb_destroy = drm_gem_dumb_destroy,
254 .fops = &rcar_du_fops, 252 .fops = &rcar_du_fops,
255 .name = "rcar-du", 253 .name = "rcar-du",
256 .desc = "Renesas R-Car Display Unit", 254 .desc = "Renesas R-Car Display Unit",
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c b/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c
index ee91481131ad..b373ad48ef5f 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c
@@ -46,7 +46,6 @@ static void rcar_du_lvds_connector_destroy(struct drm_connector *connector)
46} 46}
47 47
48static const struct drm_connector_funcs connector_funcs = { 48static const struct drm_connector_funcs connector_funcs = {
49 .dpms = drm_atomic_helper_connector_dpms,
50 .reset = drm_atomic_helper_connector_reset, 49 .reset = drm_atomic_helper_connector_reset,
51 .fill_modes = drm_helper_probe_single_connector_modes, 50 .fill_modes = drm_helper_probe_single_connector_modes,
52 .destroy = rcar_du_lvds_connector_destroy, 51 .destroy = rcar_du_lvds_connector_destroy,
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
index 25623cf7fe97..61833cc1c699 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
@@ -715,7 +715,6 @@ static const struct drm_plane_funcs rcar_du_plane_funcs = {
715 .update_plane = drm_atomic_helper_update_plane, 715 .update_plane = drm_atomic_helper_update_plane,
716 .disable_plane = drm_atomic_helper_disable_plane, 716 .disable_plane = drm_atomic_helper_disable_plane,
717 .reset = rcar_du_plane_reset, 717 .reset = rcar_du_plane_reset,
718 .set_property = drm_atomic_helper_plane_set_property,
719 .destroy = drm_plane_cleanup, 718 .destroy = drm_plane_cleanup,
720 .atomic_duplicate_state = rcar_du_plane_atomic_duplicate_state, 719 .atomic_duplicate_state = rcar_du_plane_atomic_duplicate_state,
721 .atomic_destroy_state = rcar_du_plane_atomic_destroy_state, 720 .atomic_destroy_state = rcar_du_plane_atomic_destroy_state,
@@ -761,8 +760,8 @@ int rcar_du_planes_init(struct rcar_du_group *rgrp)
761 760
762 ret = drm_universal_plane_init(rcdu->ddev, &plane->plane, crtcs, 761 ret = drm_universal_plane_init(rcdu->ddev, &plane->plane, crtcs,
763 &rcar_du_plane_funcs, formats, 762 &rcar_du_plane_funcs, formats,
764 ARRAY_SIZE(formats), type, 763 ARRAY_SIZE(formats),
765 NULL); 764 NULL, type, NULL);
766 if (ret < 0) 765 if (ret < 0)
767 return ret; 766 return ret;
768 767
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
index 6de6be3d9090..2c96147bc444 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -393,7 +393,6 @@ static const struct drm_plane_funcs rcar_du_vsp_plane_funcs = {
393 .update_plane = drm_atomic_helper_update_plane, 393 .update_plane = drm_atomic_helper_update_plane,
394 .disable_plane = drm_atomic_helper_disable_plane, 394 .disable_plane = drm_atomic_helper_disable_plane,
395 .reset = rcar_du_vsp_plane_reset, 395 .reset = rcar_du_vsp_plane_reset,
396 .set_property = drm_atomic_helper_plane_set_property,
397 .destroy = drm_plane_cleanup, 396 .destroy = drm_plane_cleanup,
398 .atomic_duplicate_state = rcar_du_vsp_plane_atomic_duplicate_state, 397 .atomic_duplicate_state = rcar_du_vsp_plane_atomic_duplicate_state,
399 .atomic_destroy_state = rcar_du_vsp_plane_atomic_destroy_state, 398 .atomic_destroy_state = rcar_du_vsp_plane_atomic_destroy_state,
@@ -444,8 +443,8 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp, struct device_node *np,
444 ret = drm_universal_plane_init(rcdu->ddev, &plane->plane, crtcs, 443 ret = drm_universal_plane_init(rcdu->ddev, &plane->plane, crtcs,
445 &rcar_du_vsp_plane_funcs, 444 &rcar_du_vsp_plane_funcs,
446 formats_kms, 445 formats_kms,
447 ARRAY_SIZE(formats_kms), type, 446 ARRAY_SIZE(formats_kms),
448 NULL); 447 NULL, type, NULL);
449 if (ret < 0) 448 if (ret < 0)
450 return ret; 449 return ret;
451 450
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 9b0b0588bbed..a57da051f516 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -254,7 +254,6 @@ static void cdn_dp_connector_destroy(struct drm_connector *connector)
254} 254}
255 255
256static const struct drm_connector_funcs cdn_dp_atomic_connector_funcs = { 256static const struct drm_connector_funcs cdn_dp_atomic_connector_funcs = {
257 .dpms = drm_atomic_helper_connector_dpms,
258 .detect = cdn_dp_connector_detect, 257 .detect = cdn_dp_connector_detect,
259 .destroy = cdn_dp_connector_destroy, 258 .destroy = cdn_dp_connector_destroy,
260 .fill_modes = drm_helper_probe_single_connector_modes, 259 .fill_modes = drm_helper_probe_single_connector_modes,
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 21b9737662ae..9a20b9dc27c8 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -1080,7 +1080,6 @@ static void dw_mipi_dsi_drm_connector_destroy(struct drm_connector *connector)
1080} 1080}
1081 1081
1082static const struct drm_connector_funcs dw_mipi_dsi_atomic_connector_funcs = { 1082static const struct drm_connector_funcs dw_mipi_dsi_atomic_connector_funcs = {
1083 .dpms = drm_atomic_helper_connector_dpms,
1084 .fill_modes = drm_helper_probe_single_connector_modes, 1083 .fill_modes = drm_helper_probe_single_connector_modes,
1085 .destroy = dw_mipi_dsi_drm_connector_destroy, 1084 .destroy = dw_mipi_dsi_drm_connector_destroy,
1086 .reset = drm_atomic_helper_connector_reset, 1085 .reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 7149968aa25a..bd87768dd549 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -593,7 +593,6 @@ static void inno_hdmi_connector_destroy(struct drm_connector *connector)
593} 593}
594 594
595static struct drm_connector_funcs inno_hdmi_connector_funcs = { 595static struct drm_connector_funcs inno_hdmi_connector_funcs = {
596 .dpms = drm_atomic_helper_connector_dpms,
597 .fill_modes = inno_hdmi_probe_single_connector_modes, 596 .fill_modes = inno_hdmi_probe_single_connector_modes,
598 .detect = inno_hdmi_connector_detect, 597 .detect = inno_hdmi_connector_detect,
599 .destroy = inno_hdmi_connector_destroy, 598 .destroy = inno_hdmi_connector_destroy,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 131cb5c86def..c41f48ae7913 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -161,22 +161,21 @@ static int rockchip_drm_bind(struct device *dev)
161 */ 161 */
162 drm_dev->irq_enabled = true; 162 drm_dev->irq_enabled = true;
163 163
164 /* init kms poll for handling hpd */
165 drm_kms_helper_poll_init(drm_dev);
166
167 ret = rockchip_drm_fbdev_init(drm_dev); 164 ret = rockchip_drm_fbdev_init(drm_dev);
168 if (ret) 165 if (ret)
169 goto err_kms_helper_poll_fini; 166 goto err_unbind_all;
167
168 /* init kms poll for handling hpd */
169 drm_kms_helper_poll_init(drm_dev);
170 170
171 ret = drm_dev_register(drm_dev, 0); 171 ret = drm_dev_register(drm_dev, 0);
172 if (ret) 172 if (ret)
173 goto err_fbdev_fini; 173 goto err_kms_helper_poll_fini;
174 174
175 return 0; 175 return 0;
176err_fbdev_fini:
177 rockchip_drm_fbdev_fini(drm_dev);
178err_kms_helper_poll_fini: 176err_kms_helper_poll_fini:
179 drm_kms_helper_poll_fini(drm_dev); 177 drm_kms_helper_poll_fini(drm_dev);
178 rockchip_drm_fbdev_fini(drm_dev);
180err_unbind_all: 179err_unbind_all:
181 component_unbind_all(dev, drm_dev); 180 component_unbind_all(dev, drm_dev);
182err_mode_config_cleanup: 181err_mode_config_cleanup:
@@ -233,8 +232,6 @@ static struct drm_driver rockchip_drm_driver = {
233 .gem_vm_ops = &drm_gem_cma_vm_ops, 232 .gem_vm_ops = &drm_gem_cma_vm_ops,
234 .gem_free_object_unlocked = rockchip_gem_free_object, 233 .gem_free_object_unlocked = rockchip_gem_free_object,
235 .dumb_create = rockchip_gem_dumb_create, 234 .dumb_create = rockchip_gem_dumb_create,
236 .dumb_map_offset = rockchip_gem_dumb_map_offset,
237 .dumb_destroy = drm_gem_dumb_destroy,
238 .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 235 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
239 .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 236 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
240 .gem_prime_import = drm_gem_prime_import, 237 .gem_prime_import = drm_gem_prime_import,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index b74ac717e56a..f74333efe4bb 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -393,32 +393,6 @@ err_handle_create:
393 return ERR_PTR(ret); 393 return ERR_PTR(ret);
394} 394}
395 395
396int rockchip_gem_dumb_map_offset(struct drm_file *file_priv,
397 struct drm_device *dev, uint32_t handle,
398 uint64_t *offset)
399{
400 struct drm_gem_object *obj;
401 int ret;
402
403 obj = drm_gem_object_lookup(file_priv, handle);
404 if (!obj) {
405 DRM_ERROR("failed to lookup gem object.\n");
406 return -EINVAL;
407 }
408
409 ret = drm_gem_create_mmap_offset(obj);
410 if (ret)
411 goto out;
412
413 *offset = drm_vma_node_offset_addr(&obj->vma_node);
414 DRM_DEBUG_KMS("offset = 0x%llx\n", *offset);
415
416out:
417 drm_gem_object_unreference_unlocked(obj);
418
419 return 0;
420}
421
422/* 396/*
423 * rockchip_gem_dumb_create - (struct drm_driver)->dumb_create callback 397 * rockchip_gem_dumb_create - (struct drm_driver)->dumb_create callback
424 * function 398 * function
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.h b/drivers/gpu/drm/rockchip/rockchip_drm_gem.h
index 3f6ea4d18a5c..f237375582fb 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.h
@@ -57,7 +57,4 @@ void rockchip_gem_free_object(struct drm_gem_object *obj);
57int rockchip_gem_dumb_create(struct drm_file *file_priv, 57int rockchip_gem_dumb_create(struct drm_file *file_priv,
58 struct drm_device *dev, 58 struct drm_device *dev,
59 struct drm_mode_create_dumb *args); 59 struct drm_mode_create_dumb *args);
60int rockchip_gem_dumb_map_offset(struct drm_file *file_priv,
61 struct drm_device *dev, uint32_t handle,
62 uint64_t *offset);
63#endif /* _ROCKCHIP_DRM_GEM_H */ 60#endif /* _ROCKCHIP_DRM_GEM_H */
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 9434d616bc37..948719dddc36 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -42,33 +42,20 @@
42#include "rockchip_drm_psr.h" 42#include "rockchip_drm_psr.h"
43#include "rockchip_drm_vop.h" 43#include "rockchip_drm_vop.h"
44 44
45#define __REG_SET_RELAXED(x, off, mask, shift, v, write_mask) \
46 vop_mask_write(x, off, mask, shift, v, write_mask, true)
47
48#define __REG_SET_NORMAL(x, off, mask, shift, v, write_mask) \
49 vop_mask_write(x, off, mask, shift, v, write_mask, false)
50
51#define REG_SET(x, base, reg, v, mode) \
52 __REG_SET_##mode(x, base + reg.offset, \
53 reg.mask, reg.shift, v, reg.write_mask)
54#define REG_SET_MASK(x, base, reg, mask, v, mode) \
55 __REG_SET_##mode(x, base + reg.offset, \
56 mask, reg.shift, v, reg.write_mask)
57
58#define VOP_WIN_SET(x, win, name, v) \ 45#define VOP_WIN_SET(x, win, name, v) \
59 REG_SET(x, win->base, win->phy->name, v, RELAXED) 46 vop_reg_set(vop, &win->phy->name, win->base, ~0, v, #name)
60#define VOP_SCL_SET(x, win, name, v) \ 47#define VOP_SCL_SET(x, win, name, v) \
61 REG_SET(x, win->base, win->phy->scl->name, v, RELAXED) 48 vop_reg_set(vop, &win->phy->scl->name, win->base, ~0, v, #name)
62#define VOP_SCL_SET_EXT(x, win, name, v) \ 49#define VOP_SCL_SET_EXT(x, win, name, v) \
63 REG_SET(x, win->base, win->phy->scl->ext->name, v, RELAXED) 50 vop_reg_set(vop, &win->phy->scl->ext->name, \
64#define VOP_CTRL_SET(x, name, v) \ 51 win->base, ~0, v, #name)
65 REG_SET(x, 0, (x)->data->ctrl->name, v, NORMAL) 52
53#define VOP_INTR_SET_MASK(vop, name, mask, v) \
54 vop_reg_set(vop, &vop->data->intr->name, 0, mask, v, #name)
66 55
67#define VOP_INTR_GET(vop, name) \ 56#define VOP_REG_SET(vop, group, name, v) \
68 vop_read_reg(vop, 0, &vop->data->ctrl->name) 57 vop_reg_set(vop, &vop->data->group->name, 0, ~0, v, #name)
69 58
70#define VOP_INTR_SET(vop, name, mask, v) \
71 REG_SET_MASK(vop, 0, vop->data->intr->name, mask, v, NORMAL)
72#define VOP_INTR_SET_TYPE(vop, name, type, v) \ 59#define VOP_INTR_SET_TYPE(vop, name, type, v) \
73 do { \ 60 do { \
74 int i, reg = 0, mask = 0; \ 61 int i, reg = 0, mask = 0; \
@@ -78,13 +65,13 @@
78 mask |= 1 << i; \ 65 mask |= 1 << i; \
79 } \ 66 } \
80 } \ 67 } \
81 VOP_INTR_SET(vop, name, mask, reg); \ 68 VOP_INTR_SET_MASK(vop, name, mask, reg); \
82 } while (0) 69 } while (0)
83#define VOP_INTR_GET_TYPE(vop, name, type) \ 70#define VOP_INTR_GET_TYPE(vop, name, type) \
84 vop_get_intr_type(vop, &vop->data->intr->name, type) 71 vop_get_intr_type(vop, &vop->data->intr->name, type)
85 72
86#define VOP_WIN_GET(x, win, name) \ 73#define VOP_WIN_GET(x, win, name) \
87 vop_read_reg(x, win->base, &win->phy->name) 74 vop_read_reg(x, win->offset, win->phy->name)
88 75
89#define VOP_WIN_GET_YRGBADDR(vop, win) \ 76#define VOP_WIN_GET_YRGBADDR(vop, win) \
90 vop_readl(vop, win->base + win->phy->yrgb_mst.offset) 77 vop_readl(vop, win->base + win->phy->yrgb_mst.offset)
@@ -166,14 +153,22 @@ static inline uint32_t vop_read_reg(struct vop *vop, uint32_t base,
166 return (vop_readl(vop, base + reg->offset) >> reg->shift) & reg->mask; 153 return (vop_readl(vop, base + reg->offset) >> reg->shift) & reg->mask;
167} 154}
168 155
169static inline void vop_mask_write(struct vop *vop, uint32_t offset, 156static void vop_reg_set(struct vop *vop, const struct vop_reg *reg,
170 uint32_t mask, uint32_t shift, uint32_t v, 157 uint32_t _offset, uint32_t _mask, uint32_t v,
171 bool write_mask, bool relaxed) 158 const char *reg_name)
172{ 159{
173 if (!mask) 160 int offset, mask, shift;
161
162 if (!reg || !reg->mask) {
163 dev_dbg(vop->dev, "Warning: not support %s\n", reg_name);
174 return; 164 return;
165 }
166
167 offset = reg->offset + _offset;
168 mask = reg->mask & _mask;
169 shift = reg->shift;
175 170
176 if (write_mask) { 171 if (reg->write_mask) {
177 v = ((v << shift) & 0xffff) | (mask << (shift + 16)); 172 v = ((v << shift) & 0xffff) | (mask << (shift + 16));
178 } else { 173 } else {
179 uint32_t cached_val = vop->regsbak[offset >> 2]; 174 uint32_t cached_val = vop->regsbak[offset >> 2];
@@ -182,7 +177,7 @@ static inline void vop_mask_write(struct vop *vop, uint32_t offset,
182 vop->regsbak[offset >> 2] = v; 177 vop->regsbak[offset >> 2] = v;
183 } 178 }
184 179
185 if (relaxed) 180 if (reg->relaxed)
186 writel_relaxed(v, vop->regs + offset); 181 writel_relaxed(v, vop->regs + offset);
187 else 182 else
188 writel(v, vop->regs + offset); 183 writel(v, vop->regs + offset);
@@ -204,7 +199,7 @@ static inline uint32_t vop_get_intr_type(struct vop *vop,
204 199
205static inline void vop_cfg_done(struct vop *vop) 200static inline void vop_cfg_done(struct vop *vop)
206{ 201{
207 VOP_CTRL_SET(vop, cfg_done, 1); 202 VOP_REG_SET(vop, common, cfg_done, 1);
208} 203}
209 204
210static bool has_rb_swapped(uint32_t format) 205static bool has_rb_swapped(uint32_t format)
@@ -500,7 +495,7 @@ static void vop_line_flag_irq_disable(struct vop *vop)
500static int vop_enable(struct drm_crtc *crtc) 495static int vop_enable(struct drm_crtc *crtc)
501{ 496{
502 struct vop *vop = to_vop(crtc); 497 struct vop *vop = to_vop(crtc);
503 int ret; 498 int ret, i;
504 499
505 ret = pm_runtime_get_sync(vop->dev); 500 ret = pm_runtime_get_sync(vop->dev);
506 if (ret < 0) { 501 if (ret < 0) {
@@ -533,6 +528,20 @@ static int vop_enable(struct drm_crtc *crtc)
533 } 528 }
534 529
535 memcpy(vop->regs, vop->regsbak, vop->len); 530 memcpy(vop->regs, vop->regsbak, vop->len);
531 /*
532 * We need to make sure that all windows are disabled before we
533 * enable the crtc. Otherwise we might try to scan from a destroyed
534 * buffer later.
535 */
536 for (i = 0; i < vop->data->win_size; i++) {
537 struct vop_win *vop_win = &vop->win[i];
538 const struct vop_win_data *win = vop_win->data;
539
540 spin_lock(&vop->reg_lock);
541 VOP_WIN_SET(vop, win, enable, 0);
542 spin_unlock(&vop->reg_lock);
543 }
544
536 vop_cfg_done(vop); 545 vop_cfg_done(vop);
537 546
538 /* 547 /*
@@ -542,7 +551,7 @@ static int vop_enable(struct drm_crtc *crtc)
542 551
543 spin_lock(&vop->reg_lock); 552 spin_lock(&vop->reg_lock);
544 553
545 VOP_CTRL_SET(vop, standby, 0); 554 VOP_REG_SET(vop, common, standby, 1);
546 555
547 spin_unlock(&vop->reg_lock); 556 spin_unlock(&vop->reg_lock);
548 557
@@ -567,28 +576,11 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
567 struct drm_crtc_state *old_state) 576 struct drm_crtc_state *old_state)
568{ 577{
569 struct vop *vop = to_vop(crtc); 578 struct vop *vop = to_vop(crtc);
570 int i;
571 579
572 WARN_ON(vop->event); 580 WARN_ON(vop->event);
573 581
574 rockchip_drm_psr_deactivate(&vop->crtc); 582 rockchip_drm_psr_deactivate(&vop->crtc);
575 583
576 /*
577 * We need to make sure that all windows are disabled before we
578 * disable that crtc. Otherwise we might try to scan from a destroyed
579 * buffer later.
580 */
581 for (i = 0; i < vop->data->win_size; i++) {
582 struct vop_win *vop_win = &vop->win[i];
583 const struct vop_win_data *win = vop_win->data;
584
585 spin_lock(&vop->reg_lock);
586 VOP_WIN_SET(vop, win, enable, 0);
587 spin_unlock(&vop->reg_lock);
588 }
589
590 vop_cfg_done(vop);
591
592 drm_crtc_vblank_off(crtc); 584 drm_crtc_vblank_off(crtc);
593 585
594 /* 586 /*
@@ -603,7 +595,7 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
603 595
604 spin_lock(&vop->reg_lock); 596 spin_lock(&vop->reg_lock);
605 597
606 VOP_CTRL_SET(vop, standby, 1); 598 VOP_REG_SET(vop, common, standby, 1);
607 599
608 spin_unlock(&vop->reg_lock); 600 spin_unlock(&vop->reg_lock);
609 601
@@ -683,8 +675,10 @@ static int vop_plane_atomic_check(struct drm_plane *plane,
683 * Src.x1 can be odd when do clip, but yuv plane start point 675 * Src.x1 can be odd when do clip, but yuv plane start point
684 * need align with 2 pixel. 676 * need align with 2 pixel.
685 */ 677 */
686 if (is_yuv_support(fb->format->format) && ((state->src.x1 >> 16) % 2)) 678 if (is_yuv_support(fb->format->format) && ((state->src.x1 >> 16) % 2)) {
679 DRM_ERROR("Invalid Source: Yuv format not support odd xpos\n");
687 return -EINVAL; 680 return -EINVAL;
681 }
688 682
689 return 0; 683 return 0;
690} 684}
@@ -765,7 +759,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
765 spin_lock(&vop->reg_lock); 759 spin_lock(&vop->reg_lock);
766 760
767 VOP_WIN_SET(vop, win, format, format); 761 VOP_WIN_SET(vop, win, format, format);
768 VOP_WIN_SET(vop, win, yrgb_vir, fb->pitches[0] >> 2); 762 VOP_WIN_SET(vop, win, yrgb_vir, DIV_ROUND_UP(fb->pitches[0], 4));
769 VOP_WIN_SET(vop, win, yrgb_mst, dma_addr); 763 VOP_WIN_SET(vop, win, yrgb_mst, dma_addr);
770 if (is_yuv_support(fb->format->format)) { 764 if (is_yuv_support(fb->format->format)) {
771 int hsub = drm_format_horz_chroma_subsampling(fb->format->format); 765 int hsub = drm_format_horz_chroma_subsampling(fb->format->format);
@@ -779,7 +773,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
779 offset += (src->y1 >> 16) * fb->pitches[1] / vsub; 773 offset += (src->y1 >> 16) * fb->pitches[1] / vsub;
780 774
781 dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1]; 775 dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1];
782 VOP_WIN_SET(vop, win, uv_vir, fb->pitches[1] >> 2); 776 VOP_WIN_SET(vop, win, uv_vir, DIV_ROUND_UP(fb->pitches[1], 4));
783 VOP_WIN_SET(vop, win, uv_mst, dma_addr); 777 VOP_WIN_SET(vop, win, uv_mst, dma_addr);
784 } 778 }
785 779
@@ -900,70 +894,34 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
900 return; 894 return;
901 } 895 }
902 896
903 /*
904 * If dclk rate is zero, mean that scanout is stop,
905 * we don't need wait any more.
906 */
907 if (clk_get_rate(vop->dclk)) {
908 /*
909 * Rk3288 vop timing register is immediately, when configure
910 * display timing on display time, may cause tearing.
911 *
912 * Vop standby will take effect at end of current frame,
913 * if dsp hold valid irq happen, it means standby complete.
914 *
915 * mode set:
916 * standby and wait complete --> |----
917 * | display time
918 * |----
919 * |---> dsp hold irq
920 * configure display timing --> |
921 * standby exit |
922 * | new frame start.
923 */
924
925 reinit_completion(&vop->dsp_hold_completion);
926 vop_dsp_hold_valid_irq_enable(vop);
927
928 spin_lock(&vop->reg_lock);
929
930 VOP_CTRL_SET(vop, standby, 1);
931
932 spin_unlock(&vop->reg_lock);
933
934 wait_for_completion(&vop->dsp_hold_completion);
935
936 vop_dsp_hold_valid_irq_disable(vop);
937 }
938
939 pin_pol = BIT(DCLK_INVERT); 897 pin_pol = BIT(DCLK_INVERT);
940 pin_pol |= (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) ? 898 pin_pol |= (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) ?
941 BIT(HSYNC_POSITIVE) : 0; 899 BIT(HSYNC_POSITIVE) : 0;
942 pin_pol |= (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) ? 900 pin_pol |= (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) ?
943 BIT(VSYNC_POSITIVE) : 0; 901 BIT(VSYNC_POSITIVE) : 0;
944 VOP_CTRL_SET(vop, pin_pol, pin_pol); 902 VOP_REG_SET(vop, output, pin_pol, pin_pol);
945 903
946 switch (s->output_type) { 904 switch (s->output_type) {
947 case DRM_MODE_CONNECTOR_LVDS: 905 case DRM_MODE_CONNECTOR_LVDS:
948 VOP_CTRL_SET(vop, rgb_en, 1); 906 VOP_REG_SET(vop, output, rgb_en, 1);
949 VOP_CTRL_SET(vop, rgb_pin_pol, pin_pol); 907 VOP_REG_SET(vop, output, rgb_pin_pol, pin_pol);
950 break; 908 break;
951 case DRM_MODE_CONNECTOR_eDP: 909 case DRM_MODE_CONNECTOR_eDP:
952 VOP_CTRL_SET(vop, edp_pin_pol, pin_pol); 910 VOP_REG_SET(vop, output, edp_pin_pol, pin_pol);
953 VOP_CTRL_SET(vop, edp_en, 1); 911 VOP_REG_SET(vop, output, edp_en, 1);
954 break; 912 break;
955 case DRM_MODE_CONNECTOR_HDMIA: 913 case DRM_MODE_CONNECTOR_HDMIA:
956 VOP_CTRL_SET(vop, hdmi_pin_pol, pin_pol); 914 VOP_REG_SET(vop, output, hdmi_pin_pol, pin_pol);
957 VOP_CTRL_SET(vop, hdmi_en, 1); 915 VOP_REG_SET(vop, output, hdmi_en, 1);
958 break; 916 break;
959 case DRM_MODE_CONNECTOR_DSI: 917 case DRM_MODE_CONNECTOR_DSI:
960 VOP_CTRL_SET(vop, mipi_pin_pol, pin_pol); 918 VOP_REG_SET(vop, output, mipi_pin_pol, pin_pol);
961 VOP_CTRL_SET(vop, mipi_en, 1); 919 VOP_REG_SET(vop, output, mipi_en, 1);
962 break; 920 break;
963 case DRM_MODE_CONNECTOR_DisplayPort: 921 case DRM_MODE_CONNECTOR_DisplayPort:
964 pin_pol &= ~BIT(DCLK_INVERT); 922 pin_pol &= ~BIT(DCLK_INVERT);
965 VOP_CTRL_SET(vop, dp_pin_pol, pin_pol); 923 VOP_REG_SET(vop, output, dp_pin_pol, pin_pol);
966 VOP_CTRL_SET(vop, dp_en, 1); 924 VOP_REG_SET(vop, output, dp_en, 1);
967 break; 925 break;
968 default: 926 default:
969 DRM_DEV_ERROR(vop->dev, "unsupported connector_type [%d]\n", 927 DRM_DEV_ERROR(vop->dev, "unsupported connector_type [%d]\n",
@@ -976,25 +934,25 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
976 if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA && 934 if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
977 !(vop_data->feature & VOP_FEATURE_OUTPUT_RGB10)) 935 !(vop_data->feature & VOP_FEATURE_OUTPUT_RGB10))
978 s->output_mode = ROCKCHIP_OUT_MODE_P888; 936 s->output_mode = ROCKCHIP_OUT_MODE_P888;
979 VOP_CTRL_SET(vop, out_mode, s->output_mode); 937 VOP_REG_SET(vop, common, out_mode, s->output_mode);
980 938
981 VOP_CTRL_SET(vop, htotal_pw, (htotal << 16) | hsync_len); 939 VOP_REG_SET(vop, modeset, htotal_pw, (htotal << 16) | hsync_len);
982 val = hact_st << 16; 940 val = hact_st << 16;
983 val |= hact_end; 941 val |= hact_end;
984 VOP_CTRL_SET(vop, hact_st_end, val); 942 VOP_REG_SET(vop, modeset, hact_st_end, val);
985 VOP_CTRL_SET(vop, hpost_st_end, val); 943 VOP_REG_SET(vop, modeset, hpost_st_end, val);
986 944
987 VOP_CTRL_SET(vop, vtotal_pw, (vtotal << 16) | vsync_len); 945 VOP_REG_SET(vop, modeset, vtotal_pw, (vtotal << 16) | vsync_len);
988 val = vact_st << 16; 946 val = vact_st << 16;
989 val |= vact_end; 947 val |= vact_end;
990 VOP_CTRL_SET(vop, vact_st_end, val); 948 VOP_REG_SET(vop, modeset, vact_st_end, val);
991 VOP_CTRL_SET(vop, vpost_st_end, val); 949 VOP_REG_SET(vop, modeset, vpost_st_end, val);
992 950
993 VOP_CTRL_SET(vop, line_flag_num[0], vact_end); 951 VOP_REG_SET(vop, intr, line_flag_num[0], vact_end);
994 952
995 clk_set_rate(vop->dclk, adjusted_mode->clock * 1000); 953 clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
996 954
997 VOP_CTRL_SET(vop, standby, 0); 955 VOP_REG_SET(vop, common, standby, 0);
998 956
999 rockchip_drm_psr_activate(&vop->crtc); 957 rockchip_drm_psr_activate(&vop->crtc);
1000} 958}
@@ -1293,7 +1251,7 @@ static int vop_create_crtc(struct vop *vop)
1293 0, &vop_plane_funcs, 1251 0, &vop_plane_funcs,
1294 win_data->phy->data_formats, 1252 win_data->phy->data_formats,
1295 win_data->phy->nformats, 1253 win_data->phy->nformats,
1296 win_data->type, NULL); 1254 NULL, win_data->type, NULL);
1297 if (ret) { 1255 if (ret) {
1298 DRM_DEV_ERROR(vop->dev, "failed to init plane %d\n", 1256 DRM_DEV_ERROR(vop->dev, "failed to init plane %d\n",
1299 ret); 1257 ret);
@@ -1332,7 +1290,7 @@ static int vop_create_crtc(struct vop *vop)
1332 &vop_plane_funcs, 1290 &vop_plane_funcs,
1333 win_data->phy->data_formats, 1291 win_data->phy->data_formats,
1334 win_data->phy->nformats, 1292 win_data->phy->nformats,
1335 win_data->type, NULL); 1293 NULL, win_data->type, NULL);
1336 if (ret) { 1294 if (ret) {
1337 DRM_DEV_ERROR(vop->dev, "failed to init overlay %d\n", 1295 DRM_DEV_ERROR(vop->dev, "failed to init overlay %d\n",
1338 ret); 1296 ret);
@@ -1398,7 +1356,6 @@ static void vop_destroy_crtc(struct vop *vop)
1398static int vop_initial(struct vop *vop) 1356static int vop_initial(struct vop *vop)
1399{ 1357{
1400 const struct vop_data *vop_data = vop->data; 1358 const struct vop_data *vop_data = vop->data;
1401 const struct vop_reg_data *init_table = vop_data->init_table;
1402 struct reset_control *ahb_rst; 1359 struct reset_control *ahb_rst;
1403 int i, ret; 1360 int i, ret;
1404 1361
@@ -1458,13 +1415,16 @@ static int vop_initial(struct vop *vop)
1458 1415
1459 memcpy(vop->regsbak, vop->regs, vop->len); 1416 memcpy(vop->regsbak, vop->regs, vop->len);
1460 1417
1461 for (i = 0; i < vop_data->table_size; i++) 1418 VOP_REG_SET(vop, misc, global_regdone_en, 1);
1462 vop_writel(vop, init_table[i].offset, init_table[i].value); 1419 VOP_REG_SET(vop, common, dsp_blank, 0);
1463 1420
1464 for (i = 0; i < vop_data->win_size; i++) { 1421 for (i = 0; i < vop_data->win_size; i++) {
1465 const struct vop_win_data *win = &vop_data->win[i]; 1422 const struct vop_win_data *win = &vop_data->win[i];
1423 int channel = i * 2 + 1;
1466 1424
1425 VOP_WIN_SET(vop, win, channel, (channel + 1) << 4 | channel);
1467 VOP_WIN_SET(vop, win, enable, 0); 1426 VOP_WIN_SET(vop, win, enable, 0);
1427 VOP_WIN_SET(vop, win, gate, 1);
1468 } 1428 }
1469 1429
1470 vop_cfg_done(vop); 1430 vop_cfg_done(vop);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index 9979fd0c2282..56bbd2e2a8ef 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -15,6 +15,14 @@
15#ifndef _ROCKCHIP_DRM_VOP_H 15#ifndef _ROCKCHIP_DRM_VOP_H
16#define _ROCKCHIP_DRM_VOP_H 16#define _ROCKCHIP_DRM_VOP_H
17 17
18/*
19 * major: IP major version, used for IP structure
20 * minor: big feature change under same structure
21 */
22#define VOP_VERSION(major, minor) ((major) << 8 | (minor))
23#define VOP_MAJOR(version) ((version) >> 8)
24#define VOP_MINOR(version) ((version) & 0xff)
25
18enum vop_data_format { 26enum vop_data_format {
19 VOP_FMT_ARGB8888 = 0, 27 VOP_FMT_ARGB8888 = 0,
20 VOP_FMT_RGB888, 28 VOP_FMT_RGB888,
@@ -24,53 +32,58 @@ enum vop_data_format {
24 VOP_FMT_YUV444SP, 32 VOP_FMT_YUV444SP,
25}; 33};
26 34
27struct vop_reg_data {
28 uint32_t offset;
29 uint32_t value;
30};
31
32struct vop_reg { 35struct vop_reg {
33 uint32_t offset;
34 uint32_t shift;
35 uint32_t mask; 36 uint32_t mask;
37 uint16_t offset;
38 uint8_t shift;
36 bool write_mask; 39 bool write_mask;
40 bool relaxed;
37}; 41};
38 42
39struct vop_ctrl { 43struct vop_modeset {
40 struct vop_reg standby;
41 struct vop_reg data_blank;
42 struct vop_reg gate_en;
43 struct vop_reg mmu_en;
44 struct vop_reg rgb_en;
45 struct vop_reg edp_en;
46 struct vop_reg hdmi_en;
47 struct vop_reg mipi_en;
48 struct vop_reg dp_en;
49 struct vop_reg out_mode;
50 struct vop_reg dither_down;
51 struct vop_reg dither_up;
52 struct vop_reg pin_pol;
53 struct vop_reg rgb_pin_pol;
54 struct vop_reg hdmi_pin_pol;
55 struct vop_reg edp_pin_pol;
56 struct vop_reg mipi_pin_pol;
57 struct vop_reg dp_pin_pol;
58
59 struct vop_reg htotal_pw; 44 struct vop_reg htotal_pw;
60 struct vop_reg hact_st_end; 45 struct vop_reg hact_st_end;
46 struct vop_reg hpost_st_end;
61 struct vop_reg vtotal_pw; 47 struct vop_reg vtotal_pw;
62 struct vop_reg vact_st_end; 48 struct vop_reg vact_st_end;
63 struct vop_reg hpost_st_end;
64 struct vop_reg vpost_st_end; 49 struct vop_reg vpost_st_end;
50};
65 51
66 struct vop_reg line_flag_num[2]; 52struct vop_output {
53 struct vop_reg pin_pol;
54 struct vop_reg dp_pin_pol;
55 struct vop_reg edp_pin_pol;
56 struct vop_reg hdmi_pin_pol;
57 struct vop_reg mipi_pin_pol;
58 struct vop_reg rgb_pin_pol;
59 struct vop_reg dp_en;
60 struct vop_reg edp_en;
61 struct vop_reg hdmi_en;
62 struct vop_reg mipi_en;
63 struct vop_reg rgb_en;
64};
67 65
66struct vop_common {
68 struct vop_reg cfg_done; 67 struct vop_reg cfg_done;
68 struct vop_reg dsp_blank;
69 struct vop_reg data_blank;
70 struct vop_reg dither_down;
71 struct vop_reg dither_up;
72 struct vop_reg gate_en;
73 struct vop_reg mmu_en;
74 struct vop_reg out_mode;
75 struct vop_reg standby;
76};
77
78struct vop_misc {
79 struct vop_reg global_regdone_en;
69}; 80};
70 81
71struct vop_intr { 82struct vop_intr {
72 const int *intrs; 83 const int *intrs;
73 uint32_t nintrs; 84 uint32_t nintrs;
85
86 struct vop_reg line_flag_num[2];
74 struct vop_reg enable; 87 struct vop_reg enable;
75 struct vop_reg clear; 88 struct vop_reg clear;
76 struct vop_reg status; 89 struct vop_reg status;
@@ -115,6 +128,7 @@ struct vop_win_phy {
115 uint32_t nformats; 128 uint32_t nformats;
116 129
117 struct vop_reg enable; 130 struct vop_reg enable;
131 struct vop_reg gate;
118 struct vop_reg format; 132 struct vop_reg format;
119 struct vop_reg rb_swap; 133 struct vop_reg rb_swap;
120 struct vop_reg act_info; 134 struct vop_reg act_info;
@@ -127,6 +141,7 @@ struct vop_win_phy {
127 141
128 struct vop_reg dst_alpha_ctl; 142 struct vop_reg dst_alpha_ctl;
129 struct vop_reg src_alpha_ctl; 143 struct vop_reg src_alpha_ctl;
144 struct vop_reg channel;
130}; 145};
131 146
132struct vop_win_data { 147struct vop_win_data {
@@ -136,10 +151,12 @@ struct vop_win_data {
136}; 151};
137 152
138struct vop_data { 153struct vop_data {
139 const struct vop_reg_data *init_table; 154 uint32_t version;
140 unsigned int table_size;
141 const struct vop_ctrl *ctrl;
142 const struct vop_intr *intr; 155 const struct vop_intr *intr;
156 const struct vop_common *common;
157 const struct vop_misc *misc;
158 const struct vop_modeset *modeset;
159 const struct vop_output *output;
143 const struct vop_win_data *win; 160 const struct vop_win_data *win;
144 unsigned int win_size; 161 unsigned int win_size;
145 162
@@ -282,6 +299,9 @@ static inline uint16_t scl_get_bili_dn_vskip(int src_h, int dst_h,
282 299
283 act_height = (src_h + vskiplines - 1) / vskiplines; 300 act_height = (src_h + vskiplines - 1) / vskiplines;
284 301
302 if (act_height == dst_h)
303 return GET_SCL_FT_BILI_DN(src_h, dst_h) / vskiplines;
304
285 return GET_SCL_FT_BILI_DN(act_height, dst_h); 305 return GET_SCL_FT_BILI_DN(act_height, dst_h);
286} 306}
287 307
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index bafd698a28b1..94de7b9f6fde 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -20,17 +20,23 @@
20#include "rockchip_drm_vop.h" 20#include "rockchip_drm_vop.h"
21#include "rockchip_vop_reg.h" 21#include "rockchip_vop_reg.h"
22 22
23#define VOP_REG(off, _mask, s) \ 23#define _VOP_REG(off, _mask, _shift, _write_mask, _relaxed) \
24 {.offset = off, \ 24 { \
25 .offset = off, \
25 .mask = _mask, \ 26 .mask = _mask, \
26 .shift = s, \ 27 .shift = _shift, \
27 .write_mask = false,} 28 .write_mask = _write_mask, \
29 .relaxed = _relaxed, \
30 }
28 31
29#define VOP_REG_MASK(off, _mask, s) \ 32#define VOP_REG(off, _mask, _shift) \
30 {.offset = off, \ 33 _VOP_REG(off, _mask, _shift, false, true)
31 .mask = _mask, \ 34
32 .shift = s, \ 35#define VOP_REG_SYNC(off, _mask, _shift) \
33 .write_mask = true,} 36 _VOP_REG(off, _mask, _shift, false, false)
37
38#define VOP_REG_MASK_SYNC(off, _mask, _shift) \
39 _VOP_REG(off, _mask, _shift, true, false)
34 40
35static const uint32_t formats_win_full[] = { 41static const uint32_t formats_win_full[] = {
36 DRM_FORMAT_XRGB8888, 42 DRM_FORMAT_XRGB8888,
@@ -110,32 +116,35 @@ static const int rk3036_vop_intrs[] = {
110static const struct vop_intr rk3036_intr = { 116static const struct vop_intr rk3036_intr = {
111 .intrs = rk3036_vop_intrs, 117 .intrs = rk3036_vop_intrs,
112 .nintrs = ARRAY_SIZE(rk3036_vop_intrs), 118 .nintrs = ARRAY_SIZE(rk3036_vop_intrs),
113 .status = VOP_REG(RK3036_INT_STATUS, 0xf, 0), 119 .line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12),
114 .enable = VOP_REG(RK3036_INT_STATUS, 0xf, 4), 120 .status = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 0),
115 .clear = VOP_REG(RK3036_INT_STATUS, 0xf, 8), 121 .enable = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 4),
122 .clear = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 8),
116}; 123};
117 124
118static const struct vop_ctrl rk3036_ctrl_data = { 125static const struct vop_modeset rk3036_modeset = {
119 .standby = VOP_REG(RK3036_SYS_CTRL, 0x1, 30),
120 .out_mode = VOP_REG(RK3036_DSP_CTRL0, 0xf, 0),
121 .pin_pol = VOP_REG(RK3036_DSP_CTRL0, 0xf, 4),
122 .htotal_pw = VOP_REG(RK3036_DSP_HTOTAL_HS_END, 0x1fff1fff, 0), 126 .htotal_pw = VOP_REG(RK3036_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
123 .hact_st_end = VOP_REG(RK3036_DSP_HACT_ST_END, 0x1fff1fff, 0), 127 .hact_st_end = VOP_REG(RK3036_DSP_HACT_ST_END, 0x1fff1fff, 0),
124 .vtotal_pw = VOP_REG(RK3036_DSP_VTOTAL_VS_END, 0x1fff1fff, 0), 128 .vtotal_pw = VOP_REG(RK3036_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
125 .vact_st_end = VOP_REG(RK3036_DSP_VACT_ST_END, 0x1fff1fff, 0), 129 .vact_st_end = VOP_REG(RK3036_DSP_VACT_ST_END, 0x1fff1fff, 0),
126 .line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12),
127 .cfg_done = VOP_REG(RK3036_REG_CFG_DONE, 0x1, 0),
128}; 130};
129 131
130static const struct vop_reg_data rk3036_vop_init_reg_table[] = { 132static const struct vop_output rk3036_output = {
131 {RK3036_DSP_CTRL1, 0x00000000}, 133 .pin_pol = VOP_REG(RK3036_DSP_CTRL0, 0xf, 4),
134};
135
136static const struct vop_common rk3036_common = {
137 .standby = VOP_REG_SYNC(RK3036_SYS_CTRL, 0x1, 30),
138 .out_mode = VOP_REG(RK3036_DSP_CTRL0, 0xf, 0),
139 .dsp_blank = VOP_REG(RK3036_DSP_CTRL1, 0x1, 24),
140 .cfg_done = VOP_REG_SYNC(RK3036_REG_CFG_DONE, 0x1, 0),
132}; 141};
133 142
134static const struct vop_data rk3036_vop = { 143static const struct vop_data rk3036_vop = {
135 .init_table = rk3036_vop_init_reg_table,
136 .table_size = ARRAY_SIZE(rk3036_vop_init_reg_table),
137 .ctrl = &rk3036_ctrl_data,
138 .intr = &rk3036_intr, 144 .intr = &rk3036_intr,
145 .common = &rk3036_common,
146 .modeset = &rk3036_modeset,
147 .output = &rk3036_output,
139 .win = rk3036_vop_win_data, 148 .win = rk3036_vop_win_data,
140 .win_size = ARRAY_SIZE(rk3036_vop_win_data), 149 .win_size = ARRAY_SIZE(rk3036_vop_win_data),
141}; 150};
@@ -188,12 +197,14 @@ static const struct vop_win_phy rk3288_win01_data = {
188 .uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16), 197 .uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16),
189 .src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0), 198 .src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
190 .dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0), 199 .dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0),
200 .channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0),
191}; 201};
192 202
193static const struct vop_win_phy rk3288_win23_data = { 203static const struct vop_win_phy rk3288_win23_data = {
194 .data_formats = formats_win_lite, 204 .data_formats = formats_win_lite,
195 .nformats = ARRAY_SIZE(formats_win_lite), 205 .nformats = ARRAY_SIZE(formats_win_lite),
196 .enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0), 206 .enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 4),
207 .gate = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0),
197 .format = VOP_REG(RK3288_WIN2_CTRL0, 0x7, 1), 208 .format = VOP_REG(RK3288_WIN2_CTRL0, 0x7, 1),
198 .rb_swap = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 12), 209 .rb_swap = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 12),
199 .dsp_info = VOP_REG(RK3288_WIN2_DSP_INFO0, 0x0fff0fff, 0), 210 .dsp_info = VOP_REG(RK3288_WIN2_DSP_INFO0, 0x0fff0fff, 0),
@@ -204,40 +215,33 @@ static const struct vop_win_phy rk3288_win23_data = {
204 .dst_alpha_ctl = VOP_REG(RK3288_WIN2_DST_ALPHA_CTRL, 0xff, 0), 215 .dst_alpha_ctl = VOP_REG(RK3288_WIN2_DST_ALPHA_CTRL, 0xff, 0),
205}; 216};
206 217
207static const struct vop_ctrl rk3288_ctrl_data = { 218static const struct vop_modeset rk3288_modeset = {
208 .standby = VOP_REG(RK3288_SYS_CTRL, 0x1, 22),
209 .gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23),
210 .mmu_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 20),
211 .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
212 .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
213 .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
214 .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
215 .dither_down = VOP_REG(RK3288_DSP_CTRL1, 0xf, 1),
216 .dither_up = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6),
217 .data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19),
218 .out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0),
219 .pin_pol = VOP_REG(RK3288_DSP_CTRL0, 0xf, 4),
220 .htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0), 219 .htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
221 .hact_st_end = VOP_REG(RK3288_DSP_HACT_ST_END, 0x1fff1fff, 0), 220 .hact_st_end = VOP_REG(RK3288_DSP_HACT_ST_END, 0x1fff1fff, 0),
222 .vtotal_pw = VOP_REG(RK3288_DSP_VTOTAL_VS_END, 0x1fff1fff, 0), 221 .vtotal_pw = VOP_REG(RK3288_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
223 .vact_st_end = VOP_REG(RK3288_DSP_VACT_ST_END, 0x1fff1fff, 0), 222 .vact_st_end = VOP_REG(RK3288_DSP_VACT_ST_END, 0x1fff1fff, 0),
224 .hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0), 223 .hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
225 .vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0), 224 .vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
226 .line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12),
227 .cfg_done = VOP_REG(RK3288_REG_CFG_DONE, 0x1, 0),
228}; 225};
229 226
230static const struct vop_reg_data rk3288_init_reg_table[] = { 227static const struct vop_output rk3288_output = {
231 {RK3288_SYS_CTRL, 0x00c00000}, 228 .pin_pol = VOP_REG(RK3288_DSP_CTRL0, 0xf, 4),
232 {RK3288_DSP_CTRL0, 0x00000000}, 229 .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
233 {RK3288_WIN0_CTRL0, 0x00000080}, 230 .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
234 {RK3288_WIN1_CTRL0, 0x00000080}, 231 .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
235 /* TODO: Win2/3 support multiple area function, but we haven't found 232 .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
236 * a suitable way to use it yet, so let's just use them as other windows 233};
237 * with only area 0 enabled. 234
238 */ 235static const struct vop_common rk3288_common = {
239 {RK3288_WIN2_CTRL0, 0x00000010}, 236 .standby = VOP_REG_SYNC(RK3288_SYS_CTRL, 0x1, 22),
240 {RK3288_WIN3_CTRL0, 0x00000010}, 237 .gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23),
238 .mmu_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 20),
239 .dither_down = VOP_REG(RK3288_DSP_CTRL1, 0xf, 1),
240 .dither_up = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6),
241 .data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19),
242 .dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18),
243 .out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0),
244 .cfg_done = VOP_REG_SYNC(RK3288_REG_CFG_DONE, 0x1, 0),
241}; 245};
242 246
243/* 247/*
@@ -267,50 +271,24 @@ static const int rk3288_vop_intrs[] = {
267static const struct vop_intr rk3288_vop_intr = { 271static const struct vop_intr rk3288_vop_intr = {
268 .intrs = rk3288_vop_intrs, 272 .intrs = rk3288_vop_intrs,
269 .nintrs = ARRAY_SIZE(rk3288_vop_intrs), 273 .nintrs = ARRAY_SIZE(rk3288_vop_intrs),
274 .line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12),
270 .status = VOP_REG(RK3288_INTR_CTRL0, 0xf, 0), 275 .status = VOP_REG(RK3288_INTR_CTRL0, 0xf, 0),
271 .enable = VOP_REG(RK3288_INTR_CTRL0, 0xf, 4), 276 .enable = VOP_REG(RK3288_INTR_CTRL0, 0xf, 4),
272 .clear = VOP_REG(RK3288_INTR_CTRL0, 0xf, 8), 277 .clear = VOP_REG(RK3288_INTR_CTRL0, 0xf, 8),
273}; 278};
274 279
275static const struct vop_data rk3288_vop = { 280static const struct vop_data rk3288_vop = {
276 .init_table = rk3288_init_reg_table, 281 .version = VOP_VERSION(3, 1),
277 .table_size = ARRAY_SIZE(rk3288_init_reg_table),
278 .feature = VOP_FEATURE_OUTPUT_RGB10, 282 .feature = VOP_FEATURE_OUTPUT_RGB10,
279 .intr = &rk3288_vop_intr, 283 .intr = &rk3288_vop_intr,
280 .ctrl = &rk3288_ctrl_data, 284 .common = &rk3288_common,
285 .modeset = &rk3288_modeset,
286 .output = &rk3288_output,
281 .win = rk3288_vop_win_data, 287 .win = rk3288_vop_win_data,
282 .win_size = ARRAY_SIZE(rk3288_vop_win_data), 288 .win_size = ARRAY_SIZE(rk3288_vop_win_data),
283}; 289};
284 290
285static const struct vop_ctrl rk3399_ctrl_data = { 291static const int rk3368_vop_intrs[] = {
286 .standby = VOP_REG(RK3399_SYS_CTRL, 0x1, 22),
287 .gate_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 23),
288 .dp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 11),
289 .rgb_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 12),
290 .hdmi_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 13),
291 .edp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 14),
292 .mipi_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 15),
293 .dither_down = VOP_REG(RK3399_DSP_CTRL1, 0xf, 1),
294 .dither_up = VOP_REG(RK3399_DSP_CTRL1, 0x1, 6),
295 .data_blank = VOP_REG(RK3399_DSP_CTRL0, 0x1, 19),
296 .out_mode = VOP_REG(RK3399_DSP_CTRL0, 0xf, 0),
297 .rgb_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 16),
298 .dp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 16),
299 .hdmi_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 20),
300 .edp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 24),
301 .mipi_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 28),
302 .htotal_pw = VOP_REG(RK3399_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
303 .hact_st_end = VOP_REG(RK3399_DSP_HACT_ST_END, 0x1fff1fff, 0),
304 .vtotal_pw = VOP_REG(RK3399_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
305 .vact_st_end = VOP_REG(RK3399_DSP_VACT_ST_END, 0x1fff1fff, 0),
306 .hpost_st_end = VOP_REG(RK3399_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
307 .vpost_st_end = VOP_REG(RK3399_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
308 .line_flag_num[0] = VOP_REG(RK3399_LINE_FLAG, 0xffff, 0),
309 .line_flag_num[1] = VOP_REG(RK3399_LINE_FLAG, 0xffff, 16),
310 .cfg_done = VOP_REG_MASK(RK3399_REG_CFG_DONE, 0x1, 0),
311};
312
313static const int rk3399_vop_intrs[] = {
314 FS_INTR, 292 FS_INTR,
315 0, 0, 293 0, 0,
316 LINE_FLAG_INTR, 294 LINE_FLAG_INTR,
@@ -320,69 +298,232 @@ static const int rk3399_vop_intrs[] = {
320 DSP_HOLD_VALID_INTR, 298 DSP_HOLD_VALID_INTR,
321}; 299};
322 300
323static const struct vop_intr rk3399_vop_intr = { 301static const struct vop_intr rk3368_vop_intr = {
324 .intrs = rk3399_vop_intrs, 302 .intrs = rk3368_vop_intrs,
325 .nintrs = ARRAY_SIZE(rk3399_vop_intrs), 303 .nintrs = ARRAY_SIZE(rk3368_vop_intrs),
326 .status = VOP_REG_MASK(RK3399_INTR_STATUS0, 0xffff, 0), 304 .line_flag_num[0] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 0),
327 .enable = VOP_REG_MASK(RK3399_INTR_EN0, 0xffff, 0), 305 .line_flag_num[1] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 16),
328 .clear = VOP_REG_MASK(RK3399_INTR_CLEAR0, 0xffff, 0), 306 .status = VOP_REG_MASK_SYNC(RK3368_INTR_STATUS, 0x3fff, 0),
307 .enable = VOP_REG_MASK_SYNC(RK3368_INTR_EN, 0x3fff, 0),
308 .clear = VOP_REG_MASK_SYNC(RK3368_INTR_CLEAR, 0x3fff, 0),
329}; 309};
330 310
331static const struct vop_reg_data rk3399_init_reg_table[] = { 311static const struct vop_win_phy rk3368_win23_data = {
332 {RK3399_SYS_CTRL, 0x2000f800}, 312 .data_formats = formats_win_lite,
333 {RK3399_DSP_CTRL0, 0x00000000}, 313 .nformats = ARRAY_SIZE(formats_win_lite),
334 {RK3399_WIN0_CTRL0, 0x00000080}, 314 .gate = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 0),
335 {RK3399_WIN1_CTRL0, 0x00000080}, 315 .enable = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 4),
336 /* TODO: Win2/3 support multiple area function, but we haven't found 316 .format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 5),
337 * a suitable way to use it yet, so let's just use them as other windows 317 .rb_swap = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 20),
338 * with only area 0 enabled. 318 .dsp_info = VOP_REG(RK3368_WIN2_DSP_INFO0, 0x0fff0fff, 0),
339 */ 319 .dsp_st = VOP_REG(RK3368_WIN2_DSP_ST0, 0x1fff1fff, 0),
340 {RK3399_WIN2_CTRL0, 0x00000010}, 320 .yrgb_mst = VOP_REG(RK3368_WIN2_MST0, 0xffffffff, 0),
341 {RK3399_WIN3_CTRL0, 0x00000010}, 321 .yrgb_vir = VOP_REG(RK3368_WIN2_VIR0_1, 0x1fff, 0),
322 .src_alpha_ctl = VOP_REG(RK3368_WIN2_SRC_ALPHA_CTRL, 0xff, 0),
323 .dst_alpha_ctl = VOP_REG(RK3368_WIN2_DST_ALPHA_CTRL, 0xff, 0),
324};
325
326static const struct vop_win_data rk3368_vop_win_data[] = {
327 { .base = 0x00, .phy = &rk3288_win01_data,
328 .type = DRM_PLANE_TYPE_PRIMARY },
329 { .base = 0x40, .phy = &rk3288_win01_data,
330 .type = DRM_PLANE_TYPE_OVERLAY },
331 { .base = 0x00, .phy = &rk3368_win23_data,
332 .type = DRM_PLANE_TYPE_OVERLAY },
333 { .base = 0x50, .phy = &rk3368_win23_data,
334 .type = DRM_PLANE_TYPE_CURSOR },
335};
336
337static const struct vop_output rk3368_output = {
338 .rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 16),
339 .hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 20),
340 .edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 24),
341 .mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 28),
342 .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
343 .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
344 .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
345 .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
346};
347
348static const struct vop_misc rk3368_misc = {
349 .global_regdone_en = VOP_REG(RK3368_SYS_CTRL, 0x1, 11),
350};
351
352static const struct vop_data rk3368_vop = {
353 .version = VOP_VERSION(3, 2),
354 .intr = &rk3368_vop_intr,
355 .common = &rk3288_common,
356 .modeset = &rk3288_modeset,
357 .output = &rk3368_output,
358 .misc = &rk3368_misc,
359 .win = rk3368_vop_win_data,
360 .win_size = ARRAY_SIZE(rk3368_vop_win_data),
361};
362
363static const struct vop_intr rk3366_vop_intr = {
364 .intrs = rk3368_vop_intrs,
365 .nintrs = ARRAY_SIZE(rk3368_vop_intrs),
366 .line_flag_num[0] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 0),
367 .line_flag_num[1] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 16),
368 .status = VOP_REG_MASK_SYNC(RK3366_INTR_STATUS0, 0xffff, 0),
369 .enable = VOP_REG_MASK_SYNC(RK3366_INTR_EN0, 0xffff, 0),
370 .clear = VOP_REG_MASK_SYNC(RK3366_INTR_CLEAR0, 0xffff, 0),
371};
372
373static const struct vop_data rk3366_vop = {
374 .version = VOP_VERSION(3, 4),
375 .intr = &rk3366_vop_intr,
376 .common = &rk3288_common,
377 .modeset = &rk3288_modeset,
378 .output = &rk3368_output,
379 .misc = &rk3368_misc,
380 .win = rk3368_vop_win_data,
381 .win_size = ARRAY_SIZE(rk3368_vop_win_data),
382};
383
384static const struct vop_output rk3399_output = {
385 .dp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 16),
386 .rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 16),
387 .hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 20),
388 .edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 24),
389 .mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 28),
390 .dp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 11),
391 .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
392 .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
393 .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
394 .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
342}; 395};
343 396
344static const struct vop_data rk3399_vop_big = { 397static const struct vop_data rk3399_vop_big = {
345 .init_table = rk3399_init_reg_table, 398 .version = VOP_VERSION(3, 5),
346 .table_size = ARRAY_SIZE(rk3399_init_reg_table),
347 .feature = VOP_FEATURE_OUTPUT_RGB10, 399 .feature = VOP_FEATURE_OUTPUT_RGB10,
348 .intr = &rk3399_vop_intr, 400 .intr = &rk3366_vop_intr,
349 .ctrl = &rk3399_ctrl_data, 401 .common = &rk3288_common,
350 /* 402 .modeset = &rk3288_modeset,
351 * rk3399 vop big windows register layout is same as rk3288. 403 .output = &rk3399_output,
352 */ 404 .misc = &rk3368_misc,
353 .win = rk3288_vop_win_data, 405 .win = rk3368_vop_win_data,
354 .win_size = ARRAY_SIZE(rk3288_vop_win_data), 406 .win_size = ARRAY_SIZE(rk3368_vop_win_data),
355}; 407};
356 408
357static const struct vop_win_data rk3399_vop_lit_win_data[] = { 409static const struct vop_win_data rk3399_vop_lit_win_data[] = {
358 { .base = 0x00, .phy = &rk3288_win01_data, 410 { .base = 0x00, .phy = &rk3288_win01_data,
359 .type = DRM_PLANE_TYPE_PRIMARY }, 411 .type = DRM_PLANE_TYPE_PRIMARY },
360 { .base = 0x00, .phy = &rk3288_win23_data, 412 { .base = 0x00, .phy = &rk3368_win23_data,
361 .type = DRM_PLANE_TYPE_CURSOR}, 413 .type = DRM_PLANE_TYPE_CURSOR},
362}; 414};
363 415
364static const struct vop_data rk3399_vop_lit = { 416static const struct vop_data rk3399_vop_lit = {
365 .init_table = rk3399_init_reg_table, 417 .version = VOP_VERSION(3, 6),
366 .table_size = ARRAY_SIZE(rk3399_init_reg_table), 418 .intr = &rk3366_vop_intr,
367 .intr = &rk3399_vop_intr, 419 .common = &rk3288_common,
368 .ctrl = &rk3399_ctrl_data, 420 .modeset = &rk3288_modeset,
369 /* 421 .output = &rk3399_output,
370 * rk3399 vop lit windows register layout is same as rk3288, 422 .misc = &rk3368_misc,
371 * but cut off the win1 and win3 windows.
372 */
373 .win = rk3399_vop_lit_win_data, 423 .win = rk3399_vop_lit_win_data,
374 .win_size = ARRAY_SIZE(rk3399_vop_lit_win_data), 424 .win_size = ARRAY_SIZE(rk3399_vop_lit_win_data),
375}; 425};
376 426
427static const struct vop_win_data rk3228_vop_win_data[] = {
428 { .base = 0x00, .phy = &rk3288_win01_data,
429 .type = DRM_PLANE_TYPE_PRIMARY },
430 { .base = 0x40, .phy = &rk3288_win01_data,
431 .type = DRM_PLANE_TYPE_CURSOR },
432};
433
434static const struct vop_data rk3228_vop = {
435 .version = VOP_VERSION(3, 7),
436 .feature = VOP_FEATURE_OUTPUT_RGB10,
437 .intr = &rk3366_vop_intr,
438 .common = &rk3288_common,
439 .modeset = &rk3288_modeset,
440 .output = &rk3399_output,
441 .misc = &rk3368_misc,
442 .win = rk3228_vop_win_data,
443 .win_size = ARRAY_SIZE(rk3228_vop_win_data),
444};
445
446static const struct vop_modeset rk3328_modeset = {
447 .htotal_pw = VOP_REG(RK3328_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
448 .hact_st_end = VOP_REG(RK3328_DSP_HACT_ST_END, 0x1fff1fff, 0),
449 .vtotal_pw = VOP_REG(RK3328_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
450 .vact_st_end = VOP_REG(RK3328_DSP_VACT_ST_END, 0x1fff1fff, 0),
451 .hpost_st_end = VOP_REG(RK3328_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
452 .vpost_st_end = VOP_REG(RK3328_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
453};
454
455static const struct vop_output rk3328_output = {
456 .rgb_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 12),
457 .hdmi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 13),
458 .edp_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 14),
459 .mipi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 15),
460 .rgb_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 16),
461 .hdmi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 20),
462 .edp_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 24),
463 .mipi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 28),
464};
465
466static const struct vop_misc rk3328_misc = {
467 .global_regdone_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 11),
468};
469
470static const struct vop_common rk3328_common = {
471 .standby = VOP_REG_SYNC(RK3328_SYS_CTRL, 0x1, 22),
472 .dither_down = VOP_REG(RK3328_DSP_CTRL1, 0xf, 1),
473 .dither_up = VOP_REG(RK3328_DSP_CTRL1, 0x1, 6),
474 .dsp_blank = VOP_REG(RK3328_DSP_CTRL0, 0x3, 18),
475 .out_mode = VOP_REG(RK3328_DSP_CTRL0, 0xf, 0),
476 .cfg_done = VOP_REG_SYNC(RK3328_REG_CFG_DONE, 0x1, 0),
477};
478
479static const struct vop_intr rk3328_vop_intr = {
480 .intrs = rk3368_vop_intrs,
481 .nintrs = ARRAY_SIZE(rk3368_vop_intrs),
482 .line_flag_num[0] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 0),
483 .line_flag_num[1] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 16),
484 .status = VOP_REG_MASK_SYNC(RK3328_INTR_STATUS0, 0xffff, 0),
485 .enable = VOP_REG_MASK_SYNC(RK3328_INTR_EN0, 0xffff, 0),
486 .clear = VOP_REG_MASK_SYNC(RK3328_INTR_CLEAR0, 0xffff, 0),
487};
488
489static const struct vop_win_data rk3328_vop_win_data[] = {
490 { .base = 0xd0, .phy = &rk3288_win01_data,
491 .type = DRM_PLANE_TYPE_PRIMARY },
492 { .base = 0x1d0, .phy = &rk3288_win01_data,
493 .type = DRM_PLANE_TYPE_OVERLAY },
494 { .base = 0x2d0, .phy = &rk3288_win01_data,
495 .type = DRM_PLANE_TYPE_CURSOR },
496};
497
498static const struct vop_data rk3328_vop = {
499 .version = VOP_VERSION(3, 8),
500 .feature = VOP_FEATURE_OUTPUT_RGB10,
501 .intr = &rk3328_vop_intr,
502 .common = &rk3328_common,
503 .modeset = &rk3328_modeset,
504 .output = &rk3328_output,
505 .misc = &rk3328_misc,
506 .win = rk3328_vop_win_data,
507 .win_size = ARRAY_SIZE(rk3328_vop_win_data),
508};
509
377static const struct of_device_id vop_driver_dt_match[] = { 510static const struct of_device_id vop_driver_dt_match[] = {
378 { .compatible = "rockchip,rk3036-vop", 511 { .compatible = "rockchip,rk3036-vop",
379 .data = &rk3036_vop }, 512 .data = &rk3036_vop },
380 { .compatible = "rockchip,rk3288-vop", 513 { .compatible = "rockchip,rk3288-vop",
381 .data = &rk3288_vop }, 514 .data = &rk3288_vop },
515 { .compatible = "rockchip,rk3368-vop",
516 .data = &rk3368_vop },
517 { .compatible = "rockchip,rk3366-vop",
518 .data = &rk3366_vop },
382 { .compatible = "rockchip,rk3399-vop-big", 519 { .compatible = "rockchip,rk3399-vop-big",
383 .data = &rk3399_vop_big }, 520 .data = &rk3399_vop_big },
384 { .compatible = "rockchip,rk3399-vop-lit", 521 { .compatible = "rockchip,rk3399-vop-lit",
385 .data = &rk3399_vop_lit }, 522 .data = &rk3399_vop_lit },
523 { .compatible = "rockchip,rk3228-vop",
524 .data = &rk3228_vop },
525 { .compatible = "rockchip,rk3328-vop",
526 .data = &rk3328_vop },
386 {}, 527 {},
387}; 528};
388MODULE_DEVICE_TABLE(of, vop_driver_dt_match); 529MODULE_DEVICE_TABLE(of, vop_driver_dt_match);
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h b/drivers/gpu/drm/rockchip/rockchip_vop_reg.h
index cd197260ece5..4a4799ff65de 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.h
@@ -41,6 +41,7 @@
41#define RK3288_WIN0_SRC_ALPHA_CTRL 0x0060 41#define RK3288_WIN0_SRC_ALPHA_CTRL 0x0060
42#define RK3288_WIN0_DST_ALPHA_CTRL 0x0064 42#define RK3288_WIN0_DST_ALPHA_CTRL 0x0064
43#define RK3288_WIN0_FADING_CTRL 0x0068 43#define RK3288_WIN0_FADING_CTRL 0x0068
44#define RK3288_WIN0_CTRL2 0x006c
44 45
45/* win1 register */ 46/* win1 register */
46#define RK3288_WIN1_CTRL0 0x0070 47#define RK3288_WIN1_CTRL0 0x0070
@@ -122,6 +123,717 @@
122#define RK3288_DSP_VACT_ST_END_F1 0x019c 123#define RK3288_DSP_VACT_ST_END_F1 0x019c
123/* register definition end */ 124/* register definition end */
124 125
126/* rk3368 register definition */
127#define RK3368_REG_CFG_DONE 0x0000
128#define RK3368_VERSION_INFO 0x0004
129#define RK3368_SYS_CTRL 0x0008
130#define RK3368_SYS_CTRL1 0x000c
131#define RK3368_DSP_CTRL0 0x0010
132#define RK3368_DSP_CTRL1 0x0014
133#define RK3368_DSP_BG 0x0018
134#define RK3368_MCU_CTRL 0x001c
135#define RK3368_LINE_FLAG 0x0020
136#define RK3368_INTR_EN 0x0024
137#define RK3368_INTR_CLEAR 0x0028
138#define RK3368_INTR_STATUS 0x002c
139#define RK3368_WIN0_CTRL0 0x0030
140#define RK3368_WIN0_CTRL1 0x0034
141#define RK3368_WIN0_COLOR_KEY 0x0038
142#define RK3368_WIN0_VIR 0x003c
143#define RK3368_WIN0_YRGB_MST 0x0040
144#define RK3368_WIN0_CBR_MST 0x0044
145#define RK3368_WIN0_ACT_INFO 0x0048
146#define RK3368_WIN0_DSP_INFO 0x004c
147#define RK3368_WIN0_DSP_ST 0x0050
148#define RK3368_WIN0_SCL_FACTOR_YRGB 0x0054
149#define RK3368_WIN0_SCL_FACTOR_CBR 0x0058
150#define RK3368_WIN0_SCL_OFFSET 0x005c
151#define RK3368_WIN0_SRC_ALPHA_CTRL 0x0060
152#define RK3368_WIN0_DST_ALPHA_CTRL 0x0064
153#define RK3368_WIN0_FADING_CTRL 0x0068
154#define RK3368_WIN0_CTRL2 0x006c
155#define RK3368_WIN1_CTRL0 0x0070
156#define RK3368_WIN1_CTRL1 0x0074
157#define RK3368_WIN1_COLOR_KEY 0x0078
158#define RK3368_WIN1_VIR 0x007c
159#define RK3368_WIN1_YRGB_MST 0x0080
160#define RK3368_WIN1_CBR_MST 0x0084
161#define RK3368_WIN1_ACT_INFO 0x0088
162#define RK3368_WIN1_DSP_INFO 0x008c
163#define RK3368_WIN1_DSP_ST 0x0090
164#define RK3368_WIN1_SCL_FACTOR_YRGB 0x0094
165#define RK3368_WIN1_SCL_FACTOR_CBR 0x0098
166#define RK3368_WIN1_SCL_OFFSET 0x009c
167#define RK3368_WIN1_SRC_ALPHA_CTRL 0x00a0
168#define RK3368_WIN1_DST_ALPHA_CTRL 0x00a4
169#define RK3368_WIN1_FADING_CTRL 0x00a8
170#define RK3368_WIN1_CTRL2 0x00ac
171#define RK3368_WIN2_CTRL0 0x00b0
172#define RK3368_WIN2_CTRL1 0x00b4
173#define RK3368_WIN2_VIR0_1 0x00b8
174#define RK3368_WIN2_VIR2_3 0x00bc
175#define RK3368_WIN2_MST0 0x00c0
176#define RK3368_WIN2_DSP_INFO0 0x00c4
177#define RK3368_WIN2_DSP_ST0 0x00c8
178#define RK3368_WIN2_COLOR_KEY 0x00cc
179#define RK3368_WIN2_MST1 0x00d0
180#define RK3368_WIN2_DSP_INFO1 0x00d4
181#define RK3368_WIN2_DSP_ST1 0x00d8
182#define RK3368_WIN2_SRC_ALPHA_CTRL 0x00dc
183#define RK3368_WIN2_MST2 0x00e0
184#define RK3368_WIN2_DSP_INFO2 0x00e4
185#define RK3368_WIN2_DSP_ST2 0x00e8
186#define RK3368_WIN2_DST_ALPHA_CTRL 0x00ec
187#define RK3368_WIN2_MST3 0x00f0
188#define RK3368_WIN2_DSP_INFO3 0x00f4
189#define RK3368_WIN2_DSP_ST3 0x00f8
190#define RK3368_WIN2_FADING_CTRL 0x00fc
191#define RK3368_WIN3_CTRL0 0x0100
192#define RK3368_WIN3_CTRL1 0x0104
193#define RK3368_WIN3_VIR0_1 0x0108
194#define RK3368_WIN3_VIR2_3 0x010c
195#define RK3368_WIN3_MST0 0x0110
196#define RK3368_WIN3_DSP_INFO0 0x0114
197#define RK3368_WIN3_DSP_ST0 0x0118
198#define RK3368_WIN3_COLOR_KEY 0x011c
199#define RK3368_WIN3_MST1 0x0120
200#define RK3368_WIN3_DSP_INFO1 0x0124
201#define RK3368_WIN3_DSP_ST1 0x0128
202#define RK3368_WIN3_SRC_ALPHA_CTRL 0x012c
203#define RK3368_WIN3_MST2 0x0130
204#define RK3368_WIN3_DSP_INFO2 0x0134
205#define RK3368_WIN3_DSP_ST2 0x0138
206#define RK3368_WIN3_DST_ALPHA_CTRL 0x013c
207#define RK3368_WIN3_MST3 0x0140
208#define RK3368_WIN3_DSP_INFO3 0x0144
209#define RK3368_WIN3_DSP_ST3 0x0148
210#define RK3368_WIN3_FADING_CTRL 0x014c
211#define RK3368_HWC_CTRL0 0x0150
212#define RK3368_HWC_CTRL1 0x0154
213#define RK3368_HWC_MST 0x0158
214#define RK3368_HWC_DSP_ST 0x015c
215#define RK3368_HWC_SRC_ALPHA_CTRL 0x0160
216#define RK3368_HWC_DST_ALPHA_CTRL 0x0164
217#define RK3368_HWC_FADING_CTRL 0x0168
218#define RK3368_HWC_RESERVED1 0x016c
219#define RK3368_POST_DSP_HACT_INFO 0x0170
220#define RK3368_POST_DSP_VACT_INFO 0x0174
221#define RK3368_POST_SCL_FACTOR_YRGB 0x0178
222#define RK3368_POST_RESERVED 0x017c
223#define RK3368_POST_SCL_CTRL 0x0180
224#define RK3368_POST_DSP_VACT_INFO_F1 0x0184
225#define RK3368_DSP_HTOTAL_HS_END 0x0188
226#define RK3368_DSP_HACT_ST_END 0x018c
227#define RK3368_DSP_VTOTAL_VS_END 0x0190
228#define RK3368_DSP_VACT_ST_END 0x0194
229#define RK3368_DSP_VS_ST_END_F1 0x0198
230#define RK3368_DSP_VACT_ST_END_F1 0x019c
231#define RK3368_PWM_CTRL 0x01a0
232#define RK3368_PWM_PERIOD_HPR 0x01a4
233#define RK3368_PWM_DUTY_LPR 0x01a8
234#define RK3368_PWM_CNT 0x01ac
235#define RK3368_BCSH_COLOR_BAR 0x01b0
236#define RK3368_BCSH_BCS 0x01b4
237#define RK3368_BCSH_H 0x01b8
238#define RK3368_BCSH_CTRL 0x01bc
239#define RK3368_CABC_CTRL0 0x01c0
240#define RK3368_CABC_CTRL1 0x01c4
241#define RK3368_CABC_CTRL2 0x01c8
242#define RK3368_CABC_CTRL3 0x01cc
243#define RK3368_CABC_GAUSS_LINE0_0 0x01d0
244#define RK3368_CABC_GAUSS_LINE0_1 0x01d4
245#define RK3368_CABC_GAUSS_LINE1_0 0x01d8
246#define RK3368_CABC_GAUSS_LINE1_1 0x01dc
247#define RK3368_CABC_GAUSS_LINE2_0 0x01e0
248#define RK3368_CABC_GAUSS_LINE2_1 0x01e4
249#define RK3368_FRC_LOWER01_0 0x01e8
250#define RK3368_FRC_LOWER01_1 0x01ec
251#define RK3368_FRC_LOWER10_0 0x01f0
252#define RK3368_FRC_LOWER10_1 0x01f4
253#define RK3368_FRC_LOWER11_0 0x01f8
254#define RK3368_FRC_LOWER11_1 0x01fc
255#define RK3368_IFBDC_CTRL 0x0200
256#define RK3368_IFBDC_TILES_NUM 0x0204
257#define RK3368_IFBDC_FRAME_RST_CYCLE 0x0208
258#define RK3368_IFBDC_BASE_ADDR 0x020c
259#define RK3368_IFBDC_MB_SIZE 0x0210
260#define RK3368_IFBDC_CMP_INDEX_INIT 0x0214
261#define RK3368_IFBDC_VIR 0x0220
262#define RK3368_IFBDC_DEBUG0 0x0230
263#define RK3368_IFBDC_DEBUG1 0x0234
264#define RK3368_LATENCY_CTRL0 0x0250
265#define RK3368_RD_MAX_LATENCY_NUM0 0x0254
266#define RK3368_RD_LATENCY_THR_NUM0 0x0258
267#define RK3368_RD_LATENCY_SAMP_NUM0 0x025c
268#define RK3368_WIN0_DSP_BG 0x0260
269#define RK3368_WIN1_DSP_BG 0x0264
270#define RK3368_WIN2_DSP_BG 0x0268
271#define RK3368_WIN3_DSP_BG 0x026c
272#define RK3368_SCAN_LINE_NUM 0x0270
273#define RK3368_CABC_DEBUG0 0x0274
274#define RK3368_CABC_DEBUG1 0x0278
275#define RK3368_CABC_DEBUG2 0x027c
276#define RK3368_DBG_REG_000 0x0280
277#define RK3368_DBG_REG_001 0x0284
278#define RK3368_DBG_REG_002 0x0288
279#define RK3368_DBG_REG_003 0x028c
280#define RK3368_DBG_REG_004 0x0290
281#define RK3368_DBG_REG_005 0x0294
282#define RK3368_DBG_REG_006 0x0298
283#define RK3368_DBG_REG_007 0x029c
284#define RK3368_DBG_REG_008 0x02a0
285#define RK3368_DBG_REG_016 0x02c0
286#define RK3368_DBG_REG_017 0x02c4
287#define RK3368_DBG_REG_018 0x02c8
288#define RK3368_DBG_REG_019 0x02cc
289#define RK3368_DBG_REG_020 0x02d0
290#define RK3368_DBG_REG_021 0x02d4
291#define RK3368_DBG_REG_022 0x02d8
292#define RK3368_DBG_REG_023 0x02dc
293#define RK3368_DBG_REG_028 0x02f0
294#define RK3368_MMU_DTE_ADDR 0x0300
295#define RK3368_MMU_STATUS 0x0304
296#define RK3368_MMU_COMMAND 0x0308
297#define RK3368_MMU_PAGE_FAULT_ADDR 0x030c
298#define RK3368_MMU_ZAP_ONE_LINE 0x0310
299#define RK3368_MMU_INT_RAWSTAT 0x0314
300#define RK3368_MMU_INT_CLEAR 0x0318
301#define RK3368_MMU_INT_MASK 0x031c
302#define RK3368_MMU_INT_STATUS 0x0320
303#define RK3368_MMU_AUTO_GATING 0x0324
304#define RK3368_WIN2_LUT_ADDR 0x0400
305#define RK3368_WIN3_LUT_ADDR 0x0800
306#define RK3368_HWC_LUT_ADDR 0x0c00
307#define RK3368_GAMMA_LUT_ADDR 0x1000
308#define RK3368_CABC_GAMMA_LUT_ADDR 0x1800
309#define RK3368_MCU_BYPASS_WPORT 0x2200
310#define RK3368_MCU_BYPASS_RPORT 0x2300
311/* rk3368 register definition end */
312
313#define RK3366_REG_CFG_DONE 0x0000
314#define RK3366_VERSION_INFO 0x0004
315#define RK3366_SYS_CTRL 0x0008
316#define RK3366_SYS_CTRL1 0x000c
317#define RK3366_DSP_CTRL0 0x0010
318#define RK3366_DSP_CTRL1 0x0014
319#define RK3366_DSP_BG 0x0018
320#define RK3366_MCU_CTRL 0x001c
321#define RK3366_WB_CTRL0 0x0020
322#define RK3366_WB_CTRL1 0x0024
323#define RK3366_WB_YRGB_MST 0x0028
324#define RK3366_WB_CBR_MST 0x002c
325#define RK3366_WIN0_CTRL0 0x0030
326#define RK3366_WIN0_CTRL1 0x0034
327#define RK3366_WIN0_COLOR_KEY 0x0038
328#define RK3366_WIN0_VIR 0x003c
329#define RK3366_WIN0_YRGB_MST 0x0040
330#define RK3366_WIN0_CBR_MST 0x0044
331#define RK3366_WIN0_ACT_INFO 0x0048
332#define RK3366_WIN0_DSP_INFO 0x004c
333#define RK3366_WIN0_DSP_ST 0x0050
334#define RK3366_WIN0_SCL_FACTOR_YRGB 0x0054
335#define RK3366_WIN0_SCL_FACTOR_CBR 0x0058
336#define RK3366_WIN0_SCL_OFFSET 0x005c
337#define RK3366_WIN0_SRC_ALPHA_CTRL 0x0060
338#define RK3366_WIN0_DST_ALPHA_CTRL 0x0064
339#define RK3366_WIN0_FADING_CTRL 0x0068
340#define RK3366_WIN0_CTRL2 0x006c
341#define RK3366_WIN1_CTRL0 0x0070
342#define RK3366_WIN1_CTRL1 0x0074
343#define RK3366_WIN1_COLOR_KEY 0x0078
344#define RK3366_WIN1_VIR 0x007c
345#define RK3366_WIN1_YRGB_MST 0x0080
346#define RK3366_WIN1_CBR_MST 0x0084
347#define RK3366_WIN1_ACT_INFO 0x0088
348#define RK3366_WIN1_DSP_INFO 0x008c
349#define RK3366_WIN1_DSP_ST 0x0090
350#define RK3366_WIN1_SCL_FACTOR_YRGB 0x0094
351#define RK3366_WIN1_SCL_FACTOR_CBR 0x0098
352#define RK3366_WIN1_SCL_OFFSET 0x009c
353#define RK3366_WIN1_SRC_ALPHA_CTRL 0x00a0
354#define RK3366_WIN1_DST_ALPHA_CTRL 0x00a4
355#define RK3366_WIN1_FADING_CTRL 0x00a8
356#define RK3366_WIN1_CTRL2 0x00ac
357#define RK3366_WIN2_CTRL0 0x00b0
358#define RK3366_WIN2_CTRL1 0x00b4
359#define RK3366_WIN2_VIR0_1 0x00b8
360#define RK3366_WIN2_VIR2_3 0x00bc
361#define RK3366_WIN2_MST0 0x00c0
362#define RK3366_WIN2_DSP_INFO0 0x00c4
363#define RK3366_WIN2_DSP_ST0 0x00c8
364#define RK3366_WIN2_COLOR_KEY 0x00cc
365#define RK3366_WIN2_MST1 0x00d0
366#define RK3366_WIN2_DSP_INFO1 0x00d4
367#define RK3366_WIN2_DSP_ST1 0x00d8
368#define RK3366_WIN2_SRC_ALPHA_CTRL 0x00dc
369#define RK3366_WIN2_MST2 0x00e0
370#define RK3366_WIN2_DSP_INFO2 0x00e4
371#define RK3366_WIN2_DSP_ST2 0x00e8
372#define RK3366_WIN2_DST_ALPHA_CTRL 0x00ec
373#define RK3366_WIN2_MST3 0x00f0
374#define RK3366_WIN2_DSP_INFO3 0x00f4
375#define RK3366_WIN2_DSP_ST3 0x00f8
376#define RK3366_WIN2_FADING_CTRL 0x00fc
377#define RK3366_WIN3_CTRL0 0x0100
378#define RK3366_WIN3_CTRL1 0x0104
379#define RK3366_WIN3_VIR0_1 0x0108
380#define RK3366_WIN3_VIR2_3 0x010c
381#define RK3366_WIN3_MST0 0x0110
382#define RK3366_WIN3_DSP_INFO0 0x0114
383#define RK3366_WIN3_DSP_ST0 0x0118
384#define RK3366_WIN3_COLOR_KEY 0x011c
385#define RK3366_WIN3_MST1 0x0120
386#define RK3366_WIN3_DSP_INFO1 0x0124
387#define RK3366_WIN3_DSP_ST1 0x0128
388#define RK3366_WIN3_SRC_ALPHA_CTRL 0x012c
389#define RK3366_WIN3_MST2 0x0130
390#define RK3366_WIN3_DSP_INFO2 0x0134
391#define RK3366_WIN3_DSP_ST2 0x0138
392#define RK3366_WIN3_DST_ALPHA_CTRL 0x013c
393#define RK3366_WIN3_MST3 0x0140
394#define RK3366_WIN3_DSP_INFO3 0x0144
395#define RK3366_WIN3_DSP_ST3 0x0148
396#define RK3366_WIN3_FADING_CTRL 0x014c
397#define RK3366_HWC_CTRL0 0x0150
398#define RK3366_HWC_CTRL1 0x0154
399#define RK3366_HWC_MST 0x0158
400#define RK3366_HWC_DSP_ST 0x015c
401#define RK3366_HWC_SRC_ALPHA_CTRL 0x0160
402#define RK3366_HWC_DST_ALPHA_CTRL 0x0164
403#define RK3366_HWC_FADING_CTRL 0x0168
404#define RK3366_HWC_RESERVED1 0x016c
405#define RK3366_POST_DSP_HACT_INFO 0x0170
406#define RK3366_POST_DSP_VACT_INFO 0x0174
407#define RK3366_POST_SCL_FACTOR_YRGB 0x0178
408#define RK3366_POST_RESERVED 0x017c
409#define RK3366_POST_SCL_CTRL 0x0180
410#define RK3366_POST_DSP_VACT_INFO_F1 0x0184
411#define RK3366_DSP_HTOTAL_HS_END 0x0188
412#define RK3366_DSP_HACT_ST_END 0x018c
413#define RK3366_DSP_VTOTAL_VS_END 0x0190
414#define RK3366_DSP_VACT_ST_END 0x0194
415#define RK3366_DSP_VS_ST_END_F1 0x0198
416#define RK3366_DSP_VACT_ST_END_F1 0x019c
417#define RK3366_PWM_CTRL 0x01a0
418#define RK3366_PWM_PERIOD_HPR 0x01a4
419#define RK3366_PWM_DUTY_LPR 0x01a8
420#define RK3366_PWM_CNT 0x01ac
421#define RK3366_BCSH_COLOR_BAR 0x01b0
422#define RK3366_BCSH_BCS 0x01b4
423#define RK3366_BCSH_H 0x01b8
424#define RK3366_BCSH_CTRL 0x01bc
425#define RK3366_CABC_CTRL0 0x01c0
426#define RK3366_CABC_CTRL1 0x01c4
427#define RK3366_CABC_CTRL2 0x01c8
428#define RK3366_CABC_CTRL3 0x01cc
429#define RK3366_CABC_GAUSS_LINE0_0 0x01d0
430#define RK3366_CABC_GAUSS_LINE0_1 0x01d4
431#define RK3366_CABC_GAUSS_LINE1_0 0x01d8
432#define RK3366_CABC_GAUSS_LINE1_1 0x01dc
433#define RK3366_CABC_GAUSS_LINE2_0 0x01e0
434#define RK3366_CABC_GAUSS_LINE2_1 0x01e4
435#define RK3366_FRC_LOWER01_0 0x01e8
436#define RK3366_FRC_LOWER01_1 0x01ec
437#define RK3366_FRC_LOWER10_0 0x01f0
438#define RK3366_FRC_LOWER10_1 0x01f4
439#define RK3366_FRC_LOWER11_0 0x01f8
440#define RK3366_FRC_LOWER11_1 0x01fc
441#define RK3366_INTR_EN0 0x0280
442#define RK3366_INTR_CLEAR0 0x0284
443#define RK3366_INTR_STATUS0 0x0288
444#define RK3366_INTR_RAW_STATUS0 0x028c
445#define RK3366_INTR_EN1 0x0290
446#define RK3366_INTR_CLEAR1 0x0294
447#define RK3366_INTR_STATUS1 0x0298
448#define RK3366_INTR_RAW_STATUS1 0x029c
449#define RK3366_LINE_FLAG 0x02a0
450#define RK3366_VOP_STATUS 0x02a4
451#define RK3366_BLANKING_VALUE 0x02a8
452#define RK3366_WIN0_DSP_BG 0x02b0
453#define RK3366_WIN1_DSP_BG 0x02b4
454#define RK3366_WIN2_DSP_BG 0x02b8
455#define RK3366_WIN3_DSP_BG 0x02bc
456#define RK3366_WIN2_LUT_ADDR 0x0400
457#define RK3366_WIN3_LUT_ADDR 0x0800
458#define RK3366_HWC_LUT_ADDR 0x0c00
459#define RK3366_GAMMA0_LUT_ADDR 0x1000
460#define RK3366_GAMMA1_LUT_ADDR 0x1400
461#define RK3366_CABC_GAMMA_LUT_ADDR 0x1800
462#define RK3366_MCU_BYPASS_WPORT 0x2200
463#define RK3366_MCU_BYPASS_RPORT 0x2300
464#define RK3366_MMU_DTE_ADDR 0x2400
465#define RK3366_MMU_STATUS 0x2404
466#define RK3366_MMU_COMMAND 0x2408
467#define RK3366_MMU_PAGE_FAULT_ADDR 0x240c
468#define RK3366_MMU_ZAP_ONE_LINE 0x2410
469#define RK3366_MMU_INT_RAWSTAT 0x2414
470#define RK3366_MMU_INT_CLEAR 0x2418
471#define RK3366_MMU_INT_MASK 0x241c
472#define RK3366_MMU_INT_STATUS 0x2420
473#define RK3366_MMU_AUTO_GATING 0x2424
474
475/* rk3399 register definition */
476#define RK3399_REG_CFG_DONE 0x0000
477#define RK3399_VERSION_INFO 0x0004
478#define RK3399_SYS_CTRL 0x0008
479#define RK3399_SYS_CTRL1 0x000c
480#define RK3399_DSP_CTRL0 0x0010
481#define RK3399_DSP_CTRL1 0x0014
482#define RK3399_DSP_BG 0x0018
483#define RK3399_MCU_CTRL 0x001c
484#define RK3399_WB_CTRL0 0x0020
485#define RK3399_WB_CTRL1 0x0024
486#define RK3399_WB_YRGB_MST 0x0028
487#define RK3399_WB_CBR_MST 0x002c
488#define RK3399_WIN0_CTRL0 0x0030
489#define RK3399_WIN0_CTRL1 0x0034
490#define RK3399_WIN0_COLOR_KEY 0x0038
491#define RK3399_WIN0_VIR 0x003c
492#define RK3399_WIN0_YRGB_MST 0x0040
493#define RK3399_WIN0_CBR_MST 0x0044
494#define RK3399_WIN0_ACT_INFO 0x0048
495#define RK3399_WIN0_DSP_INFO 0x004c
496#define RK3399_WIN0_DSP_ST 0x0050
497#define RK3399_WIN0_SCL_FACTOR_YRGB 0x0054
498#define RK3399_WIN0_SCL_FACTOR_CBR 0x0058
499#define RK3399_WIN0_SCL_OFFSET 0x005c
500#define RK3399_WIN0_SRC_ALPHA_CTRL 0x0060
501#define RK3399_WIN0_DST_ALPHA_CTRL 0x0064
502#define RK3399_WIN0_FADING_CTRL 0x0068
503#define RK3399_WIN0_CTRL2 0x006c
504#define RK3399_WIN1_CTRL0 0x0070
505#define RK3399_WIN1_CTRL1 0x0074
506#define RK3399_WIN1_COLOR_KEY 0x0078
507#define RK3399_WIN1_VIR 0x007c
508#define RK3399_WIN1_YRGB_MST 0x0080
509#define RK3399_WIN1_CBR_MST 0x0084
510#define RK3399_WIN1_ACT_INFO 0x0088
511#define RK3399_WIN1_DSP_INFO 0x008c
512#define RK3399_WIN1_DSP_ST 0x0090
513#define RK3399_WIN1_SCL_FACTOR_YRGB 0x0094
514#define RK3399_WIN1_SCL_FACTOR_CBR 0x0098
515#define RK3399_WIN1_SCL_OFFSET 0x009c
516#define RK3399_WIN1_SRC_ALPHA_CTRL 0x00a0
517#define RK3399_WIN1_DST_ALPHA_CTRL 0x00a4
518#define RK3399_WIN1_FADING_CTRL 0x00a8
519#define RK3399_WIN1_CTRL2 0x00ac
520#define RK3399_WIN2_CTRL0 0x00b0
521#define RK3399_WIN2_CTRL1 0x00b4
522#define RK3399_WIN2_VIR0_1 0x00b8
523#define RK3399_WIN2_VIR2_3 0x00bc
524#define RK3399_WIN2_MST0 0x00c0
525#define RK3399_WIN2_DSP_INFO0 0x00c4
526#define RK3399_WIN2_DSP_ST0 0x00c8
527#define RK3399_WIN2_COLOR_KEY 0x00cc
528#define RK3399_WIN2_MST1 0x00d0
529#define RK3399_WIN2_DSP_INFO1 0x00d4
530#define RK3399_WIN2_DSP_ST1 0x00d8
531#define RK3399_WIN2_SRC_ALPHA_CTRL 0x00dc
532#define RK3399_WIN2_MST2 0x00e0
533#define RK3399_WIN2_DSP_INFO2 0x00e4
534#define RK3399_WIN2_DSP_ST2 0x00e8
535#define RK3399_WIN2_DST_ALPHA_CTRL 0x00ec
536#define RK3399_WIN2_MST3 0x00f0
537#define RK3399_WIN2_DSP_INFO3 0x00f4
538#define RK3399_WIN2_DSP_ST3 0x00f8
539#define RK3399_WIN2_FADING_CTRL 0x00fc
540#define RK3399_WIN3_CTRL0 0x0100
541#define RK3399_WIN3_CTRL1 0x0104
542#define RK3399_WIN3_VIR0_1 0x0108
543#define RK3399_WIN3_VIR2_3 0x010c
544#define RK3399_WIN3_MST0 0x0110
545#define RK3399_WIN3_DSP_INFO0 0x0114
546#define RK3399_WIN3_DSP_ST0 0x0118
547#define RK3399_WIN3_COLOR_KEY 0x011c
548#define RK3399_WIN3_MST1 0x0120
549#define RK3399_WIN3_DSP_INFO1 0x0124
550#define RK3399_WIN3_DSP_ST1 0x0128
551#define RK3399_WIN3_SRC_ALPHA_CTRL 0x012c
552#define RK3399_WIN3_MST2 0x0130
553#define RK3399_WIN3_DSP_INFO2 0x0134
554#define RK3399_WIN3_DSP_ST2 0x0138
555#define RK3399_WIN3_DST_ALPHA_CTRL 0x013c
556#define RK3399_WIN3_MST3 0x0140
557#define RK3399_WIN3_DSP_INFO3 0x0144
558#define RK3399_WIN3_DSP_ST3 0x0148
559#define RK3399_WIN3_FADING_CTRL 0x014c
560#define RK3399_HWC_CTRL0 0x0150
561#define RK3399_HWC_CTRL1 0x0154
562#define RK3399_HWC_MST 0x0158
563#define RK3399_HWC_DSP_ST 0x015c
564#define RK3399_HWC_SRC_ALPHA_CTRL 0x0160
565#define RK3399_HWC_DST_ALPHA_CTRL 0x0164
566#define RK3399_HWC_FADING_CTRL 0x0168
567#define RK3399_HWC_RESERVED1 0x016c
568#define RK3399_POST_DSP_HACT_INFO 0x0170
569#define RK3399_POST_DSP_VACT_INFO 0x0174
570#define RK3399_POST_SCL_FACTOR_YRGB 0x0178
571#define RK3399_POST_RESERVED 0x017c
572#define RK3399_POST_SCL_CTRL 0x0180
573#define RK3399_POST_DSP_VACT_INFO_F1 0x0184
574#define RK3399_DSP_HTOTAL_HS_END 0x0188
575#define RK3399_DSP_HACT_ST_END 0x018c
576#define RK3399_DSP_VTOTAL_VS_END 0x0190
577#define RK3399_DSP_VACT_ST_END 0x0194
578#define RK3399_DSP_VS_ST_END_F1 0x0198
579#define RK3399_DSP_VACT_ST_END_F1 0x019c
580#define RK3399_PWM_CTRL 0x01a0
581#define RK3399_PWM_PERIOD_HPR 0x01a4
582#define RK3399_PWM_DUTY_LPR 0x01a8
583#define RK3399_PWM_CNT 0x01ac
584#define RK3399_BCSH_COLOR_BAR 0x01b0
585#define RK3399_BCSH_BCS 0x01b4
586#define RK3399_BCSH_H 0x01b8
587#define RK3399_BCSH_CTRL 0x01bc
588#define RK3399_CABC_CTRL0 0x01c0
589#define RK3399_CABC_CTRL1 0x01c4
590#define RK3399_CABC_CTRL2 0x01c8
591#define RK3399_CABC_CTRL3 0x01cc
592#define RK3399_CABC_GAUSS_LINE0_0 0x01d0
593#define RK3399_CABC_GAUSS_LINE0_1 0x01d4
594#define RK3399_CABC_GAUSS_LINE1_0 0x01d8
595#define RK3399_CABC_GAUSS_LINE1_1 0x01dc
596#define RK3399_CABC_GAUSS_LINE2_0 0x01e0
597#define RK3399_CABC_GAUSS_LINE2_1 0x01e4
598#define RK3399_FRC_LOWER01_0 0x01e8
599#define RK3399_FRC_LOWER01_1 0x01ec
600#define RK3399_FRC_LOWER10_0 0x01f0
601#define RK3399_FRC_LOWER10_1 0x01f4
602#define RK3399_FRC_LOWER11_0 0x01f8
603#define RK3399_FRC_LOWER11_1 0x01fc
604#define RK3399_AFBCD0_CTRL 0x0200
605#define RK3399_AFBCD0_HDR_PTR 0x0204
606#define RK3399_AFBCD0_PIC_SIZE 0x0208
607#define RK3399_AFBCD0_STATUS 0x020c
608#define RK3399_AFBCD1_CTRL 0x0220
609#define RK3399_AFBCD1_HDR_PTR 0x0224
610#define RK3399_AFBCD1_PIC_SIZE 0x0228
611#define RK3399_AFBCD1_STATUS 0x022c
612#define RK3399_AFBCD2_CTRL 0x0240
613#define RK3399_AFBCD2_HDR_PTR 0x0244
614#define RK3399_AFBCD2_PIC_SIZE 0x0248
615#define RK3399_AFBCD2_STATUS 0x024c
616#define RK3399_AFBCD3_CTRL 0x0260
617#define RK3399_AFBCD3_HDR_PTR 0x0264
618#define RK3399_AFBCD3_PIC_SIZE 0x0268
619#define RK3399_AFBCD3_STATUS 0x026c
620#define RK3399_INTR_EN0 0x0280
621#define RK3399_INTR_CLEAR0 0x0284
622#define RK3399_INTR_STATUS0 0x0288
623#define RK3399_INTR_RAW_STATUS0 0x028c
624#define RK3399_INTR_EN1 0x0290
625#define RK3399_INTR_CLEAR1 0x0294
626#define RK3399_INTR_STATUS1 0x0298
627#define RK3399_INTR_RAW_STATUS1 0x029c
628#define RK3399_LINE_FLAG 0x02a0
629#define RK3399_VOP_STATUS 0x02a4
630#define RK3399_BLANKING_VALUE 0x02a8
631#define RK3399_MCU_BYPASS_PORT 0x02ac
632#define RK3399_WIN0_DSP_BG 0x02b0
633#define RK3399_WIN1_DSP_BG 0x02b4
634#define RK3399_WIN2_DSP_BG 0x02b8
635#define RK3399_WIN3_DSP_BG 0x02bc
636#define RK3399_YUV2YUV_WIN 0x02c0
637#define RK3399_YUV2YUV_POST 0x02c4
638#define RK3399_AUTO_GATING_EN 0x02cc
639#define RK3399_WIN0_CSC_COE 0x03a0
640#define RK3399_WIN1_CSC_COE 0x03c0
641#define RK3399_WIN2_CSC_COE 0x03e0
642#define RK3399_WIN3_CSC_COE 0x0400
643#define RK3399_HWC_CSC_COE 0x0420
644#define RK3399_BCSH_R2Y_CSC_COE 0x0440
645#define RK3399_BCSH_Y2R_CSC_COE 0x0460
646#define RK3399_POST_YUV2YUV_Y2R_COE 0x0480
647#define RK3399_POST_YUV2YUV_3X3_COE 0x04a0
648#define RK3399_POST_YUV2YUV_R2Y_COE 0x04c0
649#define RK3399_WIN0_YUV2YUV_Y2R 0x04e0
650#define RK3399_WIN0_YUV2YUV_3X3 0x0500
651#define RK3399_WIN0_YUV2YUV_R2Y 0x0520
652#define RK3399_WIN1_YUV2YUV_Y2R 0x0540
653#define RK3399_WIN1_YUV2YUV_3X3 0x0560
654#define RK3399_WIN1_YUV2YUV_R2Y 0x0580
655#define RK3399_WIN2_YUV2YUV_Y2R 0x05a0
656#define RK3399_WIN2_YUV2YUV_3X3 0x05c0
657#define RK3399_WIN2_YUV2YUV_R2Y 0x05e0
658#define RK3399_WIN3_YUV2YUV_Y2R 0x0600
659#define RK3399_WIN3_YUV2YUV_3X3 0x0620
660#define RK3399_WIN3_YUV2YUV_R2Y 0x0640
661#define RK3399_WIN2_LUT_ADDR 0x1000
662#define RK3399_WIN3_LUT_ADDR 0x1400
663#define RK3399_HWC_LUT_ADDR 0x1800
664#define RK3399_CABC_GAMMA_LUT_ADDR 0x1c00
665#define RK3399_GAMMA_LUT_ADDR 0x2000
666/* rk3399 register definition end */
667
668/* rk3328 register definition end */
669#define RK3328_REG_CFG_DONE 0x00000000
670#define RK3328_VERSION_INFO 0x00000004
671#define RK3328_SYS_CTRL 0x00000008
672#define RK3328_SYS_CTRL1 0x0000000c
673#define RK3328_DSP_CTRL0 0x00000010
674#define RK3328_DSP_CTRL1 0x00000014
675#define RK3328_DSP_BG 0x00000018
676#define RK3328_AUTO_GATING_EN 0x0000003c
677#define RK3328_LINE_FLAG 0x00000040
678#define RK3328_VOP_STATUS 0x00000044
679#define RK3328_BLANKING_VALUE 0x00000048
680#define RK3328_WIN0_DSP_BG 0x00000050
681#define RK3328_WIN1_DSP_BG 0x00000054
682#define RK3328_DBG_PERF_LATENCY_CTRL0 0x000000c0
683#define RK3328_DBG_PERF_RD_MAX_LATENCY_NUM0 0x000000c4
684#define RK3328_DBG_PERF_RD_LATENCY_THR_NUM0 0x000000c8
685#define RK3328_DBG_PERF_RD_LATENCY_SAMP_NUM0 0x000000cc
686#define RK3328_INTR_EN0 0x000000e0
687#define RK3328_INTR_CLEAR0 0x000000e4
688#define RK3328_INTR_STATUS0 0x000000e8
689#define RK3328_INTR_RAW_STATUS0 0x000000ec
690#define RK3328_INTR_EN1 0x000000f0
691#define RK3328_INTR_CLEAR1 0x000000f4
692#define RK3328_INTR_STATUS1 0x000000f8
693#define RK3328_INTR_RAW_STATUS1 0x000000fc
694#define RK3328_WIN0_CTRL0 0x00000100
695#define RK3328_WIN0_CTRL1 0x00000104
696#define RK3328_WIN0_COLOR_KEY 0x00000108
697#define RK3328_WIN0_VIR 0x0000010c
698#define RK3328_WIN0_YRGB_MST 0x00000110
699#define RK3328_WIN0_CBR_MST 0x00000114
700#define RK3328_WIN0_ACT_INFO 0x00000118
701#define RK3328_WIN0_DSP_INFO 0x0000011c
702#define RK3328_WIN0_DSP_ST 0x00000120
703#define RK3328_WIN0_SCL_FACTOR_YRGB 0x00000124
704#define RK3328_WIN0_SCL_FACTOR_CBR 0x00000128
705#define RK3328_WIN0_SCL_OFFSET 0x0000012c
706#define RK3328_WIN0_SRC_ALPHA_CTRL 0x00000130
707#define RK3328_WIN0_DST_ALPHA_CTRL 0x00000134
708#define RK3328_WIN0_FADING_CTRL 0x00000138
709#define RK3328_WIN0_CTRL2 0x0000013c
710#define RK3328_DBG_WIN0_REG0 0x000001f0
711#define RK3328_DBG_WIN0_REG1 0x000001f4
712#define RK3328_DBG_WIN0_REG2 0x000001f8
713#define RK3328_DBG_WIN0_RESERVED 0x000001fc
714#define RK3328_WIN1_CTRL0 0x00000200
715#define RK3328_WIN1_CTRL1 0x00000204
716#define RK3328_WIN1_COLOR_KEY 0x00000208
717#define RK3328_WIN1_VIR 0x0000020c
718#define RK3328_WIN1_YRGB_MST 0x00000210
719#define RK3328_WIN1_CBR_MST 0x00000214
720#define RK3328_WIN1_ACT_INFO 0x00000218
721#define RK3328_WIN1_DSP_INFO 0x0000021c
722#define RK3328_WIN1_DSP_ST 0x00000220
723#define RK3328_WIN1_SCL_FACTOR_YRGB 0x00000224
724#define RK3328_WIN1_SCL_FACTOR_CBR 0x00000228
725#define RK3328_WIN1_SCL_OFFSET 0x0000022c
726#define RK3328_WIN1_SRC_ALPHA_CTRL 0x00000230
727#define RK3328_WIN1_DST_ALPHA_CTRL 0x00000234
728#define RK3328_WIN1_FADING_CTRL 0x00000238
729#define RK3328_WIN1_CTRL2 0x0000023c
730#define RK3328_DBG_WIN1_REG0 0x000002f0
731#define RK3328_DBG_WIN1_REG1 0x000002f4
732#define RK3328_DBG_WIN1_REG2 0x000002f8
733#define RK3328_DBG_WIN1_RESERVED 0x000002fc
734#define RK3328_WIN2_CTRL0 0x00000300
735#define RK3328_WIN2_CTRL1 0x00000304
736#define RK3328_WIN2_COLOR_KEY 0x00000308
737#define RK3328_WIN2_VIR 0x0000030c
738#define RK3328_WIN2_YRGB_MST 0x00000310
739#define RK3328_WIN2_CBR_MST 0x00000314
740#define RK3328_WIN2_ACT_INFO 0x00000318
741#define RK3328_WIN2_DSP_INFO 0x0000031c
742#define RK3328_WIN2_DSP_ST 0x00000320
743#define RK3328_WIN2_SCL_FACTOR_YRGB 0x00000324
744#define RK3328_WIN2_SCL_FACTOR_CBR 0x00000328
745#define RK3328_WIN2_SCL_OFFSET 0x0000032c
746#define RK3328_WIN2_SRC_ALPHA_CTRL 0x00000330
747#define RK3328_WIN2_DST_ALPHA_CTRL 0x00000334
748#define RK3328_WIN2_FADING_CTRL 0x00000338
749#define RK3328_WIN2_CTRL2 0x0000033c
750#define RK3328_DBG_WIN2_REG0 0x000003f0
751#define RK3328_DBG_WIN2_REG1 0x000003f4
752#define RK3328_DBG_WIN2_REG2 0x000003f8
753#define RK3328_DBG_WIN2_RESERVED 0x000003fc
754#define RK3328_WIN3_CTRL0 0x00000400
755#define RK3328_WIN3_CTRL1 0x00000404
756#define RK3328_WIN3_COLOR_KEY 0x00000408
757#define RK3328_WIN3_VIR 0x0000040c
758#define RK3328_WIN3_YRGB_MST 0x00000410
759#define RK3328_WIN3_CBR_MST 0x00000414
760#define RK3328_WIN3_ACT_INFO 0x00000418
761#define RK3328_WIN3_DSP_INFO 0x0000041c
762#define RK3328_WIN3_DSP_ST 0x00000420
763#define RK3328_WIN3_SCL_FACTOR_YRGB 0x00000424
764#define RK3328_WIN3_SCL_FACTOR_CBR 0x00000428
765#define RK3328_WIN3_SCL_OFFSET 0x0000042c
766#define RK3328_WIN3_SRC_ALPHA_CTRL 0x00000430
767#define RK3328_WIN3_DST_ALPHA_CTRL 0x00000434
768#define RK3328_WIN3_FADING_CTRL 0x00000438
769#define RK3328_WIN3_CTRL2 0x0000043c
770#define RK3328_DBG_WIN3_REG0 0x000004f0
771#define RK3328_DBG_WIN3_REG1 0x000004f4
772#define RK3328_DBG_WIN3_REG2 0x000004f8
773#define RK3328_DBG_WIN3_RESERVED 0x000004fc
774
775#define RK3328_HWC_CTRL0 0x00000500
776#define RK3328_HWC_CTRL1 0x00000504
777#define RK3328_HWC_MST 0x00000508
778#define RK3328_HWC_DSP_ST 0x0000050c
779#define RK3328_HWC_SRC_ALPHA_CTRL 0x00000510
780#define RK3328_HWC_DST_ALPHA_CTRL 0x00000514
781#define RK3328_HWC_FADING_CTRL 0x00000518
782#define RK3328_HWC_RESERVED1 0x0000051c
783#define RK3328_POST_DSP_HACT_INFO 0x00000600
784#define RK3328_POST_DSP_VACT_INFO 0x00000604
785#define RK3328_POST_SCL_FACTOR_YRGB 0x00000608
786#define RK3328_POST_RESERVED 0x0000060c
787#define RK3328_POST_SCL_CTRL 0x00000610
788#define RK3328_POST_DSP_VACT_INFO_F1 0x00000614
789#define RK3328_DSP_HTOTAL_HS_END 0x00000618
790#define RK3328_DSP_HACT_ST_END 0x0000061c
791#define RK3328_DSP_VTOTAL_VS_END 0x00000620
792#define RK3328_DSP_VACT_ST_END 0x00000624
793#define RK3328_DSP_VS_ST_END_F1 0x00000628
794#define RK3328_DSP_VACT_ST_END_F1 0x0000062c
795#define RK3328_BCSH_COLOR_BAR 0x00000640
796#define RK3328_BCSH_BCS 0x00000644
797#define RK3328_BCSH_H 0x00000648
798#define RK3328_BCSH_CTRL 0x0000064c
799#define RK3328_FRC_LOWER01_0 0x00000678
800#define RK3328_FRC_LOWER01_1 0x0000067c
801#define RK3328_FRC_LOWER10_0 0x00000680
802#define RK3328_FRC_LOWER10_1 0x00000684
803#define RK3328_FRC_LOWER11_0 0x00000688
804#define RK3328_FRC_LOWER11_1 0x0000068c
805#define RK3328_DBG_POST_REG0 0x000006e8
806#define RK3328_DBG_POST_RESERVED 0x000006ec
807#define RK3328_DBG_DATAO 0x000006f0
808#define RK3328_DBG_DATAO_2 0x000006f4
809
810/* sdr to hdr */
811#define RK3328_SDR2HDR_CTRL 0x00000700
812#define RK3328_EOTF_OETF_Y0 0x00000704
813#define RK3328_RESERVED0001 0x00000708
814#define RK3328_RESERVED0002 0x0000070c
815#define RK3328_EOTF_OETF_Y1 0x00000710
816#define RK3328_EOTF_OETF_Y64 0x0000080c
817#define RK3328_OETF_DX_DXPOW1 0x00000810
818#define RK3328_OETF_DX_DXPOW64 0x0000090c
819#define RK3328_OETF_XN1 0x00000910
820#define RK3328_OETF_XN63 0x00000a08
821
822/* hdr to sdr */
823#define RK3328_HDR2SDR_CTRL 0x00000a10
824#define RK3328_HDR2SDR_SRC_RANGE 0x00000a14
825#define RK3328_HDR2SDR_NORMFACEETF 0x00000a18
826#define RK3328_RESERVED0003 0x00000a1c
827#define RK3328_HDR2SDR_DST_RANGE 0x00000a20
828#define RK3328_HDR2SDR_NORMFACCGAMMA 0x00000a24
829#define RK3328_EETF_OETF_Y0 0x00000a28
830#define RK3328_SAT_Y0 0x00000a2c
831#define RK3328_EETF_OETF_Y1 0x00000a30
832#define RK3328_SAT_Y1 0x00000ab0
833#define RK3328_SAT_Y8 0x00000acc
834
835#define RK3328_HWC_LUT_ADDR 0x00000c00
836
125/* rk3036 register definition */ 837/* rk3036 register definition */
126#define RK3036_SYS_CTRL 0x00 838#define RK3036_SYS_CTRL 0x00
127#define RK3036_DSP_CTRL0 0x04 839#define RK3036_DSP_CTRL0 0x04
@@ -166,197 +878,4 @@
166#define RK3036_HWC_LUT_ADDR 0x800 878#define RK3036_HWC_LUT_ADDR 0x800
167/* rk3036 register definition end */ 879/* rk3036 register definition end */
168 880
169/* rk3399 register definition */
170#define RK3399_REG_CFG_DONE 0x00000
171#define RK3399_VERSION_INFO 0x00004
172#define RK3399_SYS_CTRL 0x00008
173#define RK3399_SYS_CTRL1 0x0000c
174#define RK3399_DSP_CTRL0 0x00010
175#define RK3399_DSP_CTRL1 0x00014
176#define RK3399_DSP_BG 0x00018
177#define RK3399_MCU_CTRL 0x0001c
178#define RK3399_WB_CTRL0 0x00020
179#define RK3399_WB_CTRL1 0x00024
180#define RK3399_WB_YRGB_MST 0x00028
181#define RK3399_WB_CBR_MST 0x0002c
182#define RK3399_WIN0_CTRL0 0x00030
183#define RK3399_WIN0_CTRL1 0x00034
184#define RK3399_WIN0_COLOR_KEY 0x00038
185#define RK3399_WIN0_VIR 0x0003c
186#define RK3399_WIN0_YRGB_MST 0x00040
187#define RK3399_WIN0_CBR_MST 0x00044
188#define RK3399_WIN0_ACT_INFO 0x00048
189#define RK3399_WIN0_DSP_INFO 0x0004c
190#define RK3399_WIN0_DSP_ST 0x00050
191#define RK3399_WIN0_SCL_FACTOR_YRGB 0x00054
192#define RK3399_WIN0_SCL_FACTOR_CBR 0x00058
193#define RK3399_WIN0_SCL_OFFSET 0x0005c
194#define RK3399_WIN0_SRC_ALPHA_CTRL 0x00060
195#define RK3399_WIN0_DST_ALPHA_CTRL 0x00064
196#define RK3399_WIN0_FADING_CTRL 0x00068
197#define RK3399_WIN0_CTRL2 0x0006c
198#define RK3399_WIN1_CTRL0 0x00070
199#define RK3399_WIN1_CTRL1 0x00074
200#define RK3399_WIN1_COLOR_KEY 0x00078
201#define RK3399_WIN1_VIR 0x0007c
202#define RK3399_WIN1_YRGB_MST 0x00080
203#define RK3399_WIN1_CBR_MST 0x00084
204#define RK3399_WIN1_ACT_INFO 0x00088
205#define RK3399_WIN1_DSP_INFO 0x0008c
206#define RK3399_WIN1_DSP_ST 0x00090
207#define RK3399_WIN1_SCL_FACTOR_YRGB 0x00094
208#define RK3399_WIN1_SCL_FACTOR_CBR 0x00098
209#define RK3399_WIN1_SCL_OFFSET 0x0009c
210#define RK3399_WIN1_SRC_ALPHA_CTRL 0x000a0
211#define RK3399_WIN1_DST_ALPHA_CTRL 0x000a4
212#define RK3399_WIN1_FADING_CTRL 0x000a8
213#define RK3399_WIN1_CTRL2 0x000ac
214#define RK3399_WIN2_CTRL0 0x000b0
215#define RK3399_WIN2_CTRL1 0x000b4
216#define RK3399_WIN2_VIR0_1 0x000b8
217#define RK3399_WIN2_VIR2_3 0x000bc
218#define RK3399_WIN2_MST0 0x000c0
219#define RK3399_WIN2_DSP_INFO0 0x000c4
220#define RK3399_WIN2_DSP_ST0 0x000c8
221#define RK3399_WIN2_COLOR_KEY 0x000cc
222#define RK3399_WIN2_MST1 0x000d0
223#define RK3399_WIN2_DSP_INFO1 0x000d4
224#define RK3399_WIN2_DSP_ST1 0x000d8
225#define RK3399_WIN2_SRC_ALPHA_CTRL 0x000dc
226#define RK3399_WIN2_MST2 0x000e0
227#define RK3399_WIN2_DSP_INFO2 0x000e4
228#define RK3399_WIN2_DSP_ST2 0x000e8
229#define RK3399_WIN2_DST_ALPHA_CTRL 0x000ec
230#define RK3399_WIN2_MST3 0x000f0
231#define RK3399_WIN2_DSP_INFO3 0x000f4
232#define RK3399_WIN2_DSP_ST3 0x000f8
233#define RK3399_WIN2_FADING_CTRL 0x000fc
234#define RK3399_WIN3_CTRL0 0x00100
235#define RK3399_WIN3_CTRL1 0x00104
236#define RK3399_WIN3_VIR0_1 0x00108
237#define RK3399_WIN3_VIR2_3 0x0010c
238#define RK3399_WIN3_MST0 0x00110
239#define RK3399_WIN3_DSP_INFO0 0x00114
240#define RK3399_WIN3_DSP_ST0 0x00118
241#define RK3399_WIN3_COLOR_KEY 0x0011c
242#define RK3399_WIN3_MST1 0x00120
243#define RK3399_WIN3_DSP_INFO1 0x00124
244#define RK3399_WIN3_DSP_ST1 0x00128
245#define RK3399_WIN3_SRC_ALPHA_CTRL 0x0012c
246#define RK3399_WIN3_MST2 0x00130
247#define RK3399_WIN3_DSP_INFO2 0x00134
248#define RK3399_WIN3_DSP_ST2 0x00138
249#define RK3399_WIN3_DST_ALPHA_CTRL 0x0013c
250#define RK3399_WIN3_MST3 0x00140
251#define RK3399_WIN3_DSP_INFO3 0x00144
252#define RK3399_WIN3_DSP_ST3 0x00148
253#define RK3399_WIN3_FADING_CTRL 0x0014c
254#define RK3399_HWC_CTRL0 0x00150
255#define RK3399_HWC_CTRL1 0x00154
256#define RK3399_HWC_MST 0x00158
257#define RK3399_HWC_DSP_ST 0x0015c
258#define RK3399_HWC_SRC_ALPHA_CTRL 0x00160
259#define RK3399_HWC_DST_ALPHA_CTRL 0x00164
260#define RK3399_HWC_FADING_CTRL 0x00168
261#define RK3399_HWC_RESERVED1 0x0016c
262#define RK3399_POST_DSP_HACT_INFO 0x00170
263#define RK3399_POST_DSP_VACT_INFO 0x00174
264#define RK3399_POST_SCL_FACTOR_YRGB 0x00178
265#define RK3399_POST_RESERVED 0x0017c
266#define RK3399_POST_SCL_CTRL 0x00180
267#define RK3399_POST_DSP_VACT_INFO_F1 0x00184
268#define RK3399_DSP_HTOTAL_HS_END 0x00188
269#define RK3399_DSP_HACT_ST_END 0x0018c
270#define RK3399_DSP_VTOTAL_VS_END 0x00190
271#define RK3399_DSP_VACT_ST_END 0x00194
272#define RK3399_DSP_VS_ST_END_F1 0x00198
273#define RK3399_DSP_VACT_ST_END_F1 0x0019c
274#define RK3399_PWM_CTRL 0x001a0
275#define RK3399_PWM_PERIOD_HPR 0x001a4
276#define RK3399_PWM_DUTY_LPR 0x001a8
277#define RK3399_PWM_CNT 0x001ac
278#define RK3399_BCSH_COLOR_BAR 0x001b0
279#define RK3399_BCSH_BCS 0x001b4
280#define RK3399_BCSH_H 0x001b8
281#define RK3399_BCSH_CTRL 0x001bc
282#define RK3399_CABC_CTRL0 0x001c0
283#define RK3399_CABC_CTRL1 0x001c4
284#define RK3399_CABC_CTRL2 0x001c8
285#define RK3399_CABC_CTRL3 0x001cc
286#define RK3399_CABC_GAUSS_LINE0_0 0x001d0
287#define RK3399_CABC_GAUSS_LINE0_1 0x001d4
288#define RK3399_CABC_GAUSS_LINE1_0 0x001d8
289#define RK3399_CABC_GAUSS_LINE1_1 0x001dc
290#define RK3399_CABC_GAUSS_LINE2_0 0x001e0
291#define RK3399_CABC_GAUSS_LINE2_1 0x001e4
292#define RK3399_FRC_LOWER01_0 0x001e8
293#define RK3399_FRC_LOWER01_1 0x001ec
294#define RK3399_FRC_LOWER10_0 0x001f0
295#define RK3399_FRC_LOWER10_1 0x001f4
296#define RK3399_FRC_LOWER11_0 0x001f8
297#define RK3399_FRC_LOWER11_1 0x001fc
298#define RK3399_AFBCD0_CTRL 0x00200
299#define RK3399_AFBCD0_HDR_PTR 0x00204
300#define RK3399_AFBCD0_PIC_SIZE 0x00208
301#define RK3399_AFBCD0_STATUS 0x0020c
302#define RK3399_AFBCD1_CTRL 0x00220
303#define RK3399_AFBCD1_HDR_PTR 0x00224
304#define RK3399_AFBCD1_PIC_SIZE 0x00228
305#define RK3399_AFBCD1_STATUS 0x0022c
306#define RK3399_AFBCD2_CTRL 0x00240
307#define RK3399_AFBCD2_HDR_PTR 0x00244
308#define RK3399_AFBCD2_PIC_SIZE 0x00248
309#define RK3399_AFBCD2_STATUS 0x0024c
310#define RK3399_AFBCD3_CTRL 0x00260
311#define RK3399_AFBCD3_HDR_PTR 0x00264
312#define RK3399_AFBCD3_PIC_SIZE 0x00268
313#define RK3399_AFBCD3_STATUS 0x0026c
314#define RK3399_INTR_EN0 0x00280
315#define RK3399_INTR_CLEAR0 0x00284
316#define RK3399_INTR_STATUS0 0x00288
317#define RK3399_INTR_RAW_STATUS0 0x0028c
318#define RK3399_INTR_EN1 0x00290
319#define RK3399_INTR_CLEAR1 0x00294
320#define RK3399_INTR_STATUS1 0x00298
321#define RK3399_INTR_RAW_STATUS1 0x0029c
322#define RK3399_LINE_FLAG 0x002a0
323#define RK3399_VOP_STATUS 0x002a4
324#define RK3399_BLANKING_VALUE 0x002a8
325#define RK3399_MCU_BYPASS_PORT 0x002ac
326#define RK3399_WIN0_DSP_BG 0x002b0
327#define RK3399_WIN1_DSP_BG 0x002b4
328#define RK3399_WIN2_DSP_BG 0x002b8
329#define RK3399_WIN3_DSP_BG 0x002bc
330#define RK3399_YUV2YUV_WIN 0x002c0
331#define RK3399_YUV2YUV_POST 0x002c4
332#define RK3399_AUTO_GATING_EN 0x002cc
333#define RK3399_WIN0_CSC_COE 0x003a0
334#define RK3399_WIN1_CSC_COE 0x003c0
335#define RK3399_WIN2_CSC_COE 0x003e0
336#define RK3399_WIN3_CSC_COE 0x00400
337#define RK3399_HWC_CSC_COE 0x00420
338#define RK3399_BCSH_R2Y_CSC_COE 0x00440
339#define RK3399_BCSH_Y2R_CSC_COE 0x00460
340#define RK3399_POST_YUV2YUV_Y2R_COE 0x00480
341#define RK3399_POST_YUV2YUV_3X3_COE 0x004a0
342#define RK3399_POST_YUV2YUV_R2Y_COE 0x004c0
343#define RK3399_WIN0_YUV2YUV_Y2R 0x004e0
344#define RK3399_WIN0_YUV2YUV_3X3 0x00500
345#define RK3399_WIN0_YUV2YUV_R2Y 0x00520
346#define RK3399_WIN1_YUV2YUV_Y2R 0x00540
347#define RK3399_WIN1_YUV2YUV_3X3 0x00560
348#define RK3399_WIN1_YUV2YUV_R2Y 0x00580
349#define RK3399_WIN2_YUV2YUV_Y2R 0x005a0
350#define RK3399_WIN2_YUV2YUV_3X3 0x005c0
351#define RK3399_WIN2_YUV2YUV_R2Y 0x005e0
352#define RK3399_WIN3_YUV2YUV_Y2R 0x00600
353#define RK3399_WIN3_YUV2YUV_3X3 0x00620
354#define RK3399_WIN3_YUV2YUV_R2Y 0x00640
355#define RK3399_WIN2_LUT_ADDR 0x01000
356#define RK3399_WIN3_LUT_ADDR 0x01400
357#define RK3399_HWC_LUT_ADDR 0x01800
358#define RK3399_CABC_GAMMA_LUT_ADDR 0x01c00
359#define RK3399_GAMMA_LUT_ADDR 0x02000
360/* rk3399 register definition end */
361
362#endif /* _ROCKCHIP_VOP_REG_H */ 881#endif /* _ROCKCHIP_VOP_REG_H */
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/shmobile/shmob_drm_drv.c
index c2ca07357aac..592572554eb0 100644
--- a/drivers/gpu/drm/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/shmobile/shmob_drm_drv.c
@@ -145,8 +145,6 @@ static struct drm_driver shmob_drm_driver = {
145 .gem_prime_vunmap = drm_gem_cma_prime_vunmap, 145 .gem_prime_vunmap = drm_gem_cma_prime_vunmap,
146 .gem_prime_mmap = drm_gem_cma_prime_mmap, 146 .gem_prime_mmap = drm_gem_cma_prime_mmap,
147 .dumb_create = drm_gem_cma_dumb_create, 147 .dumb_create = drm_gem_cma_dumb_create,
148 .dumb_map_offset = drm_gem_cma_dumb_map_offset,
149 .dumb_destroy = drm_gem_dumb_destroy,
150 .fops = &shmob_drm_fops, 148 .fops = &shmob_drm_fops,
151 .name = "shmob-drm", 149 .name = "shmob-drm",
152 .desc = "Renesas SH Mobile DRM", 150 .desc = "Renesas SH Mobile DRM",
diff --git a/drivers/gpu/drm/sti/sti_cursor.c b/drivers/gpu/drm/sti/sti_cursor.c
index 5b3a41f74f21..b709ebbec095 100644
--- a/drivers/gpu/drm/sti/sti_cursor.c
+++ b/drivers/gpu/drm/sti/sti_cursor.c
@@ -348,7 +348,6 @@ static const struct drm_plane_funcs sti_cursor_plane_helpers_funcs = {
348 .update_plane = drm_atomic_helper_update_plane, 348 .update_plane = drm_atomic_helper_update_plane,
349 .disable_plane = drm_atomic_helper_disable_plane, 349 .disable_plane = drm_atomic_helper_disable_plane,
350 .destroy = sti_cursor_destroy, 350 .destroy = sti_cursor_destroy,
351 .set_property = drm_atomic_helper_plane_set_property,
352 .reset = sti_plane_reset, 351 .reset = sti_plane_reset,
353 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 352 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
354 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 353 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
@@ -392,7 +391,7 @@ struct drm_plane *sti_cursor_create(struct drm_device *drm_dev,
392 &sti_cursor_plane_helpers_funcs, 391 &sti_cursor_plane_helpers_funcs,
393 cursor_supported_formats, 392 cursor_supported_formats,
394 ARRAY_SIZE(cursor_supported_formats), 393 ARRAY_SIZE(cursor_supported_formats),
395 DRM_PLANE_TYPE_CURSOR, NULL); 394 NULL, DRM_PLANE_TYPE_CURSOR, NULL);
396 if (res) { 395 if (res) {
397 DRM_ERROR("Failed to initialize universal plane\n"); 396 DRM_ERROR("Failed to initialize universal plane\n");
398 goto err_plane; 397 goto err_plane;
diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c
index 06ef1e3886cf..1700c542cd93 100644
--- a/drivers/gpu/drm/sti/sti_drv.c
+++ b/drivers/gpu/drm/sti/sti_drv.c
@@ -175,8 +175,6 @@ static struct drm_driver sti_driver = {
175 .gem_free_object_unlocked = drm_gem_cma_free_object, 175 .gem_free_object_unlocked = drm_gem_cma_free_object,
176 .gem_vm_ops = &drm_gem_cma_vm_ops, 176 .gem_vm_ops = &drm_gem_cma_vm_ops,
177 .dumb_create = drm_gem_cma_dumb_create, 177 .dumb_create = drm_gem_cma_dumb_create,
178 .dumb_map_offset = drm_gem_cma_dumb_map_offset,
179 .dumb_destroy = drm_gem_dumb_destroy,
180 .fops = &sti_driver_fops, 178 .fops = &sti_driver_fops,
181 179
182 .enable_vblank = sti_crtc_enable_vblank, 180 .enable_vblank = sti_crtc_enable_vblank,
diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c
index a51cd9f754db..852bf2293b05 100644
--- a/drivers/gpu/drm/sti/sti_dvo.c
+++ b/drivers/gpu/drm/sti/sti_dvo.c
@@ -412,7 +412,6 @@ static int sti_dvo_late_register(struct drm_connector *connector)
412} 412}
413 413
414static const struct drm_connector_funcs sti_dvo_connector_funcs = { 414static const struct drm_connector_funcs sti_dvo_connector_funcs = {
415 .dpms = drm_atomic_helper_connector_dpms,
416 .fill_modes = drm_helper_probe_single_connector_modes, 415 .fill_modes = drm_helper_probe_single_connector_modes,
417 .detect = sti_dvo_connector_detect, 416 .detect = sti_dvo_connector_detect,
418 .destroy = drm_connector_cleanup, 417 .destroy = drm_connector_cleanup,
diff --git a/drivers/gpu/drm/sti/sti_gdp.c b/drivers/gpu/drm/sti/sti_gdp.c
index 5ee0503945c8..b65eea4f2c97 100644
--- a/drivers/gpu/drm/sti/sti_gdp.c
+++ b/drivers/gpu/drm/sti/sti_gdp.c
@@ -895,7 +895,6 @@ static const struct drm_plane_funcs sti_gdp_plane_helpers_funcs = {
895 .update_plane = drm_atomic_helper_update_plane, 895 .update_plane = drm_atomic_helper_update_plane,
896 .disable_plane = drm_atomic_helper_disable_plane, 896 .disable_plane = drm_atomic_helper_disable_plane,
897 .destroy = sti_gdp_destroy, 897 .destroy = sti_gdp_destroy,
898 .set_property = drm_atomic_helper_plane_set_property,
899 .reset = sti_plane_reset, 898 .reset = sti_plane_reset,
900 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 899 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
901 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 900 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
@@ -931,7 +930,7 @@ struct drm_plane *sti_gdp_create(struct drm_device *drm_dev,
931 &sti_gdp_plane_helpers_funcs, 930 &sti_gdp_plane_helpers_funcs,
932 gdp_supported_formats, 931 gdp_supported_formats,
933 ARRAY_SIZE(gdp_supported_formats), 932 ARRAY_SIZE(gdp_supported_formats),
934 type, NULL); 933 NULL, type, NULL);
935 if (res) { 934 if (res) {
936 DRM_ERROR("Failed to initialize universal plane\n"); 935 DRM_ERROR("Failed to initialize universal plane\n");
937 goto err; 936 goto err;
diff --git a/drivers/gpu/drm/sti/sti_hda.c b/drivers/gpu/drm/sti/sti_hda.c
index d6ed909d9d75..cf65e32b5090 100644
--- a/drivers/gpu/drm/sti/sti_hda.c
+++ b/drivers/gpu/drm/sti/sti_hda.c
@@ -647,7 +647,6 @@ static int sti_hda_late_register(struct drm_connector *connector)
647} 647}
648 648
649static const struct drm_connector_funcs sti_hda_connector_funcs = { 649static const struct drm_connector_funcs sti_hda_connector_funcs = {
650 .dpms = drm_atomic_helper_connector_dpms,
651 .fill_modes = drm_helper_probe_single_connector_modes, 650 .fill_modes = drm_helper_probe_single_connector_modes,
652 .destroy = drm_connector_cleanup, 651 .destroy = drm_connector_cleanup,
653 .reset = drm_atomic_helper_connector_reset, 652 .reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
index dbc6a195d6f9..30f02d2fdd03 100644
--- a/drivers/gpu/drm/sti/sti_hdmi.c
+++ b/drivers/gpu/drm/sti/sti_hdmi.c
@@ -1113,12 +1113,10 @@ static int sti_hdmi_late_register(struct drm_connector *connector)
1113} 1113}
1114 1114
1115static const struct drm_connector_funcs sti_hdmi_connector_funcs = { 1115static const struct drm_connector_funcs sti_hdmi_connector_funcs = {
1116 .dpms = drm_atomic_helper_connector_dpms,
1117 .fill_modes = drm_helper_probe_single_connector_modes, 1116 .fill_modes = drm_helper_probe_single_connector_modes,
1118 .detect = sti_hdmi_connector_detect, 1117 .detect = sti_hdmi_connector_detect,
1119 .destroy = drm_connector_cleanup, 1118 .destroy = drm_connector_cleanup,
1120 .reset = drm_atomic_helper_connector_reset, 1119 .reset = drm_atomic_helper_connector_reset,
1121 .set_property = drm_atomic_helper_connector_set_property,
1122 .atomic_set_property = sti_hdmi_connector_set_property, 1120 .atomic_set_property = sti_hdmi_connector_set_property,
1123 .atomic_get_property = sti_hdmi_connector_get_property, 1121 .atomic_get_property = sti_hdmi_connector_get_property,
1124 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 1122 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
diff --git a/drivers/gpu/drm/sti/sti_hqvdp.c b/drivers/gpu/drm/sti/sti_hqvdp.c
index 53a46dda8bd5..b19b3430b296 100644
--- a/drivers/gpu/drm/sti/sti_hqvdp.c
+++ b/drivers/gpu/drm/sti/sti_hqvdp.c
@@ -1276,7 +1276,6 @@ static const struct drm_plane_funcs sti_hqvdp_plane_helpers_funcs = {
1276 .update_plane = drm_atomic_helper_update_plane, 1276 .update_plane = drm_atomic_helper_update_plane,
1277 .disable_plane = drm_atomic_helper_disable_plane, 1277 .disable_plane = drm_atomic_helper_disable_plane,
1278 .destroy = sti_hqvdp_destroy, 1278 .destroy = sti_hqvdp_destroy,
1279 .set_property = drm_atomic_helper_plane_set_property,
1280 .reset = sti_plane_reset, 1279 .reset = sti_plane_reset,
1281 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 1280 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
1282 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 1281 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
@@ -1298,7 +1297,7 @@ static struct drm_plane *sti_hqvdp_create(struct drm_device *drm_dev,
1298 &sti_hqvdp_plane_helpers_funcs, 1297 &sti_hqvdp_plane_helpers_funcs,
1299 hqvdp_supported_formats, 1298 hqvdp_supported_formats,
1300 ARRAY_SIZE(hqvdp_supported_formats), 1299 ARRAY_SIZE(hqvdp_supported_formats),
1301 DRM_PLANE_TYPE_OVERLAY, NULL); 1300 NULL, DRM_PLANE_TYPE_OVERLAY, NULL);
1302 if (res) { 1301 if (res) {
1303 DRM_ERROR("Failed to initialize universal plane\n"); 1302 DRM_ERROR("Failed to initialize universal plane\n");
1304 return NULL; 1303 return NULL;
diff --git a/drivers/gpu/drm/stm/Kconfig b/drivers/gpu/drm/stm/Kconfig
index 4b88223f9aed..35367ada3bc1 100644
--- a/drivers/gpu/drm/stm/Kconfig
+++ b/drivers/gpu/drm/stm/Kconfig
@@ -7,10 +7,16 @@ config DRM_STM
7 select DRM_PANEL_BRIDGE 7 select DRM_PANEL_BRIDGE
8 select VIDEOMODE_HELPERS 8 select VIDEOMODE_HELPERS
9 select FB_PROVIDE_GET_FB_UNMAPPED_AREA 9 select FB_PROVIDE_GET_FB_UNMAPPED_AREA
10 default y
11 10
12 help 11 help
13 Enable support for the on-chip display controller on 12 Enable support for the on-chip display controller on
14 STMicroelectronics STM32 MCUs. 13 STMicroelectronics STM32 MCUs.
15 To compile this driver as a module, choose M here: the module 14 To compile this driver as a module, choose M here: the module
16 will be called stm-drm. 15 will be called stm-drm.
16
17config DRM_STM_DSI
18 tristate "STMicroelectronics specific extensions for Synopsys MIPI DSI"
19 depends on DRM_STM
20 select DRM_DW_MIPI_DSI
21 help
22 Choose this option for MIPI DSI support on STMicroelectronics SoC.
diff --git a/drivers/gpu/drm/stm/Makefile b/drivers/gpu/drm/stm/Makefile
index a09ecf450218..d883adc365a2 100644
--- a/drivers/gpu/drm/stm/Makefile
+++ b/drivers/gpu/drm/stm/Makefile
@@ -2,4 +2,6 @@ stm-drm-y := \
2 drv.o \ 2 drv.o \
3 ltdc.o 3 ltdc.o
4 4
5obj-$(CONFIG_DRM_STM_DSI) += dw_mipi_dsi-stm.o
6
5obj-$(CONFIG_DRM_STM) += stm-drm.o 7obj-$(CONFIG_DRM_STM) += stm-drm.o
diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c
index 83ab48f1fd00..b333b37f3f89 100644
--- a/drivers/gpu/drm/stm/drv.c
+++ b/drivers/gpu/drm/stm/drv.c
@@ -20,13 +20,6 @@
20 20
21#include "ltdc.h" 21#include "ltdc.h"
22 22
23#define DRIVER_NAME "stm"
24#define DRIVER_DESC "STMicroelectronics SoC DRM"
25#define DRIVER_DATE "20170330"
26#define DRIVER_MAJOR 1
27#define DRIVER_MINOR 0
28#define DRIVER_PATCH_LEVEL 0
29
30#define STM_MAX_FB_WIDTH 2048 23#define STM_MAX_FB_WIDTH 2048
31#define STM_MAX_FB_HEIGHT 2048 /* same as width to handle orientation */ 24#define STM_MAX_FB_HEIGHT 2048 /* same as width to handle orientation */
32 25
@@ -59,16 +52,14 @@ static struct drm_driver drv_driver = {
59 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | 52 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
60 DRIVER_ATOMIC, 53 DRIVER_ATOMIC,
61 .lastclose = drv_lastclose, 54 .lastclose = drv_lastclose,
62 .name = DRIVER_NAME, 55 .name = "stm",
63 .desc = DRIVER_DESC, 56 .desc = "STMicroelectronics SoC DRM",
64 .date = DRIVER_DATE, 57 .date = "20170330",
65 .major = DRIVER_MAJOR, 58 .major = 1,
66 .minor = DRIVER_MINOR, 59 .minor = 0,
67 .patchlevel = DRIVER_PATCH_LEVEL, 60 .patchlevel = 0,
68 .fops = &drv_driver_fops, 61 .fops = &drv_driver_fops,
69 .dumb_create = drm_gem_cma_dumb_create, 62 .dumb_create = drm_gem_cma_dumb_create,
70 .dumb_map_offset = drm_gem_cma_dumb_map_offset,
71 .dumb_destroy = drm_gem_dumb_destroy,
72 .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 63 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
73 .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 64 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
74 .gem_free_object_unlocked = drm_gem_cma_free_object, 65 .gem_free_object_unlocked = drm_gem_cma_free_object,
@@ -206,7 +197,7 @@ static struct platform_driver stm_drm_platform_driver = {
206 .probe = stm_drm_platform_probe, 197 .probe = stm_drm_platform_probe,
207 .remove = stm_drm_platform_remove, 198 .remove = stm_drm_platform_remove,
208 .driver = { 199 .driver = {
209 .name = DRIVER_NAME, 200 .name = "stm32-display",
210 .of_match_table = drv_dt_ids, 201 .of_match_table = drv_dt_ids,
211 }, 202 },
212}; 203};
diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
new file mode 100644
index 000000000000..568c5d0461ea
--- /dev/null
+++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
@@ -0,0 +1,352 @@
1/*
2 * Copyright (C) STMicroelectronics SA 2017
3 *
4 * Authors: Philippe Cornu <philippe.cornu@st.com>
5 * Yannick Fertre <yannick.fertre@st.com>
6 *
7 * License terms: GNU General Public License (GPL), version 2
8 */
9
10#include <linux/clk.h>
11#include <linux/iopoll.h>
12#include <linux/module.h>
13#include <drm/drmP.h>
14#include <drm/drm_mipi_dsi.h>
15#include <drm/bridge/dw_mipi_dsi.h>
16#include <video/mipi_display.h>
17
18/* DSI wrapper register & bit definitions */
19/* Note: registers are named as in the Reference Manual */
20#define DSI_WCFGR 0x0400 /* Wrapper ConFiGuration Reg */
21#define WCFGR_DSIM BIT(0) /* DSI Mode */
22#define WCFGR_COLMUX GENMASK(3, 1) /* COLor MUltipleXing */
23
24#define DSI_WCR 0x0404 /* Wrapper Control Reg */
25#define WCR_DSIEN BIT(3) /* DSI ENable */
26
27#define DSI_WISR 0x040C /* Wrapper Interrupt and Status Reg */
28#define WISR_PLLLS BIT(8) /* PLL Lock Status */
29#define WISR_RRS BIT(12) /* Regulator Ready Status */
30
31#define DSI_WPCR0 0x0418 /* Wrapper Phy Conf Reg 0 */
32#define WPCR0_UIX4 GENMASK(5, 0) /* Unit Interval X 4 */
33#define WPCR0_TDDL BIT(16) /* Turn Disable Data Lanes */
34
35#define DSI_WRPCR 0x0430 /* Wrapper Regulator & Pll Ctrl Reg */
36#define WRPCR_PLLEN BIT(0) /* PLL ENable */
37#define WRPCR_NDIV GENMASK(8, 2) /* pll loop DIVision Factor */
38#define WRPCR_IDF GENMASK(14, 11) /* pll Input Division Factor */
39#define WRPCR_ODF GENMASK(17, 16) /* pll Output Division Factor */
40#define WRPCR_REGEN BIT(24) /* REGulator ENable */
41#define WRPCR_BGREN BIT(28) /* BandGap Reference ENable */
42#define IDF_MIN 1
43#define IDF_MAX 7
44#define NDIV_MIN 10
45#define NDIV_MAX 125
46#define ODF_MIN 1
47#define ODF_MAX 8
48
49/* dsi color format coding according to the datasheet */
50enum dsi_color {
51 DSI_RGB565_CONF1,
52 DSI_RGB565_CONF2,
53 DSI_RGB565_CONF3,
54 DSI_RGB666_CONF1,
55 DSI_RGB666_CONF2,
56 DSI_RGB888,
57};
58
59#define LANE_MIN_KBPS 31250
60#define LANE_MAX_KBPS 500000
61
62/* Sleep & timeout for regulator on/off, pll lock/unlock & fifo empty */
63#define SLEEP_US 1000
64#define TIMEOUT_US 200000
65
66struct dw_mipi_dsi_stm {
67 void __iomem *base;
68 struct clk *pllref_clk;
69};
70
71static inline void dsi_write(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 val)
72{
73 writel(val, dsi->base + reg);
74}
75
76static inline u32 dsi_read(struct dw_mipi_dsi_stm *dsi, u32 reg)
77{
78 return readl(dsi->base + reg);
79}
80
81static inline void dsi_set(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 mask)
82{
83 dsi_write(dsi, reg, dsi_read(dsi, reg) | mask);
84}
85
86static inline void dsi_clear(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 mask)
87{
88 dsi_write(dsi, reg, dsi_read(dsi, reg) & ~mask);
89}
90
91static inline void dsi_update_bits(struct dw_mipi_dsi_stm *dsi, u32 reg,
92 u32 mask, u32 val)
93{
94 dsi_write(dsi, reg, (dsi_read(dsi, reg) & ~mask) | val);
95}
96
97static enum dsi_color dsi_color_from_mipi(enum mipi_dsi_pixel_format fmt)
98{
99 switch (fmt) {
100 case MIPI_DSI_FMT_RGB888:
101 return DSI_RGB888;
102 case MIPI_DSI_FMT_RGB666:
103 return DSI_RGB666_CONF2;
104 case MIPI_DSI_FMT_RGB666_PACKED:
105 return DSI_RGB666_CONF1;
106 case MIPI_DSI_FMT_RGB565:
107 return DSI_RGB565_CONF1;
108 default:
109 DRM_DEBUG_DRIVER("MIPI color invalid, so we use rgb888\n");
110 }
111 return DSI_RGB888;
112}
113
114static int dsi_pll_get_clkout_khz(int clkin_khz, int idf, int ndiv, int odf)
115{
116 /* prevent from division by 0 */
117 if (idf * odf)
118 return DIV_ROUND_CLOSEST(clkin_khz * ndiv, idf * odf);
119
120 return 0;
121}
122
123static int dsi_pll_get_params(int clkin_khz, int clkout_khz,
124 int *idf, int *ndiv, int *odf)
125{
126 int i, o, n, n_min, n_max;
127 int fvco_min, fvco_max, delta, best_delta; /* all in khz */
128
129 /* Early checks preventing division by 0 & odd results */
130 if ((clkin_khz <= 0) || (clkout_khz <= 0))
131 return -EINVAL;
132
133 fvco_min = LANE_MIN_KBPS * 2 * ODF_MAX;
134 fvco_max = LANE_MAX_KBPS * 2 * ODF_MIN;
135
136 best_delta = 1000000; /* big started value (1000000khz) */
137
138 for (i = IDF_MIN; i <= IDF_MAX; i++) {
139 /* Compute ndiv range according to Fvco */
140 n_min = ((fvco_min * i) / (2 * clkin_khz)) + 1;
141 n_max = (fvco_max * i) / (2 * clkin_khz);
142
143 /* No need to continue idf loop if we reach ndiv max */
144 if (n_min >= NDIV_MAX)
145 break;
146
147 /* Clamp ndiv to valid values */
148 if (n_min < NDIV_MIN)
149 n_min = NDIV_MIN;
150 if (n_max > NDIV_MAX)
151 n_max = NDIV_MAX;
152
153 for (o = ODF_MIN; o <= ODF_MAX; o *= 2) {
154 n = DIV_ROUND_CLOSEST(i * o * clkout_khz, clkin_khz);
155 /* Check ndiv according to vco range */
156 if ((n < n_min) || (n > n_max))
157 continue;
158 /* Check if new delta is better & saves parameters */
159 delta = dsi_pll_get_clkout_khz(clkin_khz, i, n, o) -
160 clkout_khz;
161 if (delta < 0)
162 delta = -delta;
163 if (delta < best_delta) {
164 *idf = i;
165 *ndiv = n;
166 *odf = o;
167 best_delta = delta;
168 }
169 /* fast return in case of "perfect result" */
170 if (!delta)
171 return 0;
172 }
173 }
174
175 return 0;
176}
177
178static int dw_mipi_dsi_phy_init(void *priv_data)
179{
180 struct dw_mipi_dsi_stm *dsi = priv_data;
181 u32 val;
182 int ret;
183
184 /* Enable the regulator */
185 dsi_set(dsi, DSI_WRPCR, WRPCR_REGEN | WRPCR_BGREN);
186 ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_RRS,
187 SLEEP_US, TIMEOUT_US);
188 if (ret)
189 DRM_DEBUG_DRIVER("!TIMEOUT! waiting REGU, let's continue\n");
190
191 /* Enable the DSI PLL & wait for its lock */
192 dsi_set(dsi, DSI_WRPCR, WRPCR_PLLEN);
193 ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_PLLLS,
194 SLEEP_US, TIMEOUT_US);
195 if (ret)
196 DRM_DEBUG_DRIVER("!TIMEOUT! waiting PLL, let's continue\n");
197
198 /* Enable the DSI wrapper */
199 dsi_set(dsi, DSI_WCR, WCR_DSIEN);
200
201 return 0;
202}
203
204static int
205dw_mipi_dsi_get_lane_mbps(void *priv_data, struct drm_display_mode *mode,
206 unsigned long mode_flags, u32 lanes, u32 format,
207 unsigned int *lane_mbps)
208{
209 struct dw_mipi_dsi_stm *dsi = priv_data;
210 unsigned int idf, ndiv, odf, pll_in_khz, pll_out_khz;
211 int ret, bpp;
212 u32 val;
213
214 pll_in_khz = (unsigned int)(clk_get_rate(dsi->pllref_clk) / 1000);
215
216 /* Compute requested pll out */
217 bpp = mipi_dsi_pixel_format_to_bpp(format);
218 pll_out_khz = mode->clock * bpp / lanes;
219 /* Add 20% to pll out to be higher than pixel bw (burst mode only) */
220 pll_out_khz = (pll_out_khz * 12) / 10;
221 if (pll_out_khz > LANE_MAX_KBPS) {
222 pll_out_khz = LANE_MAX_KBPS;
223 DRM_WARN("Warning max phy mbps is used\n");
224 }
225 if (pll_out_khz < LANE_MIN_KBPS) {
226 pll_out_khz = LANE_MIN_KBPS;
227 DRM_WARN("Warning min phy mbps is used\n");
228 }
229
230 /* Compute best pll parameters */
231 idf = 0;
232 ndiv = 0;
233 odf = 0;
234 ret = dsi_pll_get_params(pll_in_khz, pll_out_khz, &idf, &ndiv, &odf);
235 if (ret)
236 DRM_WARN("Warning dsi_pll_get_params(): bad params\n");
237
238 /* Get the adjusted pll out value */
239 pll_out_khz = dsi_pll_get_clkout_khz(pll_in_khz, idf, ndiv, odf);
240
241 /* Set the PLL division factors */
242 dsi_update_bits(dsi, DSI_WRPCR, WRPCR_NDIV | WRPCR_IDF | WRPCR_ODF,
243 (ndiv << 2) | (idf << 11) | ((ffs(odf) - 1) << 16));
244
245 /* Compute uix4 & set the bit period in high-speed mode */
246 val = 4000000 / pll_out_khz;
247 dsi_update_bits(dsi, DSI_WPCR0, WPCR0_UIX4, val);
248
249 /* Select video mode by resetting DSIM bit */
250 dsi_clear(dsi, DSI_WCFGR, WCFGR_DSIM);
251
252 /* Select the color coding */
253 dsi_update_bits(dsi, DSI_WCFGR, WCFGR_COLMUX,
254 dsi_color_from_mipi(format) << 1);
255
256 *lane_mbps = pll_out_khz / 1000;
257
258 DRM_DEBUG_DRIVER("pll_in %ukHz pll_out %ukHz lane_mbps %uMHz\n",
259 pll_in_khz, pll_out_khz, *lane_mbps);
260
261 return 0;
262}
263
264static const struct dw_mipi_dsi_phy_ops dw_mipi_dsi_stm_phy_ops = {
265 .init = dw_mipi_dsi_phy_init,
266 .get_lane_mbps = dw_mipi_dsi_get_lane_mbps,
267};
268
269static struct dw_mipi_dsi_plat_data dw_mipi_dsi_stm_plat_data = {
270 .max_data_lanes = 2,
271 .phy_ops = &dw_mipi_dsi_stm_phy_ops,
272};
273
274static const struct of_device_id dw_mipi_dsi_stm_dt_ids[] = {
275 { .compatible = "st,stm32-dsi", .data = &dw_mipi_dsi_stm_plat_data, },
276 { },
277};
278MODULE_DEVICE_TABLE(of, dw_mipi_dsi_stm_dt_ids);
279
280static int dw_mipi_dsi_stm_probe(struct platform_device *pdev)
281{
282 struct device *dev = &pdev->dev;
283 struct dw_mipi_dsi_stm *dsi;
284 struct resource *res;
285 int ret;
286
287 dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
288 if (!dsi)
289 return -ENOMEM;
290
291 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
292 if (!res) {
293 DRM_ERROR("Unable to get resource\n");
294 return -ENODEV;
295 }
296
297 dsi->base = devm_ioremap_resource(dev, res);
298 if (IS_ERR(dsi->base)) {
299 DRM_ERROR("Unable to get dsi registers\n");
300 return PTR_ERR(dsi->base);
301 }
302
303 dsi->pllref_clk = devm_clk_get(dev, "ref");
304 if (IS_ERR(dsi->pllref_clk)) {
305 ret = PTR_ERR(dsi->pllref_clk);
306 dev_err(dev, "Unable to get pll reference clock: %d\n", ret);
307 return ret;
308 }
309
310 ret = clk_prepare_enable(dsi->pllref_clk);
311 if (ret) {
312 dev_err(dev, "%s: Failed to enable pllref_clk\n", __func__);
313 return ret;
314 }
315
316 dw_mipi_dsi_stm_plat_data.base = dsi->base;
317 dw_mipi_dsi_stm_plat_data.priv_data = dsi;
318
319 ret = dw_mipi_dsi_probe(pdev, &dw_mipi_dsi_stm_plat_data);
320 if (ret) {
321 DRM_ERROR("Failed to initialize mipi dsi host\n");
322 clk_disable_unprepare(dsi->pllref_clk);
323 }
324
325 return ret;
326}
327
328static int dw_mipi_dsi_stm_remove(struct platform_device *pdev)
329{
330 struct dw_mipi_dsi_stm *dsi = dw_mipi_dsi_stm_plat_data.priv_data;
331
332 clk_disable_unprepare(dsi->pllref_clk);
333 dw_mipi_dsi_remove(pdev);
334
335 return 0;
336}
337
338static struct platform_driver dw_mipi_dsi_stm_driver = {
339 .probe = dw_mipi_dsi_stm_probe,
340 .remove = dw_mipi_dsi_stm_remove,
341 .driver = {
342 .of_match_table = dw_mipi_dsi_stm_dt_ids,
343 .name = "dw_mipi_dsi-stm",
344 },
345};
346
347module_platform_driver(dw_mipi_dsi_stm_driver);
348
349MODULE_AUTHOR("Philippe Cornu <philippe.cornu@st.com>");
350MODULE_AUTHOR("Yannick Fertre <yannick.fertre@st.com>");
351MODULE_DESCRIPTION("STMicroelectronics DW MIPI DSI host controller driver");
352MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index e46b427eacc7..d394a03632c4 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -42,52 +42,52 @@
42 * an extra offset specified with reg_ofs. 42 * an extra offset specified with reg_ofs.
43 */ 43 */
44#define REG_OFS_NONE 0 44#define REG_OFS_NONE 0
45#define REG_OFS_4 4 /* Insertion of "Layer Configuration 2" reg */ 45#define REG_OFS_4 4 /* Insertion of "Layer Conf. 2" reg */
46#define REG_OFS (ldev->caps.reg_ofs) 46#define REG_OFS (ldev->caps.reg_ofs)
47#define LAY_OFS 0x80 /* Register Offset between 2 layers */ 47#define LAY_OFS 0x80 /* Register Offset between 2 layers */
48 48
49/* Global register offsets */ 49/* Global register offsets */
50#define LTDC_IDR 0x0000 /* IDentification */ 50#define LTDC_IDR 0x0000 /* IDentification */
51#define LTDC_LCR 0x0004 /* Layer Count */ 51#define LTDC_LCR 0x0004 /* Layer Count */
52#define LTDC_SSCR 0x0008 /* Synchronization Size Configuration */ 52#define LTDC_SSCR 0x0008 /* Synchronization Size Configuration */
53#define LTDC_BPCR 0x000C /* Back Porch Configuration */ 53#define LTDC_BPCR 0x000C /* Back Porch Configuration */
54#define LTDC_AWCR 0x0010 /* Active Width Configuration */ 54#define LTDC_AWCR 0x0010 /* Active Width Configuration */
55#define LTDC_TWCR 0x0014 /* Total Width Configuration */ 55#define LTDC_TWCR 0x0014 /* Total Width Configuration */
56#define LTDC_GCR 0x0018 /* Global Control */ 56#define LTDC_GCR 0x0018 /* Global Control */
57#define LTDC_GC1R 0x001C /* Global Configuration 1 */ 57#define LTDC_GC1R 0x001C /* Global Configuration 1 */
58#define LTDC_GC2R 0x0020 /* Global Configuration 2 */ 58#define LTDC_GC2R 0x0020 /* Global Configuration 2 */
59#define LTDC_SRCR 0x0024 /* Shadow Reload Configuration */ 59#define LTDC_SRCR 0x0024 /* Shadow Reload Configuration */
60#define LTDC_GACR 0x0028 /* GAmma Correction */ 60#define LTDC_GACR 0x0028 /* GAmma Correction */
61#define LTDC_BCCR 0x002C /* Background Color Configuration */ 61#define LTDC_BCCR 0x002C /* Background Color Configuration */
62#define LTDC_IER 0x0034 /* Interrupt Enable */ 62#define LTDC_IER 0x0034 /* Interrupt Enable */
63#define LTDC_ISR 0x0038 /* Interrupt Status */ 63#define LTDC_ISR 0x0038 /* Interrupt Status */
64#define LTDC_ICR 0x003C /* Interrupt Clear */ 64#define LTDC_ICR 0x003C /* Interrupt Clear */
65#define LTDC_LIPCR 0x0040 /* Line Interrupt Position Configuration */ 65#define LTDC_LIPCR 0x0040 /* Line Interrupt Position Conf. */
66#define LTDC_CPSR 0x0044 /* Current Position Status */ 66#define LTDC_CPSR 0x0044 /* Current Position Status */
67#define LTDC_CDSR 0x0048 /* Current Display Status */ 67#define LTDC_CDSR 0x0048 /* Current Display Status */
68 68
69/* Layer register offsets */ 69/* Layer register offsets */
70#define LTDC_L1LC1R (0x0080) /* L1 Layer Configuration 1 */ 70#define LTDC_L1LC1R (0x80) /* L1 Layer Configuration 1 */
71#define LTDC_L1LC2R (0x0084) /* L1 Layer Configuration 2 */ 71#define LTDC_L1LC2R (0x84) /* L1 Layer Configuration 2 */
72#define LTDC_L1CR (0x0084 + REG_OFS) /* L1 Control */ 72#define LTDC_L1CR (0x84 + REG_OFS)/* L1 Control */
73#define LTDC_L1WHPCR (0x0088 + REG_OFS) /* L1 Window Hor Position Config */ 73#define LTDC_L1WHPCR (0x88 + REG_OFS)/* L1 Window Hor Position Config */
74#define LTDC_L1WVPCR (0x008C + REG_OFS) /* L1 Window Vert Position Config */ 74#define LTDC_L1WVPCR (0x8C + REG_OFS)/* L1 Window Vert Position Config */
75#define LTDC_L1CKCR (0x0090 + REG_OFS) /* L1 Color Keying Configuration */ 75#define LTDC_L1CKCR (0x90 + REG_OFS)/* L1 Color Keying Configuration */
76#define LTDC_L1PFCR (0x0094 + REG_OFS) /* L1 Pixel Format Configuration */ 76#define LTDC_L1PFCR (0x94 + REG_OFS)/* L1 Pixel Format Configuration */
77#define LTDC_L1CACR (0x0098 + REG_OFS) /* L1 Constant Alpha Config */ 77#define LTDC_L1CACR (0x98 + REG_OFS)/* L1 Constant Alpha Config */
78#define LTDC_L1DCCR (0x009C + REG_OFS) /* L1 Default Color Configuration */ 78#define LTDC_L1DCCR (0x9C + REG_OFS)/* L1 Default Color Configuration */
79#define LTDC_L1BFCR (0x00A0 + REG_OFS) /* L1 Blend Factors Configuration */ 79#define LTDC_L1BFCR (0xA0 + REG_OFS)/* L1 Blend Factors Configuration */
80#define LTDC_L1FBBCR (0x00A4 + REG_OFS) /* L1 FrameBuffer Bus Control */ 80#define LTDC_L1FBBCR (0xA4 + REG_OFS)/* L1 FrameBuffer Bus Control */
81#define LTDC_L1AFBCR (0x00A8 + REG_OFS) /* L1 AuxFB Control */ 81#define LTDC_L1AFBCR (0xA8 + REG_OFS)/* L1 AuxFB Control */
82#define LTDC_L1CFBAR (0x00AC + REG_OFS) /* L1 Color FrameBuffer Address */ 82#define LTDC_L1CFBAR (0xAC + REG_OFS)/* L1 Color FrameBuffer Address */
83#define LTDC_L1CFBLR (0x00B0 + REG_OFS) /* L1 Color FrameBuffer Length */ 83#define LTDC_L1CFBLR (0xB0 + REG_OFS)/* L1 Color FrameBuffer Length */
84#define LTDC_L1CFBLNR (0x00B4 + REG_OFS) /* L1 Color FrameBuffer Line Nb */ 84#define LTDC_L1CFBLNR (0xB4 + REG_OFS)/* L1 Color FrameBuffer Line Nb */
85#define LTDC_L1AFBAR (0x00B8 + REG_OFS) /* L1 AuxFB Address */ 85#define LTDC_L1AFBAR (0xB8 + REG_OFS)/* L1 AuxFB Address */
86#define LTDC_L1AFBLR (0x00BC + REG_OFS) /* L1 AuxFB Length */ 86#define LTDC_L1AFBLR (0xBC + REG_OFS)/* L1 AuxFB Length */
87#define LTDC_L1AFBLNR (0x00C0 + REG_OFS) /* L1 AuxFB Line Number */ 87#define LTDC_L1AFBLNR (0xC0 + REG_OFS)/* L1 AuxFB Line Number */
88#define LTDC_L1CLUTWR (0x00C4 + REG_OFS) /* L1 CLUT Write */ 88#define LTDC_L1CLUTWR (0xC4 + REG_OFS)/* L1 CLUT Write */
89#define LTDC_L1YS1R (0x00E0 + REG_OFS) /* L1 YCbCr Scale 1 */ 89#define LTDC_L1YS1R (0xE0 + REG_OFS)/* L1 YCbCr Scale 1 */
90#define LTDC_L1YS2R (0x00E4 + REG_OFS) /* L1 YCbCr Scale 2 */ 90#define LTDC_L1YS2R (0xE4 + REG_OFS)/* L1 YCbCr Scale 2 */
91 91
92/* Bit definitions */ 92/* Bit definitions */
93#define SSCR_VSH GENMASK(10, 0) /* Vertical Synchronization Height */ 93#define SSCR_VSH GENMASK(10, 0) /* Vertical Synchronization Height */
@@ -104,10 +104,10 @@
104 104
105#define GCR_LTDCEN BIT(0) /* LTDC ENable */ 105#define GCR_LTDCEN BIT(0) /* LTDC ENable */
106#define GCR_DEN BIT(16) /* Dither ENable */ 106#define GCR_DEN BIT(16) /* Dither ENable */
107#define GCR_PCPOL BIT(28) /* Pixel Clock POLarity */ 107#define GCR_PCPOL BIT(28) /* Pixel Clock POLarity-Inverted */
108#define GCR_DEPOL BIT(29) /* Data Enable POLarity */ 108#define GCR_DEPOL BIT(29) /* Data Enable POLarity-High */
109#define GCR_VSPOL BIT(30) /* Vertical Synchro POLarity */ 109#define GCR_VSPOL BIT(30) /* Vertical Synchro POLarity-High */
110#define GCR_HSPOL BIT(31) /* Horizontal Synchro POLarity */ 110#define GCR_HSPOL BIT(31) /* Horizontal Synchro POLarity-High */
111 111
112#define GC1R_WBCH GENMASK(3, 0) /* Width of Blue CHannel output */ 112#define GC1R_WBCH GENMASK(3, 0) /* Width of Blue CHannel output */
113#define GC1R_WGCH GENMASK(7, 4) /* Width of Green Channel output */ 113#define GC1R_WGCH GENMASK(7, 4) /* Width of Green Channel output */
@@ -172,60 +172,52 @@
172#define LXCFBLR_CFBLL GENMASK(12, 0) /* Color Frame Buffer Line Length */ 172#define LXCFBLR_CFBLL GENMASK(12, 0) /* Color Frame Buffer Line Length */
173#define LXCFBLR_CFBP GENMASK(28, 16) /* Color Frame Buffer Pitch in bytes */ 173#define LXCFBLR_CFBP GENMASK(28, 16) /* Color Frame Buffer Pitch in bytes */
174 174
175#define LXCFBLNR_CFBLN GENMASK(10, 0) /* Color Frame Buffer Line Number */ 175#define LXCFBLNR_CFBLN GENMASK(10, 0) /* Color Frame Buffer Line Number */
176 176
177#define HSPOL_AL 0 /* Horizontal Sync POLarity Active Low */ 177#define CONSTA_MAX 0xFF /* CONSTant Alpha MAX= 1.0 */
178#define VSPOL_AL 0 /* Vertical Sync POLarity Active Low */ 178#define BF1_PAXCA 0x600 /* Pixel Alpha x Constant Alpha */
179#define DEPOL_AL 0 /* Data Enable POLarity Active Low */ 179#define BF1_CA 0x400 /* Constant Alpha */
180#define PCPOL_IPC 0 /* Input Pixel Clock */ 180#define BF2_1PAXCA 0x007 /* 1 - (Pixel Alpha x Constant Alpha) */
181#define HSPOL_AH GCR_HSPOL /* Horizontal Sync POLarity Active High */ 181#define BF2_1CA 0x005 /* 1 - Constant Alpha */
182#define VSPOL_AH GCR_VSPOL /* Vertical Sync POLarity Active High */
183#define DEPOL_AH GCR_DEPOL /* Data Enable POLarity Active High */
184#define PCPOL_IIPC GCR_PCPOL /* Inverted Input Pixel Clock */
185#define CONSTA_MAX 0xFF /* CONSTant Alpha MAX= 1.0 */
186#define BF1_PAXCA 0x600 /* Pixel Alpha x Constant Alpha */
187#define BF1_CA 0x400 /* Constant Alpha */
188#define BF2_1PAXCA 0x007 /* 1 - (Pixel Alpha x Constant Alpha) */
189#define BF2_1CA 0x005 /* 1 - Constant Alpha */
190 182
191#define NB_PF 8 /* Max nb of HW pixel format */ 183#define NB_PF 8 /* Max nb of HW pixel format */
192 184
193enum ltdc_pix_fmt { 185enum ltdc_pix_fmt {
194 PF_NONE, 186 PF_NONE,
195 /* RGB formats */ 187 /* RGB formats */
196 PF_ARGB8888, /* ARGB [32 bits] */ 188 PF_ARGB8888, /* ARGB [32 bits] */
197 PF_RGBA8888, /* RGBA [32 bits] */ 189 PF_RGBA8888, /* RGBA [32 bits] */
198 PF_RGB888, /* RGB [24 bits] */ 190 PF_RGB888, /* RGB [24 bits] */
199 PF_RGB565, /* RGB [16 bits] */ 191 PF_RGB565, /* RGB [16 bits] */
200 PF_ARGB1555, /* ARGB A:1 bit RGB:15 bits [16 bits] */ 192 PF_ARGB1555, /* ARGB A:1 bit RGB:15 bits [16 bits] */
201 PF_ARGB4444, /* ARGB A:4 bits R/G/B: 4 bits each [16 bits] */ 193 PF_ARGB4444, /* ARGB A:4 bits R/G/B: 4 bits each [16 bits] */
202 /* Indexed formats */ 194 /* Indexed formats */
203 PF_L8, /* Indexed 8 bits [8 bits] */ 195 PF_L8, /* Indexed 8 bits [8 bits] */
204 PF_AL44, /* Alpha:4 bits + indexed 4 bits [8 bits] */ 196 PF_AL44, /* Alpha:4 bits + indexed 4 bits [8 bits] */
205 PF_AL88 /* Alpha:8 bits + indexed 8 bits [16 bits] */ 197 PF_AL88 /* Alpha:8 bits + indexed 8 bits [16 bits] */
206}; 198};
207 199
208/* The index gives the encoding of the pixel format for an HW version */ 200/* The index gives the encoding of the pixel format for an HW version */
209static const enum ltdc_pix_fmt ltdc_pix_fmt_a0[NB_PF] = { 201static const enum ltdc_pix_fmt ltdc_pix_fmt_a0[NB_PF] = {
210 PF_ARGB8888, /* 0x00 */ 202 PF_ARGB8888, /* 0x00 */
211 PF_RGB888, /* 0x01 */ 203 PF_RGB888, /* 0x01 */
212 PF_RGB565, /* 0x02 */ 204 PF_RGB565, /* 0x02 */
213 PF_ARGB1555, /* 0x03 */ 205 PF_ARGB1555, /* 0x03 */
214 PF_ARGB4444, /* 0x04 */ 206 PF_ARGB4444, /* 0x04 */
215 PF_L8, /* 0x05 */ 207 PF_L8, /* 0x05 */
216 PF_AL44, /* 0x06 */ 208 PF_AL44, /* 0x06 */
217 PF_AL88 /* 0x07 */ 209 PF_AL88 /* 0x07 */
218}; 210};
219 211
220static const enum ltdc_pix_fmt ltdc_pix_fmt_a1[NB_PF] = { 212static const enum ltdc_pix_fmt ltdc_pix_fmt_a1[NB_PF] = {
221 PF_ARGB8888, /* 0x00 */ 213 PF_ARGB8888, /* 0x00 */
222 PF_RGB888, /* 0x01 */ 214 PF_RGB888, /* 0x01 */
223 PF_RGB565, /* 0x02 */ 215 PF_RGB565, /* 0x02 */
224 PF_RGBA8888, /* 0x03 */ 216 PF_RGBA8888, /* 0x03 */
225 PF_AL44, /* 0x04 */ 217 PF_AL44, /* 0x04 */
226 PF_L8, /* 0x05 */ 218 PF_L8, /* 0x05 */
227 PF_ARGB1555, /* 0x06 */ 219 PF_ARGB1555, /* 0x06 */
228 PF_ARGB4444 /* 0x07 */ 220 PF_ARGB4444 /* 0x07 */
229}; 221};
230 222
231static inline u32 reg_read(void __iomem *base, u32 reg) 223static inline u32 reg_read(void __iomem *base, u32 reg)
@@ -302,7 +294,7 @@ static inline enum ltdc_pix_fmt to_ltdc_pixelformat(u32 drm_fmt)
302 default: 294 default:
303 pf = PF_NONE; 295 pf = PF_NONE;
304 break; 296 break;
305 /* Note: There are no DRM_FORMAT for AL44 and AL88 */ 297 /* Note: There are no DRM_FORMAT for AL44 and AL88 */
306 } 298 }
307 299
308 return pf; 300 return pf;
@@ -325,8 +317,8 @@ static inline u32 to_drm_pixelformat(enum ltdc_pix_fmt pf)
325 return DRM_FORMAT_ARGB4444; 317 return DRM_FORMAT_ARGB4444;
326 case PF_L8: 318 case PF_L8:
327 return DRM_FORMAT_C8; 319 return DRM_FORMAT_C8;
328 case PF_AL44: /* No DRM support */ 320 case PF_AL44: /* No DRM support */
329 case PF_AL88: /* No DRM support */ 321 case PF_AL88: /* No DRM support */
330 case PF_NONE: 322 case PF_NONE:
331 default: 323 default:
332 return 0; 324 return 0;
@@ -370,17 +362,6 @@ static irqreturn_t ltdc_irq(int irq, void *arg)
370 * DRM_CRTC 362 * DRM_CRTC
371 */ 363 */
372 364
373static void ltdc_crtc_load_lut(struct drm_crtc *crtc)
374{
375 struct ltdc_device *ldev = crtc_to_ltdc(crtc);
376 unsigned int i, lay;
377
378 for (lay = 0; lay < ldev->caps.nb_layers; lay++)
379 for (i = 0; i < 256; i++)
380 reg_write(ldev->regs, LTDC_L1CLUTWR + lay * LAY_OFS,
381 ldev->clut[i]);
382}
383
384static void ltdc_crtc_atomic_enable(struct drm_crtc *crtc, 365static void ltdc_crtc_atomic_enable(struct drm_crtc *crtc,
385 struct drm_crtc_state *old_state) 366 struct drm_crtc_state *old_state)
386{ 367{
@@ -459,20 +440,20 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc)
459 440
460 clk_enable(ldev->pixel_clk); 441 clk_enable(ldev->pixel_clk);
461 442
462 /* Configures the HS, VS, DE and PC polarities. */ 443 /* Configures the HS, VS, DE and PC polarities. Default Active Low */
463 val = HSPOL_AL | VSPOL_AL | DEPOL_AL | PCPOL_IPC; 444 val = 0;
464 445
465 if (vm.flags & DISPLAY_FLAGS_HSYNC_HIGH) 446 if (vm.flags & DISPLAY_FLAGS_HSYNC_HIGH)
466 val |= HSPOL_AH; 447 val |= GCR_HSPOL;
467 448
468 if (vm.flags & DISPLAY_FLAGS_VSYNC_HIGH) 449 if (vm.flags & DISPLAY_FLAGS_VSYNC_HIGH)
469 val |= VSPOL_AH; 450 val |= GCR_VSPOL;
470 451
471 if (vm.flags & DISPLAY_FLAGS_DE_HIGH) 452 if (vm.flags & DISPLAY_FLAGS_DE_HIGH)
472 val |= DEPOL_AH; 453 val |= GCR_DEPOL;
473 454
474 if (vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) 455 if (vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
475 val |= PCPOL_IIPC; 456 val |= GCR_PCPOL;
476 457
477 reg_update_bits(ldev->regs, LTDC_GCR, 458 reg_update_bits(ldev->regs, LTDC_GCR,
478 GCR_HSPOL | GCR_VSPOL | GCR_DEPOL | GCR_PCPOL, val); 459 GCR_HSPOL | GCR_VSPOL | GCR_DEPOL | GCR_PCPOL, val);
@@ -519,8 +500,7 @@ static void ltdc_crtc_atomic_flush(struct drm_crtc *crtc,
519 } 500 }
520} 501}
521 502
522static struct drm_crtc_helper_funcs ltdc_crtc_helper_funcs = { 503static const struct drm_crtc_helper_funcs ltdc_crtc_helper_funcs = {
523 .load_lut = ltdc_crtc_load_lut,
524 .mode_set_nofb = ltdc_crtc_mode_set_nofb, 504 .mode_set_nofb = ltdc_crtc_mode_set_nofb,
525 .atomic_flush = ltdc_crtc_atomic_flush, 505 .atomic_flush = ltdc_crtc_atomic_flush,
526 .atomic_enable = ltdc_crtc_atomic_enable, 506 .atomic_enable = ltdc_crtc_atomic_enable,
@@ -545,7 +525,7 @@ void ltdc_crtc_disable_vblank(struct drm_device *ddev, unsigned int pipe)
545 reg_clear(ldev->regs, LTDC_IER, IER_LIE); 525 reg_clear(ldev->regs, LTDC_IER, IER_LIE);
546} 526}
547 527
548static struct drm_crtc_funcs ltdc_crtc_funcs = { 528static const struct drm_crtc_funcs ltdc_crtc_funcs = {
549 .destroy = drm_crtc_cleanup, 529 .destroy = drm_crtc_cleanup,
550 .set_config = drm_atomic_helper_set_config, 530 .set_config = drm_atomic_helper_set_config,
551 .page_flip = drm_atomic_helper_page_flip, 531 .page_flip = drm_atomic_helper_page_flip,
@@ -610,11 +590,11 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane,
610 src_w = state->src_w >> 16; 590 src_w = state->src_w >> 16;
611 src_h = state->src_h >> 16; 591 src_h = state->src_h >> 16;
612 592
613 DRM_DEBUG_DRIVER( 593 DRM_DEBUG_DRIVER("plane:%d fb:%d (%dx%d)@(%d,%d) -> (%dx%d)@(%d,%d)\n",
614 "plane:%d fb:%d (%dx%d)@(%d,%d) -> (%dx%d)@(%d,%d)\n", 594 plane->base.id, fb->base.id,
615 plane->base.id, fb->base.id, 595 src_w, src_h, src_x, src_y,
616 src_w, src_h, src_x, src_y, 596 state->crtc_w, state->crtc_h,
617 state->crtc_w, state->crtc_h, state->crtc_x, state->crtc_y); 597 state->crtc_x, state->crtc_y);
618 598
619 bpcr = reg_read(ldev->regs, LTDC_BPCR); 599 bpcr = reg_read(ldev->regs, LTDC_BPCR);
620 ahbp = (bpcr & BPCR_AHBP) >> 16; 600 ahbp = (bpcr & BPCR_AHBP) >> 16;
@@ -639,7 +619,7 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane,
639 if (val == NB_PF) { 619 if (val == NB_PF) {
640 DRM_ERROR("Pixel format %.4s not supported\n", 620 DRM_ERROR("Pixel format %.4s not supported\n",
641 (char *)&fb->format->format); 621 (char *)&fb->format->format);
642 val = 0; /* set by default ARGB 32 bits */ 622 val = 0; /* set by default ARGB 32 bits */
643 } 623 }
644 reg_update_bits(ldev->regs, LTDC_L1PFCR + lofs, LXPFCR_PF, val); 624 reg_update_bits(ldev->regs, LTDC_L1PFCR + lofs, LXPFCR_PF, val);
645 625
@@ -653,8 +633,7 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane,
653 633
654 /* Specifies the constant alpha value */ 634 /* Specifies the constant alpha value */
655 val = CONSTA_MAX; 635 val = CONSTA_MAX;
656 reg_update_bits(ldev->regs, LTDC_L1CACR + lofs, 636 reg_update_bits(ldev->regs, LTDC_L1CACR + lofs, LXCACR_CONSTA, val);
657 LXCACR_CONSTA, val);
658 637
659 /* Specifies the blending factors */ 638 /* Specifies the blending factors */
660 val = BF1_PAXCA | BF2_1PAXCA; 639 val = BF1_PAXCA | BF2_1PAXCA;
@@ -663,8 +642,7 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane,
663 642
664 /* Configures the frame buffer line number */ 643 /* Configures the frame buffer line number */
665 val = y1 - y0 + 1; 644 val = y1 - y0 + 1;
666 reg_update_bits(ldev->regs, LTDC_L1CFBLNR + lofs, 645 reg_update_bits(ldev->regs, LTDC_L1CFBLNR + lofs, LXCFBLNR_CFBLN, val);
667 LXCFBLNR_CFBLN, val);
668 646
669 /* Sets the FB address */ 647 /* Sets the FB address */
670 paddr = (u32)drm_fb_cma_get_gem_addr(fb, state, 0); 648 paddr = (u32)drm_fb_cma_get_gem_addr(fb, state, 0);
@@ -703,11 +681,10 @@ static void ltdc_plane_atomic_disable(struct drm_plane *plane,
703 oldstate->crtc->base.id, plane->base.id); 681 oldstate->crtc->base.id, plane->base.id);
704} 682}
705 683
706static struct drm_plane_funcs ltdc_plane_funcs = { 684static const struct drm_plane_funcs ltdc_plane_funcs = {
707 .update_plane = drm_atomic_helper_update_plane, 685 .update_plane = drm_atomic_helper_update_plane,
708 .disable_plane = drm_atomic_helper_disable_plane, 686 .disable_plane = drm_atomic_helper_disable_plane,
709 .destroy = drm_plane_cleanup, 687 .destroy = drm_plane_cleanup,
710 .set_property = drm_atomic_helper_plane_set_property,
711 .reset = drm_atomic_helper_plane_reset, 688 .reset = drm_atomic_helper_plane_reset,
712 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 689 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
713 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 690 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
@@ -745,7 +722,7 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev,
745 722
746 ret = drm_universal_plane_init(ddev, plane, possible_crtcs, 723 ret = drm_universal_plane_init(ddev, plane, possible_crtcs,
747 &ltdc_plane_funcs, formats, nb_fmt, 724 &ltdc_plane_funcs, formats, nb_fmt,
748 type, NULL); 725 NULL, type, NULL);
749 if (ret < 0) 726 if (ret < 0)
750 return 0; 727 return 0;
751 728
@@ -770,7 +747,7 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)
770 struct ltdc_device *ldev = ddev->dev_private; 747 struct ltdc_device *ldev = ddev->dev_private;
771 struct drm_plane *primary, *overlay; 748 struct drm_plane *primary, *overlay;
772 unsigned int i; 749 unsigned int i;
773 int res; 750 int ret;
774 751
775 primary = ltdc_plane_create(ddev, DRM_PLANE_TYPE_PRIMARY); 752 primary = ltdc_plane_create(ddev, DRM_PLANE_TYPE_PRIMARY);
776 if (!primary) { 753 if (!primary) {
@@ -778,9 +755,9 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)
778 return -EINVAL; 755 return -EINVAL;
779 } 756 }
780 757
781 res = drm_crtc_init_with_planes(ddev, crtc, primary, NULL, 758 ret = drm_crtc_init_with_planes(ddev, crtc, primary, NULL,
782 &ltdc_crtc_funcs, NULL); 759 &ltdc_crtc_funcs, NULL);
783 if (res) { 760 if (ret) {
784 DRM_ERROR("Can not initialize CRTC\n"); 761 DRM_ERROR("Can not initialize CRTC\n");
785 goto cleanup; 762 goto cleanup;
786 } 763 }
@@ -793,7 +770,7 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)
793 for (i = 1; i < ldev->caps.nb_layers; i++) { 770 for (i = 1; i < ldev->caps.nb_layers; i++) {
794 overlay = ltdc_plane_create(ddev, DRM_PLANE_TYPE_OVERLAY); 771 overlay = ltdc_plane_create(ddev, DRM_PLANE_TYPE_OVERLAY);
795 if (!overlay) { 772 if (!overlay) {
796 res = -ENOMEM; 773 ret = -ENOMEM;
797 DRM_ERROR("Can not create overlay plane %d\n", i); 774 DRM_ERROR("Can not create overlay plane %d\n", i);
798 goto cleanup; 775 goto cleanup;
799 } 776 }
@@ -803,7 +780,7 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)
803 780
804cleanup: 781cleanup:
805 ltdc_plane_destroy_all(ddev); 782 ltdc_plane_destroy_all(ddev);
806 return res; 783 return ret;
807} 784}
808 785
809/* 786/*
@@ -825,7 +802,7 @@ static int ltdc_encoder_init(struct drm_device *ddev)
825 return -ENOMEM; 802 return -ENOMEM;
826 803
827 encoder->possible_crtcs = CRTC_MASK; 804 encoder->possible_crtcs = CRTC_MASK;
828 encoder->possible_clones = 0; /* No cloning support */ 805 encoder->possible_clones = 0; /* No cloning support */
829 806
830 drm_encoder_init(ddev, encoder, &ltdc_encoder_funcs, 807 drm_encoder_init(ddev, encoder, &ltdc_encoder_funcs,
831 DRM_MODE_ENCODER_DPI, NULL); 808 DRM_MODE_ENCODER_DPI, NULL);
@@ -884,7 +861,7 @@ int ltdc_load(struct drm_device *ddev)
884 struct drm_panel *panel; 861 struct drm_panel *panel;
885 struct drm_crtc *crtc; 862 struct drm_crtc *crtc;
886 struct reset_control *rstc; 863 struct reset_control *rstc;
887 struct resource res; 864 struct resource *res;
888 int irq, ret, i; 865 int irq, ret, i;
889 866
890 DRM_DEBUG_DRIVER("\n"); 867 DRM_DEBUG_DRIVER("\n");
@@ -893,7 +870,7 @@ int ltdc_load(struct drm_device *ddev)
893 if (ret) 870 if (ret)
894 return ret; 871 return ret;
895 872
896 rstc = of_reset_control_get(np, NULL); 873 rstc = devm_reset_control_get_exclusive(dev, NULL);
897 874
898 mutex_init(&ldev->err_lock); 875 mutex_init(&ldev->err_lock);
899 876
@@ -908,13 +885,14 @@ int ltdc_load(struct drm_device *ddev)
908 return -ENODEV; 885 return -ENODEV;
909 } 886 }
910 887
911 if (of_address_to_resource(np, 0, &res)) { 888 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
889 if (!res) {
912 DRM_ERROR("Unable to get resource\n"); 890 DRM_ERROR("Unable to get resource\n");
913 ret = -ENODEV; 891 ret = -ENODEV;
914 goto err; 892 goto err;
915 } 893 }
916 894
917 ldev->regs = devm_ioremap_resource(dev, &res); 895 ldev->regs = devm_ioremap_resource(dev, res);
918 if (IS_ERR(ldev->regs)) { 896 if (IS_ERR(ldev->regs)) {
919 DRM_ERROR("Unable to get ltdc registers\n"); 897 DRM_ERROR("Unable to get ltdc registers\n");
920 ret = PTR_ERR(ldev->regs); 898 ret = PTR_ERR(ldev->regs);
diff --git a/drivers/gpu/drm/stm/ltdc.h b/drivers/gpu/drm/stm/ltdc.h
index d9e899d296ec..bc6d6f6419a9 100644
--- a/drivers/gpu/drm/stm/ltdc.h
+++ b/drivers/gpu/drm/stm/ltdc.h
@@ -28,7 +28,6 @@ struct ltdc_device {
28 bool is_panel_bridge; 28 bool is_panel_bridge;
29 struct mutex err_lock; /* protecting error_status */ 29 struct mutex err_lock; /* protecting error_status */
30 struct ltdc_caps caps; 30 struct ltdc_caps caps;
31 u32 clut[256]; /* color look up table */
32 u32 error_status; 31 u32 error_status;
33 u32 irq_status; 32 u32 irq_status;
34}; 33};
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index 89cd590723ac..d599206a1e86 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -40,8 +40,6 @@ static struct drm_driver sun4i_drv_driver = {
40 40
41 /* GEM Operations */ 41 /* GEM Operations */
42 .dumb_create = drm_gem_cma_dumb_create, 42 .dumb_create = drm_gem_cma_dumb_create,
43 .dumb_destroy = drm_gem_dumb_destroy,
44 .dumb_map_offset = drm_gem_cma_dumb_map_offset,
45 .gem_free_object_unlocked = drm_gem_cma_free_object, 43 .gem_free_object_unlocked = drm_gem_cma_free_object,
46 .gem_vm_ops = &drm_gem_cma_vm_ops, 44 .gem_vm_ops = &drm_gem_cma_vm_ops,
47 45
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index 83b7a2a025f2..f5d0d6bd1084 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -306,7 +306,6 @@ sun4i_hdmi_connector_detect(struct drm_connector *connector, bool force)
306} 306}
307 307
308static const struct drm_connector_funcs sun4i_hdmi_connector_funcs = { 308static const struct drm_connector_funcs sun4i_hdmi_connector_funcs = {
309 .dpms = drm_atomic_helper_connector_dpms,
310 .detect = sun4i_hdmi_connector_detect, 309 .detect = sun4i_hdmi_connector_detect,
311 .fill_modes = drm_helper_probe_single_connector_modes, 310 .fill_modes = drm_helper_probe_single_connector_modes,
312 .destroy = drm_connector_cleanup, 311 .destroy = drm_connector_cleanup,
diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c
index ead4f9d4c1ee..d45f3a1a0a29 100644
--- a/drivers/gpu/drm/sun4i/sun4i_layer.c
+++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
@@ -115,7 +115,7 @@ static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm,
115 ret = drm_universal_plane_init(drm, &layer->plane, 0, 115 ret = drm_universal_plane_init(drm, &layer->plane, 0,
116 &sun4i_backend_layer_funcs, 116 &sun4i_backend_layer_funcs,
117 plane->formats, plane->nformats, 117 plane->formats, plane->nformats,
118 plane->type, NULL); 118 NULL, plane->type, NULL);
119 if (ret) { 119 if (ret) {
120 dev_err(drm->dev, "Couldn't initialize layer\n"); 120 dev_err(drm->dev, "Couldn't initialize layer\n");
121 return ERR_PTR(ret); 121 return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/sun4i/sun4i_rgb.c b/drivers/gpu/drm/sun4i/sun4i_rgb.c
index 422b191faa77..550bb262943f 100644
--- a/drivers/gpu/drm/sun4i/sun4i_rgb.c
+++ b/drivers/gpu/drm/sun4i/sun4i_rgb.c
@@ -120,7 +120,6 @@ sun4i_rgb_connector_destroy(struct drm_connector *connector)
120} 120}
121 121
122static struct drm_connector_funcs sun4i_rgb_con_funcs = { 122static struct drm_connector_funcs sun4i_rgb_con_funcs = {
123 .dpms = drm_atomic_helper_connector_dpms,
124 .fill_modes = drm_helper_probe_single_connector_modes, 123 .fill_modes = drm_helper_probe_single_connector_modes,
125 .destroy = sun4i_rgb_connector_destroy, 124 .destroy = sun4i_rgb_connector_destroy,
126 .reset = drm_atomic_helper_connector_reset, 125 .reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c
index 338b9e5bb2a3..7b45ac9383ea 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
@@ -546,7 +546,6 @@ sun4i_tv_comp_connector_destroy(struct drm_connector *connector)
546} 546}
547 547
548static struct drm_connector_funcs sun4i_tv_comp_connector_funcs = { 548static struct drm_connector_funcs sun4i_tv_comp_connector_funcs = {
549 .dpms = drm_atomic_helper_connector_dpms,
550 .fill_modes = drm_helper_probe_single_connector_modes, 549 .fill_modes = drm_helper_probe_single_connector_modes,
551 .destroy = sun4i_tv_comp_connector_destroy, 550 .destroy = sun4i_tv_comp_connector_destroy,
552 .reset = drm_atomic_helper_connector_reset, 551 .reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/sun4i/sun8i_layer.c b/drivers/gpu/drm/sun4i/sun8i_layer.c
index e627eeece658..23810ff72684 100644
--- a/drivers/gpu/drm/sun4i/sun8i_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_layer.c
@@ -90,7 +90,7 @@ static struct sun8i_layer *sun8i_layer_init_one(struct drm_device *drm,
90 ret = drm_universal_plane_init(drm, &layer->plane, 0, 90 ret = drm_universal_plane_init(drm, &layer->plane, 0,
91 &sun8i_mixer_layer_funcs, 91 &sun8i_mixer_layer_funcs,
92 plane->formats, plane->nformats, 92 plane->formats, plane->nformats,
93 plane->type, NULL); 93 NULL, plane->type, NULL);
94 if (ret) { 94 if (ret) {
95 dev_err(drm->dev, "Couldn't initialize layer\n"); 95 dev_err(drm->dev, "Couldn't initialize layer\n");
96 return ERR_PTR(ret); 96 return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 0cb9b90e2e68..4df39112e38e 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -678,8 +678,8 @@ static struct drm_plane *tegra_dc_primary_plane_create(struct drm_device *drm,
678 678
679 err = drm_universal_plane_init(drm, &plane->base, possible_crtcs, 679 err = drm_universal_plane_init(drm, &plane->base, possible_crtcs,
680 &tegra_primary_plane_funcs, formats, 680 &tegra_primary_plane_funcs, formats,
681 num_formats, DRM_PLANE_TYPE_PRIMARY, 681 num_formats, NULL,
682 NULL); 682 DRM_PLANE_TYPE_PRIMARY, NULL);
683 if (err < 0) { 683 if (err < 0) {
684 kfree(plane); 684 kfree(plane);
685 return ERR_PTR(err); 685 return ERR_PTR(err);
@@ -844,8 +844,8 @@ static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm,
844 844
845 err = drm_universal_plane_init(drm, &plane->base, 1 << dc->pipe, 845 err = drm_universal_plane_init(drm, &plane->base, 1 << dc->pipe,
846 &tegra_cursor_plane_funcs, formats, 846 &tegra_cursor_plane_funcs, formats,
847 num_formats, DRM_PLANE_TYPE_CURSOR, 847 num_formats, NULL,
848 NULL); 848 DRM_PLANE_TYPE_CURSOR, NULL);
849 if (err < 0) { 849 if (err < 0) {
850 kfree(plane); 850 kfree(plane);
851 return ERR_PTR(err); 851 return ERR_PTR(err);
@@ -906,8 +906,8 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
906 906
907 err = drm_universal_plane_init(drm, &plane->base, 1 << dc->pipe, 907 err = drm_universal_plane_init(drm, &plane->base, 1 << dc->pipe,
908 &tegra_overlay_plane_funcs, formats, 908 &tegra_overlay_plane_funcs, formats,
909 num_formats, DRM_PLANE_TYPE_OVERLAY, 909 num_formats, NULL,
910 NULL); 910 DRM_PLANE_TYPE_OVERLAY, NULL);
911 if (err < 0) { 911 if (err < 0) {
912 kfree(plane); 912 kfree(plane);
913 return ERR_PTR(err); 913 return ERR_PTR(err);
diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
index 3dea1216bafd..e4b5aedfdbd4 100644
--- a/drivers/gpu/drm/tegra/dsi.c
+++ b/drivers/gpu/drm/tegra/dsi.c
@@ -815,7 +815,6 @@ tegra_dsi_connector_duplicate_state(struct drm_connector *connector)
815} 815}
816 816
817static const struct drm_connector_funcs tegra_dsi_connector_funcs = { 817static const struct drm_connector_funcs tegra_dsi_connector_funcs = {
818 .dpms = drm_atomic_helper_connector_dpms,
819 .reset = tegra_dsi_connector_reset, 818 .reset = tegra_dsi_connector_reset,
820 .detect = tegra_output_connector_detect, 819 .detect = tegra_output_connector_detect,
821 .fill_modes = drm_helper_probe_single_connector_modes, 820 .fill_modes = drm_helper_probe_single_connector_modes,
diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c
index 718d8db406a6..a621b0da4092 100644
--- a/drivers/gpu/drm/tegra/hdmi.c
+++ b/drivers/gpu/drm/tegra/hdmi.c
@@ -902,7 +902,6 @@ tegra_hdmi_connector_detect(struct drm_connector *connector, bool force)
902} 902}
903 903
904static const struct drm_connector_funcs tegra_hdmi_connector_funcs = { 904static const struct drm_connector_funcs tegra_hdmi_connector_funcs = {
905 .dpms = drm_atomic_helper_connector_dpms,
906 .reset = drm_atomic_helper_connector_reset, 905 .reset = drm_atomic_helper_connector_reset,
907 .detect = tegra_hdmi_connector_detect, 906 .detect = tegra_hdmi_connector_detect,
908 .fill_modes = drm_helper_probe_single_connector_modes, 907 .fill_modes = drm_helper_probe_single_connector_modes,
diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c
index a131b44e2d6f..78ec5193741d 100644
--- a/drivers/gpu/drm/tegra/rgb.c
+++ b/drivers/gpu/drm/tegra/rgb.c
@@ -88,7 +88,6 @@ static void tegra_dc_write_regs(struct tegra_dc *dc,
88} 88}
89 89
90static const struct drm_connector_funcs tegra_rgb_connector_funcs = { 90static const struct drm_connector_funcs tegra_rgb_connector_funcs = {
91 .dpms = drm_atomic_helper_connector_dpms,
92 .reset = drm_atomic_helper_connector_reset, 91 .reset = drm_atomic_helper_connector_reset,
93 .detect = tegra_output_connector_detect, 92 .detect = tegra_output_connector_detect,
94 .fill_modes = drm_helper_probe_single_connector_modes, 93 .fill_modes = drm_helper_probe_single_connector_modes,
diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index fb2709c0c461..e0642d05a8d3 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -1340,7 +1340,6 @@ tegra_sor_connector_duplicate_state(struct drm_connector *connector)
1340} 1340}
1341 1341
1342static const struct drm_connector_funcs tegra_sor_connector_funcs = { 1342static const struct drm_connector_funcs tegra_sor_connector_funcs = {
1343 .dpms = drm_atomic_helper_connector_dpms,
1344 .reset = tegra_sor_connector_reset, 1343 .reset = tegra_sor_connector_reset,
1345 .detect = tegra_sor_connector_detect, 1344 .detect = tegra_sor_connector_detect,
1346 .fill_modes = drm_helper_probe_single_connector_modes, 1345 .fill_modes = drm_helper_probe_single_connector_modes,
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index 049d2f5a1ee4..b0d70f943cec 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -542,8 +542,6 @@ static struct drm_driver tilcdc_driver = {
542 .gem_free_object_unlocked = drm_gem_cma_free_object, 542 .gem_free_object_unlocked = drm_gem_cma_free_object,
543 .gem_vm_ops = &drm_gem_cma_vm_ops, 543 .gem_vm_ops = &drm_gem_cma_vm_ops,
544 .dumb_create = drm_gem_cma_dumb_create, 544 .dumb_create = drm_gem_cma_dumb_create,
545 .dumb_map_offset = drm_gem_cma_dumb_map_offset,
546 .dumb_destroy = drm_gem_dumb_destroy,
547 545
548 .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 546 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
549 .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 547 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
index 28c3e2f44f64..1813a3623ce6 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
@@ -189,7 +189,6 @@ static struct drm_encoder *panel_connector_best_encoder(
189 189
190static const struct drm_connector_funcs panel_connector_funcs = { 190static const struct drm_connector_funcs panel_connector_funcs = {
191 .destroy = panel_connector_destroy, 191 .destroy = panel_connector_destroy,
192 .dpms = drm_atomic_helper_connector_dpms,
193 .fill_modes = drm_helper_probe_single_connector_modes, 192 .fill_modes = drm_helper_probe_single_connector_modes,
194 .reset = drm_atomic_helper_connector_reset, 193 .reset = drm_atomic_helper_connector_reset,
195 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 194 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_plane.c b/drivers/gpu/drm/tilcdc/tilcdc_plane.c
index ba0d66c0d8ac..7667b038ae7f 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_plane.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_plane.c
@@ -28,7 +28,6 @@ static struct drm_plane_funcs tilcdc_plane_funcs = {
28 .update_plane = drm_atomic_helper_update_plane, 28 .update_plane = drm_atomic_helper_update_plane,
29 .disable_plane = drm_atomic_helper_disable_plane, 29 .disable_plane = drm_atomic_helper_disable_plane,
30 .destroy = drm_plane_cleanup, 30 .destroy = drm_plane_cleanup,
31 .set_property = drm_atomic_helper_plane_set_property,
32 .reset = drm_atomic_helper_plane_reset, 31 .reset = drm_atomic_helper_plane_reset,
33 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 32 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
34 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 33 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
index aabfad882e23..1e2dfb1b1d6b 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
@@ -202,7 +202,6 @@ static struct drm_encoder *tfp410_connector_best_encoder(
202 202
203static const struct drm_connector_funcs tfp410_connector_funcs = { 203static const struct drm_connector_funcs tfp410_connector_funcs = {
204 .destroy = tfp410_connector_destroy, 204 .destroy = tfp410_connector_destroy,
205 .dpms = drm_atomic_helper_connector_dpms,
206 .detect = tfp410_connector_detect, 205 .detect = tfp410_connector_detect,
207 .fill_modes = drm_helper_probe_single_connector_modes, 206 .fill_modes = drm_helper_probe_single_connector_modes,
208 .reset = drm_atomic_helper_connector_reset, 207 .reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/tinydrm/Kconfig b/drivers/gpu/drm/tinydrm/Kconfig
index 9596e447f877..f17c3caceab2 100644
--- a/drivers/gpu/drm/tinydrm/Kconfig
+++ b/drivers/gpu/drm/tinydrm/Kconfig
@@ -23,6 +23,7 @@ config TINYDRM_MI0283QT
23config TINYDRM_REPAPER 23config TINYDRM_REPAPER
24 tristate "DRM support for Pervasive Displays RePaper panels (V231)" 24 tristate "DRM support for Pervasive Displays RePaper panels (V231)"
25 depends on DRM_TINYDRM && SPI 25 depends on DRM_TINYDRM && SPI
26 depends on THERMAL || !THERMAL
26 help 27 help
27 DRM driver for the following Pervasive Displays panels: 28 DRM driver for the following Pervasive Displays panels:
28 1.44" TFT EPD Panel (E1144CS021) 29 1.44" TFT EPD Panel (E1144CS021)
diff --git a/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c b/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c
index ec43fb7ad9e4..f224b54a30f6 100644
--- a/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c
+++ b/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c
@@ -71,7 +71,6 @@ static void tinydrm_connector_destroy(struct drm_connector *connector)
71} 71}
72 72
73static const struct drm_connector_funcs tinydrm_connector_funcs = { 73static const struct drm_connector_funcs tinydrm_connector_funcs = {
74 .dpms = drm_atomic_helper_connector_dpms,
75 .reset = drm_atomic_helper_connector_reset, 74 .reset = drm_atomic_helper_connector_reset,
76 .detect = tinydrm_connector_detect, 75 .detect = tinydrm_connector_detect,
77 .fill_modes = drm_helper_probe_single_connector_modes, 76 .fill_modes = drm_helper_probe_single_connector_modes,
@@ -225,7 +224,7 @@ tinydrm_display_pipe_init(struct tinydrm_device *tdev,
225 return PTR_ERR(connector); 224 return PTR_ERR(connector);
226 225
227 ret = drm_simple_display_pipe_init(drm, &tdev->pipe, funcs, formats, 226 ret = drm_simple_display_pipe_init(drm, &tdev->pipe, funcs, formats,
228 format_count, connector); 227 format_count, NULL, connector);
229 if (ret) 228 if (ret)
230 return ret; 229 return ret;
231 230
diff --git a/drivers/gpu/drm/tinydrm/mi0283qt.c b/drivers/gpu/drm/tinydrm/mi0283qt.c
index 482ff1c3db61..7e5bb7d6f655 100644
--- a/drivers/gpu/drm/tinydrm/mi0283qt.c
+++ b/drivers/gpu/drm/tinydrm/mi0283qt.c
@@ -195,8 +195,12 @@ static int mi0283qt_probe(struct spi_device *spi)
195 195
196 device_property_read_u32(dev, "rotation", &rotation); 196 device_property_read_u32(dev, "rotation", &rotation);
197 197
198 ret = mipi_dbi_spi_init(spi, mipi, dc, &mi0283qt_pipe_funcs, 198 ret = mipi_dbi_spi_init(spi, mipi, dc);
199 &mi0283qt_driver, &mi0283qt_mode, rotation); 199 if (ret)
200 return ret;
201
202 ret = mipi_dbi_init(&spi->dev, mipi, &mi0283qt_pipe_funcs,
203 &mi0283qt_driver, &mi0283qt_mode, rotation);
200 if (ret) 204 if (ret)
201 return ret; 205 return ret;
202 206
diff --git a/drivers/gpu/drm/tinydrm/mipi-dbi.c b/drivers/gpu/drm/tinydrm/mipi-dbi.c
index c83eeb7a34b0..2caeabcd3458 100644
--- a/drivers/gpu/drm/tinydrm/mipi-dbi.c
+++ b/drivers/gpu/drm/tinydrm/mipi-dbi.c
@@ -776,15 +776,12 @@ static int mipi_dbi_typec3_command(struct mipi_dbi *mipi, u8 cmd,
776/** 776/**
777 * mipi_dbi_spi_init - Initialize MIPI DBI SPI interfaced controller 777 * mipi_dbi_spi_init - Initialize MIPI DBI SPI interfaced controller
778 * @spi: SPI device 778 * @spi: SPI device
779 * @dc: D/C gpio (optional)
780 * @mipi: &mipi_dbi structure to initialize 779 * @mipi: &mipi_dbi structure to initialize
781 * @pipe_funcs: Display pipe functions 780 * @dc: D/C gpio (optional)
782 * @driver: DRM driver
783 * @mode: Display mode
784 * @rotation: Initial rotation in degrees Counter Clock Wise
785 * 781 *
786 * This function sets &mipi_dbi->command, enables &mipi->read_commands for the 782 * This function sets &mipi_dbi->command, enables &mipi->read_commands for the
787 * usual read commands and initializes @mipi using mipi_dbi_init(). 783 * usual read commands. It should be followed by a call to mipi_dbi_init() or
784 * a driver-specific init.
788 * 785 *
789 * If @dc is set, a Type C Option 3 interface is assumed, if not 786 * If @dc is set, a Type C Option 3 interface is assumed, if not
790 * Type C Option 1. 787 * Type C Option 1.
@@ -799,11 +796,7 @@ static int mipi_dbi_typec3_command(struct mipi_dbi *mipi, u8 cmd,
799 * Zero on success, negative error code on failure. 796 * Zero on success, negative error code on failure.
800 */ 797 */
801int mipi_dbi_spi_init(struct spi_device *spi, struct mipi_dbi *mipi, 798int mipi_dbi_spi_init(struct spi_device *spi, struct mipi_dbi *mipi,
802 struct gpio_desc *dc, 799 struct gpio_desc *dc)
803 const struct drm_simple_display_pipe_funcs *pipe_funcs,
804 struct drm_driver *driver,
805 const struct drm_display_mode *mode,
806 unsigned int rotation)
807{ 800{
808 size_t tx_size = tinydrm_spi_max_transfer_size(spi, 0); 801 size_t tx_size = tinydrm_spi_max_transfer_size(spi, 0);
809 struct device *dev = &spi->dev; 802 struct device *dev = &spi->dev;
@@ -849,7 +842,7 @@ int mipi_dbi_spi_init(struct spi_device *spi, struct mipi_dbi *mipi,
849 return -ENOMEM; 842 return -ENOMEM;
850 } 843 }
851 844
852 return mipi_dbi_init(dev, mipi, pipe_funcs, driver, mode, rotation); 845 return 0;
853} 846}
854EXPORT_SYMBOL(mipi_dbi_spi_init); 847EXPORT_SYMBOL(mipi_dbi_spi_init);
855 848
diff --git a/drivers/gpu/drm/vc4/Kconfig b/drivers/gpu/drm/vc4/Kconfig
index 4361bdcfd28a..fdae18aeab4f 100644
--- a/drivers/gpu/drm/vc4/Kconfig
+++ b/drivers/gpu/drm/vc4/Kconfig
@@ -19,3 +19,11 @@ config DRM_VC4
19 This driver requires that "avoid_warnings=2" be present in 19 This driver requires that "avoid_warnings=2" be present in
20 the config.txt for the firmware, to keep it from smashing 20 the config.txt for the firmware, to keep it from smashing
21 our display setup. 21 our display setup.
22
23config DRM_VC4_HDMI_CEC
24 bool "Broadcom VC4 HDMI CEC Support"
25 depends on DRM_VC4
26 select CEC_CORE
27 help
28 Choose this option if you have a Broadcom VC4 GPU
29 and want to use CEC.
diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index 487f96412d35..b24dd8685590 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -24,21 +24,35 @@
24#include "vc4_drv.h" 24#include "vc4_drv.h"
25#include "uapi/drm/vc4_drm.h" 25#include "uapi/drm/vc4_drm.h"
26 26
27static const char * const bo_type_names[] = {
28 "kernel",
29 "V3D",
30 "V3D shader",
31 "dumb",
32 "binner",
33 "RCL",
34 "BCL",
35 "kernel BO cache",
36};
37
38static bool is_user_label(int label)
39{
40 return label >= VC4_BO_TYPE_COUNT;
41}
42
27static void vc4_bo_stats_dump(struct vc4_dev *vc4) 43static void vc4_bo_stats_dump(struct vc4_dev *vc4)
28{ 44{
29 DRM_INFO("num bos allocated: %d\n", 45 int i;
30 vc4->bo_stats.num_allocated); 46
31 DRM_INFO("size bos allocated: %dkb\n", 47 for (i = 0; i < vc4->num_labels; i++) {
32 vc4->bo_stats.size_allocated / 1024); 48 if (!vc4->bo_labels[i].num_allocated)
33 DRM_INFO("num bos used: %d\n", 49 continue;
34 vc4->bo_stats.num_allocated - vc4->bo_stats.num_cached); 50
35 DRM_INFO("size bos used: %dkb\n", 51 DRM_INFO("%30s: %6dkb BOs (%d)\n",
36 (vc4->bo_stats.size_allocated - 52 vc4->bo_labels[i].name,
37 vc4->bo_stats.size_cached) / 1024); 53 vc4->bo_labels[i].size_allocated / 1024,
38 DRM_INFO("num bos cached: %d\n", 54 vc4->bo_labels[i].num_allocated);
39 vc4->bo_stats.num_cached); 55 }
40 DRM_INFO("size bos cached: %dkb\n",
41 vc4->bo_stats.size_cached / 1024);
42} 56}
43 57
44#ifdef CONFIG_DEBUG_FS 58#ifdef CONFIG_DEBUG_FS
@@ -47,64 +61,133 @@ int vc4_bo_stats_debugfs(struct seq_file *m, void *unused)
47 struct drm_info_node *node = (struct drm_info_node *)m->private; 61 struct drm_info_node *node = (struct drm_info_node *)m->private;
48 struct drm_device *dev = node->minor->dev; 62 struct drm_device *dev = node->minor->dev;
49 struct vc4_dev *vc4 = to_vc4_dev(dev); 63 struct vc4_dev *vc4 = to_vc4_dev(dev);
50 struct vc4_bo_stats stats; 64 int i;
51 65
52 /* Take a snapshot of the current stats with the lock held. */
53 mutex_lock(&vc4->bo_lock); 66 mutex_lock(&vc4->bo_lock);
54 stats = vc4->bo_stats; 67 for (i = 0; i < vc4->num_labels; i++) {
68 if (!vc4->bo_labels[i].num_allocated)
69 continue;
70
71 seq_printf(m, "%30s: %6dkb BOs (%d)\n",
72 vc4->bo_labels[i].name,
73 vc4->bo_labels[i].size_allocated / 1024,
74 vc4->bo_labels[i].num_allocated);
75 }
55 mutex_unlock(&vc4->bo_lock); 76 mutex_unlock(&vc4->bo_lock);
56 77
57 seq_printf(m, "num bos allocated: %d\n",
58 stats.num_allocated);
59 seq_printf(m, "size bos allocated: %dkb\n",
60 stats.size_allocated / 1024);
61 seq_printf(m, "num bos used: %d\n",
62 stats.num_allocated - stats.num_cached);
63 seq_printf(m, "size bos used: %dkb\n",
64 (stats.size_allocated - stats.size_cached) / 1024);
65 seq_printf(m, "num bos cached: %d\n",
66 stats.num_cached);
67 seq_printf(m, "size bos cached: %dkb\n",
68 stats.size_cached / 1024);
69
70 return 0; 78 return 0;
71} 79}
72#endif 80#endif
73 81
82/* Takes ownership of *name and returns the appropriate slot for it in
83 * the bo_labels[] array, extending it as necessary.
84 *
85 * This is inefficient and could use a hash table instead of walking
86 * an array and strcmp()ing. However, the assumption is that user
87 * labeling will be infrequent (scanout buffers and other long-lived
88 * objects, or debug driver builds), so we can live with it for now.
89 */
90static int vc4_get_user_label(struct vc4_dev *vc4, const char *name)
91{
92 int i;
93 int free_slot = -1;
94
95 for (i = 0; i < vc4->num_labels; i++) {
96 if (!vc4->bo_labels[i].name) {
97 free_slot = i;
98 } else if (strcmp(vc4->bo_labels[i].name, name) == 0) {
99 kfree(name);
100 return i;
101 }
102 }
103
104 if (free_slot != -1) {
105 WARN_ON(vc4->bo_labels[free_slot].num_allocated != 0);
106 vc4->bo_labels[free_slot].name = name;
107 return free_slot;
108 } else {
109 u32 new_label_count = vc4->num_labels + 1;
110 struct vc4_label *new_labels =
111 krealloc(vc4->bo_labels,
112 new_label_count * sizeof(*new_labels),
113 GFP_KERNEL);
114
115 if (!new_labels) {
116 kfree(name);
117 return -1;
118 }
119
120 free_slot = vc4->num_labels;
121 vc4->bo_labels = new_labels;
122 vc4->num_labels = new_label_count;
123
124 vc4->bo_labels[free_slot].name = name;
125 vc4->bo_labels[free_slot].num_allocated = 0;
126 vc4->bo_labels[free_slot].size_allocated = 0;
127
128 return free_slot;
129 }
130}
131
132static void vc4_bo_set_label(struct drm_gem_object *gem_obj, int label)
133{
134 struct vc4_bo *bo = to_vc4_bo(gem_obj);
135 struct vc4_dev *vc4 = to_vc4_dev(gem_obj->dev);
136
137 lockdep_assert_held(&vc4->bo_lock);
138
139 if (label != -1) {
140 vc4->bo_labels[label].num_allocated++;
141 vc4->bo_labels[label].size_allocated += gem_obj->size;
142 }
143
144 vc4->bo_labels[bo->label].num_allocated--;
145 vc4->bo_labels[bo->label].size_allocated -= gem_obj->size;
146
147 if (vc4->bo_labels[bo->label].num_allocated == 0 &&
148 is_user_label(bo->label)) {
149 /* Free user BO label slots on last unreference.
150 * Slots are just where we track the stats for a given
151 * name, and once a name is unused we can reuse that
152 * slot.
153 */
154 kfree(vc4->bo_labels[bo->label].name);
155 vc4->bo_labels[bo->label].name = NULL;
156 }
157
158 bo->label = label;
159}
160
74static uint32_t bo_page_index(size_t size) 161static uint32_t bo_page_index(size_t size)
75{ 162{
76 return (size / PAGE_SIZE) - 1; 163 return (size / PAGE_SIZE) - 1;
77} 164}
78 165
79/* Must be called with bo_lock held. */
80static void vc4_bo_destroy(struct vc4_bo *bo) 166static void vc4_bo_destroy(struct vc4_bo *bo)
81{ 167{
82 struct drm_gem_object *obj = &bo->base.base; 168 struct drm_gem_object *obj = &bo->base.base;
83 struct vc4_dev *vc4 = to_vc4_dev(obj->dev); 169 struct vc4_dev *vc4 = to_vc4_dev(obj->dev);
84 170
171 lockdep_assert_held(&vc4->bo_lock);
172
173 vc4_bo_set_label(obj, -1);
174
85 if (bo->validated_shader) { 175 if (bo->validated_shader) {
86 kfree(bo->validated_shader->texture_samples); 176 kfree(bo->validated_shader->texture_samples);
87 kfree(bo->validated_shader); 177 kfree(bo->validated_shader);
88 bo->validated_shader = NULL; 178 bo->validated_shader = NULL;
89 } 179 }
90 180
91 vc4->bo_stats.num_allocated--;
92 vc4->bo_stats.size_allocated -= obj->size;
93
94 reservation_object_fini(&bo->_resv); 181 reservation_object_fini(&bo->_resv);
95 182
96 drm_gem_cma_free_object(obj); 183 drm_gem_cma_free_object(obj);
97} 184}
98 185
99/* Must be called with bo_lock held. */
100static void vc4_bo_remove_from_cache(struct vc4_bo *bo) 186static void vc4_bo_remove_from_cache(struct vc4_bo *bo)
101{ 187{
102 struct drm_gem_object *obj = &bo->base.base; 188 struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);
103 struct vc4_dev *vc4 = to_vc4_dev(obj->dev);
104
105 vc4->bo_stats.num_cached--;
106 vc4->bo_stats.size_cached -= obj->size;
107 189
190 lockdep_assert_held(&vc4->bo_lock);
108 list_del(&bo->unref_head); 191 list_del(&bo->unref_head);
109 list_del(&bo->size_head); 192 list_del(&bo->size_head);
110} 193}
@@ -165,7 +248,8 @@ static void vc4_bo_cache_purge(struct drm_device *dev)
165} 248}
166 249
167static struct vc4_bo *vc4_bo_get_from_cache(struct drm_device *dev, 250static struct vc4_bo *vc4_bo_get_from_cache(struct drm_device *dev,
168 uint32_t size) 251 uint32_t size,
252 enum vc4_kernel_bo_type type)
169{ 253{
170 struct vc4_dev *vc4 = to_vc4_dev(dev); 254 struct vc4_dev *vc4 = to_vc4_dev(dev);
171 uint32_t page_index = bo_page_index(size); 255 uint32_t page_index = bo_page_index(size);
@@ -186,6 +270,8 @@ static struct vc4_bo *vc4_bo_get_from_cache(struct drm_device *dev,
186 kref_init(&bo->base.base.refcount); 270 kref_init(&bo->base.base.refcount);
187 271
188out: 272out:
273 if (bo)
274 vc4_bo_set_label(&bo->base.base, type);
189 mutex_unlock(&vc4->bo_lock); 275 mutex_unlock(&vc4->bo_lock);
190 return bo; 276 return bo;
191} 277}
@@ -208,8 +294,9 @@ struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size)
208 return ERR_PTR(-ENOMEM); 294 return ERR_PTR(-ENOMEM);
209 295
210 mutex_lock(&vc4->bo_lock); 296 mutex_lock(&vc4->bo_lock);
211 vc4->bo_stats.num_allocated++; 297 bo->label = VC4_BO_TYPE_KERNEL;
212 vc4->bo_stats.size_allocated += size; 298 vc4->bo_labels[VC4_BO_TYPE_KERNEL].num_allocated++;
299 vc4->bo_labels[VC4_BO_TYPE_KERNEL].size_allocated += size;
213 mutex_unlock(&vc4->bo_lock); 300 mutex_unlock(&vc4->bo_lock);
214 bo->resv = &bo->_resv; 301 bo->resv = &bo->_resv;
215 reservation_object_init(bo->resv); 302 reservation_object_init(bo->resv);
@@ -218,7 +305,7 @@ struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size)
218} 305}
219 306
220struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size, 307struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size,
221 bool allow_unzeroed) 308 bool allow_unzeroed, enum vc4_kernel_bo_type type)
222{ 309{
223 size_t size = roundup(unaligned_size, PAGE_SIZE); 310 size_t size = roundup(unaligned_size, PAGE_SIZE);
224 struct vc4_dev *vc4 = to_vc4_dev(dev); 311 struct vc4_dev *vc4 = to_vc4_dev(dev);
@@ -229,7 +316,7 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size,
229 return ERR_PTR(-EINVAL); 316 return ERR_PTR(-EINVAL);
230 317
231 /* First, try to get a vc4_bo from the kernel BO cache. */ 318 /* First, try to get a vc4_bo from the kernel BO cache. */
232 bo = vc4_bo_get_from_cache(dev, size); 319 bo = vc4_bo_get_from_cache(dev, size, type);
233 if (bo) { 320 if (bo) {
234 if (!allow_unzeroed) 321 if (!allow_unzeroed)
235 memset(bo->base.vaddr, 0, bo->base.base.size); 322 memset(bo->base.vaddr, 0, bo->base.base.size);
@@ -251,7 +338,13 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size,
251 return ERR_PTR(-ENOMEM); 338 return ERR_PTR(-ENOMEM);
252 } 339 }
253 } 340 }
254 return to_vc4_bo(&cma_obj->base); 341 bo = to_vc4_bo(&cma_obj->base);
342
343 mutex_lock(&vc4->bo_lock);
344 vc4_bo_set_label(&cma_obj->base, type);
345 mutex_unlock(&vc4->bo_lock);
346
347 return bo;
255} 348}
256 349
257int vc4_dumb_create(struct drm_file *file_priv, 350int vc4_dumb_create(struct drm_file *file_priv,
@@ -268,7 +361,7 @@ int vc4_dumb_create(struct drm_file *file_priv,
268 if (args->size < args->pitch * args->height) 361 if (args->size < args->pitch * args->height)
269 args->size = args->pitch * args->height; 362 args->size = args->pitch * args->height;
270 363
271 bo = vc4_bo_create(dev, args->size, false); 364 bo = vc4_bo_create(dev, args->size, false, VC4_BO_TYPE_DUMB);
272 if (IS_ERR(bo)) 365 if (IS_ERR(bo))
273 return PTR_ERR(bo); 366 return PTR_ERR(bo);
274 367
@@ -278,12 +371,13 @@ int vc4_dumb_create(struct drm_file *file_priv,
278 return ret; 371 return ret;
279} 372}
280 373
281/* Must be called with bo_lock held. */
282static void vc4_bo_cache_free_old(struct drm_device *dev) 374static void vc4_bo_cache_free_old(struct drm_device *dev)
283{ 375{
284 struct vc4_dev *vc4 = to_vc4_dev(dev); 376 struct vc4_dev *vc4 = to_vc4_dev(dev);
285 unsigned long expire_time = jiffies - msecs_to_jiffies(1000); 377 unsigned long expire_time = jiffies - msecs_to_jiffies(1000);
286 378
379 lockdep_assert_held(&vc4->bo_lock);
380
287 while (!list_empty(&vc4->bo_cache.time_list)) { 381 while (!list_empty(&vc4->bo_cache.time_list)) {
288 struct vc4_bo *bo = list_last_entry(&vc4->bo_cache.time_list, 382 struct vc4_bo *bo = list_last_entry(&vc4->bo_cache.time_list,
289 struct vc4_bo, unref_head); 383 struct vc4_bo, unref_head);
@@ -348,8 +442,7 @@ void vc4_free_object(struct drm_gem_object *gem_bo)
348 list_add(&bo->size_head, cache_list); 442 list_add(&bo->size_head, cache_list);
349 list_add(&bo->unref_head, &vc4->bo_cache.time_list); 443 list_add(&bo->unref_head, &vc4->bo_cache.time_list);
350 444
351 vc4->bo_stats.num_cached++; 445 vc4_bo_set_label(&bo->base.base, VC4_BO_TYPE_KERNEL_CACHE);
352 vc4->bo_stats.size_cached += gem_bo->size;
353 446
354 vc4_bo_cache_free_old(dev); 447 vc4_bo_cache_free_old(dev);
355 448
@@ -483,7 +576,7 @@ int vc4_create_bo_ioctl(struct drm_device *dev, void *data,
483 * We can't allocate from the BO cache, because the BOs don't 576 * We can't allocate from the BO cache, because the BOs don't
484 * get zeroed, and that might leak data between users. 577 * get zeroed, and that might leak data between users.
485 */ 578 */
486 bo = vc4_bo_create(dev, args->size, false); 579 bo = vc4_bo_create(dev, args->size, false, VC4_BO_TYPE_V3D);
487 if (IS_ERR(bo)) 580 if (IS_ERR(bo))
488 return PTR_ERR(bo); 581 return PTR_ERR(bo);
489 582
@@ -536,7 +629,7 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data,
536 return -EINVAL; 629 return -EINVAL;
537 } 630 }
538 631
539 bo = vc4_bo_create(dev, args->size, true); 632 bo = vc4_bo_create(dev, args->size, true, VC4_BO_TYPE_V3D_SHADER);
540 if (IS_ERR(bo)) 633 if (IS_ERR(bo))
541 return PTR_ERR(bo); 634 return PTR_ERR(bo);
542 635
@@ -651,9 +744,24 @@ int vc4_get_tiling_ioctl(struct drm_device *dev, void *data,
651 return 0; 744 return 0;
652} 745}
653 746
654void vc4_bo_cache_init(struct drm_device *dev) 747int vc4_bo_cache_init(struct drm_device *dev)
655{ 748{
656 struct vc4_dev *vc4 = to_vc4_dev(dev); 749 struct vc4_dev *vc4 = to_vc4_dev(dev);
750 int i;
751
752 /* Create the initial set of BO labels that the kernel will
753 * use. This lets us avoid a bunch of string reallocation in
754 * the kernel's draw and BO allocation paths.
755 */
756 vc4->bo_labels = kcalloc(VC4_BO_TYPE_COUNT, sizeof(*vc4->bo_labels),
757 GFP_KERNEL);
758 if (!vc4->bo_labels)
759 return -ENOMEM;
760 vc4->num_labels = VC4_BO_TYPE_COUNT;
761
762 BUILD_BUG_ON(ARRAY_SIZE(bo_type_names) != VC4_BO_TYPE_COUNT);
763 for (i = 0; i < VC4_BO_TYPE_COUNT; i++)
764 vc4->bo_labels[i].name = bo_type_names[i];
657 765
658 mutex_init(&vc4->bo_lock); 766 mutex_init(&vc4->bo_lock);
659 767
@@ -663,19 +771,66 @@ void vc4_bo_cache_init(struct drm_device *dev)
663 setup_timer(&vc4->bo_cache.time_timer, 771 setup_timer(&vc4->bo_cache.time_timer,
664 vc4_bo_cache_time_timer, 772 vc4_bo_cache_time_timer,
665 (unsigned long)dev); 773 (unsigned long)dev);
774
775 return 0;
666} 776}
667 777
668void vc4_bo_cache_destroy(struct drm_device *dev) 778void vc4_bo_cache_destroy(struct drm_device *dev)
669{ 779{
670 struct vc4_dev *vc4 = to_vc4_dev(dev); 780 struct vc4_dev *vc4 = to_vc4_dev(dev);
781 int i;
671 782
672 del_timer(&vc4->bo_cache.time_timer); 783 del_timer(&vc4->bo_cache.time_timer);
673 cancel_work_sync(&vc4->bo_cache.time_work); 784 cancel_work_sync(&vc4->bo_cache.time_work);
674 785
675 vc4_bo_cache_purge(dev); 786 vc4_bo_cache_purge(dev);
676 787
677 if (vc4->bo_stats.num_allocated) { 788 for (i = 0; i < vc4->num_labels; i++) {
678 DRM_ERROR("Destroying BO cache while BOs still allocated:\n"); 789 if (vc4->bo_labels[i].num_allocated) {
679 vc4_bo_stats_dump(vc4); 790 DRM_ERROR("Destroying BO cache with %d %s "
791 "BOs still allocated\n",
792 vc4->bo_labels[i].num_allocated,
793 vc4->bo_labels[i].name);
794 }
795
796 if (is_user_label(i))
797 kfree(vc4->bo_labels[i].name);
798 }
799 kfree(vc4->bo_labels);
800}
801
802int vc4_label_bo_ioctl(struct drm_device *dev, void *data,
803 struct drm_file *file_priv)
804{
805 struct vc4_dev *vc4 = to_vc4_dev(dev);
806 struct drm_vc4_label_bo *args = data;
807 char *name;
808 struct drm_gem_object *gem_obj;
809 int ret = 0, label;
810
811 if (!args->len)
812 return -EINVAL;
813
814 name = strndup_user(u64_to_user_ptr(args->name), args->len + 1);
815 if (IS_ERR(name))
816 return PTR_ERR(name);
817
818 gem_obj = drm_gem_object_lookup(file_priv, args->handle);
819 if (!gem_obj) {
820 DRM_ERROR("Failed to look up GEM BO %d\n", args->handle);
821 kfree(name);
822 return -ENOENT;
680 } 823 }
824
825 mutex_lock(&vc4->bo_lock);
826 label = vc4_get_user_label(vc4, name);
827 if (label != -1)
828 vc4_bo_set_label(gem_obj, label);
829 else
830 ret = -ENOMEM;
831 mutex_unlock(&vc4->bo_lock);
832
833 drm_gem_object_unreference_unlocked(gem_obj);
834
835 return ret;
681} 836}
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index c6b487c3d2b7..e8f0e1790d5e 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -140,6 +140,7 @@ static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
140 DRM_IOCTL_DEF_DRV(VC4_GET_PARAM, vc4_get_param_ioctl, DRM_RENDER_ALLOW), 140 DRM_IOCTL_DEF_DRV(VC4_GET_PARAM, vc4_get_param_ioctl, DRM_RENDER_ALLOW),
141 DRM_IOCTL_DEF_DRV(VC4_SET_TILING, vc4_set_tiling_ioctl, DRM_RENDER_ALLOW), 141 DRM_IOCTL_DEF_DRV(VC4_SET_TILING, vc4_set_tiling_ioctl, DRM_RENDER_ALLOW),
142 DRM_IOCTL_DEF_DRV(VC4_GET_TILING, vc4_get_tiling_ioctl, DRM_RENDER_ALLOW), 142 DRM_IOCTL_DEF_DRV(VC4_GET_TILING, vc4_get_tiling_ioctl, DRM_RENDER_ALLOW),
143 DRM_IOCTL_DEF_DRV(VC4_LABEL_BO, vc4_label_bo_ioctl, DRM_RENDER_ALLOW),
143}; 144};
144 145
145static struct drm_driver vc4_drm_driver = { 146static struct drm_driver vc4_drm_driver = {
@@ -178,8 +179,6 @@ static struct drm_driver vc4_drm_driver = {
178 .gem_prime_mmap = vc4_prime_mmap, 179 .gem_prime_mmap = vc4_prime_mmap,
179 180
180 .dumb_create = vc4_dumb_create, 181 .dumb_create = vc4_dumb_create,
181 .dumb_map_offset = drm_gem_cma_dumb_map_offset,
182 .dumb_destroy = drm_gem_dumb_destroy,
183 182
184 .ioctls = vc4_drm_ioctls, 183 .ioctls = vc4_drm_ioctls,
185 .num_ioctls = ARRAY_SIZE(vc4_drm_ioctls), 184 .num_ioctls = ARRAY_SIZE(vc4_drm_ioctls),
@@ -257,7 +256,9 @@ static int vc4_drm_bind(struct device *dev)
257 vc4->dev = drm; 256 vc4->dev = drm;
258 drm->dev_private = vc4; 257 drm->dev_private = vc4;
259 258
260 vc4_bo_cache_init(drm); 259 ret = vc4_bo_cache_init(drm);
260 if (ret)
261 goto dev_unref;
261 262
262 drm_mode_config_init(drm); 263 drm_mode_config_init(drm);
263 264
@@ -281,8 +282,9 @@ unbind_all:
281 component_unbind_all(dev, drm); 282 component_unbind_all(dev, drm);
282gem_destroy: 283gem_destroy:
283 vc4_gem_destroy(drm); 284 vc4_gem_destroy(drm);
284 drm_dev_unref(drm);
285 vc4_bo_cache_destroy(drm); 285 vc4_bo_cache_destroy(drm);
286dev_unref:
287 drm_dev_unref(drm);
286 return ret; 288 return ret;
287} 289}
288 290
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 1047953216a8..87f2d8e5c134 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -11,6 +11,24 @@
11#include <drm/drm_encoder.h> 11#include <drm/drm_encoder.h>
12#include <drm/drm_gem_cma_helper.h> 12#include <drm/drm_gem_cma_helper.h>
13 13
14/* Don't forget to update vc4_bo.c: bo_type_names[] when adding to
15 * this.
16 */
17enum vc4_kernel_bo_type {
18 /* Any kernel allocation (gem_create_object hook) before it
19 * gets another type set.
20 */
21 VC4_BO_TYPE_KERNEL,
22 VC4_BO_TYPE_V3D,
23 VC4_BO_TYPE_V3D_SHADER,
24 VC4_BO_TYPE_DUMB,
25 VC4_BO_TYPE_BIN,
26 VC4_BO_TYPE_RCL,
27 VC4_BO_TYPE_BCL,
28 VC4_BO_TYPE_KERNEL_CACHE,
29 VC4_BO_TYPE_COUNT
30};
31
14struct vc4_dev { 32struct vc4_dev {
15 struct drm_device *dev; 33 struct drm_device *dev;
16 34
@@ -46,14 +64,14 @@ struct vc4_dev {
46 struct timer_list time_timer; 64 struct timer_list time_timer;
47 } bo_cache; 65 } bo_cache;
48 66
49 struct vc4_bo_stats { 67 u32 num_labels;
68 struct vc4_label {
69 const char *name;
50 u32 num_allocated; 70 u32 num_allocated;
51 u32 size_allocated; 71 u32 size_allocated;
52 u32 num_cached; 72 } *bo_labels;
53 u32 size_cached;
54 } bo_stats;
55 73
56 /* Protects bo_cache and the BO stats. */ 74 /* Protects bo_cache and bo_labels. */
57 struct mutex bo_lock; 75 struct mutex bo_lock;
58 76
59 uint64_t dma_fence_context; 77 uint64_t dma_fence_context;
@@ -169,6 +187,11 @@ struct vc4_bo {
169 /* normally (resv == &_resv) except for imported bo's */ 187 /* normally (resv == &_resv) except for imported bo's */
170 struct reservation_object *resv; 188 struct reservation_object *resv;
171 struct reservation_object _resv; 189 struct reservation_object _resv;
190
191 /* One of enum vc4_kernel_bo_type, or VC4_BO_TYPE_COUNT + i
192 * for user-allocated labels.
193 */
194 int label;
172}; 195};
173 196
174static inline struct vc4_bo * 197static inline struct vc4_bo *
@@ -460,7 +483,7 @@ struct vc4_validated_shader_info {
460struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size); 483struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size);
461void vc4_free_object(struct drm_gem_object *gem_obj); 484void vc4_free_object(struct drm_gem_object *gem_obj);
462struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size, 485struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size,
463 bool from_cache); 486 bool from_cache, enum vc4_kernel_bo_type type);
464int vc4_dumb_create(struct drm_file *file_priv, 487int vc4_dumb_create(struct drm_file *file_priv,
465 struct drm_device *dev, 488 struct drm_device *dev,
466 struct drm_mode_create_dumb *args); 489 struct drm_mode_create_dumb *args);
@@ -478,6 +501,8 @@ int vc4_get_tiling_ioctl(struct drm_device *dev, void *data,
478 struct drm_file *file_priv); 501 struct drm_file *file_priv);
479int vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, 502int vc4_get_hang_state_ioctl(struct drm_device *dev, void *data,
480 struct drm_file *file_priv); 503 struct drm_file *file_priv);
504int vc4_label_bo_ioctl(struct drm_device *dev, void *data,
505 struct drm_file *file_priv);
481int vc4_mmap(struct file *filp, struct vm_area_struct *vma); 506int vc4_mmap(struct file *filp, struct vm_area_struct *vma);
482struct reservation_object *vc4_prime_res_obj(struct drm_gem_object *obj); 507struct reservation_object *vc4_prime_res_obj(struct drm_gem_object *obj);
483int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); 508int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
@@ -485,7 +510,7 @@ struct drm_gem_object *vc4_prime_import_sg_table(struct drm_device *dev,
485 struct dma_buf_attachment *attach, 510 struct dma_buf_attachment *attach,
486 struct sg_table *sgt); 511 struct sg_table *sgt);
487void *vc4_prime_vmap(struct drm_gem_object *obj); 512void *vc4_prime_vmap(struct drm_gem_object *obj);
488void vc4_bo_cache_init(struct drm_device *dev); 513int vc4_bo_cache_init(struct drm_device *dev);
489void vc4_bo_cache_destroy(struct drm_device *dev); 514void vc4_bo_cache_destroy(struct drm_device *dev);
490int vc4_bo_stats_debugfs(struct seq_file *m, void *arg); 515int vc4_bo_stats_debugfs(struct seq_file *m, void *arg);
491 516
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
index d5b821ad06af..209fccd0d3b4 100644
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -119,7 +119,7 @@ vc4_get_hang_state_ioctl(struct drm_device *dev, void *data,
119 bo_state[i].size = vc4_bo->base.base.size; 119 bo_state[i].size = vc4_bo->base.base.size;
120 } 120 }
121 121
122 if (copy_to_user((void __user *)(uintptr_t)get_state->bo, 122 if (copy_to_user(u64_to_user_ptr(get_state->bo),
123 bo_state, 123 bo_state,
124 state->bo_count * sizeof(*bo_state))) 124 state->bo_count * sizeof(*bo_state)))
125 ret = -EFAULT; 125 ret = -EFAULT;
@@ -678,8 +678,7 @@ vc4_cl_lookup_bos(struct drm_device *dev,
678 goto fail; 678 goto fail;
679 } 679 }
680 680
681 if (copy_from_user(handles, 681 if (copy_from_user(handles, u64_to_user_ptr(args->bo_handles),
682 (void __user *)(uintptr_t)args->bo_handles,
683 exec->bo_count * sizeof(uint32_t))) { 682 exec->bo_count * sizeof(uint32_t))) {
684 ret = -EFAULT; 683 ret = -EFAULT;
685 DRM_ERROR("Failed to copy in GEM handles\n"); 684 DRM_ERROR("Failed to copy in GEM handles\n");
@@ -755,27 +754,27 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec)
755 exec->shader_state_size = args->shader_rec_count; 754 exec->shader_state_size = args->shader_rec_count;
756 755
757 if (copy_from_user(bin, 756 if (copy_from_user(bin,
758 (void __user *)(uintptr_t)args->bin_cl, 757 u64_to_user_ptr(args->bin_cl),
759 args->bin_cl_size)) { 758 args->bin_cl_size)) {
760 ret = -EFAULT; 759 ret = -EFAULT;
761 goto fail; 760 goto fail;
762 } 761 }
763 762
764 if (copy_from_user(exec->shader_rec_u, 763 if (copy_from_user(exec->shader_rec_u,
765 (void __user *)(uintptr_t)args->shader_rec, 764 u64_to_user_ptr(args->shader_rec),
766 args->shader_rec_size)) { 765 args->shader_rec_size)) {
767 ret = -EFAULT; 766 ret = -EFAULT;
768 goto fail; 767 goto fail;
769 } 768 }
770 769
771 if (copy_from_user(exec->uniforms_u, 770 if (copy_from_user(exec->uniforms_u,
772 (void __user *)(uintptr_t)args->uniforms, 771 u64_to_user_ptr(args->uniforms),
773 args->uniforms_size)) { 772 args->uniforms_size)) {
774 ret = -EFAULT; 773 ret = -EFAULT;
775 goto fail; 774 goto fail;
776 } 775 }
777 776
778 bo = vc4_bo_create(dev, exec_size, true); 777 bo = vc4_bo_create(dev, exec_size, true, VC4_BO_TYPE_BCL);
779 if (IS_ERR(bo)) { 778 if (IS_ERR(bo)) {
780 DRM_ERROR("Couldn't allocate BO for binning\n"); 779 DRM_ERROR("Couldn't allocate BO for binning\n");
781 ret = PTR_ERR(bo); 780 ret = PTR_ERR(bo);
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 406d6d83b6c6..ff09b8e2f9ee 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -57,9 +57,14 @@
57#include <sound/pcm_drm_eld.h> 57#include <sound/pcm_drm_eld.h>
58#include <sound/pcm_params.h> 58#include <sound/pcm_params.h>
59#include <sound/soc.h> 59#include <sound/soc.h>
60#include "media/cec.h"
60#include "vc4_drv.h" 61#include "vc4_drv.h"
61#include "vc4_regs.h" 62#include "vc4_regs.h"
62 63
64#define HSM_CLOCK_FREQ 163682864
65#define CEC_CLOCK_FREQ 40000
66#define CEC_CLOCK_DIV (HSM_CLOCK_FREQ / CEC_CLOCK_FREQ)
67
63/* HDMI audio information */ 68/* HDMI audio information */
64struct vc4_hdmi_audio { 69struct vc4_hdmi_audio {
65 struct snd_soc_card card; 70 struct snd_soc_card card;
@@ -85,6 +90,11 @@ struct vc4_hdmi {
85 int hpd_gpio; 90 int hpd_gpio;
86 bool hpd_active_low; 91 bool hpd_active_low;
87 92
93 struct cec_adapter *cec_adap;
94 struct cec_msg cec_rx_msg;
95 bool cec_tx_ok;
96 bool cec_irq_was_rx;
97
88 struct clk *pixel_clock; 98 struct clk *pixel_clock;
89 struct clk *hsm_clock; 99 struct clk *hsm_clock;
90}; 100};
@@ -149,6 +159,23 @@ static const struct {
149 HDMI_REG(VC4_HDMI_VERTB1), 159 HDMI_REG(VC4_HDMI_VERTB1),
150 HDMI_REG(VC4_HDMI_TX_PHY_RESET_CTL), 160 HDMI_REG(VC4_HDMI_TX_PHY_RESET_CTL),
151 HDMI_REG(VC4_HDMI_TX_PHY_CTL0), 161 HDMI_REG(VC4_HDMI_TX_PHY_CTL0),
162
163 HDMI_REG(VC4_HDMI_CEC_CNTRL_1),
164 HDMI_REG(VC4_HDMI_CEC_CNTRL_2),
165 HDMI_REG(VC4_HDMI_CEC_CNTRL_3),
166 HDMI_REG(VC4_HDMI_CEC_CNTRL_4),
167 HDMI_REG(VC4_HDMI_CEC_CNTRL_5),
168 HDMI_REG(VC4_HDMI_CPU_STATUS),
169 HDMI_REG(VC4_HDMI_CPU_MASK_STATUS),
170
171 HDMI_REG(VC4_HDMI_CEC_RX_DATA_1),
172 HDMI_REG(VC4_HDMI_CEC_RX_DATA_2),
173 HDMI_REG(VC4_HDMI_CEC_RX_DATA_3),
174 HDMI_REG(VC4_HDMI_CEC_RX_DATA_4),
175 HDMI_REG(VC4_HDMI_CEC_TX_DATA_1),
176 HDMI_REG(VC4_HDMI_CEC_TX_DATA_2),
177 HDMI_REG(VC4_HDMI_CEC_TX_DATA_3),
178 HDMI_REG(VC4_HDMI_CEC_TX_DATA_4),
152}; 179};
153 180
154static const struct { 181static const struct {
@@ -216,8 +243,8 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
216 if (gpio_get_value_cansleep(vc4->hdmi->hpd_gpio) ^ 243 if (gpio_get_value_cansleep(vc4->hdmi->hpd_gpio) ^
217 vc4->hdmi->hpd_active_low) 244 vc4->hdmi->hpd_active_low)
218 return connector_status_connected; 245 return connector_status_connected;
219 else 246 cec_phys_addr_invalidate(vc4->hdmi->cec_adap);
220 return connector_status_disconnected; 247 return connector_status_disconnected;
221 } 248 }
222 249
223 if (drm_probe_ddc(vc4->hdmi->ddc)) 250 if (drm_probe_ddc(vc4->hdmi->ddc))
@@ -225,8 +252,8 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
225 252
226 if (HDMI_READ(VC4_HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED) 253 if (HDMI_READ(VC4_HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED)
227 return connector_status_connected; 254 return connector_status_connected;
228 else 255 cec_phys_addr_invalidate(vc4->hdmi->cec_adap);
229 return connector_status_disconnected; 256 return connector_status_disconnected;
230} 257}
231 258
232static void vc4_hdmi_connector_destroy(struct drm_connector *connector) 259static void vc4_hdmi_connector_destroy(struct drm_connector *connector)
@@ -247,6 +274,7 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
247 struct edid *edid; 274 struct edid *edid;
248 275
249 edid = drm_get_edid(connector, vc4->hdmi->ddc); 276 edid = drm_get_edid(connector, vc4->hdmi->ddc);
277 cec_s_phys_addr_from_edid(vc4->hdmi->cec_adap, edid);
250 if (!edid) 278 if (!edid)
251 return -ENODEV; 279 return -ENODEV;
252 280
@@ -265,7 +293,6 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
265} 293}
266 294
267static const struct drm_connector_funcs vc4_hdmi_connector_funcs = { 295static const struct drm_connector_funcs vc4_hdmi_connector_funcs = {
268 .dpms = drm_atomic_helper_connector_dpms,
269 .detect = vc4_hdmi_connector_detect, 296 .detect = vc4_hdmi_connector_detect,
270 .fill_modes = drm_helper_probe_single_connector_modes, 297 .fill_modes = drm_helper_probe_single_connector_modes,
271 .destroy = vc4_hdmi_connector_destroy, 298 .destroy = vc4_hdmi_connector_destroy,
@@ -463,11 +490,6 @@ static void vc4_hdmi_encoder_disable(struct drm_encoder *encoder)
463 HD_WRITE(VC4_HD_VID_CTL, 490 HD_WRITE(VC4_HD_VID_CTL,
464 HD_READ(VC4_HD_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE); 491 HD_READ(VC4_HD_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
465 492
466 HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_SW_RST);
467 udelay(1);
468 HD_WRITE(VC4_HD_M_CTL, 0);
469
470 clk_disable_unprepare(hdmi->hsm_clock);
471 clk_disable_unprepare(hdmi->pixel_clock); 493 clk_disable_unprepare(hdmi->pixel_clock);
472 494
473 ret = pm_runtime_put(&hdmi->pdev->dev); 495 ret = pm_runtime_put(&hdmi->pdev->dev);
@@ -509,16 +531,6 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
509 return; 531 return;
510 } 532 }
511 533
512 /* This is the rate that is set by the firmware. The number
513 * needs to be a bit higher than the pixel clock rate
514 * (generally 148.5Mhz).
515 */
516 ret = clk_set_rate(hdmi->hsm_clock, 163682864);
517 if (ret) {
518 DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
519 return;
520 }
521
522 ret = clk_set_rate(hdmi->pixel_clock, 534 ret = clk_set_rate(hdmi->pixel_clock,
523 mode->clock * 1000 * 535 mode->clock * 1000 *
524 ((mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1)); 536 ((mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1));
@@ -533,20 +545,6 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
533 return; 545 return;
534 } 546 }
535 547
536 ret = clk_prepare_enable(hdmi->hsm_clock);
537 if (ret) {
538 DRM_ERROR("Failed to turn on HDMI state machine clock: %d\n",
539 ret);
540 clk_disable_unprepare(hdmi->pixel_clock);
541 return;
542 }
543
544 HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_SW_RST);
545 udelay(1);
546 HD_WRITE(VC4_HD_M_CTL, 0);
547
548 HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_ENABLE);
549
550 HDMI_WRITE(VC4_HDMI_SW_RESET_CONTROL, 548 HDMI_WRITE(VC4_HDMI_SW_RESET_CONTROL,
551 VC4_HDMI_SW_RESET_HDMI | 549 VC4_HDMI_SW_RESET_HDMI |
552 VC4_HDMI_SW_RESET_FORMAT_DETECT); 550 VC4_HDMI_SW_RESET_FORMAT_DETECT);
@@ -1150,6 +1148,159 @@ static void vc4_hdmi_audio_cleanup(struct vc4_hdmi *hdmi)
1150 snd_soc_unregister_codec(dev); 1148 snd_soc_unregister_codec(dev);
1151} 1149}
1152 1150
1151#ifdef CONFIG_DRM_VC4_HDMI_CEC
1152static irqreturn_t vc4_cec_irq_handler_thread(int irq, void *priv)
1153{
1154 struct vc4_dev *vc4 = priv;
1155 struct vc4_hdmi *hdmi = vc4->hdmi;
1156
1157 if (hdmi->cec_irq_was_rx) {
1158 if (hdmi->cec_rx_msg.len)
1159 cec_received_msg(hdmi->cec_adap, &hdmi->cec_rx_msg);
1160 } else if (hdmi->cec_tx_ok) {
1161 cec_transmit_done(hdmi->cec_adap, CEC_TX_STATUS_OK,
1162 0, 0, 0, 0);
1163 } else {
1164 /*
1165 * This CEC implementation makes 1 retry, so if we
1166 * get a NACK, then that means it made 2 attempts.
1167 */
1168 cec_transmit_done(hdmi->cec_adap, CEC_TX_STATUS_NACK,
1169 0, 2, 0, 0);
1170 }
1171 return IRQ_HANDLED;
1172}
1173
1174static void vc4_cec_read_msg(struct vc4_dev *vc4, u32 cntrl1)
1175{
1176 struct cec_msg *msg = &vc4->hdmi->cec_rx_msg;
1177 unsigned int i;
1178
1179 msg->len = 1 + ((cntrl1 & VC4_HDMI_CEC_REC_WRD_CNT_MASK) >>
1180 VC4_HDMI_CEC_REC_WRD_CNT_SHIFT);
1181 for (i = 0; i < msg->len; i += 4) {
1182 u32 val = HDMI_READ(VC4_HDMI_CEC_RX_DATA_1 + i);
1183
1184 msg->msg[i] = val & 0xff;
1185 msg->msg[i + 1] = (val >> 8) & 0xff;
1186 msg->msg[i + 2] = (val >> 16) & 0xff;
1187 msg->msg[i + 3] = (val >> 24) & 0xff;
1188 }
1189}
1190
1191static irqreturn_t vc4_cec_irq_handler(int irq, void *priv)
1192{
1193 struct vc4_dev *vc4 = priv;
1194 struct vc4_hdmi *hdmi = vc4->hdmi;
1195 u32 stat = HDMI_READ(VC4_HDMI_CPU_STATUS);
1196 u32 cntrl1, cntrl5;
1197
1198 if (!(stat & VC4_HDMI_CPU_CEC))
1199 return IRQ_NONE;
1200 hdmi->cec_rx_msg.len = 0;
1201 cntrl1 = HDMI_READ(VC4_HDMI_CEC_CNTRL_1);
1202 cntrl5 = HDMI_READ(VC4_HDMI_CEC_CNTRL_5);
1203 hdmi->cec_irq_was_rx = cntrl5 & VC4_HDMI_CEC_RX_CEC_INT;
1204 if (hdmi->cec_irq_was_rx) {
1205 vc4_cec_read_msg(vc4, cntrl1);
1206 cntrl1 |= VC4_HDMI_CEC_CLEAR_RECEIVE_OFF;
1207 HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, cntrl1);
1208 cntrl1 &= ~VC4_HDMI_CEC_CLEAR_RECEIVE_OFF;
1209 } else {
1210 hdmi->cec_tx_ok = cntrl1 & VC4_HDMI_CEC_TX_STATUS_GOOD;
1211 cntrl1 &= ~VC4_HDMI_CEC_START_XMIT_BEGIN;
1212 }
1213 HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, cntrl1);
1214 HDMI_WRITE(VC4_HDMI_CPU_CLEAR, VC4_HDMI_CPU_CEC);
1215
1216 return IRQ_WAKE_THREAD;
1217}
1218
1219static int vc4_hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable)
1220{
1221 struct vc4_dev *vc4 = cec_get_drvdata(adap);
1222 /* clock period in microseconds */
1223 const u32 usecs = 1000000 / CEC_CLOCK_FREQ;
1224 u32 val = HDMI_READ(VC4_HDMI_CEC_CNTRL_5);
1225
1226 val &= ~(VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET |
1227 VC4_HDMI_CEC_CNT_TO_4700_US_MASK |
1228 VC4_HDMI_CEC_CNT_TO_4500_US_MASK);
1229 val |= ((4700 / usecs) << VC4_HDMI_CEC_CNT_TO_4700_US_SHIFT) |
1230 ((4500 / usecs) << VC4_HDMI_CEC_CNT_TO_4500_US_SHIFT);
1231
1232 if (enable) {
1233 HDMI_WRITE(VC4_HDMI_CEC_CNTRL_5, val |
1234 VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET);
1235 HDMI_WRITE(VC4_HDMI_CEC_CNTRL_5, val);
1236 HDMI_WRITE(VC4_HDMI_CEC_CNTRL_2,
1237 ((1500 / usecs) << VC4_HDMI_CEC_CNT_TO_1500_US_SHIFT) |
1238 ((1300 / usecs) << VC4_HDMI_CEC_CNT_TO_1300_US_SHIFT) |
1239 ((800 / usecs) << VC4_HDMI_CEC_CNT_TO_800_US_SHIFT) |
1240 ((600 / usecs) << VC4_HDMI_CEC_CNT_TO_600_US_SHIFT) |
1241 ((400 / usecs) << VC4_HDMI_CEC_CNT_TO_400_US_SHIFT));
1242 HDMI_WRITE(VC4_HDMI_CEC_CNTRL_3,
1243 ((2750 / usecs) << VC4_HDMI_CEC_CNT_TO_2750_US_SHIFT) |
1244 ((2400 / usecs) << VC4_HDMI_CEC_CNT_TO_2400_US_SHIFT) |
1245 ((2050 / usecs) << VC4_HDMI_CEC_CNT_TO_2050_US_SHIFT) |
1246 ((1700 / usecs) << VC4_HDMI_CEC_CNT_TO_1700_US_SHIFT));
1247 HDMI_WRITE(VC4_HDMI_CEC_CNTRL_4,
1248 ((4300 / usecs) << VC4_HDMI_CEC_CNT_TO_4300_US_SHIFT) |
1249 ((3900 / usecs) << VC4_HDMI_CEC_CNT_TO_3900_US_SHIFT) |
1250 ((3600 / usecs) << VC4_HDMI_CEC_CNT_TO_3600_US_SHIFT) |
1251 ((3500 / usecs) << VC4_HDMI_CEC_CNT_TO_3500_US_SHIFT));
1252
1253 HDMI_WRITE(VC4_HDMI_CPU_MASK_CLEAR, VC4_HDMI_CPU_CEC);
1254 } else {
1255 HDMI_WRITE(VC4_HDMI_CPU_MASK_SET, VC4_HDMI_CPU_CEC);
1256 HDMI_WRITE(VC4_HDMI_CEC_CNTRL_5, val |
1257 VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET);
1258 }
1259 return 0;
1260}
1261
1262static int vc4_hdmi_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
1263{
1264 struct vc4_dev *vc4 = cec_get_drvdata(adap);
1265
1266 HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1,
1267 (HDMI_READ(VC4_HDMI_CEC_CNTRL_1) & ~VC4_HDMI_CEC_ADDR_MASK) |
1268 (log_addr & 0xf) << VC4_HDMI_CEC_ADDR_SHIFT);
1269 return 0;
1270}
1271
1272static int vc4_hdmi_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
1273 u32 signal_free_time, struct cec_msg *msg)
1274{
1275 struct vc4_dev *vc4 = cec_get_drvdata(adap);
1276 u32 val;
1277 unsigned int i;
1278
1279 for (i = 0; i < msg->len; i += 4)
1280 HDMI_WRITE(VC4_HDMI_CEC_TX_DATA_1 + i,
1281 (msg->msg[i]) |
1282 (msg->msg[i + 1] << 8) |
1283 (msg->msg[i + 2] << 16) |
1284 (msg->msg[i + 3] << 24));
1285
1286 val = HDMI_READ(VC4_HDMI_CEC_CNTRL_1);
1287 val &= ~VC4_HDMI_CEC_START_XMIT_BEGIN;
1288 HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, val);
1289 val &= ~VC4_HDMI_CEC_MESSAGE_LENGTH_MASK;
1290 val |= (msg->len - 1) << VC4_HDMI_CEC_MESSAGE_LENGTH_SHIFT;
1291 val |= VC4_HDMI_CEC_START_XMIT_BEGIN;
1292
1293 HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, val);
1294 return 0;
1295}
1296
1297static const struct cec_adap_ops vc4_hdmi_cec_adap_ops = {
1298 .adap_enable = vc4_hdmi_cec_adap_enable,
1299 .adap_log_addr = vc4_hdmi_cec_adap_log_addr,
1300 .adap_transmit = vc4_hdmi_cec_adap_transmit,
1301};
1302#endif
1303
1153static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data) 1304static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
1154{ 1305{
1155 struct platform_device *pdev = to_platform_device(dev); 1306 struct platform_device *pdev = to_platform_device(dev);
@@ -1205,6 +1356,23 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
1205 return -EPROBE_DEFER; 1356 return -EPROBE_DEFER;
1206 } 1357 }
1207 1358
1359 /* This is the rate that is set by the firmware. The number
1360 * needs to be a bit higher than the pixel clock rate
1361 * (generally 148.5Mhz).
1362 */
1363 ret = clk_set_rate(hdmi->hsm_clock, HSM_CLOCK_FREQ);
1364 if (ret) {
1365 DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
1366 goto err_put_i2c;
1367 }
1368
1369 ret = clk_prepare_enable(hdmi->hsm_clock);
1370 if (ret) {
1371 DRM_ERROR("Failed to turn on HDMI state machine clock: %d\n",
1372 ret);
1373 goto err_put_i2c;
1374 }
1375
1208 /* Only use the GPIO HPD pin if present in the DT, otherwise 1376 /* Only use the GPIO HPD pin if present in the DT, otherwise
1209 * we'll use the HDMI core's register. 1377 * we'll use the HDMI core's register.
1210 */ 1378 */
@@ -1216,7 +1384,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
1216 &hpd_gpio_flags); 1384 &hpd_gpio_flags);
1217 if (hdmi->hpd_gpio < 0) { 1385 if (hdmi->hpd_gpio < 0) {
1218 ret = hdmi->hpd_gpio; 1386 ret = hdmi->hpd_gpio;
1219 goto err_put_i2c; 1387 goto err_unprepare_hsm;
1220 } 1388 }
1221 1389
1222 hdmi->hpd_active_low = hpd_gpio_flags & OF_GPIO_ACTIVE_LOW; 1390 hdmi->hpd_active_low = hpd_gpio_flags & OF_GPIO_ACTIVE_LOW;
@@ -1224,6 +1392,14 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
1224 1392
1225 vc4->hdmi = hdmi; 1393 vc4->hdmi = hdmi;
1226 1394
1395 /* HDMI core must be enabled. */
1396 if (!(HD_READ(VC4_HD_M_CTL) & VC4_HD_M_ENABLE)) {
1397 HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_SW_RST);
1398 udelay(1);
1399 HD_WRITE(VC4_HD_M_CTL, 0);
1400
1401 HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_ENABLE);
1402 }
1227 pm_runtime_enable(dev); 1403 pm_runtime_enable(dev);
1228 1404
1229 drm_encoder_init(drm, hdmi->encoder, &vc4_hdmi_encoder_funcs, 1405 drm_encoder_init(drm, hdmi->encoder, &vc4_hdmi_encoder_funcs,
@@ -1235,6 +1411,37 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
1235 ret = PTR_ERR(hdmi->connector); 1411 ret = PTR_ERR(hdmi->connector);
1236 goto err_destroy_encoder; 1412 goto err_destroy_encoder;
1237 } 1413 }
1414#ifdef CONFIG_DRM_VC4_HDMI_CEC
1415 hdmi->cec_adap = cec_allocate_adapter(&vc4_hdmi_cec_adap_ops,
1416 vc4, "vc4",
1417 CEC_CAP_TRANSMIT |
1418 CEC_CAP_LOG_ADDRS |
1419 CEC_CAP_PASSTHROUGH |
1420 CEC_CAP_RC, 1);
1421 ret = PTR_ERR_OR_ZERO(hdmi->cec_adap);
1422 if (ret < 0)
1423 goto err_destroy_conn;
1424 HDMI_WRITE(VC4_HDMI_CPU_MASK_SET, 0xffffffff);
1425 value = HDMI_READ(VC4_HDMI_CEC_CNTRL_1);
1426 value &= ~VC4_HDMI_CEC_DIV_CLK_CNT_MASK;
1427 /*
1428 * Set the logical address to Unregistered and set the clock
1429 * divider: the hsm_clock rate and this divider setting will
1430 * give a 40 kHz CEC clock.
1431 */
1432 value |= VC4_HDMI_CEC_ADDR_MASK |
1433 (4091 << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT);
1434 HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, value);
1435 ret = devm_request_threaded_irq(dev, platform_get_irq(pdev, 0),
1436 vc4_cec_irq_handler,
1437 vc4_cec_irq_handler_thread, 0,
1438 "vc4 hdmi cec", vc4);
1439 if (ret)
1440 goto err_delete_cec_adap;
1441 ret = cec_register_adapter(hdmi->cec_adap, dev);
1442 if (ret < 0)
1443 goto err_delete_cec_adap;
1444#endif
1238 1445
1239 ret = vc4_hdmi_audio_init(hdmi); 1446 ret = vc4_hdmi_audio_init(hdmi);
1240 if (ret) 1447 if (ret)
@@ -1242,8 +1449,16 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
1242 1449
1243 return 0; 1450 return 0;
1244 1451
1452#ifdef CONFIG_DRM_VC4_HDMI_CEC
1453err_delete_cec_adap:
1454 cec_delete_adapter(hdmi->cec_adap);
1455err_destroy_conn:
1456 vc4_hdmi_connector_destroy(hdmi->connector);
1457#endif
1245err_destroy_encoder: 1458err_destroy_encoder:
1246 vc4_hdmi_encoder_destroy(hdmi->encoder); 1459 vc4_hdmi_encoder_destroy(hdmi->encoder);
1460err_unprepare_hsm:
1461 clk_disable_unprepare(hdmi->hsm_clock);
1247 pm_runtime_disable(dev); 1462 pm_runtime_disable(dev);
1248err_put_i2c: 1463err_put_i2c:
1249 put_device(&hdmi->ddc->dev); 1464 put_device(&hdmi->ddc->dev);
@@ -1259,10 +1474,11 @@ static void vc4_hdmi_unbind(struct device *dev, struct device *master,
1259 struct vc4_hdmi *hdmi = vc4->hdmi; 1474 struct vc4_hdmi *hdmi = vc4->hdmi;
1260 1475
1261 vc4_hdmi_audio_cleanup(hdmi); 1476 vc4_hdmi_audio_cleanup(hdmi);
1262 1477 cec_unregister_adapter(hdmi->cec_adap);
1263 vc4_hdmi_connector_destroy(hdmi->connector); 1478 vc4_hdmi_connector_destroy(hdmi->connector);
1264 vc4_hdmi_encoder_destroy(hdmi->encoder); 1479 vc4_hdmi_encoder_destroy(hdmi->encoder);
1265 1480
1481 clk_disable_unprepare(hdmi->hsm_clock);
1266 pm_runtime_disable(dev); 1482 pm_runtime_disable(dev);
1267 1483
1268 put_device(&hdmi->ddc->dev); 1484 put_device(&hdmi->ddc->dev);
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index 8853e9a4f005..2968b3ebb895 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -902,7 +902,7 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev,
902 ret = drm_universal_plane_init(dev, plane, 0, 902 ret = drm_universal_plane_init(dev, plane, 0,
903 &vc4_plane_funcs, 903 &vc4_plane_funcs,
904 formats, num_formats, 904 formats, num_formats,
905 type, NULL); 905 NULL, type, NULL);
906 906
907 drm_plane_helper_add(plane, &vc4_plane_helper_funcs); 907 drm_plane_helper_add(plane, &vc4_plane_helper_funcs);
908 908
diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
index d382c34c1b9e..55677bd50f66 100644
--- a/drivers/gpu/drm/vc4/vc4_regs.h
+++ b/drivers/gpu/drm/vc4/vc4_regs.h
@@ -561,16 +561,129 @@
561# define VC4_HDMI_VERTB_VBP_MASK VC4_MASK(8, 0) 561# define VC4_HDMI_VERTB_VBP_MASK VC4_MASK(8, 0)
562# define VC4_HDMI_VERTB_VBP_SHIFT 0 562# define VC4_HDMI_VERTB_VBP_SHIFT 0
563 563
564#define VC4_HDMI_CEC_CNTRL_1 0x0e8
565/* Set when the transmission has ended. */
566# define VC4_HDMI_CEC_TX_EOM BIT(31)
567/* If set, transmission was acked on the 1st or 2nd attempt (only one
568 * retry is attempted). If in continuous mode, this means TX needs to
569 * be filled if !TX_EOM.
570 */
571# define VC4_HDMI_CEC_TX_STATUS_GOOD BIT(30)
572# define VC4_HDMI_CEC_RX_EOM BIT(29)
573# define VC4_HDMI_CEC_RX_STATUS_GOOD BIT(28)
574/* Number of bytes received for the message. */
575# define VC4_HDMI_CEC_REC_WRD_CNT_MASK VC4_MASK(27, 24)
576# define VC4_HDMI_CEC_REC_WRD_CNT_SHIFT 24
577/* Sets continuous receive mode. Generates interrupt after each 8
578 * bytes to signal that RX_DATA should be consumed, and at RX_EOM.
579 *
580 * If disabled, maximum 16 bytes will be received (including header),
581 * and interrupt at RX_EOM. Later bytes will be acked but not put
582 * into the RX_DATA.
583 */
584# define VC4_HDMI_CEC_RX_CONTINUE BIT(23)
585# define VC4_HDMI_CEC_TX_CONTINUE BIT(22)
586/* Set this after a CEC interrupt. */
587# define VC4_HDMI_CEC_CLEAR_RECEIVE_OFF BIT(21)
588/* Starts a TX. Will wait for appropriate idel time before CEC
589 * activity. Must be cleared in between transmits.
590 */
591# define VC4_HDMI_CEC_START_XMIT_BEGIN BIT(20)
592# define VC4_HDMI_CEC_MESSAGE_LENGTH_MASK VC4_MASK(19, 16)
593# define VC4_HDMI_CEC_MESSAGE_LENGTH_SHIFT 16
594/* Device's CEC address */
595# define VC4_HDMI_CEC_ADDR_MASK VC4_MASK(15, 12)
596# define VC4_HDMI_CEC_ADDR_SHIFT 12
597/* Divides off of HSM clock to generate CEC bit clock. */
598/* With the current defaults the CEC bit clock is 40 kHz = 25 usec */
599# define VC4_HDMI_CEC_DIV_CLK_CNT_MASK VC4_MASK(11, 0)
600# define VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT 0
601
602/* Set these fields to how many bit clock cycles get to that many
603 * microseconds.
604 */
605#define VC4_HDMI_CEC_CNTRL_2 0x0ec
606# define VC4_HDMI_CEC_CNT_TO_1500_US_MASK VC4_MASK(30, 24)
607# define VC4_HDMI_CEC_CNT_TO_1500_US_SHIFT 24
608# define VC4_HDMI_CEC_CNT_TO_1300_US_MASK VC4_MASK(23, 17)
609# define VC4_HDMI_CEC_CNT_TO_1300_US_SHIFT 17
610# define VC4_HDMI_CEC_CNT_TO_800_US_MASK VC4_MASK(16, 11)
611# define VC4_HDMI_CEC_CNT_TO_800_US_SHIFT 11
612# define VC4_HDMI_CEC_CNT_TO_600_US_MASK VC4_MASK(10, 5)
613# define VC4_HDMI_CEC_CNT_TO_600_US_SHIFT 5
614# define VC4_HDMI_CEC_CNT_TO_400_US_MASK VC4_MASK(4, 0)
615# define VC4_HDMI_CEC_CNT_TO_400_US_SHIFT 0
616
617#define VC4_HDMI_CEC_CNTRL_3 0x0f0
618# define VC4_HDMI_CEC_CNT_TO_2750_US_MASK VC4_MASK(31, 24)
619# define VC4_HDMI_CEC_CNT_TO_2750_US_SHIFT 24
620# define VC4_HDMI_CEC_CNT_TO_2400_US_MASK VC4_MASK(23, 16)
621# define VC4_HDMI_CEC_CNT_TO_2400_US_SHIFT 16
622# define VC4_HDMI_CEC_CNT_TO_2050_US_MASK VC4_MASK(15, 8)
623# define VC4_HDMI_CEC_CNT_TO_2050_US_SHIFT 8
624# define VC4_HDMI_CEC_CNT_TO_1700_US_MASK VC4_MASK(7, 0)
625# define VC4_HDMI_CEC_CNT_TO_1700_US_SHIFT 0
626
627#define VC4_HDMI_CEC_CNTRL_4 0x0f4
628# define VC4_HDMI_CEC_CNT_TO_4300_US_MASK VC4_MASK(31, 24)
629# define VC4_HDMI_CEC_CNT_TO_4300_US_SHIFT 24
630# define VC4_HDMI_CEC_CNT_TO_3900_US_MASK VC4_MASK(23, 16)
631# define VC4_HDMI_CEC_CNT_TO_3900_US_SHIFT 16
632# define VC4_HDMI_CEC_CNT_TO_3600_US_MASK VC4_MASK(15, 8)
633# define VC4_HDMI_CEC_CNT_TO_3600_US_SHIFT 8
634# define VC4_HDMI_CEC_CNT_TO_3500_US_MASK VC4_MASK(7, 0)
635# define VC4_HDMI_CEC_CNT_TO_3500_US_SHIFT 0
636
637#define VC4_HDMI_CEC_CNTRL_5 0x0f8
638# define VC4_HDMI_CEC_TX_SW_RESET BIT(27)
639# define VC4_HDMI_CEC_RX_SW_RESET BIT(26)
640# define VC4_HDMI_CEC_PAD_SW_RESET BIT(25)
641# define VC4_HDMI_CEC_MUX_TP_OUT_CEC BIT(24)
642# define VC4_HDMI_CEC_RX_CEC_INT BIT(23)
643# define VC4_HDMI_CEC_CLK_PRELOAD_MASK VC4_MASK(22, 16)
644# define VC4_HDMI_CEC_CLK_PRELOAD_SHIFT 16
645# define VC4_HDMI_CEC_CNT_TO_4700_US_MASK VC4_MASK(15, 8)
646# define VC4_HDMI_CEC_CNT_TO_4700_US_SHIFT 8
647# define VC4_HDMI_CEC_CNT_TO_4500_US_MASK VC4_MASK(7, 0)
648# define VC4_HDMI_CEC_CNT_TO_4500_US_SHIFT 0
649
650/* Transmit data, first byte is low byte of the 32-bit reg. MSB of
651 * each byte transmitted first.
652 */
653#define VC4_HDMI_CEC_TX_DATA_1 0x0fc
654#define VC4_HDMI_CEC_TX_DATA_2 0x100
655#define VC4_HDMI_CEC_TX_DATA_3 0x104
656#define VC4_HDMI_CEC_TX_DATA_4 0x108
657#define VC4_HDMI_CEC_RX_DATA_1 0x10c
658#define VC4_HDMI_CEC_RX_DATA_2 0x110
659#define VC4_HDMI_CEC_RX_DATA_3 0x114
660#define VC4_HDMI_CEC_RX_DATA_4 0x118
661
564#define VC4_HDMI_TX_PHY_RESET_CTL 0x2c0 662#define VC4_HDMI_TX_PHY_RESET_CTL 0x2c0
565 663
566#define VC4_HDMI_TX_PHY_CTL0 0x2c4 664#define VC4_HDMI_TX_PHY_CTL0 0x2c4
567# define VC4_HDMI_TX_PHY_RNG_PWRDN BIT(25) 665# define VC4_HDMI_TX_PHY_RNG_PWRDN BIT(25)
568 666
667/* Interrupt status bits */
668#define VC4_HDMI_CPU_STATUS 0x340
669#define VC4_HDMI_CPU_SET 0x344
670#define VC4_HDMI_CPU_CLEAR 0x348
671# define VC4_HDMI_CPU_CEC BIT(6)
672# define VC4_HDMI_CPU_HOTPLUG BIT(0)
673
674#define VC4_HDMI_CPU_MASK_STATUS 0x34c
675#define VC4_HDMI_CPU_MASK_SET 0x350
676#define VC4_HDMI_CPU_MASK_CLEAR 0x354
677
569#define VC4_HDMI_GCP(x) (0x400 + ((x) * 0x4)) 678#define VC4_HDMI_GCP(x) (0x400 + ((x) * 0x4))
570#define VC4_HDMI_RAM_PACKET(x) (0x400 + ((x) * 0x24)) 679#define VC4_HDMI_RAM_PACKET(x) (0x400 + ((x) * 0x24))
571#define VC4_HDMI_PACKET_STRIDE 0x24 680#define VC4_HDMI_PACKET_STRIDE 0x24
572 681
573#define VC4_HD_M_CTL 0x00c 682#define VC4_HD_M_CTL 0x00c
683/* Debug: Current receive value on the CEC pad. */
684# define VC4_HD_CECRXD BIT(9)
685/* Debug: Override CEC output to 0. */
686# define VC4_HD_CECOVR BIT(8)
574# define VC4_HD_M_REGISTER_FILE_STANDBY (3 << 6) 687# define VC4_HD_M_REGISTER_FILE_STANDBY (3 << 6)
575# define VC4_HD_M_RAM_STANDBY (3 << 4) 688# define VC4_HD_M_RAM_STANDBY (3 << 4)
576# define VC4_HD_M_SW_RST BIT(2) 689# define VC4_HD_M_SW_RST BIT(2)
diff --git a/drivers/gpu/drm/vc4/vc4_render_cl.c b/drivers/gpu/drm/vc4/vc4_render_cl.c
index 5dc19429d4ae..4a8051532f00 100644
--- a/drivers/gpu/drm/vc4/vc4_render_cl.c
+++ b/drivers/gpu/drm/vc4/vc4_render_cl.c
@@ -320,7 +320,7 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec,
320 320
321 size += xtiles * ytiles * loop_body_size; 321 size += xtiles * ytiles * loop_body_size;
322 322
323 setup->rcl = &vc4_bo_create(dev, size, true)->base; 323 setup->rcl = &vc4_bo_create(dev, size, true, VC4_BO_TYPE_RCL)->base;
324 if (IS_ERR(setup->rcl)) 324 if (IS_ERR(setup->rcl))
325 return PTR_ERR(setup->rcl); 325 return PTR_ERR(setup->rcl);
326 list_add_tail(&to_vc4_bo(&setup->rcl->base)->unref_head, 326 list_add_tail(&to_vc4_bo(&setup->rcl->base)->unref_head,
diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c
index 8c723da71f66..622cd43840b8 100644
--- a/drivers/gpu/drm/vc4/vc4_v3d.c
+++ b/drivers/gpu/drm/vc4/vc4_v3d.c
@@ -236,7 +236,8 @@ vc4_allocate_bin_bo(struct drm_device *drm)
236 INIT_LIST_HEAD(&list); 236 INIT_LIST_HEAD(&list);
237 237
238 while (true) { 238 while (true) {
239 struct vc4_bo *bo = vc4_bo_create(drm, size, true); 239 struct vc4_bo *bo = vc4_bo_create(drm, size, true,
240 VC4_BO_TYPE_BIN);
240 241
241 if (IS_ERR(bo)) { 242 if (IS_ERR(bo)) {
242 ret = PTR_ERR(bo); 243 ret = PTR_ERR(bo);
diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
index 09c1e05765fa..3a9a302247a2 100644
--- a/drivers/gpu/drm/vc4/vc4_vec.c
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
@@ -366,10 +366,8 @@ static int vc4_vec_connector_get_modes(struct drm_connector *connector)
366} 366}
367 367
368static const struct drm_connector_funcs vc4_vec_connector_funcs = { 368static const struct drm_connector_funcs vc4_vec_connector_funcs = {
369 .dpms = drm_atomic_helper_connector_dpms,
370 .detect = vc4_vec_connector_detect, 369 .detect = vc4_vec_connector_detect,
371 .fill_modes = drm_helper_probe_single_connector_modes, 370 .fill_modes = drm_helper_probe_single_connector_modes,
372 .set_property = drm_atomic_helper_connector_set_property,
373 .destroy = vc4_vec_connector_destroy, 371 .destroy = vc4_vec_connector_destroy,
374 .reset = drm_atomic_helper_connector_reset, 372 .reset = drm_atomic_helper_connector_reset,
375 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 373 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c
index ffd22e5ab43a..b6d52055a11f 100644
--- a/drivers/gpu/drm/virtio/virtgpu_display.c
+++ b/drivers/gpu/drm/virtio/virtgpu_display.c
@@ -252,7 +252,6 @@ static void virtio_gpu_conn_destroy(struct drm_connector *connector)
252} 252}
253 253
254static const struct drm_connector_funcs virtio_gpu_connector_funcs = { 254static const struct drm_connector_funcs virtio_gpu_connector_funcs = {
255 .dpms = drm_atomic_helper_connector_dpms,
256 .detect = virtio_gpu_conn_detect, 255 .detect = virtio_gpu_conn_detect,
257 .fill_modes = drm_helper_probe_single_connector_modes, 256 .fill_modes = drm_helper_probe_single_connector_modes,
258 .destroy = virtio_gpu_conn_destroy, 257 .destroy = virtio_gpu_conn_destroy,
diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c
index adcdbd0abef6..71ba455af915 100644
--- a/drivers/gpu/drm/virtio/virtgpu_plane.c
+++ b/drivers/gpu/drm/virtio/virtgpu_plane.c
@@ -298,7 +298,7 @@ struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev,
298 ret = drm_universal_plane_init(dev, plane, 1 << index, 298 ret = drm_universal_plane_init(dev, plane, 1 << index,
299 &virtio_gpu_plane_funcs, 299 &virtio_gpu_plane_funcs,
300 formats, nformats, 300 formats, nformats,
301 type, NULL); 301 NULL, type, NULL);
302 if (ret) 302 if (ret)
303 goto err_plane_init; 303 goto err_plane_init;
304 304
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
index 6391069498d6..b8a09807c5de 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
@@ -428,7 +428,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
428 0, &vmw_ldu_plane_funcs, 428 0, &vmw_ldu_plane_funcs,
429 vmw_primary_plane_formats, 429 vmw_primary_plane_formats,
430 ARRAY_SIZE(vmw_primary_plane_formats), 430 ARRAY_SIZE(vmw_primary_plane_formats),
431 DRM_PLANE_TYPE_PRIMARY, NULL); 431 NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
432 if (ret) { 432 if (ret) {
433 DRM_ERROR("Failed to initialize primary plane"); 433 DRM_ERROR("Failed to initialize primary plane");
434 goto err_free; 434 goto err_free;
@@ -443,7 +443,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
443 0, &vmw_ldu_cursor_funcs, 443 0, &vmw_ldu_cursor_funcs,
444 vmw_cursor_plane_formats, 444 vmw_cursor_plane_formats,
445 ARRAY_SIZE(vmw_cursor_plane_formats), 445 ARRAY_SIZE(vmw_cursor_plane_formats),
446 DRM_PLANE_TYPE_CURSOR, NULL); 446 NULL, DRM_PLANE_TYPE_CURSOR, NULL);
447 if (ret) { 447 if (ret) {
448 DRM_ERROR("Failed to initialize cursor plane"); 448 DRM_ERROR("Failed to initialize cursor plane");
449 drm_plane_cleanup(&ldu->base.primary); 449 drm_plane_cleanup(&ldu->base.primary);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
index 854403509216..d1552d3e0652 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
@@ -624,7 +624,7 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
624 0, &vmw_sou_plane_funcs, 624 0, &vmw_sou_plane_funcs,
625 vmw_primary_plane_formats, 625 vmw_primary_plane_formats,
626 ARRAY_SIZE(vmw_primary_plane_formats), 626 ARRAY_SIZE(vmw_primary_plane_formats),
627 DRM_PLANE_TYPE_PRIMARY, NULL); 627 NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
628 if (ret) { 628 if (ret) {
629 DRM_ERROR("Failed to initialize primary plane"); 629 DRM_ERROR("Failed to initialize primary plane");
630 goto err_free; 630 goto err_free;
@@ -639,7 +639,7 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
639 0, &vmw_sou_cursor_funcs, 639 0, &vmw_sou_cursor_funcs,
640 vmw_cursor_plane_formats, 640 vmw_cursor_plane_formats,
641 ARRAY_SIZE(vmw_cursor_plane_formats), 641 ARRAY_SIZE(vmw_cursor_plane_formats),
642 DRM_PLANE_TYPE_CURSOR, NULL); 642 NULL, DRM_PLANE_TYPE_CURSOR, NULL);
643 if (ret) { 643 if (ret) {
644 DRM_ERROR("Failed to initialize cursor plane"); 644 DRM_ERROR("Failed to initialize cursor plane");
645 drm_plane_cleanup(&sou->base.primary); 645 drm_plane_cleanup(&sou->base.primary);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
index ed9404a7f457..c4de4ad0543b 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
@@ -1475,7 +1475,7 @@ static int vmw_stdu_init(struct vmw_private *dev_priv, unsigned unit)
1475 0, &vmw_stdu_plane_funcs, 1475 0, &vmw_stdu_plane_funcs,
1476 vmw_primary_plane_formats, 1476 vmw_primary_plane_formats,
1477 ARRAY_SIZE(vmw_primary_plane_formats), 1477 ARRAY_SIZE(vmw_primary_plane_formats),
1478 DRM_PLANE_TYPE_PRIMARY, NULL); 1478 NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
1479 if (ret) { 1479 if (ret) {
1480 DRM_ERROR("Failed to initialize primary plane"); 1480 DRM_ERROR("Failed to initialize primary plane");
1481 goto err_free; 1481 goto err_free;
@@ -1490,7 +1490,7 @@ static int vmw_stdu_init(struct vmw_private *dev_priv, unsigned unit)
1490 0, &vmw_stdu_cursor_funcs, 1490 0, &vmw_stdu_cursor_funcs,
1491 vmw_cursor_plane_formats, 1491 vmw_cursor_plane_formats,
1492 ARRAY_SIZE(vmw_cursor_plane_formats), 1492 ARRAY_SIZE(vmw_cursor_plane_formats),
1493 DRM_PLANE_TYPE_CURSOR, NULL); 1493 NULL, DRM_PLANE_TYPE_CURSOR, NULL);
1494 if (ret) { 1494 if (ret) {
1495 DRM_ERROR("Failed to initialize cursor plane"); 1495 DRM_ERROR("Failed to initialize cursor plane");
1496 drm_plane_cleanup(&stdu->base.primary); 1496 drm_plane_cleanup(&stdu->base.primary);
diff --git a/drivers/gpu/drm/zte/zx_drm_drv.c b/drivers/gpu/drm/zte/zx_drm_drv.c
index c983cdfa1e34..45244828fc1f 100644
--- a/drivers/gpu/drm/zte/zx_drm_drv.c
+++ b/drivers/gpu/drm/zte/zx_drm_drv.c
@@ -62,8 +62,6 @@ static struct drm_driver zx_drm_driver = {
62 .gem_free_object_unlocked = drm_gem_cma_free_object, 62 .gem_free_object_unlocked = drm_gem_cma_free_object,
63 .gem_vm_ops = &drm_gem_cma_vm_ops, 63 .gem_vm_ops = &drm_gem_cma_vm_ops,
64 .dumb_create = drm_gem_cma_dumb_create, 64 .dumb_create = drm_gem_cma_dumb_create,
65 .dumb_map_offset = drm_gem_cma_dumb_map_offset,
66 .dumb_destroy = drm_gem_dumb_destroy,
67 .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 65 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
68 .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 66 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
69 .gem_prime_export = drm_gem_prime_export, 67 .gem_prime_export = drm_gem_prime_export,
diff --git a/drivers/gpu/drm/zte/zx_hdmi.c b/drivers/gpu/drm/zte/zx_hdmi.c
index 7e834e3eeed9..b8abb1b496ff 100644
--- a/drivers/gpu/drm/zte/zx_hdmi.c
+++ b/drivers/gpu/drm/zte/zx_hdmi.c
@@ -300,7 +300,6 @@ zx_hdmi_connector_detect(struct drm_connector *connector, bool force)
300} 300}
301 301
302static const struct drm_connector_funcs zx_hdmi_connector_funcs = { 302static const struct drm_connector_funcs zx_hdmi_connector_funcs = {
303 .dpms = drm_atomic_helper_connector_dpms,
304 .fill_modes = drm_helper_probe_single_connector_modes, 303 .fill_modes = drm_helper_probe_single_connector_modes,
305 .detect = zx_hdmi_connector_detect, 304 .detect = zx_hdmi_connector_detect,
306 .destroy = drm_connector_cleanup, 305 .destroy = drm_connector_cleanup,
diff --git a/drivers/gpu/drm/zte/zx_plane.c b/drivers/gpu/drm/zte/zx_plane.c
index 4a6252720c10..18e763493264 100644
--- a/drivers/gpu/drm/zte/zx_plane.c
+++ b/drivers/gpu/drm/zte/zx_plane.c
@@ -540,7 +540,7 @@ int zx_plane_init(struct drm_device *drm, struct zx_plane *zplane,
540 540
541 ret = drm_universal_plane_init(drm, plane, VOU_CRTC_MASK, 541 ret = drm_universal_plane_init(drm, plane, VOU_CRTC_MASK,
542 &zx_plane_funcs, formats, format_count, 542 &zx_plane_funcs, formats, format_count,
543 type, NULL); 543 NULL, type, NULL);
544 if (ret) { 544 if (ret) {
545 DRM_DEV_ERROR(dev, "failed to init universal plane: %d\n", ret); 545 DRM_DEV_ERROR(dev, "failed to init universal plane: %d\n", ret);
546 return ret; 546 return ret;
diff --git a/drivers/gpu/drm/zte/zx_tvenc.c b/drivers/gpu/drm/zte/zx_tvenc.c
index b56dc69843fc..0de1a71ca4e0 100644
--- a/drivers/gpu/drm/zte/zx_tvenc.c
+++ b/drivers/gpu/drm/zte/zx_tvenc.c
@@ -269,7 +269,6 @@ static struct drm_connector_helper_funcs zx_tvenc_connector_helper_funcs = {
269}; 269};
270 270
271static const struct drm_connector_funcs zx_tvenc_connector_funcs = { 271static const struct drm_connector_funcs zx_tvenc_connector_funcs = {
272 .dpms = drm_atomic_helper_connector_dpms,
273 .fill_modes = drm_helper_probe_single_connector_modes, 272 .fill_modes = drm_helper_probe_single_connector_modes,
274 .destroy = drm_connector_cleanup, 273 .destroy = drm_connector_cleanup,
275 .reset = drm_atomic_helper_connector_reset, 274 .reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/zte/zx_vga.c b/drivers/gpu/drm/zte/zx_vga.c
index 1e0811f775cb..3e7e33cd3dfa 100644
--- a/drivers/gpu/drm/zte/zx_vga.c
+++ b/drivers/gpu/drm/zte/zx_vga.c
@@ -138,7 +138,6 @@ zx_vga_connector_detect(struct drm_connector *connector, bool force)
138} 138}
139 139
140static const struct drm_connector_funcs zx_vga_connector_funcs = { 140static const struct drm_connector_funcs zx_vga_connector_funcs = {
141 .dpms = drm_atomic_helper_connector_dpms,
142 .fill_modes = drm_helper_probe_single_connector_modes, 141 .fill_modes = drm_helper_probe_single_connector_modes,
143 .detect = zx_vga_connector_detect, 142 .detect = zx_vga_connector_detect,
144 .destroy = drm_connector_cleanup, 143 .destroy = drm_connector_cleanup,
diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c
index a048e3ac523d..7ece0e9058c6 100644
--- a/drivers/gpu/host1x/bus.c
+++ b/drivers/gpu/host1x/bus.c
@@ -41,7 +41,6 @@ struct host1x_subdev {
41/** 41/**
42 * host1x_subdev_add() - add a new subdevice with an associated device node 42 * host1x_subdev_add() - add a new subdevice with an associated device node
43 * @device: host1x device to add the subdevice to 43 * @device: host1x device to add the subdevice to
44 * @driver: host1x driver
45 * @np: device node 44 * @np: device node
46 */ 45 */
47static int host1x_subdev_add(struct host1x_device *device, 46static int host1x_subdev_add(struct host1x_device *device,
diff --git a/drivers/staging/vboxvideo/vbox_fb.c b/drivers/staging/vboxvideo/vbox_fb.c
index 35f6d9f8c203..bf6635826159 100644
--- a/drivers/staging/vboxvideo/vbox_fb.c
+++ b/drivers/staging/vboxvideo/vbox_fb.c
@@ -317,22 +317,7 @@ static int vboxfb_create(struct drm_fb_helper *helper,
317 return 0; 317 return 0;
318} 318}
319 319
320static void vbox_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
321 u16 blue, int regno)
322{
323}
324
325static void vbox_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
326 u16 *blue, int regno)
327{
328 *red = regno;
329 *green = regno;
330 *blue = regno;
331}
332
333static struct drm_fb_helper_funcs vbox_fb_helper_funcs = { 320static struct drm_fb_helper_funcs vbox_fb_helper_funcs = {
334 .gamma_set = vbox_fb_gamma_set,
335 .gamma_get = vbox_fb_gamma_get,
336 .fb_probe = vboxfb_create, 321 .fb_probe = vboxfb_create,
337}; 322};
338 323
diff --git a/drivers/staging/vboxvideo/vbox_mode.c b/drivers/staging/vboxvideo/vbox_mode.c
index f2b85f3256fa..996da1c79158 100644
--- a/drivers/staging/vboxvideo/vbox_mode.c
+++ b/drivers/staging/vboxvideo/vbox_mode.c
@@ -134,10 +134,6 @@ static int vbox_set_view(struct drm_crtc *crtc)
134 return 0; 134 return 0;
135} 135}
136 136
137static void vbox_crtc_load_lut(struct drm_crtc *crtc)
138{
139}
140
141static void vbox_crtc_dpms(struct drm_crtc *crtc, int mode) 137static void vbox_crtc_dpms(struct drm_crtc *crtc, int mode)
142{ 138{
143 struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc); 139 struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
@@ -330,7 +326,6 @@ static const struct drm_crtc_helper_funcs vbox_crtc_helper_funcs = {
330 .mode_set = vbox_crtc_mode_set, 326 .mode_set = vbox_crtc_mode_set,
331 /* .mode_set_base = vbox_crtc_mode_set_base, */ 327 /* .mode_set_base = vbox_crtc_mode_set_base, */
332 .disable = vbox_crtc_disable, 328 .disable = vbox_crtc_disable,
333 .load_lut = vbox_crtc_load_lut,
334 .prepare = vbox_crtc_prepare, 329 .prepare = vbox_crtc_prepare,
335 .commit = vbox_crtc_commit, 330 .commit = vbox_crtc_commit,
336}; 331};
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 7cd0f303f5a3..8a5808eb5628 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -315,15 +315,9 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
315struct drm_plane_state * __must_check 315struct drm_plane_state * __must_check
316drm_atomic_get_plane_state(struct drm_atomic_state *state, 316drm_atomic_get_plane_state(struct drm_atomic_state *state,
317 struct drm_plane *plane); 317 struct drm_plane *plane);
318int drm_atomic_plane_set_property(struct drm_plane *plane,
319 struct drm_plane_state *state, struct drm_property *property,
320 uint64_t val);
321struct drm_connector_state * __must_check 318struct drm_connector_state * __must_check
322drm_atomic_get_connector_state(struct drm_atomic_state *state, 319drm_atomic_get_connector_state(struct drm_atomic_state *state,
323 struct drm_connector *connector); 320 struct drm_connector *connector);
324int drm_atomic_connector_set_property(struct drm_connector *connector,
325 struct drm_connector_state *state, struct drm_property *property,
326 uint64_t val);
327 321
328void drm_atomic_private_obj_init(struct drm_private_obj *obj, 322void drm_atomic_private_obj_init(struct drm_private_obj *obj,
329 struct drm_private_state *state, 323 struct drm_private_state *state,
@@ -551,8 +545,6 @@ int __must_check
551drm_atomic_add_affected_planes(struct drm_atomic_state *state, 545drm_atomic_add_affected_planes(struct drm_atomic_state *state,
552 struct drm_crtc *crtc); 546 struct drm_crtc *crtc);
553 547
554void drm_atomic_legacy_backoff(struct drm_atomic_state *state);
555
556void 548void
557drm_atomic_clean_old_fb(struct drm_device *dev, unsigned plane_mask, int ret); 549drm_atomic_clean_old_fb(struct drm_device *dev, unsigned plane_mask, int ret);
558 550
@@ -883,7 +875,7 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
883 * 875 *
884 * To give drivers flexibility &struct drm_crtc_state has 3 booleans to track 876 * To give drivers flexibility &struct drm_crtc_state has 3 booleans to track
885 * whether the state CRTC changed enough to need a full modeset cycle: 877 * whether the state CRTC changed enough to need a full modeset cycle:
886 * planes_changed, mode_changed and active_changed. This helper simply 878 * mode_changed, active_changed and connectors_changed. This helper simply
887 * combines these three to compute the overall need for a modeset for @state. 879 * combines these three to compute the overall need for a modeset for @state.
888 * 880 *
889 * The atomic helper code sets these booleans, but drivers can and should 881 * The atomic helper code sets these booleans, but drivers can and should
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index d6ddf5bc5fdd..d2b56cc657e9 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -124,15 +124,6 @@ int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state,
124int drm_atomic_helper_resume(struct drm_device *dev, 124int drm_atomic_helper_resume(struct drm_device *dev,
125 struct drm_atomic_state *state); 125 struct drm_atomic_state *state);
126 126
127int drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc,
128 struct drm_property *property,
129 uint64_t val);
130int drm_atomic_helper_plane_set_property(struct drm_plane *plane,
131 struct drm_property *property,
132 uint64_t val);
133int drm_atomic_helper_connector_set_property(struct drm_connector *connector,
134 struct drm_property *property,
135 uint64_t val);
136int drm_atomic_helper_page_flip(struct drm_crtc *crtc, 127int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
137 struct drm_framebuffer *fb, 128 struct drm_framebuffer *fb,
138 struct drm_pending_vblank_event *event, 129 struct drm_pending_vblank_event *event,
@@ -145,8 +136,6 @@ int drm_atomic_helper_page_flip_target(
145 uint32_t flags, 136 uint32_t flags,
146 uint32_t target, 137 uint32_t target,
147 struct drm_modeset_acquire_ctx *ctx); 138 struct drm_modeset_acquire_ctx *ctx);
148int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
149 int mode);
150struct drm_encoder * 139struct drm_encoder *
151drm_atomic_helper_best_encoder(struct drm_connector *connector); 140drm_atomic_helper_best_encoder(struct drm_connector *connector);
152 141
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 1dc94d5392e2..6522d4cbc9d9 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -268,6 +268,9 @@ void drm_bridge_enable(struct drm_bridge *bridge);
268struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel, 268struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel,
269 u32 connector_type); 269 u32 connector_type);
270void drm_panel_bridge_remove(struct drm_bridge *bridge); 270void drm_panel_bridge_remove(struct drm_bridge *bridge);
271struct drm_bridge *devm_drm_panel_bridge_add(struct device *dev,
272 struct drm_panel *panel,
273 u32 connector_type);
271#endif 274#endif
272 275
273#endif 276#endif
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 4bc088269d05..ea8da401c93c 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -382,8 +382,8 @@ struct drm_connector_funcs {
382 * implement the 4 level DPMS support on the connector any more, but 382 * implement the 4 level DPMS support on the connector any more, but
383 * instead only have an on/off "ACTIVE" property on the CRTC object. 383 * instead only have an on/off "ACTIVE" property on the CRTC object.
384 * 384 *
385 * Drivers implementing atomic modeset should use 385 * This hook is not used by atomic drivers, remapping of the legacy DPMS
386 * drm_atomic_helper_connector_dpms() to implement this hook. 386 * property is entirely handled in the DRM core.
387 * 387 *
388 * RETURNS: 388 * RETURNS:
389 * 389 *
@@ -480,11 +480,9 @@ struct drm_connector_funcs {
480 * This is the legacy entry point to update a property attached to the 480 * This is the legacy entry point to update a property attached to the
481 * connector. 481 * connector.
482 * 482 *
483 * Drivers implementing atomic modeset should use
484 * drm_atomic_helper_connector_set_property() to implement this hook.
485 *
486 * This callback is optional if the driver does not support any legacy 483 * This callback is optional if the driver does not support any legacy
487 * driver-private properties. 484 * driver-private properties. For atomic drivers it is not used because
485 * property handling is done entirely in the DRM core.
488 * 486 *
489 * RETURNS: 487 * RETURNS:
490 * 488 *
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 3a911a64c257..1a642020e306 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -358,14 +358,6 @@ struct drm_crtc_funcs {
358 * drm_crtc_enable_color_mgmt(), which then supports the legacy gamma 358 * drm_crtc_enable_color_mgmt(), which then supports the legacy gamma
359 * interface through the drm_atomic_helper_legacy_gamma_set() 359 * interface through the drm_atomic_helper_legacy_gamma_set()
360 * compatibility implementation. 360 * compatibility implementation.
361 *
362 * NOTE:
363 *
364 * Drivers that support gamma tables and also fbdev emulation through
365 * the provided helper library need to take care to fill out the gamma
366 * hooks for both. Currently there's a bit an unfortunate duplication
367 * going on, which should eventually be unified to just one set of
368 * hooks.
369 */ 361 */
370 int (*gamma_set)(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, 362 int (*gamma_set)(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
371 uint32_t size, 363 uint32_t size,
@@ -481,11 +473,9 @@ struct drm_crtc_funcs {
481 * This is the legacy entry point to update a property attached to the 473 * This is the legacy entry point to update a property attached to the
482 * CRTC. 474 * CRTC.
483 * 475 *
484 * Drivers implementing atomic modeset should use
485 * drm_atomic_helper_crtc_set_property() to implement this hook.
486 *
487 * This callback is optional if the driver does not support any legacy 476 * This callback is optional if the driver does not support any legacy
488 * driver-private properties. 477 * driver-private properties. For atomic drivers it is not used because
478 * property handling is done entirely in the DRM core.
489 * 479 *
490 * RETURNS: 480 * RETURNS:
491 * 481 *
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index 81971dc0b573..505c91354802 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -390,6 +390,11 @@ struct drm_driver {
390 */ 390 */
391 void (*master_drop)(struct drm_device *dev, struct drm_file *file_priv); 391 void (*master_drop)(struct drm_device *dev, struct drm_file *file_priv);
392 392
393 /**
394 * @debugfs_init:
395 *
396 * Allows drivers to create driver-specific debugfs files.
397 */
393 int (*debugfs_init)(struct drm_minor *minor); 398 int (*debugfs_init)(struct drm_minor *minor);
394 399
395 /** 400 /**
@@ -408,7 +413,18 @@ struct drm_driver {
408 */ 413 */
409 void (*gem_free_object_unlocked) (struct drm_gem_object *obj); 414 void (*gem_free_object_unlocked) (struct drm_gem_object *obj);
410 415
416 /**
417 * @gem_open_object:
418 *
419 * Driver hook called upon gem handle creation
420 */
411 int (*gem_open_object) (struct drm_gem_object *, struct drm_file *); 421 int (*gem_open_object) (struct drm_gem_object *, struct drm_file *);
422
423 /**
424 * @gem_close_object:
425 *
426 * Driver hook called upon gem handle release
427 */
412 void (*gem_close_object) (struct drm_gem_object *, struct drm_file *); 428 void (*gem_close_object) (struct drm_gem_object *, struct drm_file *);
413 429
414 /** 430 /**
@@ -421,19 +437,34 @@ struct drm_driver {
421 size_t size); 437 size_t size);
422 438
423 /* prime: */ 439 /* prime: */
424 /* export handle -> fd (see drm_gem_prime_handle_to_fd() helper) */ 440 /**
441 * @prime_handle_to_fd:
442 *
443 * export handle -> fd (see drm_gem_prime_handle_to_fd() helper)
444 */
425 int (*prime_handle_to_fd)(struct drm_device *dev, struct drm_file *file_priv, 445 int (*prime_handle_to_fd)(struct drm_device *dev, struct drm_file *file_priv,
426 uint32_t handle, uint32_t flags, int *prime_fd); 446 uint32_t handle, uint32_t flags, int *prime_fd);
427 /* import fd -> handle (see drm_gem_prime_fd_to_handle() helper) */ 447 /**
448 * @prime_fd_to_handle:
449 *
450 * import fd -> handle (see drm_gem_prime_fd_to_handle() helper)
451 */
428 int (*prime_fd_to_handle)(struct drm_device *dev, struct drm_file *file_priv, 452 int (*prime_fd_to_handle)(struct drm_device *dev, struct drm_file *file_priv,
429 int prime_fd, uint32_t *handle); 453 int prime_fd, uint32_t *handle);
430 /* export GEM -> dmabuf */ 454 /**
455 * @gem_prime_export:
456 *
457 * export GEM -> dmabuf
458 */
431 struct dma_buf * (*gem_prime_export)(struct drm_device *dev, 459 struct dma_buf * (*gem_prime_export)(struct drm_device *dev,
432 struct drm_gem_object *obj, int flags); 460 struct drm_gem_object *obj, int flags);
433 /* import dmabuf -> GEM */ 461 /**
462 * @gem_prime_import:
463 *
464 * import dmabuf -> GEM
465 */
434 struct drm_gem_object * (*gem_prime_import)(struct drm_device *dev, 466 struct drm_gem_object * (*gem_prime_import)(struct drm_device *dev,
435 struct dma_buf *dma_buf); 467 struct dma_buf *dma_buf);
436 /* low-level interface used by drm_gem_prime_{import,export} */
437 int (*gem_prime_pin)(struct drm_gem_object *obj); 468 int (*gem_prime_pin)(struct drm_gem_object *obj);
438 void (*gem_prime_unpin)(struct drm_gem_object *obj); 469 void (*gem_prime_unpin)(struct drm_gem_object *obj);
439 struct reservation_object * (*gem_prime_res_obj)( 470 struct reservation_object * (*gem_prime_res_obj)(
@@ -505,16 +536,25 @@ struct drm_driver {
505 struct drm_device *dev, 536 struct drm_device *dev,
506 uint32_t handle); 537 uint32_t handle);
507 538
508 /* Driver private ops for this object */ 539 /**
540 * @gem_vm_ops: Driver private ops for this object
541 */
509 const struct vm_operations_struct *gem_vm_ops; 542 const struct vm_operations_struct *gem_vm_ops;
510 543
544 /** @major: driver major number */
511 int major; 545 int major;
546 /** @minor: driver minor number */
512 int minor; 547 int minor;
548 /** @patchlevel: driver patch level */
513 int patchlevel; 549 int patchlevel;
550 /** @name: driver name */
514 char *name; 551 char *name;
552 /** @desc: driver description */
515 char *desc; 553 char *desc;
554 /** @date: driver date */
516 char *date; 555 char *date;
517 556
557 /** @driver_features: driver features */
518 u32 driver_features; 558 u32 driver_features;
519 559
520 /** 560 /**
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index a5ea6ffdfecc..33fe95927742 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -85,38 +85,6 @@ struct drm_fb_helper_surface_size {
85 */ 85 */
86struct drm_fb_helper_funcs { 86struct drm_fb_helper_funcs {
87 /** 87 /**
88 * @gamma_set:
89 *
90 * Set the given gamma LUT register on the given CRTC.
91 *
92 * This callback is optional.
93 *
94 * FIXME:
95 *
96 * This callback is functionally redundant with the core gamma table
97 * support and simply exists because the fbdev hasn't yet been
98 * refactored to use the core gamma table interfaces.
99 */
100 void (*gamma_set)(struct drm_crtc *crtc, u16 red, u16 green,
101 u16 blue, int regno);
102 /**
103 * @gamma_get:
104 *
105 * Read the given gamma LUT register on the given CRTC, used to save the
106 * current LUT when force-restoring the fbdev for e.g. kdbg.
107 *
108 * This callback is optional.
109 *
110 * FIXME:
111 *
112 * This callback is functionally redundant with the core gamma table
113 * support and simply exists because the fbdev hasn't yet been
114 * refactored to use the core gamma table interfaces.
115 */
116 void (*gamma_get)(struct drm_crtc *crtc, u16 *red, u16 *green,
117 u16 *blue, int regno);
118
119 /**
120 * @fb_probe: 88 * @fb_probe:
121 * 89 *
122 * Driver callback to allocate and initialize the fbdev info structure. 90 * Driver callback to allocate and initialize the fbdev info structure.
diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
index 4a9d231b4294..9c55c2acaa2b 100644
--- a/include/drm/drm_gem.h
+++ b/include/drm/drm_gem.h
@@ -302,6 +302,8 @@ void drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages,
302 bool dirty, bool accessed); 302 bool dirty, bool accessed);
303 303
304struct drm_gem_object *drm_gem_object_lookup(struct drm_file *filp, u32 handle); 304struct drm_gem_object *drm_gem_object_lookup(struct drm_file *filp, u32 handle);
305int drm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
306 u32 handle, u64 *offset);
305int drm_gem_dumb_destroy(struct drm_file *file, 307int drm_gem_dumb_destroy(struct drm_file *file,
306 struct drm_device *dev, 308 struct drm_device *dev,
307 uint32_t handle); 309 uint32_t handle);
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 42981711189b..1b37368416c8 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -757,6 +757,12 @@ struct drm_mode_config {
757 */ 757 */
758 bool allow_fb_modifiers; 758 bool allow_fb_modifiers;
759 759
760 /**
761 * @modifiers: Plane property to list support modifier/format
762 * combination.
763 */
764 struct drm_property *modifiers_property;
765
760 /* cursor size */ 766 /* cursor size */
761 uint32_t cursor_width, cursor_height; 767 uint32_t cursor_width, cursor_height;
762 768
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
index 06569845708c..c55cf3ff6847 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -267,22 +267,6 @@ struct drm_crtc_helper_funcs {
267 enum mode_set_atomic); 267 enum mode_set_atomic);
268 268
269 /** 269 /**
270 * @load_lut:
271 *
272 * Load a LUT prepared with the &drm_fb_helper_funcs.gamma_set vfunc.
273 *
274 * This callback is optional and is only used by the fbdev emulation
275 * helpers.
276 *
277 * FIXME:
278 *
279 * This callback is functionally redundant with the core gamma table
280 * support and simply exists because the fbdev hasn't yet been
281 * refactored to use the core gamma table interfaces.
282 */
283 void (*load_lut)(struct drm_crtc *crtc);
284
285 /**
286 * @disable: 270 * @disable:
287 * 271 *
288 * This callback should be used to disable the CRTC. With the atomic 272 * This callback should be used to disable the CRTC. With the atomic
@@ -1179,9 +1163,9 @@ struct drm_plane_helper_funcs {
1179 * - It only works for single plane updates 1163 * - It only works for single plane updates
1180 * - Async Pageflips are not supported yet 1164 * - Async Pageflips are not supported yet
1181 * - Some hw might still scan out the old buffer until the next 1165 * - Some hw might still scan out the old buffer until the next
1182 * vblank, however we let go of the fb references as soon as 1166 * vblank, however we let go of the fb references as soon as
1183 * we run this hook. For now drivers must implement their own workers 1167 * we run this hook. For now drivers must implement their own workers
1184 * for deferring if needed, until a common solution is created. 1168 * for deferring if needed, until a common solution is created.
1185 */ 1169 */
1186 void (*atomic_async_update)(struct drm_plane *plane, 1170 void (*atomic_async_update)(struct drm_plane *plane,
1187 struct drm_plane_state *new_state); 1171 struct drm_plane_state *new_state);
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 9ab3e7044812..73f90f9d057f 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -233,11 +233,9 @@ struct drm_plane_funcs {
233 * This is the legacy entry point to update a property attached to the 233 * This is the legacy entry point to update a property attached to the
234 * plane. 234 * plane.
235 * 235 *
236 * Drivers implementing atomic modeset should use
237 * drm_atomic_helper_plane_set_property() to implement this hook.
238 *
239 * This callback is optional if the driver does not support any legacy 236 * This callback is optional if the driver does not support any legacy
240 * driver-private properties. 237 * driver-private properties. For atomic drivers it is not used because
238 * property handling is done entirely in the DRM core.
241 * 239 *
242 * RETURNS: 240 * RETURNS:
243 * 241 *
@@ -392,6 +390,22 @@ struct drm_plane_funcs {
392 */ 390 */
393 void (*atomic_print_state)(struct drm_printer *p, 391 void (*atomic_print_state)(struct drm_printer *p,
394 const struct drm_plane_state *state); 392 const struct drm_plane_state *state);
393
394 /**
395 * @format_mod_supported:
396 *
397 * This optional hook is used for the DRM to determine if the given
398 * format/modifier combination is valid for the plane. This allows the
399 * DRM to generate the correct format bitmask (which formats apply to
400 * which modifier).
401 *
402 * Returns:
403 *
404 * True if the given modifier is valid for that format on the plane.
405 * False otherwise.
406 */
407 bool (*format_mod_supported)(struct drm_plane *plane, uint32_t format,
408 uint64_t modifier);
395}; 409};
396 410
397/** 411/**
@@ -487,6 +501,9 @@ struct drm_plane {
487 unsigned int format_count; 501 unsigned int format_count;
488 bool format_default; 502 bool format_default;
489 503
504 uint64_t *modifiers;
505 unsigned int modifier_count;
506
490 struct drm_crtc *crtc; 507 struct drm_crtc *crtc;
491 struct drm_framebuffer *fb; 508 struct drm_framebuffer *fb;
492 509
@@ -527,13 +544,14 @@ struct drm_plane {
527 544
528#define obj_to_plane(x) container_of(x, struct drm_plane, base) 545#define obj_to_plane(x) container_of(x, struct drm_plane, base)
529 546
530__printf(8, 9) 547__printf(9, 10)
531int drm_universal_plane_init(struct drm_device *dev, 548int drm_universal_plane_init(struct drm_device *dev,
532 struct drm_plane *plane, 549 struct drm_plane *plane,
533 uint32_t possible_crtcs, 550 uint32_t possible_crtcs,
534 const struct drm_plane_funcs *funcs, 551 const struct drm_plane_funcs *funcs,
535 const uint32_t *formats, 552 const uint32_t *formats,
536 unsigned int format_count, 553 unsigned int format_count,
554 const uint64_t *format_modifiers,
537 enum drm_plane_type type, 555 enum drm_plane_type type,
538 const char *name, ...); 556 const char *name, ...);
539int drm_plane_init(struct drm_device *dev, 557int drm_plane_init(struct drm_device *dev,
diff --git a/include/drm/drm_scdc_helper.h b/include/drm/drm_scdc_helper.h
index c25122bb490a..f92eb2094d6b 100644
--- a/include/drm/drm_scdc_helper.h
+++ b/include/drm/drm_scdc_helper.h
@@ -131,31 +131,6 @@ static inline int drm_scdc_writeb(struct i2c_adapter *adapter, u8 offset,
131 131
132bool drm_scdc_get_scrambling_status(struct i2c_adapter *adapter); 132bool drm_scdc_get_scrambling_status(struct i2c_adapter *adapter);
133 133
134/**
135 * drm_scdc_set_scrambling - enable scrambling
136 * @adapter: I2C adapter for DDC channel
137 * @enable: bool to indicate if scrambling is to be enabled/disabled
138 *
139 * Writes the TMDS config register over SCDC channel, and:
140 * enables scrambling when enable = 1
141 * disables scrambling when enable = 0
142 *
143 * Returns:
144 * True if scrambling is set/reset successfully, false otherwise.
145 */
146bool drm_scdc_set_scrambling(struct i2c_adapter *adapter, bool enable); 134bool drm_scdc_set_scrambling(struct i2c_adapter *adapter, bool enable);
147
148/**
149 * drm_scdc_set_high_tmds_clock_ratio - set TMDS clock ratio
150 * @adapter: I2C adapter for DDC channel
151 * @set: ret or reset the high clock ratio
152 *
153 * Writes to the TMDS config register over SCDC channel, and:
154 * sets TMDS clock ratio to 1/40 when set = 1
155 * sets TMDS clock ratio to 1/10 when set = 0
156 *
157 * Returns:
158 * True if write is successful, false otherwise.
159 */
160bool drm_scdc_set_high_tmds_clock_ratio(struct i2c_adapter *adapter, bool set); 135bool drm_scdc_set_high_tmds_clock_ratio(struct i2c_adapter *adapter, bool set);
161#endif 136#endif
diff --git a/include/drm/drm_simple_kms_helper.h b/include/drm/drm_simple_kms_helper.h
index 2d36538e4a17..6d9adbb46293 100644
--- a/include/drm/drm_simple_kms_helper.h
+++ b/include/drm/drm_simple_kms_helper.h
@@ -122,6 +122,7 @@ int drm_simple_display_pipe_init(struct drm_device *dev,
122 struct drm_simple_display_pipe *pipe, 122 struct drm_simple_display_pipe *pipe,
123 const struct drm_simple_display_pipe_funcs *funcs, 123 const struct drm_simple_display_pipe_funcs *funcs,
124 const uint32_t *formats, unsigned int format_count, 124 const uint32_t *formats, unsigned int format_count,
125 const uint64_t *format_modifiers,
125 struct drm_connector *connector); 126 struct drm_connector *connector);
126 127
127#endif /* __LINUX_DRM_SIMPLE_KMS_HELPER_H */ 128#endif /* __LINUX_DRM_SIMPLE_KMS_HELPER_H */
diff --git a/include/drm/tinydrm/mipi-dbi.h b/include/drm/tinydrm/mipi-dbi.h
index d137b16ee873..83346ddb9dba 100644
--- a/include/drm/tinydrm/mipi-dbi.h
+++ b/include/drm/tinydrm/mipi-dbi.h
@@ -62,11 +62,7 @@ mipi_dbi_from_tinydrm(struct tinydrm_device *tdev)
62} 62}
63 63
64int mipi_dbi_spi_init(struct spi_device *spi, struct mipi_dbi *mipi, 64int mipi_dbi_spi_init(struct spi_device *spi, struct mipi_dbi *mipi,
65 struct gpio_desc *dc, 65 struct gpio_desc *dc);
66 const struct drm_simple_display_pipe_funcs *pipe_funcs,
67 struct drm_driver *driver,
68 const struct drm_display_mode *mode,
69 unsigned int rotation);
70int mipi_dbi_init(struct device *dev, struct mipi_dbi *mipi, 66int mipi_dbi_init(struct device *dev, struct mipi_dbi *mipi,
71 const struct drm_simple_display_pipe_funcs *pipe_funcs, 67 const struct drm_simple_display_pipe_funcs *pipe_funcs,
72 struct drm_driver *driver, 68 struct drm_driver *driver,
diff --git a/include/drm/tinydrm/tinydrm.h b/include/drm/tinydrm/tinydrm.h
index 00b800df4d1b..4774fe3d4273 100644
--- a/include/drm/tinydrm/tinydrm.h
+++ b/include/drm/tinydrm/tinydrm.h
@@ -56,9 +56,7 @@ pipe_to_tinydrm(struct drm_simple_display_pipe *pipe)
56 .gem_prime_vmap = drm_gem_cma_prime_vmap, \ 56 .gem_prime_vmap = drm_gem_cma_prime_vmap, \
57 .gem_prime_vunmap = drm_gem_cma_prime_vunmap, \ 57 .gem_prime_vunmap = drm_gem_cma_prime_vunmap, \
58 .gem_prime_mmap = drm_gem_cma_prime_mmap, \ 58 .gem_prime_mmap = drm_gem_cma_prime_mmap, \
59 .dumb_create = drm_gem_cma_dumb_create, \ 59 .dumb_create = drm_gem_cma_dumb_create
60 .dumb_map_offset = drm_gem_cma_dumb_map_offset, \
61 .dumb_destroy = drm_gem_dumb_destroy
62 60
63/** 61/**
64 * TINYDRM_MODE - tinydrm display mode 62 * TINYDRM_MODE - tinydrm display mode
diff --git a/include/linux/sync_file.h b/include/linux/sync_file.h
index 5726107963b2..0ad87c434ae6 100644
--- a/include/linux/sync_file.h
+++ b/include/linux/sync_file.h
@@ -43,12 +43,13 @@ struct sync_file {
43#endif 43#endif
44 44
45 wait_queue_head_t wq; 45 wait_queue_head_t wq;
46 unsigned long flags;
46 47
47 struct dma_fence *fence; 48 struct dma_fence *fence;
48 struct dma_fence_cb cb; 49 struct dma_fence_cb cb;
49}; 50};
50 51
51#define POLL_ENABLED DMA_FENCE_FLAG_USER_BITS 52#define POLL_ENABLED 0
52 53
53struct sync_file *sync_file_create(struct dma_fence *fence); 54struct sync_file *sync_file_create(struct dma_fence *fence);
54struct dma_fence *sync_file_get_fence(int fd); 55struct dma_fence *sync_file_get_fence(int fd);
diff --git a/include/uapi/drm/armada_drm.h b/include/uapi/drm/armada_drm.h
index 72e326f9c7de..0cb932416cfe 100644
--- a/include/uapi/drm/armada_drm.h
+++ b/include/uapi/drm/armada_drm.h
@@ -23,27 +23,27 @@ extern "C" {
23 DRM_##dir(DRM_COMMAND_BASE + DRM_ARMADA_##name, struct drm_armada_##str) 23 DRM_##dir(DRM_COMMAND_BASE + DRM_ARMADA_##name, struct drm_armada_##str)
24 24
25struct drm_armada_gem_create { 25struct drm_armada_gem_create {
26 uint32_t handle; 26 __u32 handle;
27 uint32_t size; 27 __u32 size;
28}; 28};
29#define DRM_IOCTL_ARMADA_GEM_CREATE \ 29#define DRM_IOCTL_ARMADA_GEM_CREATE \
30 ARMADA_IOCTL(IOWR, GEM_CREATE, gem_create) 30 ARMADA_IOCTL(IOWR, GEM_CREATE, gem_create)
31 31
32struct drm_armada_gem_mmap { 32struct drm_armada_gem_mmap {
33 uint32_t handle; 33 __u32 handle;
34 uint32_t pad; 34 __u32 pad;
35 uint64_t offset; 35 __u64 offset;
36 uint64_t size; 36 __u64 size;
37 uint64_t addr; 37 __u64 addr;
38}; 38};
39#define DRM_IOCTL_ARMADA_GEM_MMAP \ 39#define DRM_IOCTL_ARMADA_GEM_MMAP \
40 ARMADA_IOCTL(IOWR, GEM_MMAP, gem_mmap) 40 ARMADA_IOCTL(IOWR, GEM_MMAP, gem_mmap)
41 41
42struct drm_armada_gem_pwrite { 42struct drm_armada_gem_pwrite {
43 uint64_t ptr; 43 __u64 ptr;
44 uint32_t handle; 44 __u32 handle;
45 uint32_t offset; 45 __u32 offset;
46 uint32_t size; 46 __u32 size;
47}; 47};
48#define DRM_IOCTL_ARMADA_GEM_PWRITE \ 48#define DRM_IOCTL_ARMADA_GEM_PWRITE \
49 ARMADA_IOCTL(IOW, GEM_PWRITE, gem_pwrite) 49 ARMADA_IOCTL(IOW, GEM_PWRITE, gem_pwrite)
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 7586c46f68bf..76c9101a7fc6 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -185,6 +185,8 @@ extern "C" {
185#define DRM_FORMAT_MOD_VENDOR_BROADCOM 0x07 185#define DRM_FORMAT_MOD_VENDOR_BROADCOM 0x07
186/* add more to the end as needed */ 186/* add more to the end as needed */
187 187
188#define DRM_FORMAT_RESERVED ((1ULL << 56) - 1)
189
188#define fourcc_mod_code(vendor, val) \ 190#define fourcc_mod_code(vendor, val) \
189 ((((__u64)DRM_FORMAT_MOD_VENDOR_## vendor) << 56) | (val & 0x00ffffffffffffffULL)) 191 ((((__u64)DRM_FORMAT_MOD_VENDOR_## vendor) << 56) | (val & 0x00ffffffffffffffULL))
190 192
@@ -197,6 +199,15 @@ extern "C" {
197 */ 199 */
198 200
199/* 201/*
202 * Invalid Modifier
203 *
204 * This modifier can be used as a sentinel to terminate the format modifiers
205 * list, or to initialize a variable with an invalid modifier. It might also be
206 * used to report an error back to userspace for certain APIs.
207 */
208#define DRM_FORMAT_MOD_INVALID fourcc_mod_code(NONE, DRM_FORMAT_RESERVED)
209
210/*
200 * Linear Layout 211 * Linear Layout
201 * 212 *
202 * Just plain linear layout. Note that this is different from no specifying any 213 * Just plain linear layout. Note that this is different from no specifying any
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 403339f98a92..a2bb7161f020 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -712,6 +712,56 @@ struct drm_mode_atomic {
712 __u64 user_data; 712 __u64 user_data;
713}; 713};
714 714
715struct drm_format_modifier_blob {
716#define FORMAT_BLOB_CURRENT 1
717 /* Version of this blob format */
718 u32 version;
719
720 /* Flags */
721 u32 flags;
722
723 /* Number of fourcc formats supported */
724 u32 count_formats;
725
726 /* Where in this blob the formats exist (in bytes) */
727 u32 formats_offset;
728
729 /* Number of drm_format_modifiers */
730 u32 count_modifiers;
731
732 /* Where in this blob the modifiers exist (in bytes) */
733 u32 modifiers_offset;
734
735 /* u32 formats[] */
736 /* struct drm_format_modifier modifiers[] */
737};
738
739struct drm_format_modifier {
740 /* Bitmask of formats in get_plane format list this info applies to. The
741 * offset allows a sliding window of which 64 formats (bits).
742 *
743 * Some examples:
744 * In today's world with < 65 formats, and formats 0, and 2 are
745 * supported
746 * 0x0000000000000005
747 * ^-offset = 0, formats = 5
748 *
749 * If the number formats grew to 128, and formats 98-102 are
750 * supported with the modifier:
751 *
752 * 0x0000003c00000000 0000000000000000
753 * ^
754 * |__offset = 64, formats = 0x3c00000000
755 *
756 */
757 __u64 formats;
758 __u32 offset;
759 __u32 pad;
760
761 /* The modifier that applies to the >get_plane format list bitmask. */
762 __u64 modifier;
763};
764
715/** 765/**
716 * Create a new 'blob' data property, copying length bytes from data pointer, 766 * Create a new 'blob' data property, copying length bytes from data pointer,
717 * and returning new blob ID. 767 * and returning new blob ID.
diff --git a/include/uapi/drm/vc4_drm.h b/include/uapi/drm/vc4_drm.h
index 6ac4c5c014cb..551628e571f9 100644
--- a/include/uapi/drm/vc4_drm.h
+++ b/include/uapi/drm/vc4_drm.h
@@ -40,6 +40,7 @@ extern "C" {
40#define DRM_VC4_GET_PARAM 0x07 40#define DRM_VC4_GET_PARAM 0x07
41#define DRM_VC4_SET_TILING 0x08 41#define DRM_VC4_SET_TILING 0x08
42#define DRM_VC4_GET_TILING 0x09 42#define DRM_VC4_GET_TILING 0x09
43#define DRM_VC4_LABEL_BO 0x0a
43 44
44#define DRM_IOCTL_VC4_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SUBMIT_CL, struct drm_vc4_submit_cl) 45#define DRM_IOCTL_VC4_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SUBMIT_CL, struct drm_vc4_submit_cl)
45#define DRM_IOCTL_VC4_WAIT_SEQNO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_WAIT_SEQNO, struct drm_vc4_wait_seqno) 46#define DRM_IOCTL_VC4_WAIT_SEQNO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_WAIT_SEQNO, struct drm_vc4_wait_seqno)
@@ -51,6 +52,7 @@ extern "C" {
51#define DRM_IOCTL_VC4_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_PARAM, struct drm_vc4_get_param) 52#define DRM_IOCTL_VC4_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_PARAM, struct drm_vc4_get_param)
52#define DRM_IOCTL_VC4_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SET_TILING, struct drm_vc4_set_tiling) 53#define DRM_IOCTL_VC4_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SET_TILING, struct drm_vc4_set_tiling)
53#define DRM_IOCTL_VC4_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_TILING, struct drm_vc4_get_tiling) 54#define DRM_IOCTL_VC4_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_TILING, struct drm_vc4_get_tiling)
55#define DRM_IOCTL_VC4_LABEL_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_LABEL_BO, struct drm_vc4_label_bo)
54 56
55struct drm_vc4_submit_rcl_surface { 57struct drm_vc4_submit_rcl_surface {
56 __u32 hindex; /* Handle index, or ~0 if not present. */ 58 __u32 hindex; /* Handle index, or ~0 if not present. */
@@ -311,6 +313,15 @@ struct drm_vc4_set_tiling {
311 __u64 modifier; 313 __u64 modifier;
312}; 314};
313 315
316/**
317 * struct drm_vc4_label_bo - Attach a name to a BO for debug purposes.
318 */
319struct drm_vc4_label_bo {
320 __u32 handle;
321 __u32 len;
322 __u64 name;
323};
324
314#if defined(__cplusplus) 325#if defined(__cplusplus)
315} 326}
316#endif 327#endif