aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRodrigo Vivi <rodrigo.vivi@intel.com>2024-06-26 18:22:52 -0400
committerRodrigo Vivi <rodrigo.vivi@intel.com>2024-06-26 18:22:52 -0400
commit8664e7637388c013f4e953371d023ec7c2d84c8d (patch)
tree49eecfd0934c909dff42c54c7850cc02c63f650f
parent33991ae8f40a8245f68e8e442766bf9072eaaa2a (diff)
parent541b1b0a8fc235bca355921eb7f3f59a8efa3e9a (diff)
Merge drm/drm-next into drm-xe-next
Need to sync some header include that propagated through drm-intel-next. v2: After some changes in drm/drm-next Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
-rw-r--r--Documentation/devicetree/bindings/display/panel/boe,tv101wum-nl6.yaml2
-rw-r--r--Documentation/devicetree/bindings/display/panel/himax,hx83102.yaml77
-rw-r--r--Documentation/devicetree/bindings/display/panel/panel-edp-legacy.yaml117
-rw-r--r--Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml30
-rw-r--r--Documentation/devicetree/bindings/display/panel/panel-simple-lvds-dual-ports.yaml6
-rw-r--r--Documentation/devicetree/bindings/display/panel/panel-simple.yaml58
-rw-r--r--Documentation/devicetree/bindings/display/panel/samsung,atna33xc20.yaml95
-rw-r--r--Documentation/devicetree/bindings/display/panel/sharp,ld-d5116z01b.yaml30
-rw-r--r--Documentation/devicetree/bindings/display/panel/wl-355608-a8.yaml60
-rw-r--r--Documentation/devicetree/bindings/display/rockchip/rockchip,dw-mipi-dsi.yaml2
-rw-r--r--Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml5
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.yaml6
-rw-r--r--Documentation/gpu/drm-internals.rst10
-rw-r--r--Documentation/gpu/drm-kms-helpers.rst12
-rw-r--r--Documentation/gpu/i915.rst5
-rw-r--r--Documentation/gpu/kms-properties.csv2
-rw-r--r--Documentation/gpu/todo.rst70
-rw-r--r--MAINTAINERS11
-rw-r--r--arch/x86/kernel/early-quirks.c85
-rw-r--r--drivers/accel/ivpu/Makefile11
-rw-r--r--drivers/accel/ivpu/ivpu_debugfs.c89
-rw-r--r--drivers/accel/ivpu/ivpu_drv.c113
-rw-r--r--drivers/accel/ivpu/ivpu_drv.h62
-rw-r--r--drivers/accel/ivpu/ivpu_fw.c61
-rw-r--r--drivers/accel/ivpu/ivpu_fw.h4
-rw-r--r--drivers/accel/ivpu/ivpu_gem.h11
-rw-r--r--drivers/accel/ivpu/ivpu_hw.c331
-rw-r--r--drivers/accel/ivpu/ivpu_hw.h199
-rw-r--r--drivers/accel/ivpu/ivpu_hw_37xx.c1065
-rw-r--r--drivers/accel/ivpu/ivpu_hw_37xx_reg.h72
-rw-r--r--drivers/accel/ivpu/ivpu_hw_40xx.c1250
-rw-r--r--drivers/accel/ivpu/ivpu_hw_40xx_reg.h94
-rw-r--r--drivers/accel/ivpu/ivpu_hw_btrs.c905
-rw-r--r--drivers/accel/ivpu/ivpu_hw_btrs.h50
-rw-r--r--drivers/accel/ivpu/ivpu_hw_btrs_lnl_reg.h108
-rw-r--r--drivers/accel/ivpu/ivpu_hw_btrs_mtl_reg.h83
-rw-r--r--drivers/accel/ivpu/ivpu_hw_ip.c1174
-rw-r--r--drivers/accel/ivpu/ivpu_hw_ip.h36
-rw-r--r--drivers/accel/ivpu/ivpu_ipc.c20
-rw-r--r--drivers/accel/ivpu/ivpu_ipc.h8
-rw-r--r--drivers/accel/ivpu/ivpu_job.c324
-rw-r--r--drivers/accel/ivpu/ivpu_job.h6
-rw-r--r--drivers/accel/ivpu/ivpu_jsm_msg.c311
-rw-r--r--drivers/accel/ivpu/ivpu_jsm_msg.h22
-rw-r--r--drivers/accel/ivpu/ivpu_mmu.c22
-rw-r--r--drivers/accel/ivpu/ivpu_mmu_context.c86
-rw-r--r--drivers/accel/ivpu/ivpu_mmu_context.h2
-rw-r--r--drivers/accel/ivpu/ivpu_ms.c309
-rw-r--r--drivers/accel/ivpu/ivpu_ms.h36
-rw-r--r--drivers/accel/ivpu/ivpu_pm.c111
-rw-r--r--drivers/accel/ivpu/ivpu_pm.h10
-rw-r--r--drivers/accel/ivpu/ivpu_sysfs.c58
-rw-r--r--drivers/accel/ivpu/ivpu_sysfs.h13
-rw-r--r--drivers/accel/ivpu/vpu_boot_api.h16
-rw-r--r--drivers/accel/ivpu/vpu_jsm_api.h14
-rw-r--r--drivers/char/agp/amd64-agp.c1
-rw-r--r--drivers/char/agp/intel-agp.c3
-rw-r--r--drivers/char/agp/intel-gtt.c3
-rw-r--r--drivers/char/agp/sis-agp.c1
-rw-r--r--drivers/char/agp/via-agp.c1
-rw-r--r--drivers/dma-buf/dma-fence-array.c10
-rw-r--r--drivers/dma-buf/dma-heap.c4
-rw-r--r--drivers/dma-buf/dma-resv.c7
-rw-r--r--drivers/dma-buf/heaps/cma_heap.c4
-rw-r--r--drivers/dma-buf/heaps/system_heap.c4
-rw-r--r--drivers/gpu/drm/Kconfig16
-rw-r--r--drivers/gpu/drm/Makefile6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c16
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c8
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v10_0.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v11_0.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v6_0.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v8_0.c4
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c2
-rw-r--r--drivers/gpu/drm/arm/display/komeda/komeda_crtc.c49
-rw-r--r--drivers/gpu/drm/arm/display/komeda/komeda_drv.c8
-rw-r--r--drivers/gpu/drm/arm/display/komeda/komeda_kms.h1
-rw-r--r--drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c4
-rw-r--r--drivers/gpu/drm/ast/ast_drv.c4
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/Kconfig2
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c172
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c105
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h132
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c369
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7511_drv.c5
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix-anx6345.c20
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c28
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix_dp_core.c172
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix_dp_core.h22
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c119
-rw-r--r--drivers/gpu/drm/bridge/analogix/anx7625.c36
-rw-r--r--drivers/gpu/drm/bridge/analogix/anx7625.h10
-rw-r--r--drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c5
-rw-r--r--drivers/gpu/drm/bridge/imx/imx-ldb-helper.c5
-rw-r--r--drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c5
-rw-r--r--drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c5
-rw-r--r--drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c5
-rw-r--r--drivers/gpu/drm/bridge/ite-it6505.c80
-rw-r--r--drivers/gpu/drm/bridge/lontium-lt9611.c1
-rw-r--r--drivers/gpu/drm/bridge/lontium-lt9611uxc.c6
-rw-r--r--drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c5
-rw-r--r--drivers/gpu/drm/bridge/nxp-ptn3460.c5
-rw-r--r--drivers/gpu/drm/bridge/panel.c5
-rw-r--r--drivers/gpu/drm/bridge/samsung-dsim.c25
-rw-r--r--drivers/gpu/drm/bridge/sii902x.c46
-rw-r--r--drivers/gpu/drm/bridge/sii9234.c1
-rw-r--r--drivers/gpu/drm/bridge/sil-sii8620.c1
-rw-r--r--drivers/gpu/drm/bridge/simple-bridge.c18
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c5
-rw-r--r--drivers/gpu/drm/bridge/tc358767.c27
-rw-r--r--drivers/gpu/drm/bridge/ti-tfp410.c5
-rw-r--r--drivers/gpu/drm/ci/build-igt.sh41
-rw-r--r--drivers/gpu/drm/ci/build.sh10
-rw-r--r--drivers/gpu/drm/ci/build.yml1
-rw-r--r--drivers/gpu/drm/ci/container.yml12
-rw-r--r--drivers/gpu/drm/ci/gitlab-ci.yml47
-rwxr-xr-xdrivers/gpu/drm/ci/igt_runner.sh15
-rw-r--r--drivers/gpu/drm/ci/image-tags.yml4
-rwxr-xr-xdrivers/gpu/drm/ci/lava-submit.sh4
-rw-r--r--drivers/gpu/drm/ci/test.yml41
-rw-r--r--drivers/gpu/drm/ci/testlist.txt2761
-rw-r--r--drivers/gpu/drm/ci/x86_64.config1
-rw-r--r--drivers/gpu/drm/ci/xfails/amdgpu-stoney-fails.txt41
-rw-r--r--drivers/gpu/drm/ci/xfails/amdgpu-stoney-flakes.txt7
-rw-r--r--drivers/gpu/drm/ci/xfails/amdgpu-stoney-skips.txt33
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-amly-fails.txt31
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-amly-flakes.txt9
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-amly-skips.txt22
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-apl-fails.txt46
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-apl-flakes.txt6
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-apl-skips.txt26
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-cml-fails.txt38
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-cml-flakes.txt6
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-cml-skips.txt23
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-glk-fails.txt41
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-glk-flakes.txt7
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-glk-skips.txt26
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-kbl-fails.txt42
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-kbl-flakes.txt7
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-kbl-skips.txt36
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-tgl-fails.txt77
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-tgl-skips.txt28
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-whl-fails.txt63
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-whl-flakes.txt6
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-whl-skips.txt22
-rw-r--r--drivers/gpu/drm/ci/xfails/mediatek-mt8173-fails.txt30
-rw-r--r--drivers/gpu/drm/ci/xfails/mediatek-mt8173-flakes.txt11
-rw-r--r--drivers/gpu/drm/ci/xfails/mediatek-mt8173-skips.txt16
-rw-r--r--drivers/gpu/drm/ci/xfails/mediatek-mt8183-fails.txt21
-rw-r--r--drivers/gpu/drm/ci/xfails/mediatek-mt8183-skips.txt18
-rw-r--r--drivers/gpu/drm/ci/xfails/meson-g12b-fails.txt24
-rw-r--r--drivers/gpu/drm/ci/xfails/meson-g12b-skips.txt18
-rw-r--r--drivers/gpu/drm/ci/xfails/msm-apq8016-fails.txt26
-rw-r--r--drivers/gpu/drm/ci/xfails/msm-apq8016-skips.txt15
-rw-r--r--drivers/gpu/drm/ci/xfails/msm-apq8096-fails.txt8
-rw-r--r--drivers/gpu/drm/ci/xfails/msm-apq8096-flakes.txt6
-rw-r--r--drivers/gpu/drm/ci/xfails/msm-apq8096-skips.txt26
-rw-r--r--drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-kingoftown-fails.txt175
-rw-r--r--drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-kingoftown-flakes.txt8
-rw-r--r--drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-kingoftown-skips.txt19
-rw-r--r--drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-lazor-limozeen-fails.txt175
-rw-r--r--drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-lazor-limozeen-flakes.txt6
-rw-r--r--drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-lazor-limozeen-skips.txt16
-rw-r--r--drivers/gpu/drm/ci/xfails/msm-sdm845-fails.txt38
-rw-r--r--drivers/gpu/drm/ci/xfails/msm-sdm845-flakes.txt25
-rw-r--r--drivers/gpu/drm/ci/xfails/msm-sdm845-skips.txt19
-rw-r--r--drivers/gpu/drm/ci/xfails/rockchip-rk3288-fails.txt62
-rw-r--r--drivers/gpu/drm/ci/xfails/rockchip-rk3288-skips.txt21
-rw-r--r--drivers/gpu/drm/ci/xfails/rockchip-rk3399-fails.txt83
-rw-r--r--drivers/gpu/drm/ci/xfails/rockchip-rk3399-flakes.txt13
-rw-r--r--drivers/gpu/drm/ci/xfails/rockchip-rk3399-skips.txt19
-rwxr-xr-xdrivers/gpu/drm/ci/xfails/update-xfails.py4
-rw-r--r--drivers/gpu/drm/ci/xfails/virtio_gpu-none-fails.txt94
-rw-r--r--drivers/gpu/drm/ci/xfails/virtio_gpu-none-skips.txt20
-rw-r--r--drivers/gpu/drm/ci/xfails/vkms-none-fails.txt57
-rw-r--r--drivers/gpu/drm/ci/xfails/vkms-none-flakes.txt69
-rw-r--r--drivers/gpu/drm/ci/xfails/vkms-none-skips.txt119
-rw-r--r--drivers/gpu/drm/display/Kconfig7
-rw-r--r--drivers/gpu/drm/display/Makefile2
-rw-r--r--drivers/gpu/drm/display/drm_hdmi_helper.c61
-rw-r--r--drivers/gpu/drm/display/drm_hdmi_state_helper.c752
-rw-r--r--drivers/gpu/drm/drm_atomic.c11
-rw-r--r--drivers/gpu/drm/drm_atomic_uapi.c4
-rw-r--r--drivers/gpu/drm/drm_bridge.c42
-rw-r--r--drivers/gpu/drm/drm_bridge_connector.c107
-rw-r--r--drivers/gpu/drm/drm_connector.c201
-rw-r--r--drivers/gpu/drm/drm_crtc_internal.h2
-rw-r--r--drivers/gpu/drm/drm_debugfs.c158
-rw-r--r--drivers/gpu/drm/drm_drv.c6
-rw-r--r--drivers/gpu/drm/drm_edid.c61
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c11
-rw-r--r--drivers/gpu/drm/drm_fbdev_dma.c66
-rw-r--r--drivers/gpu/drm/drm_fbdev_shmem.c317
-rw-r--r--drivers/gpu/drm/drm_fbdev_ttm.c (renamed from drivers/gpu/drm/drm_fbdev_generic.c)80
-rw-r--r--drivers/gpu/drm/drm_ioctl.c5
-rw-r--r--drivers/gpu/drm/drm_mipi_dbi.c77
-rw-r--r--drivers/gpu/drm/drm_mipi_dsi.c322
-rw-r--r--drivers/gpu/drm/drm_mm.c35
-rw-r--r--drivers/gpu/drm/drm_mode_object.c1
-rw-r--r--drivers/gpu/drm/drm_modes.c5
-rw-r--r--drivers/gpu/drm/drm_panel_orientation_quirks.c1
-rw-r--r--drivers/gpu/drm/drm_panic.c284
-rw-r--r--drivers/gpu/drm/drm_print.c72
-rw-r--r--drivers/gpu/drm/drm_probe_helper.c13
-rw-r--r--drivers/gpu/drm/drm_simple_kms_helper.c1
-rw-r--r--drivers/gpu/drm/drm_sysfs.c24
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_dp.c2
-rw-r--r--drivers/gpu/drm/gud/gud_drv.c5
-rw-r--r--drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c4
-rw-r--r--drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c17
-rw-r--r--drivers/gpu/drm/hisilicon/kirin/Kconfig2
-rw-r--r--drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c11
-rw-r--r--drivers/gpu/drm/hisilicon/kirin/dw_dsi_reg.h2
-rw-r--r--drivers/gpu/drm/hisilicon/kirin/kirin_ade_reg.h2
-rw-r--r--drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c4
-rw-r--r--drivers/gpu/drm/hyperv/hyperv_drm_drv.c4
-rw-r--r--drivers/gpu/drm/i2c/tda998x_drv.c19
-rw-r--r--drivers/gpu/drm/i915/Kconfig1
-rw-r--r--drivers/gpu/drm/i915/Makefile27
-rw-r--r--drivers/gpu/drm/i915/display/dvo_ns2501.c1
-rw-r--r--drivers/gpu/drm/i915/display/g4x_dp.c37
-rw-r--r--drivers/gpu/drm/i915/display/i9xx_plane.c104
-rw-r--r--drivers/gpu/drm/i915/display/i9xx_plane_regs.h112
-rw-r--r--drivers/gpu/drm/i915/display/i9xx_wm.c114
-rw-r--r--drivers/gpu/drm/i915/display/icl_dsi.c46
-rw-r--r--drivers/gpu/drm/i915/display/intel_alpm.c414
-rw-r--r--drivers/gpu/drm/i915/display/intel_alpm.h27
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic.c1
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic_plane.c62
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic_plane.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_audio.c17
-rw-r--r--drivers/gpu/drm/i915/display/intel_audio_regs.h3
-rw-r--r--drivers/gpu/drm/i915/display/intel_bios.c243
-rw-r--r--drivers/gpu/drm/i915/display/intel_bw.c65
-rw-r--r--drivers/gpu/drm/i915/display/intel_cdclk.c130
-rw-r--r--drivers/gpu/drm/i915/display/intel_color.c143
-rw-r--r--drivers/gpu/drm/i915/display/intel_color.h4
-rw-r--r--drivers/gpu/drm/i915/display/intel_color_regs.h5
-rw-r--r--drivers/gpu/drm/i915/display/intel_crt.c50
-rw-r--r--drivers/gpu/drm/i915/display/intel_crtc.c15
-rw-r--r--drivers/gpu/drm/i915/display/intel_crtc_state_dump.c15
-rw-r--r--drivers/gpu/drm/i915/display/intel_cursor.c102
-rw-r--r--drivers/gpu/drm/i915/display/intel_cursor_regs.h112
-rw-r--r--drivers/gpu/drm/i915/display/intel_cx0_phy.c368
-rw-r--r--drivers/gpu/drm/i915/display/intel_cx0_phy.h8
-rw-r--r--drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h48
-rw-r--r--drivers/gpu/drm/i915/display/intel_ddi.c129
-rw-r--r--drivers/gpu/drm/i915/display/intel_display.c823
-rw-r--r--drivers/gpu/drm/i915/display/intel_display.h13
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_debugfs.c12
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_device.c937
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_device.h89
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_irq.c46
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_limits.h21
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_params.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_power.c20
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_power_well.c14
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_types.h87
-rw-r--r--drivers/gpu/drm/i915/display/intel_dkl_phy.c1
-rw-r--r--drivers/gpu/drm/i915/display/intel_dmc.c21
-rw-r--r--drivers/gpu/drm/i915/display/intel_dmc.h6
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp.c414
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp.h24
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c149
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_aux_regs.h18
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_hdcp.c5
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_link_training.c538
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_link_training.h8
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_mst.c84
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpll.c63
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpll_mgr.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpt.c9
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpt.h5
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpt_common.c1
-rw-r--r--drivers/gpu/drm/i915/display/intel_drrs.c8
-rw-r--r--drivers/gpu/drm/i915/display/intel_dsb.c31
-rw-r--r--drivers/gpu/drm/i915/display/intel_dsb.h9
-rw-r--r--drivers/gpu/drm/i915/display/intel_dsi_vbt.c6
-rw-r--r--drivers/gpu/drm/i915/display/intel_dvo.c5
-rw-r--r--drivers/gpu/drm/i915/display/intel_encoder.c39
-rw-r--r--drivers/gpu/drm/i915/display/intel_encoder.h16
-rw-r--r--drivers/gpu/drm/i915/display/intel_fb.c45
-rw-r--r--drivers/gpu/drm/i915/display/intel_fb_pin.c75
-rw-r--r--drivers/gpu/drm/i915/display/intel_fb_pin.h12
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbc.c38
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbdev.c40
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbdev_fb.c6
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbdev_fb.h4
-rw-r--r--drivers/gpu/drm/i915/display/intel_fdi.c15
-rw-r--r--drivers/gpu/drm/i915/display/intel_fifo_underrun.c13
-rw-r--r--drivers/gpu/drm/i915/display/intel_frontbuffer.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdcp.c27
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdcp_gsc.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdmi.c41
-rw-r--r--drivers/gpu/drm/i915/display/intel_hotplug_irq.c12
-rw-r--r--drivers/gpu/drm/i915/display/intel_lpe_audio.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_lspcon.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_lvds.c31
-rw-r--r--drivers/gpu/drm/i915/display/intel_modeset_setup.c60
-rw-r--r--drivers/gpu/drm/i915/display/intel_modeset_verify.c8
-rw-r--r--drivers/gpu/drm/i915/display/intel_overlay.c21
-rw-r--r--drivers/gpu/drm/i915/display/intel_overlay.h6
-rw-r--r--drivers/gpu/drm/i915/display/intel_panel.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_pch_display.c21
-rw-r--r--drivers/gpu/drm/i915/display/intel_pipe_crc.c21
-rw-r--r--drivers/gpu/drm/i915/display/intel_pipe_crc_regs.h152
-rw-r--r--drivers/gpu/drm/i915/display/intel_pps.c32
-rw-r--r--drivers/gpu/drm/i915/display/intel_pps_regs.h16
-rw-r--r--drivers/gpu/drm/i915/display/intel_psr.c969
-rw-r--r--drivers/gpu/drm/i915/display/intel_psr_regs.h93
-rw-r--r--drivers/gpu/drm/i915/display/intel_sprite.c1
-rw-r--r--drivers/gpu/drm/i915/display/intel_sprite_regs.h242
-rw-r--r--drivers/gpu/drm/i915/display/intel_sprite_uapi.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_tdf.h25
-rw-r--r--drivers/gpu/drm/i915/display/intel_vblank.c169
-rw-r--r--drivers/gpu/drm/i915/display/intel_vblank.h5
-rw-r--r--drivers/gpu/drm/i915/display/intel_vbt_defs.h729
-rw-r--r--drivers/gpu/drm/i915/display/intel_vdsc.c19
-rw-r--r--drivers/gpu/drm/i915/display/intel_vdsc_regs.h6
-rw-r--r--drivers/gpu/drm/i915/display/intel_vrr.c182
-rw-r--r--drivers/gpu/drm/i915/display/intel_vrr_regs.h127
-rw-r--r--drivers/gpu/drm/i915/display/skl_universal_plane.c206
-rw-r--r--drivers/gpu/drm/i915/display/skl_universal_plane.h2
-rw-r--r--drivers/gpu/drm/i915/display/skl_universal_plane_regs.h442
-rw-r--r--drivers/gpu/drm/i915/display/skl_watermark.c134
-rw-r--r--drivers/gpu/drm/i915/display/skl_watermark.h13
-rw-r--r--drivers/gpu/drm/i915/display/skl_watermark_regs.h83
-rw-r--r--drivers/gpu/drm/i915/display/vlv_dsi.c3
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_stolen.c2
-rw-r--r--drivers/gpu/drm/i915/gt/intel_ggtt.c4
-rw-r--r--drivers/gpu/drm/i915/gt/intel_ggtt_gmch.c2
-rw-r--r--drivers/gpu/drm/i915/gt/intel_gt.c2
-rw-r--r--drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c3
-rw-r--r--drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c1
-rw-r--r--drivers/gpu/drm/i915/gt/intel_reset.c2
-rw-r--r--drivers/gpu/drm/i915/gt/intel_rps.c13
-rw-r--r--drivers/gpu/drm/i915/gt/selftest_context.c2
-rw-r--r--drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c4
-rw-r--r--drivers/gpu/drm/i915/gvt/cmd_parser.c15
-rw-r--r--drivers/gpu/drm/i915/gvt/display.c73
-rw-r--r--drivers/gpu/drm/i915/gvt/dmabuf.c3
-rw-r--r--drivers/gpu/drm/i915/gvt/fb_decoder.c23
-rw-r--r--drivers/gpu/drm/i915/gvt/handlers.c163
-rw-r--r--drivers/gpu/drm/i915/gvt/kvmgt.c1
-rw-r--r--drivers/gpu/drm/i915/gvt/reg.h3
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h11
-rw-r--r--drivers/gpu/drm/i915/i915_gpu_error.c5
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c5
-rw-r--r--drivers/gpu/drm/i915/i915_pci.c151
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h927
-rw-r--r--drivers/gpu/drm/i915/i915_suspend.c48
-rw-r--r--drivers/gpu/drm/i915/intel_clock_gating.c14
-rw-r--r--drivers/gpu/drm/i915/intel_device_info.c92
-rw-r--r--drivers/gpu/drm/i915/intel_gvt_mmio_table.c353
-rw-r--r--drivers/gpu/drm/i915/intel_pci_config.h2
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp_tee.c4
-rw-r--r--drivers/gpu/drm/i915/soc/intel_dram.c216
-rw-r--r--drivers/gpu/drm/i915/soc/intel_dram.h1
-rw-r--r--drivers/gpu/drm/i915/soc/intel_gmch.c2
-rw-r--r--drivers/gpu/drm/i915/soc/intel_pch.c4
-rw-r--r--drivers/gpu/drm/imx/ipuv3/imx-ldb.c24
-rw-r--r--drivers/gpu/drm/imx/ipuv3/imx-tve.c14
-rw-r--r--drivers/gpu/drm/imx/lcdc/imx-lcdc.c4
-rw-r--r--drivers/gpu/drm/ingenic/ingenic-drm-drv.c4
-rw-r--r--drivers/gpu/drm/loongson/Kconfig1
-rw-r--r--drivers/gpu/drm/loongson/lsdc_drv.c4
-rw-r--r--drivers/gpu/drm/loongson/lsdc_output_7a1000.c15
-rw-r--r--drivers/gpu/drm/loongson/lsdc_output_7a2000.c15
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_drv.c4
-rw-r--r--drivers/gpu/drm/mediatek/mtk_hdmi.c11
-rw-r--r--drivers/gpu/drm/meson/meson_plane.c17
-rw-r--r--drivers/gpu/drm/mgag200/Kconfig18
-rw-r--r--drivers/gpu/drm/mgag200/Makefile5
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_bmc.c107
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_ddc.c179
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_ddc.h11
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_drv.c27
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_drv.h46
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_g200.c46
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_g200eh.c46
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_g200eh3.c46
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_g200er.c46
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_g200ev.c46
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_g200ew3.c46
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_g200se.c46
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_g200wb.c46
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_i2c.c129
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_mode.c35
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_vga.c72
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/disp.c8
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/head.c8
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_chan.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dmem.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_exec.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.c30
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.h2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gem.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_sched.h4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_uvmm.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c362
-rw-r--r--drivers/gpu/drm/omapdrm/Kconfig2
-rw-r--r--drivers/gpu/drm/omapdrm/omap_gem.c4
-rw-r--r--drivers/gpu/drm/panel/Kconfig9
-rw-r--r--drivers/gpu/drm/panel/Makefile1
-rw-r--r--drivers/gpu/drm/panel/panel-abt-y030xx067a.c1
-rw-r--r--drivers/gpu/drm/panel/panel-auo-a030jtn01.c1
-rw-r--r--drivers/gpu/drm/panel/panel-boe-himax8279d.c40
-rw-r--r--drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c2757
-rw-r--r--drivers/gpu/drm/panel/panel-edp.c260
-rw-r--r--drivers/gpu/drm/panel/panel-himax-hx83102.c706
-rw-r--r--drivers/gpu/drm/panel/panel-himax-hx8394.c3
-rw-r--r--drivers/gpu/drm/panel/panel-ilitek-ili9341.c7
-rw-r--r--drivers/gpu/drm/panel/panel-ilitek-ili9882t.c830
-rw-r--r--drivers/gpu/drm/panel/panel-innolux-ej030na.c1
-rw-r--r--drivers/gpu/drm/panel/panel-innolux-p079zca.c332
-rw-r--r--drivers/gpu/drm/panel/panel-jdi-lt070me05000.c35
-rw-r--r--drivers/gpu/drm/panel/panel-khadas-ts050.c39
-rw-r--r--drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c48
-rw-r--r--drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c28
-rw-r--r--drivers/gpu/drm/panel/panel-leadtek-ltk500hd1829.c28
-rw-r--r--drivers/gpu/drm/panel/panel-lg-sw43408.c74
-rw-r--r--drivers/gpu/drm/panel/panel-newvision-nv3052c.c226
-rw-r--r--drivers/gpu/drm/panel/panel-novatek-nt36672a.c29
-rw-r--r--drivers/gpu/drm/panel/panel-novatek-nt36672e.c647
-rw-r--r--drivers/gpu/drm/panel/panel-novatek-nt39016.c1
-rw-r--r--drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c44
-rw-r--r--drivers/gpu/drm/panel/panel-orisetech-ota5601a.c1
-rw-r--r--drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c41
-rw-r--r--drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c47
-rw-r--r--drivers/gpu/drm/panel/panel-raydium-rm67191.c26
-rw-r--r--drivers/gpu/drm/panel/panel-raydium-rm692e5.c10
-rw-r--r--drivers/gpu/drm/panel/panel-samsung-atna33xc20.c36
-rw-r--r--drivers/gpu/drm/panel/panel-seiko-43wvf1g.c49
-rw-r--r--drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c63
-rw-r--r--drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c24
-rw-r--r--drivers/gpu/drm/panel/panel-simple.c185
-rw-r--r--drivers/gpu/drm/panel/panel-sitronix-st7703.c35
-rw-r--r--drivers/gpu/drm/panel/panel-sony-acx565akm.c6
-rw-r--r--drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c23
-rw-r--r--drivers/gpu/drm/panel/panel-xinpeng-xpp055c272.c28
-rw-r--r--drivers/gpu/drm/panfrost/panfrost_drv.c10
-rw-r--r--drivers/gpu/drm/qxl/qxl_drv.c4
-rw-r--r--drivers/gpu/drm/radeon/atombios_encoders.c10
-rw-r--r--drivers/gpu/drm/radeon/evergreen_hdmi.c5
-rw-r--r--drivers/gpu/drm/radeon/radeon_audio.c13
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c27
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_encoders.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h2
-rw-r--r--drivers/gpu/drm/renesas/rcar-du/Kconfig2
-rw-r--r--drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c4
-rw-r--r--drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c4
-rw-r--r--drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c4
-rw-r--r--drivers/gpu/drm/rockchip/Kconfig3
-rw-r--r--drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c20
-rw-r--r--drivers/gpu/drm/rockchip/inno_hdmi.c152
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_drv.c4
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop2.c2
-rw-r--r--drivers/gpu/drm/solomon/ssd130x.c4
-rw-r--r--drivers/gpu/drm/sti/Kconfig2
-rw-r--r--drivers/gpu/drm/sti/sti_dvo.c1
-rw-r--r--drivers/gpu/drm/stm/Kconfig2
-rw-r--r--drivers/gpu/drm/sun4i/Kconfig3
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_backend.c4
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_crtc.c2
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c83
-rw-r--r--drivers/gpu/drm/sun4i/sun8i_mixer.c70
-rw-r--r--drivers/gpu/drm/sun4i/sun8i_mixer.h20
-rw-r--r--drivers/gpu/drm/sun4i/sun8i_ui_layer.c85
-rw-r--r--drivers/gpu/drm/sun4i/sun8i_ui_layer.h20
-rw-r--r--drivers/gpu/drm/sun4i/sun8i_vi_layer.c86
-rw-r--r--drivers/gpu/drm/sun4i/sun8i_vi_layer.h20
-rw-r--r--drivers/gpu/drm/sun4i/sunxi_engine.h13
-rw-r--r--drivers/gpu/drm/tests/Makefile1
-rw-r--r--drivers/gpu/drm/tests/drm_buddy_test.c1
-rw-r--r--drivers/gpu/drm/tests/drm_cmdline_parser_test.c1
-rw-r--r--drivers/gpu/drm/tests/drm_connector_test.c1052
-rw-r--r--drivers/gpu/drm/tests/drm_damage_helper_test.c1
-rw-r--r--drivers/gpu/drm/tests/drm_dp_mst_helper_test.c1
-rw-r--r--drivers/gpu/drm/tests/drm_exec_test.c1
-rw-r--r--drivers/gpu/drm/tests/drm_format_test.c1
-rw-r--r--drivers/gpu/drm/tests/drm_framebuffer_test.c1
-rw-r--r--drivers/gpu/drm/tests/drm_gem_shmem_test.c1
-rw-r--r--drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c1743
-rw-r--r--drivers/gpu/drm/tests/drm_kunit_edid.h484
-rw-r--r--drivers/gpu/drm/tests/drm_kunit_helpers.c1
-rw-r--r--drivers/gpu/drm/tests/drm_managed_test.c1
-rw-r--r--drivers/gpu/drm/tests/drm_mm_test.c1
-rw-r--r--drivers/gpu/drm/tests/drm_modes_test.c1
-rw-r--r--drivers/gpu/drm/tests/drm_plane_helper_test.c1
-rw-r--r--drivers/gpu/drm/tests/drm_probe_helper_test.c1
-rw-r--r--drivers/gpu/drm/tests/drm_rect_test.c1
-rw-r--r--drivers/gpu/drm/tidss/tidss_plane.c14
-rw-r--r--drivers/gpu/drm/tiny/bochs.c28
-rw-r--r--drivers/gpu/drm/tiny/cirrus.c5
-rw-r--r--drivers/gpu/drm/tiny/gm12u320.c5
-rw-r--r--drivers/gpu/drm/tiny/hx8357d.c4
-rw-r--r--drivers/gpu/drm/tiny/ili9163.c4
-rw-r--r--drivers/gpu/drm/tiny/ili9225.c5
-rw-r--r--drivers/gpu/drm/tiny/ili9341.c4
-rw-r--r--drivers/gpu/drm/tiny/ili9486.c4
-rw-r--r--drivers/gpu/drm/tiny/mi0283qt.c5
-rw-r--r--drivers/gpu/drm/tiny/ofdrm.c4
-rw-r--r--drivers/gpu/drm/tiny/panel-mipi-dbi.c60
-rw-r--r--drivers/gpu/drm/tiny/repaper.c4
-rw-r--r--drivers/gpu/drm/tiny/simpledrm.c4
-rw-r--r--drivers/gpu/drm/tiny/st7586.c5
-rw-r--r--drivers/gpu/drm/tiny/st7735r.c4
-rw-r--r--drivers/gpu/drm/udl/Makefile8
-rw-r--r--drivers/gpu/drm/udl/udl_drv.c5
-rw-r--r--drivers/gpu/drm/udl/udl_drv.h12
-rw-r--r--drivers/gpu/drm/udl/udl_edid.c80
-rw-r--r--drivers/gpu/drm/udl/udl_edid.h15
-rw-r--r--drivers/gpu/drm/udl/udl_modeset.c138
-rw-r--r--drivers/gpu/drm/v3d/v3d_drv.c11
-rw-r--r--drivers/gpu/drm/v3d/v3d_drv.h11
-rw-r--r--drivers/gpu/drm/v3d/v3d_perfmon.c228
-rw-r--r--drivers/gpu/drm/v3d/v3d_performance_counters.h29
-rw-r--r--drivers/gpu/drm/v3d/v3d_sched.c2
-rw-r--r--drivers/gpu/drm/vboxvideo/vbox_drv.c4
-rw-r--r--drivers/gpu/drm/vc4/Kconfig1
-rw-r--r--drivers/gpu/drm/vc4/tests/vc4_mock.c6
-rw-r--r--drivers/gpu/drm/vc4/tests/vc4_mock.h9
-rw-r--r--drivers/gpu/drm/vc4/tests/vc4_mock_plane.c44
-rw-r--r--drivers/gpu/drm/vc4/vc4_hdmi.c644
-rw-r--r--drivers/gpu/drm/vc4/vc4_hdmi.h44
-rw-r--r--drivers/gpu/drm/vc4/vc4_hdmi_phy.c6
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_display.c10
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_drv.c4
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_drv.h2
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_vq.c12
-rw-r--r--drivers/gpu/drm/vkms/vkms_drv.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_vkms.c1
-rw-r--r--drivers/gpu/drm/xe/Makefile5
-rw-r--r--drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object_types.h11
-rw-r--r--drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_stolen.h (renamed from drivers/gpu/drm/xe/compat-i915-headers/i915_gem_stolen.h)0
-rw-r--r--drivers/gpu/drm/xe/compat-i915-headers/gt/intel_gt_types.h (renamed from drivers/gpu/drm/xe/compat-i915-headers/intel_gt_types.h)0
-rw-r--r--drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h67
-rw-r--r--drivers/gpu/drm/xe/compat-i915-headers/intel_runtime_pm.h51
-rw-r--r--drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h5
-rw-r--r--drivers/gpu/drm/xe/display/ext/i915_irq.c1
-rw-r--r--drivers/gpu/drm/xe/display/intel_fb_bo.c7
-rw-r--r--drivers/gpu/drm/xe/display/intel_fbdev_fb.c37
-rw-r--r--drivers/gpu/drm/xe/display/intel_fbdev_fb.h21
-rw-r--r--drivers/gpu/drm/xe/display/xe_display.c3
-rw-r--r--drivers/gpu/drm/xe/display/xe_dsb_buffer.c9
-rw-r--r--drivers/gpu/drm/xe/display/xe_fb_pin.c24
-rw-r--r--drivers/gpu/drm/xe/display/xe_hdcp_gsc.c2
-rw-r--r--drivers/gpu/drm/xe/display/xe_plane_initial.c23
-rw-r--r--drivers/gpu/drm/xe/display/xe_tdf.c13
-rw-r--r--drivers/gpu/drm/xe/regs/xe_gt_regs.h3
-rw-r--r--drivers/gpu/drm/xe/xe_device.c49
-rw-r--r--drivers/gpu/drm/xe/xe_device.h2
-rw-r--r--drivers/gpu/drm/xe/xe_device_types.h6
-rw-r--r--drivers/gpu/drm/xe/xe_ggtt.c2
-rw-r--r--drivers/gpu/drm/xe/xe_gsc_proxy.c4
-rw-r--r--drivers/gpu/drm/xe/xe_gt_printk.h3
-rw-r--r--drivers/gpu/drm/xe/xe_pci.c3
-rw-r--r--drivers/gpu/drm/xlnx/zynqmp_disp.c44
-rw-r--r--drivers/gpu/drm/xlnx/zynqmp_dp.c62
-rw-r--r--drivers/gpu/drm/xlnx/zynqmp_dpsub.c1
-rw-r--r--drivers/gpu/drm/xlnx/zynqmp_dpsub.h1
-rw-r--r--drivers/gpu/drm/xlnx/zynqmp_kms.c22
-rw-r--r--drivers/gpu/drm/xlnx/zynqmp_kms.h4
-rw-r--r--drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c4
-rw-r--r--drivers/misc/mei/hdcp/mei_hdcp.c4
-rw-r--r--drivers/misc/mei/pxp/mei_pxp.c4
-rw-r--r--drivers/platform/x86/intel_ips.c2
-rw-r--r--drivers/video/fbdev/core/fb_defio.c82
-rw-r--r--include/drm/display/drm_dp.h28
-rw-r--r--include/drm/display/drm_dp_helper.h3
-rw-r--r--include/drm/display/drm_hdmi_helper.h4
-rw-r--r--include/drm/display/drm_hdmi_state_helper.h23
-rw-r--r--include/drm/drm_bridge.h84
-rw-r--r--include/drm/drm_connector.h252
-rw-r--r--include/drm/drm_drv.h2
-rw-r--r--include/drm/drm_edid.h4
-rw-r--r--include/drm/drm_fbdev_generic.h15
-rw-r--r--include/drm/drm_fbdev_shmem.h15
-rw-r--r--include/drm/drm_fbdev_ttm.h15
-rw-r--r--include/drm/drm_mipi_dbi.h10
-rw-r--r--include/drm/drm_mipi_dsi.h122
-rw-r--r--include/drm/drm_mm.h1
-rw-r--r--include/drm/drm_mode_config.h4
-rw-r--r--include/drm/drm_panic.h9
-rw-r--r--include/drm/drm_print.h14
-rw-r--r--include/drm/i915_pciids.h767
-rw-r--r--include/drm/intel/i915_component.h (renamed from include/drm/i915_component.h)0
-rw-r--r--include/drm/intel/i915_drm.h (renamed from include/drm/i915_drm.h)0
-rw-r--r--include/drm/intel/i915_gsc_proxy_mei_interface.h (renamed from include/drm/i915_gsc_proxy_mei_interface.h)0
-rw-r--r--include/drm/intel/i915_hdcp_interface.h (renamed from include/drm/i915_hdcp_interface.h)0
-rw-r--r--include/drm/intel/i915_pciids.h800
-rw-r--r--include/drm/intel/i915_pxp_tee_interface.h (renamed from include/drm/i915_pxp_tee_interface.h)0
-rw-r--r--include/drm/intel/intel-gtt.h (renamed from include/drm/intel-gtt.h)0
-rw-r--r--include/drm/intel/intel_lpe_audio.h (renamed from include/drm/intel_lpe_audio.h)0
-rw-r--r--include/drm/intel/xe_pciids.h (renamed from include/drm/xe_pciids.h)0
-rw-r--r--include/linux/dma-fence-array.h3
-rw-r--r--include/linux/dma-heap.h4
-rw-r--r--include/linux/fb.h1
-rw-r--r--include/linux/mfd/atmel-hlcdc.h10
-rw-r--r--include/sound/hdaudio.h2
-rw-r--r--include/uapi/drm/amdgpu_drm.h9
-rw-r--r--include/uapi/drm/drm_mode.h8
-rw-r--r--include/uapi/drm/ivpu_accel.h69
-rw-r--r--include/uapi/drm/v3d_drm.h48
-rw-r--r--include/uapi/linux/dma-heap.h2
-rw-r--r--lib/fonts/Kconfig20
-rw-r--r--sound/x86/intel_hdmi_audio.c2
616 files changed, 27860 insertions, 18095 deletions
diff --git a/Documentation/devicetree/bindings/display/panel/boe,tv101wum-nl6.yaml b/Documentation/devicetree/bindings/display/panel/boe,tv101wum-nl6.yaml
index 9e603cad1348..7a9f49e40e75 100644
--- a/Documentation/devicetree/bindings/display/panel/boe,tv101wum-nl6.yaml
+++ b/Documentation/devicetree/bindings/display/panel/boe,tv101wum-nl6.yaml
@@ -32,8 +32,6 @@ properties:
- innolux,hj110iz-01a
# STARRY 2081101QFH032011-53G 10.1" WUXGA TFT LCD panel
- starry,2081101qfh032011-53g
- # STARRY himax83102-j02 10.51" WUXGA TFT LCD panel
- - starry,himax83102-j02
# STARRY ili9882t 10.51" WUXGA TFT LCD panel
- starry,ili9882t
diff --git a/Documentation/devicetree/bindings/display/panel/himax,hx83102.yaml b/Documentation/devicetree/bindings/display/panel/himax,hx83102.yaml
new file mode 100644
index 000000000000..c649fb085833
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/himax,hx83102.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/himax,hx83102.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Himax HX83102 MIPI-DSI LCD panel controller
+
+maintainers:
+ - Cong Yang <yangcong5@huaqin.corp-partner.google.com>
+
+allOf:
+ - $ref: panel-common.yaml#
+
+properties:
+ compatible:
+ items:
+ - enum:
+ # Boe nv110wum-l60 11.0" WUXGA TFT LCD panel
+ - boe,nv110wum-l60
+ # IVO t109nw41 11.0" WUXGA TFT LCD panel
+ - ivo,t109nw41
+ # STARRY himax83102-j02 10.51" WUXGA TFT LCD panel
+ - starry,himax83102-j02
+ - const: himax,hx83102
+
+ reg:
+ description: the virtual channel number of a DSI peripheral
+
+ enable-gpios:
+ description: a GPIO spec for the enable pin
+
+ pp1800-supply:
+ description: core voltage supply
+
+ avdd-supply:
+ description: phandle of the regulator that provides positive voltage
+
+ avee-supply:
+ description: phandle of the regulator that provides negative voltage
+
+ backlight: true
+ port: true
+ rotation: true
+
+required:
+ - compatible
+ - reg
+ - enable-gpios
+ - pp1800-supply
+ - avdd-supply
+ - avee-supply
+
+additionalProperties: false
+
+examples:
+ - |
+ dsi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ panel@0 {
+ compatible = "starry,himax83102-j02", "himax,hx83102";
+ reg = <0>;
+ enable-gpios = <&pio 45 0>;
+ avdd-supply = <&ppvarn_lcd>;
+ avee-supply = <&ppvarp_lcd>;
+ pp1800-supply = <&pp1800_lcd>;
+ backlight = <&backlight_lcd0>;
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&dsi_out>;
+ };
+ };
+ };
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/display/panel/panel-edp-legacy.yaml b/Documentation/devicetree/bindings/display/panel/panel-edp-legacy.yaml
new file mode 100644
index 000000000000..b308047c1edf
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/panel-edp-legacy.yaml
@@ -0,0 +1,117 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/panel-edp-legacy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Legacy eDP panels from before the "edp-panel" compatible
+
+maintainers:
+ - Douglas Anderson <dianders@chromium.org>
+
+description: |
+ This binding file is a collection of eDP panels from before the generic
+ "edp-panel" compatible was introduced. It is kept around to support old
+ dts files. The only reason one might add a new panel here instead of using
+ the generic "edp-panel" is if it needed to be used on an eDP controller
+ that doesn't support the generic "edp-panel" compatible, but it should be
+ a strong preference to add the generic "edp-panel" compatible instead.
+
+allOf:
+ - $ref: panel-common.yaml#
+
+properties:
+ compatible:
+ enum:
+ # compatible must be listed in alphabetical order, ordered by compatible.
+ # The description in the comment is mandatory for each compatible.
+
+ # AU Optronics Corporation 10.1" WSVGA TFT LCD panel
+ - auo,b101ean01
+ # AUO B116XAK01 eDP TFT LCD panel
+ - auo,b116xa01
+ # AU Optronics Corporation 13.3" FHD (1920x1080) color TFT-LCD panel
+ - auo,b133htn01
+ # AU Optronics Corporation 13.3" WXGA (1366x768) TFT LCD panel
+ - auo,b133xtn01
+ # BOE OPTOELECTRONICS TECHNOLOGY 10.1" WXGA TFT LCD panel
+ - boe,nv101wxmn51
+ # BOE NV133FHM-N61 13.3" FHD (1920x1080) TFT LCD Panel
+ - boe,nv110wtm-n61
+ # BOE NV110WTM-N61 11.0" 2160x1440 TFT LCD Panel
+ - boe,nv133fhm-n61
+ # BOE NV133FHM-N62 13.3" FHD (1920x1080) TFT LCD Panel
+ - boe,nv133fhm-n62
+ # BOE NV140FHM-N49 14.0" FHD a-Si FT panel
+ - boe,nv140fhmn49
+ # Innolux Corporation 11.6" WXGA (1366x768) TFT LCD panel
+ - innolux,n116bca-ea1
+ # Innolux Corporation 11.6" WXGA (1366x768) TFT LCD panel
+ - innolux,n116bge
+ # InnoLux 13.3" FHD (1920x1080) eDP TFT LCD panel
+ - innolux,n125hce-gn1
+ # Innolux P120ZDG-BF1 12.02 inch eDP 2K display panel
+ - innolux,p120zdg-bf1
+ # King & Display KD116N21-30NV-A010 eDP TFT LCD panel
+ - kingdisplay,kd116n21-30nv-a010
+ # LG LP079QX1-SP0V 7.9" (1536x2048 pixels) TFT LCD panel
+ - lg,lp079qx1-sp0v
+ # LG 9.7" (2048x1536 pixels) TFT LCD panel
+ - lg,lp097qx1-spa1
+ # LG 12.0" (1920x1280 pixels) TFT LCD panel
+ - lg,lp120up1
+ # LG 12.9" (2560x1700 pixels) TFT LCD panel
+ - lg,lp129qe
+ # NewEast Optoelectronics CO., LTD WJFH116008A eDP TFT LCD panel
+ - neweast,wjfh116008a
+ # Samsung 12.2" (2560x1600 pixels) TFT LCD panel
+ - samsung,lsn122dl01-c01
+ # Samsung Electronics 14" WXGA (1366x768) TFT LCD panel
+ - samsung,ltn140at29-301
+ # Sharp LD-D5116Z01B 12.3" WUXGA+ eDP panel
+ - sharp,ld-d5116z01b
+ # Sharp 12.3" (2400x1600 pixels) TFT LCD panel
+ - sharp,lq123p1jx31
+
+ backlight: true
+ ddc-i2c-bus: true
+ enable-gpios: true
+ panel-timing: true
+ port: true
+ power-supply: true
+ no-hpd: true
+ hpd-gpios: true
+
+additionalProperties: false
+
+required:
+ - compatible
+ - power-supply
+
+examples:
+ - |
+ panel: panel {
+ compatible = "innolux,n116bge";
+ power-supply = <&panel_regulator>;
+ backlight = <&backlight>;
+
+ panel-timing {
+ clock-frequency = <74250000>;
+ hactive = <1366>;
+ hfront-porch = <136>;
+ hback-porch = <60>;
+ hsync-len = <30>;
+ hsync-active = <0>;
+ vactive = <768>;
+ vfront-porch = <8>;
+ vback-porch = <12>;
+ vsync-len = <12>;
+ vsync-active = <0>;
+ };
+
+ port {
+ panel_in_edp: endpoint {
+ remote-endpoint = <&edp_out_panel>;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml b/Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml
index d0ac31ab60cf..6f0290c4e291 100644
--- a/Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml
+++ b/Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml
@@ -50,6 +50,12 @@ description: |
| Command or data |
|<D7><D6><D5><D4><D3><D2><D1><D0>|
+ The standard defines one pixel format for type C: RGB111. The industry
+ however has decided to provide the type A/B interface pixel formats also on
+ the Type C interface and most common among these are RGB565 and RGB666.
+ The MIPI DCS command set_address_mode (36h) has one bit that controls RGB/BGR
+ order. This gives each supported RGB format a BGR variant.
+
The panel resolution is specified using the panel-timing node properties
hactive (width) and vactive (height). The other mandatory panel-timing
properties should be set to zero except clock-frequency which can be
@@ -93,6 +99,28 @@ properties:
spi-3wire: true
+ format:
+ description: >
+ Pixel format in bit order as going on the wire:
+ * `x2r1g1b1r1g1b1` - RGB111, 2 pixels per byte
+ * `x2b1g1r1b1g1r1` - BGR111, 2 pixels per byte
+ * `x1r1g1b1x1r1g1b1` - RGB111, 2 pixels per byte
+ * `x1b1g1r1x1b1g1r1` - BGR111, 2 pixels per byte
+ * `r5g6b5` - RGB565, 2 bytes
+ * `b5g6r5` - BGR565, 2 bytes
+ * `r6x2g6x2b6x2` - RGB666, 3 bytes
+ * `b6x2g6x2r6x2` - BGR666, 3 bytes
+ enum:
+ - x2r1g1b1r1g1b1
+ - x2b1g1r1b1g1r1
+ - x1r1g1b1x1r1g1b1
+ - x1b1g1r1x1b1g1r1
+ - r5g6b5
+ - b5g6r5
+ - r6x2g6x2b6x2
+ - b6x2g6x2r6x2
+ default: r5g6b5
+
required:
- compatible
- reg
@@ -119,6 +147,8 @@ examples:
reset-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>;
write-only;
+ format = "r5g6b5";
+
backlight = <&backlight>;
width-mm = <35>;
diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple-lvds-dual-ports.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple-lvds-dual-ports.yaml
index 716ece5f3978..e78160d1aa24 100644
--- a/Documentation/devicetree/bindings/display/panel/panel-simple-lvds-dual-ports.yaml
+++ b/Documentation/devicetree/bindings/display/panel/panel-simple-lvds-dual-ports.yaml
@@ -41,6 +41,12 @@ properties:
- auo,g190ean01
# Kaohsiung Opto-Electronics Inc. 10.1" WUXGA (1920 x 1200) LVDS TFT LCD panel
- koe,tx26d202vm0bwa
+ # Lincoln Technology Solutions, LCD185-101CT 10.1" TFT 1920x1200
+ - lincolntech,lcd185-101ct
+ # Microtips Technology MF-101HIEBCAF0 10.1" WUXGA (1920x1200) TFT LCD panel
+ - microtips,mf-101hiebcaf0
+ # Microtips Technology MF-103HIEB0GA0 10.25" 1920x720 TFT LCD panel
+ - microtips,mf-103hieb0ga0
# NLT Technologies, Ltd. 15.6" FHD (1920x1080) LVDS TFT LCD panel
- nlt,nl192108ac18-02d
diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
index 5067f5c0a272..2ffb2c2e84f9 100644
--- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
+++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
@@ -41,22 +41,10 @@ properties:
- ampire,am800600p5tmqw-tb8h
# AU Optronics Corporation 10.1" WSVGA TFT LCD panel
- auo,b101aw03
- # AU Optronics Corporation 10.1" WSVGA TFT LCD panel
- - auo,b101ean01
# AU Optronics Corporation 10.1" WXGA TFT LCD panel
- auo,b101xtn01
- # AUO B116XAK01 eDP TFT LCD panel
- - auo,b116xa01
# AU Optronics Corporation 11.6" HD (1366x768) color TFT-LCD panel
- auo,b116xw03
- # AU Optronics Corporation 13.3" FHD (1920x1080) color TFT-LCD panel
- - auo,b133han05
- # AU Optronics Corporation 13.3" FHD (1920x1080) color TFT-LCD panel
- - auo,b133htn01
- # AU Optronics Corporation 13.3" WXGA (1366x768) TFT LCD panel
- - auo,b133xtn01
- # AU Optronics Corporation 14.0" FHD (1920x1080) color TFT-LCD panel
- - auo,b140han06
# AU Optronics Corporation 7.0" FHD (800 x 480) TFT LCD panel
- auo,g070vvn01
# AU Optronics Corporation 10.1" (1280x800) color TFT LCD panel
@@ -81,16 +69,6 @@ properties:
- boe,ev121wxm-n10-1850
# BOE HV070WSA-100 7.01" WSVGA TFT LCD panel
- boe,hv070wsa-100
- # BOE OPTOELECTRONICS TECHNOLOGY 10.1" WXGA TFT LCD panel
- - boe,nv101wxmn51
- # BOE NV133FHM-N61 13.3" FHD (1920x1080) TFT LCD Panel
- - boe,nv110wtm-n61
- # BOE NV110WTM-N61 11.0" 2160x1440 TFT LCD Panel
- - boe,nv133fhm-n61
- # BOE NV133FHM-N62 13.3" FHD (1920x1080) TFT LCD Panel
- - boe,nv133fhm-n62
- # BOE NV140FHM-N49 14.0" FHD a-Si FT panel
- - boe,nv140fhmn49
# Crystal Clear Technology CMT430B19N00 4.3" 480x272 TFT-LCD panel
- cct,cmt430b19n00
# CDTech(H.K.) Electronics Limited 4.3" 480x272 color TFT-LCD panel
@@ -172,8 +150,6 @@ properties:
- hannstar,hsd100pxn1
# Hitachi Ltd. Corporation 9" WVGA (800x480) TFT LCD panel
- hit,tx23d38vm0caa
- # InfoVision Optoelectronics M133NWF4 R0 13.3" FHD (1920x1080) TFT LCD panel
- - ivo,m133nwf4-r0
# Innolux AT043TN24 4.3" WQVGA TFT LCD panel
- innolux,at043tn24
# Innolux AT070TN92 7.0" WQVGA TFT LCD panel
@@ -192,22 +168,12 @@ properties:
- innolux,g121x1-l03
# Innolux Corporation 12.1" G121XCE-L01 XGA (1024x768) TFT LCD panel
- innolux,g121xce-l01
- # Innolux Corporation 11.6" WXGA (1366x768) TFT LCD panel
- - innolux,n116bca-ea1
- # Innolux Corporation 11.6" WXGA (1366x768) TFT LCD panel
- - innolux,n116bge
- # InnoLux 13.3" FHD (1920x1080) eDP TFT LCD panel
- - innolux,n125hce-gn1
# InnoLux 15.6" FHD (1920x1080) TFT LCD panel
- innolux,g156hce-l01
# InnoLux 15.6" WXGA TFT LCD panel
- innolux,n156bge-l21
- # Innolux P120ZDG-BF1 12.02 inch eDP 2K display panel
- - innolux,p120zdg-bf1
# Innolux Corporation 7.0" WSVGA (1024x600) TFT LCD panel
- innolux,zj070na-01p
- # King & Display KD116N21-30NV-A010 eDP TFT LCD panel
- - kingdisplay,kd116n21-30nv-a010
# Kaohsiung Opto-Electronics Inc. 5.7" QVGA (320 x 240) TFT LCD panel
- koe,tx14d24vm1bpa
# Kaohsiung Opto-Electronics. TX31D200VM0BAA 12.3" HSXGA LVDS panel
@@ -220,14 +186,6 @@ properties:
- lemaker,bl035-rgb-002
# LG 7" (800x480 pixels) TFT LCD panel
- lg,lb070wv8
- # LG LP079QX1-SP0V 7.9" (1536x2048 pixels) TFT LCD panel
- - lg,lp079qx1-sp0v
- # LG 9.7" (2048x1536 pixels) TFT LCD panel
- - lg,lp097qx1-spa1
- # LG 12.0" (1920x1280 pixels) TFT LCD panel
- - lg,lp120up1
- # LG 12.9" (2560x1700 pixels) TFT LCD panel
- - lg,lp129qe
# Logic Technologies LT161010-2NHC 7" WVGA TFT Cap Touch Module
- logictechno,lt161010-2nhc
# Logic Technologies LT161010-2NHR 7" WVGA TFT Resistive Touch Module
@@ -254,8 +212,6 @@ properties:
- nec,nl4827hc19-05b
# Netron-DY E231732 7.0" WSVGA TFT LCD panel
- netron-dy,e231732
- # NewEast Optoelectronics CO., LTD WJFH116008A eDP TFT LCD panel
- - neweast,wjfh116008a
# Newhaven Display International 480 x 272 TFT LCD panel
- newhaven,nhd-4.3-480272ef-atxl
# New Vision Display 7.0" 800 RGB x 480 TFT LCD panel
@@ -280,6 +236,8 @@ properties:
- powertip,ph128800t006-zhc01
# POWERTIP PH800480T013-IDF2 7.0" WVGA TFT LCD panel
- powertip,ph800480t013-idf02
+ # PrimeView PM070WL4 7.0" 800x480 TFT LCD panel
+ - primeview,pm070wl4
# QiaoDian XianShi Corporation 4"3 TFT LCD panel
- qiaodian,qd43003c0-40
# Shenzhen QiShenglong Industrialist Co., Ltd. Gopher 2b 4.3" 480(RGB)x272 TFT LCD panel
@@ -290,16 +248,10 @@ properties:
- rocktech,rk070er9427
# Rocktech Display Ltd. RK043FN48H 4.3" 480x272 LCD-TFT panel
- rocktech,rk043fn48h
- # Samsung 13.3" FHD (1920x1080 pixels) eDP AMOLED panel
- - samsung,atna33xc20
- # Samsung 12.2" (2560x1600 pixels) TFT LCD panel
- - samsung,lsn122dl01-c01
# Samsung Electronics 10.1" WXGA (1280x800) TFT LCD panel
- samsung,ltl101al01
# Samsung Electronics 10.1" WSVGA TFT LCD panel
- samsung,ltn101nt05
- # Samsung Electronics 14" WXGA (1366x768) TFT LCD panel
- - samsung,ltn140at29-301
# Satoz SAT050AT40H12R2 5.0" WVGA TFT LCD panel
- satoz,sat050at40h12r2
# Sharp LQ035Q7DB03 3.5" QVGA TFT LCD panel
@@ -308,18 +260,12 @@ properties:
- sharp,lq070y3dg3b
# Sharp Display Corp. LQ101K1LY04 10.07" WXGA TFT LCD panel
- sharp,lq101k1ly04
- # Sharp 12.3" (2400x1600 pixels) TFT LCD panel
- - sharp,lq123p1jx31
- # Sharp 14" (1920x1080 pixels) TFT LCD panel
- - sharp,lq140m1jw46
# Sharp LS020B1DD01D 2.0" HQVGA TFT LCD panel
- sharp,ls020b1dd01d
# Shelly SCA07010-BFN-LNN 7.0" WVGA TFT LCD panel
- shelly,sca07010-bfn-lnn
# Starry KR070PE2T 7" WVGA TFT LCD panel
- starry,kr070pe2t
- # Starry 12.2" (1920x1200 pixels) TFT LCD panel
- - starry,kr122ea0sra
# Startek KD070WVFPA043-C069A 7" TFT LCD panel
- startek,kd070wvfpa
# Team Source Display Technology TST043015CMHX 4.3" WQVGA TFT LCD panel
diff --git a/Documentation/devicetree/bindings/display/panel/samsung,atna33xc20.yaml b/Documentation/devicetree/bindings/display/panel/samsung,atna33xc20.yaml
new file mode 100644
index 000000000000..765ca155c83a
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/samsung,atna33xc20.yaml
@@ -0,0 +1,95 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/samsung,atna33xc20.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung 13.3" FHD (1920x1080 pixels) eDP AMOLED panel
+
+maintainers:
+ - Douglas Anderson <dianders@chromium.org>
+
+allOf:
+ - $ref: panel-common.yaml#
+
+properties:
+ compatible:
+ const: samsung,atna33xc20
+
+ enable-gpios: true
+ port: true
+ power-supply: true
+ no-hpd: true
+ hpd-gpios: true
+
+additionalProperties: false
+
+required:
+ - compatible
+ - enable-gpios
+ - power-supply
+
+examples:
+ - |
+ #include <dt-bindings/clock/qcom,rpmh.h>
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ bridge@2d {
+ compatible = "ti,sn65dsi86";
+ reg = <0x2d>;
+
+ interrupt-parent = <&tlmm>;
+ interrupts = <10 IRQ_TYPE_LEVEL_HIGH>;
+
+ enable-gpios = <&tlmm 102 GPIO_ACTIVE_HIGH>;
+
+ vpll-supply = <&src_pp1800_s4a>;
+ vccio-supply = <&src_pp1800_s4a>;
+ vcca-supply = <&src_pp1200_l2a>;
+ vcc-supply = <&src_pp1200_l2a>;
+
+ clocks = <&rpmhcc RPMH_LN_BB_CLK2>;
+ clock-names = "refclk";
+
+ no-hpd;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ endpoint {
+ remote-endpoint = <&dsi0_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ sn65dsi86_out: endpoint {
+ remote-endpoint = <&panel_in_edp>;
+ };
+ };
+ };
+
+ aux-bus {
+ panel {
+ compatible = "samsung,atna33xc20";
+ enable-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;
+ power-supply = <&pp3300_dx_edp>;
+ hpd-gpios = <&sn65dsi86_bridge 2 GPIO_ACTIVE_HIGH>;
+
+ port {
+ panel_in_edp: endpoint {
+ remote-endpoint = <&sn65dsi86_out>;
+ };
+ };
+ };
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/display/panel/sharp,ld-d5116z01b.yaml b/Documentation/devicetree/bindings/display/panel/sharp,ld-d5116z01b.yaml
deleted file mode 100644
index fbb647eb33c9..000000000000
--- a/Documentation/devicetree/bindings/display/panel/sharp,ld-d5116z01b.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/display/panel/sharp,ld-d5116z01b.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: Sharp LD-D5116Z01B 12.3" WUXGA+ eDP panel
-
-maintainers:
- - Jeffrey Hugo <jeffrey.l.hugo@gmail.com>
-
-allOf:
- - $ref: panel-common.yaml#
-
-properties:
- compatible:
- const: sharp,ld-d5116z01b
-
- power-supply: true
- backlight: true
- port: true
- no-hpd: true
-
-additionalProperties: false
-
-required:
- - compatible
- - power-supply
-
-...
diff --git a/Documentation/devicetree/bindings/display/panel/wl-355608-a8.yaml b/Documentation/devicetree/bindings/display/panel/wl-355608-a8.yaml
new file mode 100644
index 000000000000..e552d01b52b9
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/wl-355608-a8.yaml
@@ -0,0 +1,60 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/wl-355608-a8.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: WL-355608-A8 3.5" (640x480 pixels) 24-bit IPS LCD panel
+
+maintainers:
+ - Ryan Walklin <ryan@testtoast.com>
+
+allOf:
+ - $ref: panel-common.yaml#
+ - $ref: /schemas/spi/spi-peripheral-props.yaml#
+
+properties:
+ compatible:
+ const: wl-355608-a8
+
+ reg:
+ maxItems: 1
+
+ spi-3wire: true
+
+required:
+ - compatible
+ - reg
+ - port
+ - power-supply
+ - reset-gpios
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+
+ spi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ panel@0 {
+ compatible = "wl-355608-a8";
+ reg = <0>;
+
+ spi-3wire;
+ spi-max-frequency = <3125000>;
+
+ reset-gpios = <&pio 8 14 GPIO_ACTIVE_LOW>; // PI14
+
+ backlight = <&backlight>;
+ power-supply = <&reg_lcd>;
+
+ port {
+ endpoint {
+ remote-endpoint = <&tcon_lcd0_out_lcd>;
+ };
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-mipi-dsi.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-mipi-dsi.yaml
index ccf79e738fa1..ccd71c5324af 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-mipi-dsi.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-mipi-dsi.yaml
@@ -15,6 +15,7 @@ properties:
items:
- enum:
- rockchip,px30-mipi-dsi
+ - rockchip,rk3128-mipi-dsi
- rockchip,rk3288-mipi-dsi
- rockchip,rk3399-mipi-dsi
- rockchip,rk3568-mipi-dsi
@@ -77,6 +78,7 @@ allOf:
contains:
enum:
- rockchip,px30-mipi-dsi
+ - rockchip,rk3128-mipi-dsi
- rockchip,rk3568-mipi-dsi
- rockchip,rv1126-mipi-dsi
diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml b/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml
index e796a1ff8c82..278399adc550 100644
--- a/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml
+++ b/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml
@@ -34,6 +34,7 @@ properties:
- const: arm,mali-valhall-jm # Mali Valhall GPU model/revision is fully discoverable
- items:
- enum:
+ - mediatek,mt8188-mali
- mediatek,mt8192-mali
- const: arm,mali-valhall-jm # Mali Valhall GPU model/revision is fully discoverable
@@ -195,7 +196,9 @@ allOf:
properties:
compatible:
contains:
- const: mediatek,mt8183b-mali
+ enum:
+ - mediatek,mt8183b-mali
+ - mediatek,mt8188-mali
then:
properties:
power-domains:
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index fbf47f0bacf1..77eccc5c4889 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -820,6 +820,8 @@ patternProperties:
description: Lichee Pi
"^linaro,.*":
description: Linaro Limited
+ "^lincolntech,.*":
+ description: Lincoln Technology Solutions
"^lineartechnology,.*":
description: Linear Technology
"^linksprite,.*":
@@ -924,6 +926,8 @@ patternProperties:
description: Microsoft Corporation
"^microsys,.*":
description: MicroSys Electronics GmbH
+ "^microtips,.*":
+ description: Microtips Technology USA
"^mikroe,.*":
description: MikroElektronika d.o.o.
"^mikrotik,.*":
@@ -1160,6 +1164,8 @@ patternProperties:
description: PowerVR (deprecated, use img)
"^powkiddy,.*":
description: Powkiddy
+ "^primeview,.*":
+ description: Prime View International (PVI)
"^primux,.*":
description: Primux Trading, S.L.
"^probox2,.*":
diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst
index 335de7fcddee..11d9a5730fb2 100644
--- a/Documentation/gpu/drm-internals.rst
+++ b/Documentation/gpu/drm-internals.rst
@@ -57,8 +57,8 @@ is larger than the driver minor, the DRM_IOCTL_SET_VERSION call will
return an error. Otherwise the driver's set_version() method will be
called with the requested version.
-Name, Description and Date
-~~~~~~~~~~~~~~~~~~~~~~~~~~
+Name and Description
+~~~~~~~~~~~~~~~~~~~~
char \*name; char \*desc; char \*date;
The driver name is printed to the kernel log at initialization time,
@@ -69,12 +69,6 @@ The driver description is a purely informative string passed to
userspace through the DRM_IOCTL_VERSION ioctl and otherwise unused by
the kernel.
-The driver date, formatted as YYYYMMDD, is meant to identify the date of
-the latest modification to the driver. However, as most drivers fail to
-update it, its value is mostly useless. The DRM core prints it to the
-kernel log at initialization time and passes it to userspace through the
-DRM_IOCTL_VERSION ioctl.
-
Module Initialization
---------------------
diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst
index 59cfe8a7a8ba..8435e8621cc0 100644
--- a/Documentation/gpu/drm-kms-helpers.rst
+++ b/Documentation/gpu/drm-kms-helpers.rst
@@ -110,15 +110,21 @@ fbdev Helper Functions Reference
.. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c
:doc: fbdev helpers
+.. kernel-doc:: drivers/gpu/drm/drm_fbdev_dma.c
+ :export:
+
+.. kernel-doc:: drivers/gpu/drm/drm_fbdev_shmem.c
+ :export:
+
+.. kernel-doc:: drivers/gpu/drm/drm_fbdev_ttm.c
+ :export:
+
.. kernel-doc:: include/drm/drm_fb_helper.h
:internal:
.. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c
:export:
-.. kernel-doc:: drivers/gpu/drm/drm_fbdev_generic.c
- :export:
-
format Helper Functions Reference
=================================
diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst
index 17261ba18313..ad59ae579237 100644
--- a/Documentation/gpu/i915.rst
+++ b/Documentation/gpu/i915.rst
@@ -150,7 +150,7 @@ High Definition Audio
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_audio.c
:internal:
-.. kernel-doc:: include/drm/i915_component.h
+.. kernel-doc:: include/drm/intel/i915_component.h
:internal:
Intel HDMI LPE Audio Support
@@ -210,9 +210,6 @@ DMC wakelock support
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dmc_wl.c
:doc: DMC wakelock support
-.. kernel-doc:: drivers/gpu/drm/i915/display/intel_dmc_wl.c
- :internal:
-
Video BIOS Table (VBT)
----------------------
diff --git a/Documentation/gpu/kms-properties.csv b/Documentation/gpu/kms-properties.csv
index 0f9590834829..bfbfbf4f102d 100644
--- a/Documentation/gpu/kms-properties.csv
+++ b/Documentation/gpu/kms-properties.csv
@@ -17,7 +17,6 @@ Owner Module/Drivers,Group,Property Name,Type,Property Values,Object attached,De
,Virtual GPU,“suggested X”,RANGE,"Min=0, Max=0xffffffff",Connector,property to suggest an X offset for a connector
,,“suggested Y”,RANGE,"Min=0, Max=0xffffffff",Connector,property to suggest an Y offset for a connector
,Optional,"""aspect ratio""",ENUM,"{ ""None"", ""4:3"", ""16:9"" }",Connector,TDB
-i915,Generic,"""Broadcast RGB""",ENUM,"{ ""Automatic"", ""Full"", ""Limited 16:235"" }",Connector,"When this property is set to Limited 16:235 and CTM is set, the hardware will be programmed with the result of the multiplication of CTM by the limited range matrix to ensure the pixels normally in the range 0..1.0 are remapped to the range 16/255..235/255."
,,“audio”,ENUM,"{ ""force-dvi"", ""off"", ""auto"", ""on"" }",Connector,TBD
,SDVO-TV,“mode”,ENUM,"{ ""NTSC_M"", ""NTSC_J"", ""NTSC_443"", ""PAL_B"" } etc.",Connector,TBD
,,"""left_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
@@ -38,7 +37,6 @@ i915,Generic,"""Broadcast RGB""",ENUM,"{ ""Automatic"", ""Full"", ""Limited 16:2
,,“dot_crawl”,RANGE,"Min=0, Max=1",Connector,TBD
,SDVO-TV/LVDS,“brightness”,RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
CDV gma-500,Generic,"""Broadcast RGB""",ENUM,"{ “Full”, “Limited 16:235” }",Connector,TBD
-,,"""Broadcast RGB""",ENUM,"{ “off”, “auto”, “on” }",Connector,TBD
Poulsbo,Generic,“backlight”,RANGE,"Min=0, Max=100",Connector,TBD
,SDVO-TV,“mode”,ENUM,"{ ""NTSC_M"", ""NTSC_J"", ""NTSC_443"", ""PAL_B"" } etc.",Connector,TBD
,,"""left_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD
diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index fb9ad120b141..2ea6ffc9b22b 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -243,19 +243,6 @@ Contact: Maintainer of the driver you plan to convert
Level: Intermediate
-Convert drivers to use drm_fbdev_generic_setup()
-------------------------------------------------
-
-Most drivers can use drm_fbdev_generic_setup(). Driver have to implement
-atomic modesetting and GEM vmap support. Historically, generic fbdev emulation
-expected the framebuffer in system memory or system-like memory. By employing
-struct iosys_map, drivers with frambuffers in I/O memory can be supported
-as well.
-
-Contact: Maintainer of the driver you plan to convert
-
-Level: Intermediate
-
Reimplement functions in drm_fbdev_fb_ops without fbdev
-------------------------------------------------------
@@ -482,30 +469,53 @@ Contact: Thomas Zimmermann <tzimmermann@suse.de>
Level: Starter
-Clean up checks for already prepared/enabled in panels
-------------------------------------------------------
+Remove disable/unprepare in remove/shutdown in panel-simple and panel-edp
+-------------------------------------------------------------------------
+
+As of commit d2aacaf07395 ("drm/panel: Check for already prepared/enabled in
+drm_panel"), we have a check in the drm_panel core to make sure nobody
+double-calls prepare/enable/disable/unprepare. Eventually that should probably
+be turned into a WARN_ON() or somehow made louder, but right now we actually
+expect it to trigger and so we don't want it to be too loud.
+
+Specifically, that warning will trigger for panel-edp and panel-simple at
+shutdown time because those panels hardcode a call to drm_panel_disable()
+and drm_panel_unprepare() at shutdown and remove time that they call regardless
+of panel state. On systems with a properly coded DRM modeset driver that
+calls drm_atomic_helper_shutdown() this is pretty much guaranteed to cause
+the warning to fire.
+
+Unfortunately we can't safely remove the calls in panel-edp and panel-simple
+until we're sure that all DRM modeset drivers that are used with those panels
+properly call drm_atomic_helper_shutdown(). This TODO item is to validate
+that all DRM modeset drivers used with panel-edp and panel-simple properly
+call drm_atomic_helper_shutdown() and then remove the calls to
+disable/unprepare from those panels. Alternatively, this TODO item could be
+removed by convincing stakeholders that those calls are fine and downgrading
+the error message in drm_panel_disable() / drm_panel_unprepare() to a
+debug-level message.
-In a whole pile of panel drivers, we have code to make the
-prepare/unprepare/enable/disable callbacks behave as no-ops if they've already
-been called. To get some idea of the duplicated code, try::
+Contact: Douglas Anderson <dianders@chromium.org>
- git grep 'if.*>prepared' -- drivers/gpu/drm/panel
- git grep 'if.*>enabled' -- drivers/gpu/drm/panel
+Level: Intermediate
-In the patch ("drm/panel: Check for already prepared/enabled in drm_panel")
-we've moved this check to the core. Now we can most definitely remove the
-check from the individual panels and save a pile of code.
+Transition away from using mipi_dsi_*_write_seq()
+-------------------------------------------------
-In adition to removing the check from the individual panels, it is believed
-that even the core shouldn't need this check and that should be considered
-an error if other code ever relies on this check. The check in the core
-currently prints a warning whenever something is relying on this check with
-dev_warn(). After a little while, we likely want to promote this to a
-WARN(1) to help encourage folks not to rely on this behavior.
+The macros mipi_dsi_generic_write_seq() and mipi_dsi_dcs_write_seq() are
+non-intuitive because, if there are errors, they return out of the *caller's*
+function. We should move all callers to use mipi_dsi_generic_write_seq_multi()
+and mipi_dsi_dcs_write_seq_multi() macros instead.
+
+Once all callers are transitioned, the macros and the functions that they call,
+mipi_dsi_generic_write_chatty() and mipi_dsi_dcs_write_buffer_chatty(), can
+probably be removed. Alternatively, if people feel like the _multi() variants
+are overkill for some use cases, we could keep the mipi_dsi_*_write_seq()
+variants but change them not to return out of the caller.
Contact: Douglas Anderson <dianders@chromium.org>
-Level: Starter/Intermediate
+Level: Starter
Core refactorings
diff --git a/MAINTAINERS b/MAINTAINERS
index ad897082a9cd..082483b40fac 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6909,7 +6909,7 @@ DRM DRIVER FOR LG SW43408 PANELS
M: Sumit Semwal <sumit.semwal@linaro.org>
M: Caleb Connolly <caleb.connolly@linaro.org>
S: Maintained
-T: git git://anongit.freedesktop.org/drm/drm-misc
+T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: Documentation/devicetree/bindings/display/panel/lg,sw43408.yaml
F: drivers/gpu/drm/panel/panel-lg-sw43408.c
@@ -7196,6 +7196,7 @@ L: dri-devel@lists.freedesktop.org
S: Maintained
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: Documentation/gpu/vkms.rst
+F: drivers/gpu/drm/ci/xfails/vkms*
F: drivers/gpu/drm/vkms/
DRM DRIVER FOR VIRTUALBOX VIRTUAL GPU
@@ -7566,7 +7567,6 @@ F: include/drm/gpu_scheduler.h
DRM PANEL DRIVERS
M: Neil Armstrong <neil.armstrong@linaro.org>
R: Jessica Zhang <quic_jesszhan@quicinc.com>
-R: Sam Ravnborg <sam@ravnborg.org>
L: dri-devel@lists.freedesktop.org
S: Maintained
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
@@ -11012,6 +11012,7 @@ S: Supported
F: drivers/gpu/drm/i915/display/
F: drivers/gpu/drm/xe/display/
F: drivers/gpu/drm/xe/compat-i915-headers
+F: include/drm/intel/
INTEL DRM I915 DRIVER (Meteor Lake, DG2 and older excluding Poulsbo, Moorestown and derivative)
M: Jani Nikula <jani.nikula@linux.intel.com>
@@ -11024,12 +11025,12 @@ W: https://drm.pages.freedesktop.org/intel-docs/
Q: http://patchwork.freedesktop.org/project/intel-gfx/
B: https://drm.pages.freedesktop.org/intel-docs/how-to-file-i915-bugs.html
C: irc://irc.oftc.net/intel-gfx
-T: git git://anongit.freedesktop.org/drm-intel
+T: git https://gitlab.freedesktop.org/drm/i915/kernel.git
F: Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon
F: Documentation/gpu/i915.rst
F: drivers/gpu/drm/ci/xfails/i915*
F: drivers/gpu/drm/i915/
-F: include/drm/i915*
+F: include/drm/intel/
F: include/uapi/drm/i915_drm.h
INTEL DRM XE DRIVER (Lunar Lake and newer)
@@ -11045,7 +11046,7 @@ T: git https://gitlab.freedesktop.org/drm/xe/kernel.git
F: Documentation/ABI/testing/sysfs-driver-intel-xe-hwmon
F: Documentation/gpu/xe/
F: drivers/gpu/drm/xe/
-F: include/drm/xe*
+F: include/drm/intel/
F: include/uapi/drm/xe_drm.h
INTEL ETHERNET DRIVERS
diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
index 59f4aefc6bc1..29d1f9104e94 100644
--- a/arch/x86/kernel/early-quirks.c
+++ b/arch/x86/kernel/early-quirks.c
@@ -17,8 +17,8 @@
#include <linux/bcma/bcma.h>
#include <linux/bcma/bcma_regs.h>
#include <linux/platform_data/x86/apple.h>
-#include <drm/i915_drm.h>
-#include <drm/i915_pciids.h>
+#include <drm/intel/i915_drm.h>
+#include <drm/intel/i915_pciids.h>
#include <asm/pci-direct.h>
#include <asm/dma.h>
#include <asm/io_apic.h>
@@ -518,47 +518,46 @@ static const struct intel_early_ops gen11_early_ops __initconst = {
/* Intel integrated GPUs for which we need to reserve "stolen memory" */
static const struct pci_device_id intel_early_ids[] __initconst = {
- INTEL_I830_IDS(&i830_early_ops),
- INTEL_I845G_IDS(&i845_early_ops),
- INTEL_I85X_IDS(&i85x_early_ops),
- INTEL_I865G_IDS(&i865_early_ops),
- INTEL_I915G_IDS(&gen3_early_ops),
- INTEL_I915GM_IDS(&gen3_early_ops),
- INTEL_I945G_IDS(&gen3_early_ops),
- INTEL_I945GM_IDS(&gen3_early_ops),
- INTEL_VLV_IDS(&gen6_early_ops),
- INTEL_PINEVIEW_G_IDS(&gen3_early_ops),
- INTEL_PINEVIEW_M_IDS(&gen3_early_ops),
- INTEL_I965G_IDS(&gen3_early_ops),
- INTEL_G33_IDS(&gen3_early_ops),
- INTEL_I965GM_IDS(&gen3_early_ops),
- INTEL_GM45_IDS(&gen3_early_ops),
- INTEL_G45_IDS(&gen3_early_ops),
- INTEL_IRONLAKE_D_IDS(&gen3_early_ops),
- INTEL_IRONLAKE_M_IDS(&gen3_early_ops),
- INTEL_SNB_D_IDS(&gen6_early_ops),
- INTEL_SNB_M_IDS(&gen6_early_ops),
- INTEL_IVB_M_IDS(&gen6_early_ops),
- INTEL_IVB_D_IDS(&gen6_early_ops),
- INTEL_HSW_IDS(&gen6_early_ops),
- INTEL_BDW_IDS(&gen8_early_ops),
- INTEL_CHV_IDS(&chv_early_ops),
- INTEL_SKL_IDS(&gen9_early_ops),
- INTEL_BXT_IDS(&gen9_early_ops),
- INTEL_KBL_IDS(&gen9_early_ops),
- INTEL_CFL_IDS(&gen9_early_ops),
- INTEL_GLK_IDS(&gen9_early_ops),
- INTEL_CNL_IDS(&gen9_early_ops),
- INTEL_ICL_11_IDS(&gen11_early_ops),
- INTEL_EHL_IDS(&gen11_early_ops),
- INTEL_JSL_IDS(&gen11_early_ops),
- INTEL_TGL_12_IDS(&gen11_early_ops),
- INTEL_RKL_IDS(&gen11_early_ops),
- INTEL_ADLS_IDS(&gen11_early_ops),
- INTEL_ADLP_IDS(&gen11_early_ops),
- INTEL_ADLN_IDS(&gen11_early_ops),
- INTEL_RPLS_IDS(&gen11_early_ops),
- INTEL_RPLP_IDS(&gen11_early_ops),
+ INTEL_I830_IDS(INTEL_VGA_DEVICE, &i830_early_ops),
+ INTEL_I845G_IDS(INTEL_VGA_DEVICE, &i845_early_ops),
+ INTEL_I85X_IDS(INTEL_VGA_DEVICE, &i85x_early_ops),
+ INTEL_I865G_IDS(INTEL_VGA_DEVICE, &i865_early_ops),
+ INTEL_I915G_IDS(INTEL_VGA_DEVICE, &gen3_early_ops),
+ INTEL_I915GM_IDS(INTEL_VGA_DEVICE, &gen3_early_ops),
+ INTEL_I945G_IDS(INTEL_VGA_DEVICE, &gen3_early_ops),
+ INTEL_I945GM_IDS(INTEL_VGA_DEVICE, &gen3_early_ops),
+ INTEL_VLV_IDS(INTEL_VGA_DEVICE, &gen6_early_ops),
+ INTEL_PNV_IDS(INTEL_VGA_DEVICE, &gen3_early_ops),
+ INTEL_I965G_IDS(INTEL_VGA_DEVICE, &gen3_early_ops),
+ INTEL_G33_IDS(INTEL_VGA_DEVICE, &gen3_early_ops),
+ INTEL_I965GM_IDS(INTEL_VGA_DEVICE, &gen3_early_ops),
+ INTEL_GM45_IDS(INTEL_VGA_DEVICE, &gen3_early_ops),
+ INTEL_G45_IDS(INTEL_VGA_DEVICE, &gen3_early_ops),
+ INTEL_ILK_IDS(INTEL_VGA_DEVICE, &gen3_early_ops),
+ INTEL_SNB_IDS(INTEL_VGA_DEVICE, &gen6_early_ops),
+ INTEL_IVB_IDS(INTEL_VGA_DEVICE, &gen6_early_ops),
+ INTEL_HSW_IDS(INTEL_VGA_DEVICE, &gen6_early_ops),
+ INTEL_BDW_IDS(INTEL_VGA_DEVICE, &gen8_early_ops),
+ INTEL_CHV_IDS(INTEL_VGA_DEVICE, &chv_early_ops),
+ INTEL_SKL_IDS(INTEL_VGA_DEVICE, &gen9_early_ops),
+ INTEL_BXT_IDS(INTEL_VGA_DEVICE, &gen9_early_ops),
+ INTEL_KBL_IDS(INTEL_VGA_DEVICE, &gen9_early_ops),
+ INTEL_CFL_IDS(INTEL_VGA_DEVICE, &gen9_early_ops),
+ INTEL_WHL_IDS(INTEL_VGA_DEVICE, &gen9_early_ops),
+ INTEL_CML_IDS(INTEL_VGA_DEVICE, &gen9_early_ops),
+ INTEL_GLK_IDS(INTEL_VGA_DEVICE, &gen9_early_ops),
+ INTEL_CNL_IDS(INTEL_VGA_DEVICE, &gen9_early_ops),
+ INTEL_ICL_IDS(INTEL_VGA_DEVICE, &gen11_early_ops),
+ INTEL_EHL_IDS(INTEL_VGA_DEVICE, &gen11_early_ops),
+ INTEL_JSL_IDS(INTEL_VGA_DEVICE, &gen11_early_ops),
+ INTEL_TGL_IDS(INTEL_VGA_DEVICE, &gen11_early_ops),
+ INTEL_RKL_IDS(INTEL_VGA_DEVICE, &gen11_early_ops),
+ INTEL_ADLS_IDS(INTEL_VGA_DEVICE, &gen11_early_ops),
+ INTEL_ADLP_IDS(INTEL_VGA_DEVICE, &gen11_early_ops),
+ INTEL_ADLN_IDS(INTEL_VGA_DEVICE, &gen11_early_ops),
+ INTEL_RPLS_IDS(INTEL_VGA_DEVICE, &gen11_early_ops),
+ INTEL_RPLU_IDS(INTEL_VGA_DEVICE, &gen11_early_ops),
+ INTEL_RPLP_IDS(INTEL_VGA_DEVICE, &gen11_early_ops),
};
struct resource intel_graphics_stolen_res __ro_after_init = DEFINE_RES_MEM(0, 0);
diff --git a/drivers/accel/ivpu/Makefile b/drivers/accel/ivpu/Makefile
index 95ff7ad16338..ebd682a42eb1 100644
--- a/drivers/accel/ivpu/Makefile
+++ b/drivers/accel/ivpu/Makefile
@@ -1,19 +1,22 @@
# SPDX-License-Identifier: GPL-2.0-only
-# Copyright (C) 2023 Intel Corporation
+# Copyright (C) 2023-2024 Intel Corporation
intel_vpu-y := \
ivpu_drv.o \
ivpu_fw.o \
ivpu_fw_log.o \
ivpu_gem.o \
- ivpu_hw_37xx.o \
- ivpu_hw_40xx.o \
+ ivpu_hw.o \
+ ivpu_hw_btrs.o \
+ ivpu_hw_ip.o \
ivpu_ipc.o \
ivpu_job.o \
ivpu_jsm_msg.o \
ivpu_mmu.o \
ivpu_mmu_context.o \
- ivpu_pm.o
+ ivpu_ms.o \
+ ivpu_pm.o \
+ ivpu_sysfs.o
intel_vpu-$(CONFIG_DEBUG_FS) += ivpu_debugfs.o
diff --git a/drivers/accel/ivpu/ivpu_debugfs.c b/drivers/accel/ivpu/ivpu_debugfs.c
index e07e447d08d1..6f86f8df30db 100644
--- a/drivers/accel/ivpu/ivpu_debugfs.c
+++ b/drivers/accel/ivpu/ivpu_debugfs.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2020-2023 Intel Corporation
+ * Copyright (C) 2020-2024 Intel Corporation
*/
#include <linux/debugfs.h>
@@ -145,6 +145,30 @@ static const struct file_operations dvfs_mode_fops = {
.write = dvfs_mode_fops_write,
};
+static ssize_t
+fw_dyndbg_fops_write(struct file *file, const char __user *user_buf, size_t size, loff_t *pos)
+{
+ struct ivpu_device *vdev = file->private_data;
+ char buffer[VPU_DYNDBG_CMD_MAX_LEN] = {};
+ int ret;
+
+ if (size >= VPU_DYNDBG_CMD_MAX_LEN)
+ return -EINVAL;
+
+ ret = strncpy_from_user(buffer, user_buf, size);
+ if (ret < 0)
+ return ret;
+
+ ivpu_jsm_dyndbg_control(vdev, buffer, size);
+ return size;
+}
+
+static const struct file_operations fw_dyndbg_fops = {
+ .owner = THIS_MODULE,
+ .open = simple_open,
+ .write = fw_dyndbg_fops_write,
+};
+
static int fw_log_show(struct seq_file *s, void *v)
{
struct ivpu_device *vdev = s->private;
@@ -335,6 +359,61 @@ static const struct file_operations ivpu_reset_engine_fops = {
.write = ivpu_reset_engine_fn,
};
+static ssize_t
+ivpu_resume_engine_fn(struct file *file, const char __user *user_buf, size_t size, loff_t *pos)
+{
+ struct ivpu_device *vdev = file->private_data;
+
+ if (!size)
+ return -EINVAL;
+
+ if (ivpu_jsm_hws_resume_engine(vdev, DRM_IVPU_ENGINE_COMPUTE))
+ return -ENODEV;
+ if (ivpu_jsm_hws_resume_engine(vdev, DRM_IVPU_ENGINE_COPY))
+ return -ENODEV;
+
+ return size;
+}
+
+static const struct file_operations ivpu_resume_engine_fops = {
+ .owner = THIS_MODULE,
+ .open = simple_open,
+ .write = ivpu_resume_engine_fn,
+};
+
+static int dct_active_get(void *data, u64 *active_percent)
+{
+ struct ivpu_device *vdev = data;
+
+ *active_percent = vdev->pm->dct_active_percent;
+
+ return 0;
+}
+
+static int dct_active_set(void *data, u64 active_percent)
+{
+ struct ivpu_device *vdev = data;
+ int ret;
+
+ if (active_percent > 100)
+ return -EINVAL;
+
+ ret = ivpu_rpm_get(vdev);
+ if (ret)
+ return ret;
+
+ if (active_percent)
+ ret = ivpu_pm_dct_enable(vdev, active_percent);
+ else
+ ret = ivpu_pm_dct_disable(vdev);
+
+ ivpu_rpm_put(vdev);
+
+ return ret;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(ivpu_dct_fops, dct_active_get, dct_active_set, "%llu\n");
+
void ivpu_debugfs_init(struct ivpu_device *vdev)
{
struct dentry *debugfs_root = vdev->drm.debugfs_root;
@@ -347,6 +426,8 @@ void ivpu_debugfs_init(struct ivpu_device *vdev)
debugfs_create_file("dvfs_mode", 0200, debugfs_root, vdev,
&dvfs_mode_fops);
+ debugfs_create_file("fw_dyndbg", 0200, debugfs_root, vdev,
+ &fw_dyndbg_fops);
debugfs_create_file("fw_log", 0644, debugfs_root, vdev,
&fw_log_fops);
debugfs_create_file("fw_trace_destination_mask", 0200, debugfs_root, vdev,
@@ -358,8 +439,12 @@ void ivpu_debugfs_init(struct ivpu_device *vdev)
debugfs_create_file("reset_engine", 0200, debugfs_root, vdev,
&ivpu_reset_engine_fops);
+ debugfs_create_file("resume_engine", 0200, debugfs_root, vdev,
+ &ivpu_resume_engine_fops);
- if (ivpu_hw_gen(vdev) >= IVPU_HW_40XX)
+ if (ivpu_hw_ip_gen(vdev) >= IVPU_HW_IP_40XX) {
debugfs_create_file("fw_profiling_freq_drive", 0200,
debugfs_root, vdev, &fw_profiling_freq_fops);
+ debugfs_create_file("dct", 0644, debugfs_root, vdev, &ivpu_dct_fops);
+ }
}
diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c
index 51d3f1a55d02..c91400ecf926 100644
--- a/drivers/accel/ivpu/ivpu_drv.c
+++ b/drivers/accel/ivpu/ivpu_drv.c
@@ -26,7 +26,9 @@
#include "ivpu_jsm_msg.h"
#include "ivpu_mmu.h"
#include "ivpu_mmu_context.h"
+#include "ivpu_ms.h"
#include "ivpu_pm.h"
+#include "ivpu_sysfs.h"
#ifndef DRIVER_VERSION_STR
#define DRIVER_VERSION_STR __stringify(DRM_IVPU_DRIVER_MAJOR) "." \
@@ -51,10 +53,18 @@ u8 ivpu_pll_max_ratio = U8_MAX;
module_param_named(pll_max_ratio, ivpu_pll_max_ratio, byte, 0644);
MODULE_PARM_DESC(pll_max_ratio, "Maximum PLL ratio used to set NPU frequency");
+int ivpu_sched_mode;
+module_param_named(sched_mode, ivpu_sched_mode, int, 0444);
+MODULE_PARM_DESC(sched_mode, "Scheduler mode: 0 - Default scheduler, 1 - Force HW scheduler");
+
bool ivpu_disable_mmu_cont_pages;
-module_param_named(disable_mmu_cont_pages, ivpu_disable_mmu_cont_pages, bool, 0644);
+module_param_named(disable_mmu_cont_pages, ivpu_disable_mmu_cont_pages, bool, 0444);
MODULE_PARM_DESC(disable_mmu_cont_pages, "Disable MMU contiguous pages optimization");
+bool ivpu_force_snoop;
+module_param_named(force_snoop, ivpu_force_snoop, bool, 0444);
+MODULE_PARM_DESC(force_snoop, "Force snooping for NPU host memory access");
+
struct ivpu_file_priv *ivpu_file_priv_get(struct ivpu_file_priv *file_priv)
{
struct ivpu_device *vdev = file_priv->vdev;
@@ -74,7 +84,6 @@ static void file_priv_unbind(struct ivpu_device *vdev, struct ivpu_file_priv *fi
ivpu_dbg(vdev, FILE, "file_priv unbind: ctx %u\n", file_priv->ctx.id);
ivpu_cmdq_release_all_locked(file_priv);
- ivpu_jsm_context_release(vdev, file_priv->ctx.id);
ivpu_bo_unbind_all_bos_from_context(vdev, &file_priv->ctx);
ivpu_mmu_user_context_fini(vdev, &file_priv->ctx);
file_priv->bound = false;
@@ -97,6 +106,7 @@ static void file_priv_release(struct kref *ref)
mutex_unlock(&vdev->context_list_lock);
pm_runtime_put_autosuspend(vdev->drm.dev);
+ mutex_destroy(&file_priv->ms_lock);
mutex_destroy(&file_priv->lock);
kfree(file_priv);
}
@@ -119,7 +129,7 @@ static int ivpu_get_capabilities(struct ivpu_device *vdev, struct drm_ivpu_param
{
switch (args->index) {
case DRM_IVPU_CAP_METRIC_STREAMER:
- args->value = 0;
+ args->value = 1;
break;
case DRM_IVPU_CAP_DMA_MEMORY_RANGE:
args->value = 1;
@@ -228,10 +238,13 @@ static int ivpu_open(struct drm_device *dev, struct drm_file *file)
goto err_dev_exit;
}
+ INIT_LIST_HEAD(&file_priv->ms_instance_list);
+
file_priv->vdev = vdev;
file_priv->bound = true;
kref_init(&file_priv->ref);
mutex_init(&file_priv->lock);
+ mutex_init(&file_priv->ms_lock);
mutex_lock(&vdev->context_list_lock);
@@ -260,6 +273,7 @@ err_xa_erase:
xa_erase_irq(&vdev->context_xa, ctx_id);
err_unlock:
mutex_unlock(&vdev->context_list_lock);
+ mutex_destroy(&file_priv->ms_lock);
mutex_destroy(&file_priv->lock);
kfree(file_priv);
err_dev_exit:
@@ -275,6 +289,7 @@ static void ivpu_postclose(struct drm_device *dev, struct drm_file *file)
ivpu_dbg(vdev, FILE, "file_priv close: ctx %u process %s pid %d\n",
file_priv->ctx.id, current->comm, task_pid_nr(current));
+ ivpu_ms_cleanup(file_priv);
ivpu_file_priv_put(&file_priv);
}
@@ -285,6 +300,10 @@ static const struct drm_ioctl_desc ivpu_drm_ioctls[] = {
DRM_IOCTL_DEF_DRV(IVPU_BO_INFO, ivpu_bo_info_ioctl, 0),
DRM_IOCTL_DEF_DRV(IVPU_SUBMIT, ivpu_submit_ioctl, 0),
DRM_IOCTL_DEF_DRV(IVPU_BO_WAIT, ivpu_bo_wait_ioctl, 0),
+ DRM_IOCTL_DEF_DRV(IVPU_METRIC_STREAMER_START, ivpu_ms_start_ioctl, 0),
+ DRM_IOCTL_DEF_DRV(IVPU_METRIC_STREAMER_GET_DATA, ivpu_ms_get_data_ioctl, 0),
+ DRM_IOCTL_DEF_DRV(IVPU_METRIC_STREAMER_STOP, ivpu_ms_stop_ioctl, 0),
+ DRM_IOCTL_DEF_DRV(IVPU_METRIC_STREAMER_GET_INFO, ivpu_ms_get_info_ioctl, 0),
};
static int ivpu_wait_for_ready(struct ivpu_device *vdev)
@@ -301,7 +320,7 @@ static int ivpu_wait_for_ready(struct ivpu_device *vdev)
timeout = jiffies + msecs_to_jiffies(vdev->timeout.boot);
while (1) {
- ivpu_ipc_irq_handler(vdev, NULL);
+ ivpu_ipc_irq_handler(vdev);
ret = ivpu_ipc_receive(vdev, &cons, &ipc_hdr, NULL, 0);
if (ret != -ETIMEDOUT || time_after_eq(jiffies, timeout))
break;
@@ -323,6 +342,21 @@ static int ivpu_wait_for_ready(struct ivpu_device *vdev)
return ret;
}
+static int ivpu_hw_sched_init(struct ivpu_device *vdev)
+{
+ int ret = 0;
+
+ if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW) {
+ ret = ivpu_jsm_hws_setup_priority_bands(vdev);
+ if (ret) {
+ ivpu_err(vdev, "Failed to enable hw scheduler: %d", ret);
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
/**
* ivpu_boot() - Start VPU firmware
* @vdev: VPU device
@@ -356,6 +390,15 @@ int ivpu_boot(struct ivpu_device *vdev)
enable_irq(vdev->irq);
ivpu_hw_irq_enable(vdev);
ivpu_ipc_enable(vdev);
+
+ if (ivpu_fw_is_cold_boot(vdev)) {
+ ret = ivpu_pm_dct_init(vdev);
+ if (ret)
+ return ret;
+
+ return ivpu_hw_sched_init(vdev);
+ }
+
return 0;
}
@@ -408,11 +451,52 @@ static const struct drm_driver driver = {
.minor = DRM_IVPU_DRIVER_MINOR,
};
+static void ivpu_context_abort_invalid(struct ivpu_device *vdev)
+{
+ struct ivpu_file_priv *file_priv;
+ unsigned long ctx_id;
+
+ mutex_lock(&vdev->context_list_lock);
+
+ xa_for_each(&vdev->context_xa, ctx_id, file_priv) {
+ if (!file_priv->has_mmu_faults || file_priv->aborted)
+ continue;
+
+ mutex_lock(&file_priv->lock);
+ ivpu_context_abort_locked(file_priv);
+ file_priv->aborted = true;
+ mutex_unlock(&file_priv->lock);
+ }
+
+ mutex_unlock(&vdev->context_list_lock);
+}
+
static irqreturn_t ivpu_irq_thread_handler(int irq, void *arg)
{
struct ivpu_device *vdev = arg;
+ u8 irq_src;
+
+ if (kfifo_is_empty(&vdev->hw->irq.fifo))
+ return IRQ_NONE;
- return ivpu_ipc_irq_thread_handler(vdev);
+ while (kfifo_get(&vdev->hw->irq.fifo, &irq_src)) {
+ switch (irq_src) {
+ case IVPU_HW_IRQ_SRC_IPC:
+ ivpu_ipc_irq_thread_handler(vdev);
+ break;
+ case IVPU_HW_IRQ_SRC_MMU_EVTQ:
+ ivpu_context_abort_invalid(vdev);
+ break;
+ case IVPU_HW_IRQ_SRC_DCT:
+ ivpu_pm_dct_irq_thread_handler(vdev);
+ break;
+ default:
+ ivpu_err_ratelimited(vdev, "Unknown IRQ source: %u\n", irq_src);
+ break;
+ }
+ }
+
+ return IRQ_HANDLED;
}
static int ivpu_irq_init(struct ivpu_device *vdev)
@@ -426,9 +510,11 @@ static int ivpu_irq_init(struct ivpu_device *vdev)
return ret;
}
+ ivpu_irq_handlers_init(vdev);
+
vdev->irq = pci_irq_vector(pdev, 0);
- ret = devm_request_threaded_irq(vdev->drm.dev, vdev->irq, vdev->hw->ops->irq_handler,
+ ret = devm_request_threaded_irq(vdev->drm.dev, vdev->irq, ivpu_hw_irq_handler,
ivpu_irq_thread_handler, IRQF_NO_AUTOEN, DRIVER_NAME, vdev);
if (ret)
ivpu_err(vdev, "Failed to request an IRQ %d\n", ret);
@@ -505,13 +591,10 @@ static int ivpu_dev_init(struct ivpu_device *vdev)
if (!vdev->pm)
return -ENOMEM;
- if (ivpu_hw_gen(vdev) >= IVPU_HW_40XX) {
- vdev->hw->ops = &ivpu_hw_40xx_ops;
+ if (ivpu_hw_ip_gen(vdev) >= IVPU_HW_IP_40XX)
vdev->hw->dma_bits = 48;
- } else {
- vdev->hw->ops = &ivpu_hw_37xx_ops;
+ else
vdev->hw->dma_bits = 38;
- }
vdev->platform = IVPU_PLATFORM_INVALID;
vdev->context_xa_limit.min = IVPU_USER_CONTEXT_MIN_SSID;
@@ -540,7 +623,7 @@ static int ivpu_dev_init(struct ivpu_device *vdev)
goto err_xa_destroy;
/* Init basic HW info based on buttress registers which are accessible before power up */
- ret = ivpu_hw_info_init(vdev);
+ ret = ivpu_hw_init(vdev);
if (ret)
goto err_xa_destroy;
@@ -612,13 +695,14 @@ static void ivpu_bo_unbind_all_user_contexts(struct ivpu_device *vdev)
static void ivpu_dev_fini(struct ivpu_device *vdev)
{
+ ivpu_jobs_abort_all(vdev);
+ ivpu_pm_cancel_recovery(vdev);
ivpu_pm_disable(vdev);
ivpu_prepare_for_reset(vdev);
ivpu_shutdown(vdev);
- ivpu_jobs_abort_all(vdev);
+ ivpu_ms_cleanup_all(vdev);
ivpu_job_done_consumer_fini(vdev);
- ivpu_pm_cancel_recovery(vdev);
ivpu_bo_unbind_all_user_contexts(vdev);
ivpu_ipc_fini(vdev);
@@ -658,6 +742,7 @@ static int ivpu_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return ret;
ivpu_debugfs_init(vdev);
+ ivpu_sysfs_init(vdev);
ret = drm_dev_register(&vdev->drm, 0);
if (ret) {
diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h
index bb4374d0eaec..63f13b697eed 100644
--- a/drivers/accel/ivpu/ivpu_drv.h
+++ b/drivers/accel/ivpu/ivpu_drv.h
@@ -27,8 +27,15 @@
#define PCI_DEVICE_ID_ARL 0xad1d
#define PCI_DEVICE_ID_LNL 0x643e
-#define IVPU_HW_37XX 37
-#define IVPU_HW_40XX 40
+#define IVPU_HW_IP_37XX 37
+#define IVPU_HW_IP_40XX 40
+#define IVPU_HW_IP_50XX 50
+#define IVPU_HW_IP_60XX 60
+
+#define IVPU_HW_IP_REV_LNL_B0 4
+
+#define IVPU_HW_BTRS_MTL 1
+#define IVPU_HW_BTRS_LNL 2
#define IVPU_GLOBAL_CONTEXT_MMU_SSID 0
/* SSID 1 is used by the VPU to represent reserved context */
@@ -39,7 +46,11 @@
#define IVPU_MIN_DB 1
#define IVPU_MAX_DB 255
-#define IVPU_NUM_ENGINES 2
+#define IVPU_NUM_ENGINES 2
+#define IVPU_NUM_PRIORITIES 4
+#define IVPU_NUM_CMDQS_PER_CTX (IVPU_NUM_ENGINES * IVPU_NUM_PRIORITIES)
+
+#define IVPU_CMDQ_INDEX(engine, priority) ((engine) * IVPU_NUM_PRIORITIES + (priority))
#define IVPU_PLATFORM_SILICON 0
#define IVPU_PLATFORM_SIMICS 2
@@ -93,6 +104,7 @@ struct ivpu_wa_table {
bool interrupt_clear_with_0;
bool disable_clock_relinquish;
bool disable_d0i3_msg;
+ bool wp0_during_power_up;
};
struct ivpu_hw_info;
@@ -131,11 +143,13 @@ struct ivpu_device {
atomic64_t unique_id_counter;
+ ktime_t busy_start_ts;
+ ktime_t busy_time;
+
struct {
int boot;
int jsm;
int tdr;
- int reschedule_suspend;
int autosuspend;
int d0i3_entry_msg;
} timeout;
@@ -149,22 +163,31 @@ struct ivpu_file_priv {
struct kref ref;
struct ivpu_device *vdev;
struct mutex lock; /* Protects cmdq */
- struct ivpu_cmdq *cmdq[IVPU_NUM_ENGINES];
+ struct ivpu_cmdq *cmdq[IVPU_NUM_CMDQS_PER_CTX];
struct ivpu_mmu_context ctx;
+ struct mutex ms_lock; /* Protects ms_instance_list, ms_info_bo */
+ struct list_head ms_instance_list;
+ struct ivpu_bo *ms_info_bo;
bool has_mmu_faults;
bool bound;
+ bool aborted;
};
extern int ivpu_dbg_mask;
extern u8 ivpu_pll_min_ratio;
extern u8 ivpu_pll_max_ratio;
+extern int ivpu_sched_mode;
extern bool ivpu_disable_mmu_cont_pages;
+extern bool ivpu_force_snoop;
#define IVPU_TEST_MODE_FW_TEST BIT(0)
#define IVPU_TEST_MODE_NULL_HW BIT(1)
#define IVPU_TEST_MODE_NULL_SUBMISSION BIT(2)
#define IVPU_TEST_MODE_D0I3_MSG_DISABLE BIT(4)
#define IVPU_TEST_MODE_D0I3_MSG_ENABLE BIT(5)
+#define IVPU_TEST_MODE_PREEMPTION_DISABLE BIT(6)
+#define IVPU_TEST_MODE_HWS_EXTRA_EVENTS BIT(7)
+#define IVPU_TEST_MODE_DISABLE_TIMEOUTS BIT(8)
extern int ivpu_test_mode;
struct ivpu_file_priv *ivpu_file_priv_get(struct ivpu_file_priv *file_priv);
@@ -184,16 +207,32 @@ static inline u16 ivpu_device_id(struct ivpu_device *vdev)
return to_pci_dev(vdev->drm.dev)->device;
}
-static inline int ivpu_hw_gen(struct ivpu_device *vdev)
+static inline int ivpu_hw_ip_gen(struct ivpu_device *vdev)
{
switch (ivpu_device_id(vdev)) {
case PCI_DEVICE_ID_MTL:
case PCI_DEVICE_ID_ARL:
- return IVPU_HW_37XX;
+ return IVPU_HW_IP_37XX;
case PCI_DEVICE_ID_LNL:
- return IVPU_HW_40XX;
+ return IVPU_HW_IP_40XX;
default:
- ivpu_err(vdev, "Unknown NPU device\n");
+ dump_stack();
+ ivpu_err(vdev, "Unknown NPU IP generation\n");
+ return 0;
+ }
+}
+
+static inline int ivpu_hw_btrs_gen(struct ivpu_device *vdev)
+{
+ switch (ivpu_device_id(vdev)) {
+ case PCI_DEVICE_ID_MTL:
+ case PCI_DEVICE_ID_ARL:
+ return IVPU_HW_BTRS_MTL;
+ case PCI_DEVICE_ID_LNL:
+ return IVPU_HW_BTRS_LNL;
+ default:
+ dump_stack();
+ ivpu_err(vdev, "Unknown buttress generation\n");
return 0;
}
}
@@ -231,4 +270,9 @@ static inline bool ivpu_is_fpga(struct ivpu_device *vdev)
return ivpu_get_platform(vdev) == IVPU_PLATFORM_FPGA;
}
+static inline bool ivpu_is_force_snoop_enabled(struct ivpu_device *vdev)
+{
+ return ivpu_force_snoop;
+}
+
#endif /* __IVPU_DRV_H__ */
diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c
index 1457300828bf..de3d66116375 100644
--- a/drivers/accel/ivpu/ivpu_fw.c
+++ b/drivers/accel/ivpu/ivpu_fw.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2020-2023 Intel Corporation
+ * Copyright (C) 2020-2024 Intel Corporation
*/
#include <linux/firmware.h>
@@ -44,6 +44,8 @@
#define IVPU_FW_CHECK_API_VER_LT(vdev, fw_hdr, name, major, minor) \
ivpu_fw_check_api_ver_lt(vdev, fw_hdr, #name, VPU_##name##_API_VER_INDEX, major, minor)
+#define IVPU_FOCUS_PRESENT_TIMER_MS 1000
+
static char *ivpu_firmware;
module_param_named_unsafe(firmware, ivpu_firmware, charp, 0644);
MODULE_PARM_DESC(firmware, "NPU firmware binary in /lib/firmware/..");
@@ -52,10 +54,10 @@ static struct {
int gen;
const char *name;
} fw_names[] = {
- { IVPU_HW_37XX, "vpu_37xx.bin" },
- { IVPU_HW_37XX, "intel/vpu/vpu_37xx_v0.0.bin" },
- { IVPU_HW_40XX, "vpu_40xx.bin" },
- { IVPU_HW_40XX, "intel/vpu/vpu_40xx_v0.0.bin" },
+ { IVPU_HW_IP_37XX, "vpu_37xx.bin" },
+ { IVPU_HW_IP_37XX, "intel/vpu/vpu_37xx_v0.0.bin" },
+ { IVPU_HW_IP_40XX, "vpu_40xx.bin" },
+ { IVPU_HW_IP_40XX, "intel/vpu/vpu_40xx_v0.0.bin" },
};
static int ivpu_fw_request(struct ivpu_device *vdev)
@@ -71,7 +73,7 @@ static int ivpu_fw_request(struct ivpu_device *vdev)
}
for (i = 0; i < ARRAY_SIZE(fw_names); i++) {
- if (fw_names[i].gen != ivpu_hw_gen(vdev))
+ if (fw_names[i].gen != ivpu_hw_ip_gen(vdev))
continue;
ret = firmware_request_nowarn(&vdev->fw->file, fw_names[i].name, vdev->drm.dev);
@@ -121,6 +123,14 @@ ivpu_fw_check_api_ver_lt(struct ivpu_device *vdev, const struct vpu_firmware_hea
return false;
}
+static bool is_within_range(u64 addr, size_t size, u64 range_start, size_t range_size)
+{
+ if (addr < range_start || addr + size > range_start + range_size)
+ return false;
+
+ return true;
+}
+
static int ivpu_fw_parse(struct ivpu_device *vdev)
{
struct ivpu_fw_info *fw = vdev->fw;
@@ -200,10 +210,27 @@ static int ivpu_fw_parse(struct ivpu_device *vdev)
fw->dvfs_mode = 0;
+ fw->primary_preempt_buf_size = fw_hdr->preemption_buffer_1_size;
+ fw->secondary_preempt_buf_size = fw_hdr->preemption_buffer_2_size;
+
+ if (fw_hdr->ro_section_start_address && !is_within_range(fw_hdr->ro_section_start_address,
+ fw_hdr->ro_section_size,
+ fw_hdr->image_load_address,
+ fw_hdr->image_size)) {
+ ivpu_err(vdev, "Invalid read-only section: start address 0x%llx, size %u\n",
+ fw_hdr->ro_section_start_address, fw_hdr->ro_section_size);
+ return -EINVAL;
+ }
+
+ fw->read_only_addr = fw_hdr->ro_section_start_address;
+ fw->read_only_size = fw_hdr->ro_section_size;
+
ivpu_dbg(vdev, FW_BOOT, "Size: file %lu image %u runtime %u shavenn %u\n",
fw->file->size, fw->image_size, fw->runtime_size, fw->shave_nn_size);
ivpu_dbg(vdev, FW_BOOT, "Address: runtime 0x%llx, load 0x%llx, entry point 0x%llx\n",
fw->runtime_addr, image_load_addr, fw->entry_point);
+ ivpu_dbg(vdev, FW_BOOT, "Read-only section: address 0x%llx, size %u\n",
+ fw->read_only_addr, fw->read_only_size);
return 0;
}
@@ -241,7 +268,7 @@ static int ivpu_fw_update_global_range(struct ivpu_device *vdev)
return -EINVAL;
}
- ivpu_hw_init_range(&vdev->hw->ranges.global, start, size);
+ ivpu_hw_range_init(&vdev->hw->ranges.global, start, size);
return 0;
}
@@ -265,6 +292,13 @@ static int ivpu_fw_mem_init(struct ivpu_device *vdev)
return -ENOMEM;
}
+ ret = ivpu_mmu_context_set_pages_ro(vdev, &vdev->gctx, fw->read_only_addr,
+ fw->read_only_size);
+ if (ret) {
+ ivpu_err(vdev, "Failed to set firmware image read-only\n");
+ goto err_free_fw_mem;
+ }
+
fw->mem_log_crit = ivpu_bo_create_global(vdev, IVPU_FW_CRITICAL_BUFFER_SIZE,
DRM_IVPU_BO_CACHED | DRM_IVPU_BO_MAPPABLE);
if (!fw->mem_log_crit) {
@@ -464,6 +498,8 @@ static void ivpu_fw_boot_params_print(struct ivpu_device *vdev, struct vpu_boot_
boot_params->punit_telemetry_sram_size);
ivpu_dbg(vdev, FW_BOOT, "boot_params.vpu_telemetry_enable = 0x%x\n",
boot_params->vpu_telemetry_enable);
+ ivpu_dbg(vdev, FW_BOOT, "boot_params.vpu_scheduling_mode = 0x%x\n",
+ boot_params->vpu_scheduling_mode);
ivpu_dbg(vdev, FW_BOOT, "boot_params.dvfs_mode = %u\n",
boot_params->dvfs_mode);
ivpu_dbg(vdev, FW_BOOT, "boot_params.d0i3_delayed_entry = %d\n",
@@ -504,7 +540,7 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params
boot_params->magic = VPU_BOOT_PARAMS_MAGIC;
boot_params->vpu_id = to_pci_dev(vdev->drm.dev)->bus->number;
- boot_params->frequency = ivpu_hw_reg_pll_freq_get(vdev);
+ boot_params->frequency = ivpu_hw_pll_freq_get(vdev);
/*
* This param is a debug firmware feature. It switches default clock
@@ -561,9 +597,12 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params
boot_params->verbose_tracing_buff_addr = vdev->fw->mem_log_verb->vpu_addr;
boot_params->verbose_tracing_buff_size = ivpu_bo_size(vdev->fw->mem_log_verb);
- boot_params->punit_telemetry_sram_base = ivpu_hw_reg_telemetry_offset_get(vdev);
- boot_params->punit_telemetry_sram_size = ivpu_hw_reg_telemetry_size_get(vdev);
- boot_params->vpu_telemetry_enable = ivpu_hw_reg_telemetry_enable_get(vdev);
+ boot_params->punit_telemetry_sram_base = ivpu_hw_telemetry_offset_get(vdev);
+ boot_params->punit_telemetry_sram_size = ivpu_hw_telemetry_size_get(vdev);
+ boot_params->vpu_telemetry_enable = ivpu_hw_telemetry_enable_get(vdev);
+ boot_params->vpu_scheduling_mode = vdev->hw->sched_mode;
+ if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW)
+ boot_params->vpu_focus_present_timer_ms = IVPU_FOCUS_PRESENT_TIMER_MS;
boot_params->dvfs_mode = vdev->fw->dvfs_mode;
if (!IVPU_WA(disable_d0i3_msg))
boot_params->d0i3_delayed_entry = 1;
diff --git a/drivers/accel/ivpu/ivpu_fw.h b/drivers/accel/ivpu/ivpu_fw.h
index 66b60fa161b5..40d9d17be3f5 100644
--- a/drivers/accel/ivpu/ivpu_fw.h
+++ b/drivers/accel/ivpu/ivpu_fw.h
@@ -28,6 +28,10 @@ struct ivpu_fw_info {
u32 trace_destination_mask;
u64 trace_hw_component_mask;
u32 dvfs_mode;
+ u32 primary_preempt_buf_size;
+ u32 secondary_preempt_buf_size;
+ u64 read_only_addr;
+ u32 read_only_size;
};
int ivpu_fw_init(struct ivpu_device *vdev);
diff --git a/drivers/accel/ivpu/ivpu_gem.h b/drivers/accel/ivpu/ivpu_gem.h
index fb7117c13eec..d975000abd78 100644
--- a/drivers/accel/ivpu/ivpu_gem.h
+++ b/drivers/accel/ivpu/ivpu_gem.h
@@ -60,14 +60,17 @@ static inline u32 ivpu_bo_cache_mode(struct ivpu_bo *bo)
return bo->flags & DRM_IVPU_BO_CACHE_MASK;
}
-static inline bool ivpu_bo_is_snooped(struct ivpu_bo *bo)
+static inline struct ivpu_device *ivpu_bo_to_vdev(struct ivpu_bo *bo)
{
- return ivpu_bo_cache_mode(bo) == DRM_IVPU_BO_CACHED;
+ return to_ivpu_device(bo->base.base.dev);
}
-static inline struct ivpu_device *ivpu_bo_to_vdev(struct ivpu_bo *bo)
+static inline bool ivpu_bo_is_snooped(struct ivpu_bo *bo)
{
- return to_ivpu_device(bo->base.base.dev);
+ if (ivpu_is_force_snoop_enabled(ivpu_bo_to_vdev(bo)))
+ return true;
+
+ return ivpu_bo_cache_mode(bo) == DRM_IVPU_BO_CACHED;
}
static inline void *ivpu_to_cpu_addr(struct ivpu_bo *bo, u32 vpu_addr)
diff --git a/drivers/accel/ivpu/ivpu_hw.c b/drivers/accel/ivpu/ivpu_hw.c
new file mode 100644
index 000000000000..27f0fe4d54e0
--- /dev/null
+++ b/drivers/accel/ivpu/ivpu_hw.c
@@ -0,0 +1,331 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020 - 2024 Intel Corporation
+ */
+
+#include "ivpu_drv.h"
+#include "ivpu_hw.h"
+#include "ivpu_hw_btrs.h"
+#include "ivpu_hw_ip.h"
+
+#include <linux/dmi.h>
+
+static char *platform_to_str(u32 platform)
+{
+ switch (platform) {
+ case IVPU_PLATFORM_SILICON:
+ return "SILICON";
+ case IVPU_PLATFORM_SIMICS:
+ return "SIMICS";
+ case IVPU_PLATFORM_FPGA:
+ return "FPGA";
+ default:
+ return "Invalid platform";
+ }
+}
+
+static const struct dmi_system_id dmi_platform_simulation[] = {
+ {
+ .ident = "Intel Simics",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "lnlrvp"),
+ DMI_MATCH(DMI_BOARD_VERSION, "1.0"),
+ DMI_MATCH(DMI_BOARD_SERIAL, "123456789"),
+ },
+ },
+ {
+ .ident = "Intel Simics",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "Simics"),
+ },
+ },
+ { }
+};
+
+static void platform_init(struct ivpu_device *vdev)
+{
+ if (dmi_check_system(dmi_platform_simulation))
+ vdev->platform = IVPU_PLATFORM_SIMICS;
+ else
+ vdev->platform = IVPU_PLATFORM_SILICON;
+
+ ivpu_dbg(vdev, MISC, "Platform type: %s (%d)\n",
+ platform_to_str(vdev->platform), vdev->platform);
+}
+
+static void wa_init(struct ivpu_device *vdev)
+{
+ vdev->wa.punit_disabled = ivpu_is_fpga(vdev);
+ vdev->wa.clear_runtime_mem = false;
+
+ if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
+ vdev->wa.interrupt_clear_with_0 = ivpu_hw_btrs_irqs_clear_with_0_mtl(vdev);
+
+ if (ivpu_device_id(vdev) == PCI_DEVICE_ID_LNL &&
+ ivpu_revision(vdev) < IVPU_HW_IP_REV_LNL_B0)
+ vdev->wa.disable_clock_relinquish = true;
+
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ vdev->wa.wp0_during_power_up = true;
+
+ IVPU_PRINT_WA(punit_disabled);
+ IVPU_PRINT_WA(clear_runtime_mem);
+ IVPU_PRINT_WA(interrupt_clear_with_0);
+ IVPU_PRINT_WA(disable_clock_relinquish);
+ IVPU_PRINT_WA(wp0_during_power_up);
+}
+
+static void timeouts_init(struct ivpu_device *vdev)
+{
+ if (ivpu_test_mode & IVPU_TEST_MODE_DISABLE_TIMEOUTS) {
+ vdev->timeout.boot = -1;
+ vdev->timeout.jsm = -1;
+ vdev->timeout.tdr = -1;
+ vdev->timeout.autosuspend = -1;
+ vdev->timeout.d0i3_entry_msg = -1;
+ } else if (ivpu_is_fpga(vdev)) {
+ vdev->timeout.boot = 100000;
+ vdev->timeout.jsm = 50000;
+ vdev->timeout.tdr = 2000000;
+ vdev->timeout.autosuspend = -1;
+ vdev->timeout.d0i3_entry_msg = 500;
+ } else if (ivpu_is_simics(vdev)) {
+ vdev->timeout.boot = 50;
+ vdev->timeout.jsm = 500;
+ vdev->timeout.tdr = 10000;
+ vdev->timeout.autosuspend = -1;
+ vdev->timeout.d0i3_entry_msg = 100;
+ } else {
+ vdev->timeout.boot = 1000;
+ vdev->timeout.jsm = 500;
+ vdev->timeout.tdr = 2000;
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ vdev->timeout.autosuspend = 10;
+ else
+ vdev->timeout.autosuspend = 100;
+ vdev->timeout.d0i3_entry_msg = 5;
+ }
+}
+
+static void memory_ranges_init(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) {
+ ivpu_hw_range_init(&vdev->hw->ranges.global, 0x80000000, SZ_512M);
+ ivpu_hw_range_init(&vdev->hw->ranges.user, 0xc0000000, 255 * SZ_1M);
+ ivpu_hw_range_init(&vdev->hw->ranges.shave, 0x180000000, SZ_2G);
+ ivpu_hw_range_init(&vdev->hw->ranges.dma, 0x200000000, SZ_8G);
+ } else {
+ ivpu_hw_range_init(&vdev->hw->ranges.global, 0x80000000, SZ_512M);
+ ivpu_hw_range_init(&vdev->hw->ranges.user, 0x80000000, SZ_256M);
+ ivpu_hw_range_init(&vdev->hw->ranges.shave, 0x80000000 + SZ_256M, SZ_2G - SZ_256M);
+ ivpu_hw_range_init(&vdev->hw->ranges.dma, 0x200000000, SZ_8G);
+ }
+}
+
+static int wp_enable(struct ivpu_device *vdev)
+{
+ return ivpu_hw_btrs_wp_drive(vdev, true);
+}
+
+static int wp_disable(struct ivpu_device *vdev)
+{
+ return ivpu_hw_btrs_wp_drive(vdev, false);
+}
+
+int ivpu_hw_power_up(struct ivpu_device *vdev)
+{
+ int ret;
+
+ if (IVPU_WA(wp0_during_power_up)) {
+ /* WP requests may fail when powering down, so issue WP 0 here */
+ ret = wp_disable(vdev);
+ if (ret)
+ ivpu_warn(vdev, "Failed to disable workpoint: %d\n", ret);
+ }
+
+ ret = ivpu_hw_btrs_d0i3_disable(vdev);
+ if (ret)
+ ivpu_warn(vdev, "Failed to disable D0I3: %d\n", ret);
+
+ ret = wp_enable(vdev);
+ if (ret) {
+ ivpu_err(vdev, "Failed to enable workpoint: %d\n", ret);
+ return ret;
+ }
+
+ if (ivpu_hw_btrs_gen(vdev) >= IVPU_HW_BTRS_LNL) {
+ if (IVPU_WA(disable_clock_relinquish))
+ ivpu_hw_btrs_clock_relinquish_disable_lnl(vdev);
+ ivpu_hw_btrs_profiling_freq_reg_set_lnl(vdev);
+ ivpu_hw_btrs_ats_print_lnl(vdev);
+ }
+
+ ret = ivpu_hw_ip_host_ss_configure(vdev);
+ if (ret) {
+ ivpu_err(vdev, "Failed to configure host SS: %d\n", ret);
+ return ret;
+ }
+
+ ivpu_hw_ip_idle_gen_disable(vdev);
+
+ ret = ivpu_hw_btrs_wait_for_clock_res_own_ack(vdev);
+ if (ret) {
+ ivpu_err(vdev, "Timed out waiting for clock resource own ACK\n");
+ return ret;
+ }
+
+ ret = ivpu_hw_ip_pwr_domain_enable(vdev);
+ if (ret) {
+ ivpu_err(vdev, "Failed to enable power domain: %d\n", ret);
+ return ret;
+ }
+
+ ret = ivpu_hw_ip_host_ss_axi_enable(vdev);
+ if (ret) {
+ ivpu_err(vdev, "Failed to enable AXI: %d\n", ret);
+ return ret;
+ }
+
+ if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_LNL)
+ ivpu_hw_btrs_set_port_arbitration_weights_lnl(vdev);
+
+ ret = ivpu_hw_ip_top_noc_enable(vdev);
+ if (ret)
+ ivpu_err(vdev, "Failed to enable TOP NOC: %d\n", ret);
+
+ return ret;
+}
+
+static void save_d0i3_entry_timestamp(struct ivpu_device *vdev)
+{
+ vdev->hw->d0i3_entry_host_ts = ktime_get_boottime();
+ vdev->hw->d0i3_entry_vpu_ts = ivpu_hw_ip_read_perf_timer_counter(vdev);
+}
+
+int ivpu_hw_reset(struct ivpu_device *vdev)
+{
+ int ret = 0;
+
+ if (ivpu_hw_btrs_ip_reset(vdev)) {
+ ivpu_err(vdev, "Failed to reset NPU IP\n");
+ ret = -EIO;
+ }
+
+ if (wp_disable(vdev)) {
+ ivpu_err(vdev, "Failed to disable workpoint\n");
+ ret = -EIO;
+ }
+
+ return ret;
+}
+
+int ivpu_hw_power_down(struct ivpu_device *vdev)
+{
+ int ret = 0;
+
+ save_d0i3_entry_timestamp(vdev);
+
+ if (!ivpu_hw_is_idle(vdev))
+ ivpu_warn(vdev, "NPU not idle during power down\n");
+
+ if (ivpu_hw_reset(vdev)) {
+ ivpu_err(vdev, "Failed to reset NPU\n");
+ ret = -EIO;
+ }
+
+ if (ivpu_hw_btrs_d0i3_enable(vdev)) {
+ ivpu_err(vdev, "Failed to enter D0I3\n");
+ ret = -EIO;
+ }
+
+ return ret;
+}
+
+int ivpu_hw_init(struct ivpu_device *vdev)
+{
+ ivpu_hw_btrs_info_init(vdev);
+ ivpu_hw_btrs_freq_ratios_init(vdev);
+ memory_ranges_init(vdev);
+ platform_init(vdev);
+ wa_init(vdev);
+ timeouts_init(vdev);
+
+ return 0;
+}
+
+int ivpu_hw_boot_fw(struct ivpu_device *vdev)
+{
+ int ret;
+
+ ivpu_hw_ip_snoop_disable(vdev);
+ ivpu_hw_ip_tbu_mmu_enable(vdev);
+ ret = ivpu_hw_ip_soc_cpu_boot(vdev);
+ if (ret)
+ ivpu_err(vdev, "Failed to boot SOC CPU: %d\n", ret);
+
+ return ret;
+}
+
+void ivpu_hw_profiling_freq_drive(struct ivpu_device *vdev, bool enable)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) {
+ vdev->hw->pll.profiling_freq = PLL_PROFILING_FREQ_DEFAULT;
+ return;
+ }
+
+ if (enable)
+ vdev->hw->pll.profiling_freq = PLL_PROFILING_FREQ_HIGH;
+ else
+ vdev->hw->pll.profiling_freq = PLL_PROFILING_FREQ_DEFAULT;
+}
+
+void ivpu_irq_handlers_init(struct ivpu_device *vdev)
+{
+ INIT_KFIFO(vdev->hw->irq.fifo);
+
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ vdev->hw->irq.ip_irq_handler = ivpu_hw_ip_irq_handler_37xx;
+ else
+ vdev->hw->irq.ip_irq_handler = ivpu_hw_ip_irq_handler_40xx;
+
+ if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
+ vdev->hw->irq.btrs_irq_handler = ivpu_hw_btrs_irq_handler_mtl;
+ else
+ vdev->hw->irq.btrs_irq_handler = ivpu_hw_btrs_irq_handler_lnl;
+}
+
+void ivpu_hw_irq_enable(struct ivpu_device *vdev)
+{
+ kfifo_reset(&vdev->hw->irq.fifo);
+ ivpu_hw_ip_irq_enable(vdev);
+ ivpu_hw_btrs_irq_enable(vdev);
+}
+
+void ivpu_hw_irq_disable(struct ivpu_device *vdev)
+{
+ ivpu_hw_btrs_irq_disable(vdev);
+ ivpu_hw_ip_irq_disable(vdev);
+}
+
+irqreturn_t ivpu_hw_irq_handler(int irq, void *ptr)
+{
+ struct ivpu_device *vdev = ptr;
+ bool ip_handled, btrs_handled;
+
+ ivpu_hw_btrs_global_int_disable(vdev);
+
+ btrs_handled = ivpu_hw_btrs_irq_handler(vdev, irq);
+ if (!ivpu_hw_is_idle((vdev)) || !btrs_handled)
+ ip_handled = ivpu_hw_ip_irq_handler(vdev, irq);
+ else
+ ip_handled = false;
+
+ /* Re-enable global interrupts to re-trigger MSI for pending interrupts */
+ ivpu_hw_btrs_global_int_enable(vdev);
+
+ if (!kfifo_is_empty(&vdev->hw->irq.fifo))
+ return IRQ_WAKE_THREAD;
+ if (ip_handled || btrs_handled)
+ return IRQ_HANDLED;
+ return IRQ_NONE;
+}
diff --git a/drivers/accel/ivpu/ivpu_hw.h b/drivers/accel/ivpu/ivpu_hw.h
index 094c659d2800..1c0c98e3afb8 100644
--- a/drivers/accel/ivpu/ivpu_hw.h
+++ b/drivers/accel/ivpu/ivpu_hw.h
@@ -1,39 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (C) 2020-2023 Intel Corporation
+ * Copyright (C) 2020-2024 Intel Corporation
*/
#ifndef __IVPU_HW_H__
#define __IVPU_HW_H__
+#include <linux/kfifo.h>
+
#include "ivpu_drv.h"
+#include "ivpu_hw_btrs.h"
+#include "ivpu_hw_ip.h"
-struct ivpu_hw_ops {
- int (*info_init)(struct ivpu_device *vdev);
- int (*power_up)(struct ivpu_device *vdev);
- int (*boot_fw)(struct ivpu_device *vdev);
- int (*power_down)(struct ivpu_device *vdev);
- int (*reset)(struct ivpu_device *vdev);
- bool (*is_idle)(struct ivpu_device *vdev);
- int (*wait_for_idle)(struct ivpu_device *vdev);
- void (*wdt_disable)(struct ivpu_device *vdev);
- void (*diagnose_failure)(struct ivpu_device *vdev);
- u32 (*profiling_freq_get)(struct ivpu_device *vdev);
- void (*profiling_freq_drive)(struct ivpu_device *vdev, bool enable);
- u32 (*reg_pll_freq_get)(struct ivpu_device *vdev);
- u32 (*ratio_to_freq)(struct ivpu_device *vdev, u32 ratio);
- u32 (*reg_telemetry_offset_get)(struct ivpu_device *vdev);
- u32 (*reg_telemetry_size_get)(struct ivpu_device *vdev);
- u32 (*reg_telemetry_enable_get)(struct ivpu_device *vdev);
- void (*reg_db_set)(struct ivpu_device *vdev, u32 db_id);
- u32 (*reg_ipc_rx_addr_get)(struct ivpu_device *vdev);
- u32 (*reg_ipc_rx_count_get)(struct ivpu_device *vdev);
- void (*reg_ipc_tx_set)(struct ivpu_device *vdev, u32 vpu_addr);
- void (*irq_clear)(struct ivpu_device *vdev);
- void (*irq_enable)(struct ivpu_device *vdev);
- void (*irq_disable)(struct ivpu_device *vdev);
- irqreturn_t (*irq_handler)(int irq, void *ptr);
-};
+#define IVPU_HW_IRQ_FIFO_LENGTH 1024
+
+#define IVPU_HW_IRQ_SRC_IPC 1
+#define IVPU_HW_IRQ_SRC_MMU_EVTQ 2
+#define IVPU_HW_IRQ_SRC_DCT 3
struct ivpu_addr_range {
resource_size_t start;
@@ -41,7 +24,11 @@ struct ivpu_addr_range {
};
struct ivpu_hw_info {
- const struct ivpu_hw_ops *ops;
+ struct {
+ bool (*btrs_irq_handler)(struct ivpu_device *vdev, int irq);
+ bool (*ip_irq_handler)(struct ivpu_device *vdev, int irq);
+ DECLARE_KFIFO(fifo, u8, IVPU_HW_IRQ_FIFO_LENGTH);
+ } irq;
struct {
struct ivpu_addr_range global;
struct ivpu_addr_range user;
@@ -59,6 +46,7 @@ struct ivpu_hw_info {
u32 profiling_freq;
} pll;
u32 tile_fuse;
+ u32 sched_mode;
u32 sku;
u16 config;
int dma_bits;
@@ -66,140 +54,107 @@ struct ivpu_hw_info {
u64 d0i3_entry_vpu_ts;
};
-extern const struct ivpu_hw_ops ivpu_hw_37xx_ops;
-extern const struct ivpu_hw_ops ivpu_hw_40xx_ops;
-
-static inline int ivpu_hw_info_init(struct ivpu_device *vdev)
-{
- return vdev->hw->ops->info_init(vdev);
-};
-
-static inline int ivpu_hw_power_up(struct ivpu_device *vdev)
-{
- ivpu_dbg(vdev, PM, "HW power up\n");
+int ivpu_hw_init(struct ivpu_device *vdev);
+int ivpu_hw_power_up(struct ivpu_device *vdev);
+int ivpu_hw_power_down(struct ivpu_device *vdev);
+int ivpu_hw_reset(struct ivpu_device *vdev);
+int ivpu_hw_boot_fw(struct ivpu_device *vdev);
+void ivpu_hw_profiling_freq_drive(struct ivpu_device *vdev, bool enable);
+void ivpu_irq_handlers_init(struct ivpu_device *vdev);
+void ivpu_hw_irq_enable(struct ivpu_device *vdev);
+void ivpu_hw_irq_disable(struct ivpu_device *vdev);
+irqreturn_t ivpu_hw_irq_handler(int irq, void *ptr);
- return vdev->hw->ops->power_up(vdev);
-};
-
-static inline int ivpu_hw_boot_fw(struct ivpu_device *vdev)
-{
- return vdev->hw->ops->boot_fw(vdev);
-};
-
-static inline bool ivpu_hw_is_idle(struct ivpu_device *vdev)
-{
- return vdev->hw->ops->is_idle(vdev);
-};
-
-static inline int ivpu_hw_wait_for_idle(struct ivpu_device *vdev)
+static inline u32 ivpu_hw_btrs_irq_handler(struct ivpu_device *vdev, int irq)
{
- return vdev->hw->ops->wait_for_idle(vdev);
-};
-
-static inline int ivpu_hw_power_down(struct ivpu_device *vdev)
-{
- ivpu_dbg(vdev, PM, "HW power down\n");
-
- return vdev->hw->ops->power_down(vdev);
-};
-
-static inline int ivpu_hw_reset(struct ivpu_device *vdev)
-{
- ivpu_dbg(vdev, PM, "HW reset\n");
-
- return vdev->hw->ops->reset(vdev);
-};
-
-static inline void ivpu_hw_wdt_disable(struct ivpu_device *vdev)
-{
- vdev->hw->ops->wdt_disable(vdev);
-};
+ return vdev->hw->irq.btrs_irq_handler(vdev, irq);
+}
-static inline u32 ivpu_hw_profiling_freq_get(struct ivpu_device *vdev)
+static inline u32 ivpu_hw_ip_irq_handler(struct ivpu_device *vdev, int irq)
{
- return vdev->hw->ops->profiling_freq_get(vdev);
-};
+ return vdev->hw->irq.ip_irq_handler(vdev, irq);
+}
-static inline void ivpu_hw_profiling_freq_drive(struct ivpu_device *vdev, bool enable)
+static inline void ivpu_hw_range_init(struct ivpu_addr_range *range, u64 start, u64 size)
{
- return vdev->hw->ops->profiling_freq_drive(vdev, enable);
-};
+ range->start = start;
+ range->end = start + size;
+}
-/* Register indirect accesses */
-static inline u32 ivpu_hw_reg_pll_freq_get(struct ivpu_device *vdev)
+static inline u64 ivpu_hw_range_size(const struct ivpu_addr_range *range)
{
- return vdev->hw->ops->reg_pll_freq_get(vdev);
-};
+ return range->end - range->start;
+}
static inline u32 ivpu_hw_ratio_to_freq(struct ivpu_device *vdev, u32 ratio)
{
- return vdev->hw->ops->ratio_to_freq(vdev, ratio);
+ return ivpu_hw_btrs_ratio_to_freq(vdev, ratio);
}
-static inline u32 ivpu_hw_reg_telemetry_offset_get(struct ivpu_device *vdev)
+static inline void ivpu_hw_irq_clear(struct ivpu_device *vdev)
{
- return vdev->hw->ops->reg_telemetry_offset_get(vdev);
-};
+ ivpu_hw_ip_irq_clear(vdev);
+}
-static inline u32 ivpu_hw_reg_telemetry_size_get(struct ivpu_device *vdev)
+static inline u32 ivpu_hw_pll_freq_get(struct ivpu_device *vdev)
{
- return vdev->hw->ops->reg_telemetry_size_get(vdev);
-};
+ return ivpu_hw_btrs_pll_freq_get(vdev);
+}
-static inline u32 ivpu_hw_reg_telemetry_enable_get(struct ivpu_device *vdev)
+static inline u32 ivpu_hw_profiling_freq_get(struct ivpu_device *vdev)
{
- return vdev->hw->ops->reg_telemetry_enable_get(vdev);
-};
+ return vdev->hw->pll.profiling_freq;
+}
-static inline void ivpu_hw_reg_db_set(struct ivpu_device *vdev, u32 db_id)
+static inline void ivpu_hw_diagnose_failure(struct ivpu_device *vdev)
{
- vdev->hw->ops->reg_db_set(vdev, db_id);
-};
+ ivpu_hw_ip_diagnose_failure(vdev);
+ ivpu_hw_btrs_diagnose_failure(vdev);
+}
-static inline u32 ivpu_hw_reg_ipc_rx_addr_get(struct ivpu_device *vdev)
+static inline u32 ivpu_hw_telemetry_offset_get(struct ivpu_device *vdev)
{
- return vdev->hw->ops->reg_ipc_rx_addr_get(vdev);
-};
+ return ivpu_hw_btrs_telemetry_offset_get(vdev);
+}
-static inline u32 ivpu_hw_reg_ipc_rx_count_get(struct ivpu_device *vdev)
+static inline u32 ivpu_hw_telemetry_size_get(struct ivpu_device *vdev)
{
- return vdev->hw->ops->reg_ipc_rx_count_get(vdev);
-};
+ return ivpu_hw_btrs_telemetry_size_get(vdev);
+}
-static inline void ivpu_hw_reg_ipc_tx_set(struct ivpu_device *vdev, u32 vpu_addr)
+static inline u32 ivpu_hw_telemetry_enable_get(struct ivpu_device *vdev)
{
- vdev->hw->ops->reg_ipc_tx_set(vdev, vpu_addr);
-};
+ return ivpu_hw_btrs_telemetry_enable_get(vdev);
+}
-static inline void ivpu_hw_irq_clear(struct ivpu_device *vdev)
+static inline bool ivpu_hw_is_idle(struct ivpu_device *vdev)
{
- vdev->hw->ops->irq_clear(vdev);
-};
+ return ivpu_hw_btrs_is_idle(vdev);
+}
-static inline void ivpu_hw_irq_enable(struct ivpu_device *vdev)
+static inline int ivpu_hw_wait_for_idle(struct ivpu_device *vdev)
{
- vdev->hw->ops->irq_enable(vdev);
-};
+ return ivpu_hw_btrs_wait_for_idle(vdev);
+}
-static inline void ivpu_hw_irq_disable(struct ivpu_device *vdev)
+static inline void ivpu_hw_ipc_tx_set(struct ivpu_device *vdev, u32 vpu_addr)
{
- vdev->hw->ops->irq_disable(vdev);
-};
+ ivpu_hw_ip_ipc_tx_set(vdev, vpu_addr);
+}
-static inline void ivpu_hw_init_range(struct ivpu_addr_range *range, u64 start, u64 size)
+static inline void ivpu_hw_db_set(struct ivpu_device *vdev, u32 db_id)
{
- range->start = start;
- range->end = start + size;
+ ivpu_hw_ip_db_set(vdev, db_id);
}
-static inline u64 ivpu_hw_range_size(const struct ivpu_addr_range *range)
+static inline u32 ivpu_hw_ipc_rx_addr_get(struct ivpu_device *vdev)
{
- return range->end - range->start;
+ return ivpu_hw_ip_ipc_rx_addr_get(vdev);
}
-static inline void ivpu_hw_diagnose_failure(struct ivpu_device *vdev)
+static inline u32 ivpu_hw_ipc_rx_count_get(struct ivpu_device *vdev)
{
- vdev->hw->ops->diagnose_failure(vdev);
+ return ivpu_hw_ip_ipc_rx_count_get(vdev);
}
#endif /* __IVPU_HW_H__ */
diff --git a/drivers/accel/ivpu/ivpu_hw_37xx.c b/drivers/accel/ivpu/ivpu_hw_37xx.c
deleted file mode 100644
index bd25e2d9fb0f..000000000000
--- a/drivers/accel/ivpu/ivpu_hw_37xx.c
+++ /dev/null
@@ -1,1065 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2020-2024 Intel Corporation
- */
-
-#include "ivpu_drv.h"
-#include "ivpu_fw.h"
-#include "ivpu_hw_37xx_reg.h"
-#include "ivpu_hw_reg_io.h"
-#include "ivpu_hw.h"
-#include "ivpu_ipc.h"
-#include "ivpu_mmu.h"
-#include "ivpu_pm.h"
-
-#define TILE_FUSE_ENABLE_BOTH 0x0
-#define TILE_SKU_BOTH 0x3630
-
-/* Work point configuration values */
-#define CONFIG_1_TILE 0x01
-#define CONFIG_2_TILE 0x02
-#define PLL_RATIO_5_3 0x01
-#define PLL_RATIO_4_3 0x02
-#define WP_CONFIG(tile, ratio) (((tile) << 8) | (ratio))
-#define WP_CONFIG_1_TILE_5_3_RATIO WP_CONFIG(CONFIG_1_TILE, PLL_RATIO_5_3)
-#define WP_CONFIG_1_TILE_4_3_RATIO WP_CONFIG(CONFIG_1_TILE, PLL_RATIO_4_3)
-#define WP_CONFIG_2_TILE_5_3_RATIO WP_CONFIG(CONFIG_2_TILE, PLL_RATIO_5_3)
-#define WP_CONFIG_2_TILE_4_3_RATIO WP_CONFIG(CONFIG_2_TILE, PLL_RATIO_4_3)
-#define WP_CONFIG_0_TILE_PLL_OFF WP_CONFIG(0, 0)
-
-#define PLL_REF_CLK_FREQ (50 * 1000000)
-#define PLL_SIMULATION_FREQ (10 * 1000000)
-#define PLL_PROF_CLK_FREQ (38400 * 1000)
-#define PLL_DEFAULT_EPP_VALUE 0x80
-
-#define TIM_SAFE_ENABLE 0xf1d0dead
-#define TIM_WATCHDOG_RESET_VALUE 0xffffffff
-
-#define TIMEOUT_US (150 * USEC_PER_MSEC)
-#define PWR_ISLAND_STATUS_TIMEOUT_US (5 * USEC_PER_MSEC)
-#define PLL_TIMEOUT_US (1500 * USEC_PER_MSEC)
-#define IDLE_TIMEOUT_US (5 * USEC_PER_MSEC)
-
-#define ICB_0_IRQ_MASK ((REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, HOST_IPC_FIFO_INT)) | \
- (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_0_INT)) | \
- (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_1_INT)) | \
- (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_2_INT)) | \
- (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT)) | \
- (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT)) | \
- (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT)))
-
-#define ICB_1_IRQ_MASK ((REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_2_INT)) | \
- (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_3_INT)) | \
- (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_4_INT)))
-
-#define ICB_0_1_IRQ_MASK ((((u64)ICB_1_IRQ_MASK) << 32) | ICB_0_IRQ_MASK)
-
-#define BUTTRESS_IRQ_MASK ((REG_FLD(VPU_37XX_BUTTRESS_INTERRUPT_STAT, ATS_ERR)) | \
- (REG_FLD(VPU_37XX_BUTTRESS_INTERRUPT_STAT, UFI_ERR)))
-
-#define BUTTRESS_ALL_IRQ_MASK (BUTTRESS_IRQ_MASK | \
- (REG_FLD(VPU_37XX_BUTTRESS_INTERRUPT_STAT, FREQ_CHANGE)))
-
-#define BUTTRESS_IRQ_ENABLE_MASK ((u32)~BUTTRESS_IRQ_MASK)
-#define BUTTRESS_IRQ_DISABLE_MASK ((u32)-1)
-
-#define ITF_FIREWALL_VIOLATION_MASK ((REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, CSS_ROM_CMX)) | \
- (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, CSS_DBG)) | \
- (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, CSS_CTRL)) | \
- (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, DEC400)) | \
- (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, MSS_NCE)) | \
- (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, MSS_MBI)) | \
- (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, MSS_MBI_CMX)))
-
-static void ivpu_hw_wa_init(struct ivpu_device *vdev)
-{
- vdev->wa.punit_disabled = false;
- vdev->wa.clear_runtime_mem = false;
-
- REGB_WR32(VPU_37XX_BUTTRESS_INTERRUPT_STAT, BUTTRESS_ALL_IRQ_MASK);
- if (REGB_RD32(VPU_37XX_BUTTRESS_INTERRUPT_STAT) == BUTTRESS_ALL_IRQ_MASK) {
- /* Writing 1s does not clear the interrupt status register */
- vdev->wa.interrupt_clear_with_0 = true;
- REGB_WR32(VPU_37XX_BUTTRESS_INTERRUPT_STAT, 0x0);
- }
-
- IVPU_PRINT_WA(punit_disabled);
- IVPU_PRINT_WA(clear_runtime_mem);
- IVPU_PRINT_WA(interrupt_clear_with_0);
-}
-
-static void ivpu_hw_timeouts_init(struct ivpu_device *vdev)
-{
- vdev->timeout.boot = 1000;
- vdev->timeout.jsm = 500;
- vdev->timeout.tdr = 2000;
- vdev->timeout.reschedule_suspend = 10;
- vdev->timeout.autosuspend = 10;
- vdev->timeout.d0i3_entry_msg = 5;
-}
-
-static int ivpu_pll_wait_for_cmd_send(struct ivpu_device *vdev)
-{
- return REGB_POLL_FLD(VPU_37XX_BUTTRESS_WP_REQ_CMD, SEND, 0, PLL_TIMEOUT_US);
-}
-
-/* Send KMD initiated workpoint change */
-static int ivpu_pll_cmd_send(struct ivpu_device *vdev, u16 min_ratio, u16 max_ratio,
- u16 target_ratio, u16 config)
-{
- int ret;
- u32 val;
-
- ret = ivpu_pll_wait_for_cmd_send(vdev);
- if (ret) {
- ivpu_err(vdev, "Failed to sync before WP request: %d\n", ret);
- return ret;
- }
-
- val = REGB_RD32(VPU_37XX_BUTTRESS_WP_REQ_PAYLOAD0);
- val = REG_SET_FLD_NUM(VPU_37XX_BUTTRESS_WP_REQ_PAYLOAD0, MIN_RATIO, min_ratio, val);
- val = REG_SET_FLD_NUM(VPU_37XX_BUTTRESS_WP_REQ_PAYLOAD0, MAX_RATIO, max_ratio, val);
- REGB_WR32(VPU_37XX_BUTTRESS_WP_REQ_PAYLOAD0, val);
-
- val = REGB_RD32(VPU_37XX_BUTTRESS_WP_REQ_PAYLOAD1);
- val = REG_SET_FLD_NUM(VPU_37XX_BUTTRESS_WP_REQ_PAYLOAD1, TARGET_RATIO, target_ratio, val);
- val = REG_SET_FLD_NUM(VPU_37XX_BUTTRESS_WP_REQ_PAYLOAD1, EPP, PLL_DEFAULT_EPP_VALUE, val);
- REGB_WR32(VPU_37XX_BUTTRESS_WP_REQ_PAYLOAD1, val);
-
- val = REGB_RD32(VPU_37XX_BUTTRESS_WP_REQ_PAYLOAD2);
- val = REG_SET_FLD_NUM(VPU_37XX_BUTTRESS_WP_REQ_PAYLOAD2, CONFIG, config, val);
- REGB_WR32(VPU_37XX_BUTTRESS_WP_REQ_PAYLOAD2, val);
-
- val = REGB_RD32(VPU_37XX_BUTTRESS_WP_REQ_CMD);
- val = REG_SET_FLD(VPU_37XX_BUTTRESS_WP_REQ_CMD, SEND, val);
- REGB_WR32(VPU_37XX_BUTTRESS_WP_REQ_CMD, val);
-
- ret = ivpu_pll_wait_for_cmd_send(vdev);
- if (ret)
- ivpu_err(vdev, "Failed to sync after WP request: %d\n", ret);
-
- return ret;
-}
-
-static int ivpu_pll_wait_for_lock(struct ivpu_device *vdev, bool enable)
-{
- u32 exp_val = enable ? 0x1 : 0x0;
-
- if (IVPU_WA(punit_disabled))
- return 0;
-
- return REGB_POLL_FLD(VPU_37XX_BUTTRESS_PLL_STATUS, LOCK, exp_val, PLL_TIMEOUT_US);
-}
-
-static int ivpu_pll_wait_for_status_ready(struct ivpu_device *vdev)
-{
- if (IVPU_WA(punit_disabled))
- return 0;
-
- return REGB_POLL_FLD(VPU_37XX_BUTTRESS_VPU_STATUS, READY, 1, PLL_TIMEOUT_US);
-}
-
-static void ivpu_pll_init_frequency_ratios(struct ivpu_device *vdev)
-{
- struct ivpu_hw_info *hw = vdev->hw;
- u8 fuse_min_ratio, fuse_max_ratio, fuse_pn_ratio;
- u32 fmin_fuse, fmax_fuse;
-
- fmin_fuse = REGB_RD32(VPU_37XX_BUTTRESS_FMIN_FUSE);
- fuse_min_ratio = REG_GET_FLD(VPU_37XX_BUTTRESS_FMIN_FUSE, MIN_RATIO, fmin_fuse);
- fuse_pn_ratio = REG_GET_FLD(VPU_37XX_BUTTRESS_FMIN_FUSE, PN_RATIO, fmin_fuse);
-
- fmax_fuse = REGB_RD32(VPU_37XX_BUTTRESS_FMAX_FUSE);
- fuse_max_ratio = REG_GET_FLD(VPU_37XX_BUTTRESS_FMAX_FUSE, MAX_RATIO, fmax_fuse);
-
- hw->pll.min_ratio = clamp_t(u8, ivpu_pll_min_ratio, fuse_min_ratio, fuse_max_ratio);
- hw->pll.max_ratio = clamp_t(u8, ivpu_pll_max_ratio, hw->pll.min_ratio, fuse_max_ratio);
- hw->pll.pn_ratio = clamp_t(u8, fuse_pn_ratio, hw->pll.min_ratio, hw->pll.max_ratio);
-}
-
-static int ivpu_hw_37xx_wait_for_vpuip_bar(struct ivpu_device *vdev)
-{
- return REGV_POLL_FLD(VPU_37XX_HOST_SS_CPR_RST_CLR, AON, 0, 100);
-}
-
-static int ivpu_pll_drive(struct ivpu_device *vdev, bool enable)
-{
- struct ivpu_hw_info *hw = vdev->hw;
- u16 target_ratio;
- u16 config;
- int ret;
-
- if (IVPU_WA(punit_disabled)) {
- ivpu_dbg(vdev, PM, "Skipping PLL request\n");
- return 0;
- }
-
- if (enable) {
- target_ratio = hw->pll.pn_ratio;
- config = hw->config;
- } else {
- target_ratio = 0;
- config = 0;
- }
-
- ivpu_dbg(vdev, PM, "PLL workpoint request: config 0x%04x pll ratio 0x%x\n",
- config, target_ratio);
-
- ret = ivpu_pll_cmd_send(vdev, hw->pll.min_ratio, hw->pll.max_ratio, target_ratio, config);
- if (ret) {
- ivpu_err(vdev, "Failed to send PLL workpoint request: %d\n", ret);
- return ret;
- }
-
- ret = ivpu_pll_wait_for_lock(vdev, enable);
- if (ret) {
- ivpu_err(vdev, "Timed out waiting for PLL lock\n");
- return ret;
- }
-
- if (enable) {
- ret = ivpu_pll_wait_for_status_ready(vdev);
- if (ret) {
- ivpu_err(vdev, "Timed out waiting for PLL ready status\n");
- return ret;
- }
-
- ret = ivpu_hw_37xx_wait_for_vpuip_bar(vdev);
- if (ret) {
- ivpu_err(vdev, "Timed out waiting for NPU IP bar\n");
- return ret;
- }
- }
-
- return 0;
-}
-
-static int ivpu_pll_enable(struct ivpu_device *vdev)
-{
- return ivpu_pll_drive(vdev, true);
-}
-
-static int ivpu_pll_disable(struct ivpu_device *vdev)
-{
- return ivpu_pll_drive(vdev, false);
-}
-
-static void ivpu_boot_host_ss_rst_clr_assert(struct ivpu_device *vdev)
-{
- u32 val = 0;
-
- val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_CLR, TOP_NOC, val);
- val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_CLR, DSS_MAS, val);
- val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_CLR, MSS_MAS, val);
-
- REGV_WR32(VPU_37XX_HOST_SS_CPR_RST_CLR, val);
-}
-
-static void ivpu_boot_host_ss_rst_drive(struct ivpu_device *vdev, bool enable)
-{
- u32 val = REGV_RD32(VPU_37XX_HOST_SS_CPR_RST_SET);
-
- if (enable) {
- val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, TOP_NOC, val);
- val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, DSS_MAS, val);
- val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, MSS_MAS, val);
- } else {
- val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, TOP_NOC, val);
- val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, DSS_MAS, val);
- val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, MSS_MAS, val);
- }
-
- REGV_WR32(VPU_37XX_HOST_SS_CPR_RST_SET, val);
-}
-
-static void ivpu_boot_host_ss_clk_drive(struct ivpu_device *vdev, bool enable)
-{
- u32 val = REGV_RD32(VPU_37XX_HOST_SS_CPR_CLK_SET);
-
- if (enable) {
- val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, TOP_NOC, val);
- val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, DSS_MAS, val);
- val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, MSS_MAS, val);
- } else {
- val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, TOP_NOC, val);
- val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, DSS_MAS, val);
- val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, MSS_MAS, val);
- }
-
- REGV_WR32(VPU_37XX_HOST_SS_CPR_CLK_SET, val);
-}
-
-static int ivpu_boot_noc_qreqn_check(struct ivpu_device *vdev, u32 exp_val)
-{
- u32 val = REGV_RD32(VPU_37XX_HOST_SS_NOC_QREQN);
-
- if (!REG_TEST_FLD_NUM(VPU_37XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, exp_val, val))
- return -EIO;
-
- return 0;
-}
-
-static int ivpu_boot_noc_qacceptn_check(struct ivpu_device *vdev, u32 exp_val)
-{
- u32 val = REGV_RD32(VPU_37XX_HOST_SS_NOC_QACCEPTN);
-
- if (!REG_TEST_FLD_NUM(VPU_37XX_HOST_SS_NOC_QACCEPTN, TOP_SOCMMIO, exp_val, val))
- return -EIO;
-
- return 0;
-}
-
-static int ivpu_boot_noc_qdeny_check(struct ivpu_device *vdev, u32 exp_val)
-{
- u32 val = REGV_RD32(VPU_37XX_HOST_SS_NOC_QDENY);
-
- if (!REG_TEST_FLD_NUM(VPU_37XX_HOST_SS_NOC_QDENY, TOP_SOCMMIO, exp_val, val))
- return -EIO;
-
- return 0;
-}
-
-static int ivpu_boot_top_noc_qrenqn_check(struct ivpu_device *vdev, u32 exp_val)
-{
- u32 val = REGV_RD32(VPU_37XX_TOP_NOC_QREQN);
-
- if (!REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QREQN, CPU_CTRL, exp_val, val) ||
- !REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, exp_val, val))
- return -EIO;
-
- return 0;
-}
-
-static int ivpu_boot_top_noc_qacceptn_check(struct ivpu_device *vdev, u32 exp_val)
-{
- u32 val = REGV_RD32(VPU_37XX_TOP_NOC_QACCEPTN);
-
- if (!REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QACCEPTN, CPU_CTRL, exp_val, val) ||
- !REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QACCEPTN, HOSTIF_L2CACHE, exp_val, val))
- return -EIO;
-
- return 0;
-}
-
-static int ivpu_boot_top_noc_qdeny_check(struct ivpu_device *vdev, u32 exp_val)
-{
- u32 val = REGV_RD32(VPU_37XX_TOP_NOC_QDENY);
-
- if (!REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QDENY, CPU_CTRL, exp_val, val) ||
- !REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QDENY, HOSTIF_L2CACHE, exp_val, val))
- return -EIO;
-
- return 0;
-}
-
-static int ivpu_boot_host_ss_configure(struct ivpu_device *vdev)
-{
- ivpu_boot_host_ss_rst_clr_assert(vdev);
-
- return ivpu_boot_noc_qreqn_check(vdev, 0x0);
-}
-
-static void ivpu_boot_vpu_idle_gen_disable(struct ivpu_device *vdev)
-{
- REGV_WR32(VPU_37XX_HOST_SS_AON_VPU_IDLE_GEN, 0x0);
-}
-
-static int ivpu_boot_host_ss_axi_drive(struct ivpu_device *vdev, bool enable)
-{
- int ret;
- u32 val;
-
- val = REGV_RD32(VPU_37XX_HOST_SS_NOC_QREQN);
- if (enable)
- val = REG_SET_FLD(VPU_37XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, val);
- else
- val = REG_CLR_FLD(VPU_37XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, val);
- REGV_WR32(VPU_37XX_HOST_SS_NOC_QREQN, val);
-
- ret = ivpu_boot_noc_qacceptn_check(vdev, enable ? 0x1 : 0x0);
- if (ret) {
- ivpu_err(vdev, "Failed qacceptn check: %d\n", ret);
- return ret;
- }
-
- ret = ivpu_boot_noc_qdeny_check(vdev, 0x0);
- if (ret)
- ivpu_err(vdev, "Failed qdeny check: %d\n", ret);
-
- return ret;
-}
-
-static int ivpu_boot_host_ss_axi_enable(struct ivpu_device *vdev)
-{
- return ivpu_boot_host_ss_axi_drive(vdev, true);
-}
-
-static int ivpu_boot_host_ss_top_noc_drive(struct ivpu_device *vdev, bool enable)
-{
- int ret;
- u32 val;
-
- val = REGV_RD32(VPU_37XX_TOP_NOC_QREQN);
- if (enable) {
- val = REG_SET_FLD(VPU_37XX_TOP_NOC_QREQN, CPU_CTRL, val);
- val = REG_SET_FLD(VPU_37XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, val);
- } else {
- val = REG_CLR_FLD(VPU_37XX_TOP_NOC_QREQN, CPU_CTRL, val);
- val = REG_CLR_FLD(VPU_37XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, val);
- }
- REGV_WR32(VPU_37XX_TOP_NOC_QREQN, val);
-
- ret = ivpu_boot_top_noc_qacceptn_check(vdev, enable ? 0x1 : 0x0);
- if (ret) {
- ivpu_err(vdev, "Failed qacceptn check: %d\n", ret);
- return ret;
- }
-
- ret = ivpu_boot_top_noc_qdeny_check(vdev, 0x0);
- if (ret)
- ivpu_err(vdev, "Failed qdeny check: %d\n", ret);
-
- return ret;
-}
-
-static int ivpu_boot_host_ss_top_noc_enable(struct ivpu_device *vdev)
-{
- return ivpu_boot_host_ss_top_noc_drive(vdev, true);
-}
-
-static void ivpu_boot_pwr_island_trickle_drive(struct ivpu_device *vdev, bool enable)
-{
- u32 val = REGV_RD32(VPU_37XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0);
-
- if (enable)
- val = REG_SET_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, MSS_CPU, val);
- else
- val = REG_CLR_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, MSS_CPU, val);
-
- REGV_WR32(VPU_37XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, val);
-}
-
-static void ivpu_boot_pwr_island_drive(struct ivpu_device *vdev, bool enable)
-{
- u32 val = REGV_RD32(VPU_37XX_HOST_SS_AON_PWR_ISLAND_EN0);
-
- if (enable)
- val = REG_SET_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_EN0, MSS_CPU, val);
- else
- val = REG_CLR_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_EN0, MSS_CPU, val);
-
- REGV_WR32(VPU_37XX_HOST_SS_AON_PWR_ISLAND_EN0, val);
-}
-
-static int ivpu_boot_wait_for_pwr_island_status(struct ivpu_device *vdev, u32 exp_val)
-{
- return REGV_POLL_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_STATUS0, MSS_CPU,
- exp_val, PWR_ISLAND_STATUS_TIMEOUT_US);
-}
-
-static void ivpu_boot_pwr_island_isolation_drive(struct ivpu_device *vdev, bool enable)
-{
- u32 val = REGV_RD32(VPU_37XX_HOST_SS_AON_PWR_ISO_EN0);
-
- if (enable)
- val = REG_SET_FLD(VPU_37XX_HOST_SS_AON_PWR_ISO_EN0, MSS_CPU, val);
- else
- val = REG_CLR_FLD(VPU_37XX_HOST_SS_AON_PWR_ISO_EN0, MSS_CPU, val);
-
- REGV_WR32(VPU_37XX_HOST_SS_AON_PWR_ISO_EN0, val);
-}
-
-static void ivpu_boot_dpu_active_drive(struct ivpu_device *vdev, bool enable)
-{
- u32 val = REGV_RD32(VPU_37XX_HOST_SS_AON_DPU_ACTIVE);
-
- if (enable)
- val = REG_SET_FLD(VPU_37XX_HOST_SS_AON_DPU_ACTIVE, DPU_ACTIVE, val);
- else
- val = REG_CLR_FLD(VPU_37XX_HOST_SS_AON_DPU_ACTIVE, DPU_ACTIVE, val);
-
- REGV_WR32(VPU_37XX_HOST_SS_AON_DPU_ACTIVE, val);
-}
-
-static int ivpu_boot_pwr_domain_enable(struct ivpu_device *vdev)
-{
- int ret;
-
- ivpu_boot_pwr_island_trickle_drive(vdev, true);
- ivpu_boot_pwr_island_drive(vdev, true);
-
- ret = ivpu_boot_wait_for_pwr_island_status(vdev, 0x1);
- if (ret) {
- ivpu_err(vdev, "Timed out waiting for power island status\n");
- return ret;
- }
-
- ret = ivpu_boot_top_noc_qrenqn_check(vdev, 0x0);
- if (ret) {
- ivpu_err(vdev, "Failed qrenqn check %d\n", ret);
- return ret;
- }
-
- ivpu_boot_host_ss_clk_drive(vdev, true);
- ivpu_boot_pwr_island_isolation_drive(vdev, false);
- ivpu_boot_host_ss_rst_drive(vdev, true);
- ivpu_boot_dpu_active_drive(vdev, true);
-
- return ret;
-}
-
-static void ivpu_boot_no_snoop_enable(struct ivpu_device *vdev)
-{
- u32 val = REGV_RD32(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES);
-
- val = REG_SET_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, NOSNOOP_OVERRIDE_EN, val);
- val = REG_CLR_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, AW_NOSNOOP_OVERRIDE, val);
- val = REG_SET_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, AR_NOSNOOP_OVERRIDE, val);
-
- REGV_WR32(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, val);
-}
-
-static void ivpu_boot_tbu_mmu_enable(struct ivpu_device *vdev)
-{
- u32 val = REGV_RD32(VPU_37XX_HOST_IF_TBU_MMUSSIDV);
-
- val = REG_SET_FLD(VPU_37XX_HOST_IF_TBU_MMUSSIDV, TBU0_AWMMUSSIDV, val);
- val = REG_SET_FLD(VPU_37XX_HOST_IF_TBU_MMUSSIDV, TBU0_ARMMUSSIDV, val);
- val = REG_SET_FLD(VPU_37XX_HOST_IF_TBU_MMUSSIDV, TBU2_AWMMUSSIDV, val);
- val = REG_SET_FLD(VPU_37XX_HOST_IF_TBU_MMUSSIDV, TBU2_ARMMUSSIDV, val);
-
- REGV_WR32(VPU_37XX_HOST_IF_TBU_MMUSSIDV, val);
-}
-
-static void ivpu_boot_soc_cpu_boot(struct ivpu_device *vdev)
-{
- u32 val;
-
- val = REGV_RD32(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC);
- val = REG_SET_FLD(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, IRQI_RSTRUN0, val);
-
- val = REG_CLR_FLD(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, IRQI_RSTVEC, val);
- REGV_WR32(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, val);
-
- val = REG_SET_FLD(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, IRQI_RESUME0, val);
- REGV_WR32(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, val);
-
- val = REG_CLR_FLD(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, IRQI_RESUME0, val);
- REGV_WR32(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, val);
-
- val = vdev->fw->entry_point >> 9;
- REGV_WR32(VPU_37XX_HOST_SS_LOADING_ADDRESS_LO, val);
-
- val = REG_SET_FLD(VPU_37XX_HOST_SS_LOADING_ADDRESS_LO, DONE, val);
- REGV_WR32(VPU_37XX_HOST_SS_LOADING_ADDRESS_LO, val);
-
- ivpu_dbg(vdev, PM, "Booting firmware, mode: %s\n",
- vdev->fw->entry_point == vdev->fw->cold_boot_entry_point ? "cold boot" : "resume");
-}
-
-static int ivpu_boot_d0i3_drive(struct ivpu_device *vdev, bool enable)
-{
- int ret;
- u32 val;
-
- ret = REGB_POLL_FLD(VPU_37XX_BUTTRESS_VPU_D0I3_CONTROL, INPROGRESS, 0, TIMEOUT_US);
- if (ret) {
- ivpu_err(vdev, "Failed to sync before D0i3 transition: %d\n", ret);
- return ret;
- }
-
- val = REGB_RD32(VPU_37XX_BUTTRESS_VPU_D0I3_CONTROL);
- if (enable)
- val = REG_SET_FLD(VPU_37XX_BUTTRESS_VPU_D0I3_CONTROL, I3, val);
- else
- val = REG_CLR_FLD(VPU_37XX_BUTTRESS_VPU_D0I3_CONTROL, I3, val);
- REGB_WR32(VPU_37XX_BUTTRESS_VPU_D0I3_CONTROL, val);
-
- ret = REGB_POLL_FLD(VPU_37XX_BUTTRESS_VPU_D0I3_CONTROL, INPROGRESS, 0, TIMEOUT_US);
- if (ret)
- ivpu_err(vdev, "Failed to sync after D0i3 transition: %d\n", ret);
-
- return ret;
-}
-
-static int ivpu_hw_37xx_info_init(struct ivpu_device *vdev)
-{
- struct ivpu_hw_info *hw = vdev->hw;
-
- hw->tile_fuse = TILE_FUSE_ENABLE_BOTH;
- hw->sku = TILE_SKU_BOTH;
- hw->config = WP_CONFIG_2_TILE_4_3_RATIO;
-
- ivpu_pll_init_frequency_ratios(vdev);
-
- ivpu_hw_init_range(&hw->ranges.global, 0x80000000, SZ_512M);
- ivpu_hw_init_range(&hw->ranges.user, 0xc0000000, 255 * SZ_1M);
- ivpu_hw_init_range(&hw->ranges.shave, 0x180000000, SZ_2G);
- ivpu_hw_init_range(&hw->ranges.dma, 0x200000000, SZ_8G);
-
- vdev->platform = IVPU_PLATFORM_SILICON;
- ivpu_hw_wa_init(vdev);
- ivpu_hw_timeouts_init(vdev);
-
- return 0;
-}
-
-static int ivpu_hw_37xx_ip_reset(struct ivpu_device *vdev)
-{
- int ret;
- u32 val;
-
- if (IVPU_WA(punit_disabled))
- return 0;
-
- ret = REGB_POLL_FLD(VPU_37XX_BUTTRESS_VPU_IP_RESET, TRIGGER, 0, TIMEOUT_US);
- if (ret) {
- ivpu_err(vdev, "Timed out waiting for TRIGGER bit\n");
- return ret;
- }
-
- val = REGB_RD32(VPU_37XX_BUTTRESS_VPU_IP_RESET);
- val = REG_SET_FLD(VPU_37XX_BUTTRESS_VPU_IP_RESET, TRIGGER, val);
- REGB_WR32(VPU_37XX_BUTTRESS_VPU_IP_RESET, val);
-
- ret = REGB_POLL_FLD(VPU_37XX_BUTTRESS_VPU_IP_RESET, TRIGGER, 0, TIMEOUT_US);
- if (ret)
- ivpu_err(vdev, "Timed out waiting for RESET completion\n");
-
- return ret;
-}
-
-static int ivpu_hw_37xx_reset(struct ivpu_device *vdev)
-{
- int ret = 0;
-
- if (ivpu_hw_37xx_ip_reset(vdev)) {
- ivpu_err(vdev, "Failed to reset NPU\n");
- ret = -EIO;
- }
-
- if (ivpu_pll_disable(vdev)) {
- ivpu_err(vdev, "Failed to disable PLL\n");
- ret = -EIO;
- }
-
- return ret;
-}
-
-static int ivpu_hw_37xx_d0i3_enable(struct ivpu_device *vdev)
-{
- int ret;
-
- ret = ivpu_boot_d0i3_drive(vdev, true);
- if (ret)
- ivpu_err(vdev, "Failed to enable D0i3: %d\n", ret);
-
- udelay(5); /* VPU requires 5 us to complete the transition */
-
- return ret;
-}
-
-static int ivpu_hw_37xx_d0i3_disable(struct ivpu_device *vdev)
-{
- int ret;
-
- ret = ivpu_boot_d0i3_drive(vdev, false);
- if (ret)
- ivpu_err(vdev, "Failed to disable D0i3: %d\n", ret);
-
- return ret;
-}
-
-static int ivpu_hw_37xx_power_up(struct ivpu_device *vdev)
-{
- int ret;
-
- /* PLL requests may fail when powering down, so issue WP 0 here */
- ret = ivpu_pll_disable(vdev);
- if (ret)
- ivpu_warn(vdev, "Failed to disable PLL: %d\n", ret);
-
- ret = ivpu_hw_37xx_d0i3_disable(vdev);
- if (ret)
- ivpu_warn(vdev, "Failed to disable D0I3: %d\n", ret);
-
- ret = ivpu_pll_enable(vdev);
- if (ret) {
- ivpu_err(vdev, "Failed to enable PLL: %d\n", ret);
- return ret;
- }
-
- ret = ivpu_boot_host_ss_configure(vdev);
- if (ret) {
- ivpu_err(vdev, "Failed to configure host SS: %d\n", ret);
- return ret;
- }
-
- /*
- * The control circuitry for vpu_idle indication logic powers up active.
- * To ensure unnecessary low power mode signal from LRT during bring up,
- * KMD disables the circuitry prior to bringing up the Main Power island.
- */
- ivpu_boot_vpu_idle_gen_disable(vdev);
-
- ret = ivpu_boot_pwr_domain_enable(vdev);
- if (ret) {
- ivpu_err(vdev, "Failed to enable power domain: %d\n", ret);
- return ret;
- }
-
- ret = ivpu_boot_host_ss_axi_enable(vdev);
- if (ret) {
- ivpu_err(vdev, "Failed to enable AXI: %d\n", ret);
- return ret;
- }
-
- ret = ivpu_boot_host_ss_top_noc_enable(vdev);
- if (ret)
- ivpu_err(vdev, "Failed to enable TOP NOC: %d\n", ret);
-
- return ret;
-}
-
-static int ivpu_hw_37xx_boot_fw(struct ivpu_device *vdev)
-{
- ivpu_boot_no_snoop_enable(vdev);
- ivpu_boot_tbu_mmu_enable(vdev);
- ivpu_boot_soc_cpu_boot(vdev);
-
- return 0;
-}
-
-static bool ivpu_hw_37xx_is_idle(struct ivpu_device *vdev)
-{
- u32 val;
-
- if (IVPU_WA(punit_disabled))
- return true;
-
- val = REGB_RD32(VPU_37XX_BUTTRESS_VPU_STATUS);
- return REG_TEST_FLD(VPU_37XX_BUTTRESS_VPU_STATUS, READY, val) &&
- REG_TEST_FLD(VPU_37XX_BUTTRESS_VPU_STATUS, IDLE, val);
-}
-
-static int ivpu_hw_37xx_wait_for_idle(struct ivpu_device *vdev)
-{
- return REGB_POLL_FLD(VPU_37XX_BUTTRESS_VPU_STATUS, IDLE, 0x1, IDLE_TIMEOUT_US);
-}
-
-static void ivpu_hw_37xx_save_d0i3_entry_timestamp(struct ivpu_device *vdev)
-{
- vdev->hw->d0i3_entry_host_ts = ktime_get_boottime();
- vdev->hw->d0i3_entry_vpu_ts = REGV_RD64(VPU_37XX_CPU_SS_TIM_PERF_FREE_CNT);
-}
-
-static int ivpu_hw_37xx_power_down(struct ivpu_device *vdev)
-{
- int ret = 0;
-
- ivpu_hw_37xx_save_d0i3_entry_timestamp(vdev);
-
- if (!ivpu_hw_37xx_is_idle(vdev))
- ivpu_warn(vdev, "NPU not idle during power down\n");
-
- if (ivpu_hw_37xx_reset(vdev)) {
- ivpu_err(vdev, "Failed to reset NPU\n");
- ret = -EIO;
- }
-
- if (ivpu_hw_37xx_d0i3_enable(vdev)) {
- ivpu_err(vdev, "Failed to enter D0I3\n");
- ret = -EIO;
- }
-
- return ret;
-}
-
-static void ivpu_hw_37xx_wdt_disable(struct ivpu_device *vdev)
-{
- u32 val;
-
- /* Enable writing and set non-zero WDT value */
- REGV_WR32(VPU_37XX_CPU_SS_TIM_SAFE, TIM_SAFE_ENABLE);
- REGV_WR32(VPU_37XX_CPU_SS_TIM_WATCHDOG, TIM_WATCHDOG_RESET_VALUE);
-
- /* Enable writing and disable watchdog timer */
- REGV_WR32(VPU_37XX_CPU_SS_TIM_SAFE, TIM_SAFE_ENABLE);
- REGV_WR32(VPU_37XX_CPU_SS_TIM_WDOG_EN, 0);
-
- /* Now clear the timeout interrupt */
- val = REGV_RD32(VPU_37XX_CPU_SS_TIM_GEN_CONFIG);
- val = REG_CLR_FLD(VPU_37XX_CPU_SS_TIM_GEN_CONFIG, WDOG_TO_INT_CLR, val);
- REGV_WR32(VPU_37XX_CPU_SS_TIM_GEN_CONFIG, val);
-}
-
-static u32 ivpu_hw_37xx_profiling_freq_get(struct ivpu_device *vdev)
-{
- return PLL_PROF_CLK_FREQ;
-}
-
-static void ivpu_hw_37xx_profiling_freq_drive(struct ivpu_device *vdev, bool enable)
-{
- /* Profiling freq - is a debug feature. Unavailable on VPU 37XX. */
-}
-
-static u32 ivpu_hw_37xx_ratio_to_freq(struct ivpu_device *vdev, u32 ratio)
-{
- u32 pll_clock = PLL_REF_CLK_FREQ * ratio;
- u32 cpu_clock;
-
- if ((vdev->hw->config & 0xff) == PLL_RATIO_4_3)
- cpu_clock = pll_clock * 2 / 4;
- else
- cpu_clock = pll_clock * 2 / 5;
-
- return cpu_clock;
-}
-
-/* Register indirect accesses */
-static u32 ivpu_hw_37xx_reg_pll_freq_get(struct ivpu_device *vdev)
-{
- u32 pll_curr_ratio;
-
- pll_curr_ratio = REGB_RD32(VPU_37XX_BUTTRESS_CURRENT_PLL);
- pll_curr_ratio &= VPU_37XX_BUTTRESS_CURRENT_PLL_RATIO_MASK;
-
- if (!ivpu_is_silicon(vdev))
- return PLL_SIMULATION_FREQ;
-
- return ivpu_hw_37xx_ratio_to_freq(vdev, pll_curr_ratio);
-}
-
-static u32 ivpu_hw_37xx_reg_telemetry_offset_get(struct ivpu_device *vdev)
-{
- return REGB_RD32(VPU_37XX_BUTTRESS_VPU_TELEMETRY_OFFSET);
-}
-
-static u32 ivpu_hw_37xx_reg_telemetry_size_get(struct ivpu_device *vdev)
-{
- return REGB_RD32(VPU_37XX_BUTTRESS_VPU_TELEMETRY_SIZE);
-}
-
-static u32 ivpu_hw_37xx_reg_telemetry_enable_get(struct ivpu_device *vdev)
-{
- return REGB_RD32(VPU_37XX_BUTTRESS_VPU_TELEMETRY_ENABLE);
-}
-
-static void ivpu_hw_37xx_reg_db_set(struct ivpu_device *vdev, u32 db_id)
-{
- u32 reg_stride = VPU_37XX_CPU_SS_DOORBELL_1 - VPU_37XX_CPU_SS_DOORBELL_0;
- u32 val = REG_FLD(VPU_37XX_CPU_SS_DOORBELL_0, SET);
-
- REGV_WR32I(VPU_37XX_CPU_SS_DOORBELL_0, reg_stride, db_id, val);
-}
-
-static u32 ivpu_hw_37xx_reg_ipc_rx_addr_get(struct ivpu_device *vdev)
-{
- return REGV_RD32(VPU_37XX_HOST_SS_TIM_IPC_FIFO_ATM);
-}
-
-static u32 ivpu_hw_37xx_reg_ipc_rx_count_get(struct ivpu_device *vdev)
-{
- u32 count = REGV_RD32_SILENT(VPU_37XX_HOST_SS_TIM_IPC_FIFO_STAT);
-
- return REG_GET_FLD(VPU_37XX_HOST_SS_TIM_IPC_FIFO_STAT, FILL_LEVEL, count);
-}
-
-static void ivpu_hw_37xx_reg_ipc_tx_set(struct ivpu_device *vdev, u32 vpu_addr)
-{
- REGV_WR32(VPU_37XX_CPU_SS_TIM_IPC_FIFO, vpu_addr);
-}
-
-static void ivpu_hw_37xx_irq_clear(struct ivpu_device *vdev)
-{
- REGV_WR64(VPU_37XX_HOST_SS_ICB_CLEAR_0, ICB_0_1_IRQ_MASK);
-}
-
-static void ivpu_hw_37xx_irq_enable(struct ivpu_device *vdev)
-{
- REGV_WR32(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, ITF_FIREWALL_VIOLATION_MASK);
- REGV_WR64(VPU_37XX_HOST_SS_ICB_ENABLE_0, ICB_0_1_IRQ_MASK);
- REGB_WR32(VPU_37XX_BUTTRESS_LOCAL_INT_MASK, BUTTRESS_IRQ_ENABLE_MASK);
- REGB_WR32(VPU_37XX_BUTTRESS_GLOBAL_INT_MASK, 0x0);
-}
-
-static void ivpu_hw_37xx_irq_disable(struct ivpu_device *vdev)
-{
- REGB_WR32(VPU_37XX_BUTTRESS_GLOBAL_INT_MASK, 0x1);
- REGB_WR32(VPU_37XX_BUTTRESS_LOCAL_INT_MASK, BUTTRESS_IRQ_DISABLE_MASK);
- REGV_WR64(VPU_37XX_HOST_SS_ICB_ENABLE_0, 0x0ull);
- REGV_WR32(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, 0x0);
-}
-
-static void ivpu_hw_37xx_irq_wdt_nce_handler(struct ivpu_device *vdev)
-{
- ivpu_pm_trigger_recovery(vdev, "WDT NCE IRQ");
-}
-
-static void ivpu_hw_37xx_irq_wdt_mss_handler(struct ivpu_device *vdev)
-{
- ivpu_hw_wdt_disable(vdev);
- ivpu_pm_trigger_recovery(vdev, "WDT MSS IRQ");
-}
-
-static void ivpu_hw_37xx_irq_noc_firewall_handler(struct ivpu_device *vdev)
-{
- ivpu_pm_trigger_recovery(vdev, "NOC Firewall IRQ");
-}
-
-/* Handler for IRQs from VPU core (irqV) */
-static bool ivpu_hw_37xx_irqv_handler(struct ivpu_device *vdev, int irq, bool *wake_thread)
-{
- u32 status = REGV_RD32(VPU_37XX_HOST_SS_ICB_STATUS_0) & ICB_0_IRQ_MASK;
-
- if (!status)
- return false;
-
- REGV_WR32(VPU_37XX_HOST_SS_ICB_CLEAR_0, status);
-
- if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_0_INT, status))
- ivpu_mmu_irq_evtq_handler(vdev);
-
- if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, HOST_IPC_FIFO_INT, status))
- ivpu_ipc_irq_handler(vdev, wake_thread);
-
- if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_1_INT, status))
- ivpu_dbg(vdev, IRQ, "MMU sync complete\n");
-
- if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_2_INT, status))
- ivpu_mmu_irq_gerr_handler(vdev);
-
- if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT, status))
- ivpu_hw_37xx_irq_wdt_mss_handler(vdev);
-
- if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT, status))
- ivpu_hw_37xx_irq_wdt_nce_handler(vdev);
-
- if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT, status))
- ivpu_hw_37xx_irq_noc_firewall_handler(vdev);
-
- return true;
-}
-
-/* Handler for IRQs from Buttress core (irqB) */
-static bool ivpu_hw_37xx_irqb_handler(struct ivpu_device *vdev, int irq)
-{
- u32 status = REGB_RD32(VPU_37XX_BUTTRESS_INTERRUPT_STAT) & BUTTRESS_IRQ_MASK;
- bool schedule_recovery = false;
-
- if (!status)
- return false;
-
- if (REG_TEST_FLD(VPU_37XX_BUTTRESS_INTERRUPT_STAT, FREQ_CHANGE, status))
- ivpu_dbg(vdev, IRQ, "FREQ_CHANGE irq: %08x",
- REGB_RD32(VPU_37XX_BUTTRESS_CURRENT_PLL));
-
- if (REG_TEST_FLD(VPU_37XX_BUTTRESS_INTERRUPT_STAT, ATS_ERR, status)) {
- ivpu_err(vdev, "ATS_ERR irq 0x%016llx", REGB_RD64(VPU_37XX_BUTTRESS_ATS_ERR_LOG_0));
- REGB_WR32(VPU_37XX_BUTTRESS_ATS_ERR_CLEAR, 0x1);
- schedule_recovery = true;
- }
-
- if (REG_TEST_FLD(VPU_37XX_BUTTRESS_INTERRUPT_STAT, UFI_ERR, status)) {
- u32 ufi_log = REGB_RD32(VPU_37XX_BUTTRESS_UFI_ERR_LOG);
-
- ivpu_err(vdev, "UFI_ERR irq (0x%08x) opcode: 0x%02lx axi_id: 0x%02lx cq_id: 0x%03lx",
- ufi_log, REG_GET_FLD(VPU_37XX_BUTTRESS_UFI_ERR_LOG, OPCODE, ufi_log),
- REG_GET_FLD(VPU_37XX_BUTTRESS_UFI_ERR_LOG, AXI_ID, ufi_log),
- REG_GET_FLD(VPU_37XX_BUTTRESS_UFI_ERR_LOG, CQ_ID, ufi_log));
- REGB_WR32(VPU_37XX_BUTTRESS_UFI_ERR_CLEAR, 0x1);
- schedule_recovery = true;
- }
-
- /* This must be done after interrupts are cleared at the source. */
- if (IVPU_WA(interrupt_clear_with_0))
- /*
- * Writing 1 triggers an interrupt, so we can't perform read update write.
- * Clear local interrupt status by writing 0 to all bits.
- */
- REGB_WR32(VPU_37XX_BUTTRESS_INTERRUPT_STAT, 0x0);
- else
- REGB_WR32(VPU_37XX_BUTTRESS_INTERRUPT_STAT, status);
-
- if (schedule_recovery)
- ivpu_pm_trigger_recovery(vdev, "Buttress IRQ");
-
- return true;
-}
-
-static irqreturn_t ivpu_hw_37xx_irq_handler(int irq, void *ptr)
-{
- struct ivpu_device *vdev = ptr;
- bool irqv_handled, irqb_handled, wake_thread = false;
-
- REGB_WR32(VPU_37XX_BUTTRESS_GLOBAL_INT_MASK, 0x1);
-
- irqv_handled = ivpu_hw_37xx_irqv_handler(vdev, irq, &wake_thread);
- irqb_handled = ivpu_hw_37xx_irqb_handler(vdev, irq);
-
- /* Re-enable global interrupts to re-trigger MSI for pending interrupts */
- REGB_WR32(VPU_37XX_BUTTRESS_GLOBAL_INT_MASK, 0x0);
-
- if (wake_thread)
- return IRQ_WAKE_THREAD;
- if (irqv_handled || irqb_handled)
- return IRQ_HANDLED;
- return IRQ_NONE;
-}
-
-static void ivpu_hw_37xx_diagnose_failure(struct ivpu_device *vdev)
-{
- u32 irqv = REGV_RD32(VPU_37XX_HOST_SS_ICB_STATUS_0) & ICB_0_IRQ_MASK;
- u32 irqb = REGB_RD32(VPU_37XX_BUTTRESS_INTERRUPT_STAT) & BUTTRESS_IRQ_MASK;
-
- if (ivpu_hw_37xx_reg_ipc_rx_count_get(vdev))
- ivpu_err(vdev, "IPC FIFO queue not empty, missed IPC IRQ");
-
- if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT, irqv))
- ivpu_err(vdev, "WDT MSS timeout detected\n");
-
- if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT, irqv))
- ivpu_err(vdev, "WDT NCE timeout detected\n");
-
- if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT, irqv))
- ivpu_err(vdev, "NOC Firewall irq detected\n");
-
- if (REG_TEST_FLD(VPU_37XX_BUTTRESS_INTERRUPT_STAT, ATS_ERR, irqb))
- ivpu_err(vdev, "ATS_ERR irq 0x%016llx", REGB_RD64(VPU_37XX_BUTTRESS_ATS_ERR_LOG_0));
-
- if (REG_TEST_FLD(VPU_37XX_BUTTRESS_INTERRUPT_STAT, UFI_ERR, irqb)) {
- u32 ufi_log = REGB_RD32(VPU_37XX_BUTTRESS_UFI_ERR_LOG);
-
- ivpu_err(vdev, "UFI_ERR irq (0x%08x) opcode: 0x%02lx axi_id: 0x%02lx cq_id: 0x%03lx",
- ufi_log, REG_GET_FLD(VPU_37XX_BUTTRESS_UFI_ERR_LOG, OPCODE, ufi_log),
- REG_GET_FLD(VPU_37XX_BUTTRESS_UFI_ERR_LOG, AXI_ID, ufi_log),
- REG_GET_FLD(VPU_37XX_BUTTRESS_UFI_ERR_LOG, CQ_ID, ufi_log));
- }
-}
-
-const struct ivpu_hw_ops ivpu_hw_37xx_ops = {
- .info_init = ivpu_hw_37xx_info_init,
- .power_up = ivpu_hw_37xx_power_up,
- .is_idle = ivpu_hw_37xx_is_idle,
- .wait_for_idle = ivpu_hw_37xx_wait_for_idle,
- .power_down = ivpu_hw_37xx_power_down,
- .reset = ivpu_hw_37xx_reset,
- .boot_fw = ivpu_hw_37xx_boot_fw,
- .wdt_disable = ivpu_hw_37xx_wdt_disable,
- .diagnose_failure = ivpu_hw_37xx_diagnose_failure,
- .profiling_freq_get = ivpu_hw_37xx_profiling_freq_get,
- .profiling_freq_drive = ivpu_hw_37xx_profiling_freq_drive,
- .reg_pll_freq_get = ivpu_hw_37xx_reg_pll_freq_get,
- .ratio_to_freq = ivpu_hw_37xx_ratio_to_freq,
- .reg_telemetry_offset_get = ivpu_hw_37xx_reg_telemetry_offset_get,
- .reg_telemetry_size_get = ivpu_hw_37xx_reg_telemetry_size_get,
- .reg_telemetry_enable_get = ivpu_hw_37xx_reg_telemetry_enable_get,
- .reg_db_set = ivpu_hw_37xx_reg_db_set,
- .reg_ipc_rx_addr_get = ivpu_hw_37xx_reg_ipc_rx_addr_get,
- .reg_ipc_rx_count_get = ivpu_hw_37xx_reg_ipc_rx_count_get,
- .reg_ipc_tx_set = ivpu_hw_37xx_reg_ipc_tx_set,
- .irq_clear = ivpu_hw_37xx_irq_clear,
- .irq_enable = ivpu_hw_37xx_irq_enable,
- .irq_disable = ivpu_hw_37xx_irq_disable,
- .irq_handler = ivpu_hw_37xx_irq_handler,
-};
diff --git a/drivers/accel/ivpu/ivpu_hw_37xx_reg.h b/drivers/accel/ivpu/ivpu_hw_37xx_reg.h
index f6fec1919202..cf5e2f01049c 100644
--- a/drivers/accel/ivpu/ivpu_hw_37xx_reg.h
+++ b/drivers/accel/ivpu/ivpu_hw_37xx_reg.h
@@ -8,78 +8,6 @@
#include <linux/bits.h>
-#define VPU_37XX_BUTTRESS_INTERRUPT_TYPE 0x00000000u
-
-#define VPU_37XX_BUTTRESS_INTERRUPT_STAT 0x00000004u
-#define VPU_37XX_BUTTRESS_INTERRUPT_STAT_FREQ_CHANGE_MASK BIT_MASK(0)
-#define VPU_37XX_BUTTRESS_INTERRUPT_STAT_ATS_ERR_MASK BIT_MASK(1)
-#define VPU_37XX_BUTTRESS_INTERRUPT_STAT_UFI_ERR_MASK BIT_MASK(2)
-
-#define VPU_37XX_BUTTRESS_WP_REQ_PAYLOAD0 0x00000008u
-#define VPU_37XX_BUTTRESS_WP_REQ_PAYLOAD0_MIN_RATIO_MASK GENMASK(15, 0)
-#define VPU_37XX_BUTTRESS_WP_REQ_PAYLOAD0_MAX_RATIO_MASK GENMASK(31, 16)
-
-#define VPU_37XX_BUTTRESS_WP_REQ_PAYLOAD1 0x0000000cu
-#define VPU_37XX_BUTTRESS_WP_REQ_PAYLOAD1_TARGET_RATIO_MASK GENMASK(15, 0)
-#define VPU_37XX_BUTTRESS_WP_REQ_PAYLOAD1_EPP_MASK GENMASK(31, 16)
-
-#define VPU_37XX_BUTTRESS_WP_REQ_PAYLOAD2 0x00000010u
-#define VPU_37XX_BUTTRESS_WP_REQ_PAYLOAD2_CONFIG_MASK GENMASK(15, 0)
-
-#define VPU_37XX_BUTTRESS_WP_REQ_CMD 0x00000014u
-#define VPU_37XX_BUTTRESS_WP_REQ_CMD_SEND_MASK BIT_MASK(0)
-
-#define VPU_37XX_BUTTRESS_WP_DOWNLOAD 0x00000018u
-#define VPU_37XX_BUTTRESS_WP_DOWNLOAD_TARGET_RATIO_MASK GENMASK(15, 0)
-
-#define VPU_37XX_BUTTRESS_CURRENT_PLL 0x0000001cu
-#define VPU_37XX_BUTTRESS_CURRENT_PLL_RATIO_MASK GENMASK(15, 0)
-
-#define VPU_37XX_BUTTRESS_PLL_ENABLE 0x00000020u
-
-#define VPU_37XX_BUTTRESS_FMIN_FUSE 0x00000024u
-#define VPU_37XX_BUTTRESS_FMIN_FUSE_MIN_RATIO_MASK GENMASK(7, 0)
-#define VPU_37XX_BUTTRESS_FMIN_FUSE_PN_RATIO_MASK GENMASK(15, 8)
-
-#define VPU_37XX_BUTTRESS_FMAX_FUSE 0x00000028u
-#define VPU_37XX_BUTTRESS_FMAX_FUSE_MAX_RATIO_MASK GENMASK(7, 0)
-
-#define VPU_37XX_BUTTRESS_TILE_FUSE 0x0000002cu
-#define VPU_37XX_BUTTRESS_TILE_FUSE_VALID_MASK BIT_MASK(0)
-#define VPU_37XX_BUTTRESS_TILE_FUSE_SKU_MASK GENMASK(3, 2)
-
-#define VPU_37XX_BUTTRESS_LOCAL_INT_MASK 0x00000030u
-#define VPU_37XX_BUTTRESS_GLOBAL_INT_MASK 0x00000034u
-
-#define VPU_37XX_BUTTRESS_PLL_STATUS 0x00000040u
-#define VPU_37XX_BUTTRESS_PLL_STATUS_LOCK_MASK BIT_MASK(1)
-
-#define VPU_37XX_BUTTRESS_VPU_STATUS 0x00000044u
-#define VPU_37XX_BUTTRESS_VPU_STATUS_READY_MASK BIT_MASK(0)
-#define VPU_37XX_BUTTRESS_VPU_STATUS_IDLE_MASK BIT_MASK(1)
-
-#define VPU_37XX_BUTTRESS_VPU_D0I3_CONTROL 0x00000060u
-#define VPU_37XX_BUTTRESS_VPU_D0I3_CONTROL_INPROGRESS_MASK BIT_MASK(0)
-#define VPU_37XX_BUTTRESS_VPU_D0I3_CONTROL_I3_MASK BIT_MASK(2)
-
-#define VPU_37XX_BUTTRESS_VPU_IP_RESET 0x00000050u
-#define VPU_37XX_BUTTRESS_VPU_IP_RESET_TRIGGER_MASK BIT_MASK(0)
-
-#define VPU_37XX_BUTTRESS_VPU_TELEMETRY_OFFSET 0x00000080u
-#define VPU_37XX_BUTTRESS_VPU_TELEMETRY_SIZE 0x00000084u
-#define VPU_37XX_BUTTRESS_VPU_TELEMETRY_ENABLE 0x00000088u
-
-#define VPU_37XX_BUTTRESS_ATS_ERR_LOG_0 0x000000a0u
-#define VPU_37XX_BUTTRESS_ATS_ERR_LOG_1 0x000000a4u
-#define VPU_37XX_BUTTRESS_ATS_ERR_CLEAR 0x000000a8u
-
-#define VPU_37XX_BUTTRESS_UFI_ERR_LOG 0x000000b0u
-#define VPU_37XX_BUTTRESS_UFI_ERR_LOG_CQ_ID_MASK GENMASK(11, 0)
-#define VPU_37XX_BUTTRESS_UFI_ERR_LOG_AXI_ID_MASK GENMASK(19, 12)
-#define VPU_37XX_BUTTRESS_UFI_ERR_LOG_OPCODE_MASK GENMASK(24, 20)
-
-#define VPU_37XX_BUTTRESS_UFI_ERR_CLEAR 0x000000b4u
-
#define VPU_37XX_HOST_SS_CPR_CLK_SET 0x00000084u
#define VPU_37XX_HOST_SS_CPR_CLK_SET_TOP_NOC_MASK BIT_MASK(1)
#define VPU_37XX_HOST_SS_CPR_CLK_SET_DSS_MAS_MASK BIT_MASK(10)
diff --git a/drivers/accel/ivpu/ivpu_hw_40xx.c b/drivers/accel/ivpu/ivpu_hw_40xx.c
deleted file mode 100644
index b0b88d4c8926..000000000000
--- a/drivers/accel/ivpu/ivpu_hw_40xx.c
+++ /dev/null
@@ -1,1250 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2020-2023 Intel Corporation
- */
-
-#include "ivpu_drv.h"
-#include "ivpu_fw.h"
-#include "ivpu_hw.h"
-#include "ivpu_hw_40xx_reg.h"
-#include "ivpu_hw_reg_io.h"
-#include "ivpu_ipc.h"
-#include "ivpu_mmu.h"
-#include "ivpu_pm.h"
-
-#include <linux/dmi.h>
-
-#define TILE_MAX_NUM 6
-#define TILE_MAX_MASK 0x3f
-
-#define LNL_HW_ID 0x4040
-
-#define SKU_TILE_SHIFT 0u
-#define SKU_TILE_MASK 0x0000ffffu
-#define SKU_HW_ID_SHIFT 16u
-#define SKU_HW_ID_MASK 0xffff0000u
-
-#define PLL_CONFIG_DEFAULT 0x0
-#define PLL_CDYN_DEFAULT 0x80
-#define PLL_EPP_DEFAULT 0x80
-#define PLL_REF_CLK_FREQ (50 * 1000000)
-#define PLL_RATIO_TO_FREQ(x) ((x) * PLL_REF_CLK_FREQ)
-
-#define PLL_PROFILING_FREQ_DEFAULT 38400000
-#define PLL_PROFILING_FREQ_HIGH 400000000
-
-#define TIM_SAFE_ENABLE 0xf1d0dead
-#define TIM_WATCHDOG_RESET_VALUE 0xffffffff
-
-#define TIMEOUT_US (150 * USEC_PER_MSEC)
-#define PWR_ISLAND_STATUS_TIMEOUT_US (5 * USEC_PER_MSEC)
-#define PLL_TIMEOUT_US (1500 * USEC_PER_MSEC)
-#define IDLE_TIMEOUT_US (5 * USEC_PER_MSEC)
-
-#define WEIGHTS_DEFAULT 0xf711f711u
-#define WEIGHTS_ATS_DEFAULT 0x0000f711u
-
-#define ICB_0_IRQ_MASK ((REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, HOST_IPC_FIFO_INT)) | \
- (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_0_INT)) | \
- (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_1_INT)) | \
- (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_2_INT)) | \
- (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT)) | \
- (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT)) | \
- (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT)))
-
-#define ICB_1_IRQ_MASK ((REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_2_INT)) | \
- (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_3_INT)) | \
- (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_4_INT)))
-
-#define ICB_0_1_IRQ_MASK ((((u64)ICB_1_IRQ_MASK) << 32) | ICB_0_IRQ_MASK)
-
-#define BUTTRESS_IRQ_MASK ((REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, ATS_ERR)) | \
- (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, CFI0_ERR)) | \
- (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, CFI1_ERR)) | \
- (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, IMR0_ERR)) | \
- (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, IMR1_ERR)) | \
- (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, SURV_ERR)))
-
-#define BUTTRESS_IRQ_ENABLE_MASK ((u32)~BUTTRESS_IRQ_MASK)
-#define BUTTRESS_IRQ_DISABLE_MASK ((u32)-1)
-
-#define ITF_FIREWALL_VIOLATION_MASK ((REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, CSS_ROM_CMX)) | \
- (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, CSS_DBG)) | \
- (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, CSS_CTRL)) | \
- (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, DEC400)) | \
- (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, MSS_NCE)) | \
- (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, MSS_MBI)) | \
- (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, MSS_MBI_CMX)))
-
-static char *ivpu_platform_to_str(u32 platform)
-{
- switch (platform) {
- case IVPU_PLATFORM_SILICON:
- return "SILICON";
- case IVPU_PLATFORM_SIMICS:
- return "SIMICS";
- case IVPU_PLATFORM_FPGA:
- return "FPGA";
- default:
- return "Invalid platform";
- }
-}
-
-static const struct dmi_system_id ivpu_dmi_platform_simulation[] = {
- {
- .ident = "Intel Simics",
- .matches = {
- DMI_MATCH(DMI_BOARD_NAME, "lnlrvp"),
- DMI_MATCH(DMI_BOARD_VERSION, "1.0"),
- DMI_MATCH(DMI_BOARD_SERIAL, "123456789"),
- },
- },
- {
- .ident = "Intel Simics",
- .matches = {
- DMI_MATCH(DMI_BOARD_NAME, "Simics"),
- },
- },
- { }
-};
-
-static void ivpu_hw_read_platform(struct ivpu_device *vdev)
-{
- if (dmi_check_system(ivpu_dmi_platform_simulation))
- vdev->platform = IVPU_PLATFORM_SIMICS;
- else
- vdev->platform = IVPU_PLATFORM_SILICON;
-
- ivpu_dbg(vdev, MISC, "Platform type: %s (%d)\n",
- ivpu_platform_to_str(vdev->platform), vdev->platform);
-}
-
-static void ivpu_hw_wa_init(struct ivpu_device *vdev)
-{
- vdev->wa.punit_disabled = ivpu_is_fpga(vdev);
- vdev->wa.clear_runtime_mem = false;
-
- if (ivpu_hw_gen(vdev) == IVPU_HW_40XX)
- vdev->wa.disable_clock_relinquish = true;
-
- IVPU_PRINT_WA(punit_disabled);
- IVPU_PRINT_WA(clear_runtime_mem);
- IVPU_PRINT_WA(disable_clock_relinquish);
-}
-
-static void ivpu_hw_timeouts_init(struct ivpu_device *vdev)
-{
- if (ivpu_is_fpga(vdev)) {
- vdev->timeout.boot = 100000;
- vdev->timeout.jsm = 50000;
- vdev->timeout.tdr = 2000000;
- vdev->timeout.reschedule_suspend = 1000;
- vdev->timeout.autosuspend = -1;
- vdev->timeout.d0i3_entry_msg = 500;
- } else if (ivpu_is_simics(vdev)) {
- vdev->timeout.boot = 50;
- vdev->timeout.jsm = 500;
- vdev->timeout.tdr = 10000;
- vdev->timeout.reschedule_suspend = 10;
- vdev->timeout.autosuspend = -1;
- vdev->timeout.d0i3_entry_msg = 100;
- } else {
- vdev->timeout.boot = 1000;
- vdev->timeout.jsm = 500;
- vdev->timeout.tdr = 2000;
- vdev->timeout.reschedule_suspend = 10;
- vdev->timeout.autosuspend = 10;
- vdev->timeout.d0i3_entry_msg = 5;
- }
-}
-
-static int ivpu_pll_wait_for_cmd_send(struct ivpu_device *vdev)
-{
- return REGB_POLL_FLD(VPU_40XX_BUTTRESS_WP_REQ_CMD, SEND, 0, PLL_TIMEOUT_US);
-}
-
-static int ivpu_pll_cmd_send(struct ivpu_device *vdev, u16 min_ratio, u16 max_ratio,
- u16 target_ratio, u16 epp, u16 config, u16 cdyn)
-{
- int ret;
- u32 val;
-
- ret = ivpu_pll_wait_for_cmd_send(vdev);
- if (ret) {
- ivpu_err(vdev, "Failed to sync before WP request: %d\n", ret);
- return ret;
- }
-
- val = REGB_RD32(VPU_40XX_BUTTRESS_WP_REQ_PAYLOAD0);
- val = REG_SET_FLD_NUM(VPU_40XX_BUTTRESS_WP_REQ_PAYLOAD0, MIN_RATIO, min_ratio, val);
- val = REG_SET_FLD_NUM(VPU_40XX_BUTTRESS_WP_REQ_PAYLOAD0, MAX_RATIO, max_ratio, val);
- REGB_WR32(VPU_40XX_BUTTRESS_WP_REQ_PAYLOAD0, val);
-
- val = REGB_RD32(VPU_40XX_BUTTRESS_WP_REQ_PAYLOAD1);
- val = REG_SET_FLD_NUM(VPU_40XX_BUTTRESS_WP_REQ_PAYLOAD1, TARGET_RATIO, target_ratio, val);
- val = REG_SET_FLD_NUM(VPU_40XX_BUTTRESS_WP_REQ_PAYLOAD1, EPP, epp, val);
- REGB_WR32(VPU_40XX_BUTTRESS_WP_REQ_PAYLOAD1, val);
-
- val = REGB_RD32(VPU_40XX_BUTTRESS_WP_REQ_PAYLOAD2);
- val = REG_SET_FLD_NUM(VPU_40XX_BUTTRESS_WP_REQ_PAYLOAD2, CONFIG, config, val);
- val = REG_SET_FLD_NUM(VPU_40XX_BUTTRESS_WP_REQ_PAYLOAD2, CDYN, cdyn, val);
- REGB_WR32(VPU_40XX_BUTTRESS_WP_REQ_PAYLOAD2, val);
-
- val = REGB_RD32(VPU_40XX_BUTTRESS_WP_REQ_CMD);
- val = REG_SET_FLD(VPU_40XX_BUTTRESS_WP_REQ_CMD, SEND, val);
- REGB_WR32(VPU_40XX_BUTTRESS_WP_REQ_CMD, val);
-
- ret = ivpu_pll_wait_for_cmd_send(vdev);
- if (ret)
- ivpu_err(vdev, "Failed to sync after WP request: %d\n", ret);
-
- return ret;
-}
-
-static int ivpu_pll_wait_for_status_ready(struct ivpu_device *vdev)
-{
- return REGB_POLL_FLD(VPU_40XX_BUTTRESS_VPU_STATUS, READY, 1, PLL_TIMEOUT_US);
-}
-
-static int ivpu_wait_for_clock_own_resource_ack(struct ivpu_device *vdev)
-{
- if (ivpu_is_simics(vdev))
- return 0;
-
- return REGB_POLL_FLD(VPU_40XX_BUTTRESS_VPU_STATUS, CLOCK_RESOURCE_OWN_ACK, 1, TIMEOUT_US);
-}
-
-static void ivpu_pll_init_frequency_ratios(struct ivpu_device *vdev)
-{
- struct ivpu_hw_info *hw = vdev->hw;
- u8 fuse_min_ratio, fuse_pn_ratio, fuse_max_ratio;
- u32 fmin_fuse, fmax_fuse;
-
- fmin_fuse = REGB_RD32(VPU_40XX_BUTTRESS_FMIN_FUSE);
- fuse_min_ratio = REG_GET_FLD(VPU_40XX_BUTTRESS_FMIN_FUSE, MIN_RATIO, fmin_fuse);
- fuse_pn_ratio = REG_GET_FLD(VPU_40XX_BUTTRESS_FMIN_FUSE, PN_RATIO, fmin_fuse);
-
- fmax_fuse = REGB_RD32(VPU_40XX_BUTTRESS_FMAX_FUSE);
- fuse_max_ratio = REG_GET_FLD(VPU_40XX_BUTTRESS_FMAX_FUSE, MAX_RATIO, fmax_fuse);
-
- hw->pll.min_ratio = clamp_t(u8, ivpu_pll_min_ratio, fuse_min_ratio, fuse_max_ratio);
- hw->pll.max_ratio = clamp_t(u8, ivpu_pll_max_ratio, hw->pll.min_ratio, fuse_max_ratio);
- hw->pll.pn_ratio = clamp_t(u8, fuse_pn_ratio, hw->pll.min_ratio, hw->pll.max_ratio);
-}
-
-static int ivpu_pll_drive(struct ivpu_device *vdev, bool enable)
-{
- u16 config = enable ? PLL_CONFIG_DEFAULT : 0;
- u16 cdyn = enable ? PLL_CDYN_DEFAULT : 0;
- u16 epp = enable ? PLL_EPP_DEFAULT : 0;
- struct ivpu_hw_info *hw = vdev->hw;
- u16 target_ratio = hw->pll.pn_ratio;
- int ret;
-
- ivpu_dbg(vdev, PM, "PLL workpoint request: %u Hz, epp: 0x%x, config: 0x%x, cdyn: 0x%x\n",
- PLL_RATIO_TO_FREQ(target_ratio), epp, config, cdyn);
-
- ret = ivpu_pll_cmd_send(vdev, hw->pll.min_ratio, hw->pll.max_ratio,
- target_ratio, epp, config, cdyn);
- if (ret) {
- ivpu_err(vdev, "Failed to send PLL workpoint request: %d\n", ret);
- return ret;
- }
-
- if (enable) {
- ret = ivpu_pll_wait_for_status_ready(vdev);
- if (ret) {
- ivpu_err(vdev, "Timed out waiting for PLL ready status\n");
- return ret;
- }
- }
-
- return 0;
-}
-
-static int ivpu_pll_enable(struct ivpu_device *vdev)
-{
- return ivpu_pll_drive(vdev, true);
-}
-
-static int ivpu_pll_disable(struct ivpu_device *vdev)
-{
- return ivpu_pll_drive(vdev, false);
-}
-
-static void ivpu_boot_host_ss_rst_drive(struct ivpu_device *vdev, bool enable)
-{
- u32 val = REGV_RD32(VPU_40XX_HOST_SS_CPR_RST_EN);
-
- if (enable) {
- val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, TOP_NOC, val);
- val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, DSS_MAS, val);
- val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, CSS_MAS, val);
- } else {
- val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, TOP_NOC, val);
- val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, DSS_MAS, val);
- val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, CSS_MAS, val);
- }
-
- REGV_WR32(VPU_40XX_HOST_SS_CPR_RST_EN, val);
-}
-
-static void ivpu_boot_host_ss_clk_drive(struct ivpu_device *vdev, bool enable)
-{
- u32 val = REGV_RD32(VPU_40XX_HOST_SS_CPR_CLK_EN);
-
- if (enable) {
- val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, TOP_NOC, val);
- val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, DSS_MAS, val);
- val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, CSS_MAS, val);
- } else {
- val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, TOP_NOC, val);
- val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, DSS_MAS, val);
- val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, CSS_MAS, val);
- }
-
- REGV_WR32(VPU_40XX_HOST_SS_CPR_CLK_EN, val);
-}
-
-static int ivpu_boot_noc_qreqn_check(struct ivpu_device *vdev, u32 exp_val)
-{
- u32 val = REGV_RD32(VPU_40XX_HOST_SS_NOC_QREQN);
-
- if (!REG_TEST_FLD_NUM(VPU_40XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, exp_val, val))
- return -EIO;
-
- return 0;
-}
-
-static int ivpu_boot_noc_qacceptn_check(struct ivpu_device *vdev, u32 exp_val)
-{
- u32 val = REGV_RD32(VPU_40XX_HOST_SS_NOC_QACCEPTN);
-
- if (!REG_TEST_FLD_NUM(VPU_40XX_HOST_SS_NOC_QACCEPTN, TOP_SOCMMIO, exp_val, val))
- return -EIO;
-
- return 0;
-}
-
-static int ivpu_boot_noc_qdeny_check(struct ivpu_device *vdev, u32 exp_val)
-{
- u32 val = REGV_RD32(VPU_40XX_HOST_SS_NOC_QDENY);
-
- if (!REG_TEST_FLD_NUM(VPU_40XX_HOST_SS_NOC_QDENY, TOP_SOCMMIO, exp_val, val))
- return -EIO;
-
- return 0;
-}
-
-static int ivpu_boot_top_noc_qrenqn_check(struct ivpu_device *vdev, u32 exp_val)
-{
- u32 val = REGV_RD32(VPU_40XX_TOP_NOC_QREQN);
-
- if (!REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QREQN, CPU_CTRL, exp_val, val) ||
- !REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, exp_val, val))
- return -EIO;
-
- return 0;
-}
-
-static int ivpu_boot_top_noc_qacceptn_check(struct ivpu_device *vdev, u32 exp_val)
-{
- u32 val = REGV_RD32(VPU_40XX_TOP_NOC_QACCEPTN);
-
- if (!REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QACCEPTN, CPU_CTRL, exp_val, val) ||
- !REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QACCEPTN, HOSTIF_L2CACHE, exp_val, val))
- return -EIO;
-
- return 0;
-}
-
-static int ivpu_boot_top_noc_qdeny_check(struct ivpu_device *vdev, u32 exp_val)
-{
- u32 val = REGV_RD32(VPU_40XX_TOP_NOC_QDENY);
-
- if (!REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QDENY, CPU_CTRL, exp_val, val) ||
- !REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QDENY, HOSTIF_L2CACHE, exp_val, val))
- return -EIO;
-
- return 0;
-}
-
-static void ivpu_boot_idle_gen_drive(struct ivpu_device *vdev, bool enable)
-{
- u32 val = REGV_RD32(VPU_40XX_HOST_SS_AON_IDLE_GEN);
-
- if (enable)
- val = REG_SET_FLD(VPU_40XX_HOST_SS_AON_IDLE_GEN, EN, val);
- else
- val = REG_CLR_FLD(VPU_40XX_HOST_SS_AON_IDLE_GEN, EN, val);
-
- REGV_WR32(VPU_40XX_HOST_SS_AON_IDLE_GEN, val);
-}
-
-static int ivpu_boot_host_ss_check(struct ivpu_device *vdev)
-{
- int ret;
-
- ret = ivpu_boot_noc_qreqn_check(vdev, 0x0);
- if (ret) {
- ivpu_err(vdev, "Failed qreqn check: %d\n", ret);
- return ret;
- }
-
- ret = ivpu_boot_noc_qacceptn_check(vdev, 0x0);
- if (ret) {
- ivpu_err(vdev, "Failed qacceptn check: %d\n", ret);
- return ret;
- }
-
- ret = ivpu_boot_noc_qdeny_check(vdev, 0x0);
- if (ret)
- ivpu_err(vdev, "Failed qdeny check %d\n", ret);
-
- return ret;
-}
-
-static int ivpu_boot_host_ss_axi_drive(struct ivpu_device *vdev, bool enable)
-{
- int ret;
- u32 val;
-
- val = REGV_RD32(VPU_40XX_HOST_SS_NOC_QREQN);
- if (enable)
- val = REG_SET_FLD(VPU_40XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, val);
- else
- val = REG_CLR_FLD(VPU_40XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, val);
- REGV_WR32(VPU_40XX_HOST_SS_NOC_QREQN, val);
-
- ret = ivpu_boot_noc_qacceptn_check(vdev, enable ? 0x1 : 0x0);
- if (ret) {
- ivpu_err(vdev, "Failed qacceptn check: %d\n", ret);
- return ret;
- }
-
- ret = ivpu_boot_noc_qdeny_check(vdev, 0x0);
- if (ret) {
- ivpu_err(vdev, "Failed qdeny check: %d\n", ret);
- return ret;
- }
-
- if (enable) {
- REGB_WR32(VPU_40XX_BUTTRESS_PORT_ARBITRATION_WEIGHTS, WEIGHTS_DEFAULT);
- REGB_WR32(VPU_40XX_BUTTRESS_PORT_ARBITRATION_WEIGHTS_ATS, WEIGHTS_ATS_DEFAULT);
- }
-
- return ret;
-}
-
-static int ivpu_boot_host_ss_axi_enable(struct ivpu_device *vdev)
-{
- return ivpu_boot_host_ss_axi_drive(vdev, true);
-}
-
-static int ivpu_boot_host_ss_top_noc_drive(struct ivpu_device *vdev, bool enable)
-{
- int ret;
- u32 val;
-
- val = REGV_RD32(VPU_40XX_TOP_NOC_QREQN);
- if (enable) {
- val = REG_SET_FLD(VPU_40XX_TOP_NOC_QREQN, CPU_CTRL, val);
- val = REG_SET_FLD(VPU_40XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, val);
- } else {
- val = REG_CLR_FLD(VPU_40XX_TOP_NOC_QREQN, CPU_CTRL, val);
- val = REG_CLR_FLD(VPU_40XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, val);
- }
- REGV_WR32(VPU_40XX_TOP_NOC_QREQN, val);
-
- ret = ivpu_boot_top_noc_qacceptn_check(vdev, enable ? 0x1 : 0x0);
- if (ret) {
- ivpu_err(vdev, "Failed qacceptn check: %d\n", ret);
- return ret;
- }
-
- ret = ivpu_boot_top_noc_qdeny_check(vdev, 0x0);
- if (ret)
- ivpu_err(vdev, "Failed qdeny check: %d\n", ret);
-
- return ret;
-}
-
-static int ivpu_boot_host_ss_top_noc_enable(struct ivpu_device *vdev)
-{
- return ivpu_boot_host_ss_top_noc_drive(vdev, true);
-}
-
-static void ivpu_boot_pwr_island_trickle_drive(struct ivpu_device *vdev, bool enable)
-{
- u32 val = REGV_RD32(VPU_40XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0);
-
- if (enable)
- val = REG_SET_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, CSS_CPU, val);
- else
- val = REG_CLR_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, CSS_CPU, val);
-
- REGV_WR32(VPU_40XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, val);
-
- if (enable)
- ndelay(500);
-}
-
-static void ivpu_boot_pwr_island_drive(struct ivpu_device *vdev, bool enable)
-{
- u32 val = REGV_RD32(VPU_40XX_HOST_SS_AON_PWR_ISLAND_EN0);
-
- if (enable)
- val = REG_SET_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_EN0, CSS_CPU, val);
- else
- val = REG_CLR_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_EN0, CSS_CPU, val);
-
- REGV_WR32(VPU_40XX_HOST_SS_AON_PWR_ISLAND_EN0, val);
-
- if (!enable)
- ndelay(500);
-}
-
-static int ivpu_boot_wait_for_pwr_island_status(struct ivpu_device *vdev, u32 exp_val)
-{
- if (ivpu_is_fpga(vdev))
- return 0;
-
- return REGV_POLL_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_STATUS0, CSS_CPU,
- exp_val, PWR_ISLAND_STATUS_TIMEOUT_US);
-}
-
-static void ivpu_boot_pwr_island_isolation_drive(struct ivpu_device *vdev, bool enable)
-{
- u32 val = REGV_RD32(VPU_40XX_HOST_SS_AON_PWR_ISO_EN0);
-
- if (enable)
- val = REG_SET_FLD(VPU_40XX_HOST_SS_AON_PWR_ISO_EN0, CSS_CPU, val);
- else
- val = REG_CLR_FLD(VPU_40XX_HOST_SS_AON_PWR_ISO_EN0, CSS_CPU, val);
-
- REGV_WR32(VPU_40XX_HOST_SS_AON_PWR_ISO_EN0, val);
-}
-
-static void ivpu_boot_no_snoop_enable(struct ivpu_device *vdev)
-{
- u32 val = REGV_RD32(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES);
-
- val = REG_SET_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, SNOOP_OVERRIDE_EN, val);
- val = REG_SET_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, AW_SNOOP_OVERRIDE, val);
- val = REG_CLR_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, AR_SNOOP_OVERRIDE, val);
-
- REGV_WR32(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, val);
-}
-
-static void ivpu_boot_tbu_mmu_enable(struct ivpu_device *vdev)
-{
- u32 val = REGV_RD32(VPU_40XX_HOST_IF_TBU_MMUSSIDV);
-
- val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU0_AWMMUSSIDV, val);
- val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU0_ARMMUSSIDV, val);
- val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU1_AWMMUSSIDV, val);
- val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU1_ARMMUSSIDV, val);
- val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU2_AWMMUSSIDV, val);
- val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU2_ARMMUSSIDV, val);
-
- REGV_WR32(VPU_40XX_HOST_IF_TBU_MMUSSIDV, val);
-}
-
-static int ivpu_boot_cpu_noc_qacceptn_check(struct ivpu_device *vdev, u32 exp_val)
-{
- u32 val = REGV_RD32(VPU_40XX_CPU_SS_CPR_NOC_QACCEPTN);
-
- if (!REG_TEST_FLD_NUM(VPU_40XX_CPU_SS_CPR_NOC_QACCEPTN, TOP_MMIO, exp_val, val))
- return -EIO;
-
- return 0;
-}
-
-static int ivpu_boot_cpu_noc_qdeny_check(struct ivpu_device *vdev, u32 exp_val)
-{
- u32 val = REGV_RD32(VPU_40XX_CPU_SS_CPR_NOC_QDENY);
-
- if (!REG_TEST_FLD_NUM(VPU_40XX_CPU_SS_CPR_NOC_QDENY, TOP_MMIO, exp_val, val))
- return -EIO;
-
- return 0;
-}
-
-static int ivpu_boot_pwr_domain_enable(struct ivpu_device *vdev)
-{
- int ret;
-
- ret = ivpu_wait_for_clock_own_resource_ack(vdev);
- if (ret) {
- ivpu_err(vdev, "Timed out waiting for clock own resource ACK\n");
- return ret;
- }
-
- ivpu_boot_pwr_island_trickle_drive(vdev, true);
- ivpu_boot_pwr_island_drive(vdev, true);
-
- ret = ivpu_boot_wait_for_pwr_island_status(vdev, 0x1);
- if (ret) {
- ivpu_err(vdev, "Timed out waiting for power island status\n");
- return ret;
- }
-
- ret = ivpu_boot_top_noc_qrenqn_check(vdev, 0x0);
- if (ret) {
- ivpu_err(vdev, "Failed qrenqn check %d\n", ret);
- return ret;
- }
-
- ivpu_boot_host_ss_clk_drive(vdev, true);
- ivpu_boot_host_ss_rst_drive(vdev, true);
- ivpu_boot_pwr_island_isolation_drive(vdev, false);
-
- return ret;
-}
-
-static int ivpu_boot_soc_cpu_drive(struct ivpu_device *vdev, bool enable)
-{
- int ret;
- u32 val;
-
- val = REGV_RD32(VPU_40XX_CPU_SS_CPR_NOC_QREQN);
- if (enable)
- val = REG_SET_FLD(VPU_40XX_CPU_SS_CPR_NOC_QREQN, TOP_MMIO, val);
- else
- val = REG_CLR_FLD(VPU_40XX_CPU_SS_CPR_NOC_QREQN, TOP_MMIO, val);
- REGV_WR32(VPU_40XX_CPU_SS_CPR_NOC_QREQN, val);
-
- ret = ivpu_boot_cpu_noc_qacceptn_check(vdev, enable ? 0x1 : 0x0);
- if (ret) {
- ivpu_err(vdev, "Failed qacceptn check: %d\n", ret);
- return ret;
- }
-
- ret = ivpu_boot_cpu_noc_qdeny_check(vdev, 0x0);
- if (ret)
- ivpu_err(vdev, "Failed qdeny check: %d\n", ret);
-
- return ret;
-}
-
-static int ivpu_boot_soc_cpu_enable(struct ivpu_device *vdev)
-{
- return ivpu_boot_soc_cpu_drive(vdev, true);
-}
-
-static int ivpu_boot_soc_cpu_boot(struct ivpu_device *vdev)
-{
- int ret;
- u32 val;
- u64 val64;
-
- ret = ivpu_boot_soc_cpu_enable(vdev);
- if (ret) {
- ivpu_err(vdev, "Failed to enable SOC CPU: %d\n", ret);
- return ret;
- }
-
- val64 = vdev->fw->entry_point;
- val64 <<= ffs(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO_IMAGE_LOCATION_MASK) - 1;
- REGV_WR64(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO, val64);
-
- val = REGV_RD32(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO);
- val = REG_SET_FLD(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO, DONE, val);
- REGV_WR32(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO, val);
-
- ivpu_dbg(vdev, PM, "Booting firmware, mode: %s\n",
- ivpu_fw_is_cold_boot(vdev) ? "cold boot" : "resume");
-
- return 0;
-}
-
-static int ivpu_boot_d0i3_drive(struct ivpu_device *vdev, bool enable)
-{
- int ret;
- u32 val;
-
- ret = REGB_POLL_FLD(VPU_40XX_BUTTRESS_D0I3_CONTROL, INPROGRESS, 0, TIMEOUT_US);
- if (ret) {
- ivpu_err(vdev, "Failed to sync before D0i3 transition: %d\n", ret);
- return ret;
- }
-
- val = REGB_RD32(VPU_40XX_BUTTRESS_D0I3_CONTROL);
- if (enable)
- val = REG_SET_FLD(VPU_40XX_BUTTRESS_D0I3_CONTROL, I3, val);
- else
- val = REG_CLR_FLD(VPU_40XX_BUTTRESS_D0I3_CONTROL, I3, val);
- REGB_WR32(VPU_40XX_BUTTRESS_D0I3_CONTROL, val);
-
- ret = REGB_POLL_FLD(VPU_40XX_BUTTRESS_D0I3_CONTROL, INPROGRESS, 0, TIMEOUT_US);
- if (ret) {
- ivpu_err(vdev, "Failed to sync after D0i3 transition: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-static bool ivpu_tile_disable_check(u32 config)
-{
- /* Allowed values: 0 or one bit from range 0-5 (6 tiles) */
- if (config == 0)
- return true;
-
- if (config > BIT(TILE_MAX_NUM - 1))
- return false;
-
- if ((config & (config - 1)) == 0)
- return true;
-
- return false;
-}
-
-static int ivpu_hw_40xx_info_init(struct ivpu_device *vdev)
-{
- struct ivpu_hw_info *hw = vdev->hw;
- u32 tile_disable;
- u32 fuse;
-
- fuse = REGB_RD32(VPU_40XX_BUTTRESS_TILE_FUSE);
- if (!REG_TEST_FLD(VPU_40XX_BUTTRESS_TILE_FUSE, VALID, fuse)) {
- ivpu_err(vdev, "Fuse: invalid (0x%x)\n", fuse);
- return -EIO;
- }
-
- tile_disable = REG_GET_FLD(VPU_40XX_BUTTRESS_TILE_FUSE, CONFIG, fuse);
- if (!ivpu_tile_disable_check(tile_disable)) {
- ivpu_err(vdev, "Fuse: Invalid tile disable config (0x%x)\n", tile_disable);
- return -EIO;
- }
-
- if (tile_disable)
- ivpu_dbg(vdev, MISC, "Fuse: %d tiles enabled. Tile number %d disabled\n",
- TILE_MAX_NUM - 1, ffs(tile_disable) - 1);
- else
- ivpu_dbg(vdev, MISC, "Fuse: All %d tiles enabled\n", TILE_MAX_NUM);
-
- hw->tile_fuse = tile_disable;
- hw->pll.profiling_freq = PLL_PROFILING_FREQ_DEFAULT;
-
- ivpu_pll_init_frequency_ratios(vdev);
-
- ivpu_hw_init_range(&vdev->hw->ranges.global, 0x80000000, SZ_512M);
- ivpu_hw_init_range(&vdev->hw->ranges.user, 0x80000000, SZ_256M);
- ivpu_hw_init_range(&vdev->hw->ranges.shave, 0x80000000 + SZ_256M, SZ_2G - SZ_256M);
- ivpu_hw_init_range(&vdev->hw->ranges.dma, 0x200000000, SZ_8G);
-
- ivpu_hw_read_platform(vdev);
- ivpu_hw_wa_init(vdev);
- ivpu_hw_timeouts_init(vdev);
-
- return 0;
-}
-
-static int ivpu_hw_40xx_ip_reset(struct ivpu_device *vdev)
-{
- int ret;
- u32 val;
-
- ret = REGB_POLL_FLD(VPU_40XX_BUTTRESS_IP_RESET, TRIGGER, 0, TIMEOUT_US);
- if (ret) {
- ivpu_err(vdev, "Wait for *_TRIGGER timed out\n");
- return ret;
- }
-
- val = REGB_RD32(VPU_40XX_BUTTRESS_IP_RESET);
- val = REG_SET_FLD(VPU_40XX_BUTTRESS_IP_RESET, TRIGGER, val);
- REGB_WR32(VPU_40XX_BUTTRESS_IP_RESET, val);
-
- ret = REGB_POLL_FLD(VPU_40XX_BUTTRESS_IP_RESET, TRIGGER, 0, TIMEOUT_US);
- if (ret)
- ivpu_err(vdev, "Timed out waiting for RESET completion\n");
-
- return ret;
-}
-
-static int ivpu_hw_40xx_reset(struct ivpu_device *vdev)
-{
- int ret = 0;
-
- if (ivpu_hw_40xx_ip_reset(vdev)) {
- ivpu_err(vdev, "Failed to reset NPU IP\n");
- ret = -EIO;
- }
-
- if (ivpu_pll_disable(vdev)) {
- ivpu_err(vdev, "Failed to disable PLL\n");
- ret = -EIO;
- }
-
- return ret;
-}
-
-static int ivpu_hw_40xx_d0i3_enable(struct ivpu_device *vdev)
-{
- int ret;
-
- if (IVPU_WA(punit_disabled))
- return 0;
-
- ret = ivpu_boot_d0i3_drive(vdev, true);
- if (ret)
- ivpu_err(vdev, "Failed to enable D0i3: %d\n", ret);
-
- udelay(5); /* VPU requires 5 us to complete the transition */
-
- return ret;
-}
-
-static int ivpu_hw_40xx_d0i3_disable(struct ivpu_device *vdev)
-{
- int ret;
-
- if (IVPU_WA(punit_disabled))
- return 0;
-
- ret = ivpu_boot_d0i3_drive(vdev, false);
- if (ret)
- ivpu_err(vdev, "Failed to disable D0i3: %d\n", ret);
-
- return ret;
-}
-
-static void ivpu_hw_40xx_profiling_freq_reg_set(struct ivpu_device *vdev)
-{
- u32 val = REGB_RD32(VPU_40XX_BUTTRESS_VPU_STATUS);
-
- if (vdev->hw->pll.profiling_freq == PLL_PROFILING_FREQ_DEFAULT)
- val = REG_CLR_FLD(VPU_40XX_BUTTRESS_VPU_STATUS, PERF_CLK, val);
- else
- val = REG_SET_FLD(VPU_40XX_BUTTRESS_VPU_STATUS, PERF_CLK, val);
-
- REGB_WR32(VPU_40XX_BUTTRESS_VPU_STATUS, val);
-}
-
-static void ivpu_hw_40xx_ats_print(struct ivpu_device *vdev)
-{
- ivpu_dbg(vdev, MISC, "Buttress ATS: %s\n",
- REGB_RD32(VPU_40XX_BUTTRESS_HM_ATS) ? "Enable" : "Disable");
-}
-
-static void ivpu_hw_40xx_clock_relinquish_disable(struct ivpu_device *vdev)
-{
- u32 val = REGB_RD32(VPU_40XX_BUTTRESS_VPU_STATUS);
-
- val = REG_SET_FLD(VPU_40XX_BUTTRESS_VPU_STATUS, DISABLE_CLK_RELINQUISH, val);
- REGB_WR32(VPU_40XX_BUTTRESS_VPU_STATUS, val);
-}
-
-static int ivpu_hw_40xx_power_up(struct ivpu_device *vdev)
-{
- int ret;
-
- ret = ivpu_hw_40xx_d0i3_disable(vdev);
- if (ret)
- ivpu_warn(vdev, "Failed to disable D0I3: %d\n", ret);
-
- ret = ivpu_pll_enable(vdev);
- if (ret) {
- ivpu_err(vdev, "Failed to enable PLL: %d\n", ret);
- return ret;
- }
-
- if (IVPU_WA(disable_clock_relinquish))
- ivpu_hw_40xx_clock_relinquish_disable(vdev);
- ivpu_hw_40xx_profiling_freq_reg_set(vdev);
- ivpu_hw_40xx_ats_print(vdev);
-
- ret = ivpu_boot_host_ss_check(vdev);
- if (ret) {
- ivpu_err(vdev, "Failed to configure host SS: %d\n", ret);
- return ret;
- }
-
- ivpu_boot_idle_gen_drive(vdev, false);
-
- ret = ivpu_boot_pwr_domain_enable(vdev);
- if (ret) {
- ivpu_err(vdev, "Failed to enable power domain: %d\n", ret);
- return ret;
- }
-
- ret = ivpu_boot_host_ss_axi_enable(vdev);
- if (ret) {
- ivpu_err(vdev, "Failed to enable AXI: %d\n", ret);
- return ret;
- }
-
- ret = ivpu_boot_host_ss_top_noc_enable(vdev);
- if (ret)
- ivpu_err(vdev, "Failed to enable TOP NOC: %d\n", ret);
-
- return ret;
-}
-
-static int ivpu_hw_40xx_boot_fw(struct ivpu_device *vdev)
-{
- int ret;
-
- ivpu_boot_no_snoop_enable(vdev);
- ivpu_boot_tbu_mmu_enable(vdev);
-
- ret = ivpu_boot_soc_cpu_boot(vdev);
- if (ret)
- ivpu_err(vdev, "Failed to boot SOC CPU: %d\n", ret);
-
- return ret;
-}
-
-static bool ivpu_hw_40xx_is_idle(struct ivpu_device *vdev)
-{
- u32 val;
-
- if (IVPU_WA(punit_disabled))
- return true;
-
- val = REGB_RD32(VPU_40XX_BUTTRESS_VPU_STATUS);
- return REG_TEST_FLD(VPU_40XX_BUTTRESS_VPU_STATUS, READY, val) &&
- REG_TEST_FLD(VPU_40XX_BUTTRESS_VPU_STATUS, IDLE, val);
-}
-
-static int ivpu_hw_40xx_wait_for_idle(struct ivpu_device *vdev)
-{
- return REGB_POLL_FLD(VPU_40XX_BUTTRESS_VPU_STATUS, IDLE, 0x1, IDLE_TIMEOUT_US);
-}
-
-static void ivpu_hw_40xx_save_d0i3_entry_timestamp(struct ivpu_device *vdev)
-{
- vdev->hw->d0i3_entry_host_ts = ktime_get_boottime();
- vdev->hw->d0i3_entry_vpu_ts = REGV_RD64(VPU_40XX_CPU_SS_TIM_PERF_EXT_FREE_CNT);
-}
-
-static int ivpu_hw_40xx_power_down(struct ivpu_device *vdev)
-{
- int ret = 0;
-
- ivpu_hw_40xx_save_d0i3_entry_timestamp(vdev);
-
- if (!ivpu_hw_40xx_is_idle(vdev) && ivpu_hw_40xx_ip_reset(vdev))
- ivpu_warn(vdev, "Failed to reset the NPU\n");
-
- if (ivpu_pll_disable(vdev)) {
- ivpu_err(vdev, "Failed to disable PLL\n");
- ret = -EIO;
- }
-
- if (ivpu_hw_40xx_d0i3_enable(vdev)) {
- ivpu_err(vdev, "Failed to enter D0I3\n");
- ret = -EIO;
- }
-
- return ret;
-}
-
-static void ivpu_hw_40xx_wdt_disable(struct ivpu_device *vdev)
-{
- u32 val;
-
- REGV_WR32(VPU_40XX_CPU_SS_TIM_SAFE, TIM_SAFE_ENABLE);
- REGV_WR32(VPU_40XX_CPU_SS_TIM_WATCHDOG, TIM_WATCHDOG_RESET_VALUE);
-
- REGV_WR32(VPU_40XX_CPU_SS_TIM_SAFE, TIM_SAFE_ENABLE);
- REGV_WR32(VPU_40XX_CPU_SS_TIM_WDOG_EN, 0);
-
- val = REGV_RD32(VPU_40XX_CPU_SS_TIM_GEN_CONFIG);
- val = REG_CLR_FLD(VPU_40XX_CPU_SS_TIM_GEN_CONFIG, WDOG_TO_INT_CLR, val);
- REGV_WR32(VPU_40XX_CPU_SS_TIM_GEN_CONFIG, val);
-}
-
-static u32 ivpu_hw_40xx_profiling_freq_get(struct ivpu_device *vdev)
-{
- return vdev->hw->pll.profiling_freq;
-}
-
-static void ivpu_hw_40xx_profiling_freq_drive(struct ivpu_device *vdev, bool enable)
-{
- if (enable)
- vdev->hw->pll.profiling_freq = PLL_PROFILING_FREQ_HIGH;
- else
- vdev->hw->pll.profiling_freq = PLL_PROFILING_FREQ_DEFAULT;
-}
-
-/* Register indirect accesses */
-static u32 ivpu_hw_40xx_reg_pll_freq_get(struct ivpu_device *vdev)
-{
- u32 pll_curr_ratio;
-
- pll_curr_ratio = REGB_RD32(VPU_40XX_BUTTRESS_PLL_FREQ);
- pll_curr_ratio &= VPU_40XX_BUTTRESS_PLL_FREQ_RATIO_MASK;
-
- return PLL_RATIO_TO_FREQ(pll_curr_ratio);
-}
-
-static u32 ivpu_hw_40xx_ratio_to_freq(struct ivpu_device *vdev, u32 ratio)
-{
- return PLL_RATIO_TO_FREQ(ratio);
-}
-
-static u32 ivpu_hw_40xx_reg_telemetry_offset_get(struct ivpu_device *vdev)
-{
- return REGB_RD32(VPU_40XX_BUTTRESS_VPU_TELEMETRY_OFFSET);
-}
-
-static u32 ivpu_hw_40xx_reg_telemetry_size_get(struct ivpu_device *vdev)
-{
- return REGB_RD32(VPU_40XX_BUTTRESS_VPU_TELEMETRY_SIZE);
-}
-
-static u32 ivpu_hw_40xx_reg_telemetry_enable_get(struct ivpu_device *vdev)
-{
- return REGB_RD32(VPU_40XX_BUTTRESS_VPU_TELEMETRY_ENABLE);
-}
-
-static void ivpu_hw_40xx_reg_db_set(struct ivpu_device *vdev, u32 db_id)
-{
- u32 reg_stride = VPU_40XX_CPU_SS_DOORBELL_1 - VPU_40XX_CPU_SS_DOORBELL_0;
- u32 val = REG_FLD(VPU_40XX_CPU_SS_DOORBELL_0, SET);
-
- REGV_WR32I(VPU_40XX_CPU_SS_DOORBELL_0, reg_stride, db_id, val);
-}
-
-static u32 ivpu_hw_40xx_reg_ipc_rx_addr_get(struct ivpu_device *vdev)
-{
- return REGV_RD32(VPU_40XX_HOST_SS_TIM_IPC_FIFO_ATM);
-}
-
-static u32 ivpu_hw_40xx_reg_ipc_rx_count_get(struct ivpu_device *vdev)
-{
- u32 count = REGV_RD32_SILENT(VPU_40XX_HOST_SS_TIM_IPC_FIFO_STAT);
-
- return REG_GET_FLD(VPU_40XX_HOST_SS_TIM_IPC_FIFO_STAT, FILL_LEVEL, count);
-}
-
-static void ivpu_hw_40xx_reg_ipc_tx_set(struct ivpu_device *vdev, u32 vpu_addr)
-{
- REGV_WR32(VPU_40XX_CPU_SS_TIM_IPC_FIFO, vpu_addr);
-}
-
-static void ivpu_hw_40xx_irq_clear(struct ivpu_device *vdev)
-{
- REGV_WR64(VPU_40XX_HOST_SS_ICB_CLEAR_0, ICB_0_1_IRQ_MASK);
-}
-
-static void ivpu_hw_40xx_irq_enable(struct ivpu_device *vdev)
-{
- REGV_WR32(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, ITF_FIREWALL_VIOLATION_MASK);
- REGV_WR64(VPU_40XX_HOST_SS_ICB_ENABLE_0, ICB_0_1_IRQ_MASK);
- REGB_WR32(VPU_40XX_BUTTRESS_LOCAL_INT_MASK, BUTTRESS_IRQ_ENABLE_MASK);
- REGB_WR32(VPU_40XX_BUTTRESS_GLOBAL_INT_MASK, 0x0);
-}
-
-static void ivpu_hw_40xx_irq_disable(struct ivpu_device *vdev)
-{
- REGB_WR32(VPU_40XX_BUTTRESS_GLOBAL_INT_MASK, 0x1);
- REGB_WR32(VPU_40XX_BUTTRESS_LOCAL_INT_MASK, BUTTRESS_IRQ_DISABLE_MASK);
- REGV_WR64(VPU_40XX_HOST_SS_ICB_ENABLE_0, 0x0ull);
- REGV_WR32(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, 0x0ul);
-}
-
-static void ivpu_hw_40xx_irq_wdt_nce_handler(struct ivpu_device *vdev)
-{
- /* TODO: For LNN hang consider engine reset instead of full recovery */
- ivpu_pm_trigger_recovery(vdev, "WDT NCE IRQ");
-}
-
-static void ivpu_hw_40xx_irq_wdt_mss_handler(struct ivpu_device *vdev)
-{
- ivpu_hw_wdt_disable(vdev);
- ivpu_pm_trigger_recovery(vdev, "WDT MSS IRQ");
-}
-
-static void ivpu_hw_40xx_irq_noc_firewall_handler(struct ivpu_device *vdev)
-{
- ivpu_pm_trigger_recovery(vdev, "NOC Firewall IRQ");
-}
-
-/* Handler for IRQs from VPU core (irqV) */
-static bool ivpu_hw_40xx_irqv_handler(struct ivpu_device *vdev, int irq, bool *wake_thread)
-{
- u32 status = REGV_RD32(VPU_40XX_HOST_SS_ICB_STATUS_0) & ICB_0_IRQ_MASK;
-
- if (!status)
- return false;
-
- REGV_WR32(VPU_40XX_HOST_SS_ICB_CLEAR_0, status);
-
- if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_0_INT, status))
- ivpu_mmu_irq_evtq_handler(vdev);
-
- if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, HOST_IPC_FIFO_INT, status))
- ivpu_ipc_irq_handler(vdev, wake_thread);
-
- if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_1_INT, status))
- ivpu_dbg(vdev, IRQ, "MMU sync complete\n");
-
- if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_2_INT, status))
- ivpu_mmu_irq_gerr_handler(vdev);
-
- if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT, status))
- ivpu_hw_40xx_irq_wdt_mss_handler(vdev);
-
- if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT, status))
- ivpu_hw_40xx_irq_wdt_nce_handler(vdev);
-
- if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT, status))
- ivpu_hw_40xx_irq_noc_firewall_handler(vdev);
-
- return true;
-}
-
-/* Handler for IRQs from Buttress core (irqB) */
-static bool ivpu_hw_40xx_irqb_handler(struct ivpu_device *vdev, int irq)
-{
- bool schedule_recovery = false;
- u32 status = REGB_RD32(VPU_40XX_BUTTRESS_INTERRUPT_STAT) & BUTTRESS_IRQ_MASK;
-
- if (!status)
- return false;
-
- if (REG_TEST_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, FREQ_CHANGE, status))
- ivpu_dbg(vdev, IRQ, "FREQ_CHANGE");
-
- if (REG_TEST_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, ATS_ERR, status)) {
- ivpu_err(vdev, "ATS_ERR LOG1 0x%08x ATS_ERR_LOG2 0x%08x\n",
- REGB_RD32(VPU_40XX_BUTTRESS_ATS_ERR_LOG1),
- REGB_RD32(VPU_40XX_BUTTRESS_ATS_ERR_LOG2));
- REGB_WR32(VPU_40XX_BUTTRESS_ATS_ERR_CLEAR, 0x1);
- schedule_recovery = true;
- }
-
- if (REG_TEST_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, CFI0_ERR, status)) {
- ivpu_err(vdev, "CFI0_ERR 0x%08x", REGB_RD32(VPU_40XX_BUTTRESS_CFI0_ERR_LOG));
- REGB_WR32(VPU_40XX_BUTTRESS_CFI0_ERR_CLEAR, 0x1);
- schedule_recovery = true;
- }
-
- if (REG_TEST_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, CFI1_ERR, status)) {
- ivpu_err(vdev, "CFI1_ERR 0x%08x", REGB_RD32(VPU_40XX_BUTTRESS_CFI1_ERR_LOG));
- REGB_WR32(VPU_40XX_BUTTRESS_CFI1_ERR_CLEAR, 0x1);
- schedule_recovery = true;
- }
-
- if (REG_TEST_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, IMR0_ERR, status)) {
- ivpu_err(vdev, "IMR_ERR_CFI0 LOW: 0x%08x HIGH: 0x%08x",
- REGB_RD32(VPU_40XX_BUTTRESS_IMR_ERR_CFI0_LOW),
- REGB_RD32(VPU_40XX_BUTTRESS_IMR_ERR_CFI0_HIGH));
- REGB_WR32(VPU_40XX_BUTTRESS_IMR_ERR_CFI0_CLEAR, 0x1);
- schedule_recovery = true;
- }
-
- if (REG_TEST_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, IMR1_ERR, status)) {
- ivpu_err(vdev, "IMR_ERR_CFI1 LOW: 0x%08x HIGH: 0x%08x",
- REGB_RD32(VPU_40XX_BUTTRESS_IMR_ERR_CFI1_LOW),
- REGB_RD32(VPU_40XX_BUTTRESS_IMR_ERR_CFI1_HIGH));
- REGB_WR32(VPU_40XX_BUTTRESS_IMR_ERR_CFI1_CLEAR, 0x1);
- schedule_recovery = true;
- }
-
- if (REG_TEST_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, SURV_ERR, status)) {
- ivpu_err(vdev, "Survivability error detected\n");
- schedule_recovery = true;
- }
-
- /* This must be done after interrupts are cleared at the source. */
- REGB_WR32(VPU_40XX_BUTTRESS_INTERRUPT_STAT, status);
-
- if (schedule_recovery)
- ivpu_pm_trigger_recovery(vdev, "Buttress IRQ");
-
- return true;
-}
-
-static irqreturn_t ivpu_hw_40xx_irq_handler(int irq, void *ptr)
-{
- bool irqv_handled, irqb_handled, wake_thread = false;
- struct ivpu_device *vdev = ptr;
-
- REGB_WR32(VPU_40XX_BUTTRESS_GLOBAL_INT_MASK, 0x1);
-
- irqv_handled = ivpu_hw_40xx_irqv_handler(vdev, irq, &wake_thread);
- irqb_handled = ivpu_hw_40xx_irqb_handler(vdev, irq);
-
- /* Re-enable global interrupts to re-trigger MSI for pending interrupts */
- REGB_WR32(VPU_40XX_BUTTRESS_GLOBAL_INT_MASK, 0x0);
-
- if (wake_thread)
- return IRQ_WAKE_THREAD;
- if (irqv_handled || irqb_handled)
- return IRQ_HANDLED;
- return IRQ_NONE;
-}
-
-static void ivpu_hw_40xx_diagnose_failure(struct ivpu_device *vdev)
-{
- u32 irqv = REGV_RD32(VPU_40XX_HOST_SS_ICB_STATUS_0) & ICB_0_IRQ_MASK;
- u32 irqb = REGB_RD32(VPU_40XX_BUTTRESS_INTERRUPT_STAT) & BUTTRESS_IRQ_MASK;
-
- if (ivpu_hw_40xx_reg_ipc_rx_count_get(vdev))
- ivpu_err(vdev, "IPC FIFO queue not empty, missed IPC IRQ");
-
- if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT, irqv))
- ivpu_err(vdev, "WDT MSS timeout detected\n");
-
- if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT, irqv))
- ivpu_err(vdev, "WDT NCE timeout detected\n");
-
- if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT, irqv))
- ivpu_err(vdev, "NOC Firewall irq detected\n");
-
- if (REG_TEST_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, ATS_ERR, irqb)) {
- ivpu_err(vdev, "ATS_ERR_LOG1 0x%08x ATS_ERR_LOG2 0x%08x\n",
- REGB_RD32(VPU_40XX_BUTTRESS_ATS_ERR_LOG1),
- REGB_RD32(VPU_40XX_BUTTRESS_ATS_ERR_LOG2));
- }
-
- if (REG_TEST_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, CFI0_ERR, irqb))
- ivpu_err(vdev, "CFI0_ERR_LOG 0x%08x\n", REGB_RD32(VPU_40XX_BUTTRESS_CFI0_ERR_LOG));
-
- if (REG_TEST_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, CFI1_ERR, irqb))
- ivpu_err(vdev, "CFI1_ERR_LOG 0x%08x\n", REGB_RD32(VPU_40XX_BUTTRESS_CFI1_ERR_LOG));
-
- if (REG_TEST_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, IMR0_ERR, irqb))
- ivpu_err(vdev, "IMR_ERR_CFI0 LOW: 0x%08x HIGH: 0x%08x\n",
- REGB_RD32(VPU_40XX_BUTTRESS_IMR_ERR_CFI0_LOW),
- REGB_RD32(VPU_40XX_BUTTRESS_IMR_ERR_CFI0_HIGH));
-
- if (REG_TEST_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, IMR1_ERR, irqb))
- ivpu_err(vdev, "IMR_ERR_CFI1 LOW: 0x%08x HIGH: 0x%08x\n",
- REGB_RD32(VPU_40XX_BUTTRESS_IMR_ERR_CFI1_LOW),
- REGB_RD32(VPU_40XX_BUTTRESS_IMR_ERR_CFI1_HIGH));
-
- if (REG_TEST_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, SURV_ERR, irqb))
- ivpu_err(vdev, "Survivability error detected\n");
-}
-
-const struct ivpu_hw_ops ivpu_hw_40xx_ops = {
- .info_init = ivpu_hw_40xx_info_init,
- .power_up = ivpu_hw_40xx_power_up,
- .is_idle = ivpu_hw_40xx_is_idle,
- .wait_for_idle = ivpu_hw_40xx_wait_for_idle,
- .power_down = ivpu_hw_40xx_power_down,
- .reset = ivpu_hw_40xx_reset,
- .boot_fw = ivpu_hw_40xx_boot_fw,
- .wdt_disable = ivpu_hw_40xx_wdt_disable,
- .diagnose_failure = ivpu_hw_40xx_diagnose_failure,
- .profiling_freq_get = ivpu_hw_40xx_profiling_freq_get,
- .profiling_freq_drive = ivpu_hw_40xx_profiling_freq_drive,
- .reg_pll_freq_get = ivpu_hw_40xx_reg_pll_freq_get,
- .ratio_to_freq = ivpu_hw_40xx_ratio_to_freq,
- .reg_telemetry_offset_get = ivpu_hw_40xx_reg_telemetry_offset_get,
- .reg_telemetry_size_get = ivpu_hw_40xx_reg_telemetry_size_get,
- .reg_telemetry_enable_get = ivpu_hw_40xx_reg_telemetry_enable_get,
- .reg_db_set = ivpu_hw_40xx_reg_db_set,
- .reg_ipc_rx_addr_get = ivpu_hw_40xx_reg_ipc_rx_addr_get,
- .reg_ipc_rx_count_get = ivpu_hw_40xx_reg_ipc_rx_count_get,
- .reg_ipc_tx_set = ivpu_hw_40xx_reg_ipc_tx_set,
- .irq_clear = ivpu_hw_40xx_irq_clear,
- .irq_enable = ivpu_hw_40xx_irq_enable,
- .irq_disable = ivpu_hw_40xx_irq_disable,
- .irq_handler = ivpu_hw_40xx_irq_handler,
-};
diff --git a/drivers/accel/ivpu/ivpu_hw_40xx_reg.h b/drivers/accel/ivpu/ivpu_hw_40xx_reg.h
index ff4a5d4f5821..d0b795b344c7 100644
--- a/drivers/accel/ivpu/ivpu_hw_40xx_reg.h
+++ b/drivers/accel/ivpu/ivpu_hw_40xx_reg.h
@@ -8,91 +8,6 @@
#include <linux/bits.h>
-#define VPU_40XX_BUTTRESS_INTERRUPT_STAT 0x00000000u
-#define VPU_40XX_BUTTRESS_INTERRUPT_STAT_FREQ_CHANGE_MASK BIT_MASK(0)
-#define VPU_40XX_BUTTRESS_INTERRUPT_STAT_ATS_ERR_MASK BIT_MASK(1)
-#define VPU_40XX_BUTTRESS_INTERRUPT_STAT_CFI0_ERR_MASK BIT_MASK(2)
-#define VPU_40XX_BUTTRESS_INTERRUPT_STAT_CFI1_ERR_MASK BIT_MASK(3)
-#define VPU_40XX_BUTTRESS_INTERRUPT_STAT_IMR0_ERR_MASK BIT_MASK(4)
-#define VPU_40XX_BUTTRESS_INTERRUPT_STAT_IMR1_ERR_MASK BIT_MASK(5)
-#define VPU_40XX_BUTTRESS_INTERRUPT_STAT_SURV_ERR_MASK BIT_MASK(6)
-
-#define VPU_40XX_BUTTRESS_LOCAL_INT_MASK 0x00000004u
-#define VPU_40XX_BUTTRESS_GLOBAL_INT_MASK 0x00000008u
-
-#define VPU_40XX_BUTTRESS_HM_ATS 0x0000000cu
-
-#define VPU_40XX_BUTTRESS_ATS_ERR_LOG1 0x00000010u
-#define VPU_40XX_BUTTRESS_ATS_ERR_LOG2 0x00000014u
-#define VPU_40XX_BUTTRESS_ATS_ERR_CLEAR 0x00000018u
-
-#define VPU_40XX_BUTTRESS_CFI0_ERR_LOG 0x0000001cu
-#define VPU_40XX_BUTTRESS_CFI0_ERR_CLEAR 0x00000020u
-
-#define VPU_40XX_BUTTRESS_PORT_ARBITRATION_WEIGHTS_ATS 0x00000024u
-
-#define VPU_40XX_BUTTRESS_CFI1_ERR_LOG 0x00000040u
-#define VPU_40XX_BUTTRESS_CFI1_ERR_CLEAR 0x00000044u
-
-#define VPU_40XX_BUTTRESS_IMR_ERR_CFI0_LOW 0x00000048u
-#define VPU_40XX_BUTTRESS_IMR_ERR_CFI0_HIGH 0x0000004cu
-#define VPU_40XX_BUTTRESS_IMR_ERR_CFI0_CLEAR 0x00000050u
-
-#define VPU_40XX_BUTTRESS_PORT_ARBITRATION_WEIGHTS 0x00000054u
-
-#define VPU_40XX_BUTTRESS_IMR_ERR_CFI1_LOW 0x00000058u
-#define VPU_40XX_BUTTRESS_IMR_ERR_CFI1_HIGH 0x0000005cu
-#define VPU_40XX_BUTTRESS_IMR_ERR_CFI1_CLEAR 0x00000060u
-
-#define VPU_40XX_BUTTRESS_WP_REQ_PAYLOAD0 0x00000130u
-#define VPU_40XX_BUTTRESS_WP_REQ_PAYLOAD0_MIN_RATIO_MASK GENMASK(15, 0)
-#define VPU_40XX_BUTTRESS_WP_REQ_PAYLOAD0_MAX_RATIO_MASK GENMASK(31, 16)
-
-#define VPU_40XX_BUTTRESS_WP_REQ_PAYLOAD1 0x00000134u
-#define VPU_40XX_BUTTRESS_WP_REQ_PAYLOAD1_TARGET_RATIO_MASK GENMASK(15, 0)
-#define VPU_40XX_BUTTRESS_WP_REQ_PAYLOAD1_EPP_MASK GENMASK(31, 16)
-
-#define VPU_40XX_BUTTRESS_WP_REQ_PAYLOAD2 0x00000138u
-#define VPU_40XX_BUTTRESS_WP_REQ_PAYLOAD2_CONFIG_MASK GENMASK(15, 0)
-#define VPU_40XX_BUTTRESS_WP_REQ_PAYLOAD2_CDYN_MASK GENMASK(31, 16)
-
-#define VPU_40XX_BUTTRESS_WP_REQ_CMD 0x0000013cu
-#define VPU_40XX_BUTTRESS_WP_REQ_CMD_SEND_MASK BIT_MASK(0)
-
-#define VPU_40XX_BUTTRESS_PLL_FREQ 0x00000148u
-#define VPU_40XX_BUTTRESS_PLL_FREQ_RATIO_MASK GENMASK(15, 0)
-
-#define VPU_40XX_BUTTRESS_TILE_FUSE 0x00000150u
-#define VPU_40XX_BUTTRESS_TILE_FUSE_VALID_MASK BIT_MASK(0)
-#define VPU_40XX_BUTTRESS_TILE_FUSE_CONFIG_MASK GENMASK(6, 1)
-
-#define VPU_40XX_BUTTRESS_VPU_STATUS 0x00000154u
-#define VPU_40XX_BUTTRESS_VPU_STATUS_READY_MASK BIT_MASK(0)
-#define VPU_40XX_BUTTRESS_VPU_STATUS_IDLE_MASK BIT_MASK(1)
-#define VPU_40XX_BUTTRESS_VPU_STATUS_DUP_IDLE_MASK BIT_MASK(2)
-#define VPU_40XX_BUTTRESS_VPU_STATUS_CLOCK_RESOURCE_OWN_ACK_MASK BIT_MASK(6)
-#define VPU_40XX_BUTTRESS_VPU_STATUS_POWER_RESOURCE_OWN_ACK_MASK BIT_MASK(7)
-#define VPU_40XX_BUTTRESS_VPU_STATUS_PERF_CLK_MASK BIT_MASK(11)
-#define VPU_40XX_BUTTRESS_VPU_STATUS_DISABLE_CLK_RELINQUISH_MASK BIT_MASK(12)
-
-#define VPU_40XX_BUTTRESS_IP_RESET 0x00000160u
-#define VPU_40XX_BUTTRESS_IP_RESET_TRIGGER_MASK BIT_MASK(0)
-
-#define VPU_40XX_BUTTRESS_D0I3_CONTROL 0x00000164u
-#define VPU_40XX_BUTTRESS_D0I3_CONTROL_INPROGRESS_MASK BIT_MASK(0)
-#define VPU_40XX_BUTTRESS_D0I3_CONTROL_I3_MASK BIT_MASK(2)
-
-#define VPU_40XX_BUTTRESS_VPU_TELEMETRY_OFFSET 0x00000168u
-#define VPU_40XX_BUTTRESS_VPU_TELEMETRY_SIZE 0x0000016cu
-#define VPU_40XX_BUTTRESS_VPU_TELEMETRY_ENABLE 0x00000170u
-
-#define VPU_40XX_BUTTRESS_FMIN_FUSE 0x00000174u
-#define VPU_40XX_BUTTRESS_FMIN_FUSE_MIN_RATIO_MASK GENMASK(7, 0)
-#define VPU_40XX_BUTTRESS_FMIN_FUSE_PN_RATIO_MASK GENMASK(15, 8)
-
-#define VPU_40XX_BUTTRESS_FMAX_FUSE 0x00000178u
-#define VPU_40XX_BUTTRESS_FMAX_FUSE_MAX_RATIO_MASK GENMASK(7, 0)
-
#define VPU_40XX_HOST_SS_CPR_CLK_EN 0x00000080u
#define VPU_40XX_HOST_SS_CPR_CLK_EN_TOP_NOC_MASK BIT_MASK(1)
#define VPU_40XX_HOST_SS_CPR_CLK_EN_DSS_MAS_MASK BIT_MASK(10)
@@ -198,6 +113,12 @@
#define VPU_40XX_HOST_SS_AON_PWR_ISLAND_STATUS0 0x0003002cu
#define VPU_40XX_HOST_SS_AON_PWR_ISLAND_STATUS0_CSS_CPU_MASK BIT_MASK(3)
+#define VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY 0x00030068u
+#define VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY_POST_DLY_MASK GENMASK(7, 0)
+
+#define VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY 0x0003006cu
+#define VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY_STATUS_DLY_MASK GENMASK(7, 0)
+
#define VPU_40XX_HOST_SS_AON_IDLE_GEN 0x00030200u
#define VPU_40XX_HOST_SS_AON_IDLE_GEN_EN_MASK BIT_MASK(0)
#define VPU_40XX_HOST_SS_AON_IDLE_GEN_HW_PG_EN_MASK BIT_MASK(1)
@@ -205,6 +126,9 @@
#define VPU_40XX_HOST_SS_AON_DPU_ACTIVE 0x00030204u
#define VPU_40XX_HOST_SS_AON_DPU_ACTIVE_DPU_ACTIVE_MASK BIT_MASK(0)
+#define VPU_50XX_HOST_SS_AON_FABRIC_REQ_OVERRIDE 0x00030210u
+#define VPU_50XX_HOST_SS_AON_FABRIC_REQ_OVERRIDE_REQ_OVERRIDE_MASK BIT_MASK(0)
+
#define VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO 0x00040040u
#define VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO_DONE_MASK BIT_MASK(0)
#define VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO_IOSF_RS_ID_MASK GENMASK(2, 1)
diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.c b/drivers/accel/ivpu/ivpu_hw_btrs.c
new file mode 100644
index 000000000000..745e5248803d
--- /dev/null
+++ b/drivers/accel/ivpu/ivpu_hw_btrs.c
@@ -0,0 +1,905 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020-2024 Intel Corporation
+ */
+
+#include "ivpu_drv.h"
+#include "ivpu_hw.h"
+#include "ivpu_hw_btrs.h"
+#include "ivpu_hw_btrs_lnl_reg.h"
+#include "ivpu_hw_btrs_mtl_reg.h"
+#include "ivpu_hw_reg_io.h"
+#include "ivpu_pm.h"
+
+#define BTRS_MTL_IRQ_MASK ((REG_FLD(VPU_HW_BTRS_MTL_INTERRUPT_STAT, ATS_ERR)) | \
+ (REG_FLD(VPU_HW_BTRS_MTL_INTERRUPT_STAT, UFI_ERR)))
+
+#define BTRS_LNL_IRQ_MASK ((REG_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, ATS_ERR)) | \
+ (REG_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, CFI0_ERR)) | \
+ (REG_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, CFI1_ERR)) | \
+ (REG_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, IMR0_ERR)) | \
+ (REG_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, IMR1_ERR)) | \
+ (REG_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, SURV_ERR)))
+
+#define BTRS_MTL_ALL_IRQ_MASK (BTRS_MTL_IRQ_MASK | (REG_FLD(VPU_HW_BTRS_MTL_INTERRUPT_STAT, \
+ FREQ_CHANGE)))
+
+#define BTRS_IRQ_DISABLE_MASK ((u32)-1)
+
+#define BTRS_LNL_ALL_IRQ_MASK ((u32)-1)
+
+#define BTRS_MTL_WP_CONFIG_1_TILE_5_3_RATIO WP_CONFIG(MTL_CONFIG_1_TILE, MTL_PLL_RATIO_5_3)
+#define BTRS_MTL_WP_CONFIG_1_TILE_4_3_RATIO WP_CONFIG(MTL_CONFIG_1_TILE, MTL_PLL_RATIO_4_3)
+#define BTRS_MTL_WP_CONFIG_2_TILE_5_3_RATIO WP_CONFIG(MTL_CONFIG_2_TILE, MTL_PLL_RATIO_5_3)
+#define BTRS_MTL_WP_CONFIG_2_TILE_4_3_RATIO WP_CONFIG(MTL_CONFIG_2_TILE, MTL_PLL_RATIO_4_3)
+#define BTRS_MTL_WP_CONFIG_0_TILE_PLL_OFF WP_CONFIG(0, 0)
+
+#define PLL_CDYN_DEFAULT 0x80
+#define PLL_EPP_DEFAULT 0x80
+#define PLL_CONFIG_DEFAULT 0x0
+#define PLL_SIMULATION_FREQ 10000000
+#define PLL_REF_CLK_FREQ 50000000
+#define PLL_TIMEOUT_US (1500 * USEC_PER_MSEC)
+#define IDLE_TIMEOUT_US (5 * USEC_PER_MSEC)
+#define TIMEOUT_US (150 * USEC_PER_MSEC)
+
+/* Work point configuration values */
+#define WP_CONFIG(tile, ratio) (((tile) << 8) | (ratio))
+#define MTL_CONFIG_1_TILE 0x01
+#define MTL_CONFIG_2_TILE 0x02
+#define MTL_PLL_RATIO_5_3 0x01
+#define MTL_PLL_RATIO_4_3 0x02
+#define BTRS_MTL_TILE_FUSE_ENABLE_BOTH 0x0
+#define BTRS_MTL_TILE_SKU_BOTH 0x3630
+
+#define BTRS_LNL_TILE_MAX_NUM 6
+#define BTRS_LNL_TILE_MAX_MASK 0x3f
+
+#define WEIGHTS_DEFAULT 0xf711f711u
+#define WEIGHTS_ATS_DEFAULT 0x0000f711u
+
+#define DCT_REQ 0x2
+#define DCT_ENABLE 0x1
+#define DCT_DISABLE 0x0
+
+int ivpu_hw_btrs_irqs_clear_with_0_mtl(struct ivpu_device *vdev)
+{
+ REGB_WR32(VPU_HW_BTRS_MTL_INTERRUPT_STAT, BTRS_MTL_ALL_IRQ_MASK);
+ if (REGB_RD32(VPU_HW_BTRS_MTL_INTERRUPT_STAT) == BTRS_MTL_ALL_IRQ_MASK) {
+ /* Writing 1s does not clear the interrupt status register */
+ REGB_WR32(VPU_HW_BTRS_MTL_INTERRUPT_STAT, 0x0);
+ return true;
+ }
+
+ return false;
+}
+
+static void freq_ratios_init_mtl(struct ivpu_device *vdev)
+{
+ struct ivpu_hw_info *hw = vdev->hw;
+ u32 fmin_fuse, fmax_fuse;
+
+ fmin_fuse = REGB_RD32(VPU_HW_BTRS_MTL_FMIN_FUSE);
+ hw->pll.min_ratio = REG_GET_FLD(VPU_HW_BTRS_MTL_FMIN_FUSE, MIN_RATIO, fmin_fuse);
+ hw->pll.pn_ratio = REG_GET_FLD(VPU_HW_BTRS_MTL_FMIN_FUSE, PN_RATIO, fmin_fuse);
+
+ fmax_fuse = REGB_RD32(VPU_HW_BTRS_MTL_FMAX_FUSE);
+ hw->pll.max_ratio = REG_GET_FLD(VPU_HW_BTRS_MTL_FMAX_FUSE, MAX_RATIO, fmax_fuse);
+}
+
+static void freq_ratios_init_lnl(struct ivpu_device *vdev)
+{
+ struct ivpu_hw_info *hw = vdev->hw;
+ u32 fmin_fuse, fmax_fuse;
+
+ fmin_fuse = REGB_RD32(VPU_HW_BTRS_LNL_FMIN_FUSE);
+ hw->pll.min_ratio = REG_GET_FLD(VPU_HW_BTRS_LNL_FMIN_FUSE, MIN_RATIO, fmin_fuse);
+ hw->pll.pn_ratio = REG_GET_FLD(VPU_HW_BTRS_LNL_FMIN_FUSE, PN_RATIO, fmin_fuse);
+
+ fmax_fuse = REGB_RD32(VPU_HW_BTRS_LNL_FMAX_FUSE);
+ hw->pll.max_ratio = REG_GET_FLD(VPU_HW_BTRS_LNL_FMAX_FUSE, MAX_RATIO, fmax_fuse);
+}
+
+void ivpu_hw_btrs_freq_ratios_init(struct ivpu_device *vdev)
+{
+ struct ivpu_hw_info *hw = vdev->hw;
+
+ if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
+ freq_ratios_init_mtl(vdev);
+ else
+ freq_ratios_init_lnl(vdev);
+
+ hw->pll.min_ratio = clamp_t(u8, ivpu_pll_min_ratio, hw->pll.min_ratio, hw->pll.max_ratio);
+ hw->pll.max_ratio = clamp_t(u8, ivpu_pll_max_ratio, hw->pll.min_ratio, hw->pll.max_ratio);
+ hw->pll.pn_ratio = clamp_t(u8, hw->pll.pn_ratio, hw->pll.min_ratio, hw->pll.max_ratio);
+}
+
+static bool tile_disable_check(u32 config)
+{
+ /* Allowed values: 0 or one bit from range 0-5 (6 tiles) */
+ if (config == 0)
+ return true;
+
+ if (config > BIT(BTRS_LNL_TILE_MAX_NUM - 1))
+ return false;
+
+ if ((config & (config - 1)) == 0)
+ return true;
+
+ return false;
+}
+
+static int read_tile_config_fuse(struct ivpu_device *vdev, u32 *tile_fuse_config)
+{
+ u32 fuse;
+ u32 config;
+
+ fuse = REGB_RD32(VPU_HW_BTRS_LNL_TILE_FUSE);
+ if (!REG_TEST_FLD(VPU_HW_BTRS_LNL_TILE_FUSE, VALID, fuse)) {
+ ivpu_err(vdev, "Fuse: invalid (0x%x)\n", fuse);
+ return -EIO;
+ }
+
+ config = REG_GET_FLD(VPU_HW_BTRS_LNL_TILE_FUSE, CONFIG, fuse);
+ if (!tile_disable_check(config)) {
+ ivpu_err(vdev, "Fuse: Invalid tile disable config (0x%x)\n", config);
+ return -EIO;
+ }
+
+ if (config)
+ ivpu_dbg(vdev, MISC, "Fuse: %d tiles enabled. Tile number %d disabled\n",
+ BTRS_LNL_TILE_MAX_NUM - 1, ffs(config) - 1);
+ else
+ ivpu_dbg(vdev, MISC, "Fuse: All %d tiles enabled\n", BTRS_LNL_TILE_MAX_NUM);
+
+ *tile_fuse_config = config;
+ return 0;
+}
+
+static int info_init_mtl(struct ivpu_device *vdev)
+{
+ struct ivpu_hw_info *hw = vdev->hw;
+
+ hw->tile_fuse = BTRS_MTL_TILE_FUSE_ENABLE_BOTH;
+ hw->sku = BTRS_MTL_TILE_SKU_BOTH;
+ hw->config = BTRS_MTL_WP_CONFIG_2_TILE_4_3_RATIO;
+ hw->sched_mode = ivpu_sched_mode;
+
+ return 0;
+}
+
+static int info_init_lnl(struct ivpu_device *vdev)
+{
+ struct ivpu_hw_info *hw = vdev->hw;
+ u32 tile_fuse_config;
+ int ret;
+
+ ret = read_tile_config_fuse(vdev, &tile_fuse_config);
+ if (ret)
+ return ret;
+
+ hw->sched_mode = ivpu_sched_mode;
+ hw->tile_fuse = tile_fuse_config;
+ hw->pll.profiling_freq = PLL_PROFILING_FREQ_DEFAULT;
+
+ return 0;
+}
+
+int ivpu_hw_btrs_info_init(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
+ return info_init_mtl(vdev);
+ else
+ return info_init_lnl(vdev);
+}
+
+static int wp_request_sync(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
+ return REGB_POLL_FLD(VPU_HW_BTRS_MTL_WP_REQ_CMD, SEND, 0, PLL_TIMEOUT_US);
+ else
+ return REGB_POLL_FLD(VPU_HW_BTRS_LNL_WP_REQ_CMD, SEND, 0, PLL_TIMEOUT_US);
+}
+
+static int wait_for_status_ready(struct ivpu_device *vdev, bool enable)
+{
+ u32 exp_val = enable ? 0x1 : 0x0;
+
+ if (IVPU_WA(punit_disabled))
+ return 0;
+
+ if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
+ return REGB_POLL_FLD(VPU_HW_BTRS_MTL_VPU_STATUS, READY, exp_val, PLL_TIMEOUT_US);
+ else
+ return REGB_POLL_FLD(VPU_HW_BTRS_LNL_VPU_STATUS, READY, exp_val, PLL_TIMEOUT_US);
+}
+
+struct wp_request {
+ u16 min;
+ u16 max;
+ u16 target;
+ u16 cfg;
+ u16 epp;
+ u16 cdyn;
+};
+
+static void wp_request_mtl(struct ivpu_device *vdev, struct wp_request *wp)
+{
+ u32 val;
+
+ val = REGB_RD32(VPU_HW_BTRS_MTL_WP_REQ_PAYLOAD0);
+ val = REG_SET_FLD_NUM(VPU_HW_BTRS_MTL_WP_REQ_PAYLOAD0, MIN_RATIO, wp->min, val);
+ val = REG_SET_FLD_NUM(VPU_HW_BTRS_MTL_WP_REQ_PAYLOAD0, MAX_RATIO, wp->max, val);
+ REGB_WR32(VPU_HW_BTRS_MTL_WP_REQ_PAYLOAD0, val);
+
+ val = REGB_RD32(VPU_HW_BTRS_MTL_WP_REQ_PAYLOAD1);
+ val = REG_SET_FLD_NUM(VPU_HW_BTRS_MTL_WP_REQ_PAYLOAD1, TARGET_RATIO, wp->target, val);
+ val = REG_SET_FLD_NUM(VPU_HW_BTRS_MTL_WP_REQ_PAYLOAD1, EPP, PLL_EPP_DEFAULT, val);
+ REGB_WR32(VPU_HW_BTRS_MTL_WP_REQ_PAYLOAD1, val);
+
+ val = REGB_RD32(VPU_HW_BTRS_MTL_WP_REQ_PAYLOAD2);
+ val = REG_SET_FLD_NUM(VPU_HW_BTRS_MTL_WP_REQ_PAYLOAD2, CONFIG, wp->cfg, val);
+ REGB_WR32(VPU_HW_BTRS_MTL_WP_REQ_PAYLOAD2, val);
+
+ val = REGB_RD32(VPU_HW_BTRS_MTL_WP_REQ_CMD);
+ val = REG_SET_FLD(VPU_HW_BTRS_MTL_WP_REQ_CMD, SEND, val);
+ REGB_WR32(VPU_HW_BTRS_MTL_WP_REQ_CMD, val);
+}
+
+static void wp_request_lnl(struct ivpu_device *vdev, struct wp_request *wp)
+{
+ u32 val;
+
+ val = REGB_RD32(VPU_HW_BTRS_LNL_WP_REQ_PAYLOAD0);
+ val = REG_SET_FLD_NUM(VPU_HW_BTRS_LNL_WP_REQ_PAYLOAD0, MIN_RATIO, wp->min, val);
+ val = REG_SET_FLD_NUM(VPU_HW_BTRS_LNL_WP_REQ_PAYLOAD0, MAX_RATIO, wp->max, val);
+ REGB_WR32(VPU_HW_BTRS_LNL_WP_REQ_PAYLOAD0, val);
+
+ val = REGB_RD32(VPU_HW_BTRS_LNL_WP_REQ_PAYLOAD1);
+ val = REG_SET_FLD_NUM(VPU_HW_BTRS_LNL_WP_REQ_PAYLOAD1, TARGET_RATIO, wp->target, val);
+ val = REG_SET_FLD_NUM(VPU_HW_BTRS_LNL_WP_REQ_PAYLOAD1, EPP, wp->epp, val);
+ REGB_WR32(VPU_HW_BTRS_LNL_WP_REQ_PAYLOAD1, val);
+
+ val = REGB_RD32(VPU_HW_BTRS_LNL_WP_REQ_PAYLOAD2);
+ val = REG_SET_FLD_NUM(VPU_HW_BTRS_LNL_WP_REQ_PAYLOAD2, CONFIG, wp->cfg, val);
+ val = REG_SET_FLD_NUM(VPU_HW_BTRS_LNL_WP_REQ_PAYLOAD2, CDYN, wp->cdyn, val);
+ REGB_WR32(VPU_HW_BTRS_LNL_WP_REQ_PAYLOAD2, val);
+
+ val = REGB_RD32(VPU_HW_BTRS_LNL_WP_REQ_CMD);
+ val = REG_SET_FLD(VPU_HW_BTRS_LNL_WP_REQ_CMD, SEND, val);
+ REGB_WR32(VPU_HW_BTRS_LNL_WP_REQ_CMD, val);
+}
+
+static void wp_request(struct ivpu_device *vdev, struct wp_request *wp)
+{
+ if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
+ wp_request_mtl(vdev, wp);
+ else
+ wp_request_lnl(vdev, wp);
+}
+
+static int wp_request_send(struct ivpu_device *vdev, struct wp_request *wp)
+{
+ int ret;
+
+ ret = wp_request_sync(vdev);
+ if (ret) {
+ ivpu_err(vdev, "Failed to sync before workpoint request: %d\n", ret);
+ return ret;
+ }
+
+ wp_request(vdev, wp);
+
+ ret = wp_request_sync(vdev);
+ if (ret)
+ ivpu_err(vdev, "Failed to sync after workpoint request: %d\n", ret);
+
+ return ret;
+}
+
+static void prepare_wp_request(struct ivpu_device *vdev, struct wp_request *wp, bool enable)
+{
+ struct ivpu_hw_info *hw = vdev->hw;
+
+ wp->min = hw->pll.min_ratio;
+ wp->max = hw->pll.max_ratio;
+
+ if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL) {
+ wp->target = enable ? hw->pll.pn_ratio : 0;
+ wp->cfg = enable ? hw->config : 0;
+ wp->cdyn = 0;
+ wp->epp = 0;
+ } else {
+ wp->target = hw->pll.pn_ratio;
+ wp->cfg = enable ? PLL_CONFIG_DEFAULT : 0;
+ wp->cdyn = enable ? PLL_CDYN_DEFAULT : 0;
+ wp->epp = enable ? PLL_EPP_DEFAULT : 0;
+ }
+
+ /* Simics cannot start without at least one tile */
+ if (enable && ivpu_is_simics(vdev))
+ wp->cfg = 1;
+}
+
+static int wait_for_pll_lock(struct ivpu_device *vdev, bool enable)
+{
+ u32 exp_val = enable ? 0x1 : 0x0;
+
+ if (ivpu_hw_btrs_gen(vdev) != IVPU_HW_BTRS_MTL)
+ return 0;
+
+ if (IVPU_WA(punit_disabled))
+ return 0;
+
+ return REGB_POLL_FLD(VPU_HW_BTRS_MTL_PLL_STATUS, LOCK, exp_val, PLL_TIMEOUT_US);
+}
+
+int ivpu_hw_btrs_wp_drive(struct ivpu_device *vdev, bool enable)
+{
+ struct wp_request wp;
+ int ret;
+
+ if (IVPU_WA(punit_disabled)) {
+ ivpu_dbg(vdev, PM, "Skipping workpoint request\n");
+ return 0;
+ }
+
+ prepare_wp_request(vdev, &wp, enable);
+
+ ivpu_dbg(vdev, PM, "PLL workpoint request: %u Hz, config: 0x%x, epp: 0x%x, cdyn: 0x%x\n",
+ PLL_RATIO_TO_FREQ(wp.target), wp.cfg, wp.epp, wp.cdyn);
+
+ ret = wp_request_send(vdev, &wp);
+ if (ret) {
+ ivpu_err(vdev, "Failed to send workpoint request: %d\n", ret);
+ return ret;
+ }
+
+ ret = wait_for_pll_lock(vdev, enable);
+ if (ret) {
+ ivpu_err(vdev, "Timed out waiting for PLL lock\n");
+ return ret;
+ }
+
+ ret = wait_for_status_ready(vdev, enable);
+ if (ret) {
+ ivpu_err(vdev, "Timed out waiting for NPU ready status\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int d0i3_drive_mtl(struct ivpu_device *vdev, bool enable)
+{
+ int ret;
+ u32 val;
+
+ ret = REGB_POLL_FLD(VPU_HW_BTRS_MTL_VPU_D0I3_CONTROL, INPROGRESS, 0, TIMEOUT_US);
+ if (ret) {
+ ivpu_err(vdev, "Failed to sync before D0i3 transition: %d\n", ret);
+ return ret;
+ }
+
+ val = REGB_RD32(VPU_HW_BTRS_MTL_VPU_D0I3_CONTROL);
+ if (enable)
+ val = REG_SET_FLD(VPU_HW_BTRS_MTL_VPU_D0I3_CONTROL, I3, val);
+ else
+ val = REG_CLR_FLD(VPU_HW_BTRS_MTL_VPU_D0I3_CONTROL, I3, val);
+ REGB_WR32(VPU_HW_BTRS_MTL_VPU_D0I3_CONTROL, val);
+
+ ret = REGB_POLL_FLD(VPU_HW_BTRS_MTL_VPU_D0I3_CONTROL, INPROGRESS, 0, TIMEOUT_US);
+ if (ret)
+ ivpu_err(vdev, "Failed to sync after D0i3 transition: %d\n", ret);
+
+ return ret;
+}
+
+static int d0i3_drive_lnl(struct ivpu_device *vdev, bool enable)
+{
+ int ret;
+ u32 val;
+
+ ret = REGB_POLL_FLD(VPU_HW_BTRS_LNL_D0I3_CONTROL, INPROGRESS, 0, TIMEOUT_US);
+ if (ret) {
+ ivpu_err(vdev, "Failed to sync before D0i3 transition: %d\n", ret);
+ return ret;
+ }
+
+ val = REGB_RD32(VPU_HW_BTRS_LNL_D0I3_CONTROL);
+ if (enable)
+ val = REG_SET_FLD(VPU_HW_BTRS_LNL_D0I3_CONTROL, I3, val);
+ else
+ val = REG_CLR_FLD(VPU_HW_BTRS_LNL_D0I3_CONTROL, I3, val);
+ REGB_WR32(VPU_HW_BTRS_LNL_D0I3_CONTROL, val);
+
+ ret = REGB_POLL_FLD(VPU_HW_BTRS_LNL_D0I3_CONTROL, INPROGRESS, 0, TIMEOUT_US);
+ if (ret) {
+ ivpu_err(vdev, "Failed to sync after D0i3 transition: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int d0i3_drive(struct ivpu_device *vdev, bool enable)
+{
+ if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
+ return d0i3_drive_mtl(vdev, enable);
+ else
+ return d0i3_drive_lnl(vdev, enable);
+}
+
+int ivpu_hw_btrs_d0i3_enable(struct ivpu_device *vdev)
+{
+ int ret;
+
+ if (IVPU_WA(punit_disabled))
+ return 0;
+
+ ret = d0i3_drive(vdev, true);
+ if (ret)
+ ivpu_err(vdev, "Failed to enable D0i3: %d\n", ret);
+
+ udelay(5); /* VPU requires 5 us to complete the transition */
+
+ return ret;
+}
+
+int ivpu_hw_btrs_d0i3_disable(struct ivpu_device *vdev)
+{
+ int ret;
+
+ if (IVPU_WA(punit_disabled))
+ return 0;
+
+ ret = d0i3_drive(vdev, false);
+ if (ret)
+ ivpu_err(vdev, "Failed to disable D0i3: %d\n", ret);
+
+ return ret;
+}
+
+int ivpu_hw_btrs_wait_for_clock_res_own_ack(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
+ return 0;
+
+ if (ivpu_is_simics(vdev))
+ return 0;
+
+ return REGB_POLL_FLD(VPU_HW_BTRS_LNL_VPU_STATUS, CLOCK_RESOURCE_OWN_ACK, 1, TIMEOUT_US);
+}
+
+void ivpu_hw_btrs_set_port_arbitration_weights_lnl(struct ivpu_device *vdev)
+{
+ REGB_WR32(VPU_HW_BTRS_LNL_PORT_ARBITRATION_WEIGHTS, WEIGHTS_DEFAULT);
+ REGB_WR32(VPU_HW_BTRS_LNL_PORT_ARBITRATION_WEIGHTS_ATS, WEIGHTS_ATS_DEFAULT);
+}
+
+static int ip_reset_mtl(struct ivpu_device *vdev)
+{
+ int ret;
+ u32 val;
+
+ ret = REGB_POLL_FLD(VPU_HW_BTRS_MTL_VPU_IP_RESET, TRIGGER, 0, TIMEOUT_US);
+ if (ret) {
+ ivpu_err(vdev, "Timed out waiting for TRIGGER bit\n");
+ return ret;
+ }
+
+ val = REGB_RD32(VPU_HW_BTRS_MTL_VPU_IP_RESET);
+ val = REG_SET_FLD(VPU_HW_BTRS_MTL_VPU_IP_RESET, TRIGGER, val);
+ REGB_WR32(VPU_HW_BTRS_MTL_VPU_IP_RESET, val);
+
+ ret = REGB_POLL_FLD(VPU_HW_BTRS_MTL_VPU_IP_RESET, TRIGGER, 0, TIMEOUT_US);
+ if (ret)
+ ivpu_err(vdev, "Timed out waiting for RESET completion\n");
+
+ return ret;
+}
+
+static int ip_reset_lnl(struct ivpu_device *vdev)
+{
+ int ret;
+ u32 val;
+
+ ivpu_hw_btrs_clock_relinquish_disable_lnl(vdev);
+
+ ret = REGB_POLL_FLD(VPU_HW_BTRS_LNL_IP_RESET, TRIGGER, 0, TIMEOUT_US);
+ if (ret) {
+ ivpu_err(vdev, "Wait for *_TRIGGER timed out\n");
+ return ret;
+ }
+
+ val = REGB_RD32(VPU_HW_BTRS_LNL_IP_RESET);
+ val = REG_SET_FLD(VPU_HW_BTRS_LNL_IP_RESET, TRIGGER, val);
+ REGB_WR32(VPU_HW_BTRS_LNL_IP_RESET, val);
+
+ ret = REGB_POLL_FLD(VPU_HW_BTRS_LNL_IP_RESET, TRIGGER, 0, TIMEOUT_US);
+ if (ret)
+ ivpu_err(vdev, "Timed out waiting for RESET completion\n");
+
+ return ret;
+}
+
+int ivpu_hw_btrs_ip_reset(struct ivpu_device *vdev)
+{
+ if (IVPU_WA(punit_disabled))
+ return 0;
+
+ if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
+ return ip_reset_mtl(vdev);
+ else
+ return ip_reset_lnl(vdev);
+}
+
+void ivpu_hw_btrs_profiling_freq_reg_set_lnl(struct ivpu_device *vdev)
+{
+ u32 val = REGB_RD32(VPU_HW_BTRS_LNL_VPU_STATUS);
+
+ if (vdev->hw->pll.profiling_freq == PLL_PROFILING_FREQ_DEFAULT)
+ val = REG_CLR_FLD(VPU_HW_BTRS_LNL_VPU_STATUS, PERF_CLK, val);
+ else
+ val = REG_SET_FLD(VPU_HW_BTRS_LNL_VPU_STATUS, PERF_CLK, val);
+
+ REGB_WR32(VPU_HW_BTRS_LNL_VPU_STATUS, val);
+}
+
+void ivpu_hw_btrs_ats_print_lnl(struct ivpu_device *vdev)
+{
+ ivpu_dbg(vdev, MISC, "Buttress ATS: %s\n",
+ REGB_RD32(VPU_HW_BTRS_LNL_HM_ATS) ? "Enable" : "Disable");
+}
+
+void ivpu_hw_btrs_clock_relinquish_disable_lnl(struct ivpu_device *vdev)
+{
+ u32 val = REGB_RD32(VPU_HW_BTRS_LNL_VPU_STATUS);
+
+ val = REG_SET_FLD(VPU_HW_BTRS_LNL_VPU_STATUS, DISABLE_CLK_RELINQUISH, val);
+ REGB_WR32(VPU_HW_BTRS_LNL_VPU_STATUS, val);
+}
+
+bool ivpu_hw_btrs_is_idle(struct ivpu_device *vdev)
+{
+ u32 val;
+
+ if (IVPU_WA(punit_disabled))
+ return true;
+
+ if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL) {
+ val = REGB_RD32(VPU_HW_BTRS_MTL_VPU_STATUS);
+
+ return REG_TEST_FLD(VPU_HW_BTRS_MTL_VPU_STATUS, READY, val) &&
+ REG_TEST_FLD(VPU_HW_BTRS_MTL_VPU_STATUS, IDLE, val);
+ } else {
+ val = REGB_RD32(VPU_HW_BTRS_LNL_VPU_STATUS);
+
+ return REG_TEST_FLD(VPU_HW_BTRS_LNL_VPU_STATUS, READY, val) &&
+ REG_TEST_FLD(VPU_HW_BTRS_LNL_VPU_STATUS, IDLE, val);
+ }
+}
+
+int ivpu_hw_btrs_wait_for_idle(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
+ return REGB_POLL_FLD(VPU_HW_BTRS_MTL_VPU_STATUS, IDLE, 0x1, IDLE_TIMEOUT_US);
+ else
+ return REGB_POLL_FLD(VPU_HW_BTRS_LNL_VPU_STATUS, IDLE, 0x1, IDLE_TIMEOUT_US);
+}
+
+/* Handler for IRQs from Buttress core (irqB) */
+bool ivpu_hw_btrs_irq_handler_mtl(struct ivpu_device *vdev, int irq)
+{
+ u32 status = REGB_RD32(VPU_HW_BTRS_MTL_INTERRUPT_STAT) & BTRS_MTL_IRQ_MASK;
+ bool schedule_recovery = false;
+
+ if (!status)
+ return false;
+
+ if (REG_TEST_FLD(VPU_HW_BTRS_MTL_INTERRUPT_STAT, FREQ_CHANGE, status))
+ ivpu_dbg(vdev, IRQ, "FREQ_CHANGE irq: %08x",
+ REGB_RD32(VPU_HW_BTRS_MTL_CURRENT_PLL));
+
+ if (REG_TEST_FLD(VPU_HW_BTRS_MTL_INTERRUPT_STAT, ATS_ERR, status)) {
+ ivpu_err(vdev, "ATS_ERR irq 0x%016llx", REGB_RD64(VPU_HW_BTRS_MTL_ATS_ERR_LOG_0));
+ REGB_WR32(VPU_HW_BTRS_MTL_ATS_ERR_CLEAR, 0x1);
+ schedule_recovery = true;
+ }
+
+ if (REG_TEST_FLD(VPU_HW_BTRS_MTL_INTERRUPT_STAT, UFI_ERR, status)) {
+ u32 ufi_log = REGB_RD32(VPU_HW_BTRS_MTL_UFI_ERR_LOG);
+
+ ivpu_err(vdev, "UFI_ERR irq (0x%08x) opcode: 0x%02lx axi_id: 0x%02lx cq_id: 0x%03lx",
+ ufi_log, REG_GET_FLD(VPU_HW_BTRS_MTL_UFI_ERR_LOG, OPCODE, ufi_log),
+ REG_GET_FLD(VPU_HW_BTRS_MTL_UFI_ERR_LOG, AXI_ID, ufi_log),
+ REG_GET_FLD(VPU_HW_BTRS_MTL_UFI_ERR_LOG, CQ_ID, ufi_log));
+ REGB_WR32(VPU_HW_BTRS_MTL_UFI_ERR_CLEAR, 0x1);
+ schedule_recovery = true;
+ }
+
+ /* This must be done after interrupts are cleared at the source. */
+ if (IVPU_WA(interrupt_clear_with_0))
+ /*
+ * Writing 1 triggers an interrupt, so we can't perform read update write.
+ * Clear local interrupt status by writing 0 to all bits.
+ */
+ REGB_WR32(VPU_HW_BTRS_MTL_INTERRUPT_STAT, 0x0);
+ else
+ REGB_WR32(VPU_HW_BTRS_MTL_INTERRUPT_STAT, status);
+
+ if (schedule_recovery)
+ ivpu_pm_trigger_recovery(vdev, "Buttress IRQ");
+
+ return true;
+}
+
+/* Handler for IRQs from Buttress core (irqB) */
+bool ivpu_hw_btrs_irq_handler_lnl(struct ivpu_device *vdev, int irq)
+{
+ u32 status = REGB_RD32(VPU_HW_BTRS_LNL_INTERRUPT_STAT) & BTRS_LNL_IRQ_MASK;
+ bool schedule_recovery = false;
+
+ if (!status)
+ return false;
+
+ if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, SURV_ERR, status)) {
+ ivpu_dbg(vdev, IRQ, "Survivability IRQ\n");
+ if (!kfifo_put(&vdev->hw->irq.fifo, IVPU_HW_IRQ_SRC_DCT))
+ ivpu_err_ratelimited(vdev, "IRQ FIFO full\n");
+ }
+
+ if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, FREQ_CHANGE, status))
+ ivpu_dbg(vdev, IRQ, "FREQ_CHANGE irq: %08x", REGB_RD32(VPU_HW_BTRS_LNL_PLL_FREQ));
+
+ if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, ATS_ERR, status)) {
+ ivpu_err(vdev, "ATS_ERR LOG1 0x%08x ATS_ERR_LOG2 0x%08x\n",
+ REGB_RD32(VPU_HW_BTRS_LNL_ATS_ERR_LOG1),
+ REGB_RD32(VPU_HW_BTRS_LNL_ATS_ERR_LOG2));
+ REGB_WR32(VPU_HW_BTRS_LNL_ATS_ERR_CLEAR, 0x1);
+ schedule_recovery = true;
+ }
+
+ if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, CFI0_ERR, status)) {
+ ivpu_err(vdev, "CFI0_ERR 0x%08x", REGB_RD32(VPU_HW_BTRS_LNL_CFI0_ERR_LOG));
+ REGB_WR32(VPU_HW_BTRS_LNL_CFI0_ERR_CLEAR, 0x1);
+ schedule_recovery = true;
+ }
+
+ if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, CFI1_ERR, status)) {
+ ivpu_err(vdev, "CFI1_ERR 0x%08x", REGB_RD32(VPU_HW_BTRS_LNL_CFI1_ERR_LOG));
+ REGB_WR32(VPU_HW_BTRS_LNL_CFI1_ERR_CLEAR, 0x1);
+ schedule_recovery = true;
+ }
+
+ if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, IMR0_ERR, status)) {
+ ivpu_err(vdev, "IMR_ERR_CFI0 LOW: 0x%08x HIGH: 0x%08x",
+ REGB_RD32(VPU_HW_BTRS_LNL_IMR_ERR_CFI0_LOW),
+ REGB_RD32(VPU_HW_BTRS_LNL_IMR_ERR_CFI0_HIGH));
+ REGB_WR32(VPU_HW_BTRS_LNL_IMR_ERR_CFI0_CLEAR, 0x1);
+ schedule_recovery = true;
+ }
+
+ if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, IMR1_ERR, status)) {
+ ivpu_err(vdev, "IMR_ERR_CFI1 LOW: 0x%08x HIGH: 0x%08x",
+ REGB_RD32(VPU_HW_BTRS_LNL_IMR_ERR_CFI1_LOW),
+ REGB_RD32(VPU_HW_BTRS_LNL_IMR_ERR_CFI1_HIGH));
+ REGB_WR32(VPU_HW_BTRS_LNL_IMR_ERR_CFI1_CLEAR, 0x1);
+ schedule_recovery = true;
+ }
+
+ /* This must be done after interrupts are cleared at the source. */
+ REGB_WR32(VPU_HW_BTRS_LNL_INTERRUPT_STAT, status);
+
+ if (schedule_recovery)
+ ivpu_pm_trigger_recovery(vdev, "Buttress IRQ");
+
+ return true;
+}
+
+int ivpu_hw_btrs_dct_get_request(struct ivpu_device *vdev, bool *enable)
+{
+ u32 val = REGB_RD32(VPU_HW_BTRS_LNL_PCODE_MAILBOX_SHADOW);
+ u32 cmd = REG_GET_FLD(VPU_HW_BTRS_LNL_PCODE_MAILBOX_SHADOW, CMD, val);
+ u32 param1 = REG_GET_FLD(VPU_HW_BTRS_LNL_PCODE_MAILBOX_SHADOW, PARAM1, val);
+
+ if (cmd != DCT_REQ) {
+ ivpu_err_ratelimited(vdev, "Unsupported PCODE command: 0x%x\n", cmd);
+ return -EBADR;
+ }
+
+ switch (param1) {
+ case DCT_ENABLE:
+ *enable = true;
+ return 0;
+ case DCT_DISABLE:
+ *enable = false;
+ return 0;
+ default:
+ ivpu_err_ratelimited(vdev, "Invalid PARAM1 value: %u\n", param1);
+ return -EINVAL;
+ }
+}
+
+void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u32 active_percent)
+{
+ u32 val = 0;
+ u32 cmd = enable ? DCT_ENABLE : DCT_DISABLE;
+
+ val = REG_SET_FLD_NUM(VPU_HW_BTRS_LNL_PCODE_MAILBOX_STATUS, CMD, DCT_REQ, val);
+ val = REG_SET_FLD_NUM(VPU_HW_BTRS_LNL_PCODE_MAILBOX_STATUS, PARAM1, cmd, val);
+ val = REG_SET_FLD_NUM(VPU_HW_BTRS_LNL_PCODE_MAILBOX_STATUS, PARAM2, active_percent, val);
+
+ REGB_WR32(VPU_HW_BTRS_LNL_PCODE_MAILBOX_STATUS, val);
+}
+
+static u32 pll_ratio_to_freq_mtl(u32 ratio, u32 config)
+{
+ u32 pll_clock = PLL_REF_CLK_FREQ * ratio;
+ u32 cpu_clock;
+
+ if ((config & 0xff) == MTL_PLL_RATIO_4_3)
+ cpu_clock = pll_clock * 2 / 4;
+ else
+ cpu_clock = pll_clock * 2 / 5;
+
+ return cpu_clock;
+}
+
+u32 ivpu_hw_btrs_ratio_to_freq(struct ivpu_device *vdev, u32 ratio)
+{
+ struct ivpu_hw_info *hw = vdev->hw;
+
+ if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
+ return pll_ratio_to_freq_mtl(ratio, hw->config);
+ else
+ return PLL_RATIO_TO_FREQ(ratio);
+}
+
+static u32 pll_freq_get_mtl(struct ivpu_device *vdev)
+{
+ u32 pll_curr_ratio;
+
+ pll_curr_ratio = REGB_RD32(VPU_HW_BTRS_MTL_CURRENT_PLL);
+ pll_curr_ratio &= VPU_HW_BTRS_MTL_CURRENT_PLL_RATIO_MASK;
+
+ if (!ivpu_is_silicon(vdev))
+ return PLL_SIMULATION_FREQ;
+
+ return pll_ratio_to_freq_mtl(pll_curr_ratio, vdev->hw->config);
+}
+
+static u32 pll_freq_get_lnl(struct ivpu_device *vdev)
+{
+ u32 pll_curr_ratio;
+
+ pll_curr_ratio = REGB_RD32(VPU_HW_BTRS_LNL_PLL_FREQ);
+ pll_curr_ratio &= VPU_HW_BTRS_LNL_PLL_FREQ_RATIO_MASK;
+
+ return PLL_RATIO_TO_FREQ(pll_curr_ratio);
+}
+
+u32 ivpu_hw_btrs_pll_freq_get(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
+ return pll_freq_get_mtl(vdev);
+ else
+ return pll_freq_get_lnl(vdev);
+}
+
+u32 ivpu_hw_btrs_telemetry_offset_get(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
+ return REGB_RD32(VPU_HW_BTRS_MTL_VPU_TELEMETRY_OFFSET);
+ else
+ return REGB_RD32(VPU_HW_BTRS_LNL_VPU_TELEMETRY_OFFSET);
+}
+
+u32 ivpu_hw_btrs_telemetry_size_get(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
+ return REGB_RD32(VPU_HW_BTRS_MTL_VPU_TELEMETRY_SIZE);
+ else
+ return REGB_RD32(VPU_HW_BTRS_LNL_VPU_TELEMETRY_SIZE);
+}
+
+u32 ivpu_hw_btrs_telemetry_enable_get(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
+ return REGB_RD32(VPU_HW_BTRS_MTL_VPU_TELEMETRY_ENABLE);
+ else
+ return REGB_RD32(VPU_HW_BTRS_LNL_VPU_TELEMETRY_ENABLE);
+}
+
+void ivpu_hw_btrs_global_int_disable(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
+ REGB_WR32(VPU_HW_BTRS_MTL_GLOBAL_INT_MASK, 0x1);
+ else
+ REGB_WR32(VPU_HW_BTRS_LNL_GLOBAL_INT_MASK, 0x1);
+}
+
+void ivpu_hw_btrs_global_int_enable(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
+ REGB_WR32(VPU_HW_BTRS_MTL_GLOBAL_INT_MASK, 0x0);
+ else
+ REGB_WR32(VPU_HW_BTRS_LNL_GLOBAL_INT_MASK, 0x0);
+}
+
+void ivpu_hw_btrs_irq_enable(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL) {
+ REGB_WR32(VPU_HW_BTRS_MTL_LOCAL_INT_MASK, (u32)(~BTRS_MTL_IRQ_MASK));
+ REGB_WR32(VPU_HW_BTRS_MTL_GLOBAL_INT_MASK, 0x0);
+ } else {
+ REGB_WR32(VPU_HW_BTRS_LNL_LOCAL_INT_MASK, (u32)(~BTRS_LNL_IRQ_MASK));
+ REGB_WR32(VPU_HW_BTRS_LNL_GLOBAL_INT_MASK, 0x0);
+ }
+}
+
+void ivpu_hw_btrs_irq_disable(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL) {
+ REGB_WR32(VPU_HW_BTRS_MTL_GLOBAL_INT_MASK, 0x1);
+ REGB_WR32(VPU_HW_BTRS_MTL_LOCAL_INT_MASK, BTRS_IRQ_DISABLE_MASK);
+ } else {
+ REGB_WR32(VPU_HW_BTRS_LNL_GLOBAL_INT_MASK, 0x1);
+ REGB_WR32(VPU_HW_BTRS_LNL_LOCAL_INT_MASK, BTRS_IRQ_DISABLE_MASK);
+ }
+}
+
+static void diagnose_failure_mtl(struct ivpu_device *vdev)
+{
+ u32 reg = REGB_RD32(VPU_HW_BTRS_MTL_INTERRUPT_STAT) & BTRS_MTL_IRQ_MASK;
+
+ if (REG_TEST_FLD(VPU_HW_BTRS_MTL_INTERRUPT_STAT, ATS_ERR, reg))
+ ivpu_err(vdev, "ATS_ERR irq 0x%016llx", REGB_RD64(VPU_HW_BTRS_MTL_ATS_ERR_LOG_0));
+
+ if (REG_TEST_FLD(VPU_HW_BTRS_MTL_INTERRUPT_STAT, UFI_ERR, reg)) {
+ u32 log = REGB_RD32(VPU_HW_BTRS_MTL_UFI_ERR_LOG);
+
+ ivpu_err(vdev, "UFI_ERR irq (0x%08x) opcode: 0x%02lx axi_id: 0x%02lx cq_id: 0x%03lx",
+ log, REG_GET_FLD(VPU_HW_BTRS_MTL_UFI_ERR_LOG, OPCODE, log),
+ REG_GET_FLD(VPU_HW_BTRS_MTL_UFI_ERR_LOG, AXI_ID, log),
+ REG_GET_FLD(VPU_HW_BTRS_MTL_UFI_ERR_LOG, CQ_ID, log));
+ }
+}
+
+static void diagnose_failure_lnl(struct ivpu_device *vdev)
+{
+ u32 reg = REGB_RD32(VPU_HW_BTRS_MTL_INTERRUPT_STAT) & BTRS_LNL_IRQ_MASK;
+
+ if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, ATS_ERR, reg)) {
+ ivpu_err(vdev, "ATS_ERR_LOG1 0x%08x ATS_ERR_LOG2 0x%08x\n",
+ REGB_RD32(VPU_HW_BTRS_LNL_ATS_ERR_LOG1),
+ REGB_RD32(VPU_HW_BTRS_LNL_ATS_ERR_LOG2));
+ }
+
+ if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, CFI0_ERR, reg))
+ ivpu_err(vdev, "CFI0_ERR_LOG 0x%08x\n", REGB_RD32(VPU_HW_BTRS_LNL_CFI0_ERR_LOG));
+
+ if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, CFI1_ERR, reg))
+ ivpu_err(vdev, "CFI1_ERR_LOG 0x%08x\n", REGB_RD32(VPU_HW_BTRS_LNL_CFI1_ERR_LOG));
+
+ if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, IMR0_ERR, reg))
+ ivpu_err(vdev, "IMR_ERR_CFI0 LOW: 0x%08x HIGH: 0x%08x\n",
+ REGB_RD32(VPU_HW_BTRS_LNL_IMR_ERR_CFI0_LOW),
+ REGB_RD32(VPU_HW_BTRS_LNL_IMR_ERR_CFI0_HIGH));
+
+ if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, IMR1_ERR, reg))
+ ivpu_err(vdev, "IMR_ERR_CFI1 LOW: 0x%08x HIGH: 0x%08x\n",
+ REGB_RD32(VPU_HW_BTRS_LNL_IMR_ERR_CFI1_LOW),
+ REGB_RD32(VPU_HW_BTRS_LNL_IMR_ERR_CFI1_HIGH));
+
+ if (REG_TEST_FLD(VPU_HW_BTRS_LNL_INTERRUPT_STAT, SURV_ERR, reg))
+ ivpu_err(vdev, "Survivability IRQ\n");
+}
+
+void ivpu_hw_btrs_diagnose_failure(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
+ return diagnose_failure_mtl(vdev);
+ else
+ return diagnose_failure_lnl(vdev);
+}
diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.h b/drivers/accel/ivpu/ivpu_hw_btrs.h
new file mode 100644
index 000000000000..04f14f50fed6
--- /dev/null
+++ b/drivers/accel/ivpu/ivpu_hw_btrs.h
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2020-2024 Intel Corporation
+ */
+
+#ifndef __IVPU_HW_BTRS_H__
+#define __IVPU_HW_BTRS_H__
+
+#include "ivpu_drv.h"
+#include "ivpu_hw_37xx_reg.h"
+#include "ivpu_hw_40xx_reg.h"
+#include "ivpu_hw_reg_io.h"
+
+#define PLL_PROFILING_FREQ_DEFAULT 38400000
+#define PLL_PROFILING_FREQ_HIGH 400000000
+#define PLL_RATIO_TO_FREQ(x) ((x) * PLL_REF_CLK_FREQ)
+
+#define DCT_DEFAULT_ACTIVE_PERCENT 15u
+#define DCT_PERIOD_US 35300u
+
+int ivpu_hw_btrs_info_init(struct ivpu_device *vdev);
+void ivpu_hw_btrs_freq_ratios_init(struct ivpu_device *vdev);
+int ivpu_hw_btrs_irqs_clear_with_0_mtl(struct ivpu_device *vdev);
+int ivpu_hw_btrs_wp_drive(struct ivpu_device *vdev, bool enable);
+int ivpu_hw_btrs_wait_for_clock_res_own_ack(struct ivpu_device *vdev);
+int ivpu_hw_btrs_d0i3_enable(struct ivpu_device *vdev);
+int ivpu_hw_btrs_d0i3_disable(struct ivpu_device *vdev);
+void ivpu_hw_btrs_set_port_arbitration_weights_lnl(struct ivpu_device *vdev);
+bool ivpu_hw_btrs_is_idle(struct ivpu_device *vdev);
+int ivpu_hw_btrs_wait_for_idle(struct ivpu_device *vdev);
+int ivpu_hw_btrs_ip_reset(struct ivpu_device *vdev);
+void ivpu_hw_btrs_profiling_freq_reg_set_lnl(struct ivpu_device *vdev);
+void ivpu_hw_btrs_ats_print_lnl(struct ivpu_device *vdev);
+void ivpu_hw_btrs_clock_relinquish_disable_lnl(struct ivpu_device *vdev);
+bool ivpu_hw_btrs_irq_handler_mtl(struct ivpu_device *vdev, int irq);
+bool ivpu_hw_btrs_irq_handler_lnl(struct ivpu_device *vdev, int irq);
+int ivpu_hw_btrs_dct_get_request(struct ivpu_device *vdev, bool *enable);
+void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u32 dct_percent);
+u32 ivpu_hw_btrs_pll_freq_get(struct ivpu_device *vdev);
+u32 ivpu_hw_btrs_ratio_to_freq(struct ivpu_device *vdev, u32 ratio);
+u32 ivpu_hw_btrs_telemetry_offset_get(struct ivpu_device *vdev);
+u32 ivpu_hw_btrs_telemetry_size_get(struct ivpu_device *vdev);
+u32 ivpu_hw_btrs_telemetry_enable_get(struct ivpu_device *vdev);
+void ivpu_hw_btrs_global_int_enable(struct ivpu_device *vdev);
+void ivpu_hw_btrs_global_int_disable(struct ivpu_device *vdev);
+void ivpu_hw_btrs_irq_enable(struct ivpu_device *vdev);
+void ivpu_hw_btrs_irq_disable(struct ivpu_device *vdev);
+void ivpu_hw_btrs_diagnose_failure(struct ivpu_device *vdev);
+
+#endif /* __IVPU_HW_BTRS_H__ */
diff --git a/drivers/accel/ivpu/ivpu_hw_btrs_lnl_reg.h b/drivers/accel/ivpu/ivpu_hw_btrs_lnl_reg.h
new file mode 100644
index 000000000000..fc51f3098f97
--- /dev/null
+++ b/drivers/accel/ivpu/ivpu_hw_btrs_lnl_reg.h
@@ -0,0 +1,108 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2020-2024 Intel Corporation
+ */
+
+#ifndef __IVPU_HW_BTRS_LNL_REG_H__
+#define __IVPU_HW_BTRS_LNL_REG_H__
+
+#include <linux/bits.h>
+
+#define VPU_HW_BTRS_LNL_INTERRUPT_STAT 0x00000000u
+#define VPU_HW_BTRS_LNL_INTERRUPT_STAT_FREQ_CHANGE_MASK BIT_MASK(0)
+#define VPU_HW_BTRS_LNL_INTERRUPT_STAT_ATS_ERR_MASK BIT_MASK(1)
+#define VPU_HW_BTRS_LNL_INTERRUPT_STAT_CFI0_ERR_MASK BIT_MASK(2)
+#define VPU_HW_BTRS_LNL_INTERRUPT_STAT_CFI1_ERR_MASK BIT_MASK(3)
+#define VPU_HW_BTRS_LNL_INTERRUPT_STAT_IMR0_ERR_MASK BIT_MASK(4)
+#define VPU_HW_BTRS_LNL_INTERRUPT_STAT_IMR1_ERR_MASK BIT_MASK(5)
+#define VPU_HW_BTRS_LNL_INTERRUPT_STAT_SURV_ERR_MASK BIT_MASK(6)
+
+#define VPU_HW_BTRS_LNL_LOCAL_INT_MASK 0x00000004u
+#define VPU_HW_BTRS_LNL_GLOBAL_INT_MASK 0x00000008u
+
+#define VPU_HW_BTRS_LNL_HM_ATS 0x0000000cu
+
+#define VPU_HW_BTRS_LNL_ATS_ERR_LOG1 0x00000010u
+#define VPU_HW_BTRS_LNL_ATS_ERR_LOG2 0x00000014u
+#define VPU_HW_BTRS_LNL_ATS_ERR_CLEAR 0x00000018u
+
+#define VPU_HW_BTRS_LNL_CFI0_ERR_LOG 0x0000001cu
+#define VPU_HW_BTRS_LNL_CFI0_ERR_CLEAR 0x00000020u
+
+#define VPU_HW_BTRS_LNL_PORT_ARBITRATION_WEIGHTS_ATS 0x00000024u
+
+#define VPU_HW_BTRS_LNL_CFI1_ERR_LOG 0x00000040u
+#define VPU_HW_BTRS_LNL_CFI1_ERR_CLEAR 0x00000044u
+
+#define VPU_HW_BTRS_LNL_IMR_ERR_CFI0_LOW 0x00000048u
+#define VPU_HW_BTRS_LNL_IMR_ERR_CFI0_HIGH 0x0000004cu
+#define VPU_HW_BTRS_LNL_IMR_ERR_CFI0_CLEAR 0x00000050u
+
+#define VPU_HW_BTRS_LNL_PORT_ARBITRATION_WEIGHTS 0x00000054u
+
+#define VPU_HW_BTRS_LNL_IMR_ERR_CFI1_LOW 0x00000058u
+#define VPU_HW_BTRS_LNL_IMR_ERR_CFI1_HIGH 0x0000005cu
+#define VPU_HW_BTRS_LNL_IMR_ERR_CFI1_CLEAR 0x00000060u
+
+#define VPU_HW_BTRS_LNL_PCODE_MAILBOX_STATUS 0x00000070u
+#define VPU_HW_BTRS_LNL_PCODE_MAILBOX_STATUS_CMD_MASK GENMASK(7, 0)
+#define VPU_HW_BTRS_LNL_PCODE_MAILBOX_STATUS_PARAM1_MASK GENMASK(15, 8)
+#define VPU_HW_BTRS_LNL_PCODE_MAILBOX_STATUS_PARAM2_MASK GENMASK(23, 16)
+#define VPU_HW_BTRS_LNL_PCODE_MAILBOX_STATUS_PARAM3_MASK GENMASK(31, 24)
+
+#define VPU_HW_BTRS_LNL_PCODE_MAILBOX_SHADOW 0x00000074u
+#define VPU_HW_BTRS_LNL_PCODE_MAILBOX_SHADOW_CMD_MASK GENMASK(7, 0)
+#define VPU_HW_BTRS_LNL_PCODE_MAILBOX_SHADOW_PARAM1_MASK GENMASK(15, 8)
+#define VPU_HW_BTRS_LNL_PCODE_MAILBOX_SHADOW_PARAM2_MASK GENMASK(23, 16)
+#define VPU_HW_BTRS_LNL_PCODE_MAILBOX_SHADOW_PARAM3_MASK GENMASK(31, 24)
+
+#define VPU_HW_BTRS_LNL_WP_REQ_PAYLOAD0 0x00000130u
+#define VPU_HW_BTRS_LNL_WP_REQ_PAYLOAD0_MIN_RATIO_MASK GENMASK(15, 0)
+#define VPU_HW_BTRS_LNL_WP_REQ_PAYLOAD0_MAX_RATIO_MASK GENMASK(31, 16)
+
+#define VPU_HW_BTRS_LNL_WP_REQ_PAYLOAD1 0x00000134u
+#define VPU_HW_BTRS_LNL_WP_REQ_PAYLOAD1_TARGET_RATIO_MASK GENMASK(15, 0)
+#define VPU_HW_BTRS_LNL_WP_REQ_PAYLOAD1_EPP_MASK GENMASK(31, 16)
+
+#define VPU_HW_BTRS_LNL_WP_REQ_PAYLOAD2 0x00000138u
+#define VPU_HW_BTRS_LNL_WP_REQ_PAYLOAD2_CONFIG_MASK GENMASK(15, 0)
+#define VPU_HW_BTRS_LNL_WP_REQ_PAYLOAD2_CDYN_MASK GENMASK(31, 16)
+
+#define VPU_HW_BTRS_LNL_WP_REQ_CMD 0x0000013cu
+#define VPU_HW_BTRS_LNL_WP_REQ_CMD_SEND_MASK BIT_MASK(0)
+
+#define VPU_HW_BTRS_LNL_PLL_FREQ 0x00000148u
+#define VPU_HW_BTRS_LNL_PLL_FREQ_RATIO_MASK GENMASK(15, 0)
+
+#define VPU_HW_BTRS_LNL_TILE_FUSE 0x00000150u
+#define VPU_HW_BTRS_LNL_TILE_FUSE_VALID_MASK BIT_MASK(0)
+#define VPU_HW_BTRS_LNL_TILE_FUSE_CONFIG_MASK GENMASK(6, 1)
+
+#define VPU_HW_BTRS_LNL_VPU_STATUS 0x00000154u
+#define VPU_HW_BTRS_LNL_VPU_STATUS_READY_MASK BIT_MASK(0)
+#define VPU_HW_BTRS_LNL_VPU_STATUS_IDLE_MASK BIT_MASK(1)
+#define VPU_HW_BTRS_LNL_VPU_STATUS_DUP_IDLE_MASK BIT_MASK(2)
+#define VPU_HW_BTRS_LNL_VPU_STATUS_CLOCK_RESOURCE_OWN_ACK_MASK BIT_MASK(6)
+#define VPU_HW_BTRS_LNL_VPU_STATUS_POWER_RESOURCE_OWN_ACK_MASK BIT_MASK(7)
+#define VPU_HW_BTRS_LNL_VPU_STATUS_PERF_CLK_MASK BIT_MASK(11)
+#define VPU_HW_BTRS_LNL_VPU_STATUS_DISABLE_CLK_RELINQUISH_MASK BIT_MASK(12)
+
+#define VPU_HW_BTRS_LNL_IP_RESET 0x00000160u
+#define VPU_HW_BTRS_LNL_IP_RESET_TRIGGER_MASK BIT_MASK(0)
+
+#define VPU_HW_BTRS_LNL_D0I3_CONTROL 0x00000164u
+#define VPU_HW_BTRS_LNL_D0I3_CONTROL_INPROGRESS_MASK BIT_MASK(0)
+#define VPU_HW_BTRS_LNL_D0I3_CONTROL_I3_MASK BIT_MASK(2)
+
+#define VPU_HW_BTRS_LNL_VPU_TELEMETRY_OFFSET 0x00000168u
+#define VPU_HW_BTRS_LNL_VPU_TELEMETRY_SIZE 0x0000016cu
+#define VPU_HW_BTRS_LNL_VPU_TELEMETRY_ENABLE 0x00000170u
+
+#define VPU_HW_BTRS_LNL_FMIN_FUSE 0x00000174u
+#define VPU_HW_BTRS_LNL_FMIN_FUSE_MIN_RATIO_MASK GENMASK(7, 0)
+#define VPU_HW_BTRS_LNL_FMIN_FUSE_PN_RATIO_MASK GENMASK(15, 8)
+
+#define VPU_HW_BTRS_LNL_FMAX_FUSE 0x00000178u
+#define VPU_HW_BTRS_LNL_FMAX_FUSE_MAX_RATIO_MASK GENMASK(7, 0)
+
+#endif /* __IVPU_HW_BTRS_LNL_REG_H__ */
diff --git a/drivers/accel/ivpu/ivpu_hw_btrs_mtl_reg.h b/drivers/accel/ivpu/ivpu_hw_btrs_mtl_reg.h
new file mode 100644
index 000000000000..e93d539e066f
--- /dev/null
+++ b/drivers/accel/ivpu/ivpu_hw_btrs_mtl_reg.h
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2020-2023 Intel Corporation
+ */
+
+#ifndef __IVPU_HW_BTRS_MTL_REG_H__
+#define __IVPU_HW_BTRS_MTL_REG_H__
+
+#include <linux/bits.h>
+
+#define VPU_HW_BTRS_MTL_INTERRUPT_TYPE 0x00000000u
+
+#define VPU_HW_BTRS_MTL_INTERRUPT_STAT 0x00000004u
+#define VPU_HW_BTRS_MTL_INTERRUPT_STAT_FREQ_CHANGE_MASK BIT_MASK(0)
+#define VPU_HW_BTRS_MTL_INTERRUPT_STAT_ATS_ERR_MASK BIT_MASK(1)
+#define VPU_HW_BTRS_MTL_INTERRUPT_STAT_UFI_ERR_MASK BIT_MASK(2)
+
+#define VPU_HW_BTRS_MTL_WP_REQ_PAYLOAD0 0x00000008u
+#define VPU_HW_BTRS_MTL_WP_REQ_PAYLOAD0_MIN_RATIO_MASK GENMASK(15, 0)
+#define VPU_HW_BTRS_MTL_WP_REQ_PAYLOAD0_MAX_RATIO_MASK GENMASK(31, 16)
+
+#define VPU_HW_BTRS_MTL_WP_REQ_PAYLOAD1 0x0000000cu
+#define VPU_HW_BTRS_MTL_WP_REQ_PAYLOAD1_TARGET_RATIO_MASK GENMASK(15, 0)
+#define VPU_HW_BTRS_MTL_WP_REQ_PAYLOAD1_EPP_MASK GENMASK(31, 16)
+
+#define VPU_HW_BTRS_MTL_WP_REQ_PAYLOAD2 0x00000010u
+#define VPU_HW_BTRS_MTL_WP_REQ_PAYLOAD2_CONFIG_MASK GENMASK(15, 0)
+
+#define VPU_HW_BTRS_MTL_WP_REQ_CMD 0x00000014u
+#define VPU_HW_BTRS_MTL_WP_REQ_CMD_SEND_MASK BIT_MASK(0)
+
+#define VPU_HW_BTRS_MTL_WP_DOWNLOAD 0x00000018u
+#define VPU_HW_BTRS_MTL_WP_DOWNLOAD_TARGET_RATIO_MASK GENMASK(15, 0)
+
+#define VPU_HW_BTRS_MTL_CURRENT_PLL 0x0000001cu
+#define VPU_HW_BTRS_MTL_CURRENT_PLL_RATIO_MASK GENMASK(15, 0)
+
+#define VPU_HW_BTRS_MTL_PLL_ENABLE 0x00000020u
+
+#define VPU_HW_BTRS_MTL_FMIN_FUSE 0x00000024u
+#define VPU_HW_BTRS_MTL_FMIN_FUSE_MIN_RATIO_MASK GENMASK(7, 0)
+#define VPU_HW_BTRS_MTL_FMIN_FUSE_PN_RATIO_MASK GENMASK(15, 8)
+
+#define VPU_HW_BTRS_MTL_FMAX_FUSE 0x00000028u
+#define VPU_HW_BTRS_MTL_FMAX_FUSE_MAX_RATIO_MASK GENMASK(7, 0)
+
+#define VPU_HW_BTRS_MTL_TILE_FUSE 0x0000002cu
+#define VPU_HW_BTRS_MTL_TILE_FUSE_VALID_MASK BIT_MASK(0)
+#define VPU_HW_BTRS_MTL_TILE_FUSE_SKU_MASK GENMASK(3, 2)
+
+#define VPU_HW_BTRS_MTL_LOCAL_INT_MASK 0x00000030u
+#define VPU_HW_BTRS_MTL_GLOBAL_INT_MASK 0x00000034u
+
+#define VPU_HW_BTRS_MTL_PLL_STATUS 0x00000040u
+#define VPU_HW_BTRS_MTL_PLL_STATUS_LOCK_MASK BIT_MASK(1)
+
+#define VPU_HW_BTRS_MTL_VPU_STATUS 0x00000044u
+#define VPU_HW_BTRS_MTL_VPU_STATUS_READY_MASK BIT_MASK(0)
+#define VPU_HW_BTRS_MTL_VPU_STATUS_IDLE_MASK BIT_MASK(1)
+
+#define VPU_HW_BTRS_MTL_VPU_D0I3_CONTROL 0x00000060u
+#define VPU_HW_BTRS_MTL_VPU_D0I3_CONTROL_INPROGRESS_MASK BIT_MASK(0)
+#define VPU_HW_BTRS_MTL_VPU_D0I3_CONTROL_I3_MASK BIT_MASK(2)
+
+#define VPU_HW_BTRS_MTL_VPU_IP_RESET 0x00000050u
+#define VPU_HW_BTRS_MTL_VPU_IP_RESET_TRIGGER_MASK BIT_MASK(0)
+
+#define VPU_HW_BTRS_MTL_VPU_TELEMETRY_OFFSET 0x00000080u
+#define VPU_HW_BTRS_MTL_VPU_TELEMETRY_SIZE 0x00000084u
+#define VPU_HW_BTRS_MTL_VPU_TELEMETRY_ENABLE 0x00000088u
+
+#define VPU_HW_BTRS_MTL_ATS_ERR_LOG_0 0x000000a0u
+#define VPU_HW_BTRS_MTL_ATS_ERR_LOG_1 0x000000a4u
+#define VPU_HW_BTRS_MTL_ATS_ERR_CLEAR 0x000000a8u
+
+#define VPU_HW_BTRS_MTL_UFI_ERR_LOG 0x000000b0u
+#define VPU_HW_BTRS_MTL_UFI_ERR_LOG_CQ_ID_MASK GENMASK(11, 0)
+#define VPU_HW_BTRS_MTL_UFI_ERR_LOG_AXI_ID_MASK GENMASK(19, 12)
+#define VPU_HW_BTRS_MTL_UFI_ERR_LOG_OPCODE_MASK GENMASK(24, 20)
+
+#define VPU_HW_BTRS_MTL_UFI_ERR_CLEAR 0x000000b4u
+
+#endif /* __IVPU_HW_BTRS_MTL_REG_H__ */
diff --git a/drivers/accel/ivpu/ivpu_hw_ip.c b/drivers/accel/ivpu/ivpu_hw_ip.c
new file mode 100644
index 000000000000..dfd2f4a5b526
--- /dev/null
+++ b/drivers/accel/ivpu/ivpu_hw_ip.c
@@ -0,0 +1,1174 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020-2024 Intel Corporation
+ */
+
+#include "ivpu_drv.h"
+#include "ivpu_fw.h"
+#include "ivpu_hw.h"
+#include "ivpu_hw_37xx_reg.h"
+#include "ivpu_hw_40xx_reg.h"
+#include "ivpu_hw_ip.h"
+#include "ivpu_hw_reg_io.h"
+#include "ivpu_mmu.h"
+#include "ivpu_pm.h"
+
+#define PWR_ISLAND_EN_POST_DLY_FREQ_DEFAULT 0
+#define PWR_ISLAND_EN_POST_DLY_FREQ_HIGH 18
+#define PWR_ISLAND_STATUS_DLY_FREQ_DEFAULT 3
+#define PWR_ISLAND_STATUS_DLY_FREQ_HIGH 46
+#define PWR_ISLAND_STATUS_TIMEOUT_US (5 * USEC_PER_MSEC)
+
+#define TIM_SAFE_ENABLE 0xf1d0dead
+#define TIM_WATCHDOG_RESET_VALUE 0xffffffff
+
+#define ICB_0_IRQ_MASK_37XX ((REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, HOST_IPC_FIFO_INT)) | \
+ (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_0_INT)) | \
+ (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_1_INT)) | \
+ (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_2_INT)) | \
+ (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT)) | \
+ (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT)) | \
+ (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT)))
+
+#define ICB_1_IRQ_MASK_37XX ((REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_2_INT)) | \
+ (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_3_INT)) | \
+ (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_4_INT)))
+
+#define ICB_0_1_IRQ_MASK_37XX ((((u64)ICB_1_IRQ_MASK_37XX) << 32) | ICB_0_IRQ_MASK_37XX)
+
+#define ICB_0_IRQ_MASK_40XX ((REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, HOST_IPC_FIFO_INT)) | \
+ (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_0_INT)) | \
+ (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_1_INT)) | \
+ (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_2_INT)) | \
+ (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT)) | \
+ (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT)) | \
+ (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT)))
+
+#define ICB_1_IRQ_MASK_40XX ((REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_2_INT)) | \
+ (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_3_INT)) | \
+ (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_4_INT)))
+
+#define ICB_0_1_IRQ_MASK_40XX ((((u64)ICB_1_IRQ_MASK_40XX) << 32) | ICB_0_IRQ_MASK_40XX)
+
+#define ITF_FIREWALL_VIOLATION_MASK_37XX ((REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, CSS_ROM_CMX)) | \
+ (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, CSS_DBG)) | \
+ (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, CSS_CTRL)) | \
+ (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, DEC400)) | \
+ (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, MSS_NCE)) | \
+ (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, MSS_MBI)) | \
+ (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, MSS_MBI_CMX)))
+
+#define ITF_FIREWALL_VIOLATION_MASK_40XX ((REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, CSS_ROM_CMX)) | \
+ (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, CSS_DBG)) | \
+ (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, CSS_CTRL)) | \
+ (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, DEC400)) | \
+ (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, MSS_NCE)) | \
+ (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, MSS_MBI)) | \
+ (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, MSS_MBI_CMX)))
+
+static int wait_for_ip_bar(struct ivpu_device *vdev)
+{
+ return REGV_POLL_FLD(VPU_37XX_HOST_SS_CPR_RST_CLR, AON, 0, 100);
+}
+
+static void host_ss_rst_clr(struct ivpu_device *vdev)
+{
+ u32 val = 0;
+
+ val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_CLR, TOP_NOC, val);
+ val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_CLR, DSS_MAS, val);
+ val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_CLR, MSS_MAS, val);
+
+ REGV_WR32(VPU_37XX_HOST_SS_CPR_RST_CLR, val);
+}
+
+static int host_ss_noc_qreqn_check_37xx(struct ivpu_device *vdev, u32 exp_val)
+{
+ u32 val = REGV_RD32(VPU_37XX_HOST_SS_NOC_QREQN);
+
+ if (!REG_TEST_FLD_NUM(VPU_37XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, exp_val, val))
+ return -EIO;
+
+ return 0;
+}
+
+static int host_ss_noc_qreqn_check_40xx(struct ivpu_device *vdev, u32 exp_val)
+{
+ u32 val = REGV_RD32(VPU_40XX_HOST_SS_NOC_QREQN);
+
+ if (!REG_TEST_FLD_NUM(VPU_40XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, exp_val, val))
+ return -EIO;
+
+ return 0;
+}
+
+static int host_ss_noc_qreqn_check(struct ivpu_device *vdev, u32 exp_val)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ return host_ss_noc_qreqn_check_37xx(vdev, exp_val);
+ else
+ return host_ss_noc_qreqn_check_40xx(vdev, exp_val);
+}
+
+static int host_ss_noc_qacceptn_check_37xx(struct ivpu_device *vdev, u32 exp_val)
+{
+ u32 val = REGV_RD32(VPU_37XX_HOST_SS_NOC_QACCEPTN);
+
+ if (!REG_TEST_FLD_NUM(VPU_37XX_HOST_SS_NOC_QACCEPTN, TOP_SOCMMIO, exp_val, val))
+ return -EIO;
+
+ return 0;
+}
+
+static int host_ss_noc_qacceptn_check_40xx(struct ivpu_device *vdev, u32 exp_val)
+{
+ u32 val = REGV_RD32(VPU_40XX_HOST_SS_NOC_QACCEPTN);
+
+ if (!REG_TEST_FLD_NUM(VPU_40XX_HOST_SS_NOC_QACCEPTN, TOP_SOCMMIO, exp_val, val))
+ return -EIO;
+
+ return 0;
+}
+
+static int host_ss_noc_qacceptn_check(struct ivpu_device *vdev, u32 exp_val)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ return host_ss_noc_qacceptn_check_37xx(vdev, exp_val);
+ else
+ return host_ss_noc_qacceptn_check_40xx(vdev, exp_val);
+}
+
+static int host_ss_noc_qdeny_check_37xx(struct ivpu_device *vdev, u32 exp_val)
+{
+ u32 val = REGV_RD32(VPU_37XX_HOST_SS_NOC_QDENY);
+
+ if (!REG_TEST_FLD_NUM(VPU_37XX_HOST_SS_NOC_QDENY, TOP_SOCMMIO, exp_val, val))
+ return -EIO;
+
+ return 0;
+}
+
+static int host_ss_noc_qdeny_check_40xx(struct ivpu_device *vdev, u32 exp_val)
+{
+ u32 val = REGV_RD32(VPU_40XX_HOST_SS_NOC_QDENY);
+
+ if (!REG_TEST_FLD_NUM(VPU_40XX_HOST_SS_NOC_QDENY, TOP_SOCMMIO, exp_val, val))
+ return -EIO;
+
+ return 0;
+}
+
+static int host_ss_noc_qdeny_check(struct ivpu_device *vdev, u32 exp_val)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ return host_ss_noc_qdeny_check_37xx(vdev, exp_val);
+ else
+ return host_ss_noc_qdeny_check_40xx(vdev, exp_val);
+}
+
+static int top_noc_qrenqn_check_37xx(struct ivpu_device *vdev, u32 exp_val)
+{
+ u32 val = REGV_RD32(VPU_37XX_TOP_NOC_QREQN);
+
+ if (!REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QREQN, CPU_CTRL, exp_val, val) ||
+ !REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, exp_val, val))
+ return -EIO;
+
+ return 0;
+}
+
+static int top_noc_qrenqn_check_40xx(struct ivpu_device *vdev, u32 exp_val)
+{
+ u32 val = REGV_RD32(VPU_40XX_TOP_NOC_QREQN);
+
+ if (!REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QREQN, CPU_CTRL, exp_val, val) ||
+ !REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, exp_val, val))
+ return -EIO;
+
+ return 0;
+}
+
+static int top_noc_qreqn_check(struct ivpu_device *vdev, u32 exp_val)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ return top_noc_qrenqn_check_37xx(vdev, exp_val);
+ else
+ return top_noc_qrenqn_check_40xx(vdev, exp_val);
+}
+
+int ivpu_hw_ip_host_ss_configure(struct ivpu_device *vdev)
+{
+ int ret;
+
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) {
+ ret = wait_for_ip_bar(vdev);
+ if (ret) {
+ ivpu_err(vdev, "Timed out waiting for NPU IP bar\n");
+ return ret;
+ }
+ host_ss_rst_clr(vdev);
+ }
+
+ ret = host_ss_noc_qreqn_check(vdev, 0x0);
+ if (ret) {
+ ivpu_err(vdev, "Failed qreqn check: %d\n", ret);
+ return ret;
+ }
+
+ ret = host_ss_noc_qacceptn_check(vdev, 0x0);
+ if (ret) {
+ ivpu_err(vdev, "Failed qacceptn check: %d\n", ret);
+ return ret;
+ }
+
+ ret = host_ss_noc_qdeny_check(vdev, 0x0);
+ if (ret)
+ ivpu_err(vdev, "Failed qdeny check %d\n", ret);
+
+ return ret;
+}
+
+static void idle_gen_drive_37xx(struct ivpu_device *vdev, bool enable)
+{
+ u32 val = REGV_RD32(VPU_37XX_HOST_SS_AON_VPU_IDLE_GEN);
+
+ if (enable)
+ val = REG_SET_FLD(VPU_37XX_HOST_SS_AON_VPU_IDLE_GEN, EN, val);
+ else
+ val = REG_CLR_FLD(VPU_37XX_HOST_SS_AON_VPU_IDLE_GEN, EN, val);
+
+ REGV_WR32(VPU_37XX_HOST_SS_AON_VPU_IDLE_GEN, val);
+}
+
+static void idle_gen_drive_40xx(struct ivpu_device *vdev, bool enable)
+{
+ u32 val = REGV_RD32(VPU_40XX_HOST_SS_AON_IDLE_GEN);
+
+ if (enable)
+ val = REG_SET_FLD(VPU_40XX_HOST_SS_AON_IDLE_GEN, EN, val);
+ else
+ val = REG_CLR_FLD(VPU_40XX_HOST_SS_AON_IDLE_GEN, EN, val);
+
+ REGV_WR32(VPU_40XX_HOST_SS_AON_IDLE_GEN, val);
+}
+
+void ivpu_hw_ip_idle_gen_enable(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ idle_gen_drive_37xx(vdev, true);
+ else
+ idle_gen_drive_40xx(vdev, true);
+}
+
+void ivpu_hw_ip_idle_gen_disable(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ idle_gen_drive_37xx(vdev, false);
+ else
+ idle_gen_drive_40xx(vdev, false);
+}
+
+static void pwr_island_delay_set_50xx(struct ivpu_device *vdev)
+{
+ u32 val, post, status;
+
+ if (vdev->hw->pll.profiling_freq == PLL_PROFILING_FREQ_DEFAULT) {
+ post = PWR_ISLAND_EN_POST_DLY_FREQ_DEFAULT;
+ status = PWR_ISLAND_STATUS_DLY_FREQ_DEFAULT;
+ } else {
+ post = PWR_ISLAND_EN_POST_DLY_FREQ_HIGH;
+ status = PWR_ISLAND_STATUS_DLY_FREQ_HIGH;
+ }
+
+ val = REGV_RD32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY);
+ val = REG_SET_FLD_NUM(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, POST_DLY, post, val);
+ REGV_WR32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, val);
+
+ val = REGV_RD32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY);
+ val = REG_SET_FLD_NUM(VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY, STATUS_DLY, status, val);
+ REGV_WR32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY, val);
+}
+
+static void pwr_island_trickle_drive_37xx(struct ivpu_device *vdev, bool enable)
+{
+ u32 val = REGV_RD32(VPU_37XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0);
+
+ if (enable)
+ val = REG_SET_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, MSS_CPU, val);
+ else
+ val = REG_CLR_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, MSS_CPU, val);
+
+ REGV_WR32(VPU_37XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, val);
+}
+
+static void pwr_island_trickle_drive_40xx(struct ivpu_device *vdev, bool enable)
+{
+ u32 val = REGV_RD32(VPU_40XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0);
+
+ if (enable)
+ val = REG_SET_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, CSS_CPU, val);
+ else
+ val = REG_CLR_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, CSS_CPU, val);
+
+ REGV_WR32(VPU_40XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, val);
+
+ if (enable)
+ ndelay(500);
+}
+
+static void pwr_island_drive_37xx(struct ivpu_device *vdev, bool enable)
+{
+ u32 val = REGV_RD32(VPU_40XX_HOST_SS_AON_PWR_ISLAND_EN0);
+
+ if (enable)
+ val = REG_SET_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_EN0, CSS_CPU, val);
+ else
+ val = REG_CLR_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_EN0, CSS_CPU, val);
+
+ REGV_WR32(VPU_40XX_HOST_SS_AON_PWR_ISLAND_EN0, val);
+
+ if (!enable)
+ ndelay(500);
+}
+
+static void pwr_island_drive_40xx(struct ivpu_device *vdev, bool enable)
+{
+ u32 val = REGV_RD32(VPU_37XX_HOST_SS_AON_PWR_ISLAND_EN0);
+
+ if (enable)
+ val = REG_SET_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_EN0, MSS_CPU, val);
+ else
+ val = REG_CLR_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_EN0, MSS_CPU, val);
+
+ REGV_WR32(VPU_37XX_HOST_SS_AON_PWR_ISLAND_EN0, val);
+}
+
+static void pwr_island_enable(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) {
+ pwr_island_trickle_drive_37xx(vdev, true);
+ pwr_island_drive_37xx(vdev, true);
+ } else {
+ pwr_island_trickle_drive_40xx(vdev, true);
+ pwr_island_drive_40xx(vdev, true);
+ }
+}
+
+static int wait_for_pwr_island_status(struct ivpu_device *vdev, u32 exp_val)
+{
+ if (IVPU_WA(punit_disabled))
+ return 0;
+
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ return REGV_POLL_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_STATUS0, MSS_CPU, exp_val,
+ PWR_ISLAND_STATUS_TIMEOUT_US);
+ else
+ return REGV_POLL_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_STATUS0, CSS_CPU, exp_val,
+ PWR_ISLAND_STATUS_TIMEOUT_US);
+}
+
+static void pwr_island_isolation_drive_37xx(struct ivpu_device *vdev, bool enable)
+{
+ u32 val = REGV_RD32(VPU_37XX_HOST_SS_AON_PWR_ISO_EN0);
+
+ if (enable)
+ val = REG_SET_FLD(VPU_37XX_HOST_SS_AON_PWR_ISO_EN0, MSS_CPU, val);
+ else
+ val = REG_CLR_FLD(VPU_37XX_HOST_SS_AON_PWR_ISO_EN0, MSS_CPU, val);
+
+ REGV_WR32(VPU_37XX_HOST_SS_AON_PWR_ISO_EN0, val);
+}
+
+static void pwr_island_isolation_drive_40xx(struct ivpu_device *vdev, bool enable)
+{
+ u32 val = REGV_RD32(VPU_40XX_HOST_SS_AON_PWR_ISO_EN0);
+
+ if (enable)
+ val = REG_SET_FLD(VPU_40XX_HOST_SS_AON_PWR_ISO_EN0, CSS_CPU, val);
+ else
+ val = REG_CLR_FLD(VPU_40XX_HOST_SS_AON_PWR_ISO_EN0, CSS_CPU, val);
+
+ REGV_WR32(VPU_40XX_HOST_SS_AON_PWR_ISO_EN0, val);
+}
+
+static void pwr_island_isolation_drive(struct ivpu_device *vdev, bool enable)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ pwr_island_isolation_drive_37xx(vdev, enable);
+ else
+ pwr_island_isolation_drive_40xx(vdev, enable);
+}
+
+static void pwr_island_isolation_disable(struct ivpu_device *vdev)
+{
+ pwr_island_isolation_drive(vdev, false);
+}
+
+static void host_ss_clk_drive_37xx(struct ivpu_device *vdev, bool enable)
+{
+ u32 val = REGV_RD32(VPU_37XX_HOST_SS_CPR_CLK_SET);
+
+ if (enable) {
+ val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, TOP_NOC, val);
+ val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, DSS_MAS, val);
+ val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, MSS_MAS, val);
+ } else {
+ val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, TOP_NOC, val);
+ val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, DSS_MAS, val);
+ val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, MSS_MAS, val);
+ }
+
+ REGV_WR32(VPU_37XX_HOST_SS_CPR_CLK_SET, val);
+}
+
+static void host_ss_clk_drive_40xx(struct ivpu_device *vdev, bool enable)
+{
+ u32 val = REGV_RD32(VPU_40XX_HOST_SS_CPR_CLK_EN);
+
+ if (enable) {
+ val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, TOP_NOC, val);
+ val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, DSS_MAS, val);
+ val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, CSS_MAS, val);
+ } else {
+ val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, TOP_NOC, val);
+ val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, DSS_MAS, val);
+ val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, CSS_MAS, val);
+ }
+
+ REGV_WR32(VPU_40XX_HOST_SS_CPR_CLK_EN, val);
+}
+
+static void host_ss_clk_drive(struct ivpu_device *vdev, bool enable)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ host_ss_clk_drive_37xx(vdev, enable);
+ else
+ host_ss_clk_drive_40xx(vdev, enable);
+}
+
+static void host_ss_clk_enable(struct ivpu_device *vdev)
+{
+ host_ss_clk_drive(vdev, true);
+}
+
+static void host_ss_rst_drive_37xx(struct ivpu_device *vdev, bool enable)
+{
+ u32 val = REGV_RD32(VPU_37XX_HOST_SS_CPR_RST_SET);
+
+ if (enable) {
+ val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, TOP_NOC, val);
+ val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, DSS_MAS, val);
+ val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, MSS_MAS, val);
+ } else {
+ val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, TOP_NOC, val);
+ val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, DSS_MAS, val);
+ val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, MSS_MAS, val);
+ }
+
+ REGV_WR32(VPU_37XX_HOST_SS_CPR_RST_SET, val);
+}
+
+static void host_ss_rst_drive_40xx(struct ivpu_device *vdev, bool enable)
+{
+ u32 val = REGV_RD32(VPU_40XX_HOST_SS_CPR_RST_EN);
+
+ if (enable) {
+ val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, TOP_NOC, val);
+ val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, DSS_MAS, val);
+ val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, CSS_MAS, val);
+ } else {
+ val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, TOP_NOC, val);
+ val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, DSS_MAS, val);
+ val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, CSS_MAS, val);
+ }
+
+ REGV_WR32(VPU_40XX_HOST_SS_CPR_RST_EN, val);
+}
+
+static void host_ss_rst_drive(struct ivpu_device *vdev, bool enable)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ host_ss_rst_drive_37xx(vdev, enable);
+ else
+ host_ss_rst_drive_40xx(vdev, enable);
+}
+
+static void host_ss_rst_enable(struct ivpu_device *vdev)
+{
+ host_ss_rst_drive(vdev, true);
+}
+
+static void host_ss_noc_qreqn_top_socmmio_drive_37xx(struct ivpu_device *vdev, bool enable)
+{
+ u32 val = REGV_RD32(VPU_37XX_HOST_SS_NOC_QREQN);
+
+ if (enable)
+ val = REG_SET_FLD(VPU_37XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, val);
+ else
+ val = REG_CLR_FLD(VPU_37XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, val);
+ REGV_WR32(VPU_37XX_HOST_SS_NOC_QREQN, val);
+}
+
+static void host_ss_noc_qreqn_top_socmmio_drive_40xx(struct ivpu_device *vdev, bool enable)
+{
+ u32 val = REGV_RD32(VPU_40XX_HOST_SS_NOC_QREQN);
+
+ if (enable)
+ val = REG_SET_FLD(VPU_40XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, val);
+ else
+ val = REG_CLR_FLD(VPU_40XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, val);
+ REGV_WR32(VPU_40XX_HOST_SS_NOC_QREQN, val);
+}
+
+static void host_ss_noc_qreqn_top_socmmio_drive(struct ivpu_device *vdev, bool enable)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ host_ss_noc_qreqn_top_socmmio_drive_37xx(vdev, enable);
+ else
+ host_ss_noc_qreqn_top_socmmio_drive_40xx(vdev, enable);
+}
+
+static int host_ss_axi_drive(struct ivpu_device *vdev, bool enable)
+{
+ int ret;
+
+ host_ss_noc_qreqn_top_socmmio_drive(vdev, enable);
+
+ ret = host_ss_noc_qacceptn_check(vdev, enable ? 0x1 : 0x0);
+ if (ret) {
+ ivpu_err(vdev, "Failed HOST SS NOC QACCEPTN check: %d\n", ret);
+ return ret;
+ }
+
+ ret = host_ss_noc_qdeny_check(vdev, 0x0);
+ if (ret)
+ ivpu_err(vdev, "Failed HOST SS NOC QDENY check: %d\n", ret);
+
+ return ret;
+}
+
+static void top_noc_qreqn_drive_40xx(struct ivpu_device *vdev, bool enable)
+{
+ u32 val = REGV_RD32(VPU_40XX_TOP_NOC_QREQN);
+
+ if (enable) {
+ val = REG_SET_FLD(VPU_40XX_TOP_NOC_QREQN, CPU_CTRL, val);
+ val = REG_SET_FLD(VPU_40XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, val);
+ } else {
+ val = REG_CLR_FLD(VPU_40XX_TOP_NOC_QREQN, CPU_CTRL, val);
+ val = REG_CLR_FLD(VPU_40XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, val);
+ }
+
+ REGV_WR32(VPU_40XX_TOP_NOC_QREQN, val);
+}
+
+static void top_noc_qreqn_drive_37xx(struct ivpu_device *vdev, bool enable)
+{
+ u32 val = REGV_RD32(VPU_37XX_TOP_NOC_QREQN);
+
+ if (enable) {
+ val = REG_SET_FLD(VPU_37XX_TOP_NOC_QREQN, CPU_CTRL, val);
+ val = REG_SET_FLD(VPU_37XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, val);
+ } else {
+ val = REG_CLR_FLD(VPU_37XX_TOP_NOC_QREQN, CPU_CTRL, val);
+ val = REG_CLR_FLD(VPU_37XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, val);
+ }
+
+ REGV_WR32(VPU_37XX_TOP_NOC_QREQN, val);
+}
+
+static void top_noc_qreqn_drive(struct ivpu_device *vdev, bool enable)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ top_noc_qreqn_drive_37xx(vdev, enable);
+ else
+ top_noc_qreqn_drive_40xx(vdev, enable);
+}
+
+int ivpu_hw_ip_host_ss_axi_enable(struct ivpu_device *vdev)
+{
+ return host_ss_axi_drive(vdev, true);
+}
+
+static int top_noc_qacceptn_check_37xx(struct ivpu_device *vdev, u32 exp_val)
+{
+ u32 val = REGV_RD32(VPU_37XX_TOP_NOC_QACCEPTN);
+
+ if (!REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QACCEPTN, CPU_CTRL, exp_val, val) ||
+ !REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QACCEPTN, HOSTIF_L2CACHE, exp_val, val))
+ return -EIO;
+
+ return 0;
+}
+
+static int top_noc_qacceptn_check_40xx(struct ivpu_device *vdev, u32 exp_val)
+{
+ u32 val = REGV_RD32(VPU_40XX_TOP_NOC_QACCEPTN);
+
+ if (!REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QACCEPTN, CPU_CTRL, exp_val, val) ||
+ !REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QACCEPTN, HOSTIF_L2CACHE, exp_val, val))
+ return -EIO;
+
+ return 0;
+}
+
+static int top_noc_qacceptn_check(struct ivpu_device *vdev, u32 exp_val)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ return top_noc_qacceptn_check_37xx(vdev, exp_val);
+ else
+ return top_noc_qacceptn_check_40xx(vdev, exp_val);
+}
+
+static int top_noc_qdeny_check_37xx(struct ivpu_device *vdev, u32 exp_val)
+{
+ u32 val = REGV_RD32(VPU_37XX_TOP_NOC_QDENY);
+
+ if (!REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QDENY, CPU_CTRL, exp_val, val) ||
+ !REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QDENY, HOSTIF_L2CACHE, exp_val, val))
+ return -EIO;
+
+ return 0;
+}
+
+static int top_noc_qdeny_check_40xx(struct ivpu_device *vdev, u32 exp_val)
+{
+ u32 val = REGV_RD32(VPU_40XX_TOP_NOC_QDENY);
+
+ if (!REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QDENY, CPU_CTRL, exp_val, val) ||
+ !REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QDENY, HOSTIF_L2CACHE, exp_val, val))
+ return -EIO;
+
+ return 0;
+}
+
+static int top_noc_qdeny_check(struct ivpu_device *vdev, u32 exp_val)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ return top_noc_qdeny_check_37xx(vdev, exp_val);
+ else
+ return top_noc_qdeny_check_40xx(vdev, exp_val);
+}
+
+static int top_noc_drive(struct ivpu_device *vdev, bool enable)
+{
+ int ret;
+
+ top_noc_qreqn_drive(vdev, enable);
+
+ ret = top_noc_qacceptn_check(vdev, enable ? 0x1 : 0x0);
+ if (ret) {
+ ivpu_err(vdev, "Failed TOP NOC QACCEPTN check: %d\n", ret);
+ return ret;
+ }
+
+ ret = top_noc_qdeny_check(vdev, 0x0);
+ if (ret)
+ ivpu_err(vdev, "Failed TOP NOC QDENY check: %d\n", ret);
+
+ return ret;
+}
+
+int ivpu_hw_ip_top_noc_enable(struct ivpu_device *vdev)
+{
+ return top_noc_drive(vdev, true);
+}
+
+static void dpu_active_drive_37xx(struct ivpu_device *vdev, bool enable)
+{
+ u32 val = REGV_RD32(VPU_37XX_HOST_SS_AON_DPU_ACTIVE);
+
+ if (enable)
+ val = REG_SET_FLD(VPU_37XX_HOST_SS_AON_DPU_ACTIVE, DPU_ACTIVE, val);
+ else
+ val = REG_CLR_FLD(VPU_37XX_HOST_SS_AON_DPU_ACTIVE, DPU_ACTIVE, val);
+
+ REGV_WR32(VPU_37XX_HOST_SS_AON_DPU_ACTIVE, val);
+}
+
+int ivpu_hw_ip_pwr_domain_enable(struct ivpu_device *vdev)
+{
+ int ret;
+
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_50XX)
+ pwr_island_delay_set_50xx(vdev);
+
+ pwr_island_enable(vdev);
+
+ ret = wait_for_pwr_island_status(vdev, 0x1);
+ if (ret) {
+ ivpu_err(vdev, "Timed out waiting for power island status\n");
+ return ret;
+ }
+
+ ret = top_noc_qreqn_check(vdev, 0x0);
+ if (ret) {
+ ivpu_err(vdev, "Failed TOP NOC QREQN check %d\n", ret);
+ return ret;
+ }
+
+ host_ss_clk_enable(vdev);
+ pwr_island_isolation_disable(vdev);
+ host_ss_rst_enable(vdev);
+
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ dpu_active_drive_37xx(vdev, true);
+
+ return ret;
+}
+
+u64 ivpu_hw_ip_read_perf_timer_counter(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ return REGV_RD64(VPU_37XX_CPU_SS_TIM_PERF_FREE_CNT);
+ else
+ return REGV_RD64(VPU_40XX_CPU_SS_TIM_PERF_EXT_FREE_CNT);
+}
+
+static void ivpu_hw_ip_snoop_disable_37xx(struct ivpu_device *vdev)
+{
+ u32 val = REGV_RD32(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES);
+
+ val = REG_SET_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, NOSNOOP_OVERRIDE_EN, val);
+ val = REG_CLR_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, AW_NOSNOOP_OVERRIDE, val);
+
+ if (ivpu_is_force_snoop_enabled(vdev))
+ val = REG_CLR_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, AR_NOSNOOP_OVERRIDE, val);
+ else
+ val = REG_SET_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, AR_NOSNOOP_OVERRIDE, val);
+
+ REGV_WR32(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, val);
+}
+
+static void ivpu_hw_ip_snoop_disable_40xx(struct ivpu_device *vdev)
+{
+ u32 val = REGV_RD32(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES);
+
+ val = REG_SET_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, SNOOP_OVERRIDE_EN, val);
+ val = REG_SET_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, AW_SNOOP_OVERRIDE, val);
+
+ if (ivpu_is_force_snoop_enabled(vdev))
+ val = REG_SET_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, AR_SNOOP_OVERRIDE, val);
+ else
+ val = REG_CLR_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, AR_SNOOP_OVERRIDE, val);
+
+ REGV_WR32(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, val);
+}
+
+void ivpu_hw_ip_snoop_disable(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ return ivpu_hw_ip_snoop_disable_37xx(vdev);
+ else
+ return ivpu_hw_ip_snoop_disable_40xx(vdev);
+}
+
+static void ivpu_hw_ip_tbu_mmu_enable_37xx(struct ivpu_device *vdev)
+{
+ u32 val = REGV_RD32(VPU_37XX_HOST_IF_TBU_MMUSSIDV);
+
+ val = REG_SET_FLD(VPU_37XX_HOST_IF_TBU_MMUSSIDV, TBU0_AWMMUSSIDV, val);
+ val = REG_SET_FLD(VPU_37XX_HOST_IF_TBU_MMUSSIDV, TBU0_ARMMUSSIDV, val);
+ val = REG_SET_FLD(VPU_37XX_HOST_IF_TBU_MMUSSIDV, TBU2_AWMMUSSIDV, val);
+ val = REG_SET_FLD(VPU_37XX_HOST_IF_TBU_MMUSSIDV, TBU2_ARMMUSSIDV, val);
+
+ REGV_WR32(VPU_37XX_HOST_IF_TBU_MMUSSIDV, val);
+}
+
+static void ivpu_hw_ip_tbu_mmu_enable_40xx(struct ivpu_device *vdev)
+{
+ u32 val = REGV_RD32(VPU_40XX_HOST_IF_TBU_MMUSSIDV);
+
+ val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU0_AWMMUSSIDV, val);
+ val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU0_ARMMUSSIDV, val);
+ val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU1_AWMMUSSIDV, val);
+ val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU1_ARMMUSSIDV, val);
+ val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU2_AWMMUSSIDV, val);
+ val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU2_ARMMUSSIDV, val);
+
+ REGV_WR32(VPU_40XX_HOST_IF_TBU_MMUSSIDV, val);
+}
+
+void ivpu_hw_ip_tbu_mmu_enable(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ return ivpu_hw_ip_tbu_mmu_enable_37xx(vdev);
+ else
+ return ivpu_hw_ip_tbu_mmu_enable_40xx(vdev);
+}
+
+static int soc_cpu_boot_37xx(struct ivpu_device *vdev)
+{
+ u32 val;
+
+ val = REGV_RD32(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC);
+ val = REG_SET_FLD(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, IRQI_RSTRUN0, val);
+
+ val = REG_CLR_FLD(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, IRQI_RSTVEC, val);
+ REGV_WR32(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, val);
+
+ val = REG_SET_FLD(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, IRQI_RESUME0, val);
+ REGV_WR32(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, val);
+
+ val = REG_CLR_FLD(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, IRQI_RESUME0, val);
+ REGV_WR32(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, val);
+
+ val = vdev->fw->entry_point >> 9;
+ REGV_WR32(VPU_37XX_HOST_SS_LOADING_ADDRESS_LO, val);
+
+ val = REG_SET_FLD(VPU_37XX_HOST_SS_LOADING_ADDRESS_LO, DONE, val);
+ REGV_WR32(VPU_37XX_HOST_SS_LOADING_ADDRESS_LO, val);
+
+ ivpu_dbg(vdev, PM, "Booting firmware, mode: %s\n",
+ vdev->fw->entry_point == vdev->fw->cold_boot_entry_point ? "cold boot" : "resume");
+
+ return 0;
+}
+
+static int cpu_noc_qacceptn_check_40xx(struct ivpu_device *vdev, u32 exp_val)
+{
+ u32 val = REGV_RD32(VPU_40XX_CPU_SS_CPR_NOC_QACCEPTN);
+
+ if (!REG_TEST_FLD_NUM(VPU_40XX_CPU_SS_CPR_NOC_QACCEPTN, TOP_MMIO, exp_val, val))
+ return -EIO;
+
+ return 0;
+}
+
+static int cpu_noc_qdeny_check_40xx(struct ivpu_device *vdev, u32 exp_val)
+{
+ u32 val = REGV_RD32(VPU_40XX_CPU_SS_CPR_NOC_QDENY);
+
+ if (!REG_TEST_FLD_NUM(VPU_40XX_CPU_SS_CPR_NOC_QDENY, TOP_MMIO, exp_val, val))
+ return -EIO;
+
+ return 0;
+}
+
+static void cpu_noc_top_mmio_drive_40xx(struct ivpu_device *vdev, bool enable)
+{
+ u32 val = REGV_RD32(VPU_40XX_CPU_SS_CPR_NOC_QREQN);
+
+ if (enable)
+ val = REG_SET_FLD(VPU_40XX_CPU_SS_CPR_NOC_QREQN, TOP_MMIO, val);
+ else
+ val = REG_CLR_FLD(VPU_40XX_CPU_SS_CPR_NOC_QREQN, TOP_MMIO, val);
+ REGV_WR32(VPU_40XX_CPU_SS_CPR_NOC_QREQN, val);
+}
+
+static int soc_cpu_drive_40xx(struct ivpu_device *vdev, bool enable)
+{
+ int ret;
+
+ cpu_noc_top_mmio_drive_40xx(vdev, enable);
+
+ ret = cpu_noc_qacceptn_check_40xx(vdev, enable ? 0x1 : 0x0);
+ if (ret) {
+ ivpu_err(vdev, "Failed qacceptn check: %d\n", ret);
+ return ret;
+ }
+
+ ret = cpu_noc_qdeny_check_40xx(vdev, 0x0);
+ if (ret)
+ ivpu_err(vdev, "Failed qdeny check: %d\n", ret);
+
+ return ret;
+}
+
+static int soc_cpu_enable(struct ivpu_device *vdev)
+{
+ return soc_cpu_drive_40xx(vdev, true);
+}
+
+static int soc_cpu_boot_40xx(struct ivpu_device *vdev)
+{
+ int ret;
+ u32 val;
+ u64 val64;
+
+ ret = soc_cpu_enable(vdev);
+ if (ret) {
+ ivpu_err(vdev, "Failed to enable SOC CPU: %d\n", ret);
+ return ret;
+ }
+
+ val64 = vdev->fw->entry_point;
+ val64 <<= ffs(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO_IMAGE_LOCATION_MASK) - 1;
+ REGV_WR64(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO, val64);
+
+ val = REGV_RD32(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO);
+ val = REG_SET_FLD(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO, DONE, val);
+ REGV_WR32(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO, val);
+
+ ivpu_dbg(vdev, PM, "Booting firmware, mode: %s\n",
+ ivpu_fw_is_cold_boot(vdev) ? "cold boot" : "resume");
+
+ return 0;
+}
+
+int ivpu_hw_ip_soc_cpu_boot(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ return soc_cpu_boot_37xx(vdev);
+ else
+ return soc_cpu_boot_40xx(vdev);
+}
+
+static void wdt_disable_37xx(struct ivpu_device *vdev)
+{
+ u32 val;
+
+ /* Enable writing and set non-zero WDT value */
+ REGV_WR32(VPU_37XX_CPU_SS_TIM_SAFE, TIM_SAFE_ENABLE);
+ REGV_WR32(VPU_37XX_CPU_SS_TIM_WATCHDOG, TIM_WATCHDOG_RESET_VALUE);
+
+ /* Enable writing and disable watchdog timer */
+ REGV_WR32(VPU_37XX_CPU_SS_TIM_SAFE, TIM_SAFE_ENABLE);
+ REGV_WR32(VPU_37XX_CPU_SS_TIM_WDOG_EN, 0);
+
+ /* Now clear the timeout interrupt */
+ val = REGV_RD32(VPU_37XX_CPU_SS_TIM_GEN_CONFIG);
+ val = REG_CLR_FLD(VPU_37XX_CPU_SS_TIM_GEN_CONFIG, WDOG_TO_INT_CLR, val);
+ REGV_WR32(VPU_37XX_CPU_SS_TIM_GEN_CONFIG, val);
+}
+
+static void wdt_disable_40xx(struct ivpu_device *vdev)
+{
+ u32 val;
+
+ REGV_WR32(VPU_40XX_CPU_SS_TIM_SAFE, TIM_SAFE_ENABLE);
+ REGV_WR32(VPU_40XX_CPU_SS_TIM_WATCHDOG, TIM_WATCHDOG_RESET_VALUE);
+
+ REGV_WR32(VPU_40XX_CPU_SS_TIM_SAFE, TIM_SAFE_ENABLE);
+ REGV_WR32(VPU_40XX_CPU_SS_TIM_WDOG_EN, 0);
+
+ val = REGV_RD32(VPU_40XX_CPU_SS_TIM_GEN_CONFIG);
+ val = REG_CLR_FLD(VPU_40XX_CPU_SS_TIM_GEN_CONFIG, WDOG_TO_INT_CLR, val);
+ REGV_WR32(VPU_40XX_CPU_SS_TIM_GEN_CONFIG, val);
+}
+
+void ivpu_hw_ip_wdt_disable(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ return wdt_disable_37xx(vdev);
+ else
+ return wdt_disable_40xx(vdev);
+}
+
+static u32 ipc_rx_count_get_37xx(struct ivpu_device *vdev)
+{
+ u32 count = REGV_RD32_SILENT(VPU_37XX_HOST_SS_TIM_IPC_FIFO_STAT);
+
+ return REG_GET_FLD(VPU_37XX_HOST_SS_TIM_IPC_FIFO_STAT, FILL_LEVEL, count);
+}
+
+static u32 ipc_rx_count_get_40xx(struct ivpu_device *vdev)
+{
+ u32 count = REGV_RD32_SILENT(VPU_40XX_HOST_SS_TIM_IPC_FIFO_STAT);
+
+ return REG_GET_FLD(VPU_40XX_HOST_SS_TIM_IPC_FIFO_STAT, FILL_LEVEL, count);
+}
+
+u32 ivpu_hw_ip_ipc_rx_count_get(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ return ipc_rx_count_get_37xx(vdev);
+ else
+ return ipc_rx_count_get_40xx(vdev);
+}
+
+void ivpu_hw_ip_irq_enable(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) {
+ REGV_WR32(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, ITF_FIREWALL_VIOLATION_MASK_37XX);
+ REGV_WR64(VPU_37XX_HOST_SS_ICB_ENABLE_0, ICB_0_1_IRQ_MASK_37XX);
+ } else {
+ REGV_WR32(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, ITF_FIREWALL_VIOLATION_MASK_40XX);
+ REGV_WR64(VPU_40XX_HOST_SS_ICB_ENABLE_0, ICB_0_1_IRQ_MASK_40XX);
+ }
+}
+
+void ivpu_hw_ip_irq_disable(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) {
+ REGV_WR64(VPU_37XX_HOST_SS_ICB_ENABLE_0, 0x0ull);
+ REGV_WR32(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, 0x0);
+ } else {
+ REGV_WR64(VPU_40XX_HOST_SS_ICB_ENABLE_0, 0x0ull);
+ REGV_WR32(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, 0x0ul);
+ }
+}
+
+static void diagnose_failure_37xx(struct ivpu_device *vdev)
+{
+ u32 reg = REGV_RD32(VPU_37XX_HOST_SS_ICB_STATUS_0) & ICB_0_IRQ_MASK_37XX;
+
+ if (ipc_rx_count_get_37xx(vdev))
+ ivpu_err(vdev, "IPC FIFO queue not empty, missed IPC IRQ");
+
+ if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT, reg))
+ ivpu_err(vdev, "WDT MSS timeout detected\n");
+
+ if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT, reg))
+ ivpu_err(vdev, "WDT NCE timeout detected\n");
+
+ if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT, reg))
+ ivpu_err(vdev, "NOC Firewall irq detected\n");
+}
+
+static void diagnose_failure_40xx(struct ivpu_device *vdev)
+{
+ u32 reg = REGV_RD32(VPU_40XX_HOST_SS_ICB_STATUS_0) & ICB_0_IRQ_MASK_40XX;
+
+ if (ipc_rx_count_get_40xx(vdev))
+ ivpu_err(vdev, "IPC FIFO queue not empty, missed IPC IRQ");
+
+ if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT, reg))
+ ivpu_err(vdev, "WDT MSS timeout detected\n");
+
+ if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT, reg))
+ ivpu_err(vdev, "WDT NCE timeout detected\n");
+
+ if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT, reg))
+ ivpu_err(vdev, "NOC Firewall irq detected\n");
+}
+
+void ivpu_hw_ip_diagnose_failure(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ diagnose_failure_37xx(vdev);
+ else
+ diagnose_failure_40xx(vdev);
+}
+
+void ivpu_hw_ip_irq_clear(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ REGV_WR64(VPU_37XX_HOST_SS_ICB_CLEAR_0, ICB_0_1_IRQ_MASK_37XX);
+ else
+ REGV_WR64(VPU_40XX_HOST_SS_ICB_CLEAR_0, ICB_0_1_IRQ_MASK_40XX);
+}
+
+static void irq_wdt_nce_handler(struct ivpu_device *vdev)
+{
+ ivpu_pm_trigger_recovery(vdev, "WDT NCE IRQ");
+}
+
+static void irq_wdt_mss_handler(struct ivpu_device *vdev)
+{
+ ivpu_hw_ip_wdt_disable(vdev);
+ ivpu_pm_trigger_recovery(vdev, "WDT MSS IRQ");
+}
+
+static void irq_noc_firewall_handler(struct ivpu_device *vdev)
+{
+ ivpu_pm_trigger_recovery(vdev, "NOC Firewall IRQ");
+}
+
+/* Handler for IRQs from NPU core */
+bool ivpu_hw_ip_irq_handler_37xx(struct ivpu_device *vdev, int irq)
+{
+ u32 status = REGV_RD32(VPU_37XX_HOST_SS_ICB_STATUS_0) & ICB_0_IRQ_MASK_37XX;
+
+ if (!status)
+ return false;
+
+ REGV_WR32(VPU_37XX_HOST_SS_ICB_CLEAR_0, status);
+
+ if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_0_INT, status))
+ ivpu_mmu_irq_evtq_handler(vdev);
+
+ if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, HOST_IPC_FIFO_INT, status))
+ ivpu_ipc_irq_handler(vdev);
+
+ if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_1_INT, status))
+ ivpu_dbg(vdev, IRQ, "MMU sync complete\n");
+
+ if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_2_INT, status))
+ ivpu_mmu_irq_gerr_handler(vdev);
+
+ if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT, status))
+ irq_wdt_mss_handler(vdev);
+
+ if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT, status))
+ irq_wdt_nce_handler(vdev);
+
+ if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT, status))
+ irq_noc_firewall_handler(vdev);
+
+ return true;
+}
+
+/* Handler for IRQs from NPU core */
+bool ivpu_hw_ip_irq_handler_40xx(struct ivpu_device *vdev, int irq)
+{
+ u32 status = REGV_RD32(VPU_40XX_HOST_SS_ICB_STATUS_0) & ICB_0_IRQ_MASK_40XX;
+
+ if (!status)
+ return false;
+
+ REGV_WR32(VPU_40XX_HOST_SS_ICB_CLEAR_0, status);
+
+ if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_0_INT, status))
+ ivpu_mmu_irq_evtq_handler(vdev);
+
+ if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, HOST_IPC_FIFO_INT, status))
+ ivpu_ipc_irq_handler(vdev);
+
+ if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_1_INT, status))
+ ivpu_dbg(vdev, IRQ, "MMU sync complete\n");
+
+ if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_2_INT, status))
+ ivpu_mmu_irq_gerr_handler(vdev);
+
+ if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT, status))
+ irq_wdt_mss_handler(vdev);
+
+ if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT, status))
+ irq_wdt_nce_handler(vdev);
+
+ if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT, status))
+ irq_noc_firewall_handler(vdev);
+
+ return true;
+}
+
+static void db_set_37xx(struct ivpu_device *vdev, u32 db_id)
+{
+ u32 reg_stride = VPU_37XX_CPU_SS_DOORBELL_1 - VPU_37XX_CPU_SS_DOORBELL_0;
+ u32 val = REG_FLD(VPU_37XX_CPU_SS_DOORBELL_0, SET);
+
+ REGV_WR32I(VPU_37XX_CPU_SS_DOORBELL_0, reg_stride, db_id, val);
+}
+
+static void db_set_40xx(struct ivpu_device *vdev, u32 db_id)
+{
+ u32 reg_stride = VPU_40XX_CPU_SS_DOORBELL_1 - VPU_40XX_CPU_SS_DOORBELL_0;
+ u32 val = REG_FLD(VPU_40XX_CPU_SS_DOORBELL_0, SET);
+
+ REGV_WR32I(VPU_40XX_CPU_SS_DOORBELL_0, reg_stride, db_id, val);
+}
+
+void ivpu_hw_ip_db_set(struct ivpu_device *vdev, u32 db_id)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ db_set_37xx(vdev, db_id);
+ else
+ db_set_40xx(vdev, db_id);
+}
+
+u32 ivpu_hw_ip_ipc_rx_addr_get(struct ivpu_device *vdev)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ return REGV_RD32(VPU_37XX_HOST_SS_TIM_IPC_FIFO_ATM);
+ else
+ return REGV_RD32(VPU_40XX_HOST_SS_TIM_IPC_FIFO_ATM);
+}
+
+void ivpu_hw_ip_ipc_tx_set(struct ivpu_device *vdev, u32 vpu_addr)
+{
+ if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
+ REGV_WR32(VPU_37XX_CPU_SS_TIM_IPC_FIFO, vpu_addr);
+ else
+ REGV_WR32(VPU_40XX_CPU_SS_TIM_IPC_FIFO, vpu_addr);
+}
diff --git a/drivers/accel/ivpu/ivpu_hw_ip.h b/drivers/accel/ivpu/ivpu_hw_ip.h
new file mode 100644
index 000000000000..5b1b391aa577
--- /dev/null
+++ b/drivers/accel/ivpu/ivpu_hw_ip.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2020-2024 Intel Corporation
+ */
+
+#ifndef __IVPU_HW_IP_H__
+#define __IVPU_HW_IP_H__
+
+#include "ivpu_drv.h"
+
+int ivpu_hw_ip_host_ss_configure(struct ivpu_device *vdev);
+void ivpu_hw_ip_idle_gen_enable(struct ivpu_device *vdev);
+void ivpu_hw_ip_idle_gen_disable(struct ivpu_device *vdev);
+int ivpu_hw_ip_pwr_domain_enable(struct ivpu_device *vdev);
+int ivpu_hw_ip_host_ss_axi_enable(struct ivpu_device *vdev);
+int ivpu_hw_ip_top_noc_enable(struct ivpu_device *vdev);
+u64 ivpu_hw_ip_read_perf_timer_counter(struct ivpu_device *vdev);
+void ivpu_hw_ip_snoop_disable(struct ivpu_device *vdev);
+void ivpu_hw_ip_tbu_mmu_enable(struct ivpu_device *vdev);
+int ivpu_hw_ip_soc_cpu_boot(struct ivpu_device *vdev);
+void ivpu_hw_ip_wdt_disable(struct ivpu_device *vdev);
+void ivpu_hw_ip_diagnose_failure(struct ivpu_device *vdev);
+u32 ivpu_hw_ip_ipc_rx_count_get(struct ivpu_device *vdev);
+void ivpu_hw_ip_irq_clear(struct ivpu_device *vdev);
+bool ivpu_hw_ip_irq_handler_37xx(struct ivpu_device *vdev, int irq);
+bool ivpu_hw_ip_irq_handler_40xx(struct ivpu_device *vdev, int irq);
+void ivpu_hw_ip_db_set(struct ivpu_device *vdev, u32 db_id);
+u32 ivpu_hw_ip_ipc_rx_addr_get(struct ivpu_device *vdev);
+void ivpu_hw_ip_ipc_tx_set(struct ivpu_device *vdev, u32 vpu_addr);
+void ivpu_hw_ip_irq_enable(struct ivpu_device *vdev);
+void ivpu_hw_ip_irq_disable(struct ivpu_device *vdev);
+void ivpu_hw_ip_diagnose_failure(struct ivpu_device *vdev);
+void ivpu_hw_ip_fabric_req_override_enable_50xx(struct ivpu_device *vdev);
+void ivpu_hw_ip_fabric_req_override_disable_50xx(struct ivpu_device *vdev);
+
+#endif /* __IVPU_HW_IP_H__ */
diff --git a/drivers/accel/ivpu/ivpu_ipc.c b/drivers/accel/ivpu/ivpu_ipc.c
index 56ff067f63e2..78b32a823241 100644
--- a/drivers/accel/ivpu/ivpu_ipc.c
+++ b/drivers/accel/ivpu/ivpu_ipc.c
@@ -129,7 +129,7 @@ static void ivpu_ipc_tx_release(struct ivpu_device *vdev, u32 vpu_addr)
static void ivpu_ipc_tx(struct ivpu_device *vdev, u32 vpu_addr)
{
- ivpu_hw_reg_ipc_tx_set(vdev, vpu_addr);
+ ivpu_hw_ipc_tx_set(vdev, vpu_addr);
}
static void
@@ -210,8 +210,7 @@ void ivpu_ipc_consumer_del(struct ivpu_device *vdev, struct ivpu_ipc_consumer *c
ivpu_ipc_tx_release(vdev, cons->tx_vpu_addr);
}
-static int
-ivpu_ipc_send(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, struct vpu_jsm_msg *req)
+int ivpu_ipc_send(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, struct vpu_jsm_msg *req)
{
struct ivpu_ipc_info *ipc = vdev->ipc;
int ret;
@@ -378,7 +377,7 @@ ivpu_ipc_match_consumer(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons
return false;
}
-void ivpu_ipc_irq_handler(struct ivpu_device *vdev, bool *wake_thread)
+void ivpu_ipc_irq_handler(struct ivpu_device *vdev)
{
struct ivpu_ipc_info *ipc = vdev->ipc;
struct ivpu_ipc_consumer *cons;
@@ -392,8 +391,8 @@ void ivpu_ipc_irq_handler(struct ivpu_device *vdev, bool *wake_thread)
* Driver needs to purge all messages from IPC FIFO to clear IPC interrupt.
* Without purge IPC FIFO to 0 next IPC interrupts won't be generated.
*/
- while (ivpu_hw_reg_ipc_rx_count_get(vdev)) {
- vpu_addr = ivpu_hw_reg_ipc_rx_addr_get(vdev);
+ while (ivpu_hw_ipc_rx_count_get(vdev)) {
+ vpu_addr = ivpu_hw_ipc_rx_addr_get(vdev);
if (vpu_addr == REG_IO_ERROR) {
ivpu_err_ratelimited(vdev, "Failed to read IPC rx addr register\n");
return;
@@ -442,11 +441,12 @@ void ivpu_ipc_irq_handler(struct ivpu_device *vdev, bool *wake_thread)
}
}
- if (wake_thread)
- *wake_thread = !list_empty(&ipc->cb_msg_list);
+ if (!list_empty(&ipc->cb_msg_list))
+ if (!kfifo_put(&vdev->hw->irq.fifo, IVPU_HW_IRQ_SRC_IPC))
+ ivpu_err_ratelimited(vdev, "IRQ FIFO full\n");
}
-irqreturn_t ivpu_ipc_irq_thread_handler(struct ivpu_device *vdev)
+void ivpu_ipc_irq_thread_handler(struct ivpu_device *vdev)
{
struct ivpu_ipc_info *ipc = vdev->ipc;
struct ivpu_ipc_rx_msg *rx_msg, *r;
@@ -462,8 +462,6 @@ irqreturn_t ivpu_ipc_irq_thread_handler(struct ivpu_device *vdev)
rx_msg->callback(vdev, rx_msg->ipc_hdr, rx_msg->jsm_msg);
ivpu_ipc_rx_msg_del(vdev, rx_msg);
}
-
- return IRQ_HANDLED;
}
int ivpu_ipc_init(struct ivpu_device *vdev)
diff --git a/drivers/accel/ivpu/ivpu_ipc.h b/drivers/accel/ivpu/ivpu_ipc.h
index 40ca3cc4e61f..4fe38141045e 100644
--- a/drivers/accel/ivpu/ivpu_ipc.h
+++ b/drivers/accel/ivpu/ivpu_ipc.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (C) 2020-2023 Intel Corporation
+ * Copyright (C) 2020-2024 Intel Corporation
*/
#ifndef __IVPU_IPC_H__
@@ -89,13 +89,15 @@ void ivpu_ipc_enable(struct ivpu_device *vdev);
void ivpu_ipc_disable(struct ivpu_device *vdev);
void ivpu_ipc_reset(struct ivpu_device *vdev);
-void ivpu_ipc_irq_handler(struct ivpu_device *vdev, bool *wake_thread);
-irqreturn_t ivpu_ipc_irq_thread_handler(struct ivpu_device *vdev);
+void ivpu_ipc_irq_handler(struct ivpu_device *vdev);
+void ivpu_ipc_irq_thread_handler(struct ivpu_device *vdev);
void ivpu_ipc_consumer_add(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
u32 channel, ivpu_ipc_rx_callback_t callback);
void ivpu_ipc_consumer_del(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons);
+int ivpu_ipc_send(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
+ struct vpu_jsm_msg *req);
int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
struct ivpu_ipc_hdr *ipc_buf, struct vpu_jsm_msg *jsm_msg,
unsigned long timeout_ms);
diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c
index a49bc9105ed0..be2e2bf0f43f 100644
--- a/drivers/accel/ivpu/ivpu_job.c
+++ b/drivers/accel/ivpu/ivpu_job.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2020-2023 Intel Corporation
+ * Copyright (C) 2020-2024 Intel Corporation
*/
#include <drm/drm_file.h>
@@ -12,11 +12,13 @@
#include <uapi/drm/ivpu_accel.h>
#include "ivpu_drv.h"
+#include "ivpu_fw.h"
#include "ivpu_hw.h"
#include "ivpu_ipc.h"
#include "ivpu_job.h"
#include "ivpu_jsm_msg.h"
#include "ivpu_pm.h"
+#include "vpu_boot_api.h"
#define CMD_BUF_IDX 0
#define JOB_ID_JOB_MASK GENMASK(7, 0)
@@ -25,14 +27,60 @@
static void ivpu_cmdq_ring_db(struct ivpu_device *vdev, struct ivpu_cmdq *cmdq)
{
- ivpu_hw_reg_db_set(vdev, cmdq->db_id);
+ ivpu_hw_db_set(vdev, cmdq->db_id);
}
-static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv, u16 engine)
+static int ivpu_preemption_buffers_create(struct ivpu_device *vdev,
+ struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq)
+{
+ u64 primary_size = ALIGN(vdev->fw->primary_preempt_buf_size, PAGE_SIZE);
+ u64 secondary_size = ALIGN(vdev->fw->secondary_preempt_buf_size, PAGE_SIZE);
+ struct ivpu_addr_range range;
+
+ if (vdev->hw->sched_mode != VPU_SCHEDULING_MODE_HW)
+ return 0;
+
+ range.start = vdev->hw->ranges.user.end - (primary_size * IVPU_NUM_CMDQS_PER_CTX);
+ range.end = vdev->hw->ranges.user.end;
+ cmdq->primary_preempt_buf = ivpu_bo_create(vdev, &file_priv->ctx, &range, primary_size,
+ DRM_IVPU_BO_WC);
+ if (!cmdq->primary_preempt_buf) {
+ ivpu_err(vdev, "Failed to create primary preemption buffer\n");
+ return -ENOMEM;
+ }
+
+ range.start = vdev->hw->ranges.shave.end - (secondary_size * IVPU_NUM_CMDQS_PER_CTX);
+ range.end = vdev->hw->ranges.shave.end;
+ cmdq->secondary_preempt_buf = ivpu_bo_create(vdev, &file_priv->ctx, &range, secondary_size,
+ DRM_IVPU_BO_WC);
+ if (!cmdq->secondary_preempt_buf) {
+ ivpu_err(vdev, "Failed to create secondary preemption buffer\n");
+ goto err_free_primary;
+ }
+
+ return 0;
+
+err_free_primary:
+ ivpu_bo_free(cmdq->primary_preempt_buf);
+ return -ENOMEM;
+}
+
+static void ivpu_preemption_buffers_free(struct ivpu_device *vdev,
+ struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq)
+{
+ if (vdev->hw->sched_mode != VPU_SCHEDULING_MODE_HW)
+ return;
+
+ drm_WARN_ON(&vdev->drm, !cmdq->primary_preempt_buf);
+ drm_WARN_ON(&vdev->drm, !cmdq->secondary_preempt_buf);
+ ivpu_bo_free(cmdq->primary_preempt_buf);
+ ivpu_bo_free(cmdq->secondary_preempt_buf);
+}
+
+static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv)
{
struct xa_limit db_xa_limit = {.max = IVPU_MAX_DB, .min = IVPU_MIN_DB};
struct ivpu_device *vdev = file_priv->vdev;
- struct vpu_job_queue_header *jobq_header;
struct ivpu_cmdq *cmdq;
int ret;
@@ -50,18 +98,14 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv, u16 e
if (!cmdq->mem)
goto err_erase_xa;
- cmdq->entry_count = (u32)((ivpu_bo_size(cmdq->mem) - sizeof(struct vpu_job_queue_header)) /
- sizeof(struct vpu_job_queue_entry));
-
- cmdq->jobq = (struct vpu_job_queue *)ivpu_bo_vaddr(cmdq->mem);
- jobq_header = &cmdq->jobq->header;
- jobq_header->engine_idx = engine;
- jobq_header->head = 0;
- jobq_header->tail = 0;
- wmb(); /* Flush WC buffer for jobq->header */
+ ret = ivpu_preemption_buffers_create(vdev, file_priv, cmdq);
+ if (ret)
+ goto err_free_cmdq_mem;
return cmdq;
+err_free_cmdq_mem:
+ ivpu_bo_free(cmdq->mem);
err_erase_xa:
xa_erase(&vdev->db_xa, cmdq->db_id);
err_free_cmdq:
@@ -74,92 +118,183 @@ static void ivpu_cmdq_free(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *c
if (!cmdq)
return;
+ ivpu_preemption_buffers_free(file_priv->vdev, file_priv, cmdq);
ivpu_bo_free(cmdq->mem);
xa_erase(&file_priv->vdev->db_xa, cmdq->db_id);
kfree(cmdq);
}
-static struct ivpu_cmdq *ivpu_cmdq_acquire(struct ivpu_file_priv *file_priv, u16 engine)
+static int ivpu_hws_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq, u16 engine,
+ u8 priority)
{
struct ivpu_device *vdev = file_priv->vdev;
- struct ivpu_cmdq *cmdq = file_priv->cmdq[engine];
+ int ret;
+
+ ret = ivpu_jsm_hws_create_cmdq(vdev, file_priv->ctx.id, file_priv->ctx.id, cmdq->db_id,
+ task_pid_nr(current), engine,
+ cmdq->mem->vpu_addr, ivpu_bo_size(cmdq->mem));
+ if (ret)
+ return ret;
+
+ ret = ivpu_jsm_hws_set_context_sched_properties(vdev, file_priv->ctx.id, cmdq->db_id,
+ priority);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int ivpu_register_db(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq)
+{
+ struct ivpu_device *vdev = file_priv->vdev;
+ int ret;
+
+ if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW)
+ ret = ivpu_jsm_hws_register_db(vdev, file_priv->ctx.id, cmdq->db_id, cmdq->db_id,
+ cmdq->mem->vpu_addr, ivpu_bo_size(cmdq->mem));
+ else
+ ret = ivpu_jsm_register_db(vdev, file_priv->ctx.id, cmdq->db_id,
+ cmdq->mem->vpu_addr, ivpu_bo_size(cmdq->mem));
+
+ if (!ret)
+ ivpu_dbg(vdev, JOB, "DB %d registered to ctx %d\n", cmdq->db_id, file_priv->ctx.id);
+
+ return ret;
+}
+
+static int
+ivpu_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq, u16 engine, u8 priority)
+{
+ struct ivpu_device *vdev = file_priv->vdev;
+ struct vpu_job_queue_header *jobq_header;
+ int ret;
+
+ lockdep_assert_held(&file_priv->lock);
+
+ if (cmdq->db_registered)
+ return 0;
+
+ cmdq->entry_count = (u32)((ivpu_bo_size(cmdq->mem) - sizeof(struct vpu_job_queue_header)) /
+ sizeof(struct vpu_job_queue_entry));
+
+ cmdq->jobq = (struct vpu_job_queue *)ivpu_bo_vaddr(cmdq->mem);
+ jobq_header = &cmdq->jobq->header;
+ jobq_header->engine_idx = engine;
+ jobq_header->head = 0;
+ jobq_header->tail = 0;
+ wmb(); /* Flush WC buffer for jobq->header */
+
+ if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW) {
+ ret = ivpu_hws_cmdq_init(file_priv, cmdq, engine, priority);
+ if (ret)
+ return ret;
+ }
+
+ ret = ivpu_register_db(file_priv, cmdq);
+ if (ret)
+ return ret;
+
+ cmdq->db_registered = true;
+
+ return 0;
+}
+
+static int ivpu_cmdq_fini(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq)
+{
+ struct ivpu_device *vdev = file_priv->vdev;
+ int ret;
+
+ lockdep_assert_held(&file_priv->lock);
+
+ if (!cmdq->db_registered)
+ return 0;
+
+ cmdq->db_registered = false;
+
+ if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW) {
+ ret = ivpu_jsm_hws_destroy_cmdq(vdev, file_priv->ctx.id, cmdq->db_id);
+ if (!ret)
+ ivpu_dbg(vdev, JOB, "Command queue %d destroyed\n", cmdq->db_id);
+ }
+
+ ret = ivpu_jsm_unregister_db(vdev, cmdq->db_id);
+ if (!ret)
+ ivpu_dbg(vdev, JOB, "DB %d unregistered\n", cmdq->db_id);
+
+ return 0;
+}
+
+static struct ivpu_cmdq *ivpu_cmdq_acquire(struct ivpu_file_priv *file_priv, u16 engine,
+ u8 priority)
+{
+ int cmdq_idx = IVPU_CMDQ_INDEX(engine, priority);
+ struct ivpu_cmdq *cmdq = file_priv->cmdq[cmdq_idx];
int ret;
lockdep_assert_held(&file_priv->lock);
if (!cmdq) {
- cmdq = ivpu_cmdq_alloc(file_priv, engine);
+ cmdq = ivpu_cmdq_alloc(file_priv);
if (!cmdq)
return NULL;
- file_priv->cmdq[engine] = cmdq;
+ file_priv->cmdq[cmdq_idx] = cmdq;
}
- if (cmdq->db_registered)
- return cmdq;
-
- ret = ivpu_jsm_register_db(vdev, file_priv->ctx.id, cmdq->db_id,
- cmdq->mem->vpu_addr, ivpu_bo_size(cmdq->mem));
+ ret = ivpu_cmdq_init(file_priv, cmdq, engine, priority);
if (ret)
return NULL;
- cmdq->db_registered = true;
-
return cmdq;
}
-static void ivpu_cmdq_release_locked(struct ivpu_file_priv *file_priv, u16 engine)
+static void ivpu_cmdq_release_locked(struct ivpu_file_priv *file_priv, u16 engine, u8 priority)
{
- struct ivpu_cmdq *cmdq = file_priv->cmdq[engine];
+ int cmdq_idx = IVPU_CMDQ_INDEX(engine, priority);
+ struct ivpu_cmdq *cmdq = file_priv->cmdq[cmdq_idx];
lockdep_assert_held(&file_priv->lock);
if (cmdq) {
- file_priv->cmdq[engine] = NULL;
- if (cmdq->db_registered)
- ivpu_jsm_unregister_db(file_priv->vdev, cmdq->db_id);
-
+ file_priv->cmdq[cmdq_idx] = NULL;
+ ivpu_cmdq_fini(file_priv, cmdq);
ivpu_cmdq_free(file_priv, cmdq);
}
}
void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv)
{
- int i;
+ u16 engine;
+ u8 priority;
lockdep_assert_held(&file_priv->lock);
- for (i = 0; i < IVPU_NUM_ENGINES; i++)
- ivpu_cmdq_release_locked(file_priv, i);
+ for (engine = 0; engine < IVPU_NUM_ENGINES; engine++)
+ for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++)
+ ivpu_cmdq_release_locked(file_priv, engine, priority);
}
/*
- * Mark the doorbell as unregistered and reset job queue pointers.
+ * Mark the doorbell as unregistered
* This function needs to be called when the VPU hardware is restarted
* and FW loses job queue state. The next time job queue is used it
* will be registered again.
*/
-static void ivpu_cmdq_reset_locked(struct ivpu_file_priv *file_priv, u16 engine)
-{
- struct ivpu_cmdq *cmdq = file_priv->cmdq[engine];
-
- lockdep_assert_held(&file_priv->lock);
-
- if (cmdq) {
- cmdq->db_registered = false;
- cmdq->jobq->header.head = 0;
- cmdq->jobq->header.tail = 0;
- wmb(); /* Flush WC buffer for jobq header */
- }
-}
-
-static void ivpu_cmdq_reset_all(struct ivpu_file_priv *file_priv)
+static void ivpu_cmdq_reset(struct ivpu_file_priv *file_priv)
{
- int i;
+ u16 engine;
+ u8 priority;
mutex_lock(&file_priv->lock);
- for (i = 0; i < IVPU_NUM_ENGINES; i++)
- ivpu_cmdq_reset_locked(file_priv, i);
+ for (engine = 0; engine < IVPU_NUM_ENGINES; engine++) {
+ for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) {
+ int cmdq_idx = IVPU_CMDQ_INDEX(engine, priority);
+ struct ivpu_cmdq *cmdq = file_priv->cmdq[cmdq_idx];
+
+ if (cmdq)
+ cmdq->db_registered = false;
+ }
+ }
mutex_unlock(&file_priv->lock);
}
@@ -172,10 +307,36 @@ void ivpu_cmdq_reset_all_contexts(struct ivpu_device *vdev)
mutex_lock(&vdev->context_list_lock);
xa_for_each(&vdev->context_xa, ctx_id, file_priv)
- ivpu_cmdq_reset_all(file_priv);
+ ivpu_cmdq_reset(file_priv);
mutex_unlock(&vdev->context_list_lock);
+}
+
+static void ivpu_cmdq_fini_all(struct ivpu_file_priv *file_priv)
+{
+ u16 engine;
+ u8 priority;
+
+ for (engine = 0; engine < IVPU_NUM_ENGINES; engine++) {
+ for (priority = 0; priority < IVPU_NUM_PRIORITIES; priority++) {
+ int cmdq_idx = IVPU_CMDQ_INDEX(engine, priority);
+
+ if (file_priv->cmdq[cmdq_idx])
+ ivpu_cmdq_fini(file_priv, file_priv->cmdq[cmdq_idx]);
+ }
+ }
+}
+void ivpu_context_abort_locked(struct ivpu_file_priv *file_priv)
+{
+ struct ivpu_device *vdev = file_priv->vdev;
+
+ lockdep_assert_held(&file_priv->lock);
+
+ ivpu_cmdq_fini_all(file_priv);
+
+ if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_OS)
+ ivpu_jsm_context_release(vdev, file_priv->ctx.id);
}
static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job)
@@ -199,6 +360,15 @@ static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job)
entry->flags = 0;
if (unlikely(ivpu_test_mode & IVPU_TEST_MODE_NULL_SUBMISSION))
entry->flags = VPU_JOB_FLAGS_NULL_SUBMISSION_MASK;
+
+ if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW &&
+ (unlikely(!(ivpu_test_mode & IVPU_TEST_MODE_PREEMPTION_DISABLE)))) {
+ entry->primary_preempt_buf_addr = cmdq->primary_preempt_buf->vpu_addr;
+ entry->primary_preempt_buf_size = ivpu_bo_size(cmdq->primary_preempt_buf);
+ entry->secondary_preempt_buf_addr = cmdq->secondary_preempt_buf->vpu_addr;
+ entry->secondary_preempt_buf_size = ivpu_bo_size(cmdq->secondary_preempt_buf);
+ }
+
wmb(); /* Ensure that tail is updated after filling entry */
header->tail = next_entry;
wmb(); /* Flush WC buffer for jobq header */
@@ -295,11 +465,28 @@ err_free_job:
return NULL;
}
+static struct ivpu_job *ivpu_job_remove_from_submitted_jobs(struct ivpu_device *vdev, u32 job_id)
+{
+ struct ivpu_job *job;
+
+ xa_lock(&vdev->submitted_jobs_xa);
+ job = __xa_erase(&vdev->submitted_jobs_xa, job_id);
+
+ if (xa_empty(&vdev->submitted_jobs_xa) && job) {
+ vdev->busy_time = ktime_add(ktime_sub(ktime_get(), vdev->busy_start_ts),
+ vdev->busy_time);
+ }
+
+ xa_unlock(&vdev->submitted_jobs_xa);
+
+ return job;
+}
+
static int ivpu_job_signal_and_destroy(struct ivpu_device *vdev, u32 job_id, u32 job_status)
{
struct ivpu_job *job;
- job = xa_erase(&vdev->submitted_jobs_xa, job_id);
+ job = ivpu_job_remove_from_submitted_jobs(vdev, job_id);
if (!job)
return -ENOENT;
@@ -328,12 +515,13 @@ void ivpu_jobs_abort_all(struct ivpu_device *vdev)
ivpu_job_signal_and_destroy(vdev, id, DRM_IVPU_JOB_STATUS_ABORTED);
}
-static int ivpu_job_submit(struct ivpu_job *job)
+static int ivpu_job_submit(struct ivpu_job *job, u8 priority)
{
struct ivpu_file_priv *file_priv = job->file_priv;
struct ivpu_device *vdev = job->vdev;
struct xa_limit job_id_range;
struct ivpu_cmdq *cmdq;
+ bool is_first_job;
int ret;
ret = ivpu_rpm_get(vdev);
@@ -342,10 +530,10 @@ static int ivpu_job_submit(struct ivpu_job *job)
mutex_lock(&file_priv->lock);
- cmdq = ivpu_cmdq_acquire(job->file_priv, job->engine_idx);
+ cmdq = ivpu_cmdq_acquire(job->file_priv, job->engine_idx, priority);
if (!cmdq) {
- ivpu_warn_ratelimited(vdev, "Failed get job queue, ctx %d engine %d\n",
- file_priv->ctx.id, job->engine_idx);
+ ivpu_warn_ratelimited(vdev, "Failed to get job queue, ctx %d engine %d prio %d\n",
+ file_priv->ctx.id, job->engine_idx, priority);
ret = -EINVAL;
goto err_unlock_file_priv;
}
@@ -354,6 +542,7 @@ static int ivpu_job_submit(struct ivpu_job *job)
job_id_range.max = job_id_range.min | JOB_ID_JOB_MASK;
xa_lock(&vdev->submitted_jobs_xa);
+ is_first_job = xa_empty(&vdev->submitted_jobs_xa);
ret = __xa_alloc(&vdev->submitted_jobs_xa, &job->job_id, job, job_id_range, GFP_KERNEL);
if (ret) {
ivpu_dbg(vdev, JOB, "Too many active jobs in ctx %d\n",
@@ -373,10 +562,12 @@ static int ivpu_job_submit(struct ivpu_job *job)
wmb(); /* Flush WC buffer for jobq header */
} else {
ivpu_cmdq_ring_db(vdev, cmdq);
+ if (is_first_job)
+ vdev->busy_start_ts = ktime_get();
}
- ivpu_dbg(vdev, JOB, "Job submitted: id %3u ctx %2d engine %d addr 0x%llx next %d\n",
- job->job_id, file_priv->ctx.id, job->engine_idx,
+ ivpu_dbg(vdev, JOB, "Job submitted: id %3u ctx %2d engine %d prio %d addr 0x%llx next %d\n",
+ job->job_id, file_priv->ctx.id, job->engine_idx, priority,
job->cmd_buf_vpu_addr, cmdq->jobq->header.tail);
xa_unlock(&vdev->submitted_jobs_xa);
@@ -464,6 +655,14 @@ unlock_reservations:
return ret;
}
+static inline u8 ivpu_job_to_hws_priority(struct ivpu_file_priv *file_priv, u8 priority)
+{
+ if (priority == DRM_IVPU_JOB_PRIORITY_DEFAULT)
+ return DRM_IVPU_JOB_PRIORITY_NORMAL;
+
+ return priority - 1;
+}
+
int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
{
struct ivpu_file_priv *file_priv = file->driver_priv;
@@ -472,6 +671,7 @@ int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
struct ivpu_job *job;
u32 *buf_handles;
int idx, ret;
+ u8 priority;
if (params->engine > DRM_IVPU_ENGINE_COPY)
return -EINVAL;
@@ -525,8 +725,10 @@ int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
goto err_destroy_job;
}
+ priority = ivpu_job_to_hws_priority(file_priv, params->priority);
+
down_read(&vdev->pm->reset_lock);
- ret = ivpu_job_submit(job);
+ ret = ivpu_job_submit(job, priority);
up_read(&vdev->pm->reset_lock);
if (ret)
goto err_signal_fence;
diff --git a/drivers/accel/ivpu/ivpu_job.h b/drivers/accel/ivpu/ivpu_job.h
index ca4984071cc7..6accb94028c7 100644
--- a/drivers/accel/ivpu/ivpu_job.h
+++ b/drivers/accel/ivpu/ivpu_job.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (C) 2020-2023 Intel Corporation
+ * Copyright (C) 2020-2024 Intel Corporation
*/
#ifndef __IVPU_JOB_H__
@@ -24,6 +24,8 @@ struct ivpu_file_priv;
*/
struct ivpu_cmdq {
struct vpu_job_queue *jobq;
+ struct ivpu_bo *primary_preempt_buf;
+ struct ivpu_bo *secondary_preempt_buf;
struct ivpu_bo *mem;
u32 entry_count;
u32 db_id;
@@ -55,6 +57,8 @@ struct ivpu_job {
int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
+void ivpu_context_abort_locked(struct ivpu_file_priv *file_priv);
+
void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv);
void ivpu_cmdq_reset_all_contexts(struct ivpu_device *vdev);
diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.c b/drivers/accel/ivpu/ivpu_jsm_msg.c
index 8cea0dd731b9..46ef16c3c069 100644
--- a/drivers/accel/ivpu/ivpu_jsm_msg.c
+++ b/drivers/accel/ivpu/ivpu_jsm_msg.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2020-2023 Intel Corporation
+ * Copyright (C) 2020-2024 Intel Corporation
*/
#include "ivpu_drv.h"
@@ -103,14 +103,10 @@ int ivpu_jsm_register_db(struct ivpu_device *vdev, u32 ctx_id, u32 db_id,
ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_REGISTER_DB_DONE, &resp,
VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
- if (ret) {
- ivpu_err_ratelimited(vdev, "Failed to register doorbell %d: %d\n", db_id, ret);
- return ret;
- }
-
- ivpu_dbg(vdev, JSM, "Doorbell %d registered to context %d\n", db_id, ctx_id);
+ if (ret)
+ ivpu_err_ratelimited(vdev, "Failed to register doorbell %u: %d\n", db_id, ret);
- return 0;
+ return ret;
}
int ivpu_jsm_unregister_db(struct ivpu_device *vdev, u32 db_id)
@@ -123,14 +119,10 @@ int ivpu_jsm_unregister_db(struct ivpu_device *vdev, u32 db_id)
ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_UNREGISTER_DB_DONE, &resp,
VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
- if (ret) {
- ivpu_warn_ratelimited(vdev, "Failed to unregister doorbell %d: %d\n", db_id, ret);
- return ret;
- }
-
- ivpu_dbg(vdev, JSM, "Doorbell %d unregistered\n", db_id);
+ if (ret)
+ ivpu_warn_ratelimited(vdev, "Failed to unregister doorbell %u: %d\n", db_id, ret);
- return 0;
+ return ret;
}
int ivpu_jsm_get_heartbeat(struct ivpu_device *vdev, u32 engine, u64 *heartbeat)
@@ -255,11 +247,16 @@ int ivpu_jsm_context_release(struct ivpu_device *vdev, u32 host_ssid)
{
struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_SSID_RELEASE };
struct vpu_jsm_msg resp;
+ int ret;
req.payload.ssid_release.host_ssid = host_ssid;
- return ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_SSID_RELEASE_DONE, &resp,
- VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
+ ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_SSID_RELEASE_DONE, &resp,
+ VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
+ if (ret)
+ ivpu_warn_ratelimited(vdev, "Failed to release context: %d\n", ret);
+
+ return ret;
}
int ivpu_jsm_pwr_d0i3_enter(struct ivpu_device *vdev)
@@ -281,3 +278,283 @@ int ivpu_jsm_pwr_d0i3_enter(struct ivpu_device *vdev)
return ivpu_hw_wait_for_idle(vdev);
}
+
+int ivpu_jsm_hws_create_cmdq(struct ivpu_device *vdev, u32 ctx_id, u32 cmdq_group, u32 cmdq_id,
+ u32 pid, u32 engine, u64 cmdq_base, u32 cmdq_size)
+{
+ struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_CREATE_CMD_QUEUE };
+ struct vpu_jsm_msg resp;
+ int ret;
+
+ req.payload.hws_create_cmdq.host_ssid = ctx_id;
+ req.payload.hws_create_cmdq.process_id = pid;
+ req.payload.hws_create_cmdq.engine_idx = engine;
+ req.payload.hws_create_cmdq.cmdq_group = cmdq_group;
+ req.payload.hws_create_cmdq.cmdq_id = cmdq_id;
+ req.payload.hws_create_cmdq.cmdq_base = cmdq_base;
+ req.payload.hws_create_cmdq.cmdq_size = cmdq_size;
+
+ ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_CREATE_CMD_QUEUE_RSP, &resp,
+ VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
+ if (ret)
+ ivpu_warn_ratelimited(vdev, "Failed to create command queue: %d\n", ret);
+
+ return ret;
+}
+
+int ivpu_jsm_hws_destroy_cmdq(struct ivpu_device *vdev, u32 ctx_id, u32 cmdq_id)
+{
+ struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_DESTROY_CMD_QUEUE };
+ struct vpu_jsm_msg resp;
+ int ret;
+
+ req.payload.hws_destroy_cmdq.host_ssid = ctx_id;
+ req.payload.hws_destroy_cmdq.cmdq_id = cmdq_id;
+
+ ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_DESTROY_CMD_QUEUE_RSP, &resp,
+ VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
+ if (ret)
+ ivpu_warn_ratelimited(vdev, "Failed to destroy command queue: %d\n", ret);
+
+ return ret;
+}
+
+int ivpu_jsm_hws_register_db(struct ivpu_device *vdev, u32 ctx_id, u32 cmdq_id, u32 db_id,
+ u64 cmdq_base, u32 cmdq_size)
+{
+ struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_HWS_REGISTER_DB };
+ struct vpu_jsm_msg resp;
+ int ret = 0;
+
+ req.payload.hws_register_db.db_id = db_id;
+ req.payload.hws_register_db.host_ssid = ctx_id;
+ req.payload.hws_register_db.cmdq_id = cmdq_id;
+ req.payload.hws_register_db.cmdq_base = cmdq_base;
+ req.payload.hws_register_db.cmdq_size = cmdq_size;
+
+ ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_REGISTER_DB_DONE, &resp,
+ VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
+ if (ret)
+ ivpu_err_ratelimited(vdev, "Failed to register doorbell %u: %d\n", db_id, ret);
+
+ return ret;
+}
+
+int ivpu_jsm_hws_resume_engine(struct ivpu_device *vdev, u32 engine)
+{
+ struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_HWS_ENGINE_RESUME };
+ struct vpu_jsm_msg resp;
+ int ret;
+
+ if (engine >= VPU_ENGINE_NB)
+ return -EINVAL;
+
+ req.payload.hws_resume_engine.engine_idx = engine;
+
+ ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_HWS_RESUME_ENGINE_DONE, &resp,
+ VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
+ if (ret)
+ ivpu_err_ratelimited(vdev, "Failed to resume engine %d: %d\n", engine, ret);
+
+ return ret;
+}
+
+int ivpu_jsm_hws_set_context_sched_properties(struct ivpu_device *vdev, u32 ctx_id, u32 cmdq_id,
+ u32 priority)
+{
+ struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_SET_CONTEXT_SCHED_PROPERTIES };
+ struct vpu_jsm_msg resp;
+ int ret;
+
+ req.payload.hws_set_context_sched_properties.host_ssid = ctx_id;
+ req.payload.hws_set_context_sched_properties.cmdq_id = cmdq_id;
+ req.payload.hws_set_context_sched_properties.priority_band = priority;
+ req.payload.hws_set_context_sched_properties.realtime_priority_level = 0;
+ req.payload.hws_set_context_sched_properties.in_process_priority = 0;
+ req.payload.hws_set_context_sched_properties.context_quantum = 20000;
+ req.payload.hws_set_context_sched_properties.grace_period_same_priority = 10000;
+ req.payload.hws_set_context_sched_properties.grace_period_lower_priority = 0;
+
+ ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_SET_CONTEXT_SCHED_PROPERTIES_RSP, &resp,
+ VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
+ if (ret)
+ ivpu_warn_ratelimited(vdev, "Failed to set context sched properties: %d\n", ret);
+
+ return ret;
+}
+
+int ivpu_jsm_hws_set_scheduling_log(struct ivpu_device *vdev, u32 engine_idx, u32 host_ssid,
+ u64 vpu_log_buffer_va)
+{
+ struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_HWS_SET_SCHEDULING_LOG };
+ struct vpu_jsm_msg resp;
+ int ret;
+
+ req.payload.hws_set_scheduling_log.engine_idx = engine_idx;
+ req.payload.hws_set_scheduling_log.host_ssid = host_ssid;
+ req.payload.hws_set_scheduling_log.vpu_log_buffer_va = vpu_log_buffer_va;
+ req.payload.hws_set_scheduling_log.notify_index = 0;
+ req.payload.hws_set_scheduling_log.enable_extra_events =
+ ivpu_test_mode & IVPU_TEST_MODE_HWS_EXTRA_EVENTS;
+
+ ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_HWS_SET_SCHEDULING_LOG_RSP, &resp,
+ VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
+ if (ret)
+ ivpu_warn_ratelimited(vdev, "Failed to set scheduling log: %d\n", ret);
+
+ return ret;
+}
+
+int ivpu_jsm_hws_setup_priority_bands(struct ivpu_device *vdev)
+{
+ struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_SET_PRIORITY_BAND_SETUP };
+ struct vpu_jsm_msg resp;
+ int ret;
+
+ /* Idle */
+ req.payload.hws_priority_band_setup.grace_period[0] = 0;
+ req.payload.hws_priority_band_setup.process_grace_period[0] = 50000;
+ req.payload.hws_priority_band_setup.process_quantum[0] = 160000;
+ /* Normal */
+ req.payload.hws_priority_band_setup.grace_period[1] = 50000;
+ req.payload.hws_priority_band_setup.process_grace_period[1] = 50000;
+ req.payload.hws_priority_band_setup.process_quantum[1] = 300000;
+ /* Focus */
+ req.payload.hws_priority_band_setup.grace_period[2] = 50000;
+ req.payload.hws_priority_band_setup.process_grace_period[2] = 50000;
+ req.payload.hws_priority_band_setup.process_quantum[2] = 200000;
+ /* Realtime */
+ req.payload.hws_priority_band_setup.grace_period[3] = 0;
+ req.payload.hws_priority_band_setup.process_grace_period[3] = 50000;
+ req.payload.hws_priority_band_setup.process_quantum[3] = 200000;
+
+ req.payload.hws_priority_band_setup.normal_band_percentage = 10;
+
+ ret = ivpu_ipc_send_receive_active(vdev, &req, VPU_JSM_MSG_SET_PRIORITY_BAND_SETUP_RSP,
+ &resp, VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
+ if (ret)
+ ivpu_warn_ratelimited(vdev, "Failed to set priority bands: %d\n", ret);
+
+ return ret;
+}
+
+int ivpu_jsm_metric_streamer_start(struct ivpu_device *vdev, u64 metric_group_mask,
+ u64 sampling_rate, u64 buffer_addr, u64 buffer_size)
+{
+ struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_METRIC_STREAMER_START };
+ struct vpu_jsm_msg resp;
+ int ret;
+
+ req.payload.metric_streamer_start.metric_group_mask = metric_group_mask;
+ req.payload.metric_streamer_start.sampling_rate = sampling_rate;
+ req.payload.metric_streamer_start.buffer_addr = buffer_addr;
+ req.payload.metric_streamer_start.buffer_size = buffer_size;
+
+ ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_METRIC_STREAMER_START_DONE, &resp,
+ VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
+ if (ret) {
+ ivpu_warn_ratelimited(vdev, "Failed to start metric streamer: ret %d\n", ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+int ivpu_jsm_metric_streamer_stop(struct ivpu_device *vdev, u64 metric_group_mask)
+{
+ struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_METRIC_STREAMER_STOP };
+ struct vpu_jsm_msg resp;
+ int ret;
+
+ req.payload.metric_streamer_stop.metric_group_mask = metric_group_mask;
+
+ ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_METRIC_STREAMER_STOP_DONE, &resp,
+ VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
+ if (ret)
+ ivpu_warn_ratelimited(vdev, "Failed to stop metric streamer: ret %d\n", ret);
+
+ return ret;
+}
+
+int ivpu_jsm_metric_streamer_update(struct ivpu_device *vdev, u64 metric_group_mask,
+ u64 buffer_addr, u64 buffer_size, u64 *bytes_written)
+{
+ struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_METRIC_STREAMER_UPDATE };
+ struct vpu_jsm_msg resp;
+ int ret;
+
+ req.payload.metric_streamer_update.metric_group_mask = metric_group_mask;
+ req.payload.metric_streamer_update.buffer_addr = buffer_addr;
+ req.payload.metric_streamer_update.buffer_size = buffer_size;
+
+ ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_METRIC_STREAMER_UPDATE_DONE, &resp,
+ VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
+ if (ret) {
+ ivpu_warn_ratelimited(vdev, "Failed to update metric streamer: ret %d\n", ret);
+ return ret;
+ }
+
+ if (buffer_size && resp.payload.metric_streamer_done.bytes_written > buffer_size) {
+ ivpu_warn_ratelimited(vdev, "MS buffer overflow: bytes_written %#llx > buffer_size %#llx\n",
+ resp.payload.metric_streamer_done.bytes_written, buffer_size);
+ return -EOVERFLOW;
+ }
+
+ *bytes_written = resp.payload.metric_streamer_done.bytes_written;
+
+ return ret;
+}
+
+int ivpu_jsm_metric_streamer_info(struct ivpu_device *vdev, u64 metric_group_mask, u64 buffer_addr,
+ u64 buffer_size, u32 *sample_size, u64 *info_size)
+{
+ struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_METRIC_STREAMER_INFO };
+ struct vpu_jsm_msg resp;
+ int ret;
+
+ req.payload.metric_streamer_start.metric_group_mask = metric_group_mask;
+ req.payload.metric_streamer_start.buffer_addr = buffer_addr;
+ req.payload.metric_streamer_start.buffer_size = buffer_size;
+
+ ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_METRIC_STREAMER_INFO_DONE, &resp,
+ VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
+ if (ret) {
+ ivpu_warn_ratelimited(vdev, "Failed to get metric streamer info: ret %d\n", ret);
+ return ret;
+ }
+
+ if (!resp.payload.metric_streamer_done.sample_size) {
+ ivpu_warn_ratelimited(vdev, "Invalid sample size\n");
+ return -EBADMSG;
+ }
+
+ if (sample_size)
+ *sample_size = resp.payload.metric_streamer_done.sample_size;
+ if (info_size)
+ *info_size = resp.payload.metric_streamer_done.bytes_written;
+
+ return ret;
+}
+
+int ivpu_jsm_dct_enable(struct ivpu_device *vdev, u32 active_us, u32 inactive_us)
+{
+ struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_DCT_ENABLE };
+ struct vpu_jsm_msg resp;
+
+ req.payload.pwr_dct_control.dct_active_us = active_us;
+ req.payload.pwr_dct_control.dct_inactive_us = inactive_us;
+
+ return ivpu_ipc_send_receive_active(vdev, &req, VPU_JSM_MSG_DCT_ENABLE_DONE,
+ &resp, VPU_IPC_CHAN_ASYNC_CMD,
+ vdev->timeout.jsm);
+}
+
+int ivpu_jsm_dct_disable(struct ivpu_device *vdev)
+{
+ struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_DCT_DISABLE };
+ struct vpu_jsm_msg resp;
+
+ return ivpu_ipc_send_receive_active(vdev, &req, VPU_JSM_MSG_DCT_DISABLE_DONE,
+ &resp, VPU_IPC_CHAN_ASYNC_CMD,
+ vdev->timeout.jsm);
+}
diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.h b/drivers/accel/ivpu/ivpu_jsm_msg.h
index ae75e5dbcc41..e4e42c0ff6e6 100644
--- a/drivers/accel/ivpu/ivpu_jsm_msg.h
+++ b/drivers/accel/ivpu/ivpu_jsm_msg.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (C) 2020-2023 Intel Corporation
+ * Copyright (C) 2020-2024 Intel Corporation
*/
#ifndef __IVPU_JSM_MSG_H__
@@ -23,4 +23,24 @@ int ivpu_jsm_trace_set_config(struct ivpu_device *vdev, u32 trace_level, u32 tra
u64 trace_hw_component_mask);
int ivpu_jsm_context_release(struct ivpu_device *vdev, u32 host_ssid);
int ivpu_jsm_pwr_d0i3_enter(struct ivpu_device *vdev);
+int ivpu_jsm_hws_create_cmdq(struct ivpu_device *vdev, u32 ctx_id, u32 cmdq_group, u32 cmdq_id,
+ u32 pid, u32 engine, u64 cmdq_base, u32 cmdq_size);
+int ivpu_jsm_hws_destroy_cmdq(struct ivpu_device *vdev, u32 ctx_id, u32 cmdq_id);
+int ivpu_jsm_hws_register_db(struct ivpu_device *vdev, u32 ctx_id, u32 cmdq_id, u32 db_id,
+ u64 cmdq_base, u32 cmdq_size);
+int ivpu_jsm_hws_resume_engine(struct ivpu_device *vdev, u32 engine);
+int ivpu_jsm_hws_set_context_sched_properties(struct ivpu_device *vdev, u32 ctx_id, u32 cmdq_id,
+ u32 priority);
+int ivpu_jsm_hws_set_scheduling_log(struct ivpu_device *vdev, u32 engine_idx, u32 host_ssid,
+ u64 vpu_log_buffer_va);
+int ivpu_jsm_hws_setup_priority_bands(struct ivpu_device *vdev);
+int ivpu_jsm_metric_streamer_start(struct ivpu_device *vdev, u64 metric_group_mask,
+ u64 sampling_rate, u64 buffer_addr, u64 buffer_size);
+int ivpu_jsm_metric_streamer_stop(struct ivpu_device *vdev, u64 metric_group_mask);
+int ivpu_jsm_metric_streamer_update(struct ivpu_device *vdev, u64 metric_group_mask,
+ u64 buffer_addr, u64 buffer_size, u64 *bytes_written);
+int ivpu_jsm_metric_streamer_info(struct ivpu_device *vdev, u64 metric_group_mask, u64 buffer_addr,
+ u64 buffer_size, u32 *sample_size, u64 *info_size);
+int ivpu_jsm_dct_enable(struct ivpu_device *vdev, u32 active_us, u32 inactive_us);
+int ivpu_jsm_dct_disable(struct ivpu_device *vdev);
#endif
diff --git a/drivers/accel/ivpu/ivpu_mmu.c b/drivers/accel/ivpu/ivpu_mmu.c
index 2e46b322c450..c078e214b221 100644
--- a/drivers/accel/ivpu/ivpu_mmu.c
+++ b/drivers/accel/ivpu/ivpu_mmu.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2020-2023 Intel Corporation
+ * Copyright (C) 2020-2024 Intel Corporation
*/
#include <linux/circ_buf.h>
@@ -519,7 +519,8 @@ static int ivpu_mmu_cmdq_sync(struct ivpu_device *vdev)
if (ret)
return ret;
- clflush_cache_range(q->base, IVPU_MMU_CMDQ_SIZE);
+ if (!ivpu_is_force_snoop_enabled(vdev))
+ clflush_cache_range(q->base, IVPU_MMU_CMDQ_SIZE);
REGV_WR32(IVPU_MMU_REG_CMDQ_PROD, q->prod);
ret = ivpu_mmu_cmdq_wait_for_cons(vdev);
@@ -567,7 +568,8 @@ static int ivpu_mmu_reset(struct ivpu_device *vdev)
int ret;
memset(mmu->cmdq.base, 0, IVPU_MMU_CMDQ_SIZE);
- clflush_cache_range(mmu->cmdq.base, IVPU_MMU_CMDQ_SIZE);
+ if (!ivpu_is_force_snoop_enabled(vdev))
+ clflush_cache_range(mmu->cmdq.base, IVPU_MMU_CMDQ_SIZE);
mmu->cmdq.prod = 0;
mmu->cmdq.cons = 0;
@@ -661,7 +663,8 @@ static void ivpu_mmu_strtab_link_cd(struct ivpu_device *vdev, u32 sid)
WRITE_ONCE(entry[1], str[1]);
WRITE_ONCE(entry[0], str[0]);
- clflush_cache_range(entry, IVPU_MMU_STRTAB_ENT_SIZE);
+ if (!ivpu_is_force_snoop_enabled(vdev))
+ clflush_cache_range(entry, IVPU_MMU_STRTAB_ENT_SIZE);
ivpu_dbg(vdev, MMU, "STRTAB write entry (SSID=%u): 0x%llx, 0x%llx\n", sid, str[0], str[1]);
}
@@ -735,7 +738,8 @@ static int ivpu_mmu_cd_add(struct ivpu_device *vdev, u32 ssid, u64 cd_dma)
WRITE_ONCE(entry[3], cd[3]);
WRITE_ONCE(entry[0], cd[0]);
- clflush_cache_range(entry, IVPU_MMU_CDTAB_ENT_SIZE);
+ if (!ivpu_is_force_snoop_enabled(vdev))
+ clflush_cache_range(entry, IVPU_MMU_CDTAB_ENT_SIZE);
ivpu_dbg(vdev, MMU, "CDTAB %s entry (SSID=%u, dma=%pad): 0x%llx, 0x%llx, 0x%llx, 0x%llx\n",
cd_dma ? "write" : "clear", ssid, &cd_dma, cd[0], cd[1], cd[2], cd[3]);
@@ -874,8 +878,9 @@ static void ivpu_mmu_dump_event(struct ivpu_device *vdev, u32 *event)
u64 in_addr = ((u64)event[5]) << 32 | event[4];
u32 sid = event[1];
- ivpu_err(vdev, "MMU EVTQ: 0x%x (%s) SSID: %d SID: %d, e[2] %08x, e[3] %08x, in addr: 0x%llx, fetch addr: 0x%llx\n",
- op, ivpu_mmu_event_to_str(op), ssid, sid, event[2], event[3], in_addr, fetch_addr);
+ ivpu_err_ratelimited(vdev, "MMU EVTQ: 0x%x (%s) SSID: %d SID: %d, e[2] %08x, e[3] %08x, in addr: 0x%llx, fetch addr: 0x%llx\n",
+ op, ivpu_mmu_event_to_str(op), ssid, sid,
+ event[2], event[3], in_addr, fetch_addr);
}
static u32 *ivpu_mmu_get_event(struct ivpu_device *vdev)
@@ -911,6 +916,9 @@ void ivpu_mmu_irq_evtq_handler(struct ivpu_device *vdev)
ivpu_mmu_user_context_mark_invalid(vdev, ssid);
REGV_WR32(IVPU_MMU_REG_EVTQ_CONS_SEC, vdev->mmu->evtq.cons);
}
+
+ if (!kfifo_put(&vdev->hw->irq.fifo, IVPU_HW_IRQ_SRC_MMU_EVTQ))
+ ivpu_err_ratelimited(vdev, "IRQ FIFO full\n");
}
void ivpu_mmu_evtq_dump(struct ivpu_device *vdev)
diff --git a/drivers/accel/ivpu/ivpu_mmu_context.c b/drivers/accel/ivpu/ivpu_mmu_context.c
index 128aef8e5a19..bbe652a7019d 100644
--- a/drivers/accel/ivpu/ivpu_mmu_context.c
+++ b/drivers/accel/ivpu/ivpu_mmu_context.c
@@ -24,6 +24,7 @@
#define IVPU_MMU_ENTRY_FLAG_CONT BIT(52)
#define IVPU_MMU_ENTRY_FLAG_NG BIT(11)
#define IVPU_MMU_ENTRY_FLAG_AF BIT(10)
+#define IVPU_MMU_ENTRY_FLAG_RO BIT(7)
#define IVPU_MMU_ENTRY_FLAG_USER BIT(6)
#define IVPU_MMU_ENTRY_FLAG_LLC_COHERENT BIT(2)
#define IVPU_MMU_ENTRY_FLAG_TYPE_PAGE BIT(1)
@@ -319,6 +320,91 @@ ivpu_mmu_context_map_pages(struct ivpu_device *vdev, struct ivpu_mmu_context *ct
return 0;
}
+static void ivpu_mmu_context_set_page_ro(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx,
+ u64 vpu_addr)
+{
+ int pgd_idx = FIELD_GET(IVPU_MMU_PGD_INDEX_MASK, vpu_addr);
+ int pud_idx = FIELD_GET(IVPU_MMU_PUD_INDEX_MASK, vpu_addr);
+ int pmd_idx = FIELD_GET(IVPU_MMU_PMD_INDEX_MASK, vpu_addr);
+ int pte_idx = FIELD_GET(IVPU_MMU_PTE_INDEX_MASK, vpu_addr);
+
+ ctx->pgtable.pte_ptrs[pgd_idx][pud_idx][pmd_idx][pte_idx] |= IVPU_MMU_ENTRY_FLAG_RO;
+}
+
+static void ivpu_mmu_context_split_page(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx,
+ u64 vpu_addr)
+{
+ int pgd_idx = FIELD_GET(IVPU_MMU_PGD_INDEX_MASK, vpu_addr);
+ int pud_idx = FIELD_GET(IVPU_MMU_PUD_INDEX_MASK, vpu_addr);
+ int pmd_idx = FIELD_GET(IVPU_MMU_PMD_INDEX_MASK, vpu_addr);
+ int pte_idx = FIELD_GET(IVPU_MMU_PTE_INDEX_MASK, vpu_addr);
+
+ ctx->pgtable.pte_ptrs[pgd_idx][pud_idx][pmd_idx][pte_idx] &= ~IVPU_MMU_ENTRY_FLAG_CONT;
+}
+
+static void ivpu_mmu_context_split_64k_page(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx,
+ u64 vpu_addr)
+{
+ u64 start = ALIGN_DOWN(vpu_addr, IVPU_MMU_CONT_PAGES_SIZE);
+ u64 end = ALIGN(vpu_addr, IVPU_MMU_CONT_PAGES_SIZE);
+ u64 offset = 0;
+
+ ivpu_dbg(vdev, MMU_MAP, "Split 64K page ctx: %u vpu_addr: 0x%llx\n", ctx->id, vpu_addr);
+
+ while (start + offset < end) {
+ ivpu_mmu_context_split_page(vdev, ctx, start + offset);
+ offset += IVPU_MMU_PAGE_SIZE;
+ }
+}
+
+int
+ivpu_mmu_context_set_pages_ro(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, u64 vpu_addr,
+ size_t size)
+{
+ u64 end = vpu_addr + size;
+ size_t size_left = size;
+ int ret;
+
+ if (size == 0)
+ return 0;
+
+ if (drm_WARN_ON(&vdev->drm, !IS_ALIGNED(vpu_addr | size, IVPU_MMU_PAGE_SIZE)))
+ return -EINVAL;
+
+ mutex_lock(&ctx->lock);
+
+ ivpu_dbg(vdev, MMU_MAP, "Set read-only pages ctx: %u vpu_addr: 0x%llx size: %lu\n",
+ ctx->id, vpu_addr, size);
+
+ if (!ivpu_disable_mmu_cont_pages) {
+ /* Split 64K contiguous page at the beginning if needed */
+ if (!IS_ALIGNED(vpu_addr, IVPU_MMU_CONT_PAGES_SIZE))
+ ivpu_mmu_context_split_64k_page(vdev, ctx, vpu_addr);
+
+ /* Split 64K contiguous page at the end if needed */
+ if (!IS_ALIGNED(vpu_addr + size, IVPU_MMU_CONT_PAGES_SIZE))
+ ivpu_mmu_context_split_64k_page(vdev, ctx, vpu_addr + size);
+ }
+
+ while (size_left) {
+ if (vpu_addr < end)
+ ivpu_mmu_context_set_page_ro(vdev, ctx, vpu_addr);
+
+ vpu_addr += IVPU_MMU_PAGE_SIZE;
+ size_left -= IVPU_MMU_PAGE_SIZE;
+ }
+
+ /* Ensure page table modifications are flushed from wc buffers to memory */
+ wmb();
+
+ mutex_unlock(&ctx->lock);
+ ret = ivpu_mmu_invalidate_tlb(vdev, ctx->id);
+ if (ret)
+ ivpu_err(vdev, "Failed to invalidate TLB for ctx %u: %d\n", ctx->id, ret);
+
+ return 0;
+}
+
static void ivpu_mmu_context_unmap_pages(struct ivpu_mmu_context *ctx, u64 vpu_addr, size_t size)
{
while (size) {
diff --git a/drivers/accel/ivpu/ivpu_mmu_context.h b/drivers/accel/ivpu/ivpu_mmu_context.h
index 535db3a1fc74..7f9aaf3d10c2 100644
--- a/drivers/accel/ivpu/ivpu_mmu_context.h
+++ b/drivers/accel/ivpu/ivpu_mmu_context.h
@@ -46,5 +46,7 @@ int ivpu_mmu_context_map_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *
u64 vpu_addr, struct sg_table *sgt, bool llc_coherent);
void ivpu_mmu_context_unmap_sgt(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx,
u64 vpu_addr, struct sg_table *sgt);
+int ivpu_mmu_context_set_pages_ro(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx,
+ u64 vpu_addr, size_t size);
#endif /* __IVPU_MMU_CONTEXT_H__ */
diff --git a/drivers/accel/ivpu/ivpu_ms.c b/drivers/accel/ivpu/ivpu_ms.c
new file mode 100644
index 000000000000..2f9d37f5c208
--- /dev/null
+++ b/drivers/accel/ivpu/ivpu_ms.c
@@ -0,0 +1,309 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2020-2024 Intel Corporation
+ */
+
+#include <drm/drm_file.h>
+
+#include "ivpu_drv.h"
+#include "ivpu_gem.h"
+#include "ivpu_jsm_msg.h"
+#include "ivpu_ms.h"
+#include "ivpu_pm.h"
+
+#define MS_INFO_BUFFER_SIZE SZ_16K
+#define MS_NUM_BUFFERS 2
+#define MS_READ_PERIOD_MULTIPLIER 2
+#define MS_MIN_SAMPLE_PERIOD_NS 1000000
+
+static struct ivpu_ms_instance *
+get_instance_by_mask(struct ivpu_file_priv *file_priv, u64 metric_mask)
+{
+ struct ivpu_ms_instance *ms;
+
+ lockdep_assert_held(&file_priv->ms_lock);
+
+ list_for_each_entry(ms, &file_priv->ms_instance_list, ms_instance_node)
+ if (ms->mask == metric_mask)
+ return ms;
+
+ return NULL;
+}
+
+int ivpu_ms_start_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
+{
+ struct ivpu_file_priv *file_priv = file->driver_priv;
+ struct drm_ivpu_metric_streamer_start *args = data;
+ struct ivpu_device *vdev = file_priv->vdev;
+ struct ivpu_ms_instance *ms;
+ u64 single_buff_size;
+ u32 sample_size;
+ int ret;
+
+ if (!args->metric_group_mask || !args->read_period_samples ||
+ args->sampling_period_ns < MS_MIN_SAMPLE_PERIOD_NS)
+ return -EINVAL;
+
+ mutex_lock(&file_priv->ms_lock);
+
+ if (get_instance_by_mask(file_priv, args->metric_group_mask)) {
+ ivpu_err(vdev, "Instance already exists (mask %#llx)\n", args->metric_group_mask);
+ ret = -EALREADY;
+ goto unlock;
+ }
+
+ ms = kzalloc(sizeof(*ms), GFP_KERNEL);
+ if (!ms) {
+ ret = -ENOMEM;
+ goto unlock;
+ }
+
+ ms->mask = args->metric_group_mask;
+
+ ret = ivpu_jsm_metric_streamer_info(vdev, ms->mask, 0, 0, &sample_size, NULL);
+ if (ret)
+ goto err_free_ms;
+
+ single_buff_size = sample_size *
+ ((u64)args->read_period_samples * MS_READ_PERIOD_MULTIPLIER);
+ ms->bo = ivpu_bo_create_global(vdev, PAGE_ALIGN(single_buff_size * MS_NUM_BUFFERS),
+ DRM_IVPU_BO_CACHED | DRM_IVPU_BO_MAPPABLE);
+ if (!ms->bo) {
+ ivpu_err(vdev, "Failed to allocate MS buffer (size %llu)\n", single_buff_size);
+ ret = -ENOMEM;
+ goto err_free_ms;
+ }
+
+ ms->buff_size = ivpu_bo_size(ms->bo) / MS_NUM_BUFFERS;
+ ms->active_buff_vpu_addr = ms->bo->vpu_addr;
+ ms->inactive_buff_vpu_addr = ms->bo->vpu_addr + ms->buff_size;
+ ms->active_buff_ptr = ivpu_bo_vaddr(ms->bo);
+ ms->inactive_buff_ptr = ivpu_bo_vaddr(ms->bo) + ms->buff_size;
+
+ ret = ivpu_jsm_metric_streamer_start(vdev, ms->mask, args->sampling_period_ns,
+ ms->active_buff_vpu_addr, ms->buff_size);
+ if (ret)
+ goto err_free_bo;
+
+ args->sample_size = sample_size;
+ args->max_data_size = ivpu_bo_size(ms->bo);
+ list_add_tail(&ms->ms_instance_node, &file_priv->ms_instance_list);
+ goto unlock;
+
+err_free_bo:
+ ivpu_bo_free(ms->bo);
+err_free_ms:
+ kfree(ms);
+unlock:
+ mutex_unlock(&file_priv->ms_lock);
+ return ret;
+}
+
+static int
+copy_leftover_bytes(struct ivpu_ms_instance *ms,
+ void __user *user_ptr, u64 user_size, u64 *user_bytes_copied)
+{
+ u64 copy_bytes;
+
+ if (ms->leftover_bytes) {
+ copy_bytes = min(user_size - *user_bytes_copied, ms->leftover_bytes);
+ if (copy_to_user(user_ptr + *user_bytes_copied, ms->leftover_addr, copy_bytes))
+ return -EFAULT;
+
+ ms->leftover_bytes -= copy_bytes;
+ ms->leftover_addr += copy_bytes;
+ *user_bytes_copied += copy_bytes;
+ }
+
+ return 0;
+}
+
+static int
+copy_samples_to_user(struct ivpu_device *vdev, struct ivpu_ms_instance *ms,
+ void __user *user_ptr, u64 user_size, u64 *user_bytes_copied)
+{
+ u64 bytes_written;
+ int ret;
+
+ *user_bytes_copied = 0;
+
+ ret = copy_leftover_bytes(ms, user_ptr, user_size, user_bytes_copied);
+ if (ret)
+ return ret;
+
+ if (*user_bytes_copied == user_size)
+ return 0;
+
+ ret = ivpu_jsm_metric_streamer_update(vdev, ms->mask, ms->inactive_buff_vpu_addr,
+ ms->buff_size, &bytes_written);
+ if (ret)
+ return ret;
+
+ swap(ms->active_buff_vpu_addr, ms->inactive_buff_vpu_addr);
+ swap(ms->active_buff_ptr, ms->inactive_buff_ptr);
+
+ ms->leftover_bytes = bytes_written;
+ ms->leftover_addr = ms->inactive_buff_ptr;
+
+ return copy_leftover_bytes(ms, user_ptr, user_size, user_bytes_copied);
+}
+
+int ivpu_ms_get_data_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
+{
+ struct drm_ivpu_metric_streamer_get_data *args = data;
+ struct ivpu_file_priv *file_priv = file->driver_priv;
+ struct ivpu_device *vdev = file_priv->vdev;
+ struct ivpu_ms_instance *ms;
+ u64 bytes_written;
+ int ret;
+
+ if (!args->metric_group_mask)
+ return -EINVAL;
+
+ mutex_lock(&file_priv->ms_lock);
+
+ ms = get_instance_by_mask(file_priv, args->metric_group_mask);
+ if (!ms) {
+ ivpu_err(vdev, "Instance doesn't exist for mask: %#llx\n", args->metric_group_mask);
+ ret = -EINVAL;
+ goto unlock;
+ }
+
+ if (!args->buffer_size) {
+ ret = ivpu_jsm_metric_streamer_update(vdev, ms->mask, 0, 0, &bytes_written);
+ if (ret)
+ goto unlock;
+ args->data_size = bytes_written + ms->leftover_bytes;
+ goto unlock;
+ }
+
+ if (!args->buffer_ptr) {
+ ret = -EINVAL;
+ goto unlock;
+ }
+
+ ret = copy_samples_to_user(vdev, ms, u64_to_user_ptr(args->buffer_ptr),
+ args->buffer_size, &args->data_size);
+unlock:
+ mutex_unlock(&file_priv->ms_lock);
+
+ return ret;
+}
+
+static void free_instance(struct ivpu_file_priv *file_priv, struct ivpu_ms_instance *ms)
+{
+ lockdep_assert_held(&file_priv->ms_lock);
+
+ list_del(&ms->ms_instance_node);
+ ivpu_jsm_metric_streamer_stop(file_priv->vdev, ms->mask);
+ ivpu_bo_free(ms->bo);
+ kfree(ms);
+}
+
+int ivpu_ms_stop_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
+{
+ struct ivpu_file_priv *file_priv = file->driver_priv;
+ struct drm_ivpu_metric_streamer_stop *args = data;
+ struct ivpu_ms_instance *ms;
+
+ if (!args->metric_group_mask)
+ return -EINVAL;
+
+ mutex_lock(&file_priv->ms_lock);
+
+ ms = get_instance_by_mask(file_priv, args->metric_group_mask);
+ if (ms)
+ free_instance(file_priv, ms);
+
+ mutex_unlock(&file_priv->ms_lock);
+
+ return ms ? 0 : -EINVAL;
+}
+
+static inline struct ivpu_bo *get_ms_info_bo(struct ivpu_file_priv *file_priv)
+{
+ lockdep_assert_held(&file_priv->ms_lock);
+
+ if (file_priv->ms_info_bo)
+ return file_priv->ms_info_bo;
+
+ file_priv->ms_info_bo = ivpu_bo_create_global(file_priv->vdev, MS_INFO_BUFFER_SIZE,
+ DRM_IVPU_BO_CACHED | DRM_IVPU_BO_MAPPABLE);
+ return file_priv->ms_info_bo;
+}
+
+int ivpu_ms_get_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
+{
+ struct drm_ivpu_metric_streamer_get_data *args = data;
+ struct ivpu_file_priv *file_priv = file->driver_priv;
+ struct ivpu_device *vdev = file_priv->vdev;
+ struct ivpu_bo *bo;
+ u64 info_size;
+ int ret;
+
+ if (!args->metric_group_mask)
+ return -EINVAL;
+
+ if (!args->buffer_size)
+ return ivpu_jsm_metric_streamer_info(vdev, args->metric_group_mask,
+ 0, 0, NULL, &args->data_size);
+ if (!args->buffer_ptr)
+ return -EINVAL;
+
+ mutex_lock(&file_priv->ms_lock);
+
+ bo = get_ms_info_bo(file_priv);
+ if (!bo) {
+ ret = -ENOMEM;
+ goto unlock;
+ }
+
+ ret = ivpu_jsm_metric_streamer_info(vdev, args->metric_group_mask, bo->vpu_addr,
+ ivpu_bo_size(bo), NULL, &info_size);
+ if (ret)
+ goto unlock;
+
+ if (args->buffer_size < info_size) {
+ ret = -ENOSPC;
+ goto unlock;
+ }
+
+ if (copy_to_user(u64_to_user_ptr(args->buffer_ptr), ivpu_bo_vaddr(bo), info_size))
+ ret = -EFAULT;
+
+ args->data_size = info_size;
+unlock:
+ mutex_unlock(&file_priv->ms_lock);
+
+ return ret;
+}
+
+void ivpu_ms_cleanup(struct ivpu_file_priv *file_priv)
+{
+ struct ivpu_ms_instance *ms, *tmp;
+
+ mutex_lock(&file_priv->ms_lock);
+
+ if (file_priv->ms_info_bo) {
+ ivpu_bo_free(file_priv->ms_info_bo);
+ file_priv->ms_info_bo = NULL;
+ }
+
+ list_for_each_entry_safe(ms, tmp, &file_priv->ms_instance_list, ms_instance_node)
+ free_instance(file_priv, ms);
+
+ mutex_unlock(&file_priv->ms_lock);
+}
+
+void ivpu_ms_cleanup_all(struct ivpu_device *vdev)
+{
+ struct ivpu_file_priv *file_priv;
+ unsigned long ctx_id;
+
+ mutex_lock(&vdev->context_list_lock);
+
+ xa_for_each(&vdev->context_xa, ctx_id, file_priv)
+ ivpu_ms_cleanup(file_priv);
+
+ mutex_unlock(&vdev->context_list_lock);
+}
diff --git a/drivers/accel/ivpu/ivpu_ms.h b/drivers/accel/ivpu/ivpu_ms.h
new file mode 100644
index 000000000000..fbd5ebebc3d9
--- /dev/null
+++ b/drivers/accel/ivpu/ivpu_ms.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
+/*
+ * Copyright (C) 2020-2024 Intel Corporation
+ */
+#ifndef __IVPU_MS_H__
+#define __IVPU_MS_H__
+
+#include <linux/list.h>
+
+struct drm_device;
+struct drm_file;
+struct ivpu_bo;
+struct ivpu_device;
+struct ivpu_file_priv;
+
+struct ivpu_ms_instance {
+ struct ivpu_bo *bo;
+ struct list_head ms_instance_node;
+ u64 mask;
+ u64 buff_size;
+ u64 active_buff_vpu_addr;
+ u64 inactive_buff_vpu_addr;
+ void *active_buff_ptr;
+ void *inactive_buff_ptr;
+ u64 leftover_bytes;
+ void *leftover_addr;
+};
+
+int ivpu_ms_start_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
+int ivpu_ms_stop_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
+int ivpu_ms_get_data_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
+int ivpu_ms_get_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
+void ivpu_ms_cleanup(struct ivpu_file_priv *file_priv);
+void ivpu_ms_cleanup_all(struct ivpu_device *vdev);
+
+#endif /* __IVPU_MS_H__ */
diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c
index 4f5ea466731f..59d3170f5e35 100644
--- a/drivers/accel/ivpu/ivpu_pm.c
+++ b/drivers/accel/ivpu/ivpu_pm.c
@@ -18,6 +18,7 @@
#include "ivpu_job.h"
#include "ivpu_jsm_msg.h"
#include "ivpu_mmu.h"
+#include "ivpu_ms.h"
#include "ivpu_pm.h"
static bool ivpu_disable_recovery;
@@ -131,6 +132,7 @@ static void ivpu_pm_recovery_work(struct work_struct *work)
ivpu_suspend(vdev);
ivpu_pm_prepare_cold_boot(vdev);
ivpu_jobs_abort_all(vdev);
+ ivpu_ms_cleanup_all(vdev);
ret = ivpu_resume(vdev);
if (ret)
@@ -235,41 +237,37 @@ int ivpu_pm_runtime_suspend_cb(struct device *dev)
{
struct drm_device *drm = dev_get_drvdata(dev);
struct ivpu_device *vdev = to_ivpu_device(drm);
- bool hw_is_idle = true;
- int ret;
+ int ret, ret_d0i3;
+ bool is_idle;
drm_WARN_ON(&vdev->drm, !xa_empty(&vdev->submitted_jobs_xa));
drm_WARN_ON(&vdev->drm, work_pending(&vdev->pm->recovery_work));
ivpu_dbg(vdev, PM, "Runtime suspend..\n");
- if (!ivpu_hw_is_idle(vdev) && vdev->pm->suspend_reschedule_counter) {
- ivpu_dbg(vdev, PM, "Failed to enter idle, rescheduling suspend, retries left %d\n",
- vdev->pm->suspend_reschedule_counter);
- pm_schedule_suspend(dev, vdev->timeout.reschedule_suspend);
- vdev->pm->suspend_reschedule_counter--;
- return -EAGAIN;
- }
+ ivpu_mmu_disable(vdev);
+
+ is_idle = ivpu_hw_is_idle(vdev) || vdev->pm->dct_active_percent;
+ if (!is_idle)
+ ivpu_err(vdev, "NPU is not idle before autosuspend\n");
- if (!vdev->pm->suspend_reschedule_counter)
- hw_is_idle = false;
- else if (ivpu_jsm_pwr_d0i3_enter(vdev))
- hw_is_idle = false;
+ ret_d0i3 = ivpu_jsm_pwr_d0i3_enter(vdev);
+ if (ret_d0i3)
+ ivpu_err(vdev, "Failed to prepare for d0i3: %d\n", ret_d0i3);
ret = ivpu_suspend(vdev);
if (ret)
ivpu_err(vdev, "Failed to suspend NPU: %d\n", ret);
- if (!hw_is_idle) {
- ivpu_err(vdev, "NPU failed to enter idle, force suspended.\n");
+ if (!is_idle || ret_d0i3) {
+ ivpu_err(vdev, "Forcing cold boot due to previous errors\n");
+ atomic_inc(&vdev->pm->reset_counter);
ivpu_fw_log_dump(vdev);
ivpu_pm_prepare_cold_boot(vdev);
} else {
ivpu_pm_prepare_warm_boot(vdev);
}
- vdev->pm->suspend_reschedule_counter = PM_RESCHEDULE_LIMIT;
-
ivpu_dbg(vdev, PM, "Runtime suspend done.\n");
return 0;
@@ -297,17 +295,6 @@ int ivpu_rpm_get(struct ivpu_device *vdev)
int ret;
ret = pm_runtime_resume_and_get(vdev->drm.dev);
- if (!drm_WARN_ON(&vdev->drm, ret < 0))
- vdev->pm->suspend_reschedule_counter = PM_RESCHEDULE_LIMIT;
-
- return ret;
-}
-
-int ivpu_rpm_get_if_active(struct ivpu_device *vdev)
-{
- int ret;
-
- ret = pm_runtime_get_if_in_use(vdev->drm.dev);
drm_WARN_ON(&vdev->drm, ret < 0);
return ret;
@@ -333,6 +320,8 @@ void ivpu_pm_reset_prepare_cb(struct pci_dev *pdev)
ivpu_hw_reset(vdev);
ivpu_pm_prepare_cold_boot(vdev);
ivpu_jobs_abort_all(vdev);
+ ivpu_ms_cleanup_all(vdev);
+
ivpu_dbg(vdev, PM, "Pre-reset done.\n");
}
@@ -360,7 +349,6 @@ void ivpu_pm_init(struct ivpu_device *vdev)
int delay;
pm->vdev = vdev;
- pm->suspend_reschedule_counter = PM_RESCHEDULE_LIMIT;
init_rwsem(&pm->reset_lock);
atomic_set(&pm->reset_pending, 0);
@@ -401,3 +389,68 @@ void ivpu_pm_disable(struct ivpu_device *vdev)
pm_runtime_get_noresume(vdev->drm.dev);
pm_runtime_forbid(vdev->drm.dev);
}
+
+int ivpu_pm_dct_init(struct ivpu_device *vdev)
+{
+ if (vdev->pm->dct_active_percent)
+ return ivpu_pm_dct_enable(vdev, vdev->pm->dct_active_percent);
+
+ return 0;
+}
+
+int ivpu_pm_dct_enable(struct ivpu_device *vdev, u8 active_percent)
+{
+ u32 active_us, inactive_us;
+ int ret;
+
+ if (active_percent == 0 || active_percent > 100)
+ return -EINVAL;
+
+ active_us = (DCT_PERIOD_US * active_percent) / 100;
+ inactive_us = DCT_PERIOD_US - active_us;
+
+ ret = ivpu_jsm_dct_enable(vdev, active_us, inactive_us);
+ if (ret) {
+ ivpu_err_ratelimited(vdev, "Filed to enable DCT: %d\n", ret);
+ return ret;
+ }
+
+ vdev->pm->dct_active_percent = active_percent;
+
+ ivpu_dbg(vdev, PM, "DCT set to %u%% (D0: %uus, D0i2: %uus)\n",
+ active_percent, active_us, inactive_us);
+ return 0;
+}
+
+int ivpu_pm_dct_disable(struct ivpu_device *vdev)
+{
+ int ret;
+
+ ret = ivpu_jsm_dct_disable(vdev);
+ if (ret) {
+ ivpu_err_ratelimited(vdev, "Filed to disable DCT: %d\n", ret);
+ return ret;
+ }
+
+ vdev->pm->dct_active_percent = 0;
+
+ ivpu_dbg(vdev, PM, "DCT disabled\n");
+ return 0;
+}
+
+void ivpu_pm_dct_irq_thread_handler(struct ivpu_device *vdev)
+{
+ bool enable;
+ int ret;
+
+ if (ivpu_hw_btrs_dct_get_request(vdev, &enable))
+ return;
+
+ if (vdev->pm->dct_active_percent)
+ ret = ivpu_pm_dct_enable(vdev, DCT_DEFAULT_ACTIVE_PERCENT);
+ else
+ ret = ivpu_pm_dct_disable(vdev);
+
+ if (!ret)
+ ivpu_hw_btrs_dct_set_status(vdev, enable, vdev->pm->dct_active_percent);
+}
diff --git a/drivers/accel/ivpu/ivpu_pm.h b/drivers/accel/ivpu/ivpu_pm.h
index ec60fbeefefc..b70efe6c36e4 100644
--- a/drivers/accel/ivpu/ivpu_pm.h
+++ b/drivers/accel/ivpu/ivpu_pm.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (C) 2020-2023 Intel Corporation
+ * Copyright (C) 2020-2024 Intel Corporation
*/
#ifndef __IVPU_PM_H__
@@ -19,7 +19,7 @@ struct ivpu_pm_info {
atomic_t reset_counter;
atomic_t reset_pending;
bool is_warmboot;
- u32 suspend_reschedule_counter;
+ u8 dct_active_percent;
};
void ivpu_pm_init(struct ivpu_device *vdev);
@@ -36,11 +36,15 @@ void ivpu_pm_reset_prepare_cb(struct pci_dev *pdev);
void ivpu_pm_reset_done_cb(struct pci_dev *pdev);
int __must_check ivpu_rpm_get(struct ivpu_device *vdev);
-int __must_check ivpu_rpm_get_if_active(struct ivpu_device *vdev);
void ivpu_rpm_put(struct ivpu_device *vdev);
void ivpu_pm_trigger_recovery(struct ivpu_device *vdev, const char *reason);
void ivpu_start_job_timeout_detection(struct ivpu_device *vdev);
void ivpu_stop_job_timeout_detection(struct ivpu_device *vdev);
+int ivpu_pm_dct_init(struct ivpu_device *vdev);
+int ivpu_pm_dct_enable(struct ivpu_device *vdev, u8 active_percent);
+int ivpu_pm_dct_disable(struct ivpu_device *vdev);
+void ivpu_pm_dct_irq_thread_handler(struct ivpu_device *vdev);
+
#endif /* __IVPU_PM_H__ */
diff --git a/drivers/accel/ivpu/ivpu_sysfs.c b/drivers/accel/ivpu/ivpu_sysfs.c
new file mode 100644
index 000000000000..913669f1786e
--- /dev/null
+++ b/drivers/accel/ivpu/ivpu_sysfs.c
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 Intel Corporation
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+
+#include "ivpu_hw.h"
+#include "ivpu_sysfs.h"
+
+/*
+ * npu_busy_time_us is the time that the device spent executing jobs.
+ * The time is counted when and only when there are jobs submitted to firmware.
+ *
+ * This time can be used to measure the utilization of NPU, either by calculating
+ * npu_busy_time_us difference between two timepoints (i.e. measuring the time
+ * that the NPU was active during some workload) or monitoring utilization percentage
+ * by reading npu_busy_time_us periodically.
+ *
+ * When reading the value periodically, it shouldn't be read too often as it may have
+ * an impact on job submission performance. Recommended period is 1 second.
+ */
+static ssize_t
+npu_busy_time_us_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct drm_device *drm = dev_get_drvdata(dev);
+ struct ivpu_device *vdev = to_ivpu_device(drm);
+ ktime_t total, now = 0;
+
+ xa_lock(&vdev->submitted_jobs_xa);
+ total = vdev->busy_time;
+ if (!xa_empty(&vdev->submitted_jobs_xa))
+ now = ktime_sub(ktime_get(), vdev->busy_start_ts);
+ xa_unlock(&vdev->submitted_jobs_xa);
+
+ return sysfs_emit(buf, "%lld\n", ktime_to_us(ktime_add(total, now)));
+}
+
+static DEVICE_ATTR_RO(npu_busy_time_us);
+
+static struct attribute *ivpu_dev_attrs[] = {
+ &dev_attr_npu_busy_time_us.attr,
+ NULL,
+};
+
+static struct attribute_group ivpu_dev_attr_group = {
+ .attrs = ivpu_dev_attrs,
+};
+
+void ivpu_sysfs_init(struct ivpu_device *vdev)
+{
+ int ret;
+
+ ret = devm_device_add_group(vdev->drm.dev, &ivpu_dev_attr_group);
+ if (ret)
+ ivpu_warn(vdev, "Failed to add group to device, ret %d", ret);
+}
diff --git a/drivers/accel/ivpu/ivpu_sysfs.h b/drivers/accel/ivpu/ivpu_sysfs.h
new file mode 100644
index 000000000000..9836f09b35a3
--- /dev/null
+++ b/drivers/accel/ivpu/ivpu_sysfs.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2024 Intel Corporation
+ */
+
+#ifndef __IVPU_SYSFS_H__
+#define __IVPU_SYSFS_H__
+
+#include "ivpu_drv.h"
+
+void ivpu_sysfs_init(struct ivpu_device *vdev);
+
+#endif /* __IVPU_SYSFS_H__ */
diff --git a/drivers/accel/ivpu/vpu_boot_api.h b/drivers/accel/ivpu/vpu_boot_api.h
index 87cac7bc730a..82954b91b748 100644
--- a/drivers/accel/ivpu/vpu_boot_api.h
+++ b/drivers/accel/ivpu/vpu_boot_api.h
@@ -27,7 +27,7 @@
* Minor version changes when API backward compatibility is preserved.
* Resets to 0 if Major version is incremented.
*/
-#define VPU_BOOT_API_VER_MINOR 22
+#define VPU_BOOT_API_VER_MINOR 24
/*
* API header changed (field names, documentation, formatting) but API itself has not been changed
@@ -80,6 +80,11 @@ struct vpu_firmware_header {
u32 preemption_buffer_2_size;
/* Space reserved for future preemption-related fields. */
u32 preemption_reserved[6];
+ /* FW image read only section start address, 4KB aligned */
+ u64 ro_section_start_address;
+ /* FW image read only section size, 4KB aligned */
+ u32 ro_section_size;
+ u32 reserved;
};
/*
@@ -333,7 +338,14 @@ struct vpu_boot_params {
* The KMD is required to update this value on every VPU reset.
*/
u64 system_time_us;
- u32 pad4[18];
+ u32 pad4[2];
+ /*
+ * The delta between device monotonic time and the current value of the
+ * HW timestamp register, in ticks. Written by the firmware during boot.
+ * Can be used by the KMD to calculate device time.
+ */
+ u64 device_time_delta_ticks;
+ u32 pad7[14];
/* Warm boot information: 0x400 - 0x43F */
u32 warm_boot_sections_count;
u32 warm_boot_start_address_reference;
diff --git a/drivers/accel/ivpu/vpu_jsm_api.h b/drivers/accel/ivpu/vpu_jsm_api.h
index e46f3531211a..33f462b1a25d 100644
--- a/drivers/accel/ivpu/vpu_jsm_api.h
+++ b/drivers/accel/ivpu/vpu_jsm_api.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: MIT */
/*
- * Copyright (c) 2020-2023, Intel Corporation.
+ * Copyright (c) 2020-2024, Intel Corporation.
*/
/**
@@ -22,12 +22,12 @@
/*
* Minor version changes when API backward compatibility is preserved.
*/
-#define VPU_JSM_API_VER_MINOR 15
+#define VPU_JSM_API_VER_MINOR 16
/*
* API header changed (field names, documentation, formatting) but API itself has not been changed
*/
-#define VPU_JSM_API_VER_PATCH 6
+#define VPU_JSM_API_VER_PATCH 0
/*
* Index in the API version table
@@ -868,6 +868,14 @@ struct vpu_ipc_msg_payload_hws_set_scheduling_log {
* is generated when an event log is written to this index.
*/
u64 notify_index;
+ /*
+ * Enable extra events to be output to log for debug of scheduling algorithm.
+ * Interpreted by VPU as a boolean to enable or disable, expected values are
+ * 0 and 1.
+ */
+ u32 enable_extra_events;
+ /* Zero Padding */
+ u32 reserved_0;
};
/*
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index ce8651436609..8e41731d3642 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -802,4 +802,5 @@ module_exit(agp_amd64_cleanup);
MODULE_AUTHOR("Dave Jones, Andi Kleen");
module_param(agp_try_unsupported, bool, 0);
+MODULE_DESCRIPTION("GART driver for the AMD Opteron/Athlon64 on-CPU northbridge");
MODULE_LICENSE("GPL");
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index c518b3a9db04..3111e320b2c5 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -12,7 +12,7 @@
#include <asm/smp.h>
#include "agp.h"
#include "intel-agp.h"
-#include <drm/intel-gtt.h>
+#include <drm/intel/intel-gtt.h>
static int intel_fetch_size(void)
{
@@ -920,4 +920,5 @@ module_init(agp_intel_init);
module_exit(agp_intel_cleanup);
MODULE_AUTHOR("Dave Jones, Various @Intel");
+MODULE_DESCRIPTION("Intel AGPGART routines");
MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
index bf6716ff863b..ef30445527a2 100644
--- a/drivers/char/agp/intel-gtt.c
+++ b/drivers/char/agp/intel-gtt.c
@@ -25,7 +25,7 @@
#include <asm/smp.h>
#include "agp.h"
#include "intel-agp.h"
-#include <drm/intel-gtt.h>
+#include <drm/intel/intel-gtt.h>
#include <asm/set_memory.h>
/*
@@ -1461,4 +1461,5 @@ void intel_gmch_remove(void)
EXPORT_SYMBOL(intel_gmch_remove);
MODULE_AUTHOR("Dave Jones, Various @Intel");
+MODULE_DESCRIPTION("Intel GTT (Graphics Translation Table) routines");
MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c
index 484bb101c53b..a0deb97cedb0 100644
--- a/drivers/char/agp/sis-agp.c
+++ b/drivers/char/agp/sis-agp.c
@@ -433,4 +433,5 @@ module_param(agp_sis_force_delay, bool, 0);
MODULE_PARM_DESC(agp_sis_force_delay,"forces sis delay hack");
module_param(agp_sis_agp_spec, int, 0);
MODULE_PARM_DESC(agp_sis_agp_spec,"0=force sis init, 1=force generic agp3 init, default: autodetect");
+MODULE_DESCRIPTION("SiS AGPGART routines");
MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c
index bc5140af2dcb..8b19a5d1a09b 100644
--- a/drivers/char/agp/via-agp.c
+++ b/drivers/char/agp/via-agp.c
@@ -575,5 +575,6 @@ static void __exit agp_via_cleanup(void)
module_init(agp_via_init);
module_exit(agp_via_cleanup);
+MODULE_DESCRIPTION("VIA AGPGART routines");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Dave Jones");
diff --git a/drivers/dma-buf/dma-fence-array.c b/drivers/dma-buf/dma-fence-array.c
index 9b3ce8948351..c74ac197d5fe 100644
--- a/drivers/dma-buf/dma-fence-array.c
+++ b/drivers/dma-buf/dma-fence-array.c
@@ -70,7 +70,7 @@ static void dma_fence_array_cb_func(struct dma_fence *f,
static bool dma_fence_array_enable_signaling(struct dma_fence *fence)
{
struct dma_fence_array *array = to_dma_fence_array(fence);
- struct dma_fence_array_cb *cb = (void *)(&array[1]);
+ struct dma_fence_array_cb *cb = array->callbacks;
unsigned i;
for (i = 0; i < array->num_fences; ++i) {
@@ -168,22 +168,20 @@ struct dma_fence_array *dma_fence_array_create(int num_fences,
bool signal_on_any)
{
struct dma_fence_array *array;
- size_t size = sizeof(*array);
WARN_ON(!num_fences || !fences);
- /* Allocate the callback structures behind the array. */
- size += num_fences * sizeof(struct dma_fence_array_cb);
- array = kzalloc(size, GFP_KERNEL);
+ array = kzalloc(struct_size(array, callbacks, num_fences), GFP_KERNEL);
if (!array)
return NULL;
+ array->num_fences = num_fences;
+
spin_lock_init(&array->lock);
dma_fence_init(&array->base, &dma_fence_array_ops, &array->lock,
context, seqno);
init_irq_work(&array->work, irq_dma_fence_array_work);
- array->num_fences = num_fences;
atomic_set(&array->num_pending, signal_on_any ? 1 : num_fences);
array->fences = fences;
diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
index 84ae708fafe7..2298ca5e112e 100644
--- a/drivers/dma-buf/dma-heap.c
+++ b/drivers/dma-buf/dma-heap.c
@@ -50,8 +50,8 @@ static struct class *dma_heap_class;
static DEFINE_XARRAY_ALLOC(dma_heap_minors);
static int dma_heap_buffer_alloc(struct dma_heap *heap, size_t len,
- unsigned int fd_flags,
- unsigned int heap_flags)
+ u32 fd_flags,
+ u64 heap_flags)
{
struct dma_buf *dmabuf;
int fd;
diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c
index e2869fb31140..5f8d010516f0 100644
--- a/drivers/dma-buf/dma-resv.c
+++ b/drivers/dma-buf/dma-resv.c
@@ -186,6 +186,13 @@ int dma_resv_reserve_fences(struct dma_resv *obj, unsigned int num_fences)
dma_resv_assert_held(obj);
+ /* Driver and component code should never call this function with
+ * num_fences=0. If they do it usually points to bugs when calculating
+ * the number of needed fences dynamically.
+ */
+ if (WARN_ON(!num_fences))
+ return -EINVAL;
+
old = dma_resv_fences_list(obj);
if (old && old->max_fences) {
if ((old->num_fences + num_fences) <= old->max_fences)
diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c
index 4a63567e93ba..c384004b918e 100644
--- a/drivers/dma-buf/heaps/cma_heap.c
+++ b/drivers/dma-buf/heaps/cma_heap.c
@@ -274,8 +274,8 @@ static const struct dma_buf_ops cma_heap_buf_ops = {
static struct dma_buf *cma_heap_allocate(struct dma_heap *heap,
unsigned long len,
- unsigned long fd_flags,
- unsigned long heap_flags)
+ u32 fd_flags,
+ u64 heap_flags)
{
struct cma_heap *cma_heap = dma_heap_get_drvdata(heap);
struct cma_heap_buffer *buffer;
diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c
index 9076d47ed2ef..d78cdb9d01e5 100644
--- a/drivers/dma-buf/heaps/system_heap.c
+++ b/drivers/dma-buf/heaps/system_heap.c
@@ -333,8 +333,8 @@ static struct page *alloc_largest_available(unsigned long size,
static struct dma_buf *system_heap_allocate(struct dma_heap *heap,
unsigned long len,
- unsigned long fd_flags,
- unsigned long heap_flags)
+ u32 fd_flags,
+ u64 heap_flags)
{
struct system_heap_buffer *buffer;
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 026444eeb5c6..f5c989aed7e9 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -79,6 +79,7 @@ config DRM_KUNIT_TEST
depends on DRM && KUNIT && MMU
select DRM_BUDDY
select DRM_DISPLAY_DP_HELPER
+ select DRM_DISPLAY_HDMI_STATE_HELPER
select DRM_DISPLAY_HELPER
select DRM_EXEC
select DRM_EXPORT_FOR_TESTS if m
@@ -106,7 +107,7 @@ config DRM_KMS_HELPER
config DRM_PANIC
bool "Display a user-friendly message when a kernel panic occurs"
- depends on DRM && !FRAMEBUFFER_CONSOLE
+ depends on DRM && !(FRAMEBUFFER_CONSOLE && VT_CONSOLE)
select DRM_KMS_HELPER
select FONT_SUPPORT
help
@@ -136,6 +137,19 @@ config DRM_PANIC_DEBUG
This is unsafe and should not be enabled on a production build.
If in doubt, say "N".
+config DRM_PANIC_SCREEN
+ string "Panic screen formater"
+ default "user"
+ depends on DRM_PANIC
+ help
+ This option enable to choose what will be displayed when a kernel
+ panic occurs. You can choose between "user", a short message telling
+ the user to reboot the system, or "kmsg" which will display the last
+ lines of kmsg.
+ This can also be overridden by drm.panic_screen=xxxx kernel parameter
+ or by writing to /sys/module/drm/parameters/panic_screen sysfs entry
+ Default is "user"
+
config DRM_DEBUG_DP_MST_TOPOLOGY_REFS
bool "Enable refcount backtrace history in the DP MST helpers"
depends on STACKTRACE_SUPPORT
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index f9ca4f8fa6c5..68cc9258ffc4 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -108,6 +108,7 @@ drm_dma_helper-$(CONFIG_DRM_KMS_HELPER) += drm_fb_dma_helper.o
obj-$(CONFIG_DRM_GEM_DMA_HELPER) += drm_dma_helper.o
drm_shmem_helper-y := drm_gem_shmem_helper.o
+drm_shmem_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fbdev_shmem.o
obj-$(CONFIG_DRM_GEM_SHMEM_HELPER) += drm_shmem_helper.o
drm_suballoc_helper-y := drm_suballoc.o
@@ -117,6 +118,7 @@ drm_vram_helper-y := drm_gem_vram_helper.o
obj-$(CONFIG_DRM_VRAM_HELPER) += drm_vram_helper.o
drm_ttm_helper-y := drm_gem_ttm_helper.o
+drm_ttm_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fbdev_ttm.o
obj-$(CONFIG_DRM_TTM_HELPER) += drm_ttm_helper.o
#
@@ -142,9 +144,7 @@ drm_kms_helper-y := \
drm_self_refresh_helper.o \
drm_simple_kms_helper.o
drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o
-drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += \
- drm_fbdev_generic.o \
- drm_fb_helper.o
+drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
#
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
index 9caba10315a8..cae7479c3ecf 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
@@ -246,22 +246,6 @@ amdgpu_connector_find_encoder(struct drm_connector *connector,
return NULL;
}
-struct edid *amdgpu_connector_edid(struct drm_connector *connector)
-{
- struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
- struct drm_property_blob *edid_blob = connector->edid_blob_ptr;
-
- if (amdgpu_connector->edid) {
- return amdgpu_connector->edid;
- } else if (edid_blob) {
- struct edid *edid = kmemdup(edid_blob->data, edid_blob->length, GFP_KERNEL);
-
- if (edid)
- amdgpu_connector->edid = edid;
- }
- return amdgpu_connector->edid;
-}
-
static struct edid *
amdgpu_connector_get_hardcoded_edid(struct amdgpu_device *adev)
{
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.h
index 61fcef15ad72..eff833b6ed31 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.h
@@ -24,7 +24,6 @@
#ifndef __AMDGPU_CONNECTORS_H__
#define __AMDGPU_CONNECTORS_H__
-struct edid *amdgpu_connector_edid(struct drm_connector *connector);
void amdgpu_connector_hotplug(struct drm_connector *connector);
int amdgpu_connector_get_monitor_bpc(struct drm_connector *connector);
u16 amdgpu_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 2da76fadf6ea..9f2db858c6e0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -24,7 +24,7 @@
#include <drm/amdgpu_drm.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_ttm.h>
#include <drm/drm_gem.h>
#include <drm/drm_managed.h>
#include <drm/drm_pciids.h>
@@ -2346,9 +2346,9 @@ retry_init:
!list_empty(&adev_to_drm(adev)->mode_config.connector_list)) {
/* select 8 bpp console on low vram cards */
if (adev->gmc.real_vram_size <= (32*1024*1024))
- drm_fbdev_generic_setup(adev_to_drm(adev), 8);
+ drm_fbdev_ttm_setup(adev_to_drm(adev), 8);
else
- drm_fbdev_generic_setup(adev_to_drm(adev), 32);
+ drm_fbdev_ttm_setup(adev_to_drm(adev), 32);
}
ret = amdgpu_debugfs_init(adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
index e30eecd02ae1..821f9491565b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
@@ -65,9 +65,7 @@ static enum hrtimer_restart amdgpu_vkms_vblank_simulate(struct hrtimer *timer)
static int amdgpu_vkms_enable_vblank(struct drm_crtc *crtc)
{
- struct drm_device *dev = crtc->dev;
- unsigned int pipe = drm_crtc_index(crtc);
- struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
+ struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
struct amdgpu_vkms_output *out = drm_crtc_to_amdgpu_vkms_output(crtc);
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
@@ -91,10 +89,8 @@ static bool amdgpu_vkms_get_vblank_timestamp(struct drm_crtc *crtc,
ktime_t *vblank_time,
bool in_vblank_irq)
{
- struct drm_device *dev = crtc->dev;
- unsigned int pipe = crtc->index;
struct amdgpu_vkms_output *output = drm_crtc_to_amdgpu_vkms_output(crtc);
- struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
+ struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
if (!READ_ONCE(vblank->enabled)) {
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
index b44fce44c066..dddb5fe16f2c 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
@@ -1299,7 +1299,7 @@ static void dce_v10_0_audio_write_speaker_allocation(struct drm_encoder *encoder
return;
}
- sad_count = drm_edid_to_speaker_allocation(amdgpu_connector_edid(connector), &sadb);
+ sad_count = drm_edid_to_speaker_allocation(amdgpu_connector->edid, &sadb);
if (sad_count < 0) {
DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
sad_count = 0;
@@ -1369,7 +1369,7 @@ static void dce_v10_0_audio_write_sad_regs(struct drm_encoder *encoder)
return;
}
- sad_count = drm_edid_to_sad(amdgpu_connector_edid(connector), &sads);
+ sad_count = drm_edid_to_sad(amdgpu_connector->edid, &sads);
if (sad_count < 0)
DRM_ERROR("Couldn't read SADs: %d\n", sad_count);
if (sad_count <= 0)
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
index 80b2e7f79acf..11780e4d7e9f 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
@@ -1331,7 +1331,7 @@ static void dce_v11_0_audio_write_speaker_allocation(struct drm_encoder *encoder
return;
}
- sad_count = drm_edid_to_speaker_allocation(amdgpu_connector_edid(connector), &sadb);
+ sad_count = drm_edid_to_speaker_allocation(amdgpu_connector->edid, &sadb);
if (sad_count < 0) {
DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
sad_count = 0;
@@ -1401,7 +1401,7 @@ static void dce_v11_0_audio_write_sad_regs(struct drm_encoder *encoder)
return;
}
- sad_count = drm_edid_to_sad(amdgpu_connector_edid(connector), &sads);
+ sad_count = drm_edid_to_sad(amdgpu_connector->edid, &sads);
if (sad_count < 0)
DRM_ERROR("Couldn't read SADs: %d\n", sad_count);
if (sad_count <= 0)
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
index db20012600f5..05c0df97f01d 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
@@ -1217,7 +1217,7 @@ static void dce_v6_0_audio_write_speaker_allocation(struct drm_encoder *encoder)
return;
}
- sad_count = drm_edid_to_speaker_allocation(amdgpu_connector_edid(connector), &sadb);
+ sad_count = drm_edid_to_speaker_allocation(amdgpu_connector->edid, &sadb);
if (sad_count < 0) {
DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
sad_count = 0;
@@ -1292,7 +1292,7 @@ static void dce_v6_0_audio_write_sad_regs(struct drm_encoder *encoder)
return;
}
- sad_count = drm_edid_to_sad(amdgpu_connector_edid(connector), &sads);
+ sad_count = drm_edid_to_sad(amdgpu_connector->edid, &sads);
if (sad_count < 0)
DRM_ERROR("Couldn't read SADs: %d\n", sad_count);
if (sad_count <= 0)
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
index 5b56100ec902..dc73e301d937 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
@@ -1272,7 +1272,7 @@ static void dce_v8_0_audio_write_speaker_allocation(struct drm_encoder *encoder)
return;
}
- sad_count = drm_edid_to_speaker_allocation(amdgpu_connector_edid(connector), &sadb);
+ sad_count = drm_edid_to_speaker_allocation(amdgpu_connector->edid, &sadb);
if (sad_count < 0) {
DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
sad_count = 0;
@@ -1340,7 +1340,7 @@ static void dce_v8_0_audio_write_sad_regs(struct drm_encoder *encoder)
return;
}
- sad_count = drm_edid_to_sad(amdgpu_connector_edid(connector), &sads);
+ sad_count = drm_edid_to_sad(amdgpu_connector->edid, &sads);
if (sad_count < 0)
DRM_ERROR("Couldn't read SADs: %d\n", sad_count);
if (sad_count <= 0)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 6196de6cebbf..ac18cddeb191 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -534,7 +534,7 @@ static void dm_vupdate_high_irq(void *interrupt_params)
if (acrtc) {
vrr_active = amdgpu_dm_crtc_vrr_active_irq(acrtc);
drm_dev = acrtc->base.dev;
- vblank = &drm_dev->vblank[acrtc->base.index];
+ vblank = drm_crtc_vblank_crtc(&acrtc->base);
previous_timestamp = atomic64_read(&irq_params->previous_timestamp);
frame_duration_ns = vblank->time - previous_timestamp;
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index 2c661f28410e..2ad33559a33a 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -5,6 +5,7 @@
*
*/
#include <linux/clk.h>
+#include <linux/of.h>
#include <linux/pm_runtime.h>
#include <linux/spinlock.h>
@@ -294,7 +295,6 @@ komeda_crtc_flush_and_wait_for_flip_done(struct komeda_crtc *kcrtc,
struct komeda_dev *mdev = kcrtc->master->mdev;
struct completion *flip_done;
struct completion temp;
- int timeout;
/* if caller doesn't send a flip_done, use a private flip_done */
if (input_flip_done) {
@@ -308,8 +308,7 @@ komeda_crtc_flush_and_wait_for_flip_done(struct komeda_crtc *kcrtc,
mdev->funcs->flush(mdev, kcrtc->master->id, 0);
/* wait the flip take affect.*/
- timeout = wait_for_completion_timeout(flip_done, HZ);
- if (timeout == 0) {
+ if (wait_for_completion_timeout(flip_done, HZ) == 0) {
DRM_ERROR("wait pipe%d flip done timeout\n", kcrtc->master->id);
if (!input_flip_done) {
unsigned long flags;
@@ -610,12 +609,34 @@ get_crtc_primary(struct komeda_kms_dev *kms, struct komeda_crtc *crtc)
return NULL;
}
+static int komeda_attach_bridge(struct device *dev,
+ struct komeda_pipeline *pipe,
+ struct drm_encoder *encoder)
+{
+ struct drm_bridge *bridge;
+ int err;
+
+ bridge = devm_drm_of_get_bridge(dev, pipe->of_node,
+ KOMEDA_OF_PORT_OUTPUT, 0);
+ if (IS_ERR(bridge))
+ return dev_err_probe(dev, PTR_ERR(bridge), "remote bridge not found for pipe: %s\n",
+ of_node_full_name(pipe->of_node));
+
+ err = drm_bridge_attach(encoder, bridge, NULL, 0);
+ if (err)
+ dev_err(dev, "bridge_attach() failed for pipe: %s\n",
+ of_node_full_name(pipe->of_node));
+
+ return err;
+}
+
static int komeda_crtc_add(struct komeda_kms_dev *kms,
struct komeda_crtc *kcrtc)
{
struct drm_crtc *crtc = &kcrtc->base;
struct drm_device *base = &kms->base;
- struct drm_bridge *bridge;
+ struct komeda_pipeline *pipe = kcrtc->master;
+ struct drm_encoder *encoder = &kcrtc->encoder;
int err;
err = drm_crtc_init_with_planes(base, crtc,
@@ -626,27 +647,27 @@ static int komeda_crtc_add(struct komeda_kms_dev *kms,
drm_crtc_helper_add(crtc, &komeda_crtc_helper_funcs);
- crtc->port = kcrtc->master->of_output_port;
+ crtc->port = pipe->of_output_port;
/* Construct an encoder for each pipeline and attach it to the remote
* bridge
*/
kcrtc->encoder.possible_crtcs = drm_crtc_mask(crtc);
- err = drm_simple_encoder_init(base, &kcrtc->encoder,
- DRM_MODE_ENCODER_TMDS);
+ err = drm_simple_encoder_init(base, encoder, DRM_MODE_ENCODER_TMDS);
if (err)
return err;
- bridge = devm_drm_of_get_bridge(base->dev, kcrtc->master->of_node,
- KOMEDA_OF_PORT_OUTPUT, 0);
- if (IS_ERR(bridge))
- return PTR_ERR(bridge);
-
- err = drm_bridge_attach(&kcrtc->encoder, bridge, NULL, 0);
+ if (pipe->of_output_links[0]) {
+ err = komeda_attach_bridge(base->dev, pipe, encoder);
+ if (err)
+ return err;
+ }
drm_crtc_enable_color_mgmt(crtc, 0, true, KOMEDA_COLOR_LUT_SIZE);
- return err;
+ komeda_pipeline_dump(pipe);
+
+ return 0;
}
int komeda_kms_add_crtcs(struct komeda_kms_dev *kms, struct komeda_dev *mdev)
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
index cc57ea4e13ae..55c3773befde 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
@@ -9,7 +9,7 @@
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_dma.h>
#include <drm/drm_module.h>
#include <drm/drm_of.h>
#include "komeda_dev.h"
@@ -59,6 +59,10 @@ static int komeda_platform_probe(struct platform_device *pdev)
struct komeda_drv *mdrv;
int err;
+ err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40));
+ if (err)
+ return dev_err_probe(dev, err, "DMA mask error\n");
+
mdrv = devm_kzalloc(dev, sizeof(*mdrv), GFP_KERNEL);
if (!mdrv)
return -ENOMEM;
@@ -80,7 +84,7 @@ static int komeda_platform_probe(struct platform_device *pdev)
}
dev_set_drvdata(dev, mdrv);
- drm_fbdev_generic_setup(&mdrv->kms->base, 32);
+ drm_fbdev_dma_setup(&mdrv->kms->base, 32);
return 0;
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
index a4048724564d..83e61c4080c2 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
@@ -191,5 +191,6 @@ void komeda_crtc_flush_and_wait_for_flip_done(struct komeda_crtc *kcrtc,
struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev);
void komeda_kms_detach(struct komeda_kms_dev *kms);
void komeda_kms_shutdown(struct komeda_kms_dev *kms);
+void komeda_pipeline_dump(struct komeda_pipeline *pipe);
#endif /*_KOMEDA_KMS_H_*/
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
index 00f5864a0495..81e244f0c0ca 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
@@ -10,6 +10,7 @@
#include <drm/drm_print.h>
#include "komeda_dev.h"
+#include "komeda_kms.h"
#include "komeda_pipeline.h"
/** komeda_pipeline_add - Add a pipeline to &komeda_dev */
@@ -247,7 +248,7 @@ static void komeda_component_dump(struct komeda_component *c)
c->max_active_outputs, c->supported_outputs);
}
-static void komeda_pipeline_dump(struct komeda_pipeline *pipe)
+void komeda_pipeline_dump(struct komeda_pipeline *pipe)
{
struct komeda_component *c;
int id;
@@ -351,7 +352,6 @@ int komeda_assemble_pipelines(struct komeda_dev *mdev)
pipe = mdev->pipelines[i];
komeda_pipeline_assemble(pipe);
- komeda_pipeline_dump(pipe);
}
return 0;
diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
index f8c49ba68e78..aae019e79bda 100644
--- a/drivers/gpu/drm/ast/ast_drv.c
+++ b/drivers/gpu/drm/ast/ast_drv.c
@@ -33,7 +33,7 @@
#include <drm/drm_aperture.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_shmem.h>
#include <drm/drm_gem_shmem_helper.h>
#include <drm/drm_module.h>
#include <drm/drm_probe_helper.h>
@@ -360,7 +360,7 @@ static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (ret)
return ret;
- drm_fbdev_generic_setup(drm, 32);
+ drm_fbdev_shmem_setup(drm, 32);
return 0;
}
diff --git a/drivers/gpu/drm/atmel-hlcdc/Kconfig b/drivers/gpu/drm/atmel-hlcdc/Kconfig
index 3bdbab3a6333..945f3aa7bb24 100644
--- a/drivers/gpu/drm/atmel-hlcdc/Kconfig
+++ b/drivers/gpu/drm/atmel-hlcdc/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config DRM_ATMEL_HLCDC
tristate "DRM Support for ATMEL HLCDC Display Controller"
- depends on DRM && OF && COMMON_CLK && MFD_ATMEL_HLCDC && ARM
+ depends on DRM && OF && COMMON_CLK && ((MFD_ATMEL_HLCDC && ARM) || COMPILE_TEST)
select DRM_GEM_DMA_HELPER
select DRM_KMS_HELPER
select DRM_PANEL
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
index cc5cf4c2faf7..0f7ffb3ced20 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
@@ -30,10 +30,12 @@
*
* @base: base CRTC state
* @output_mode: RGBXXX output mode
+ * @dpi: output DPI mode
*/
struct atmel_hlcdc_crtc_state {
struct drm_crtc_state base;
unsigned int output_mode;
+ u8 dpi;
};
static inline struct atmel_hlcdc_crtc_state *
@@ -164,18 +166,24 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct drm_crtc *c)
state = drm_crtc_state_to_atmel_hlcdc_crtc_state(c->state);
cfg = state->output_mode << 8;
- if (adj->flags & DRM_MODE_FLAG_NVSYNC)
- cfg |= ATMEL_HLCDC_VSPOL;
+ if (!crtc->dc->desc->is_xlcdc) {
+ if (adj->flags & DRM_MODE_FLAG_NVSYNC)
+ cfg |= ATMEL_HLCDC_VSPOL;
- if (adj->flags & DRM_MODE_FLAG_NHSYNC)
- cfg |= ATMEL_HLCDC_HSPOL;
+ if (adj->flags & DRM_MODE_FLAG_NHSYNC)
+ cfg |= ATMEL_HLCDC_HSPOL;
+ } else {
+ cfg |= state->dpi << 11;
+ }
regmap_update_bits(regmap, ATMEL_HLCDC_CFG(5),
ATMEL_HLCDC_HSPOL | ATMEL_HLCDC_VSPOL |
ATMEL_HLCDC_VSPDLYS | ATMEL_HLCDC_VSPDLYE |
ATMEL_HLCDC_DISPPOL | ATMEL_HLCDC_DISPDLY |
ATMEL_HLCDC_VSPSU | ATMEL_HLCDC_VSPHO |
- ATMEL_HLCDC_GUARDTIME_MASK | ATMEL_HLCDC_MODE_MASK,
+ ATMEL_HLCDC_GUARDTIME_MASK |
+ (crtc->dc->desc->is_xlcdc ? ATMEL_XLCDC_MODE_MASK |
+ ATMEL_XLCDC_DPI : ATMEL_HLCDC_MODE_MASK),
cfg);
clk_disable_unprepare(crtc->dc->hlcdc->sys_clk);
@@ -202,20 +210,37 @@ static void atmel_hlcdc_crtc_atomic_disable(struct drm_crtc *c,
pm_runtime_get_sync(dev->dev);
+ if (crtc->dc->desc->is_xlcdc) {
+ regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_XLCDC_CM);
+ if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
+ !(status & ATMEL_XLCDC_CM),
+ 10, 1000))
+ dev_warn(dev->dev, "Atmel LCDC status register CMSTS timeout\n");
+
+ regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_XLCDC_SD);
+ if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
+ status & ATMEL_XLCDC_SD,
+ 10, 1000))
+ dev_warn(dev->dev, "Atmel LCDC status register SDSTS timeout\n");
+ }
+
regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_HLCDC_DISP);
- while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
- (status & ATMEL_HLCDC_DISP))
- cpu_relax();
+ if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
+ !(status & ATMEL_HLCDC_DISP),
+ 10, 1000))
+ dev_warn(dev->dev, "Atmel LCDC status register DISPSTS timeout\n");
regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_HLCDC_SYNC);
- while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
- (status & ATMEL_HLCDC_SYNC))
- cpu_relax();
+ if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
+ !(status & ATMEL_HLCDC_SYNC),
+ 10, 1000))
+ dev_warn(dev->dev, "Atmel LCDC status register LCDSTS timeout\n");
regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_HLCDC_PIXEL_CLK);
- while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
- (status & ATMEL_HLCDC_PIXEL_CLK))
- cpu_relax();
+ if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
+ !(status & ATMEL_HLCDC_PIXEL_CLK),
+ 10, 1000))
+ dev_warn(dev->dev, "Atmel LCDC status register CLKSTS timeout\n");
clk_disable_unprepare(crtc->dc->hlcdc->sys_clk);
pinctrl_pm_select_sleep_state(dev->dev);
@@ -241,30 +266,95 @@ static void atmel_hlcdc_crtc_atomic_enable(struct drm_crtc *c,
clk_prepare_enable(crtc->dc->hlcdc->sys_clk);
regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_HLCDC_PIXEL_CLK);
- while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
- !(status & ATMEL_HLCDC_PIXEL_CLK))
- cpu_relax();
-
+ if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
+ status & ATMEL_HLCDC_PIXEL_CLK,
+ 10, 1000))
+ dev_warn(dev->dev, "Atmel LCDC status register CLKSTS timeout\n");
regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_HLCDC_SYNC);
- while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
- !(status & ATMEL_HLCDC_SYNC))
- cpu_relax();
+ if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
+ status & ATMEL_HLCDC_SYNC,
+ 10, 1000))
+ dev_warn(dev->dev, "Atmel LCDC status register LCDSTS timeout\n");
regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_HLCDC_DISP);
- while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
- !(status & ATMEL_HLCDC_DISP))
- cpu_relax();
+ if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
+ status & ATMEL_HLCDC_DISP,
+ 10, 1000))
+ dev_warn(dev->dev, "Atmel LCDC status register DISPSTS timeout\n");
+
+ if (crtc->dc->desc->is_xlcdc) {
+ regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_XLCDC_CM);
+ if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
+ status & ATMEL_XLCDC_CM,
+ 10, 1000))
+ dev_warn(dev->dev, "Atmel LCDC status register CMSTS timeout\n");
+
+ regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_XLCDC_SD);
+ if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
+ !(status & ATMEL_XLCDC_SD),
+ 10, 1000))
+ dev_warn(dev->dev, "Atmel LCDC status register SDSTS timeout\n");
+ }
pm_runtime_put_sync(dev->dev);
}
-#define ATMEL_HLCDC_RGB444_OUTPUT BIT(0)
-#define ATMEL_HLCDC_RGB565_OUTPUT BIT(1)
-#define ATMEL_HLCDC_RGB666_OUTPUT BIT(2)
-#define ATMEL_HLCDC_RGB888_OUTPUT BIT(3)
-#define ATMEL_HLCDC_OUTPUT_MODE_MASK GENMASK(3, 0)
+#define ATMEL_HLCDC_RGB444_OUTPUT BIT(0)
+#define ATMEL_HLCDC_RGB565_OUTPUT BIT(1)
+#define ATMEL_HLCDC_RGB666_OUTPUT BIT(2)
+#define ATMEL_HLCDC_RGB888_OUTPUT BIT(3)
+#define ATMEL_HLCDC_DPI_RGB565C1_OUTPUT BIT(4)
+#define ATMEL_HLCDC_DPI_RGB565C2_OUTPUT BIT(5)
+#define ATMEL_HLCDC_DPI_RGB565C3_OUTPUT BIT(6)
+#define ATMEL_HLCDC_DPI_RGB666C1_OUTPUT BIT(7)
+#define ATMEL_HLCDC_DPI_RGB666C2_OUTPUT BIT(8)
+#define ATMEL_HLCDC_DPI_RGB888_OUTPUT BIT(9)
+#define ATMEL_HLCDC_OUTPUT_MODE_MASK GENMASK(3, 0)
+#define ATMEL_XLCDC_OUTPUT_MODE_MASK GENMASK(9, 0)
+
+static int atmel_xlcdc_connector_output_dsi(struct drm_encoder *encoder,
+ struct drm_display_info *info)
+{
+ int j;
+ unsigned int supported_fmts = 0;
+
+ switch (atmel_hlcdc_encoder_get_bus_fmt(encoder)) {
+ case 0:
+ break;
+ case MEDIA_BUS_FMT_RGB565_1X16:
+ return ATMEL_HLCDC_DPI_RGB565C1_OUTPUT;
+ case MEDIA_BUS_FMT_RGB666_1X18:
+ return ATMEL_HLCDC_DPI_RGB666C1_OUTPUT;
+ case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
+ return ATMEL_HLCDC_DPI_RGB666C2_OUTPUT;
+ case MEDIA_BUS_FMT_RGB888_1X24:
+ return ATMEL_HLCDC_DPI_RGB888_OUTPUT;
+ default:
+ return -EINVAL;
+ }
+
+ for (j = 0; j < info->num_bus_formats; j++) {
+ switch (info->bus_formats[j]) {
+ case MEDIA_BUS_FMT_RGB565_1X16:
+ supported_fmts |= ATMEL_HLCDC_DPI_RGB565C1_OUTPUT;
+ break;
+ case MEDIA_BUS_FMT_RGB666_1X18:
+ supported_fmts |= ATMEL_HLCDC_DPI_RGB666C1_OUTPUT;
+ break;
+ case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
+ supported_fmts |= ATMEL_HLCDC_DPI_RGB666C2_OUTPUT;
+ break;
+ case MEDIA_BUS_FMT_RGB888_1X24:
+ supported_fmts |= ATMEL_HLCDC_DPI_RGB888_OUTPUT;
+ break;
+ default:
+ break;
+ }
+ }
+ return supported_fmts;
+}
static int atmel_hlcdc_connector_output_mode(struct drm_connector_state *state)
{
@@ -277,6 +367,13 @@ static int atmel_hlcdc_connector_output_mode(struct drm_connector_state *state)
encoder = state->best_encoder;
if (!encoder)
encoder = connector->encoder;
+ /*
+ * atmel-hlcdc to support DSI formats with DSI video pipeline
+ * when DRM_MODE_ENCODER_DSI type is set by
+ * connector driver component.
+ */
+ if (encoder->encoder_type == DRM_MODE_ENCODER_DSI)
+ return atmel_xlcdc_connector_output_dsi(encoder, info);
switch (atmel_hlcdc_encoder_get_bus_fmt(encoder)) {
case 0:
@@ -317,7 +414,7 @@ static int atmel_hlcdc_connector_output_mode(struct drm_connector_state *state)
static int atmel_hlcdc_crtc_select_output_mode(struct drm_crtc_state *state)
{
- unsigned int output_fmts = ATMEL_HLCDC_OUTPUT_MODE_MASK;
+ unsigned int output_fmts;
struct atmel_hlcdc_crtc_state *hstate;
struct drm_connector_state *cstate;
struct drm_connector *connector;
@@ -325,6 +422,8 @@ static int atmel_hlcdc_crtc_select_output_mode(struct drm_crtc_state *state)
int i;
crtc = drm_crtc_to_atmel_hlcdc_crtc(state->crtc);
+ output_fmts = crtc->dc->desc->is_xlcdc ? ATMEL_XLCDC_OUTPUT_MODE_MASK :
+ ATMEL_HLCDC_OUTPUT_MODE_MASK;
for_each_new_connector_in_state(state->state, connector, cstate, i) {
unsigned int supported_fmts = 0;
@@ -345,7 +444,15 @@ static int atmel_hlcdc_crtc_select_output_mode(struct drm_crtc_state *state)
hstate = drm_crtc_state_to_atmel_hlcdc_crtc_state(state);
hstate->output_mode = fls(output_fmts) - 1;
-
+ if (crtc->dc->desc->is_xlcdc) {
+ /* check if MIPI DPI bit needs to be set */
+ if (fls(output_fmts) > 3) {
+ hstate->output_mode -= 4;
+ hstate->dpi = 1;
+ } else {
+ hstate->dpi = 0;
+ }
+ }
return 0;
}
@@ -449,6 +556,7 @@ static struct drm_crtc_state *
atmel_hlcdc_crtc_duplicate_state(struct drm_crtc *crtc)
{
struct atmel_hlcdc_crtc_state *state, *cur;
+ struct atmel_hlcdc_crtc *c = drm_crtc_to_atmel_hlcdc_crtc(crtc);
if (WARN_ON(!crtc->state))
return NULL;
@@ -460,6 +568,8 @@ atmel_hlcdc_crtc_duplicate_state(struct drm_crtc *crtc)
cur = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state);
state->output_mode = cur->output_mode;
+ if (c->dc->desc->is_xlcdc)
+ state->dpi = cur->dpi;
return &state->base;
}
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
index 84c54e8622d1..9ce429f889ca 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
@@ -58,6 +58,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_at91sam9n12 = {
.conflicting_output_formats = true,
.nlayers = ARRAY_SIZE(atmel_hlcdc_at91sam9n12_layers),
.layers = atmel_hlcdc_at91sam9n12_layers,
+ .ops = &atmel_hlcdc_ops,
};
static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = {
@@ -151,6 +152,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_at91sam9x5 = {
.conflicting_output_formats = true,
.nlayers = ARRAY_SIZE(atmel_hlcdc_at91sam9x5_layers),
.layers = atmel_hlcdc_at91sam9x5_layers,
+ .ops = &atmel_hlcdc_ops,
};
static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
@@ -269,6 +271,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sama5d3 = {
.conflicting_output_formats = true,
.nlayers = ARRAY_SIZE(atmel_hlcdc_sama5d3_layers),
.layers = atmel_hlcdc_sama5d3_layers,
+ .ops = &atmel_hlcdc_ops,
};
static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = {
@@ -364,6 +367,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sama5d4 = {
.max_hpw = 0x3ff,
.nlayers = ARRAY_SIZE(atmel_hlcdc_sama5d4_layers),
.layers = atmel_hlcdc_sama5d4_layers,
+ .ops = &atmel_hlcdc_ops,
};
static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sam9x60_layers[] = {
@@ -460,6 +464,103 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sam9x60 = {
.fixed_clksrc = true,
.nlayers = ARRAY_SIZE(atmel_hlcdc_sam9x60_layers),
.layers = atmel_hlcdc_sam9x60_layers,
+ .ops = &atmel_hlcdc_ops,
+};
+
+static const struct atmel_hlcdc_layer_desc atmel_xlcdc_sam9x75_layers[] = {
+ {
+ .name = "base",
+ .formats = &atmel_hlcdc_plane_rgb_formats,
+ .regs_offset = 0x60,
+ .id = 0,
+ .type = ATMEL_HLCDC_BASE_LAYER,
+ .cfgs_offset = 0x1c,
+ .layout = {
+ .xstride = { 2 },
+ .default_color = 3,
+ .general_config = 4,
+ .disc_pos = 5,
+ .disc_size = 6,
+ },
+ .clut_offset = 0x700,
+ },
+ {
+ .name = "overlay1",
+ .formats = &atmel_hlcdc_plane_rgb_formats,
+ .regs_offset = 0x160,
+ .id = 1,
+ .type = ATMEL_HLCDC_OVERLAY_LAYER,
+ .cfgs_offset = 0x1c,
+ .layout = {
+ .pos = 2,
+ .size = 3,
+ .xstride = { 4 },
+ .pstride = { 5 },
+ .default_color = 6,
+ .chroma_key = 7,
+ .chroma_key_mask = 8,
+ .general_config = 9,
+ },
+ .clut_offset = 0xb00,
+ },
+ {
+ .name = "overlay2",
+ .formats = &atmel_hlcdc_plane_rgb_formats,
+ .regs_offset = 0x260,
+ .id = 2,
+ .type = ATMEL_HLCDC_OVERLAY_LAYER,
+ .cfgs_offset = 0x1c,
+ .layout = {
+ .pos = 2,
+ .size = 3,
+ .xstride = { 4 },
+ .pstride = { 5 },
+ .default_color = 6,
+ .chroma_key = 7,
+ .chroma_key_mask = 8,
+ .general_config = 9,
+ },
+ .clut_offset = 0xf00,
+ },
+ {
+ .name = "high-end-overlay",
+ .formats = &atmel_hlcdc_plane_rgb_and_yuv_formats,
+ .regs_offset = 0x360,
+ .id = 3,
+ .type = ATMEL_HLCDC_OVERLAY_LAYER,
+ .cfgs_offset = 0x30,
+ .layout = {
+ .pos = 2,
+ .size = 3,
+ .memsize = 4,
+ .xstride = { 5, 7 },
+ .pstride = { 6, 8 },
+ .default_color = 9,
+ .chroma_key = 10,
+ .chroma_key_mask = 11,
+ .general_config = 12,
+ .csc = 16,
+ .scaler_config = 23,
+ .vxs_config = 30,
+ .hxs_config = 31,
+ },
+ .clut_offset = 0x1300,
+ },
+};
+
+static const struct atmel_hlcdc_dc_desc atmel_xlcdc_dc_sam9x75 = {
+ .min_width = 0,
+ .min_height = 0,
+ .max_width = 2048,
+ .max_height = 2048,
+ .max_spw = 0x3ff,
+ .max_vpw = 0x3ff,
+ .max_hpw = 0x3ff,
+ .fixed_clksrc = true,
+ .is_xlcdc = true,
+ .nlayers = ARRAY_SIZE(atmel_xlcdc_sam9x75_layers),
+ .layers = atmel_xlcdc_sam9x75_layers,
+ .ops = &atmel_xlcdc_ops,
};
static const struct of_device_id atmel_hlcdc_of_match[] = {
@@ -487,6 +588,10 @@ static const struct of_device_id atmel_hlcdc_of_match[] = {
.compatible = "microchip,sam9x60-hlcdc",
.data = &atmel_hlcdc_dc_sam9x60,
},
+ {
+ .compatible = "microchip,sam9x75-xlcdc",
+ .data = &atmel_xlcdc_dc_sam9x75,
+ },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, atmel_hlcdc_of_match);
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
index 5b5c774e0edf..e1a0bb24b511 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
@@ -15,6 +15,7 @@
#include <drm/drm_plane.h>
+/* LCD controller common registers */
#define ATMEL_HLCDC_LAYER_CHER 0x0
#define ATMEL_HLCDC_LAYER_CHDR 0x4
#define ATMEL_HLCDC_LAYER_CHSR 0x8
@@ -128,6 +129,47 @@
#define ATMEL_HLCDC_MAX_LAYERS 6
+/* XLCDC controller specific registers */
+#define ATMEL_XLCDC_LAYER_ENR 0x10
+#define ATMEL_XLCDC_LAYER_EN BIT(0)
+
+#define ATMEL_XLCDC_LAYER_IER 0x0
+#define ATMEL_XLCDC_LAYER_IDR 0x4
+#define ATMEL_XLCDC_LAYER_ISR 0xc
+#define ATMEL_XLCDC_LAYER_OVR_IRQ(p) BIT(2 + (8 * (p)))
+
+#define ATMEL_XLCDC_LAYER_PLANE_ADDR(p) (((p) * 0x4) + 0x18)
+
+#define ATMEL_XLCDC_LAYER_DMA_CFG 0
+
+#define ATMEL_XLCDC_LAYER_DMA BIT(0)
+#define ATMEL_XLCDC_LAYER_REP BIT(1)
+#define ATMEL_XLCDC_LAYER_DISCEN BIT(4)
+
+#define ATMEL_XLCDC_LAYER_SFACTC_A0_MULT_AS (4 << 6)
+#define ATMEL_XLCDC_LAYER_SFACTA_ONE BIT(9)
+#define ATMEL_XLCDC_LAYER_DFACTC_M_A0_MULT_AS (6 << 11)
+#define ATMEL_XLCDC_LAYER_DFACTA_ONE BIT(14)
+
+#define ATMEL_XLCDC_LAYER_A0_SHIFT 16
+#define ATMEL_XLCDC_LAYER_A0(x) \
+ ((x) << ATMEL_XLCDC_LAYER_A0_SHIFT)
+
+#define ATMEL_XLCDC_LAYER_VSCALER_LUMA_ENABLE BIT(0)
+#define ATMEL_XLCDC_LAYER_VSCALER_CHROMA_ENABLE BIT(1)
+#define ATMEL_XLCDC_LAYER_HSCALER_LUMA_ENABLE BIT(4)
+#define ATMEL_XLCDC_LAYER_HSCALER_CHROMA_ENABLE BIT(5)
+
+#define ATMEL_XLCDC_LAYER_VXSYCFG_ONE BIT(0)
+#define ATMEL_XLCDC_LAYER_VXSYTAP2_ENABLE BIT(4)
+#define ATMEL_XLCDC_LAYER_VXSCCFG_ONE BIT(16)
+#define ATMEL_XLCDC_LAYER_VXSCTAP2_ENABLE BIT(20)
+
+#define ATMEL_XLCDC_LAYER_HXSYCFG_ONE BIT(0)
+#define ATMEL_XLCDC_LAYER_HXSYTAP2_ENABLE BIT(4)
+#define ATMEL_XLCDC_LAYER_HXSCCFG_ONE BIT(16)
+#define ATMEL_XLCDC_LAYER_HXSCTAP2_ENABLE BIT(20)
+
/**
* Atmel HLCDC Layer registers layout structure
*
@@ -156,6 +198,8 @@
* @disc_pos: discard area position register
* @disc_size: discard area size register
* @csc: color space conversion register
+ * @vxs_config: vertical scalar filter taps control register
+ * @hxs_config: horizontal scalar filter taps control register
*/
struct atmel_hlcdc_layer_cfg_layout {
int xstride[ATMEL_HLCDC_LAYER_MAX_PLANES];
@@ -175,6 +219,8 @@ struct atmel_hlcdc_layer_cfg_layout {
int disc_pos;
int disc_size;
int csc;
+ int vxs_config;
+ int hxs_config;
};
/**
@@ -289,6 +335,64 @@ atmel_hlcdc_layer_to_plane(struct atmel_hlcdc_layer *layer)
}
/**
+ * struct atmel_hlcdc_dc - Atmel HLCDC Display Controller.
+ * @desc: HLCDC Display Controller description
+ * @dscrpool: DMA coherent pool used to allocate DMA descriptors
+ * @hlcdc: pointer to the atmel_hlcdc structure provided by the MFD device
+ * @crtc: CRTC provided by the display controller
+ * @layers: active HLCDC layers
+ * @suspend: used to store the HLCDC state when entering suspend
+ * @suspend.imr: used to read/write LCDC Interrupt Mask Register
+ * @suspend.state: Atomic commit structure
+ */
+struct atmel_hlcdc_dc {
+ const struct atmel_hlcdc_dc_desc *desc;
+ struct dma_pool *dscrpool;
+ struct atmel_hlcdc *hlcdc;
+ struct drm_crtc *crtc;
+ struct atmel_hlcdc_layer *layers[ATMEL_HLCDC_MAX_LAYERS];
+ struct {
+ u32 imr;
+ struct drm_atomic_state *state;
+ } suspend;
+};
+
+struct atmel_hlcdc_plane_state;
+
+/**
+ * struct atmel_lcdc_dc_ops - describes atmel_lcdc ops group
+ * to differentiate HLCDC and XLCDC IP code support
+ * @plane_setup_scaler: update the vertical and horizontal scaling factors
+ * @update_lcdc_buffers: update the each LCDC layers DMA registers
+ * @lcdc_atomic_disable: disable LCDC interrupts and layers
+ * @lcdc_update_general_settings: update each LCDC layers general
+ * configuration register
+ * @lcdc_atomic_update: enable the LCDC layers and interrupts
+ * @lcdc_csc_init: update the color space conversion co-efficient of
+ * High-end overlay register
+ * @lcdc_irq_dbg: to raise alert incase of interrupt overrun in any LCDC layer
+ */
+struct atmel_lcdc_dc_ops {
+ void (*plane_setup_scaler)(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_plane_state *state);
+ void (*lcdc_update_buffers)(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_plane_state *state,
+ u32 sr, int i);
+ void (*lcdc_atomic_disable)(struct atmel_hlcdc_plane *plane);
+ void (*lcdc_update_general_settings)(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_plane_state *state);
+ void (*lcdc_atomic_update)(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_dc *dc);
+ void (*lcdc_csc_init)(struct atmel_hlcdc_plane *plane,
+ const struct atmel_hlcdc_layer_desc *desc);
+ void (*lcdc_irq_dbg)(struct atmel_hlcdc_plane *plane,
+ const struct atmel_hlcdc_layer_desc *desc);
+};
+
+extern const struct atmel_lcdc_dc_ops atmel_hlcdc_ops;
+extern const struct atmel_lcdc_dc_ops atmel_xlcdc_ops;
+
+/**
* Atmel HLCDC Display Controller description structure.
*
* This structure describes the HLCDC IP capabilities and depends on the
@@ -304,8 +408,10 @@ atmel_hlcdc_layer_to_plane(struct atmel_hlcdc_layer *layer)
* @conflicting_output_formats: true if RGBXXX output formats conflict with
* each other.
* @fixed_clksrc: true if clock source is fixed
+ * @is_xlcdc: true if XLCDC IP is supported
* @layers: a layer description table describing available layers
* @nlayers: layer description table size
+ * @ops: atmel lcdc dc ops
*/
struct atmel_hlcdc_dc_desc {
int min_width;
@@ -317,32 +423,10 @@ struct atmel_hlcdc_dc_desc {
int max_hpw;
bool conflicting_output_formats;
bool fixed_clksrc;
+ bool is_xlcdc;
const struct atmel_hlcdc_layer_desc *layers;
int nlayers;
-};
-
-/**
- * Atmel HLCDC Display Controller.
- *
- * @desc: HLCDC Display Controller description
- * @dscrpool: DMA coherent pool used to allocate DMA descriptors
- * @hlcdc: pointer to the atmel_hlcdc structure provided by the MFD device
- * @fbdev: framebuffer device attached to the Display Controller
- * @crtc: CRTC provided by the display controller
- * @planes: instantiated planes
- * @layers: active HLCDC layers
- * @suspend: used to store the HLCDC state when entering suspend
- */
-struct atmel_hlcdc_dc {
- const struct atmel_hlcdc_dc_desc *desc;
- struct dma_pool *dscrpool;
- struct atmel_hlcdc *hlcdc;
- struct drm_crtc *crtc;
- struct atmel_hlcdc_layer *layers[ATMEL_HLCDC_MAX_LAYERS];
- struct {
- u32 imr;
- struct drm_atomic_state *state;
- } suspend;
+ const struct atmel_lcdc_dc_ops *ops;
};
extern struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_formats;
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
index daa508504f47..4a7ba0918eca 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
@@ -282,8 +282,9 @@ atmel_hlcdc_plane_scaler_set_phicoeff(struct atmel_hlcdc_plane *plane,
coeff_tab[i]);
}
-static void atmel_hlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
- struct atmel_hlcdc_plane_state *state)
+static
+void atmel_hlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_plane_state *state)
{
const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
u32 xfactor, yfactor;
@@ -330,11 +331,61 @@ static void atmel_hlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
yfactor));
}
+static
+void atmel_xlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_plane_state *state)
+{
+ const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
+ u32 xfactor, yfactor;
+
+ if (!desc->layout.scaler_config)
+ return;
+
+ if (state->crtc_w == state->src_w && state->crtc_h == state->src_h) {
+ atmel_hlcdc_layer_write_cfg(&plane->layer,
+ desc->layout.scaler_config, 0);
+ return;
+ }
+
+ /* xfactor = round[(2^20 * XMEMSIZE)/XSIZE)] */
+ xfactor = (u32)(((1 << 20) * state->src_w) / state->crtc_w);
+
+ /* yfactor = round[(2^20 * YMEMSIZE)/YSIZE)] */
+ yfactor = (u32)(((1 << 20) * state->src_h) / state->crtc_h);
+
+ atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config,
+ ATMEL_XLCDC_LAYER_VSCALER_LUMA_ENABLE |
+ ATMEL_XLCDC_LAYER_VSCALER_CHROMA_ENABLE |
+ ATMEL_XLCDC_LAYER_HSCALER_LUMA_ENABLE |
+ ATMEL_XLCDC_LAYER_HSCALER_CHROMA_ENABLE);
+
+ atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 1,
+ yfactor);
+ atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 3,
+ xfactor);
+
+ /*
+ * With YCbCr 4:2:2 and YCbYcr 4:2:0 window resampling, configuration
+ * register LCDC_HEOCFG25.VXSCFACT and LCDC_HEOCFG27.HXSCFACT is half
+ * the value of yfactor and xfactor.
+ */
+ if (state->base.fb->format->format == DRM_FORMAT_YUV420) {
+ yfactor /= 2;
+ xfactor /= 2;
+ }
+
+ atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 2,
+ yfactor);
+ atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 4,
+ xfactor);
+}
+
static void
atmel_hlcdc_plane_update_pos_and_size(struct atmel_hlcdc_plane *plane,
struct atmel_hlcdc_plane_state *state)
{
const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
+ struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
if (desc->layout.size)
atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.size,
@@ -352,12 +403,12 @@ atmel_hlcdc_plane_update_pos_and_size(struct atmel_hlcdc_plane *plane,
ATMEL_HLCDC_LAYER_POS(state->crtc_x,
state->crtc_y));
- atmel_hlcdc_plane_setup_scaler(plane, state);
+ dc->desc->ops->plane_setup_scaler(plane, state);
}
-static void
-atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
- struct atmel_hlcdc_plane_state *state)
+static
+void atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_plane_state *state)
{
unsigned int cfg = ATMEL_HLCDC_LAYER_DMA_BLEN_INCR16 | state->ahb_id;
const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
@@ -393,6 +444,40 @@ atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
cfg);
}
+static
+void atmel_xlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_plane_state *state)
+{
+ const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
+ const struct drm_format_info *format = state->base.fb->format;
+ unsigned int cfg;
+
+ atmel_hlcdc_layer_write_cfg(&plane->layer, ATMEL_XLCDC_LAYER_DMA_CFG,
+ ATMEL_HLCDC_LAYER_DMA_BLEN_INCR16 | state->ahb_id);
+
+ cfg = ATMEL_XLCDC_LAYER_DMA | ATMEL_XLCDC_LAYER_REP;
+
+ if (plane->base.type != DRM_PLANE_TYPE_PRIMARY) {
+ /*
+ * Alpha Blending bits specific to SAM9X7 SoC
+ */
+ cfg |= ATMEL_XLCDC_LAYER_SFACTC_A0_MULT_AS |
+ ATMEL_XLCDC_LAYER_SFACTA_ONE |
+ ATMEL_XLCDC_LAYER_DFACTC_M_A0_MULT_AS |
+ ATMEL_XLCDC_LAYER_DFACTA_ONE;
+ if (format->has_alpha)
+ cfg |= ATMEL_XLCDC_LAYER_A0(0xff);
+ else
+ cfg |= ATMEL_XLCDC_LAYER_A0(state->base.alpha);
+ }
+
+ if (state->disc_h && state->disc_w)
+ cfg |= ATMEL_XLCDC_LAYER_DISCEN;
+
+ atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.general_config,
+ cfg);
+}
+
static void atmel_hlcdc_plane_update_format(struct atmel_hlcdc_plane *plane,
struct atmel_hlcdc_plane_state *state)
{
@@ -437,36 +522,55 @@ static void atmel_hlcdc_plane_update_clut(struct atmel_hlcdc_plane *plane,
}
}
+static void atmel_hlcdc_update_buffers(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_plane_state *state,
+ u32 sr, int i)
+{
+ atmel_hlcdc_layer_write_reg(&plane->layer,
+ ATMEL_HLCDC_LAYER_PLANE_HEAD(i),
+ state->dscrs[i]->self);
+
+ if (sr & ATMEL_HLCDC_LAYER_EN)
+ return;
+
+ atmel_hlcdc_layer_write_reg(&plane->layer,
+ ATMEL_HLCDC_LAYER_PLANE_ADDR(i),
+ state->dscrs[i]->addr);
+ atmel_hlcdc_layer_write_reg(&plane->layer,
+ ATMEL_HLCDC_LAYER_PLANE_CTRL(i),
+ state->dscrs[i]->ctrl);
+ atmel_hlcdc_layer_write_reg(&plane->layer,
+ ATMEL_HLCDC_LAYER_PLANE_NEXT(i),
+ state->dscrs[i]->self);
+}
+
+static void atmel_xlcdc_update_buffers(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_plane_state *state,
+ u32 sr, int i)
+{
+ atmel_hlcdc_layer_write_reg(&plane->layer,
+ ATMEL_XLCDC_LAYER_PLANE_ADDR(i),
+ state->dscrs[i]->addr);
+}
+
static void atmel_hlcdc_plane_update_buffers(struct atmel_hlcdc_plane *plane,
- struct atmel_hlcdc_plane_state *state)
+ struct atmel_hlcdc_plane_state *state)
{
const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
+ struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
struct drm_framebuffer *fb = state->base.fb;
u32 sr;
int i;
- sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR);
+ if (!dc->desc->is_xlcdc)
+ sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR);
for (i = 0; i < state->nplanes; i++) {
struct drm_gem_dma_object *gem = drm_fb_dma_get_gem_obj(fb, i);
state->dscrs[i]->addr = gem->dma_addr + state->offsets[i];
- atmel_hlcdc_layer_write_reg(&plane->layer,
- ATMEL_HLCDC_LAYER_PLANE_HEAD(i),
- state->dscrs[i]->self);
-
- if (!(sr & ATMEL_HLCDC_LAYER_EN)) {
- atmel_hlcdc_layer_write_reg(&plane->layer,
- ATMEL_HLCDC_LAYER_PLANE_ADDR(i),
- state->dscrs[i]->addr);
- atmel_hlcdc_layer_write_reg(&plane->layer,
- ATMEL_HLCDC_LAYER_PLANE_CTRL(i),
- state->dscrs[i]->ctrl);
- atmel_hlcdc_layer_write_reg(&plane->layer,
- ATMEL_HLCDC_LAYER_PLANE_NEXT(i),
- state->dscrs[i]->self);
- }
+ dc->desc->ops->lcdc_update_buffers(plane, state, sr, i);
if (desc->layout.xstride[i])
atmel_hlcdc_layer_write_cfg(&plane->layer,
@@ -712,11 +816,8 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p,
return 0;
}
-static void atmel_hlcdc_plane_atomic_disable(struct drm_plane *p,
- struct drm_atomic_state *state)
+static void atmel_hlcdc_atomic_disable(struct atmel_hlcdc_plane *plane)
{
- struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
-
/* Disable interrupts */
atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_IDR,
0xffffffff);
@@ -731,6 +832,70 @@ static void atmel_hlcdc_plane_atomic_disable(struct drm_plane *p,
atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_ISR);
}
+static void atmel_xlcdc_atomic_disable(struct atmel_hlcdc_plane *plane)
+{
+ /* Disable interrupts */
+ atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_XLCDC_LAYER_IDR,
+ 0xffffffff);
+
+ /* Disable the layer */
+ atmel_hlcdc_layer_write_reg(&plane->layer,
+ ATMEL_XLCDC_LAYER_ENR, 0);
+
+ /* Clear all pending interrupts */
+ atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_XLCDC_LAYER_ISR);
+}
+
+static void atmel_hlcdc_plane_atomic_disable(struct drm_plane *p,
+ struct drm_atomic_state *state)
+{
+ struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
+ struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
+
+ dc->desc->ops->lcdc_atomic_disable(plane);
+}
+
+static void atmel_hlcdc_atomic_update(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_dc *dc)
+{
+ u32 sr;
+
+ /* Enable the overrun interrupts. */
+ atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_IER,
+ ATMEL_HLCDC_LAYER_OVR_IRQ(0) |
+ ATMEL_HLCDC_LAYER_OVR_IRQ(1) |
+ ATMEL_HLCDC_LAYER_OVR_IRQ(2));
+
+ /* Apply the new config at the next SOF event. */
+ sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR);
+ atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHER,
+ ATMEL_HLCDC_LAYER_UPDATE |
+ (sr & ATMEL_HLCDC_LAYER_EN ?
+ ATMEL_HLCDC_LAYER_A2Q : ATMEL_HLCDC_LAYER_EN));
+}
+
+static void atmel_xlcdc_atomic_update(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_dc *dc)
+{
+ /* Enable the overrun interrupts. */
+ atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_XLCDC_LAYER_IER,
+ ATMEL_XLCDC_LAYER_OVR_IRQ(0) |
+ ATMEL_XLCDC_LAYER_OVR_IRQ(1) |
+ ATMEL_XLCDC_LAYER_OVR_IRQ(2));
+
+ atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_XLCDC_LAYER_ENR,
+ ATMEL_XLCDC_LAYER_EN);
+
+ /*
+ * Updating XLCDC_xxxCFGx, XLCDC_xxxFBA and XLCDC_xxxEN,
+ * (where xxx indicates each layer) requires writing one to the
+ * Update Attribute field for each layer in LCDC_ATTRE register for SAM9X7.
+ */
+ regmap_write(dc->hlcdc->regmap, ATMEL_XLCDC_ATTRE, ATMEL_XLCDC_BASE_UPDATE |
+ ATMEL_XLCDC_OVR1_UPDATE | ATMEL_XLCDC_OVR3_UPDATE |
+ ATMEL_XLCDC_HEO_UPDATE);
+}
+
static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p,
struct drm_atomic_state *state)
{
@@ -739,7 +904,7 @@ static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p,
struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
struct atmel_hlcdc_plane_state *hstate =
drm_plane_state_to_atmel_hlcdc_plane_state(new_s);
- u32 sr;
+ struct atmel_hlcdc_dc *dc = p->dev->dev_private;
if (!new_s->crtc || !new_s->fb)
return;
@@ -750,29 +915,83 @@ static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p,
}
atmel_hlcdc_plane_update_pos_and_size(plane, hstate);
- atmel_hlcdc_plane_update_general_settings(plane, hstate);
+ dc->desc->ops->lcdc_update_general_settings(plane, hstate);
atmel_hlcdc_plane_update_format(plane, hstate);
atmel_hlcdc_plane_update_clut(plane, hstate);
atmel_hlcdc_plane_update_buffers(plane, hstate);
atmel_hlcdc_plane_update_disc_area(plane, hstate);
- /* Enable the overrun interrupts. */
- atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_IER,
- ATMEL_HLCDC_LAYER_OVR_IRQ(0) |
- ATMEL_HLCDC_LAYER_OVR_IRQ(1) |
- ATMEL_HLCDC_LAYER_OVR_IRQ(2));
+ dc->desc->ops->lcdc_atomic_update(plane, dc);
+}
- /* Apply the new config at the next SOF event. */
- sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR);
- atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHER,
- ATMEL_HLCDC_LAYER_UPDATE |
- (sr & ATMEL_HLCDC_LAYER_EN ?
- ATMEL_HLCDC_LAYER_A2Q : ATMEL_HLCDC_LAYER_EN));
+static void atmel_hlcdc_csc_init(struct atmel_hlcdc_plane *plane,
+ const struct atmel_hlcdc_layer_desc *desc)
+{
+ /*
+ * TODO: declare a "yuv-to-rgb-conv-factors" property to let
+ * userspace modify these factors (using a BLOB property ?).
+ */
+ static const u32 hlcdc_csc_coeffs[] = {
+ 0x4c900091,
+ 0x7a5f5090,
+ 0x40040890
+ };
+
+ for (int i = 0; i < ARRAY_SIZE(hlcdc_csc_coeffs); i++) {
+ atmel_hlcdc_layer_write_cfg(&plane->layer,
+ desc->layout.csc + i,
+ hlcdc_csc_coeffs[i]);
+ }
+}
+
+static void atmel_xlcdc_csc_init(struct atmel_hlcdc_plane *plane,
+ const struct atmel_hlcdc_layer_desc *desc)
+{
+ /*
+ * yuv-to-rgb-conv-factors are now defined from LCDC_HEOCFG16 to
+ * LCDC_HEOCFG21 registers in SAM9X7.
+ */
+ static const u32 xlcdc_csc_coeffs[] = {
+ 0x00000488,
+ 0x00000648,
+ 0x1EA00480,
+ 0x00001D28,
+ 0x08100480,
+ 0x00000000,
+ 0x00000007
+ };
+
+ for (int i = 0; i < ARRAY_SIZE(xlcdc_csc_coeffs); i++) {
+ atmel_hlcdc_layer_write_cfg(&plane->layer,
+ desc->layout.csc + i,
+ xlcdc_csc_coeffs[i]);
+ }
+
+ if (desc->layout.vxs_config && desc->layout.hxs_config) {
+ /*
+ * Updating vxs.config and hxs.config fixes the
+ * Green Color Issue in SAM9X7 EGT Video Player App
+ */
+ atmel_hlcdc_layer_write_cfg(&plane->layer,
+ desc->layout.vxs_config,
+ ATMEL_XLCDC_LAYER_VXSYCFG_ONE |
+ ATMEL_XLCDC_LAYER_VXSYTAP2_ENABLE |
+ ATMEL_XLCDC_LAYER_VXSCCFG_ONE |
+ ATMEL_XLCDC_LAYER_VXSCTAP2_ENABLE);
+
+ atmel_hlcdc_layer_write_cfg(&plane->layer,
+ desc->layout.hxs_config,
+ ATMEL_XLCDC_LAYER_HXSYCFG_ONE |
+ ATMEL_XLCDC_LAYER_HXSYTAP2_ENABLE |
+ ATMEL_XLCDC_LAYER_HXSCCFG_ONE |
+ ATMEL_XLCDC_LAYER_HXSCTAP2_ENABLE);
+ }
}
static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane)
{
const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
+ struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
if (desc->type == ATMEL_HLCDC_OVERLAY_LAYER ||
desc->type == ATMEL_HLCDC_CURSOR_LAYER) {
@@ -796,31 +1015,16 @@ static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane)
return ret;
}
- if (desc->layout.csc) {
- /*
- * TODO: decare a "yuv-to-rgb-conv-factors" property to let
- * userspace modify these factors (using a BLOB property ?).
- */
- atmel_hlcdc_layer_write_cfg(&plane->layer,
- desc->layout.csc,
- 0x4c900091);
- atmel_hlcdc_layer_write_cfg(&plane->layer,
- desc->layout.csc + 1,
- 0x7a5f5090);
- atmel_hlcdc_layer_write_cfg(&plane->layer,
- desc->layout.csc + 2,
- 0x40040890);
- }
+ if (desc->layout.csc)
+ dc->desc->ops->lcdc_csc_init(plane, desc);
return 0;
}
-void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane)
+static void atmel_hlcdc_irq_dbg(struct atmel_hlcdc_plane *plane,
+ const struct atmel_hlcdc_layer_desc *desc)
{
- const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
- u32 isr;
-
- isr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_ISR);
+ u32 isr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_ISR);
/*
* There's not much we can do in case of overrun except informing
@@ -834,6 +1038,51 @@ void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane)
desc->name);
}
+static void atmel_xlcdc_irq_dbg(struct atmel_hlcdc_plane *plane,
+ const struct atmel_hlcdc_layer_desc *desc)
+{
+ u32 isr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_XLCDC_LAYER_ISR);
+
+ /*
+ * There's not much we can do in case of overrun except informing
+ * the user. However, we are in interrupt context here, hence the
+ * use of dev_dbg().
+ */
+ if (isr &
+ (ATMEL_XLCDC_LAYER_OVR_IRQ(0) | ATMEL_XLCDC_LAYER_OVR_IRQ(1) |
+ ATMEL_XLCDC_LAYER_OVR_IRQ(2)))
+ dev_dbg(plane->base.dev->dev, "overrun on plane %s\n",
+ desc->name);
+}
+
+void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane)
+{
+ const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
+ struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
+
+ dc->desc->ops->lcdc_irq_dbg(plane, desc);
+}
+
+const struct atmel_lcdc_dc_ops atmel_hlcdc_ops = {
+ .plane_setup_scaler = atmel_hlcdc_plane_setup_scaler,
+ .lcdc_update_buffers = atmel_hlcdc_update_buffers,
+ .lcdc_atomic_disable = atmel_hlcdc_atomic_disable,
+ .lcdc_update_general_settings = atmel_hlcdc_plane_update_general_settings,
+ .lcdc_atomic_update = atmel_hlcdc_atomic_update,
+ .lcdc_csc_init = atmel_hlcdc_csc_init,
+ .lcdc_irq_dbg = atmel_hlcdc_irq_dbg,
+};
+
+const struct atmel_lcdc_dc_ops atmel_xlcdc_ops = {
+ .plane_setup_scaler = atmel_xlcdc_plane_setup_scaler,
+ .lcdc_update_buffers = atmel_xlcdc_update_buffers,
+ .lcdc_atomic_disable = atmel_xlcdc_atomic_disable,
+ .lcdc_update_general_settings = atmel_xlcdc_plane_update_general_settings,
+ .lcdc_atomic_update = atmel_xlcdc_atomic_update,
+ .lcdc_csc_init = atmel_xlcdc_csc_init,
+ .lcdc_irq_dbg = atmel_xlcdc_irq_dbg,
+};
+
static const struct drm_plane_helper_funcs atmel_hlcdc_layer_plane_helper_funcs = {
.atomic_check = atmel_hlcdc_plane_atomic_check,
.atomic_update = atmel_hlcdc_plane_atomic_update,
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index 66ccb61e2a66..3cd130965e9d 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -877,11 +877,6 @@ static int adv7511_connector_init(struct adv7511 *adv)
struct drm_bridge *bridge = &adv->bridge;
int ret;
- if (!bridge->encoder) {
- DRM_ERROR("Parent encoder object not found");
- return -ENODEV;
- }
-
if (adv->i2c_main->irq)
adv->connector.polled = DRM_CONNECTOR_POLL_HPD;
else
diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
index c9e35731e6a1..b754947e3e00 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
@@ -47,7 +47,7 @@ struct anx6345 {
struct drm_dp_aux aux;
struct drm_bridge bridge;
struct i2c_client *client;
- struct edid *edid;
+ const struct drm_edid *drm_edid;
struct drm_connector connector;
struct drm_panel *panel;
struct regulator *dvdd12;
@@ -458,7 +458,7 @@ static int anx6345_get_modes(struct drm_connector *connector)
mutex_lock(&anx6345->lock);
- if (!anx6345->edid) {
+ if (!anx6345->drm_edid) {
if (!anx6345->powered) {
anx6345_poweron(anx6345);
power_off = true;
@@ -470,19 +470,18 @@ static int anx6345_get_modes(struct drm_connector *connector)
goto unlock;
}
- anx6345->edid = drm_get_edid(connector, &anx6345->aux.ddc);
- if (!anx6345->edid)
+ anx6345->drm_edid = drm_edid_read_ddc(connector, &anx6345->aux.ddc);
+ if (!anx6345->drm_edid)
DRM_ERROR("Failed to read EDID from panel\n");
- err = drm_connector_update_edid_property(connector,
- anx6345->edid);
+ err = drm_edid_connector_update(connector, anx6345->drm_edid);
if (err) {
DRM_ERROR("Failed to update EDID property: %d\n", err);
goto unlock;
}
}
- num_modes += drm_add_edid_modes(connector, anx6345->edid);
+ num_modes += drm_edid_connector_add_modes(connector);
/* Driver currently supports only 6bpc */
connector->display_info.bpc = 6;
@@ -528,11 +527,6 @@ static int anx6345_bridge_attach(struct drm_bridge *bridge,
return -EINVAL;
}
- if (!bridge->encoder) {
- DRM_ERROR("Parent encoder object not found");
- return -ENODEV;
- }
-
/* Register aux channel */
anx6345->aux.name = "DP-AUX";
anx6345->aux.dev = &anx6345->client->dev;
@@ -793,7 +787,7 @@ static void anx6345_i2c_remove(struct i2c_client *client)
unregister_i2c_dummy_clients(anx6345);
- kfree(anx6345->edid);
+ drm_edid_free(anx6345->drm_edid);
mutex_destroy(&anx6345->lock);
}
diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
index 5748a8581af4..f74694bb9c50 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
@@ -67,7 +67,7 @@ struct anx78xx {
struct drm_dp_aux aux;
struct drm_bridge bridge;
struct i2c_client *client;
- struct edid *edid;
+ const struct drm_edid *drm_edid;
struct drm_connector connector;
struct anx78xx_platform_data pdata;
struct mutex lock;
@@ -830,8 +830,8 @@ static int anx78xx_get_modes(struct drm_connector *connector)
if (WARN_ON(!anx78xx->powered))
return 0;
- if (anx78xx->edid)
- return drm_add_edid_modes(connector, anx78xx->edid);
+ if (anx78xx->drm_edid)
+ return drm_edid_connector_add_modes(connector);
mutex_lock(&anx78xx->lock);
@@ -841,20 +841,21 @@ static int anx78xx_get_modes(struct drm_connector *connector)
goto unlock;
}
- anx78xx->edid = drm_get_edid(connector, &anx78xx->aux.ddc);
- if (!anx78xx->edid) {
+ anx78xx->drm_edid = drm_edid_read_ddc(connector, &anx78xx->aux.ddc);
+
+ err = drm_edid_connector_update(connector, anx78xx->drm_edid);
+
+ if (!anx78xx->drm_edid) {
DRM_ERROR("Failed to read EDID\n");
goto unlock;
}
- err = drm_connector_update_edid_property(connector,
- anx78xx->edid);
if (err) {
DRM_ERROR("Failed to update EDID property: %d\n", err);
goto unlock;
}
- num_modes = drm_add_edid_modes(connector, anx78xx->edid);
+ num_modes = drm_edid_connector_add_modes(connector);
unlock:
mutex_unlock(&anx78xx->lock);
@@ -897,11 +898,6 @@ static int anx78xx_bridge_attach(struct drm_bridge *bridge,
return -EINVAL;
}
- if (!bridge->encoder) {
- DRM_ERROR("Parent encoder object not found");
- return -ENODEV;
- }
-
/* Register aux channel */
anx78xx->aux.name = "DP-AUX";
anx78xx->aux.dev = &anx78xx->client->dev;
@@ -1091,8 +1087,8 @@ static bool anx78xx_handle_common_int_4(struct anx78xx *anx78xx, u8 irq)
event = true;
anx78xx_poweroff(anx78xx);
/* Free cached EDID */
- kfree(anx78xx->edid);
- anx78xx->edid = NULL;
+ drm_edid_free(anx78xx->drm_edid);
+ anx78xx->drm_edid = NULL;
} else if (irq & SP_HPD_PLUG) {
DRM_DEBUG_KMS("IRQ: Hot plug detect - cable plug\n");
event = true;
@@ -1363,7 +1359,7 @@ static void anx78xx_i2c_remove(struct i2c_client *client)
unregister_i2c_dummy_clients(anx78xx);
- kfree(anx78xx->edid);
+ drm_edid_free(anx78xx->drm_edid);
}
static const struct of_device_id anx78xx_match_table[] = {
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index df9370e0ff23..b5dbff21c187 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -234,28 +234,6 @@ static int analogix_dp_training_pattern_dis(struct analogix_dp_device *dp)
return ret < 0 ? ret : 0;
}
-static void
-analogix_dp_set_lane_lane_pre_emphasis(struct analogix_dp_device *dp,
- int pre_emphasis, int lane)
-{
- switch (lane) {
- case 0:
- analogix_dp_set_lane0_pre_emphasis(dp, pre_emphasis);
- break;
- case 1:
- analogix_dp_set_lane1_pre_emphasis(dp, pre_emphasis);
- break;
-
- case 2:
- analogix_dp_set_lane2_pre_emphasis(dp, pre_emphasis);
- break;
-
- case 3:
- analogix_dp_set_lane3_pre_emphasis(dp, pre_emphasis);
- break;
- }
-}
-
static int analogix_dp_link_start(struct analogix_dp_device *dp)
{
u8 buf[4];
@@ -286,10 +264,12 @@ static int analogix_dp_link_start(struct analogix_dp_device *dp)
return retval;
}
- /* Set TX pre-emphasis to minimum */
+ /* Set TX voltage-swing and pre-emphasis to minimum */
for (lane = 0; lane < lane_count; lane++)
- analogix_dp_set_lane_lane_pre_emphasis(dp,
- PRE_EMPHASIS_LEVEL_0, lane);
+ dp->link_train.training_lane[lane] =
+ DP_TRAIN_VOLTAGE_SWING_LEVEL_0 |
+ DP_TRAIN_PRE_EMPH_LEVEL_0;
+ analogix_dp_set_lane_link_training(dp);
/* Wait for PLL lock */
pll_tries = 0;
@@ -384,54 +364,6 @@ static unsigned char analogix_dp_get_adjust_request_pre_emphasis(
return ((link_value >> shift) & 0xc) >> 2;
}
-static void analogix_dp_set_lane_link_training(struct analogix_dp_device *dp,
- u8 training_lane_set, int lane)
-{
- switch (lane) {
- case 0:
- analogix_dp_set_lane0_link_training(dp, training_lane_set);
- break;
- case 1:
- analogix_dp_set_lane1_link_training(dp, training_lane_set);
- break;
-
- case 2:
- analogix_dp_set_lane2_link_training(dp, training_lane_set);
- break;
-
- case 3:
- analogix_dp_set_lane3_link_training(dp, training_lane_set);
- break;
- }
-}
-
-static unsigned int
-analogix_dp_get_lane_link_training(struct analogix_dp_device *dp,
- int lane)
-{
- u32 reg;
-
- switch (lane) {
- case 0:
- reg = analogix_dp_get_lane0_link_training(dp);
- break;
- case 1:
- reg = analogix_dp_get_lane1_link_training(dp);
- break;
- case 2:
- reg = analogix_dp_get_lane2_link_training(dp);
- break;
- case 3:
- reg = analogix_dp_get_lane3_link_training(dp);
- break;
- default:
- WARN_ON(1);
- return 0;
- }
-
- return reg;
-}
-
static void analogix_dp_reduce_link_rate(struct analogix_dp_device *dp)
{
analogix_dp_training_pattern_dis(dp);
@@ -478,11 +410,6 @@ static int analogix_dp_process_clock_recovery(struct analogix_dp_device *dp)
if (retval < 0)
return retval;
- retval = drm_dp_dpcd_read(&dp->aux, DP_ADJUST_REQUEST_LANE0_1,
- adjust_request, 2);
- if (retval < 0)
- return retval;
-
if (analogix_dp_clock_recovery_ok(link_status, lane_count) == 0) {
/* set training pattern 2 for EQ */
analogix_dp_set_training_pattern(dp, TRAINING_PTN2);
@@ -495,38 +422,37 @@ static int analogix_dp_process_clock_recovery(struct analogix_dp_device *dp)
dev_dbg(dp->dev, "Link Training Clock Recovery success\n");
dp->link_train.lt_state = EQUALIZER_TRAINING;
- } else {
- for (lane = 0; lane < lane_count; lane++) {
- training_lane = analogix_dp_get_lane_link_training(
- dp, lane);
- voltage_swing = analogix_dp_get_adjust_request_voltage(
- adjust_request, lane);
- pre_emphasis = analogix_dp_get_adjust_request_pre_emphasis(
- adjust_request, lane);
-
- if (DPCD_VOLTAGE_SWING_GET(training_lane) ==
- voltage_swing &&
- DPCD_PRE_EMPHASIS_GET(training_lane) ==
- pre_emphasis)
- dp->link_train.cr_loop[lane]++;
-
- if (dp->link_train.cr_loop[lane] == MAX_CR_LOOP ||
- voltage_swing == VOLTAGE_LEVEL_3 ||
- pre_emphasis == PRE_EMPHASIS_LEVEL_3) {
- dev_err(dp->dev, "CR Max reached (%d,%d,%d)\n",
- dp->link_train.cr_loop[lane],
- voltage_swing, pre_emphasis);
- analogix_dp_reduce_link_rate(dp);
- return -EIO;
- }
+
+ return 0;
+ }
+
+ retval = drm_dp_dpcd_read(&dp->aux, DP_ADJUST_REQUEST_LANE0_1,
+ adjust_request, 2);
+ if (retval < 0)
+ return retval;
+
+ for (lane = 0; lane < lane_count; lane++) {
+ training_lane = analogix_dp_get_lane_link_training(dp, lane);
+ voltage_swing = analogix_dp_get_adjust_request_voltage(adjust_request, lane);
+ pre_emphasis = analogix_dp_get_adjust_request_pre_emphasis(adjust_request, lane);
+
+ if (DPCD_VOLTAGE_SWING_GET(training_lane) == voltage_swing &&
+ DPCD_PRE_EMPHASIS_GET(training_lane) == pre_emphasis)
+ dp->link_train.cr_loop[lane]++;
+
+ if (dp->link_train.cr_loop[lane] == MAX_CR_LOOP ||
+ voltage_swing == VOLTAGE_LEVEL_3 ||
+ pre_emphasis == PRE_EMPHASIS_LEVEL_3) {
+ dev_err(dp->dev, "CR Max reached (%d,%d,%d)\n",
+ dp->link_train.cr_loop[lane],
+ voltage_swing, pre_emphasis);
+ analogix_dp_reduce_link_rate(dp);
+ return -EIO;
}
}
analogix_dp_get_adjust_training_lane(dp, adjust_request);
-
- for (lane = 0; lane < lane_count; lane++)
- analogix_dp_set_lane_link_training(dp,
- dp->link_train.training_lane[lane], lane);
+ analogix_dp_set_lane_link_training(dp);
retval = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET,
dp->link_train.training_lane, lane_count);
@@ -538,7 +464,7 @@ static int analogix_dp_process_clock_recovery(struct analogix_dp_device *dp)
static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp)
{
- int lane, lane_count, retval;
+ int lane_count, retval;
u32 reg;
u8 link_align, link_status[2], adjust_request[2];
@@ -598,9 +524,7 @@ static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp)
return -EIO;
}
- for (lane = 0; lane < lane_count; lane++)
- analogix_dp_set_lane_link_training(dp,
- dp->link_train.training_lane[lane], lane);
+ analogix_dp_set_lane_link_training(dp);
retval = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET,
dp->link_train.training_lane, lane_count);
@@ -712,7 +636,7 @@ static int analogix_dp_full_link_train(struct analogix_dp_device *dp,
static int analogix_dp_fast_link_train(struct analogix_dp_device *dp)
{
- int i, ret;
+ int ret;
u8 link_align, link_status[2];
enum pll_status status;
@@ -720,11 +644,7 @@ static int analogix_dp_fast_link_train(struct analogix_dp_device *dp)
analogix_dp_set_link_bandwidth(dp, dp->link_train.link_rate);
analogix_dp_set_lane_count(dp, dp->link_train.lane_count);
-
- for (i = 0; i < dp->link_train.lane_count; i++) {
- analogix_dp_set_lane_link_training(dp,
- dp->link_train.training_lane[i], i);
- }
+ analogix_dp_set_lane_link_training(dp);
ret = readx_poll_timeout(analogix_dp_get_pll_lock_status, dp, status,
status != PLL_UNLOCKED, 120,
@@ -1108,7 +1028,7 @@ out:
static int analogix_dp_get_modes(struct drm_connector *connector)
{
struct analogix_dp_device *dp = to_dp(connector);
- struct edid *edid;
+ const struct drm_edid *drm_edid;
int ret, num_modes = 0;
if (dp->plat_data->panel) {
@@ -1120,12 +1040,13 @@ static int analogix_dp_get_modes(struct drm_connector *connector)
return 0;
}
- edid = drm_get_edid(connector, &dp->aux.ddc);
- if (edid) {
- drm_connector_update_edid_property(&dp->connector,
- edid);
- num_modes += drm_add_edid_modes(&dp->connector, edid);
- kfree(edid);
+ drm_edid = drm_edid_read_ddc(connector, &dp->aux.ddc);
+
+ drm_edid_connector_update(&dp->connector, drm_edid);
+
+ if (drm_edid) {
+ num_modes += drm_edid_connector_add_modes(&dp->connector);
+ drm_edid_free(drm_edid);
}
ret = analogix_dp_prepare_panel(dp, false, false);
@@ -1228,11 +1149,6 @@ static int analogix_dp_bridge_attach(struct drm_bridge *bridge,
return -EINVAL;
}
- if (!bridge->encoder) {
- DRM_ERROR("Parent encoder object not found");
- return -ENODEV;
- }
-
if (!dp->plat_data->skip_connector) {
connector = &dp->connector;
connector->polled = DRM_CONNECTOR_POLL_HPD;
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
index 433f2d7efa0c..382b2f068ab9 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
@@ -213,26 +213,8 @@ void analogix_dp_enable_enhanced_mode(struct analogix_dp_device *dp,
bool enable);
void analogix_dp_set_training_pattern(struct analogix_dp_device *dp,
enum pattern_set pattern);
-void analogix_dp_set_lane0_pre_emphasis(struct analogix_dp_device *dp,
- u32 level);
-void analogix_dp_set_lane1_pre_emphasis(struct analogix_dp_device *dp,
- u32 level);
-void analogix_dp_set_lane2_pre_emphasis(struct analogix_dp_device *dp,
- u32 level);
-void analogix_dp_set_lane3_pre_emphasis(struct analogix_dp_device *dp,
- u32 level);
-void analogix_dp_set_lane0_link_training(struct analogix_dp_device *dp,
- u32 training_lane);
-void analogix_dp_set_lane1_link_training(struct analogix_dp_device *dp,
- u32 training_lane);
-void analogix_dp_set_lane2_link_training(struct analogix_dp_device *dp,
- u32 training_lane);
-void analogix_dp_set_lane3_link_training(struct analogix_dp_device *dp,
- u32 training_lane);
-u32 analogix_dp_get_lane0_link_training(struct analogix_dp_device *dp);
-u32 analogix_dp_get_lane1_link_training(struct analogix_dp_device *dp);
-u32 analogix_dp_get_lane2_link_training(struct analogix_dp_device *dp);
-u32 analogix_dp_get_lane3_link_training(struct analogix_dp_device *dp);
+void analogix_dp_set_lane_link_training(struct analogix_dp_device *dp);
+u32 analogix_dp_get_lane_link_training(struct analogix_dp_device *dp, u8 lane);
void analogix_dp_reset_macro(struct analogix_dp_device *dp);
void analogix_dp_init_video(struct analogix_dp_device *dp);
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 6a4f20fccf84..d267cf05cbca 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -557,6 +557,20 @@ void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count)
*count = reg;
}
+void analogix_dp_set_lane_link_training(struct analogix_dp_device *dp)
+{
+ u8 lane;
+
+ for (lane = 0; lane < dp->link_train.lane_count; lane++)
+ writel(dp->link_train.training_lane[lane],
+ dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL + 4 * lane);
+}
+
+u32 analogix_dp_get_lane_link_training(struct analogix_dp_device *dp, u8 lane)
+{
+ return readl(dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL + 4 * lane);
+}
+
void analogix_dp_enable_enhanced_mode(struct analogix_dp_device *dp,
bool enable)
{
@@ -606,106 +620,6 @@ void analogix_dp_set_training_pattern(struct analogix_dp_device *dp,
}
}
-void analogix_dp_set_lane0_pre_emphasis(struct analogix_dp_device *dp,
- u32 level)
-{
- u32 reg;
-
- reg = readl(dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
- reg &= ~PRE_EMPHASIS_SET_MASK;
- reg |= level << PRE_EMPHASIS_SET_SHIFT;
- writel(reg, dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
-}
-
-void analogix_dp_set_lane1_pre_emphasis(struct analogix_dp_device *dp,
- u32 level)
-{
- u32 reg;
-
- reg = readl(dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
- reg &= ~PRE_EMPHASIS_SET_MASK;
- reg |= level << PRE_EMPHASIS_SET_SHIFT;
- writel(reg, dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
-}
-
-void analogix_dp_set_lane2_pre_emphasis(struct analogix_dp_device *dp,
- u32 level)
-{
- u32 reg;
-
- reg = readl(dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
- reg &= ~PRE_EMPHASIS_SET_MASK;
- reg |= level << PRE_EMPHASIS_SET_SHIFT;
- writel(reg, dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
-}
-
-void analogix_dp_set_lane3_pre_emphasis(struct analogix_dp_device *dp,
- u32 level)
-{
- u32 reg;
-
- reg = readl(dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
- reg &= ~PRE_EMPHASIS_SET_MASK;
- reg |= level << PRE_EMPHASIS_SET_SHIFT;
- writel(reg, dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
-}
-
-void analogix_dp_set_lane0_link_training(struct analogix_dp_device *dp,
- u32 training_lane)
-{
- u32 reg;
-
- reg = training_lane;
- writel(reg, dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
-}
-
-void analogix_dp_set_lane1_link_training(struct analogix_dp_device *dp,
- u32 training_lane)
-{
- u32 reg;
-
- reg = training_lane;
- writel(reg, dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
-}
-
-void analogix_dp_set_lane2_link_training(struct analogix_dp_device *dp,
- u32 training_lane)
-{
- u32 reg;
-
- reg = training_lane;
- writel(reg, dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
-}
-
-void analogix_dp_set_lane3_link_training(struct analogix_dp_device *dp,
- u32 training_lane)
-{
- u32 reg;
-
- reg = training_lane;
- writel(reg, dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
-}
-
-u32 analogix_dp_get_lane0_link_training(struct analogix_dp_device *dp)
-{
- return readl(dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
-}
-
-u32 analogix_dp_get_lane1_link_training(struct analogix_dp_device *dp)
-{
- return readl(dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
-}
-
-u32 analogix_dp_get_lane2_link_training(struct analogix_dp_device *dp)
-{
- return readl(dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
-}
-
-u32 analogix_dp_get_lane3_link_training(struct analogix_dp_device *dp)
-{
- return readl(dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
-}
-
void analogix_dp_reset_macro(struct analogix_dp_device *dp)
{
u32 reg;
@@ -1027,7 +941,6 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
u32 status_reg;
u8 *buffer = msg->buffer;
unsigned int i;
- int num_transferred = 0;
int ret;
/* Buffer size of AUX CH is 16 bytes */
@@ -1079,7 +992,6 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
reg = buffer[i];
writel(reg, dp->reg_base + ANALOGIX_DP_BUF_DATA_0 +
4 * i);
- num_transferred++;
}
}
@@ -1127,7 +1039,6 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0 +
4 * i);
buffer[i] = (unsigned char)reg;
- num_transferred++;
}
}
@@ -1144,7 +1055,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
(msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ)
msg->reply = DP_AUX_NATIVE_REPLY_ACK;
- return num_transferred > 0 ? num_transferred : -EBUSY;
+ return msg->size;
aux_error:
/* if aux err happen, reset aux */
diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
index 59e9ad349969..88e4aa5830f3 100644
--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
+++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
@@ -464,9 +464,11 @@ static int anx7625_odfc_config(struct anx7625_data *ctx,
*/
static int anx7625_set_k_value(struct anx7625_data *ctx)
{
- struct edid *edid = (struct edid *)ctx->slimport_edid_p.edid_raw_data;
+ struct drm_edid_product_id id;
- if (edid->mfg_id[0] == IVO_MID0 && edid->mfg_id[1] == IVO_MID1)
+ drm_edid_get_product_id(ctx->cached_drm_edid, &id);
+
+ if (be16_to_cpu(id.manufacturer_name) == IVO_MID)
return anx7625_reg_write(ctx, ctx->i2c.rx_p1_client,
MIPI_DIGITAL_ADJ_1, 0x3B);
@@ -1526,7 +1528,8 @@ static int anx7625_wait_hpd_asserted(struct drm_dp_aux *aux,
static void anx7625_remove_edid(struct anx7625_data *ctx)
{
- ctx->slimport_edid_p.edid_block_num = -1;
+ drm_edid_free(ctx->cached_drm_edid);
+ ctx->cached_drm_edid = NULL;
}
static void anx7625_dp_adjust_swing(struct anx7625_data *ctx)
@@ -1787,27 +1790,32 @@ static ssize_t anx7625_aux_transfer(struct drm_dp_aux *aux,
static const struct drm_edid *anx7625_edid_read(struct anx7625_data *ctx)
{
struct device *dev = ctx->dev;
- struct s_edid_data *p_edid = &ctx->slimport_edid_p;
+ u8 *edid_buf;
int edid_num;
- if (ctx->slimport_edid_p.edid_block_num > 0)
+ if (ctx->cached_drm_edid)
goto out;
+ edid_buf = kmalloc(FOUR_BLOCK_SIZE, GFP_KERNEL);
+ if (!edid_buf)
+ return NULL;
+
pm_runtime_get_sync(dev);
_anx7625_hpd_polling(ctx, 5000 * 100);
- edid_num = sp_tx_edid_read(ctx, p_edid->edid_raw_data);
+ edid_num = sp_tx_edid_read(ctx, edid_buf);
pm_runtime_put_sync(dev);
if (edid_num < 1) {
DRM_DEV_ERROR(dev, "Fail to read EDID: %d\n", edid_num);
+ kfree(edid_buf);
return NULL;
}
- p_edid->edid_block_num = edid_num;
+ ctx->cached_drm_edid = drm_edid_alloc(edid_buf, FOUR_BLOCK_SIZE);
+ kfree(edid_buf);
out:
- return drm_edid_alloc(ctx->slimport_edid_p.edid_raw_data,
- FOUR_BLOCK_SIZE);
+ return drm_edid_dup(ctx->cached_drm_edid);
}
static enum drm_connector_status anx7625_sink_detect(struct anx7625_data *ctx)
@@ -2193,11 +2201,6 @@ static int anx7625_bridge_attach(struct drm_bridge *bridge,
if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR))
return -EINVAL;
- if (!bridge->encoder) {
- DRM_DEV_ERROR(dev, "Parent encoder object not found");
- return -ENODEV;
- }
-
ctx->aux.drm_dev = bridge->dev;
err = drm_dp_aux_register(&ctx->aux);
if (err) {
@@ -2435,11 +2438,6 @@ static void anx7625_bridge_atomic_enable(struct drm_bridge *bridge,
dev_dbg(dev, "drm atomic enable\n");
- if (!bridge->encoder) {
- dev_err(dev, "Parent encoder object not found");
- return;
- }
-
connector = drm_atomic_get_new_connector_for_encoder(state->base.state,
bridge->encoder);
if (!connector)
diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.h b/drivers/gpu/drm/bridge/analogix/anx7625.h
index 39ed35d33836..eb5580f1ab2f 100644
--- a/drivers/gpu/drm/bridge/analogix/anx7625.h
+++ b/drivers/gpu/drm/bridge/analogix/anx7625.h
@@ -286,8 +286,7 @@
#define MIPI_LANE_CTRL_10 0x0F
#define MIPI_DIGITAL_ADJ_1 0x1B
-#define IVO_MID0 0x26
-#define IVO_MID1 0xCF
+#define IVO_MID 0x26CF
#define MIPI_PLL_M_NUM_23_16 0x1E
#define MIPI_PLL_M_NUM_15_8 0x1F
@@ -417,11 +416,6 @@ enum audio_wd_len {
#define EDID_TRY_CNT 3
#define SUPPORT_PIXEL_CLOCK 300000
-struct s_edid_data {
- int edid_block_num;
- u8 edid_raw_data[FOUR_BLOCK_SIZE];
-};
-
/***************** Display End *****************/
#define MAX_LANES_SUPPORT 4
@@ -466,7 +460,7 @@ struct anx7625_data {
struct anx7625_i2c_client i2c;
struct i2c_client *last_client;
struct timer_list hdcp_timer;
- struct s_edid_data slimport_edid_p;
+ const struct drm_edid *cached_drm_edid;
struct device *codec_dev;
hdmi_codec_plugged_cb plugged_cb;
struct work_struct work;
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
index 8a91ef0ae065..dee640ab1d3a 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
@@ -1697,11 +1697,6 @@ static int cdns_mhdp_connector_init(struct cdns_mhdp_device *mhdp)
struct drm_bridge *bridge = &mhdp->bridge;
int ret;
- if (!bridge->encoder) {
- dev_err(mhdp->dev, "Parent encoder object not found");
- return -ENODEV;
- }
-
conn->polled = DRM_CONNECTOR_POLL_HPD;
ret = drm_connector_init(bridge->dev, conn, &cdns_mhdp_conn_funcs,
diff --git a/drivers/gpu/drm/bridge/imx/imx-ldb-helper.c b/drivers/gpu/drm/bridge/imx/imx-ldb-helper.c
index 6967325cd8ee..9b5bebbe357d 100644
--- a/drivers/gpu/drm/bridge/imx/imx-ldb-helper.c
+++ b/drivers/gpu/drm/bridge/imx/imx-ldb-helper.c
@@ -116,11 +116,6 @@ int ldb_bridge_attach_helper(struct drm_bridge *bridge,
return -EINVAL;
}
- if (!bridge->encoder) {
- DRM_DEV_ERROR(ldb->dev, "missing encoder\n");
- return -ENODEV;
- }
-
return drm_bridge_attach(bridge->encoder,
ldb_ch->next_bridge, bridge,
DRM_BRIDGE_ATTACH_NO_CONNECTOR);
diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c
index d0868a6ac6c9..e6dbbdc87ce2 100644
--- a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c
+++ b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c
@@ -119,11 +119,6 @@ static int imx8qxp_pc_bridge_attach(struct drm_bridge *bridge,
return -EINVAL;
}
- if (!bridge->encoder) {
- DRM_DEV_ERROR(pc->dev, "missing encoder\n");
- return -ENODEV;
- }
-
return drm_bridge_attach(bridge->encoder,
ch->next_bridge, bridge,
DRM_BRIDGE_ATTACH_NO_CONNECTOR);
diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c
index ed8b7a4e0e11..1d11cc1df43c 100644
--- a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c
+++ b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c
@@ -138,11 +138,6 @@ static int imx8qxp_pixel_link_bridge_attach(struct drm_bridge *bridge,
return -EINVAL;
}
- if (!bridge->encoder) {
- DRM_DEV_ERROR(pl->dev, "missing encoder\n");
- return -ENODEV;
- }
-
return drm_bridge_attach(bridge->encoder,
pl->next_bridge, bridge,
DRM_BRIDGE_ATTACH_NO_CONNECTOR);
diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c b/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c
index 4a886cb808ca..fb7cf4369bb8 100644
--- a/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c
+++ b/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c
@@ -58,11 +58,6 @@ static int imx8qxp_pxl2dpi_bridge_attach(struct drm_bridge *bridge,
return -EINVAL;
}
- if (!bridge->encoder) {
- DRM_DEV_ERROR(p2d->dev, "missing encoder\n");
- return -ENODEV;
- }
-
return drm_bridge_attach(bridge->encoder,
p2d->next_bridge, bridge,
DRM_BRIDGE_ATTACH_NO_CONNECTOR);
diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
index 3f68c82888c2..1e1c06fdf206 100644
--- a/drivers/gpu/drm/bridge/ite-it6505.c
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
@@ -1307,9 +1307,15 @@ static void it6505_video_reset(struct it6505 *it6505)
it6505_link_reset_step_train(it6505);
it6505_set_bits(it6505, REG_DATA_MUTE_CTRL, EN_VID_MUTE, EN_VID_MUTE);
it6505_set_bits(it6505, REG_INFOFRAME_CTRL, EN_VID_CTRL_PKT, 0x00);
- it6505_set_bits(it6505, REG_RESET_CTRL, VIDEO_RESET, VIDEO_RESET);
+
+ it6505_set_bits(it6505, REG_VID_BUS_CTRL1, TX_FIFO_RESET, TX_FIFO_RESET);
+ it6505_set_bits(it6505, REG_VID_BUS_CTRL1, TX_FIFO_RESET, 0x00);
+
it6505_set_bits(it6505, REG_501_FIFO_CTRL, RST_501_FIFO, RST_501_FIFO);
it6505_set_bits(it6505, REG_501_FIFO_CTRL, RST_501_FIFO, 0x00);
+
+ it6505_set_bits(it6505, REG_RESET_CTRL, VIDEO_RESET, VIDEO_RESET);
+ usleep_range(1000, 2000);
it6505_set_bits(it6505, REG_RESET_CTRL, VIDEO_RESET, 0x00);
}
@@ -2245,12 +2251,11 @@ static void it6505_link_training_work(struct work_struct *work)
if (ret) {
it6505->auto_train_retry = AUTO_TRAIN_RETRY;
it6505_link_train_ok(it6505);
- return;
} else {
it6505->auto_train_retry--;
+ it6505_dump(it6505);
}
- it6505_dump(it6505);
}
static void it6505_plugged_status_to_codec(struct it6505 *it6505)
@@ -2471,31 +2476,53 @@ static void it6505_irq_link_train_fail(struct it6505 *it6505)
schedule_work(&it6505->link_works);
}
-static void it6505_irq_video_fifo_error(struct it6505 *it6505)
+static bool it6505_test_bit(unsigned int bit, const unsigned int *addr)
{
- struct device *dev = it6505->dev;
-
- DRM_DEV_DEBUG_DRIVER(dev, "video fifo overflow interrupt");
- it6505->auto_train_retry = AUTO_TRAIN_RETRY;
- flush_work(&it6505->link_works);
- it6505_stop_hdcp(it6505);
- it6505_video_reset(it6505);
+ return 1 & (addr[bit / BITS_PER_BYTE] >> (bit % BITS_PER_BYTE));
}
-static void it6505_irq_io_latch_fifo_overflow(struct it6505 *it6505)
+static void it6505_irq_video_handler(struct it6505 *it6505, const int *int_status)
{
struct device *dev = it6505->dev;
+ int reg_0d, reg_int03;
- DRM_DEV_DEBUG_DRIVER(dev, "IO latch fifo overflow interrupt");
- it6505->auto_train_retry = AUTO_TRAIN_RETRY;
- flush_work(&it6505->link_works);
- it6505_stop_hdcp(it6505);
- it6505_video_reset(it6505);
-}
+ /*
+ * When video SCDT change with video not stable,
+ * Or video FIFO error, need video reset
+ */
-static bool it6505_test_bit(unsigned int bit, const unsigned int *addr)
-{
- return 1 & (addr[bit / BITS_PER_BYTE] >> (bit % BITS_PER_BYTE));
+ if ((!it6505_get_video_status(it6505) &&
+ (it6505_test_bit(INT_SCDT_CHANGE, (unsigned int *)int_status))) ||
+ (it6505_test_bit(BIT_INT_IO_FIFO_OVERFLOW,
+ (unsigned int *)int_status)) ||
+ (it6505_test_bit(BIT_INT_VID_FIFO_ERROR,
+ (unsigned int *)int_status))) {
+ it6505->auto_train_retry = AUTO_TRAIN_RETRY;
+ flush_work(&it6505->link_works);
+ it6505_stop_hdcp(it6505);
+ it6505_video_reset(it6505);
+
+ usleep_range(10000, 11000);
+
+ /*
+ * Clear FIFO error IRQ to prevent fifo error -> reset loop
+ * HW will trigger SCDT change IRQ again when video stable
+ */
+
+ reg_int03 = it6505_read(it6505, INT_STATUS_03);
+ reg_0d = it6505_read(it6505, REG_SYSTEM_STS);
+
+ reg_int03 &= (BIT(INT_VID_FIFO_ERROR) | BIT(INT_IO_LATCH_FIFO_OVERFLOW));
+ it6505_write(it6505, INT_STATUS_03, reg_int03);
+
+ DRM_DEV_DEBUG_DRIVER(dev, "reg08 = 0x%02x", reg_int03);
+ DRM_DEV_DEBUG_DRIVER(dev, "reg0D = 0x%02x", reg_0d);
+
+ return;
+ }
+
+ if (it6505_test_bit(INT_SCDT_CHANGE, (unsigned int *)int_status))
+ it6505_irq_scdt(it6505);
}
static irqreturn_t it6505_int_threaded_handler(int unused, void *data)
@@ -2508,15 +2535,12 @@ static irqreturn_t it6505_int_threaded_handler(int unused, void *data)
} irq_vec[] = {
{ BIT_INT_HPD, it6505_irq_hpd },
{ BIT_INT_HPD_IRQ, it6505_irq_hpd_irq },
- { BIT_INT_SCDT, it6505_irq_scdt },
{ BIT_INT_HDCP_FAIL, it6505_irq_hdcp_fail },
{ BIT_INT_HDCP_DONE, it6505_irq_hdcp_done },
{ BIT_INT_AUX_CMD_FAIL, it6505_irq_aux_cmd_fail },
{ BIT_INT_HDCP_KSV_CHECK, it6505_irq_hdcp_ksv_check },
{ BIT_INT_AUDIO_FIFO_ERROR, it6505_irq_audio_fifo_error },
{ BIT_INT_LINK_TRAIN_FAIL, it6505_irq_link_train_fail },
- { BIT_INT_VID_FIFO_ERROR, it6505_irq_video_fifo_error },
- { BIT_INT_IO_FIFO_OVERFLOW, it6505_irq_io_latch_fifo_overflow },
};
int int_status[3], i;
@@ -2546,6 +2570,7 @@ static irqreturn_t it6505_int_threaded_handler(int unused, void *data)
if (it6505_test_bit(irq_vec[i].bit, (unsigned int *)int_status))
irq_vec[i].handler(it6505);
}
+ it6505_irq_video_handler(it6505, (unsigned int *)int_status);
}
pm_runtime_put_sync(dev);
@@ -2590,7 +2615,7 @@ static int it6505_poweron(struct it6505 *it6505)
gpiod_set_value_cansleep(pdata->gpiod_reset, 0);
usleep_range(1000, 2000);
gpiod_set_value_cansleep(pdata->gpiod_reset, 1);
- usleep_range(10000, 20000);
+ usleep_range(25000, 35000);
}
it6505->powered = true;
@@ -2882,11 +2907,6 @@ static int it6505_bridge_attach(struct drm_bridge *bridge,
return -EINVAL;
}
- if (!bridge->encoder) {
- dev_err(dev, "Parent encoder object not found");
- return -ENODEV;
- }
-
/* Register aux channel */
it6505->aux.drm_dev = bridge->dev;
diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c
index b99fe87ec738..73983f9b50cb 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -1195,4 +1195,5 @@ static struct i2c_driver lt9611_driver = {
};
module_i2c_driver(lt9611_driver);
+MODULE_DESCRIPTION("Lontium LT9611 DSI/HDMI bridge driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
index ab702471f3ab..4e802b54a1cb 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
@@ -337,11 +337,6 @@ static int lt9611uxc_connector_init(struct drm_bridge *bridge, struct lt9611uxc
{
int ret;
- if (!bridge->encoder) {
- DRM_ERROR("Parent encoder object not found");
- return -ENODEV;
- }
-
lt9611uxc->connector.polled = DRM_CONNECTOR_POLL_HPD;
drm_connector_helper_add(&lt9611uxc->connector,
@@ -1021,6 +1016,7 @@ static struct i2c_driver lt9611uxc_driver = {
module_i2c_driver(lt9611uxc_driver);
MODULE_AUTHOR("Dmitry Baryshkov <dmitry.baryshkov@linaro.org>");
+MODULE_DESCRIPTION("Lontium LT9611UXC DSI/HDMI bridge driver");
MODULE_LICENSE("GPL v2");
MODULE_FIRMWARE(FW_FILE);
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 4480523244e4..37f1acf5c0f8 100644
--- a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
+++ b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
@@ -165,11 +165,6 @@ static int ge_b850v3_lvds_create_connector(struct drm_bridge *bridge)
struct drm_connector *connector = &ge_b850v3_lvds_ptr->connector;
int ret;
- if (!bridge->encoder) {
- DRM_ERROR("Parent encoder object not found");
- return -ENODEV;
- }
-
connector->polled = DRM_CONNECTOR_POLL_HPD;
drm_connector_helper_add(connector,
diff --git a/drivers/gpu/drm/bridge/nxp-ptn3460.c b/drivers/gpu/drm/bridge/nxp-ptn3460.c
index ed93fd4c3265..e77aab965fcf 100644
--- a/drivers/gpu/drm/bridge/nxp-ptn3460.c
+++ b/drivers/gpu/drm/bridge/nxp-ptn3460.c
@@ -229,11 +229,6 @@ static int ptn3460_bridge_attach(struct drm_bridge *bridge,
if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
return 0;
- if (!bridge->encoder) {
- DRM_ERROR("Parent encoder object not found");
- return -ENODEV;
- }
-
ptn_bridge->connector.polled = DRM_CONNECTOR_POLL_HPD;
ret = drm_connector_init(bridge->dev, &ptn_bridge->connector,
&ptn3460_connector_funcs, DRM_MODE_CONNECTOR_LVDS);
diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c
index 32506524d9a2..56c40b516a8f 100644
--- a/drivers/gpu/drm/bridge/panel.c
+++ b/drivers/gpu/drm/bridge/panel.c
@@ -67,11 +67,6 @@ static int panel_bridge_attach(struct drm_bridge *bridge,
if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
return 0;
- if (!bridge->encoder) {
- DRM_ERROR("Missing encoder\n");
- return -ENODEV;
- }
-
drm_connector_helper_add(connector,
&panel_bridge_connector_helper_funcs);
diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c
index 95fedc68b0ae..e7e53a9e42af 100644
--- a/drivers/gpu/drm/bridge/samsung-dsim.c
+++ b/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -574,8 +574,8 @@ static unsigned long samsung_dsim_pll_find_pms(struct samsung_dsim *dsi,
u16 _m, best_m;
u8 _s, best_s;
- p_min = DIV_ROUND_UP(fin, (12 * MHZ));
- p_max = fin / (6 * MHZ);
+ p_min = DIV_ROUND_UP(fin, (driver_data->pll_fin_max * MHZ));
+ p_max = fin / (driver_data->pll_fin_min * MHZ);
for (_p = p_min; _p <= p_max; ++_p) {
for (_s = 0; _s <= 5; ++_s) {
@@ -1606,6 +1606,27 @@ static int samsung_dsim_atomic_check(struct drm_bridge *bridge,
adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
}
+ /*
+ * When using video sync pulses, the HFP, HBP, and HSA are divided between
+ * the available lanes if there is more than one lane. For certain
+ * timings and lane configurations, the HFP may not be evenly divisible.
+ * If the HFP is rounded down, it ends up being too small which can cause
+ * some monitors to not sync properly. In these instances, adjust htotal
+ * and hsync to round the HFP up, and recalculate the htotal. Through trial
+ * and error, it appears that the HBP and HSA do not appearto need the same
+ * correction that HFP does.
+ */
+ if (dsi->lanes > 1) {
+ int hfp = adjusted_mode->hsync_start - adjusted_mode->hdisplay;
+ int remainder = hfp % dsi->lanes;
+
+ if (remainder) {
+ adjusted_mode->hsync_start += remainder;
+ adjusted_mode->hsync_end += remainder;
+ adjusted_mode->htotal += remainder;
+ }
+ }
+
return 0;
}
diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c
index 2fbeda9025bf..7f91b0db161e 100644
--- a/drivers/gpu/drm/bridge/sii902x.c
+++ b/drivers/gpu/drm/bridge/sii902x.c
@@ -163,6 +163,14 @@
#define SII902X_AUDIO_PORT_INDEX 3
+/*
+ * The maximum resolution supported by the HDMI bridge is 1080p@60Hz
+ * and 1920x1200 requiring a pixel clock of 165MHz and the minimum
+ * resolution supported is 480p@60Hz requiring a pixel clock of 25MHz
+ */
+#define SII902X_MIN_PIXEL_CLOCK_KHZ 25000
+#define SII902X_MAX_PIXEL_CLOCK_KHZ 165000
+
struct sii902x {
struct i2c_client *i2c;
struct regmap *regmap;
@@ -310,20 +318,12 @@ static int sii902x_get_modes(struct drm_connector *connector)
return num;
}
-static enum drm_mode_status sii902x_mode_valid(struct drm_connector *connector,
- struct drm_display_mode *mode)
-{
- /* TODO: check mode */
-
- return MODE_OK;
-}
-
static const struct drm_connector_helper_funcs sii902x_connector_helper_funcs = {
.get_modes = sii902x_get_modes,
- .mode_valid = sii902x_mode_valid,
};
-static void sii902x_bridge_disable(struct drm_bridge *bridge)
+static void sii902x_bridge_atomic_disable(struct drm_bridge *bridge,
+ struct drm_bridge_state *old_bridge_state)
{
struct sii902x *sii902x = bridge_to_sii902x(bridge);
@@ -336,7 +336,8 @@ static void sii902x_bridge_disable(struct drm_bridge *bridge)
mutex_unlock(&sii902x->mutex);
}
-static void sii902x_bridge_enable(struct drm_bridge *bridge)
+static void sii902x_bridge_atomic_enable(struct drm_bridge *bridge,
+ struct drm_bridge_state *old_bridge_state)
{
struct sii902x *sii902x = bridge_to_sii902x(bridge);
@@ -495,6 +496,10 @@ static int sii902x_bridge_atomic_check(struct drm_bridge *bridge,
struct drm_crtc_state *crtc_state,
struct drm_connector_state *conn_state)
{
+ if (crtc_state->mode.clock < SII902X_MIN_PIXEL_CLOCK_KHZ ||
+ crtc_state->mode.clock > SII902X_MAX_PIXEL_CLOCK_KHZ)
+ return -EINVAL;
+
/*
* There might be flags negotiation supported in future but
* set the bus flags in atomic_check statically for now.
@@ -504,11 +509,25 @@ static int sii902x_bridge_atomic_check(struct drm_bridge *bridge,
return 0;
}
+static enum drm_mode_status
+sii902x_bridge_mode_valid(struct drm_bridge *bridge,
+ const struct drm_display_info *info,
+ const struct drm_display_mode *mode)
+{
+ if (mode->clock < SII902X_MIN_PIXEL_CLOCK_KHZ)
+ return MODE_CLOCK_LOW;
+
+ if (mode->clock > SII902X_MAX_PIXEL_CLOCK_KHZ)
+ return MODE_CLOCK_HIGH;
+
+ return MODE_OK;
+}
+
static const struct drm_bridge_funcs sii902x_bridge_funcs = {
.attach = sii902x_bridge_attach,
.mode_set = sii902x_bridge_mode_set,
- .disable = sii902x_bridge_disable,
- .enable = sii902x_bridge_enable,
+ .atomic_disable = sii902x_bridge_atomic_disable,
+ .atomic_enable = sii902x_bridge_atomic_enable,
.detect = sii902x_bridge_detect,
.edid_read = sii902x_bridge_edid_read,
.atomic_reset = drm_atomic_helper_bridge_reset,
@@ -516,6 +535,7 @@ static const struct drm_bridge_funcs sii902x_bridge_funcs = {
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
.atomic_get_input_bus_fmts = sii902x_bridge_atomic_get_input_bus_fmts,
.atomic_check = sii902x_bridge_atomic_check,
+ .mode_valid = sii902x_bridge_mode_valid,
};
static int sii902x_mute(struct sii902x *sii902x, bool mute)
diff --git a/drivers/gpu/drm/bridge/sii9234.c b/drivers/gpu/drm/bridge/sii9234.c
index d8373d918324..0c74cdc07032 100644
--- a/drivers/gpu/drm/bridge/sii9234.c
+++ b/drivers/gpu/drm/bridge/sii9234.c
@@ -961,4 +961,5 @@ static struct i2c_driver sii9234_driver = {
};
module_i2c_driver(sii9234_driver);
+MODULE_DESCRIPTION("Silicon Image SII9234 HDMI/MHL bridge driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
index 599164e3877d..6bb755e9f0a5 100644
--- a/drivers/gpu/drm/bridge/sil-sii8620.c
+++ b/drivers/gpu/drm/bridge/sil-sii8620.c
@@ -2384,4 +2384,5 @@ static struct i2c_driver sii8620_driver = {
};
module_i2c_driver(sii8620_driver);
+MODULE_DESCRIPTION("Silicon Image SiI8620 HDMI/MHL bridge driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/bridge/simple-bridge.c b/drivers/gpu/drm/bridge/simple-bridge.c
index 5813a2c4fc5e..ab0b0e36e97a 100644
--- a/drivers/gpu/drm/bridge/simple-bridge.c
+++ b/drivers/gpu/drm/bridge/simple-bridge.c
@@ -116,11 +116,6 @@ static int simple_bridge_attach(struct drm_bridge *bridge,
if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
return 0;
- if (!bridge->encoder) {
- DRM_ERROR("Missing encoder\n");
- return -ENODEV;
- }
-
drm_connector_helper_add(&sbridge->connector,
&simple_bridge_con_helper_funcs);
ret = drm_connector_init_with_ddc(bridge->dev, &sbridge->connector,
@@ -175,7 +170,6 @@ static int simple_bridge_probe(struct platform_device *pdev)
sbridge = devm_kzalloc(&pdev->dev, sizeof(*sbridge), GFP_KERNEL);
if (!sbridge)
return -ENOMEM;
- platform_set_drvdata(pdev, sbridge);
sbridge->info = of_device_get_match_data(&pdev->dev);
@@ -213,16 +207,7 @@ static int simple_bridge_probe(struct platform_device *pdev)
sbridge->bridge.of_node = pdev->dev.of_node;
sbridge->bridge.timings = sbridge->info->timings;
- drm_bridge_add(&sbridge->bridge);
-
- return 0;
-}
-
-static void simple_bridge_remove(struct platform_device *pdev)
-{
- struct simple_bridge *sbridge = platform_get_drvdata(pdev);
-
- drm_bridge_remove(&sbridge->bridge);
+ return devm_drm_bridge_add(&pdev->dev, &sbridge->bridge);
}
/*
@@ -299,7 +284,6 @@ MODULE_DEVICE_TABLE(of, simple_bridge_match);
static struct platform_driver simple_bridge_driver = {
.probe = simple_bridge_probe,
- .remove_new = simple_bridge_remove,
.driver = {
.name = "simple-bridge",
.of_match_table = simple_bridge_match,
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index 824fb3c65742..c4e9d96933dc 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -1071,11 +1071,6 @@ static int dw_mipi_dsi_bridge_attach(struct drm_bridge *bridge,
{
struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
- if (!bridge->encoder) {
- DRM_ERROR("Parent encoder object not found\n");
- return -ENODEV;
- }
-
/* Set the encoder type as caller does not know it */
bridge->encoder->encoder_type = DRM_MODE_ENCODER_DSI;
diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
index 166f9a3e9622..87c7346d037e 100644
--- a/drivers/gpu/drm/bridge/tc358767.c
+++ b/drivers/gpu/drm/bridge/tc358767.c
@@ -382,6 +382,9 @@ struct tc_data {
/* HPD pin number (0 or 1) or -ENODEV */
int hpd_pin;
+
+ /* Number of pixels to subtract from a line due to pixel clock delta */
+ u32 line_pixel_subtract;
};
static inline struct tc_data *aux_to_tc(struct drm_dp_aux *a)
@@ -577,6 +580,11 @@ static int tc_pllupdate(struct tc_data *tc, unsigned int pllctrl)
return 0;
}
+static u32 div64_round_up(u64 v, u32 d)
+{
+ return div_u64(v + d - 1, d);
+}
+
static int tc_pxl_pll_en(struct tc_data *tc, u32 refclk, u32 pixelclock)
{
int ret;
@@ -658,8 +666,11 @@ static int tc_pxl_pll_en(struct tc_data *tc, u32 refclk, u32 pixelclock)
return -EINVAL;
}
- dev_dbg(tc->dev, "PLL: got %d, delta %d\n", best_pixelclock,
- best_delta);
+ tc->line_pixel_subtract = tc->mode.htotal -
+ div64_round_up(tc->mode.htotal * (u64)best_pixelclock, pixelclock);
+
+ dev_dbg(tc->dev, "PLL: got %d, delta %d (subtract %d px)\n", best_pixelclock,
+ best_delta, tc->line_pixel_subtract);
dev_dbg(tc->dev, "PLL: %d / %d / %d * %d / %d\n", refclk,
ext_div[best_pre], best_div, best_mul, ext_div[best_post]);
@@ -885,6 +896,12 @@ static int tc_set_common_video_mode(struct tc_data *tc,
upper_margin, lower_margin, vsync_len);
dev_dbg(tc->dev, "total: %dx%d\n", mode->htotal, mode->vtotal);
+ if (right_margin > tc->line_pixel_subtract) {
+ right_margin -= tc->line_pixel_subtract;
+ } else {
+ dev_err(tc->dev, "Bridge pixel clock too slow for mode\n");
+ right_margin = 0;
+ }
/*
* LCD Ctl Frame Size
@@ -894,7 +911,7 @@ static int tc_set_common_video_mode(struct tc_data *tc,
*/
ret = regmap_write(tc->regmap, VPCTRL0,
FIELD_PREP(VSDELAY, right_margin + 10) |
- OPXLFMT_RGB888 | FRMSYNC_DISABLED | MSF_DISABLED);
+ OPXLFMT_RGB888 | FRMSYNC_ENABLED | MSF_DISABLED);
if (ret)
return ret;
@@ -1629,7 +1646,7 @@ tc_edp_mode_valid(struct drm_bridge *bridge,
u32 req, avail;
u32 bits_per_pixel = 24;
- /* DPI interface clock limitation: upto 154 MHz */
+ /* DPI->(e)DP interface clock limitation: up to 154 MHz */
if (mode->clock > 154000)
return MODE_CLOCK_HIGH;
@@ -2135,7 +2152,7 @@ static irqreturn_t tc_irq_handler(int irq, void *arg)
dev_err(tc->dev, "syserr %x\n", stat);
}
- if (tc->hpd_pin >= 0 && tc->bridge.dev) {
+ if (tc->hpd_pin >= 0 && tc->bridge.dev && tc->aux.drm_dev) {
/*
* H is triggered when the GPIO goes high.
*
diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c b/drivers/gpu/drm/bridge/ti-tfp410.c
index c7bef5c23927..b1b1e4d5a24a 100644
--- a/drivers/gpu/drm/bridge/ti-tfp410.c
+++ b/drivers/gpu/drm/bridge/ti-tfp410.c
@@ -133,11 +133,6 @@ static int tfp410_attach(struct drm_bridge *bridge,
if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
return 0;
- if (!bridge->encoder) {
- dev_err(dvi->dev, "Missing encoder\n");
- return -ENODEV;
- }
-
if (dvi->next_bridge->ops & DRM_BRIDGE_OP_DETECT)
dvi->connector.polled = DRM_CONNECTOR_POLL_HPD;
else
diff --git a/drivers/gpu/drm/ci/build-igt.sh b/drivers/gpu/drm/ci/build-igt.sh
index 500fa4f5c30a..eddb5f782a5e 100644
--- a/drivers/gpu/drm/ci/build-igt.sh
+++ b/drivers/gpu/drm/ci/build-igt.sh
@@ -3,6 +3,30 @@
set -ex
+function generate_testlist {
+ set +x
+ while read -r line; do
+ if [ "$line" = "TESTLIST" ] || [ "$line" = "END TESTLIST" ]; then
+ continue
+ fi
+
+ tests=$(echo "$line" | tr ' ' '\n')
+
+ for test in $tests; do
+ output=$(/igt/libexec/igt-gpu-tools/"$test" --list-subtests || true)
+
+ if [ -z "$output" ]; then
+ echo "$test"
+ else
+ echo "$output" | while read -r subtest; do
+ echo "$test@$subtest"
+ done
+ fi
+ done
+ done < /igt/libexec/igt-gpu-tools/test-list.txt > /igt/libexec/igt-gpu-tools/ci-testlist.txt
+ set -x
+}
+
git clone https://gitlab.freedesktop.org/drm/igt-gpu-tools.git --single-branch --no-checkout
cd igt-gpu-tools
git checkout $IGT_VERSION
@@ -21,15 +45,30 @@ MESON_OPTIONS="-Doverlay=disabled \
-Dlibunwind=enabled \
-Dprefix=/igt"
+if [[ "$KERNEL_ARCH" = "arm64" ]] || [[ "$KERNEL_ARCH" = "arm" ]]; then
+ MESON_OPTIONS="$MESON_OPTIONS -Dxe_driver=disabled"
+fi
+
mkdir -p /igt
meson build $MESON_OPTIONS $EXTRA_MESON_ARGS
ninja -C build -j${FDO_CI_CONCURRENT:-4} || ninja -C build -j 1
ninja -C build install
+if [[ "$KERNEL_ARCH" = "arm64" ]]; then
+ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/igt/lib/aarch64-linux-gnu
+elif [[ "$KERNEL_ARCH" = "arm" ]]; then
+ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/igt/lib
+else
+ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/igt/lib64
+fi
+
+echo "Generating ci-testlist.txt"
+generate_testlist
+
mkdir -p artifacts/
tar -cf artifacts/igt.tar /igt
# Pass needed files to the test stage
S3_ARTIFACT_NAME="igt.tar.gz"
gzip -c artifacts/igt.tar > ${S3_ARTIFACT_NAME}
-ci-fairy s3cp --token-file "${CI_JOB_JWT_FILE}" ${S3_ARTIFACT_NAME} https://${PIPELINE_ARTIFACTS_BASE}/${KERNEL_ARCH}/${S3_ARTIFACT_NAME}
+ci-fairy s3cp --token-file "${S3_JWT_FILE}" ${S3_ARTIFACT_NAME} https://${PIPELINE_ARTIFACTS_BASE}/${KERNEL_ARCH}/${S3_ARTIFACT_NAME}
diff --git a/drivers/gpu/drm/ci/build.sh b/drivers/gpu/drm/ci/build.sh
index 106f2d40d222..5a3bdcffae32 100644
--- a/drivers/gpu/drm/ci/build.sh
+++ b/drivers/gpu/drm/ci/build.sh
@@ -12,6 +12,9 @@ rm -rf .git/rebase-apply
apt-get update
apt-get install -y libssl-dev
+# for msm header validation
+apt-get install -y python3-lxml
+
if [[ "$KERNEL_ARCH" = "arm64" ]]; then
GCC_ARCH="aarch64-linux-gnu"
DEBIAN_ARCH="arm64"
@@ -128,6 +131,7 @@ fi
# Pass needed files to the test stage
mkdir -p install
cp -rfv .gitlab-ci/* install/.
+cp -rfv ci/* install/.
cp -rfv install/common install/ci-common
cp -rfv drivers/gpu/drm/ci/* install/.
@@ -141,21 +145,21 @@ if [[ "$UPLOAD_TO_MINIO" = "1" ]]; then
FILES_TO_UPLOAD="$FILES_TO_UPLOAD $(basename -a $DEVICE_TREES)"
fi
+ ls -l "${S3_JWT_FILE}"
for f in $FILES_TO_UPLOAD; do
- ci-fairy s3cp --token-file "${CI_JOB_JWT_FILE}" /lava-files/$f \
+ ci-fairy s3cp --token-file "${S3_JWT_FILE}" /lava-files/$f \
https://${PIPELINE_ARTIFACTS_BASE}/${DEBIAN_ARCH}/$f
done
S3_ARTIFACT_NAME="kernel-files.tar.zst"
tar --zstd -cf $S3_ARTIFACT_NAME install
- ci-fairy s3cp --token-file "${CI_JOB_JWT_FILE}" ${S3_ARTIFACT_NAME} https://${PIPELINE_ARTIFACTS_BASE}/${DEBIAN_ARCH}/${S3_ARTIFACT_NAME}
+ ci-fairy s3cp --token-file "${S3_JWT_FILE}" ${S3_ARTIFACT_NAME} https://${PIPELINE_ARTIFACTS_BASE}/${DEBIAN_ARCH}/${S3_ARTIFACT_NAME}
echo "Download vmlinux.xz from https://${PIPELINE_ARTIFACTS_BASE}/${DEBIAN_ARCH}/vmlinux.xz"
fi
mkdir -p artifacts/install/lib
mv install/* artifacts/install/.
-rm -rf artifacts/install/modules
ln -s common artifacts/install/ci-common
cp .config artifacts/${CI_JOB_NAME}_config
diff --git a/drivers/gpu/drm/ci/build.yml b/drivers/gpu/drm/ci/build.yml
index 17ab38304885..9c198239033d 100644
--- a/drivers/gpu/drm/ci/build.yml
+++ b/drivers/gpu/drm/ci/build.yml
@@ -106,6 +106,7 @@ build-nodebugfs:arm64:
extends: .build:arm64
variables:
DISABLE_KCONFIGS: "DEBUG_FS"
+ ENABLE_KCONFIGS: "EXPERT DRM_MSM_VALIDATE_XML"
build:x86_64:
extends: .build:x86_64
diff --git a/drivers/gpu/drm/ci/container.yml b/drivers/gpu/drm/ci/container.yml
index 9764e7921a4f..d6edf3635b23 100644
--- a/drivers/gpu/drm/ci/container.yml
+++ b/drivers/gpu/drm/ci/container.yml
@@ -36,15 +36,15 @@ debian/android_build:
rules:
- when: never
-debian/x86_64_test-android:
+.debian/x86_64_test-android:
rules:
- when: never
-windows_build_vs2019:
+windows_build_msvc:
rules:
- when: never
-windows_test_vs2019:
+windows_test_msvc:
rules:
- when: never
@@ -56,10 +56,6 @@ rustfmt:
rules:
- when: never
-windows_vs2019:
- rules:
- - when: never
-
-clang-format:
+windows_msvc:
rules:
- when: never \ No newline at end of file
diff --git a/drivers/gpu/drm/ci/gitlab-ci.yml b/drivers/gpu/drm/ci/gitlab-ci.yml
index 084e3ff8e3f4..80fb0f57ae46 100644
--- a/drivers/gpu/drm/ci/gitlab-ci.yml
+++ b/drivers/gpu/drm/ci/gitlab-ci.yml
@@ -1,11 +1,11 @@
variables:
DRM_CI_PROJECT_PATH: &drm-ci-project-path mesa/mesa
- DRM_CI_COMMIT_SHA: &drm-ci-commit-sha 9d162de9a05155e1c4041857a5848842749164cf
+ DRM_CI_COMMIT_SHA: &drm-ci-commit-sha e2b9c5a9e3e4f9b532067af8022eaef8d6fc6c00
UPSTREAM_REPO: git://anongit.freedesktop.org/drm/drm
TARGET_BRANCH: drm-next
- IGT_VERSION: d2af13d9f5be5ce23d996e4afd3e45990f5ab977
+ IGT_VERSION: 0df7b9b97f9da0e364f5ee30fe331004b8c86b56
DEQP_RUNNER_GIT_URL: https://gitlab.freedesktop.org/anholt/deqp-runner.git
DEQP_RUNNER_GIT_TAG: v0.15.0
@@ -19,33 +19,47 @@ variables:
bash download-git-cache.sh
rm download-git-cache.sh
set +o xtrace
+ S3_JWT_FILE: /s3_jwt
S3_HOST: s3.freedesktop.org
+ # This bucket is used to fetch the kernel image
+ S3_KERNEL_BUCKET: mesa-rootfs
+ # Bucket for git cache
+ S3_GITCACHE_BUCKET: git-cache
+ # Bucket for the pipeline artifacts pushed to S3
+ S3_ARTIFACTS_BUCKET: artifacts
# per-pipeline artifact storage on MinIO
- PIPELINE_ARTIFACTS_BASE: ${S3_HOST}/artifacts/${CI_PROJECT_PATH}/${CI_PIPELINE_ID}
+ PIPELINE_ARTIFACTS_BASE: ${S3_HOST}/${S3_ARTIFACTS_BUCKET}/${CI_PROJECT_PATH}/${CI_PIPELINE_ID}
# per-job artifact storage on MinIO
JOB_ARTIFACTS_BASE: ${PIPELINE_ARTIFACTS_BASE}/${CI_JOB_ID}
# default kernel for rootfs before injecting the current kernel tree
KERNEL_REPO: "gfx-ci/linux"
- KERNEL_TAG: "v6.6.4-for-mesa-ci-e4f4c500f7fb"
- KERNEL_IMAGE_BASE: https://${S3_HOST}/mesa-lava/${KERNEL_REPO}/${KERNEL_TAG}
+ KERNEL_TAG: "v6.6.21-mesa-f8ea"
+ KERNEL_IMAGE_BASE: https://${S3_HOST}/${S3_KERNEL_BUCKET}/${KERNEL_REPO}/${KERNEL_TAG}
+ PKG_REPO_REV: "3cc12a2a"
LAVA_TAGS: subset-1-gfx
LAVA_JOB_PRIORITY: 30
+ ARTIFACTS_BASE_URL: https://${CI_PROJECT_ROOT_NAMESPACE}.${CI_PAGES_DOMAIN}/-/${CI_PROJECT_NAME}/-/jobs/${CI_JOB_ID}/artifacts
+ # Python scripts for structured logger
+ PYTHONPATH: "$PYTHONPATH:$CI_PROJECT_DIR/install"
default:
+ id_tokens:
+ S3_JWT:
+ aud: https://s3.freedesktop.org
before_script:
- export SCRIPTS_DIR=$(mktemp -d)
- curl -L -s --retry 4 -f --retry-all-errors --retry-delay 60 -O --output-dir "${SCRIPTS_DIR}" "${DRM_CI_PROJECT_URL}/-/raw/${DRM_CI_COMMIT_SHA}/.gitlab-ci/setup-test-env.sh"
- source ${SCRIPTS_DIR}/setup-test-env.sh
- echo -e "\e[0Ksection_start:$(date +%s):unset_env_vars_section[collapsed=true]\r\e[0KUnsetting vulnerable environment variables"
- - export CI_JOB_JWT_FILE="${CI_JOB_JWT_FILE:-$(mktemp)}"
- - echo -n "${CI_JOB_JWT}" > "${CI_JOB_JWT_FILE}"
- - unset CI_JOB_JWT
+ - echo -n "${S3_JWT}" > "${S3_JWT_FILE}"
+ - unset CI_JOB_JWT S3_JWT
- echo -e "\e[0Ksection_end:$(date +%s):unset_env_vars_section\r\e[0K"
- echo -e "\e[0Ksection_start:$(date +%s):drm_ci_download_section[collapsed=true]\r\e[0KDownloading mesa from $DRM_CI_PROJECT_URL/-/archive/$DRM_CI_COMMIT_SHA/mesa-$DRM_CI_COMMIT_SHA.tar.gz"
- cd $CI_PROJECT_DIR
- curl --output - $DRM_CI_PROJECT_URL/-/archive/$DRM_CI_COMMIT_SHA/mesa-$DRM_CI_COMMIT_SHA.tar.gz | tar -xz
- mv mesa-$DRM_CI_COMMIT_SHA/.gitlab-ci* .
+ - mv mesa-$DRM_CI_COMMIT_SHA/bin/ci .
- rm -rf mesa-$DRM_CI_COMMIT_SHA/
- echo -e "\e[0Ksection_end:$(date +%s):drm_ci_download_section\r\e[0K"
@@ -53,9 +67,9 @@ default:
- >
set +x
- test -e "${CI_JOB_JWT_FILE}" &&
- export CI_JOB_JWT="$(<${CI_JOB_JWT_FILE})" &&
- rm "${CI_JOB_JWT_FILE}"
+ test -e "${S3_JWT_FILE}" &&
+ export S3_JWT="$(<${S3_JWT_FILE})" &&
+ rm "${S3_JWT_FILE}"
include:
- project: 'freedesktop/ci-templates'
@@ -87,6 +101,7 @@ include:
- '/src/intel/ci/gitlab-ci-inc.yml'
- '/src/freedreno/ci/gitlab-ci-inc.yml'
- '/src/amd/ci/gitlab-ci-inc.yml'
+ - '/src/virtio/ci/gitlab-ci-inc.yml'
- drivers/gpu/drm/ci/image-tags.yml
- drivers/gpu/drm/ci/container.yml
- drivers/gpu/drm/ci/static-checks.yml
@@ -98,6 +113,7 @@ include:
stages:
- sanity
- container
+ - code-validation
- git-archive
- build
- amdgpu
@@ -107,7 +123,7 @@ stages:
- msm
- rockchip
- virtio-gpu
- - lint
+ - software-driver
# YAML anchors for rule conditions
# --------------------------------
@@ -218,14 +234,15 @@ make git archive:
script:
# Remove drm-ci files we just added
- rm -rf .gitlab-ci.*
+ - rm -rf ci
# Compactify the .git directory
- git gc --aggressive
# compress the current folder
- tar -cvzf ../$CI_PROJECT_NAME.tar.gz .
- # login with the JWT token file
- - ci-fairy s3cp --token-file "${CI_JOB_JWT_FILE}" ../$CI_PROJECT_NAME.tar.gz https://$S3_HOST/git-cache/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME/$CI_PROJECT_NAME.tar.gz
+ # Use id_tokens for JWT auth
+ - ci-fairy s3cp --token-file "${S3_JWT_FILE}" ../$CI_PROJECT_NAME.tar.gz https://$S3_HOST/${S3_GITCACHE_BUCKET}/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME/$CI_PROJECT_NAME.tar.gz
# Sanity checks of MR settings and commit logs
@@ -262,4 +279,4 @@ sanity:
# Jobs that need to pass before spending hardware resources on further testing
.required-for-hardware-jobs:
- needs: [] \ No newline at end of file
+ needs: []
diff --git a/drivers/gpu/drm/ci/igt_runner.sh b/drivers/gpu/drm/ci/igt_runner.sh
index f1a08b9b146f..79f41d7da772 100755
--- a/drivers/gpu/drm/ci/igt_runner.sh
+++ b/drivers/gpu/drm/ci/igt_runner.sh
@@ -30,10 +30,10 @@ case "$DRIVER_NAME" in
export IGT_FORCE_DRIVER="panfrost"
fi
;;
- amdgpu)
+ amdgpu|vkms)
# Cannot use HWCI_KERNEL_MODULES as at that point we don't have the module in /lib
- mv /install/modules/lib/modules/* /lib/modules/.
- modprobe amdgpu
+ mv /install/modules/lib/modules/* /lib/modules/. || true
+ modprobe --first-time $DRIVER_NAME
;;
esac
@@ -59,25 +59,26 @@ fi
curl -L --retry 4 -f --retry-all-errors --retry-delay 60 -s ${FDO_HTTP_CACHE_URI:-}$PIPELINE_ARTIFACTS_BASE/$ARCH/igt.tar.gz | tar --zstd -v -x -C /
+TESTLIST="/igt/libexec/igt-gpu-tools/ci-testlist.txt"
# If the job is parallel at the gitab job level, take the corresponding fraction
# of the caselist.
if [ -n "$CI_NODE_INDEX" ]; then
- sed -ni $CI_NODE_INDEX~$CI_NODE_TOTAL"p" /install/testlist.txt
+ sed -ni $CI_NODE_INDEX~$CI_NODE_TOTAL"p" $TESTLIST
fi
# core_getversion checks if the driver is loaded and probed correctly
# so run it in all shards
-if ! grep -q "core_getversion" /install/testlist.txt; then
+if ! grep -q "core_getversion" $TESTLIST; then
# Add the line to the file
- echo "core_getversion" >> /install/testlist.txt
+ echo "core_getversion" >> $TESTLIST
fi
set +e
igt-runner \
run \
--igt-folder /igt/libexec/igt-gpu-tools \
- --caselist /install/testlist.txt \
+ --caselist $TESTLIST \
--output /results \
$IGT_SKIPS \
$IGT_FLAKES \
diff --git a/drivers/gpu/drm/ci/image-tags.yml b/drivers/gpu/drm/ci/image-tags.yml
index 7ab4f2514da8..13eda37bdf05 100644
--- a/drivers/gpu/drm/ci/image-tags.yml
+++ b/drivers/gpu/drm/ci/image-tags.yml
@@ -1,10 +1,10 @@
variables:
- CONTAINER_TAG: "2023-10-11-mesa-uprev"
+ CONTAINER_TAG: "2024-05-09-mesa-uprev"
DEBIAN_X86_64_BUILD_BASE_IMAGE: "debian/x86_64_build-base"
DEBIAN_BASE_TAG: "${CONTAINER_TAG}"
DEBIAN_X86_64_BUILD_IMAGE_PATH: "debian/x86_64_build"
- DEBIAN_BUILD_TAG: "2023-10-08-config"
+ DEBIAN_BUILD_TAG: "2024-06-10-vkms"
KERNEL_ROOTFS_TAG: "2023-10-06-amd"
diff --git a/drivers/gpu/drm/ci/lava-submit.sh b/drivers/gpu/drm/ci/lava-submit.sh
index 3d39b0c916a8..0707fa706a48 100755
--- a/drivers/gpu/drm/ci/lava-submit.sh
+++ b/drivers/gpu/drm/ci/lava-submit.sh
@@ -27,7 +27,7 @@ KERNEL_IMAGE_BASE="https://${BASE_SYSTEM_HOST_PATH}" \
section_end variables
tar zcf job-rootfs-overlay.tar.gz -C results/job-rootfs-overlay/ .
-ci-fairy s3cp --token-file "${CI_JOB_JWT_FILE}" job-rootfs-overlay.tar.gz "https://${JOB_ROOTFS_OVERLAY_PATH}"
+ci-fairy s3cp --token-file "${S3_JWT_FILE}" job-rootfs-overlay.tar.gz "https://${JOB_ROOTFS_OVERLAY_PATH}"
touch results/lava.log
tail -f results/lava.log &
@@ -45,7 +45,7 @@ PYTHONPATH=artifacts/ artifacts/lava/lava_job_submitter.py \
--ci-project-dir "${CI_PROJECT_DIR}" \
--device-type "${DEVICE_TYPE}" \
--dtb-filename "${DTB}" \
- --jwt-file "${CI_JOB_JWT_FILE}" \
+ --jwt-file "${S3_JWT_FILE}" \
--kernel-image-name "${KERNEL_IMAGE_NAME}" \
--kernel-image-type "${KERNEL_IMAGE_TYPE}" \
--boot-method "${BOOT_METHOD}" \
diff --git a/drivers/gpu/drm/ci/test.yml b/drivers/gpu/drm/ci/test.yml
index 8bc63912fddb..ee908b66aad2 100644
--- a/drivers/gpu/drm/ci/test.yml
+++ b/drivers/gpu/drm/ci/test.yml
@@ -24,6 +24,7 @@
variables:
HWCI_TEST_SCRIPT: "/install/igt_runner.sh"
DEBIAN_ARCH: "armhf"
+ FARM: collabora
dependencies:
- testing:arm32
needs:
@@ -39,6 +40,7 @@
variables:
HWCI_TEST_SCRIPT: "/install/igt_runner.sh"
DEBIAN_ARCH: "arm64"
+ FARM: collabora
dependencies:
- testing:arm64
needs:
@@ -54,6 +56,7 @@
variables:
HWCI_TEST_SCRIPT: "/install/igt_runner.sh"
DEBIAN_ARCH: "amd64"
+ FARM: collabora
dependencies:
- testing:x86_64
needs:
@@ -74,6 +77,7 @@
S3_ARTIFACT_NAME: "arm64/kernel-files"
BM_KERNEL: https://${PIPELINE_ARTIFACTS_BASE}/arm64/Image.gz
BM_CMDLINE: "ip=dhcp console=ttyMSM0,115200n8 $BM_KERNEL_EXTRA_ARGS root=/dev/nfs rw nfsrootdebug nfsroot=,tcp,nfsvers=4.2 init=/init $BM_KERNELARGS"
+ FARM: google
needs:
- debian/arm64_test
- job: testing:arm64
@@ -116,8 +120,9 @@ msm:apq8016:
- .baremetal-igt-arm64
stage: msm
variables:
+ DEVICE_TYPE: apq8016-sbc-usb-host
DRIVER_NAME: msm
- BM_DTB: https://${PIPELINE_ARTIFACTS_BASE}/arm64/apq8016-sbc-usb-host.dtb
+ BM_DTB: https://${PIPELINE_ARTIFACTS_BASE}/arm64/${DEVICE_TYPE}.dtb
GPU_VERSION: apq8016
# disabling unused clocks congests with the MDSS runtime PM trying to
# disable those clocks and causes boot to fail.
@@ -132,9 +137,10 @@ msm:apq8096:
- .baremetal-igt-arm64
stage: msm
variables:
+ DEVICE_TYPE: apq8096-db820c
DRIVER_NAME: msm
BM_KERNEL_EXTRA_ARGS: maxcpus=2
- BM_DTB: https://${PIPELINE_ARTIFACTS_BASE}/arm64/apq8096-db820c.dtb
+ BM_DTB: https://${PIPELINE_ARTIFACTS_BASE}/arm64/${DEVICE_TYPE}.dtb
GPU_VERSION: apq8096
RUNNER_TAG: google-freedreno-db820c
script:
@@ -146,6 +152,7 @@ msm:sdm845:
stage: msm
parallel: 6
variables:
+ DEVICE_TYPE: sdm845-cheza-r3
DRIVER_NAME: msm
BM_KERNEL: https://${PIPELINE_ARTIFACTS_BASE}/arm64/cheza-kernel
GPU_VERSION: sdm845
@@ -184,6 +191,7 @@ rockchip:rk3399:
extends:
- .lava-igt:x86_64
stage: i915
+ timeout: "1h30m"
variables:
DRIVER_NAME: i915
DTB: ""
@@ -194,7 +202,6 @@ i915:apl:
extends:
- .i915
parallel: 3
- timeout: "1h30m"
variables:
DEVICE_TYPE: asus-C523NA-A20057-coral
GPU_VERSION: apl
@@ -204,7 +211,6 @@ i915:glk:
extends:
- .i915
parallel: 2
- timeout: "1h30m"
variables:
DEVICE_TYPE: hp-x360-12b-ca0010nr-n4020-octopus
GPU_VERSION: glk
@@ -214,7 +220,6 @@ i915:amly:
extends:
- .i915
parallel: 2
- timeout: "1h30m"
variables:
DEVICE_TYPE: asus-C433TA-AJ0005-rammus
GPU_VERSION: amly
@@ -233,7 +238,6 @@ i915:whl:
extends:
- .i915
parallel: 2
- timeout: "1h30m"
variables:
DEVICE_TYPE: dell-latitude-5400-8665U-sarien
GPU_VERSION: whl
@@ -243,7 +247,6 @@ i915:cml:
extends:
- .i915
parallel: 2
- timeout: "1h30m"
variables:
DEVICE_TYPE: asus-C436FA-Flip-hatch
GPU_VERSION: cml
@@ -335,7 +338,7 @@ meson:g12b:
RUNNER_TAG: mesa-ci-x86-64-lava-meson-g12b-a311d-khadas-vim3
virtio_gpu:none:
- stage: virtio-gpu
+ stage: software-driver
variables:
CROSVM_GALLIUM_DRIVER: llvmpipe
DRIVER_NAME: virtio_gpu
@@ -355,3 +358,25 @@ virtio_gpu:none:
- debian/x86_64_test-gl
- testing:x86_64
- igt:x86_64
+
+vkms:none:
+ stage: software-driver
+ variables:
+ DRIVER_NAME: vkms
+ GPU_VERSION: none
+ extends:
+ - .test-gl
+ - .test-rules
+ tags:
+ - kvm
+ script:
+ - ln -sf $CI_PROJECT_DIR/install /install
+ - mv install/bzImage /lava-files/bzImage
+ - mkdir -p /lib/modules
+ - mkdir -p $CI_PROJECT_DIR/results
+ - ln -sf $CI_PROJECT_DIR/results /results
+ - ./install/crosvm-runner.sh ./install/igt_runner.sh
+ needs:
+ - debian/x86_64_test-gl
+ - testing:x86_64
+ - igt:x86_64
diff --git a/drivers/gpu/drm/ci/testlist.txt b/drivers/gpu/drm/ci/testlist.txt
deleted file mode 100644
index 3377f002f8c5..000000000000
--- a/drivers/gpu/drm/ci/testlist.txt
+++ /dev/null
@@ -1,2761 +0,0 @@
-core_auth@getclient-simple
-core_auth@getclient-master-drop
-core_auth@basic-auth
-core_auth@many-magics
-core_getclient
-core_getstats
-core_getversion
-core_setmaster_vs_auth
-drm_read@invalid-buffer
-drm_read@fault-buffer
-drm_read@empty-block
-drm_read@empty-nonblock
-drm_read@short-buffer-block
-drm_read@short-buffer-nonblock
-drm_read@short-buffer-wakeup
-gem_eio@throttle
-gem_eio@create
-gem_eio@create-ext
-gem_eio@context-create
-gem_eio@execbuf
-gem_eio@banned
-gem_eio@suspend
-gem_eio@hibernate
-gem_eio@in-flight-external
-gem_eio@in-flight-suspend
-gem_eio@reset-stress
-gem_eio@unwedge-stress
-gem_eio@wait-immediate
-gem_eio@wait-wedge-immediate
-gem_eio@in-flight-immediate
-gem_eio@in-flight-contexts-immediate
-gem_eio@in-flight-internal-immediate
-gem_eio@wait-1us
-gem_eio@wait-wedge-1us
-gem_eio@in-flight-1us
-gem_eio@in-flight-contexts-1us
-gem_eio@in-flight-internal-1us
-gem_eio@wait-10ms
-gem_eio@wait-wedge-10ms
-gem_eio@in-flight-10ms
-gem_eio@in-flight-contexts-10ms
-gem_eio@in-flight-internal-10ms
-gem_eio@kms
-kms_3d
-kms_addfb_basic@unused-handle
-kms_addfb_basic@unused-pitches
-kms_addfb_basic@unused-offsets
-kms_addfb_basic@unused-modifier
-kms_addfb_basic@clobberred-modifier
-kms_addfb_basic@invalid-smem-bo-on-discrete
-kms_addfb_basic@legacy-format
-kms_addfb_basic@no-handle
-kms_addfb_basic@basic
-kms_addfb_basic@bad-pitch-0
-kms_addfb_basic@bad-pitch-32
-kms_addfb_basic@bad-pitch-63
-kms_addfb_basic@bad-pitch-128
-kms_addfb_basic@bad-pitch-256
-kms_addfb_basic@bad-pitch-1024
-kms_addfb_basic@bad-pitch-999
-kms_addfb_basic@bad-pitch-65536
-kms_addfb_basic@invalid-get-prop-any
-kms_addfb_basic@invalid-get-prop
-kms_addfb_basic@invalid-set-prop-any
-kms_addfb_basic@invalid-set-prop
-kms_addfb_basic@master-rmfb
-kms_addfb_basic@addfb25-modifier-no-flag
-kms_addfb_basic@addfb25-bad-modifier
-kms_addfb_basic@addfb25-x-tiled-mismatch-legacy
-kms_addfb_basic@addfb25-x-tiled-legacy
-kms_addfb_basic@addfb25-framebuffer-vs-set-tiling
-kms_addfb_basic@basic-x-tiled-legacy
-kms_addfb_basic@framebuffer-vs-set-tiling
-kms_addfb_basic@tile-pitch-mismatch
-kms_addfb_basic@basic-y-tiled-legacy
-kms_addfb_basic@size-max
-kms_addfb_basic@too-wide
-kms_addfb_basic@too-high
-kms_addfb_basic@bo-too-small
-kms_addfb_basic@small-bo
-kms_addfb_basic@bo-too-small-due-to-tiling
-kms_addfb_basic@addfb25-y-tiled-legacy
-kms_addfb_basic@addfb25-yf-tiled-legacy
-kms_addfb_basic@addfb25-y-tiled-small-legacy
-kms_addfb_basic@addfb25-4-tiled
-kms_async_flips@async-flip-with-page-flip-events
-kms_async_flips@alternate-sync-async-flip
-kms_async_flips@test-time-stamp
-kms_async_flips@test-cursor
-kms_async_flips@invalid-async-flip
-kms_async_flips@crc
-kms_atomic@plane-overlay-legacy
-kms_atomic@plane-primary-legacy
-kms_atomic@plane-primary-overlay-mutable-zpos
-kms_atomic@plane-immutable-zpos
-kms_atomic@test-only
-kms_atomic@plane-cursor-legacy
-kms_atomic@plane-invalid-params
-kms_atomic@plane-invalid-params-fence
-kms_atomic@crtc-invalid-params
-kms_atomic@crtc-invalid-params-fence
-kms_atomic@atomic-invalid-params
-kms_atomic@atomic-plane-damage
-kms_atomic_interruptible@legacy-setmode
-kms_atomic_interruptible@atomic-setmode
-kms_atomic_interruptible@legacy-dpms
-kms_atomic_interruptible@legacy-pageflip
-kms_atomic_interruptible@legacy-cursor
-kms_atomic_interruptible@universal-setplane-primary
-kms_atomic_interruptible@universal-setplane-cursor
-kms_atomic_transition@plane-primary-toggle-with-vblank-wait
-kms_atomic_transition@plane-all-transition
-kms_atomic_transition@plane-all-transition-fencing
-kms_atomic_transition@plane-all-transition-nonblocking
-kms_atomic_transition@plane-all-transition-nonblocking-fencing
-kms_atomic_transition@plane-use-after-nonblocking-unbind
-kms_atomic_transition@plane-use-after-nonblocking-unbind-fencing
-kms_atomic_transition@plane-all-modeset-transition
-kms_atomic_transition@plane-all-modeset-transition-fencing
-kms_atomic_transition@plane-all-modeset-transition-internal-panels
-kms_atomic_transition@plane-all-modeset-transition-fencing-internal-panels
-kms_atomic_transition@plane-toggle-modeset-transition
-kms_atomic_transition@modeset-transition
-kms_atomic_transition@modeset-transition-fencing
-kms_atomic_transition@modeset-transition-nonblocking
-kms_atomic_transition@modeset-transition-nonblocking-fencing
-kms_big_fb@x-tiled-addfb-size-overflow
-kms_big_fb@y-tiled-addfb-size-overflow
-kms_big_fb@yf-tiled-addfb-size-overflow
-kms_big_fb@4-tiled-addfb-size-overflow
-kms_big_fb@x-tiled-addfb-size-offset-overflow
-kms_big_fb@y-tiled-addfb-size-offset-overflow
-kms_big_fb@yf-tiled-addfb-size-offset-overflow
-kms_big_fb@4-tiled-addfb-size-offset-overflow
-kms_big_fb@linear-addfb
-kms_big_fb@x-tiled-addfb
-kms_big_fb@y-tiled-addfb
-kms_big_fb@yf-tiled-addfb
-kms_big_fb@4-tiled-addfb
-kms_big_fb@linear-8bpp-rotate-0
-kms_big_fb@linear-8bpp-rotate-90
-kms_big_fb@linear-8bpp-rotate-180
-kms_big_fb@linear-8bpp-rotate-270
-kms_big_fb@linear-16bpp-rotate-0
-kms_big_fb@linear-16bpp-rotate-90
-kms_big_fb@linear-16bpp-rotate-180
-kms_big_fb@linear-16bpp-rotate-270
-kms_big_fb@linear-32bpp-rotate-0
-kms_big_fb@linear-32bpp-rotate-90
-kms_big_fb@linear-32bpp-rotate-180
-kms_big_fb@linear-32bpp-rotate-270
-kms_big_fb@linear-64bpp-rotate-0
-kms_big_fb@linear-64bpp-rotate-90
-kms_big_fb@linear-64bpp-rotate-180
-kms_big_fb@linear-64bpp-rotate-270
-kms_big_fb@x-tiled-8bpp-rotate-0
-kms_big_fb@x-tiled-8bpp-rotate-90
-kms_big_fb@x-tiled-8bpp-rotate-180
-kms_big_fb@x-tiled-8bpp-rotate-270
-kms_big_fb@x-tiled-16bpp-rotate-0
-kms_big_fb@x-tiled-16bpp-rotate-90
-kms_big_fb@x-tiled-16bpp-rotate-180
-kms_big_fb@x-tiled-16bpp-rotate-270
-kms_big_fb@x-tiled-32bpp-rotate-0
-kms_big_fb@x-tiled-32bpp-rotate-90
-kms_big_fb@x-tiled-32bpp-rotate-180
-kms_big_fb@x-tiled-32bpp-rotate-270
-kms_big_fb@x-tiled-64bpp-rotate-0
-kms_big_fb@x-tiled-64bpp-rotate-90
-kms_big_fb@x-tiled-64bpp-rotate-180
-kms_big_fb@x-tiled-64bpp-rotate-270
-kms_big_fb@y-tiled-8bpp-rotate-0
-kms_big_fb@y-tiled-8bpp-rotate-90
-kms_big_fb@y-tiled-8bpp-rotate-180
-kms_big_fb@y-tiled-8bpp-rotate-270
-kms_big_fb@y-tiled-16bpp-rotate-0
-kms_big_fb@y-tiled-16bpp-rotate-90
-kms_big_fb@y-tiled-16bpp-rotate-180
-kms_big_fb@y-tiled-16bpp-rotate-270
-kms_big_fb@y-tiled-32bpp-rotate-0
-kms_big_fb@y-tiled-32bpp-rotate-90
-kms_big_fb@y-tiled-32bpp-rotate-180
-kms_big_fb@y-tiled-32bpp-rotate-270
-kms_big_fb@y-tiled-64bpp-rotate-0
-kms_big_fb@y-tiled-64bpp-rotate-90
-kms_big_fb@y-tiled-64bpp-rotate-180
-kms_big_fb@y-tiled-64bpp-rotate-270
-kms_big_fb@yf-tiled-8bpp-rotate-0
-kms_big_fb@yf-tiled-8bpp-rotate-90
-kms_big_fb@yf-tiled-8bpp-rotate-180
-kms_big_fb@yf-tiled-8bpp-rotate-270
-kms_big_fb@yf-tiled-16bpp-rotate-0
-kms_big_fb@yf-tiled-16bpp-rotate-90
-kms_big_fb@yf-tiled-16bpp-rotate-180
-kms_big_fb@yf-tiled-16bpp-rotate-270
-kms_big_fb@yf-tiled-32bpp-rotate-0
-kms_big_fb@yf-tiled-32bpp-rotate-90
-kms_big_fb@yf-tiled-32bpp-rotate-180
-kms_big_fb@yf-tiled-32bpp-rotate-270
-kms_big_fb@yf-tiled-64bpp-rotate-0
-kms_big_fb@yf-tiled-64bpp-rotate-90
-kms_big_fb@yf-tiled-64bpp-rotate-180
-kms_big_fb@yf-tiled-64bpp-rotate-270
-kms_big_fb@4-tiled-8bpp-rotate-0
-kms_big_fb@4-tiled-8bpp-rotate-90
-kms_big_fb@4-tiled-8bpp-rotate-180
-kms_big_fb@4-tiled-8bpp-rotate-270
-kms_big_fb@4-tiled-16bpp-rotate-0
-kms_big_fb@4-tiled-16bpp-rotate-90
-kms_big_fb@4-tiled-16bpp-rotate-180
-kms_big_fb@4-tiled-16bpp-rotate-270
-kms_big_fb@4-tiled-32bpp-rotate-0
-kms_big_fb@4-tiled-32bpp-rotate-90
-kms_big_fb@4-tiled-32bpp-rotate-180
-kms_big_fb@4-tiled-32bpp-rotate-270
-kms_big_fb@4-tiled-64bpp-rotate-0
-kms_big_fb@4-tiled-64bpp-rotate-90
-kms_big_fb@4-tiled-64bpp-rotate-180
-kms_big_fb@4-tiled-64bpp-rotate-270
-kms_big_fb@linear-max-hw-stride-32bpp-rotate-0
-kms_big_fb@linear-max-hw-stride-32bpp-rotate-180
-kms_big_fb@linear-max-hw-stride-64bpp-rotate-0
-kms_big_fb@linear-max-hw-stride-64bpp-rotate-180
-kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-0
-kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-0-async-flip
-kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-180
-kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-180-async-flip
-kms_big_fb@x-tiled-max-hw-stride-64bpp-rotate-0
-kms_big_fb@x-tiled-max-hw-stride-64bpp-rotate-0-async-flip
-kms_big_fb@x-tiled-max-hw-stride-64bpp-rotate-180
-kms_big_fb@x-tiled-max-hw-stride-64bpp-rotate-180-async-flip
-kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-0-hflip
-kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-0-hflip-async-flip
-kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-180-hflip
-kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-180-hflip-async-flip
-kms_big_fb@x-tiled-max-hw-stride-64bpp-rotate-0-hflip
-kms_big_fb@x-tiled-max-hw-stride-64bpp-rotate-0-hflip-async-flip
-kms_big_fb@x-tiled-max-hw-stride-64bpp-rotate-180-hflip
-kms_big_fb@x-tiled-max-hw-stride-64bpp-rotate-180-hflip-async-flip
-kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-0
-kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-0-async-flip
-kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180
-kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180-async-flip
-kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-0
-kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-0-async-flip
-kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-180
-kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-180-async-flip
-kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-0-hflip
-kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-0-hflip-async-flip
-kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180-hflip
-kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180-hflip-async-flip
-kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-0-hflip
-kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-0-hflip-async-flip
-kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-180-hflip
-kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-180-hflip-async-flip
-kms_big_fb@yf-tiled-max-hw-stride-32bpp-rotate-0
-kms_big_fb@yf-tiled-max-hw-stride-32bpp-rotate-0-async-flip
-kms_big_fb@yf-tiled-max-hw-stride-32bpp-rotate-180
-kms_big_fb@yf-tiled-max-hw-stride-32bpp-rotate-180-async-flip
-kms_big_fb@yf-tiled-max-hw-stride-64bpp-rotate-0
-kms_big_fb@yf-tiled-max-hw-stride-64bpp-rotate-0-async-flip
-kms_big_fb@yf-tiled-max-hw-stride-64bpp-rotate-180
-kms_big_fb@yf-tiled-max-hw-stride-64bpp-rotate-180-async-flip
-kms_big_fb@yf-tiled-max-hw-stride-32bpp-rotate-0-hflip
-kms_big_fb@yf-tiled-max-hw-stride-32bpp-rotate-0-hflip-async-flip
-kms_big_fb@yf-tiled-max-hw-stride-32bpp-rotate-180-hflip
-kms_big_fb@yf-tiled-max-hw-stride-32bpp-rotate-180-hflip-async-flip
-kms_big_fb@yf-tiled-max-hw-stride-64bpp-rotate-0-hflip
-kms_big_fb@yf-tiled-max-hw-stride-64bpp-rotate-0-hflip-async-flip
-kms_big_fb@yf-tiled-max-hw-stride-64bpp-rotate-180-hflip
-kms_big_fb@yf-tiled-max-hw-stride-64bpp-rotate-180-hflip-async-flip
-kms_big_fb@4-tiled-max-hw-stride-32bpp-rotate-0
-kms_big_fb@4-tiled-max-hw-stride-32bpp-rotate-0-async-flip
-kms_big_fb@4-tiled-max-hw-stride-32bpp-rotate-180
-kms_big_fb@4-tiled-max-hw-stride-32bpp-rotate-180-async-flip
-kms_big_fb@4-tiled-max-hw-stride-64bpp-rotate-0
-kms_big_fb@4-tiled-max-hw-stride-64bpp-rotate-0-async-flip
-kms_big_fb@4-tiled-max-hw-stride-64bpp-rotate-180
-kms_big_fb@4-tiled-max-hw-stride-64bpp-rotate-180-async-flip
-kms_big_fb@4-tiled-max-hw-stride-32bpp-rotate-0-hflip
-kms_big_fb@4-tiled-max-hw-stride-32bpp-rotate-0-hflip-async-flip
-kms_big_fb@4-tiled-max-hw-stride-32bpp-rotate-180-hflip
-kms_big_fb@4-tiled-max-hw-stride-32bpp-rotate-180-hflip-async-flip
-kms_big_fb@4-tiled-max-hw-stride-64bpp-rotate-0-hflip
-kms_big_fb@4-tiled-max-hw-stride-64bpp-rotate-0-hflip-async-flip
-kms_big_fb@4-tiled-max-hw-stride-64bpp-rotate-180-hflip
-kms_big_fb@4-tiled-max-hw-stride-64bpp-rotate-180-hflip-async-flip
-kms_big_joiner@basic
-kms_big_joiner@invalid-modeset
-kms_big_joiner@2x-modeset
-kms_busy@basic
-kms_busy@basic-hang
-kms_busy@extended-pageflip-modeset-hang-oldfb
-kms_busy@extended-pageflip-hang-oldfb
-kms_busy@extended-pageflip-hang-newfb
-kms_busy@extended-modeset-hang-oldfb
-kms_busy@extended-modeset-hang-newfb
-kms_busy@extended-modeset-hang-oldfb-with-reset
-kms_busy@extended-modeset-hang-newfb-with-reset
-kms_bw@linear-tiling-1-displays-1920x1080p
-kms_bw@linear-tiling-1-displays-2560x1440p
-kms_bw@linear-tiling-1-displays-3840x2160p
-kms_bw@linear-tiling-2-displays-1920x1080p
-kms_bw@linear-tiling-2-displays-2560x1440p
-kms_bw@linear-tiling-2-displays-3840x2160p
-kms_bw@linear-tiling-3-displays-1920x1080p
-kms_bw@linear-tiling-3-displays-2560x1440p
-kms_bw@linear-tiling-3-displays-3840x2160p
-kms_bw@linear-tiling-4-displays-1920x1080p
-kms_bw@linear-tiling-4-displays-2560x1440p
-kms_bw@linear-tiling-4-displays-3840x2160p
-kms_bw@linear-tiling-5-displays-1920x1080p
-kms_bw@linear-tiling-5-displays-2560x1440p
-kms_bw@linear-tiling-5-displays-3840x2160p
-kms_bw@linear-tiling-6-displays-1920x1080p
-kms_bw@linear-tiling-6-displays-2560x1440p
-kms_bw@linear-tiling-6-displays-3840x2160p
-kms_bw@linear-tiling-7-displays-1920x1080p
-kms_bw@linear-tiling-7-displays-2560x1440p
-kms_bw@linear-tiling-7-displays-3840x2160p
-kms_bw@linear-tiling-8-displays-1920x1080p
-kms_bw@linear-tiling-8-displays-2560x1440p
-kms_bw@linear-tiling-8-displays-3840x2160p
-kms_ccs@pipe-A-bad-pixel-format-y-tiled-ccs
-kms_ccs@pipe-A-bad-pixel-format-yf-tiled-ccs
-kms_ccs@pipe-A-bad-pixel-format-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-A-bad-pixel-format-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-A-bad-pixel-format-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-A-bad-pixel-format-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-A-bad-pixel-format-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-A-bad-pixel-format-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-A-bad-pixel-format-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-A-bad-pixel-format-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-A-bad-pixel-format-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-A-bad-rotation-90-y-tiled-ccs
-kms_ccs@pipe-A-bad-rotation-90-yf-tiled-ccs
-kms_ccs@pipe-A-bad-rotation-90-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-A-bad-rotation-90-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-A-bad-rotation-90-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-A-bad-rotation-90-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-A-bad-rotation-90-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-A-bad-rotation-90-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-A-bad-rotation-90-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-A-bad-rotation-90-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-A-bad-rotation-90-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-A-crc-primary-basic-y-tiled-ccs
-kms_ccs@pipe-A-crc-primary-basic-yf-tiled-ccs
-kms_ccs@pipe-A-crc-primary-basic-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-A-crc-primary-basic-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-A-crc-primary-basic-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-A-crc-primary-basic-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-A-crc-primary-basic-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-A-crc-primary-basic-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-A-crc-primary-basic-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-A-crc-primary-basic-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-A-crc-primary-basic-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-A-crc-primary-rotation-180-y-tiled-ccs
-kms_ccs@pipe-A-crc-primary-rotation-180-yf-tiled-ccs
-kms_ccs@pipe-A-crc-primary-rotation-180-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-A-crc-primary-rotation-180-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-A-crc-primary-rotation-180-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-A-crc-primary-rotation-180-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-A-crc-primary-rotation-180-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-A-crc-primary-rotation-180-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-A-crc-primary-rotation-180-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-A-crc-primary-rotation-180-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-A-crc-primary-rotation-180-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-A-random-ccs-data-y-tiled-ccs
-kms_ccs@pipe-A-random-ccs-data-yf-tiled-ccs
-kms_ccs@pipe-A-random-ccs-data-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-A-random-ccs-data-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-A-random-ccs-data-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-A-random-ccs-data-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-A-random-ccs-data-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-A-random-ccs-data-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-A-random-ccs-data-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-A-random-ccs-data-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-A-random-ccs-data-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-A-missing-ccs-buffer-y-tiled-ccs
-kms_ccs@pipe-A-missing-ccs-buffer-yf-tiled-ccs
-kms_ccs@pipe-A-missing-ccs-buffer-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-A-missing-ccs-buffer-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-A-missing-ccs-buffer-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-A-missing-ccs-buffer-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-A-missing-ccs-buffer-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-A-missing-ccs-buffer-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-A-ccs-on-another-bo-y-tiled-ccs
-kms_ccs@pipe-A-ccs-on-another-bo-yf-tiled-ccs
-kms_ccs@pipe-A-ccs-on-another-bo-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-A-ccs-on-another-bo-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-A-ccs-on-another-bo-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-A-ccs-on-another-bo-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-A-ccs-on-another-bo-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-A-ccs-on-another-bo-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-A-bad-aux-stride-y-tiled-ccs
-kms_ccs@pipe-A-bad-aux-stride-yf-tiled-ccs
-kms_ccs@pipe-A-bad-aux-stride-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-A-bad-aux-stride-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-A-bad-aux-stride-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-A-bad-aux-stride-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-A-bad-aux-stride-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-A-bad-aux-stride-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-A-crc-sprite-planes-basic-y-tiled-ccs
-kms_ccs@pipe-A-crc-sprite-planes-basic-yf-tiled-ccs
-kms_ccs@pipe-A-crc-sprite-planes-basic-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-A-crc-sprite-planes-basic-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-A-crc-sprite-planes-basic-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-A-crc-sprite-planes-basic-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-A-crc-sprite-planes-basic-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-A-crc-sprite-planes-basic-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-A-crc-sprite-planes-basic-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-A-crc-sprite-planes-basic-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-A-crc-sprite-planes-basic-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-B-bad-pixel-format-y-tiled-ccs
-kms_ccs@pipe-B-bad-pixel-format-yf-tiled-ccs
-kms_ccs@pipe-B-bad-pixel-format-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-B-bad-pixel-format-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-B-bad-pixel-format-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-B-bad-pixel-format-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-B-bad-pixel-format-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-B-bad-pixel-format-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-B-bad-pixel-format-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-B-bad-pixel-format-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-B-bad-pixel-format-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-B-bad-rotation-90-y-tiled-ccs
-kms_ccs@pipe-B-bad-rotation-90-yf-tiled-ccs
-kms_ccs@pipe-B-bad-rotation-90-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-B-bad-rotation-90-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-B-bad-rotation-90-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-B-bad-rotation-90-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-B-bad-rotation-90-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-B-bad-rotation-90-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-B-bad-rotation-90-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-B-bad-rotation-90-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-B-bad-rotation-90-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-B-crc-primary-basic-y-tiled-ccs
-kms_ccs@pipe-B-crc-primary-basic-yf-tiled-ccs
-kms_ccs@pipe-B-crc-primary-basic-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-B-crc-primary-basic-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-B-crc-primary-basic-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-B-crc-primary-basic-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-B-crc-primary-basic-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-B-crc-primary-basic-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-B-crc-primary-basic-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-B-crc-primary-basic-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-B-crc-primary-basic-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-B-crc-primary-rotation-180-y-tiled-ccs
-kms_ccs@pipe-B-crc-primary-rotation-180-yf-tiled-ccs
-kms_ccs@pipe-B-crc-primary-rotation-180-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-B-crc-primary-rotation-180-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-B-crc-primary-rotation-180-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-B-crc-primary-rotation-180-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-B-crc-primary-rotation-180-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-B-crc-primary-rotation-180-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-B-crc-primary-rotation-180-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-B-crc-primary-rotation-180-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-B-crc-primary-rotation-180-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-B-random-ccs-data-y-tiled-ccs
-kms_ccs@pipe-B-random-ccs-data-yf-tiled-ccs
-kms_ccs@pipe-B-random-ccs-data-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-B-random-ccs-data-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-B-random-ccs-data-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-B-random-ccs-data-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-B-random-ccs-data-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-B-random-ccs-data-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-B-random-ccs-data-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-B-random-ccs-data-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-B-random-ccs-data-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-B-missing-ccs-buffer-y-tiled-ccs
-kms_ccs@pipe-B-missing-ccs-buffer-yf-tiled-ccs
-kms_ccs@pipe-B-missing-ccs-buffer-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-B-missing-ccs-buffer-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-B-missing-ccs-buffer-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-B-missing-ccs-buffer-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-B-missing-ccs-buffer-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-B-missing-ccs-buffer-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-B-ccs-on-another-bo-y-tiled-ccs
-kms_ccs@pipe-B-ccs-on-another-bo-yf-tiled-ccs
-kms_ccs@pipe-B-ccs-on-another-bo-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-B-ccs-on-another-bo-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-B-ccs-on-another-bo-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-B-ccs-on-another-bo-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-B-ccs-on-another-bo-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-B-ccs-on-another-bo-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-B-bad-aux-stride-y-tiled-ccs
-kms_ccs@pipe-B-bad-aux-stride-yf-tiled-ccs
-kms_ccs@pipe-B-bad-aux-stride-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-B-bad-aux-stride-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-B-bad-aux-stride-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-B-bad-aux-stride-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-B-bad-aux-stride-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-B-bad-aux-stride-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-B-crc-sprite-planes-basic-y-tiled-ccs
-kms_ccs@pipe-B-crc-sprite-planes-basic-yf-tiled-ccs
-kms_ccs@pipe-B-crc-sprite-planes-basic-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-B-crc-sprite-planes-basic-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-B-crc-sprite-planes-basic-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-B-crc-sprite-planes-basic-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-B-crc-sprite-planes-basic-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-B-crc-sprite-planes-basic-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-B-crc-sprite-planes-basic-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-B-crc-sprite-planes-basic-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-B-crc-sprite-planes-basic-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-C-bad-pixel-format-y-tiled-ccs
-kms_ccs@pipe-C-bad-pixel-format-yf-tiled-ccs
-kms_ccs@pipe-C-bad-pixel-format-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-C-bad-pixel-format-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-C-bad-pixel-format-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-C-bad-pixel-format-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-C-bad-pixel-format-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-C-bad-pixel-format-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-C-bad-pixel-format-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-C-bad-pixel-format-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-C-bad-pixel-format-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-C-bad-rotation-90-y-tiled-ccs
-kms_ccs@pipe-C-bad-rotation-90-yf-tiled-ccs
-kms_ccs@pipe-C-bad-rotation-90-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-C-bad-rotation-90-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-C-bad-rotation-90-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-C-bad-rotation-90-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-C-bad-rotation-90-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-C-bad-rotation-90-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-C-bad-rotation-90-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-C-bad-rotation-90-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-C-bad-rotation-90-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-C-crc-primary-basic-y-tiled-ccs
-kms_ccs@pipe-C-crc-primary-basic-yf-tiled-ccs
-kms_ccs@pipe-C-crc-primary-basic-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-C-crc-primary-basic-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-C-crc-primary-basic-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-C-crc-primary-basic-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-C-crc-primary-basic-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-C-crc-primary-basic-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-C-crc-primary-basic-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-C-crc-primary-basic-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-C-crc-primary-basic-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-C-crc-primary-rotation-180-y-tiled-ccs
-kms_ccs@pipe-C-crc-primary-rotation-180-yf-tiled-ccs
-kms_ccs@pipe-C-crc-primary-rotation-180-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-C-crc-primary-rotation-180-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-C-crc-primary-rotation-180-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-C-crc-primary-rotation-180-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-C-crc-primary-rotation-180-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-C-crc-primary-rotation-180-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-C-crc-primary-rotation-180-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-C-crc-primary-rotation-180-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-C-crc-primary-rotation-180-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-C-random-ccs-data-y-tiled-ccs
-kms_ccs@pipe-C-random-ccs-data-yf-tiled-ccs
-kms_ccs@pipe-C-random-ccs-data-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-C-random-ccs-data-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-C-random-ccs-data-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-C-random-ccs-data-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-C-random-ccs-data-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-C-random-ccs-data-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-C-random-ccs-data-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-C-random-ccs-data-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-C-random-ccs-data-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-C-missing-ccs-buffer-y-tiled-ccs
-kms_ccs@pipe-C-missing-ccs-buffer-yf-tiled-ccs
-kms_ccs@pipe-C-missing-ccs-buffer-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-C-missing-ccs-buffer-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-C-missing-ccs-buffer-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-C-missing-ccs-buffer-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-C-missing-ccs-buffer-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-C-missing-ccs-buffer-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-C-ccs-on-another-bo-y-tiled-ccs
-kms_ccs@pipe-C-ccs-on-another-bo-yf-tiled-ccs
-kms_ccs@pipe-C-ccs-on-another-bo-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-C-ccs-on-another-bo-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-C-ccs-on-another-bo-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-C-ccs-on-another-bo-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-C-ccs-on-another-bo-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-C-ccs-on-another-bo-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-C-bad-aux-stride-y-tiled-ccs
-kms_ccs@pipe-C-bad-aux-stride-yf-tiled-ccs
-kms_ccs@pipe-C-bad-aux-stride-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-C-bad-aux-stride-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-C-bad-aux-stride-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-C-bad-aux-stride-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-C-bad-aux-stride-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-C-bad-aux-stride-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-C-crc-sprite-planes-basic-y-tiled-ccs
-kms_ccs@pipe-C-crc-sprite-planes-basic-yf-tiled-ccs
-kms_ccs@pipe-C-crc-sprite-planes-basic-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-C-crc-sprite-planes-basic-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-C-crc-sprite-planes-basic-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-C-crc-sprite-planes-basic-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-C-crc-sprite-planes-basic-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-C-crc-sprite-planes-basic-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-C-crc-sprite-planes-basic-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-C-crc-sprite-planes-basic-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-C-crc-sprite-planes-basic-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-D-bad-pixel-format-y-tiled-ccs
-kms_ccs@pipe-D-bad-pixel-format-yf-tiled-ccs
-kms_ccs@pipe-D-bad-pixel-format-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-D-bad-pixel-format-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-D-bad-pixel-format-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-D-bad-pixel-format-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-D-bad-pixel-format-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-D-bad-pixel-format-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-D-bad-pixel-format-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-D-bad-pixel-format-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-D-bad-pixel-format-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-D-bad-rotation-90-y-tiled-ccs
-kms_ccs@pipe-D-bad-rotation-90-yf-tiled-ccs
-kms_ccs@pipe-D-bad-rotation-90-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-D-bad-rotation-90-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-D-bad-rotation-90-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-D-bad-rotation-90-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-D-bad-rotation-90-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-D-bad-rotation-90-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-D-bad-rotation-90-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-D-bad-rotation-90-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-D-bad-rotation-90-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-D-crc-primary-basic-y-tiled-ccs
-kms_ccs@pipe-D-crc-primary-basic-yf-tiled-ccs
-kms_ccs@pipe-D-crc-primary-basic-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-D-crc-primary-basic-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-D-crc-primary-basic-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-D-crc-primary-basic-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-D-crc-primary-basic-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-D-crc-primary-basic-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-D-crc-primary-basic-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-D-crc-primary-basic-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-D-crc-primary-basic-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-D-crc-primary-rotation-180-y-tiled-ccs
-kms_ccs@pipe-D-crc-primary-rotation-180-yf-tiled-ccs
-kms_ccs@pipe-D-crc-primary-rotation-180-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-D-crc-primary-rotation-180-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-D-crc-primary-rotation-180-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-D-crc-primary-rotation-180-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-D-crc-primary-rotation-180-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-D-crc-primary-rotation-180-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-D-crc-primary-rotation-180-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-D-crc-primary-rotation-180-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-D-crc-primary-rotation-180-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-D-random-ccs-data-y-tiled-ccs
-kms_ccs@pipe-D-random-ccs-data-yf-tiled-ccs
-kms_ccs@pipe-D-random-ccs-data-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-D-random-ccs-data-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-D-random-ccs-data-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-D-random-ccs-data-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-D-random-ccs-data-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-D-random-ccs-data-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-D-random-ccs-data-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-D-random-ccs-data-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-D-random-ccs-data-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-D-missing-ccs-buffer-y-tiled-ccs
-kms_ccs@pipe-D-missing-ccs-buffer-yf-tiled-ccs
-kms_ccs@pipe-D-missing-ccs-buffer-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-D-missing-ccs-buffer-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-D-missing-ccs-buffer-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-D-missing-ccs-buffer-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-D-missing-ccs-buffer-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-D-missing-ccs-buffer-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-D-ccs-on-another-bo-y-tiled-ccs
-kms_ccs@pipe-D-ccs-on-another-bo-yf-tiled-ccs
-kms_ccs@pipe-D-ccs-on-another-bo-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-D-ccs-on-another-bo-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-D-ccs-on-another-bo-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-D-ccs-on-another-bo-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-D-ccs-on-another-bo-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-D-ccs-on-another-bo-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-D-bad-aux-stride-y-tiled-ccs
-kms_ccs@pipe-D-bad-aux-stride-yf-tiled-ccs
-kms_ccs@pipe-D-bad-aux-stride-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-D-bad-aux-stride-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-D-bad-aux-stride-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-D-bad-aux-stride-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-D-bad-aux-stride-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-D-bad-aux-stride-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-D-crc-sprite-planes-basic-y-tiled-ccs
-kms_ccs@pipe-D-crc-sprite-planes-basic-yf-tiled-ccs
-kms_ccs@pipe-D-crc-sprite-planes-basic-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-D-crc-sprite-planes-basic-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-D-crc-sprite-planes-basic-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-D-crc-sprite-planes-basic-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-D-crc-sprite-planes-basic-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-D-crc-sprite-planes-basic-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-D-crc-sprite-planes-basic-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-D-crc-sprite-planes-basic-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-D-crc-sprite-planes-basic-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-E-bad-pixel-format-y-tiled-ccs
-kms_ccs@pipe-E-bad-pixel-format-yf-tiled-ccs
-kms_ccs@pipe-E-bad-pixel-format-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-E-bad-pixel-format-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-E-bad-pixel-format-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-E-bad-pixel-format-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-E-bad-pixel-format-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-E-bad-pixel-format-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-E-bad-pixel-format-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-E-bad-pixel-format-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-E-bad-pixel-format-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-E-bad-rotation-90-y-tiled-ccs
-kms_ccs@pipe-E-bad-rotation-90-yf-tiled-ccs
-kms_ccs@pipe-E-bad-rotation-90-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-E-bad-rotation-90-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-E-bad-rotation-90-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-E-bad-rotation-90-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-E-bad-rotation-90-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-E-bad-rotation-90-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-E-bad-rotation-90-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-E-bad-rotation-90-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-E-bad-rotation-90-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-E-crc-primary-basic-y-tiled-ccs
-kms_ccs@pipe-E-crc-primary-basic-yf-tiled-ccs
-kms_ccs@pipe-E-crc-primary-basic-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-E-crc-primary-basic-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-E-crc-primary-basic-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-E-crc-primary-basic-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-E-crc-primary-basic-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-E-crc-primary-basic-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-E-crc-primary-basic-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-E-crc-primary-basic-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-E-crc-primary-basic-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-E-crc-primary-rotation-180-y-tiled-ccs
-kms_ccs@pipe-E-crc-primary-rotation-180-yf-tiled-ccs
-kms_ccs@pipe-E-crc-primary-rotation-180-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-E-crc-primary-rotation-180-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-E-crc-primary-rotation-180-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-E-crc-primary-rotation-180-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-E-crc-primary-rotation-180-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-E-crc-primary-rotation-180-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-E-crc-primary-rotation-180-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-E-crc-primary-rotation-180-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-E-crc-primary-rotation-180-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-E-random-ccs-data-y-tiled-ccs
-kms_ccs@pipe-E-random-ccs-data-yf-tiled-ccs
-kms_ccs@pipe-E-random-ccs-data-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-E-random-ccs-data-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-E-random-ccs-data-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-E-random-ccs-data-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-E-random-ccs-data-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-E-random-ccs-data-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-E-random-ccs-data-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-E-random-ccs-data-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-E-random-ccs-data-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-E-missing-ccs-buffer-y-tiled-ccs
-kms_ccs@pipe-E-missing-ccs-buffer-yf-tiled-ccs
-kms_ccs@pipe-E-missing-ccs-buffer-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-E-missing-ccs-buffer-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-E-missing-ccs-buffer-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-E-missing-ccs-buffer-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-E-missing-ccs-buffer-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-E-missing-ccs-buffer-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-E-ccs-on-another-bo-y-tiled-ccs
-kms_ccs@pipe-E-ccs-on-another-bo-yf-tiled-ccs
-kms_ccs@pipe-E-ccs-on-another-bo-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-E-ccs-on-another-bo-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-E-ccs-on-another-bo-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-E-ccs-on-another-bo-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-E-ccs-on-another-bo-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-E-ccs-on-another-bo-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-E-bad-aux-stride-y-tiled-ccs
-kms_ccs@pipe-E-bad-aux-stride-yf-tiled-ccs
-kms_ccs@pipe-E-bad-aux-stride-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-E-bad-aux-stride-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-E-bad-aux-stride-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-E-bad-aux-stride-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-E-bad-aux-stride-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-E-bad-aux-stride-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-E-crc-sprite-planes-basic-y-tiled-ccs
-kms_ccs@pipe-E-crc-sprite-planes-basic-yf-tiled-ccs
-kms_ccs@pipe-E-crc-sprite-planes-basic-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-E-crc-sprite-planes-basic-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-E-crc-sprite-planes-basic-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-E-crc-sprite-planes-basic-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-E-crc-sprite-planes-basic-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-E-crc-sprite-planes-basic-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-E-crc-sprite-planes-basic-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-E-crc-sprite-planes-basic-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-E-crc-sprite-planes-basic-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-F-bad-pixel-format-y-tiled-ccs
-kms_ccs@pipe-F-bad-pixel-format-yf-tiled-ccs
-kms_ccs@pipe-F-bad-pixel-format-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-F-bad-pixel-format-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-F-bad-pixel-format-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-F-bad-pixel-format-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-F-bad-pixel-format-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-F-bad-pixel-format-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-F-bad-pixel-format-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-F-bad-pixel-format-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-F-bad-pixel-format-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-F-bad-rotation-90-y-tiled-ccs
-kms_ccs@pipe-F-bad-rotation-90-yf-tiled-ccs
-kms_ccs@pipe-F-bad-rotation-90-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-F-bad-rotation-90-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-F-bad-rotation-90-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-F-bad-rotation-90-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-F-bad-rotation-90-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-F-bad-rotation-90-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-F-bad-rotation-90-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-F-bad-rotation-90-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-F-bad-rotation-90-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-F-crc-primary-basic-y-tiled-ccs
-kms_ccs@pipe-F-crc-primary-basic-yf-tiled-ccs
-kms_ccs@pipe-F-crc-primary-basic-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-F-crc-primary-basic-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-F-crc-primary-basic-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-F-crc-primary-basic-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-F-crc-primary-basic-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-F-crc-primary-basic-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-F-crc-primary-basic-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-F-crc-primary-basic-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-F-crc-primary-basic-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-F-crc-primary-rotation-180-y-tiled-ccs
-kms_ccs@pipe-F-crc-primary-rotation-180-yf-tiled-ccs
-kms_ccs@pipe-F-crc-primary-rotation-180-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-F-crc-primary-rotation-180-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-F-crc-primary-rotation-180-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-F-crc-primary-rotation-180-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-F-crc-primary-rotation-180-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-F-crc-primary-rotation-180-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-F-crc-primary-rotation-180-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-F-crc-primary-rotation-180-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-F-crc-primary-rotation-180-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-F-random-ccs-data-y-tiled-ccs
-kms_ccs@pipe-F-random-ccs-data-yf-tiled-ccs
-kms_ccs@pipe-F-random-ccs-data-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-F-random-ccs-data-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-F-random-ccs-data-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-F-random-ccs-data-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-F-random-ccs-data-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-F-random-ccs-data-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-F-random-ccs-data-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-F-random-ccs-data-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-F-random-ccs-data-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-F-missing-ccs-buffer-y-tiled-ccs
-kms_ccs@pipe-F-missing-ccs-buffer-yf-tiled-ccs
-kms_ccs@pipe-F-missing-ccs-buffer-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-F-missing-ccs-buffer-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-F-missing-ccs-buffer-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-F-missing-ccs-buffer-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-F-missing-ccs-buffer-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-F-missing-ccs-buffer-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-F-ccs-on-another-bo-y-tiled-ccs
-kms_ccs@pipe-F-ccs-on-another-bo-yf-tiled-ccs
-kms_ccs@pipe-F-ccs-on-another-bo-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-F-ccs-on-another-bo-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-F-ccs-on-another-bo-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-F-ccs-on-another-bo-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-F-ccs-on-another-bo-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-F-ccs-on-another-bo-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-F-bad-aux-stride-y-tiled-ccs
-kms_ccs@pipe-F-bad-aux-stride-yf-tiled-ccs
-kms_ccs@pipe-F-bad-aux-stride-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-F-bad-aux-stride-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-F-bad-aux-stride-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-F-bad-aux-stride-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-F-bad-aux-stride-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-F-bad-aux-stride-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-F-crc-sprite-planes-basic-y-tiled-ccs
-kms_ccs@pipe-F-crc-sprite-planes-basic-yf-tiled-ccs
-kms_ccs@pipe-F-crc-sprite-planes-basic-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-F-crc-sprite-planes-basic-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-F-crc-sprite-planes-basic-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-F-crc-sprite-planes-basic-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-F-crc-sprite-planes-basic-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-F-crc-sprite-planes-basic-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-F-crc-sprite-planes-basic-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-F-crc-sprite-planes-basic-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-F-crc-sprite-planes-basic-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-G-bad-pixel-format-y-tiled-ccs
-kms_ccs@pipe-G-bad-pixel-format-yf-tiled-ccs
-kms_ccs@pipe-G-bad-pixel-format-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-G-bad-pixel-format-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-G-bad-pixel-format-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-G-bad-pixel-format-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-G-bad-pixel-format-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-G-bad-pixel-format-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-G-bad-pixel-format-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-G-bad-pixel-format-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-G-bad-pixel-format-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-G-bad-rotation-90-y-tiled-ccs
-kms_ccs@pipe-G-bad-rotation-90-yf-tiled-ccs
-kms_ccs@pipe-G-bad-rotation-90-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-G-bad-rotation-90-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-G-bad-rotation-90-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-G-bad-rotation-90-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-G-bad-rotation-90-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-G-bad-rotation-90-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-G-bad-rotation-90-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-G-bad-rotation-90-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-G-bad-rotation-90-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-G-crc-primary-basic-y-tiled-ccs
-kms_ccs@pipe-G-crc-primary-basic-yf-tiled-ccs
-kms_ccs@pipe-G-crc-primary-basic-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-G-crc-primary-basic-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-G-crc-primary-basic-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-G-crc-primary-basic-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-G-crc-primary-basic-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-G-crc-primary-basic-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-G-crc-primary-basic-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-G-crc-primary-basic-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-G-crc-primary-basic-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-G-crc-primary-rotation-180-y-tiled-ccs
-kms_ccs@pipe-G-crc-primary-rotation-180-yf-tiled-ccs
-kms_ccs@pipe-G-crc-primary-rotation-180-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-G-crc-primary-rotation-180-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-G-crc-primary-rotation-180-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-G-crc-primary-rotation-180-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-G-crc-primary-rotation-180-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-G-crc-primary-rotation-180-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-G-crc-primary-rotation-180-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-G-crc-primary-rotation-180-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-G-crc-primary-rotation-180-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-G-random-ccs-data-y-tiled-ccs
-kms_ccs@pipe-G-random-ccs-data-yf-tiled-ccs
-kms_ccs@pipe-G-random-ccs-data-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-G-random-ccs-data-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-G-random-ccs-data-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-G-random-ccs-data-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-G-random-ccs-data-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-G-random-ccs-data-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-G-random-ccs-data-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-G-random-ccs-data-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-G-random-ccs-data-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-G-missing-ccs-buffer-y-tiled-ccs
-kms_ccs@pipe-G-missing-ccs-buffer-yf-tiled-ccs
-kms_ccs@pipe-G-missing-ccs-buffer-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-G-missing-ccs-buffer-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-G-missing-ccs-buffer-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-G-missing-ccs-buffer-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-G-missing-ccs-buffer-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-G-missing-ccs-buffer-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-G-ccs-on-another-bo-y-tiled-ccs
-kms_ccs@pipe-G-ccs-on-another-bo-yf-tiled-ccs
-kms_ccs@pipe-G-ccs-on-another-bo-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-G-ccs-on-another-bo-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-G-ccs-on-another-bo-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-G-ccs-on-another-bo-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-G-ccs-on-another-bo-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-G-ccs-on-another-bo-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-G-bad-aux-stride-y-tiled-ccs
-kms_ccs@pipe-G-bad-aux-stride-yf-tiled-ccs
-kms_ccs@pipe-G-bad-aux-stride-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-G-bad-aux-stride-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-G-bad-aux-stride-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-G-bad-aux-stride-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-G-bad-aux-stride-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-G-bad-aux-stride-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-G-crc-sprite-planes-basic-y-tiled-ccs
-kms_ccs@pipe-G-crc-sprite-planes-basic-yf-tiled-ccs
-kms_ccs@pipe-G-crc-sprite-planes-basic-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-G-crc-sprite-planes-basic-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-G-crc-sprite-planes-basic-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-G-crc-sprite-planes-basic-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-G-crc-sprite-planes-basic-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-G-crc-sprite-planes-basic-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-G-crc-sprite-planes-basic-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-G-crc-sprite-planes-basic-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-G-crc-sprite-planes-basic-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-H-bad-pixel-format-y-tiled-ccs
-kms_ccs@pipe-H-bad-pixel-format-yf-tiled-ccs
-kms_ccs@pipe-H-bad-pixel-format-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-H-bad-pixel-format-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-H-bad-pixel-format-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-H-bad-pixel-format-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-H-bad-pixel-format-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-H-bad-pixel-format-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-H-bad-pixel-format-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-H-bad-pixel-format-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-H-bad-pixel-format-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-H-bad-rotation-90-y-tiled-ccs
-kms_ccs@pipe-H-bad-rotation-90-yf-tiled-ccs
-kms_ccs@pipe-H-bad-rotation-90-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-H-bad-rotation-90-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-H-bad-rotation-90-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-H-bad-rotation-90-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-H-bad-rotation-90-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-H-bad-rotation-90-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-H-bad-rotation-90-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-H-bad-rotation-90-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-H-bad-rotation-90-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-H-crc-primary-basic-y-tiled-ccs
-kms_ccs@pipe-H-crc-primary-basic-yf-tiled-ccs
-kms_ccs@pipe-H-crc-primary-basic-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-H-crc-primary-basic-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-H-crc-primary-basic-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-H-crc-primary-basic-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-H-crc-primary-basic-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-H-crc-primary-basic-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-H-crc-primary-basic-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-H-crc-primary-basic-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-H-crc-primary-basic-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-H-crc-primary-rotation-180-y-tiled-ccs
-kms_ccs@pipe-H-crc-primary-rotation-180-yf-tiled-ccs
-kms_ccs@pipe-H-crc-primary-rotation-180-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-H-crc-primary-rotation-180-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-H-crc-primary-rotation-180-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-H-crc-primary-rotation-180-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-H-crc-primary-rotation-180-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-H-crc-primary-rotation-180-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-H-crc-primary-rotation-180-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-H-crc-primary-rotation-180-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-H-crc-primary-rotation-180-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-H-random-ccs-data-y-tiled-ccs
-kms_ccs@pipe-H-random-ccs-data-yf-tiled-ccs
-kms_ccs@pipe-H-random-ccs-data-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-H-random-ccs-data-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-H-random-ccs-data-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-H-random-ccs-data-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-H-random-ccs-data-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-H-random-ccs-data-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-H-random-ccs-data-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-H-random-ccs-data-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-H-random-ccs-data-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-H-missing-ccs-buffer-y-tiled-ccs
-kms_ccs@pipe-H-missing-ccs-buffer-yf-tiled-ccs
-kms_ccs@pipe-H-missing-ccs-buffer-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-H-missing-ccs-buffer-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-H-missing-ccs-buffer-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-H-missing-ccs-buffer-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-H-missing-ccs-buffer-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-H-missing-ccs-buffer-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-H-ccs-on-another-bo-y-tiled-ccs
-kms_ccs@pipe-H-ccs-on-another-bo-yf-tiled-ccs
-kms_ccs@pipe-H-ccs-on-another-bo-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-H-ccs-on-another-bo-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-H-ccs-on-another-bo-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-H-ccs-on-another-bo-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-H-ccs-on-another-bo-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-H-ccs-on-another-bo-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-H-bad-aux-stride-y-tiled-ccs
-kms_ccs@pipe-H-bad-aux-stride-yf-tiled-ccs
-kms_ccs@pipe-H-bad-aux-stride-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-H-bad-aux-stride-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-H-bad-aux-stride-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-H-bad-aux-stride-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-H-bad-aux-stride-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-H-bad-aux-stride-4-tiled-mtl-rc-ccs-cc
-kms_ccs@pipe-H-crc-sprite-planes-basic-y-tiled-ccs
-kms_ccs@pipe-H-crc-sprite-planes-basic-yf-tiled-ccs
-kms_ccs@pipe-H-crc-sprite-planes-basic-y-tiled-gen12-rc-ccs
-kms_ccs@pipe-H-crc-sprite-planes-basic-y-tiled-gen12-rc-ccs-cc
-kms_ccs@pipe-H-crc-sprite-planes-basic-y-tiled-gen12-mc-ccs
-kms_ccs@pipe-H-crc-sprite-planes-basic-4-tiled-dg2-rc-ccs
-kms_ccs@pipe-H-crc-sprite-planes-basic-4-tiled-dg2-mc-ccs
-kms_ccs@pipe-H-crc-sprite-planes-basic-4-tiled-dg2-rc-ccs-cc
-kms_ccs@pipe-H-crc-sprite-planes-basic-4-tiled-mtl-rc-ccs
-kms_ccs@pipe-H-crc-sprite-planes-basic-4-tiled-mtl-mc-ccs
-kms_ccs@pipe-H-crc-sprite-planes-basic-4-tiled-mtl-rc-ccs-cc
-kms_cdclk@plane-scaling
-kms_cdclk@mode-transition
-kms_cdclk@mode-transition-all-outputs
-kms_color@degamma
-kms_color@gamma
-kms_color@legacy-gamma
-kms_color@legacy-gamma-reset
-kms_color@ctm-red-to-blue
-kms_color@ctm-green-to-red
-kms_color@ctm-blue-to-red
-kms_color@ctm-max
-kms_color@ctm-negative
-kms_color@ctm-0-25
-kms_color@ctm-0-50
-kms_color@ctm-0-75
-kms_color@ctm-signed
-kms_color@deep-color
-kms_color@invalid-gamma-lut-sizes
-kms_color@invalid-degamma-lut-sizes
-kms_color@invalid-ctm-matrix-sizes
-kms_concurrent@multi-plane-atomic-lowres
-kms_content_protection@legacy
-kms_content_protection@atomic
-kms_content_protection@atomic-dpms
-kms_content_protection@lic
-kms_content_protection@type1
-kms_content_protection@mei-interface
-kms_content_protection@content-type-change
-kms_content_protection@uevent
-kms_content_protection@srm
-kms_content_protection@dp-mst-type-0
-kms_content_protection@dp-mst-lic-type-0
-kms_content_protection@dp-mst-type-1
-kms_content_protection@dp-mst-lic-type-1
-kms_cursor_crc@cursor-size-change
-kms_cursor_crc@cursor-alpha-opaque
-kms_cursor_crc@cursor-alpha-transparent
-kms_cursor_crc@cursor-dpms
-kms_cursor_crc@cursor-suspend
-kms_cursor_crc@cursor-onscreen-32x32
-kms_cursor_crc@cursor-offscreen-32x32
-kms_cursor_crc@cursor-sliding-32x32
-kms_cursor_crc@cursor-random-32x32
-kms_cursor_crc@cursor-rapid-movement-32x32
-kms_cursor_crc@cursor-onscreen-32x10
-kms_cursor_crc@cursor-offscreen-32x10
-kms_cursor_crc@cursor-sliding-32x10
-kms_cursor_crc@cursor-random-32x10
-kms_cursor_crc@cursor-rapid-movement-32x10
-kms_cursor_crc@cursor-onscreen-64x64
-kms_cursor_crc@cursor-offscreen-64x64
-kms_cursor_crc@cursor-sliding-64x64
-kms_cursor_crc@cursor-random-64x64
-kms_cursor_crc@cursor-rapid-movement-64x64
-kms_cursor_crc@cursor-onscreen-64x21
-kms_cursor_crc@cursor-offscreen-64x21
-kms_cursor_crc@cursor-sliding-64x21
-kms_cursor_crc@cursor-random-64x21
-kms_cursor_crc@cursor-rapid-movement-64x21
-kms_cursor_crc@cursor-onscreen-128x128
-kms_cursor_crc@cursor-offscreen-128x128
-kms_cursor_crc@cursor-sliding-128x128
-kms_cursor_crc@cursor-random-128x128
-kms_cursor_crc@cursor-rapid-movement-128x128
-kms_cursor_crc@cursor-onscreen-128x42
-kms_cursor_crc@cursor-offscreen-128x42
-kms_cursor_crc@cursor-sliding-128x42
-kms_cursor_crc@cursor-random-128x42
-kms_cursor_crc@cursor-rapid-movement-128x42
-kms_cursor_crc@cursor-onscreen-256x256
-kms_cursor_crc@cursor-offscreen-256x256
-kms_cursor_crc@cursor-sliding-256x256
-kms_cursor_crc@cursor-random-256x256
-kms_cursor_crc@cursor-rapid-movement-256x256
-kms_cursor_crc@cursor-onscreen-256x85
-kms_cursor_crc@cursor-offscreen-256x85
-kms_cursor_crc@cursor-sliding-256x85
-kms_cursor_crc@cursor-random-256x85
-kms_cursor_crc@cursor-rapid-movement-256x85
-kms_cursor_crc@cursor-onscreen-512x512
-kms_cursor_crc@cursor-offscreen-512x512
-kms_cursor_crc@cursor-sliding-512x512
-kms_cursor_crc@cursor-random-512x512
-kms_cursor_crc@cursor-rapid-movement-512x512
-kms_cursor_crc@cursor-onscreen-512x170
-kms_cursor_crc@cursor-offscreen-512x170
-kms_cursor_crc@cursor-sliding-512x170
-kms_cursor_crc@cursor-random-512x170
-kms_cursor_crc@cursor-rapid-movement-512x170
-kms_cursor_crc@cursor-onscreen-max-size
-kms_cursor_crc@cursor-offscreen-max-size
-kms_cursor_crc@cursor-sliding-max-size
-kms_cursor_crc@cursor-random-max-size
-kms_cursor_crc@cursor-rapid-movement-max-size
-kms_cursor_legacy@single-bo
-kms_cursor_legacy@single-move
-kms_cursor_legacy@forked-bo
-kms_cursor_legacy@forked-move
-kms_cursor_legacy@torture-bo
-kms_cursor_legacy@torture-move
-kms_cursor_legacy@nonblocking-modeset-vs-cursor-atomic
-kms_cursor_legacy@long-nonblocking-modeset-vs-cursor-atomic
-kms_cursor_legacy@2x-flip-vs-cursor-legacy
-kms_cursor_legacy@2x-flip-vs-cursor-atomic
-kms_cursor_legacy@2x-long-flip-vs-cursor-legacy
-kms_cursor_legacy@2x-long-flip-vs-cursor-atomic
-kms_cursor_legacy@2x-nonblocking-modeset-vs-cursor-atomic
-kms_cursor_legacy@2x-long-nonblocking-modeset-vs-cursor-atomic
-kms_cursor_legacy@2x-cursor-vs-flip-legacy
-kms_cursor_legacy@2x-long-cursor-vs-flip-legacy
-kms_cursor_legacy@2x-cursor-vs-flip-atomic
-kms_cursor_legacy@2x-long-cursor-vs-flip-atomic
-kms_cursor_legacy@flip-vs-cursor-crc-legacy
-kms_cursor_legacy@flip-vs-cursor-crc-atomic
-kms_cursor_legacy@flip-vs-cursor-busy-crc-legacy
-kms_cursor_legacy@flip-vs-cursor-busy-crc-atomic
-kms_cursor_legacy@basic-flip-before-cursor-legacy
-kms_cursor_legacy@basic-busy-flip-before-cursor-legacy
-kms_cursor_legacy@basic-flip-after-cursor-legacy
-kms_cursor_legacy@basic-flip-before-cursor-varying-size
-kms_cursor_legacy@basic-busy-flip-before-cursor-varying-size
-kms_cursor_legacy@basic-flip-after-cursor-varying-size
-kms_cursor_legacy@short-flip-before-cursor-toggle
-kms_cursor_legacy@short-busy-flip-before-cursor-toggle
-kms_cursor_legacy@short-flip-after-cursor-toggle
-kms_cursor_legacy@basic-flip-before-cursor-atomic
-kms_cursor_legacy@basic-busy-flip-before-cursor-atomic
-kms_cursor_legacy@basic-flip-after-cursor-atomic
-kms_cursor_legacy@short-flip-before-cursor-atomic-transitions
-kms_cursor_legacy@short-busy-flip-before-cursor-atomic-transitions
-kms_cursor_legacy@short-flip-after-cursor-atomic-transitions
-kms_cursor_legacy@short-flip-before-cursor-atomic-transitions-varying-size
-kms_cursor_legacy@short-busy-flip-before-cursor-atomic-transitions-varying-size
-kms_cursor_legacy@short-flip-after-cursor-atomic-transitions-varying-size
-kms_cursor_legacy@cursor-vs-flip-legacy
-kms_cursor_legacy@flip-vs-cursor-legacy
-kms_cursor_legacy@cursorA-vs-flipA-legacy
-kms_cursor_legacy@cursorA-vs-flipB-legacy
-kms_cursor_legacy@cursorB-vs-flipA-legacy
-kms_cursor_legacy@cursorB-vs-flipB-legacy
-kms_cursor_legacy@cursor-vs-flip-varying-size
-kms_cursor_legacy@flip-vs-cursor-varying-size
-kms_cursor_legacy@cursorA-vs-flipA-varying-size
-kms_cursor_legacy@cursorA-vs-flipB-varying-size
-kms_cursor_legacy@cursorB-vs-flipA-varying-size
-kms_cursor_legacy@cursorB-vs-flipB-varying-size
-kms_cursor_legacy@cursor-vs-flip-toggle
-kms_cursor_legacy@flip-vs-cursor-toggle
-kms_cursor_legacy@cursorA-vs-flipA-toggle
-kms_cursor_legacy@cursorA-vs-flipB-toggle
-kms_cursor_legacy@cursorB-vs-flipA-toggle
-kms_cursor_legacy@cursorB-vs-flipB-toggle
-kms_cursor_legacy@cursor-vs-flip-atomic
-kms_cursor_legacy@flip-vs-cursor-atomic
-kms_cursor_legacy@cursorA-vs-flipA-atomic
-kms_cursor_legacy@cursorA-vs-flipB-atomic
-kms_cursor_legacy@cursorB-vs-flipA-atomic
-kms_cursor_legacy@cursorB-vs-flipB-atomic
-kms_cursor_legacy@cursor-vs-flip-atomic-transitions
-kms_cursor_legacy@flip-vs-cursor-atomic-transitions
-kms_cursor_legacy@cursorA-vs-flipA-atomic-transitions
-kms_cursor_legacy@cursorA-vs-flipB-atomic-transitions
-kms_cursor_legacy@cursorB-vs-flipA-atomic-transitions
-kms_cursor_legacy@cursorB-vs-flipB-atomic-transitions
-kms_cursor_legacy@cursor-vs-flip-atomic-transitions-varying-size
-kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size
-kms_cursor_legacy@cursorA-vs-flipA-atomic-transitions-varying-size
-kms_cursor_legacy@cursorA-vs-flipB-atomic-transitions-varying-size
-kms_cursor_legacy@cursorB-vs-flipA-atomic-transitions-varying-size
-kms_cursor_legacy@cursorB-vs-flipB-atomic-transitions-varying-size
-kms_dither@fb-8bpc-vs-panel-6bpc
-kms_dither@fb-8bpc-vs-panel-8bpc
-kms_dp_aux_dev
-kms_tiled_display@basic-test-pattern
-kms_tiled_display@basic-test-pattern-with-chamelium
-kms_draw_crc@draw-method-mmap-cpu
-kms_draw_crc@draw-method-mmap-gtt
-kms_draw_crc@draw-method-mmap-wc
-kms_draw_crc@draw-method-pwrite
-kms_draw_crc@draw-method-blt
-kms_draw_crc@draw-method-render
-kms_draw_crc@fill-fb
-kms_dsc@dsc-basic
-kms_dsc@dsc-with-formats
-kms_dsc@dsc-with-bpc
-kms_dsc@dsc-with-bpc-formats
-kms_dsc@dsc-with-output-formats
-kms_fbcon_fbt@fbc
-kms_fbcon_fbt@psr
-kms_fbcon_fbt@fbc-suspend
-kms_fbcon_fbt@psr-suspend
-kms_fence_pin_leak
-kms_flip@nonblocking-read
-kms_flip@wf_vblank-ts-check
-kms_flip@2x-wf_vblank-ts-check
-kms_flip@blocking-wf_vblank
-kms_flip@2x-blocking-wf_vblank
-kms_flip@absolute-wf_vblank
-kms_flip@2x-absolute-wf_vblank
-kms_flip@blocking-absolute-wf_vblank
-kms_flip@2x-blocking-absolute-wf_vblank
-kms_flip@basic-plain-flip
-kms_flip@2x-plain-flip
-kms_flip@busy-flip
-kms_flip@2x-busy-flip
-kms_flip@flip-vs-fences
-kms_flip@2x-flip-vs-fences
-kms_flip@plain-flip-ts-check
-kms_flip@2x-plain-flip-ts-check
-kms_flip@plain-flip-fb-recreate
-kms_flip@2x-plain-flip-fb-recreate
-kms_flip@flip-vs-rmfb
-kms_flip@2x-flip-vs-rmfb
-kms_flip@basic-flip-vs-dpms
-kms_flip@2x-flip-vs-dpms
-kms_flip@flip-vs-panning
-kms_flip@2x-flip-vs-panning
-kms_flip@basic-flip-vs-modeset
-kms_flip@2x-flip-vs-modeset
-kms_flip@flip-vs-expired-vblank
-kms_flip@2x-flip-vs-expired-vblank
-kms_flip@flip-vs-absolute-wf_vblank
-kms_flip@2x-flip-vs-absolute-wf_vblank
-kms_flip@basic-flip-vs-wf_vblank
-kms_flip@2x-flip-vs-wf_vblank
-kms_flip@flip-vs-blocking-wf-vblank
-kms_flip@2x-flip-vs-blocking-wf-vblank
-kms_flip@flip-vs-modeset-vs-hang
-kms_flip@2x-flip-vs-modeset-vs-hang
-kms_flip@flip-vs-panning-vs-hang
-kms_flip@2x-flip-vs-panning-vs-hang
-kms_flip@flip-vs-dpms-off-vs-modeset
-kms_flip@2x-flip-vs-dpms-off-vs-modeset
-kms_flip@single-buffer-flip-vs-dpms-off-vs-modeset
-kms_flip@2x-single-buffer-flip-vs-dpms-off-vs-modeset
-kms_flip@dpms-off-confusion
-kms_flip@nonexisting-fb
-kms_flip@2x-nonexisting-fb
-kms_flip@dpms-vs-vblank-race
-kms_flip@2x-dpms-vs-vblank-race
-kms_flip@modeset-vs-vblank-race
-kms_flip@2x-modeset-vs-vblank-race
-kms_flip@bo-too-big
-kms_flip@flip-vs-suspend
-kms_flip@2x-flip-vs-suspend
-kms_flip@wf_vblank-ts-check-interruptible
-kms_flip@2x-wf_vblank-ts-check-interruptible
-kms_flip@absolute-wf_vblank-interruptible
-kms_flip@2x-absolute-wf_vblank-interruptible
-kms_flip@blocking-absolute-wf_vblank-interruptible
-kms_flip@2x-blocking-absolute-wf_vblank-interruptible
-kms_flip@plain-flip-interruptible
-kms_flip@2x-plain-flip-interruptible
-kms_flip@flip-vs-fences-interruptible
-kms_flip@2x-flip-vs-fences-interruptible
-kms_flip@plain-flip-ts-check-interruptible
-kms_flip@2x-plain-flip-ts-check-interruptible
-kms_flip@plain-flip-fb-recreate-interruptible
-kms_flip@2x-plain-flip-fb-recreate-interruptible
-kms_flip@flip-vs-rmfb-interruptible
-kms_flip@2x-flip-vs-rmfb-interruptible
-kms_flip@flip-vs-panning-interruptible
-kms_flip@2x-flip-vs-panning-interruptible
-kms_flip@flip-vs-expired-vblank-interruptible
-kms_flip@2x-flip-vs-expired-vblank-interruptible
-kms_flip@flip-vs-absolute-wf_vblank-interruptible
-kms_flip@2x-flip-vs-absolute-wf_vblank-interruptible
-kms_flip@flip-vs-wf_vblank-interruptible
-kms_flip@2x-flip-vs-wf_vblank-interruptible
-kms_flip@flip-vs-dpms-off-vs-modeset-interruptible
-kms_flip@2x-flip-vs-dpms-off-vs-modeset-interruptible
-kms_flip@single-buffer-flip-vs-dpms-off-vs-modeset-interruptible
-kms_flip@2x-single-buffer-flip-vs-dpms-off-vs-modeset-interruptible
-kms_flip@dpms-off-confusion-interruptible
-kms_flip@nonexisting-fb-interruptible
-kms_flip@2x-nonexisting-fb-interruptible
-kms_flip@dpms-vs-vblank-race-interruptible
-kms_flip@2x-dpms-vs-vblank-race-interruptible
-kms_flip@modeset-vs-vblank-race-interruptible
-kms_flip@2x-modeset-vs-vblank-race-interruptible
-kms_flip@bo-too-big-interruptible
-kms_flip@flip-vs-suspend-interruptible
-kms_flip@2x-flip-vs-suspend-interruptible
-kms_flip_event_leak@basic
-kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-downscaling
-kms_flip_scaled_crc@flip-32bpp-yftile-to-64bpp-yftile-downscaling
-kms_flip_scaled_crc@flip-32bpp-xtile-to-64bpp-xtile-downscaling
-kms_flip_scaled_crc@flip-32bpp-4tile-to-64bpp-4tile-downscaling
-kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-downscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-downscaling
-kms_flip_scaled_crc@flip-64bpp-yftile-to-32bpp-yftile-downscaling
-kms_flip_scaled_crc@flip-64bpp-xtile-to-32bpp-xtile-downscaling
-kms_flip_scaled_crc@flip-64bpp-4tile-to-32bpp-4tile-downscaling
-kms_flip_scaled_crc@flip-64bpp-linear-to-32bpp-linear-downscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-downscaling
-kms_flip_scaled_crc@flip-64bpp-yftile-to-16bpp-yftile-downscaling
-kms_flip_scaled_crc@flip-64bpp-xtile-to-16bpp-xtile-downscaling
-kms_flip_scaled_crc@flip-64bpp-4tile-to-16bpp-4tile-downscaling
-kms_flip_scaled_crc@flip-64bpp-linear-to-16bpp-linear-downscaling
-kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-downscaling
-kms_flip_scaled_crc@flip-32bpp-yftileccs-to-64bpp-yftile-downscaling
-kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytilegen12rcccs-downscaling
-kms_flip_scaled_crc@flip-32bpp-4tile-to-32bpp-4tiledg2rcccs-downscaling
-kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs-downscaling
-kms_flip_scaled_crc@flip-32bpp-yftile-to-32bpp-yftileccs-downscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-downscaling
-kms_flip_scaled_crc@flip-64bpp-4tile-to-32bpp-4tiledg2rcccs-downscaling
-kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-upscaling
-kms_flip_scaled_crc@flip-32bpp-yftile-to-64bpp-yftile-upscaling
-kms_flip_scaled_crc@flip-32bpp-xtile-to-64bpp-xtile-upscaling
-kms_flip_scaled_crc@flip-32bpp-4tile-to-64bpp-4tile-upscaling
-kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-upscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-upscaling
-kms_flip_scaled_crc@flip-64bpp-yftile-to-32bpp-yftile-upscaling
-kms_flip_scaled_crc@flip-64bpp-xtile-to-32bpp-xtile-upscaling
-kms_flip_scaled_crc@flip-64bpp-4tile-to-32bpp-4tile-upscaling
-kms_flip_scaled_crc@flip-64bpp-linear-to-32bpp-linear-upscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-upscaling
-kms_flip_scaled_crc@flip-64bpp-yftile-to-16bpp-yftile-upscaling
-kms_flip_scaled_crc@flip-64bpp-xtile-to-16bpp-xtile-upscaling
-kms_flip_scaled_crc@flip-64bpp-4tile-to-16bpp-4tile-upscaling
-kms_flip_scaled_crc@flip-64bpp-linear-to-16bpp-linear-upscaling
-kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-upscaling
-kms_flip_scaled_crc@flip-32bpp-yftileccs-to-64bpp-yftile-upscaling
-kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytilegen12rcccs-upscaling
-kms_flip_scaled_crc@flip-32bpp-4tile-to-32bpp-4tiledg2rcccs-upscaling
-kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs-upscaling
-kms_flip_scaled_crc@flip-32bpp-yftile-to-32bpp-yftileccs-upscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilegen12rcccs-upscaling
-kms_flip_scaled_crc@flip-64bpp-4tile-to-32bpp-4tiledg2rcccs-upscaling
-kms_force_connector_basic@force-load-detect
-kms_force_connector_basic@force-connector-state
-kms_force_connector_basic@force-edid
-kms_force_connector_basic@prune-stale-modes
-kms_frontbuffer_tracking@fbc-1p-rte
-kms_frontbuffer_tracking@fbc-2p-rte
-kms_frontbuffer_tracking@psr-1p-rte
-kms_frontbuffer_tracking@psr-2p-rte
-kms_frontbuffer_tracking@fbcpsr-1p-rte
-kms_frontbuffer_tracking@fbcpsr-2p-rte
-kms_frontbuffer_tracking@drrs-1p-rte
-kms_frontbuffer_tracking@drrs-2p-rte
-kms_frontbuffer_tracking@fbcdrrs-1p-rte
-kms_frontbuffer_tracking@fbcdrrs-2p-rte
-kms_frontbuffer_tracking@psrdrrs-1p-rte
-kms_frontbuffer_tracking@psrdrrs-2p-rte
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-rte
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-rte
-kms_frontbuffer_tracking@fbc-1p-primscrn-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbc-1p-primscrn-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbc-1p-primscrn-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbc-1p-primscrn-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbc-1p-primscrn-pri-indfb-draw-blt
-kms_frontbuffer_tracking@fbc-1p-primscrn-pri-indfb-draw-render
-kms_frontbuffer_tracking@fbc-1p-primscrn-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbc-1p-primscrn-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbc-1p-primscrn-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbc-1p-primscrn-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@fbc-1p-primscrn-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@fbc-1p-primscrn-pri-shrfb-draw-render
-kms_frontbuffer_tracking@fbc-1p-primscrn-cur-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbc-1p-primscrn-cur-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbc-1p-primscrn-cur-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbc-1p-primscrn-cur-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbc-1p-primscrn-cur-indfb-draw-blt
-kms_frontbuffer_tracking@fbc-1p-primscrn-cur-indfb-draw-render
-kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-draw-blt
-kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-draw-render
-kms_frontbuffer_tracking@fbc-1p-offscren-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbc-1p-offscren-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbc-1p-offscren-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbc-1p-offscren-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbc-1p-offscren-pri-indfb-draw-blt
-kms_frontbuffer_tracking@fbc-1p-offscren-pri-indfb-draw-render
-kms_frontbuffer_tracking@fbc-1p-offscren-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbc-1p-offscren-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbc-1p-offscren-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbc-1p-offscren-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@fbc-1p-offscren-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@fbc-1p-offscren-pri-shrfb-draw-render
-kms_frontbuffer_tracking@fbc-2p-primscrn-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbc-2p-primscrn-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbc-2p-primscrn-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbc-2p-primscrn-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbc-2p-primscrn-pri-indfb-draw-blt
-kms_frontbuffer_tracking@fbc-2p-primscrn-pri-indfb-draw-render
-kms_frontbuffer_tracking@fbc-2p-primscrn-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbc-2p-primscrn-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbc-2p-primscrn-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbc-2p-primscrn-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@fbc-2p-primscrn-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@fbc-2p-primscrn-pri-shrfb-draw-render
-kms_frontbuffer_tracking@fbc-2p-primscrn-cur-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbc-2p-primscrn-cur-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbc-2p-primscrn-cur-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbc-2p-primscrn-cur-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbc-2p-primscrn-cur-indfb-draw-blt
-kms_frontbuffer_tracking@fbc-2p-primscrn-cur-indfb-draw-render
-kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-draw-blt
-kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-draw-render
-kms_frontbuffer_tracking@fbc-2p-scndscrn-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbc-2p-scndscrn-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbc-2p-scndscrn-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbc-2p-scndscrn-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbc-2p-scndscrn-pri-indfb-draw-blt
-kms_frontbuffer_tracking@fbc-2p-scndscrn-pri-indfb-draw-render
-kms_frontbuffer_tracking@fbc-2p-scndscrn-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbc-2p-scndscrn-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbc-2p-scndscrn-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbc-2p-scndscrn-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@fbc-2p-scndscrn-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@fbc-2p-scndscrn-pri-shrfb-draw-render
-kms_frontbuffer_tracking@fbc-2p-scndscrn-cur-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbc-2p-scndscrn-cur-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbc-2p-scndscrn-cur-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbc-2p-scndscrn-cur-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbc-2p-scndscrn-cur-indfb-draw-blt
-kms_frontbuffer_tracking@fbc-2p-scndscrn-cur-indfb-draw-render
-kms_frontbuffer_tracking@fbc-2p-scndscrn-spr-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbc-2p-scndscrn-spr-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbc-2p-scndscrn-spr-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbc-2p-scndscrn-spr-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbc-2p-scndscrn-spr-indfb-draw-blt
-kms_frontbuffer_tracking@fbc-2p-scndscrn-spr-indfb-draw-render
-kms_frontbuffer_tracking@psr-1p-primscrn-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psr-1p-primscrn-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psr-1p-primscrn-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@psr-1p-primscrn-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@psr-1p-primscrn-pri-indfb-draw-blt
-kms_frontbuffer_tracking@psr-1p-primscrn-pri-indfb-draw-render
-kms_frontbuffer_tracking@psr-1p-primscrn-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psr-1p-primscrn-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psr-1p-primscrn-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@psr-1p-primscrn-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@psr-1p-primscrn-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@psr-1p-primscrn-pri-shrfb-draw-render
-kms_frontbuffer_tracking@psr-1p-primscrn-cur-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psr-1p-primscrn-cur-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psr-1p-primscrn-cur-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@psr-1p-primscrn-cur-indfb-draw-pwrite
-kms_frontbuffer_tracking@psr-1p-primscrn-cur-indfb-draw-blt
-kms_frontbuffer_tracking@psr-1p-primscrn-cur-indfb-draw-render
-kms_frontbuffer_tracking@psr-1p-primscrn-spr-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psr-1p-primscrn-spr-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psr-1p-primscrn-spr-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@psr-1p-primscrn-spr-indfb-draw-pwrite
-kms_frontbuffer_tracking@psr-1p-primscrn-spr-indfb-draw-blt
-kms_frontbuffer_tracking@psr-1p-primscrn-spr-indfb-draw-render
-kms_frontbuffer_tracking@psr-1p-offscren-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psr-1p-offscren-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psr-1p-offscren-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@psr-1p-offscren-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@psr-1p-offscren-pri-indfb-draw-blt
-kms_frontbuffer_tracking@psr-1p-offscren-pri-indfb-draw-render
-kms_frontbuffer_tracking@psr-1p-offscren-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psr-1p-offscren-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psr-1p-offscren-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@psr-1p-offscren-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@psr-1p-offscren-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@psr-1p-offscren-pri-shrfb-draw-render
-kms_frontbuffer_tracking@psr-2p-primscrn-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psr-2p-primscrn-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psr-2p-primscrn-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@psr-2p-primscrn-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@psr-2p-primscrn-pri-indfb-draw-blt
-kms_frontbuffer_tracking@psr-2p-primscrn-pri-indfb-draw-render
-kms_frontbuffer_tracking@psr-2p-primscrn-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psr-2p-primscrn-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psr-2p-primscrn-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@psr-2p-primscrn-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@psr-2p-primscrn-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@psr-2p-primscrn-pri-shrfb-draw-render
-kms_frontbuffer_tracking@psr-2p-primscrn-cur-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psr-2p-primscrn-cur-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psr-2p-primscrn-cur-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@psr-2p-primscrn-cur-indfb-draw-pwrite
-kms_frontbuffer_tracking@psr-2p-primscrn-cur-indfb-draw-blt
-kms_frontbuffer_tracking@psr-2p-primscrn-cur-indfb-draw-render
-kms_frontbuffer_tracking@psr-2p-primscrn-spr-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psr-2p-primscrn-spr-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psr-2p-primscrn-spr-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@psr-2p-primscrn-spr-indfb-draw-pwrite
-kms_frontbuffer_tracking@psr-2p-primscrn-spr-indfb-draw-blt
-kms_frontbuffer_tracking@psr-2p-primscrn-spr-indfb-draw-render
-kms_frontbuffer_tracking@psr-2p-scndscrn-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psr-2p-scndscrn-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psr-2p-scndscrn-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@psr-2p-scndscrn-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@psr-2p-scndscrn-pri-indfb-draw-blt
-kms_frontbuffer_tracking@psr-2p-scndscrn-pri-indfb-draw-render
-kms_frontbuffer_tracking@psr-2p-scndscrn-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psr-2p-scndscrn-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psr-2p-scndscrn-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@psr-2p-scndscrn-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@psr-2p-scndscrn-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@psr-2p-scndscrn-pri-shrfb-draw-render
-kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-draw-pwrite
-kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-draw-blt
-kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-draw-render
-kms_frontbuffer_tracking@psr-2p-scndscrn-spr-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psr-2p-scndscrn-spr-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psr-2p-scndscrn-spr-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@psr-2p-scndscrn-spr-indfb-draw-pwrite
-kms_frontbuffer_tracking@psr-2p-scndscrn-spr-indfb-draw-blt
-kms_frontbuffer_tracking@psr-2p-scndscrn-spr-indfb-draw-render
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-blt
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-render
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-shrfb-draw-render
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-draw-blt
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-draw-render
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-spr-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-spr-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-spr-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-spr-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-spr-indfb-draw-blt
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-spr-indfb-draw-render
-kms_frontbuffer_tracking@fbcpsr-1p-offscren-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsr-1p-offscren-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsr-1p-offscren-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsr-1p-offscren-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsr-1p-offscren-pri-indfb-draw-blt
-kms_frontbuffer_tracking@fbcpsr-1p-offscren-pri-indfb-draw-render
-kms_frontbuffer_tracking@fbcpsr-1p-offscren-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsr-1p-offscren-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsr-1p-offscren-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsr-1p-offscren-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsr-1p-offscren-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@fbcpsr-1p-offscren-pri-shrfb-draw-render
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-pri-indfb-draw-blt
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-pri-indfb-draw-render
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-pri-shrfb-draw-render
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-cur-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-cur-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-cur-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-cur-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-cur-indfb-draw-blt
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-cur-indfb-draw-render
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-spr-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-spr-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-spr-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-spr-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-spr-indfb-draw-blt
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-spr-indfb-draw-render
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-pri-indfb-draw-blt
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-pri-indfb-draw-render
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-pri-shrfb-draw-render
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-cur-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-cur-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-cur-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-cur-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-cur-indfb-draw-blt
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-cur-indfb-draw-render
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-spr-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-spr-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-spr-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-spr-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-spr-indfb-draw-blt
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-spr-indfb-draw-render
-kms_frontbuffer_tracking@drrs-1p-primscrn-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@drrs-1p-primscrn-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@drrs-1p-primscrn-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@drrs-1p-primscrn-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@drrs-1p-primscrn-pri-indfb-draw-blt
-kms_frontbuffer_tracking@drrs-1p-primscrn-pri-indfb-draw-render
-kms_frontbuffer_tracking@drrs-1p-primscrn-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@drrs-1p-primscrn-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@drrs-1p-primscrn-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@drrs-1p-primscrn-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@drrs-1p-primscrn-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@drrs-1p-primscrn-pri-shrfb-draw-render
-kms_frontbuffer_tracking@drrs-1p-primscrn-cur-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@drrs-1p-primscrn-cur-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@drrs-1p-primscrn-cur-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@drrs-1p-primscrn-cur-indfb-draw-pwrite
-kms_frontbuffer_tracking@drrs-1p-primscrn-cur-indfb-draw-blt
-kms_frontbuffer_tracking@drrs-1p-primscrn-cur-indfb-draw-render
-kms_frontbuffer_tracking@drrs-1p-primscrn-spr-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@drrs-1p-primscrn-spr-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@drrs-1p-primscrn-spr-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@drrs-1p-primscrn-spr-indfb-draw-pwrite
-kms_frontbuffer_tracking@drrs-1p-primscrn-spr-indfb-draw-blt
-kms_frontbuffer_tracking@drrs-1p-primscrn-spr-indfb-draw-render
-kms_frontbuffer_tracking@drrs-1p-offscren-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@drrs-1p-offscren-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@drrs-1p-offscren-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@drrs-1p-offscren-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@drrs-1p-offscren-pri-indfb-draw-blt
-kms_frontbuffer_tracking@drrs-1p-offscren-pri-indfb-draw-render
-kms_frontbuffer_tracking@drrs-1p-offscren-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@drrs-1p-offscren-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@drrs-1p-offscren-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@drrs-1p-offscren-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@drrs-1p-offscren-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@drrs-1p-offscren-pri-shrfb-draw-render
-kms_frontbuffer_tracking@drrs-2p-primscrn-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@drrs-2p-primscrn-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@drrs-2p-primscrn-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@drrs-2p-primscrn-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@drrs-2p-primscrn-pri-indfb-draw-blt
-kms_frontbuffer_tracking@drrs-2p-primscrn-pri-indfb-draw-render
-kms_frontbuffer_tracking@drrs-2p-primscrn-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@drrs-2p-primscrn-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@drrs-2p-primscrn-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@drrs-2p-primscrn-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@drrs-2p-primscrn-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@drrs-2p-primscrn-pri-shrfb-draw-render
-kms_frontbuffer_tracking@drrs-2p-primscrn-cur-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@drrs-2p-primscrn-cur-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@drrs-2p-primscrn-cur-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@drrs-2p-primscrn-cur-indfb-draw-pwrite
-kms_frontbuffer_tracking@drrs-2p-primscrn-cur-indfb-draw-blt
-kms_frontbuffer_tracking@drrs-2p-primscrn-cur-indfb-draw-render
-kms_frontbuffer_tracking@drrs-2p-primscrn-spr-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@drrs-2p-primscrn-spr-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@drrs-2p-primscrn-spr-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@drrs-2p-primscrn-spr-indfb-draw-pwrite
-kms_frontbuffer_tracking@drrs-2p-primscrn-spr-indfb-draw-blt
-kms_frontbuffer_tracking@drrs-2p-primscrn-spr-indfb-draw-render
-kms_frontbuffer_tracking@drrs-2p-scndscrn-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@drrs-2p-scndscrn-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@drrs-2p-scndscrn-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@drrs-2p-scndscrn-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@drrs-2p-scndscrn-pri-indfb-draw-blt
-kms_frontbuffer_tracking@drrs-2p-scndscrn-pri-indfb-draw-render
-kms_frontbuffer_tracking@drrs-2p-scndscrn-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@drrs-2p-scndscrn-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@drrs-2p-scndscrn-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@drrs-2p-scndscrn-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@drrs-2p-scndscrn-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@drrs-2p-scndscrn-pri-shrfb-draw-render
-kms_frontbuffer_tracking@drrs-2p-scndscrn-cur-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@drrs-2p-scndscrn-cur-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@drrs-2p-scndscrn-cur-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@drrs-2p-scndscrn-cur-indfb-draw-pwrite
-kms_frontbuffer_tracking@drrs-2p-scndscrn-cur-indfb-draw-blt
-kms_frontbuffer_tracking@drrs-2p-scndscrn-cur-indfb-draw-render
-kms_frontbuffer_tracking@drrs-2p-scndscrn-spr-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@drrs-2p-scndscrn-spr-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@drrs-2p-scndscrn-spr-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@drrs-2p-scndscrn-spr-indfb-draw-pwrite
-kms_frontbuffer_tracking@drrs-2p-scndscrn-spr-indfb-draw-blt
-kms_frontbuffer_tracking@drrs-2p-scndscrn-spr-indfb-draw-render
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-pri-indfb-draw-blt
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-pri-indfb-draw-render
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-pri-shrfb-draw-render
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-cur-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-cur-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-cur-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-cur-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-cur-indfb-draw-blt
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-cur-indfb-draw-render
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-spr-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-spr-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-spr-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-spr-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-spr-indfb-draw-blt
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-spr-indfb-draw-render
-kms_frontbuffer_tracking@fbcdrrs-1p-offscren-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcdrrs-1p-offscren-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcdrrs-1p-offscren-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcdrrs-1p-offscren-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcdrrs-1p-offscren-pri-indfb-draw-blt
-kms_frontbuffer_tracking@fbcdrrs-1p-offscren-pri-indfb-draw-render
-kms_frontbuffer_tracking@fbcdrrs-1p-offscren-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcdrrs-1p-offscren-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcdrrs-1p-offscren-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcdrrs-1p-offscren-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@fbcdrrs-1p-offscren-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@fbcdrrs-1p-offscren-pri-shrfb-draw-render
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-pri-indfb-draw-blt
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-pri-indfb-draw-render
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-pri-shrfb-draw-render
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-cur-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-cur-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-cur-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-cur-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-cur-indfb-draw-blt
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-cur-indfb-draw-render
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-spr-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-spr-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-spr-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-spr-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-spr-indfb-draw-blt
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-spr-indfb-draw-render
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-pri-indfb-draw-blt
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-pri-indfb-draw-render
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-pri-shrfb-draw-render
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-cur-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-cur-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-cur-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-cur-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-cur-indfb-draw-blt
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-cur-indfb-draw-render
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-spr-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-spr-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-spr-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-spr-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-spr-indfb-draw-blt
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-spr-indfb-draw-render
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-pri-indfb-draw-blt
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-pri-indfb-draw-render
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-pri-shrfb-draw-render
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-cur-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-cur-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-cur-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-cur-indfb-draw-pwrite
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-cur-indfb-draw-blt
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-cur-indfb-draw-render
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-spr-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-spr-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-spr-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-spr-indfb-draw-pwrite
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-spr-indfb-draw-blt
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-spr-indfb-draw-render
-kms_frontbuffer_tracking@psrdrrs-1p-offscren-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psrdrrs-1p-offscren-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psrdrrs-1p-offscren-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@psrdrrs-1p-offscren-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@psrdrrs-1p-offscren-pri-indfb-draw-blt
-kms_frontbuffer_tracking@psrdrrs-1p-offscren-pri-indfb-draw-render
-kms_frontbuffer_tracking@psrdrrs-1p-offscren-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psrdrrs-1p-offscren-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psrdrrs-1p-offscren-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@psrdrrs-1p-offscren-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@psrdrrs-1p-offscren-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@psrdrrs-1p-offscren-pri-shrfb-draw-render
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-pri-indfb-draw-blt
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-pri-indfb-draw-render
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-pri-shrfb-draw-render
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-cur-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-cur-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-cur-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-cur-indfb-draw-pwrite
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-cur-indfb-draw-blt
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-cur-indfb-draw-render
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-spr-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-spr-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-spr-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-spr-indfb-draw-pwrite
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-spr-indfb-draw-blt
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-spr-indfb-draw-render
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-pri-indfb-draw-blt
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-pri-indfb-draw-render
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-pri-shrfb-draw-render
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-cur-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-cur-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-cur-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-cur-indfb-draw-pwrite
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-cur-indfb-draw-blt
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-cur-indfb-draw-render
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-spr-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-spr-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-spr-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-spr-indfb-draw-pwrite
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-spr-indfb-draw-blt
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-spr-indfb-draw-render
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-pri-indfb-draw-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-pri-indfb-draw-render
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-pri-shrfb-draw-render
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-cur-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-cur-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-cur-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-cur-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-cur-indfb-draw-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-cur-indfb-draw-render
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-spr-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-spr-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-spr-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-spr-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-spr-indfb-draw-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-spr-indfb-draw-render
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-offscren-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-offscren-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-offscren-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-offscren-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-offscren-pri-indfb-draw-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-offscren-pri-indfb-draw-render
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-offscren-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-offscren-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-offscren-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-offscren-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-offscren-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-offscren-pri-shrfb-draw-render
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-pri-indfb-draw-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-pri-indfb-draw-render
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-pri-shrfb-draw-render
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-cur-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-cur-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-cur-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-cur-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-cur-indfb-draw-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-cur-indfb-draw-render
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-spr-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-spr-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-spr-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-spr-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-spr-indfb-draw-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-spr-indfb-draw-render
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-pri-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-pri-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-pri-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-pri-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-pri-indfb-draw-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-pri-indfb-draw-render
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-pri-shrfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-pri-shrfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-pri-shrfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-pri-shrfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-pri-shrfb-draw-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-pri-shrfb-draw-render
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-cur-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-cur-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-cur-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-cur-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-cur-indfb-draw-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-cur-indfb-draw-render
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-spr-indfb-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-spr-indfb-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-spr-indfb-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-spr-indfb-draw-pwrite
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-spr-indfb-draw-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-spr-indfb-draw-render
-kms_frontbuffer_tracking@fbc-1p-primscrn-indfb-pgflip-blt
-kms_frontbuffer_tracking@fbc-1p-primscrn-indfb-msflip-blt
-kms_frontbuffer_tracking@fbc-1p-primscrn-indfb-plflip-blt
-kms_frontbuffer_tracking@fbc-1p-primscrn-shrfb-pgflip-blt
-kms_frontbuffer_tracking@fbc-1p-primscrn-shrfb-msflip-blt
-kms_frontbuffer_tracking@fbc-1p-primscrn-shrfb-plflip-blt
-kms_frontbuffer_tracking@fbc-2p-primscrn-indfb-pgflip-blt
-kms_frontbuffer_tracking@fbc-2p-primscrn-indfb-msflip-blt
-kms_frontbuffer_tracking@fbc-2p-primscrn-indfb-plflip-blt
-kms_frontbuffer_tracking@fbc-2p-primscrn-shrfb-pgflip-blt
-kms_frontbuffer_tracking@fbc-2p-primscrn-shrfb-msflip-blt
-kms_frontbuffer_tracking@fbc-2p-primscrn-shrfb-plflip-blt
-kms_frontbuffer_tracking@fbc-2p-scndscrn-indfb-pgflip-blt
-kms_frontbuffer_tracking@fbc-2p-scndscrn-indfb-msflip-blt
-kms_frontbuffer_tracking@fbc-2p-scndscrn-indfb-plflip-blt
-kms_frontbuffer_tracking@fbc-2p-scndscrn-shrfb-pgflip-blt
-kms_frontbuffer_tracking@fbc-2p-scndscrn-shrfb-msflip-blt
-kms_frontbuffer_tracking@fbc-2p-scndscrn-shrfb-plflip-blt
-kms_frontbuffer_tracking@psr-1p-primscrn-indfb-pgflip-blt
-kms_frontbuffer_tracking@psr-1p-primscrn-indfb-msflip-blt
-kms_frontbuffer_tracking@psr-1p-primscrn-indfb-plflip-blt
-kms_frontbuffer_tracking@psr-1p-primscrn-shrfb-pgflip-blt
-kms_frontbuffer_tracking@psr-1p-primscrn-shrfb-msflip-blt
-kms_frontbuffer_tracking@psr-1p-primscrn-shrfb-plflip-blt
-kms_frontbuffer_tracking@psr-2p-primscrn-indfb-pgflip-blt
-kms_frontbuffer_tracking@psr-2p-primscrn-indfb-msflip-blt
-kms_frontbuffer_tracking@psr-2p-primscrn-indfb-plflip-blt
-kms_frontbuffer_tracking@psr-2p-primscrn-shrfb-pgflip-blt
-kms_frontbuffer_tracking@psr-2p-primscrn-shrfb-msflip-blt
-kms_frontbuffer_tracking@psr-2p-primscrn-shrfb-plflip-blt
-kms_frontbuffer_tracking@psr-2p-scndscrn-indfb-pgflip-blt
-kms_frontbuffer_tracking@psr-2p-scndscrn-indfb-msflip-blt
-kms_frontbuffer_tracking@psr-2p-scndscrn-indfb-plflip-blt
-kms_frontbuffer_tracking@psr-2p-scndscrn-shrfb-pgflip-blt
-kms_frontbuffer_tracking@psr-2p-scndscrn-shrfb-msflip-blt
-kms_frontbuffer_tracking@psr-2p-scndscrn-shrfb-plflip-blt
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-indfb-pgflip-blt
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-indfb-msflip-blt
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-indfb-plflip-blt
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-shrfb-pgflip-blt
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-shrfb-msflip-blt
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-shrfb-plflip-blt
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-indfb-pgflip-blt
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-indfb-msflip-blt
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-indfb-plflip-blt
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-shrfb-pgflip-blt
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-shrfb-msflip-blt
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-shrfb-plflip-blt
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-indfb-pgflip-blt
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-indfb-msflip-blt
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-indfb-plflip-blt
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-shrfb-pgflip-blt
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-shrfb-msflip-blt
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-shrfb-plflip-blt
-kms_frontbuffer_tracking@drrs-1p-primscrn-indfb-pgflip-blt
-kms_frontbuffer_tracking@drrs-1p-primscrn-indfb-msflip-blt
-kms_frontbuffer_tracking@drrs-1p-primscrn-indfb-plflip-blt
-kms_frontbuffer_tracking@drrs-1p-primscrn-shrfb-pgflip-blt
-kms_frontbuffer_tracking@drrs-1p-primscrn-shrfb-msflip-blt
-kms_frontbuffer_tracking@drrs-1p-primscrn-shrfb-plflip-blt
-kms_frontbuffer_tracking@drrs-2p-primscrn-indfb-pgflip-blt
-kms_frontbuffer_tracking@drrs-2p-primscrn-indfb-msflip-blt
-kms_frontbuffer_tracking@drrs-2p-primscrn-indfb-plflip-blt
-kms_frontbuffer_tracking@drrs-2p-primscrn-shrfb-pgflip-blt
-kms_frontbuffer_tracking@drrs-2p-primscrn-shrfb-msflip-blt
-kms_frontbuffer_tracking@drrs-2p-primscrn-shrfb-plflip-blt
-kms_frontbuffer_tracking@drrs-2p-scndscrn-indfb-pgflip-blt
-kms_frontbuffer_tracking@drrs-2p-scndscrn-indfb-msflip-blt
-kms_frontbuffer_tracking@drrs-2p-scndscrn-indfb-plflip-blt
-kms_frontbuffer_tracking@drrs-2p-scndscrn-shrfb-pgflip-blt
-kms_frontbuffer_tracking@drrs-2p-scndscrn-shrfb-msflip-blt
-kms_frontbuffer_tracking@drrs-2p-scndscrn-shrfb-plflip-blt
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-indfb-pgflip-blt
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-indfb-msflip-blt
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-indfb-plflip-blt
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-shrfb-pgflip-blt
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-shrfb-msflip-blt
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-shrfb-plflip-blt
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-indfb-pgflip-blt
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-indfb-msflip-blt
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-indfb-plflip-blt
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-shrfb-pgflip-blt
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-shrfb-msflip-blt
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-shrfb-plflip-blt
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-indfb-pgflip-blt
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-indfb-msflip-blt
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-indfb-plflip-blt
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-shrfb-pgflip-blt
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-shrfb-msflip-blt
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-shrfb-plflip-blt
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-indfb-pgflip-blt
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-indfb-msflip-blt
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-indfb-plflip-blt
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-shrfb-pgflip-blt
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-shrfb-msflip-blt
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-shrfb-plflip-blt
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-indfb-pgflip-blt
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-indfb-msflip-blt
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-indfb-plflip-blt
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-shrfb-pgflip-blt
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-shrfb-msflip-blt
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-shrfb-plflip-blt
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-indfb-pgflip-blt
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-indfb-msflip-blt
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-indfb-plflip-blt
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-shrfb-pgflip-blt
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-shrfb-msflip-blt
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-shrfb-plflip-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-indfb-pgflip-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-indfb-msflip-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-indfb-plflip-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-shrfb-pgflip-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-shrfb-msflip-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-shrfb-plflip-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-indfb-pgflip-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-indfb-msflip-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-indfb-plflip-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-shrfb-pgflip-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-shrfb-msflip-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-shrfb-plflip-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-indfb-pgflip-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-indfb-msflip-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-indfb-plflip-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-shrfb-pgflip-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-shrfb-msflip-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-shrfb-plflip-blt
-kms_frontbuffer_tracking@fbc-1p-indfb-fliptrack-mmap-gtt
-kms_frontbuffer_tracking@fbc-1p-shrfb-fliptrack-mmap-gtt
-kms_frontbuffer_tracking@fbc-2p-indfb-fliptrack-mmap-gtt
-kms_frontbuffer_tracking@fbc-2p-shrfb-fliptrack-mmap-gtt
-kms_frontbuffer_tracking@fbcpsr-1p-indfb-fliptrack-mmap-gtt
-kms_frontbuffer_tracking@fbcpsr-1p-shrfb-fliptrack-mmap-gtt
-kms_frontbuffer_tracking@fbcpsr-2p-indfb-fliptrack-mmap-gtt
-kms_frontbuffer_tracking@fbcpsr-2p-shrfb-fliptrack-mmap-gtt
-kms_frontbuffer_tracking@fbcdrrs-1p-indfb-fliptrack-mmap-gtt
-kms_frontbuffer_tracking@fbcdrrs-1p-shrfb-fliptrack-mmap-gtt
-kms_frontbuffer_tracking@fbcdrrs-2p-indfb-fliptrack-mmap-gtt
-kms_frontbuffer_tracking@fbcdrrs-2p-shrfb-fliptrack-mmap-gtt
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-indfb-fliptrack-mmap-gtt
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-shrfb-fliptrack-mmap-gtt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-indfb-fliptrack-mmap-gtt
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-shrfb-fliptrack-mmap-gtt
-kms_frontbuffer_tracking@fbc-1p-primscrn-cur-indfb-move
-kms_frontbuffer_tracking@fbc-1p-primscrn-cur-indfb-onoff
-kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-move
-kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-onoff
-kms_frontbuffer_tracking@fbc-2p-primscrn-cur-indfb-move
-kms_frontbuffer_tracking@fbc-2p-primscrn-cur-indfb-onoff
-kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-move
-kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-onoff
-kms_frontbuffer_tracking@fbc-2p-scndscrn-cur-indfb-move
-kms_frontbuffer_tracking@fbc-2p-scndscrn-cur-indfb-onoff
-kms_frontbuffer_tracking@fbc-2p-scndscrn-spr-indfb-move
-kms_frontbuffer_tracking@fbc-2p-scndscrn-spr-indfb-onoff
-kms_frontbuffer_tracking@psr-1p-primscrn-cur-indfb-move
-kms_frontbuffer_tracking@psr-1p-primscrn-cur-indfb-onoff
-kms_frontbuffer_tracking@psr-1p-primscrn-spr-indfb-move
-kms_frontbuffer_tracking@psr-1p-primscrn-spr-indfb-onoff
-kms_frontbuffer_tracking@psr-2p-primscrn-cur-indfb-move
-kms_frontbuffer_tracking@psr-2p-primscrn-cur-indfb-onoff
-kms_frontbuffer_tracking@psr-2p-primscrn-spr-indfb-move
-kms_frontbuffer_tracking@psr-2p-primscrn-spr-indfb-onoff
-kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-move
-kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-onoff
-kms_frontbuffer_tracking@psr-2p-scndscrn-spr-indfb-move
-kms_frontbuffer_tracking@psr-2p-scndscrn-spr-indfb-onoff
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-move
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-onoff
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-spr-indfb-move
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-spr-indfb-onoff
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-cur-indfb-move
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-cur-indfb-onoff
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-spr-indfb-move
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-spr-indfb-onoff
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-cur-indfb-move
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-cur-indfb-onoff
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-spr-indfb-move
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-spr-indfb-onoff
-kms_frontbuffer_tracking@drrs-1p-primscrn-cur-indfb-move
-kms_frontbuffer_tracking@drrs-1p-primscrn-cur-indfb-onoff
-kms_frontbuffer_tracking@drrs-1p-primscrn-spr-indfb-move
-kms_frontbuffer_tracking@drrs-1p-primscrn-spr-indfb-onoff
-kms_frontbuffer_tracking@drrs-2p-primscrn-cur-indfb-move
-kms_frontbuffer_tracking@drrs-2p-primscrn-cur-indfb-onoff
-kms_frontbuffer_tracking@drrs-2p-primscrn-spr-indfb-move
-kms_frontbuffer_tracking@drrs-2p-primscrn-spr-indfb-onoff
-kms_frontbuffer_tracking@drrs-2p-scndscrn-cur-indfb-move
-kms_frontbuffer_tracking@drrs-2p-scndscrn-cur-indfb-onoff
-kms_frontbuffer_tracking@drrs-2p-scndscrn-spr-indfb-move
-kms_frontbuffer_tracking@drrs-2p-scndscrn-spr-indfb-onoff
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-cur-indfb-move
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-cur-indfb-onoff
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-spr-indfb-move
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-spr-indfb-onoff
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-cur-indfb-move
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-cur-indfb-onoff
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-spr-indfb-move
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-spr-indfb-onoff
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-cur-indfb-move
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-cur-indfb-onoff
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-spr-indfb-move
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-spr-indfb-onoff
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-cur-indfb-move
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-cur-indfb-onoff
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-spr-indfb-move
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-spr-indfb-onoff
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-cur-indfb-move
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-cur-indfb-onoff
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-spr-indfb-move
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-spr-indfb-onoff
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-cur-indfb-move
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-cur-indfb-onoff
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-spr-indfb-move
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-spr-indfb-onoff
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-cur-indfb-move
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-cur-indfb-onoff
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-spr-indfb-move
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-spr-indfb-onoff
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-cur-indfb-move
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-cur-indfb-onoff
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-spr-indfb-move
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-spr-indfb-onoff
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-cur-indfb-move
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-cur-indfb-onoff
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-spr-indfb-move
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-spr-indfb-onoff
-kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-fullscreen
-kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-fullscreen
-kms_frontbuffer_tracking@fbc-2p-scndscrn-spr-indfb-fullscreen
-kms_frontbuffer_tracking@psr-1p-primscrn-spr-indfb-fullscreen
-kms_frontbuffer_tracking@psr-2p-primscrn-spr-indfb-fullscreen
-kms_frontbuffer_tracking@psr-2p-scndscrn-spr-indfb-fullscreen
-kms_frontbuffer_tracking@fbcpsr-1p-primscrn-spr-indfb-fullscreen
-kms_frontbuffer_tracking@fbcpsr-2p-primscrn-spr-indfb-fullscreen
-kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-spr-indfb-fullscreen
-kms_frontbuffer_tracking@drrs-1p-primscrn-spr-indfb-fullscreen
-kms_frontbuffer_tracking@drrs-2p-primscrn-spr-indfb-fullscreen
-kms_frontbuffer_tracking@drrs-2p-scndscrn-spr-indfb-fullscreen
-kms_frontbuffer_tracking@fbcdrrs-1p-primscrn-spr-indfb-fullscreen
-kms_frontbuffer_tracking@fbcdrrs-2p-primscrn-spr-indfb-fullscreen
-kms_frontbuffer_tracking@fbcdrrs-2p-scndscrn-spr-indfb-fullscreen
-kms_frontbuffer_tracking@psrdrrs-1p-primscrn-spr-indfb-fullscreen
-kms_frontbuffer_tracking@psrdrrs-2p-primscrn-spr-indfb-fullscreen
-kms_frontbuffer_tracking@psrdrrs-2p-scndscrn-spr-indfb-fullscreen
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-primscrn-spr-indfb-fullscreen
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-primscrn-spr-indfb-fullscreen
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-scndscrn-spr-indfb-fullscreen
-kms_frontbuffer_tracking@fbc-1p-pri-indfb-multidraw
-kms_frontbuffer_tracking@fbc-2p-pri-indfb-multidraw
-kms_frontbuffer_tracking@psr-1p-pri-indfb-multidraw
-kms_frontbuffer_tracking@psr-2p-pri-indfb-multidraw
-kms_frontbuffer_tracking@fbcpsr-1p-pri-indfb-multidraw
-kms_frontbuffer_tracking@fbcpsr-2p-pri-indfb-multidraw
-kms_frontbuffer_tracking@drrs-1p-pri-indfb-multidraw
-kms_frontbuffer_tracking@drrs-2p-pri-indfb-multidraw
-kms_frontbuffer_tracking@fbcdrrs-1p-pri-indfb-multidraw
-kms_frontbuffer_tracking@fbcdrrs-2p-pri-indfb-multidraw
-kms_frontbuffer_tracking@psrdrrs-1p-pri-indfb-multidraw
-kms_frontbuffer_tracking@psrdrrs-2p-pri-indfb-multidraw
-kms_frontbuffer_tracking@fbcpsrdrrs-1p-pri-indfb-multidraw
-kms_frontbuffer_tracking@fbcpsrdrrs-2p-pri-indfb-multidraw
-kms_frontbuffer_tracking@fbc-farfromfence-mmap-gtt
-kms_frontbuffer_tracking@psr-farfromfence-mmap-gtt
-kms_frontbuffer_tracking@fbcpsr-farfromfence-mmap-gtt
-kms_frontbuffer_tracking@drrs-farfromfence-mmap-gtt
-kms_frontbuffer_tracking@fbcdrrs-farfromfence-mmap-gtt
-kms_frontbuffer_tracking@psrdrrs-farfromfence-mmap-gtt
-kms_frontbuffer_tracking@fbcpsrdrrs-farfromfence-mmap-gtt
-kms_frontbuffer_tracking@fbc-rgb565-draw-mmap-cpu
-kms_frontbuffer_tracking@fbc-rgb101010-draw-mmap-cpu
-kms_frontbuffer_tracking@fbc-rgb565-draw-mmap-gtt
-kms_frontbuffer_tracking@fbc-rgb101010-draw-mmap-gtt
-kms_frontbuffer_tracking@fbc-rgb565-draw-mmap-wc
-kms_frontbuffer_tracking@fbc-rgb101010-draw-mmap-wc
-kms_frontbuffer_tracking@fbc-rgb565-draw-pwrite
-kms_frontbuffer_tracking@fbc-rgb101010-draw-pwrite
-kms_frontbuffer_tracking@fbc-rgb565-draw-blt
-kms_frontbuffer_tracking@fbc-rgb101010-draw-blt
-kms_frontbuffer_tracking@fbc-rgb565-draw-render
-kms_frontbuffer_tracking@fbc-rgb101010-draw-render
-kms_frontbuffer_tracking@psr-rgb565-draw-mmap-cpu
-kms_frontbuffer_tracking@psr-rgb101010-draw-mmap-cpu
-kms_frontbuffer_tracking@psr-rgb565-draw-mmap-gtt
-kms_frontbuffer_tracking@psr-rgb101010-draw-mmap-gtt
-kms_frontbuffer_tracking@psr-rgb565-draw-mmap-wc
-kms_frontbuffer_tracking@psr-rgb101010-draw-mmap-wc
-kms_frontbuffer_tracking@psr-rgb565-draw-pwrite
-kms_frontbuffer_tracking@psr-rgb101010-draw-pwrite
-kms_frontbuffer_tracking@psr-rgb565-draw-blt
-kms_frontbuffer_tracking@psr-rgb101010-draw-blt
-kms_frontbuffer_tracking@psr-rgb565-draw-render
-kms_frontbuffer_tracking@psr-rgb101010-draw-render
-kms_frontbuffer_tracking@fbcpsr-rgb565-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsr-rgb101010-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsr-rgb565-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsr-rgb101010-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsr-rgb565-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsr-rgb101010-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsr-rgb565-draw-pwrite
-kms_frontbuffer_tracking@fbcpsr-rgb101010-draw-pwrite
-kms_frontbuffer_tracking@fbcpsr-rgb565-draw-blt
-kms_frontbuffer_tracking@fbcpsr-rgb101010-draw-blt
-kms_frontbuffer_tracking@fbcpsr-rgb565-draw-render
-kms_frontbuffer_tracking@fbcpsr-rgb101010-draw-render
-kms_frontbuffer_tracking@drrs-rgb565-draw-mmap-cpu
-kms_frontbuffer_tracking@drrs-rgb101010-draw-mmap-cpu
-kms_frontbuffer_tracking@drrs-rgb565-draw-mmap-gtt
-kms_frontbuffer_tracking@drrs-rgb101010-draw-mmap-gtt
-kms_frontbuffer_tracking@drrs-rgb565-draw-mmap-wc
-kms_frontbuffer_tracking@drrs-rgb101010-draw-mmap-wc
-kms_frontbuffer_tracking@drrs-rgb565-draw-pwrite
-kms_frontbuffer_tracking@drrs-rgb101010-draw-pwrite
-kms_frontbuffer_tracking@drrs-rgb565-draw-blt
-kms_frontbuffer_tracking@drrs-rgb101010-draw-blt
-kms_frontbuffer_tracking@drrs-rgb565-draw-render
-kms_frontbuffer_tracking@drrs-rgb101010-draw-render
-kms_frontbuffer_tracking@fbcdrrs-rgb565-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcdrrs-rgb101010-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcdrrs-rgb565-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcdrrs-rgb101010-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcdrrs-rgb565-draw-mmap-wc
-kms_frontbuffer_tracking@fbcdrrs-rgb101010-draw-mmap-wc
-kms_frontbuffer_tracking@fbcdrrs-rgb565-draw-pwrite
-kms_frontbuffer_tracking@fbcdrrs-rgb101010-draw-pwrite
-kms_frontbuffer_tracking@fbcdrrs-rgb565-draw-blt
-kms_frontbuffer_tracking@fbcdrrs-rgb101010-draw-blt
-kms_frontbuffer_tracking@fbcdrrs-rgb565-draw-render
-kms_frontbuffer_tracking@fbcdrrs-rgb101010-draw-render
-kms_frontbuffer_tracking@psrdrrs-rgb565-draw-mmap-cpu
-kms_frontbuffer_tracking@psrdrrs-rgb101010-draw-mmap-cpu
-kms_frontbuffer_tracking@psrdrrs-rgb565-draw-mmap-gtt
-kms_frontbuffer_tracking@psrdrrs-rgb101010-draw-mmap-gtt
-kms_frontbuffer_tracking@psrdrrs-rgb565-draw-mmap-wc
-kms_frontbuffer_tracking@psrdrrs-rgb101010-draw-mmap-wc
-kms_frontbuffer_tracking@psrdrrs-rgb565-draw-pwrite
-kms_frontbuffer_tracking@psrdrrs-rgb101010-draw-pwrite
-kms_frontbuffer_tracking@psrdrrs-rgb565-draw-blt
-kms_frontbuffer_tracking@psrdrrs-rgb101010-draw-blt
-kms_frontbuffer_tracking@psrdrrs-rgb565-draw-render
-kms_frontbuffer_tracking@psrdrrs-rgb101010-draw-render
-kms_frontbuffer_tracking@fbcpsrdrrs-rgb565-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsrdrrs-rgb101010-draw-mmap-cpu
-kms_frontbuffer_tracking@fbcpsrdrrs-rgb565-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsrdrrs-rgb101010-draw-mmap-gtt
-kms_frontbuffer_tracking@fbcpsrdrrs-rgb565-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsrdrrs-rgb101010-draw-mmap-wc
-kms_frontbuffer_tracking@fbcpsrdrrs-rgb565-draw-pwrite
-kms_frontbuffer_tracking@fbcpsrdrrs-rgb101010-draw-pwrite
-kms_frontbuffer_tracking@fbcpsrdrrs-rgb565-draw-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-rgb101010-draw-blt
-kms_frontbuffer_tracking@fbcpsrdrrs-rgb565-draw-render
-kms_frontbuffer_tracking@fbcpsrdrrs-rgb101010-draw-render
-kms_frontbuffer_tracking@fbc-indfb-scaledprimary
-kms_frontbuffer_tracking@fbc-shrfb-scaledprimary
-kms_frontbuffer_tracking@psr-indfb-scaledprimary
-kms_frontbuffer_tracking@psr-shrfb-scaledprimary
-kms_frontbuffer_tracking@fbcpsr-indfb-scaledprimary
-kms_frontbuffer_tracking@fbcpsr-shrfb-scaledprimary
-kms_frontbuffer_tracking@drrs-indfb-scaledprimary
-kms_frontbuffer_tracking@drrs-shrfb-scaledprimary
-kms_frontbuffer_tracking@fbcdrrs-indfb-scaledprimary
-kms_frontbuffer_tracking@fbcdrrs-shrfb-scaledprimary
-kms_frontbuffer_tracking@psrdrrs-indfb-scaledprimary
-kms_frontbuffer_tracking@psrdrrs-shrfb-scaledprimary
-kms_frontbuffer_tracking@fbcpsrdrrs-indfb-scaledprimary
-kms_frontbuffer_tracking@fbcpsrdrrs-shrfb-scaledprimary
-kms_frontbuffer_tracking@fbc-modesetfrombusy
-kms_frontbuffer_tracking@fbc-stridechange
-kms_frontbuffer_tracking@fbc-tiling-linear
-kms_frontbuffer_tracking@fbc-tiling-y
-kms_frontbuffer_tracking@fbc-tiling-4
-kms_frontbuffer_tracking@fbc-suspend
-kms_frontbuffer_tracking@psr-modesetfrombusy
-kms_frontbuffer_tracking@psr-slowdraw
-kms_frontbuffer_tracking@psr-suspend
-kms_frontbuffer_tracking@fbcpsr-modesetfrombusy
-kms_frontbuffer_tracking@fbcpsr-stridechange
-kms_frontbuffer_tracking@fbcpsr-tiling-linear
-kms_frontbuffer_tracking@fbcpsr-tiling-y
-kms_frontbuffer_tracking@fbcpsr-tiling-4
-kms_frontbuffer_tracking@fbcpsr-slowdraw
-kms_frontbuffer_tracking@fbcpsr-suspend
-kms_frontbuffer_tracking@drrs-modesetfrombusy
-kms_frontbuffer_tracking@drrs-slowdraw
-kms_frontbuffer_tracking@drrs-suspend
-kms_frontbuffer_tracking@fbcdrrs-modesetfrombusy
-kms_frontbuffer_tracking@fbcdrrs-stridechange
-kms_frontbuffer_tracking@fbcdrrs-tiling-linear
-kms_frontbuffer_tracking@fbcdrrs-tiling-y
-kms_frontbuffer_tracking@fbcdrrs-tiling-4
-kms_frontbuffer_tracking@fbcdrrs-slowdraw
-kms_frontbuffer_tracking@fbcdrrs-suspend
-kms_frontbuffer_tracking@psrdrrs-modesetfrombusy
-kms_frontbuffer_tracking@psrdrrs-slowdraw
-kms_frontbuffer_tracking@psrdrrs-suspend
-kms_frontbuffer_tracking@fbcpsrdrrs-modesetfrombusy
-kms_frontbuffer_tracking@fbcpsrdrrs-stridechange
-kms_frontbuffer_tracking@fbcpsrdrrs-tiling-linear
-kms_frontbuffer_tracking@fbcpsrdrrs-tiling-y
-kms_frontbuffer_tracking@fbcpsrdrrs-tiling-4
-kms_frontbuffer_tracking@fbcpsrdrrs-slowdraw
-kms_frontbuffer_tracking@fbcpsrdrrs-suspend
-kms_frontbuffer_tracking@basic
-kms_getfb@getfb-handle-zero
-kms_getfb@getfb-handle-valid
-kms_getfb@getfb-handle-closed
-kms_getfb@getfb-handle-not-fb
-kms_getfb@getfb-addfb-different-handles
-kms_getfb@getfb-repeated-different-handles
-kms_getfb@getfb-reject-ccs
-kms_getfb@getfb2-handle-zero
-kms_getfb@getfb2-handle-closed
-kms_getfb@getfb2-handle-not-fb
-kms_getfb@getfb2-accept-ccs
-kms_getfb@getfb2-into-addfb2
-kms_getfb@getfb-handle-protection
-kms_getfb@getfb2-handle-protection
-kms_hdmi_inject@inject-4k
-kms_hdmi_inject@inject-audio
-kms_hdr@bpc-switch
-kms_hdr@bpc-switch-dpms
-kms_hdr@bpc-switch-suspend
-kms_hdr@static-toggle
-kms_hdr@static-toggle-dpms
-kms_hdr@static-toggle-suspend
-kms_hdr@static-swap
-kms_hdr@invalid-metadata-sizes
-kms_hdr@invalid-hdr
-kms_invalid_mode@clock-too-high
-kms_invalid_mode@zero-clock
-kms_invalid_mode@int-max-clock
-kms_invalid_mode@uint-max-clock
-kms_invalid_mode@zero-hdisplay
-kms_invalid_mode@zero-vdisplay
-kms_invalid_mode@bad-hsync-start
-kms_invalid_mode@bad-vsync-start
-kms_invalid_mode@bad-hsync-end
-kms_invalid_mode@bad-vsync-end
-kms_invalid_mode@bad-htotal
-kms_invalid_mode@bad-vtotal
-kms_legacy_colorkey@basic
-kms_legacy_colorkey@invalid-plane
-kms_multipipe_modeset@basic-max-pipe-crc-check
-kms_panel_fitting@legacy
-kms_panel_fitting@atomic-fastset
-kms_pipe_b_c_ivb@pipe-B-dpms-off-modeset-pipe-C
-kms_pipe_b_c_ivb@pipe-B-double-modeset-then-modeset-pipe-C
-kms_pipe_b_c_ivb@disable-pipe-B-enable-pipe-C
-kms_pipe_b_c_ivb@from-pipe-C-to-B-with-3-lanes
-kms_pipe_b_c_ivb@enable-pipe-C-while-B-has-3-lanes
-kms_pipe_crc_basic@bad-source
-kms_pipe_crc_basic@read-crc
-kms_pipe_crc_basic@read-crc-frame-sequence
-kms_pipe_crc_basic@nonblocking-crc
-kms_pipe_crc_basic@nonblocking-crc-frame-sequence
-kms_pipe_crc_basic@suspend-read-crc
-kms_pipe_crc_basic@hang-read-crc
-kms_pipe_crc_basic@disable-crc-after-crtc
-kms_pipe_crc_basic@compare-crc-sanitycheck-xr24
-kms_pipe_crc_basic@compare-crc-sanitycheck-nv12
-kms_plane@pixel-format
-kms_plane@pixel-format-source-clamping
-kms_plane@plane-position-covered
-kms_plane@plane-position-hole
-kms_plane@plane-position-hole-dpms
-kms_plane@plane-panning-top-left
-kms_plane@plane-panning-bottom-right
-kms_plane@plane-panning-bottom-right-suspend
-kms_plane@planar-pixel-format-settings
-kms_plane_alpha_blend@alpha-basic
-kms_plane_alpha_blend@alpha-7efc
-kms_plane_alpha_blend@coverage-7efc
-kms_plane_alpha_blend@coverage-vs-premult-vs-constant
-kms_plane_alpha_blend@alpha-transparent-fb
-kms_plane_alpha_blend@alpha-opaque-fb
-kms_plane_alpha_blend@constant-alpha-min
-kms_plane_alpha_blend@constant-alpha-mid
-kms_plane_alpha_blend@constant-alpha-max
-kms_plane_cursor@primary
-kms_plane_cursor@overlay
-kms_plane_cursor@viewport
-kms_plane_lowres@tiling-none
-kms_plane_lowres@tiling-x
-kms_plane_lowres@tiling-y
-kms_plane_lowres@tiling-yf
-kms_plane_lowres@tiling-4
-kms_plane_multiple@tiling-none
-kms_plane_multiple@tiling-x
-kms_plane_multiple@tiling-y
-kms_plane_multiple@tiling-yf
-kms_plane_multiple@tiling-4
-kms_plane_scaling@plane-upscale-20x20-with-pixel-format
-kms_plane_scaling@plane-upscale-factor-0-25-with-pixel-format
-kms_plane_scaling@plane-downscale-factor-0-25-with-pixel-format
-kms_plane_scaling@plane-downscale-factor-0-5-with-pixel-format
-kms_plane_scaling@plane-downscale-factor-0-75-with-pixel-format
-kms_plane_scaling@plane-scaler-unity-scaling-with-pixel-format
-kms_plane_scaling@plane-upscale-20x20-with-rotation
-kms_plane_scaling@plane-upscale-factor-0-25-with-rotation
-kms_plane_scaling@plane-downscale-factor-0-25-with-rotation
-kms_plane_scaling@plane-downscale-factor-0-5-with-rotation
-kms_plane_scaling@plane-downscale-factor-0-75-with-rotation
-kms_plane_scaling@plane-scaler-unity-scaling-with-rotation
-kms_plane_scaling@plane-upscale-20x20-with-modifiers
-kms_plane_scaling@plane-upscale-factor-0-25-with-modifiers
-kms_plane_scaling@plane-downscale-factor-0-25-with-modifiers
-kms_plane_scaling@plane-downscale-factor-0-5-with-modifiers
-kms_plane_scaling@plane-downscale-factor-0-75-with-modifiers
-kms_plane_scaling@plane-scaler-unity-scaling-with-modifiers
-kms_plane_scaling@plane-scaler-with-clipping-clamping-pixel-formats
-kms_plane_scaling@plane-scaler-with-clipping-clamping-rotation
-kms_plane_scaling@plane-scaler-with-clipping-clamping-modifiers
-kms_plane_scaling@planes-upscale-20x20
-kms_plane_scaling@planes-upscale-factor-0-25
-kms_plane_scaling@planes-scaler-unity-scaling
-kms_plane_scaling@planes-downscale-factor-0-25
-kms_plane_scaling@planes-downscale-factor-0-5
-kms_plane_scaling@planes-downscale-factor-0-75
-kms_plane_scaling@planes-upscale-20x20-downscale-factor-0-25
-kms_plane_scaling@planes-upscale-20x20-downscale-factor-0-5
-kms_plane_scaling@planes-upscale-20x20-downscale-factor-0-75
-kms_plane_scaling@planes-upscale-factor-0-25-downscale-factor-0-25
-kms_plane_scaling@planes-upscale-factor-0-25-downscale-factor-0-5
-kms_plane_scaling@planes-upscale-factor-0-25-downscale-factor-0-75
-kms_plane_scaling@planes-unity-scaling-downscale-factor-0-25
-kms_plane_scaling@planes-unity-scaling-downscale-factor-0-5
-kms_plane_scaling@planes-unity-scaling-downscale-factor-0-75
-kms_plane_scaling@planes-downscale-factor-0-25-upscale-20x20
-kms_plane_scaling@planes-downscale-factor-0-25-upscale-factor-0-25
-kms_plane_scaling@planes-downscale-factor-0-25-unity-scaling
-kms_plane_scaling@planes-downscale-factor-0-5-upscale-20x20
-kms_plane_scaling@planes-downscale-factor-0-5-upscale-factor-0-25
-kms_plane_scaling@planes-downscale-factor-0-5-unity-scaling
-kms_plane_scaling@planes-downscale-factor-0-75-upscale-20x20
-kms_plane_scaling@planes-downscale-factor-0-75-upscale-factor-0-25
-kms_plane_scaling@planes-downscale-factor-0-75-unity-scaling
-kms_plane_scaling@intel-max-src-size
-kms_plane_scaling@invalid-num-scalers
-kms_plane_scaling@invalid-parameters
-kms_plane_scaling@2x-scaler-multi-pipe
-kms_prime@basic-crc-hybrid
-kms_prime@basic-modeset-hybrid
-kms_prime@D3hot
-kms_prime@basic-crc-vgem
-kms_prop_blob@basic
-kms_prop_blob@blob-prop-core
-kms_prop_blob@blob-prop-validate
-kms_prop_blob@blob-prop-lifetime
-kms_prop_blob@blob-multiple
-kms_prop_blob@invalid-get-prop-any
-kms_prop_blob@invalid-get-prop
-kms_prop_blob@invalid-set-prop-any
-kms_prop_blob@invalid-set-prop
-kms_properties@plane-properties-legacy
-kms_properties@plane-properties-atomic
-kms_properties@crtc-properties-legacy
-kms_properties@crtc-properties-atomic
-kms_properties@connector-properties-legacy
-kms_properties@connector-properties-atomic
-kms_properties@invalid-properties-legacy
-kms_properties@invalid-properties-atomic
-kms_properties@get_properties-sanity-atomic
-kms_properties@get_properties-sanity-non-atomic
-kms_psr@pr-basic
-kms_psr@pr-no-drrs
-kms_psr@pr-primary-page-flip
-kms_psr@pr-primary-mmap-gtt
-kms_psr@pr-primary-mmap-cpu
-kms_psr@pr-primary-blt
-kms_psr@pr-primary-render
-kms_psr@pr-sprite-mmap-gtt
-kms_psr@pr-cursor-mmap-gtt
-kms_psr@pr-sprite-mmap-cpu
-kms_psr@pr-cursor-mmap-cpu
-kms_psr@pr-sprite-blt
-kms_psr@pr-cursor-blt
-kms_psr@pr-sprite-render
-kms_psr@pr-cursor-render
-kms_psr@pr-sprite-plane-move
-kms_psr@pr-cursor-plane-move
-kms_psr@pr-sprite-plane-onoff
-kms_psr@pr-cursor-plane-onoff
-kms_psr@pr-dpms
-kms_psr@pr-suspend
-kms_psr@psr-basic
-kms_psr@psr-no-drrs
-kms_psr@psr-primary-page-flip
-kms_psr@psr-primary-mmap-gtt
-kms_psr@psr-primary-mmap-cpu
-kms_psr@psr-primary-blt
-kms_psr@psr-primary-render
-kms_psr@psr-sprite-mmap-gtt
-kms_psr@psr-cursor-mmap-gtt
-kms_psr@psr-sprite-mmap-cpu
-kms_psr@psr-cursor-mmap-cpu
-kms_psr@psr-sprite-blt
-kms_psr@psr-cursor-blt
-kms_psr@psr-sprite-render
-kms_psr@psr-cursor-render
-kms_psr@psr-sprite-plane-move
-kms_psr@psr-cursor-plane-move
-kms_psr@psr-sprite-plane-onoff
-kms_psr@psr-cursor-plane-onoff
-kms_psr@psr-dpms
-kms_psr@psr-suspend
-kms_psr@psr2-basic
-kms_psr@psr2-no-drrs
-kms_psr@psr2-primary-page-flip
-kms_psr@psr2-primary-mmap-gtt
-kms_psr@psr2-primary-mmap-cpu
-kms_psr@psr2-primary-blt
-kms_psr@psr2-primary-render
-kms_psr@psr2-sprite-mmap-gtt
-kms_psr@psr2-cursor-mmap-gtt
-kms_psr@psr2-sprite-mmap-cpu
-kms_psr@psr2-cursor-mmap-cpu
-kms_psr@psr2-sprite-blt
-kms_psr@psr2-cursor-blt
-kms_psr@psr2-sprite-render
-kms_psr@psr2-cursor-render
-kms_psr@psr2-sprite-plane-move
-kms_psr@psr2-cursor-plane-move
-kms_psr@psr2-sprite-plane-onoff
-kms_psr@psr2-cursor-plane-onoff
-kms_psr@psr2-dpms
-kms_psr@psr2-suspend
-kms_psr2_sf@primary-plane-update-sf-dmg-area
-kms_psr2_sf@primary-plane-update-sf-dmg-area-big-fb
-kms_psr2_sf@overlay-plane-update-sf-dmg-area
-kms_psr2_sf@cursor-plane-update-sf
-kms_psr2_sf@cursor-plane-move-continuous-sf
-kms_psr2_sf@cursor-plane-move-continuous-exceed-sf
-kms_psr2_sf@cursor-plane-move-continuous-exceed-fully-sf
-kms_psr2_sf@plane-move-sf-dmg-area
-kms_psr2_sf@overlay-plane-move-continuous-sf
-kms_psr2_sf@overlay-plane-move-continuous-exceed-sf
-kms_psr2_sf@overlay-plane-move-continuous-exceed-fully-sf
-kms_psr2_sf@overlay-primary-update-sf-dmg-area
-kms_psr2_sf@overlay-plane-update-continuous-sf
-kms_psr2_su@page_flip-XRGB8888
-kms_psr2_su@page_flip-NV12
-kms_psr2_su@page_flip-P010
-kms_psr2_su@frontbuffer-XRGB8888
-kms_pwrite_crc
-kms_rmfb@rmfb-ioctl
-kms_rmfb@close-fd
-kms_rotation_crc@primary-rotation-90
-kms_rotation_crc@primary-rotation-180
-kms_rotation_crc@primary-rotation-270
-kms_rotation_crc@sprite-rotation-90
-kms_rotation_crc@sprite-rotation-180
-kms_rotation_crc@sprite-rotation-270
-kms_rotation_crc@cursor-rotation-180
-kms_rotation_crc@sprite-rotation-90-pos-100-0
-kms_rotation_crc@bad-pixel-format
-kms_rotation_crc@bad-tiling
-kms_rotation_crc@primary-x-tiled-reflect-x-0
-kms_rotation_crc@primary-x-tiled-reflect-x-180
-kms_rotation_crc@primary-y-tiled-reflect-x-0
-kms_rotation_crc@primary-y-tiled-reflect-x-90
-kms_rotation_crc@primary-y-tiled-reflect-x-180
-kms_rotation_crc@primary-y-tiled-reflect-x-270
-kms_rotation_crc@primary-yf-tiled-reflect-x-0
-kms_rotation_crc@primary-yf-tiled-reflect-x-90
-kms_rotation_crc@primary-yf-tiled-reflect-x-180
-kms_rotation_crc@primary-yf-tiled-reflect-x-270
-kms_rotation_crc@primary-4-tiled-reflect-x-0
-kms_rotation_crc@primary-4-tiled-reflect-x-180
-kms_rotation_crc@multiplane-rotation
-kms_rotation_crc@multiplane-rotation-cropping-top
-kms_rotation_crc@multiplane-rotation-cropping-bottom
-kms_rotation_crc@exhaust-fences
-kms_scaling_modes@scaling-mode-full
-kms_scaling_modes@scaling-mode-center
-kms_scaling_modes@scaling-mode-full-aspect
-kms_scaling_modes@scaling-mode-none
-kms_selftest@drm_cmdline_parser
-kms_selftest@drm_damage_helper
-kms_selftest@drm_dp_mst_helper
-kms_selftest@drm_format_helper
-kms_selftest@drm_format
-kms_selftest@drm_framebuffer
-kms_selftest@drm_plane_helper
-kms_setmode@basic
-kms_setmode@basic-clone-single-crtc
-kms_setmode@invalid-clone-single-crtc
-kms_setmode@invalid-clone-exclusive-crtc
-kms_setmode@clone-exclusive-crtc
-kms_setmode@invalid-clone-single-crtc-stealing
-kms_sysfs_edid_timing
-kms_tv_load_detect@load-detect
-kms_universal_plane@universal-plane-functional
-kms_universal_plane@universal-plane-sanity
-kms_universal_plane@disable-primary-vs-flip
-kms_universal_plane@cursor-fb-leak
-kms_universal_plane@universal-plane-pageflip-windowed
-kms_vblank@invalid
-kms_vblank@crtc-id
-kms_vblank@accuracy-idle
-kms_vblank@query-idle
-kms_vblank@query-idle-hang
-kms_vblank@query-forked
-kms_vblank@query-forked-hang
-kms_vblank@query-busy
-kms_vblank@query-busy-hang
-kms_vblank@query-forked-busy
-kms_vblank@query-forked-busy-hang
-kms_vblank@wait-idle
-kms_vblank@wait-idle-hang
-kms_vblank@wait-forked
-kms_vblank@wait-forked-hang
-kms_vblank@wait-busy
-kms_vblank@wait-busy-hang
-kms_vblank@wait-forked-busy
-kms_vblank@wait-forked-busy-hang
-kms_vblank@ts-continuation-idle
-kms_vblank@ts-continuation-idle-hang
-kms_vblank@ts-continuation-dpms-rpm
-kms_vblank@ts-continuation-dpms-suspend
-kms_vblank@ts-continuation-suspend
-kms_vblank@ts-continuation-modeset
-kms_vblank@ts-continuation-modeset-hang
-kms_vblank@ts-continuation-modeset-rpm
-kms_vrr@flip-basic
-kms_vrr@flip-dpms
-kms_vrr@flip-suspend
-kms_vrr@flipline
-kms_vrr@negative-basic
-kms_writeback@writeback-pixel-formats
-kms_writeback@writeback-invalid-parameters
-kms_writeback@writeback-fb-id
-kms_writeback@writeback-check-output
-prime_mmap_kms@buffer-sharing
-msm_shrink@copy-gpu-sanitycheck-8
-msm_shrink@copy-gpu-sanitycheck-32
-msm_shrink@copy-gpu-8
-msm_shrink@copy-gpu-32
-msm_shrink@copy-gpu-madvise-8
-msm_shrink@copy-gpu-madvise-32
-msm_shrink@copy-gpu-oom-8
-msm_shrink@copy-gpu-oom-32
-msm_shrink@copy-mmap-sanitycheck-8
-msm_shrink@copy-mmap-sanitycheck-32
-msm_shrink@copy-mmap-8
-msm_shrink@copy-mmap-32
-msm_shrink@copy-mmap-madvise-8
-msm_shrink@copy-mmap-madvise-32
-msm_shrink@copy-mmap-oom-8
-msm_shrink@copy-mmap-oom-32
-msm_shrink@copy-mmap-dmabuf-sanitycheck-8
-msm_shrink@copy-mmap-dmabuf-sanitycheck-32
-msm_shrink@copy-mmap-dmabuf-8
-msm_shrink@copy-mmap-dmabuf-32
-msm_shrink@copy-mmap-dmabuf-madvise-8
-msm_shrink@copy-mmap-dmabuf-madvise-32
-msm_shrink@copy-mmap-dmabuf-oom-8
-msm_shrink@copy-mmap-dmabuf-oom-32
-msm_mapping@ring
-msm_mapping@sqefw
-msm_mapping@shadow
-msm_submitoverhead@submitbench-10-bos
-msm_submitoverhead@submitbench-10-bos-no-implicit-sync
-msm_submitoverhead@submitbench-100-bos
-msm_submitoverhead@submitbench-100-bos-no-implicit-sync
-msm_submitoverhead@submitbench-250-bos
-msm_submitoverhead@submitbench-250-bos-no-implicit-sync
-msm_submitoverhead@submitbench-500-bos
-msm_submitoverhead@submitbench-500-bos-no-implicit-sync
-msm_submitoverhead@submitbench-1000-bos
-msm_submitoverhead@submitbench-1000-bos-no-implicit-sync
-msm_recovery@hangcheck
-msm_recovery@gpu-fault
-msm_recovery@gpu-fault-parallel
-msm_recovery@iova-fault
-msm_submit@empty-submit
-msm_submit@invalid-queue-submit
-msm_submit@invalid-flags-submit
-msm_submit@invalid-in-fence-submit
-msm_submit@invalid-duplicate-bo-submit
-msm_submit@invalid-cmd-idx-submit
-msm_submit@invalid-cmd-type-submit
-msm_submit@valid-submit
diff --git a/drivers/gpu/drm/ci/x86_64.config b/drivers/gpu/drm/ci/x86_64.config
index 1cbd49a5b23a..8eaba388b141 100644
--- a/drivers/gpu/drm/ci/x86_64.config
+++ b/drivers/gpu/drm/ci/x86_64.config
@@ -24,6 +24,7 @@ CONFIG_DRM=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_PWM_CROS_EC=y
CONFIG_BACKLIGHT_PWM=y
+CONFIG_DRM_VKMS=m
# Strip out some stuff we don't need for graphics testing, to reduce
# the build.
diff --git a/drivers/gpu/drm/ci/xfails/amdgpu-stoney-fails.txt b/drivers/gpu/drm/ci/xfails/amdgpu-stoney-fails.txt
index ea87dc46bc2b..e8c2f4044a92 100644
--- a/drivers/gpu/drm/ci/xfails/amdgpu-stoney-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/amdgpu-stoney-fails.txt
@@ -1,27 +1,40 @@
+amdgpu/amd_abm@abm_enabled,Fail
+amdgpu/amd_abm@abm_gradual,Fail
+amdgpu/amd_abm@backlight_monotonic_abm,Fail
+amdgpu/amd_abm@backlight_monotonic_basic,Fail
+amdgpu/amd_assr@assr-links,Fail
+amdgpu/amd_assr@assr-links-dpms,Fail
+amdgpu/amd_mall@static-screen,Crash
+amdgpu/amd_mode_switch@mode-switch-first-last-pipe-2,Crash
+amdgpu/amd_plane@mpo-pan-nv12,Fail
+amdgpu/amd_plane@mpo-pan-p010,Fail
+amdgpu/amd_plane@mpo-pan-rgb,Crash
+amdgpu/amd_plane@mpo-scale-nv12,Fail
+amdgpu/amd_plane@mpo-scale-p010,Fail
+amdgpu/amd_plane@mpo-scale-rgb,Crash
+amdgpu/amd_plane@mpo-swizzle-toggle,Fail
+amdgpu/amd_uvd_dec@amdgpu_uvd_decode,Fail
+dumb_buffer@invalid-bpp,Fail
kms_addfb_basic@bad-pitch-65536,Fail
kms_addfb_basic@bo-too-small,Fail
kms_addfb_basic@too-high,Fail
-kms_async_flips@async-flip-with-page-flip-events,Fail
-kms_async_flips@crc,Fail
-kms_async_flips@invalid-async-flip,Fail
kms_atomic_transition@plane-all-modeset-transition-internal-panels,Fail
kms_atomic_transition@plane-all-transition,Fail
kms_atomic_transition@plane-all-transition-nonblocking,Fail
kms_atomic_transition@plane-toggle-modeset-transition,Fail
kms_atomic_transition@plane-use-after-nonblocking-unbind,Fail
-kms_bw@linear-tiling-1-displays-2560x1440p,Fail
-kms_bw@linear-tiling-1-displays-3840x2160p,Fail
-kms_bw@linear-tiling-2-displays-3840x2160p,Fail
-kms_bw@linear-tiling-3-displays-1920x1080p,Fail
-kms_color@degamma,Fail
+kms_cursor_crc@cursor-onscreen-64x21,Fail
+kms_cursor_crc@cursor-onscreen-64x64,Fail
+kms_cursor_crc@cursor-random-64x21,Fail
+kms_cursor_crc@cursor-random-64x64,Fail
kms_cursor_crc@cursor-size-change,Fail
-kms_cursor_crc@pipe-A-cursor-size-change,Fail
-kms_cursor_crc@pipe-B-cursor-size-change,Fail
+kms_cursor_crc@cursor-sliding-64x21,Fail
+kms_cursor_crc@cursor-sliding-64x64,Fail
kms_flip@flip-vs-modeset-vs-hang,Fail
kms_flip@flip-vs-panning-vs-hang,Fail
-kms_hdr@bpc-switch,Fail
-kms_hdr@bpc-switch-dpms,Fail
+kms_lease@lease-uevent,Fail
kms_plane@pixel-format,Fail
-kms_plane_multiple@atomic-pipe-A-tiling-none,Fail
-kms_rmfb@close-fd,Fail
+kms_plane_cursor@primary,Fail
kms_rotation_crc@primary-rotation-180,Fail
+perf@i915-ref-count,Fail
+tools_test@tools_test,Fail
diff --git a/drivers/gpu/drm/ci/xfails/amdgpu-stoney-flakes.txt b/drivers/gpu/drm/ci/xfails/amdgpu-stoney-flakes.txt
index 6faf75e667d3..ea512ff8c352 100644
--- a/drivers/gpu/drm/ci/xfails/amdgpu-stoney-flakes.txt
+++ b/drivers/gpu/drm/ci/xfails/amdgpu-stoney-flakes.txt
@@ -1 +1,8 @@
+# Board Name: hp-11A-G6-EE-grunt
+# Bug Report: https://lore.kernel.org/amd-gfx/3542730f-b8d7-404d-a947-b7a5e95d661c@collabora.com/T/#u
+# IGT Version: 1.28-g0df7b9b97
+# Linux Version: 6.9.0-rc7
+# Failure Rate: 50
kms_async_flips@async-flip-with-page-flip-events
+kms_async_flips@crc
+kms_plane@pixel-format-source-clamping
diff --git a/drivers/gpu/drm/ci/xfails/amdgpu-stoney-skips.txt b/drivers/gpu/drm/ci/xfails/amdgpu-stoney-skips.txt
index e2c538a0f954..3a2ce45d3cb9 100644
--- a/drivers/gpu/drm/ci/xfails/amdgpu-stoney-skips.txt
+++ b/drivers/gpu/drm/ci/xfails/amdgpu-stoney-skips.txt
@@ -1,2 +1,33 @@
# Suspend to RAM seems to be broken on this machine
-.*suspend.* \ No newline at end of file
+.*suspend.*
+
+# Skip driver specific tests
+msm_.*
+nouveau_.*
+panfrost_.*
+^v3d.*
+^vc4.*
+^vmwgfx*
+
+# Skip intel specific tests
+gem_.*
+i915_.*
+xe_.*
+
+# Currently fails and causes coverage loss for other tests
+# since core_getversion also fails.
+amdgpu/amd_module_load@reload
+core_hotunplug.*
+
+# GPU reset seen and it hangs the machine
+amdgpu/amd_deadlock@amdgpu-deadlock-sdma
+amdgpu/amd_deadlock@amdgpu-gfx-illegal-reg-access
+amdgpu/amd_dispatch@amdgpu-reset-test-gfx-with-IP-GFX-and-COMPUTE
+
+# Hangs the machine and timeout occurs
+amdgpu/amd_pci_unplug@amdgpu_hotunplug_simple
+amdgpu/amd_pci_unplug@amdgpu_hotunplug_with_cs
+amdgpu/amd_pci_unplug@amdgpu_hotunplug_with_exported_bo
+amdgpu/amd_pci_unplug@amdgpu_hotunplug_with_exported_fence
+amdgpu/amd_vrr_range@freesync-parsing
+device_reset.*
diff --git a/drivers/gpu/drm/ci/xfails/i915-amly-fails.txt b/drivers/gpu/drm/ci/xfails/i915-amly-fails.txt
index 59438e4df86e..6641520ac587 100644
--- a/drivers/gpu/drm/ci/xfails/i915-amly-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/i915-amly-fails.txt
@@ -1,3 +1,16 @@
+core_setmaster@master-drop-set-user,Fail
+core_setmaster_vs_auth,Fail
+i915_module_load@load,Fail
+i915_module_load@reload,Fail
+i915_module_load@reload-no-display,Fail
+i915_module_load@resize-bar,Fail
+i915_pm_rpm@gem-execbuf-stress,Timeout
+i915_pm_rpm@module-reload,Fail
+kms_async_flips@invalid-async-flip,Timeout
+kms_atomic_transition@modeset-transition-fencing,Timeout
+kms_ccs@crc-primary-rotation-180-yf-tiled-ccs,Timeout
+kms_fb_coherency@memset-crc,Crash
+kms_flip@flip-vs-dpms-off-vs-modeset,Timeout
kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-downscaling,Fail
kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-upscaling,Fail
kms_flip_scaled_crc@flip-32bpp-xtile-to-64bpp-xtile-downscaling,Fail
@@ -20,7 +33,25 @@ kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-downscaling,Fail
kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-upscaling,Fail
kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilegen12rcccs-upscaling,Fail
kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-downscaling,Fail
+kms_lease@lease-uevent,Fail
kms_plane_alpha_blend@alpha-basic,Fail
kms_plane_alpha_blend@alpha-opaque-fb,Fail
kms_plane_alpha_blend@alpha-transparent-fb,Fail
kms_plane_alpha_blend@constant-alpha-max,Fail
+kms_plane_scaling@plane-scaler-with-clipping-clamping-rotation,Timeout
+kms_pm_rpm@modeset-lpsp-stress,Timeout
+kms_pm_rpm@modeset-stress-extra-wait,Timeout
+kms_pm_rpm@universal-planes,Timeout
+kms_pm_rpm@universal-planes-dpms,Timeout
+perf@i915-ref-count,Fail
+perf_pmu@module-unload,Fail
+perf_pmu@rc6,Crash
+sysfs_heartbeat_interval@long,Timeout
+sysfs_heartbeat_interval@off,Timeout
+sysfs_preempt_timeout@off,Timeout
+sysfs_timeslice_duration@off,Timeout
+xe_module_load@force-load,Fail
+xe_module_load@load,Fail
+xe_module_load@many-reload,Fail
+xe_module_load@reload,Fail
+xe_module_load@reload-no-display,Fail
diff --git a/drivers/gpu/drm/ci/xfails/i915-amly-flakes.txt b/drivers/gpu/drm/ci/xfails/i915-amly-flakes.txt
new file mode 100644
index 000000000000..0a76547a103d
--- /dev/null
+++ b/drivers/gpu/drm/ci/xfails/i915-amly-flakes.txt
@@ -0,0 +1,9 @@
+# Board Name: asus-C433TA-AJ0005-rammus
+# Bug Report: https://lore.kernel.org/intel-gfx/af4ca4df-a3ef-4943-bdbf-4c3af2c333af@collabora.com/T/#u
+# IGT Version: 1.28-g0df7b9b97
+# Linux Version: 6.9.0-rc7
+# Failure Rate: 50
+i915_hangman@engine-engine-error
+i915_hangman@gt-engine-hang
+kms_async_flips@crc
+kms_universal_plane@cursor-fb-leak
diff --git a/drivers/gpu/drm/ci/xfails/i915-amly-skips.txt b/drivers/gpu/drm/ci/xfails/i915-amly-skips.txt
index fe55540a3f9a..5663ed0420a7 100644
--- a/drivers/gpu/drm/ci/xfails/i915-amly-skips.txt
+++ b/drivers/gpu/drm/ci/xfails/i915-amly-skips.txt
@@ -1,4 +1,24 @@
# Suspend to RAM seems to be broken on this machine
.*suspend.*
# This is generating kernel oops with divide error
-kms_plane_scaling@invalid-parameters \ No newline at end of file
+kms_plane_scaling@invalid-parameters
+
+# Skip driver specific tests
+^amdgpu.*
+msm_.*
+nouveau_.*
+panfrost_.*
+^v3d.*
+^vc4.*
+^vmwgfx*
+
+# GEM tests takes ~1000 hours, so skip it
+gem_.*
+
+# Hangs the machine and timeout occurs
+i915_pm_rc6_residency.*
+i915_suspend.*
+kms_scaling_modes.*
+
+# Kernel panic
+drm_fdinfo.*
diff --git a/drivers/gpu/drm/ci/xfails/i915-apl-fails.txt b/drivers/gpu/drm/ci/xfails/i915-apl-fails.txt
index 2e3b7c5dac3c..e612281149aa 100644
--- a/drivers/gpu/drm/ci/xfails/i915-apl-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/i915-apl-fails.txt
@@ -1,13 +1,7 @@
-kms_3d,Timeout
-kms_bw@linear-tiling-2-displays-1920x1080p,Fail
-kms_bw@linear-tiling-2-displays-2560x1440p,Fail
-kms_bw@linear-tiling-2-displays-3840x2160p,Fail
-kms_bw@linear-tiling-3-displays-1920x1080p,Fail
-kms_bw@linear-tiling-3-displays-2560x1440p,Fail
-kms_bw@linear-tiling-3-displays-3840x2160p,Fail
-kms_bw@linear-tiling-4-displays-1920x1080p,Fail
-kms_bw@linear-tiling-4-displays-2560x1440p,Fail
-kms_bw@linear-tiling-4-displays-3840x2160p,Fail
+i915_module_load@load,Fail
+i915_module_load@reload,Fail
+i915_module_load@reload-no-display,Fail
+i915_module_load@resize-bar,Fail
kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-downscaling,Fail
kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-upscaling,Fail
kms_flip_scaled_crc@flip-32bpp-xtile-to-64bpp-xtile-downscaling,Fail
@@ -30,18 +24,30 @@ kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-downscaling,Fail
kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-upscaling,Fail
kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilegen12rcccs-upscaling,Fail
kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-downscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-upscaling,Fail
+kms_lease@lease-uevent,Fail
kms_plane_alpha_blend@alpha-basic,Fail
kms_plane_alpha_blend@alpha-opaque-fb,Fail
kms_plane_alpha_blend@alpha-transparent-fb,Fail
kms_plane_alpha_blend@constant-alpha-max,Fail
-kms_plane_alpha_blend@pipe-A-alpha-opaque-fb,Fail
-kms_plane_alpha_blend@pipe-A-alpha-transparent-fb,Fail
-kms_plane_alpha_blend@pipe-A-constant-alpha-max,Fail
-kms_plane_alpha_blend@pipe-B-alpha-opaque-fb,Fail
-kms_plane_alpha_blend@pipe-B-alpha-transparent-fb,Fail
-kms_plane_alpha_blend@pipe-B-constant-alpha-max,Fail
-kms_plane_alpha_blend@pipe-C-alpha-opaque-fb,Fail
-kms_plane_alpha_blend@pipe-C-alpha-transparent-fb,Fail
-kms_plane_alpha_blend@pipe-C-constant-alpha-max,Fail
+kms_pm_backlight@basic-brightness,Fail
+kms_pm_backlight@fade,Fail
+kms_pm_backlight@fade-with-dpms,Fail
+kms_pm_rpm@legacy-planes,Timeout
+kms_pm_rpm@legacy-planes-dpms,Timeout
+kms_pm_rpm@modeset-stress-extra-wait,Timeout
+kms_pm_rpm@universal-planes,Timeout
+kms_pm_rpm@universal-planes-dpms,Timeout
kms_sysfs_edid_timing,Fail
+perf@i915-ref-count,Fail
+perf@non-zero-reason,Timeout
+perf_pmu@module-unload,Fail
+perf_pmu@rc6,Crash
+sysfs_heartbeat_interval@long,Timeout
+sysfs_heartbeat_interval@off,Timeout
+sysfs_preempt_timeout@off,Timeout
+sysfs_timeslice_duration@off,Timeout
+xe_module_load@force-load,Fail
+xe_module_load@load,Fail
+xe_module_load@many-reload,Fail
+xe_module_load@reload,Fail
+xe_module_load@reload-no-display,Fail
diff --git a/drivers/gpu/drm/ci/xfails/i915-apl-flakes.txt b/drivers/gpu/drm/ci/xfails/i915-apl-flakes.txt
new file mode 100644
index 000000000000..cb010c153a6a
--- /dev/null
+++ b/drivers/gpu/drm/ci/xfails/i915-apl-flakes.txt
@@ -0,0 +1,6 @@
+# Board Name: asus-C523NA-A20057-coral
+# Bug Report: https://lore.kernel.org/intel-gfx/af4ca4df-a3ef-4943-bdbf-4c3af2c333af@collabora.com/T/#u
+# IGT Version: 1.28-g0df7b9b97
+# Linux Version: 6.9.0-rc7
+# Failure Rate: 50
+kms_fb_coherency@memset-crc
diff --git a/drivers/gpu/drm/ci/xfails/i915-apl-skips.txt b/drivers/gpu/drm/ci/xfails/i915-apl-skips.txt
index 3430b215c06e..ab588e7a447c 100644
--- a/drivers/gpu/drm/ci/xfails/i915-apl-skips.txt
+++ b/drivers/gpu/drm/ci/xfails/i915-apl-skips.txt
@@ -3,4 +3,28 @@
# This is generating kernel oops with divide error
kms_plane_scaling@invalid-parameters
# This is cascading issues
-kms_3d \ No newline at end of file
+kms_3d
+
+# Skip driver specific tests
+^amdgpu.*
+msm_.*
+nouveau_.*
+panfrost_.*
+^v3d.*
+^vc4.*
+^vmwgfx*
+
+# GEM tests takes ~1000 hours, so skip it
+gem_.*
+
+# Hangs the machine and timeout occurs
+i915_pm_rc6_residency.*
+i915_suspend.*
+i915_pm_rpm.*
+device_reset.*
+api_intel_allocator.*
+kms_frontbuffer_tracking.*
+kms_ccs.*
+
+# Kernel panic
+drm_fdinfo.*
diff --git a/drivers/gpu/drm/ci/xfails/i915-cml-fails.txt b/drivers/gpu/drm/ci/xfails/i915-cml-fails.txt
index 240ef8467c26..26cd62bbf30a 100644
--- a/drivers/gpu/drm/ci/xfails/i915-cml-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/i915-cml-fails.txt
@@ -1,3 +1,19 @@
+core_setmaster@master-drop-set-user,Fail
+core_setmaster_vs_auth,Fail
+i915_module_load@load,Fail
+i915_module_load@reload,Fail
+i915_module_load@reload-no-display,Fail
+i915_module_load@resize-bar,Fail
+i915_pipe_stress@stress-xrgb8888-untiled,Fail
+i915_pipe_stress@stress-xrgb8888-ytiled,Fail
+i915_pm_rpm@gem-execbuf-stress,Timeout
+i915_pm_rpm@module-reload,Fail
+i915_pm_rpm@system-suspend-execbuf,Timeout
+kms_async_flips@invalid-async-flip,Timeout
+kms_atomic_transition@modeset-transition-fencing,Timeout
+kms_ccs@crc-primary-rotation-180-yf-tiled-ccs,Timeout
+kms_fb_coherency@memset-crc,Crash
+kms_flip@flip-vs-dpms-off-vs-modeset,Timeout
kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-downscaling,Fail
kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-upscaling,Fail
kms_flip_scaled_crc@flip-32bpp-xtile-to-64bpp-xtile-downscaling,Fail
@@ -20,11 +36,33 @@ kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-downscaling,Fail
kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-upscaling,Fail
kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilegen12rcccs-upscaling,Fail
kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-downscaling,Fail
+kms_lease@lease-uevent,Fail
kms_plane_alpha_blend@alpha-basic,Fail
kms_plane_alpha_blend@alpha-opaque-fb,Fail
kms_plane_alpha_blend@alpha-transparent-fb,Fail
kms_plane_alpha_blend@constant-alpha-max,Fail
kms_plane_alpha_blend@constant-alpha-min,Fail
+kms_plane_scaling@plane-scaler-with-clipping-clamping-rotation,Timeout
+kms_pm_rpm@modeset-stress-extra-wait,Timeout
+kms_pm_rpm@universal-planes,Timeout
+kms_pm_rpm@universal-planes-dpms,Timeout
+kms_psr2_sf@fbc-plane-move-sf-dmg-area,Timeout
+kms_psr2_sf@overlay-plane-update-continuous-sf,Fail
+kms_psr2_sf@overlay-plane-update-sf-dmg-area,Fail
+kms_psr2_sf@primary-plane-update-sf-dmg-area,Fail
+kms_psr2_sf@primary-plane-update-sf-dmg-area-big-fb,Fail
kms_psr2_su@page_flip-NV12,Fail
kms_psr2_su@page_flip-P010,Fail
+kms_psr@psr-sprite-render,Timeout
kms_setmode@basic,Fail
+perf@i915-ref-count,Fail
+perf_pmu@module-unload,Fail
+perf_pmu@rc6,Crash
+perf_pmu@rc6-suspend,Crash
+sysfs_heartbeat_interval@long,Timeout
+sysfs_heartbeat_interval@off,Timeout
+sysfs_preempt_timeout@off,Timeout
+sysfs_timeslice_duration@off,Timeout
+xe_module_load@force-load,Fail
+xe_module_load@load,Fail
+xe_module_load@many-reload,Fail
diff --git a/drivers/gpu/drm/ci/xfails/i915-cml-flakes.txt b/drivers/gpu/drm/ci/xfails/i915-cml-flakes.txt
new file mode 100644
index 000000000000..bb560ff1e2cd
--- /dev/null
+++ b/drivers/gpu/drm/ci/xfails/i915-cml-flakes.txt
@@ -0,0 +1,6 @@
+# Board Name: asus-C436FA-Flip-hatch
+# Bug Report: https://lore.kernel.org/intel-gfx/af4ca4df-a3ef-4943-bdbf-4c3af2c333af@collabora.com/T/#u
+# IGT Version: 1.28-g0df7b9b97
+# Linux Version: 6.9.0-rc7
+# Failure Rate: 50
+kms_plane_alpha_blend@constant-alpha-min
diff --git a/drivers/gpu/drm/ci/xfails/i915-cml-skips.txt b/drivers/gpu/drm/ci/xfails/i915-cml-skips.txt
index 6d3d7ddc377f..93b7736fffbb 100644
--- a/drivers/gpu/drm/ci/xfails/i915-cml-skips.txt
+++ b/drivers/gpu/drm/ci/xfails/i915-cml-skips.txt
@@ -1,2 +1,25 @@
# This is generating kernel oops with divide error
kms_plane_scaling@invalid-parameters
+
+# Skip driver specific tests
+^amdgpu.*
+msm_.*
+nouveau_.*
+panfrost_.*
+^v3d.*
+^vc4.*
+^vmwgfx*
+
+# GEM tests takes ~1000 hours, so skip it
+gem_.*
+
+# Hangs the machine and timeout occurs
+i915_pm_rc6_residency.*
+i915_suspend.*
+xe_module_load.*
+api_intel_allocator.*
+kms_cursor_legacy.*
+
+# Kernel panic
+drm_fdinfo.*
+kms_frontbuffer_tracking.*
diff --git a/drivers/gpu/drm/ci/xfails/i915-glk-fails.txt b/drivers/gpu/drm/ci/xfails/i915-glk-fails.txt
index 4596055d7e5e..fca15b487929 100644
--- a/drivers/gpu/drm/ci/xfails/i915-glk-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/i915-glk-fails.txt
@@ -1,5 +1,20 @@
-kms_fbcon_fbt@fbc,Fail
-kms_flip@blocking-wf_vblank,Fail
+core_setmaster@master-drop-set-user,Fail
+i915_module_load@load,Fail
+i915_module_load@reload,Fail
+i915_module_load@reload-no-display,Fail
+i915_module_load@resize-bar,Fail
+kms_async_flips@invalid-async-flip,Timeout
+kms_atomic_transition@modeset-transition-fencing,Timeout
+kms_big_fb@linear-16bpp-rotate-0,Fail
+kms_big_fb@linear-16bpp-rotate-180,Fail
+kms_big_fb@linear-32bpp-rotate-0,Fail
+kms_big_fb@linear-32bpp-rotate-180,Fail
+kms_big_fb@linear-8bpp-rotate-0,Fail
+kms_big_fb@linear-8bpp-rotate-180,Fail
+kms_big_fb@linear-max-hw-stride-32bpp-rotate-0,Fail
+kms_dirtyfb@default-dirtyfb-ioctl,Fail
+kms_draw_crc@draw-method-render,Fail
+kms_flip@flip-vs-dpms-off-vs-modeset,Timeout
kms_flip@wf_vblank-ts-check,Fail
kms_flip@wf_vblank-ts-check-interruptible,Fail
kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-downscaling,Fail
@@ -11,7 +26,6 @@ kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-upscaling,Fail
kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-downscaling,Fail
kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-upscaling,Fail
kms_flip_scaled_crc@flip-64bpp-linear-to-16bpp-linear-downscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-linear-to-16bpp-linear-upscaling,Fail
kms_flip_scaled_crc@flip-64bpp-linear-to-32bpp-linear-downscaling,Fail
kms_flip_scaled_crc@flip-64bpp-linear-to-32bpp-linear-upscaling,Fail
kms_flip_scaled_crc@flip-64bpp-xtile-to-16bpp-xtile-downscaling,Fail
@@ -26,11 +40,24 @@ kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilegen12rcccs-upscaling,Fail
kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-downscaling,Fail
kms_frontbuffer_tracking@fbc-tiling-linear,Fail
kms_frontbuffer_tracking@fbcdrrs-tiling-linear,Fail
-kms_plane_alpha_blend@alpha-basic,Fail
+kms_lease@lease-uevent,Fail
kms_plane_alpha_blend@alpha-opaque-fb,Fail
-kms_plane_alpha_blend@alpha-transparent-fb,Fail
-kms_plane_alpha_blend@constant-alpha-max,Fail
+kms_plane_scaling@plane-scaler-with-clipping-clamping-rotation,Timeout
+kms_pm_rpm@legacy-planes,Timeout
+kms_pm_rpm@legacy-planes-dpms,Timeout
+kms_pm_rpm@modeset-stress-extra-wait,Timeout
+kms_pm_rpm@universal-planes,Timeout
+kms_pm_rpm@universal-planes-dpms,Timeout
kms_rotation_crc@multiplane-rotation,Fail
kms_rotation_crc@multiplane-rotation-cropping-bottom,Fail
kms_rotation_crc@multiplane-rotation-cropping-top,Fail
-kms_setmode@basic,Fail
+perf@non-zero-reason,Timeout
+sysfs_heartbeat_interval@long,Timeout
+sysfs_heartbeat_interval@off,Timeout
+sysfs_preempt_timeout@off,Timeout
+sysfs_timeslice_duration@off,Timeout
+xe_module_load@force-load,Fail
+xe_module_load@load,Fail
+xe_module_load@many-reload,Fail
+xe_module_load@reload,Fail
+xe_module_load@reload-no-display,Fail
diff --git a/drivers/gpu/drm/ci/xfails/i915-glk-flakes.txt b/drivers/gpu/drm/ci/xfails/i915-glk-flakes.txt
new file mode 100644
index 000000000000..58fc424f8a42
--- /dev/null
+++ b/drivers/gpu/drm/ci/xfails/i915-glk-flakes.txt
@@ -0,0 +1,7 @@
+# Board Name: hp-x360-12b-ca0010nr-n4020-octopus
+# Bug Report: https://lore.kernel.org/intel-gfx/af4ca4df-a3ef-4943-bdbf-4c3af2c333af@collabora.com/T/#u
+# IGT Version: 1.28-g0df7b9b97
+# Linux Version: 6.9.0-rc7
+# Failure Rate: 50
+core_hotunplug@unplug-rescan
+kms_fb_coherency@memset-crc
diff --git a/drivers/gpu/drm/ci/xfails/i915-glk-skips.txt b/drivers/gpu/drm/ci/xfails/i915-glk-skips.txt
index 4c7d00ce14bc..b3226b2d9ba1 100644
--- a/drivers/gpu/drm/ci/xfails/i915-glk-skips.txt
+++ b/drivers/gpu/drm/ci/xfails/i915-glk-skips.txt
@@ -2,4 +2,28 @@
.*suspend.*
# This is generating kernel oops with divide error
-kms_plane_scaling@invalid-parameters \ No newline at end of file
+kms_plane_scaling@invalid-parameters
+
+# Skip driver specific tests
+^amdgpu.*
+msm_.*
+nouveau_.*
+panfrost_.*
+^v3d.*
+^vc4.*
+^vmwgfx*
+
+# GEM tests takes ~1000 hours, so skip it
+gem_.*
+
+# Hangs the machine and timeout occurs
+i915_pm_rc6_residency.*
+i915_suspend.*
+i915_pm_rpm.*
+kms_ccs.*
+kms_plane_multiple.*
+perf.*
+
+# Kernel panic
+drm_fdinfo.*
+kms_plane_alpha_blend.*
diff --git a/drivers/gpu/drm/ci/xfails/i915-kbl-fails.txt b/drivers/gpu/drm/ci/xfails/i915-kbl-fails.txt
index dab202716909..d4fba4f55ec1 100644
--- a/drivers/gpu/drm/ci/xfails/i915-kbl-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/i915-kbl-fails.txt
@@ -1,32 +1,28 @@
-kms_bw@linear-tiling-2-displays-2560x1440p,Fail
-kms_bw@linear-tiling-4-displays-2560x1440p,Fail
-kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-downscaling,Fail
-kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-upscaling,Fail
+i915_module_load@load,Fail
+i915_module_load@reload,Fail
+i915_module_load@reload-no-display,Fail
+i915_module_load@resize-bar,Fail
+i915_pm_rpm@gem-execbuf-stress,Timeout
kms_flip_scaled_crc@flip-32bpp-xtile-to-64bpp-xtile-downscaling,Fail
-kms_flip_scaled_crc@flip-32bpp-xtile-to-64bpp-xtile-upscaling,Fail
-kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-downscaling,Fail
kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-upscaling,Fail
-kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-downscaling,Fail
kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-upscaling,Fail
kms_flip_scaled_crc@flip-64bpp-linear-to-16bpp-linear-downscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-linear-to-16bpp-linear-upscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-linear-to-32bpp-linear-downscaling,Fail
kms_flip_scaled_crc@flip-64bpp-linear-to-32bpp-linear-upscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-xtile-to-16bpp-xtile-downscaling,Fail
kms_flip_scaled_crc@flip-64bpp-xtile-to-16bpp-xtile-upscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-xtile-to-32bpp-xtile-downscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-xtile-to-32bpp-xtile-upscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-downscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-upscaling,Fail
kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-downscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-upscaling,Fail
kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilegen12rcccs-upscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-downscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-upscaling,Fail
-kms_plane_alpha_blend@alpha-basic,Fail
-kms_plane_alpha_blend@alpha-opaque-fb,Fail
+kms_lease@lease-uevent,Fail
kms_plane_alpha_blend@alpha-transparent-fb,Fail
-kms_plane_alpha_blend@constant-alpha-max,Fail
-kms_plane_alpha_blend@pipe-A-constant-alpha-max,Fail
-kms_plane_alpha_blend@pipe-B-alpha-opaque-fb,Fail
-kms_plane_alpha_blend@pipe-C-constant-alpha-max,Fail
+perf@i915-ref-count,Fail
+perf_pmu@busy-accuracy-50,Fail
+perf_pmu@module-unload,Fail
+perf_pmu@rc6,Crash
+sysfs_heartbeat_interval@long,Timeout
+sysfs_heartbeat_interval@off,Timeout
+sysfs_preempt_timeout@off,Timeout
+sysfs_timeslice_duration@off,Timeout
+xe_module_load@force-load,Fail
+xe_module_load@load,Fail
+xe_module_load@many-reload,Fail
+xe_module_load@reload,Fail
+xe_module_load@reload-no-display,Fail
diff --git a/drivers/gpu/drm/ci/xfails/i915-kbl-flakes.txt b/drivers/gpu/drm/ci/xfails/i915-kbl-flakes.txt
index a12f888530dd..6cf1fed2e575 100644
--- a/drivers/gpu/drm/ci/xfails/i915-kbl-flakes.txt
+++ b/drivers/gpu/drm/ci/xfails/i915-kbl-flakes.txt
@@ -1 +1,6 @@
-kms_async_flips@crc
+# Board Name: hp-x360-14-G1-sona
+# Bug Report: https://lore.kernel.org/intel-gfx/af4ca4df-a3ef-4943-bdbf-4c3af2c333af@collabora.com/T/#u
+# IGT Version: 1.28-g0df7b9b97
+# Linux Version: 6.9.0-rc7
+# Failure Rate: 50
+prime_busy@hang
diff --git a/drivers/gpu/drm/ci/xfails/i915-kbl-skips.txt b/drivers/gpu/drm/ci/xfails/i915-kbl-skips.txt
index 4c7d00ce14bc..f0cf8a6dda25 100644
--- a/drivers/gpu/drm/ci/xfails/i915-kbl-skips.txt
+++ b/drivers/gpu/drm/ci/xfails/i915-kbl-skips.txt
@@ -2,4 +2,38 @@
.*suspend.*
# This is generating kernel oops with divide error
-kms_plane_scaling@invalid-parameters \ No newline at end of file
+kms_plane_scaling@invalid-parameters
+
+# Skip driver specific tests
+^amdgpu.*
+msm_.*
+nouveau_.*
+panfrost_.*
+^v3d.*
+^vc4.*
+^vmwgfx*
+
+# GEM tests takes ~1000 hours, so skip it
+gem_.*
+
+# Hangs the machine and timeout occurs
+i915_.*
+api_intel_bb.*
+
+# Kernel panic
+drm_fdinfo.*
+kms_.*
+prime_mmap_coherency.*
+perf.*
+drm_read.*
+api_intel_allocator.*
+sysfs_preempt_timeout.*
+dumb_buffer.*
+gen9_exec_parse.*
+debugfs_test.*
+core_hotunplug.*
+tools_test.*
+
+# GPU hang
+sysfs_timeslice_.*
+sysfs_heartbeat_.*
diff --git a/drivers/gpu/drm/ci/xfails/i915-tgl-fails.txt b/drivers/gpu/drm/ci/xfails/i915-tgl-fails.txt
index 27bfca1c6f2c..9a50e894c3e7 100644
--- a/drivers/gpu/drm/ci/xfails/i915-tgl-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/i915-tgl-fails.txt
@@ -1,36 +1,43 @@
-kms_bw@linear-tiling-2-displays-3840x2160p,Fail
-kms_bw@linear-tiling-3-displays-1920x1080p,Fail
-kms_bw@linear-tiling-3-displays-2560x1440p,Fail
-kms_bw@linear-tiling-3-displays-3840x2160p,Fail
-kms_bw@linear-tiling-4-displays-1920x1080p,Fail
-kms_bw@linear-tiling-4-displays-2560x1440p,Fail
-kms_bw@linear-tiling-4-displays-3840x2160p,Fail
-kms_bw@linear-tiling-5-displays-1920x1080p,Fail
-kms_bw@linear-tiling-5-displays-2560x1440p,Fail
-kms_bw@linear-tiling-5-displays-3840x2160p,Fail
-kms_flip@flip-vs-panning-vs-hang,Timeout
-kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-downscaling,Fail
-kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-upscaling,Fail
-kms_flip_scaled_crc@flip-32bpp-xtile-to-64bpp-xtile-downscaling,Fail
-kms_flip_scaled_crc@flip-32bpp-xtile-to-64bpp-xtile-upscaling,Fail
-kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-downscaling,Fail
-kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-upscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-linear-to-16bpp-linear-downscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-linear-to-16bpp-linear-upscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-linear-to-32bpp-linear-downscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-linear-to-32bpp-linear-upscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-xtile-to-16bpp-xtile-downscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-xtile-to-16bpp-xtile-upscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-xtile-to-32bpp-xtile-downscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-xtile-to-32bpp-xtile-upscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-downscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-upscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-downscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-upscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilegen12rcccs-upscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-downscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-upscaling,Fail
-kms_rotation_crc@bad-pixel-format,Fail
+api_intel_bb@blit-noreloc-keep-cache,Timeout
+api_intel_bb@offset-control,Timeout
+api_intel_bb@render-ccs,Timeout
+core_getclient,Timeout
+core_hotunplug@hotreplug-lateclose,Timeout
+drm_read@short-buffer-block,Timeout
+drm_read@short-buffer-nonblock,Timeout
+dumb_buffer@map-uaf,Timeout
+gen3_render_tiledx_blits,Timeout
+gen7_exec_parse@basic-allocation,Timeout
+gen7_exec_parse@batch-without-end,Timeout
+gen9_exec_parse@batch-invalid-length,Timeout
+gen9_exec_parse@bb-secure,Timeout
+i915_module_load@load,Fail
+i915_module_load@reload,Fail
+i915_module_load@reload-no-display,Fail
+i915_module_load@resize-bar,Fail
+i915_pciid,Timeout
+i915_query@engine-info,Timeout
+kms_lease@lease-uevent,Fail
kms_rotation_crc@multiplane-rotation,Fail
-kms_rotation_crc@multiplane-rotation-cropping-bottom,Fail
-kms_rotation_crc@multiplane-rotation-cropping-top,Fail
+perf@i915-ref-count,Fail
+perf_pmu@busy,Timeout
+perf_pmu@enable-race,Timeout
+perf_pmu@event-wait,Timeout
+perf_pmu@gt-awake,Timeout
+perf_pmu@module-unload,Fail
+perf_pmu@rc6,Crash
+prime_mmap@test_map_unmap,Timeout
+prime_self_import@basic-with_one_bo,Timeout
+syncobj_basic@bad-destroy,Timeout
+syncobj_eventfd@invalid-bad-pad,Timeout
+syncobj_wait@invalid-multi-wait-unsubmitted-signaled,Timeout
+syncobj_wait@invalid-signal-illegal-handle,Timeout
+syncobj_wait@invalid-single-wait-all-unsubmitted,Timeout
+syncobj_wait@multi-wait-all-submitted,Timeout
+syncobj_wait@multi-wait-for-submit-submitted-signaled,Timeout
+syncobj_wait@wait-any-complex,Timeout
+syncobj_wait@wait-delayed-signal,Timeout
+xe_module_load@force-load,Fail
+xe_module_load@load,Fail
+xe_module_load@reload,Fail
+xe_module_load@reload-no-display,Fail
diff --git a/drivers/gpu/drm/ci/xfails/i915-tgl-skips.txt b/drivers/gpu/drm/ci/xfails/i915-tgl-skips.txt
index 1d0621750b14..e600782ef96a 100644
--- a/drivers/gpu/drm/ci/xfails/i915-tgl-skips.txt
+++ b/drivers/gpu/drm/ci/xfails/i915-tgl-skips.txt
@@ -8,4 +8,30 @@ gem_eio.*
kms_flip@absolute-wf_vblank@a-edp1
# This is generating kernel oops with divide error
-kms_plane_scaling@invalid-parameters \ No newline at end of file
+kms_plane_scaling@invalid-parameters
+
+# Skip driver specific tests
+^amdgpu.*
+msm_.*
+nouveau_.*
+panfrost_.*
+^v3d.*
+^vc4.*
+^vmwgfx*
+
+# GEM tests takes ~1000 hours, so skip it
+gem_.*
+
+# Kernel panic
+drm_fdinfo.*
+
+# Hangs the machine and timeout occurs
+i915_pm_rc6_residency.*
+i915_suspend.*
+sysfs_heartbeat_interval.*
+syncobj_timeline.*
+sysfs_timeslice_duration.*
+syncobj_wait.*
+
+# Kernel panic and test hangs with multiple kms tests
+kms_.*
diff --git a/drivers/gpu/drm/ci/xfails/i915-whl-fails.txt b/drivers/gpu/drm/ci/xfails/i915-whl-fails.txt
index 967327ddc1ac..7582d313dd9b 100644
--- a/drivers/gpu/drm/ci/xfails/i915-whl-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/i915-whl-fails.txt
@@ -1,14 +1,25 @@
-kms_bw@linear-tiling-2-displays-1920x1080p,Fail
-kms_bw@linear-tiling-2-displays-2560x1440p,Fail
-kms_bw@linear-tiling-2-displays-3840x2160p,Fail
-kms_bw@linear-tiling-3-displays-1920x1080p,Fail
-kms_bw@linear-tiling-3-displays-2560x1440p,Fail
-kms_bw@linear-tiling-3-displays-3840x2160p,Fail
-kms_bw@linear-tiling-4-displays-1920x1080p,Fail
-kms_bw@linear-tiling-4-displays-2560x1440p,Fail
-kms_bw@linear-tiling-4-displays-3840x2160p,Fail
-kms_fbcon_fbt@fbc,Fail
-kms_fbcon_fbt@fbc-suspend,Fail
+core_setmaster@master-drop-set-user,Fail
+core_setmaster_vs_auth,Fail
+i915_module_load@load,Fail
+i915_module_load@reload,Fail
+i915_module_load@reload-no-display,Fail
+i915_module_load@resize-bar,Fail
+i915_pm_rpm@gem-execbuf-stress,Timeout
+i915_pm_rpm@module-reload,Fail
+i915_pm_rpm@system-suspend-execbuf,Timeout
+kms_async_flips@invalid-async-flip,Timeout
+kms_atomic_transition@modeset-transition-fencing,Timeout
+kms_big_fb@linear-16bpp-rotate-0,Fail
+kms_big_fb@linear-16bpp-rotate-180,Fail
+kms_big_fb@linear-32bpp-rotate-0,Fail
+kms_big_fb@linear-32bpp-rotate-180,Fail
+kms_big_fb@linear-8bpp-rotate-0,Fail
+kms_big_fb@linear-8bpp-rotate-180,Fail
+kms_big_fb@linear-max-hw-stride-32bpp-rotate-0,Fail
+kms_ccs@crc-primary-rotation-180-yf-tiled-ccs,Timeout
+kms_dirtyfb@default-dirtyfb-ioctl,Fail
+kms_draw_crc@draw-method-render,Fail
+kms_fb_coherency@memset-crc,Crash
kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-downscaling,Fail
kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-upscaling,Fail
kms_flip_scaled_crc@flip-32bpp-xtile-to-64bpp-xtile-downscaling,Fail
@@ -18,8 +29,6 @@ kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-upscaling,Fail
kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-downscaling,Fail
kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-upscaling,Fail
kms_flip_scaled_crc@flip-64bpp-linear-to-16bpp-linear-downscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-linear-to-16bpp-linear-upscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-linear-to-32bpp-linear-downscaling,Fail
kms_flip_scaled_crc@flip-64bpp-linear-to-32bpp-linear-upscaling,Fail
kms_flip_scaled_crc@flip-64bpp-xtile-to-16bpp-xtile-downscaling,Fail
kms_flip_scaled_crc@flip-64bpp-xtile-to-16bpp-xtile-upscaling,Fail
@@ -31,18 +40,26 @@ kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-downscaling,Fail
kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-upscaling,Fail
kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilegen12rcccs-upscaling,Fail
kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-downscaling,Fail
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-upscaling,Fail
kms_frontbuffer_tracking@fbc-tiling-linear,Fail
+kms_lease@lease-uevent,Fail
kms_plane_alpha_blend@alpha-basic,Fail
kms_plane_alpha_blend@alpha-opaque-fb,Fail
kms_plane_alpha_blend@alpha-transparent-fb,Fail
kms_plane_alpha_blend@constant-alpha-max,Fail
-kms_plane_alpha_blend@pipe-A-alpha-opaque-fb,Fail
-kms_plane_alpha_blend@pipe-A-alpha-transparent-fb,Fail
-kms_plane_alpha_blend@pipe-A-constant-alpha-max,Fail
-kms_plane_alpha_blend@pipe-B-alpha-opaque-fb,Fail
-kms_plane_alpha_blend@pipe-B-alpha-transparent-fb,Fail
-kms_plane_alpha_blend@pipe-B-constant-alpha-max,Fail
-kms_plane_alpha_blend@pipe-C-alpha-opaque-fb,Fail
-kms_plane_alpha_blend@pipe-C-alpha-transparent-fb,Fail
-kms_plane_alpha_blend@pipe-C-constant-alpha-max,Fail
+kms_plane_scaling@plane-scaler-with-clipping-clamping-rotation,Timeout
+kms_pm_rpm@modeset-stress-extra-wait,Timeout
+kms_pm_rpm@universal-planes,Timeout
+kms_pm_rpm@universal-planes-dpms,Timeout
+perf@i915-ref-count,Fail
+perf_pmu@module-unload,Fail
+perf_pmu@rc6,Crash
+perf_pmu@rc6-suspend,Crash
+sysfs_heartbeat_interval@long,Timeout
+sysfs_heartbeat_interval@off,Timeout
+sysfs_preempt_timeout@off,Timeout
+sysfs_timeslice_duration@off,Timeout
+xe_module_load@force-load,Fail
+xe_module_load@load,Fail
+xe_module_load@many-reload,Fail
+xe_module_load@reload,Fail
+xe_module_load@reload-no-display,Fail
diff --git a/drivers/gpu/drm/ci/xfails/i915-whl-flakes.txt b/drivers/gpu/drm/ci/xfails/i915-whl-flakes.txt
new file mode 100644
index 000000000000..1167a58c7dd1
--- /dev/null
+++ b/drivers/gpu/drm/ci/xfails/i915-whl-flakes.txt
@@ -0,0 +1,6 @@
+# Board Name: dell-latitude-5400-8665U-sarien
+# Bug Report: https://lore.kernel.org/intel-gfx/af4ca4df-a3ef-4943-bdbf-4c3af2c333af@collabora.com/T/#u
+# IGT Version: 1.28-g0df7b9b97
+# Linux Version: 6.9.0-rc7
+# Failure Rate: 50
+kms_pm_rpm@modeset-lpsp-stress
diff --git a/drivers/gpu/drm/ci/xfails/i915-whl-skips.txt b/drivers/gpu/drm/ci/xfails/i915-whl-skips.txt
index f3be0888a214..20bd91525f45 100644
--- a/drivers/gpu/drm/ci/xfails/i915-whl-skips.txt
+++ b/drivers/gpu/drm/ci/xfails/i915-whl-skips.txt
@@ -1,2 +1,22 @@
# This is generating kernel oops with divide error
-kms_plane_scaling@invalid-parameters \ No newline at end of file
+kms_plane_scaling@invalid-parameters
+
+# Skip driver specific tests
+^amdgpu.*
+msm_.*
+nouveau_.*
+panfrost_.*
+^v3d.*
+^vc4.*
+^vmwgfx*
+
+# GEM tests takes ~1000 hours, so skip it
+gem_.*
+
+# Hangs the machine and timeout occurs
+i915_pm_rc6_residency.*
+i915_suspend.*
+kms_flip.*
+
+# Kernel panic
+drm_fdinfo.*
diff --git a/drivers/gpu/drm/ci/xfails/mediatek-mt8173-fails.txt b/drivers/gpu/drm/ci/xfails/mediatek-mt8173-fails.txt
index ef0cb7c3698c..cc5e9c1c2d57 100644
--- a/drivers/gpu/drm/ci/xfails/mediatek-mt8173-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/mediatek-mt8173-fails.txt
@@ -1,36 +1,30 @@
+device_reset@cold-reset-bound,Fail
+device_reset@reset-bound,Fail
+device_reset@unbind-cold-reset-rebind,Fail
+device_reset@unbind-reset-rebind,Fail
+dumb_buffer@invalid-bpp,Fail
+fbdev@eof,Fail
+fbdev@read,Fail
+fbdev@unaligned-write,Fail
kms_3d,Fail
kms_bw@linear-tiling-1-displays-1920x1080p,Fail
+kms_bw@linear-tiling-1-displays-2160x1440p,Fail
kms_bw@linear-tiling-1-displays-2560x1440p,Fail
kms_bw@linear-tiling-1-displays-3840x2160p,Fail
kms_bw@linear-tiling-2-displays-1920x1080p,Fail
+kms_bw@linear-tiling-2-displays-2160x1440p,Fail
kms_bw@linear-tiling-2-displays-2560x1440p,Fail
kms_bw@linear-tiling-2-displays-3840x2160p,Fail
-kms_bw@linear-tiling-3-displays-1920x1080p,Fail
-kms_bw@linear-tiling-3-displays-2560x1440p,Fail
-kms_bw@linear-tiling-3-displays-3840x2160p,Fail
kms_color@invalid-gamma-lut-sizes,Fail
-kms_color@pipe-A-invalid-gamma-lut-sizes,Fail
-kms_color@pipe-B-invalid-gamma-lut-sizes,Fail
kms_cursor_legacy@cursor-vs-flip-atomic,Fail
kms_cursor_legacy@cursor-vs-flip-legacy,Fail
kms_flip@flip-vs-modeset-vs-hang,Fail
kms_flip@flip-vs-panning-vs-hang,Fail
kms_flip@flip-vs-suspend,Fail
kms_flip@flip-vs-suspend-interruptible,Fail
-kms_force_connector_basic@force-edid,Fail
-kms_force_connector_basic@force-load-detect,Fail
-kms_force_connector_basic@prune-stale-modes,Fail
-kms_hdmi_inject@inject-4k,Fail
-kms_plane_scaling@planes-upscale-20x20,Fail
-kms_plane_scaling@planes-upscale-20x20-downscale-factor-0-25,Fail
-kms_plane_scaling@planes-upscale-20x20-downscale-factor-0-5,Fail
-kms_plane_scaling@planes-upscale-20x20-downscale-factor-0-75,Fail
-kms_plane_scaling@upscale-with-modifier-20x20,Fail
-kms_plane_scaling@upscale-with-pixel-format-20x20,Fail
-kms_plane_scaling@upscale-with-rotation-20x20,Fail
+kms_lease@lease-uevent,Fail
kms_properties@get_properties-sanity-atomic,Fail
kms_properties@plane-properties-atomic,Fail
kms_properties@plane-properties-legacy,Fail
kms_rmfb@close-fd,Fail
-kms_selftest@drm_format,Timeout
-kms_selftest@drm_format_helper,Timeout
+tools_test@tools_test,Fail
diff --git a/drivers/gpu/drm/ci/xfails/mediatek-mt8173-flakes.txt b/drivers/gpu/drm/ci/xfails/mediatek-mt8173-flakes.txt
new file mode 100644
index 000000000000..395ac0463404
--- /dev/null
+++ b/drivers/gpu/drm/ci/xfails/mediatek-mt8173-flakes.txt
@@ -0,0 +1,11 @@
+# Board Name: mt8173-elm-hana
+# Bug Report: https://lore.kernel.org/linux-mediatek/0b2a1899-15dd-42fa-8f63-ea0ca28dbb17@collabora.com/T/#u
+# IGT Version: 1.28-g0df7b9b97
+# Linux Version: 6.9.0-rc7
+# Failure Rate: 50
+core_setmaster_vs_auth
+dumb_buffer@create-clear
+fbdev@unaligned-write
+fbdev@write
+kms_cursor_legacy@cursor-vs-flip-atomic-transitions
+kms_prop_blob@invalid-set-prop
diff --git a/drivers/gpu/drm/ci/xfails/mediatek-mt8173-skips.txt b/drivers/gpu/drm/ci/xfails/mediatek-mt8173-skips.txt
new file mode 100644
index 000000000000..0c6108392140
--- /dev/null
+++ b/drivers/gpu/drm/ci/xfails/mediatek-mt8173-skips.txt
@@ -0,0 +1,16 @@
+# Skip driver specific tests
+^amdgpu.*
+msm_.*
+nouveau_.*
+panfrost_.*
+^v3d.*
+^vc4.*
+^vmwgfx*
+
+# Skip intel specific tests
+gem_.*
+i915_.*
+
+# Currently fails and causes coverage loss for other tests
+# since core_getversion also fails.
+core_hotunplug.*
diff --git a/drivers/gpu/drm/ci/xfails/mediatek-mt8183-fails.txt b/drivers/gpu/drm/ci/xfails/mediatek-mt8183-fails.txt
index 67d690fc4037..9ef460646d76 100644
--- a/drivers/gpu/drm/ci/xfails/mediatek-mt8183-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/mediatek-mt8183-fails.txt
@@ -1,13 +1,8 @@
-kms_addfb_basic@addfb25-bad-modifier,Fail
-kms_bw@linear-tiling-1-displays-2560x1440p,Fail
-kms_bw@linear-tiling-2-displays-1920x1080p,Fail
-kms_bw@linear-tiling-2-displays-2560x1440p,Fail
-kms_bw@linear-tiling-2-displays-3840x2160p,Fail
-kms_bw@linear-tiling-3-displays-2560x1440p,Fail
-kms_bw@linear-tiling-3-displays-3840x2160p,Fail
-kms_color@pipe-A-invalid-gamma-lut-sizes,Fail
-kms_plane_cursor@overlay,Fail
-kms_plane_cursor@primary,Fail
-kms_plane_cursor@viewport,Fail
-kms_plane_scaling@upscale-with-rotation-20x20,Fail
-kms_rmfb@close-fd,Fail
+dumb_buffer@create-clear,Fail
+dumb_buffer@create-valid-dumb,Fail
+dumb_buffer@invalid-bpp,Fail
+dumb_buffer@map-invalid-size,Fail
+dumb_buffer@map-uaf,Fail
+dumb_buffer@map-valid,Fail
+panfrost_prime@gem-prime-import,Fail
+tools_test@tools_test,Fail
diff --git a/drivers/gpu/drm/ci/xfails/mediatek-mt8183-skips.txt b/drivers/gpu/drm/ci/xfails/mediatek-mt8183-skips.txt
new file mode 100644
index 000000000000..715b9a8f4997
--- /dev/null
+++ b/drivers/gpu/drm/ci/xfails/mediatek-mt8183-skips.txt
@@ -0,0 +1,18 @@
+# Skip driver specific tests
+^amdgpu.*
+msm_.*
+nouveau_.*
+^v3d.*
+^vc4.*
+^vmwgfx*
+
+# Skip intel specific tests
+gem_.*
+i915_.*
+
+# Panfrost is not a KMS driver, so skip the KMS tests
+kms_.*
+
+# Currently fails and causes coverage loss for other tests
+# since core_getversion also fails.
+core_hotunplug.*
diff --git a/drivers/gpu/drm/ci/xfails/meson-g12b-fails.txt b/drivers/gpu/drm/ci/xfails/meson-g12b-fails.txt
index 56a2ae7047b4..9ef460646d76 100644
--- a/drivers/gpu/drm/ci/xfails/meson-g12b-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/meson-g12b-fails.txt
@@ -1,16 +1,8 @@
-kms_3d,Fail
-kms_cursor_legacy@forked-bo,Fail
-kms_cursor_legacy@forked-move,Fail
-kms_cursor_legacy@single-bo,Fail
-kms_cursor_legacy@single-move,Fail
-kms_cursor_legacy@torture-bo,Fail
-kms_cursor_legacy@torture-move,Fail
-kms_force_connector_basic@force-edid,Fail
-kms_hdmi_inject@inject-4k,Fail
-kms_plane_cursor@overlay,Fail
-kms_plane_cursor@primary,Fail
-kms_plane_cursor@viewport,Fail
-kms_properties@connector-properties-atomic,Fail
-kms_properties@connector-properties-legacy,Fail
-kms_properties@get_properties-sanity-atomic,Fail
-kms_properties@get_properties-sanity-non-atomic,Fail
+dumb_buffer@create-clear,Fail
+dumb_buffer@create-valid-dumb,Fail
+dumb_buffer@invalid-bpp,Fail
+dumb_buffer@map-invalid-size,Fail
+dumb_buffer@map-uaf,Fail
+dumb_buffer@map-valid,Fail
+panfrost_prime@gem-prime-import,Fail
+tools_test@tools_test,Fail
diff --git a/drivers/gpu/drm/ci/xfails/meson-g12b-skips.txt b/drivers/gpu/drm/ci/xfails/meson-g12b-skips.txt
new file mode 100644
index 000000000000..715b9a8f4997
--- /dev/null
+++ b/drivers/gpu/drm/ci/xfails/meson-g12b-skips.txt
@@ -0,0 +1,18 @@
+# Skip driver specific tests
+^amdgpu.*
+msm_.*
+nouveau_.*
+^v3d.*
+^vc4.*
+^vmwgfx*
+
+# Skip intel specific tests
+gem_.*
+i915_.*
+
+# Panfrost is not a KMS driver, so skip the KMS tests
+kms_.*
+
+# Currently fails and causes coverage loss for other tests
+# since core_getversion also fails.
+core_hotunplug.*
diff --git a/drivers/gpu/drm/ci/xfails/msm-apq8016-fails.txt b/drivers/gpu/drm/ci/xfails/msm-apq8016-fails.txt
index 44a5c62dedad..6e7fd1ccd1e3 100644
--- a/drivers/gpu/drm/ci/xfails/msm-apq8016-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/msm-apq8016-fails.txt
@@ -1,19 +1,15 @@
+device_reset@cold-reset-bound,Fail
+device_reset@reset-bound,Fail
+device_reset@unbind-cold-reset-rebind,Fail
+device_reset@unbind-reset-rebind,Fail
+dumb_buffer@invalid-bpp,Fail
kms_3d,Fail
-kms_addfb_basic@addfb25-bad-modifier,Fail
-kms_cursor_legacy@all-pipes-forked-bo,Fail
-kms_cursor_legacy@all-pipes-forked-move,Fail
-kms_cursor_legacy@all-pipes-single-bo,Fail
-kms_cursor_legacy@all-pipes-single-move,Fail
-kms_cursor_legacy@all-pipes-torture-bo,Fail
-kms_cursor_legacy@all-pipes-torture-move,Fail
-kms_cursor_legacy@pipe-A-forked-bo,Fail
-kms_cursor_legacy@pipe-A-forked-move,Fail
-kms_cursor_legacy@pipe-A-single-bo,Fail
-kms_cursor_legacy@pipe-A-single-move,Fail
-kms_cursor_legacy@pipe-A-torture-bo,Fail
-kms_cursor_legacy@pipe-A-torture-move,Fail
+kms_cursor_legacy@forked-move,Fail
+kms_cursor_legacy@single-bo,Fail
+kms_cursor_legacy@torture-bo,Fail
+kms_cursor_legacy@torture-move,Fail
kms_force_connector_basic@force-edid,Fail
kms_hdmi_inject@inject-4k,Fail
-kms_selftest@drm_format,Timeout
-kms_selftest@drm_format_helper,Timeout
+kms_lease@lease-uevent,Fail
msm_mapping@ring,Fail
+tools_test@tools_test,Fail
diff --git a/drivers/gpu/drm/ci/xfails/msm-apq8016-skips.txt b/drivers/gpu/drm/ci/xfails/msm-apq8016-skips.txt
new file mode 100644
index 000000000000..ff12202abb6e
--- /dev/null
+++ b/drivers/gpu/drm/ci/xfails/msm-apq8016-skips.txt
@@ -0,0 +1,15 @@
+# Skip driver specific tests
+^amdgpu.*
+nouveau_.*
+panfrost_.*
+^v3d.*
+^vc4.*
+^vmwgfx*
+
+# Skip intel specific tests
+gem_.*
+i915_.*
+
+# Currently fails and causes coverage loss for other tests
+# since core_getversion also fails.
+core_hotunplug.*
diff --git a/drivers/gpu/drm/ci/xfails/msm-apq8096-fails.txt b/drivers/gpu/drm/ci/xfails/msm-apq8096-fails.txt
index 88a1fc0a3b0d..46ca69ce2ffe 100644
--- a/drivers/gpu/drm/ci/xfails/msm-apq8096-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/msm-apq8096-fails.txt
@@ -1,2 +1,8 @@
+device_reset@cold-reset-bound,Fail
+device_reset@reset-bound,Fail
+device_reset@unbind-cold-reset-rebind,Fail
+device_reset@unbind-reset-rebind,Fail
+dumb_buffer@invalid-bpp,Fail
kms_3d,Fail
-kms_addfb_basic@addfb25-bad-modifier,Fail
+kms_lease@lease-uevent,Fail
+tools_test@tools_test,Fail
diff --git a/drivers/gpu/drm/ci/xfails/msm-apq8096-flakes.txt b/drivers/gpu/drm/ci/xfails/msm-apq8096-flakes.txt
new file mode 100644
index 000000000000..a275584c8bbb
--- /dev/null
+++ b/drivers/gpu/drm/ci/xfails/msm-apq8096-flakes.txt
@@ -0,0 +1,6 @@
+# Board Name: apq8096-db820c
+# Bug Report: https://lore.kernel.org/linux-arm-msm/661483c8-ad82-400d-bcd8-e94986d20d7d@collabora.com/T/#u
+# IGT Version: 1.28-g0df7b9b97
+# Linux Version: 6.9.0-rc7
+# Failure Rate: 50
+dumb_buffer@create-clear
diff --git a/drivers/gpu/drm/ci/xfails/msm-apq8096-skips.txt b/drivers/gpu/drm/ci/xfails/msm-apq8096-skips.txt
index cd49c8ce2059..1c45fc6c512d 100644
--- a/drivers/gpu/drm/ci/xfails/msm-apq8096-skips.txt
+++ b/drivers/gpu/drm/ci/xfails/msm-apq8096-skips.txt
@@ -1,2 +1,26 @@
# Whole machine hangs
-kms_cursor_legacy@all-pipes-torture-move \ No newline at end of file
+kms_cursor_legacy@all-pipes-torture-move
+
+# Skip driver specific tests
+^amdgpu.*
+nouveau_.*
+panfrost_.*
+^v3d.*
+^vc4.*
+^vmwgfx*
+
+# Skip intel specific tests
+gem_.*
+i915_.*
+
+# Currently fails and causes coverage loss for other tests
+# since core_getversion also fails.
+core_hotunplug.*
+
+# gpu fault
+# [IGT] msm_mapping: executing
+# [IGT] msm_mapping: starting subtest shadow
+# *** gpu fault: ttbr0=00000001030ea000 iova=0000000001074000 dir=WRITE type=PERMISSION source=1f030000 (0,0,0,0)
+# msm_mdp 901000.display-controller: RBBM | ME master split | status=0x701000B0
+# watchdog: BUG: soft lockup - CPU#0 stuck for 26s! [kworker/u16:3:46]
+msm_mapping@shadow
diff --git a/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-kingoftown-fails.txt b/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-kingoftown-fails.txt
index f0576aa629e8..eb7a3886d397 100644
--- a/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-kingoftown-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-kingoftown-fails.txt
@@ -1,18 +1,191 @@
+device_reset@cold-reset-bound,Fail
+device_reset@reset-bound,Fail
+device_reset@unbind-cold-reset-rebind,Fail
+device_reset@unbind-reset-rebind,Fail
+dumb_buffer@invalid-bpp,Fail
+kms_atomic_transition@plane-primary-toggle-with-vblank-wait,Fail
kms_color@ctm-0-25,Fail
kms_color@ctm-0-50,Fail
kms_color@ctm-0-75,Fail
kms_color@ctm-blue-to-red,Fail
kms_color@ctm-green-to-red,Fail
+kms_color@ctm-max,Fail
kms_color@ctm-negative,Fail
kms_color@ctm-red-to-blue,Fail
kms_color@ctm-signed,Fail
+kms_content_protection@atomic,Crash
+kms_content_protection@atomic-dpms,Crash
+kms_content_protection@content-type-change,Crash
+kms_content_protection@lic-type-0,Crash
+kms_content_protection@lic-type-1,Crash
+kms_content_protection@srm,Crash
+kms_content_protection@type1,Crash
+kms_content_protection@uevent,Crash
+kms_cursor_crc@cursor-alpha-opaque,Fail
+kms_cursor_crc@cursor-alpha-transparent,Fail
+kms_cursor_crc@cursor-dpms,Fail
+kms_cursor_crc@cursor-offscreen-128x128,Fail
+kms_cursor_crc@cursor-offscreen-128x42,Fail
+kms_cursor_crc@cursor-offscreen-256x256,Fail
+kms_cursor_crc@cursor-offscreen-256x85,Fail
+kms_cursor_crc@cursor-offscreen-32x10,Fail
+kms_cursor_crc@cursor-offscreen-32x32,Fail
+kms_cursor_crc@cursor-offscreen-512x170,Fail
+kms_cursor_crc@cursor-offscreen-512x512,Fail
+kms_cursor_crc@cursor-offscreen-64x21,Fail
+kms_cursor_crc@cursor-offscreen-64x64,Fail
+kms_cursor_crc@cursor-onscreen-128x128,Fail
+kms_cursor_crc@cursor-onscreen-128x42,Fail
+kms_cursor_crc@cursor-onscreen-256x256,Fail
+kms_cursor_crc@cursor-onscreen-256x85,Fail
+kms_cursor_crc@cursor-onscreen-32x10,Fail
+kms_cursor_crc@cursor-onscreen-32x32,Fail
+kms_cursor_crc@cursor-onscreen-512x170,Fail
+kms_cursor_crc@cursor-onscreen-512x512,Fail
+kms_cursor_crc@cursor-onscreen-64x21,Fail
+kms_cursor_crc@cursor-onscreen-64x64,Fail
+kms_cursor_crc@cursor-random-128x128,Fail
+kms_cursor_crc@cursor-random-128x42,Fail
+kms_cursor_crc@cursor-random-256x256,Fail
+kms_cursor_crc@cursor-random-256x85,Fail
+kms_cursor_crc@cursor-random-32x10,Fail
+kms_cursor_crc@cursor-random-32x32,Fail
+kms_cursor_crc@cursor-random-512x170,Fail
+kms_cursor_crc@cursor-random-512x512,Fail
+kms_cursor_crc@cursor-random-64x21,Fail
+kms_cursor_crc@cursor-random-64x64,Fail
+kms_cursor_crc@cursor-rapid-movement-128x128,Fail
+kms_cursor_crc@cursor-rapid-movement-128x42,Fail
+kms_cursor_crc@cursor-rapid-movement-256x256,Fail
+kms_cursor_crc@cursor-rapid-movement-256x85,Fail
+kms_cursor_crc@cursor-rapid-movement-32x10,Fail
+kms_cursor_crc@cursor-rapid-movement-32x32,Fail
+kms_cursor_crc@cursor-rapid-movement-512x170,Fail
+kms_cursor_crc@cursor-rapid-movement-512x512,Fail
+kms_cursor_crc@cursor-rapid-movement-64x21,Fail
+kms_cursor_crc@cursor-rapid-movement-64x64,Fail
+kms_cursor_crc@cursor-size-change,Fail
+kms_cursor_crc@cursor-sliding-128x128,Fail
+kms_cursor_crc@cursor-sliding-128x42,Fail
+kms_cursor_crc@cursor-sliding-256x256,Fail
+kms_cursor_crc@cursor-sliding-256x85,Fail
+kms_cursor_crc@cursor-sliding-32x10,Fail
+kms_cursor_crc@cursor-sliding-32x32,Fail
+kms_cursor_crc@cursor-sliding-512x170,Fail
+kms_cursor_crc@cursor-sliding-512x512,Fail
+kms_cursor_crc@cursor-sliding-64x21,Fail
+kms_cursor_crc@cursor-sliding-64x64,Fail
+kms_cursor_edge_walk@128x128-left-edge,Fail
+kms_cursor_edge_walk@128x128-right-edge,Fail
+kms_cursor_edge_walk@128x128-top-bottom,Fail
+kms_cursor_edge_walk@128x128-top-edge,Fail
+kms_cursor_edge_walk@256x256-left-edge,Fail
+kms_cursor_edge_walk@256x256-right-edge,Fail
+kms_cursor_edge_walk@256x256-top-bottom,Fail
+kms_cursor_edge_walk@256x256-top-edge,Fail
+kms_cursor_edge_walk@64x64-left-edge,Fail
+kms_cursor_edge_walk@64x64-right-edge,Fail
+kms_cursor_edge_walk@64x64-top-bottom,Fail
+kms_cursor_edge_walk@64x64-top-edge,Fail
+kms_cursor_legacy@2x-cursor-vs-flip-atomic,Fail
+kms_cursor_legacy@2x-cursor-vs-flip-legacy,Fail
+kms_cursor_legacy@2x-flip-vs-cursor-atomic,Fail
+kms_cursor_legacy@2x-flip-vs-cursor-legacy,Fail
+kms_cursor_legacy@2x-long-cursor-vs-flip-atomic,Fail
+kms_cursor_legacy@2x-long-cursor-vs-flip-legacy,Fail
+kms_cursor_legacy@2x-long-flip-vs-cursor-atomic,Fail
+kms_cursor_legacy@2x-long-flip-vs-cursor-legacy,Fail
kms_cursor_legacy@cursor-vs-flip-toggle,Fail
kms_cursor_legacy@cursor-vs-flip-varying-size,Fail
+kms_display_modes@extended-mode-basic,Fail
+kms_flip@2x-flip-vs-modeset-vs-hang,Fail
+kms_flip@2x-flip-vs-panning-vs-hang,Fail
+kms_flip@absolute-wf_vblank,Fail
+kms_flip@absolute-wf_vblank-interruptible,Fail
+kms_flip@basic-flip-vs-wf_vblank,Fail
+kms_flip@basic-plain-flip,Fail
+kms_flip@blocking-absolute-wf_vblank,Fail
+kms_flip@blocking-absolute-wf_vblank-interruptible,Fail
+kms_flip@blocking-wf_vblank,Fail
+kms_flip@busy-flip,Fail
+kms_flip@dpms-off-confusion,Fail
+kms_flip@dpms-off-confusion-interruptible,Fail
+kms_flip@dpms-vs-vblank-race,Fail
+kms_flip@dpms-vs-vblank-race-interruptible,Fail
+kms_flip@flip-vs-absolute-wf_vblank,Fail
+kms_flip@flip-vs-absolute-wf_vblank-interruptible,Fail
+kms_flip@flip-vs-blocking-wf-vblank,Fail
+kms_flip@flip-vs-expired-vblank,Fail
+kms_flip@flip-vs-expired-vblank-interruptible,Fail
kms_flip@flip-vs-modeset-vs-hang,Fail
+kms_flip@flip-vs-panning,Fail
+kms_flip@flip-vs-panning-interruptible,Fail
kms_flip@flip-vs-panning-vs-hang,Fail
+kms_flip@flip-vs-rmfb,Fail
+kms_flip@flip-vs-rmfb-interruptible,Fail
+kms_flip@flip-vs-wf_vblank-interruptible,Fail
+kms_flip@modeset-vs-vblank-race,Fail
+kms_flip@modeset-vs-vblank-race-interruptible,Fail
+kms_flip@plain-flip-fb-recreate,Fail
+kms_flip@plain-flip-fb-recreate-interruptible,Fail
+kms_flip@plain-flip-interruptible,Fail
+kms_flip@plain-flip-ts-check,Fail
+kms_flip@plain-flip-ts-check-interruptible,Fail
+kms_flip@wf_vblank-ts-check,Fail
+kms_flip@wf_vblank-ts-check-interruptible,Fail
+kms_lease@cursor-implicit-plane,Fail
+kms_lease@lease-uevent,Fail
+kms_lease@page-flip-implicit-plane,Fail
+kms_lease@setcrtc-implicit-plane,Fail
+kms_lease@simple-lease,Fail
+kms_multipipe_modeset@basic-max-pipe-crc-check,Fail
kms_pipe_crc_basic@compare-crc-sanitycheck-nv12,Fail
+kms_pipe_crc_basic@compare-crc-sanitycheck-xr24,Fail
+kms_pipe_crc_basic@disable-crc-after-crtc,Fail
+kms_pipe_crc_basic@nonblocking-crc,Fail
+kms_pipe_crc_basic@nonblocking-crc-frame-sequence,Fail
+kms_pipe_crc_basic@read-crc,Fail
+kms_pipe_crc_basic@read-crc-frame-sequence,Fail
+kms_plane@pixel-format,Fail
+kms_plane@pixel-format-source-clamping,Fail
+kms_plane@plane-panning-bottom-right,Fail
+kms_plane@plane-panning-top-left,Fail
+kms_plane@plane-position-covered,Fail
+kms_plane@plane-position-hole,Fail
+kms_plane@plane-position-hole-dpms,Fail
kms_plane_alpha_blend@alpha-7efc,Fail
+kms_plane_alpha_blend@alpha-basic,Fail
+kms_plane_alpha_blend@alpha-opaque-fb,Fail
+kms_plane_alpha_blend@alpha-transparent-fb,Fail
+kms_plane_alpha_blend@constant-alpha-max,Fail
+kms_plane_alpha_blend@constant-alpha-mid,Fail
+kms_plane_alpha_blend@constant-alpha-min,Fail
kms_plane_alpha_blend@coverage-7efc,Fail
kms_plane_alpha_blend@coverage-vs-premult-vs-constant,Fail
+kms_plane_cursor@primary,Fail
+kms_plane_lowres@tiling-none,Fail
+kms_plane_multiple@tiling-none,Fail
kms_rmfb@close-fd,Fail
-kms_universal_plane@universal-plane-sanity,Fail
+kms_rotation_crc@cursor-rotation-180,Fail
+kms_rotation_crc@primary-rotation-180,Fail
+kms_sequence@get-busy,Fail
+kms_sequence@get-forked,Fail
+kms_sequence@get-forked-busy,Fail
+kms_sequence@get-idle,Fail
+kms_sequence@queue-busy,Fail
+kms_sequence@queue-idle,Fail
+kms_vblank@accuracy-idle,Fail
+kms_vblank@crtc-id,Fail
+kms_vblank@query-busy,Fail
+kms_vblank@query-forked,Fail
+kms_vblank@query-forked-busy,Fail
+kms_vblank@query-idle,Fail
+kms_vblank@ts-continuation-dpms-rpm,Fail
+kms_vblank@ts-continuation-idle,Fail
+kms_vblank@ts-continuation-modeset,Fail
+kms_vblank@ts-continuation-modeset-rpm,Fail
+kms_vblank@wait-busy,Fail
+kms_vblank@wait-forked,Fail
+kms_vblank@wait-forked-busy,Fail
+kms_vblank@wait-idle,Fail
+tools_test@tools_test,Fail
diff --git a/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-kingoftown-flakes.txt b/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-kingoftown-flakes.txt
new file mode 100644
index 000000000000..6dec63d48cfb
--- /dev/null
+++ b/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-kingoftown-flakes.txt
@@ -0,0 +1,8 @@
+# Board Name: sc7180-trogdor-kingoftown
+# Bug Report: https://lore.kernel.org/linux-arm-msm/661483c8-ad82-400d-bcd8-e94986d20d7d@collabora.com/T/#u
+# IGT Version: 1.28-g0df7b9b97
+# Linux Version: 6.9.0-rc7
+# Failure Rate: 50
+msm_mapping@shadow
+msm_shrink@copy-gpu-oom-32
+msm_shrink@copy-gpu-oom-8
diff --git a/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-kingoftown-skips.txt b/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-kingoftown-skips.txt
index 327039f70252..68c96005ba54 100644
--- a/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-kingoftown-skips.txt
+++ b/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-kingoftown-skips.txt
@@ -1,2 +1,21 @@
# Suspend to RAM seems to be broken on this machine
.*suspend.*
+
+# Skip driver specific tests
+^amdgpu.*
+nouveau_.*
+panfrost_.*
+^v3d.*
+^vc4.*
+^vmwgfx*
+
+# Skip intel specific tests
+gem_.*
+i915_.*
+
+# Currently fails and causes coverage loss for other tests
+# since core_getversion also fails.
+core_hotunplug.*
+
+# Timeout occurs
+kms_flip@2x-wf_vblank-ts-check
diff --git a/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-lazor-limozeen-fails.txt b/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-lazor-limozeen-fails.txt
index f0576aa629e8..eb7a3886d397 100644
--- a/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-lazor-limozeen-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-lazor-limozeen-fails.txt
@@ -1,18 +1,191 @@
+device_reset@cold-reset-bound,Fail
+device_reset@reset-bound,Fail
+device_reset@unbind-cold-reset-rebind,Fail
+device_reset@unbind-reset-rebind,Fail
+dumb_buffer@invalid-bpp,Fail
+kms_atomic_transition@plane-primary-toggle-with-vblank-wait,Fail
kms_color@ctm-0-25,Fail
kms_color@ctm-0-50,Fail
kms_color@ctm-0-75,Fail
kms_color@ctm-blue-to-red,Fail
kms_color@ctm-green-to-red,Fail
+kms_color@ctm-max,Fail
kms_color@ctm-negative,Fail
kms_color@ctm-red-to-blue,Fail
kms_color@ctm-signed,Fail
+kms_content_protection@atomic,Crash
+kms_content_protection@atomic-dpms,Crash
+kms_content_protection@content-type-change,Crash
+kms_content_protection@lic-type-0,Crash
+kms_content_protection@lic-type-1,Crash
+kms_content_protection@srm,Crash
+kms_content_protection@type1,Crash
+kms_content_protection@uevent,Crash
+kms_cursor_crc@cursor-alpha-opaque,Fail
+kms_cursor_crc@cursor-alpha-transparent,Fail
+kms_cursor_crc@cursor-dpms,Fail
+kms_cursor_crc@cursor-offscreen-128x128,Fail
+kms_cursor_crc@cursor-offscreen-128x42,Fail
+kms_cursor_crc@cursor-offscreen-256x256,Fail
+kms_cursor_crc@cursor-offscreen-256x85,Fail
+kms_cursor_crc@cursor-offscreen-32x10,Fail
+kms_cursor_crc@cursor-offscreen-32x32,Fail
+kms_cursor_crc@cursor-offscreen-512x170,Fail
+kms_cursor_crc@cursor-offscreen-512x512,Fail
+kms_cursor_crc@cursor-offscreen-64x21,Fail
+kms_cursor_crc@cursor-offscreen-64x64,Fail
+kms_cursor_crc@cursor-onscreen-128x128,Fail
+kms_cursor_crc@cursor-onscreen-128x42,Fail
+kms_cursor_crc@cursor-onscreen-256x256,Fail
+kms_cursor_crc@cursor-onscreen-256x85,Fail
+kms_cursor_crc@cursor-onscreen-32x10,Fail
+kms_cursor_crc@cursor-onscreen-32x32,Fail
+kms_cursor_crc@cursor-onscreen-512x170,Fail
+kms_cursor_crc@cursor-onscreen-512x512,Fail
+kms_cursor_crc@cursor-onscreen-64x21,Fail
+kms_cursor_crc@cursor-onscreen-64x64,Fail
+kms_cursor_crc@cursor-random-128x128,Fail
+kms_cursor_crc@cursor-random-128x42,Fail
+kms_cursor_crc@cursor-random-256x256,Fail
+kms_cursor_crc@cursor-random-256x85,Fail
+kms_cursor_crc@cursor-random-32x10,Fail
+kms_cursor_crc@cursor-random-32x32,Fail
+kms_cursor_crc@cursor-random-512x170,Fail
+kms_cursor_crc@cursor-random-512x512,Fail
+kms_cursor_crc@cursor-random-64x21,Fail
+kms_cursor_crc@cursor-random-64x64,Fail
+kms_cursor_crc@cursor-rapid-movement-128x128,Fail
+kms_cursor_crc@cursor-rapid-movement-128x42,Fail
+kms_cursor_crc@cursor-rapid-movement-256x256,Fail
+kms_cursor_crc@cursor-rapid-movement-256x85,Fail
+kms_cursor_crc@cursor-rapid-movement-32x10,Fail
+kms_cursor_crc@cursor-rapid-movement-32x32,Fail
+kms_cursor_crc@cursor-rapid-movement-512x170,Fail
+kms_cursor_crc@cursor-rapid-movement-512x512,Fail
+kms_cursor_crc@cursor-rapid-movement-64x21,Fail
+kms_cursor_crc@cursor-rapid-movement-64x64,Fail
+kms_cursor_crc@cursor-size-change,Fail
+kms_cursor_crc@cursor-sliding-128x128,Fail
+kms_cursor_crc@cursor-sliding-128x42,Fail
+kms_cursor_crc@cursor-sliding-256x256,Fail
+kms_cursor_crc@cursor-sliding-256x85,Fail
+kms_cursor_crc@cursor-sliding-32x10,Fail
+kms_cursor_crc@cursor-sliding-32x32,Fail
+kms_cursor_crc@cursor-sliding-512x170,Fail
+kms_cursor_crc@cursor-sliding-512x512,Fail
+kms_cursor_crc@cursor-sliding-64x21,Fail
+kms_cursor_crc@cursor-sliding-64x64,Fail
+kms_cursor_edge_walk@128x128-left-edge,Fail
+kms_cursor_edge_walk@128x128-right-edge,Fail
+kms_cursor_edge_walk@128x128-top-bottom,Fail
+kms_cursor_edge_walk@128x128-top-edge,Fail
+kms_cursor_edge_walk@256x256-left-edge,Fail
+kms_cursor_edge_walk@256x256-right-edge,Fail
+kms_cursor_edge_walk@256x256-top-bottom,Fail
+kms_cursor_edge_walk@256x256-top-edge,Fail
+kms_cursor_edge_walk@64x64-left-edge,Fail
+kms_cursor_edge_walk@64x64-right-edge,Fail
+kms_cursor_edge_walk@64x64-top-bottom,Fail
+kms_cursor_edge_walk@64x64-top-edge,Fail
+kms_cursor_legacy@2x-cursor-vs-flip-atomic,Fail
+kms_cursor_legacy@2x-cursor-vs-flip-legacy,Fail
+kms_cursor_legacy@2x-flip-vs-cursor-atomic,Fail
+kms_cursor_legacy@2x-flip-vs-cursor-legacy,Fail
+kms_cursor_legacy@2x-long-cursor-vs-flip-atomic,Fail
+kms_cursor_legacy@2x-long-cursor-vs-flip-legacy,Fail
+kms_cursor_legacy@2x-long-flip-vs-cursor-atomic,Fail
+kms_cursor_legacy@2x-long-flip-vs-cursor-legacy,Fail
kms_cursor_legacy@cursor-vs-flip-toggle,Fail
kms_cursor_legacy@cursor-vs-flip-varying-size,Fail
+kms_display_modes@extended-mode-basic,Fail
+kms_flip@2x-flip-vs-modeset-vs-hang,Fail
+kms_flip@2x-flip-vs-panning-vs-hang,Fail
+kms_flip@absolute-wf_vblank,Fail
+kms_flip@absolute-wf_vblank-interruptible,Fail
+kms_flip@basic-flip-vs-wf_vblank,Fail
+kms_flip@basic-plain-flip,Fail
+kms_flip@blocking-absolute-wf_vblank,Fail
+kms_flip@blocking-absolute-wf_vblank-interruptible,Fail
+kms_flip@blocking-wf_vblank,Fail
+kms_flip@busy-flip,Fail
+kms_flip@dpms-off-confusion,Fail
+kms_flip@dpms-off-confusion-interruptible,Fail
+kms_flip@dpms-vs-vblank-race,Fail
+kms_flip@dpms-vs-vblank-race-interruptible,Fail
+kms_flip@flip-vs-absolute-wf_vblank,Fail
+kms_flip@flip-vs-absolute-wf_vblank-interruptible,Fail
+kms_flip@flip-vs-blocking-wf-vblank,Fail
+kms_flip@flip-vs-expired-vblank,Fail
+kms_flip@flip-vs-expired-vblank-interruptible,Fail
kms_flip@flip-vs-modeset-vs-hang,Fail
+kms_flip@flip-vs-panning,Fail
+kms_flip@flip-vs-panning-interruptible,Fail
kms_flip@flip-vs-panning-vs-hang,Fail
+kms_flip@flip-vs-rmfb,Fail
+kms_flip@flip-vs-rmfb-interruptible,Fail
+kms_flip@flip-vs-wf_vblank-interruptible,Fail
+kms_flip@modeset-vs-vblank-race,Fail
+kms_flip@modeset-vs-vblank-race-interruptible,Fail
+kms_flip@plain-flip-fb-recreate,Fail
+kms_flip@plain-flip-fb-recreate-interruptible,Fail
+kms_flip@plain-flip-interruptible,Fail
+kms_flip@plain-flip-ts-check,Fail
+kms_flip@plain-flip-ts-check-interruptible,Fail
+kms_flip@wf_vblank-ts-check,Fail
+kms_flip@wf_vblank-ts-check-interruptible,Fail
+kms_lease@cursor-implicit-plane,Fail
+kms_lease@lease-uevent,Fail
+kms_lease@page-flip-implicit-plane,Fail
+kms_lease@setcrtc-implicit-plane,Fail
+kms_lease@simple-lease,Fail
+kms_multipipe_modeset@basic-max-pipe-crc-check,Fail
kms_pipe_crc_basic@compare-crc-sanitycheck-nv12,Fail
+kms_pipe_crc_basic@compare-crc-sanitycheck-xr24,Fail
+kms_pipe_crc_basic@disable-crc-after-crtc,Fail
+kms_pipe_crc_basic@nonblocking-crc,Fail
+kms_pipe_crc_basic@nonblocking-crc-frame-sequence,Fail
+kms_pipe_crc_basic@read-crc,Fail
+kms_pipe_crc_basic@read-crc-frame-sequence,Fail
+kms_plane@pixel-format,Fail
+kms_plane@pixel-format-source-clamping,Fail
+kms_plane@plane-panning-bottom-right,Fail
+kms_plane@plane-panning-top-left,Fail
+kms_plane@plane-position-covered,Fail
+kms_plane@plane-position-hole,Fail
+kms_plane@plane-position-hole-dpms,Fail
kms_plane_alpha_blend@alpha-7efc,Fail
+kms_plane_alpha_blend@alpha-basic,Fail
+kms_plane_alpha_blend@alpha-opaque-fb,Fail
+kms_plane_alpha_blend@alpha-transparent-fb,Fail
+kms_plane_alpha_blend@constant-alpha-max,Fail
+kms_plane_alpha_blend@constant-alpha-mid,Fail
+kms_plane_alpha_blend@constant-alpha-min,Fail
kms_plane_alpha_blend@coverage-7efc,Fail
kms_plane_alpha_blend@coverage-vs-premult-vs-constant,Fail
+kms_plane_cursor@primary,Fail
+kms_plane_lowres@tiling-none,Fail
+kms_plane_multiple@tiling-none,Fail
kms_rmfb@close-fd,Fail
-kms_universal_plane@universal-plane-sanity,Fail
+kms_rotation_crc@cursor-rotation-180,Fail
+kms_rotation_crc@primary-rotation-180,Fail
+kms_sequence@get-busy,Fail
+kms_sequence@get-forked,Fail
+kms_sequence@get-forked-busy,Fail
+kms_sequence@get-idle,Fail
+kms_sequence@queue-busy,Fail
+kms_sequence@queue-idle,Fail
+kms_vblank@accuracy-idle,Fail
+kms_vblank@crtc-id,Fail
+kms_vblank@query-busy,Fail
+kms_vblank@query-forked,Fail
+kms_vblank@query-forked-busy,Fail
+kms_vblank@query-idle,Fail
+kms_vblank@ts-continuation-dpms-rpm,Fail
+kms_vblank@ts-continuation-idle,Fail
+kms_vblank@ts-continuation-modeset,Fail
+kms_vblank@ts-continuation-modeset-rpm,Fail
+kms_vblank@wait-busy,Fail
+kms_vblank@wait-forked,Fail
+kms_vblank@wait-forked-busy,Fail
+kms_vblank@wait-idle,Fail
+tools_test@tools_test,Fail
diff --git a/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-lazor-limozeen-flakes.txt b/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-lazor-limozeen-flakes.txt
new file mode 100644
index 000000000000..dcb24b835dc3
--- /dev/null
+++ b/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-lazor-limozeen-flakes.txt
@@ -0,0 +1,6 @@
+# Board Name: sc7180-trogdor-lazor-limozeen-nots-r5
+# Bug Report: https://lore.kernel.org/linux-arm-msm/661483c8-ad82-400d-bcd8-e94986d20d7d@collabora.com/T/#u
+# IGT Version: 1.28-g0df7b9b97
+# Linux Version: 6.9.0-rc7
+# Failure Rate: 50
+msm_mapping@shadow
diff --git a/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-lazor-limozeen-skips.txt b/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-lazor-limozeen-skips.txt
index 327039f70252..1168c53acd2d 100644
--- a/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-lazor-limozeen-skips.txt
+++ b/drivers/gpu/drm/ci/xfails/msm-sc7180-trogdor-lazor-limozeen-skips.txt
@@ -1,2 +1,18 @@
# Suspend to RAM seems to be broken on this machine
.*suspend.*
+
+# Skip driver specific tests
+^amdgpu.*
+nouveau_.*
+panfrost_.*
+^v3d.*
+^vc4.*
+^vmwgfx*
+
+# Skip intel specific tests
+gem_.*
+i915_.*
+
+# Currently fails and causes coverage loss for other tests
+# since core_getversion also fails.
+core_hotunplug.*
diff --git a/drivers/gpu/drm/ci/xfails/msm-sdm845-fails.txt b/drivers/gpu/drm/ci/xfails/msm-sdm845-fails.txt
index e9043a00383e..8f010c8a9c4f 100644
--- a/drivers/gpu/drm/ci/xfails/msm-sdm845-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/msm-sdm845-fails.txt
@@ -1,3 +1,8 @@
+device_reset@cold-reset-bound,Fail
+device_reset@reset-bound,Fail
+device_reset@unbind-cold-reset-rebind,Fail
+device_reset@unbind-reset-rebind,Fail
+dumb_buffer@invalid-bpp,Fail
kms_color@ctm-0-25,Fail
kms_color@ctm-0-50,Fail
kms_color@ctm-0-75,Fail
@@ -6,17 +11,6 @@ kms_color@ctm-green-to-red,Fail
kms_color@ctm-negative,Fail
kms_color@ctm-red-to-blue,Fail
kms_color@ctm-signed,Fail
-kms_color@pipe-A-ctm-0-25,Fail
-kms_color@pipe-A-ctm-0-5,Fail
-kms_color@pipe-A-ctm-0-75,Fail
-kms_color@pipe-A-ctm-blue-to-red,Fail
-kms_color@pipe-A-ctm-green-to-red,Fail
-kms_color@pipe-A-ctm-max,Fail
-kms_color@pipe-A-ctm-negative,Fail
-kms_color@pipe-A-ctm-red-to-blue,Fail
-kms_color@pipe-A-legacy-gamma,Fail
-kms_cursor_legacy@basic-flip-after-cursor-atomic,Fail
-kms_cursor_legacy@basic-flip-after-cursor-varying-size,Fail
kms_cursor_legacy@basic-flip-before-cursor-atomic,Fail
kms_cursor_legacy@basic-flip-before-cursor-legacy,Fail
kms_cursor_legacy@cursor-vs-flip-atomic,Fail
@@ -31,30 +25,12 @@ kms_cursor_legacy@flip-vs-cursor-crc-legacy,Fail
kms_cursor_legacy@flip-vs-cursor-legacy,Fail
kms_flip@flip-vs-modeset-vs-hang,Fail
kms_flip@flip-vs-panning-vs-hang,Fail
+kms_lease@lease-uevent,Fail
kms_pipe_crc_basic@compare-crc-sanitycheck-nv12,Fail
kms_plane_alpha_blend@alpha-7efc,Fail
kms_plane_alpha_blend@coverage-7efc,Fail
kms_plane_alpha_blend@coverage-vs-premult-vs-constant,Fail
-kms_plane_alpha_blend@pipe-A-alpha-7efc,Fail
-kms_plane_alpha_blend@pipe-A-coverage-7efc,Fail
-kms_plane_alpha_blend@pipe-A-coverage-vs-premult-vs-constant,Fail
kms_plane_cursor@overlay,Fail
-kms_plane_cursor@pipe-A-overlay-size-128,Fail
-kms_plane_cursor@pipe-A-overlay-size-256,Fail
-kms_plane_cursor@pipe-A-overlay-size-64,Fail
-kms_plane_cursor@pipe-A-viewport-size-128,Fail
-kms_plane_cursor@pipe-A-viewport-size-256,Fail
-kms_plane_cursor@pipe-A-viewport-size-64,Fail
kms_plane_cursor@viewport,Fail
-kms_plane_scaling@downscale-with-pixel-format-factor-0-25,Timeout
-kms_plane_scaling@downscale-with-pixel-format-factor-0-5,Timeout
-kms_plane_scaling@downscale-with-pixel-format-factor-0-75,Timeout
-kms_plane_scaling@plane-downscale-with-pixel-format-factor-0-25,Timeout
-kms_plane_scaling@plane-downscale-with-pixel-format-factor-0-5,Timeout
-kms_plane_scaling@plane-downscale-with-pixel-format-factor-0-75,Timeout
-kms_plane_scaling@plane-scaler-with-clipping-clamping-pixel-formats,Timeout
-kms_plane_scaling@plane-scaler-with-pixel-format-unity-scaling,Timeout
-kms_plane_scaling@planes-downscale-factor-0-25,Fail
-kms_plane_scaling@scaler-with-clipping-clamping,Timeout
-kms_plane_scaling@scaler-with-pixel-format-unity-scaling,Timeout
kms_rmfb@close-fd,Fail
+tools_test@tools_test,Fail
diff --git a/drivers/gpu/drm/ci/xfails/msm-sdm845-flakes.txt b/drivers/gpu/drm/ci/xfails/msm-sdm845-flakes.txt
index 8a492f01eaa4..2c5f62b07632 100644
--- a/drivers/gpu/drm/ci/xfails/msm-sdm845-flakes.txt
+++ b/drivers/gpu/drm/ci/xfails/msm-sdm845-flakes.txt
@@ -1,22 +1,19 @@
-# Board Name: msm:sdm845
-# Bug Report: https://lore.kernel.org/dri-devel/46287831-edfa-78e8-6055-d7a08831c445@collabora.com/T/#u
+# Board Name: sdm845-cheza-r3
+# Bug Report: https://lore.kernel.org/linux-arm-msm/661483c8-ad82-400d-bcd8-e94986d20d7d@collabora.com/T/#u
+# IGT Version: 1.28-g0df7b9b97
+# Linux Version: 6.9.0-rc7
# Failure Rate: 50
-# IGT Version: 1.28-gd2af13d9f
-# Linux Version: 6.7.0-rc3
-
-# Reported by deqp-runner
+kms_cursor_legacy@basic-flip-after-cursor-atomic
kms_cursor_legacy@basic-flip-after-cursor-legacy
-kms_cursor_legacy@flip-vs-cursor-toggle
+kms_cursor_legacy@basic-flip-after-cursor-varying-size
+kms_cursor_legacy@basic-flip-before-cursor-varying-size
+kms_cursor_legacy@flip-vs-cursor-atomic-transitions
+kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size
kms_cursor_legacy@flip-vs-cursor-varying-size
+kms_cursor_legacy@short-flip-after-cursor-atomic-transitions
+kms_cursor_legacy@short-flip-after-cursor-atomic-transitions-varying-size
kms_cursor_legacy@short-flip-after-cursor-toggle
kms_cursor_legacy@short-flip-before-cursor-atomic-transitions
kms_cursor_legacy@short-flip-before-cursor-atomic-transitions-varying-size
msm_shrink@copy-gpu-32
msm_shrink@copy-gpu-oom-32
-
-# The below test shows inconsistency across multiple runs, giving
-# results of Pass and Fail alternately.
-kms_cursor_legacy@basic-flip-before-cursor-varying-size
-kms_cursor_legacy@flip-vs-cursor-atomic-transitions
-kms_cursor_legacy@short-flip-after-cursor-atomic-transitions
-kms_cursor_legacy@short-flip-after-cursor-atomic-transitions-varying-size
diff --git a/drivers/gpu/drm/ci/xfails/msm-sdm845-skips.txt b/drivers/gpu/drm/ci/xfails/msm-sdm845-skips.txt
index 618e3a3a7277..5185212c8fb2 100644
--- a/drivers/gpu/drm/ci/xfails/msm-sdm845-skips.txt
+++ b/drivers/gpu/drm/ci/xfails/msm-sdm845-skips.txt
@@ -5,3 +5,22 @@ kms_bw.*
# https://gitlab.freedesktop.org/gfx-ci/linux/-/commit/4b49f902ec6f2bb382cbbf489870573f4b43371e
# https://gitlab.freedesktop.org/gfx-ci/linux/-/commit/38cdf4c5559771e2474ae0fecef8469f65147bc1
msm_mapping@*
+
+# Skip driver specific tests
+^amdgpu.*
+nouveau_.*
+panfrost_.*
+^v3d.*
+^vc4.*
+^vmwgfx*
+
+# Skip intel specific tests
+gem_.*
+i915_.*
+
+# Currently fails and causes coverage loss for other tests
+# since core_getversion also fails.
+core_hotunplug.*
+
+# Whole machine hangs
+kms_cursor_crc.*
diff --git a/drivers/gpu/drm/ci/xfails/rockchip-rk3288-fails.txt b/drivers/gpu/drm/ci/xfails/rockchip-rk3288-fails.txt
index 90c63f519e9e..f9b99bf27105 100644
--- a/drivers/gpu/drm/ci/xfails/rockchip-rk3288-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/rockchip-rk3288-fails.txt
@@ -1,54 +1,8 @@
-kms_3d,Crash
-kms_bw@linear-tiling-2-displays-1920x1080p,Fail
-kms_bw@linear-tiling-2-displays-2560x1440p,Fail
-kms_bw@linear-tiling-2-displays-3840x2160p,Fail
-kms_bw@linear-tiling-3-displays-1920x1080p,Fail
-kms_bw@linear-tiling-3-displays-2560x1440p,Fail
-kms_bw@linear-tiling-3-displays-3840x2160p,Fail
-kms_flip@flip-vs-modeset-vs-hang,Crash
-kms_flip@flip-vs-panning-vs-hang,Crash
-kms_force_connector_basic@force-load-detect,Fail
-kms_invalid_mode@int-max-clock,Crash
-kms_pipe_crc_basic@compare-crc-sanitycheck-nv12,Crash
-kms_pipe_crc_basic@nonblocking-crc-frame-sequence,Crash
-kms_pipe_crc_basic@read-crc-frame-sequence,Crash
-kms_plane@pixel-format,Crash
-kms_plane@pixel-format-source-clamping,Crash
-kms_plane@plane-position-hole,Crash
-kms_plane@plane-position-hole-dpms,Crash
-kms_plane_cursor@overlay,Crash
-kms_plane_cursor@pipe-A-overlay-size-128,Fail
-kms_plane_cursor@pipe-A-overlay-size-256,Fail
-kms_plane_cursor@pipe-A-overlay-size-64,Fail
-kms_plane_cursor@pipe-A-primary-size-128,Fail
-kms_plane_cursor@pipe-A-primary-size-256,Fail
-kms_plane_cursor@pipe-A-primary-size-64,Fail
-kms_plane_cursor@pipe-A-viewport-size-128,Fail
-kms_plane_cursor@pipe-A-viewport-size-256,Fail
-kms_plane_cursor@pipe-A-viewport-size-64,Fail
-kms_plane_cursor@pipe-B-overlay-size-128,Fail
-kms_plane_cursor@pipe-B-overlay-size-256,Fail
-kms_plane_cursor@pipe-B-overlay-size-64,Fail
-kms_plane_cursor@pipe-B-primary-size-128,Fail
-kms_plane_cursor@pipe-B-primary-size-256,Fail
-kms_plane_cursor@pipe-B-primary-size-64,Fail
-kms_plane_cursor@pipe-B-viewport-size-128,Fail
-kms_plane_cursor@pipe-B-viewport-size-256,Fail
-kms_plane_cursor@pipe-B-viewport-size-64,Fail
-kms_plane_cursor@primary,Crash
-kms_plane_cursor@viewport,Crash
-kms_plane_lowres@tiling-none,Fail
-kms_plane_scaling@downscale-with-modifier-factor-0-25,Fail
-kms_plane_scaling@downscale-with-rotation-factor-0-25,Fail
-kms_plane_scaling@upscale-with-modifier-20x20,Fail
-kms_plane_scaling@upscale-with-modifier-factor-0-25,Fail
-kms_plane_scaling@upscale-with-pixel-format-20x20,Fail
-kms_plane_scaling@upscale-with-pixel-format-factor-0-25,Fail
-kms_plane_scaling@upscale-with-rotation-20x20,Fail
-kms_prime@basic-crc,Fail
-kms_properties@connector-properties-atomic,Crash
-kms_properties@connector-properties-legacy,Crash
-kms_properties@get_properties-sanity-atomic,Crash
-kms_properties@get_properties-sanity-non-atomic,Crash
-kms_rmfb@close-fd,Crash
-kms_setmode@invalid-clone-single-crtc,Crash
+dumb_buffer@create-clear,Crash
+dumb_buffer@create-valid-dumb,Crash
+dumb_buffer@invalid-bpp,Crash
+dumb_buffer@map-invalid-size,Crash
+dumb_buffer@map-uaf,Crash
+dumb_buffer@map-valid,Crash
+panfrost_prime@gem-prime-import,Crash
+tools_test@tools_test,Crash
diff --git a/drivers/gpu/drm/ci/xfails/rockchip-rk3288-skips.txt b/drivers/gpu/drm/ci/xfails/rockchip-rk3288-skips.txt
index f20c3574b75a..6d3757dca83b 100644
--- a/drivers/gpu/drm/ci/xfails/rockchip-rk3288-skips.txt
+++ b/drivers/gpu/drm/ci/xfails/rockchip-rk3288-skips.txt
@@ -49,4 +49,23 @@ kms_plane_lowres@pipe-F-tiling-y
kms_cursor_crc.*
# Machine is hanging in this test, so skip it
-kms_pipe_crc_basic@disable-crc-after-crtc \ No newline at end of file
+kms_pipe_crc_basic@disable-crc-after-crtc
+
+# Skip driver specific tests
+^amdgpu.*
+msm_.*
+nouveau_.*
+^v3d.*
+^vc4.*
+^vmwgfx*
+
+# Skip intel specific tests
+gem_.*
+i915_.*
+
+# Panfrost is not a KMS driver, so skip the KMS tests
+kms_.*
+
+# Currently fails and causes coverage loss for other tests
+# since core_getversion also fails.
+core_hotunplug.*
diff --git a/drivers/gpu/drm/ci/xfails/rockchip-rk3399-fails.txt b/drivers/gpu/drm/ci/xfails/rockchip-rk3399-fails.txt
index d516d9c1d546..9ef460646d76 100644
--- a/drivers/gpu/drm/ci/xfails/rockchip-rk3399-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/rockchip-rk3399-fails.txt
@@ -1,75 +1,8 @@
-kms_color@gamma,Fail
-kms_color@legacy-gamma,Fail
-kms_color@pipe-A-legacy-gamma,Fail
-kms_color@pipe-B-legacy-gamma,Fail
-kms_cursor_crc@cursor-alpha-opaque,Fail
-kms_cursor_crc@cursor-alpha-transparent,Fail
-kms_cursor_crc@cursor-dpms,Fail
-kms_cursor_crc@cursor-offscreen-32x10,Fail
-kms_cursor_crc@cursor-offscreen-32x32,Fail
-kms_cursor_crc@cursor-offscreen-64x64,Fail
-kms_cursor_crc@cursor-onscreen-32x10,Fail
-kms_cursor_crc@cursor-onscreen-32x32,Fail
-kms_cursor_crc@cursor-onscreen-64x21,Fail
-kms_cursor_crc@cursor-onscreen-64x64,Fail
-kms_cursor_crc@cursor-random-32x10,Fail
-kms_cursor_crc@cursor-random-32x32,Fail
-kms_cursor_crc@cursor-random-64x21,Fail
-kms_cursor_crc@cursor-random-64x64,Fail
-kms_cursor_crc@cursor-rapid-movement-32x32,Fail
-kms_cursor_crc@cursor-rapid-movement-64x21,Fail
-kms_cursor_crc@cursor-rapid-movement-64x64,Fail
-kms_cursor_crc@cursor-size-change,Fail
-kms_cursor_crc@cursor-sliding-32x10,Fail
-kms_cursor_crc@cursor-sliding-32x32,Fail
-kms_cursor_crc@cursor-sliding-64x21,Fail
-kms_cursor_crc@cursor-sliding-64x64,Fail
-kms_flip@basic-flip-vs-wf_vblank,Fail
-kms_flip@blocking-wf_vblank,Fail
-kms_flip@dpms-vs-vblank-race,Fail
-kms_flip@flip-vs-absolute-wf_vblank,Fail
-kms_flip@flip-vs-absolute-wf_vblank-interruptible,Fail
-kms_flip@flip-vs-blocking-wf-vblank,Fail
-kms_flip@flip-vs-modeset-vs-hang,Fail
-kms_flip@flip-vs-panning,Fail
-kms_flip@flip-vs-panning-interruptible,Fail
-kms_flip@flip-vs-panning-vs-hang,Fail
-kms_flip@modeset-vs-vblank-race,Fail
-kms_flip@plain-flip-fb-recreate,Fail
-kms_flip@plain-flip-fb-recreate-interruptible,Fail
-kms_flip@plain-flip-ts-check,Fail
-kms_flip@plain-flip-ts-check-interruptible,Fail
-kms_flip@wf_vblank-ts-check,Fail
-kms_flip@wf_vblank-ts-check-interruptible,Fail
-kms_invalid_mode@int-max-clock,Fail
-kms_pipe_crc_basic@compare-crc-sanitycheck-nv12,Fail
-kms_pipe_crc_basic@compare-crc-sanitycheck-xr24,Fail
-kms_pipe_crc_basic@disable-crc-after-crtc,Fail
-kms_pipe_crc_basic@nonblocking-crc,Fail
-kms_pipe_crc_basic@nonblocking-crc-frame-sequence,Fail
-kms_pipe_crc_basic@read-crc,Fail
-kms_pipe_crc_basic@read-crc-frame-sequence,Fail
-kms_plane@pixel-format,Fail
-kms_plane@pixel-format-source-clamping,Fail
-kms_plane@plane-panning-bottom-right,Fail
-kms_plane@plane-panning-top-left,Fail
-kms_plane@plane-position-covered,Fail
-kms_plane@plane-position-hole,Fail
-kms_plane@plane-position-hole-dpms,Fail
-kms_plane_cursor@overlay,Fail
-kms_plane_cursor@pipe-B-overlay-size-128,Fail
-kms_plane_cursor@pipe-B-overlay-size-256,Fail
-kms_plane_cursor@pipe-B-overlay-size-64,Fail
-kms_plane_cursor@pipe-B-primary-size-128,Fail
-kms_plane_cursor@pipe-B-primary-size-256,Fail
-kms_plane_cursor@pipe-B-primary-size-64,Fail
-kms_plane_cursor@pipe-B-viewport-size-128,Fail
-kms_plane_cursor@pipe-B-viewport-size-256,Fail
-kms_plane_cursor@pipe-B-viewport-size-64,Fail
-kms_plane_cursor@primary,Fail
-kms_plane_cursor@viewport,Fail
-kms_plane_multiple@atomic-pipe-B-tiling-none,Fail
-kms_plane_multiple@tiling-none,Fail
-kms_prime@basic-crc,Fail
-kms_rmfb@close-fd,Fail
-kms_universal_plane@universal-plane-pipe-B-functional,Fail
+dumb_buffer@create-clear,Fail
+dumb_buffer@create-valid-dumb,Fail
+dumb_buffer@invalid-bpp,Fail
+dumb_buffer@map-invalid-size,Fail
+dumb_buffer@map-uaf,Fail
+dumb_buffer@map-valid,Fail
+panfrost_prime@gem-prime-import,Fail
+tools_test@tools_test,Fail
diff --git a/drivers/gpu/drm/ci/xfails/rockchip-rk3399-flakes.txt b/drivers/gpu/drm/ci/xfails/rockchip-rk3399-flakes.txt
index c9fdc623ab91..742c27d9a598 100644
--- a/drivers/gpu/drm/ci/xfails/rockchip-rk3399-flakes.txt
+++ b/drivers/gpu/drm/ci/xfails/rockchip-rk3399-flakes.txt
@@ -1,7 +1,6 @@
-kms_bw@linear-tiling-2-displays-1920x1080p
-kms_cursor_crc@cursor-offscreen-64x21
-kms_flip@dpms-vs-vblank-race-interruptible
-kms_flip@flip-vs-wf_vblank-interruptible
-kms_plane_cursor@overlay
-kms_plane_cursor@primary
-kms_plane_cursor@viewport
+# Board Name: rk3399-gru-kevin
+# Bug Report: https://lore.kernel.org/dri-devel/5cc34a8b-c1fa-4744-9031-2d33ecf41011@collabora.com/T/#u
+# IGT Version: 1.28-g0df7b9b97
+# Linux Version: 6.9.0-rc7
+# Failure Rate: 50
+panfrost_submit@pan-unhandled-pagefault
diff --git a/drivers/gpu/drm/ci/xfails/rockchip-rk3399-skips.txt b/drivers/gpu/drm/ci/xfails/rockchip-rk3399-skips.txt
index 10c3d81a919a..5c52b25b4213 100644
--- a/drivers/gpu/drm/ci/xfails/rockchip-rk3399-skips.txt
+++ b/drivers/gpu/drm/ci/xfails/rockchip-rk3399-skips.txt
@@ -3,3 +3,22 @@
# Too unstable, machine ends up hanging after lots of Oopses
kms_cursor_legacy.*
+
+# Skip driver specific tests
+^amdgpu.*
+msm_.*
+nouveau_.*
+^v3d.*
+^vc4.*
+^vmwgfx*
+
+# Skip intel specific tests
+gem_.*
+i915_.*
+
+# Panfrost is not a KMS driver, so skip the KMS tests
+kms_.*
+
+# Currently fails and causes coverage loss for other tests
+# since core_getversion also fails.
+core_hotunplug.*
diff --git a/drivers/gpu/drm/ci/xfails/update-xfails.py b/drivers/gpu/drm/ci/xfails/update-xfails.py
index e9f0ec7fed8d..a446e98d72a1 100755
--- a/drivers/gpu/drm/ci/xfails/update-xfails.py
+++ b/drivers/gpu/drm/ci/xfails/update-xfails.py
@@ -93,10 +93,10 @@ def add_unit_test_or_update_result_to_fails_if_present(fails_txt, unit_test, fai
def split_unit_test_from_collate(xfails):
for job_name in xfails.keys():
for job_id in xfails[job_name].copy().keys():
- if "not found" in xfails[job_name][job_id]:
+ if "not found" in xfails[job_name][job_id].content_as_str:
del xfails[job_name][job_id]
continue
- xfails[job_name][job_id] = xfails[job_name][job_id].strip().split("\n")
+ xfails[job_name][job_id] = xfails[job_name][job_id].content_as_str.splitlines()
def get_xfails_from_pipeline_url(pipeline_url):
diff --git a/drivers/gpu/drm/ci/xfails/virtio_gpu-none-fails.txt b/drivers/gpu/drm/ci/xfails/virtio_gpu-none-fails.txt
index 007f21e56d89..fdf09fe11566 100644
--- a/drivers/gpu/drm/ci/xfails/virtio_gpu-none-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/virtio_gpu-none-fails.txt
@@ -1,33 +1,72 @@
-kms_addfb_basic@addfb25-bad-modifier,Fail
kms_addfb_basic@bad-pitch-65536,Fail
kms_addfb_basic@bo-too-small,Fail
kms_addfb_basic@size-max,Fail
kms_addfb_basic@too-high,Fail
kms_atomic_transition@plane-primary-toggle-with-vblank-wait,Fail
kms_bw@linear-tiling-1-displays-1920x1080p,Fail
+kms_bw@linear-tiling-1-displays-2160x1440p,Fail
kms_bw@linear-tiling-1-displays-2560x1440p,Fail
kms_bw@linear-tiling-1-displays-3840x2160p,Fail
+kms_bw@linear-tiling-10-displays-1920x1080p,Fail
+kms_bw@linear-tiling-10-displays-2160x1440p,Fail
+kms_bw@linear-tiling-10-displays-2560x1440p,Fail
+kms_bw@linear-tiling-10-displays-3840x2160p,Fail
+kms_bw@linear-tiling-11-displays-1920x1080p,Fail
+kms_bw@linear-tiling-11-displays-2160x1440p,Fail
+kms_bw@linear-tiling-11-displays-2560x1440p,Fail
+kms_bw@linear-tiling-11-displays-3840x2160p,Fail
+kms_bw@linear-tiling-12-displays-1920x1080p,Fail
+kms_bw@linear-tiling-12-displays-2160x1440p,Fail
+kms_bw@linear-tiling-12-displays-2560x1440p,Fail
+kms_bw@linear-tiling-12-displays-3840x2160p,Fail
+kms_bw@linear-tiling-13-displays-1920x1080p,Fail
+kms_bw@linear-tiling-13-displays-2160x1440p,Fail
+kms_bw@linear-tiling-13-displays-2560x1440p,Fail
+kms_bw@linear-tiling-13-displays-3840x2160p,Fail
+kms_bw@linear-tiling-14-displays-1920x1080p,Fail
+kms_bw@linear-tiling-14-displays-2160x1440p,Fail
+kms_bw@linear-tiling-14-displays-2560x1440p,Fail
+kms_bw@linear-tiling-14-displays-3840x2160p,Fail
+kms_bw@linear-tiling-15-displays-1920x1080p,Fail
+kms_bw@linear-tiling-15-displays-2160x1440p,Fail
+kms_bw@linear-tiling-15-displays-2560x1440p,Fail
+kms_bw@linear-tiling-15-displays-3840x2160p,Fail
+kms_bw@linear-tiling-16-displays-1920x1080p,Fail
+kms_bw@linear-tiling-16-displays-2160x1440p,Fail
+kms_bw@linear-tiling-16-displays-2560x1440p,Fail
+kms_bw@linear-tiling-16-displays-3840x2160p,Fail
kms_bw@linear-tiling-2-displays-1920x1080p,Fail
+kms_bw@linear-tiling-2-displays-2160x1440p,Fail
kms_bw@linear-tiling-2-displays-2560x1440p,Fail
kms_bw@linear-tiling-2-displays-3840x2160p,Fail
kms_bw@linear-tiling-3-displays-1920x1080p,Fail
+kms_bw@linear-tiling-3-displays-2160x1440p,Fail
kms_bw@linear-tiling-3-displays-2560x1440p,Fail
kms_bw@linear-tiling-3-displays-3840x2160p,Fail
kms_bw@linear-tiling-4-displays-1920x1080p,Fail
+kms_bw@linear-tiling-4-displays-2160x1440p,Fail
kms_bw@linear-tiling-4-displays-2560x1440p,Fail
kms_bw@linear-tiling-4-displays-3840x2160p,Fail
kms_bw@linear-tiling-5-displays-1920x1080p,Fail
+kms_bw@linear-tiling-5-displays-2160x1440p,Fail
kms_bw@linear-tiling-5-displays-2560x1440p,Fail
kms_bw@linear-tiling-5-displays-3840x2160p,Fail
kms_bw@linear-tiling-6-displays-1920x1080p,Fail
+kms_bw@linear-tiling-6-displays-2160x1440p,Fail
kms_bw@linear-tiling-6-displays-2560x1440p,Fail
kms_bw@linear-tiling-6-displays-3840x2160p,Fail
kms_bw@linear-tiling-7-displays-1920x1080p,Fail
+kms_bw@linear-tiling-7-displays-2160x1440p,Fail
kms_bw@linear-tiling-7-displays-2560x1440p,Fail
kms_bw@linear-tiling-7-displays-3840x2160p,Fail
kms_bw@linear-tiling-8-displays-1920x1080p,Fail
+kms_bw@linear-tiling-8-displays-2160x1440p,Fail
kms_bw@linear-tiling-8-displays-2560x1440p,Fail
kms_bw@linear-tiling-8-displays-3840x2160p,Fail
+kms_bw@linear-tiling-9-displays-1920x1080p,Fail
+kms_bw@linear-tiling-9-displays-2160x1440p,Fail
+kms_bw@linear-tiling-9-displays-2560x1440p,Fail
+kms_bw@linear-tiling-9-displays-3840x2160p,Fail
kms_flip@absolute-wf_vblank,Fail
kms_flip@absolute-wf_vblank-interruptible,Fail
kms_flip@basic-flip-vs-wf_vblank,Fail
@@ -54,31 +93,34 @@ kms_flip@plain-flip-ts-check-interruptible,Fail
kms_flip@wf_vblank-ts-check,Fail
kms_flip@wf_vblank-ts-check-interruptible,Fail
kms_invalid_mode@int-max-clock,Fail
-kms_plane_scaling@downscale-with-modifier-factor-0-25,Fail
-kms_plane_scaling@downscale-with-rotation-factor-0-25,Fail
-kms_plane_scaling@planes-upscale-20x20,Fail
-kms_plane_scaling@planes-upscale-20x20-downscale-factor-0-25,Fail
-kms_plane_scaling@planes-upscale-20x20-downscale-factor-0-5,Fail
-kms_plane_scaling@planes-upscale-20x20-downscale-factor-0-75,Fail
-kms_plane_scaling@upscale-with-modifier-20x20,Fail
-kms_plane_scaling@upscale-with-modifier-factor-0-25,Fail
-kms_plane_scaling@upscale-with-pixel-format-20x20,Fail
-kms_plane_scaling@upscale-with-pixel-format-factor-0-25,Fail
-kms_plane_scaling@upscale-with-rotation-20x20,Fail
-kms_selftest@drm_format,Timeout
-kms_selftest@drm_format_helper,Timeout
+kms_lease@cursor-implicit-plane,Fail
+kms_lease@lease-uevent,Fail
+kms_lease@page-flip-implicit-plane,Fail
+kms_lease@setcrtc-implicit-plane,Fail
+kms_lease@simple-lease,Fail
+kms_sequence@get-busy,Fail
+kms_sequence@get-forked,Fail
+kms_sequence@get-forked-busy,Fail
+kms_sequence@get-idle,Fail
+kms_sequence@queue-busy,Fail
+kms_sequence@queue-idle,Fail
kms_setmode@basic,Fail
+kms_vblank@accuracy-idle,Fail
kms_vblank@crtc-id,Fail
kms_vblank@invalid,Fail
-kms_vblank@pipe-A-accuracy-idle,Fail
-kms_vblank@pipe-A-query-busy,Fail
-kms_vblank@pipe-A-query-forked,Fail
-kms_vblank@pipe-A-query-forked-busy,Fail
-kms_vblank@pipe-A-query-idle,Fail
-kms_vblank@pipe-A-ts-continuation-idle,Fail
-kms_vblank@pipe-A-ts-continuation-modeset,Fail
-kms_vblank@pipe-A-ts-continuation-suspend,Fail
-kms_vblank@pipe-A-wait-busy,Fail
-kms_vblank@pipe-A-wait-forked,Fail
-kms_vblank@pipe-A-wait-forked-busy,Fail
-kms_vblank@pipe-A-wait-idle,Fail
+kms_vblank@query-busy,Fail
+kms_vblank@query-forked,Fail
+kms_vblank@query-forked-busy,Fail
+kms_vblank@query-idle,Fail
+kms_vblank@ts-continuation-dpms-rpm,Fail
+kms_vblank@ts-continuation-dpms-suspend,Fail
+kms_vblank@ts-continuation-idle,Fail
+kms_vblank@ts-continuation-modeset,Fail
+kms_vblank@ts-continuation-modeset-rpm,Fail
+kms_vblank@ts-continuation-suspend,Fail
+kms_vblank@wait-busy,Fail
+kms_vblank@wait-forked,Fail
+kms_vblank@wait-forked-busy,Fail
+kms_vblank@wait-idle,Fail
+perf@i915-ref-count,Fail
+tools_test@tools_test,Fail
diff --git a/drivers/gpu/drm/ci/xfails/virtio_gpu-none-skips.txt b/drivers/gpu/drm/ci/xfails/virtio_gpu-none-skips.txt
index 78be18174012..e0ca4fadb84f 100644
--- a/drivers/gpu/drm/ci/xfails/virtio_gpu-none-skips.txt
+++ b/drivers/gpu/drm/ci/xfails/virtio_gpu-none-skips.txt
@@ -3,4 +3,22 @@
kms_cursor_legacy.*
# Job just hangs without any output
-kms_flip@flip-vs-suspend.* \ No newline at end of file
+kms_flip@flip-vs-suspend.*
+
+# Skip driver specific tests
+^amdgpu.*
+msm_.*
+nouveau_.*
+panfrost_.*
+^v3d.*
+^vc4.*
+^vmwgfx*
+
+# Skip intel specific tests
+gem_.*
+i915_.*
+xe_.*
+
+# Currently fails and causes coverage loss for other tests
+# since core_getversion also fails.
+core_hotunplug.*
diff --git a/drivers/gpu/drm/ci/xfails/vkms-none-fails.txt b/drivers/gpu/drm/ci/xfails/vkms-none-fails.txt
new file mode 100644
index 000000000000..691c383b21a0
--- /dev/null
+++ b/drivers/gpu/drm/ci/xfails/vkms-none-fails.txt
@@ -0,0 +1,57 @@
+core_hotunplug@hotrebind,Fail
+core_hotunplug@hotrebind-lateclose,Fail
+core_hotunplug@hotreplug,Fail
+core_hotunplug@hotreplug-lateclose,Fail
+core_hotunplug@hotunbind-rebind,Fail
+core_hotunplug@hotunplug-rescan,Fail
+core_hotunplug@unbind-rebind,Fail
+core_hotunplug@unplug-rescan,Fail
+device_reset@cold-reset-bound,Fail
+device_reset@reset-bound,Fail
+device_reset@unbind-cold-reset-rebind,Fail
+device_reset@unbind-reset-rebind,Fail
+dumb_buffer@invalid-bpp,Fail
+kms_content_protection@atomic,Crash
+kms_content_protection@atomic-dpms,Crash
+kms_content_protection@content-type-change,Crash
+kms_content_protection@lic-type-0,Crash
+kms_content_protection@lic-type-1,Crash
+kms_content_protection@srm,Crash
+kms_content_protection@type1,Crash
+kms_content_protection@uevent,Crash
+kms_cursor_crc@cursor-rapid-movement-128x128,Fail
+kms_cursor_crc@cursor-rapid-movement-128x42,Fail
+kms_cursor_crc@cursor-rapid-movement-256x256,Fail
+kms_cursor_crc@cursor-rapid-movement-256x85,Fail
+kms_cursor_crc@cursor-rapid-movement-32x10,Fail
+kms_cursor_crc@cursor-rapid-movement-32x32,Fail
+kms_cursor_crc@cursor-rapid-movement-512x170,Fail
+kms_cursor_crc@cursor-rapid-movement-512x512,Fail
+kms_cursor_crc@cursor-rapid-movement-64x21,Fail
+kms_cursor_crc@cursor-rapid-movement-64x64,Fail
+kms_cursor_legacy@basic-flip-before-cursor-atomic,Fail
+kms_cursor_legacy@basic-flip-before-cursor-legacy,Fail
+kms_cursor_legacy@cursor-vs-flip-atomic,Fail
+kms_cursor_legacy@cursor-vs-flip-legacy,Fail
+kms_cursor_legacy@cursor-vs-flip-toggle,Fail
+kms_cursor_legacy@cursor-vs-flip-varying-size,Fail
+kms_cursor_legacy@flip-vs-cursor-atomic,Fail
+kms_cursor_legacy@flip-vs-cursor-crc-atomic,Fail
+kms_cursor_legacy@flip-vs-cursor-crc-legacy,Fail
+kms_cursor_legacy@flip-vs-cursor-legacy,Fail
+kms_flip@flip-vs-modeset-vs-hang,Fail
+kms_flip@flip-vs-panning-vs-hang,Fail
+kms_flip@flip-vs-suspend,Timeout
+kms_flip@flip-vs-suspend-interruptible,Timeout
+kms_flip@plain-flip-fb-recreate,Fail
+kms_lease@lease-uevent,Fail
+kms_pipe_crc_basic@nonblocking-crc,Fail
+kms_pipe_crc_basic@nonblocking-crc-frame-sequence,Fail
+kms_writeback@writeback-check-output,Fail
+kms_writeback@writeback-check-output-XRGB2101010,Fail
+kms_writeback@writeback-fb-id,Fail
+kms_writeback@writeback-fb-id-XRGB2101010,Fail
+kms_writeback@writeback-invalid-parameters,Fail
+kms_writeback@writeback-pixel-formats,Fail
+perf@i915-ref-count,Fail
+tools_test@tools_test,Fail
diff --git a/drivers/gpu/drm/ci/xfails/vkms-none-flakes.txt b/drivers/gpu/drm/ci/xfails/vkms-none-flakes.txt
new file mode 100644
index 000000000000..eeaa1d5825af
--- /dev/null
+++ b/drivers/gpu/drm/ci/xfails/vkms-none-flakes.txt
@@ -0,0 +1,69 @@
+# Board Name: vkms
+# Bug Report: https://lore.kernel.org/dri-devel/61ed26af-062c-443c-9df2-d1ee319f3fb0@collabora.com/T/#u
+# Failure Rate: 50
+# IGT Version: 1.28-g0df7b9b97
+# Linux Version: 6.9.0-rc7
+kms_cursor_legacy@long-nonblocking-modeset-vs-cursor-atomic
+
+# Board Name: vkms
+# Bug Report: https://lore.kernel.org/dri-devel/61ed26af-062c-443c-9df2-d1ee319f3fb0@collabora.com/T/#u
+# Failure Rate: 50
+# IGT Version: 1.28-g0df7b9b97
+# Linux Version: 6.9.0-rc7
+kms_flip@basic-flip-vs-wf_vblank
+
+# Board Name: vkms
+# Bug Report: https://lore.kernel.org/dri-devel/61ed26af-062c-443c-9df2-d1ee319f3fb0@collabora.com/T/#u
+# Failure Rate: 50
+# IGT Version: 1.28-g0df7b9b97
+# Linux Version: 6.9.0-rc7
+kms_flip@flip-vs-expired-vblank-interruptible
+
+# Board Name: vkms
+# Bug Report: https://lore.kernel.org/dri-devel/61ed26af-062c-443c-9df2-d1ee319f3fb0@collabora.com/T/#u
+# Failure Rate: 50
+# IGT Version: 1.28-g0df7b9b97
+# Linux Version: 6.9.0-rc7
+kms_flip@flip-vs-wf_vblank-interruptible
+
+# Board Name: vkms
+# Bug Report: https://lore.kernel.org/dri-devel/61ed26af-062c-443c-9df2-d1ee319f3fb0@collabora.com/T/#u
+# Failure Rate: 50
+# IGT Version: 1.28-g0df7b9b97
+# Linux Version: 6.9.0-rc7
+kms_flip@plain-flip-fb-recreate-interruptible
+
+# Board Name: vkms
+# Bug Report: https://lore.kernel.org/dri-devel/61ed26af-062c-443c-9df2-d1ee319f3fb0@collabora.com/T/#u
+# Failure Rate: 50
+# IGT Version: 1.28-g0df7b9b97
+# Linux Version: 6.9.0-rc7
+kms_flip@plain-flip-ts-check
+
+# Board Name: vkms
+# Bug Report: https://lore.kernel.org/dri-devel/61ed26af-062c-443c-9df2-d1ee319f3fb0@collabora.com/T/#u
+# Failure Rate: 50
+# IGT Version: 1.28-g0df7b9b97
+# Linux Version: 6.9.0-rc7
+kms_flip@plain-flip-ts-check-interruptible
+
+# Board Name: vkms
+# Bug Report: https://lore.kernel.org/dri-devel/61ed26af-062c-443c-9df2-d1ee319f3fb0@collabora.com/T/#u
+# Failure Rate: 50
+# IGT Version: 1.28-g0df7b9b97
+# Linux Version: 6.9.0-rc7
+kms_flip@flip-vs-absolute-wf_vblank
+
+# Board Name: vkms
+# Bug Report: https://lore.kernel.org/dri-devel/61ed26af-062c-443c-9df2-d1ee319f3fb0@collabora.com/T/#u
+# Failure Rate: 50
+# IGT Version: 1.28-g0df7b9b97
+# Linux Version: 6.9.0-rc7
+kms_flip@flip-vs-absolute-wf_vblank-interruptible
+
+# Board Name: vkms
+# Bug Report: https://lore.kernel.org/dri-devel/61ed26af-062c-443c-9df2-d1ee319f3fb0@collabora.com/T/#u
+# Failure Rate: 50
+# IGT Version: 1.28-g0df7b9b97
+# Linux Version: 6.9.0-rc7
+kms_flip@flip-vs-blocking-wf-vblank
diff --git a/drivers/gpu/drm/ci/xfails/vkms-none-skips.txt b/drivers/gpu/drm/ci/xfails/vkms-none-skips.txt
new file mode 100644
index 000000000000..fd5d1271115f
--- /dev/null
+++ b/drivers/gpu/drm/ci/xfails/vkms-none-skips.txt
@@ -0,0 +1,119 @@
+# keeps printing vkms_vblank_simulate: vblank timer overrun and never ends
+kms_invalid_mode@int-max-clock
+
+# Kernel panic
+kms_cursor_crc@cursor-rapid-movement-32x10
+# Oops: 0000 [#1] PREEMPT SMP NOPTI
+# CPU: 0 PID: 2635 Comm: kworker/u8:13 Not tainted 6.9.0-rc7-g40935263a1fd #1
+# Hardware name: ChromiumOS crosvm, BIOS 0
+# Workqueue: vkms_composer vkms_composer_worker [vkms]
+# RIP: 0010:compose_active_planes+0x1c7/0x4e0 [vkms]
+# Code: c9 0f 84 6a 01 00 00 8b 42 30 2b 42 28 41 39 c5 0f 8c 6f 01 00 00 49 83 c7 01 49 39 df 74 3b 4b 8b 34 fc 48 8b 96 48 01 00 00 <8b> 42 78 89 c1 83 e1 0a a8 20 74 b1 45 89 f5 41 f7 d5 44 03 6a 34
+# RSP: 0018:ffffbb4700c17d58 EFLAGS: 00010246
+# RAX: 0000000000000400 RBX: 0000000000000002 RCX: 0000000000000002
+# RDX: 0000000000000000 RSI: ffffa2ad0788c000 RDI: 00000000fff479a8
+# RBP: 0000000000000004 R08: 0000000000000000 R09: 0000000000000000
+# R10: ffffa2ad0bb14000 R11: 0000000000000000 R12: ffffa2ad03e21700
+# R13: 0000000000000003 R14: 0000000000000004 R15: 0000000000000000
+# FS: 0000000000000000(0000) GS:ffffa2ad2bc00000(0000) knlGS:0000000000000000
+# CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+# CR2: 0000000000000078 CR3: 000000010bd30000 CR4: 0000000000350ef0
+# Call Trace:
+# <TASK>
+# ? __die+0x1e/0x60
+# ? page_fault_oops+0x17b/0x490
+# ? exc_page_fault+0x6d/0x230
+# ? asm_exc_page_fault+0x26/0x30
+# ? compose_active_planes+0x1c7/0x4e0 [vkms]
+# ? compose_active_planes+0x2a3/0x4e0 [vkms]
+# ? srso_return_thunk+0x5/0x5f
+# vkms_composer_worker+0x205/0x240 [vkms]
+# process_one_work+0x1f4/0x6b0
+# ? lock_is_held_type+0x9e/0x110
+# worker_thread+0x17e/0x350
+# ? __pfx_worker_thread+0x10/0x10
+# kthread+0xce/0x100
+# ? __pfx_kthread+0x10/0x10
+# ret_from_fork+0x2f/0x50
+# ? __pfx_kthread+0x10/0x10
+# ret_from_fork_asm+0x1a/0x30
+# </TASK>
+# Modules linked in: vkms
+# CR2: 0000000000000078
+# ---[ end trace 0000000000000000 ]---
+# RIP: 0010:compose_active_planes+0x1c7/0x4e0 [vkms]
+# Code: c9 0f 84 6a 01 00 00 8b 42 30 2b 42 28 41 39 c5 0f 8c 6f 01 00 00 49 83 c7 01 49 39 df 74 3b 4b 8b 34 fc 48 8b 96 48 01 00 00 <8b> 42 78 89 c1 83 e1 0a a8 20 74 b1 45 89 f5 41 f7 d5 44 03 6a 34
+# RSP: 0018:ffffbb4700c17d58 EFLAGS: 00010246
+# RAX: 0000000000000400 RBX: 0000000000000002 RCX: 0000000000000002
+# RDX: 0000000000000000 RSI: ffffa2ad0788c000 RDI: 00000000fff479a8
+# RBP: 0000000000000004 R08: 0000000000000000 R09: 0000000000000000
+# R10: ffffa2ad0bb14000 R11: 0000000000000000 R12: ffffa2ad03e21700
+# R13: 0000000000000003 R14: 0000000000000004 R15: 0000000000000000
+# FS: 0000000000000000(0000) GS:ffffa2ad2bc00000(0000) knlGS:0000000000000000
+# CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+
+kms_cursor_crc@cursor-rapid-movement-256x85
+# [drm:drm_crtc_add_crc_entry] *ERROR* Overflow of CRC buffer, userspace reads too slow.
+# Oops: 0000 [#1] PREEMPT SMP NOPTI
+# CPU: 1 PID: 10 Comm: kworker/u8:0 Not tainted 6.9.0-rc7-g646381cde463 #1
+# Hardware name: ChromiumOS crosvm, BIOS 0
+# Workqueue: vkms_composer vkms_composer_worker [vkms]
+# RIP: 0010:compose_active_planes+0x1c7/0x4e0 [vkms]
+# Code: c9 0f 84 6a 01 00 00 8b 42 30 2b 42 28 41 39 c5 0f 8c 6f 01 00 00 49 83 c7 01 49 39 df 74 3b 4b 8b 34 fc 48 8b 96 48 01 00 00 <8b> 42 78 89 c1 83 e1 0a a8 20 74 b1 45 89 f5 41 f7 d5 44 03 6a 34
+# RSP: 0018:ffffa7e980057d58 EFLAGS: 00010246
+# RAX: 0000000000000400 RBX: 0000000000000002 RCX: 0000000000000002
+# RDX: 0000000000000000 RSI: ffff977987aa5c00 RDI: 000000001b43a85f
+# RBP: 0000000000000001 R08: 0000000000000000 R09: 0000000000000000
+# R10: ffff977981bf0000 R11: 0000000000000000 R12: ffff977989622590
+# R13: 0000000000000000 R14: 0000000000000001 R15: 0000000000000000
+# FS: 0000000000000000(0000) GS:ffff9779abd00000(0000) knlGS:0000000000000000
+# CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+# CR2: 0000000000000078 CR3: 0000000109b38000 CR4: 0000000000350ef0
+# Call Trace:
+# <TASK>
+# ? __die+0x1e/0x60
+# ? page_fault_oops+0x17b/0x490
+# ? exc_page_fault+0x6d/0x230
+# ? asm_exc_page_fault+0x26/0x30
+# ? compose_active_planes+0x1c7/0x4e0 [vkms]
+# ? compose_active_planes+0x2a3/0x4e0 [vkms]
+# ? srso_return_thunk+0x5/0x5f
+# vkms_composer_worker+0x205/0x240 [vkms]
+# process_one_work+0x1f4/0x6b0
+# ? lock_is_held_type+0x9e/0x110
+# worker_thread+0x17e/0x350
+# ? __pfx_worker_thread+0x10/0x10
+# kthread+0xce/0x100
+# ? __pfx_kthread+0x10/0x10
+# ret_from_fork+0x2f/0x50
+# ? __pfx_kthread+0x10/0x10
+# ret_from_fork_asm+0x1a/0x30
+# </TASK>
+# Modules linked in: vkms
+# CR2: 0000000000000078
+# ---[ end trace 0000000000000000 ]---
+# RIP: 0010:compose_active_planes+0x1c7/0x4e0 [vkms]
+# Code: c9 0f 84 6a 01 00 00 8b 42 30 2b 42 28 41 39 c5 0f 8c 6f 01 00 00 49 83 c7 01 49 39 df 74 3b 4b 8b 34 fc 48 8b 96 48 01 00 00 <8b> 42 78 89 c1 83 e1 0a a8 20 74 b1 45 89 f5 41 f7 d5 44 03 6a 34
+# RSP: 0018:ffffa7e980057d58 EFLAGS: 00010246
+# RAX: 0000000000000400 RBX: 0000000000000002 RCX: 0000000000000002
+# RDX: 0000000000000000 RSI: ffff977987aa5c00 RDI: 000000001b43a85f
+# RBP: 0000000000000001 R08: 0000000000000000 R09: 0000000000000000
+# R10: ffff977981bf0000 R11: 0000000000000000 R12: ffff977989622590
+# R13: 0000000000000000 R14: 0000000000000001 R15: 0000000000000000
+# FS: 0000000000000000(0000) GS:ffff9779abd00000(0000) knlGS:0000000000000000
+# CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+# CR2: 0000000000000078 CR3: 0000000109b38000 CR4: 0000000000350ef0
+
+# Skip driver specific tests
+^amdgpu.*
+msm_.*
+nouveau_.*
+panfrost_.*
+^v3d.*
+^vc4.*
+^vmwgfx*
+
+# Skip intel specific tests
+gem_.*
+i915_.*
+xe_.*
diff --git a/drivers/gpu/drm/display/Kconfig b/drivers/gpu/drm/display/Kconfig
index 864a6488bfdf..479e62690d75 100644
--- a/drivers/gpu/drm/display/Kconfig
+++ b/drivers/gpu/drm/display/Kconfig
@@ -70,3 +70,10 @@ config DRM_DISPLAY_HDMI_HELPER
depends on DRM_DISPLAY_HELPER
help
DRM display helpers for HDMI.
+
+config DRM_DISPLAY_HDMI_STATE_HELPER
+ bool
+ depends on DRM_DISPLAY_HELPER
+ select DRM_DISPLAY_HDMI_HELPER
+ help
+ DRM KMS state helpers for HDMI.
diff --git a/drivers/gpu/drm/display/Makefile b/drivers/gpu/drm/display/Makefile
index 17d2cc73ff56..629df2f4d322 100644
--- a/drivers/gpu/drm/display/Makefile
+++ b/drivers/gpu/drm/display/Makefile
@@ -14,6 +14,8 @@ drm_display_helper-$(CONFIG_DRM_DISPLAY_HDCP_HELPER) += drm_hdcp_helper.o
drm_display_helper-$(CONFIG_DRM_DISPLAY_HDMI_HELPER) += \
drm_hdmi_helper.o \
drm_scdc_helper.o
+drm_display_helper-$(CONFIG_DRM_DISPLAY_HDMI_STATE_HELPER) += \
+ drm_hdmi_state_helper.o
drm_display_helper-$(CONFIG_DRM_DISPLAY_DP_AUX_CHARDEV) += drm_dp_aux_dev.o
drm_display_helper-$(CONFIG_DRM_DISPLAY_DP_AUX_CEC) += drm_dp_cec.o
diff --git a/drivers/gpu/drm/display/drm_hdmi_helper.c b/drivers/gpu/drm/display/drm_hdmi_helper.c
index faf5e9efa7d3..74dd4d01dd9b 100644
--- a/drivers/gpu/drm/display/drm_hdmi_helper.c
+++ b/drivers/gpu/drm/display/drm_hdmi_helper.c
@@ -195,3 +195,64 @@ void drm_hdmi_avi_infoframe_content_type(struct hdmi_avi_infoframe *frame,
frame->itc = conn_state->content_type != DRM_MODE_CONTENT_TYPE_NO_DATA;
}
EXPORT_SYMBOL(drm_hdmi_avi_infoframe_content_type);
+
+/**
+ * drm_hdmi_compute_mode_clock() - Computes the TMDS Character Rate
+ * @mode: Display mode to compute the clock for
+ * @bpc: Bits per character
+ * @fmt: Output Pixel Format used
+ *
+ * Returns the TMDS Character Rate for a given mode, bpc count and output format.
+ *
+ * RETURNS:
+ * The TMDS Character Rate, in Hertz, or 0 on error.
+ */
+unsigned long long
+drm_hdmi_compute_mode_clock(const struct drm_display_mode *mode,
+ unsigned int bpc, enum hdmi_colorspace fmt)
+{
+ unsigned long long clock = mode->clock * 1000ULL;
+ unsigned int vic = drm_match_cea_mode(mode);
+
+ /*
+ * CTA-861-G Spec, section 5.4 - Color Coding and Quantization
+ * mandates that VIC 1 always uses 8 bpc.
+ */
+ if (vic == 1 && bpc != 8)
+ return 0;
+
+ if (fmt == HDMI_COLORSPACE_YUV422) {
+ /*
+ * HDMI 1.0 Spec, section 6.5 - Pixel Encoding states that
+ * YUV422 sends 24 bits over three channels, with Cb and Cr
+ * components being sent on odd and even pixels, respectively.
+ *
+ * If fewer than 12 bpc are sent, data are left justified.
+ */
+ if (bpc > 12)
+ return 0;
+
+ /*
+ * HDMI 1.0 Spec, section 6.5 - Pixel Encoding
+ * specifies that YUV422 sends two 12-bits components over
+ * three TMDS channels per pixel clock, which is equivalent to
+ * three 8-bits components over three channels used by RGB as
+ * far as the clock rate goes.
+ */
+ bpc = 8;
+ }
+
+ /*
+ * HDMI 2.0 Spec, Section 7.1 - YCbCr 4:2:0 Pixel Encoding
+ * specifies that YUV420 encoding is carried at a TMDS Character Rate
+ * equal to half the pixel clock rate.
+ */
+ if (fmt == HDMI_COLORSPACE_YUV420)
+ clock = clock / 2;
+
+ if (mode->flags & DRM_MODE_FLAG_DBLCLK)
+ clock = clock * 2;
+
+ return DIV_ROUND_CLOSEST_ULL(clock * bpc, 8);
+}
+EXPORT_SYMBOL(drm_hdmi_compute_mode_clock);
diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
new file mode 100644
index 000000000000..2dab3ad8ce64
--- /dev/null
+++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
@@ -0,0 +1,752 @@
+// SPDX-License-Identifier: MIT
+
+#include <drm/drm_atomic.h>
+#include <drm/drm_connector.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_print.h>
+
+#include <drm/display/drm_hdmi_helper.h>
+#include <drm/display/drm_hdmi_state_helper.h>
+
+/**
+ * __drm_atomic_helper_connector_hdmi_reset() - Initializes all HDMI @drm_connector_state resources
+ * @connector: DRM connector
+ * @new_conn_state: connector state to reset
+ *
+ * Initializes all HDMI resources from a @drm_connector_state without
+ * actually allocating it. This is useful for HDMI drivers, in
+ * combination with __drm_atomic_helper_connector_reset() or
+ * drm_atomic_helper_connector_reset().
+ */
+void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector,
+ struct drm_connector_state *new_conn_state)
+{
+ unsigned int max_bpc = connector->max_bpc;
+
+ new_conn_state->max_bpc = max_bpc;
+ new_conn_state->max_requested_bpc = max_bpc;
+ new_conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_AUTO;
+}
+EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset);
+
+static const struct drm_display_mode *
+connector_state_get_mode(const struct drm_connector_state *conn_state)
+{
+ struct drm_atomic_state *state;
+ struct drm_crtc_state *crtc_state;
+ struct drm_crtc *crtc;
+
+ state = conn_state->state;
+ if (!state)
+ return NULL;
+
+ crtc = conn_state->crtc;
+ if (!crtc)
+ return NULL;
+
+ crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+ if (!crtc_state)
+ return NULL;
+
+ return &crtc_state->mode;
+}
+
+static bool hdmi_is_limited_range(const struct drm_connector *connector,
+ const struct drm_connector_state *conn_state)
+{
+ const struct drm_display_info *info = &connector->display_info;
+ const struct drm_display_mode *mode =
+ connector_state_get_mode(conn_state);
+
+ /*
+ * The Broadcast RGB property only applies to RGB format, and
+ * i915 just assumes limited range for YCbCr output, so let's
+ * just do the same.
+ */
+ if (conn_state->hdmi.output_format != HDMI_COLORSPACE_RGB)
+ return true;
+
+ if (conn_state->hdmi.broadcast_rgb == DRM_HDMI_BROADCAST_RGB_FULL)
+ return false;
+
+ if (conn_state->hdmi.broadcast_rgb == DRM_HDMI_BROADCAST_RGB_LIMITED)
+ return true;
+
+ if (!info->is_hdmi)
+ return false;
+
+ return drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_LIMITED;
+}
+
+static bool
+sink_supports_format_bpc(const struct drm_connector *connector,
+ const struct drm_display_info *info,
+ const struct drm_display_mode *mode,
+ unsigned int format, unsigned int bpc)
+{
+ struct drm_device *dev = connector->dev;
+ u8 vic = drm_match_cea_mode(mode);
+
+ /*
+ * CTA-861-F, section 5.4 - Color Coding & Quantization states
+ * that the bpc must be 8, 10, 12 or 16 except for the default
+ * 640x480 VIC1 where the value must be 8.
+ *
+ * The definition of default here is ambiguous but the spec
+ * refers to VIC1 being the default timing in several occasions
+ * so our understanding is that for the default timing (ie,
+ * VIC1), the bpc must be 8.
+ */
+ if (vic == 1 && bpc != 8) {
+ drm_dbg_kms(dev, "VIC1 requires a bpc of 8, got %u\n", bpc);
+ return false;
+ }
+
+ if (!info->is_hdmi &&
+ (format != HDMI_COLORSPACE_RGB || bpc != 8)) {
+ drm_dbg_kms(dev, "DVI Monitors require an RGB output at 8 bpc\n");
+ return false;
+ }
+
+ if (!(connector->hdmi.supported_formats & BIT(format))) {
+ drm_dbg_kms(dev, "%s format unsupported by the connector.\n",
+ drm_hdmi_connector_get_output_format_name(format));
+ return false;
+ }
+
+ switch (format) {
+ case HDMI_COLORSPACE_RGB:
+ drm_dbg_kms(dev, "RGB Format, checking the constraints.\n");
+
+ /*
+ * In some cases, like when the EDID readout fails, or
+ * is not an HDMI compliant EDID for some reason, the
+ * color_formats field will be blank and not report any
+ * format supported. In such a case, assume that RGB is
+ * supported so we can keep things going and light up
+ * the display.
+ */
+ if (!(info->color_formats & DRM_COLOR_FORMAT_RGB444))
+ drm_warn(dev, "HDMI Sink doesn't support RGB, something's wrong.\n");
+
+ if (bpc == 10 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_30)) {
+ drm_dbg_kms(dev, "10 BPC but sink doesn't support Deep Color 30.\n");
+ return false;
+ }
+
+ if (bpc == 12 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_36)) {
+ drm_dbg_kms(dev, "12 BPC but sink doesn't support Deep Color 36.\n");
+ return false;
+ }
+
+ drm_dbg_kms(dev, "RGB format supported in that configuration.\n");
+
+ return true;
+
+ case HDMI_COLORSPACE_YUV420:
+ /* TODO: YUV420 is unsupported at the moment. */
+ drm_dbg_kms(dev, "YUV420 format isn't supported yet.\n");
+ return false;
+
+ case HDMI_COLORSPACE_YUV422:
+ drm_dbg_kms(dev, "YUV422 format, checking the constraints.\n");
+
+ if (!(info->color_formats & DRM_COLOR_FORMAT_YCBCR422)) {
+ drm_dbg_kms(dev, "Sink doesn't support YUV422.\n");
+ return false;
+ }
+
+ if (bpc > 12) {
+ drm_dbg_kms(dev, "YUV422 only supports 12 bpc or lower.\n");
+ return false;
+ }
+
+ /*
+ * HDMI Spec 1.3 - Section 6.5 Pixel Encodings and Color Depth
+ * states that Deep Color is not relevant for YUV422 so we
+ * don't need to check the Deep Color bits in the EDIDs here.
+ */
+
+ drm_dbg_kms(dev, "YUV422 format supported in that configuration.\n");
+
+ return true;
+
+ case HDMI_COLORSPACE_YUV444:
+ drm_dbg_kms(dev, "YUV444 format, checking the constraints.\n");
+
+ if (!(info->color_formats & DRM_COLOR_FORMAT_YCBCR444)) {
+ drm_dbg_kms(dev, "Sink doesn't support YUV444.\n");
+ return false;
+ }
+
+ if (bpc == 10 && !(info->edid_hdmi_ycbcr444_dc_modes & DRM_EDID_HDMI_DC_30)) {
+ drm_dbg_kms(dev, "10 BPC but sink doesn't support Deep Color 30.\n");
+ return false;
+ }
+
+ if (bpc == 12 && !(info->edid_hdmi_ycbcr444_dc_modes & DRM_EDID_HDMI_DC_36)) {
+ drm_dbg_kms(dev, "12 BPC but sink doesn't support Deep Color 36.\n");
+ return false;
+ }
+
+ drm_dbg_kms(dev, "YUV444 format supported in that configuration.\n");
+
+ return true;
+ }
+
+ drm_dbg_kms(dev, "Unsupported pixel format.\n");
+ return false;
+}
+
+static enum drm_mode_status
+hdmi_clock_valid(const struct drm_connector *connector,
+ const struct drm_display_mode *mode,
+ unsigned long long clock)
+{
+ const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs;
+ const struct drm_display_info *info = &connector->display_info;
+
+ if (info->max_tmds_clock && clock > info->max_tmds_clock * 1000)
+ return MODE_CLOCK_HIGH;
+
+ if (funcs && funcs->tmds_char_rate_valid) {
+ enum drm_mode_status status;
+
+ status = funcs->tmds_char_rate_valid(connector, mode, clock);
+ if (status != MODE_OK)
+ return status;
+ }
+
+ return MODE_OK;
+}
+
+static int
+hdmi_compute_clock(const struct drm_connector *connector,
+ struct drm_connector_state *conn_state,
+ const struct drm_display_mode *mode,
+ unsigned int bpc, enum hdmi_colorspace fmt)
+{
+ enum drm_mode_status status;
+ unsigned long long clock;
+
+ clock = drm_hdmi_compute_mode_clock(mode, bpc, fmt);
+ if (!clock)
+ return -EINVAL;
+
+ status = hdmi_clock_valid(connector, mode, clock);
+ if (status != MODE_OK)
+ return -EINVAL;
+
+ conn_state->hdmi.tmds_char_rate = clock;
+
+ return 0;
+}
+
+static bool
+hdmi_try_format_bpc(const struct drm_connector *connector,
+ struct drm_connector_state *conn_state,
+ const struct drm_display_mode *mode,
+ unsigned int bpc, enum hdmi_colorspace fmt)
+{
+ const struct drm_display_info *info = &connector->display_info;
+ struct drm_device *dev = connector->dev;
+ int ret;
+
+ drm_dbg_kms(dev, "Trying %s output format\n",
+ drm_hdmi_connector_get_output_format_name(fmt));
+
+ if (!sink_supports_format_bpc(connector, info, mode, fmt, bpc)) {
+ drm_dbg_kms(dev, "%s output format not supported with %u bpc\n",
+ drm_hdmi_connector_get_output_format_name(fmt),
+ bpc);
+ return false;
+ }
+
+ ret = hdmi_compute_clock(connector, conn_state, mode, bpc, fmt);
+ if (ret) {
+ drm_dbg_kms(dev, "Couldn't compute clock for %s output format and %u bpc\n",
+ drm_hdmi_connector_get_output_format_name(fmt),
+ bpc);
+ return false;
+ }
+
+ drm_dbg_kms(dev, "%s output format supported with %u (TMDS char rate: %llu Hz)\n",
+ drm_hdmi_connector_get_output_format_name(fmt),
+ bpc, conn_state->hdmi.tmds_char_rate);
+
+ return true;
+}
+
+static int
+hdmi_compute_format(const struct drm_connector *connector,
+ struct drm_connector_state *conn_state,
+ const struct drm_display_mode *mode,
+ unsigned int bpc)
+{
+ struct drm_device *dev = connector->dev;
+
+ /*
+ * TODO: Add support for YCbCr420 output for HDMI 2.0 capable
+ * devices, for modes that only support YCbCr420.
+ */
+ if (hdmi_try_format_bpc(connector, conn_state, mode, bpc, HDMI_COLORSPACE_RGB)) {
+ conn_state->hdmi.output_format = HDMI_COLORSPACE_RGB;
+ return 0;
+ }
+
+ drm_dbg_kms(dev, "Failed. No Format Supported for that bpc count.\n");
+
+ return -EINVAL;
+}
+
+static int
+hdmi_compute_config(const struct drm_connector *connector,
+ struct drm_connector_state *conn_state,
+ const struct drm_display_mode *mode)
+{
+ struct drm_device *dev = connector->dev;
+ unsigned int max_bpc = clamp_t(unsigned int,
+ conn_state->max_bpc,
+ 8, connector->max_bpc);
+ unsigned int bpc;
+ int ret;
+
+ for (bpc = max_bpc; bpc >= 8; bpc -= 2) {
+ drm_dbg_kms(dev, "Trying with a %d bpc output\n", bpc);
+
+ ret = hdmi_compute_format(connector, conn_state, mode, bpc);
+ if (ret)
+ continue;
+
+ conn_state->hdmi.output_bpc = bpc;
+
+ drm_dbg_kms(dev,
+ "Mode %ux%u @ %uHz: Found configuration: bpc: %u, fmt: %s, clock: %llu\n",
+ mode->hdisplay, mode->vdisplay, drm_mode_vrefresh(mode),
+ conn_state->hdmi.output_bpc,
+ drm_hdmi_connector_get_output_format_name(conn_state->hdmi.output_format),
+ conn_state->hdmi.tmds_char_rate);
+
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int hdmi_generate_avi_infoframe(const struct drm_connector *connector,
+ struct drm_connector_state *conn_state)
+{
+ const struct drm_display_mode *mode =
+ connector_state_get_mode(conn_state);
+ struct drm_connector_hdmi_infoframe *infoframe =
+ &conn_state->hdmi.infoframes.avi;
+ struct hdmi_avi_infoframe *frame =
+ &infoframe->data.avi;
+ bool is_limited_range = conn_state->hdmi.is_limited_range;
+ enum hdmi_quantization_range rgb_quant_range =
+ is_limited_range ? HDMI_QUANTIZATION_RANGE_LIMITED : HDMI_QUANTIZATION_RANGE_FULL;
+ int ret;
+
+ ret = drm_hdmi_avi_infoframe_from_display_mode(frame, connector, mode);
+ if (ret)
+ return ret;
+
+ frame->colorspace = conn_state->hdmi.output_format;
+
+ /*
+ * FIXME: drm_hdmi_avi_infoframe_quant_range() doesn't handle
+ * YUV formats at all at the moment, so if we ever support YUV
+ * formats this needs to be revised.
+ */
+ drm_hdmi_avi_infoframe_quant_range(frame, connector, mode, rgb_quant_range);
+ drm_hdmi_avi_infoframe_colorimetry(frame, conn_state);
+ drm_hdmi_avi_infoframe_bars(frame, conn_state);
+
+ infoframe->set = true;
+
+ return 0;
+}
+
+static int hdmi_generate_spd_infoframe(const struct drm_connector *connector,
+ struct drm_connector_state *conn_state)
+{
+ struct drm_connector_hdmi_infoframe *infoframe =
+ &conn_state->hdmi.infoframes.spd;
+ struct hdmi_spd_infoframe *frame =
+ &infoframe->data.spd;
+ int ret;
+
+ ret = hdmi_spd_infoframe_init(frame,
+ connector->hdmi.vendor,
+ connector->hdmi.product);
+ if (ret)
+ return ret;
+
+ frame->sdi = HDMI_SPD_SDI_PC;
+
+ infoframe->set = true;
+
+ return 0;
+}
+
+static int hdmi_generate_hdr_infoframe(const struct drm_connector *connector,
+ struct drm_connector_state *conn_state)
+{
+ struct drm_connector_hdmi_infoframe *infoframe =
+ &conn_state->hdmi.infoframes.hdr_drm;
+ struct hdmi_drm_infoframe *frame =
+ &infoframe->data.drm;
+ int ret;
+
+ if (connector->max_bpc < 10)
+ return 0;
+
+ if (!conn_state->hdr_output_metadata)
+ return 0;
+
+ ret = drm_hdmi_infoframe_set_hdr_metadata(frame, conn_state);
+ if (ret)
+ return ret;
+
+ infoframe->set = true;
+
+ return 0;
+}
+
+static int hdmi_generate_hdmi_vendor_infoframe(const struct drm_connector *connector,
+ struct drm_connector_state *conn_state)
+{
+ const struct drm_display_info *info = &connector->display_info;
+ const struct drm_display_mode *mode =
+ connector_state_get_mode(conn_state);
+ struct drm_connector_hdmi_infoframe *infoframe =
+ &conn_state->hdmi.infoframes.hdmi;
+ struct hdmi_vendor_infoframe *frame =
+ &infoframe->data.vendor.hdmi;
+ int ret;
+
+ if (!info->has_hdmi_infoframe)
+ return 0;
+
+ ret = drm_hdmi_vendor_infoframe_from_display_mode(frame, connector, mode);
+ if (ret)
+ return ret;
+
+ infoframe->set = true;
+
+ return 0;
+}
+
+static int
+hdmi_generate_infoframes(const struct drm_connector *connector,
+ struct drm_connector_state *conn_state)
+{
+ const struct drm_display_info *info = &connector->display_info;
+ int ret;
+
+ if (!info->is_hdmi)
+ return 0;
+
+ ret = hdmi_generate_avi_infoframe(connector, conn_state);
+ if (ret)
+ return ret;
+
+ ret = hdmi_generate_spd_infoframe(connector, conn_state);
+ if (ret)
+ return ret;
+
+ /*
+ * Audio Infoframes will be generated by ALSA, and updated by
+ * drm_atomic_helper_connector_hdmi_update_audio_infoframe().
+ */
+
+ ret = hdmi_generate_hdr_infoframe(connector, conn_state);
+ if (ret)
+ return ret;
+
+ ret = hdmi_generate_hdmi_vendor_infoframe(connector, conn_state);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+/**
+ * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector atomic state
+ * @connector: DRM Connector
+ * @state: the DRM State object
+ *
+ * Provides a default connector state check handler for HDMI connectors.
+ * Checks that a desired connector update is valid, and updates various
+ * fields of derived state.
+ *
+ * RETURNS:
+ * Zero on success, or an errno code otherwise.
+ */
+int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
+ struct drm_atomic_state *state)
+{
+ struct drm_connector_state *old_conn_state =
+ drm_atomic_get_old_connector_state(state, connector);
+ struct drm_connector_state *new_conn_state =
+ drm_atomic_get_new_connector_state(state, connector);
+ const struct drm_display_mode *mode =
+ connector_state_get_mode(new_conn_state);
+ int ret;
+
+ new_conn_state->hdmi.is_limited_range = hdmi_is_limited_range(connector, new_conn_state);
+
+ ret = hdmi_compute_config(connector, new_conn_state, mode);
+ if (ret)
+ return ret;
+
+ ret = hdmi_generate_infoframes(connector, new_conn_state);
+ if (ret)
+ return ret;
+
+ if (old_conn_state->hdmi.broadcast_rgb != new_conn_state->hdmi.broadcast_rgb ||
+ old_conn_state->hdmi.output_bpc != new_conn_state->hdmi.output_bpc ||
+ old_conn_state->hdmi.output_format != new_conn_state->hdmi.output_format) {
+ struct drm_crtc *crtc = new_conn_state->crtc;
+ struct drm_crtc_state *crtc_state;
+
+ crtc_state = drm_atomic_get_crtc_state(state, crtc);
+ if (IS_ERR(crtc_state))
+ return PTR_ERR(crtc_state);
+
+ crtc_state->mode_changed = true;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_check);
+
+#define HDMI_MAX_INFOFRAME_SIZE 29
+
+static int clear_device_infoframe(struct drm_connector *connector,
+ enum hdmi_infoframe_type type)
+{
+ const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs;
+ struct drm_device *dev = connector->dev;
+ int ret;
+
+ drm_dbg_kms(dev, "Clearing infoframe type 0x%x\n", type);
+
+ if (!funcs || !funcs->clear_infoframe) {
+ drm_dbg_kms(dev, "Function not implemented, bailing.\n");
+ return 0;
+ }
+
+ ret = funcs->clear_infoframe(connector, type);
+ if (ret) {
+ drm_dbg_kms(dev, "Call failed: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int clear_infoframe(struct drm_connector *connector,
+ struct drm_connector_hdmi_infoframe *old_frame)
+{
+ int ret;
+
+ ret = clear_device_infoframe(connector, old_frame->data.any.type);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int write_device_infoframe(struct drm_connector *connector,
+ union hdmi_infoframe *frame)
+{
+ const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs;
+ struct drm_device *dev = connector->dev;
+ u8 buffer[HDMI_MAX_INFOFRAME_SIZE];
+ int ret;
+ int len;
+
+ drm_dbg_kms(dev, "Writing infoframe type %x\n", frame->any.type);
+
+ if (!funcs || !funcs->write_infoframe) {
+ drm_dbg_kms(dev, "Function not implemented, bailing.\n");
+ return -EINVAL;
+ }
+
+ len = hdmi_infoframe_pack(frame, buffer, sizeof(buffer));
+ if (len < 0)
+ return len;
+
+ ret = funcs->write_infoframe(connector, frame->any.type, buffer, len);
+ if (ret) {
+ drm_dbg_kms(dev, "Call failed: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int write_infoframe(struct drm_connector *connector,
+ struct drm_connector_hdmi_infoframe *new_frame)
+{
+ int ret;
+
+ ret = write_device_infoframe(connector, &new_frame->data);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int write_or_clear_infoframe(struct drm_connector *connector,
+ struct drm_connector_hdmi_infoframe *old_frame,
+ struct drm_connector_hdmi_infoframe *new_frame)
+{
+ if (new_frame->set)
+ return write_infoframe(connector, new_frame);
+
+ if (old_frame->set && !new_frame->set)
+ return clear_infoframe(connector, old_frame);
+
+ return 0;
+}
+
+/**
+ * drm_atomic_helper_connector_hdmi_update_infoframes - Update the Infoframes
+ * @connector: A pointer to the HDMI connector
+ * @state: The HDMI connector state to generate the infoframe from
+ *
+ * This function is meant for HDMI connector drivers to write their
+ * infoframes. It will typically be used in a
+ * @drm_connector_helper_funcs.atomic_enable implementation.
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector,
+ struct drm_atomic_state *state)
+{
+ struct drm_connector_state *old_conn_state =
+ drm_atomic_get_old_connector_state(state, connector);
+ struct drm_connector_state *new_conn_state =
+ drm_atomic_get_new_connector_state(state, connector);
+ struct drm_display_info *info = &connector->display_info;
+ int ret;
+
+ if (!info->is_hdmi)
+ return 0;
+
+ mutex_lock(&connector->hdmi.infoframes.lock);
+
+ ret = write_or_clear_infoframe(connector,
+ &old_conn_state->hdmi.infoframes.avi,
+ &new_conn_state->hdmi.infoframes.avi);
+ if (ret)
+ goto out;
+
+ if (connector->hdmi.infoframes.audio.set) {
+ ret = write_infoframe(connector,
+ &connector->hdmi.infoframes.audio);
+ if (ret)
+ goto out;
+ }
+
+ ret = write_or_clear_infoframe(connector,
+ &old_conn_state->hdmi.infoframes.hdr_drm,
+ &new_conn_state->hdmi.infoframes.hdr_drm);
+ if (ret)
+ goto out;
+
+ ret = write_or_clear_infoframe(connector,
+ &old_conn_state->hdmi.infoframes.spd,
+ &new_conn_state->hdmi.infoframes.spd);
+ if (ret)
+ goto out;
+
+ if (info->has_hdmi_infoframe) {
+ ret = write_or_clear_infoframe(connector,
+ &old_conn_state->hdmi.infoframes.hdmi,
+ &new_conn_state->hdmi.infoframes.hdmi);
+ if (ret)
+ goto out;
+ }
+
+out:
+ mutex_unlock(&connector->hdmi.infoframes.lock);
+ return ret;
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_update_infoframes);
+
+/**
+ * drm_atomic_helper_connector_hdmi_update_audio_infoframe - Update the Audio Infoframe
+ * @connector: A pointer to the HDMI connector
+ * @frame: A pointer to the audio infoframe to write
+ *
+ * This function is meant for HDMI connector drivers to update their
+ * audio infoframe. It will typically be used in one of the ALSA hooks
+ * (most likely prepare).
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int
+drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector *connector,
+ struct hdmi_audio_infoframe *frame)
+{
+ struct drm_connector_hdmi_infoframe *infoframe =
+ &connector->hdmi.infoframes.audio;
+ struct drm_display_info *info = &connector->display_info;
+ int ret;
+
+ if (!info->is_hdmi)
+ return 0;
+
+ mutex_lock(&connector->hdmi.infoframes.lock);
+
+ memcpy(&infoframe->data, frame, sizeof(infoframe->data));
+ infoframe->set = true;
+
+ ret = write_infoframe(connector, infoframe);
+
+ mutex_unlock(&connector->hdmi.infoframes.lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_update_audio_infoframe);
+
+/**
+ * drm_atomic_helper_connector_hdmi_disable_audio_infoframe - Stop sending the Audio Infoframe
+ * @connector: A pointer to the HDMI connector
+ *
+ * This function is meant for HDMI connector drivers to stop sending their
+ * audio infoframe. It will typically be used in one of the ALSA hooks
+ * (most likely shutdown).
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int
+drm_atomic_helper_connector_hdmi_disable_audio_infoframe(struct drm_connector *connector)
+{
+ struct drm_connector_hdmi_infoframe *infoframe =
+ &connector->hdmi.infoframes.audio;
+ struct drm_display_info *info = &connector->display_info;
+ int ret;
+
+ if (!info->is_hdmi)
+ return 0;
+
+ mutex_lock(&connector->hdmi.infoframes.lock);
+
+ infoframe->set = false;
+
+ ret = clear_infoframe(connector, infoframe);
+
+ memset(&infoframe->data, 0, sizeof(infoframe->data));
+
+ mutex_unlock(&connector->hdmi.infoframes.lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_disable_audio_infoframe);
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index a91737adf8e7..07b4b394e3bf 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1143,6 +1143,17 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
drm_printf(p, "\tmax_requested_bpc=%d\n", state->max_requested_bpc);
drm_printf(p, "\tcolorspace=%s\n", drm_get_colorspace_name(state->colorspace));
+ if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
+ connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) {
+ drm_printf(p, "\tbroadcast_rgb=%s\n",
+ drm_hdmi_connector_get_broadcast_rgb_name(state->hdmi.broadcast_rgb));
+ drm_printf(p, "\tis_limited_range=%c\n", state->hdmi.is_limited_range ? 'y' : 'n');
+ drm_printf(p, "\toutput_bpc=%u\n", state->hdmi.output_bpc);
+ drm_printf(p, "\toutput_format=%s\n",
+ drm_hdmi_connector_get_output_format_name(state->hdmi.output_format));
+ drm_printf(p, "\ttmds_char_rate=%llu\n", state->hdmi.tmds_char_rate);
+ }
+
if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
if (state->writeback_job && state->writeback_job->fb)
drm_printf(p, "\tfb=%d\n", state->writeback_job->fb->base.id);
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index fc16fddee5c5..22bbb2d83e30 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -776,6 +776,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
state->max_requested_bpc = val;
} else if (property == connector->privacy_screen_sw_state_property) {
state->privacy_screen_sw_state = val;
+ } else if (property == connector->broadcast_rgb_property) {
+ state->hdmi.broadcast_rgb = val;
} else if (connector->funcs->atomic_set_property) {
return connector->funcs->atomic_set_property(connector,
state, property, val);
@@ -859,6 +861,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
*val = state->max_requested_bpc;
} else if (property == connector->privacy_screen_sw_state_property) {
*val = state->privacy_screen_sw_state;
+ } else if (property == connector->broadcast_rgb_property) {
+ *val = state->hdmi.broadcast_rgb;
} else if (connector->funcs->atomic_get_property) {
return connector->funcs->atomic_get_property(connector,
state, property, val);
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index 28abe9aa99ca..d44f055dbe3e 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -353,13 +353,8 @@ err_reset_bridge:
bridge->encoder = NULL;
list_del(&bridge->chain_node);
-#ifdef CONFIG_OF
DRM_ERROR("failed to attach bridge %pOF to encoder %s: %d\n",
bridge->of_node, encoder->name, ret);
-#else
- DRM_ERROR("failed to attach bridge to encoder %s: %d\n",
- encoder->name, ret);
-#endif
return ret;
}
@@ -473,43 +468,6 @@ void drm_bridge_detach(struct drm_bridge *bridge)
*/
/**
- * drm_bridge_chain_mode_fixup - fixup proposed mode for all bridges in the
- * encoder chain
- * @bridge: bridge control structure
- * @mode: desired mode to be set for the bridge
- * @adjusted_mode: updated mode that works for this bridge
- *
- * Calls &drm_bridge_funcs.mode_fixup for all the bridges in the
- * encoder chain, starting from the first bridge to the last.
- *
- * Note: the bridge passed should be the one closest to the encoder
- *
- * RETURNS:
- * true on success, false on failure
- */
-bool drm_bridge_chain_mode_fixup(struct drm_bridge *bridge,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- struct drm_encoder *encoder;
-
- if (!bridge)
- return true;
-
- encoder = bridge->encoder;
- list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
- if (!bridge->funcs->mode_fixup)
- continue;
-
- if (!bridge->funcs->mode_fixup(bridge, mode, adjusted_mode))
- return false;
- }
-
- return true;
-}
-EXPORT_SYMBOL(drm_bridge_chain_mode_fixup);
-
-/**
* drm_bridge_chain_mode_valid - validate the mode against all bridges in the
* encoder chain.
* @bridge: bridge control structure
diff --git a/drivers/gpu/drm/drm_bridge_connector.c b/drivers/gpu/drm/drm_bridge_connector.c
index 982552c9f92c..0869b663f17e 100644
--- a/drivers/gpu/drm/drm_bridge_connector.c
+++ b/drivers/gpu/drm/drm_bridge_connector.c
@@ -15,8 +15,10 @@
#include <drm/drm_connector.h>
#include <drm/drm_device.h>
#include <drm/drm_edid.h>
+#include <drm/drm_managed.h>
#include <drm/drm_modeset_helper_vtables.h>
#include <drm/drm_probe_helper.h>
+#include <drm/display/drm_hdmi_state_helper.h>
/**
* DOC: overview
@@ -86,6 +88,13 @@ struct drm_bridge_connector {
* connector modes detection, if any (see &DRM_BRIDGE_OP_MODES).
*/
struct drm_bridge *bridge_modes;
+ /**
+ * @bridge_hdmi:
+ *
+ * The bridge in the chain that implements necessary support for the
+ * HDMI connector infrastructure, if any (see &DRM_BRIDGE_OP_HDMI).
+ */
+ struct drm_bridge *bridge_hdmi;
};
#define to_drm_bridge_connector(x) \
@@ -193,19 +202,6 @@ drm_bridge_connector_detect(struct drm_connector *connector, bool force)
return status;
}
-static void drm_bridge_connector_destroy(struct drm_connector *connector)
-{
- struct drm_bridge_connector *bridge_connector =
- to_drm_bridge_connector(connector);
-
- drm_connector_unregister(connector);
- drm_connector_cleanup(connector);
-
- fwnode_handle_put(connector->fwnode);
-
- kfree(bridge_connector);
-}
-
static void drm_bridge_connector_debugfs_init(struct drm_connector *connector,
struct dentry *root)
{
@@ -224,7 +220,6 @@ static const struct drm_connector_funcs drm_bridge_connector_funcs = {
.reset = drm_atomic_helper_connector_reset,
.detect = drm_bridge_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
- .destroy = drm_bridge_connector_destroy,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
.debugfs_init = drm_bridge_connector_debugfs_init,
@@ -300,6 +295,60 @@ static const struct drm_connector_helper_funcs drm_bridge_connector_helper_funcs
.disable_hpd = drm_bridge_connector_disable_hpd,
};
+static enum drm_mode_status
+drm_bridge_connector_tmds_char_rate_valid(const struct drm_connector *connector,
+ const struct drm_display_mode *mode,
+ unsigned long long tmds_rate)
+{
+ struct drm_bridge_connector *bridge_connector =
+ to_drm_bridge_connector(connector);
+ struct drm_bridge *bridge;
+
+ bridge = bridge_connector->bridge_hdmi;
+ if (!bridge)
+ return MODE_ERROR;
+
+ if (bridge->funcs->hdmi_tmds_char_rate_valid)
+ return bridge->funcs->hdmi_tmds_char_rate_valid(bridge, mode, tmds_rate);
+ else
+ return MODE_OK;
+}
+
+static int drm_bridge_connector_clear_infoframe(struct drm_connector *connector,
+ enum hdmi_infoframe_type type)
+{
+ struct drm_bridge_connector *bridge_connector =
+ to_drm_bridge_connector(connector);
+ struct drm_bridge *bridge;
+
+ bridge = bridge_connector->bridge_hdmi;
+ if (!bridge)
+ return -EINVAL;
+
+ return bridge->funcs->hdmi_clear_infoframe(bridge, type);
+}
+
+static int drm_bridge_connector_write_infoframe(struct drm_connector *connector,
+ enum hdmi_infoframe_type type,
+ const u8 *buffer, size_t len)
+{
+ struct drm_bridge_connector *bridge_connector =
+ to_drm_bridge_connector(connector);
+ struct drm_bridge *bridge;
+
+ bridge = bridge_connector->bridge_hdmi;
+ if (!bridge)
+ return -EINVAL;
+
+ return bridge->funcs->hdmi_write_infoframe(bridge, type, buffer, len);
+}
+
+static const struct drm_connector_hdmi_funcs drm_bridge_connector_hdmi_funcs = {
+ .tmds_char_rate_valid = drm_bridge_connector_tmds_char_rate_valid,
+ .clear_infoframe = drm_bridge_connector_clear_infoframe,
+ .write_infoframe = drm_bridge_connector_write_infoframe,
+};
+
/* -----------------------------------------------------------------------------
* Bridge Connector Initialisation
*/
@@ -325,10 +374,12 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
struct drm_connector *connector;
struct i2c_adapter *ddc = NULL;
struct drm_bridge *bridge, *panel_bridge = NULL;
+ unsigned int supported_formats = BIT(HDMI_COLORSPACE_RGB);
+ unsigned int max_bpc = 8;
int connector_type;
int ret;
- bridge_connector = kzalloc(sizeof(*bridge_connector), GFP_KERNEL);
+ bridge_connector = drmm_kzalloc(drm, sizeof(*bridge_connector), GFP_KERNEL);
if (!bridge_connector)
return ERR_PTR(-ENOMEM);
@@ -361,6 +412,20 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
bridge_connector->bridge_detect = bridge;
if (bridge->ops & DRM_BRIDGE_OP_MODES)
bridge_connector->bridge_modes = bridge;
+ if (bridge->ops & DRM_BRIDGE_OP_HDMI) {
+ if (bridge_connector->bridge_hdmi)
+ return ERR_PTR(-EBUSY);
+ if (!bridge->funcs->hdmi_write_infoframe ||
+ !bridge->funcs->hdmi_clear_infoframe)
+ return ERR_PTR(-EINVAL);
+
+ bridge_connector->bridge_hdmi = bridge;
+
+ if (bridge->supported_formats)
+ supported_formats = bridge->supported_formats;
+ if (bridge->max_bpc)
+ max_bpc = bridge->max_bpc;
+ }
if (!drm_bridge_get_next_bridge(bridge))
connector_type = bridge->type;
@@ -383,7 +448,17 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
return ERR_PTR(-EINVAL);
}
- ret = drm_connector_init_with_ddc(drm, connector,
+ if (bridge_connector->bridge_hdmi)
+ ret = drmm_connector_hdmi_init(drm, connector,
+ bridge_connector->bridge_hdmi->vendor,
+ bridge_connector->bridge_hdmi->product,
+ &drm_bridge_connector_funcs,
+ &drm_bridge_connector_hdmi_funcs,
+ connector_type, ddc,
+ supported_formats,
+ max_bpc);
+ else
+ ret = drmm_connector_init(drm, connector,
&drm_bridge_connector_funcs,
connector_type, ddc);
if (ret) {
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 4d2df7f64dc5..ab6ab7ff7ea8 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -278,6 +278,7 @@ static int __drm_connector_init(struct drm_device *dev,
INIT_LIST_HEAD(&connector->modes);
mutex_init(&connector->mutex);
mutex_init(&connector->edid_override_mutex);
+ mutex_init(&connector->hdmi.infoframes.lock);
connector->edid_blob_ptr = NULL;
connector->epoch_counter = 0;
connector->tile_blob_ptr = NULL;
@@ -453,6 +454,86 @@ int drmm_connector_init(struct drm_device *dev,
EXPORT_SYMBOL(drmm_connector_init);
/**
+ * drmm_connector_hdmi_init - Init a preallocated HDMI connector
+ * @dev: DRM device
+ * @connector: A pointer to the HDMI connector to init
+ * @vendor: HDMI Controller Vendor name
+ * @product: HDMI Controller Product name
+ * @funcs: callbacks for this connector
+ * @hdmi_funcs: HDMI-related callbacks for this connector
+ * @connector_type: user visible type of the connector
+ * @ddc: optional pointer to the associated ddc adapter
+ * @supported_formats: Bitmask of @hdmi_colorspace listing supported output formats
+ * @max_bpc: Maximum bits per char the HDMI connector supports
+ *
+ * Initialises a preallocated HDMI connector. Connectors can be
+ * subclassed as part of driver connector objects.
+ *
+ * Cleanup is automatically handled with a call to
+ * drm_connector_cleanup() in a DRM-managed action.
+ *
+ * The connector structure should be allocated with drmm_kzalloc().
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drmm_connector_hdmi_init(struct drm_device *dev,
+ struct drm_connector *connector,
+ const char *vendor, const char *product,
+ const struct drm_connector_funcs *funcs,
+ const struct drm_connector_hdmi_funcs *hdmi_funcs,
+ int connector_type,
+ struct i2c_adapter *ddc,
+ unsigned long supported_formats,
+ unsigned int max_bpc)
+{
+ int ret;
+
+ if (!vendor || !product)
+ return -EINVAL;
+
+ if ((strlen(vendor) > DRM_CONNECTOR_HDMI_VENDOR_LEN) ||
+ (strlen(product) > DRM_CONNECTOR_HDMI_PRODUCT_LEN))
+ return -EINVAL;
+
+ if (!(connector_type == DRM_MODE_CONNECTOR_HDMIA ||
+ connector_type == DRM_MODE_CONNECTOR_HDMIB))
+ return -EINVAL;
+
+ if (!supported_formats || !(supported_formats & BIT(HDMI_COLORSPACE_RGB)))
+ return -EINVAL;
+
+ if (!(max_bpc == 8 || max_bpc == 10 || max_bpc == 12))
+ return -EINVAL;
+
+ ret = drmm_connector_init(dev, connector, funcs, connector_type, ddc);
+ if (ret)
+ return ret;
+
+ connector->hdmi.supported_formats = supported_formats;
+ strtomem_pad(connector->hdmi.vendor, vendor, 0);
+ strtomem_pad(connector->hdmi.product, product, 0);
+
+ /*
+ * drm_connector_attach_max_bpc_property() requires the
+ * connector to have a state.
+ */
+ if (connector->funcs->reset)
+ connector->funcs->reset(connector);
+
+ drm_connector_attach_max_bpc_property(connector, 8, max_bpc);
+ connector->max_bpc = max_bpc;
+
+ if (max_bpc > 8)
+ drm_connector_attach_hdr_output_metadata_property(connector);
+
+ connector->hdmi.funcs = hdmi_funcs;
+
+ return 0;
+}
+EXPORT_SYMBOL(drmm_connector_hdmi_init);
+
+/**
* drm_connector_attach_edid_property - attach edid property.
* @connector: the connector
*
@@ -584,6 +665,7 @@ void drm_connector_cleanup(struct drm_connector *connector)
connector->funcs->atomic_destroy_state(connector,
connector->state);
+ mutex_destroy(&connector->hdmi.infoframes.lock);
mutex_destroy(&connector->mutex);
memset(connector, 0, sizeof(*connector));
@@ -1005,6 +1087,7 @@ static const struct drm_prop_enum_list drm_tv_mode_enum_list[] = {
{ DRM_MODE_TV_MODE_PAL_M, "PAL-M" },
{ DRM_MODE_TV_MODE_PAL_N, "PAL-N" },
{ DRM_MODE_TV_MODE_SECAM, "SECAM" },
+ { DRM_MODE_TV_MODE_MONOCHROME, "Mono" },
};
DRM_ENUM_NAME_FN(drm_get_tv_mode_name, drm_tv_mode_enum_list)
@@ -1144,6 +1227,53 @@ static const u32 dp_colorspaces =
BIT(DRM_MODE_COLORIMETRY_BT2020_CYCC) |
BIT(DRM_MODE_COLORIMETRY_BT2020_YCC);
+static const struct drm_prop_enum_list broadcast_rgb_names[] = {
+ { DRM_HDMI_BROADCAST_RGB_AUTO, "Automatic" },
+ { DRM_HDMI_BROADCAST_RGB_FULL, "Full" },
+ { DRM_HDMI_BROADCAST_RGB_LIMITED, "Limited 16:235" },
+};
+
+/*
+ * drm_hdmi_connector_get_broadcast_rgb_name - Return a string for HDMI connector RGB broadcast selection
+ * @broadcast_rgb: Broadcast RGB selection to compute name of
+ *
+ * Returns: the name of the Broadcast RGB selection, or NULL if the type
+ * is not valid.
+ */
+const char *
+drm_hdmi_connector_get_broadcast_rgb_name(enum drm_hdmi_broadcast_rgb broadcast_rgb)
+{
+ if (broadcast_rgb >= ARRAY_SIZE(broadcast_rgb_names))
+ return NULL;
+
+ return broadcast_rgb_names[broadcast_rgb].name;
+}
+EXPORT_SYMBOL(drm_hdmi_connector_get_broadcast_rgb_name);
+
+static const char * const output_format_str[] = {
+ [HDMI_COLORSPACE_RGB] = "RGB",
+ [HDMI_COLORSPACE_YUV420] = "YUV 4:2:0",
+ [HDMI_COLORSPACE_YUV422] = "YUV 4:2:2",
+ [HDMI_COLORSPACE_YUV444] = "YUV 4:4:4",
+};
+
+/*
+ * drm_hdmi_connector_get_output_format_name() - Return a string for HDMI connector output format
+ * @fmt: Output format to compute name of
+ *
+ * Returns: the name of the output format, or NULL if the type is not
+ * valid.
+ */
+const char *
+drm_hdmi_connector_get_output_format_name(enum hdmi_colorspace fmt)
+{
+ if (fmt >= ARRAY_SIZE(output_format_str))
+ return NULL;
+
+ return output_format_str[fmt];
+}
+EXPORT_SYMBOL(drm_hdmi_connector_get_output_format_name);
+
/**
* DOC: standard connector properties
*
@@ -1616,6 +1746,38 @@ EXPORT_SYMBOL(drm_connector_attach_dp_subconnector_property);
/**
* DOC: HDMI connector properties
*
+ * Broadcast RGB (HDMI specific)
+ * Indicates the Quantization Range (Full vs Limited) used. The color
+ * processing pipeline will be adjusted to match the value of the
+ * property, and the Infoframes will be generated and sent accordingly.
+ *
+ * This property is only relevant if the HDMI output format is RGB. If
+ * it's one of the YCbCr variant, it will be ignored.
+ *
+ * The CRTC attached to the connector must be configured by user-space to
+ * always produce full-range pixels.
+ *
+ * The value of this property can be one of the following:
+ *
+ * Automatic:
+ * The quantization range is selected automatically based on the
+ * mode according to the HDMI specifications (HDMI 1.4b - Section
+ * 6.6 - Video Quantization Ranges).
+ *
+ * Full:
+ * Full quantization range is forced.
+ *
+ * Limited 16:235:
+ * Limited quantization range is forced. Unlike the name suggests,
+ * this works for any number of bits-per-component.
+ *
+ * Property values other than Automatic can result in colors being off (if
+ * limited is selected but the display expects full), or a black screen
+ * (if full is selected but the display expects limited).
+ *
+ * Drivers can set up this property by calling
+ * drm_connector_attach_broadcast_rgb_property().
+ *
* content type (HDMI specific):
* Indicates content type setting to be used in HDMI infoframes to indicate
* content type for the external device, so that it adjusts its display
@@ -1697,6 +1859,12 @@ EXPORT_SYMBOL(drm_connector_attach_dp_subconnector_property);
* TV Mode is CCIR System B (aka 625-lines) together with
* the SECAM Color Encoding.
*
+ * Mono:
+ *
+ * Use timings appropriate to the DRM mode, including
+ * equalizing pulses for a 525-line or 625-line mode,
+ * with no pedestal or color encoding.
+ *
* Drivers can set up this property by calling
* drm_mode_create_tv_properties().
*/
@@ -2479,6 +2647,39 @@ int drm_connector_attach_hdr_output_metadata_property(struct drm_connector *conn
EXPORT_SYMBOL(drm_connector_attach_hdr_output_metadata_property);
/**
+ * drm_connector_attach_broadcast_rgb_property - attach "Broadcast RGB" property
+ * @connector: connector to attach the property on.
+ *
+ * This is used to add support for forcing the RGB range on a connector
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_connector_attach_broadcast_rgb_property(struct drm_connector *connector)
+{
+ struct drm_device *dev = connector->dev;
+ struct drm_property *prop;
+
+ prop = connector->broadcast_rgb_property;
+ if (!prop) {
+ prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM,
+ "Broadcast RGB",
+ broadcast_rgb_names,
+ ARRAY_SIZE(broadcast_rgb_names));
+ if (!prop)
+ return -EINVAL;
+
+ connector->broadcast_rgb_property = prop;
+ }
+
+ drm_object_attach_property(&connector->base, prop,
+ DRM_HDMI_BROADCAST_RGB_AUTO);
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_broadcast_rgb_property);
+
+/**
* drm_connector_attach_colorspace_property - attach "Colorspace" property
* @connector: connector to attach the property on.
*
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
index 25aaae937ceb..20e9d7b206a2 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -303,6 +303,8 @@ const u8 *drm_edid_find_extension(const struct drm_edid *drm_edid,
int ext_id, int *ext_index);
void drm_edid_cta_sad_get(const struct cea_sad *cta_sad, u8 *sad);
void drm_edid_cta_sad_set(struct cea_sad *cta_sad, const u8 *sad);
+ssize_t drm_edid_connector_property_show(struct drm_connector *connector,
+ char *buf, loff_t off, size_t count);
/* drm_edid_load.c */
#ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
index 08fcefd804bc..6b239a24f1df 100644
--- a/drivers/gpu/drm/drm_debugfs.c
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -520,6 +520,156 @@ static const struct file_operations drm_connector_fops = {
.write = connector_write
};
+#define HDMI_MAX_INFOFRAME_SIZE 29
+
+static ssize_t
+audio_infoframe_read(struct file *filp, char __user *ubuf, size_t count, loff_t *ppos)
+{
+ struct drm_connector_hdmi_infoframe *infoframe;
+ struct drm_connector *connector;
+ union hdmi_infoframe *frame;
+ u8 buf[HDMI_INFOFRAME_SIZE(AUDIO)];
+ ssize_t len = 0;
+
+ connector = filp->private_data;
+ mutex_lock(&connector->hdmi.infoframes.lock);
+
+ infoframe = &connector->hdmi.infoframes.audio;
+ if (!infoframe->set)
+ goto out;
+
+ frame = &infoframe->data;
+ len = hdmi_infoframe_pack(frame, buf, sizeof(buf));
+ if (len < 0)
+ goto out;
+
+ len = simple_read_from_buffer(ubuf, count, ppos, buf, len);
+
+out:
+ mutex_unlock(&connector->hdmi.infoframes.lock);
+ return len;
+}
+
+static const struct file_operations audio_infoframe_fops = {
+ .owner = THIS_MODULE,
+ .open = simple_open,
+ .read = audio_infoframe_read,
+};
+
+static int create_hdmi_audio_infoframe_file(struct drm_connector *connector,
+ struct dentry *parent)
+{
+ struct dentry *file;
+
+ file = debugfs_create_file("audio", 0400, parent, connector, &audio_infoframe_fops);
+ if (IS_ERR(file))
+ return PTR_ERR(file);
+
+ return 0;
+}
+
+#define DEFINE_INFOFRAME_FILE(_f) \
+static ssize_t _f##_read_infoframe(struct file *filp, \
+ char __user *ubuf, \
+ size_t count, \
+ loff_t *ppos) \
+{ \
+ struct drm_connector_hdmi_infoframe *infoframe; \
+ struct drm_connector_state *conn_state; \
+ struct drm_connector *connector; \
+ union hdmi_infoframe *frame; \
+ struct drm_device *dev; \
+ u8 buf[HDMI_MAX_INFOFRAME_SIZE]; \
+ ssize_t len = 0; \
+ \
+ connector = filp->private_data; \
+ dev = connector->dev; \
+ \
+ drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); \
+ \
+ conn_state = connector->state; \
+ infoframe = &conn_state->hdmi.infoframes._f; \
+ if (!infoframe->set) \
+ goto out; \
+ \
+ frame = &infoframe->data; \
+ len = hdmi_infoframe_pack(frame, buf, sizeof(buf)); \
+ if (len < 0) \
+ goto out; \
+ \
+ len = simple_read_from_buffer(ubuf, count, ppos, buf, len); \
+ \
+out: \
+ drm_modeset_unlock(&dev->mode_config.connection_mutex); \
+ return len; \
+} \
+\
+static const struct file_operations _f##_infoframe_fops = { \
+ .owner = THIS_MODULE, \
+ .open = simple_open, \
+ .read = _f##_read_infoframe, \
+}; \
+\
+static int create_hdmi_## _f ## _infoframe_file(struct drm_connector *connector, \
+ struct dentry *parent) \
+{ \
+ struct dentry *file; \
+ \
+ file = debugfs_create_file(#_f, 0400, parent, connector, &_f ## _infoframe_fops); \
+ if (IS_ERR(file)) \
+ return PTR_ERR(file); \
+ \
+ return 0; \
+}
+
+DEFINE_INFOFRAME_FILE(avi);
+DEFINE_INFOFRAME_FILE(hdmi);
+DEFINE_INFOFRAME_FILE(hdr_drm);
+DEFINE_INFOFRAME_FILE(spd);
+
+static int create_hdmi_infoframe_files(struct drm_connector *connector,
+ struct dentry *parent)
+{
+ int ret;
+
+ ret = create_hdmi_audio_infoframe_file(connector, parent);
+ if (ret)
+ return ret;
+
+ ret = create_hdmi_avi_infoframe_file(connector, parent);
+ if (ret)
+ return ret;
+
+ ret = create_hdmi_hdmi_infoframe_file(connector, parent);
+ if (ret)
+ return ret;
+
+ ret = create_hdmi_hdr_drm_infoframe_file(connector, parent);
+ if (ret)
+ return ret;
+
+ ret = create_hdmi_spd_infoframe_file(connector, parent);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static void hdmi_debugfs_add(struct drm_connector *connector)
+{
+ struct dentry *dir;
+
+ if (!(connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
+ connector->connector_type == DRM_MODE_CONNECTOR_HDMIB))
+ return;
+
+ dir = debugfs_create_dir("infoframes", connector->debugfs_entry);
+ if (IS_ERR(dir))
+ return;
+
+ create_hdmi_infoframe_files(connector, dir);
+}
+
void drm_debugfs_connector_add(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
@@ -547,6 +697,8 @@ void drm_debugfs_connector_add(struct drm_connector *connector)
debugfs_create_file("output_bpc", 0444, root, connector,
&output_bpc_fops);
+ hdmi_debugfs_add(connector);
+
if (connector->funcs->debugfs_init)
connector->funcs->debugfs_init(connector, root);
}
@@ -597,10 +749,10 @@ static int bridges_show(struct seq_file *m, void *data)
drm_printf(&p, "\ttype: [%d] %s\n",
bridge->type,
drm_get_connector_type_name(bridge->type));
-#ifdef CONFIG_OF
+
if (bridge->of_node)
drm_printf(&p, "\tOF: %pOFfc\n", bridge->of_node);
-#endif
+
drm_printf(&p, "\tops: [0x%x]", bridge->ops);
if (bridge->ops & DRM_BRIDGE_OP_DETECT)
drm_puts(&p, " detect");
@@ -610,6 +762,8 @@ static int bridges_show(struct seq_file *m, void *data)
drm_puts(&p, " hpd");
if (bridge->ops & DRM_BRIDGE_OP_MODES)
drm_puts(&p, " modes");
+ if (bridge->ops & DRM_BRIDGE_OP_HDMI)
+ drm_puts(&p, " hdmi");
drm_puts(&p, "\n");
}
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 535b624d4c9d..93543071a500 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -346,7 +346,7 @@ void drm_minor_release(struct drm_minor *minor)
* if (ret)
* return ret;
*
- * drm_fbdev_generic_setup(drm, 32);
+ * drm_fbdev_{...}_setup(drm, 32);
*
* return 0;
* }
@@ -947,9 +947,9 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags)
}
drm_panic_register(dev);
- DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
+ DRM_INFO("Initialized %s %d.%d.%d for %s on minor %d\n",
driver->name, driver->major, driver->minor,
- driver->patchlevel, driver->date,
+ driver->patchlevel,
dev->dev ? dev_name(dev->dev) : "virtual device",
dev->primary ? dev->primary->index : dev->accel->index);
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 4f54c91b31b2..f68a41eeb1fa 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2465,34 +2465,6 @@ fail:
}
/**
- * drm_do_get_edid - get EDID data using a custom EDID block read function
- * @connector: connector we're probing
- * @read_block: EDID block read function
- * @context: private data passed to the block read function
- *
- * When the I2C adapter connected to the DDC bus is hidden behind a device that
- * exposes a different interface to read EDID blocks this function can be used
- * to get EDID data using a custom block read function.
- *
- * As in the general case the DDC bus is accessible by the kernel at the I2C
- * level, drivers must make all reasonable efforts to expose it as an I2C
- * adapter and use drm_get_edid() instead of abusing this function.
- *
- * The EDID may be overridden using debugfs override_edid or firmware EDID
- * (drm_edid_load_firmware() and drm.edid_firmware parameter), in this priority
- * order. Having either of them bypasses actual EDID reads.
- *
- * Return: Pointer to valid EDID or NULL if we couldn't find any.
- */
-struct edid *drm_do_get_edid(struct drm_connector *connector,
- read_block_fn read_block,
- void *context)
-{
- return _drm_do_get_edid(connector, read_block, context, NULL);
-}
-EXPORT_SYMBOL_GPL(drm_do_get_edid);
-
-/**
* drm_edid_raw - Get a pointer to the raw EDID data.
* @drm_edid: drm_edid container
*
@@ -6969,6 +6941,39 @@ out:
return ret;
}
+/* For sysfs edid show implementation */
+ssize_t drm_edid_connector_property_show(struct drm_connector *connector,
+ char *buf, loff_t off, size_t count)
+{
+ const void *edid;
+ size_t size;
+ ssize_t ret = 0;
+
+ mutex_lock(&connector->dev->mode_config.mutex);
+
+ if (!connector->edid_blob_ptr)
+ goto unlock;
+
+ edid = connector->edid_blob_ptr->data;
+ size = connector->edid_blob_ptr->length;
+ if (!edid)
+ goto unlock;
+
+ if (off >= size)
+ goto unlock;
+
+ if (off + count > size)
+ count = size - off;
+
+ memcpy(buf, edid + off, count);
+
+ ret = count;
+unlock:
+ mutex_unlock(&connector->dev->mode_config.mutex);
+
+ return ret;
+}
+
/**
* drm_edid_connector_update - Update connector information from EDID
* @connector: Connector
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index d612133e2cf7..e2e19f49342e 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -85,12 +85,8 @@ static DEFINE_MUTEX(kernel_fb_helper_lock);
* The fb helper functions are useful to provide an fbdev on top of a drm kernel
* mode setting driver. They can be used mostly independently from the crtc
* helper functions used by many drivers to implement the kernel mode setting
- * interfaces.
- *
- * Drivers that support a dumb buffer with a virtual address and mmap support,
- * should try out the generic fbdev emulation using drm_fbdev_generic_setup().
- * It will automatically set up deferred I/O if the driver requires a shadow
- * buffer.
+ * interfaces. Drivers that use one of the shared memory managers, TTM, SHMEM,
+ * DMA, should instead use the corresponding fbdev emulation.
*
* Existing fbdev implementations should restore the fbdev console by using
* drm_fb_helper_lastclose() as their &drm_driver.lastclose callback.
@@ -126,9 +122,6 @@ static DEFINE_MUTEX(kernel_fb_helper_lock);
* atomic context. If drm_fb_helper_deferred_io() is used as the deferred_io
* callback it will also schedule dirty_work with the damage collected from the
* mmap page writes.
- *
- * Deferred I/O is not compatible with SHMEM. Such drivers should request an
- * fbdev shadow buffer and call drm_fbdev_generic_setup() instead.
*/
static void drm_fb_helper_restore_lut_atomic(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/drm_fbdev_dma.c b/drivers/gpu/drm/drm_fbdev_dma.c
index 6c9427bb4053..97ef6300d47e 100644
--- a/drivers/gpu/drm/drm_fbdev_dma.c
+++ b/drivers/gpu/drm/drm_fbdev_dma.c
@@ -4,6 +4,7 @@
#include <drm/drm_crtc_helper.h>
#include <drm/drm_drv.h>
+#include <drm/drm_fb_dma_helper.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_dma_helper.h>
@@ -35,6 +36,22 @@ static int drm_fbdev_dma_fb_release(struct fb_info *info, int user)
return 0;
}
+FB_GEN_DEFAULT_DEFERRED_DMAMEM_OPS(drm_fbdev_dma,
+ drm_fb_helper_damage_range,
+ drm_fb_helper_damage_area);
+
+static int drm_fbdev_dma_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+ struct drm_fb_helper *fb_helper = info->par;
+ struct drm_framebuffer *fb = fb_helper->fb;
+ struct drm_gem_dma_object *dma = drm_fb_dma_get_gem_obj(fb, 0);
+
+ if (!dma->map_noncoherent)
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+
+ return fb_deferred_io_mmap(info, vma);
+}
+
static void drm_fbdev_dma_fb_destroy(struct fb_info *info)
{
struct drm_fb_helper *fb_helper = info->par;
@@ -42,6 +59,7 @@ static void drm_fbdev_dma_fb_destroy(struct fb_info *info)
if (!fb_helper->dev)
return;
+ fb_deferred_io_cleanup(info);
drm_fb_helper_fini(fb_helper);
drm_client_buffer_vunmap(fb_helper->buffer);
@@ -51,20 +69,13 @@ static void drm_fbdev_dma_fb_destroy(struct fb_info *info)
kfree(fb_helper);
}
-static int drm_fbdev_dma_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
-{
- struct drm_fb_helper *fb_helper = info->par;
-
- return drm_gem_prime_mmap(fb_helper->buffer->gem, vma);
-}
-
static const struct fb_ops drm_fbdev_dma_fb_ops = {
.owner = THIS_MODULE,
.fb_open = drm_fbdev_dma_fb_open,
.fb_release = drm_fbdev_dma_fb_release,
- __FB_DEFAULT_DMAMEM_OPS_RDWR,
+ __FB_DEFAULT_DEFERRED_OPS_RDWR(drm_fbdev_dma),
DRM_FB_HELPER_DEFAULT_OPS,
- __FB_DEFAULT_DMAMEM_OPS_DRAW,
+ __FB_DEFAULT_DEFERRED_OPS_DRAW(drm_fbdev_dma),
.fb_mmap = drm_fbdev_dma_fb_mmap,
.fb_destroy = drm_fbdev_dma_fb_destroy,
};
@@ -98,10 +109,6 @@ static int drm_fbdev_dma_helper_fb_probe(struct drm_fb_helper *fb_helper,
dma_obj = to_drm_gem_dma_obj(buffer->gem);
fb = buffer->fb;
- if (drm_WARN_ON(dev, fb->funcs->dirty)) {
- ret = -ENODEV; /* damage handling not supported; use generic emulation */
- goto err_drm_client_buffer_delete;
- }
ret = drm_client_buffer_vmap(buffer, &map);
if (ret) {
@@ -112,7 +119,7 @@ static int drm_fbdev_dma_helper_fb_probe(struct drm_fb_helper *fb_helper,
}
fb_helper->buffer = buffer;
- fb_helper->fb = buffer->fb;
+ fb_helper->fb = fb;
info = drm_fb_helper_alloc_info(fb_helper);
if (IS_ERR(info)) {
@@ -133,8 +140,19 @@ static int drm_fbdev_dma_helper_fb_probe(struct drm_fb_helper *fb_helper,
info->fix.smem_start = page_to_phys(virt_to_page(info->screen_buffer));
info->fix.smem_len = info->screen_size;
+ /* deferred I/O */
+ fb_helper->fbdefio.delay = HZ / 20;
+ fb_helper->fbdefio.deferred_io = drm_fb_helper_deferred_io;
+
+ info->fbdefio = &fb_helper->fbdefio;
+ ret = fb_deferred_io_init(info);
+ if (ret)
+ goto err_drm_fb_helper_release_info;
+
return 0;
+err_drm_fb_helper_release_info:
+ drm_fb_helper_release_info(fb_helper);
err_drm_client_buffer_vunmap:
fb_helper->fb = NULL;
fb_helper->buffer = NULL;
@@ -144,8 +162,28 @@ err_drm_client_buffer_delete:
return ret;
}
+static int drm_fbdev_dma_helper_fb_dirty(struct drm_fb_helper *helper,
+ struct drm_clip_rect *clip)
+{
+ struct drm_device *dev = helper->dev;
+ int ret;
+
+ /* Call damage handlers only if necessary */
+ if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2))
+ return 0;
+
+ if (helper->fb->funcs->dirty) {
+ ret = helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1);
+ if (drm_WARN_ONCE(dev, ret, "Dirty helper failed: ret=%d\n", ret))
+ return ret;
+ }
+
+ return 0;
+}
+
static const struct drm_fb_helper_funcs drm_fbdev_dma_helper_funcs = {
.fb_probe = drm_fbdev_dma_helper_fb_probe,
+ .fb_dirty = drm_fbdev_dma_helper_fb_dirty,
};
/*
diff --git a/drivers/gpu/drm/drm_fbdev_shmem.c b/drivers/gpu/drm/drm_fbdev_shmem.c
new file mode 100644
index 000000000000..0c785007f11b
--- /dev/null
+++ b/drivers/gpu/drm/drm_fbdev_shmem.c
@@ -0,0 +1,317 @@
+// SPDX-License-Identifier: MIT
+
+#include <linux/fb.h>
+
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_framebuffer.h>
+#include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_gem_shmem_helper.h>
+
+#include <drm/drm_fbdev_shmem.h>
+
+/*
+ * struct fb_ops
+ */
+
+static int drm_fbdev_shmem_fb_open(struct fb_info *info, int user)
+{
+ struct drm_fb_helper *fb_helper = info->par;
+
+ /* No need to take a ref for fbcon because it unbinds on unregister */
+ if (user && !try_module_get(fb_helper->dev->driver->fops->owner))
+ return -ENODEV;
+
+ return 0;
+}
+
+static int drm_fbdev_shmem_fb_release(struct fb_info *info, int user)
+{
+ struct drm_fb_helper *fb_helper = info->par;
+
+ if (user)
+ module_put(fb_helper->dev->driver->fops->owner);
+
+ return 0;
+}
+
+FB_GEN_DEFAULT_DEFERRED_SYSMEM_OPS(drm_fbdev_shmem,
+ drm_fb_helper_damage_range,
+ drm_fb_helper_damage_area);
+
+static int drm_fbdev_shmem_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+ struct drm_fb_helper *fb_helper = info->par;
+ struct drm_framebuffer *fb = fb_helper->fb;
+ struct drm_gem_object *obj = drm_gem_fb_get_obj(fb, 0);
+ struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
+
+ if (shmem->map_wc)
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+
+ return fb_deferred_io_mmap(info, vma);
+}
+
+static void drm_fbdev_shmem_fb_destroy(struct fb_info *info)
+{
+ struct drm_fb_helper *fb_helper = info->par;
+
+ if (!fb_helper->dev)
+ return;
+
+ fb_deferred_io_cleanup(info);
+ drm_fb_helper_fini(fb_helper);
+
+ drm_client_buffer_vunmap(fb_helper->buffer);
+ drm_client_framebuffer_delete(fb_helper->buffer);
+ drm_client_release(&fb_helper->client);
+ drm_fb_helper_unprepare(fb_helper);
+ kfree(fb_helper);
+}
+
+static const struct fb_ops drm_fbdev_shmem_fb_ops = {
+ .owner = THIS_MODULE,
+ .fb_open = drm_fbdev_shmem_fb_open,
+ .fb_release = drm_fbdev_shmem_fb_release,
+ __FB_DEFAULT_DEFERRED_OPS_RDWR(drm_fbdev_shmem),
+ DRM_FB_HELPER_DEFAULT_OPS,
+ __FB_DEFAULT_DEFERRED_OPS_DRAW(drm_fbdev_shmem),
+ .fb_mmap = drm_fbdev_shmem_fb_mmap,
+ .fb_destroy = drm_fbdev_shmem_fb_destroy,
+};
+
+static struct page *drm_fbdev_shmem_get_page(struct fb_info *info, unsigned long offset)
+{
+ struct drm_fb_helper *fb_helper = info->par;
+ struct drm_framebuffer *fb = fb_helper->fb;
+ struct drm_gem_object *obj = drm_gem_fb_get_obj(fb, 0);
+ struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
+ unsigned int i = offset >> PAGE_SHIFT;
+ struct page *page;
+
+ if (fb_WARN_ON_ONCE(info, offset > obj->size))
+ return NULL;
+
+ page = shmem->pages[i]; // protected by active vmap
+ if (page)
+ get_page(page);
+ fb_WARN_ON_ONCE(info, !page);
+
+ return page;
+}
+
+/*
+ * struct drm_fb_helper
+ */
+
+static int drm_fbdev_shmem_helper_fb_probe(struct drm_fb_helper *fb_helper,
+ struct drm_fb_helper_surface_size *sizes)
+{
+ struct drm_client_dev *client = &fb_helper->client;
+ struct drm_device *dev = fb_helper->dev;
+ struct drm_client_buffer *buffer;
+ struct drm_gem_shmem_object *shmem;
+ struct drm_framebuffer *fb;
+ struct fb_info *info;
+ u32 format;
+ struct iosys_map map;
+ int ret;
+
+ drm_dbg_kms(dev, "surface width(%d), height(%d) and bpp(%d)\n",
+ sizes->surface_width, sizes->surface_height,
+ sizes->surface_bpp);
+
+ format = drm_driver_legacy_fb_format(dev, sizes->surface_bpp, sizes->surface_depth);
+ buffer = drm_client_framebuffer_create(client, sizes->surface_width,
+ sizes->surface_height, format);
+ if (IS_ERR(buffer))
+ return PTR_ERR(buffer);
+ shmem = to_drm_gem_shmem_obj(buffer->gem);
+
+ fb = buffer->fb;
+
+ ret = drm_client_buffer_vmap(buffer, &map);
+ if (ret) {
+ goto err_drm_client_buffer_delete;
+ } else if (drm_WARN_ON(dev, map.is_iomem)) {
+ ret = -ENODEV; /* I/O memory not supported; use generic emulation */
+ goto err_drm_client_buffer_delete;
+ }
+
+ fb_helper->buffer = buffer;
+ fb_helper->fb = fb;
+
+ info = drm_fb_helper_alloc_info(fb_helper);
+ if (IS_ERR(info)) {
+ ret = PTR_ERR(info);
+ goto err_drm_client_buffer_vunmap;
+ }
+
+ drm_fb_helper_fill_info(info, fb_helper, sizes);
+
+ info->fbops = &drm_fbdev_shmem_fb_ops;
+
+ /* screen */
+ info->flags |= FBINFO_VIRTFB; /* system memory */
+ if (!shmem->map_wc)
+ info->flags |= FBINFO_READS_FAST; /* signal caching */
+ info->screen_size = sizes->surface_height * fb->pitches[0];
+ info->screen_buffer = map.vaddr;
+ info->fix.smem_len = info->screen_size;
+
+ /* deferred I/O */
+ fb_helper->fbdefio.delay = HZ / 20;
+ fb_helper->fbdefio.get_page = drm_fbdev_shmem_get_page;
+ fb_helper->fbdefio.deferred_io = drm_fb_helper_deferred_io;
+
+ info->fbdefio = &fb_helper->fbdefio;
+ ret = fb_deferred_io_init(info);
+ if (ret)
+ goto err_drm_fb_helper_release_info;
+
+ return 0;
+
+err_drm_fb_helper_release_info:
+ drm_fb_helper_release_info(fb_helper);
+err_drm_client_buffer_vunmap:
+ fb_helper->fb = NULL;
+ fb_helper->buffer = NULL;
+ drm_client_buffer_vunmap(buffer);
+err_drm_client_buffer_delete:
+ drm_client_framebuffer_delete(buffer);
+ return ret;
+}
+
+static int drm_fbdev_shmem_helper_fb_dirty(struct drm_fb_helper *helper,
+ struct drm_clip_rect *clip)
+{
+ struct drm_device *dev = helper->dev;
+ int ret;
+
+ /* Call damage handlers only if necessary */
+ if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2))
+ return 0;
+
+ if (helper->fb->funcs->dirty) {
+ ret = helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1);
+ if (drm_WARN_ONCE(dev, ret, "Dirty helper failed: ret=%d\n", ret))
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct drm_fb_helper_funcs drm_fbdev_shmem_helper_funcs = {
+ .fb_probe = drm_fbdev_shmem_helper_fb_probe,
+ .fb_dirty = drm_fbdev_shmem_helper_fb_dirty,
+};
+
+/*
+ * struct drm_client_funcs
+ */
+
+static void drm_fbdev_shmem_client_unregister(struct drm_client_dev *client)
+{
+ struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
+
+ if (fb_helper->info) {
+ drm_fb_helper_unregister_info(fb_helper);
+ } else {
+ drm_client_release(&fb_helper->client);
+ drm_fb_helper_unprepare(fb_helper);
+ kfree(fb_helper);
+ }
+}
+
+static int drm_fbdev_shmem_client_restore(struct drm_client_dev *client)
+{
+ drm_fb_helper_lastclose(client->dev);
+
+ return 0;
+}
+
+static int drm_fbdev_shmem_client_hotplug(struct drm_client_dev *client)
+{
+ struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
+ struct drm_device *dev = client->dev;
+ int ret;
+
+ if (dev->fb_helper)
+ return drm_fb_helper_hotplug_event(dev->fb_helper);
+
+ ret = drm_fb_helper_init(dev, fb_helper);
+ if (ret)
+ goto err_drm_err;
+
+ if (!drm_drv_uses_atomic_modeset(dev))
+ drm_helper_disable_unused_functions(dev);
+
+ ret = drm_fb_helper_initial_config(fb_helper);
+ if (ret)
+ goto err_drm_fb_helper_fini;
+
+ return 0;
+
+err_drm_fb_helper_fini:
+ drm_fb_helper_fini(fb_helper);
+err_drm_err:
+ drm_err(dev, "fbdev-shmem: Failed to setup emulation (ret=%d)\n", ret);
+ return ret;
+}
+
+static const struct drm_client_funcs drm_fbdev_shmem_client_funcs = {
+ .owner = THIS_MODULE,
+ .unregister = drm_fbdev_shmem_client_unregister,
+ .restore = drm_fbdev_shmem_client_restore,
+ .hotplug = drm_fbdev_shmem_client_hotplug,
+};
+
+/**
+ * drm_fbdev_shmem_setup() - Setup fbdev emulation for GEM SHMEM helpers
+ * @dev: DRM device
+ * @preferred_bpp: Preferred bits per pixel for the device.
+ * 32 is used if this is zero.
+ *
+ * This function sets up fbdev emulation for GEM DMA drivers that support
+ * dumb buffers with a virtual address and that can be mmap'ed.
+ * drm_fbdev_shmem_setup() shall be called after the DRM driver registered
+ * the new DRM device with drm_dev_register().
+ *
+ * Restore, hotplug events and teardown are all taken care of. Drivers that do
+ * suspend/resume need to call drm_fb_helper_set_suspend_unlocked() themselves.
+ * Simple drivers might use drm_mode_config_helper_suspend().
+ *
+ * This function is safe to call even when there are no connectors present.
+ * Setup will be retried on the next hotplug event.
+ *
+ * The fbdev is destroyed by drm_dev_unregister().
+ */
+void drm_fbdev_shmem_setup(struct drm_device *dev, unsigned int preferred_bpp)
+{
+ struct drm_fb_helper *fb_helper;
+ int ret;
+
+ drm_WARN(dev, !dev->registered, "Device has not been registered.\n");
+ drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n");
+
+ fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL);
+ if (!fb_helper)
+ return;
+ drm_fb_helper_prepare(dev, fb_helper, preferred_bpp, &drm_fbdev_shmem_helper_funcs);
+
+ ret = drm_client_init(dev, &fb_helper->client, "fbdev", &drm_fbdev_shmem_client_funcs);
+ if (ret) {
+ drm_err(dev, "Failed to register client: %d\n", ret);
+ goto err_drm_client_init;
+ }
+
+ drm_client_register(&fb_helper->client);
+
+ return;
+
+err_drm_client_init:
+ drm_fb_helper_unprepare(fb_helper);
+ kfree(fb_helper);
+}
+EXPORT_SYMBOL(drm_fbdev_shmem_setup);
diff --git a/drivers/gpu/drm/drm_fbdev_generic.c b/drivers/gpu/drm/drm_fbdev_ttm.c
index 97e579c33d84..bb7898cd7dc6 100644
--- a/drivers/gpu/drm/drm_fbdev_generic.c
+++ b/drivers/gpu/drm/drm_fbdev_ttm.c
@@ -10,10 +10,10 @@
#include <drm/drm_gem.h>
#include <drm/drm_print.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_ttm.h>
/* @user: 1=userspace, 0=fbcon */
-static int drm_fbdev_generic_fb_open(struct fb_info *info, int user)
+static int drm_fbdev_ttm_fb_open(struct fb_info *info, int user)
{
struct drm_fb_helper *fb_helper = info->par;
@@ -24,7 +24,7 @@ static int drm_fbdev_generic_fb_open(struct fb_info *info, int user)
return 0;
}
-static int drm_fbdev_generic_fb_release(struct fb_info *info, int user)
+static int drm_fbdev_ttm_fb_release(struct fb_info *info, int user)
{
struct drm_fb_helper *fb_helper = info->par;
@@ -34,11 +34,11 @@ static int drm_fbdev_generic_fb_release(struct fb_info *info, int user)
return 0;
}
-FB_GEN_DEFAULT_DEFERRED_SYSMEM_OPS(drm_fbdev_generic,
+FB_GEN_DEFAULT_DEFERRED_SYSMEM_OPS(drm_fbdev_ttm,
drm_fb_helper_damage_range,
drm_fb_helper_damage_area);
-static void drm_fbdev_generic_fb_destroy(struct fb_info *info)
+static void drm_fbdev_ttm_fb_destroy(struct fb_info *info)
{
struct drm_fb_helper *fb_helper = info->par;
void *shadow = info->screen_buffer;
@@ -56,19 +56,19 @@ static void drm_fbdev_generic_fb_destroy(struct fb_info *info)
kfree(fb_helper);
}
-static const struct fb_ops drm_fbdev_generic_fb_ops = {
+static const struct fb_ops drm_fbdev_ttm_fb_ops = {
.owner = THIS_MODULE,
- .fb_open = drm_fbdev_generic_fb_open,
- .fb_release = drm_fbdev_generic_fb_release,
- FB_DEFAULT_DEFERRED_OPS(drm_fbdev_generic),
+ .fb_open = drm_fbdev_ttm_fb_open,
+ .fb_release = drm_fbdev_ttm_fb_release,
+ FB_DEFAULT_DEFERRED_OPS(drm_fbdev_ttm),
DRM_FB_HELPER_DEFAULT_OPS,
- .fb_destroy = drm_fbdev_generic_fb_destroy,
+ .fb_destroy = drm_fbdev_ttm_fb_destroy,
};
/*
* This function uses the client API to create a framebuffer backed by a dumb buffer.
*/
-static int drm_fbdev_generic_helper_fb_probe(struct drm_fb_helper *fb_helper,
+static int drm_fbdev_ttm_helper_fb_probe(struct drm_fb_helper *fb_helper,
struct drm_fb_helper_surface_size *sizes)
{
struct drm_client_dev *client = &fb_helper->client;
@@ -108,7 +108,7 @@ static int drm_fbdev_generic_helper_fb_probe(struct drm_fb_helper *fb_helper,
drm_fb_helper_fill_info(info, fb_helper, sizes);
- info->fbops = &drm_fbdev_generic_fb_ops;
+ info->fbops = &drm_fbdev_ttm_fb_ops;
/* screen */
info->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST;
@@ -137,9 +137,9 @@ err_drm_client_framebuffer_delete:
return ret;
}
-static void drm_fbdev_generic_damage_blit_real(struct drm_fb_helper *fb_helper,
- struct drm_clip_rect *clip,
- struct iosys_map *dst)
+static void drm_fbdev_ttm_damage_blit_real(struct drm_fb_helper *fb_helper,
+ struct drm_clip_rect *clip,
+ struct iosys_map *dst)
{
struct drm_framebuffer *fb = fb_helper->fb;
size_t offset = clip->y1 * fb->pitches[0];
@@ -176,8 +176,8 @@ static void drm_fbdev_generic_damage_blit_real(struct drm_fb_helper *fb_helper,
}
}
-static int drm_fbdev_generic_damage_blit(struct drm_fb_helper *fb_helper,
- struct drm_clip_rect *clip)
+static int drm_fbdev_ttm_damage_blit(struct drm_fb_helper *fb_helper,
+ struct drm_clip_rect *clip)
{
struct drm_client_buffer *buffer = fb_helper->buffer;
struct iosys_map map, dst;
@@ -201,7 +201,7 @@ static int drm_fbdev_generic_damage_blit(struct drm_fb_helper *fb_helper,
goto out;
dst = map;
- drm_fbdev_generic_damage_blit_real(fb_helper, clip, &dst);
+ drm_fbdev_ttm_damage_blit_real(fb_helper, clip, &dst);
drm_client_buffer_vunmap_local(buffer);
@@ -211,8 +211,8 @@ out:
return ret;
}
-static int drm_fbdev_generic_helper_fb_dirty(struct drm_fb_helper *helper,
- struct drm_clip_rect *clip)
+static int drm_fbdev_ttm_helper_fb_dirty(struct drm_fb_helper *helper,
+ struct drm_clip_rect *clip)
{
struct drm_device *dev = helper->dev;
int ret;
@@ -221,7 +221,7 @@ static int drm_fbdev_generic_helper_fb_dirty(struct drm_fb_helper *helper,
if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2))
return 0;
- ret = drm_fbdev_generic_damage_blit(helper, clip);
+ ret = drm_fbdev_ttm_damage_blit(helper, clip);
if (drm_WARN_ONCE(dev, ret, "Damage blitter failed: ret=%d\n", ret))
return ret;
@@ -234,12 +234,12 @@ static int drm_fbdev_generic_helper_fb_dirty(struct drm_fb_helper *helper,
return 0;
}
-static const struct drm_fb_helper_funcs drm_fbdev_generic_helper_funcs = {
- .fb_probe = drm_fbdev_generic_helper_fb_probe,
- .fb_dirty = drm_fbdev_generic_helper_fb_dirty,
+static const struct drm_fb_helper_funcs drm_fbdev_ttm_helper_funcs = {
+ .fb_probe = drm_fbdev_ttm_helper_fb_probe,
+ .fb_dirty = drm_fbdev_ttm_helper_fb_dirty,
};
-static void drm_fbdev_generic_client_unregister(struct drm_client_dev *client)
+static void drm_fbdev_ttm_client_unregister(struct drm_client_dev *client)
{
struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
@@ -252,14 +252,14 @@ static void drm_fbdev_generic_client_unregister(struct drm_client_dev *client)
}
}
-static int drm_fbdev_generic_client_restore(struct drm_client_dev *client)
+static int drm_fbdev_ttm_client_restore(struct drm_client_dev *client)
{
drm_fb_helper_lastclose(client->dev);
return 0;
}
-static int drm_fbdev_generic_client_hotplug(struct drm_client_dev *client)
+static int drm_fbdev_ttm_client_hotplug(struct drm_client_dev *client)
{
struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
struct drm_device *dev = client->dev;
@@ -284,32 +284,32 @@ static int drm_fbdev_generic_client_hotplug(struct drm_client_dev *client)
err_drm_fb_helper_fini:
drm_fb_helper_fini(fb_helper);
err_drm_err:
- drm_err(dev, "fbdev: Failed to setup generic emulation (ret=%d)\n", ret);
+ drm_err(dev, "fbdev: Failed to setup emulation (ret=%d)\n", ret);
return ret;
}
-static const struct drm_client_funcs drm_fbdev_generic_client_funcs = {
+static const struct drm_client_funcs drm_fbdev_ttm_client_funcs = {
.owner = THIS_MODULE,
- .unregister = drm_fbdev_generic_client_unregister,
- .restore = drm_fbdev_generic_client_restore,
- .hotplug = drm_fbdev_generic_client_hotplug,
+ .unregister = drm_fbdev_ttm_client_unregister,
+ .restore = drm_fbdev_ttm_client_restore,
+ .hotplug = drm_fbdev_ttm_client_hotplug,
};
/**
- * drm_fbdev_generic_setup() - Setup generic fbdev emulation
+ * drm_fbdev_ttm_setup() - Setup fbdev emulation for TTM-based drivers
* @dev: DRM device
* @preferred_bpp: Preferred bits per pixel for the device.
*
- * This function sets up generic fbdev emulation for drivers that supports
+ * This function sets up fbdev emulation for TTM-based drivers that support
* dumb buffers with a virtual address and that can be mmap'ed.
- * drm_fbdev_generic_setup() shall be called after the DRM driver registered
+ * drm_fbdev_ttm_setup() shall be called after the DRM driver registered
* the new DRM device with drm_dev_register().
*
* Restore, hotplug events and teardown are all taken care of. Drivers that do
* suspend/resume need to call drm_fb_helper_set_suspend_unlocked() themselves.
* Simple drivers might use drm_mode_config_helper_suspend().
*
- * In order to provide fixed mmap-able memory ranges, generic fbdev emulation
+ * In order to provide fixed mmap-able memory ranges, fbdev emulation
* uses a shadow buffer in system memory. The implementation blits the shadow
* fbdev buffer onto the real buffer in regular intervals.
*
@@ -318,7 +318,7 @@ static const struct drm_client_funcs drm_fbdev_generic_client_funcs = {
*
* The fbdev is destroyed by drm_dev_unregister().
*/
-void drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp)
+void drm_fbdev_ttm_setup(struct drm_device *dev, unsigned int preferred_bpp)
{
struct drm_fb_helper *fb_helper;
int ret;
@@ -329,9 +329,9 @@ void drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp)
fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL);
if (!fb_helper)
return;
- drm_fb_helper_prepare(dev, fb_helper, preferred_bpp, &drm_fbdev_generic_helper_funcs);
+ drm_fb_helper_prepare(dev, fb_helper, preferred_bpp, &drm_fbdev_ttm_helper_funcs);
- ret = drm_client_init(dev, &fb_helper->client, "fbdev", &drm_fbdev_generic_client_funcs);
+ ret = drm_client_init(dev, &fb_helper->client, "fbdev", &drm_fbdev_ttm_client_funcs);
if (ret) {
drm_err(dev, "Failed to register client: %d\n", ret);
goto err_drm_client_init;
@@ -346,4 +346,4 @@ err_drm_client_init:
kfree(fb_helper);
return;
}
-EXPORT_SYMBOL(drm_fbdev_generic_setup);
+EXPORT_SYMBOL(drm_fbdev_ttm_setup);
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index e368fc084c77..51f39912866f 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -529,9 +529,10 @@ int drm_version(struct drm_device *dev, void *data,
version->version_patchlevel = dev->driver->patchlevel;
err = drm_copy_field(version->name, &version->name_len,
dev->driver->name);
+
+ /* Driver date is deprecated. Userspace expects a non-empty string. */
if (!err)
- err = drm_copy_field(version->date, &version->date_len,
- dev->driver->date);
+ err = drm_copy_field(version->date, &version->date_len, "0");
if (!err)
err = drm_copy_field(version->desc, &version->desc_len,
dev->driver->desc);
diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c
index daac649aabdb..34bca7567576 100644
--- a/drivers/gpu/drm/drm_mipi_dbi.c
+++ b/drivers/gpu/drm/drm_mipi_dbi.c
@@ -206,6 +206,7 @@ int mipi_dbi_buf_copy(void *dst, struct iosys_map *src, struct drm_framebuffer *
struct drm_rect *clip, bool swap,
struct drm_format_conv_state *fmtcnv_state)
{
+ struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(fb->dev);
struct drm_gem_object *gem = drm_gem_fb_get_obj(fb, 0);
struct iosys_map dst_map = IOSYS_MAP_INIT_VADDR(dst);
int ret;
@@ -222,8 +223,18 @@ int mipi_dbi_buf_copy(void *dst, struct iosys_map *src, struct drm_framebuffer *
else
drm_fb_memcpy(&dst_map, NULL, src, fb, clip);
break;
+ case DRM_FORMAT_RGB888:
+ drm_fb_memcpy(&dst_map, NULL, src, fb, clip);
+ break;
case DRM_FORMAT_XRGB8888:
- drm_fb_xrgb8888_to_rgb565(&dst_map, NULL, src, fb, clip, fmtcnv_state, swap);
+ switch (dbidev->pixel_format) {
+ case DRM_FORMAT_RGB565:
+ drm_fb_xrgb8888_to_rgb565(&dst_map, NULL, src, fb, clip, fmtcnv_state, swap);
+ break;
+ case DRM_FORMAT_RGB888:
+ drm_fb_xrgb8888_to_rgb888(&dst_map, NULL, src, fb, clip, fmtcnv_state);
+ break;
+ }
break;
default:
drm_err_once(fb->dev, "Format is not supported: %p4cc\n",
@@ -260,9 +271,11 @@ static void mipi_dbi_fb_dirty(struct iosys_map *src, struct drm_framebuffer *fb,
struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(fb->dev);
unsigned int height = rect->y2 - rect->y1;
unsigned int width = rect->x2 - rect->x1;
+ const struct drm_format_info *dst_format;
struct mipi_dbi *dbi = &dbidev->dbi;
bool swap = dbi->swap_bytes;
int ret = 0;
+ size_t len;
bool full;
void *tr;
@@ -283,8 +296,13 @@ static void mipi_dbi_fb_dirty(struct iosys_map *src, struct drm_framebuffer *fb,
mipi_dbi_set_window_address(dbidev, rect->x1, rect->x2 - 1, rect->y1,
rect->y2 - 1);
- ret = mipi_dbi_command_buf(dbi, MIPI_DCS_WRITE_MEMORY_START, tr,
- width * height * 2);
+ if (fb->format->format == DRM_FORMAT_XRGB8888)
+ dst_format = drm_format_info(dbidev->pixel_format);
+ else
+ dst_format = fb->format;
+ len = drm_format_info_min_pitch(dst_format, 0, width) * height;
+
+ ret = mipi_dbi_command_buf(dbi, MIPI_DCS_WRITE_MEMORY_START, tr, len);
err_msg:
if (ret)
drm_err_once(fb->dev, "Failed to update display %d\n", ret);
@@ -572,7 +590,7 @@ static const uint32_t mipi_dbi_formats[] = {
* has one fixed &drm_display_mode which is rotated according to @rotation.
* This mode is used to set the mode config min/max width/height properties.
*
- * Use mipi_dbi_dev_init() if you don't need custom formats.
+ * Use mipi_dbi_dev_init() if you want native RGB565 and emulated XRGB8888 format.
*
* Note:
* Some of the helper functions expects RGB565 to be the default format and the
@@ -631,6 +649,9 @@ int mipi_dbi_dev_init_with_formats(struct mipi_dbi_dev *dbidev,
drm->mode_config.min_height = dbidev->mode.vdisplay;
drm->mode_config.max_height = dbidev->mode.vdisplay;
dbidev->rotation = rotation;
+ dbidev->pixel_format = formats[0];
+ if (formats[0] == DRM_FORMAT_RGB888)
+ dbidev->dbi.write_memory_bpw = 8;
DRM_DEBUG_KMS("rotation = %u\n", rotation);
@@ -824,15 +845,6 @@ u32 mipi_dbi_spi_cmd_max_speed(struct spi_device *spi, size_t len)
}
EXPORT_SYMBOL(mipi_dbi_spi_cmd_max_speed);
-static bool mipi_dbi_machine_little_endian(void)
-{
-#if defined(__LITTLE_ENDIAN)
- return true;
-#else
- return false;
-#endif
-}
-
/*
* MIPI DBI Type C Option 1
*
@@ -855,7 +867,7 @@ static int mipi_dbi_spi1e_transfer(struct mipi_dbi *dbi, int dc,
const void *buf, size_t len,
unsigned int bpw)
{
- bool swap_bytes = (bpw == 16 && mipi_dbi_machine_little_endian());
+ bool swap_bytes = (bpw == 16);
size_t chunk, max_chunk = dbi->tx_buf9_len;
struct spi_device *spi = dbi->spi;
struct spi_transfer tr = {
@@ -1004,7 +1016,7 @@ static int mipi_dbi_spi1_transfer(struct mipi_dbi *dbi, int dc,
size_t chunk = min(len, max_chunk);
unsigned int i;
- if (bpw == 16 && mipi_dbi_machine_little_endian()) {
+ if (bpw == 16) {
for (i = 0; i < (chunk * 2); i += 2) {
dst16[i] = *src16 >> 8;
dst16[i + 1] = *src16++ & 0xFF;
@@ -1088,7 +1100,7 @@ static int mipi_dbi_typec1_command_read(struct mipi_dbi *dbi, u8 *cmd,
static int mipi_dbi_typec1_command(struct mipi_dbi *dbi, u8 *cmd,
u8 *parameters, size_t num)
{
- unsigned int bpw = (*cmd == MIPI_DCS_WRITE_MEMORY_START) ? 16 : 8;
+ unsigned int bpw = 8;
int ret;
if (mipi_dbi_command_is_read(dbi, *cmd))
@@ -1100,6 +1112,9 @@ static int mipi_dbi_typec1_command(struct mipi_dbi *dbi, u8 *cmd,
if (ret || !num)
return ret;
+ if (*cmd == MIPI_DCS_WRITE_MEMORY_START)
+ bpw = dbi->write_memory_bpw;
+
return mipi_dbi_spi1_transfer(dbi, 1, parameters, num, bpw);
}
@@ -1193,8 +1208,8 @@ static int mipi_dbi_typec3_command(struct mipi_dbi *dbi, u8 *cmd,
if (ret || !num)
return ret;
- if (*cmd == MIPI_DCS_WRITE_MEMORY_START && !dbi->swap_bytes)
- bpw = 16;
+ if (*cmd == MIPI_DCS_WRITE_MEMORY_START)
+ bpw = dbi->write_memory_bpw;
spi_bus_lock(spi->controller);
gpiod_set_value_cansleep(dbi->dc, 1);
@@ -1218,11 +1233,23 @@ static int mipi_dbi_typec3_command(struct mipi_dbi *dbi, u8 *cmd,
* If @dc is set, a Type C Option 3 interface is assumed, if not
* Type C Option 1.
*
- * If the SPI master driver doesn't support the necessary bits per word,
- * the following transformation is used:
+ * If the command is %MIPI_DCS_WRITE_MEMORY_START and the pixel format is RGB565, endianness has
+ * to be taken into account. The MIPI DBI serial interface is big endian and framebuffers are
+ * assumed stored in memory as little endian (%DRM_FORMAT_BIG_ENDIAN is not supported).
*
- * - 9-bit: reorder buffer as 9x 8-bit words, padded with no-op command.
- * - 16-bit: if big endian send as 8-bit, if little endian swap bytes
+ * This is how endianness is handled:
+ *
+ * Option 1 (D/C as a bit): The buffer is sent on the wire byte by byte so the 16-bit buffer is
+ * byteswapped before transfer.
+ *
+ * Option 3 (D/C as a gpio): If the SPI controller supports 16 bits per word the buffer can be
+ * sent as-is. If not the caller is responsible for swapping the bytes
+ * before calling mipi_dbi_command_buf() and the buffer is sent 8 bpw.
+ *
+ * This handling is optimised for %DRM_FORMAT_RGB565 framebuffers.
+ *
+ * If the interface is Option 1 and the SPI controller doesn't support 9 bits per word,
+ * the buffer is sent as 9x 8-bit words, padded with MIPI DCS no-op commands if necessary.
*
* Returns:
* Zero on success, negative error code on failure.
@@ -1253,12 +1280,15 @@ int mipi_dbi_spi_init(struct spi_device *spi, struct mipi_dbi *dbi,
dbi->spi = spi;
dbi->read_commands = mipi_dbi_dcs_read_commands;
+ dbi->write_memory_bpw = 16;
if (dc) {
dbi->command = mipi_dbi_typec3_command;
dbi->dc = dc;
- if (mipi_dbi_machine_little_endian() && !spi_is_bpw_supported(spi, 16))
+ if (!spi_is_bpw_supported(spi, 16)) {
+ dbi->write_memory_bpw = 8;
dbi->swap_bytes = true;
+ }
} else {
dbi->command = mipi_dbi_typec1_command;
dbi->tx_buf9_len = SZ_16K;
@@ -1475,4 +1505,5 @@ EXPORT_SYMBOL(mipi_dbi_debugfs_init);
#endif
+MODULE_DESCRIPTION("MIPI Display Bus Interface (DBI) LCD controller support");
MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 795001bb7ff1..a471c46f5ca6 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -765,6 +765,62 @@ ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload,
EXPORT_SYMBOL(mipi_dsi_generic_write);
/**
+ * mipi_dsi_generic_write_chatty() - mipi_dsi_generic_write() w/ an error log
+ * @dsi: DSI peripheral device
+ * @payload: buffer containing the payload
+ * @size: size of payload buffer
+ *
+ * Like mipi_dsi_generic_write() but includes a dev_err()
+ * call for you and returns 0 upon success, not the number of bytes sent.
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int mipi_dsi_generic_write_chatty(struct mipi_dsi_device *dsi,
+ const void *payload, size_t size)
+{
+ struct device *dev = &dsi->dev;
+ ssize_t ret;
+
+ ret = mipi_dsi_generic_write(dsi, payload, size);
+ if (ret < 0) {
+ dev_err(dev, "sending generic data %*ph failed: %zd\n",
+ (int)size, payload, ret);
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(mipi_dsi_generic_write_chatty);
+
+/**
+ * mipi_dsi_generic_write_multi() - mipi_dsi_generic_write_chatty() w/ accum_err
+ * @ctx: Context for multiple DSI transactions
+ * @payload: buffer containing the payload
+ * @size: size of payload buffer
+ *
+ * Like mipi_dsi_generic_write_chatty() but deals with errors in a way that
+ * makes it convenient to make several calls in a row.
+ */
+void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx,
+ const void *payload, size_t size)
+{
+ struct mipi_dsi_device *dsi = ctx->dsi;
+ struct device *dev = &dsi->dev;
+ ssize_t ret;
+
+ if (ctx->accum_err)
+ return;
+
+ ret = mipi_dsi_generic_write(dsi, payload, size);
+ if (ret < 0) {
+ ctx->accum_err = ret;
+ dev_err(dev, "sending generic data %*ph failed: %d\n",
+ (int)size, payload, ctx->accum_err);
+ }
+}
+EXPORT_SYMBOL(mipi_dsi_generic_write_multi);
+
+/**
* mipi_dsi_generic_read() - receive data using a generic read packet
* @dsi: DSI peripheral device
* @params: buffer containing the request parameters
@@ -853,6 +909,62 @@ ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi,
EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer);
/**
+ * mipi_dsi_dcs_write_buffer_chatty - mipi_dsi_dcs_write_buffer() w/ an error log
+ * @dsi: DSI peripheral device
+ * @data: buffer containing data to be transmitted
+ * @len: size of transmission buffer
+ *
+ * Like mipi_dsi_dcs_write_buffer() but includes a dev_err()
+ * call for you and returns 0 upon success, not the number of bytes sent.
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int mipi_dsi_dcs_write_buffer_chatty(struct mipi_dsi_device *dsi,
+ const void *data, size_t len)
+{
+ struct device *dev = &dsi->dev;
+ ssize_t ret;
+
+ ret = mipi_dsi_dcs_write_buffer(dsi, data, len);
+ if (ret < 0) {
+ dev_err(dev, "sending dcs data %*ph failed: %zd\n",
+ (int)len, data, ret);
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer_chatty);
+
+/**
+ * mipi_dsi_dcs_write_buffer_multi - mipi_dsi_dcs_write_buffer_chatty() w/ accum_err
+ * @ctx: Context for multiple DSI transactions
+ * @data: buffer containing data to be transmitted
+ * @len: size of transmission buffer
+ *
+ * Like mipi_dsi_dcs_write_buffer_chatty() but deals with errors in a way that
+ * makes it convenient to make several calls in a row.
+ */
+void mipi_dsi_dcs_write_buffer_multi(struct mipi_dsi_multi_context *ctx,
+ const void *data, size_t len)
+{
+ struct mipi_dsi_device *dsi = ctx->dsi;
+ struct device *dev = &dsi->dev;
+ ssize_t ret;
+
+ if (ctx->accum_err)
+ return;
+
+ ret = mipi_dsi_dcs_write_buffer(dsi, data, len);
+ if (ret < 0) {
+ ctx->accum_err = ret;
+ dev_err(dev, "sending dcs data %*ph failed: %d\n",
+ (int)len, data, ctx->accum_err);
+ }
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer_multi);
+
+/**
* mipi_dsi_dcs_write() - send DCS write command
* @dsi: DSI peripheral device
* @cmd: DCS command
@@ -1317,6 +1429,216 @@ int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi,
}
EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness_large);
+/**
+ * mipi_dsi_picture_parameter_set_multi() - transmit the DSC PPS to the peripheral
+ * @ctx: Context for multiple DSI transactions
+ * @pps: VESA DSC 1.1 Picture Parameter Set
+ *
+ * Like mipi_dsi_picture_parameter_set() but deals with errors in a way that
+ * makes it convenient to make several calls in a row.
+ */
+void mipi_dsi_picture_parameter_set_multi(struct mipi_dsi_multi_context *ctx,
+ const struct drm_dsc_picture_parameter_set *pps)
+{
+ struct mipi_dsi_device *dsi = ctx->dsi;
+ struct device *dev = &dsi->dev;
+ ssize_t ret;
+
+ if (ctx->accum_err)
+ return;
+
+ ret = mipi_dsi_picture_parameter_set(dsi, pps);
+ if (ret < 0) {
+ ctx->accum_err = ret;
+ dev_err(dev, "sending PPS failed: %d\n",
+ ctx->accum_err);
+ }
+}
+EXPORT_SYMBOL(mipi_dsi_picture_parameter_set_multi);
+
+/**
+ * mipi_dsi_compression_mode_ext_multi() - enable/disable DSC on the peripheral
+ * @ctx: Context for multiple DSI transactions
+ * @enable: Whether to enable or disable the DSC
+ * @algo: Selected compression algorithm
+ * @pps_selector: Select PPS from the table of pre-stored or uploaded PPS entries
+ *
+ * Like mipi_dsi_compression_mode_ext() but deals with errors in a way that
+ * makes it convenient to make several calls in a row.
+ */
+void mipi_dsi_compression_mode_ext_multi(struct mipi_dsi_multi_context *ctx,
+ bool enable,
+ enum mipi_dsi_compression_algo algo,
+ unsigned int pps_selector)
+{
+ struct mipi_dsi_device *dsi = ctx->dsi;
+ struct device *dev = &dsi->dev;
+ ssize_t ret;
+
+ if (ctx->accum_err)
+ return;
+
+ ret = mipi_dsi_compression_mode_ext(dsi, enable, algo, pps_selector);
+ if (ret < 0) {
+ ctx->accum_err = ret;
+ dev_err(dev, "sending COMPRESSION_MODE failed: %d\n",
+ ctx->accum_err);
+ }
+}
+EXPORT_SYMBOL(mipi_dsi_compression_mode_ext_multi);
+
+/**
+ * mipi_dsi_dcs_nop_multi() - send DCS NOP packet
+ * @ctx: Context for multiple DSI transactions
+ *
+ * Like mipi_dsi_dcs_nop() but deals with errors in a way that
+ * makes it convenient to make several calls in a row.
+ */
+void mipi_dsi_dcs_nop_multi(struct mipi_dsi_multi_context *ctx)
+{
+ struct mipi_dsi_device *dsi = ctx->dsi;
+ struct device *dev = &dsi->dev;
+ ssize_t ret;
+
+ if (ctx->accum_err)
+ return;
+
+ ret = mipi_dsi_dcs_nop(dsi);
+ if (ret < 0) {
+ ctx->accum_err = ret;
+ dev_err(dev, "sending DCS NOP failed: %d\n",
+ ctx->accum_err);
+ }
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_nop_multi);
+
+/**
+ * mipi_dsi_dcs_enter_sleep_mode_multi() - send DCS ENTER_SLEEP_MODE packet
+ * @ctx: Context for multiple DSI transactions
+ *
+ * Like mipi_dsi_dcs_enter_sleep_mode() but deals with errors in a way that
+ * makes it convenient to make several calls in a row.
+ */
+void mipi_dsi_dcs_enter_sleep_mode_multi(struct mipi_dsi_multi_context *ctx)
+{
+ struct mipi_dsi_device *dsi = ctx->dsi;
+ struct device *dev = &dsi->dev;
+ ssize_t ret;
+
+ if (ctx->accum_err)
+ return;
+
+ ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
+ if (ret < 0) {
+ ctx->accum_err = ret;
+ dev_err(dev, "sending DCS ENTER_SLEEP_MODE failed: %d\n",
+ ctx->accum_err);
+ }
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode_multi);
+
+/**
+ * mipi_dsi_dcs_exit_sleep_mode_multi() - send DCS EXIT_SLEEP_MODE packet
+ * @ctx: Context for multiple DSI transactions
+ *
+ * Like mipi_dsi_dcs_exit_sleep_mode() but deals with errors in a way that
+ * makes it convenient to make several calls in a row.
+ */
+void mipi_dsi_dcs_exit_sleep_mode_multi(struct mipi_dsi_multi_context *ctx)
+{
+ struct mipi_dsi_device *dsi = ctx->dsi;
+ struct device *dev = &dsi->dev;
+ ssize_t ret;
+
+ if (ctx->accum_err)
+ return;
+
+ ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
+ if (ret < 0) {
+ ctx->accum_err = ret;
+ dev_err(dev, "sending DCS EXIT_SLEEP_MODE failed: %d\n",
+ ctx->accum_err);
+ }
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode_multi);
+
+/**
+ * mipi_dsi_dcs_set_display_off_multi() - send DCS SET_DISPLAY_OFF packet
+ * @ctx: Context for multiple DSI transactions
+ *
+ * Like mipi_dsi_dcs_set_display_off() but deals with errors in a way that
+ * makes it convenient to make several calls in a row.
+ */
+void mipi_dsi_dcs_set_display_off_multi(struct mipi_dsi_multi_context *ctx)
+{
+ struct mipi_dsi_device *dsi = ctx->dsi;
+ struct device *dev = &dsi->dev;
+ ssize_t ret;
+
+ if (ctx->accum_err)
+ return;
+
+ ret = mipi_dsi_dcs_set_display_off(dsi);
+ if (ret < 0) {
+ ctx->accum_err = ret;
+ dev_err(dev, "sending DCS SET_DISPLAY_OFF failed: %d\n",
+ ctx->accum_err);
+ }
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off_multi);
+
+/**
+ * mipi_dsi_dcs_set_display_on_multi() - send DCS SET_DISPLAY_ON packet
+ * @ctx: Context for multiple DSI transactions
+ *
+ * Like mipi_dsi_dcs_set_display_on() but deals with errors in a way that
+ * makes it convenient to make several calls in a row.
+ */
+void mipi_dsi_dcs_set_display_on_multi(struct mipi_dsi_multi_context *ctx)
+{
+ struct mipi_dsi_device *dsi = ctx->dsi;
+ struct device *dev = &dsi->dev;
+ ssize_t ret;
+
+ if (ctx->accum_err)
+ return;
+
+ ret = mipi_dsi_dcs_set_display_on(dsi);
+ if (ret < 0) {
+ ctx->accum_err = ret;
+ dev_err(dev, "sending DCS SET_DISPLAY_ON failed: %d\n",
+ ctx->accum_err);
+ }
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on_multi);
+
+/**
+ * mipi_dsi_dcs_set_tear_on_multi() - send DCS SET_TEAR_ON packet
+ * @ctx: Context for multiple DSI transactions
+ * @mode: the Tearing Effect Output Line mode
+ *
+ * Like mipi_dsi_dcs_set_tear_on() but deals with errors in a way that
+ * makes it convenient to make several calls in a row.
+ */
+void mipi_dsi_dcs_set_tear_on_multi(struct mipi_dsi_multi_context *ctx,
+ enum mipi_dsi_dcs_tear_mode mode)
+{
+ struct mipi_dsi_device *dsi = ctx->dsi;
+ struct device *dev = &dsi->dev;
+ ssize_t ret;
+
+ if (ctx->accum_err)
+ return;
+
+ ret = mipi_dsi_dcs_set_tear_on(dsi, mode);
+ if (ret < 0) {
+ ctx->accum_err = ret;
+ dev_err(dev, "sending DCS SET_TEAR_ON failed: %d\n",
+ ctx->accum_err);
+ }
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on_multi);
+
static int mipi_dsi_drv_probe(struct device *dev)
{
struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver);
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 8257f9d4f619..5ace481c1901 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -649,41 +649,6 @@ void drm_mm_remove_node(struct drm_mm_node *node)
EXPORT_SYMBOL(drm_mm_remove_node);
/**
- * drm_mm_replace_node - move an allocation from @old to @new
- * @old: drm_mm_node to remove from the allocator
- * @new: drm_mm_node which should inherit @old's allocation
- *
- * This is useful for when drivers embed the drm_mm_node structure and hence
- * can't move allocations by reassigning pointers. It's a combination of remove
- * and insert with the guarantee that the allocation start will match.
- */
-void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new)
-{
- struct drm_mm *mm = old->mm;
-
- DRM_MM_BUG_ON(!drm_mm_node_allocated(old));
-
- *new = *old;
-
- __set_bit(DRM_MM_NODE_ALLOCATED_BIT, &new->flags);
- list_replace(&old->node_list, &new->node_list);
- rb_replace_node_cached(&old->rb, &new->rb, &mm->interval_tree);
-
- if (drm_mm_hole_follows(old)) {
- list_replace(&old->hole_stack, &new->hole_stack);
- rb_replace_node_cached(&old->rb_hole_size,
- &new->rb_hole_size,
- &mm->holes_size);
- rb_replace_node(&old->rb_hole_addr,
- &new->rb_hole_addr,
- &mm->holes_addr);
- }
-
- clear_bit_unlock(DRM_MM_NODE_ALLOCATED_BIT, &old->flags);
-}
-EXPORT_SYMBOL(drm_mm_replace_node);
-
-/**
* DOC: lru scan roster
*
* Very often GPUs need to have continuous allocations for a given object. When
diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c
index 0e8355063eee..df4cc0e8e263 100644
--- a/drivers/gpu/drm/drm_mode_object.c
+++ b/drivers/gpu/drm/drm_mode_object.c
@@ -478,6 +478,7 @@ struct drm_property *drm_mode_obj_find_prop_id(struct drm_mode_object *obj,
return NULL;
}
+EXPORT_SYMBOL_FOR_TESTS_ONLY(drm_mode_obj_find_prop_id);
static int set_property_legacy(struct drm_mode_object *obj,
struct drm_property *prop,
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 2d8b0371619d..1a0890083aee 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -531,7 +531,8 @@ static int fill_analog_mode(struct drm_device *dev,
* @interlace: whether to compute an interlaced mode
*
* This function creates a struct drm_display_mode instance suited for
- * an analog TV output, for one of the usual analog TV mode.
+ * an analog TV output, for one of the usual analog TV modes. Where
+ * this is DRM_MODE_TV_MODE_MONOCHROME, a 625-line mode will be created.
*
* Note that @hdisplay is larger than the usual constraints for the PAL
* and NTSC timings, and we'll choose to ignore most timings constraints
@@ -569,6 +570,8 @@ struct drm_display_mode *drm_analog_tv_mode(struct drm_device *dev,
case DRM_MODE_TV_MODE_PAL_N:
fallthrough;
case DRM_MODE_TV_MODE_SECAM:
+ fallthrough;
+ case DRM_MODE_TV_MODE_MONOCHROME:
analog = DRM_MODE_ANALOG_PAL;
break;
diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c
index aa93129c3397..ca5a2222ebc0 100644
--- a/drivers/gpu/drm/drm_panel_orientation_quirks.c
+++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c
@@ -501,4 +501,5 @@ EXPORT_SYMBOL(drm_get_panel_orientation_quirk);
#endif
+MODULE_DESCRIPTION("Quirks for non-normal panel orientation");
MODULE_LICENSE("Dual MIT/GPL");
diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
index 7ece67086cec..293d4dcbc80d 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ -12,6 +12,7 @@
#include <linux/kmsg_dump.h>
#include <linux/list.h>
#include <linux/module.h>
+#include <linux/printk.h>
#include <linux/types.h>
#include <drm/drm_drv.h>
@@ -27,6 +28,12 @@ MODULE_AUTHOR("Jocelyn Falempe");
MODULE_DESCRIPTION("DRM panic handler");
MODULE_LICENSE("GPL");
+static char drm_panic_screen[16] = CONFIG_DRM_PANIC_SCREEN;
+module_param_string(panic_screen, drm_panic_screen, sizeof(drm_panic_screen), 0644);
+MODULE_PARM_DESC(panic_screen,
+ "Choose what will be displayed by drm_panic, 'user' or 'kmsg' [default="
+ CONFIG_DRM_PANIC_SCREEN "]");
+
/**
* DOC: overview
*
@@ -194,40 +201,42 @@ static u32 convert_from_xrgb8888(u32 color, u32 format)
/*
* Blit & Fill
*/
+/* check if the pixel at coord x,y is 1 (foreground) or 0 (background) */
+static bool drm_panic_is_pixel_fg(const u8 *sbuf8, unsigned int spitch, int x, int y)
+{
+ return (sbuf8[(y * spitch) + x / 8] & (0x80 >> (x % 8))) != 0;
+}
+
static void drm_panic_blit16(struct iosys_map *dmap, unsigned int dpitch,
const u8 *sbuf8, unsigned int spitch,
unsigned int height, unsigned int width,
- u16 fg16, u16 bg16)
+ u16 fg16)
{
unsigned int y, x;
- u16 val16;
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++) {
- val16 = (sbuf8[(y * spitch) + x / 8] & (0x80 >> (x % 8))) ? fg16 : bg16;
- iosys_map_wr(dmap, y * dpitch + x * sizeof(u16), u16, val16);
- }
- }
+ for (y = 0; y < height; y++)
+ for (x = 0; x < width; x++)
+ if (drm_panic_is_pixel_fg(sbuf8, spitch, x, y))
+ iosys_map_wr(dmap, y * dpitch + x * sizeof(u16), u16, fg16);
}
static void drm_panic_blit24(struct iosys_map *dmap, unsigned int dpitch,
const u8 *sbuf8, unsigned int spitch,
unsigned int height, unsigned int width,
- u32 fg32, u32 bg32)
+ u32 fg32)
{
unsigned int y, x;
- u32 val32;
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
u32 off = y * dpitch + x * 3;
- val32 = (sbuf8[(y * spitch) + x / 8] & (0x80 >> (x % 8))) ? fg32 : bg32;
-
- /* write blue-green-red to output in little endianness */
- iosys_map_wr(dmap, off, u8, (val32 & 0x000000FF) >> 0);
- iosys_map_wr(dmap, off + 1, u8, (val32 & 0x0000FF00) >> 8);
- iosys_map_wr(dmap, off + 2, u8, (val32 & 0x00FF0000) >> 16);
+ if (drm_panic_is_pixel_fg(sbuf8, spitch, x, y)) {
+ /* write blue-green-red to output in little endianness */
+ iosys_map_wr(dmap, off, u8, (fg32 & 0x000000FF) >> 0);
+ iosys_map_wr(dmap, off + 1, u8, (fg32 & 0x0000FF00) >> 8);
+ iosys_map_wr(dmap, off + 2, u8, (fg32 & 0x00FF0000) >> 16);
+ }
}
}
}
@@ -235,55 +244,64 @@ static void drm_panic_blit24(struct iosys_map *dmap, unsigned int dpitch,
static void drm_panic_blit32(struct iosys_map *dmap, unsigned int dpitch,
const u8 *sbuf8, unsigned int spitch,
unsigned int height, unsigned int width,
- u32 fg32, u32 bg32)
+ u32 fg32)
{
unsigned int y, x;
- u32 val32;
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++) {
- val32 = (sbuf8[(y * spitch) + x / 8] & (0x80 >> (x % 8))) ? fg32 : bg32;
- iosys_map_wr(dmap, y * dpitch + x * sizeof(u32), u32, val32);
- }
- }
+ for (y = 0; y < height; y++)
+ for (x = 0; x < width; x++)
+ if (drm_panic_is_pixel_fg(sbuf8, spitch, x, y))
+ iosys_map_wr(dmap, y * dpitch + x * sizeof(u32), u32, fg32);
+}
+
+static void drm_panic_blit_pixel(struct drm_scanout_buffer *sb, struct drm_rect *clip,
+ const u8 *sbuf8, unsigned int spitch, u32 fg_color)
+{
+ unsigned int y, x;
+
+ for (y = 0; y < drm_rect_height(clip); y++)
+ for (x = 0; x < drm_rect_width(clip); x++)
+ if (drm_panic_is_pixel_fg(sbuf8, spitch, x, y))
+ sb->set_pixel(sb, clip->x1 + x, clip->y1 + y, fg_color);
}
/*
* drm_panic_blit - convert a monochrome image to a linear framebuffer
- * @dmap: destination iosys_map
- * @dpitch: destination pitch in bytes
+ * @sb: destination scanout buffer
+ * @clip: destination rectangle
* @sbuf8: source buffer, in monochrome format, 8 pixels per byte.
* @spitch: source pitch in bytes
- * @height: height of the image to copy, in pixels
- * @width: width of the image to copy, in pixels
* @fg_color: foreground color, in destination format
- * @bg_color: background color, in destination format
- * @pixel_width: pixel width in bytes.
*
* This can be used to draw a font character, which is a monochrome image, to a
* framebuffer in other supported format.
*/
-static void drm_panic_blit(struct iosys_map *dmap, unsigned int dpitch,
- const u8 *sbuf8, unsigned int spitch,
- unsigned int height, unsigned int width,
- u32 fg_color, u32 bg_color,
- unsigned int pixel_width)
+static void drm_panic_blit(struct drm_scanout_buffer *sb, struct drm_rect *clip,
+ const u8 *sbuf8, unsigned int spitch, u32 fg_color)
{
- switch (pixel_width) {
+ struct iosys_map map;
+
+ if (sb->set_pixel)
+ return drm_panic_blit_pixel(sb, clip, sbuf8, spitch, fg_color);
+
+ map = sb->map[0];
+ iosys_map_incr(&map, clip->y1 * sb->pitch[0] + clip->x1 * sb->format->cpp[0]);
+
+ switch (sb->format->cpp[0]) {
case 2:
- drm_panic_blit16(dmap, dpitch, sbuf8, spitch,
- height, width, fg_color, bg_color);
+ drm_panic_blit16(&map, sb->pitch[0], sbuf8, spitch,
+ drm_rect_height(clip), drm_rect_width(clip), fg_color);
break;
case 3:
- drm_panic_blit24(dmap, dpitch, sbuf8, spitch,
- height, width, fg_color, bg_color);
+ drm_panic_blit24(&map, sb->pitch[0], sbuf8, spitch,
+ drm_rect_height(clip), drm_rect_width(clip), fg_color);
break;
case 4:
- drm_panic_blit32(dmap, dpitch, sbuf8, spitch,
- height, width, fg_color, bg_color);
+ drm_panic_blit32(&map, sb->pitch[0], sbuf8, spitch,
+ drm_rect_height(clip), drm_rect_width(clip), fg_color);
break;
default:
- WARN_ONCE(1, "Can't blit with pixel width %d\n", pixel_width);
+ WARN_ONCE(1, "Can't blit with pixel width %d\n", sb->format->cpp[0]);
}
}
@@ -327,33 +345,51 @@ static void drm_panic_fill32(struct iosys_map *dmap, unsigned int dpitch,
iosys_map_wr(dmap, y * dpitch + x * sizeof(u32), u32, color);
}
+static void drm_panic_fill_pixel(struct drm_scanout_buffer *sb,
+ struct drm_rect *clip,
+ u32 color)
+{
+ unsigned int y, x;
+
+ for (y = 0; y < drm_rect_height(clip); y++)
+ for (x = 0; x < drm_rect_width(clip); x++)
+ sb->set_pixel(sb, clip->x1 + x, clip->y1 + y, color);
+}
+
/*
* drm_panic_fill - Fill a rectangle with a color
- * @dmap: destination iosys_map, pointing to the top left corner of the rectangle
- * @dpitch: destination pitch in bytes
- * @height: height of the rectangle, in pixels
- * @width: width of the rectangle, in pixels
- * @color: color to fill the rectangle.
- * @pixel_width: pixel width in bytes
+ * @sb: destination scanout buffer
+ * @clip: destination rectangle
+ * @color: foreground color, in destination format
*
* Fill a rectangle with a color, in a linear framebuffer.
*/
-static void drm_panic_fill(struct iosys_map *dmap, unsigned int dpitch,
- unsigned int height, unsigned int width,
- u32 color, unsigned int pixel_width)
+static void drm_panic_fill(struct drm_scanout_buffer *sb, struct drm_rect *clip,
+ u32 color)
{
- switch (pixel_width) {
+ struct iosys_map map;
+
+ if (sb->set_pixel)
+ return drm_panic_fill_pixel(sb, clip, color);
+
+ map = sb->map[0];
+ iosys_map_incr(&map, clip->y1 * sb->pitch[0] + clip->x1 * sb->format->cpp[0]);
+
+ switch (sb->format->cpp[0]) {
case 2:
- drm_panic_fill16(dmap, dpitch, height, width, color);
+ drm_panic_fill16(&map, sb->pitch[0], drm_rect_height(clip),
+ drm_rect_width(clip), color);
break;
case 3:
- drm_panic_fill24(dmap, dpitch, height, width, color);
+ drm_panic_fill24(&map, sb->pitch[0], drm_rect_height(clip),
+ drm_rect_width(clip), color);
break;
case 4:
- drm_panic_fill32(dmap, dpitch, height, width, color);
+ drm_panic_fill32(&map, sb->pitch[0], drm_rect_height(clip),
+ drm_rect_width(clip), color);
break;
default:
- WARN_ONCE(1, "Can't fill with pixel width %d\n", pixel_width);
+ WARN_ONCE(1, "Can't fill with pixel width %d\n", sb->format->cpp[0]);
}
}
@@ -381,53 +417,46 @@ static void draw_txt_rectangle(struct drm_scanout_buffer *sb,
unsigned int msg_lines,
bool centered,
struct drm_rect *clip,
- u32 fg_color,
- u32 bg_color)
+ u32 color)
{
int i, j;
const u8 *src;
size_t font_pitch = DIV_ROUND_UP(font->width, 8);
- struct iosys_map dst;
- unsigned int px_width = sb->format->cpp[0];
- int left = 0;
+ struct drm_rect rec;
msg_lines = min(msg_lines, drm_rect_height(clip) / font->height);
for (i = 0; i < msg_lines; i++) {
size_t line_len = min(msg[i].len, drm_rect_width(clip) / font->width);
+ rec.y1 = clip->y1 + i * font->height;
+ rec.y2 = rec.y1 + font->height;
+ rec.x1 = clip->x1;
+
if (centered)
- left = (drm_rect_width(clip) - (line_len * font->width)) / 2;
+ rec.x1 += (drm_rect_width(clip) - (line_len * font->width)) / 2;
- dst = sb->map[0];
- iosys_map_incr(&dst, (clip->y1 + i * font->height) * sb->pitch[0] +
- (clip->x1 + left) * px_width);
for (j = 0; j < line_len; j++) {
src = get_char_bitmap(font, msg[i].txt[j], font_pitch);
- drm_panic_blit(&dst, sb->pitch[0], src, font_pitch,
- font->height, font->width,
- fg_color, bg_color, px_width);
- iosys_map_incr(&dst, font->width * px_width);
+ rec.x2 = rec.x1 + font->width;
+ drm_panic_blit(sb, &rec, src, font_pitch, color);
+ rec.x1 += font->width;
}
}
}
-/*
- * Draw the panic message at the center of the screen
- */
-static void draw_panic_static(struct drm_scanout_buffer *sb)
+static void draw_panic_static_user(struct drm_scanout_buffer *sb)
{
size_t msg_lines = ARRAY_SIZE(panic_msg);
size_t logo_lines = ARRAY_SIZE(logo);
- u32 fg_color = CONFIG_DRM_PANIC_FOREGROUND_COLOR;
- u32 bg_color = CONFIG_DRM_PANIC_BACKGROUND_COLOR;
+ u32 fg_color = convert_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR, sb->format->format);
+ u32 bg_color = convert_from_xrgb8888(CONFIG_DRM_PANIC_BACKGROUND_COLOR, sb->format->format);
const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL);
- struct drm_rect r_logo, r_msg;
+ struct drm_rect r_screen, r_logo, r_msg;
if (!font)
return;
- fg_color = convert_from_xrgb8888(fg_color, sb->format->format);
- bg_color = convert_from_xrgb8888(bg_color, sb->format->format);
+ r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height);
r_logo = DRM_RECT_INIT(0, 0,
get_max_line_len(logo, logo_lines) * font->width,
@@ -440,14 +469,92 @@ static void draw_panic_static(struct drm_scanout_buffer *sb)
drm_rect_translate(&r_msg, (sb->width - r_msg.x2) / 2, (sb->height - r_msg.y2) / 2);
/* Fill with the background color, and draw text on top */
- drm_panic_fill(&sb->map[0], sb->pitch[0], sb->height, sb->width,
- bg_color, sb->format->cpp[0]);
+ drm_panic_fill(sb, &r_screen, bg_color);
if ((r_msg.x1 >= drm_rect_width(&r_logo) || r_msg.y1 >= drm_rect_height(&r_logo)) &&
drm_rect_width(&r_logo) < sb->width && drm_rect_height(&r_logo) < sb->height) {
- draw_txt_rectangle(sb, font, logo, logo_lines, false, &r_logo, fg_color, bg_color);
+ draw_txt_rectangle(sb, font, logo, logo_lines, false, &r_logo, fg_color);
+ }
+ draw_txt_rectangle(sb, font, panic_msg, msg_lines, true, &r_msg, fg_color);
+}
+
+/*
+ * Draw one line of kmsg, and handle wrapping if it won't fit in the screen width.
+ * Return the y-offset of the next line.
+ */
+static int draw_line_with_wrap(struct drm_scanout_buffer *sb, const struct font_desc *font,
+ struct drm_panic_line *line, int yoffset, u32 fg_color)
+{
+ int chars_per_row = sb->width / font->width;
+ struct drm_rect r_txt = DRM_RECT_INIT(0, yoffset, sb->width, sb->height);
+ struct drm_panic_line line_wrap;
+
+ if (line->len > chars_per_row) {
+ line_wrap.len = line->len % chars_per_row;
+ line_wrap.txt = line->txt + line->len - line_wrap.len;
+ draw_txt_rectangle(sb, font, &line_wrap, 1, false, &r_txt, fg_color);
+ r_txt.y1 -= font->height;
+ if (r_txt.y1 < 0)
+ return r_txt.y1;
+ while (line_wrap.txt > line->txt) {
+ line_wrap.txt -= chars_per_row;
+ line_wrap.len = chars_per_row;
+ draw_txt_rectangle(sb, font, &line_wrap, 1, false, &r_txt, fg_color);
+ r_txt.y1 -= font->height;
+ if (r_txt.y1 < 0)
+ return r_txt.y1;
+ }
+ } else {
+ draw_txt_rectangle(sb, font, line, 1, false, &r_txt, fg_color);
+ r_txt.y1 -= font->height;
+ }
+ return r_txt.y1;
+}
+
+/*
+ * Draw the kmsg buffer to the screen, starting from the youngest message at the bottom,
+ * and going up until reaching the top of the screen.
+ */
+static void draw_panic_static_kmsg(struct drm_scanout_buffer *sb)
+{
+ u32 fg_color = convert_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR, sb->format->format);
+ u32 bg_color = convert_from_xrgb8888(CONFIG_DRM_PANIC_BACKGROUND_COLOR, sb->format->format);
+ const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL);
+ struct drm_rect r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height);
+ struct kmsg_dump_iter iter;
+ char kmsg_buf[512];
+ size_t kmsg_len;
+ struct drm_panic_line line;
+ int yoffset;
+
+ if (!font)
+ return;
+
+ yoffset = sb->height - font->height - (sb->height % font->height) / 2;
+
+ /* Fill with the background color, and draw text on top */
+ drm_panic_fill(sb, &r_screen, bg_color);
+
+ kmsg_dump_rewind(&iter);
+ while (kmsg_dump_get_buffer(&iter, false, kmsg_buf, sizeof(kmsg_buf), &kmsg_len)) {
+ char *start;
+ char *end;
+
+ /* ignore terminating NUL and newline */
+ start = kmsg_buf + kmsg_len - 2;
+ end = kmsg_buf + kmsg_len - 1;
+ while (start > kmsg_buf && yoffset >= 0) {
+ while (start > kmsg_buf && *start != '\n')
+ start--;
+ /* don't count the newline character */
+ line.txt = start + (start == kmsg_buf ? 0 : 1);
+ line.len = end - line.txt;
+
+ yoffset = draw_line_with_wrap(sb, font, &line, yoffset, fg_color);
+ end = start;
+ start--;
+ }
}
- draw_txt_rectangle(sb, font, panic_msg, msg_lines, true, &r_msg, fg_color, bg_color);
}
/*
@@ -464,6 +571,15 @@ static bool drm_panic_is_format_supported(const struct drm_format_info *format)
return convert_from_xrgb8888(0xffffff, format->format) != 0;
}
+static void draw_panic_dispatch(struct drm_scanout_buffer *sb)
+{
+ if (!strcmp(drm_panic_screen, "kmsg")) {
+ draw_panic_static_kmsg(sb);
+ } else {
+ draw_panic_static_user(sb);
+ }
+}
+
static void draw_panic_plane(struct drm_plane *plane)
{
struct drm_scanout_buffer sb;
@@ -476,7 +592,7 @@ static void draw_panic_plane(struct drm_plane *plane)
ret = plane->helper_private->get_scanout_buffer(plane, &sb);
if (!ret && drm_panic_is_format_supported(sb.format)) {
- draw_panic_static(&sb);
+ draw_panic_dispatch(&sb);
if (plane->helper_private->panic_flush)
plane->helper_private->panic_flush(plane);
}
diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index cf2efb44722c..cf24dfdeb6b2 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -176,6 +176,32 @@ void __drm_printfn_seq_file(struct drm_printer *p, struct va_format *vaf)
}
EXPORT_SYMBOL(__drm_printfn_seq_file);
+static void __drm_dev_vprintk(const struct device *dev, const char *level,
+ const void *origin, const char *prefix,
+ struct va_format *vaf)
+{
+ const char *prefix_pad = prefix ? " " : "";
+
+ if (!prefix)
+ prefix = "";
+
+ if (dev) {
+ if (origin)
+ dev_printk(level, dev, "[" DRM_NAME ":%ps]%s%s %pV",
+ origin, prefix_pad, prefix, vaf);
+ else
+ dev_printk(level, dev, "[" DRM_NAME "]%s%s %pV",
+ prefix_pad, prefix, vaf);
+ } else {
+ if (origin)
+ printk("%s" "[" DRM_NAME ":%ps]%s%s %pV",
+ level, origin, prefix_pad, prefix, vaf);
+ else
+ printk("%s" "[" DRM_NAME "]%s%s %pV",
+ level, prefix_pad, prefix, vaf);
+ }
+}
+
void __drm_printfn_info(struct drm_printer *p, struct va_format *vaf)
{
dev_info(p->arg, "[" DRM_NAME "] %pV", vaf);
@@ -187,19 +213,11 @@ void __drm_printfn_dbg(struct drm_printer *p, struct va_format *vaf)
const struct drm_device *drm = p->arg;
const struct device *dev = drm ? drm->dev : NULL;
enum drm_debug_category category = p->category;
- const char *prefix = p->prefix ?: "";
- const char *prefix_pad = p->prefix ? " " : "";
if (!__drm_debug_enabled(category))
return;
- /* Note: __builtin_return_address(0) is useless here. */
- if (dev)
- dev_printk(KERN_DEBUG, dev, "[" DRM_NAME "]%s%s %pV",
- prefix_pad, prefix, vaf);
- else
- printk(KERN_DEBUG "[" DRM_NAME "]%s%s %pV",
- prefix_pad, prefix, vaf);
+ __drm_dev_vprintk(dev, KERN_DEBUG, p->origin, p->prefix, vaf);
}
EXPORT_SYMBOL(__drm_printfn_dbg);
@@ -287,12 +305,7 @@ void drm_dev_printk(const struct device *dev, const char *level,
vaf.fmt = format;
vaf.va = &args;
- if (dev)
- dev_printk(level, dev, "[" DRM_NAME ":%ps] %pV",
- __builtin_return_address(0), &vaf);
- else
- printk("%s" "[" DRM_NAME ":%ps] %pV",
- level, __builtin_return_address(0), &vaf);
+ __drm_dev_vprintk(dev, level, __builtin_return_address(0), NULL, &vaf);
va_end(args);
}
@@ -312,36 +325,12 @@ void __drm_dev_dbg(struct _ddebug *desc, const struct device *dev,
vaf.fmt = format;
vaf.va = &args;
- if (dev)
- dev_printk(KERN_DEBUG, dev, "[" DRM_NAME ":%ps] %pV",
- __builtin_return_address(0), &vaf);
- else
- printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV",
- __builtin_return_address(0), &vaf);
+ __drm_dev_vprintk(dev, KERN_DEBUG, __builtin_return_address(0), NULL, &vaf);
va_end(args);
}
EXPORT_SYMBOL(__drm_dev_dbg);
-void ___drm_dbg(struct _ddebug *desc, enum drm_debug_category category, const char *format, ...)
-{
- struct va_format vaf;
- va_list args;
-
- if (!__drm_debug_enabled(category))
- return;
-
- va_start(args, format);
- vaf.fmt = format;
- vaf.va = &args;
-
- printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV",
- __builtin_return_address(0), &vaf);
-
- va_end(args);
-}
-EXPORT_SYMBOL(___drm_dbg);
-
void __drm_err(const char *format, ...)
{
struct va_format vaf;
@@ -351,8 +340,7 @@ void __drm_err(const char *format, ...)
vaf.fmt = format;
vaf.va = &args;
- printk(KERN_ERR "[" DRM_NAME ":%ps] *ERROR* %pV",
- __builtin_return_address(0), &vaf);
+ __drm_dev_vprintk(NULL, KERN_ERR, __builtin_return_address(0), "*ERROR*", &vaf);
va_end(args);
}
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index 4f75a1cfd820..bb49d552e671 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -474,6 +474,10 @@ static int __drm_helper_update_and_validate(struct drm_connector *connector,
if (mode->status != MODE_OK)
continue;
+ mode->status = drm_mode_validate_ycbcr420(mode, connector);
+ if (mode->status != MODE_OK)
+ continue;
+
ret = drm_mode_validate_pipeline(mode, connector, ctx,
&mode->status);
if (ret) {
@@ -486,10 +490,6 @@ static int __drm_helper_update_and_validate(struct drm_connector *connector,
else
return -EDEADLK;
}
-
- if (mode->status != MODE_OK)
- continue;
- mode->status = drm_mode_validate_ycbcr420(mode, connector);
}
return 0;
@@ -1259,8 +1259,9 @@ int drm_connector_helper_tv_get_modes(struct drm_connector *connector)
for (i = 0; i < tv_mode_property->num_values; i++)
supported_tv_modes |= BIT(tv_mode_property->values[i]);
- if ((supported_tv_modes & ntsc_modes) &&
- (supported_tv_modes & pal_modes)) {
+ if (((supported_tv_modes & ntsc_modes) &&
+ (supported_tv_modes & pal_modes)) ||
+ (supported_tv_modes & BIT(DRM_MODE_TV_MODE_MONOCHROME))) {
uint64_t default_mode;
if (drm_object_property_get_default_value(&connector->base,
diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c b/drivers/gpu/drm/drm_simple_kms_helper.c
index 270523ae36d4..250819fbc5ce 100644
--- a/drivers/gpu/drm/drm_simple_kms_helper.c
+++ b/drivers/gpu/drm/drm_simple_kms_helper.c
@@ -453,4 +453,5 @@ int drm_simple_display_pipe_init(struct drm_device *dev,
}
EXPORT_SYMBOL(drm_simple_display_pipe_init);
+MODULE_DESCRIPTION("Helpers for drivers for simple display hardware");
MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index bd9b8ab4f82b..fb3bbb6adcd1 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -266,29 +266,9 @@ static ssize_t edid_show(struct file *filp, struct kobject *kobj,
{
struct device *connector_dev = kobj_to_dev(kobj);
struct drm_connector *connector = to_drm_connector(connector_dev);
- unsigned char *edid;
- size_t size;
- ssize_t ret = 0;
+ ssize_t ret;
- mutex_lock(&connector->dev->mode_config.mutex);
- if (!connector->edid_blob_ptr)
- goto unlock;
-
- edid = connector->edid_blob_ptr->data;
- size = connector->edid_blob_ptr->length;
- if (!edid)
- goto unlock;
-
- if (off >= size)
- goto unlock;
-
- if (off + count > size)
- count = size - off;
- memcpy(buf, edid + off, count);
-
- ret = count;
-unlock:
- mutex_unlock(&connector->dev->mode_config.mutex);
+ ret = drm_edid_connector_property_show(connector, buf, off, count);
return ret;
}
diff --git a/drivers/gpu/drm/gma500/cdv_intel_dp.c b/drivers/gpu/drm/gma500/cdv_intel_dp.c
index dd1eb7e9877d..cc2ed9b3fd2d 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_dp.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_dp.c
@@ -1547,7 +1547,7 @@ cdv_intel_dp_start_link_train(struct gma_encoder *encoder)
}
if (!clock_recovery) {
- DRM_DEBUG_KMS("failure in DP patter 1 training, train set %x\n", intel_dp->train_set[0]);
+ DRM_DEBUG_KMS("failure in DP pattern 1 training, train set %x\n", intel_dp->train_set[0]);
}
intel_dp->DP = DP;
diff --git a/drivers/gpu/drm/gud/gud_drv.c b/drivers/gpu/drm/gud/gud_drv.c
index 9d7bf8ee45f1..ac6bbf920c72 100644
--- a/drivers/gpu/drm/gud/gud_drv.c
+++ b/drivers/gpu/drm/gud/gud_drv.c
@@ -18,7 +18,7 @@
#include <drm/drm_damage_helper.h>
#include <drm/drm_debugfs.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_shmem.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
@@ -622,7 +622,7 @@ static int gud_probe(struct usb_interface *intf, const struct usb_device_id *id)
drm_kms_helper_poll_init(drm);
- drm_fbdev_generic_setup(drm, 0);
+ drm_fbdev_shmem_setup(drm, 0);
return 0;
}
@@ -678,4 +678,5 @@ static struct usb_driver gud_usb_driver = {
module_usb_driver(gud_usb_driver);
MODULE_AUTHOR("Noralf Trønnes");
+MODULE_DESCRIPTION("GUD USB Display driver");
MODULE_LICENSE("Dual MIT/GPL");
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
index 57c21ec452b7..9f9b19ea0587 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
@@ -17,7 +17,7 @@
#include <drm/drm_aperture.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_ttm.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_gem_vram_helper.h>
#include <drm/drm_managed.h>
@@ -339,7 +339,7 @@ static int hibmc_pci_probe(struct pci_dev *pdev,
goto err_unload;
}
- drm_fbdev_generic_setup(dev, 32);
+ drm_fbdev_ttm_setup(dev, 32);
return 0;
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
index 94e2c573a7af..409c551c92af 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
@@ -24,14 +24,16 @@
static int hibmc_connector_get_modes(struct drm_connector *connector)
{
- int count;
- void *edid;
struct hibmc_connector *hibmc_connector = to_hibmc_connector(connector);
+ const struct drm_edid *drm_edid;
+ int count;
+
+ drm_edid = drm_edid_read_ddc(connector, &hibmc_connector->adapter);
- edid = drm_get_edid(connector, &hibmc_connector->adapter);
- if (edid) {
- drm_connector_update_edid_property(connector, edid);
- count = drm_add_edid_modes(connector, edid);
+ drm_edid_connector_update(connector, drm_edid);
+
+ if (drm_edid) {
+ count = drm_edid_connector_add_modes(connector);
if (count)
goto out;
}
@@ -42,7 +44,8 @@ static int hibmc_connector_get_modes(struct drm_connector *connector)
drm_set_preferred_mode(connector, 1024, 768);
out:
- kfree(edid);
+ drm_edid_free(drm_edid);
+
return count;
}
diff --git a/drivers/gpu/drm/hisilicon/kirin/Kconfig b/drivers/gpu/drm/hisilicon/kirin/Kconfig
index c5265675bf0c..0772f79567ef 100644
--- a/drivers/gpu/drm/hisilicon/kirin/Kconfig
+++ b/drivers/gpu/drm/hisilicon/kirin/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config DRM_HISI_KIRIN
tristate "DRM Support for Hisilicon Kirin series SoCs Platform"
- depends on DRM && OF && ARM64
+ depends on DRM && OF && (ARM64 || COMPILE_TEST)
select DRM_KMS_HELPER
select DRM_GEM_DMA_HELPER
select DRM_MIPI_DSI
diff --git a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c
index 566de4658719..a39cc549c20b 100644
--- a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c
+++ b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c
@@ -157,8 +157,8 @@ static u32 dsi_calc_phy_rate(u32 req_kHz, struct mipi_phy_params *phy)
q_pll = 0x10 >> (7 - phy->hstx_ckg_sel);
temp = f_kHz * (u64)q_pll * (u64)ref_clk_ps;
- m_n_int = temp / (u64)1000000000;
- m_n = (temp % (u64)1000000000) / (u64)100000000;
+ m_n_int = div64_u64_rem(temp, 1000000000, &temp);
+ m_n = div_u64(temp, 100000000);
if (m_n_int % 2 == 0) {
if (m_n * 6 >= 50) {
@@ -229,9 +229,8 @@ static u32 dsi_calc_phy_rate(u32 req_kHz, struct mipi_phy_params *phy)
phy->pll_fbd_div5f = 1;
}
- f_kHz = (u64)1000000000 * (u64)m_pll /
- ((u64)ref_clk_ps * (u64)n_pll * (u64)q_pll);
-
+ f_kHz = div64_u64((u64)1000000000 * (u64)m_pll,
+ (u64)ref_clk_ps * (u64)n_pll * (u64)q_pll);
if (f_kHz >= req_kHz)
break;
@@ -490,7 +489,7 @@ static void dsi_set_mode_timing(void __iomem *base,
hsa_time = (hsw * lane_byte_clk_kHz) / pixel_clk_kHz;
hbp_time = (hbp * lane_byte_clk_kHz) / pixel_clk_kHz;
tmp = (u64)htot * (u64)lane_byte_clk_kHz;
- hline_time = DIV_ROUND_UP(tmp, pixel_clk_kHz);
+ hline_time = DIV_ROUND_UP_ULL(tmp, pixel_clk_kHz);
/* all specified in byte-lane clocks */
writel(hsa_time, base + VID_HSA_TIME);
diff --git a/drivers/gpu/drm/hisilicon/kirin/dw_dsi_reg.h b/drivers/gpu/drm/hisilicon/kirin/dw_dsi_reg.h
index d79fc031e53d..a87d1135856f 100644
--- a/drivers/gpu/drm/hisilicon/kirin/dw_dsi_reg.h
+++ b/drivers/gpu/drm/hisilicon/kirin/dw_dsi_reg.h
@@ -7,6 +7,8 @@
#ifndef __DW_DSI_REG_H__
#define __DW_DSI_REG_H__
+#include <linux/io.h>
+
#define MASK(x) (BIT(x) - 1)
/*
diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_ade_reg.h b/drivers/gpu/drm/hisilicon/kirin/kirin_ade_reg.h
index be9e789c2d04..36f923cc7594 100644
--- a/drivers/gpu/drm/hisilicon/kirin/kirin_ade_reg.h
+++ b/drivers/gpu/drm/hisilicon/kirin/kirin_ade_reg.h
@@ -10,7 +10,7 @@
/*
* ADE Registers
*/
-#define MASK(x) (BIT(x) - 1)
+#define MASK(x) (BIT_ULL(x) - 1)
#define ADE_CTRL 0x0004
#define FRM_END_START_OFST 0
diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
index 75292a2f4644..12666985686b 100644
--- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
+++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
@@ -19,7 +19,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_dma.h>
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_module.h>
@@ -237,7 +237,7 @@ static int kirin_drm_bind(struct device *dev)
if (ret)
goto err_kms_cleanup;
- drm_fbdev_generic_setup(drm_dev, 32);
+ drm_fbdev_dma_setup(drm_dev, 32);
return 0;
diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
index cff85086f2d6..ff93e08d5036 100644
--- a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
+++ b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
@@ -11,7 +11,7 @@
#include <drm/drm_aperture.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_shmem.h>
#include <drm/drm_gem_shmem_helper.h>
#include <drm/drm_simple_kms_helper.h>
@@ -149,7 +149,7 @@ static int hyperv_vmbus_probe(struct hv_device *hdev,
goto err_free_mmio;
}
- drm_fbdev_generic_setup(dev, 0);
+ drm_fbdev_shmem_setup(dev, 0);
return 0;
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index d8d7de18dd65..2160f05bbd16 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -1283,7 +1283,7 @@ static int read_edid_block(void *data, u8 *buf, unsigned int blk, size_t length)
static int tda998x_connector_get_modes(struct drm_connector *connector)
{
struct tda998x_priv *priv = conn_to_tda998x_priv(connector);
- struct edid *edid;
+ const struct drm_edid *drm_edid;
int n;
/*
@@ -1297,25 +1297,26 @@ static int tda998x_connector_get_modes(struct drm_connector *connector)
if (priv->rev == TDA19988)
reg_clear(priv, REG_TX4, TX4_PD_RAM);
- edid = drm_do_get_edid(connector, read_edid_block, priv);
+ drm_edid = drm_edid_read_custom(connector, read_edid_block, priv);
if (priv->rev == TDA19988)
reg_set(priv, REG_TX4, TX4_PD_RAM);
- if (!edid) {
+ drm_edid_connector_update(connector, drm_edid);
+ cec_notifier_set_phys_addr(priv->cec_notify,
+ connector->display_info.source_physical_address);
+
+ if (!drm_edid) {
dev_warn(&priv->hdmi->dev, "failed to read EDID\n");
return 0;
}
- drm_connector_update_edid_property(connector, edid);
- cec_notifier_set_phys_addr_from_edid(priv->cec_notify, edid);
-
mutex_lock(&priv->audio_mutex);
- n = drm_add_edid_modes(connector, edid);
- priv->sink_has_audio = drm_detect_monitor_audio(edid);
+ n = drm_edid_connector_add_modes(connector);
+ priv->sink_has_audio = connector->display_info.has_audio;
mutex_unlock(&priv->audio_mutex);
- kfree(edid);
+ drm_edid_free(drm_edid);
return n;
}
diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index 5932024f8f95..faa253b27664 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -29,7 +29,6 @@ config DRM_I915
select X86_PLATFORM_DEVICES if ACPI
select ACPI_WMI if ACPI
select ACPI_VIDEO if ACPI
- select ACPI_BUTTON if ACPI
select SYNC_FILE
select IOSF_MBI if X86
select CRC32
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index c8c8b31da4fb..c63fa2133ccb 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -3,31 +3,8 @@
# Makefile for the drm device driver. This driver provides support for the
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
-# Unconditionally enable W=1 warnings locally
-# --- begin copy-paste W=1 warnings from scripts/Makefile.extrawarn
-subdir-ccflags-y += -Wextra -Wunused -Wno-unused-parameter
-subdir-ccflags-y += -Wmissing-declarations
-subdir-ccflags-y += $(call cc-option, -Wrestrict)
-subdir-ccflags-y += -Wmissing-format-attribute
-subdir-ccflags-y += -Wmissing-prototypes
-subdir-ccflags-y += -Wold-style-definition
-subdir-ccflags-y += -Wmissing-include-dirs
-subdir-ccflags-y += $(call cc-option, -Wunused-but-set-variable)
-subdir-ccflags-y += $(call cc-option, -Wunused-const-variable)
-subdir-ccflags-y += $(call cc-option, -Wpacked-not-aligned)
-subdir-ccflags-y += $(call cc-option, -Wformat-overflow)
+# Enable W=1 warnings not enabled in drm subsystem Makefile
subdir-ccflags-y += $(call cc-option, -Wformat-truncation)
-subdir-ccflags-y += $(call cc-option, -Wstringop-truncation)
-# The following turn off the warnings enabled by -Wextra
-ifeq ($(findstring 2, $(KBUILD_EXTRA_WARN)),)
-subdir-ccflags-y += -Wno-missing-field-initializers
-subdir-ccflags-y += -Wno-type-limits
-subdir-ccflags-y += -Wno-shift-negative-value
-endif
-ifeq ($(findstring 3, $(KBUILD_EXTRA_WARN)),)
-subdir-ccflags-y += -Wno-sign-compare
-endif
-# --- end copy-paste
# Enable -Werror in CI and development
subdir-ccflags-$(CONFIG_DRM_I915_WERROR) += -Werror
@@ -243,6 +220,7 @@ i915-y += \
display/hsw_ips.o \
display/i9xx_plane.o \
display/i9xx_wm.o \
+ display/intel_alpm.o \
display/intel_atomic.o \
display/intel_atomic_plane.o \
display/intel_audio.o \
@@ -351,6 +329,7 @@ i915-y += \
display/intel_dsi_dcs_backlight.o \
display/intel_dsi_vbt.o \
display/intel_dvo.o \
+ display/intel_encoder.o \
display/intel_gmbus.o \
display/intel_hdmi.o \
display/intel_lspcon.o \
diff --git a/drivers/gpu/drm/i915/display/dvo_ns2501.c b/drivers/gpu/drm/i915/display/dvo_ns2501.c
index 1df212fb000e..21486008dae9 100644
--- a/drivers/gpu/drm/i915/display/dvo_ns2501.c
+++ b/drivers/gpu/drm/i915/display/dvo_ns2501.c
@@ -27,7 +27,6 @@
*/
#include "i915_drv.h"
-#include "i915_reg.h"
#include "intel_display_types.h"
#include "intel_dvo_dev.h"
diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c
index 06ec04e667e3..a8e746a0f670 100644
--- a/drivers/gpu/drm/i915/display/g4x_dp.c
+++ b/drivers/gpu/drm/i915/display/g4x_dp.c
@@ -20,6 +20,7 @@
#include "intel_dp_aux.h"
#include "intel_dp_link_training.h"
#include "intel_dpio_phy.h"
+#include "intel_encoder.h"
#include "intel_fifo_underrun.h"
#include "intel_hdmi.h"
#include "intel_hotplug.h"
@@ -706,7 +707,7 @@ static void intel_enable_dp(struct intel_atomic_state *state,
intel_dp_configure_protocol_converter(intel_dp, pipe_config);
intel_dp_check_frl_training(intel_dp);
intel_dp_pcon_dsc_configure(intel_dp, pipe_config);
- intel_dp_start_link_train(intel_dp, pipe_config);
+ intel_dp_start_link_train(state, intel_dp, pipe_config);
intel_dp_stop_link_train(intel_dp, pipe_config);
}
@@ -1159,9 +1160,7 @@ intel_dp_hotplug(struct intel_encoder *encoder,
struct intel_connector *connector)
{
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
- struct drm_modeset_acquire_ctx ctx;
enum intel_hotplug_state state;
- int ret;
if (intel_dp->compliance.test_active &&
intel_dp->compliance.test_type == DP_TEST_LINK_PHY_TEST_PATTERN) {
@@ -1172,23 +1171,7 @@ intel_dp_hotplug(struct intel_encoder *encoder,
state = intel_encoder_hotplug(encoder, connector);
- drm_modeset_acquire_init(&ctx, 0);
-
- for (;;) {
- ret = intel_dp_retrain_link(encoder, &ctx);
-
- if (ret == -EDEADLK) {
- drm_modeset_backoff(&ctx);
- continue;
- }
-
- break;
- }
-
- drm_modeset_drop_locks(&ctx);
- drm_modeset_acquire_fini(&ctx);
- drm_WARN(encoder->base.dev, ret,
- "Acquiring modeset locks failed with %i\n", ret);
+ intel_dp_check_link_state(intel_dp);
/*
* Keeping it consistent with intel_ddi_hotplug() and
@@ -1228,7 +1211,7 @@ static bool g4x_digital_port_connected(struct intel_encoder *encoder)
return false;
}
- return intel_de_read(dev_priv, PORT_HOTPLUG_STAT) & bit;
+ return intel_de_read(dev_priv, PORT_HOTPLUG_STAT(dev_priv)) & bit;
}
static bool ilk_digital_port_connected(struct intel_encoder *encoder)
@@ -1239,6 +1222,15 @@ static bool ilk_digital_port_connected(struct intel_encoder *encoder)
return intel_de_read(dev_priv, DEISR) & bit;
}
+static void g4x_dp_suspend_complete(struct intel_encoder *encoder)
+{
+ /*
+ * TODO: Move this to intel_dp_encoder_suspend(),
+ * once modeset locking around that is removed.
+ */
+ intel_encoder_link_check_flush_work(encoder);
+}
+
static void intel_dp_encoder_destroy(struct drm_encoder *encoder)
{
intel_dp_encoder_flush_work(encoder);
@@ -1325,6 +1317,8 @@ bool g4x_dp_init(struct drm_i915_private *dev_priv,
"DP %c", port_name(port)))
goto err_encoder_init;
+ intel_encoder_link_check_init(intel_encoder, intel_dp_link_check);
+
intel_encoder->hotplug = intel_dp_hotplug;
intel_encoder->compute_config = intel_dp_compute_config;
intel_encoder->get_hw_state = intel_dp_get_hw_state;
@@ -1333,6 +1327,7 @@ bool g4x_dp_init(struct drm_i915_private *dev_priv,
intel_encoder->initial_fastset_check = intel_dp_initial_fastset_check;
intel_encoder->update_pipe = intel_backlight_update;
intel_encoder->suspend = intel_dp_encoder_suspend;
+ intel_encoder->suspend_complete = g4x_dp_suspend_complete;
intel_encoder->shutdown = intel_dp_encoder_shutdown;
if (IS_CHERRYVIEW(dev_priv)) {
intel_encoder->pre_pll_enable = chv_dp_pre_pll_enable;
diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c
index 0279c8aabdd1..864d94406894 100644
--- a/drivers/gpu/drm/i915/display/i9xx_plane.c
+++ b/drivers/gpu/drm/i915/display/i9xx_plane.c
@@ -10,6 +10,7 @@
#include "i915_reg.h"
#include "i9xx_plane.h"
+#include "i9xx_plane_regs.h"
#include "intel_atomic.h"
#include "intel_atomic_plane.h"
#include "intel_de.h"
@@ -266,7 +267,7 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
* despite them not using the linear offset anymore.
*/
if (DISPLAY_VER(dev_priv) >= 4 && fb->modifier == I915_FORMAT_MOD_X_TILED) {
- u32 alignment = intel_surf_alignment(fb, 0);
+ unsigned int alignment = intel_surf_alignment(fb, 0);
int cpp = fb->format->cpp[0];
while ((src_x + src_w) * cpp > plane_state->view.color_plane[0].mapping_stride) {
@@ -422,7 +423,7 @@ static void i9xx_plane_update_noarm(struct intel_plane *plane,
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
- intel_de_write_fw(dev_priv, DSPSTRIDE(i9xx_plane),
+ intel_de_write_fw(dev_priv, DSPSTRIDE(dev_priv, i9xx_plane),
plane_state->view.color_plane[0].mapping_stride);
if (DISPLAY_VER(dev_priv) < 4) {
@@ -436,9 +437,9 @@ static void i9xx_plane_update_noarm(struct intel_plane *plane,
* generator but let's assume we still need to
* program whatever is there.
*/
- intel_de_write_fw(dev_priv, DSPPOS(i9xx_plane),
+ intel_de_write_fw(dev_priv, DSPPOS(dev_priv, i9xx_plane),
DISP_POS_Y(crtc_y) | DISP_POS_X(crtc_x));
- intel_de_write_fw(dev_priv, DSPSIZE(i9xx_plane),
+ intel_de_write_fw(dev_priv, DSPSIZE(dev_priv, i9xx_plane),
DISP_HEIGHT(crtc_h - 1) | DISP_WIDTH(crtc_w - 1));
}
}
@@ -455,6 +456,11 @@ static void i9xx_plane_update_arm(struct intel_plane *plane,
dspcntr = plane_state->ctl | i9xx_plane_ctl_crtc(crtc_state);
+ /* see intel_plane_atomic_calc_changes() */
+ if (plane->need_async_flip_toggle_wa &&
+ crtc_state->async_flip_planes & BIT(plane->id))
+ dspcntr |= DISP_ASYNC_FLIP;
+
linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
if (DISPLAY_VER(dev_priv) >= 4)
@@ -468,20 +474,21 @@ static void i9xx_plane_update_arm(struct intel_plane *plane,
int crtc_w = drm_rect_width(&plane_state->uapi.dst);
int crtc_h = drm_rect_height(&plane_state->uapi.dst);
- intel_de_write_fw(dev_priv, PRIMPOS(i9xx_plane),
+ intel_de_write_fw(dev_priv, PRIMPOS(dev_priv, i9xx_plane),
PRIM_POS_Y(crtc_y) | PRIM_POS_X(crtc_x));
- intel_de_write_fw(dev_priv, PRIMSIZE(i9xx_plane),
+ intel_de_write_fw(dev_priv, PRIMSIZE(dev_priv, i9xx_plane),
PRIM_HEIGHT(crtc_h - 1) | PRIM_WIDTH(crtc_w - 1));
- intel_de_write_fw(dev_priv, PRIMCNSTALPHA(i9xx_plane), 0);
+ intel_de_write_fw(dev_priv,
+ PRIMCNSTALPHA(dev_priv, i9xx_plane), 0);
}
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
- intel_de_write_fw(dev_priv, DSPOFFSET(i9xx_plane),
+ intel_de_write_fw(dev_priv, DSPOFFSET(dev_priv, i9xx_plane),
DISP_OFFSET_Y(y) | DISP_OFFSET_X(x));
} else if (DISPLAY_VER(dev_priv) >= 4) {
- intel_de_write_fw(dev_priv, DSPLINOFF(i9xx_plane),
+ intel_de_write_fw(dev_priv, DSPLINOFF(dev_priv, i9xx_plane),
linear_offset);
- intel_de_write_fw(dev_priv, DSPTILEOFF(i9xx_plane),
+ intel_de_write_fw(dev_priv, DSPTILEOFF(dev_priv, i9xx_plane),
DISP_OFFSET_Y(y) | DISP_OFFSET_X(x));
}
@@ -490,13 +497,13 @@ static void i9xx_plane_update_arm(struct intel_plane *plane,
* disabled. Try to make the plane enable atomic by writing
* the control register just before the surface register.
*/
- intel_de_write_fw(dev_priv, DSPCNTR(i9xx_plane), dspcntr);
+ intel_de_write_fw(dev_priv, DSPCNTR(dev_priv, i9xx_plane), dspcntr);
if (DISPLAY_VER(dev_priv) >= 4)
- intel_de_write_fw(dev_priv, DSPSURF(i9xx_plane),
+ intel_de_write_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane),
intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
else
- intel_de_write_fw(dev_priv, DSPADDR(i9xx_plane),
+ intel_de_write_fw(dev_priv, DSPADDR(dev_priv, i9xx_plane),
intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
}
@@ -533,12 +540,12 @@ static void i9xx_plane_disable_arm(struct intel_plane *plane,
*/
dspcntr = i9xx_plane_ctl_crtc(crtc_state);
- intel_de_write_fw(dev_priv, DSPCNTR(i9xx_plane), dspcntr);
+ intel_de_write_fw(dev_priv, DSPCNTR(dev_priv, i9xx_plane), dspcntr);
if (DISPLAY_VER(dev_priv) >= 4)
- intel_de_write_fw(dev_priv, DSPSURF(i9xx_plane), 0);
+ intel_de_write_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane), 0);
else
- intel_de_write_fw(dev_priv, DSPADDR(i9xx_plane), 0);
+ intel_de_write_fw(dev_priv, DSPADDR(dev_priv, i9xx_plane), 0);
}
static void
@@ -555,9 +562,9 @@ g4x_primary_async_flip(struct intel_plane *plane,
if (async_flip)
dspcntr |= DISP_ASYNC_FLIP;
- intel_de_write_fw(dev_priv, DSPCNTR(i9xx_plane), dspcntr);
+ intel_de_write_fw(dev_priv, DSPCNTR(dev_priv, i9xx_plane), dspcntr);
- intel_de_write_fw(dev_priv, DSPSURF(i9xx_plane),
+ intel_de_write_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane),
intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
}
@@ -571,7 +578,7 @@ vlv_primary_async_flip(struct intel_plane *plane,
u32 dspaddr_offset = plane_state->view.color_plane[0].offset;
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
- intel_de_write_fw(dev_priv, DSPADDR_VLV(i9xx_plane),
+ intel_de_write_fw(dev_priv, DSPADDR_VLV(dev_priv, i9xx_plane),
intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
}
@@ -679,7 +686,7 @@ static bool i9xx_plane_get_hw_state(struct intel_plane *plane,
if (!wakeref)
return false;
- val = intel_de_read(dev_priv, DSPCNTR(i9xx_plane));
+ val = intel_de_read(dev_priv, DSPCNTR(dev_priv, i9xx_plane));
ret = val & DISP_ENABLE;
@@ -736,23 +743,25 @@ i965_plane_max_stride(struct intel_plane *plane,
}
static unsigned int
-i9xx_plane_max_stride(struct intel_plane *plane,
+i915_plane_max_stride(struct intel_plane *plane,
u32 pixel_format, u64 modifier,
unsigned int rotation)
{
- struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+ if (modifier == I915_FORMAT_MOD_X_TILED)
+ return 8 * 1024;
+ else
+ return 16 * 1024;
+}
- if (DISPLAY_VER(dev_priv) >= 3) {
- if (modifier == I915_FORMAT_MOD_X_TILED)
- return 8*1024;
- else
- return 16*1024;
- } else {
- if (plane->i9xx_plane == PLANE_C)
- return 4*1024;
- else
- return 8*1024;
- }
+static unsigned int
+i8xx_plane_max_stride(struct intel_plane *plane,
+ u32 pixel_format, u64 modifier,
+ unsigned int rotation)
+{
+ if (plane->i9xx_plane == PLANE_C)
+ return 4 * 1024;
+ else
+ return 8 * 1024;
}
static const struct drm_plane_funcs i965_plane_funcs = {
@@ -849,8 +858,10 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
if (HAS_GMCH(dev_priv)) {
if (DISPLAY_VER(dev_priv) >= 4)
plane->max_stride = i965_plane_max_stride;
+ else if (DISPLAY_VER(dev_priv) == 3)
+ plane->max_stride = i915_plane_max_stride;
else
- plane->max_stride = i9xx_plane_max_stride;
+ plane->max_stride = i8xx_plane_max_stride;
} else {
if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
plane->max_stride = hsw_primary_max_stride;
@@ -873,7 +884,7 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
plane->enable_flip_done = vlv_primary_enable_flip_done;
plane->disable_flip_done = vlv_primary_disable_flip_done;
} else if (IS_BROADWELL(dev_priv)) {
- plane->need_async_flip_disable_wa = true;
+ plane->need_async_flip_toggle_wa = true;
plane->async_flip = g4x_primary_async_flip;
plane->enable_flip_done = bdw_primary_enable_flip_done;
plane->disable_flip_done = bdw_primary_disable_flip_done;
@@ -1002,7 +1013,7 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
fb->dev = dev;
- val = intel_de_read(dev_priv, DSPCNTR(i9xx_plane));
+ val = intel_de_read(dev_priv, DSPCNTR(dev_priv, i9xx_plane));
if (DISPLAY_VER(dev_priv) >= 4) {
if (val & DISP_TILED) {
@@ -1023,29 +1034,30 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
fb->format = drm_format_info(fourcc);
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
- offset = intel_de_read(dev_priv, DSPOFFSET(i9xx_plane));
- base = intel_de_read(dev_priv, DSPSURF(i9xx_plane)) & DISP_ADDR_MASK;
+ offset = intel_de_read(dev_priv,
+ DSPOFFSET(dev_priv, i9xx_plane));
+ base = intel_de_read(dev_priv, DSPSURF(dev_priv, i9xx_plane)) & DISP_ADDR_MASK;
} else if (DISPLAY_VER(dev_priv) >= 4) {
if (plane_config->tiling)
offset = intel_de_read(dev_priv,
- DSPTILEOFF(i9xx_plane));
+ DSPTILEOFF(dev_priv, i9xx_plane));
else
offset = intel_de_read(dev_priv,
- DSPLINOFF(i9xx_plane));
- base = intel_de_read(dev_priv, DSPSURF(i9xx_plane)) & DISP_ADDR_MASK;
+ DSPLINOFF(dev_priv, i9xx_plane));
+ base = intel_de_read(dev_priv, DSPSURF(dev_priv, i9xx_plane)) & DISP_ADDR_MASK;
} else {
offset = 0;
- base = intel_de_read(dev_priv, DSPADDR(i9xx_plane));
+ base = intel_de_read(dev_priv, DSPADDR(dev_priv, i9xx_plane));
}
plane_config->base = base;
drm_WARN_ON(&dev_priv->drm, offset != 0);
- val = intel_de_read(dev_priv, PIPESRC(pipe));
+ val = intel_de_read(dev_priv, PIPESRC(dev_priv, pipe));
fb->width = REG_FIELD_GET(PIPESRC_WIDTH_MASK, val) + 1;
fb->height = REG_FIELD_GET(PIPESRC_HEIGHT_MASK, val) + 1;
- val = intel_de_read(dev_priv, DSPSTRIDE(i9xx_plane));
+ val = intel_de_read(dev_priv, DSPSTRIDE(dev_priv, i9xx_plane));
fb->pitches[0] = val & 0xffffffc0;
aligned_height = intel_fb_align_height(fb, 0, fb->height);
@@ -1084,9 +1096,9 @@ bool i9xx_fixup_initial_plane_config(struct intel_crtc *crtc,
return false;
if (DISPLAY_VER(dev_priv) >= 4)
- intel_de_write(dev_priv, DSPSURF(i9xx_plane), base);
+ intel_de_write(dev_priv, DSPSURF(dev_priv, i9xx_plane), base);
else
- intel_de_write(dev_priv, DSPADDR(i9xx_plane), base);
+ intel_de_write(dev_priv, DSPADDR(dev_priv, i9xx_plane), base);
return true;
}
diff --git a/drivers/gpu/drm/i915/display/i9xx_plane_regs.h b/drivers/gpu/drm/i915/display/i9xx_plane_regs.h
new file mode 100644
index 000000000000..5d7ba824f354
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/i9xx_plane_regs.h
@@ -0,0 +1,112 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef __I9XX_PLANE_REGS_H__
+#define __I9XX_PLANE_REGS_H__
+
+#include "intel_display_reg_defs.h"
+
+#define _DSPAADDR_VLV 0x7017C /* vlv/chv */
+#define DSPADDR_VLV(dev_priv, plane) _MMIO_PIPE2(dev_priv, plane, _DSPAADDR_VLV)
+
+#define _DSPACNTR 0x70180
+#define DSPCNTR(dev_priv, plane) _MMIO_PIPE2(dev_priv, plane, _DSPACNTR)
+#define DISP_ENABLE REG_BIT(31)
+#define DISP_PIPE_GAMMA_ENABLE REG_BIT(30)
+#define DISP_FORMAT_MASK REG_GENMASK(29, 26)
+#define DISP_FORMAT_8BPP REG_FIELD_PREP(DISP_FORMAT_MASK, 2)
+#define DISP_FORMAT_BGRA555 REG_FIELD_PREP(DISP_FORMAT_MASK, 3)
+#define DISP_FORMAT_BGRX555 REG_FIELD_PREP(DISP_FORMAT_MASK, 4)
+#define DISP_FORMAT_BGRX565 REG_FIELD_PREP(DISP_FORMAT_MASK, 5)
+#define DISP_FORMAT_BGRX888 REG_FIELD_PREP(DISP_FORMAT_MASK, 6)
+#define DISP_FORMAT_BGRA888 REG_FIELD_PREP(DISP_FORMAT_MASK, 7)
+#define DISP_FORMAT_RGBX101010 REG_FIELD_PREP(DISP_FORMAT_MASK, 8)
+#define DISP_FORMAT_RGBA101010 REG_FIELD_PREP(DISP_FORMAT_MASK, 9)
+#define DISP_FORMAT_BGRX101010 REG_FIELD_PREP(DISP_FORMAT_MASK, 10)
+#define DISP_FORMAT_BGRA101010 REG_FIELD_PREP(DISP_FORMAT_MASK, 11)
+#define DISP_FORMAT_RGBX161616 REG_FIELD_PREP(DISP_FORMAT_MASK, 12)
+#define DISP_FORMAT_RGBX888 REG_FIELD_PREP(DISP_FORMAT_MASK, 14)
+#define DISP_FORMAT_RGBA888 REG_FIELD_PREP(DISP_FORMAT_MASK, 15)
+#define DISP_STEREO_ENABLE REG_BIT(25)
+#define DISP_PIPE_CSC_ENABLE REG_BIT(24) /* ilk+ */
+#define DISP_PIPE_SEL_MASK REG_GENMASK(25, 24)
+#define DISP_PIPE_SEL(pipe) REG_FIELD_PREP(DISP_PIPE_SEL_MASK, (pipe))
+#define DISP_SRC_KEY_ENABLE REG_BIT(22)
+#define DISP_LINE_DOUBLE REG_BIT(20)
+#define DISP_STEREO_POLARITY_SECOND REG_BIT(18)
+#define DISP_ALPHA_PREMULTIPLY REG_BIT(16) /* CHV pipe B */
+#define DISP_ROTATE_180 REG_BIT(15) /* i965+ */
+#define DISP_ALPHA_TRANS_ENABLE REG_BIT(15) /* pre-g4x plane B */
+#define DISP_TRICKLE_FEED_DISABLE REG_BIT(14) /* g4x+ */
+#define DISP_TILED REG_BIT(10) /* i965+ */
+#define DISP_ASYNC_FLIP REG_BIT(9) /* g4x+ */
+#define DISP_MIRROR REG_BIT(8) /* CHV pipe B */
+#define DISP_SPRITE_ABOVE_OVERLAY REG_BIT(0) /* pre-g4x plane B/C */
+
+#define _DSPAADDR 0x70184 /* pre-i965 */
+#define DSPADDR(dev_priv, plane) _MMIO_PIPE2(dev_priv, plane, _DSPAADDR)
+
+#define _DSPALINOFF 0x70184 /* i965+ */
+#define DSPLINOFF(dev_priv, plane) _MMIO_PIPE2(dev_priv, plane, _DSPALINOFF)
+
+#define _DSPASTRIDE 0x70188
+#define DSPSTRIDE(dev_priv, plane) _MMIO_PIPE2(dev_priv, plane, _DSPASTRIDE)
+
+#define _DSPAPOS 0x7018C /* pre-g4x */
+#define DSPPOS(dev_priv, plane) _MMIO_PIPE2(dev_priv, plane, _DSPAPOS)
+#define DISP_POS_Y_MASK REG_GENMASK(31, 16)
+#define DISP_POS_Y(y) REG_FIELD_PREP(DISP_POS_Y_MASK, (y))
+#define DISP_POS_X_MASK REG_GENMASK(15, 0)
+#define DISP_POS_X(x) REG_FIELD_PREP(DISP_POS_X_MASK, (x))
+
+#define _DSPASIZE 0x70190 /* pre-g4x */
+#define DSPSIZE(dev_priv, plane) _MMIO_PIPE2(dev_priv, plane, _DSPASIZE)
+#define DISP_HEIGHT_MASK REG_GENMASK(31, 16)
+#define DISP_HEIGHT(h) REG_FIELD_PREP(DISP_HEIGHT_MASK, (h))
+#define DISP_WIDTH_MASK REG_GENMASK(15, 0)
+#define DISP_WIDTH(w) REG_FIELD_PREP(DISP_WIDTH_MASK, (w))
+
+#define _DSPASURF 0x7019C /* i965+ */
+#define DSPSURF(dev_priv, plane) _MMIO_PIPE2(dev_priv, plane, _DSPASURF)
+#define DISP_ADDR_MASK REG_GENMASK(31, 12)
+
+#define _DSPATILEOFF 0x701A4 /* i965+ */
+#define DSPTILEOFF(dev_priv, plane) _MMIO_PIPE2(dev_priv, plane, _DSPATILEOFF)
+#define DISP_OFFSET_Y_MASK REG_GENMASK(31, 16)
+#define DISP_OFFSET_Y(y) REG_FIELD_PREP(DISP_OFFSET_Y_MASK, (y))
+#define DISP_OFFSET_X_MASK REG_GENMASK(15, 0)
+#define DISP_OFFSET_X(x) REG_FIELD_PREP(DISP_OFFSET_X_MASK, (x))
+
+#define _DSPAOFFSET 0x701A4 /* hsw+ */
+#define DSPOFFSET(dev_priv, plane) _MMIO_PIPE2(dev_priv, plane, _DSPAOFFSET)
+
+#define _DSPASURFLIVE 0x701AC /* g4x+ */
+#define DSPSURFLIVE(dev_priv, plane) _MMIO_PIPE2(dev_priv, plane, _DSPASURFLIVE)
+
+#define _DSPAGAMC 0x701E0 /* pre-g4x */
+#define DSPGAMC(dev_priv, plane, i) _MMIO_PIPE2(dev_priv, plane, _DSPAGAMC + (5 - (i)) * 4) /* plane C only, 6 x u0.8 */
+
+/* CHV pipe B primary plane */
+#define _PRIMPOS_A 0x60a08
+#define PRIMPOS(dev_priv, plane) _MMIO_TRANS2(dev_priv, plane, _PRIMPOS_A)
+#define PRIM_POS_Y_MASK REG_GENMASK(31, 16)
+#define PRIM_POS_Y(y) REG_FIELD_PREP(PRIM_POS_Y_MASK, (y))
+#define PRIM_POS_X_MASK REG_GENMASK(15, 0)
+#define PRIM_POS_X(x) REG_FIELD_PREP(PRIM_POS_X_MASK, (x))
+
+#define _PRIMSIZE_A 0x60a0c
+#define PRIMSIZE(dev_priv, plane) _MMIO_TRANS2(dev_priv, plane, _PRIMSIZE_A)
+#define PRIM_HEIGHT_MASK REG_GENMASK(31, 16)
+#define PRIM_HEIGHT(h) REG_FIELD_PREP(PRIM_HEIGHT_MASK, (h))
+#define PRIM_WIDTH_MASK REG_GENMASK(15, 0)
+#define PRIM_WIDTH(w) REG_FIELD_PREP(PRIM_WIDTH_MASK, (w))
+
+#define _PRIMCNSTALPHA_A 0x60a10
+#define PRIMCNSTALPHA(dev_priv, plane) _MMIO_TRANS2(dev_priv, plane, _PRIMCNSTALPHA_A)
+#define PRIM_CONST_ALPHA_ENABLE REG_BIT(31)
+#define PRIM_CONST_ALPHA_MASK REG_GENMASK(7, 0)
+#define PRIM_CONST_ALPHA(alpha) REG_FIELD_PREP(PRIM_CONST_ALPHA_MASK, (alpha))
+
+#endif /* __I9XX_PLANE_REGS_H__ */
diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.c b/drivers/gpu/drm/i915/display/i9xx_wm.c
index 628e7192ebc9..2b7c3d270b17 100644
--- a/drivers/gpu/drm/i915/display/i9xx_wm.c
+++ b/drivers/gpu/drm/i915/display/i9xx_wm.c
@@ -70,25 +70,24 @@ static const struct cxsr_latency cxsr_latency_table[] = {
{0, 1, 400, 800, 6042, 36042, 6584, 36584}, /* DDR3-800 SC */
};
-static const struct cxsr_latency *intel_get_cxsr_latency(struct drm_i915_private *i915)
+static const struct cxsr_latency *pnv_get_cxsr_latency(struct drm_i915_private *i915)
{
int i;
- if (i915->fsb_freq == 0 || i915->mem_freq == 0)
- return NULL;
-
for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) {
const struct cxsr_latency *latency = &cxsr_latency_table[i];
bool is_desktop = !IS_MOBILE(i915);
if (is_desktop == latency->is_desktop &&
i915->is_ddr3 == latency->is_ddr3 &&
- i915->fsb_freq == latency->fsb_freq &&
- i915->mem_freq == latency->mem_freq)
+ DIV_ROUND_CLOSEST(i915->fsb_freq, 1000) == latency->fsb_freq &&
+ DIV_ROUND_CLOSEST(i915->mem_freq, 1000) == latency->mem_freq)
return latency;
}
- drm_dbg_kms(&i915->drm, "Unknown FSB/MEM found, disable CxSR\n");
+ drm_dbg_kms(&i915->drm,
+ "Could not find CxSR latency for DDR%s, FSB %u kHz, MEM %u kHz\n",
+ i915->is_ddr3 ? "3" : "2", i915->fsb_freq, i915->mem_freq);
return NULL;
}
@@ -149,14 +148,14 @@ static bool _intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enabl
intel_uncore_write(&dev_priv->uncore, FW_BLC_SELF, enable ? FW_BLC_SELF_EN : 0);
intel_uncore_posting_read(&dev_priv->uncore, FW_BLC_SELF);
} else if (IS_PINEVIEW(dev_priv)) {
- val = intel_uncore_read(&dev_priv->uncore, DSPFW3);
+ val = intel_uncore_read(&dev_priv->uncore, DSPFW3(dev_priv));
was_enabled = val & PINEVIEW_SELF_REFRESH_EN;
if (enable)
val |= PINEVIEW_SELF_REFRESH_EN;
else
val &= ~PINEVIEW_SELF_REFRESH_EN;
- intel_uncore_write(&dev_priv->uncore, DSPFW3, val);
- intel_uncore_posting_read(&dev_priv->uncore, DSPFW3);
+ intel_uncore_write(&dev_priv->uncore, DSPFW3(dev_priv), val);
+ intel_uncore_posting_read(&dev_priv->uncore, DSPFW3(dev_priv));
} else if (IS_I945G(dev_priv) || IS_I945GM(dev_priv)) {
was_enabled = intel_uncore_read(&dev_priv->uncore, FW_BLC_SELF) & FW_BLC_SELF_EN;
val = enable ? _MASKED_BIT_ENABLE(FW_BLC_SELF_EN) :
@@ -269,13 +268,15 @@ static void vlv_get_fifo_size(struct intel_crtc_state *crtc_state)
switch (pipe) {
case PIPE_A:
- dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB);
+ dsparb = intel_uncore_read(&dev_priv->uncore,
+ DSPARB(dev_priv));
dsparb2 = intel_uncore_read(&dev_priv->uncore, DSPARB2);
sprite0_start = VLV_FIFO_START(dsparb, dsparb2, 0, 0);
sprite1_start = VLV_FIFO_START(dsparb, dsparb2, 8, 4);
break;
case PIPE_B:
- dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB);
+ dsparb = intel_uncore_read(&dev_priv->uncore,
+ DSPARB(dev_priv));
dsparb2 = intel_uncore_read(&dev_priv->uncore, DSPARB2);
sprite0_start = VLV_FIFO_START(dsparb, dsparb2, 16, 8);
sprite1_start = VLV_FIFO_START(dsparb, dsparb2, 24, 12);
@@ -300,7 +301,7 @@ static void vlv_get_fifo_size(struct intel_crtc_state *crtc_state)
static int i9xx_get_fifo_size(struct drm_i915_private *dev_priv,
enum i9xx_plane_id i9xx_plane)
{
- u32 dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB);
+ u32 dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB(dev_priv));
int size;
size = dsparb & 0x7f;
@@ -316,7 +317,7 @@ static int i9xx_get_fifo_size(struct drm_i915_private *dev_priv,
static int i830_get_fifo_size(struct drm_i915_private *dev_priv,
enum i9xx_plane_id i9xx_plane)
{
- u32 dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB);
+ u32 dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB(dev_priv));
int size;
size = dsparb & 0x1ff;
@@ -333,7 +334,7 @@ static int i830_get_fifo_size(struct drm_i915_private *dev_priv,
static int i845_get_fifo_size(struct drm_i915_private *dev_priv,
enum i9xx_plane_id i9xx_plane)
{
- u32 dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB);
+ u32 dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB(dev_priv));
int size;
size = dsparb & 0x7f;
@@ -635,10 +636,9 @@ static void pnv_update_wm(struct drm_i915_private *dev_priv)
u32 reg;
unsigned int wm;
- latency = intel_get_cxsr_latency(dev_priv);
+ latency = pnv_get_cxsr_latency(dev_priv);
if (!latency) {
- drm_dbg_kms(&dev_priv->drm,
- "Unknown FSB/MEM found, disable CxSR\n");
+ drm_dbg_kms(&dev_priv->drm, "Unknown FSB/MEM, disabling CxSR\n");
intel_set_memory_cxsr(dev_priv, false);
return;
}
@@ -655,10 +655,10 @@ static void pnv_update_wm(struct drm_i915_private *dev_priv)
&pnv_display_wm,
pnv_display_wm.fifo_size,
cpp, latency->display_sr);
- reg = intel_uncore_read(&dev_priv->uncore, DSPFW1);
+ reg = intel_uncore_read(&dev_priv->uncore, DSPFW1(dev_priv));
reg &= ~DSPFW_SR_MASK;
reg |= FW_WM(wm, SR);
- intel_uncore_write(&dev_priv->uncore, DSPFW1, reg);
+ intel_uncore_write(&dev_priv->uncore, DSPFW1(dev_priv), reg);
drm_dbg_kms(&dev_priv->drm, "DSPFW1 register is %x\n", reg);
/* cursor SR */
@@ -666,7 +666,8 @@ static void pnv_update_wm(struct drm_i915_private *dev_priv)
&pnv_cursor_wm,
pnv_display_wm.fifo_size,
4, latency->cursor_sr);
- intel_uncore_rmw(&dev_priv->uncore, DSPFW3, DSPFW_CURSOR_SR_MASK,
+ intel_uncore_rmw(&dev_priv->uncore, DSPFW3(dev_priv),
+ DSPFW_CURSOR_SR_MASK,
FW_WM(wm, CURSOR_SR));
/* Display HPLL off SR */
@@ -674,17 +675,18 @@ static void pnv_update_wm(struct drm_i915_private *dev_priv)
&pnv_display_hplloff_wm,
pnv_display_hplloff_wm.fifo_size,
cpp, latency->display_hpll_disable);
- intel_uncore_rmw(&dev_priv->uncore, DSPFW3, DSPFW_HPLL_SR_MASK, FW_WM(wm, HPLL_SR));
+ intel_uncore_rmw(&dev_priv->uncore, DSPFW3(dev_priv),
+ DSPFW_HPLL_SR_MASK, FW_WM(wm, HPLL_SR));
/* cursor HPLL off SR */
wm = intel_calculate_wm(dev_priv, pixel_rate,
&pnv_cursor_hplloff_wm,
pnv_display_hplloff_wm.fifo_size,
4, latency->cursor_hpll_disable);
- reg = intel_uncore_read(&dev_priv->uncore, DSPFW3);
+ reg = intel_uncore_read(&dev_priv->uncore, DSPFW3(dev_priv));
reg &= ~DSPFW_HPLL_CURSOR_MASK;
reg |= FW_WM(wm, HPLL_CURSOR);
- intel_uncore_write(&dev_priv->uncore, DSPFW3, reg);
+ intel_uncore_write(&dev_priv->uncore, DSPFW3(dev_priv), reg);
drm_dbg_kms(&dev_priv->drm, "DSPFW3 register is %x\n", reg);
intel_set_memory_cxsr(dev_priv, true);
@@ -718,25 +720,25 @@ static void g4x_write_wm_values(struct drm_i915_private *dev_priv,
for_each_pipe(dev_priv, pipe)
trace_g4x_wm(intel_crtc_for_pipe(dev_priv, pipe), wm);
- intel_uncore_write(&dev_priv->uncore, DSPFW1,
+ intel_uncore_write(&dev_priv->uncore, DSPFW1(dev_priv),
FW_WM(wm->sr.plane, SR) |
FW_WM(wm->pipe[PIPE_B].plane[PLANE_CURSOR], CURSORB) |
FW_WM(wm->pipe[PIPE_B].plane[PLANE_PRIMARY], PLANEB) |
FW_WM(wm->pipe[PIPE_A].plane[PLANE_PRIMARY], PLANEA));
- intel_uncore_write(&dev_priv->uncore, DSPFW2,
+ intel_uncore_write(&dev_priv->uncore, DSPFW2(dev_priv),
(wm->fbc_en ? DSPFW_FBC_SR_EN : 0) |
FW_WM(wm->sr.fbc, FBC_SR) |
FW_WM(wm->hpll.fbc, FBC_HPLL_SR) |
FW_WM(wm->pipe[PIPE_B].plane[PLANE_SPRITE0], SPRITEB) |
FW_WM(wm->pipe[PIPE_A].plane[PLANE_CURSOR], CURSORA) |
FW_WM(wm->pipe[PIPE_A].plane[PLANE_SPRITE0], SPRITEA));
- intel_uncore_write(&dev_priv->uncore, DSPFW3,
+ intel_uncore_write(&dev_priv->uncore, DSPFW3(dev_priv),
(wm->hpll_en ? DSPFW_HPLL_SR_EN : 0) |
FW_WM(wm->sr.cursor, CURSOR_SR) |
FW_WM(wm->hpll.cursor, HPLL_CURSOR) |
FW_WM(wm->hpll.plane, HPLL_SR));
- intel_uncore_posting_read(&dev_priv->uncore, DSPFW1);
+ intel_uncore_posting_read(&dev_priv->uncore, DSPFW1(dev_priv));
}
#define FW_WM_VLV(value, plane) \
@@ -768,16 +770,16 @@ static void vlv_write_wm_values(struct drm_i915_private *dev_priv,
intel_uncore_write(&dev_priv->uncore, DSPFW5, 0);
intel_uncore_write(&dev_priv->uncore, DSPFW6, 0);
- intel_uncore_write(&dev_priv->uncore, DSPFW1,
+ intel_uncore_write(&dev_priv->uncore, DSPFW1(dev_priv),
FW_WM(wm->sr.plane, SR) |
FW_WM(wm->pipe[PIPE_B].plane[PLANE_CURSOR], CURSORB) |
FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_PRIMARY], PLANEB) |
FW_WM_VLV(wm->pipe[PIPE_A].plane[PLANE_PRIMARY], PLANEA));
- intel_uncore_write(&dev_priv->uncore, DSPFW2,
+ intel_uncore_write(&dev_priv->uncore, DSPFW2(dev_priv),
FW_WM_VLV(wm->pipe[PIPE_A].plane[PLANE_SPRITE1], SPRITEB) |
FW_WM(wm->pipe[PIPE_A].plane[PLANE_CURSOR], CURSORA) |
FW_WM_VLV(wm->pipe[PIPE_A].plane[PLANE_SPRITE0], SPRITEA));
- intel_uncore_write(&dev_priv->uncore, DSPFW3,
+ intel_uncore_write(&dev_priv->uncore, DSPFW3(dev_priv),
FW_WM(wm->sr.cursor, CURSOR_SR));
if (IS_CHERRYVIEW(dev_priv)) {
@@ -815,7 +817,7 @@ static void vlv_write_wm_values(struct drm_i915_private *dev_priv,
FW_WM(wm->pipe[PIPE_A].plane[PLANE_PRIMARY] >> 8, PLANEA_HI));
}
- intel_uncore_posting_read(&dev_priv->uncore, DSPFW1);
+ intel_uncore_posting_read(&dev_priv->uncore, DSPFW1(dev_priv));
}
#undef FW_WM_VLV
@@ -1787,7 +1789,7 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state,
switch (crtc->pipe) {
case PIPE_A:
- dsparb = intel_uncore_read_fw(uncore, DSPARB);
+ dsparb = intel_uncore_read_fw(uncore, DSPARB(dev_priv));
dsparb2 = intel_uncore_read_fw(uncore, DSPARB2);
dsparb &= ~(VLV_FIFO(SPRITEA, 0xff) |
@@ -1800,11 +1802,11 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state,
dsparb2 |= (VLV_FIFO(SPRITEA_HI, sprite0_start >> 8) |
VLV_FIFO(SPRITEB_HI, sprite1_start >> 8));
- intel_uncore_write_fw(uncore, DSPARB, dsparb);
+ intel_uncore_write_fw(uncore, DSPARB(dev_priv), dsparb);
intel_uncore_write_fw(uncore, DSPARB2, dsparb2);
break;
case PIPE_B:
- dsparb = intel_uncore_read_fw(uncore, DSPARB);
+ dsparb = intel_uncore_read_fw(uncore, DSPARB(dev_priv));
dsparb2 = intel_uncore_read_fw(uncore, DSPARB2);
dsparb &= ~(VLV_FIFO(SPRITEC, 0xff) |
@@ -1817,7 +1819,7 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state,
dsparb2 |= (VLV_FIFO(SPRITEC_HI, sprite0_start >> 8) |
VLV_FIFO(SPRITED_HI, sprite1_start >> 8));
- intel_uncore_write_fw(uncore, DSPARB, dsparb);
+ intel_uncore_write_fw(uncore, DSPARB(dev_priv), dsparb);
intel_uncore_write_fw(uncore, DSPARB2, dsparb2);
break;
case PIPE_C:
@@ -1841,7 +1843,7 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state,
break;
}
- intel_uncore_posting_read_fw(uncore, DSPARB);
+ intel_uncore_posting_read_fw(uncore, DSPARB(dev_priv));
spin_unlock(&uncore->lock);
}
@@ -2065,14 +2067,17 @@ static void i965_update_wm(struct drm_i915_private *dev_priv)
srwm);
/* 965 has limitations... */
- intel_uncore_write(&dev_priv->uncore, DSPFW1, FW_WM(srwm, SR) |
- FW_WM(8, CURSORB) |
- FW_WM(8, PLANEB) |
- FW_WM(8, PLANEA));
- intel_uncore_write(&dev_priv->uncore, DSPFW2, FW_WM(8, CURSORA) |
- FW_WM(8, PLANEC_OLD));
+ intel_uncore_write(&dev_priv->uncore, DSPFW1(dev_priv),
+ FW_WM(srwm, SR) |
+ FW_WM(8, CURSORB) |
+ FW_WM(8, PLANEB) |
+ FW_WM(8, PLANEA));
+ intel_uncore_write(&dev_priv->uncore, DSPFW2(dev_priv),
+ FW_WM(8, CURSORA) |
+ FW_WM(8, PLANEC_OLD));
/* update cursor SR watermark */
- intel_uncore_write(&dev_priv->uncore, DSPFW3, FW_WM(cursor_sr, CURSOR_SR));
+ intel_uncore_write(&dev_priv->uncore, DSPFW3(dev_priv),
+ FW_WM(cursor_sr, CURSOR_SR));
if (cxsr_enabled)
intel_set_memory_cxsr(dev_priv, true);
@@ -3519,13 +3524,13 @@ static void g4x_read_wm_values(struct drm_i915_private *dev_priv,
{
u32 tmp;
- tmp = intel_uncore_read(&dev_priv->uncore, DSPFW1);
+ tmp = intel_uncore_read(&dev_priv->uncore, DSPFW1(dev_priv));
wm->sr.plane = _FW_WM(tmp, SR);
wm->pipe[PIPE_B].plane[PLANE_CURSOR] = _FW_WM(tmp, CURSORB);
wm->pipe[PIPE_B].plane[PLANE_PRIMARY] = _FW_WM(tmp, PLANEB);
wm->pipe[PIPE_A].plane[PLANE_PRIMARY] = _FW_WM(tmp, PLANEA);
- tmp = intel_uncore_read(&dev_priv->uncore, DSPFW2);
+ tmp = intel_uncore_read(&dev_priv->uncore, DSPFW2(dev_priv));
wm->fbc_en = tmp & DSPFW_FBC_SR_EN;
wm->sr.fbc = _FW_WM(tmp, FBC_SR);
wm->hpll.fbc = _FW_WM(tmp, FBC_HPLL_SR);
@@ -3533,7 +3538,7 @@ static void g4x_read_wm_values(struct drm_i915_private *dev_priv,
wm->pipe[PIPE_A].plane[PLANE_CURSOR] = _FW_WM(tmp, CURSORA);
wm->pipe[PIPE_A].plane[PLANE_SPRITE0] = _FW_WM(tmp, SPRITEA);
- tmp = intel_uncore_read(&dev_priv->uncore, DSPFW3);
+ tmp = intel_uncore_read(&dev_priv->uncore, DSPFW3(dev_priv));
wm->hpll_en = tmp & DSPFW_HPLL_SR_EN;
wm->sr.cursor = _FW_WM(tmp, CURSOR_SR);
wm->hpll.cursor = _FW_WM(tmp, HPLL_CURSOR);
@@ -3559,18 +3564,18 @@ static void vlv_read_wm_values(struct drm_i915_private *dev_priv,
(tmp >> DDL_SPRITE_SHIFT(1)) & (DDL_PRECISION_HIGH | DRAIN_LATENCY_MASK);
}
- tmp = intel_uncore_read(&dev_priv->uncore, DSPFW1);
+ tmp = intel_uncore_read(&dev_priv->uncore, DSPFW1(dev_priv));
wm->sr.plane = _FW_WM(tmp, SR);
wm->pipe[PIPE_B].plane[PLANE_CURSOR] = _FW_WM(tmp, CURSORB);
wm->pipe[PIPE_B].plane[PLANE_PRIMARY] = _FW_WM_VLV(tmp, PLANEB);
wm->pipe[PIPE_A].plane[PLANE_PRIMARY] = _FW_WM_VLV(tmp, PLANEA);
- tmp = intel_uncore_read(&dev_priv->uncore, DSPFW2);
+ tmp = intel_uncore_read(&dev_priv->uncore, DSPFW2(dev_priv));
wm->pipe[PIPE_A].plane[PLANE_SPRITE1] = _FW_WM_VLV(tmp, SPRITEB);
wm->pipe[PIPE_A].plane[PLANE_CURSOR] = _FW_WM(tmp, CURSORA);
wm->pipe[PIPE_A].plane[PLANE_SPRITE0] = _FW_WM_VLV(tmp, SPRITEA);
- tmp = intel_uncore_read(&dev_priv->uncore, DSPFW3);
+ tmp = intel_uncore_read(&dev_priv->uncore, DSPFW3(dev_priv));
wm->sr.cursor = _FW_WM(tmp, CURSOR_SR);
if (IS_CHERRYVIEW(dev_priv)) {
@@ -4022,13 +4027,8 @@ void i9xx_wm_init(struct drm_i915_private *dev_priv)
g4x_setup_wm_latency(dev_priv);
dev_priv->display.funcs.wm = &g4x_wm_funcs;
} else if (IS_PINEVIEW(dev_priv)) {
- if (!intel_get_cxsr_latency(dev_priv)) {
- drm_info(&dev_priv->drm,
- "failed to find known CxSR latency "
- "(found ddr%s fsb freq %d, mem freq %d), "
- "disabling CxSR\n",
- (dev_priv->is_ddr3 == 1) ? "3" : "2",
- dev_priv->fsb_freq, dev_priv->mem_freq);
+ if (!pnv_get_cxsr_latency(dev_priv)) {
+ drm_info(&dev_priv->drm, "Unknown FSB/MEM, disabling CxSR\n");
/* Disable CxSR and never update its watermark again */
intel_set_memory_cxsr(dev_priv, false);
dev_priv->display.funcs.wm = &nop_funcs;
diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
index 79ecfc339430..ae8f6617aa70 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -784,7 +784,8 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
if (intel_dsi->dual_link) {
for_each_dsi_port(port, intel_dsi->ports) {
dsi_trans = dsi_port_to_transcoder(port);
- intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL2(dsi_trans),
+ intel_de_rmw(dev_priv,
+ TRANS_DDI_FUNC_CTL2(dev_priv, dsi_trans),
0, PORT_SYNC_MODE_ENABLE);
}
@@ -796,7 +797,8 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
dsi_trans = dsi_port_to_transcoder(port);
/* select data lane width */
- tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(dsi_trans));
+ tmp = intel_de_read(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, dsi_trans));
tmp &= ~DDI_PORT_WIDTH_MASK;
tmp |= DDI_PORT_WIDTH(intel_dsi->lane_count);
@@ -822,7 +824,8 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
/* enable DDI buffer */
tmp |= TRANS_DDI_FUNC_ENABLE;
- intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(dsi_trans), tmp);
+ intel_de_write(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, dsi_trans), tmp);
}
/* wait for link ready */
@@ -915,7 +918,7 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
/* program TRANS_HTOTAL register */
for_each_dsi_port(port, intel_dsi->ports) {
dsi_trans = dsi_port_to_transcoder(port);
- intel_de_write(dev_priv, TRANS_HTOTAL(dsi_trans),
+ intel_de_write(dev_priv, TRANS_HTOTAL(dev_priv, dsi_trans),
HACTIVE(hactive - 1) | HTOTAL(htotal - 1));
}
@@ -938,7 +941,8 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
for_each_dsi_port(port, intel_dsi->ports) {
dsi_trans = dsi_port_to_transcoder(port);
- intel_de_write(dev_priv, TRANS_HSYNC(dsi_trans),
+ intel_de_write(dev_priv,
+ TRANS_HSYNC(dev_priv, dsi_trans),
HSYNC_START(hsync_start - 1) | HSYNC_END(hsync_end - 1));
}
}
@@ -952,7 +956,7 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
* struct drm_display_mode.
* For interlace mode: program required pixel minus 2
*/
- intel_de_write(dev_priv, TRANS_VTOTAL(dsi_trans),
+ intel_de_write(dev_priv, TRANS_VTOTAL(dev_priv, dsi_trans),
VACTIVE(vactive - 1) | VTOTAL(vtotal - 1));
}
@@ -966,7 +970,8 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
if (is_vid_mode(intel_dsi)) {
for_each_dsi_port(port, intel_dsi->ports) {
dsi_trans = dsi_port_to_transcoder(port);
- intel_de_write(dev_priv, TRANS_VSYNC(dsi_trans),
+ intel_de_write(dev_priv,
+ TRANS_VSYNC(dev_priv, dsi_trans),
VSYNC_START(vsync_start - 1) | VSYNC_END(vsync_end - 1));
}
}
@@ -980,7 +985,8 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
if (is_vid_mode(intel_dsi)) {
for_each_dsi_port(port, intel_dsi->ports) {
dsi_trans = dsi_port_to_transcoder(port);
- intel_de_write(dev_priv, TRANS_VSYNCSHIFT(dsi_trans),
+ intel_de_write(dev_priv,
+ TRANS_VSYNCSHIFT(dev_priv, dsi_trans),
vsync_shift);
}
}
@@ -994,7 +1000,8 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
if (DISPLAY_VER(dev_priv) >= 12) {
for_each_dsi_port(port, intel_dsi->ports) {
dsi_trans = dsi_port_to_transcoder(port);
- intel_de_write(dev_priv, TRANS_VBLANK(dsi_trans),
+ intel_de_write(dev_priv,
+ TRANS_VBLANK(dev_priv, dsi_trans),
VBLANK_START(vactive - 1) | VBLANK_END(vtotal - 1));
}
}
@@ -1009,10 +1016,11 @@ static void gen11_dsi_enable_transcoder(struct intel_encoder *encoder)
for_each_dsi_port(port, intel_dsi->ports) {
dsi_trans = dsi_port_to_transcoder(port);
- intel_de_rmw(dev_priv, TRANSCONF(dsi_trans), 0, TRANSCONF_ENABLE);
+ intel_de_rmw(dev_priv, TRANSCONF(dev_priv, dsi_trans), 0,
+ TRANSCONF_ENABLE);
/* wait for transcoder to be enabled */
- if (intel_de_wait_for_set(dev_priv, TRANSCONF(dsi_trans),
+ if (intel_de_wait_for_set(dev_priv, TRANSCONF(dev_priv, dsi_trans),
TRANSCONF_STATE_ENABLE, 10))
drm_err(&dev_priv->drm,
"DSI transcoder not enabled\n");
@@ -1275,10 +1283,11 @@ static void gen11_dsi_disable_transcoder(struct intel_encoder *encoder)
dsi_trans = dsi_port_to_transcoder(port);
/* disable transcoder */
- intel_de_rmw(dev_priv, TRANSCONF(dsi_trans), TRANSCONF_ENABLE, 0);
+ intel_de_rmw(dev_priv, TRANSCONF(dev_priv, dsi_trans),
+ TRANSCONF_ENABLE, 0);
/* wait for transcoder to be disabled */
- if (intel_de_wait_for_clear(dev_priv, TRANSCONF(dsi_trans),
+ if (intel_de_wait_for_clear(dev_priv, TRANSCONF(dev_priv, dsi_trans),
TRANSCONF_STATE_ENABLE, 50))
drm_err(&dev_priv->drm,
"DSI trancoder not disabled\n");
@@ -1327,7 +1336,8 @@ static void gen11_dsi_deconfigure_trancoder(struct intel_encoder *encoder)
/* disable ddi function */
for_each_dsi_port(port, intel_dsi->ports) {
dsi_trans = dsi_port_to_transcoder(port);
- intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(dsi_trans),
+ intel_de_rmw(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, dsi_trans),
TRANS_DDI_FUNC_ENABLE, 0);
}
@@ -1335,7 +1345,8 @@ static void gen11_dsi_deconfigure_trancoder(struct intel_encoder *encoder)
if (intel_dsi->dual_link) {
for_each_dsi_port(port, intel_dsi->ports) {
dsi_trans = dsi_port_to_transcoder(port);
- intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL2(dsi_trans),
+ intel_de_rmw(dev_priv,
+ TRANS_DDI_FUNC_CTL2(dev_priv, dsi_trans),
PORT_SYNC_MODE_ENABLE, 0);
}
}
@@ -1691,7 +1702,8 @@ static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder,
for_each_dsi_port(port, intel_dsi->ports) {
dsi_trans = dsi_port_to_transcoder(port);
- tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(dsi_trans));
+ tmp = intel_de_read(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, dsi_trans));
switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
case TRANS_DDI_EDP_INPUT_A_ON:
*pipe = PIPE_A;
@@ -1710,7 +1722,7 @@ static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder,
goto out;
}
- tmp = intel_de_read(dev_priv, TRANSCONF(dsi_trans));
+ tmp = intel_de_read(dev_priv, TRANSCONF(dev_priv, dsi_trans));
ret = tmp & TRANSCONF_ENABLE;
}
out:
diff --git a/drivers/gpu/drm/i915/display/intel_alpm.c b/drivers/gpu/drm/i915/display/intel_alpm.c
new file mode 100644
index 000000000000..c7092af7da33
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_alpm.c
@@ -0,0 +1,414 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright 2024, Intel Corporation.
+ */
+
+#include "intel_alpm.h"
+#include "intel_crtc.h"
+#include "intel_de.h"
+#include "intel_display_types.h"
+#include "intel_dp.h"
+#include "intel_dp_aux.h"
+#include "intel_psr_regs.h"
+
+bool intel_alpm_aux_wake_supported(struct intel_dp *intel_dp)
+{
+ return intel_dp->alpm_dpcd & DP_ALPM_CAP;
+}
+
+bool intel_alpm_aux_less_wake_supported(struct intel_dp *intel_dp)
+{
+ return intel_dp->alpm_dpcd & DP_ALPM_AUX_LESS_CAP;
+}
+
+void intel_alpm_init_dpcd(struct intel_dp *intel_dp)
+{
+ u8 dpcd;
+
+ if (drm_dp_dpcd_readb(&intel_dp->aux, DP_RECEIVER_ALPM_CAP, &dpcd) < 0)
+ return;
+
+ intel_dp->alpm_dpcd = dpcd;
+}
+
+/*
+ * See Bspec: 71632 for the table
+ *
+ * Silence_period = tSilence,Min + ((tSilence,Max - tSilence,Min) / 2)
+ *
+ * Half cycle duration:
+ *
+ * Link rates 1.62 - 4.32 and tLFPS_Cycle = 70 ns
+ * FLOOR( (Link Rate * tLFPS_Cycle) / (2 * 10) )
+ *
+ * Link rates 5.4 - 8.1
+ * PORT_ALPM_LFPS_CTL[ LFPS Cycle Count ] = 10
+ * LFPS Period chosen is the mid-point of the min:max values from the table
+ * FLOOR( LFPS Period in Symbol clocks /
+ * (2 * PORT_ALPM_LFPS_CTL[ LFPS Cycle Count ]) )
+ */
+static bool _lnl_get_silence_period_and_lfps_half_cycle(int link_rate,
+ int *silence_period,
+ int *lfps_half_cycle)
+{
+ switch (link_rate) {
+ case 162000:
+ *silence_period = 20;
+ *lfps_half_cycle = 5;
+ break;
+ case 216000:
+ *silence_period = 27;
+ *lfps_half_cycle = 7;
+ break;
+ case 243000:
+ *silence_period = 31;
+ *lfps_half_cycle = 8;
+ break;
+ case 270000:
+ *silence_period = 34;
+ *lfps_half_cycle = 9;
+ break;
+ case 324000:
+ *silence_period = 41;
+ *lfps_half_cycle = 11;
+ break;
+ case 432000:
+ *silence_period = 56;
+ *lfps_half_cycle = 15;
+ break;
+ case 540000:
+ *silence_period = 69;
+ *lfps_half_cycle = 12;
+ break;
+ case 648000:
+ *silence_period = 84;
+ *lfps_half_cycle = 15;
+ break;
+ case 675000:
+ *silence_period = 87;
+ *lfps_half_cycle = 15;
+ break;
+ case 810000:
+ *silence_period = 104;
+ *lfps_half_cycle = 19;
+ break;
+ default:
+ *silence_period = *lfps_half_cycle = -1;
+ return false;
+ }
+ return true;
+}
+
+/*
+ * AUX-Less Wake Time = CEILING( ((PHY P2 to P0) + tLFPS_Period, Max+
+ * tSilence, Max+ tPHY Establishment + tCDS) / tline)
+ * For the "PHY P2 to P0" latency see the PHY Power Control page
+ * (PHY P2 to P0) : https://gfxspecs.intel.com/Predator/Home/Index/68965
+ * : 12 us
+ * The tLFPS_Period, Max term is 800ns
+ * The tSilence, Max term is 180ns
+ * The tPHY Establishment (a.k.a. t1) term is 50us
+ * The tCDS term is 1 or 2 times t2
+ * t2 = Number ML_PHY_LOCK * tML_PHY_LOCK
+ * Number ML_PHY_LOCK = ( 7 + CEILING( 6.5us / tML_PHY_LOCK ) + 1)
+ * Rounding up the 6.5us padding to the next ML_PHY_LOCK boundary and
+ * adding the "+ 1" term ensures all ML_PHY_LOCK sequences that start
+ * within the CDS period complete within the CDS period regardless of
+ * entry into the period
+ * tML_PHY_LOCK = TPS4 Length * ( 10 / (Link Rate in MHz) )
+ * TPS4 Length = 252 Symbols
+ */
+static int _lnl_compute_aux_less_wake_time(int port_clock)
+{
+ int tphy2_p2_to_p0 = 12 * 1000;
+ int tlfps_period_max = 800;
+ int tsilence_max = 180;
+ int t1 = 50 * 1000;
+ int tps4 = 252;
+ /* port_clock is link rate in 10kbit/s units */
+ int tml_phy_lock = 1000 * 1000 * tps4 / port_clock;
+ int num_ml_phy_lock = 7 + DIV_ROUND_UP(6500, tml_phy_lock) + 1;
+ int t2 = num_ml_phy_lock * tml_phy_lock;
+ int tcds = 1 * t2;
+
+ return DIV_ROUND_UP(tphy2_p2_to_p0 + tlfps_period_max + tsilence_max +
+ t1 + tcds, 1000);
+}
+
+static int _lnl_compute_aux_less_alpm_params(struct intel_dp *intel_dp,
+ struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ int aux_less_wake_time, aux_less_wake_lines, silence_period,
+ lfps_half_cycle;
+
+ aux_less_wake_time =
+ _lnl_compute_aux_less_wake_time(crtc_state->port_clock);
+ aux_less_wake_lines = intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode,
+ aux_less_wake_time);
+
+ if (!_lnl_get_silence_period_and_lfps_half_cycle(crtc_state->port_clock,
+ &silence_period,
+ &lfps_half_cycle))
+ return false;
+
+ if (aux_less_wake_lines > ALPM_CTL_AUX_LESS_WAKE_TIME_MASK ||
+ silence_period > PORT_ALPM_CTL_SILENCE_PERIOD_MASK ||
+ lfps_half_cycle > PORT_ALPM_LFPS_CTL_LAST_LFPS_HALF_CYCLE_DURATION_MASK)
+ return false;
+
+ if (i915->display.params.psr_safest_params)
+ aux_less_wake_lines = ALPM_CTL_AUX_LESS_WAKE_TIME_MASK;
+
+ intel_dp->alpm_parameters.aux_less_wake_lines = aux_less_wake_lines;
+ intel_dp->alpm_parameters.silence_period_sym_clocks = silence_period;
+ intel_dp->alpm_parameters.lfps_half_cycle_num_of_syms = lfps_half_cycle;
+
+ return true;
+}
+
+static bool _lnl_compute_alpm_params(struct intel_dp *intel_dp,
+ struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ int check_entry_lines;
+
+ if (DISPLAY_VER(i915) < 20)
+ return true;
+
+ /* ALPM Entry Check = 2 + CEILING( 5us /tline ) */
+ check_entry_lines = 2 +
+ intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, 5);
+
+ if (check_entry_lines > 15)
+ return false;
+
+ if (!_lnl_compute_aux_less_alpm_params(intel_dp, crtc_state))
+ return false;
+
+ if (i915->display.params.psr_safest_params)
+ check_entry_lines = 15;
+
+ intel_dp->alpm_parameters.check_entry_lines = check_entry_lines;
+
+ return true;
+}
+
+/*
+ * IO wake time for DISPLAY_VER < 12 is not directly mentioned in Bspec. There
+ * are 50 us io wake time and 32 us fast wake time. Clearly preharge pulses are
+ * not (improperly) included in 32 us fast wake time. 50 us - 32 us = 18 us.
+ */
+static int skl_io_buffer_wake_time(void)
+{
+ return 18;
+}
+
+static int tgl_io_buffer_wake_time(void)
+{
+ return 10;
+}
+
+static int io_buffer_wake_time(const struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+
+ if (DISPLAY_VER(i915) >= 12)
+ return tgl_io_buffer_wake_time();
+ else
+ return skl_io_buffer_wake_time();
+}
+
+bool intel_alpm_compute_params(struct intel_dp *intel_dp,
+ struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ int io_wake_lines, io_wake_time, fast_wake_lines, fast_wake_time;
+ int tfw_exit_latency = 20; /* eDP spec */
+ int phy_wake = 4; /* eDP spec */
+ int preamble = 8; /* eDP spec */
+ int precharge = intel_dp_aux_fw_sync_len() - preamble;
+ u8 max_wake_lines;
+
+ io_wake_time = max(precharge, io_buffer_wake_time(crtc_state)) +
+ preamble + phy_wake + tfw_exit_latency;
+ fast_wake_time = precharge + preamble + phy_wake +
+ tfw_exit_latency;
+
+ if (DISPLAY_VER(i915) >= 20)
+ max_wake_lines = 68;
+ else if (DISPLAY_VER(i915) >= 12)
+ max_wake_lines = 12;
+ else
+ max_wake_lines = 8;
+
+ io_wake_lines = intel_usecs_to_scanlines(
+ &crtc_state->hw.adjusted_mode, io_wake_time);
+ fast_wake_lines = intel_usecs_to_scanlines(
+ &crtc_state->hw.adjusted_mode, fast_wake_time);
+
+ if (io_wake_lines > max_wake_lines ||
+ fast_wake_lines > max_wake_lines)
+ return false;
+
+ if (!_lnl_compute_alpm_params(intel_dp, crtc_state))
+ return false;
+
+ if (i915->display.params.psr_safest_params)
+ io_wake_lines = fast_wake_lines = max_wake_lines;
+
+ /* According to Bspec lower limit should be set as 7 lines. */
+ intel_dp->alpm_parameters.io_wake_lines = max(io_wake_lines, 7);
+ intel_dp->alpm_parameters.fast_wake_lines = max(fast_wake_lines, 7);
+
+ return true;
+}
+
+void intel_alpm_lobf_compute_config(struct intel_dp *intel_dp,
+ struct intel_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state)
+{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
+ int waketime_in_lines, first_sdp_position;
+ int context_latency, guardband;
+
+ if (!intel_dp_is_edp(intel_dp))
+ return;
+
+ if (DISPLAY_VER(i915) < 20)
+ return;
+
+ if (!intel_dp_as_sdp_supported(intel_dp))
+ return;
+
+ if (crtc_state->has_psr)
+ return;
+
+ if (!(intel_alpm_aux_wake_supported(intel_dp) ||
+ intel_alpm_aux_less_wake_supported(intel_dp)))
+ return;
+
+ if (!intel_alpm_compute_params(intel_dp, crtc_state))
+ return;
+
+ context_latency = adjusted_mode->crtc_vblank_start - adjusted_mode->crtc_vdisplay;
+ guardband = adjusted_mode->crtc_vtotal -
+ adjusted_mode->crtc_vdisplay - context_latency;
+ first_sdp_position = adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vsync_start;
+ if (intel_alpm_aux_less_wake_supported(intel_dp))
+ waketime_in_lines = intel_dp->alpm_parameters.io_wake_lines;
+ else
+ waketime_in_lines = intel_dp->alpm_parameters.aux_less_wake_lines;
+
+ crtc_state->has_lobf = (context_latency + guardband) >
+ (first_sdp_position + waketime_in_lines);
+}
+
+static void lnl_alpm_configure(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+ enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
+ enum port port = dp_to_dig_port(intel_dp)->base.port;
+ u32 alpm_ctl;
+
+ if (DISPLAY_VER(dev_priv) < 20 || (!intel_dp->psr.sel_update_enabled &&
+ !intel_dp_is_edp(intel_dp)))
+ return;
+
+ /*
+ * Panel Replay on eDP is always using ALPM aux less. I.e. no need to
+ * check panel support at this point.
+ */
+ if ((intel_dp->psr.panel_replay_enabled && intel_dp_is_edp(intel_dp)) ||
+ (crtc_state->has_lobf && intel_alpm_aux_less_wake_supported(intel_dp))) {
+ alpm_ctl = ALPM_CTL_ALPM_ENABLE |
+ ALPM_CTL_ALPM_AUX_LESS_ENABLE |
+ ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_50_SYMBOLS |
+ ALPM_CTL_AUX_LESS_WAKE_TIME(intel_dp->alpm_parameters.aux_less_wake_lines);
+
+ intel_de_write(dev_priv,
+ PORT_ALPM_CTL(dev_priv, port),
+ PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE |
+ PORT_ALPM_CTL_MAX_PHY_SWING_SETUP(15) |
+ PORT_ALPM_CTL_MAX_PHY_SWING_HOLD(0) |
+ PORT_ALPM_CTL_SILENCE_PERIOD(
+ intel_dp->alpm_parameters.silence_period_sym_clocks));
+
+ intel_de_write(dev_priv,
+ PORT_ALPM_LFPS_CTL(dev_priv, port),
+ PORT_ALPM_LFPS_CTL_LFPS_CYCLE_COUNT(10) |
+ PORT_ALPM_LFPS_CTL_LFPS_HALF_CYCLE_DURATION(
+ intel_dp->alpm_parameters.lfps_half_cycle_num_of_syms) |
+ PORT_ALPM_LFPS_CTL_FIRST_LFPS_HALF_CYCLE_DURATION(
+ intel_dp->alpm_parameters.lfps_half_cycle_num_of_syms) |
+ PORT_ALPM_LFPS_CTL_LAST_LFPS_HALF_CYCLE_DURATION(
+ intel_dp->alpm_parameters.lfps_half_cycle_num_of_syms));
+ } else {
+ alpm_ctl = ALPM_CTL_EXTENDED_FAST_WAKE_ENABLE |
+ ALPM_CTL_EXTENDED_FAST_WAKE_TIME(intel_dp->alpm_parameters.fast_wake_lines);
+ }
+
+ if (crtc_state->has_lobf)
+ alpm_ctl |= ALPM_CTL_LOBF_ENABLE;
+
+ alpm_ctl |= ALPM_CTL_ALPM_ENTRY_CHECK(intel_dp->alpm_parameters.check_entry_lines);
+
+ intel_de_write(dev_priv, ALPM_CTL(dev_priv, cpu_transcoder), alpm_ctl);
+}
+
+void intel_alpm_configure(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
+{
+ lnl_alpm_configure(intel_dp, crtc_state);
+}
+
+static int i915_edp_lobf_info_show(struct seq_file *m, void *data)
+{
+ struct intel_connector *connector = m->private;
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ struct drm_crtc *crtc;
+ struct intel_crtc_state *crtc_state;
+ enum transcoder cpu_transcoder;
+ u32 alpm_ctl;
+ int ret;
+
+ ret = drm_modeset_lock_single_interruptible(&dev_priv->drm.mode_config.connection_mutex);
+ if (ret)
+ return ret;
+
+ crtc = connector->base.state->crtc;
+ if (connector->base.status != connector_status_connected || !crtc) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ crtc_state = to_intel_crtc_state(crtc->state);
+ cpu_transcoder = crtc_state->cpu_transcoder;
+ alpm_ctl = intel_de_read(dev_priv, ALPM_CTL(dev_priv, cpu_transcoder));
+ seq_printf(m, "LOBF status: %s\n", str_enabled_disabled(alpm_ctl & ALPM_CTL_LOBF_ENABLE));
+ seq_printf(m, "Aux-wake alpm status: %s\n",
+ str_enabled_disabled(!(alpm_ctl & ALPM_CTL_ALPM_AUX_LESS_ENABLE)));
+ seq_printf(m, "Aux-less alpm status: %s\n",
+ str_enabled_disabled(alpm_ctl & ALPM_CTL_ALPM_AUX_LESS_ENABLE));
+out:
+ drm_modeset_unlock(&dev_priv->drm.mode_config.connection_mutex);
+
+ return ret;
+}
+
+DEFINE_SHOW_ATTRIBUTE(i915_edp_lobf_info);
+
+void intel_alpm_lobf_debugfs_add(struct intel_connector *connector)
+{
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct dentry *root = connector->base.debugfs_entry;
+
+ if (DISPLAY_VER(i915) < 20 ||
+ connector->base.connector_type != DRM_MODE_CONNECTOR_eDP)
+ return;
+
+ debugfs_create_file("i915_edp_lobf_info", 0444, root,
+ connector, &i915_edp_lobf_info_fops);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_alpm.h b/drivers/gpu/drm/i915/display/intel_alpm.h
new file mode 100644
index 000000000000..d4fb60393c91
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_alpm.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: MIT
+ *
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef _INTEL_ALPM_H
+#define _INTEL_ALPM_H
+
+#include <linux/types.h>
+
+struct intel_dp;
+struct intel_crtc_state;
+struct drm_connector_state;
+struct intel_connector;
+
+void intel_alpm_init_dpcd(struct intel_dp *intel_dp);
+bool intel_alpm_compute_params(struct intel_dp *intel_dp,
+ struct intel_crtc_state *crtc_state);
+void intel_alpm_lobf_compute_config(struct intel_dp *intel_dp,
+ struct intel_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state);
+void intel_alpm_configure(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state);
+void intel_alpm_lobf_debugfs_add(struct intel_connector *connector);
+bool intel_alpm_aux_wake_supported(struct intel_dp *intel_dp);
+bool intel_alpm_aux_less_wake_supported(struct intel_dp *intel_dp);
+#endif
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index 7a77ae3dc394..76aa10b6f647 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -35,7 +35,6 @@
#include <drm/drm_fourcc.h>
#include "i915_drv.h"
-#include "i915_reg.h"
#include "intel_atomic.h"
#include "intel_cdclk.h"
#include "intel_display_types.h"
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 76d77d5a0409..8ec1bab1b15d 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -32,6 +32,7 @@
*/
#include <linux/dma-fence-chain.h>
+#include <linux/dma-resv.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_gem_atomic_helper.h>
@@ -39,7 +40,7 @@
#include <drm/drm_fourcc.h>
#include "i915_config.h"
-#include "i915_reg.h"
+#include "i9xx_plane_regs.h"
#include "intel_atomic_plane.h"
#include "intel_cdclk.h"
#include "intel_display_rps.h"
@@ -144,6 +145,14 @@ intel_plane_destroy_state(struct drm_plane *plane,
kfree(plane_state);
}
+bool intel_plane_needs_physical(struct intel_plane *plane)
+{
+ struct drm_i915_private *i915 = to_i915(plane->base.dev);
+
+ return plane->id == PLANE_CURSOR &&
+ DISPLAY_INFO(i915)->cursor_needs_physical;
+}
+
unsigned int intel_adjusted_rate(const struct drm_rect *src,
const struct drm_rect *dst,
unsigned int rate)
@@ -327,10 +336,10 @@ void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
intel_plane_clear_hw_state(plane_state);
/*
- * For the bigjoiner slave uapi.crtc will point at
- * the master crtc. So we explicitly assign the right
- * slave crtc to hw.crtc. uapi.crtc!=NULL simply indicates
- * the plane is logically enabled on the uapi level.
+ * For the joiner secondary uapi.crtc will point at
+ * the primary crtc. So we explicitly assign the right
+ * secondary crtc to hw.crtc. uapi.crtc!=NULL simply
+ * indicates the plane is logically enabled on the uapi level.
*/
plane_state->hw.crtc = from_plane_state->uapi.crtc ? &crtc->base : NULL;
@@ -429,10 +438,16 @@ static bool intel_plane_do_async_flip(struct intel_plane *plane,
* In platforms after DISPLAY13, we might need to override
* first async flip in order to change watermark levels
* as part of optimization.
- * So for those, we are checking if this is a first async flip.
- * For platforms earlier than DISPLAY13 we always do async flip.
+ *
+ * And let's do this for all skl+ so that we can eg. change the
+ * modifier as well.
+ *
+ * TODO: For older platforms there is less reason to do this as
+ * only X-tile is supported with async flips, though we could
+ * extend this so other scanout parameters (stride/etc) could
+ * be changed as well...
*/
- return DISPLAY_VER(i915) < 13 || old_crtc_state->uapi.async_flip;
+ return DISPLAY_VER(i915) < 9 || old_crtc_state->uapi.async_flip;
}
static bool i9xx_must_disable_cxsr(const struct intel_crtc_state *new_crtc_state,
@@ -594,6 +609,17 @@ static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_cr
if (intel_plane_do_async_flip(plane, old_crtc_state, new_crtc_state)) {
new_crtc_state->do_async_flip = true;
new_crtc_state->async_flip_planes |= BIT(plane->id);
+ } else if (plane->need_async_flip_toggle_wa &&
+ new_crtc_state->uapi.async_flip) {
+ /*
+ * On platforms with double buffered async flip bit we
+ * set the bit already one frame early during the sync
+ * flip (see {i9xx,skl}_plane_update_arm()). The
+ * hardware will therefore be ready to perform a real
+ * async flip during the next commit, without having
+ * to wait yet another frame for the bit to latch.
+ */
+ new_crtc_state->async_flip_planes |= BIT(plane->id);
}
return 0;
@@ -688,27 +714,27 @@ int intel_plane_atomic_check(struct intel_atomic_state *state,
intel_atomic_get_new_plane_state(state, plane);
const struct intel_plane_state *old_plane_state =
intel_atomic_get_old_plane_state(state, plane);
- const struct intel_plane_state *new_master_plane_state;
+ const struct intel_plane_state *new_primary_crtc_plane_state;
struct intel_crtc *crtc = intel_crtc_for_pipe(i915, plane->pipe);
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
struct intel_crtc_state *new_crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
- if (new_crtc_state && intel_crtc_is_bigjoiner_slave(new_crtc_state)) {
- struct intel_crtc *master_crtc =
- intel_master_crtc(new_crtc_state);
- struct intel_plane *master_plane =
- intel_crtc_get_plane(master_crtc, plane->id);
+ if (new_crtc_state && intel_crtc_is_joiner_secondary(new_crtc_state)) {
+ struct intel_crtc *primary_crtc =
+ intel_primary_crtc(new_crtc_state);
+ struct intel_plane *primary_crtc_plane =
+ intel_crtc_get_plane(primary_crtc, plane->id);
- new_master_plane_state =
- intel_atomic_get_new_plane_state(state, master_plane);
+ new_primary_crtc_plane_state =
+ intel_atomic_get_new_plane_state(state, primary_crtc_plane);
} else {
- new_master_plane_state = new_plane_state;
+ new_primary_crtc_plane_state = new_plane_state;
}
intel_plane_copy_uapi_to_hw_state(new_plane_state,
- new_master_plane_state,
+ new_primary_crtc_plane_state,
crtc);
new_plane_state->uapi.visible = false;
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
index 191dad0efc8e..e7a0699f17c8 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
@@ -66,5 +66,6 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state);
void intel_plane_set_invisible(struct intel_crtc_state *crtc_state,
struct intel_plane_state *plane_state);
void intel_plane_helper_add(struct intel_plane *plane);
+bool intel_plane_needs_physical(struct intel_plane *plane);
#endif /* __INTEL_ATOMIC_PLANE_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c
index 40e7d862675e..b9bafec06fb8 100644
--- a/drivers/gpu/drm/i915/display/intel_audio.c
+++ b/drivers/gpu/drm/i915/display/intel_audio.c
@@ -26,7 +26,7 @@
#include <drm/drm_edid.h>
#include <drm/drm_eld.h>
-#include <drm/i915_component.h>
+#include <drm/intel/i915_component.h>
#include "i915_drv.h"
#include "intel_atomic.h"
@@ -183,6 +183,15 @@ static const struct hdmi_aud_ncts hdmi_aud_ncts_36bpp[] = {
{ 192000, TMDS_445_5M, 20480, 371250 },
};
+/*
+ * WA_14020863754: Implement Audio Workaround
+ * Corner case with Min Hblank Fix can cause audio hang
+ */
+static bool needs_wa_14020863754(struct drm_i915_private *i915)
+{
+ return (DISPLAY_VER(i915) == 20 || IS_BATTLEMAGE(i915));
+}
+
/* get AUD_CONFIG_PIXEL_CLOCK_HDMI_* value for mode */
static u32 audio_config_hdmi_pixel_clock(const struct intel_crtc_state *crtc_state)
{
@@ -415,6 +424,9 @@ static void hsw_audio_codec_disable(struct intel_encoder *encoder,
intel_de_rmw(i915, HSW_AUD_PIN_ELD_CP_VLD,
AUDIO_OUTPUT_ENABLE(cpu_transcoder), 0);
+ if (needs_wa_14020863754(i915))
+ intel_de_rmw(i915, AUD_CHICKENBIT_REG3, DACBE_DISABLE_MIN_HBLANK_FIX, 0);
+
mutex_unlock(&i915->display.audio.mutex);
}
@@ -540,6 +552,9 @@ static void hsw_audio_codec_enable(struct intel_encoder *encoder,
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP))
enable_audio_dsc_wa(encoder, crtc_state);
+ if (needs_wa_14020863754(i915))
+ intel_de_rmw(i915, AUD_CHICKENBIT_REG3, 0, DACBE_DISABLE_MIN_HBLANK_FIX);
+
/* Enable audio presence detect */
intel_de_rmw(i915, HSW_AUD_PIN_ELD_CP_VLD,
0, AUDIO_OUTPUT_ENABLE(cpu_transcoder));
diff --git a/drivers/gpu/drm/i915/display/intel_audio_regs.h b/drivers/gpu/drm/i915/display/intel_audio_regs.h
index 88ea2740365d..4c31844d21df 100644
--- a/drivers/gpu/drm/i915/display/intel_audio_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_audio_regs.h
@@ -164,4 +164,7 @@
_VLV_AUD_PORT_EN_D_DBG)
#define VLV_AMP_MUTE (1 << 1)
+#define AUD_CHICKENBIT_REG3 _MMIO(0x65F1C)
+#define DACBE_DISABLE_MIN_HBLANK_FIX REG_BIT(18)
+
#endif /* __INTEL_AUDIO_REGS_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
index 5fb48b6129b6..ec1e3a380360 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -36,6 +36,7 @@
#include "intel_display.h"
#include "intel_display_types.h"
#include "intel_gmbus.h"
+#include "intel_uncore.h"
#define _INTEL_BIOS_PRIVATE
#include "intel_vbt_defs.h"
@@ -170,22 +171,22 @@ static const struct {
.min_size = sizeof(struct bdb_driver_features), },
{ .section_id = BDB_SDVO_LVDS_OPTIONS,
.min_size = sizeof(struct bdb_sdvo_lvds_options), },
- { .section_id = BDB_SDVO_PANEL_DTDS,
- .min_size = sizeof(struct bdb_sdvo_panel_dtds), },
+ { .section_id = BDB_SDVO_LVDS_DTD,
+ .min_size = sizeof(struct bdb_sdvo_lvds_dtd), },
{ .section_id = BDB_EDP,
.min_size = sizeof(struct bdb_edp), },
- { .section_id = BDB_LVDS_OPTIONS,
- .min_size = sizeof(struct bdb_lvds_options), },
+ { .section_id = BDB_LFP_OPTIONS,
+ .min_size = sizeof(struct bdb_lfp_options), },
/*
- * BDB_LVDS_LFP_DATA depends on BDB_LVDS_LFP_DATA_PTRS,
+ * BDB_LFP_DATA depends on BDB_LFP_DATA_PTRS,
* so keep the two ordered.
*/
- { .section_id = BDB_LVDS_LFP_DATA_PTRS,
- .min_size = sizeof(struct bdb_lvds_lfp_data_ptrs), },
- { .section_id = BDB_LVDS_LFP_DATA,
+ { .section_id = BDB_LFP_DATA_PTRS,
+ .min_size = sizeof(struct bdb_lfp_data_ptrs), },
+ { .section_id = BDB_LFP_DATA,
.min_size = 0, /* special case */ },
- { .section_id = BDB_LVDS_BACKLIGHT,
- .min_size = sizeof(struct bdb_lfp_backlight_data), },
+ { .section_id = BDB_LFP_BACKLIGHT,
+ .min_size = sizeof(struct bdb_lfp_backlight), },
{ .section_id = BDB_LFP_POWER,
.min_size = sizeof(struct bdb_lfp_power), },
{ .section_id = BDB_MIPI_CONFIG,
@@ -200,30 +201,30 @@ static const struct {
static size_t lfp_data_min_size(struct drm_i915_private *i915)
{
- const struct bdb_lvds_lfp_data_ptrs *ptrs;
+ const struct bdb_lfp_data_ptrs *ptrs;
size_t size;
- ptrs = bdb_find_section(i915, BDB_LVDS_LFP_DATA_PTRS);
+ ptrs = bdb_find_section(i915, BDB_LFP_DATA_PTRS);
if (!ptrs)
return 0;
- size = sizeof(struct bdb_lvds_lfp_data);
+ size = sizeof(struct bdb_lfp_data);
if (ptrs->panel_name.table_size)
size = max(size, ptrs->panel_name.offset +
- sizeof(struct bdb_lvds_lfp_data_tail));
+ sizeof(struct bdb_lfp_data_tail));
return size;
}
static bool validate_lfp_data_ptrs(const void *bdb,
- const struct bdb_lvds_lfp_data_ptrs *ptrs)
+ const struct bdb_lfp_data_ptrs *ptrs)
{
int fp_timing_size, dvo_timing_size, panel_pnp_id_size, panel_name_size;
int data_block_size, lfp_data_size;
const void *data_block;
int i;
- data_block = find_raw_section(bdb, BDB_LVDS_LFP_DATA);
+ data_block = find_raw_section(bdb, BDB_LFP_DATA);
if (!data_block)
return false;
@@ -232,7 +233,7 @@ static bool validate_lfp_data_ptrs(const void *bdb,
return false;
/* always 3 indicating the presence of fp_timing+dvo_timing+panel_pnp_id */
- if (ptrs->lvds_entries != 3)
+ if (ptrs->num_entries != 3)
return false;
fp_timing_size = ptrs->ptr[0].fp_timing.table_size;
@@ -242,13 +243,13 @@ static bool validate_lfp_data_ptrs(const void *bdb,
/* fp_timing has variable size */
if (fp_timing_size < 32 ||
- dvo_timing_size != sizeof(struct lvds_dvo_timing) ||
- panel_pnp_id_size != sizeof(struct lvds_pnp_id))
+ dvo_timing_size != sizeof(struct bdb_edid_dtd) ||
+ panel_pnp_id_size != sizeof(struct bdb_edid_pnp_id))
return false;
/* panel_name is not present in old VBTs */
if (panel_name_size != 0 &&
- panel_name_size != sizeof(struct lvds_lfp_panel_name))
+ panel_name_size != sizeof(struct bdb_edid_product_name))
return false;
lfp_data_size = ptrs->ptr[1].fp_timing.offset - ptrs->ptr[0].fp_timing.offset;
@@ -311,11 +312,11 @@ static bool validate_lfp_data_ptrs(const void *bdb,
/* make the data table offsets relative to the data block */
static bool fixup_lfp_data_ptrs(const void *bdb, void *ptrs_block)
{
- struct bdb_lvds_lfp_data_ptrs *ptrs = ptrs_block;
+ struct bdb_lfp_data_ptrs *ptrs = ptrs_block;
u32 offset;
int i;
- offset = raw_block_offset(bdb, BDB_LVDS_LFP_DATA);
+ offset = raw_block_offset(bdb, BDB_LFP_DATA);
for (i = 0; i < 16; i++) {
if (ptrs->ptr[i].fp_timing.offset < offset ||
@@ -338,7 +339,7 @@ static bool fixup_lfp_data_ptrs(const void *bdb, void *ptrs_block)
return validate_lfp_data_ptrs(bdb, ptrs);
}
-static int make_lfp_data_ptr(struct lvds_lfp_data_ptr_table *table,
+static int make_lfp_data_ptr(struct lfp_data_ptr_table *table,
int table_size, int total_size)
{
if (total_size < table_size)
@@ -350,8 +351,8 @@ static int make_lfp_data_ptr(struct lvds_lfp_data_ptr_table *table,
return total_size - table_size;
}
-static void next_lfp_data_ptr(struct lvds_lfp_data_ptr_table *next,
- const struct lvds_lfp_data_ptr_table *prev,
+static void next_lfp_data_ptr(struct lfp_data_ptr_table *next,
+ const struct lfp_data_ptr_table *prev,
int size)
{
next->table_size = prev->table_size;
@@ -362,7 +363,7 @@ static void *generate_lfp_data_ptrs(struct drm_i915_private *i915,
const void *bdb)
{
int i, size, table_size, block_size, offset, fp_timing_size;
- struct bdb_lvds_lfp_data_ptrs *ptrs;
+ struct bdb_lfp_data_ptrs *ptrs;
const void *block;
void *ptrs_block;
@@ -377,7 +378,7 @@ static void *generate_lfp_data_ptrs(struct drm_i915_private *i915,
fp_timing_size = 38;
- block = find_raw_section(bdb, BDB_LVDS_LFP_DATA);
+ block = find_raw_section(bdb, BDB_LFP_DATA);
if (!block)
return NULL;
@@ -385,8 +386,8 @@ static void *generate_lfp_data_ptrs(struct drm_i915_private *i915,
block_size = get_blocksize(block);
- size = fp_timing_size + sizeof(struct lvds_dvo_timing) +
- sizeof(struct lvds_pnp_id);
+ size = fp_timing_size + sizeof(struct bdb_edid_dtd) +
+ sizeof(struct bdb_edid_pnp_id);
if (size * 16 > block_size)
return NULL;
@@ -394,40 +395,40 @@ static void *generate_lfp_data_ptrs(struct drm_i915_private *i915,
if (!ptrs_block)
return NULL;
- *(u8 *)(ptrs_block + 0) = BDB_LVDS_LFP_DATA_PTRS;
+ *(u8 *)(ptrs_block + 0) = BDB_LFP_DATA_PTRS;
*(u16 *)(ptrs_block + 1) = sizeof(*ptrs);
ptrs = ptrs_block + 3;
- table_size = sizeof(struct lvds_pnp_id);
+ table_size = sizeof(struct bdb_edid_pnp_id);
size = make_lfp_data_ptr(&ptrs->ptr[0].panel_pnp_id, table_size, size);
- table_size = sizeof(struct lvds_dvo_timing);
+ table_size = sizeof(struct bdb_edid_dtd);
size = make_lfp_data_ptr(&ptrs->ptr[0].dvo_timing, table_size, size);
table_size = fp_timing_size;
size = make_lfp_data_ptr(&ptrs->ptr[0].fp_timing, table_size, size);
if (ptrs->ptr[0].fp_timing.table_size)
- ptrs->lvds_entries++;
+ ptrs->num_entries++;
if (ptrs->ptr[0].dvo_timing.table_size)
- ptrs->lvds_entries++;
+ ptrs->num_entries++;
if (ptrs->ptr[0].panel_pnp_id.table_size)
- ptrs->lvds_entries++;
+ ptrs->num_entries++;
- if (size != 0 || ptrs->lvds_entries != 3) {
+ if (size != 0 || ptrs->num_entries != 3) {
kfree(ptrs_block);
return NULL;
}
- size = fp_timing_size + sizeof(struct lvds_dvo_timing) +
- sizeof(struct lvds_pnp_id);
+ size = fp_timing_size + sizeof(struct bdb_edid_dtd) +
+ sizeof(struct bdb_edid_pnp_id);
for (i = 1; i < 16; i++) {
next_lfp_data_ptr(&ptrs->ptr[i].fp_timing, &ptrs->ptr[i-1].fp_timing, size);
next_lfp_data_ptr(&ptrs->ptr[i].dvo_timing, &ptrs->ptr[i-1].dvo_timing, size);
next_lfp_data_ptr(&ptrs->ptr[i].panel_pnp_id, &ptrs->ptr[i-1].panel_pnp_id, size);
}
- table_size = sizeof(struct lvds_lfp_panel_name);
+ table_size = sizeof(struct bdb_edid_product_name);
if (16 * (size + table_size) <= block_size) {
ptrs->panel_name.table_size = table_size;
@@ -461,7 +462,7 @@ init_bdb_block(struct drm_i915_private *i915,
block = find_raw_section(bdb, section_id);
/* Modern VBTs lack the LFP data table pointers block, make one up */
- if (!block && section_id == BDB_LVDS_LFP_DATA_PTRS) {
+ if (!block && section_id == BDB_LFP_DATA_PTRS) {
temp_block = generate_lfp_data_ptrs(i915, bdb);
if (temp_block)
block = temp_block + 3;
@@ -496,7 +497,7 @@ init_bdb_block(struct drm_i915_private *i915,
drm_dbg_kms(&i915->drm, "Found BDB block %d (size %zu, min size %zu)\n",
section_id, block_size, min_size);
- if (section_id == BDB_LVDS_LFP_DATA_PTRS &&
+ if (section_id == BDB_LFP_DATA_PTRS &&
!fixup_lfp_data_ptrs(bdb, entry->data + 3)) {
drm_err(&i915->drm, "VBT has malformed LFP data table pointers\n");
kfree(entry);
@@ -515,7 +516,7 @@ static void init_bdb_blocks(struct drm_i915_private *i915,
enum bdb_block_id section_id = bdb_blocks[i].section_id;
size_t min_size = bdb_blocks[i].min_size;
- if (section_id == BDB_LVDS_LFP_DATA)
+ if (section_id == BDB_LFP_DATA)
min_size = lfp_data_min_size(i915);
init_bdb_block(i915, bdb, section_id, min_size);
@@ -525,7 +526,7 @@ static void init_bdb_blocks(struct drm_i915_private *i915,
static void
fill_detail_timing_data(struct drm_i915_private *i915,
struct drm_display_mode *panel_fixed_mode,
- const struct lvds_dvo_timing *dvo_timing)
+ const struct bdb_edid_dtd *dvo_timing)
{
panel_fixed_mode->hdisplay = (dvo_timing->hactive_hi << 8) |
dvo_timing->hactive_lo;
@@ -579,36 +580,36 @@ fill_detail_timing_data(struct drm_i915_private *i915,
drm_mode_set_name(panel_fixed_mode);
}
-static const struct lvds_dvo_timing *
-get_lvds_dvo_timing(const struct bdb_lvds_lfp_data *data,
- const struct bdb_lvds_lfp_data_ptrs *ptrs,
- int index)
+static const struct bdb_edid_dtd *
+get_lfp_dvo_timing(const struct bdb_lfp_data *data,
+ const struct bdb_lfp_data_ptrs *ptrs,
+ int index)
{
return (const void *)data + ptrs->ptr[index].dvo_timing.offset;
}
-static const struct lvds_fp_timing *
-get_lvds_fp_timing(const struct bdb_lvds_lfp_data *data,
- const struct bdb_lvds_lfp_data_ptrs *ptrs,
- int index)
+static const struct fp_timing *
+get_lfp_fp_timing(const struct bdb_lfp_data *data,
+ const struct bdb_lfp_data_ptrs *ptrs,
+ int index)
{
return (const void *)data + ptrs->ptr[index].fp_timing.offset;
}
static const struct drm_edid_product_id *
-get_lvds_pnp_id(const struct bdb_lvds_lfp_data *data,
- const struct bdb_lvds_lfp_data_ptrs *ptrs,
- int index)
+get_lfp_pnp_id(const struct bdb_lfp_data *data,
+ const struct bdb_lfp_data_ptrs *ptrs,
+ int index)
{
/* These two are supposed to have the same layout in memory. */
- BUILD_BUG_ON(sizeof(struct lvds_pnp_id) != sizeof(struct drm_edid_product_id));
+ BUILD_BUG_ON(sizeof(struct bdb_edid_pnp_id) != sizeof(struct drm_edid_product_id));
return (const void *)data + ptrs->ptr[index].panel_pnp_id.offset;
}
-static const struct bdb_lvds_lfp_data_tail *
-get_lfp_data_tail(const struct bdb_lvds_lfp_data *data,
- const struct bdb_lvds_lfp_data_ptrs *ptrs)
+static const struct bdb_lfp_data_tail *
+get_lfp_data_tail(const struct bdb_lfp_data *data,
+ const struct bdb_lfp_data_ptrs *ptrs)
{
if (ptrs->panel_name.table_size)
return (const void *)data + ptrs->panel_name.offset;
@@ -627,33 +628,33 @@ static int vbt_get_panel_type(struct drm_i915_private *i915,
const struct intel_bios_encoder_data *devdata,
const struct drm_edid *drm_edid, bool use_fallback)
{
- const struct bdb_lvds_options *lvds_options;
+ const struct bdb_lfp_options *lfp_options;
- lvds_options = bdb_find_section(i915, BDB_LVDS_OPTIONS);
- if (!lvds_options)
+ lfp_options = bdb_find_section(i915, BDB_LFP_OPTIONS);
+ if (!lfp_options)
return -1;
- if (lvds_options->panel_type > 0xf &&
- lvds_options->panel_type != 0xff) {
+ if (lfp_options->panel_type > 0xf &&
+ lfp_options->panel_type != 0xff) {
drm_dbg_kms(&i915->drm, "Invalid VBT panel type 0x%x\n",
- lvds_options->panel_type);
+ lfp_options->panel_type);
return -1;
}
if (devdata && devdata->child.handle == DEVICE_HANDLE_LFP2)
- return lvds_options->panel_type2;
+ return lfp_options->panel_type2;
drm_WARN_ON(&i915->drm, devdata && devdata->child.handle != DEVICE_HANDLE_LFP1);
- return lvds_options->panel_type;
+ return lfp_options->panel_type;
}
static int pnpid_get_panel_type(struct drm_i915_private *i915,
const struct intel_bios_encoder_data *devdata,
const struct drm_edid *drm_edid, bool use_fallback)
{
- const struct bdb_lvds_lfp_data *data;
- const struct bdb_lvds_lfp_data_ptrs *ptrs;
+ const struct bdb_lfp_data *data;
+ const struct bdb_lfp_data_ptrs *ptrs;
struct drm_edid_product_id product_id, product_id_nodate;
struct drm_printer p;
int i, best = -1;
@@ -670,17 +671,17 @@ static int pnpid_get_panel_type(struct drm_i915_private *i915,
p = drm_dbg_printer(&i915->drm, DRM_UT_KMS, "EDID");
drm_edid_print_product_id(&p, &product_id, true);
- ptrs = bdb_find_section(i915, BDB_LVDS_LFP_DATA_PTRS);
+ ptrs = bdb_find_section(i915, BDB_LFP_DATA_PTRS);
if (!ptrs)
return -1;
- data = bdb_find_section(i915, BDB_LVDS_LFP_DATA);
+ data = bdb_find_section(i915, BDB_LFP_DATA);
if (!data)
return -1;
for (i = 0; i < 16; i++) {
const struct drm_edid_product_id *vbt_id =
- get_lvds_pnp_id(data, ptrs, i);
+ get_lfp_pnp_id(data, ptrs, i);
/* full match? */
if (!memcmp(vbt_id, &product_id, sizeof(*vbt_id)))
@@ -786,25 +787,25 @@ static void
parse_panel_options(struct drm_i915_private *i915,
struct intel_panel *panel)
{
- const struct bdb_lvds_options *lvds_options;
+ const struct bdb_lfp_options *lfp_options;
int panel_type = panel->vbt.panel_type;
int drrs_mode;
- lvds_options = bdb_find_section(i915, BDB_LVDS_OPTIONS);
- if (!lvds_options)
+ lfp_options = bdb_find_section(i915, BDB_LFP_OPTIONS);
+ if (!lfp_options)
return;
- panel->vbt.lvds_dither = lvds_options->pixel_dither;
+ panel->vbt.lvds_dither = lfp_options->pixel_dither;
/*
* Empirical evidence indicates the block size can be
* either 4,14,16,24+ bytes. For older VBTs no clear
* relationship between the block size vs. BDB version.
*/
- if (get_blocksize(lvds_options) < 16)
+ if (get_blocksize(lfp_options) < 16)
return;
- drrs_mode = panel_bits(lvds_options->dps_panel_type_bits,
+ drrs_mode = panel_bits(lfp_options->dps_panel_type_bits,
panel_type, 2);
/*
* VBT has static DRRS = 0 and seamless DRRS = 2.
@@ -832,17 +833,17 @@ parse_panel_options(struct drm_i915_private *i915,
static void
parse_lfp_panel_dtd(struct drm_i915_private *i915,
struct intel_panel *panel,
- const struct bdb_lvds_lfp_data *lvds_lfp_data,
- const struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs)
+ const struct bdb_lfp_data *lfp_data,
+ const struct bdb_lfp_data_ptrs *lfp_data_ptrs)
{
- const struct lvds_dvo_timing *panel_dvo_timing;
- const struct lvds_fp_timing *fp_timing;
+ const struct bdb_edid_dtd *panel_dvo_timing;
+ const struct fp_timing *fp_timing;
struct drm_display_mode *panel_fixed_mode;
int panel_type = panel->vbt.panel_type;
- panel_dvo_timing = get_lvds_dvo_timing(lvds_lfp_data,
- lvds_lfp_data_ptrs,
- panel_type);
+ panel_dvo_timing = get_lfp_dvo_timing(lfp_data,
+ lfp_data_ptrs,
+ panel_type);
panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL);
if (!panel_fixed_mode)
@@ -850,15 +851,15 @@ parse_lfp_panel_dtd(struct drm_i915_private *i915,
fill_detail_timing_data(i915, panel_fixed_mode, panel_dvo_timing);
- panel->vbt.lfp_lvds_vbt_mode = panel_fixed_mode;
+ panel->vbt.lfp_vbt_mode = panel_fixed_mode;
drm_dbg_kms(&i915->drm,
"Found panel mode in BIOS VBT legacy lfp table: " DRM_MODE_FMT "\n",
DRM_MODE_ARG(panel_fixed_mode));
- fp_timing = get_lvds_fp_timing(lvds_lfp_data,
- lvds_lfp_data_ptrs,
- panel_type);
+ fp_timing = get_lfp_fp_timing(lfp_data,
+ lfp_data_ptrs,
+ panel_type);
/* check the resolution, just to be sure */
if (fp_timing->x_res == panel_fixed_mode->hdisplay &&
@@ -874,25 +875,25 @@ static void
parse_lfp_data(struct drm_i915_private *i915,
struct intel_panel *panel)
{
- const struct bdb_lvds_lfp_data *data;
- const struct bdb_lvds_lfp_data_tail *tail;
- const struct bdb_lvds_lfp_data_ptrs *ptrs;
+ const struct bdb_lfp_data *data;
+ const struct bdb_lfp_data_tail *tail;
+ const struct bdb_lfp_data_ptrs *ptrs;
const struct drm_edid_product_id *pnp_id;
struct drm_printer p;
int panel_type = panel->vbt.panel_type;
- ptrs = bdb_find_section(i915, BDB_LVDS_LFP_DATA_PTRS);
+ ptrs = bdb_find_section(i915, BDB_LFP_DATA_PTRS);
if (!ptrs)
return;
- data = bdb_find_section(i915, BDB_LVDS_LFP_DATA);
+ data = bdb_find_section(i915, BDB_LFP_DATA);
if (!data)
return;
- if (!panel->vbt.lfp_lvds_vbt_mode)
+ if (!panel->vbt.lfp_vbt_mode)
parse_lfp_panel_dtd(i915, panel, data, ptrs);
- pnp_id = get_lvds_pnp_id(data, ptrs, panel_type);
+ pnp_id = get_lfp_pnp_id(data, ptrs, panel_type);
p = drm_dbg_printer(&i915->drm, DRM_UT_KMS, "Panel");
drm_edid_print_product_id(&p, pnp_id, false);
@@ -1001,19 +1002,19 @@ parse_generic_dtd(struct drm_i915_private *i915,
"Found panel mode in BIOS VBT generic dtd table: " DRM_MODE_FMT "\n",
DRM_MODE_ARG(panel_fixed_mode));
- panel->vbt.lfp_lvds_vbt_mode = panel_fixed_mode;
+ panel->vbt.lfp_vbt_mode = panel_fixed_mode;
}
static void
parse_lfp_backlight(struct drm_i915_private *i915,
struct intel_panel *panel)
{
- const struct bdb_lfp_backlight_data *backlight_data;
+ const struct bdb_lfp_backlight *backlight_data;
const struct lfp_backlight_data_entry *entry;
int panel_type = panel->vbt.panel_type;
u16 level;
- backlight_data = bdb_find_section(i915, BDB_LVDS_BACKLIGHT);
+ backlight_data = bdb_find_section(i915, BDB_LFP_BACKLIGHT);
if (!backlight_data)
return;
@@ -1091,19 +1092,18 @@ parse_lfp_backlight(struct drm_i915_private *i915,
panel->vbt.backlight.controller);
}
-/* Try to find sdvo panel data */
static void
-parse_sdvo_panel_data(struct drm_i915_private *i915,
- struct intel_panel *panel)
+parse_sdvo_lvds_data(struct drm_i915_private *i915,
+ struct intel_panel *panel)
{
- const struct bdb_sdvo_panel_dtds *dtds;
+ const struct bdb_sdvo_lvds_dtd *dtd;
struct drm_display_mode *panel_fixed_mode;
int index;
index = i915->display.params.vbt_sdvo_panel_type;
if (index == -2) {
drm_dbg_kms(&i915->drm,
- "Ignore SDVO panel mode from BIOS VBT tables.\n");
+ "Ignore SDVO LVDS mode from BIOS VBT tables.\n");
return;
}
@@ -1117,20 +1117,32 @@ parse_sdvo_panel_data(struct drm_i915_private *i915,
index = sdvo_lvds_options->panel_type;
}
- dtds = bdb_find_section(i915, BDB_SDVO_PANEL_DTDS);
- if (!dtds)
+ dtd = bdb_find_section(i915, BDB_SDVO_LVDS_DTD);
+ if (!dtd)
return;
+ /*
+ * This should not happen, as long as the panel_type
+ * enumeration doesn't grow over 4 items. But if it does, it
+ * could lead to hard-to-detect bugs, so better double-check
+ * it here to be sure.
+ */
+ if (index >= ARRAY_SIZE(dtd->dtd)) {
+ drm_err(&i915->drm, "index %d is larger than dtd->dtd[4] array\n",
+ index);
+ return;
+ }
+
panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL);
if (!panel_fixed_mode)
return;
- fill_detail_timing_data(i915, panel_fixed_mode, &dtds->dtds[index]);
+ fill_detail_timing_data(i915, panel_fixed_mode, &dtd->dtd[index]);
panel->vbt.sdvo_lvds_vbt_mode = panel_fixed_mode;
drm_dbg_kms(&i915->drm,
- "Found SDVO panel mode in BIOS VBT tables: " DRM_MODE_FMT "\n",
+ "Found SDVO LVDS mode in BIOS VBT tables: " DRM_MODE_FMT "\n",
DRM_MODE_ARG(panel_fixed_mode));
}
@@ -1513,6 +1525,10 @@ parse_edp(struct drm_i915_private *i915,
if (i915->display.vbt.version >= 244)
panel->vbt.edp.max_link_rate =
edp->edp_max_port_link_rate[panel_type] * 20;
+
+ if (i915->display.vbt.version >= 251)
+ panel->vbt.edp.dsc_disable =
+ panel_bool(edp->edp_dsc_disable, panel_type);
}
static void
@@ -1677,7 +1693,7 @@ parse_mipi_config(struct drm_i915_private *i915,
panel->vbt.dsi.panel_id = MIPI_DSI_UNDEFINED_PANEL_ID;
/* Block #40 is already parsed and panel_fixed_mode is
- * stored in i915->lfp_lvds_vbt_mode
+ * stored in i915->lfp_vbt_mode
* resuse this when needed
*/
@@ -2220,15 +2236,14 @@ static u8 map_ddc_pin(struct drm_i915_private *i915, u8 vbt_pin)
const u8 *ddc_pin_map;
int i, n_entries;
- if (IS_DGFX(i915))
- return vbt_pin;
-
if (INTEL_PCH_TYPE(i915) >= PCH_MTL || IS_ALDERLAKE_P(i915)) {
ddc_pin_map = adlp_ddc_pin_map;
n_entries = ARRAY_SIZE(adlp_ddc_pin_map);
} else if (IS_ALDERLAKE_S(i915)) {
ddc_pin_map = adls_ddc_pin_map;
n_entries = ARRAY_SIZE(adls_ddc_pin_map);
+ } else if (INTEL_PCH_TYPE(i915) >= PCH_DG1) {
+ return vbt_pin;
} else if (IS_ROCKETLAKE(i915) && INTEL_PCH_TYPE(i915) == PCH_TGP) {
ddc_pin_map = rkl_pch_tgp_ddc_pin_map;
n_entries = ARRAY_SIZE(rkl_pch_tgp_ddc_pin_map);
@@ -3258,7 +3273,7 @@ static void intel_bios_init_panel(struct drm_i915_private *i915,
parse_generic_dtd(i915, panel);
parse_lfp_data(i915, panel);
parse_lfp_backlight(i915, panel);
- parse_sdvo_panel_data(i915, panel);
+ parse_sdvo_lvds_data(i915, panel);
parse_panel_driver_features(i915, panel);
parse_power_conservation_features(i915, panel);
parse_edp(i915, panel);
@@ -3307,8 +3322,8 @@ void intel_bios_fini_panel(struct intel_panel *panel)
{
kfree(panel->vbt.sdvo_lvds_vbt_mode);
panel->vbt.sdvo_lvds_vbt_mode = NULL;
- kfree(panel->vbt.lfp_lvds_vbt_mode);
- panel->vbt.lfp_lvds_vbt_mode = NULL;
+ kfree(panel->vbt.lfp_vbt_mode);
+ panel->vbt.lfp_vbt_mode = NULL;
kfree(panel->vbt.dsi.data);
panel->vbt.dsi.data = NULL;
kfree(panel->vbt.dsi.pps);
diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
index 972ea887e232..47036d4abb33 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_bw.c
@@ -22,6 +22,8 @@ struct intel_qgv_point {
u16 dclk, t_rp, t_rdpre, t_rc, t_ras, t_rcd;
};
+#define DEPROGBWPCLIMIT 60
+
struct intel_psf_gv_point {
u8 clk; /* clock in multiples of 16.6666 MHz */
};
@@ -241,6 +243,9 @@ static int icl_get_qgv_points(struct drm_i915_private *dev_priv,
qi->channel_width = 16;
qi->deinterleave = 4;
break;
+ case INTEL_DRAM_GDDR:
+ qi->channel_width = 32;
+ break;
default:
MISSING_CASE(dram_info->type);
return -EINVAL;
@@ -387,6 +392,12 @@ static const struct intel_sa_info mtl_sa_info = {
.derating = 10,
};
+static const struct intel_sa_info xe2_hpd_sa_info = {
+ .derating = 30,
+ .deprogbwlimit = 53,
+ /* Other values not used by simplified algorithm */
+};
+
static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel_sa_info *sa)
{
struct intel_qgv_info qi = {};
@@ -493,7 +504,7 @@ static int tgl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel
dclk_max = icl_sagv_max_dclk(&qi);
peakbw = num_channels * DIV_ROUND_UP(qi.channel_width, 8) * dclk_max;
- maxdebw = min(sa->deprogbwlimit * 1000, peakbw * 6 / 10); /* 60% */
+ maxdebw = min(sa->deprogbwlimit * 1000, peakbw * DEPROGBWPCLIMIT / 100);
ipqdepth = min(ipqdepthpch, sa->displayrtids / num_channels);
/*
@@ -598,6 +609,54 @@ static void dg2_get_bw_info(struct drm_i915_private *i915)
i915->display.sagv.status = I915_SAGV_NOT_CONTROLLED;
}
+static int xe2_hpd_get_bw_info(struct drm_i915_private *i915,
+ const struct intel_sa_info *sa)
+{
+ struct intel_qgv_info qi = {};
+ int num_channels = i915->dram_info.num_channels;
+ int peakbw, maxdebw;
+ int ret, i;
+
+ ret = icl_get_qgv_points(i915, &qi, true);
+ if (ret) {
+ drm_dbg_kms(&i915->drm,
+ "Failed to get memory subsystem information, ignoring bandwidth limits");
+ return ret;
+ }
+
+ peakbw = num_channels * qi.channel_width / 8 * icl_sagv_max_dclk(&qi);
+ maxdebw = min(sa->deprogbwlimit * 1000, peakbw * DEPROGBWPCLIMIT / 10);
+
+ for (i = 0; i < qi.num_points; i++) {
+ const struct intel_qgv_point *point = &qi.points[i];
+ int bw = num_channels * (qi.channel_width / 8) * point->dclk;
+
+ i915->display.bw.max[0].deratedbw[i] =
+ min(maxdebw, (100 - sa->derating) * bw / 100);
+ i915->display.bw.max[0].peakbw[i] = bw;
+
+ drm_dbg_kms(&i915->drm, "QGV %d: deratedbw=%u peakbw: %u\n",
+ i, i915->display.bw.max[0].deratedbw[i],
+ i915->display.bw.max[0].peakbw[i]);
+ }
+
+ /* Bandwidth does not depend on # of planes; set all groups the same */
+ i915->display.bw.max[0].num_planes = 1;
+ i915->display.bw.max[0].num_qgv_points = qi.num_points;
+ for (i = 1; i < ARRAY_SIZE(i915->display.bw.max); i++)
+ memcpy(&i915->display.bw.max[i], &i915->display.bw.max[0],
+ sizeof(i915->display.bw.max[0]));
+
+ /*
+ * Xe2_HPD should always have exactly two QGV points representing
+ * battery and plugged-in operation.
+ */
+ drm_WARN_ON(&i915->drm, qi.num_points != 2);
+ i915->display.sagv.status = I915_SAGV_ENABLED;
+
+ return 0;
+}
+
static unsigned int icl_max_bw_index(struct drm_i915_private *dev_priv,
int num_planes, int qgv_point)
{
@@ -684,7 +743,9 @@ void intel_bw_init_hw(struct drm_i915_private *dev_priv)
if (!HAS_DISPLAY(dev_priv))
return;
- if (DISPLAY_VER(dev_priv) >= 14)
+ if (DISPLAY_VER_FULL(dev_priv) >= IP_VER(14, 1) && IS_DGFX(dev_priv))
+ xe2_hpd_get_bw_info(dev_priv, &xe2_hpd_sa_info);
+ else if (DISPLAY_VER(dev_priv) >= 14)
tgl_get_bw_info(dev_priv, &mtl_sa_info);
else if (IS_DG2(dev_priv))
dg2_get_bw_info(dev_priv);
diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
index 7a833b5f2de2..16d5550f7e5e 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -23,6 +23,7 @@
#include <linux/time.h>
+#include "soc/intel_dram.h"
#include "hsw_ips.h"
#include "i915_reg.h"
#include "intel_atomic.h"
@@ -113,7 +114,7 @@ struct intel_cdclk_funcs {
void (*set_cdclk)(struct drm_i915_private *i915,
const struct intel_cdclk_config *cdclk_config,
enum pipe pipe);
- int (*modeset_calc_cdclk)(struct intel_cdclk_state *state);
+ int (*modeset_calc_cdclk)(struct intel_atomic_state *state);
u8 (*calc_voltage_level)(int cdclk);
};
@@ -130,10 +131,11 @@ static void intel_cdclk_set_cdclk(struct drm_i915_private *dev_priv,
dev_priv->display.funcs.cdclk->set_cdclk(dev_priv, cdclk_config, pipe);
}
-static int intel_cdclk_modeset_calc_cdclk(struct drm_i915_private *dev_priv,
- struct intel_cdclk_state *cdclk_config)
+static int intel_cdclk_modeset_calc_cdclk(struct intel_atomic_state *state)
{
- return dev_priv->display.funcs.cdclk->modeset_calc_cdclk(cdclk_config);
+ struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+
+ return dev_priv->display.funcs.cdclk->modeset_calc_cdclk(state);
}
static u8 intel_cdclk_calc_voltage_level(struct drm_i915_private *dev_priv,
@@ -1443,6 +1445,14 @@ static const struct intel_cdclk_vals xe2lpd_cdclk_table[] = {
{}
};
+/*
+ * Xe2_HPD always uses the minimal cdclk table from Wa_15015413771
+ */
+static const struct intel_cdclk_vals xe2hpd_cdclk_table[] = {
+ { .refclk = 38400, .cdclk = 652800, .ratio = 34, .waveform = 0xffff },
+ {}
+};
+
static const int cdclk_squash_len = 16;
static int cdclk_squash_divider(u16 waveform)
@@ -2723,7 +2733,7 @@ static int intel_vdsc_min_cdclk(const struct intel_crtc_state *crtc_state)
min_cdclk = max_t(int, min_cdclk,
DIV_ROUND_UP(crtc_state->pixel_rate, num_vdsc_instances));
- if (crtc_state->bigjoiner_pipes) {
+ if (crtc_state->joiner_pipes) {
int pixel_clock = intel_dp_mode_to_fec_clock(crtc_state->hw.adjusted_mode.clock);
/*
@@ -2826,10 +2836,11 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
return min_cdclk;
}
-static int intel_compute_min_cdclk(struct intel_cdclk_state *cdclk_state)
+static int intel_compute_min_cdclk(struct intel_atomic_state *state)
{
- struct intel_atomic_state *state = cdclk_state->base.state;
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+ struct intel_cdclk_state *cdclk_state =
+ intel_atomic_get_new_cdclk_state(state);
const struct intel_bw_state *bw_state;
struct intel_crtc *crtc;
struct intel_crtc_state *crtc_state;
@@ -2908,10 +2919,11 @@ static int intel_compute_min_cdclk(struct intel_cdclk_state *cdclk_state)
* future platforms this code will need to be
* adjusted.
*/
-static int bxt_compute_min_voltage_level(struct intel_cdclk_state *cdclk_state)
+static int bxt_compute_min_voltage_level(struct intel_atomic_state *state)
{
- struct intel_atomic_state *state = cdclk_state->base.state;
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+ struct intel_cdclk_state *cdclk_state =
+ intel_atomic_get_new_cdclk_state(state);
struct intel_crtc *crtc;
struct intel_crtc_state *crtc_state;
u8 min_voltage_level;
@@ -2944,13 +2956,14 @@ static int bxt_compute_min_voltage_level(struct intel_cdclk_state *cdclk_state)
return min_voltage_level;
}
-static int vlv_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
+static int vlv_modeset_calc_cdclk(struct intel_atomic_state *state)
{
- struct intel_atomic_state *state = cdclk_state->base.state;
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+ struct intel_cdclk_state *cdclk_state =
+ intel_atomic_get_new_cdclk_state(state);
int min_cdclk, cdclk;
- min_cdclk = intel_compute_min_cdclk(cdclk_state);
+ min_cdclk = intel_compute_min_cdclk(state);
if (min_cdclk < 0)
return min_cdclk;
@@ -2973,11 +2986,13 @@ static int vlv_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
return 0;
}
-static int bdw_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
+static int bdw_modeset_calc_cdclk(struct intel_atomic_state *state)
{
+ struct intel_cdclk_state *cdclk_state =
+ intel_atomic_get_new_cdclk_state(state);
int min_cdclk, cdclk;
- min_cdclk = intel_compute_min_cdclk(cdclk_state);
+ min_cdclk = intel_compute_min_cdclk(state);
if (min_cdclk < 0)
return min_cdclk;
@@ -3000,10 +3015,11 @@ static int bdw_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
return 0;
}
-static int skl_dpll0_vco(struct intel_cdclk_state *cdclk_state)
+static int skl_dpll0_vco(struct intel_atomic_state *state)
{
- struct intel_atomic_state *state = cdclk_state->base.state;
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+ struct intel_cdclk_state *cdclk_state =
+ intel_atomic_get_new_cdclk_state(state);
struct intel_crtc *crtc;
struct intel_crtc_state *crtc_state;
int vco, i;
@@ -3037,15 +3053,17 @@ static int skl_dpll0_vco(struct intel_cdclk_state *cdclk_state)
return vco;
}
-static int skl_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
+static int skl_modeset_calc_cdclk(struct intel_atomic_state *state)
{
+ struct intel_cdclk_state *cdclk_state =
+ intel_atomic_get_new_cdclk_state(state);
int min_cdclk, cdclk, vco;
- min_cdclk = intel_compute_min_cdclk(cdclk_state);
+ min_cdclk = intel_compute_min_cdclk(state);
if (min_cdclk < 0)
return min_cdclk;
- vco = skl_dpll0_vco(cdclk_state);
+ vco = skl_dpll0_vco(state);
cdclk = skl_calc_cdclk(min_cdclk, vco);
@@ -3068,17 +3086,18 @@ static int skl_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
return 0;
}
-static int bxt_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
+static int bxt_modeset_calc_cdclk(struct intel_atomic_state *state)
{
- struct intel_atomic_state *state = cdclk_state->base.state;
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+ struct intel_cdclk_state *cdclk_state =
+ intel_atomic_get_new_cdclk_state(state);
int min_cdclk, min_voltage_level, cdclk, vco;
- min_cdclk = intel_compute_min_cdclk(cdclk_state);
+ min_cdclk = intel_compute_min_cdclk(state);
if (min_cdclk < 0)
return min_cdclk;
- min_voltage_level = bxt_compute_min_voltage_level(cdclk_state);
+ min_voltage_level = bxt_compute_min_voltage_level(state);
if (min_voltage_level < 0)
return min_voltage_level;
@@ -3106,7 +3125,7 @@ static int bxt_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
return 0;
}
-static int fixed_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
+static int fixed_modeset_calc_cdclk(struct intel_atomic_state *state)
{
int min_cdclk;
@@ -3115,7 +3134,7 @@ static int fixed_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
* check that the required minimum frequency doesn't exceed
* the actual cdclk frequency.
*/
- min_cdclk = intel_compute_min_cdclk(cdclk_state);
+ min_cdclk = intel_compute_min_cdclk(state);
if (min_cdclk < 0)
return min_cdclk;
@@ -3255,7 +3274,7 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
new_cdclk_state->active_pipes =
intel_calc_active_pipes(state, old_cdclk_state->active_pipes);
- ret = intel_cdclk_modeset_calc_cdclk(dev_priv, new_cdclk_state);
+ ret = intel_cdclk_modeset_calc_cdclk(state);
if (ret)
return ret;
@@ -3521,60 +3540,10 @@ static int vlv_hrawclk(struct drm_i915_private *dev_priv)
CCK_DISPLAY_REF_CLOCK_CONTROL);
}
-static int i9xx_hrawclk(struct drm_i915_private *dev_priv)
+static int i9xx_hrawclk(struct drm_i915_private *i915)
{
- u32 clkcfg;
-
- /*
- * hrawclock is 1/4 the FSB frequency
- *
- * Note that this only reads the state of the FSB
- * straps, not the actual FSB frequency. Some BIOSen
- * let you configure each independently. Ideally we'd
- * read out the actual FSB frequency but sadly we
- * don't know which registers have that information,
- * and all the relevant docs have gone to bit heaven :(
- */
- clkcfg = intel_de_read(dev_priv, CLKCFG) & CLKCFG_FSB_MASK;
-
- if (IS_MOBILE(dev_priv)) {
- switch (clkcfg) {
- case CLKCFG_FSB_400:
- return 100000;
- case CLKCFG_FSB_533:
- return 133333;
- case CLKCFG_FSB_667:
- return 166667;
- case CLKCFG_FSB_800:
- return 200000;
- case CLKCFG_FSB_1067:
- return 266667;
- case CLKCFG_FSB_1333:
- return 333333;
- default:
- MISSING_CASE(clkcfg);
- return 133333;
- }
- } else {
- switch (clkcfg) {
- case CLKCFG_FSB_400_ALT:
- return 100000;
- case CLKCFG_FSB_533:
- return 133333;
- case CLKCFG_FSB_667:
- return 166667;
- case CLKCFG_FSB_800:
- return 200000;
- case CLKCFG_FSB_1067_ALT:
- return 266667;
- case CLKCFG_FSB_1333_ALT:
- return 333333;
- case CLKCFG_FSB_1600_ALT:
- return 400000;
- default:
- return 133333;
- }
- }
+ /* hrawclock is 1/4 the FSB frequency */
+ return DIV_ROUND_CLOSEST(i9xx_fsb_freq(i915), 4);
}
/**
@@ -3778,6 +3747,9 @@ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)
if (DISPLAY_VER(dev_priv) >= 20) {
dev_priv->display.funcs.cdclk = &rplu_cdclk_funcs;
dev_priv->display.cdclk.table = xe2lpd_cdclk_table;
+ } else if (DISPLAY_VER_FULL(dev_priv) >= IP_VER(14, 1)) {
+ dev_priv->display.funcs.cdclk = &rplu_cdclk_funcs;
+ dev_priv->display.cdclk.table = xe2hpd_cdclk_table;
} else if (DISPLAY_VER(dev_priv) >= 14) {
dev_priv->display.funcs.cdclk = &rplu_cdclk_funcs;
dev_priv->display.cdclk.table = mtl_cdclk_table;
diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c
index d23163dc64d4..98553e8a5149 100644
--- a/drivers/gpu/drm/i915/display/intel_color.c
+++ b/drivers/gpu/drm/i915/display/intel_color.c
@@ -22,7 +22,7 @@
*
*/
-#include "i915_reg.h"
+#include "i9xx_plane_regs.h"
#include "intel_color.h"
#include "intel_color_regs.h"
#include "intel_de.h"
@@ -30,7 +30,8 @@
#include "intel_dsb.h"
struct intel_color_funcs {
- int (*color_check)(struct intel_crtc_state *crtc_state);
+ int (*color_check)(struct intel_atomic_state *state,
+ struct intel_crtc *crtc);
/*
* Program non-arming double buffered color management registers
* before vblank evasion. The registers should then latch after
@@ -1038,7 +1039,7 @@ static void i9xx_get_config(struct intel_crtc_state *crtc_state)
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
u32 tmp;
- tmp = intel_de_read(dev_priv, DSPCNTR(i9xx_plane));
+ tmp = intel_de_read(dev_priv, DSPCNTR(dev_priv, i9xx_plane));
if (tmp & DISP_PIPE_GAMMA_ENABLE)
crtc_state->gamma_enable = true;
@@ -1284,9 +1285,9 @@ static void i965_load_lut_10p6(struct intel_crtc *crtc,
i965_lut_10p6_udw(&lut[i]));
}
- intel_de_write_fw(dev_priv, PIPEGCMAX(pipe, 0), lut[i].red);
- intel_de_write_fw(dev_priv, PIPEGCMAX(pipe, 1), lut[i].green);
- intel_de_write_fw(dev_priv, PIPEGCMAX(pipe, 2), lut[i].blue);
+ intel_de_write_fw(dev_priv, PIPEGCMAX(dev_priv, pipe, 0), lut[i].red);
+ intel_de_write_fw(dev_priv, PIPEGCMAX(dev_priv, pipe, 1), lut[i].green);
+ intel_de_write_fw(dev_priv, PIPEGCMAX(dev_priv, pipe, 2), lut[i].blue);
}
static void i965_load_luts(const struct intel_crtc_state *crtc_state)
@@ -1913,7 +1914,7 @@ void intel_color_prepare_commit(struct intel_crtc_state *crtc_state)
if (!crtc_state->pre_csc_lut && !crtc_state->post_csc_lut)
return;
- crtc_state->dsb = intel_dsb_prepare(crtc_state, 1024);
+ crtc_state->dsb = intel_dsb_prepare(crtc_state, INTEL_DSB_0, 1024);
if (!crtc_state->dsb)
return;
@@ -1942,11 +1943,9 @@ bool intel_color_uses_dsb(const struct intel_crtc_state *crtc_state)
return crtc_state->dsb;
}
-static bool intel_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
+static bool intel_can_preload_luts(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
- struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
- struct intel_atomic_state *state =
- to_intel_atomic_state(new_crtc_state->uapi.state);
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
@@ -1954,11 +1953,9 @@ static bool intel_can_preload_luts(const struct intel_crtc_state *new_crtc_state
!old_crtc_state->pre_csc_lut;
}
-static bool vlv_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
+static bool vlv_can_preload_luts(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
- struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
- struct intel_atomic_state *state =
- to_intel_atomic_state(new_crtc_state->uapi.state);
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
@@ -1966,13 +1963,13 @@ static bool vlv_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
!old_crtc_state->post_csc_lut;
}
-static bool chv_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
+static bool chv_can_preload_luts(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
- struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
- struct intel_atomic_state *state =
- to_intel_atomic_state(new_crtc_state->uapi.state);
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
+ const struct intel_crtc_state *new_crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
/*
* CGM_PIPE_MODE is itself single buffered. We'd have to
@@ -1982,14 +1979,29 @@ static bool chv_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
if (old_crtc_state->cgm_mode || new_crtc_state->cgm_mode)
return false;
- return vlv_can_preload_luts(new_crtc_state);
+ return vlv_can_preload_luts(state, crtc);
}
-int intel_color_check(struct intel_crtc_state *crtc_state)
+int intel_color_check(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
- struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
+ const struct intel_crtc_state *old_crtc_state =
+ intel_atomic_get_old_crtc_state(state, crtc);
+ struct intel_crtc_state *new_crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
- return i915->display.funcs.color->color_check(crtc_state);
+ /*
+ * May need to update pipe gamma enable bits
+ * when C8 planes are getting enabled/disabled.
+ */
+ if (!old_crtc_state->c8_planes != !new_crtc_state->c8_planes)
+ new_crtc_state->uapi.color_mgmt_changed = true;
+
+ if (!intel_crtc_needs_color_update(new_crtc_state))
+ return 0;
+
+ return i915->display.funcs.color->color_check(state, crtc);
}
void intel_color_get_config(struct intel_crtc_state *crtc_state)
@@ -2039,14 +2051,14 @@ static bool need_plane_update(struct intel_plane *plane,
}
static int
-intel_color_add_affected_planes(struct intel_crtc_state *new_crtc_state)
+intel_color_add_affected_planes(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
- struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
- struct drm_i915_private *i915 = to_i915(crtc->base.dev);
- struct intel_atomic_state *state =
- to_intel_atomic_state(new_crtc_state->uapi.state);
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
+ struct intel_crtc_state *new_crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
struct intel_plane *plane;
if (!new_crtc_state->hw.active ||
@@ -2240,9 +2252,12 @@ static void intel_assign_luts(struct intel_crtc_state *crtc_state)
crtc_state->hw.gamma_lut);
}
-static int i9xx_color_check(struct intel_crtc_state *crtc_state)
+static int i9xx_color_check(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
- struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
+ struct intel_crtc_state *crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
int ret;
ret = check_luts(crtc_state);
@@ -2262,13 +2277,13 @@ static int i9xx_color_check(struct intel_crtc_state *crtc_state)
return ret;
}
- ret = intel_color_add_affected_planes(crtc_state);
+ ret = intel_color_add_affected_planes(state, crtc);
if (ret)
return ret;
intel_assign_luts(crtc_state);
- crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
+ crtc_state->preload_luts = intel_can_preload_luts(state, crtc);
return 0;
}
@@ -2277,8 +2292,11 @@ static int i9xx_color_check(struct intel_crtc_state *crtc_state)
* VLV color pipeline:
* u0.10 -> WGC csc -> u0.10 -> pipe gamma -> u0.10
*/
-static int vlv_color_check(struct intel_crtc_state *crtc_state)
+static int vlv_color_check(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
+ struct intel_crtc_state *crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
int ret;
ret = check_luts(crtc_state);
@@ -2293,7 +2311,7 @@ static int vlv_color_check(struct intel_crtc_state *crtc_state)
crtc_state->wgc_enable = crtc_state->hw.ctm;
- ret = intel_color_add_affected_planes(crtc_state);
+ ret = intel_color_add_affected_planes(state, crtc);
if (ret)
return ret;
@@ -2301,7 +2319,7 @@ static int vlv_color_check(struct intel_crtc_state *crtc_state)
vlv_assign_csc(crtc_state);
- crtc_state->preload_luts = vlv_can_preload_luts(crtc_state);
+ crtc_state->preload_luts = vlv_can_preload_luts(state, crtc);
return 0;
}
@@ -2336,8 +2354,11 @@ static u32 chv_cgm_mode(const struct intel_crtc_state *crtc_state)
* We always bypass the WGC csc and use the CGM csc
* instead since it has degamma and better precision.
*/
-static int chv_color_check(struct intel_crtc_state *crtc_state)
+static int chv_color_check(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
+ struct intel_crtc_state *crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
int ret;
ret = check_luts(crtc_state);
@@ -2362,7 +2383,7 @@ static int chv_color_check(struct intel_crtc_state *crtc_state)
*/
crtc_state->wgc_enable = false;
- ret = intel_color_add_affected_planes(crtc_state);
+ ret = intel_color_add_affected_planes(state, crtc);
if (ret)
return ret;
@@ -2370,7 +2391,7 @@ static int chv_color_check(struct intel_crtc_state *crtc_state)
chv_assign_csc(crtc_state);
- crtc_state->preload_luts = chv_can_preload_luts(crtc_state);
+ crtc_state->preload_luts = chv_can_preload_luts(state, crtc);
return 0;
}
@@ -2454,9 +2475,12 @@ static int ilk_assign_luts(struct intel_crtc_state *crtc_state)
return 0;
}
-static int ilk_color_check(struct intel_crtc_state *crtc_state)
+static int ilk_color_check(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
- struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
+ struct intel_crtc_state *crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
int ret;
ret = check_luts(crtc_state);
@@ -2484,7 +2508,7 @@ static int ilk_color_check(struct intel_crtc_state *crtc_state)
crtc_state->csc_mode = ilk_csc_mode(crtc_state);
- ret = intel_color_add_affected_planes(crtc_state);
+ ret = intel_color_add_affected_planes(state, crtc);
if (ret)
return ret;
@@ -2494,7 +2518,7 @@ static int ilk_color_check(struct intel_crtc_state *crtc_state)
ilk_assign_csc(crtc_state);
- crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
+ crtc_state->preload_luts = intel_can_preload_luts(state, crtc);
return 0;
}
@@ -2555,9 +2579,12 @@ static int ivb_assign_luts(struct intel_crtc_state *crtc_state)
return 0;
}
-static int ivb_color_check(struct intel_crtc_state *crtc_state)
+static int ivb_color_check(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
- struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
+ struct intel_crtc_state *crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
int ret;
ret = check_luts(crtc_state);
@@ -2592,7 +2619,7 @@ static int ivb_color_check(struct intel_crtc_state *crtc_state)
crtc_state->csc_mode = ivb_csc_mode(crtc_state);
- ret = intel_color_add_affected_planes(crtc_state);
+ ret = intel_color_add_affected_planes(state, crtc);
if (ret)
return ret;
@@ -2602,7 +2629,7 @@ static int ivb_color_check(struct intel_crtc_state *crtc_state)
ilk_assign_csc(crtc_state);
- crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
+ crtc_state->preload_luts = intel_can_preload_luts(state, crtc);
return 0;
}
@@ -2686,9 +2713,12 @@ static int glk_check_luts(const struct intel_crtc_state *crtc_state)
return _check_luts(crtc_state, degamma_tests, gamma_tests);
}
-static int glk_color_check(struct intel_crtc_state *crtc_state)
+static int glk_color_check(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
- struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
+ struct intel_crtc_state *crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
int ret;
ret = glk_check_luts(crtc_state);
@@ -2725,7 +2755,7 @@ static int glk_color_check(struct intel_crtc_state *crtc_state)
crtc_state->csc_mode = 0;
- ret = intel_color_add_affected_planes(crtc_state);
+ ret = intel_color_add_affected_planes(state, crtc);
if (ret)
return ret;
@@ -2735,7 +2765,7 @@ static int glk_color_check(struct intel_crtc_state *crtc_state)
ilk_assign_csc(crtc_state);
- crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
+ crtc_state->preload_luts = intel_can_preload_luts(state, crtc);
return 0;
}
@@ -2783,8 +2813,11 @@ static u32 icl_csc_mode(const struct intel_crtc_state *crtc_state)
return csc_mode;
}
-static int icl_color_check(struct intel_crtc_state *crtc_state)
+static int icl_color_check(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
+ struct intel_crtc_state *crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
int ret;
ret = check_luts(crtc_state);
@@ -2799,7 +2832,7 @@ static int icl_color_check(struct intel_crtc_state *crtc_state)
icl_assign_csc(crtc_state);
- crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
+ crtc_state->preload_luts = intel_can_preload_luts(state, crtc);
return 0;
}
@@ -3239,9 +3272,9 @@ static struct drm_property_blob *i965_read_lut_10p6(struct intel_crtc *crtc)
i965_lut_10p6_pack(&lut[i], ldw, udw);
}
- lut[i].red = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(pipe, 0)));
- lut[i].green = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(pipe, 1)));
- lut[i].blue = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(pipe, 2)));
+ lut[i].red = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(dev_priv, pipe, 0)));
+ lut[i].green = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(dev_priv, pipe, 1)));
+ lut[i].blue = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(dev_priv, pipe, 2)));
return blob;
}
diff --git a/drivers/gpu/drm/i915/display/intel_color.h b/drivers/gpu/drm/i915/display/intel_color.h
index 8ecd36149def..21ba4aa02e7b 100644
--- a/drivers/gpu/drm/i915/display/intel_color.h
+++ b/drivers/gpu/drm/i915/display/intel_color.h
@@ -8,6 +8,7 @@
#include <linux/types.h>
+struct intel_atomic_state;
struct intel_crtc_state;
struct intel_crtc;
struct drm_i915_private;
@@ -16,7 +17,8 @@ struct drm_property_blob;
void intel_color_init_hooks(struct drm_i915_private *i915);
int intel_color_init(struct drm_i915_private *i915);
void intel_color_crtc_init(struct intel_crtc *crtc);
-int intel_color_check(struct intel_crtc_state *crtc_state);
+int intel_color_check(struct intel_atomic_state *state,
+ struct intel_crtc *crtc);
void intel_color_prepare_commit(struct intel_crtc_state *crtc_state);
void intel_color_cleanup_commit(struct intel_crtc_state *crtc_state);
bool intel_color_uses_dsb(const struct intel_crtc_state *crtc_state);
diff --git a/drivers/gpu/drm/i915/display/intel_color_regs.h b/drivers/gpu/drm/i915/display/intel_color_regs.h
index bb99ea533842..8eb643cfead7 100644
--- a/drivers/gpu/drm/i915/display/intel_color_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_color_regs.h
@@ -36,6 +36,11 @@
_CHV_PALETTE_C, _CHV_PALETTE_C) + \
(i) * 4)
+/* i965/g4x/vlv/chv */
+#define _PIPEAGCMAX 0x70010
+#define _PIPEBGCMAX 0x71010
+#define PIPEGCMAX(dev_priv, pipe, i) _MMIO_PIPE2(dev_priv, pipe, _PIPEAGCMAX + (i) * 4) /* u1.16 */
+
/* ilk+ palette */
#define _LGC_PALETTE_A 0x4a000
#define _LGC_PALETTE_B 0x4a800
diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c
index 10e95dc425a6..835c8b844494 100644
--- a/drivers/gpu/drm/i915/display/intel_crt.c
+++ b/drivers/gpu/drm/i915/display/intel_crt.c
@@ -193,7 +193,7 @@ static void intel_crt_set_dpms(struct intel_encoder *encoder,
adpa |= ADPA_PIPE_SEL(crtc->pipe);
if (!HAS_PCH_SPLIT(dev_priv))
- intel_de_write(dev_priv, BCLRPAT(crtc->pipe), 0);
+ intel_de_write(dev_priv, BCLRPAT(dev_priv, crtc->pipe), 0);
switch (mode) {
case DRM_MODE_DPMS_ON:
@@ -603,18 +603,19 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
CRT_HOTPLUG_FORCE_DETECT,
CRT_HOTPLUG_FORCE_DETECT);
/* wait for FORCE_DETECT to go off */
- if (intel_de_wait_for_clear(dev_priv, PORT_HOTPLUG_EN,
+ if (intel_de_wait_for_clear(dev_priv, PORT_HOTPLUG_EN(dev_priv),
CRT_HOTPLUG_FORCE_DETECT, 1000))
drm_dbg_kms(&dev_priv->drm,
"timed out waiting for FORCE_DETECT to go off");
}
- stat = intel_de_read(dev_priv, PORT_HOTPLUG_STAT);
+ stat = intel_de_read(dev_priv, PORT_HOTPLUG_STAT(dev_priv));
if ((stat & CRT_HOTPLUG_MONITOR_MASK) != CRT_HOTPLUG_MONITOR_NONE)
ret = true;
/* clear the interrupt we just generated, if any */
- intel_de_write(dev_priv, PORT_HOTPLUG_STAT, CRT_HOTPLUG_INT_STATUS);
+ intel_de_write(dev_priv, PORT_HOTPLUG_STAT(dev_priv),
+ CRT_HOTPLUG_INT_STATUS);
i915_hotplug_interrupt_update(dev_priv, CRT_HOTPLUG_FORCE_DETECT, 0);
@@ -707,9 +708,12 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
drm_dbg_kms(&dev_priv->drm, "starting load-detect on CRT\n");
- save_bclrpat = intel_de_read(dev_priv, BCLRPAT(cpu_transcoder));
- save_vtotal = intel_de_read(dev_priv, TRANS_VTOTAL(cpu_transcoder));
- vblank = intel_de_read(dev_priv, TRANS_VBLANK(cpu_transcoder));
+ save_bclrpat = intel_de_read(dev_priv,
+ BCLRPAT(dev_priv, cpu_transcoder));
+ save_vtotal = intel_de_read(dev_priv,
+ TRANS_VTOTAL(dev_priv, cpu_transcoder));
+ vblank = intel_de_read(dev_priv,
+ TRANS_VBLANK(dev_priv, cpu_transcoder));
vtotal = REG_FIELD_GET(VTOTAL_MASK, save_vtotal) + 1;
vactive = REG_FIELD_GET(VACTIVE_MASK, save_vtotal) + 1;
@@ -718,14 +722,16 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
vblank_end = REG_FIELD_GET(VBLANK_END_MASK, vblank) + 1;
/* Set the border color to purple. */
- intel_de_write(dev_priv, BCLRPAT(cpu_transcoder), 0x500050);
+ intel_de_write(dev_priv, BCLRPAT(dev_priv, cpu_transcoder), 0x500050);
if (DISPLAY_VER(dev_priv) != 2) {
- u32 transconf = intel_de_read(dev_priv, TRANSCONF(cpu_transcoder));
+ u32 transconf = intel_de_read(dev_priv,
+ TRANSCONF(dev_priv, cpu_transcoder));
- intel_de_write(dev_priv, TRANSCONF(cpu_transcoder),
+ intel_de_write(dev_priv, TRANSCONF(dev_priv, cpu_transcoder),
transconf | TRANSCONF_FORCE_BORDER);
- intel_de_posting_read(dev_priv, TRANSCONF(cpu_transcoder));
+ intel_de_posting_read(dev_priv,
+ TRANSCONF(dev_priv, cpu_transcoder));
/* Wait for next Vblank to substitue
* border color for Color info */
intel_crtc_wait_for_next_vblank(intel_crtc_for_pipe(dev_priv, pipe));
@@ -734,7 +740,8 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
connector_status_connected :
connector_status_disconnected;
- intel_de_write(dev_priv, TRANSCONF(cpu_transcoder), transconf);
+ intel_de_write(dev_priv, TRANSCONF(dev_priv, cpu_transcoder),
+ transconf);
} else {
bool restore_vblank = false;
int count, detect;
@@ -744,11 +751,13 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
* Yes, this will flicker
*/
if (vblank_start <= vactive && vblank_end >= vtotal) {
- u32 vsync = intel_de_read(dev_priv, TRANS_VSYNC(cpu_transcoder));
+ u32 vsync = intel_de_read(dev_priv,
+ TRANS_VSYNC(dev_priv, cpu_transcoder));
u32 vsync_start = REG_FIELD_GET(VSYNC_START_MASK, vsync) + 1;
vblank_start = vsync_start;
- intel_de_write(dev_priv, TRANS_VBLANK(cpu_transcoder),
+ intel_de_write(dev_priv,
+ TRANS_VBLANK(dev_priv, cpu_transcoder),
VBLANK_START(vblank_start - 1) |
VBLANK_END(vblank_end - 1));
restore_vblank = true;
@@ -762,9 +771,9 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
/*
* Wait for the border to be displayed
*/
- while (intel_de_read(dev_priv, PIPEDSL(pipe)) >= vactive)
+ while (intel_de_read(dev_priv, PIPEDSL(dev_priv, pipe)) >= vactive)
;
- while ((dsl = intel_de_read(dev_priv, PIPEDSL(pipe))) <= vsample)
+ while ((dsl = intel_de_read(dev_priv, PIPEDSL(dev_priv, pipe))) <= vsample)
;
/*
* Watch ST00 for an entire scanline
@@ -777,11 +786,13 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
st00 = intel_de_read8(dev_priv, _VGA_MSR_WRITE);
if (st00 & (1 << 4))
detect++;
- } while ((intel_de_read(dev_priv, PIPEDSL(pipe)) == dsl));
+ } while ((intel_de_read(dev_priv, PIPEDSL(dev_priv, pipe)) == dsl));
/* restore vblank if necessary */
if (restore_vblank)
- intel_de_write(dev_priv, TRANS_VBLANK(cpu_transcoder), vblank);
+ intel_de_write(dev_priv,
+ TRANS_VBLANK(dev_priv, cpu_transcoder),
+ vblank);
/*
* If more than 3/4 of the scanline detected a monitor,
* then it is assumed to be present. This works even on i830,
@@ -794,7 +805,8 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
}
/* Restore previous settings */
- intel_de_write(dev_priv, BCLRPAT(cpu_transcoder), save_bclrpat);
+ intel_de_write(dev_priv, BCLRPAT(dev_priv, cpu_transcoder),
+ save_bclrpat);
return status;
}
diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c
index 25593f6aae7d..54b529bfc935 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc.c
+++ b/drivers/gpu/drm/i915/display/intel_crtc.c
@@ -78,8 +78,7 @@ void intel_wait_for_vblank_if_active(struct drm_i915_private *i915,
u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc)
{
- struct drm_device *dev = crtc->base.dev;
- struct drm_vblank_crtc *vblank = &dev->vblank[drm_crtc_index(&crtc->base)];
+ struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(&crtc->base);
if (!crtc->active)
return 0;
@@ -311,8 +310,7 @@ int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
crtc->num_scalers = DISPLAY_RUNTIME_INFO(dev_priv)->num_scalers[pipe];
if (DISPLAY_VER(dev_priv) >= 9)
- primary = skl_universal_plane_create(dev_priv, pipe,
- PLANE_PRIMARY);
+ primary = skl_universal_plane_create(dev_priv, pipe, PLANE_1);
else
primary = intel_primary_plane_create(dev_priv, pipe);
if (IS_ERR(primary)) {
@@ -327,8 +325,7 @@ int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
struct intel_plane *plane;
if (DISPLAY_VER(dev_priv) >= 9)
- plane = skl_universal_plane_create(dev_priv, pipe,
- PLANE_SPRITE0 + sprite);
+ plane = skl_universal_plane_create(dev_priv, pipe, PLANE_2 + sprite);
else
plane = intel_sprite_plane_create(dev_priv, pipe, sprite);
if (IS_ERR(plane)) {
@@ -414,8 +411,8 @@ static void intel_crtc_vblank_work(struct kthread_work *base)
if (crtc_state->uapi.event) {
spin_lock_irq(&crtc->base.dev->event_lock);
drm_crtc_send_vblank_event(&crtc->base, crtc_state->uapi.event);
- crtc_state->uapi.event = NULL;
spin_unlock_irq(&crtc->base.dev->event_lock);
+ crtc_state->uapi.event = NULL;
}
trace_intel_crtc_vblank_work_end(crtc);
@@ -457,8 +454,8 @@ int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
if (!adjusted_mode->crtc_htotal)
return 1;
- return DIV_ROUND_UP(usecs * adjusted_mode->crtc_clock,
- 1000 * adjusted_mode->crtc_htotal);
+ return DIV_ROUND_UP_ULL(mul_u32_u32(usecs, adjusted_mode->crtc_clock),
+ 1000 * adjusted_mode->crtc_htotal);
}
/**
diff --git a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c
index ccaa4cb2809b..6df526e189b5 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c
+++ b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c
@@ -222,10 +222,10 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config,
transcoder_name(pipe_config->master_transcoder),
pipe_config->sync_mode_slaves_mask);
- drm_printf(&p, "bigjoiner: %s, pipes: 0x%x\n",
- intel_crtc_is_bigjoiner_slave(pipe_config) ? "slave" :
- intel_crtc_is_bigjoiner_master(pipe_config) ? "master" : "no",
- pipe_config->bigjoiner_pipes);
+ drm_printf(&p, "joiner: %s, pipes: 0x%x\n",
+ intel_crtc_is_joiner_secondary(pipe_config) ? "secondary" :
+ intel_crtc_is_joiner_primary(pipe_config) ? "primary" : "no",
+ pipe_config->joiner_pipes);
drm_printf(&p, "splitter: %s, link count %d, overlap %d\n",
str_enabled_disabled(pipe_config->splitter.enable),
@@ -251,9 +251,10 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config,
drm_printf(&p, "sdp split: %s\n",
str_enabled_disabled(pipe_config->sdp_split_enable));
- drm_printf(&p, "psr: %s, psr2: %s, panel replay: %s, selective fetch: %s\n",
- str_enabled_disabled(pipe_config->has_psr),
- str_enabled_disabled(pipe_config->has_psr2),
+ drm_printf(&p, "psr: %s, selective update: %s, panel replay: %s, selective fetch: %s\n",
+ str_enabled_disabled(pipe_config->has_psr &&
+ !pipe_config->has_panel_replay),
+ str_enabled_disabled(pipe_config->has_sel_update),
str_enabled_disabled(pipe_config->has_panel_replay),
str_enabled_disabled(pipe_config->enable_psr2_sel_fetch));
}
diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c
index 23a122ee20c9..66436e526021 100644
--- a/drivers/gpu/drm/i915/display/intel_cursor.c
+++ b/drivers/gpu/drm/i915/display/intel_cursor.c
@@ -14,6 +14,7 @@
#include "intel_atomic.h"
#include "intel_atomic_plane.h"
#include "intel_cursor.h"
+#include "intel_cursor_regs.h"
#include "intel_de.h"
#include "intel_display.h"
#include "intel_display_types.h"
@@ -293,17 +294,17 @@ static void i845_cursor_update_arm(struct intel_plane *plane,
if (plane->cursor.base != base ||
plane->cursor.size != size ||
plane->cursor.cntl != cntl) {
- intel_de_write_fw(dev_priv, CURCNTR(PIPE_A), 0);
- intel_de_write_fw(dev_priv, CURBASE(PIPE_A), base);
- intel_de_write_fw(dev_priv, CURSIZE(PIPE_A), size);
- intel_de_write_fw(dev_priv, CURPOS(PIPE_A), pos);
- intel_de_write_fw(dev_priv, CURCNTR(PIPE_A), cntl);
+ intel_de_write_fw(dev_priv, CURCNTR(dev_priv, PIPE_A), 0);
+ intel_de_write_fw(dev_priv, CURBASE(dev_priv, PIPE_A), base);
+ intel_de_write_fw(dev_priv, CURSIZE(dev_priv, PIPE_A), size);
+ intel_de_write_fw(dev_priv, CURPOS(dev_priv, PIPE_A), pos);
+ intel_de_write_fw(dev_priv, CURCNTR(dev_priv, PIPE_A), cntl);
plane->cursor.base = base;
plane->cursor.size = size;
plane->cursor.cntl = cntl;
} else {
- intel_de_write_fw(dev_priv, CURPOS(PIPE_A), pos);
+ intel_de_write_fw(dev_priv, CURPOS(dev_priv, PIPE_A), pos);
}
}
@@ -326,7 +327,7 @@ static bool i845_cursor_get_hw_state(struct intel_plane *plane,
if (!wakeref)
return false;
- ret = intel_de_read(dev_priv, CURCNTR(PIPE_A)) & CURSOR_ENABLE;
+ ret = intel_de_read(dev_priv, CURCNTR(dev_priv, PIPE_A)) & CURSOR_ENABLE;
*pipe = PIPE_A;
@@ -506,7 +507,7 @@ static void i9xx_cursor_disable_sel_fetch_arm(struct intel_plane *plane,
if (!crtc_state->enable_psr2_sel_fetch)
return;
- intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_CTL(pipe, plane->id), 0);
+ intel_de_write_fw(dev_priv, SEL_FETCH_CUR_CTL(pipe), 0);
}
static void wa_16021440873(struct intel_plane *plane,
@@ -521,10 +522,10 @@ static void wa_16021440873(struct intel_plane *plane,
ctl &= ~MCURSOR_MODE_MASK;
ctl |= MCURSOR_MODE_64_2B;
- intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_CTL(pipe, plane->id), ctl);
+ intel_de_write_fw(dev_priv, SEL_FETCH_CUR_CTL(pipe), ctl);
- intel_de_write(dev_priv, PIPE_SRCSZ_ERLY_TPT(pipe),
- PIPESRC_HEIGHT(et_y_position));
+ intel_de_write(dev_priv, CURPOS_ERLY_TPT(dev_priv, pipe),
+ CURSOR_POS_Y(et_y_position));
}
static void i9xx_cursor_update_sel_fetch_arm(struct intel_plane *plane,
@@ -541,10 +542,12 @@ static void i9xx_cursor_update_sel_fetch_arm(struct intel_plane *plane,
if (crtc_state->enable_psr2_su_region_et) {
u32 val = intel_cursor_position(crtc_state, plane_state,
true);
- intel_de_write_fw(dev_priv, CURPOS_ERLY_TPT(pipe), val);
+ intel_de_write_fw(dev_priv,
+ CURPOS_ERLY_TPT(dev_priv, pipe),
+ val);
}
- intel_de_write_fw(dev_priv, PLANE_SEL_FETCH_CTL(pipe, plane->id),
+ intel_de_write_fw(dev_priv, SEL_FETCH_CUR_CTL(pipe),
plane_state->ctl);
} else {
/* Wa_16021440873 */
@@ -555,6 +558,60 @@ static void i9xx_cursor_update_sel_fetch_arm(struct intel_plane *plane,
}
}
+static u32 skl_cursor_ddb_reg_val(const struct skl_ddb_entry *entry)
+{
+ if (!entry->end)
+ return 0;
+
+ return CUR_BUF_END(entry->end - 1) |
+ CUR_BUF_START(entry->start);
+}
+
+static u32 skl_cursor_wm_reg_val(const struct skl_wm_level *level)
+{
+ u32 val = 0;
+
+ if (level->enable)
+ val |= CUR_WM_EN;
+ if (level->ignore_lines)
+ val |= CUR_WM_IGNORE_LINES;
+ val |= REG_FIELD_PREP(CUR_WM_BLOCKS_MASK, level->blocks);
+ val |= REG_FIELD_PREP(CUR_WM_LINES_MASK, level->lines);
+
+ return val;
+}
+
+static void skl_write_cursor_wm(struct intel_plane *plane,
+ const struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *i915 = to_i915(plane->base.dev);
+ enum plane_id plane_id = plane->id;
+ enum pipe pipe = plane->pipe;
+ const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
+ const struct skl_ddb_entry *ddb =
+ &crtc_state->wm.skl.plane_ddb[plane_id];
+ int level;
+
+ for (level = 0; level < i915->display.wm.num_levels; level++)
+ intel_de_write_fw(i915, CUR_WM(pipe, level),
+ skl_cursor_wm_reg_val(skl_plane_wm_level(pipe_wm, plane_id, level)));
+
+ intel_de_write_fw(i915, CUR_WM_TRANS(pipe),
+ skl_cursor_wm_reg_val(skl_plane_trans_wm(pipe_wm, plane_id)));
+
+ if (HAS_HW_SAGV_WM(i915)) {
+ const struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
+
+ intel_de_write_fw(i915, CUR_WM_SAGV(pipe),
+ skl_cursor_wm_reg_val(&wm->sagv.wm0));
+ intel_de_write_fw(i915, CUR_WM_SAGV_TRANS(pipe),
+ skl_cursor_wm_reg_val(&wm->sagv.trans_wm));
+ }
+
+ intel_de_write_fw(i915, CUR_BUF_CFG(pipe),
+ skl_cursor_ddb_reg_val(ddb));
+}
+
/* TODO: split into noarm+arm pair */
static void i9xx_cursor_update_arm(struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
@@ -611,18 +668,19 @@ static void i9xx_cursor_update_arm(struct intel_plane *plane,
plane->cursor.size != fbc_ctl ||
plane->cursor.cntl != cntl) {
if (HAS_CUR_FBC(dev_priv))
- intel_de_write_fw(dev_priv, CUR_FBC_CTL(pipe),
+ intel_de_write_fw(dev_priv,
+ CUR_FBC_CTL(dev_priv, pipe),
fbc_ctl);
- intel_de_write_fw(dev_priv, CURCNTR(pipe), cntl);
- intel_de_write_fw(dev_priv, CURPOS(pipe), pos);
- intel_de_write_fw(dev_priv, CURBASE(pipe), base);
+ intel_de_write_fw(dev_priv, CURCNTR(dev_priv, pipe), cntl);
+ intel_de_write_fw(dev_priv, CURPOS(dev_priv, pipe), pos);
+ intel_de_write_fw(dev_priv, CURBASE(dev_priv, pipe), base);
plane->cursor.base = base;
plane->cursor.size = fbc_ctl;
plane->cursor.cntl = cntl;
} else {
- intel_de_write_fw(dev_priv, CURPOS(pipe), pos);
- intel_de_write_fw(dev_priv, CURBASE(pipe), base);
+ intel_de_write_fw(dev_priv, CURPOS(dev_priv, pipe), pos);
+ intel_de_write_fw(dev_priv, CURBASE(dev_priv, pipe), base);
}
}
@@ -651,7 +709,7 @@ static bool i9xx_cursor_get_hw_state(struct intel_plane *plane,
if (!wakeref)
return false;
- val = intel_de_read(dev_priv, CURCNTR(plane->pipe));
+ val = intel_de_read(dev_priv, CURCNTR(dev_priv, plane->pipe));
ret = val & MCURSOR_MODE_MASK;
@@ -703,12 +761,12 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
* PSR2 plane and transcoder registers can only be updated during
* vblank.
*
- * FIXME bigjoiner fastpath would be good
+ * FIXME joiner fastpath would be good
*/
if (!crtc_state->hw.active ||
intel_crtc_needs_modeset(crtc_state) ||
intel_crtc_needs_fastset(crtc_state) ||
- crtc_state->bigjoiner_pipes)
+ crtc_state->joiner_pipes)
goto slow;
/*
diff --git a/drivers/gpu/drm/i915/display/intel_cursor_regs.h b/drivers/gpu/drm/i915/display/intel_cursor_regs.h
new file mode 100644
index 000000000000..aaa66331063e
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_cursor_regs.h
@@ -0,0 +1,112 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef __INTEL_CURSOR_REGS_H__
+#define __INTEL_CURSOR_REGS_H__
+
+#include "intel_display_reg_defs.h"
+
+#define _CURACNTR 0x70080
+#define CURCNTR(dev_priv, pipe) _MMIO_CURSOR2((dev_priv), (pipe), _CURACNTR)
+/* Old style CUR*CNTR flags (desktop 8xx) */
+#define CURSOR_ENABLE REG_BIT(31)
+#define CURSOR_PIPE_GAMMA_ENABLE REG_BIT(30)
+#define CURSOR_STRIDE_MASK REG_GENMASK(29, 28)
+#define CURSOR_STRIDE(stride) REG_FIELD_PREP(CURSOR_STRIDE_MASK, ffs(stride) - 9) /* 256,512,1k,2k */
+#define CURSOR_FORMAT_MASK REG_GENMASK(26, 24)
+#define CURSOR_FORMAT_2C REG_FIELD_PREP(CURSOR_FORMAT_MASK, 0)
+#define CURSOR_FORMAT_3C REG_FIELD_PREP(CURSOR_FORMAT_MASK, 1)
+#define CURSOR_FORMAT_4C REG_FIELD_PREP(CURSOR_FORMAT_MASK, 2)
+#define CURSOR_FORMAT_ARGB REG_FIELD_PREP(CURSOR_FORMAT_MASK, 4)
+#define CURSOR_FORMAT_XRGB REG_FIELD_PREP(CURSOR_FORMAT_MASK, 5)
+/* New style CUR*CNTR flags */
+#define MCURSOR_ARB_SLOTS_MASK REG_GENMASK(30, 28) /* icl+ */
+#define MCURSOR_ARB_SLOTS(x) REG_FIELD_PREP(MCURSOR_ARB_SLOTS_MASK, (x)) /* icl+ */
+#define MCURSOR_PIPE_SEL_MASK REG_GENMASK(29, 28)
+#define MCURSOR_PIPE_SEL(pipe) REG_FIELD_PREP(MCURSOR_PIPE_SEL_MASK, (pipe))
+#define MCURSOR_PIPE_GAMMA_ENABLE REG_BIT(26)
+#define MCURSOR_PIPE_CSC_ENABLE REG_BIT(24) /* ilk+ */
+#define MCURSOR_ROTATE_180 REG_BIT(15)
+#define MCURSOR_TRICKLE_FEED_DISABLE REG_BIT(14)
+#define MCURSOR_MODE_MASK 0x27
+#define MCURSOR_MODE_DISABLE 0x00
+#define MCURSOR_MODE_128_32B_AX 0x02
+#define MCURSOR_MODE_256_32B_AX 0x03
+#define MCURSOR_MODE_64_2B 0x04
+#define MCURSOR_MODE_64_32B_AX 0x07
+#define MCURSOR_MODE_128_ARGB_AX (0x20 | MCURSOR_MODE_128_32B_AX)
+#define MCURSOR_MODE_256_ARGB_AX (0x20 | MCURSOR_MODE_256_32B_AX)
+#define MCURSOR_MODE_64_ARGB_AX (0x20 | MCURSOR_MODE_64_32B_AX)
+
+#define _CURABASE 0x70084
+#define CURBASE(dev_priv, pipe) _MMIO_CURSOR2((dev_priv), (pipe), _CURABASE)
+
+#define _CURAPOS 0x70088
+#define CURPOS(dev_priv, pipe) _MMIO_CURSOR2((dev_priv), (pipe), _CURAPOS)
+#define CURSOR_POS_Y_SIGN REG_BIT(31)
+#define CURSOR_POS_Y_MASK REG_GENMASK(30, 16)
+#define CURSOR_POS_Y(y) REG_FIELD_PREP(CURSOR_POS_Y_MASK, (y))
+#define CURSOR_POS_X_SIGN REG_BIT(15)
+#define CURSOR_POS_X_MASK REG_GENMASK(14, 0)
+#define CURSOR_POS_X(x) REG_FIELD_PREP(CURSOR_POS_X_MASK, (x))
+
+#define _CURAPOS_ERLY_TPT 0x7008c
+#define CURPOS_ERLY_TPT(dev_priv, pipe) _MMIO_CURSOR2((dev_priv), (pipe), _CURAPOS_ERLY_TPT)
+
+#define _CURASIZE 0x700a0 /* 845/865 */
+#define CURSIZE(dev_priv, pipe) _MMIO_CURSOR2((dev_priv), (pipe), _CURASIZE)
+#define CURSOR_HEIGHT_MASK REG_GENMASK(21, 12)
+#define CURSOR_HEIGHT(h) REG_FIELD_PREP(CURSOR_HEIGHT_MASK, (h))
+#define CURSOR_WIDTH_MASK REG_GENMASK(9, 0)
+#define CURSOR_WIDTH(w) REG_FIELD_PREP(CURSOR_WIDTH_MASK, (w))
+
+#define _CUR_FBC_CTL_A 0x700a0 /* ivb+ */
+#define CUR_FBC_CTL(dev_priv, pipe) _MMIO_CURSOR2((dev_priv), (pipe), _CUR_FBC_CTL_A)
+#define CUR_FBC_EN REG_BIT(31)
+#define CUR_FBC_HEIGHT_MASK REG_GENMASK(7, 0)
+#define CUR_FBC_HEIGHT(h) REG_FIELD_PREP(CUR_FBC_HEIGHT_MASK, (h))
+
+#define _CUR_CHICKEN_A 0x700a4 /* mtl+ */
+#define CUR_CHICKEN(dev_priv, pipe) _MMIO_CURSOR2((dev_priv), (pipe), _CUR_CHICKEN_A)
+
+#define _CURASURFLIVE 0x700ac /* g4x+ */
+#define CURSURFLIVE(dev_priv, pipe) _MMIO_CURSOR2((dev_priv), (pipe), _CURASURFLIVE)
+
+/* skl+ */
+#define _CUR_WM_A_0 0x70140
+#define _CUR_WM_B_0 0x71140
+#define CUR_WM(pipe, level) _MMIO(_PIPE((pipe), _CUR_WM_A_0, _CUR_WM_B_0) + (level) * 4)
+#define CUR_WM_EN REG_BIT(31)
+#define CUR_WM_IGNORE_LINES REG_BIT(30)
+#define CUR_WM_LINES_MASK REG_GENMASK(26, 14)
+#define CUR_WM_BLOCKS_MASK REG_GENMASK(11, 0)
+
+#define _CUR_WM_SAGV_A 0x70158
+#define _CUR_WM_SAGV_B 0x71158
+#define CUR_WM_SAGV(pipe) _MMIO_PIPE((pipe), _CUR_WM_SAGV_A, _CUR_WM_SAGV_B)
+
+#define _CUR_WM_SAGV_TRANS_A 0x7015C
+#define _CUR_WM_SAGV_TRANS_B 0x7115C
+#define CUR_WM_SAGV_TRANS(pipe) _MMIO_PIPE((pipe), _CUR_WM_SAGV_TRANS_A, _CUR_WM_SAGV_TRANS_B)
+
+#define _CUR_WM_TRANS_A 0x70168
+#define _CUR_WM_TRANS_B 0x71168
+#define CUR_WM_TRANS(pipe) _MMIO_PIPE((pipe), _CUR_WM_TRANS_A, _CUR_WM_TRANS_B)
+
+#define _CUR_BUF_CFG_A 0x7017c
+#define _CUR_BUF_CFG_B 0x7117c
+#define CUR_BUF_CFG(pipe) _MMIO_PIPE((pipe), _CUR_BUF_CFG_A, _CUR_BUF_CFG_B)
+/* skl+: 10 bits, icl+ 11 bits, adlp+ 12 bits */
+#define CUR_BUF_END_MASK REG_GENMASK(27, 16)
+#define CUR_BUF_END(end) REG_FIELD_PREP(CUR_BUF_END_MASK, (end))
+#define CUR_BUF_START_MASK REG_GENMASK(11, 0)
+#define CUR_BUF_START(start) REG_FIELD_PREP(CUR_BUF_START_MASK, (start))
+
+/* tgl+ */
+#define _SEL_FETCH_CUR_CTL_A 0x70880
+#define _SEL_FETCH_CUR_CTL_B 0x71880
+#define SEL_FETCH_CUR_CTL(pipe) _MMIO_PIPE((pipe), _SEL_FETCH_CUR_CTL_A, _SEL_FETCH_CUR_CTL_B)
+
+#endif /* __INTEL_CURSOR_REGS_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c
index 8e3b13884bb8..41f684c970dc 100644
--- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c
@@ -946,6 +946,183 @@ static const struct intel_c20pll_state * const mtl_c20_dp_tables[] = {
};
/*
+ * eDP link rates with 38.4 MHz reference clock.
+ */
+
+static const struct intel_c20pll_state xe2hpd_c20_edp_r216 = {
+ .clock = 216000,
+ .tx = { 0xbe88,
+ 0x4800,
+ 0x0000,
+ },
+ .cmn = { 0x0500,
+ 0x0005,
+ 0x0000,
+ 0x0000,
+ },
+ .mpllb = { 0x50e1,
+ 0x2120,
+ 0x8e18,
+ 0xbfc1,
+ 0x9000,
+ 0x78f6,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ },
+};
+
+static const struct intel_c20pll_state xe2hpd_c20_edp_r243 = {
+ .clock = 243000,
+ .tx = { 0xbe88,
+ 0x4800,
+ 0x0000,
+ },
+ .cmn = { 0x0500,
+ 0x0005,
+ 0x0000,
+ 0x0000,
+ },
+ .mpllb = { 0x50fd,
+ 0x2120,
+ 0x8f18,
+ 0xbfc1,
+ 0xa200,
+ 0x8814,
+ 0x2000,
+ 0x0001,
+ 0x1000,
+ 0x0000,
+ 0x0000,
+ },
+};
+
+static const struct intel_c20pll_state xe2hpd_c20_edp_r324 = {
+ .clock = 324000,
+ .tx = { 0xbe88,
+ 0x4800,
+ 0x0000,
+ },
+ .cmn = { 0x0500,
+ 0x0005,
+ 0x0000,
+ 0x0000,
+ },
+ .mpllb = { 0x30a8,
+ 0x2110,
+ 0xcd9a,
+ 0xbfc1,
+ 0x6c00,
+ 0x5ab8,
+ 0x2000,
+ 0x0001,
+ 0x6000,
+ 0x0000,
+ 0x0000,
+ },
+};
+
+static const struct intel_c20pll_state xe2hpd_c20_edp_r432 = {
+ .clock = 432000,
+ .tx = { 0xbe88,
+ 0x4800,
+ 0x0000,
+ },
+ .cmn = { 0x0500,
+ 0x0005,
+ 0x0000,
+ 0x0000,
+ },
+ .mpllb = { 0x30e1,
+ 0x2110,
+ 0x8e18,
+ 0xbfc1,
+ 0x9000,
+ 0x78f6,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ },
+};
+
+static const struct intel_c20pll_state xe2hpd_c20_edp_r675 = {
+ .clock = 675000,
+ .tx = { 0xbe88,
+ 0x4800,
+ 0x0000,
+ },
+ .cmn = { 0x0500,
+ 0x0005,
+ 0x0000,
+ 0x0000,
+ },
+ .mpllb = { 0x10af,
+ 0x2108,
+ 0xce1a,
+ 0xbfc1,
+ 0x7080,
+ 0x5e80,
+ 0x2000,
+ 0x0001,
+ 0x6400,
+ 0x0000,
+ 0x0000,
+ },
+};
+
+static const struct intel_c20pll_state * const xe2hpd_c20_edp_tables[] = {
+ &mtl_c20_dp_rbr,
+ &xe2hpd_c20_edp_r216,
+ &xe2hpd_c20_edp_r243,
+ &mtl_c20_dp_hbr1,
+ &xe2hpd_c20_edp_r324,
+ &xe2hpd_c20_edp_r432,
+ &mtl_c20_dp_hbr2,
+ &xe2hpd_c20_edp_r675,
+ &mtl_c20_dp_hbr3,
+ NULL,
+};
+
+static const struct intel_c20pll_state xe2hpd_c20_dp_uhbr13_5 = {
+ .clock = 1350000, /* 13.5 Gbps */
+ .tx = { 0xbea0, /* tx cfg0 */
+ 0x4800, /* tx cfg1 */
+ 0x0000, /* tx cfg2 */
+ },
+ .cmn = {0x0500, /* cmn cfg0*/
+ 0x0005, /* cmn cfg1 */
+ 0x0000, /* cmn cfg2 */
+ 0x0000, /* cmn cfg3 */
+ },
+ .mpllb = { 0x015f, /* mpllb cfg0 */
+ 0x2205, /* mpllb cfg1 */
+ 0x1b17, /* mpllb cfg2 */
+ 0xffc1, /* mpllb cfg3 */
+ 0xbd00, /* mpllb cfg4 */
+ 0x9ec3, /* mpllb cfg5 */
+ 0x2000, /* mpllb cfg6 */
+ 0x0001, /* mpllb cfg7 */
+ 0x4800, /* mpllb cfg8 */
+ 0x0000, /* mpllb cfg9 */
+ 0x0000, /* mpllb cfg10 */
+ },
+};
+
+static const struct intel_c20pll_state * const xe2hpd_c20_dp_tables[] = {
+ &mtl_c20_dp_rbr,
+ &mtl_c20_dp_hbr1,
+ &mtl_c20_dp_hbr2,
+ &mtl_c20_dp_hbr3,
+ &mtl_c20_dp_uhbr10,
+ &xe2hpd_c20_dp_uhbr13_5,
+ NULL,
+};
+
+/*
* HDMI link rates with 38.4 MHz reference clock.
*/
@@ -1861,6 +2038,7 @@ static int intel_c10pll_calc_state(struct intel_crtc_state *crtc_state,
if (crtc_state->port_clock == tables[i]->clock) {
crtc_state->dpll_hw_state.cx0pll.c10 = *tables[i];
intel_c10pll_update_pll(crtc_state, encoder);
+ crtc_state->dpll_hw_state.cx0pll.use_c10 = true;
return 0;
}
@@ -1928,8 +2106,8 @@ static void intel_c10_pll_program(struct drm_i915_private *i915,
MB_WRITE_COMMITTED);
}
-void intel_c10pll_dump_hw_state(struct drm_i915_private *i915,
- const struct intel_c10pll_state *hw_state)
+static void intel_c10pll_dump_hw_state(struct drm_i915_private *i915,
+ const struct intel_c10pll_state *hw_state)
{
bool fracen;
int i;
@@ -2061,10 +2239,20 @@ static const struct intel_c20pll_state * const *
intel_c20_pll_tables_get(struct intel_crtc_state *crtc_state,
struct intel_encoder *encoder)
{
- if (intel_crtc_has_dp_encoder(crtc_state))
- return mtl_c20_dp_tables;
- else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+
+ if (intel_crtc_has_dp_encoder(crtc_state)) {
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
+ return xe2hpd_c20_edp_tables;
+
+ if (DISPLAY_VER_FULL(i915) == IP_VER(14, 1))
+ return xe2hpd_c20_dp_tables;
+ else
+ return mtl_c20_dp_tables;
+
+ } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
return mtl_c20_hdmi_tables;
+ }
MISSING_CASE(encoder->type);
return NULL;
@@ -2090,6 +2278,7 @@ static int intel_c20pll_calc_state(struct intel_crtc_state *crtc_state,
for (i = 0; tables[i]; i++) {
if (crtc_state->port_clock == tables[i]->clock) {
crtc_state->dpll_hw_state.cx0pll.c20 = *tables[i];
+ crtc_state->dpll_hw_state.cx0pll.use_c10 = false;
return 0;
}
}
@@ -2161,6 +2350,7 @@ static void intel_c20pll_readout_hw_state(struct intel_encoder *encoder,
bool cntx;
intel_wakeref_t wakeref;
int i;
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
wakeref = intel_cx0_phy_transaction_begin(encoder);
@@ -2170,42 +2360,50 @@ static void intel_c20pll_readout_hw_state(struct intel_encoder *encoder,
/* Read Tx configuration */
for (i = 0; i < ARRAY_SIZE(pll_state->tx); i++) {
if (cntx)
- pll_state->tx[i] = intel_c20_sram_read(encoder, INTEL_CX0_LANE0,
- PHY_C20_B_TX_CNTX_CFG(i));
+ pll_state->tx[i] = intel_c20_sram_read(encoder,
+ INTEL_CX0_LANE0,
+ PHY_C20_B_TX_CNTX_CFG(i915, i));
else
- pll_state->tx[i] = intel_c20_sram_read(encoder, INTEL_CX0_LANE0,
- PHY_C20_A_TX_CNTX_CFG(i));
+ pll_state->tx[i] = intel_c20_sram_read(encoder,
+ INTEL_CX0_LANE0,
+ PHY_C20_A_TX_CNTX_CFG(i915, i));
}
/* Read common configuration */
for (i = 0; i < ARRAY_SIZE(pll_state->cmn); i++) {
if (cntx)
- pll_state->cmn[i] = intel_c20_sram_read(encoder, INTEL_CX0_LANE0,
- PHY_C20_B_CMN_CNTX_CFG(i));
+ pll_state->cmn[i] = intel_c20_sram_read(encoder,
+ INTEL_CX0_LANE0,
+ PHY_C20_B_CMN_CNTX_CFG(i915, i));
else
- pll_state->cmn[i] = intel_c20_sram_read(encoder, INTEL_CX0_LANE0,
- PHY_C20_A_CMN_CNTX_CFG(i));
+ pll_state->cmn[i] = intel_c20_sram_read(encoder,
+ INTEL_CX0_LANE0,
+ PHY_C20_A_CMN_CNTX_CFG(i915, i));
}
if (intel_c20phy_use_mpllb(pll_state)) {
/* MPLLB configuration */
for (i = 0; i < ARRAY_SIZE(pll_state->mpllb); i++) {
if (cntx)
- pll_state->mpllb[i] = intel_c20_sram_read(encoder, INTEL_CX0_LANE0,
- PHY_C20_B_MPLLB_CNTX_CFG(i));
+ pll_state->mpllb[i] = intel_c20_sram_read(encoder,
+ INTEL_CX0_LANE0,
+ PHY_C20_B_MPLLB_CNTX_CFG(i915, i));
else
- pll_state->mpllb[i] = intel_c20_sram_read(encoder, INTEL_CX0_LANE0,
- PHY_C20_A_MPLLB_CNTX_CFG(i));
+ pll_state->mpllb[i] = intel_c20_sram_read(encoder,
+ INTEL_CX0_LANE0,
+ PHY_C20_A_MPLLB_CNTX_CFG(i915, i));
}
} else {
/* MPLLA configuration */
for (i = 0; i < ARRAY_SIZE(pll_state->mplla); i++) {
if (cntx)
- pll_state->mplla[i] = intel_c20_sram_read(encoder, INTEL_CX0_LANE0,
- PHY_C20_B_MPLLA_CNTX_CFG(i));
+ pll_state->mplla[i] = intel_c20_sram_read(encoder,
+ INTEL_CX0_LANE0,
+ PHY_C20_B_MPLLA_CNTX_CFG(i915, i));
else
- pll_state->mplla[i] = intel_c20_sram_read(encoder, INTEL_CX0_LANE0,
- PHY_C20_A_MPLLA_CNTX_CFG(i));
+ pll_state->mplla[i] = intel_c20_sram_read(encoder,
+ INTEL_CX0_LANE0,
+ PHY_C20_A_MPLLA_CNTX_CFG(i915, i));
}
}
@@ -2214,8 +2412,8 @@ static void intel_c20pll_readout_hw_state(struct intel_encoder *encoder,
intel_cx0_phy_transaction_end(encoder, wakeref);
}
-void intel_c20pll_dump_hw_state(struct drm_i915_private *i915,
- const struct intel_c20pll_state *hw_state)
+static void intel_c20pll_dump_hw_state(struct drm_i915_private *i915,
+ const struct intel_c20pll_state *hw_state)
{
int i;
@@ -2234,6 +2432,15 @@ void intel_c20pll_dump_hw_state(struct drm_i915_private *i915,
}
}
+void intel_cx0pll_dump_hw_state(struct drm_i915_private *i915,
+ const struct intel_cx0pll_state *hw_state)
+{
+ if (hw_state->use_c10)
+ intel_c10pll_dump_hw_state(i915, &hw_state->c10);
+ else
+ intel_c20pll_dump_hw_state(i915, &hw_state->c20);
+}
+
static u8 intel_c20_get_dp_rate(u32 clock)
{
switch (clock) {
@@ -2337,7 +2544,7 @@ static void intel_c20_pll_program(struct drm_i915_private *i915,
{
const struct intel_c20pll_state *pll_state = &crtc_state->dpll_hw_state.cx0pll.c20;
bool dp = false;
- int lane = crtc_state->lane_count > 2 ? INTEL_CX0_BOTH_LANES : INTEL_CX0_LANE0;
+ u8 owned_lane_mask = intel_cx0_get_owned_lane_mask(encoder);
u32 clock = crtc_state->port_clock;
bool cntx;
int i;
@@ -2363,17 +2570,25 @@ static void intel_c20_pll_program(struct drm_i915_private *i915,
/* 3.1 Tx configuration */
for (i = 0; i < ARRAY_SIZE(pll_state->tx); i++) {
if (cntx)
- intel_c20_sram_write(encoder, INTEL_CX0_LANE0, PHY_C20_A_TX_CNTX_CFG(i), pll_state->tx[i]);
+ intel_c20_sram_write(encoder, INTEL_CX0_LANE0,
+ PHY_C20_A_TX_CNTX_CFG(i915, i),
+ pll_state->tx[i]);
else
- intel_c20_sram_write(encoder, INTEL_CX0_LANE0, PHY_C20_B_TX_CNTX_CFG(i), pll_state->tx[i]);
+ intel_c20_sram_write(encoder, INTEL_CX0_LANE0,
+ PHY_C20_B_TX_CNTX_CFG(i915, i),
+ pll_state->tx[i]);
}
/* 3.2 common configuration */
for (i = 0; i < ARRAY_SIZE(pll_state->cmn); i++) {
if (cntx)
- intel_c20_sram_write(encoder, INTEL_CX0_LANE0, PHY_C20_A_CMN_CNTX_CFG(i), pll_state->cmn[i]);
+ intel_c20_sram_write(encoder, INTEL_CX0_LANE0,
+ PHY_C20_A_CMN_CNTX_CFG(i915, i),
+ pll_state->cmn[i]);
else
- intel_c20_sram_write(encoder, INTEL_CX0_LANE0, PHY_C20_B_CMN_CNTX_CFG(i), pll_state->cmn[i]);
+ intel_c20_sram_write(encoder, INTEL_CX0_LANE0,
+ PHY_C20_B_CMN_CNTX_CFG(i915, i),
+ pll_state->cmn[i]);
}
/* 3.3 mpllb or mplla configuration */
@@ -2381,40 +2596,40 @@ static void intel_c20_pll_program(struct drm_i915_private *i915,
for (i = 0; i < ARRAY_SIZE(pll_state->mpllb); i++) {
if (cntx)
intel_c20_sram_write(encoder, INTEL_CX0_LANE0,
- PHY_C20_A_MPLLB_CNTX_CFG(i),
+ PHY_C20_A_MPLLB_CNTX_CFG(i915, i),
pll_state->mpllb[i]);
else
intel_c20_sram_write(encoder, INTEL_CX0_LANE0,
- PHY_C20_B_MPLLB_CNTX_CFG(i),
+ PHY_C20_B_MPLLB_CNTX_CFG(i915, i),
pll_state->mpllb[i]);
}
} else {
for (i = 0; i < ARRAY_SIZE(pll_state->mplla); i++) {
if (cntx)
intel_c20_sram_write(encoder, INTEL_CX0_LANE0,
- PHY_C20_A_MPLLA_CNTX_CFG(i),
+ PHY_C20_A_MPLLA_CNTX_CFG(i915, i),
pll_state->mplla[i]);
else
intel_c20_sram_write(encoder, INTEL_CX0_LANE0,
- PHY_C20_B_MPLLA_CNTX_CFG(i),
+ PHY_C20_B_MPLLA_CNTX_CFG(i915, i),
pll_state->mplla[i]);
}
}
/* 4. Program custom width to match the link protocol */
- intel_cx0_rmw(encoder, lane, PHY_C20_VDR_CUSTOM_WIDTH,
+ intel_cx0_rmw(encoder, owned_lane_mask, PHY_C20_VDR_CUSTOM_WIDTH,
PHY_C20_CUSTOM_WIDTH_MASK,
PHY_C20_CUSTOM_WIDTH(intel_get_c20_custom_width(clock, dp)),
MB_WRITE_COMMITTED);
/* 5. For DP or 6. For HDMI */
if (dp) {
- intel_cx0_rmw(encoder, lane, PHY_C20_VDR_CUSTOM_SERDES_RATE,
+ intel_cx0_rmw(encoder, owned_lane_mask, PHY_C20_VDR_CUSTOM_SERDES_RATE,
BIT(6) | PHY_C20_CUSTOM_SERDES_MASK,
BIT(6) | PHY_C20_CUSTOM_SERDES(intel_c20_get_dp_rate(clock)),
MB_WRITE_COMMITTED);
} else {
- intel_cx0_rmw(encoder, lane, PHY_C20_VDR_CUSTOM_SERDES_RATE,
+ intel_cx0_rmw(encoder, owned_lane_mask, PHY_C20_VDR_CUSTOM_SERDES_RATE,
BIT(7) | PHY_C20_CUSTOM_SERDES_MASK,
is_hdmi_frl(clock) ? BIT(7) : 0,
MB_WRITE_COMMITTED);
@@ -2428,7 +2643,7 @@ static void intel_c20_pll_program(struct drm_i915_private *i915,
* 7. Write Vendor specific registers to toggle context setting to load
* the updated programming toggle context bit
*/
- intel_cx0_rmw(encoder, lane, PHY_C20_VDR_CUSTOM_SERDES_RATE,
+ intel_cx0_rmw(encoder, owned_lane_mask, PHY_C20_VDR_CUSTOM_SERDES_RATE,
BIT(0), cntx ? 0 : 1, MB_WRITE_COMMITTED);
}
@@ -2900,17 +3115,28 @@ void intel_mtl_pll_enable(struct intel_encoder *encoder,
intel_cx0pll_enable(encoder, crtc_state);
}
+static u8 cx0_power_control_disable_val(struct intel_encoder *encoder)
+{
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+
+ if (intel_encoder_is_c10phy(encoder))
+ return CX0_P2PG_STATE_DISABLE;
+
+ if (IS_BATTLEMAGE(i915) && encoder->port == PORT_A)
+ return CX0_P2PG_STATE_DISABLE;
+
+ return CX0_P4PG_STATE_DISABLE;
+}
+
static void intel_cx0pll_disable(struct intel_encoder *encoder)
{
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
enum phy phy = intel_encoder_to_phy(encoder);
- bool is_c10 = intel_encoder_is_c10phy(encoder);
intel_wakeref_t wakeref = intel_cx0_phy_transaction_begin(encoder);
/* 1. Change owned PHY lane power to Disable state. */
intel_cx0_powerdown_change_sequence(encoder, INTEL_CX0_BOTH_LANES,
- is_c10 ? CX0_P2PG_STATE_DISABLE :
- CX0_P4PG_STATE_DISABLE);
+ cx0_power_control_disable_val(encoder));
/*
* 2. Follow the Display Voltage Frequency Switching Sequence Before
@@ -3028,9 +3254,6 @@ static void intel_c10pll_state_verify(const struct intel_crtc_state *state,
const struct intel_c10pll_state *mpllb_sw_state = &state->dpll_hw_state.cx0pll.c10;
int i;
- if (intel_crtc_needs_fastset(state))
- return;
-
for (i = 0; i < ARRAY_SIZE(mpllb_sw_state->pll); i++) {
u8 expected = mpllb_sw_state->pll[i];
@@ -3054,10 +3277,64 @@ static void intel_c10pll_state_verify(const struct intel_crtc_state *state,
void intel_cx0pll_readout_hw_state(struct intel_encoder *encoder,
struct intel_cx0pll_state *pll_state)
{
- if (intel_encoder_is_c10phy(encoder))
+ pll_state->use_c10 = false;
+
+ if (intel_encoder_is_c10phy(encoder)) {
intel_c10pll_readout_hw_state(encoder, &pll_state->c10);
- else
+ pll_state->use_c10 = true;
+ } else {
intel_c20pll_readout_hw_state(encoder, &pll_state->c20);
+ }
+}
+
+static bool mtl_compare_hw_state_c10(const struct intel_c10pll_state *a,
+ const struct intel_c10pll_state *b)
+{
+ if (a->tx != b->tx)
+ return false;
+
+ if (a->cmn != b->cmn)
+ return false;
+
+ if (memcmp(&a->pll, &b->pll, sizeof(a->pll)) != 0)
+ return false;
+
+ return true;
+}
+
+static bool mtl_compare_hw_state_c20(const struct intel_c20pll_state *a,
+ const struct intel_c20pll_state *b)
+{
+ if (memcmp(&a->tx, &b->tx, sizeof(a->tx)) != 0)
+ return false;
+
+ if (memcmp(&a->cmn, &b->cmn, sizeof(a->cmn)) != 0)
+ return false;
+
+ if (a->tx[0] & C20_PHY_USE_MPLLB) {
+ if (memcmp(&a->mpllb, &b->mpllb, sizeof(a->mpllb)) != 0)
+ return false;
+ } else {
+ if (memcmp(&a->mplla, &b->mplla, sizeof(a->mplla)) != 0)
+ return false;
+ }
+
+ return true;
+}
+
+bool intel_cx0pll_compare_hw_state(const struct intel_cx0pll_state *a,
+ const struct intel_cx0pll_state *b)
+{
+
+ if (a->use_c10 != b->use_c10)
+ return false;
+
+ if (a->use_c10)
+ return mtl_compare_hw_state_c10(&a->c10,
+ &b->c10);
+ else
+ return mtl_compare_hw_state_c20(&a->c20,
+ &b->c20);
}
int intel_cx0pll_calc_port_clock(struct intel_encoder *encoder,
@@ -3078,9 +3355,10 @@ static void intel_c20pll_state_verify(const struct intel_crtc_state *state,
const struct intel_c20pll_state *mpll_sw_state = &state->dpll_hw_state.cx0pll.c20;
bool sw_use_mpllb = intel_c20phy_use_mpllb(mpll_sw_state);
bool hw_use_mpllb = intel_c20phy_use_mpllb(mpll_hw_state);
+ int clock = intel_c20pll_calc_port_clock(encoder, mpll_sw_state);
int i;
- I915_STATE_WARN(i915, mpll_hw_state->clock != mpll_sw_state->clock,
+ I915_STATE_WARN(i915, mpll_hw_state->clock != clock,
"[CRTC:%d:%s] mismatch in C20: Register CLOCK (expected %d, found %d)",
crtc->base.base.id, crtc->base.name,
mpll_sw_state->clock, mpll_hw_state->clock);
diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.h b/drivers/gpu/drm/i915/display/intel_cx0_phy.h
index 3e03af3e006c..9004b99bb51f 100644
--- a/drivers/gpu/drm/i915/display/intel_cx0_phy.h
+++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.h
@@ -35,12 +35,12 @@ void intel_cx0pll_readout_hw_state(struct intel_encoder *encoder,
int intel_cx0pll_calc_port_clock(struct intel_encoder *encoder,
const struct intel_cx0pll_state *pll_state);
-void intel_c10pll_dump_hw_state(struct drm_i915_private *dev_priv,
- const struct intel_c10pll_state *hw_state);
+void intel_cx0pll_dump_hw_state(struct drm_i915_private *dev_priv,
+ const struct intel_cx0pll_state *hw_state);
void intel_cx0pll_state_verify(struct intel_atomic_state *state,
struct intel_crtc *crtc);
-void intel_c20pll_dump_hw_state(struct drm_i915_private *i915,
- const struct intel_c20pll_state *hw_state);
+bool intel_cx0pll_compare_hw_state(const struct intel_cx0pll_state *a,
+ const struct intel_cx0pll_state *b);
void intel_cx0_phy_set_signal_levels(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state);
int intel_cx0_phy_check_hdmi_link_rate(struct intel_hdmi *hdmi, int clock);
diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h b/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h
index bdd0c8c4ef97..ab3ae110b68f 100644
--- a/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h
@@ -254,18 +254,50 @@
#define PHY_C20_VDR_CUSTOM_WIDTH 0xD02
#define PHY_C20_CUSTOM_WIDTH_MASK REG_GENMASK(1, 0)
#define PHY_C20_CUSTOM_WIDTH(val) REG_FIELD_PREP8(PHY_C20_CUSTOM_WIDTH_MASK, val)
-#define PHY_C20_A_TX_CNTX_CFG(idx) (0xCF2E - (idx))
-#define PHY_C20_B_TX_CNTX_CFG(idx) (0xCF2A - (idx))
+
+#define _MTL_C20_A_TX_CNTX_CFG 0xCF2E
+#define _MTL_C20_B_TX_CNTX_CFG 0xCF2A
+#define _MTL_C20_A_CMN_CNTX_CFG 0xCDAA
+#define _MTL_C20_B_CMN_CNTX_CFG 0xCDA5
+#define _MTL_C20_A_MPLLA_CFG 0xCCF0
+#define _MTL_C20_B_MPLLA_CFG 0xCCE5
+#define _MTL_C20_A_MPLLB_CFG 0xCB5A
+#define _MTL_C20_B_MPLLB_CFG 0xCB4E
+
+#define _XE2HPD_C20_A_TX_CNTX_CFG 0xCF5E
+#define _XE2HPD_C20_B_TX_CNTX_CFG 0xCF5A
+#define _XE2HPD_C20_A_CMN_CNTX_CFG 0xCE8E
+#define _XE2HPD_C20_B_CMN_CNTX_CFG 0xCE89
+#define _XE2HPD_C20_A_MPLLA_CFG 0xCE58
+#define _XE2HPD_C20_B_MPLLA_CFG 0xCE4D
+#define _XE2HPD_C20_A_MPLLB_CFG 0xCCC2
+#define _XE2HPD_C20_B_MPLLB_CFG 0xCCB6
+
+#define _IS_XE2HPD_C20(i915) (DISPLAY_VER_FULL(i915) == IP_VER(14, 1))
+
+#define PHY_C20_A_TX_CNTX_CFG(i915, idx) \
+ ((_IS_XE2HPD_C20(i915) ? _XE2HPD_C20_A_TX_CNTX_CFG : _MTL_C20_A_TX_CNTX_CFG) - (idx))
+#define PHY_C20_B_TX_CNTX_CFG(i915, idx) \
+ ((_IS_XE2HPD_C20(i915) ? _XE2HPD_C20_B_TX_CNTX_CFG : _MTL_C20_B_TX_CNTX_CFG) - (idx))
#define C20_PHY_TX_RATE REG_GENMASK(2, 0)
-#define PHY_C20_A_CMN_CNTX_CFG(idx) (0xCDAA - (idx))
-#define PHY_C20_B_CMN_CNTX_CFG(idx) (0xCDA5 - (idx))
-#define PHY_C20_A_MPLLA_CNTX_CFG(idx) (0xCCF0 - (idx))
-#define PHY_C20_B_MPLLA_CNTX_CFG(idx) (0xCCE5 - (idx))
+
+#define PHY_C20_A_CMN_CNTX_CFG(i915, idx) \
+ ((_IS_XE2HPD_C20(i915) ? _XE2HPD_C20_A_CMN_CNTX_CFG : _MTL_C20_A_CMN_CNTX_CFG) - (idx))
+#define PHY_C20_B_CMN_CNTX_CFG(i915, idx) \
+ ((_IS_XE2HPD_C20(i915) ? _XE2HPD_C20_B_CMN_CNTX_CFG : _MTL_C20_B_CMN_CNTX_CFG) - (idx))
+#define PHY_C20_A_MPLLA_CNTX_CFG(i915, idx) \
+ ((_IS_XE2HPD_C20(i915) ? _XE2HPD_C20_A_MPLLA_CFG : _MTL_C20_A_MPLLA_CFG) - (idx))
+#define PHY_C20_B_MPLLA_CNTX_CFG(i915, idx) \
+ ((_IS_XE2HPD_C20(i915) ? _XE2HPD_C20_B_MPLLA_CFG : _MTL_C20_B_MPLLA_CFG) - (idx))
#define C20_MPLLA_FRACEN REG_BIT(14)
#define C20_FB_CLK_DIV4_EN REG_BIT(13)
#define C20_MPLLA_TX_CLK_DIV_MASK REG_GENMASK(10, 8)
-#define PHY_C20_A_MPLLB_CNTX_CFG(idx) (0xCB5A - (idx))
-#define PHY_C20_B_MPLLB_CNTX_CFG(idx) (0xCB4E - (idx))
+
+#define PHY_C20_A_MPLLB_CNTX_CFG(i915, idx) \
+ ((_IS_XE2HPD_C20(i915) ? _XE2HPD_C20_A_MPLLB_CFG : _MTL_C20_A_MPLLB_CFG) - (idx))
+#define PHY_C20_B_MPLLB_CNTX_CFG(i915, idx) \
+ ((_IS_XE2HPD_C20(i915) ? _XE2HPD_C20_B_MPLLB_CFG : _MTL_C20_B_MPLLB_CFG) - (idx))
+
#define C20_MPLLB_TX_CLK_DIV_MASK REG_GENMASK(15, 13)
#define C20_MPLLB_FRACEN REG_BIT(13)
#define C20_REF_CLK_MPLLB_DIV_MASK REG_GENMASK(12, 10)
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 3c3fc53376ce..bb13a3ca8c7c 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -57,6 +57,7 @@
#include "intel_dp_tunnel.h"
#include "intel_dpio_phy.h"
#include "intel_dsi.h"
+#include "intel_encoder.h"
#include "intel_fdi.h"
#include "intel_fifo_underrun.h"
#include "intel_gmbus.h"
@@ -440,7 +441,8 @@ void intel_ddi_set_dp_msa(const struct intel_crtc_state *crtc_state,
if (intel_dp_needs_vsc_sdp(crtc_state, conn_state))
temp |= DP_MSA_MISC_COLOR_VSC_SDP;
- intel_de_write(dev_priv, TRANS_MSA_MISC(cpu_transcoder), temp);
+ intel_de_write(dev_priv, TRANS_MSA_MISC(dev_priv, cpu_transcoder),
+ temp);
}
static u32 bdw_trans_port_sync_master_select(enum transcoder master_transcoder)
@@ -603,10 +605,11 @@ void intel_ddi_enable_transcoder_func(struct intel_encoder *encoder,
}
intel_de_write(dev_priv,
- TRANS_DDI_FUNC_CTL2(cpu_transcoder), ctl2);
+ TRANS_DDI_FUNC_CTL2(dev_priv, cpu_transcoder),
+ ctl2);
}
- intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder),
intel_ddi_transcoder_func_reg_val_get(encoder,
crtc_state));
}
@@ -626,7 +629,8 @@ intel_ddi_config_transcoder_func(struct intel_encoder *encoder,
ctl = intel_ddi_transcoder_func_reg_val_get(encoder, crtc_state);
ctl &= ~TRANS_DDI_FUNC_ENABLE;
- intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder), ctl);
+ intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder),
+ ctl);
}
void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state)
@@ -639,9 +643,11 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state
if (DISPLAY_VER(dev_priv) >= 11)
intel_de_write(dev_priv,
- TRANS_DDI_FUNC_CTL2(cpu_transcoder), 0);
+ TRANS_DDI_FUNC_CTL2(dev_priv, cpu_transcoder),
+ 0);
- ctl = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
+ ctl = intel_de_read(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder));
drm_WARN_ON(crtc->base.dev, ctl & TRANS_DDI_HDCP_SIGNALLING);
@@ -660,7 +666,8 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state
ctl &= ~(TRANS_DDI_PORT_MASK | TRANS_DDI_MODE_SELECT_MASK);
}
- intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder), ctl);
+ intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder),
+ ctl);
if (intel_has_quirk(display, QUIRK_INCREASE_DDI_DISABLED_TIME) &&
intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
@@ -684,7 +691,7 @@ int intel_ddi_toggle_hdcp_bits(struct intel_encoder *intel_encoder,
if (drm_WARN_ON(dev, !wakeref))
return -ENXIO;
- intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder),
+ intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder),
hdcp_mask, enable ? hdcp_mask : 0);
intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref);
return ret;
@@ -718,7 +725,8 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
else
cpu_transcoder = (enum transcoder) pipe;
- tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
+ tmp = intel_de_read(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder));
switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
case TRANS_DDI_MODE_SELECT_HDMI:
@@ -782,7 +790,7 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder,
if (HAS_TRANSCODER(dev_priv, TRANSCODER_EDP) && port == PORT_A) {
tmp = intel_de_read(dev_priv,
- TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
+ TRANS_DDI_FUNC_CTL(dev_priv, TRANSCODER_EDP));
switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
default:
@@ -823,7 +831,7 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder,
}
tmp = intel_de_read(dev_priv,
- TRANS_DDI_FUNC_CTL(cpu_transcoder));
+ TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder));
intel_display_power_put(dev_priv, POWER_DOMAIN_TRANSCODER(cpu_transcoder),
trans_wakeref);
@@ -2072,9 +2080,9 @@ void intel_ddi_sanitize_encoder_pll_mapping(struct intel_encoder *encoder)
!encoder->is_clock_enabled(encoder))
return;
- drm_notice(&i915->drm,
- "[ENCODER:%d:%s] is disabled/in DSI mode with an ungated DDI clock, gate it\n",
- encoder->base.base.id, encoder->base.name);
+ drm_dbg_kms(&i915->drm,
+ "[ENCODER:%d:%s] is disabled/in DSI mode with an ungated DDI clock, gate it\n",
+ encoder->base.base.id, encoder->base.name);
encoder->disable_clock(encoder);
}
@@ -2178,7 +2186,8 @@ i915_reg_t dp_tp_ctl_reg(struct intel_encoder *encoder,
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
if (DISPLAY_VER(dev_priv) >= 12)
- return TGL_DP_TP_CTL(tgl_dp_tp_transcoder(crtc_state));
+ return TGL_DP_TP_CTL(dev_priv,
+ tgl_dp_tp_transcoder(crtc_state));
else
return DP_TP_CTL(encoder->port);
}
@@ -2189,7 +2198,8 @@ i915_reg_t dp_tp_status_reg(struct intel_encoder *encoder,
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
if (DISPLAY_VER(dev_priv) >= 12)
- return TGL_DP_TP_STATUS(tgl_dp_tp_transcoder(crtc_state));
+ return TGL_DP_TP_STATUS(dev_priv,
+ tgl_dp_tp_transcoder(crtc_state));
else
return DP_TP_STATUS(encoder->port);
}
@@ -2586,7 +2596,7 @@ static void mtl_ddi_pre_enable_dp(struct intel_atomic_state *state,
* Pattern, wait for 5 idle patterns (DP_TP_STATUS Min_Idles_Sent)
* (timeout after 800 us)
*/
- intel_dp_start_link_train(intel_dp, crtc_state);
+ intel_dp_start_link_train(state, intel_dp, crtc_state);
/* 6.n Set DP_TP_CTL link training to Normal */
if (!is_trans_port_sync_mode(crtc_state))
@@ -2728,7 +2738,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
* Pattern, wait for 5 idle patterns (DP_TP_STATUS Min_Idles_Sent)
* (timeout after 800 us)
*/
- intel_dp_start_link_train(intel_dp, crtc_state);
+ intel_dp_start_link_train(state, intel_dp, crtc_state);
/* 7.k Set DP_TP_CTL link training to Normal */
if (!is_trans_port_sync_mode(crtc_state))
@@ -2795,7 +2805,7 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
to_intel_connector(conn_state->connector),
crtc_state);
intel_dp_sink_set_fec_ready(intel_dp, crtc_state, true);
- intel_dp_start_link_train(intel_dp, crtc_state);
+ intel_dp_start_link_train(state, intel_dp, crtc_state);
if ((port != PORT_A || DISPLAY_VER(dev_priv) >= 9) &&
!is_trans_port_sync_mode(crtc_state))
intel_dp_stop_link_train(intel_dp, crtc_state);
@@ -3025,7 +3035,8 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state,
if (is_mst) {
enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder;
- intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder),
+ intel_de_rmw(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder),
TGL_TRANS_DDI_PORT_MASK | TRANS_DDI_MODE_SELECT_MASK,
0);
}
@@ -3506,11 +3517,10 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state,
bool is_tc_port = intel_encoder_is_tc(encoder);
if (is_tc_port) {
- struct intel_crtc *master_crtc =
- to_intel_crtc(crtc_state->uapi.crtc);
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
intel_tc_port_get_link(dig_port, crtc_state->lane_count);
- intel_ddi_update_active_dpll(state, encoder, master_crtc);
+ intel_ddi_update_active_dpll(state, encoder, crtc);
}
main_link_aux_power_domain_get(dig_port, crtc_state);
@@ -3752,14 +3762,16 @@ static enum transcoder bdw_transcoder_master_readout(struct drm_i915_private *de
u32 master_select;
if (DISPLAY_VER(dev_priv) >= 11) {
- u32 ctl2 = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL2(cpu_transcoder));
+ u32 ctl2 = intel_de_read(dev_priv,
+ TRANS_DDI_FUNC_CTL2(dev_priv, cpu_transcoder));
if ((ctl2 & PORT_SYNC_MODE_ENABLE) == 0)
return INVALID_TRANSCODER;
master_select = REG_FIELD_GET(PORT_SYNC_MODE_MASTER_SELECT_MASK, ctl2);
} else {
- u32 ctl = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
+ u32 ctl = intel_de_read(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder));
if ((ctl & TRANS_DDI_PORT_SYNC_ENABLE) == 0)
return INVALID_TRANSCODER;
@@ -3815,7 +3827,8 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder,
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
u32 temp, flags = 0;
- temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
+ temp = intel_de_read(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder));
if (temp & TRANS_DDI_PHSYNC)
flags |= DRM_MODE_FLAG_PHSYNC;
else
@@ -4264,10 +4277,10 @@ static bool crtcs_port_sync_compatible(const struct intel_crtc_state *crtc_state
{
/*
* FIXME the modeset sequence is currently wrong and
- * can't deal with bigjoiner + port sync at the same time.
+ * can't deal with joiner + port sync at the same time.
*/
return crtc_state1->hw.active && crtc_state2->hw.active &&
- !crtc_state1->bigjoiner_pipes && !crtc_state2->bigjoiner_pipes &&
+ !crtc_state1->joiner_pipes && !crtc_state2->joiner_pipes &&
crtc_state1->output_types == crtc_state2->output_types &&
crtc_state1->output_format == crtc_state2->output_format &&
crtc_state1->lane_count == crtc_state2->lane_count &&
@@ -4441,35 +4454,6 @@ intel_ddi_init_dp_connector(struct intel_digital_port *dig_port)
return connector;
}
-static int modeset_pipe(struct drm_crtc *crtc,
- struct drm_modeset_acquire_ctx *ctx)
-{
- struct drm_atomic_state *state;
- struct drm_crtc_state *crtc_state;
- int ret;
-
- state = drm_atomic_state_alloc(crtc->dev);
- if (!state)
- return -ENOMEM;
-
- state->acquire_ctx = ctx;
- to_intel_atomic_state(state)->internal = true;
-
- crtc_state = drm_atomic_get_crtc_state(state, crtc);
- if (IS_ERR(crtc_state)) {
- ret = PTR_ERR(crtc_state);
- goto out;
- }
-
- crtc_state->connectors_changed = true;
-
- ret = drm_atomic_commit(state);
-out:
- drm_atomic_state_put(state);
-
- return ret;
-}
-
static int intel_hdmi_reset_link(struct intel_encoder *encoder,
struct drm_modeset_acquire_ctx *ctx)
{
@@ -4539,7 +4523,18 @@ static int intel_hdmi_reset_link(struct intel_encoder *encoder,
* would be perfectly happy if were to just reconfigure
* the SCDC settings on the fly.
*/
- return modeset_pipe(&crtc->base, ctx);
+ return intel_modeset_commit_pipes(dev_priv, BIT(crtc->pipe), ctx);
+}
+
+static void intel_ddi_link_check(struct intel_encoder *encoder)
+{
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+ struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+
+ /* TODO: Move checking the HDMI link state here as well. */
+ drm_WARN_ON(&i915->drm, !dig_port->dp.attached_connector);
+
+ intel_dp_link_check(encoder);
}
static enum intel_hotplug_state
@@ -4563,14 +4558,13 @@ intel_ddi_hotplug(struct intel_encoder *encoder,
state = intel_encoder_hotplug(encoder, connector);
if (!intel_tc_port_link_reset(dig_port)) {
- intel_modeset_lock_ctx_retry(&ctx, NULL, 0, ret) {
- if (connector->base.connector_type == DRM_MODE_CONNECTOR_HDMIA)
+ if (connector->base.connector_type == DRM_MODE_CONNECTOR_HDMIA) {
+ intel_modeset_lock_ctx_retry(&ctx, NULL, 0, ret)
ret = intel_hdmi_reset_link(encoder, &ctx);
- else
- ret = intel_dp_retrain_link(encoder, &ctx);
+ drm_WARN_ON(encoder->base.dev, ret);
+ } else {
+ intel_dp_check_link_state(intel_dp);
}
-
- drm_WARN_ON(encoder->base.dev, ret);
}
/*
@@ -4785,6 +4779,11 @@ static void intel_ddi_tc_encoder_suspend_complete(struct intel_encoder *encoder)
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+ /*
+ * TODO: Move this to intel_dp_encoder_suspend(),
+ * once modeset locking around that is removed.
+ */
+ intel_encoder_link_check_flush_work(encoder);
intel_tc_port_suspend(dig_port);
}
@@ -4975,6 +4974,8 @@ void intel_ddi_init(struct drm_i915_private *dev_priv,
"DDI %c/PHY %c", port_name(port), phy_name(phy));
}
+ intel_encoder_link_check_init(encoder, intel_ddi_link_check);
+
mutex_init(&dig_port->hdcp_mutex);
dig_port->num_hdcp_streams = 0;
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 273323f30ae2..7bc4f3de691e 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -54,6 +54,7 @@
#include "i915_reg.h"
#include "i915_utils.h"
#include "i9xx_plane.h"
+#include "i9xx_plane_regs.h"
#include "i9xx_wm.h"
#include "intel_atomic.h"
#include "intel_atomic_plane.h"
@@ -65,6 +66,8 @@
#include "intel_crt.h"
#include "intel_crtc.h"
#include "intel_crtc_state_dump.h"
+#include "intel_cursor_regs.h"
+#include "intel_cx0_phy.h"
#include "intel_ddi.h"
#include "intel_de.h"
#include "intel_display_driver.h"
@@ -109,6 +112,7 @@
#include "intel_sdvo.h"
#include "intel_snps_phy.h"
#include "intel_tc.h"
+#include "intel_tdf.h"
#include "intel_tv.h"
#include "intel_vblank.h"
#include "intel_vdsc.h"
@@ -118,6 +122,7 @@
#include "intel_wm.h"
#include "skl_scaler.h"
#include "skl_universal_plane.h"
+#include "skl_universal_plane_regs.h"
#include "skl_watermark.h"
#include "vlv_dpio_phy_regs.h"
#include "vlv_dsi.h"
@@ -241,53 +246,53 @@ is_trans_port_sync_mode(const struct intel_crtc_state *crtc_state)
is_trans_port_sync_slave(crtc_state);
}
-static enum pipe bigjoiner_master_pipe(const struct intel_crtc_state *crtc_state)
+static enum pipe joiner_primary_pipe(const struct intel_crtc_state *crtc_state)
{
- return ffs(crtc_state->bigjoiner_pipes) - 1;
+ return ffs(crtc_state->joiner_pipes) - 1;
}
-u8 intel_crtc_bigjoiner_slave_pipes(const struct intel_crtc_state *crtc_state)
+u8 intel_crtc_joiner_secondary_pipes(const struct intel_crtc_state *crtc_state)
{
- if (crtc_state->bigjoiner_pipes)
- return crtc_state->bigjoiner_pipes & ~BIT(bigjoiner_master_pipe(crtc_state));
+ if (crtc_state->joiner_pipes)
+ return crtc_state->joiner_pipes & ~BIT(joiner_primary_pipe(crtc_state));
else
return 0;
}
-bool intel_crtc_is_bigjoiner_slave(const struct intel_crtc_state *crtc_state)
+bool intel_crtc_is_joiner_secondary(const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
- return crtc_state->bigjoiner_pipes &&
- crtc->pipe != bigjoiner_master_pipe(crtc_state);
+ return crtc_state->joiner_pipes &&
+ crtc->pipe != joiner_primary_pipe(crtc_state);
}
-bool intel_crtc_is_bigjoiner_master(const struct intel_crtc_state *crtc_state)
+bool intel_crtc_is_joiner_primary(const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
- return crtc_state->bigjoiner_pipes &&
- crtc->pipe == bigjoiner_master_pipe(crtc_state);
+ return crtc_state->joiner_pipes &&
+ crtc->pipe == joiner_primary_pipe(crtc_state);
}
-static int intel_bigjoiner_num_pipes(const struct intel_crtc_state *crtc_state)
+static int intel_joiner_num_pipes(const struct intel_crtc_state *crtc_state)
{
- return hweight8(crtc_state->bigjoiner_pipes);
+ return hweight8(crtc_state->joiner_pipes);
}
u8 intel_crtc_joined_pipe_mask(const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
- return BIT(crtc->pipe) | crtc_state->bigjoiner_pipes;
+ return BIT(crtc->pipe) | crtc_state->joiner_pipes;
}
-struct intel_crtc *intel_master_crtc(const struct intel_crtc_state *crtc_state)
+struct intel_crtc *intel_primary_crtc(const struct intel_crtc_state *crtc_state)
{
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
- if (intel_crtc_is_bigjoiner_slave(crtc_state))
- return intel_crtc_for_pipe(i915, bigjoiner_master_pipe(crtc_state));
+ if (intel_crtc_is_joiner_secondary(crtc_state))
+ return intel_crtc_for_pipe(i915, joiner_primary_pipe(crtc_state));
else
return to_intel_crtc(crtc_state->uapi.crtc);
}
@@ -302,7 +307,7 @@ intel_wait_for_pipe_off(const struct intel_crtc_state *old_crtc_state)
enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder;
/* Wait for the Pipe State to go off */
- if (intel_de_wait_for_clear(dev_priv, TRANSCONF(cpu_transcoder),
+ if (intel_de_wait_for_clear(dev_priv, TRANSCONF(dev_priv, cpu_transcoder),
TRANSCONF_STATE_ENABLE, 100))
drm_WARN(&dev_priv->drm, 1, "pipe_off wait timed out\n");
} else {
@@ -324,7 +329,8 @@ void assert_transcoder(struct drm_i915_private *dev_priv,
power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder);
wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
if (wakeref) {
- u32 val = intel_de_read(dev_priv, TRANSCONF(cpu_transcoder));
+ u32 val = intel_de_read(dev_priv,
+ TRANSCONF(dev_priv, cpu_transcoder));
cur_state = !!(val & TRANSCONF_ENABLE);
intel_display_power_put(dev_priv, power_domain, wakeref);
@@ -377,11 +383,11 @@ void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
fallthrough;
case PORT_B:
port_mask = DPLL_PORTB_READY_MASK;
- dpll_reg = DPLL(0);
+ dpll_reg = DPLL(dev_priv, 0);
break;
case PORT_C:
port_mask = DPLL_PORTC_READY_MASK;
- dpll_reg = DPLL(0);
+ dpll_reg = DPLL(dev_priv, 0);
expected_mask <<= 4;
break;
case PORT_D:
@@ -433,7 +439,7 @@ void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state)
/* Wa_22012358565:adl-p */
if (DISPLAY_VER(dev_priv) == 13)
- intel_de_rmw(dev_priv, PIPE_ARB_CTL(pipe),
+ intel_de_rmw(dev_priv, PIPE_ARB_CTL(dev_priv, pipe),
0, PIPE_ARB_USE_PROG_SLOTS);
if (DISPLAY_VER(dev_priv) >= 14) {
@@ -448,7 +454,7 @@ void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state)
clear, set);
}
- val = intel_de_read(dev_priv, TRANSCONF(cpu_transcoder));
+ val = intel_de_read(dev_priv, TRANSCONF(dev_priv, cpu_transcoder));
if (val & TRANSCONF_ENABLE) {
/* we keep both pipes enabled on 830 */
drm_WARN_ON(&dev_priv->drm, !IS_I830(dev_priv));
@@ -463,9 +469,9 @@ void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state)
TRANSCONF_PIXEL_COUNT_SCALING_X4);
}
- intel_de_write(dev_priv, TRANSCONF(cpu_transcoder),
+ intel_de_write(dev_priv, TRANSCONF(dev_priv, cpu_transcoder),
val | TRANSCONF_ENABLE);
- intel_de_posting_read(dev_priv, TRANSCONF(cpu_transcoder));
+ intel_de_posting_read(dev_priv, TRANSCONF(dev_priv, cpu_transcoder));
/*
* Until the pipe starts PIPEDSL reads will return a stale value,
@@ -494,7 +500,7 @@ void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state)
*/
assert_planes_disabled(crtc);
- val = intel_de_read(dev_priv, TRANSCONF(cpu_transcoder));
+ val = intel_de_read(dev_priv, TRANSCONF(dev_priv, cpu_transcoder));
if ((val & TRANSCONF_ENABLE) == 0)
return;
@@ -514,7 +520,7 @@ void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state)
old_crtc_state->dsc.compression_enable)
val &= ~TRANSCONF_PIXEL_COUNT_SCALING_MASK;
- intel_de_write(dev_priv, TRANSCONF(cpu_transcoder), val);
+ intel_de_write(dev_priv, TRANSCONF(dev_priv, cpu_transcoder), val);
if (DISPLAY_VER(dev_priv) >= 12)
intel_de_rmw(dev_priv, hsw_chicken_trans_reg(dev_priv, cpu_transcoder),
@@ -797,14 +803,14 @@ intel_get_crtc_new_encoder(const struct intel_atomic_state *state,
const struct drm_connector_state *connector_state;
const struct drm_connector *connector;
struct intel_encoder *encoder = NULL;
- struct intel_crtc *master_crtc;
+ struct intel_crtc *primary_crtc;
int num_encoders = 0;
int i;
- master_crtc = intel_master_crtc(crtc_state);
+ primary_crtc = intel_primary_crtc(crtc_state);
for_each_new_connector_in_state(&state->base, connector, connector_state, i) {
- if (connector_state->crtc != &master_crtc->base)
+ if (connector_state->crtc != &primary_crtc->base)
continue;
encoder = to_intel_encoder(connector_state->best_encoder);
@@ -813,7 +819,7 @@ intel_get_crtc_new_encoder(const struct intel_atomic_state *state,
drm_WARN(state->base.dev, num_encoders != 1,
"%d encoders for pipe %c\n",
- num_encoders, pipe_name(master_crtc->pipe));
+ num_encoders, pipe_name(primary_crtc->pipe));
return encoder;
}
@@ -1000,6 +1006,13 @@ static bool vrr_params_changed(const struct intel_crtc_state *old_crtc_state,
old_crtc_state->vrr.pipeline_full != new_crtc_state->vrr.pipeline_full;
}
+static bool cmrr_params_changed(const struct intel_crtc_state *old_crtc_state,
+ const struct intel_crtc_state *new_crtc_state)
+{
+ return old_crtc_state->cmrr.cmrr_m != new_crtc_state->cmrr.cmrr_m ||
+ old_crtc_state->cmrr.cmrr_n != new_crtc_state->cmrr.cmrr_n;
+}
+
static bool vrr_enabling(const struct intel_crtc_state *old_crtc_state,
const struct intel_crtc_state *new_crtc_state)
{
@@ -1140,7 +1153,7 @@ static void intel_crtc_async_flip_disable_wa(struct intel_atomic_state *state,
int i;
for_each_old_intel_plane_in_state(state, plane, old_plane_state, i) {
- if (plane->need_async_flip_disable_wa &&
+ if (plane->need_async_flip_toggle_wa &&
plane->pipe == crtc->pipe &&
disable_async_flip_planes & BIT(plane->id)) {
/*
@@ -1641,7 +1654,7 @@ static void hsw_configure_cpu_transcoder(const struct intel_crtc_state *crtc_sta
intel_vrr_set_transcoder_timings(crtc_state);
if (cpu_transcoder != TRANSCODER_EDP)
- intel_de_write(dev_priv, TRANS_MULT(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_MULT(dev_priv, cpu_transcoder),
crtc_state->pixel_multiplier - 1);
hsw_set_frame_start_delay(crtc_state);
@@ -1856,16 +1869,17 @@ static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state)
* according to register description and PRM.
*/
drm_WARN_ON(&dev_priv->drm,
- intel_de_read(dev_priv, PFIT_CONTROL) & PFIT_ENABLE);
+ intel_de_read(dev_priv, PFIT_CONTROL(dev_priv)) & PFIT_ENABLE);
assert_transcoder_disabled(dev_priv, crtc_state->cpu_transcoder);
- intel_de_write(dev_priv, PFIT_PGM_RATIOS,
+ intel_de_write(dev_priv, PFIT_PGM_RATIOS(dev_priv),
crtc_state->gmch_pfit.pgm_ratios);
- intel_de_write(dev_priv, PFIT_CONTROL, crtc_state->gmch_pfit.control);
+ intel_de_write(dev_priv, PFIT_CONTROL(dev_priv),
+ crtc_state->gmch_pfit.control);
/* Border color in case we don't scale up to the full screen. Black by
* default, change to something else for debugging. */
- intel_de_write(dev_priv, BCLRPAT(crtc->pipe), 0);
+ intel_de_write(dev_priv, BCLRPAT(dev_priv, crtc->pipe), 0);
}
/* Prefer intel_encoder_is_combo() */
@@ -1894,11 +1908,10 @@ bool intel_phy_is_combo(struct drm_i915_private *dev_priv, enum phy phy)
bool intel_phy_is_tc(struct drm_i915_private *dev_priv, enum phy phy)
{
/*
- * DG2's "TC1", although TC-capable output, doesn't share the same flow
- * as other platforms on the display engine side and rather rely on the
- * SNPS PHY, that is programmed separately
+ * Discrete GPU phy's are not attached to FIA's to support TC
+ * subsystem Legacy or non-legacy, and only support native DP/HDMI
*/
- if (IS_DG2(dev_priv))
+ if (IS_DGFX(dev_priv))
return false;
if (DISPLAY_VER(dev_priv) >= 13)
@@ -2102,8 +2115,9 @@ static void valleyview_crtc_enable(struct intel_atomic_state *state,
intel_de_write(dev_priv, VLV_PIPE_MSA_MISC(pipe), 0);
if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
- intel_de_write(dev_priv, CHV_BLEND(pipe), CHV_BLEND_LEGACY);
- intel_de_write(dev_priv, CHV_CANVAS(pipe), 0);
+ intel_de_write(dev_priv, CHV_BLEND(dev_priv, pipe),
+ CHV_BLEND_LEGACY);
+ intel_de_write(dev_priv, CHV_CANVAS(dev_priv, pipe), 0);
}
crtc->active = true;
@@ -2191,8 +2205,8 @@ static void i9xx_pfit_disable(const struct intel_crtc_state *old_crtc_state)
assert_transcoder_disabled(dev_priv, old_crtc_state->cpu_transcoder);
drm_dbg_kms(&dev_priv->drm, "disabling pfit, current: 0x%08x\n",
- intel_de_read(dev_priv, PFIT_CONTROL));
- intel_de_write(dev_priv, PFIT_CONTROL, 0);
+ intel_de_read(dev_priv, PFIT_CONTROL(dev_priv)));
+ intel_de_write(dev_priv, PFIT_CONTROL(dev_priv), 0);
}
static void i9xx_crtc_disable(struct intel_atomic_state *state,
@@ -2314,10 +2328,10 @@ static void intel_crtc_compute_pixel_rate(struct intel_crtc_state *crtc_state)
ilk_pipe_pixel_rate(crtc_state);
}
-static void intel_bigjoiner_adjust_timings(const struct intel_crtc_state *crtc_state,
- struct drm_display_mode *mode)
+static void intel_joiner_adjust_timings(const struct intel_crtc_state *crtc_state,
+ struct drm_display_mode *mode)
{
- int num_pipes = intel_bigjoiner_num_pipes(crtc_state);
+ int num_pipes = intel_joiner_num_pipes(crtc_state);
if (num_pipes < 2)
return;
@@ -2381,11 +2395,11 @@ static void intel_crtc_readout_derived_state(struct intel_crtc_state *crtc_state
drm_mode_copy(mode, pipe_mode);
intel_mode_from_crtc_timings(mode, mode);
mode->hdisplay = drm_rect_width(&crtc_state->pipe_src) *
- (intel_bigjoiner_num_pipes(crtc_state) ?: 1);
+ (intel_joiner_num_pipes(crtc_state) ?: 1);
mode->vdisplay = drm_rect_height(&crtc_state->pipe_src);
- /* Derive per-pipe timings in case bigjoiner is used */
- intel_bigjoiner_adjust_timings(crtc_state, pipe_mode);
+ /* Derive per-pipe timings in case joiner is used */
+ intel_joiner_adjust_timings(crtc_state, pipe_mode);
intel_mode_from_crtc_timings(pipe_mode, pipe_mode);
intel_crtc_compute_pixel_rate(crtc_state);
@@ -2399,9 +2413,9 @@ void intel_encoder_get_config(struct intel_encoder *encoder,
intel_crtc_readout_derived_state(crtc_state);
}
-static void intel_bigjoiner_compute_pipe_src(struct intel_crtc_state *crtc_state)
+static void intel_joiner_compute_pipe_src(struct intel_crtc_state *crtc_state)
{
- int num_pipes = intel_bigjoiner_num_pipes(crtc_state);
+ int num_pipes = intel_joiner_num_pipes(crtc_state);
int width, height;
if (num_pipes < 2)
@@ -2419,7 +2433,7 @@ static int intel_crtc_compute_pipe_src(struct intel_crtc_state *crtc_state)
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
- intel_bigjoiner_compute_pipe_src(crtc_state);
+ intel_joiner_compute_pipe_src(crtc_state);
/*
* Pipe horizontal size must be even in:
@@ -2464,8 +2478,8 @@ static int intel_crtc_compute_pipe_mode(struct intel_crtc_state *crtc_state)
/* Expand MSO per-segment transcoder timings to full */
intel_splitter_adjust_timings(crtc_state, pipe_mode);
- /* Derive per-pipe timings in case bigjoiner is used */
- intel_bigjoiner_adjust_timings(crtc_state, pipe_mode);
+ /* Derive per-pipe timings in case joiner is used */
+ intel_joiner_adjust_timings(crtc_state, pipe_mode);
intel_mode_from_crtc_timings(pipe_mode, pipe_mode);
if (DISPLAY_VER(i915) < 4) {
@@ -2634,8 +2648,10 @@ void intel_cpu_transcoder_set_m1_n1(struct intel_crtc *crtc,
if (DISPLAY_VER(dev_priv) >= 5)
intel_set_m_n(dev_priv, m_n,
- PIPE_DATA_M1(transcoder), PIPE_DATA_N1(transcoder),
- PIPE_LINK_M1(transcoder), PIPE_LINK_N1(transcoder));
+ PIPE_DATA_M1(dev_priv, transcoder),
+ PIPE_DATA_N1(dev_priv, transcoder),
+ PIPE_LINK_M1(dev_priv, transcoder),
+ PIPE_LINK_N1(dev_priv, transcoder));
else
intel_set_m_n(dev_priv, m_n,
PIPE_DATA_M_G4X(pipe), PIPE_DATA_N_G4X(pipe),
@@ -2652,8 +2668,10 @@ void intel_cpu_transcoder_set_m2_n2(struct intel_crtc *crtc,
return;
intel_set_m_n(dev_priv, m_n,
- PIPE_DATA_M2(transcoder), PIPE_DATA_N2(transcoder),
- PIPE_LINK_M2(transcoder), PIPE_LINK_N2(transcoder));
+ PIPE_DATA_M2(dev_priv, transcoder),
+ PIPE_DATA_N2(dev_priv, transcoder),
+ PIPE_LINK_M2(dev_priv, transcoder),
+ PIPE_LINK_N2(dev_priv, transcoder));
}
static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state)
@@ -2692,7 +2710,8 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta
* TRANS_SET_CONTEXT_LATENCY to configure the pipe vblank start.
*/
if (DISPLAY_VER(dev_priv) >= 13) {
- intel_de_write(dev_priv, TRANS_SET_CONTEXT_LATENCY(cpu_transcoder),
+ intel_de_write(dev_priv,
+ TRANS_SET_CONTEXT_LATENCY(dev_priv, cpu_transcoder),
crtc_vblank_start - crtc_vdisplay);
/*
@@ -2703,26 +2722,27 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta
}
if (DISPLAY_VER(dev_priv) >= 4)
- intel_de_write(dev_priv, TRANS_VSYNCSHIFT(cpu_transcoder),
+ intel_de_write(dev_priv,
+ TRANS_VSYNCSHIFT(dev_priv, cpu_transcoder),
vsyncshift);
- intel_de_write(dev_priv, TRANS_HTOTAL(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_HTOTAL(dev_priv, cpu_transcoder),
HACTIVE(adjusted_mode->crtc_hdisplay - 1) |
HTOTAL(adjusted_mode->crtc_htotal - 1));
- intel_de_write(dev_priv, TRANS_HBLANK(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_HBLANK(dev_priv, cpu_transcoder),
HBLANK_START(adjusted_mode->crtc_hblank_start - 1) |
HBLANK_END(adjusted_mode->crtc_hblank_end - 1));
- intel_de_write(dev_priv, TRANS_HSYNC(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_HSYNC(dev_priv, cpu_transcoder),
HSYNC_START(adjusted_mode->crtc_hsync_start - 1) |
HSYNC_END(adjusted_mode->crtc_hsync_end - 1));
- intel_de_write(dev_priv, TRANS_VTOTAL(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_VTOTAL(dev_priv, cpu_transcoder),
VACTIVE(crtc_vdisplay - 1) |
VTOTAL(crtc_vtotal - 1));
- intel_de_write(dev_priv, TRANS_VBLANK(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_VBLANK(dev_priv, cpu_transcoder),
VBLANK_START(crtc_vblank_start - 1) |
VBLANK_END(crtc_vblank_end - 1));
- intel_de_write(dev_priv, TRANS_VSYNC(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_VSYNC(dev_priv, cpu_transcoder),
VSYNC_START(adjusted_mode->crtc_vsync_start - 1) |
VSYNC_END(adjusted_mode->crtc_vsync_end - 1));
@@ -2732,7 +2752,7 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta
* bits. */
if (IS_HASWELL(dev_priv) && cpu_transcoder == TRANSCODER_EDP &&
(pipe == PIPE_B || pipe == PIPE_C))
- intel_de_write(dev_priv, TRANS_VTOTAL(pipe),
+ intel_de_write(dev_priv, TRANS_VTOTAL(dev_priv, pipe),
VACTIVE(crtc_vdisplay - 1) |
VTOTAL(crtc_vtotal - 1));
}
@@ -2756,14 +2776,14 @@ static void intel_set_transcoder_timings_lrr(const struct intel_crtc_state *crtc
* The hardware actually ignores TRANS_VBLANK.VBLANK_END in DP mode.
* But let's write it anyway to keep the state checker happy.
*/
- intel_de_write(dev_priv, TRANS_VBLANK(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_VBLANK(dev_priv, cpu_transcoder),
VBLANK_START(crtc_vblank_start - 1) |
VBLANK_END(crtc_vblank_end - 1));
/*
* The double buffer latch point for TRANS_VTOTAL
* is the transcoder's undelayed vblank.
*/
- intel_de_write(dev_priv, TRANS_VTOTAL(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_VTOTAL(dev_priv, cpu_transcoder),
VACTIVE(crtc_vdisplay - 1) |
VTOTAL(crtc_vtotal - 1));
}
@@ -2779,7 +2799,7 @@ static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state)
/* pipesrc controls the size that is scaled from, which should
* always be the user's requested size.
*/
- intel_de_write(dev_priv, PIPESRC(pipe),
+ intel_de_write(dev_priv, PIPESRC(dev_priv, pipe),
PIPESRC_WIDTH(width - 1) | PIPESRC_HEIGHT(height - 1));
}
@@ -2793,9 +2813,11 @@ static bool intel_pipe_is_interlaced(const struct intel_crtc_state *crtc_state)
if (DISPLAY_VER(dev_priv) >= 9 ||
IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
- return intel_de_read(dev_priv, TRANSCONF(cpu_transcoder)) & TRANSCONF_INTERLACE_MASK_HSW;
+ return intel_de_read(dev_priv,
+ TRANSCONF(dev_priv, cpu_transcoder)) & TRANSCONF_INTERLACE_MASK_HSW;
else
- return intel_de_read(dev_priv, TRANSCONF(cpu_transcoder)) & TRANSCONF_INTERLACE_MASK;
+ return intel_de_read(dev_priv,
+ TRANSCONF(dev_priv, cpu_transcoder)) & TRANSCONF_INTERLACE_MASK;
}
static void intel_get_transcoder_timings(struct intel_crtc *crtc,
@@ -2807,31 +2829,33 @@ static void intel_get_transcoder_timings(struct intel_crtc *crtc,
struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
u32 tmp;
- tmp = intel_de_read(dev_priv, TRANS_HTOTAL(cpu_transcoder));
+ tmp = intel_de_read(dev_priv, TRANS_HTOTAL(dev_priv, cpu_transcoder));
adjusted_mode->crtc_hdisplay = REG_FIELD_GET(HACTIVE_MASK, tmp) + 1;
adjusted_mode->crtc_htotal = REG_FIELD_GET(HTOTAL_MASK, tmp) + 1;
if (!transcoder_is_dsi(cpu_transcoder)) {
- tmp = intel_de_read(dev_priv, TRANS_HBLANK(cpu_transcoder));
+ tmp = intel_de_read(dev_priv,
+ TRANS_HBLANK(dev_priv, cpu_transcoder));
adjusted_mode->crtc_hblank_start = REG_FIELD_GET(HBLANK_START_MASK, tmp) + 1;
adjusted_mode->crtc_hblank_end = REG_FIELD_GET(HBLANK_END_MASK, tmp) + 1;
}
- tmp = intel_de_read(dev_priv, TRANS_HSYNC(cpu_transcoder));
+ tmp = intel_de_read(dev_priv, TRANS_HSYNC(dev_priv, cpu_transcoder));
adjusted_mode->crtc_hsync_start = REG_FIELD_GET(HSYNC_START_MASK, tmp) + 1;
adjusted_mode->crtc_hsync_end = REG_FIELD_GET(HSYNC_END_MASK, tmp) + 1;
- tmp = intel_de_read(dev_priv, TRANS_VTOTAL(cpu_transcoder));
+ tmp = intel_de_read(dev_priv, TRANS_VTOTAL(dev_priv, cpu_transcoder));
adjusted_mode->crtc_vdisplay = REG_FIELD_GET(VACTIVE_MASK, tmp) + 1;
adjusted_mode->crtc_vtotal = REG_FIELD_GET(VTOTAL_MASK, tmp) + 1;
/* FIXME TGL+ DSI transcoders have this! */
if (!transcoder_is_dsi(cpu_transcoder)) {
- tmp = intel_de_read(dev_priv, TRANS_VBLANK(cpu_transcoder));
+ tmp = intel_de_read(dev_priv,
+ TRANS_VBLANK(dev_priv, cpu_transcoder));
adjusted_mode->crtc_vblank_start = REG_FIELD_GET(VBLANK_START_MASK, tmp) + 1;
adjusted_mode->crtc_vblank_end = REG_FIELD_GET(VBLANK_END_MASK, tmp) + 1;
}
- tmp = intel_de_read(dev_priv, TRANS_VSYNC(cpu_transcoder));
+ tmp = intel_de_read(dev_priv, TRANS_VSYNC(dev_priv, cpu_transcoder));
adjusted_mode->crtc_vsync_start = REG_FIELD_GET(VSYNC_START_MASK, tmp) + 1;
adjusted_mode->crtc_vsync_end = REG_FIELD_GET(VSYNC_END_MASK, tmp) + 1;
@@ -2844,24 +2868,25 @@ static void intel_get_transcoder_timings(struct intel_crtc *crtc,
if (DISPLAY_VER(dev_priv) >= 13 && !transcoder_is_dsi(cpu_transcoder))
adjusted_mode->crtc_vblank_start =
adjusted_mode->crtc_vdisplay +
- intel_de_read(dev_priv, TRANS_SET_CONTEXT_LATENCY(cpu_transcoder));
+ intel_de_read(dev_priv,
+ TRANS_SET_CONTEXT_LATENCY(dev_priv, cpu_transcoder));
}
-static void intel_bigjoiner_adjust_pipe_src(struct intel_crtc_state *crtc_state)
+static void intel_joiner_adjust_pipe_src(struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
- int num_pipes = intel_bigjoiner_num_pipes(crtc_state);
- enum pipe master_pipe, pipe = crtc->pipe;
+ int num_pipes = intel_joiner_num_pipes(crtc_state);
+ enum pipe primary_pipe, pipe = crtc->pipe;
int width;
if (num_pipes < 2)
return;
- master_pipe = bigjoiner_master_pipe(crtc_state);
+ primary_pipe = joiner_primary_pipe(crtc_state);
width = drm_rect_width(&crtc_state->pipe_src);
drm_rect_translate_to(&crtc_state->pipe_src,
- (pipe - master_pipe) * width, 0);
+ (pipe - primary_pipe) * width, 0);
}
static void intel_get_pipe_src_size(struct intel_crtc *crtc,
@@ -2871,13 +2896,13 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
struct drm_i915_private *dev_priv = to_i915(dev);
u32 tmp;
- tmp = intel_de_read(dev_priv, PIPESRC(crtc->pipe));
+ tmp = intel_de_read(dev_priv, PIPESRC(dev_priv, crtc->pipe));
drm_rect_init(&pipe_config->pipe_src, 0, 0,
REG_FIELD_GET(PIPESRC_WIDTH_MASK, tmp) + 1,
REG_FIELD_GET(PIPESRC_HEIGHT_MASK, tmp) + 1);
- intel_bigjoiner_adjust_pipe_src(pipe_config);
+ intel_joiner_adjust_pipe_src(pipe_config);
}
void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state)
@@ -2944,8 +2969,8 @@ void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state)
val |= TRANSCONF_FRAME_START_DELAY(crtc_state->framestart_delay - 1);
- intel_de_write(dev_priv, TRANSCONF(cpu_transcoder), val);
- intel_de_posting_read(dev_priv, TRANSCONF(cpu_transcoder));
+ intel_de_write(dev_priv, TRANSCONF(dev_priv, cpu_transcoder), val);
+ intel_de_posting_read(dev_priv, TRANSCONF(dev_priv, cpu_transcoder));
}
static bool i9xx_has_pfit(struct drm_i915_private *dev_priv)
@@ -2967,7 +2992,7 @@ static void i9xx_get_pfit_config(struct intel_crtc_state *crtc_state)
if (!i9xx_has_pfit(dev_priv))
return;
- tmp = intel_de_read(dev_priv, PFIT_CONTROL);
+ tmp = intel_de_read(dev_priv, PFIT_CONTROL(dev_priv));
if (!(tmp & PFIT_ENABLE))
return;
@@ -2982,7 +3007,7 @@ static void i9xx_get_pfit_config(struct intel_crtc_state *crtc_state)
crtc_state->gmch_pfit.control = tmp;
crtc_state->gmch_pfit.pgm_ratios =
- intel_de_read(dev_priv, PFIT_PGM_RATIOS);
+ intel_de_read(dev_priv, PFIT_PGM_RATIOS(dev_priv));
}
static enum intel_output_format
@@ -3027,7 +3052,8 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
ret = false;
- tmp = intel_de_read(dev_priv, TRANSCONF(pipe_config->cpu_transcoder));
+ tmp = intel_de_read(dev_priv,
+ TRANSCONF(dev_priv, pipe_config->cpu_transcoder));
if (!(tmp & TRANSCONF_ENABLE))
goto out;
@@ -3174,8 +3200,8 @@ void ilk_set_pipeconf(const struct intel_crtc_state *crtc_state)
val |= TRANSCONF_FRAME_START_DELAY(crtc_state->framestart_delay - 1);
val |= TRANSCONF_MSA_TIMING_DELAY(crtc_state->msa_timing_delay);
- intel_de_write(dev_priv, TRANSCONF(cpu_transcoder), val);
- intel_de_posting_read(dev_priv, TRANSCONF(cpu_transcoder));
+ intel_de_write(dev_priv, TRANSCONF(dev_priv, cpu_transcoder), val);
+ intel_de_posting_read(dev_priv, TRANSCONF(dev_priv, cpu_transcoder));
}
static void hsw_set_transconf(const struct intel_crtc_state *crtc_state)
@@ -3204,8 +3230,8 @@ static void hsw_set_transconf(const struct intel_crtc_state *crtc_state)
crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)
val |= TRANSCONF_OUTPUT_COLORSPACE_YUV_HSW;
- intel_de_write(dev_priv, TRANSCONF(cpu_transcoder), val);
- intel_de_posting_read(dev_priv, TRANSCONF(cpu_transcoder));
+ intel_de_write(dev_priv, TRANSCONF(dev_priv, cpu_transcoder), val);
+ intel_de_posting_read(dev_priv, TRANSCONF(dev_priv, cpu_transcoder));
}
static void bdw_set_pipe_misc(const struct intel_crtc_state *crtc_state)
@@ -3324,8 +3350,10 @@ void intel_cpu_transcoder_get_m1_n1(struct intel_crtc *crtc,
if (DISPLAY_VER(dev_priv) >= 5)
intel_get_m_n(dev_priv, m_n,
- PIPE_DATA_M1(transcoder), PIPE_DATA_N1(transcoder),
- PIPE_LINK_M1(transcoder), PIPE_LINK_N1(transcoder));
+ PIPE_DATA_M1(dev_priv, transcoder),
+ PIPE_DATA_N1(dev_priv, transcoder),
+ PIPE_LINK_M1(dev_priv, transcoder),
+ PIPE_LINK_N1(dev_priv, transcoder));
else
intel_get_m_n(dev_priv, m_n,
PIPE_DATA_M_G4X(pipe), PIPE_DATA_N_G4X(pipe),
@@ -3342,8 +3370,10 @@ void intel_cpu_transcoder_get_m2_n2(struct intel_crtc *crtc,
return;
intel_get_m_n(dev_priv, m_n,
- PIPE_DATA_M2(transcoder), PIPE_DATA_N2(transcoder),
- PIPE_LINK_M2(transcoder), PIPE_LINK_N2(transcoder));
+ PIPE_DATA_M2(dev_priv, transcoder),
+ PIPE_DATA_N2(dev_priv, transcoder),
+ PIPE_LINK_M2(dev_priv, transcoder),
+ PIPE_LINK_N2(dev_priv, transcoder));
}
static void ilk_get_pfit_config(struct intel_crtc_state *crtc_state)
@@ -3400,7 +3430,8 @@ static bool ilk_get_pipe_config(struct intel_crtc *crtc,
pipe_config->shared_dpll = NULL;
ret = false;
- tmp = intel_de_read(dev_priv, TRANSCONF(pipe_config->cpu_transcoder));
+ tmp = intel_de_read(dev_priv,
+ TRANSCONF(dev_priv, pipe_config->cpu_transcoder));
if (!(tmp & TRANSCONF_ENABLE))
goto out;
@@ -3461,7 +3492,7 @@ out:
return ret;
}
-static u8 bigjoiner_pipes(struct drm_i915_private *i915)
+static u8 joiner_pipes(struct drm_i915_private *i915)
{
u8 pipes;
@@ -3485,21 +3516,22 @@ static bool transcoder_ddi_func_is_enabled(struct drm_i915_private *dev_priv,
power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder);
with_intel_display_power_if_enabled(dev_priv, power_domain, wakeref)
- tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
+ tmp = intel_de_read(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder));
return tmp & TRANS_DDI_FUNC_ENABLE;
}
-static void enabled_bigjoiner_pipes(struct drm_i915_private *dev_priv,
- u8 *master_pipes, u8 *slave_pipes)
+static void enabled_joiner_pipes(struct drm_i915_private *dev_priv,
+ u8 *primary_pipes, u8 *secondary_pipes)
{
struct intel_crtc *crtc;
- *master_pipes = 0;
- *slave_pipes = 0;
+ *primary_pipes = 0;
+ *secondary_pipes = 0;
for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc,
- bigjoiner_pipes(dev_priv)) {
+ joiner_pipes(dev_priv)) {
enum intel_display_power_domain power_domain;
enum pipe pipe = crtc->pipe;
intel_wakeref_t wakeref;
@@ -3511,10 +3543,10 @@ static void enabled_bigjoiner_pipes(struct drm_i915_private *dev_priv,
if (!(tmp & BIG_JOINER_ENABLE))
continue;
- if (tmp & MASTER_BIG_JOINER_ENABLE)
- *master_pipes |= BIT(pipe);
+ if (tmp & PRIMARY_BIG_JOINER_ENABLE)
+ *primary_pipes |= BIT(pipe);
else
- *slave_pipes |= BIT(pipe);
+ *secondary_pipes |= BIT(pipe);
}
if (DISPLAY_VER(dev_priv) < 13)
@@ -3524,48 +3556,48 @@ static void enabled_bigjoiner_pipes(struct drm_i915_private *dev_priv,
with_intel_display_power_if_enabled(dev_priv, power_domain, wakeref) {
u32 tmp = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL1(pipe));
- if (tmp & UNCOMPRESSED_JOINER_MASTER)
- *master_pipes |= BIT(pipe);
- if (tmp & UNCOMPRESSED_JOINER_SLAVE)
- *slave_pipes |= BIT(pipe);
+ if (tmp & UNCOMPRESSED_JOINER_PRIMARY)
+ *primary_pipes |= BIT(pipe);
+ if (tmp & UNCOMPRESSED_JOINER_SECONDARY)
+ *secondary_pipes |= BIT(pipe);
}
}
- /* Bigjoiner pipes should always be consecutive master and slave */
- drm_WARN(&dev_priv->drm, *slave_pipes != *master_pipes << 1,
- "Bigjoiner misconfigured (master pipes 0x%x, slave pipes 0x%x)\n",
- *master_pipes, *slave_pipes);
+ /* Joiner pipes should always be consecutive primary and secondary */
+ drm_WARN(&dev_priv->drm, *secondary_pipes != *primary_pipes << 1,
+ "Joiner misconfigured (primary pipes 0x%x, secondary pipes 0x%x)\n",
+ *primary_pipes, *secondary_pipes);
}
-static enum pipe get_bigjoiner_master_pipe(enum pipe pipe, u8 master_pipes, u8 slave_pipes)
+static enum pipe get_joiner_primary_pipe(enum pipe pipe, u8 primary_pipes, u8 secondary_pipes)
{
- if ((slave_pipes & BIT(pipe)) == 0)
+ if ((secondary_pipes & BIT(pipe)) == 0)
return pipe;
/* ignore everything above our pipe */
- master_pipes &= ~GENMASK(7, pipe);
+ primary_pipes &= ~GENMASK(7, pipe);
- /* highest remaining bit should be our master pipe */
- return fls(master_pipes) - 1;
+ /* highest remaining bit should be our primary pipe */
+ return fls(primary_pipes) - 1;
}
-static u8 get_bigjoiner_slave_pipes(enum pipe pipe, u8 master_pipes, u8 slave_pipes)
+static u8 get_joiner_secondary_pipes(enum pipe pipe, u8 primary_pipes, u8 secondary_pipes)
{
- enum pipe master_pipe, next_master_pipe;
+ enum pipe primary_pipe, next_primary_pipe;
- master_pipe = get_bigjoiner_master_pipe(pipe, master_pipes, slave_pipes);
+ primary_pipe = get_joiner_primary_pipe(pipe, primary_pipes, secondary_pipes);
- if ((master_pipes & BIT(master_pipe)) == 0)
+ if ((primary_pipes & BIT(primary_pipe)) == 0)
return 0;
- /* ignore our master pipe and everything below it */
- master_pipes &= ~GENMASK(master_pipe, 0);
+ /* ignore our primary pipe and everything below it */
+ primary_pipes &= ~GENMASK(primary_pipe, 0);
/* make sure a high bit is set for the ffs() */
- master_pipes |= BIT(7);
- /* lowest remaining bit should be the next master pipe */
- next_master_pipe = ffs(master_pipes) - 1;
+ primary_pipes |= BIT(7);
+ /* lowest remaining bit should be the next primary pipe */
+ next_primary_pipe = ffs(primary_pipes) - 1;
- return slave_pipes & GENMASK(next_master_pipe - 1, master_pipe);
+ return secondary_pipes & GENMASK(next_primary_pipe - 1, primary_pipe);
}
static u8 hsw_panel_transcoders(struct drm_i915_private *i915)
@@ -3584,7 +3616,7 @@ static u8 hsw_enabled_transcoders(struct intel_crtc *crtc)
struct drm_i915_private *dev_priv = to_i915(dev);
u8 panel_transcoder_mask = hsw_panel_transcoders(dev_priv);
enum transcoder cpu_transcoder;
- u8 master_pipes, slave_pipes;
+ u8 primary_pipes, secondary_pipes;
u8 enabled_transcoders = 0;
/*
@@ -3600,7 +3632,8 @@ static u8 hsw_enabled_transcoders(struct intel_crtc *crtc)
power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder);
with_intel_display_power_if_enabled(dev_priv, power_domain, wakeref)
- tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
+ tmp = intel_de_read(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder));
if (!(tmp & TRANS_DDI_FUNC_ENABLE))
continue;
@@ -3630,16 +3663,16 @@ static u8 hsw_enabled_transcoders(struct intel_crtc *crtc)
enabled_transcoders |= BIT(cpu_transcoder);
}
- /* single pipe or bigjoiner master */
+ /* single pipe or joiner primary */
cpu_transcoder = (enum transcoder) crtc->pipe;
if (transcoder_ddi_func_is_enabled(dev_priv, cpu_transcoder))
enabled_transcoders |= BIT(cpu_transcoder);
- /* bigjoiner slave -> consider the master pipe's transcoder as well */
- enabled_bigjoiner_pipes(dev_priv, &master_pipes, &slave_pipes);
- if (slave_pipes & BIT(crtc->pipe)) {
+ /* joiner secondary -> consider the primary pipe's transcoder as well */
+ enabled_joiner_pipes(dev_priv, &primary_pipes, &secondary_pipes);
+ if (secondary_pipes & BIT(crtc->pipe)) {
cpu_transcoder = (enum transcoder)
- get_bigjoiner_master_pipe(crtc->pipe, master_pipes, slave_pipes);
+ get_joiner_primary_pipe(crtc->pipe, primary_pipes, secondary_pipes);
if (transcoder_ddi_func_is_enabled(dev_priv, cpu_transcoder))
enabled_transcoders |= BIT(cpu_transcoder);
}
@@ -3707,13 +3740,15 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc,
return false;
if (hsw_panel_transcoders(dev_priv) & BIT(pipe_config->cpu_transcoder)) {
- tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(pipe_config->cpu_transcoder));
+ tmp = intel_de_read(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, pipe_config->cpu_transcoder));
if ((tmp & TRANS_DDI_EDP_INPUT_MASK) == TRANS_DDI_EDP_INPUT_A_ONOFF)
pipe_config->pch_pfit.force_thru = true;
}
- tmp = intel_de_read(dev_priv, TRANSCONF(pipe_config->cpu_transcoder));
+ tmp = intel_de_read(dev_priv,
+ TRANSCONF(dev_priv, pipe_config->cpu_transcoder));
return tmp & TRANSCONF_ENABLE;
}
@@ -3764,21 +3799,21 @@ static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc,
return transcoder_is_dsi(pipe_config->cpu_transcoder);
}
-static void intel_bigjoiner_get_config(struct intel_crtc_state *crtc_state)
+static void intel_joiner_get_config(struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
- u8 master_pipes, slave_pipes;
+ u8 primary_pipes, secondary_pipes;
enum pipe pipe = crtc->pipe;
- enabled_bigjoiner_pipes(i915, &master_pipes, &slave_pipes);
+ enabled_joiner_pipes(i915, &primary_pipes, &secondary_pipes);
- if (((master_pipes | slave_pipes) & BIT(pipe)) == 0)
+ if (((primary_pipes | secondary_pipes) & BIT(pipe)) == 0)
return;
- crtc_state->bigjoiner_pipes =
- BIT(get_bigjoiner_master_pipe(pipe, master_pipes, slave_pipes)) |
- get_bigjoiner_slave_pipes(pipe, master_pipes, slave_pipes);
+ crtc_state->joiner_pipes =
+ BIT(get_joiner_primary_pipe(pipe, primary_pipes, secondary_pipes)) |
+ get_joiner_secondary_pipes(pipe, primary_pipes, secondary_pipes);
}
static bool hsw_get_pipe_config(struct intel_crtc *crtc,
@@ -3805,7 +3840,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
if (!active)
goto out;
- intel_bigjoiner_get_config(pipe_config);
+ intel_joiner_get_config(pipe_config);
intel_dsc_get_config(pipe_config);
if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
@@ -3819,7 +3854,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
if (IS_HASWELL(dev_priv)) {
u32 tmp = intel_de_read(dev_priv,
- TRANSCONF(pipe_config->cpu_transcoder));
+ TRANSCONF(dev_priv, pipe_config->cpu_transcoder));
if (tmp & TRANSCONF_OUTPUT_COLORSPACE_YUV_HSW)
pipe_config->output_format = INTEL_OUTPUT_FORMAT_YCBCR444;
@@ -3854,7 +3889,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
!transcoder_is_dsi(pipe_config->cpu_transcoder)) {
pipe_config->pixel_multiplier =
intel_de_read(dev_priv,
- TRANS_MULT(pipe_config->cpu_transcoder)) + 1;
+ TRANS_MULT(dev_priv, pipe_config->cpu_transcoder)) + 1;
} else {
pipe_config->pixel_multiplier = 1;
}
@@ -4030,11 +4065,12 @@ static int icl_add_linked_planes(struct intel_atomic_state *state)
return 0;
}
-static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
+static int icl_check_nv12_planes(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
- struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
- struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
- struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state);
+ struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+ struct intel_crtc_state *crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
struct intel_plane *plane, *linked;
struct intel_plane_state *plane_state;
int i;
@@ -4119,13 +4155,13 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
linked_state->uapi.dst = plane_state->uapi.dst;
if (icl_is_hdr_plane(dev_priv, plane->id)) {
- if (linked->id == PLANE_SPRITE5)
+ if (linked->id == PLANE_7)
plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_7_ICL;
- else if (linked->id == PLANE_SPRITE4)
+ else if (linked->id == PLANE_6)
plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_6_ICL;
- else if (linked->id == PLANE_SPRITE3)
+ else if (linked->id == PLANE_5)
plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_5_RKL;
- else if (linked->id == PLANE_SPRITE2)
+ else if (linked->id == PLANE_4)
plane_state->cus_ctl |= PLANE_CUS_Y_PLANE_4_RKL;
else
MISSING_CASE(linked->id);
@@ -4135,17 +4171,6 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
return 0;
}
-static bool c8_planes_changed(const struct intel_crtc_state *new_crtc_state)
-{
- struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
- struct intel_atomic_state *state =
- to_intel_atomic_state(new_crtc_state->uapi.state);
- const struct intel_crtc_state *old_crtc_state =
- intel_atomic_get_old_crtc_state(state, crtc);
-
- return !old_crtc_state->c8_planes != !new_crtc_state->c8_planes;
-}
-
static u16 hsw_linetime_wm(const struct intel_crtc_state *crtc_state)
{
const struct drm_display_mode *pipe_mode =
@@ -4244,18 +4269,9 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,
return ret;
}
- /*
- * May need to update pipe gamma enable bits
- * when C8 planes are getting enabled/disabled.
- */
- if (c8_planes_changed(crtc_state))
- crtc_state->uapi.color_mgmt_changed = true;
-
- if (intel_crtc_needs_color_update(crtc_state)) {
- ret = intel_color_check(crtc_state);
- if (ret)
- return ret;
- }
+ ret = intel_color_check(state, crtc);
+ if (ret)
+ return ret;
ret = intel_compute_pipe_wm(state, crtc);
if (ret) {
@@ -4464,7 +4480,7 @@ intel_crtc_copy_uapi_to_hw_state_nomodeset(struct intel_atomic_state *state,
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
- WARN_ON(intel_crtc_is_bigjoiner_slave(crtc_state));
+ WARN_ON(intel_crtc_is_joiner_secondary(crtc_state));
drm_property_replace_blob(&crtc_state->hw.degamma_lut,
crtc_state->uapi.degamma_lut);
@@ -4481,7 +4497,7 @@ intel_crtc_copy_uapi_to_hw_state_modeset(struct intel_atomic_state *state,
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
- WARN_ON(intel_crtc_is_bigjoiner_slave(crtc_state));
+ WARN_ON(intel_crtc_is_joiner_secondary(crtc_state));
crtc_state->hw.enable = crtc_state->uapi.enable;
crtc_state->hw.active = crtc_state->uapi.active;
@@ -4495,79 +4511,79 @@ intel_crtc_copy_uapi_to_hw_state_modeset(struct intel_atomic_state *state,
}
static void
-copy_bigjoiner_crtc_state_nomodeset(struct intel_atomic_state *state,
- struct intel_crtc *slave_crtc)
+copy_joiner_crtc_state_nomodeset(struct intel_atomic_state *state,
+ struct intel_crtc *secondary_crtc)
{
- struct intel_crtc_state *slave_crtc_state =
- intel_atomic_get_new_crtc_state(state, slave_crtc);
- struct intel_crtc *master_crtc = intel_master_crtc(slave_crtc_state);
- const struct intel_crtc_state *master_crtc_state =
- intel_atomic_get_new_crtc_state(state, master_crtc);
+ struct intel_crtc_state *secondary_crtc_state =
+ intel_atomic_get_new_crtc_state(state, secondary_crtc);
+ struct intel_crtc *primary_crtc = intel_primary_crtc(secondary_crtc_state);
+ const struct intel_crtc_state *primary_crtc_state =
+ intel_atomic_get_new_crtc_state(state, primary_crtc);
- drm_property_replace_blob(&slave_crtc_state->hw.degamma_lut,
- master_crtc_state->hw.degamma_lut);
- drm_property_replace_blob(&slave_crtc_state->hw.gamma_lut,
- master_crtc_state->hw.gamma_lut);
- drm_property_replace_blob(&slave_crtc_state->hw.ctm,
- master_crtc_state->hw.ctm);
+ drm_property_replace_blob(&secondary_crtc_state->hw.degamma_lut,
+ primary_crtc_state->hw.degamma_lut);
+ drm_property_replace_blob(&secondary_crtc_state->hw.gamma_lut,
+ primary_crtc_state->hw.gamma_lut);
+ drm_property_replace_blob(&secondary_crtc_state->hw.ctm,
+ primary_crtc_state->hw.ctm);
- slave_crtc_state->uapi.color_mgmt_changed = master_crtc_state->uapi.color_mgmt_changed;
+ secondary_crtc_state->uapi.color_mgmt_changed = primary_crtc_state->uapi.color_mgmt_changed;
}
static int
-copy_bigjoiner_crtc_state_modeset(struct intel_atomic_state *state,
- struct intel_crtc *slave_crtc)
-{
- struct intel_crtc_state *slave_crtc_state =
- intel_atomic_get_new_crtc_state(state, slave_crtc);
- struct intel_crtc *master_crtc = intel_master_crtc(slave_crtc_state);
- const struct intel_crtc_state *master_crtc_state =
- intel_atomic_get_new_crtc_state(state, master_crtc);
+copy_joiner_crtc_state_modeset(struct intel_atomic_state *state,
+ struct intel_crtc *secondary_crtc)
+{
+ struct intel_crtc_state *secondary_crtc_state =
+ intel_atomic_get_new_crtc_state(state, secondary_crtc);
+ struct intel_crtc *primary_crtc = intel_primary_crtc(secondary_crtc_state);
+ const struct intel_crtc_state *primary_crtc_state =
+ intel_atomic_get_new_crtc_state(state, primary_crtc);
struct intel_crtc_state *saved_state;
- WARN_ON(master_crtc_state->bigjoiner_pipes !=
- slave_crtc_state->bigjoiner_pipes);
+ WARN_ON(primary_crtc_state->joiner_pipes !=
+ secondary_crtc_state->joiner_pipes);
- saved_state = kmemdup(master_crtc_state, sizeof(*saved_state), GFP_KERNEL);
+ saved_state = kmemdup(primary_crtc_state, sizeof(*saved_state), GFP_KERNEL);
if (!saved_state)
return -ENOMEM;
/* preserve some things from the slave's original crtc state */
- saved_state->uapi = slave_crtc_state->uapi;
- saved_state->scaler_state = slave_crtc_state->scaler_state;
- saved_state->shared_dpll = slave_crtc_state->shared_dpll;
- saved_state->crc_enabled = slave_crtc_state->crc_enabled;
-
- intel_crtc_free_hw_state(slave_crtc_state);
- if (slave_crtc_state->dp_tunnel_ref.tunnel)
- drm_dp_tunnel_ref_put(&slave_crtc_state->dp_tunnel_ref);
- memcpy(slave_crtc_state, saved_state, sizeof(*slave_crtc_state));
+ saved_state->uapi = secondary_crtc_state->uapi;
+ saved_state->scaler_state = secondary_crtc_state->scaler_state;
+ saved_state->shared_dpll = secondary_crtc_state->shared_dpll;
+ saved_state->crc_enabled = secondary_crtc_state->crc_enabled;
+
+ intel_crtc_free_hw_state(secondary_crtc_state);
+ if (secondary_crtc_state->dp_tunnel_ref.tunnel)
+ drm_dp_tunnel_ref_put(&secondary_crtc_state->dp_tunnel_ref);
+ memcpy(secondary_crtc_state, saved_state, sizeof(*secondary_crtc_state));
kfree(saved_state);
/* Re-init hw state */
- memset(&slave_crtc_state->hw, 0, sizeof(slave_crtc_state->hw));
- slave_crtc_state->hw.enable = master_crtc_state->hw.enable;
- slave_crtc_state->hw.active = master_crtc_state->hw.active;
- drm_mode_copy(&slave_crtc_state->hw.mode,
- &master_crtc_state->hw.mode);
- drm_mode_copy(&slave_crtc_state->hw.pipe_mode,
- &master_crtc_state->hw.pipe_mode);
- drm_mode_copy(&slave_crtc_state->hw.adjusted_mode,
- &master_crtc_state->hw.adjusted_mode);
- slave_crtc_state->hw.scaling_filter = master_crtc_state->hw.scaling_filter;
-
- if (master_crtc_state->dp_tunnel_ref.tunnel)
- drm_dp_tunnel_ref_get(master_crtc_state->dp_tunnel_ref.tunnel,
- &slave_crtc_state->dp_tunnel_ref);
-
- copy_bigjoiner_crtc_state_nomodeset(state, slave_crtc);
-
- slave_crtc_state->uapi.mode_changed = master_crtc_state->uapi.mode_changed;
- slave_crtc_state->uapi.connectors_changed = master_crtc_state->uapi.connectors_changed;
- slave_crtc_state->uapi.active_changed = master_crtc_state->uapi.active_changed;
-
- WARN_ON(master_crtc_state->bigjoiner_pipes !=
- slave_crtc_state->bigjoiner_pipes);
+ memset(&secondary_crtc_state->hw, 0, sizeof(secondary_crtc_state->hw));
+ secondary_crtc_state->hw.enable = primary_crtc_state->hw.enable;
+ secondary_crtc_state->hw.active = primary_crtc_state->hw.active;
+ drm_mode_copy(&secondary_crtc_state->hw.mode,
+ &primary_crtc_state->hw.mode);
+ drm_mode_copy(&secondary_crtc_state->hw.pipe_mode,
+ &primary_crtc_state->hw.pipe_mode);
+ drm_mode_copy(&secondary_crtc_state->hw.adjusted_mode,
+ &primary_crtc_state->hw.adjusted_mode);
+ secondary_crtc_state->hw.scaling_filter = primary_crtc_state->hw.scaling_filter;
+
+ if (primary_crtc_state->dp_tunnel_ref.tunnel)
+ drm_dp_tunnel_ref_get(primary_crtc_state->dp_tunnel_ref.tunnel,
+ &secondary_crtc_state->dp_tunnel_ref);
+
+ copy_joiner_crtc_state_nomodeset(state, secondary_crtc);
+
+ secondary_crtc_state->uapi.mode_changed = primary_crtc_state->uapi.mode_changed;
+ secondary_crtc_state->uapi.connectors_changed = primary_crtc_state->uapi.connectors_changed;
+ secondary_crtc_state->uapi.active_changed = primary_crtc_state->uapi.active_changed;
+
+ WARN_ON(primary_crtc_state->joiner_pipes !=
+ secondary_crtc_state->joiner_pipes);
return 0;
}
@@ -5000,6 +5016,24 @@ pipe_config_pll_mismatch(struct drm_printer *p, bool fastset,
intel_dpll_dump_hw_state(i915, p, b);
}
+static void
+pipe_config_cx0pll_mismatch(struct drm_printer *p, bool fastset,
+ const struct intel_crtc *crtc,
+ const char *name,
+ const struct intel_cx0pll_state *a,
+ const struct intel_cx0pll_state *b)
+{
+ struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+ char *chipname = a->use_c10 ? "C10" : "C20";
+
+ pipe_config_mismatch(p, fastset, crtc, name, chipname);
+
+ drm_printf(p, "expected:\n");
+ intel_cx0pll_dump_hw_state(i915, a);
+ drm_printf(p, "found:\n");
+ intel_cx0pll_dump_hw_state(i915, b);
+}
+
bool
intel_pipe_config_compare(const struct intel_crtc_state *current_config,
const struct intel_crtc_state *pipe_config,
@@ -5051,6 +5085,16 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
} \
} while (0)
+#define PIPE_CONF_CHECK_LLI(name) do { \
+ if (current_config->name != pipe_config->name) { \
+ pipe_config_mismatch(&p, fastset, crtc, __stringify(name), \
+ "(expected %lli, found %lli)", \
+ current_config->name, \
+ pipe_config->name); \
+ ret = false; \
+ } \
+} while (0)
+
#define PIPE_CONF_CHECK_BOOL(name) do { \
if (current_config->name != pipe_config->name) { \
BUILD_BUG_ON_MSG(!__same_type(current_config->name, bool), \
@@ -5103,6 +5147,16 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
} \
} while (0)
+#define PIPE_CONF_CHECK_PLL_CX0(name) do { \
+ if (!intel_cx0pll_compare_hw_state(&current_config->name, \
+ &pipe_config->name)) { \
+ pipe_config_cx0pll_mismatch(&p, fastset, crtc, __stringify(name), \
+ &current_config->name, \
+ &pipe_config->name); \
+ ret = false; \
+ } \
+} while (0)
+
#define PIPE_CONF_CHECK_TIMINGS(name) do { \
PIPE_CONF_CHECK_I(name.crtc_hdisplay); \
PIPE_CONF_CHECK_I(name.crtc_htotal); \
@@ -5318,9 +5372,11 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
* Panel replay has to be enabled before link training. PSR doesn't have
* this requirement -> check these only if using panel replay
*/
- if (current_config->has_panel_replay || pipe_config->has_panel_replay) {
+ if (current_config->active_planes &&
+ (current_config->has_panel_replay ||
+ pipe_config->has_panel_replay)) {
PIPE_CONF_CHECK_BOOL(has_psr);
- PIPE_CONF_CHECK_BOOL(has_psr2);
+ PIPE_CONF_CHECK_BOOL(has_sel_update);
PIPE_CONF_CHECK_BOOL(enable_psr2_sel_fetch);
PIPE_CONF_CHECK_BOOL(enable_psr2_su_region_et);
PIPE_CONF_CHECK_BOOL(has_panel_replay);
@@ -5335,6 +5391,10 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
if (dev_priv->display.dpll.mgr || HAS_GMCH(dev_priv))
PIPE_CONF_CHECK_PLL(dpll_hw_state);
+ /* FIXME convert MTL+ platforms over to dpll_mgr */
+ if (DISPLAY_VER(dev_priv) >= 14)
+ PIPE_CONF_CHECK_PLL_CX0(dpll_hw_state.cx0pll);
+
PIPE_CONF_CHECK_X(dsi_pll.ctrl);
PIPE_CONF_CHECK_X(dsi_pll.div);
@@ -5365,7 +5425,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
PIPE_CONF_CHECK_X(sync_mode_slaves_mask);
PIPE_CONF_CHECK_I(master_transcoder);
- PIPE_CONF_CHECK_X(bigjoiner_pipes);
+ PIPE_CONF_CHECK_X(joiner_pipes);
PIPE_CONF_CHECK_BOOL(dsc.config.block_pred_enable);
PIPE_CONF_CHECK_BOOL(dsc.config.convert_rgb);
@@ -5415,10 +5475,14 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
PIPE_CONF_CHECK_I(vrr.guardband);
PIPE_CONF_CHECK_I(vrr.vsync_start);
PIPE_CONF_CHECK_I(vrr.vsync_end);
+ PIPE_CONF_CHECK_LLI(cmrr.cmrr_m);
+ PIPE_CONF_CHECK_LLI(cmrr.cmrr_n);
+ PIPE_CONF_CHECK_BOOL(cmrr.enable);
}
#undef PIPE_CONF_CHECK_X
#undef PIPE_CONF_CHECK_I
+#undef PIPE_CONF_CHECK_LLI
#undef PIPE_CONF_CHECK_BOOL
#undef PIPE_CONF_CHECK_P
#undef PIPE_CONF_CHECK_FLAGS
@@ -5567,6 +5631,40 @@ int intel_modeset_all_pipes_late(struct intel_atomic_state *state,
return 0;
}
+int intel_modeset_commit_pipes(struct drm_i915_private *i915,
+ u8 pipe_mask,
+ struct drm_modeset_acquire_ctx *ctx)
+{
+ struct drm_atomic_state *state;
+ struct intel_crtc *crtc;
+ int ret;
+
+ state = drm_atomic_state_alloc(&i915->drm);
+ if (!state)
+ return -ENOMEM;
+
+ state->acquire_ctx = ctx;
+ to_intel_atomic_state(state)->internal = true;
+
+ for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, pipe_mask) {
+ struct intel_crtc_state *crtc_state =
+ intel_atomic_get_crtc_state(state, crtc);
+
+ if (IS_ERR(crtc_state)) {
+ ret = PTR_ERR(crtc_state);
+ goto out;
+ }
+
+ crtc_state->uapi.connectors_changed = true;
+ }
+
+ ret = drm_atomic_commit(state);
+out:
+ drm_atomic_state_put(state);
+
+ return ret;
+}
+
/*
* This implements the workaround described in the "notes" section of the mode
* set sequence documentation. When going from no pipes or single pipe to
@@ -5729,9 +5827,9 @@ static bool active_planes_affects_min_cdclk(struct drm_i915_private *dev_priv)
IS_IVYBRIDGE(dev_priv);
}
-static int intel_crtc_add_bigjoiner_planes(struct intel_atomic_state *state,
- struct intel_crtc *crtc,
- struct intel_crtc *other)
+static int intel_crtc_add_joiner_planes(struct intel_atomic_state *state,
+ struct intel_crtc *crtc,
+ struct intel_crtc *other)
{
const struct intel_plane_state __maybe_unused *plane_state;
struct intel_plane *plane;
@@ -5746,7 +5844,7 @@ static int intel_crtc_add_bigjoiner_planes(struct intel_atomic_state *state,
return intel_crtc_add_planes_to_state(state, other, plane_ids);
}
-static int intel_bigjoiner_add_affected_planes(struct intel_atomic_state *state)
+static int intel_joiner_add_affected_planes(struct intel_atomic_state *state)
{
struct drm_i915_private *i915 = to_i915(state->base.dev);
const struct intel_crtc_state *crtc_state;
@@ -5757,13 +5855,13 @@ static int intel_bigjoiner_add_affected_planes(struct intel_atomic_state *state)
struct intel_crtc *other;
for_each_intel_crtc_in_pipe_mask(&i915->drm, other,
- crtc_state->bigjoiner_pipes) {
+ crtc_state->joiner_pipes) {
int ret;
if (crtc == other)
continue;
- ret = intel_crtc_add_bigjoiner_planes(state, crtc, other);
+ ret = intel_crtc_add_joiner_planes(state, crtc, other);
if (ret)
return ret;
}
@@ -5785,7 +5883,7 @@ static int intel_atomic_check_planes(struct intel_atomic_state *state)
if (ret)
return ret;
- ret = intel_bigjoiner_add_affected_planes(state);
+ ret = intel_joiner_add_affected_planes(state);
if (ret)
return ret;
@@ -5803,7 +5901,7 @@ static int intel_atomic_check_planes(struct intel_atomic_state *state)
new_crtc_state, i) {
u8 old_active_planes, new_active_planes;
- ret = icl_check_nv12_planes(new_crtc_state);
+ ret = icl_check_nv12_planes(state, crtc);
if (ret)
return ret;
@@ -5885,70 +5983,70 @@ static bool intel_pipes_need_modeset(struct intel_atomic_state *state,
return false;
}
-static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state,
- struct intel_crtc *master_crtc)
+static int intel_atomic_check_joiner(struct intel_atomic_state *state,
+ struct intel_crtc *primary_crtc)
{
struct drm_i915_private *i915 = to_i915(state->base.dev);
- struct intel_crtc_state *master_crtc_state =
- intel_atomic_get_new_crtc_state(state, master_crtc);
- struct intel_crtc *slave_crtc;
+ struct intel_crtc_state *primary_crtc_state =
+ intel_atomic_get_new_crtc_state(state, primary_crtc);
+ struct intel_crtc *secondary_crtc;
- if (!master_crtc_state->bigjoiner_pipes)
+ if (!primary_crtc_state->joiner_pipes)
return 0;
/* sanity check */
if (drm_WARN_ON(&i915->drm,
- master_crtc->pipe != bigjoiner_master_pipe(master_crtc_state)))
+ primary_crtc->pipe != joiner_primary_pipe(primary_crtc_state)))
return -EINVAL;
- if (master_crtc_state->bigjoiner_pipes & ~bigjoiner_pipes(i915)) {
+ if (primary_crtc_state->joiner_pipes & ~joiner_pipes(i915)) {
drm_dbg_kms(&i915->drm,
- "[CRTC:%d:%s] Cannot act as big joiner master "
+ "[CRTC:%d:%s] Cannot act as joiner primary "
"(need 0x%x as pipes, only 0x%x possible)\n",
- master_crtc->base.base.id, master_crtc->base.name,
- master_crtc_state->bigjoiner_pipes, bigjoiner_pipes(i915));
+ primary_crtc->base.base.id, primary_crtc->base.name,
+ primary_crtc_state->joiner_pipes, joiner_pipes(i915));
return -EINVAL;
}
- for_each_intel_crtc_in_pipe_mask(&i915->drm, slave_crtc,
- intel_crtc_bigjoiner_slave_pipes(master_crtc_state)) {
- struct intel_crtc_state *slave_crtc_state;
+ for_each_intel_crtc_in_pipe_mask(&i915->drm, secondary_crtc,
+ intel_crtc_joiner_secondary_pipes(primary_crtc_state)) {
+ struct intel_crtc_state *secondary_crtc_state;
int ret;
- slave_crtc_state = intel_atomic_get_crtc_state(&state->base, slave_crtc);
- if (IS_ERR(slave_crtc_state))
- return PTR_ERR(slave_crtc_state);
+ secondary_crtc_state = intel_atomic_get_crtc_state(&state->base, secondary_crtc);
+ if (IS_ERR(secondary_crtc_state))
+ return PTR_ERR(secondary_crtc_state);
- /* master being enabled, slave was already configured? */
- if (slave_crtc_state->uapi.enable) {
+ /* primary being enabled, secondary was already configured? */
+ if (secondary_crtc_state->uapi.enable) {
drm_dbg_kms(&i915->drm,
- "[CRTC:%d:%s] Slave is enabled as normal CRTC, but "
- "[CRTC:%d:%s] claiming this CRTC for bigjoiner.\n",
- slave_crtc->base.base.id, slave_crtc->base.name,
- master_crtc->base.base.id, master_crtc->base.name);
+ "[CRTC:%d:%s] secondary is enabled as normal CRTC, but "
+ "[CRTC:%d:%s] claiming this CRTC for joiner.\n",
+ secondary_crtc->base.base.id, secondary_crtc->base.name,
+ primary_crtc->base.base.id, primary_crtc->base.name);
return -EINVAL;
}
/*
- * The state copy logic assumes the master crtc gets processed
- * before the slave crtc during the main compute_config loop.
+ * The state copy logic assumes the primary crtc gets processed
+ * before the secondary crtc during the main compute_config loop.
* This works because the crtcs are created in pipe order,
- * and the hardware requires master pipe < slave pipe as well.
+ * and the hardware requires primary pipe < secondary pipe as well.
* Should that change we need to rethink the logic.
*/
- if (WARN_ON(drm_crtc_index(&master_crtc->base) >
- drm_crtc_index(&slave_crtc->base)))
+ if (WARN_ON(drm_crtc_index(&primary_crtc->base) >
+ drm_crtc_index(&secondary_crtc->base)))
return -EINVAL;
drm_dbg_kms(&i915->drm,
- "[CRTC:%d:%s] Used as slave for big joiner master [CRTC:%d:%s]\n",
- slave_crtc->base.base.id, slave_crtc->base.name,
- master_crtc->base.base.id, master_crtc->base.name);
+ "[CRTC:%d:%s] Used as secondary for joiner primary [CRTC:%d:%s]\n",
+ secondary_crtc->base.base.id, secondary_crtc->base.name,
+ primary_crtc->base.base.id, primary_crtc->base.name);
- slave_crtc_state->bigjoiner_pipes =
- master_crtc_state->bigjoiner_pipes;
+ secondary_crtc_state->joiner_pipes =
+ primary_crtc_state->joiner_pipes;
- ret = copy_bigjoiner_crtc_state_modeset(state, slave_crtc);
+ ret = copy_joiner_crtc_state_modeset(state, secondary_crtc);
if (ret)
return ret;
}
@@ -5956,25 +6054,25 @@ static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state,
return 0;
}
-static void kill_bigjoiner_slave(struct intel_atomic_state *state,
- struct intel_crtc *master_crtc)
+static void kill_joiner_secondaries(struct intel_atomic_state *state,
+ struct intel_crtc *primary_crtc)
{
struct drm_i915_private *i915 = to_i915(state->base.dev);
- struct intel_crtc_state *master_crtc_state =
- intel_atomic_get_new_crtc_state(state, master_crtc);
- struct intel_crtc *slave_crtc;
+ struct intel_crtc_state *primary_crtc_state =
+ intel_atomic_get_new_crtc_state(state, primary_crtc);
+ struct intel_crtc *secondary_crtc;
- for_each_intel_crtc_in_pipe_mask(&i915->drm, slave_crtc,
- intel_crtc_bigjoiner_slave_pipes(master_crtc_state)) {
- struct intel_crtc_state *slave_crtc_state =
- intel_atomic_get_new_crtc_state(state, slave_crtc);
+ for_each_intel_crtc_in_pipe_mask(&i915->drm, secondary_crtc,
+ intel_crtc_joiner_secondary_pipes(primary_crtc_state)) {
+ struct intel_crtc_state *secondary_crtc_state =
+ intel_atomic_get_new_crtc_state(state, secondary_crtc);
- slave_crtc_state->bigjoiner_pipes = 0;
+ secondary_crtc_state->joiner_pipes = 0;
- intel_crtc_copy_uapi_to_hw_state_modeset(state, slave_crtc);
+ intel_crtc_copy_uapi_to_hw_state_modeset(state, secondary_crtc);
}
- master_crtc_state->bigjoiner_pipes = 0;
+ primary_crtc_state->joiner_pipes = 0;
}
/**
@@ -6024,12 +6122,12 @@ static int intel_async_flip_check_uapi(struct intel_atomic_state *state,
}
/*
- * FIXME: Bigjoiner+async flip is busted currently.
+ * FIXME: joiner+async flip is busted currently.
* Remove this check once the issues are fixed.
*/
- if (new_crtc_state->bigjoiner_pipes) {
+ if (new_crtc_state->joiner_pipes) {
drm_dbg_kms(&i915->drm,
- "[CRTC:%d:%s] async flip disallowed with bigjoiner\n",
+ "[CRTC:%d:%s] async flip disallowed with joiner\n",
crtc->base.base.id, crtc->base.name);
return -EINVAL;
}
@@ -6166,6 +6264,13 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in
return -EINVAL;
}
+ /*
+ * We turn the first async flip request into a sync flip
+ * so that we can reconfigure the plane (eg. change modifier).
+ */
+ if (!new_crtc_state->do_async_flip)
+ continue;
+
if (old_plane_state->view.color_plane[0].mapping_stride !=
new_plane_state->view.color_plane[0].mapping_stride) {
drm_dbg_kms(&i915->drm,
@@ -6247,7 +6352,7 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in
return 0;
}
-static int intel_bigjoiner_add_affected_crtcs(struct intel_atomic_state *state)
+static int intel_joiner_add_affected_crtcs(struct intel_atomic_state *state)
{
struct drm_i915_private *i915 = to_i915(state->base.dev);
struct intel_crtc_state *crtc_state;
@@ -6257,9 +6362,9 @@ static int intel_bigjoiner_add_affected_crtcs(struct intel_atomic_state *state)
int i;
for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
- affected_pipes |= crtc_state->bigjoiner_pipes;
+ affected_pipes |= crtc_state->joiner_pipes;
if (intel_crtc_needs_modeset(crtc_state))
- modeset_pipes |= crtc_state->bigjoiner_pipes;
+ modeset_pipes |= crtc_state->joiner_pipes;
}
for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, affected_pipes) {
@@ -6285,10 +6390,10 @@ static int intel_bigjoiner_add_affected_crtcs(struct intel_atomic_state *state)
}
for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
- /* Kill old bigjoiner link, we may re-establish afterwards */
+ /* Kill old joiner link, we may re-establish afterwards */
if (intel_crtc_needs_modeset(crtc_state) &&
- intel_crtc_is_bigjoiner_master(crtc_state))
- kill_bigjoiner_slave(state, crtc);
+ intel_crtc_is_joiner_primary(crtc_state))
+ kill_joiner_secondaries(state, crtc);
}
return 0;
@@ -6306,7 +6411,7 @@ static int intel_atomic_check_config(struct intel_atomic_state *state,
*failed_pipe = INVALID_PIPE;
- ret = intel_bigjoiner_add_affected_crtcs(state);
+ ret = intel_joiner_add_affected_crtcs(state);
if (ret)
return ret;
@@ -6316,14 +6421,14 @@ static int intel_atomic_check_config(struct intel_atomic_state *state,
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
if (!intel_crtc_needs_modeset(new_crtc_state)) {
- if (intel_crtc_is_bigjoiner_slave(new_crtc_state))
- copy_bigjoiner_crtc_state_nomodeset(state, crtc);
+ if (intel_crtc_is_joiner_secondary(new_crtc_state))
+ copy_joiner_crtc_state_nomodeset(state, crtc);
else
intel_crtc_copy_uapi_to_hw_state_nomodeset(state, crtc);
continue;
}
- if (drm_WARN_ON(&i915->drm, intel_crtc_is_bigjoiner_slave(new_crtc_state)))
+ if (drm_WARN_ON(&i915->drm, intel_crtc_is_joiner_secondary(new_crtc_state)))
continue;
ret = intel_crtc_prepare_cleared_state(state, crtc);
@@ -6342,7 +6447,7 @@ static int intel_atomic_check_config(struct intel_atomic_state *state,
if (!intel_crtc_needs_modeset(new_crtc_state))
continue;
- if (drm_WARN_ON(&i915->drm, intel_crtc_is_bigjoiner_slave(new_crtc_state)))
+ if (drm_WARN_ON(&i915->drm, intel_crtc_is_joiner_secondary(new_crtc_state)))
continue;
if (!new_crtc_state->hw.enable)
@@ -6453,12 +6558,12 @@ int intel_atomic_check(struct drm_device *dev,
if (!intel_crtc_needs_modeset(new_crtc_state))
continue;
- if (intel_crtc_is_bigjoiner_slave(new_crtc_state)) {
+ if (intel_crtc_is_joiner_secondary(new_crtc_state)) {
drm_WARN_ON(&dev_priv->drm, new_crtc_state->uapi.enable);
continue;
}
- ret = intel_atomic_check_bigjoiner(state, crtc);
+ ret = intel_atomic_check_joiner(state, crtc);
if (ret)
goto fail;
}
@@ -6468,7 +6573,7 @@ int intel_atomic_check(struct drm_device *dev,
if (!intel_crtc_needs_modeset(new_crtc_state))
continue;
- intel_bigjoiner_adjust_pipe_src(new_crtc_state);
+ intel_joiner_adjust_pipe_src(new_crtc_state);
intel_crtc_check_fastset(old_crtc_state, new_crtc_state);
}
@@ -6508,8 +6613,8 @@ int intel_atomic_check(struct drm_device *dev,
intel_crtc_flag_modeset(new_crtc_state);
}
- if (new_crtc_state->bigjoiner_pipes) {
- if (intel_pipes_need_modeset(state, new_crtc_state->bigjoiner_pipes))
+ if (new_crtc_state->joiner_pipes) {
+ if (intel_pipes_need_modeset(state, new_crtc_state->joiner_pipes))
intel_crtc_flag_modeset(new_crtc_state);
}
}
@@ -6800,7 +6905,8 @@ static void intel_pre_update_crtc(struct intel_atomic_state *state,
intel_crtc_needs_fastset(new_crtc_state))
icl_set_pipe_chicken(new_crtc_state);
- if (vrr_params_changed(old_crtc_state, new_crtc_state))
+ if (vrr_params_changed(old_crtc_state, new_crtc_state) ||
+ cmrr_params_changed(old_crtc_state, new_crtc_state))
intel_vrr_set_transcoder_timings(new_crtc_state);
}
@@ -6923,7 +7029,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
if ((disable_pipes & BIT(crtc->pipe)) == 0)
continue;
- if (intel_crtc_is_bigjoiner_slave(old_crtc_state))
+ if (intel_crtc_is_joiner_secondary(old_crtc_state))
continue;
/* In case of Transcoder port Sync master slave CRTCs can be
@@ -6945,7 +7051,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
if ((disable_pipes & BIT(crtc->pipe)) == 0)
continue;
- if (intel_crtc_is_bigjoiner_slave(old_crtc_state))
+ if (intel_crtc_is_joiner_secondary(old_crtc_state))
continue;
intel_old_crtc_state_disables(state, crtc);
@@ -7024,8 +7130,8 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
while (update_pipes) {
/*
- * Commit in reverse order to make bigjoiner master
- * send the uapi events after slaves are done.
+ * Commit in reverse order to make joiner primary
+ * send the uapi events after secondaries are done.
*/
for_each_oldnew_intel_crtc_in_state_reverse(state, crtc, old_crtc_state,
new_crtc_state, i) {
@@ -7070,7 +7176,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
if ((modeset_pipes & BIT(pipe)) == 0)
continue;
- if (intel_crtc_is_bigjoiner_slave(new_crtc_state))
+ if (intel_crtc_is_joiner_secondary(new_crtc_state))
continue;
if (intel_dp_mst_is_slave_trans(new_crtc_state) ||
@@ -7084,7 +7190,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
/*
* Then we enable all remaining pipes that depend on other
- * pipes: MST slaves and port sync masters, big joiner master
+ * pipes: MST slaves and port sync masters
*/
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
enum pipe pipe = crtc->pipe;
@@ -7092,7 +7198,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
if ((modeset_pipes & BIT(pipe)) == 0)
continue;
- if (intel_crtc_is_bigjoiner_slave(new_crtc_state))
+ if (intel_crtc_is_joiner_secondary(new_crtc_state))
continue;
modeset_pipes &= ~intel_crtc_joined_pipe_mask(new_crtc_state);
@@ -7113,8 +7219,8 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
}
/*
- * Commit in reverse order to make bigjoiner master
- * send the uapi events after slaves are done.
+ * Commit in reverse order to make joiner primary
+ * send the uapi events after secondaries are done.
*/
for_each_new_intel_crtc_in_state_reverse(state, crtc, new_crtc_state, i) {
enum pipe pipe = crtc->pipe;
@@ -7227,6 +7333,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
intel_atomic_commit_fence_wait(state);
+ intel_td_flush(dev_priv);
+
drm_atomic_helper_wait_for_dependencies(&state->base);
drm_dp_mst_atomic_wait_for_dependencies(&state->base);
intel_atomic_global_state_wait_for_dependencies(state);
@@ -7839,7 +7947,7 @@ static int max_dotclock(struct drm_i915_private *i915)
{
int max_dotclock = i915->display.cdclk.max_dotclk_freq;
- /* icl+ might use bigjoiner */
+ /* icl+ might use joiner */
if (DISPLAY_VER(i915) >= 11)
max_dotclock *= 2;
@@ -7964,7 +8072,7 @@ enum drm_mode_status intel_cpu_transcoder_mode_valid(struct drm_i915_private *de
enum drm_mode_status
intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
const struct drm_display_mode *mode,
- bool bigjoiner)
+ bool joiner)
{
int plane_width_max, plane_height_max;
@@ -7981,7 +8089,7 @@ intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
* too big for that.
*/
if (DISPLAY_VER(dev_priv) >= 11) {
- plane_width_max = 5120 << bigjoiner;
+ plane_width_max = 5120 << joiner;
plane_height_max = 4320;
} else {
plane_width_max = 5120;
@@ -8163,19 +8271,19 @@ void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
PLL_REF_INPUT_DREFCLK |
DPLL_VCO_ENABLE;
- intel_de_write(dev_priv, TRANS_HTOTAL(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_HTOTAL(dev_priv, cpu_transcoder),
HACTIVE(640 - 1) | HTOTAL(800 - 1));
- intel_de_write(dev_priv, TRANS_HBLANK(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_HBLANK(dev_priv, cpu_transcoder),
HBLANK_START(640 - 1) | HBLANK_END(800 - 1));
- intel_de_write(dev_priv, TRANS_HSYNC(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_HSYNC(dev_priv, cpu_transcoder),
HSYNC_START(656 - 1) | HSYNC_END(752 - 1));
- intel_de_write(dev_priv, TRANS_VTOTAL(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_VTOTAL(dev_priv, cpu_transcoder),
VACTIVE(480 - 1) | VTOTAL(525 - 1));
- intel_de_write(dev_priv, TRANS_VBLANK(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_VBLANK(dev_priv, cpu_transcoder),
VBLANK_START(480 - 1) | VBLANK_END(525 - 1));
- intel_de_write(dev_priv, TRANS_VSYNC(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_VSYNC(dev_priv, cpu_transcoder),
VSYNC_START(490 - 1) | VSYNC_END(492 - 1));
- intel_de_write(dev_priv, PIPESRC(pipe),
+ intel_de_write(dev_priv, PIPESRC(dev_priv, pipe),
PIPESRC_WIDTH(640 - 1) | PIPESRC_HEIGHT(480 - 1));
intel_de_write(dev_priv, FP0(pipe), fp);
@@ -8186,11 +8294,12 @@ void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
* the P1/P2 dividers. Otherwise the DPLL will keep using the old
* dividers, even though the register value does change.
*/
- intel_de_write(dev_priv, DPLL(pipe), dpll & ~DPLL_VGA_MODE_DIS);
- intel_de_write(dev_priv, DPLL(pipe), dpll);
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe),
+ dpll & ~DPLL_VGA_MODE_DIS);
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), dpll);
/* Wait for the clocks to stabilize. */
- intel_de_posting_read(dev_priv, DPLL(pipe));
+ intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe));
udelay(150);
/* The pixel multiplier can only be updated once the
@@ -8198,17 +8307,17 @@ void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
*
* So write it again.
*/
- intel_de_write(dev_priv, DPLL(pipe), dpll);
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), dpll);
/* We do this three times for luck */
for (i = 0; i < 3 ; i++) {
- intel_de_write(dev_priv, DPLL(pipe), dpll);
- intel_de_posting_read(dev_priv, DPLL(pipe));
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), dpll);
+ intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe));
udelay(150); /* wait for warmup */
}
- intel_de_write(dev_priv, TRANSCONF(pipe), TRANSCONF_ENABLE);
- intel_de_posting_read(dev_priv, TRANSCONF(pipe));
+ intel_de_write(dev_priv, TRANSCONF(dev_priv, pipe), TRANSCONF_ENABLE);
+ intel_de_posting_read(dev_priv, TRANSCONF(dev_priv, pipe));
intel_wait_for_pipe_scanline_moving(crtc);
}
@@ -8221,23 +8330,23 @@ void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
pipe_name(pipe));
drm_WARN_ON(&dev_priv->drm,
- intel_de_read(dev_priv, DSPCNTR(PLANE_A)) & DISP_ENABLE);
+ intel_de_read(dev_priv, DSPCNTR(dev_priv, PLANE_A)) & DISP_ENABLE);
drm_WARN_ON(&dev_priv->drm,
- intel_de_read(dev_priv, DSPCNTR(PLANE_B)) & DISP_ENABLE);
+ intel_de_read(dev_priv, DSPCNTR(dev_priv, PLANE_B)) & DISP_ENABLE);
drm_WARN_ON(&dev_priv->drm,
- intel_de_read(dev_priv, DSPCNTR(PLANE_C)) & DISP_ENABLE);
+ intel_de_read(dev_priv, DSPCNTR(dev_priv, PLANE_C)) & DISP_ENABLE);
drm_WARN_ON(&dev_priv->drm,
- intel_de_read(dev_priv, CURCNTR(PIPE_A)) & MCURSOR_MODE_MASK);
+ intel_de_read(dev_priv, CURCNTR(dev_priv, PIPE_A)) & MCURSOR_MODE_MASK);
drm_WARN_ON(&dev_priv->drm,
- intel_de_read(dev_priv, CURCNTR(PIPE_B)) & MCURSOR_MODE_MASK);
+ intel_de_read(dev_priv, CURCNTR(dev_priv, PIPE_B)) & MCURSOR_MODE_MASK);
- intel_de_write(dev_priv, TRANSCONF(pipe), 0);
- intel_de_posting_read(dev_priv, TRANSCONF(pipe));
+ intel_de_write(dev_priv, TRANSCONF(dev_priv, pipe), 0);
+ intel_de_posting_read(dev_priv, TRANSCONF(dev_priv, pipe));
intel_wait_for_pipe_scanline_stopped(crtc);
- intel_de_write(dev_priv, DPLL(pipe), DPLL_VGA_MODE_DIS);
- intel_de_posting_read(dev_priv, DPLL(pipe));
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), DPLL_VGA_MODE_DIS);
+ intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe));
}
void intel_hpd_poll_fini(struct drm_i915_private *i915)
diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
index 56d1c0e3e62c..b0cf6ca70952 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -415,7 +415,7 @@ u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,
enum drm_mode_status
intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
const struct drm_display_mode *mode,
- bool bigjoiner);
+ bool joiner);
enum drm_mode_status
intel_cpu_transcoder_mode_valid(struct drm_i915_private *i915,
const struct drm_display_mode *mode);
@@ -423,10 +423,10 @@ enum phy intel_port_to_phy(struct drm_i915_private *i915, enum port port);
bool is_trans_port_sync_mode(const struct intel_crtc_state *state);
bool is_trans_port_sync_master(const struct intel_crtc_state *state);
u8 intel_crtc_joined_pipe_mask(const struct intel_crtc_state *crtc_state);
-bool intel_crtc_is_bigjoiner_slave(const struct intel_crtc_state *crtc_state);
-bool intel_crtc_is_bigjoiner_master(const struct intel_crtc_state *crtc_state);
-u8 intel_crtc_bigjoiner_slave_pipes(const struct intel_crtc_state *crtc_state);
-struct intel_crtc *intel_master_crtc(const struct intel_crtc_state *crtc_state);
+bool intel_crtc_is_joiner_secondary(const struct intel_crtc_state *crtc_state);
+bool intel_crtc_is_joiner_primary(const struct intel_crtc_state *crtc_state);
+u8 intel_crtc_joiner_secondary_pipes(const struct intel_crtc_state *crtc_state);
+struct intel_crtc *intel_primary_crtc(const struct intel_crtc_state *crtc_state);
bool intel_crtc_get_pipe_config(struct intel_crtc_state *crtc_state);
bool intel_pipe_config_compare(const struct intel_crtc_state *current_config,
const struct intel_crtc_state *pipe_config,
@@ -537,6 +537,9 @@ int intel_modeset_pipes_in_mask_early(struct intel_atomic_state *state,
const char *reason, u8 pipe_mask);
int intel_modeset_all_pipes_late(struct intel_atomic_state *state,
const char *reason);
+int intel_modeset_commit_pipes(struct drm_i915_private *i915,
+ u8 pipe_mask,
+ struct drm_modeset_acquire_ctx *ctx);
void intel_modeset_get_crtc_power_domains(struct intel_crtc_state *crtc_state,
struct intel_power_domain_mask *old_domains);
void intel_modeset_put_crtc_power_domains(struct intel_crtc *crtc,
diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index 35f9f86ef70f..91757fed9c6d 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -13,6 +13,7 @@
#include "i915_debugfs.h"
#include "i915_irq.h"
#include "i915_reg.h"
+#include "intel_alpm.h"
#include "intel_crtc.h"
#include "intel_de.h"
#include "intel_crtc_state_dump.h"
@@ -23,6 +24,7 @@
#include "intel_display_types.h"
#include "intel_dmc.h"
#include "intel_dp.h"
+#include "intel_dp_link_training.h"
#include "intel_dp_mst.h"
#include "intel_drrs.h"
#include "intel_fbc.h"
@@ -76,7 +78,7 @@ static int i915_sr_status(struct seq_file *m, void *unused)
else if (IS_I915GM(dev_priv))
sr_enabled = intel_de_read(dev_priv, INSTPM) & INSTPM_SELF_EN;
else if (IS_PINEVIEW(dev_priv))
- sr_enabled = intel_de_read(dev_priv, DSPFW3) & PINEVIEW_SELF_REFRESH_EN;
+ sr_enabled = intel_de_read(dev_priv, DSPFW3(dev_priv)) & PINEVIEW_SELF_REFRESH_EN;
else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
sr_enabled = intel_de_read(dev_priv, FW_BLC_SELF_VLV) & FW_CSPWRDWNEN;
@@ -574,10 +576,10 @@ static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc)
intel_scaler_info(m, crtc);
- if (crtc_state->bigjoiner_pipes)
+ if (crtc_state->joiner_pipes)
seq_printf(m, "\tLinked to 0x%x pipes as a %s\n",
- crtc_state->bigjoiner_pipes,
- intel_crtc_is_bigjoiner_slave(crtc_state) ? "slave" : "master");
+ crtc_state->joiner_pipes,
+ intel_crtc_is_joiner_secondary(crtc_state) ? "slave" : "master");
for_each_intel_encoder_mask(&dev_priv->drm, encoder,
crtc_state->uapi.encoder_mask)
@@ -1515,6 +1517,8 @@ void intel_connector_debugfs_add(struct intel_connector *connector)
intel_drrs_connector_debugfs_add(connector);
intel_pps_connector_debugfs_add(connector);
intel_psr_connector_debugfs_add(connector);
+ intel_alpm_lobf_debugfs_add(connector);
+ intel_dp_link_training_debugfs_add(connector);
if (connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
connector_type == DRM_MODE_CONNECTOR_HDMIA ||
diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c
index 120e209ee74a..dd7dce4b0e7a 100644
--- a/drivers/gpu/drm/i915/display/intel_display_device.c
+++ b/drivers/gpu/drm/i915/display/intel_display_device.c
@@ -3,7 +3,7 @@
* Copyright © 2023 Intel Corporation
*/
-#include <drm/i915_pciids.h>
+#include <drm/intel/i915_pciids.h>
#include <drm/drm_color_mgmt.h>
#include <linux/pci.h>
@@ -20,6 +20,25 @@
__diag_push();
__diag_ignore_all("-Woverride-init", "Allow field initialization overrides for display info");
+struct subplatform_desc {
+ enum intel_display_subplatform subplatform;
+ const char *name;
+ const u16 *pciidlist;
+};
+
+struct platform_desc {
+ enum intel_display_platform platform;
+ const char *name;
+ const struct subplatform_desc *subplatforms;
+ const struct intel_display_device_info *info; /* NULL for GMD ID */
+};
+
+#define PLATFORM(_platform) \
+ .platform = (INTEL_DISPLAY_##_platform), \
+ .name = #_platform
+
+#define ID(id) (id)
+
static const struct intel_display_device_info no_display = {};
#define PIPE_A_OFFSET 0x70000
@@ -200,33 +219,45 @@ static const struct intel_display_device_info no_display = {};
.__runtime_defaults.pipe_mask = BIT(PIPE_A), \
.__runtime_defaults.cpu_transcoder_mask = BIT(TRANSCODER_A)
-static const struct intel_display_device_info i830_display = {
- I830_DISPLAY,
+static const struct platform_desc i830_desc = {
+ PLATFORM(I830),
+ .info = &(const struct intel_display_device_info) {
+ I830_DISPLAY,
- .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C), /* DVO A/B/C */
+ .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C), /* DVO A/B/C */
+ },
};
-static const struct intel_display_device_info i845_display = {
- I845_DISPLAY,
+static const struct platform_desc i845_desc = {
+ PLATFORM(I845G),
+ .info = &(const struct intel_display_device_info) {
+ I845_DISPLAY,
- .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* DVO B/C */
+ .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* DVO B/C */
+ },
};
-static const struct intel_display_device_info i85x_display = {
- I830_DISPLAY,
+static const struct platform_desc i85x_desc = {
+ PLATFORM(I85X),
+ .info = &(const struct intel_display_device_info) {
+ I830_DISPLAY,
- .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* DVO B/C */
- .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* DVO B/C */
+ .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ },
};
-static const struct intel_display_device_info i865g_display = {
- I845_DISPLAY,
+static const struct platform_desc i865g_desc = {
+ PLATFORM(I865G),
+ .info = &(const struct intel_display_device_info) {
+ I845_DISPLAY,
- .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* DVO B/C */
- .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* DVO B/C */
+ .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ },
};
-#define GEN3_DISPLAY \
+#define GEN3_DISPLAY \
.has_gmch = 1, \
.has_overlay = 1, \
I9XX_PIPE_OFFSETS, \
@@ -238,52 +269,70 @@ static const struct intel_display_device_info i865g_display = {
BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \
.__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) /* SDVO B/C */
-static const struct intel_display_device_info i915g_display = {
- GEN3_DISPLAY,
- I845_COLORS,
- .cursor_needs_physical = 1,
- .overlay_needs_physical = 1,
+static const struct platform_desc i915g_desc = {
+ PLATFORM(I915G),
+ .info = &(const struct intel_display_device_info) {
+ GEN3_DISPLAY,
+ I845_COLORS,
+ .cursor_needs_physical = 1,
+ .overlay_needs_physical = 1,
+ },
};
-static const struct intel_display_device_info i915gm_display = {
- GEN3_DISPLAY,
- I9XX_COLORS,
- .cursor_needs_physical = 1,
- .overlay_needs_physical = 1,
- .supports_tv = 1,
-
- .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+static const struct platform_desc i915gm_desc = {
+ PLATFORM(I915GM),
+ .info = &(const struct intel_display_device_info) {
+ GEN3_DISPLAY,
+ I9XX_COLORS,
+ .cursor_needs_physical = 1,
+ .overlay_needs_physical = 1,
+ .supports_tv = 1,
+
+ .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ },
};
-static const struct intel_display_device_info i945g_display = {
- GEN3_DISPLAY,
- I845_COLORS,
- .has_hotplug = 1,
- .cursor_needs_physical = 1,
- .overlay_needs_physical = 1,
+static const struct platform_desc i945g_desc = {
+ PLATFORM(I945G),
+ .info = &(const struct intel_display_device_info) {
+ GEN3_DISPLAY,
+ I845_COLORS,
+ .has_hotplug = 1,
+ .cursor_needs_physical = 1,
+ .overlay_needs_physical = 1,
+ },
};
-static const struct intel_display_device_info i945gm_display = {
- GEN3_DISPLAY,
- I9XX_COLORS,
- .has_hotplug = 1,
- .cursor_needs_physical = 1,
- .overlay_needs_physical = 1,
- .supports_tv = 1,
-
- .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+static const struct platform_desc i945gm_desc = {
+ PLATFORM(I915GM),
+ .info = &(const struct intel_display_device_info) {
+ GEN3_DISPLAY,
+ I9XX_COLORS,
+ .has_hotplug = 1,
+ .cursor_needs_physical = 1,
+ .overlay_needs_physical = 1,
+ .supports_tv = 1,
+
+ .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ },
};
-static const struct intel_display_device_info g33_display = {
- GEN3_DISPLAY,
- I845_COLORS,
- .has_hotplug = 1,
+static const struct platform_desc g33_desc = {
+ PLATFORM(G33),
+ .info = &(const struct intel_display_device_info) {
+ GEN3_DISPLAY,
+ I845_COLORS,
+ .has_hotplug = 1,
+ },
};
-static const struct intel_display_device_info pnv_display = {
- GEN3_DISPLAY,
- I9XX_COLORS,
- .has_hotplug = 1,
+static const struct platform_desc pnv_desc = {
+ PLATFORM(PINEVIEW),
+ .info = &(const struct intel_display_device_info) {
+ GEN3_DISPLAY,
+ I9XX_COLORS,
+ .has_hotplug = 1,
+ },
};
#define GEN4_DISPLAY \
@@ -298,34 +347,46 @@ static const struct intel_display_device_info pnv_display = {
.__runtime_defaults.cpu_transcoder_mask = \
BIT(TRANSCODER_A) | BIT(TRANSCODER_B)
-static const struct intel_display_device_info i965g_display = {
- GEN4_DISPLAY,
- .has_overlay = 1,
+static const struct platform_desc i965g_desc = {
+ PLATFORM(I965G),
+ .info = &(const struct intel_display_device_info) {
+ GEN4_DISPLAY,
+ .has_overlay = 1,
- .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* SDVO B/C */
+ .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* SDVO B/C */
+ },
};
-static const struct intel_display_device_info i965gm_display = {
- GEN4_DISPLAY,
- .has_overlay = 1,
- .supports_tv = 1,
+static const struct platform_desc i965gm_desc = {
+ PLATFORM(I965GM),
+ .info = &(const struct intel_display_device_info) {
+ GEN4_DISPLAY,
+ .has_overlay = 1,
+ .supports_tv = 1,
- .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* SDVO B/C */
- .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* SDVO B/C */
+ .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ },
};
-static const struct intel_display_device_info g45_display = {
- GEN4_DISPLAY,
+static const struct platform_desc g45_desc = {
+ PLATFORM(G45),
+ .info = &(const struct intel_display_device_info) {
+ GEN4_DISPLAY,
- .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* SDVO/HDMI/DP B/C, DP D */
+ .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* SDVO/HDMI/DP B/C, DP D */
+ },
};
-static const struct intel_display_device_info gm45_display = {
- GEN4_DISPLAY,
- .supports_tv = 1,
+static const struct platform_desc gm45_desc = {
+ PLATFORM(GM45),
+ .info = &(const struct intel_display_device_info) {
+ GEN4_DISPLAY,
+ .supports_tv = 1,
- .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* SDVO/HDMI/DP B/C, DP D */
- .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* SDVO/HDMI/DP B/C, DP D */
+ .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ },
};
#define ILK_DISPLAY \
@@ -340,112 +401,175 @@ static const struct intel_display_device_info gm45_display = {
BIT(TRANSCODER_A) | BIT(TRANSCODER_B), \
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) /* DP A, SDVO/HDMI/DP B, HDMI/DP C/D */
-static const struct intel_display_device_info ilk_d_display = {
- ILK_DISPLAY,
+static const struct platform_desc ilk_d_desc = {
+ PLATFORM(IRONLAKE),
+ .info = &(const struct intel_display_device_info) {
+ ILK_DISPLAY,
+ },
};
-static const struct intel_display_device_info ilk_m_display = {
- ILK_DISPLAY,
+static const struct platform_desc ilk_m_desc = {
+ PLATFORM(IRONLAKE),
+ .info = &(const struct intel_display_device_info) {
+ ILK_DISPLAY,
- .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ },
};
-static const struct intel_display_device_info snb_display = {
- .has_hotplug = 1,
- I9XX_PIPE_OFFSETS,
- I9XX_CURSOR_OFFSETS,
- ILK_COLORS,
-
- .__runtime_defaults.ip.ver = 6,
- .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B),
- .__runtime_defaults.cpu_transcoder_mask =
+static const struct platform_desc snb_desc = {
+ PLATFORM(SANDYBRIDGE),
+ .info = &(const struct intel_display_device_info) {
+ .has_hotplug = 1,
+ I9XX_PIPE_OFFSETS,
+ I9XX_CURSOR_OFFSETS,
+ ILK_COLORS,
+
+ .__runtime_defaults.ip.ver = 6,
+ .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B),
+ .__runtime_defaults.cpu_transcoder_mask =
BIT(TRANSCODER_A) | BIT(TRANSCODER_B),
- .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* DP A, SDVO/HDMI/DP B, HDMI/DP C/D */
- .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* DP A, SDVO/HDMI/DP B, HDMI/DP C/D */
+ .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ },
};
-static const struct intel_display_device_info ivb_display = {
- .has_hotplug = 1,
- IVB_PIPE_OFFSETS,
- IVB_CURSOR_OFFSETS,
- IVB_COLORS,
-
- .__runtime_defaults.ip.ver = 7,
- .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
- .__runtime_defaults.cpu_transcoder_mask =
+static const struct platform_desc ivb_desc = {
+ PLATFORM(IVYBRIDGE),
+ .info = &(const struct intel_display_device_info) {
+ .has_hotplug = 1,
+ IVB_PIPE_OFFSETS,
+ IVB_CURSOR_OFFSETS,
+ IVB_COLORS,
+
+ .__runtime_defaults.ip.ver = 7,
+ .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
+ .__runtime_defaults.cpu_transcoder_mask =
BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C),
- .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* DP A, SDVO/HDMI/DP B, HDMI/DP C/D */
- .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* DP A, SDVO/HDMI/DP B, HDMI/DP C/D */
+ .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ },
};
-static const struct intel_display_device_info vlv_display = {
- .has_gmch = 1,
- .has_hotplug = 1,
- .mmio_offset = VLV_DISPLAY_BASE,
- I9XX_PIPE_OFFSETS,
- I9XX_CURSOR_OFFSETS,
- I9XX_COLORS,
-
- .__runtime_defaults.ip.ver = 7,
- .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B),
- .__runtime_defaults.cpu_transcoder_mask =
+static const struct platform_desc vlv_desc = {
+ PLATFORM(VALLEYVIEW),
+ .info = &(const struct intel_display_device_info) {
+ .has_gmch = 1,
+ .has_hotplug = 1,
+ .mmio_offset = VLV_DISPLAY_BASE,
+ I9XX_PIPE_OFFSETS,
+ I9XX_CURSOR_OFFSETS,
+ I9XX_COLORS,
+
+ .__runtime_defaults.ip.ver = 7,
+ .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B),
+ .__runtime_defaults.cpu_transcoder_mask =
BIT(TRANSCODER_A) | BIT(TRANSCODER_B),
- .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* HDMI/DP B/C */
+ .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C), /* HDMI/DP B/C */
+ },
};
-static const struct intel_display_device_info hsw_display = {
- .has_ddi = 1,
- .has_dp_mst = 1,
- .has_fpga_dbg = 1,
- .has_hotplug = 1,
- .has_psr = 1,
- .has_psr_hw_tracking = 1,
- HSW_PIPE_OFFSETS,
- IVB_CURSOR_OFFSETS,
- IVB_COLORS,
+static const u16 hsw_ult_ids[] = {
+ INTEL_HSW_ULT_GT1_IDS(ID),
+ INTEL_HSW_ULT_GT2_IDS(ID),
+ INTEL_HSW_ULT_GT3_IDS(ID),
+ 0
+};
- .__runtime_defaults.ip.ver = 7,
- .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
- .__runtime_defaults.cpu_transcoder_mask =
+static const u16 hsw_ulx_ids[] = {
+ INTEL_HSW_ULX_GT1_IDS(ID),
+ INTEL_HSW_ULX_GT2_IDS(ID),
+ 0
+};
+
+static const struct platform_desc hsw_desc = {
+ PLATFORM(HASWELL),
+ .subplatforms = (const struct subplatform_desc[]) {
+ { INTEL_DISPLAY_HASWELL_ULT, "ULT", hsw_ult_ids },
+ { INTEL_DISPLAY_HASWELL_ULX, "ULX", hsw_ulx_ids },
+ {},
+ },
+ .info = &(const struct intel_display_device_info) {
+ .has_ddi = 1,
+ .has_dp_mst = 1,
+ .has_fpga_dbg = 1,
+ .has_hotplug = 1,
+ .has_psr = 1,
+ .has_psr_hw_tracking = 1,
+ HSW_PIPE_OFFSETS,
+ IVB_CURSOR_OFFSETS,
+ IVB_COLORS,
+
+ .__runtime_defaults.ip.ver = 7,
+ .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
+ .__runtime_defaults.cpu_transcoder_mask =
BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP),
- .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
- .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
+ .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ },
};
-static const struct intel_display_device_info bdw_display = {
- .has_ddi = 1,
- .has_dp_mst = 1,
- .has_fpga_dbg = 1,
- .has_hotplug = 1,
- .has_psr = 1,
- .has_psr_hw_tracking = 1,
- HSW_PIPE_OFFSETS,
- IVB_CURSOR_OFFSETS,
- IVB_COLORS,
+static const u16 bdw_ult_ids[] = {
+ INTEL_BDW_ULT_GT1_IDS(ID),
+ INTEL_BDW_ULT_GT2_IDS(ID),
+ INTEL_BDW_ULT_GT3_IDS(ID),
+ INTEL_BDW_ULT_RSVD_IDS(ID),
+ 0
+};
- .__runtime_defaults.ip.ver = 8,
- .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
- .__runtime_defaults.cpu_transcoder_mask =
+static const u16 bdw_ulx_ids[] = {
+ INTEL_BDW_ULX_GT1_IDS(ID),
+ INTEL_BDW_ULX_GT2_IDS(ID),
+ INTEL_BDW_ULX_GT3_IDS(ID),
+ INTEL_BDW_ULX_RSVD_IDS(ID),
+ 0
+};
+
+static const struct platform_desc bdw_desc = {
+ PLATFORM(BROADWELL),
+ .subplatforms = (const struct subplatform_desc[]) {
+ { INTEL_DISPLAY_BROADWELL_ULT, "ULT", bdw_ult_ids },
+ { INTEL_DISPLAY_BROADWELL_ULX, "ULX", bdw_ulx_ids },
+ {},
+ },
+ .info = &(const struct intel_display_device_info) {
+ .has_ddi = 1,
+ .has_dp_mst = 1,
+ .has_fpga_dbg = 1,
+ .has_hotplug = 1,
+ .has_psr = 1,
+ .has_psr_hw_tracking = 1,
+ HSW_PIPE_OFFSETS,
+ IVB_CURSOR_OFFSETS,
+ IVB_COLORS,
+
+ .__runtime_defaults.ip.ver = 8,
+ .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
+ .__runtime_defaults.cpu_transcoder_mask =
BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP),
- .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
- .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
+ .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
+ },
};
-static const struct intel_display_device_info chv_display = {
- .has_hotplug = 1,
- .has_gmch = 1,
- .mmio_offset = VLV_DISPLAY_BASE,
- CHV_PIPE_OFFSETS,
- CHV_CURSOR_OFFSETS,
- CHV_COLORS,
-
- .__runtime_defaults.ip.ver = 8,
- .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
- .__runtime_defaults.cpu_transcoder_mask =
+static const struct platform_desc chv_desc = {
+ PLATFORM(CHERRYVIEW),
+ .info = &(const struct intel_display_device_info) {
+ .has_hotplug = 1,
+ .has_gmch = 1,
+ .mmio_offset = VLV_DISPLAY_BASE,
+ CHV_PIPE_OFFSETS,
+ CHV_CURSOR_OFFSETS,
+ CHV_COLORS,
+
+ .__runtime_defaults.ip.ver = 8,
+ .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
+ .__runtime_defaults.cpu_transcoder_mask =
BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C),
- .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* HDMI/DP B/C/D */
+ .__runtime_defaults.port_mask = BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D), /* HDMI/DP B/C/D */
+ },
};
static const struct intel_display_device_info skl_display = {
@@ -467,13 +591,99 @@ static const struct intel_display_device_info skl_display = {
.__runtime_defaults.has_hdcp = 1,
.__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
.__runtime_defaults.cpu_transcoder_mask =
- BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
- BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP),
+ BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
+ BIT(TRANSCODER_C) | BIT(TRANSCODER_EDP),
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A),
};
-#define GEN9_LP_DISPLAY \
+static const u16 skl_ult_ids[] = {
+ INTEL_SKL_ULT_GT1_IDS(ID),
+ INTEL_SKL_ULT_GT2_IDS(ID),
+ INTEL_SKL_ULT_GT3_IDS(ID),
+ 0
+};
+
+static const u16 skl_ulx_ids[] = {
+ INTEL_SKL_ULX_GT1_IDS(ID),
+ INTEL_SKL_ULX_GT2_IDS(ID),
+ 0
+};
+
+static const struct platform_desc skl_desc = {
+ PLATFORM(SKYLAKE),
+ .subplatforms = (const struct subplatform_desc[]) {
+ { INTEL_DISPLAY_SKYLAKE_ULT, "ULT", skl_ult_ids },
+ { INTEL_DISPLAY_SKYLAKE_ULX, "ULX", skl_ulx_ids },
+ {},
+ },
+ .info = &skl_display,
+};
+
+static const u16 kbl_ult_ids[] = {
+ INTEL_KBL_ULT_GT1_IDS(ID),
+ INTEL_KBL_ULT_GT2_IDS(ID),
+ INTEL_KBL_ULT_GT3_IDS(ID),
+ 0
+};
+
+static const u16 kbl_ulx_ids[] = {
+ INTEL_KBL_ULX_GT1_IDS(ID),
+ INTEL_KBL_ULX_GT2_IDS(ID),
+ INTEL_AML_KBL_GT2_IDS(ID),
+ 0
+};
+
+static const struct platform_desc kbl_desc = {
+ PLATFORM(KABYLAKE),
+ .subplatforms = (const struct subplatform_desc[]) {
+ { INTEL_DISPLAY_KABYLAKE_ULT, "ULT", kbl_ult_ids },
+ { INTEL_DISPLAY_KABYLAKE_ULX, "ULX", kbl_ulx_ids },
+ {},
+ },
+ .info = &skl_display,
+};
+
+static const u16 cfl_ult_ids[] = {
+ INTEL_CFL_U_GT2_IDS(ID),
+ INTEL_CFL_U_GT3_IDS(ID),
+ INTEL_WHL_U_GT1_IDS(ID),
+ INTEL_WHL_U_GT2_IDS(ID),
+ INTEL_WHL_U_GT3_IDS(ID),
+ 0
+};
+
+static const u16 cfl_ulx_ids[] = {
+ INTEL_AML_CFL_GT2_IDS(ID),
+ 0
+};
+
+static const struct platform_desc cfl_desc = {
+ PLATFORM(COFFEELAKE),
+ .subplatforms = (const struct subplatform_desc[]) {
+ { INTEL_DISPLAY_COFFEELAKE_ULT, "ULT", cfl_ult_ids },
+ { INTEL_DISPLAY_COFFEELAKE_ULX, "ULX", cfl_ulx_ids },
+ {},
+ },
+ .info = &skl_display,
+};
+
+static const u16 cml_ult_ids[] = {
+ INTEL_CML_U_GT1_IDS(ID),
+ INTEL_CML_U_GT2_IDS(ID),
+ 0
+};
+
+static const struct platform_desc cml_desc = {
+ PLATFORM(COMETLAKE),
+ .subplatforms = (const struct subplatform_desc[]) {
+ { INTEL_DISPLAY_COMETLAKE_ULT, "ULT", cml_ult_ids },
+ {},
+ },
+ .info = &skl_display,
+};
+
+#define GEN9_LP_DISPLAY \
.dbuf.slice_mask = BIT(DBUF_S1), \
.has_dp_mst = 1, \
.has_ddi = 1, \
@@ -496,19 +706,25 @@ static const struct intel_display_device_info skl_display = {
BIT(TRANSCODER_DSI_A) | BIT(TRANSCODER_DSI_C), \
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C)
-static const struct intel_display_device_info bxt_display = {
- GEN9_LP_DISPLAY,
- .dbuf.size = 512 - 4, /* 4 blocks for bypass path allocation */
+static const struct platform_desc bxt_desc = {
+ PLATFORM(BROXTON),
+ .info = &(const struct intel_display_device_info) {
+ GEN9_LP_DISPLAY,
+ .dbuf.size = 512 - 4, /* 4 blocks for bypass path allocation */
- .__runtime_defaults.ip.ver = 9,
+ .__runtime_defaults.ip.ver = 9,
+ },
};
-static const struct intel_display_device_info glk_display = {
- GEN9_LP_DISPLAY,
- .dbuf.size = 1024 - 4, /* 4 blocks for bypass path allocation */
- GLK_COLORS,
+static const struct platform_desc glk_desc = {
+ PLATFORM(GEMINILAKE),
+ .info = &(const struct intel_display_device_info) {
+ GEN9_LP_DISPLAY,
+ .dbuf.size = 1024 - 4, /* 4 blocks for bypass path allocation */
+ GLK_COLORS,
- .__runtime_defaults.ip.ver = 10,
+ .__runtime_defaults.ip.ver = 10,
+ },
};
#define ICL_DISPLAY \
@@ -552,10 +768,22 @@ static const struct intel_display_device_info glk_display = {
BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1), \
.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A)
-static const struct intel_display_device_info icl_display = {
- ICL_DISPLAY,
+static const u16 icl_port_f_ids[] = {
+ INTEL_ICL_PORT_F_IDS(ID),
+ 0
+};
- .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
+static const struct platform_desc icl_desc = {
+ PLATFORM(ICELAKE),
+ .subplatforms = (const struct subplatform_desc[]) {
+ { INTEL_DISPLAY_ICELAKE_PORT_F, "Port F", icl_port_f_ids },
+ {},
+ },
+ .info = &(const struct intel_display_device_info) {
+ ICL_DISPLAY,
+
+ .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D) | BIT(PORT_E),
+ },
};
static const struct intel_display_device_info jsl_ehl_display = {
@@ -564,6 +792,16 @@ static const struct intel_display_device_info jsl_ehl_display = {
.__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | BIT(PORT_C) | BIT(PORT_D),
};
+static const struct platform_desc jsl_desc = {
+ PLATFORM(JASPERLAKE),
+ .info = &jsl_ehl_display,
+};
+
+static const struct platform_desc ehl_desc = {
+ PLATFORM(ELKHARTLAKE),
+ .info = &jsl_ehl_display,
+};
+
#define XE_D_DISPLAY \
.abox_mask = GENMASK(2, 1), \
.dbuf.size = 2048, \
@@ -607,44 +845,74 @@ static const struct intel_display_device_info jsl_ehl_display = {
BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1), \
.__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A)
-static const struct intel_display_device_info tgl_display = {
- XE_D_DISPLAY,
+static const u16 tgl_uy_ids[] = {
+ INTEL_TGL_GT2_IDS(ID),
+ 0
+};
- /*
- * FIXME DDI C/combo PHY C missing due to combo PHY
- * code making a mess on SKUs where the PHY is missing.
- */
- .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
+static const struct platform_desc tgl_desc = {
+ PLATFORM(TIGERLAKE),
+ .subplatforms = (const struct subplatform_desc[]) {
+ { INTEL_DISPLAY_TIGERLAKE_UY, "UY", tgl_uy_ids },
+ {},
+ },
+ .info = &(const struct intel_display_device_info) {
+ XE_D_DISPLAY,
+
+ /*
+ * FIXME DDI C/combo PHY C missing due to combo PHY
+ * code making a mess on SKUs where the PHY is missing.
+ */
+ .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4) | BIT(PORT_TC5) | BIT(PORT_TC6),
+ },
};
-static const struct intel_display_device_info dg1_display = {
- XE_D_DISPLAY,
+static const struct platform_desc dg1_desc = {
+ PLATFORM(DG1),
+ .info = &(const struct intel_display_device_info) {
+ XE_D_DISPLAY,
- .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
+ .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
BIT(PORT_TC1) | BIT(PORT_TC2),
+ },
};
-static const struct intel_display_device_info rkl_display = {
- XE_D_DISPLAY,
- .abox_mask = BIT(0),
- .has_hti = 1,
- .has_psr_hw_tracking = 0,
+static const struct platform_desc rkl_desc = {
+ PLATFORM(ROCKETLAKE),
+ .info = &(const struct intel_display_device_info) {
+ XE_D_DISPLAY,
+ .abox_mask = BIT(0),
+ .has_hti = 1,
+ .has_psr_hw_tracking = 0,
- .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
- .__runtime_defaults.cpu_transcoder_mask =
+ .__runtime_defaults.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C),
+ .__runtime_defaults.cpu_transcoder_mask =
BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C),
- .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
+ .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |
BIT(PORT_TC1) | BIT(PORT_TC2),
+ },
};
-static const struct intel_display_device_info adl_s_display = {
- XE_D_DISPLAY,
- .has_hti = 1,
- .has_psr_hw_tracking = 0,
+static const u16 adls_rpls_ids[] = {
+ INTEL_RPLS_IDS(ID),
+ 0
+};
- .__runtime_defaults.port_mask = BIT(PORT_A) |
+static const struct platform_desc adl_s_desc = {
+ PLATFORM(ALDERLAKE_S),
+ .subplatforms = (const struct subplatform_desc[]) {
+ { INTEL_DISPLAY_ALDERLAKE_S_RAPTORLAKE_S, "RPL-S", adls_rpls_ids },
+ {},
+ },
+ .info = &(const struct intel_display_device_info) {
+ XE_D_DISPLAY,
+ .has_hti = 1,
+ .has_psr_hw_tracking = 0,
+
+ .__runtime_defaults.port_mask = BIT(PORT_A) |
BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4),
+ },
};
#define XE_LPD_FEATURES \
@@ -703,6 +971,32 @@ static const struct intel_display_device_info xe_lpd_display = {
BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4),
};
+static const u16 adlp_adln_ids[] = {
+ INTEL_ADLN_IDS(ID),
+ 0
+};
+
+static const u16 adlp_rplu_ids[] = {
+ INTEL_RPLU_IDS(ID),
+ 0
+};
+
+static const u16 adlp_rplp_ids[] = {
+ INTEL_RPLP_IDS(ID),
+ 0
+};
+
+static const struct platform_desc adl_p_desc = {
+ PLATFORM(ALDERLAKE_P),
+ .subplatforms = (const struct subplatform_desc[]) {
+ { INTEL_DISPLAY_ALDERLAKE_P_ALDERLAKE_N, "ADL-N", adlp_adln_ids },
+ { INTEL_DISPLAY_ALDERLAKE_P_RAPTORLAKE_U, "RPL-U", adlp_rplu_ids },
+ { INTEL_DISPLAY_ALDERLAKE_P_RAPTORLAKE_P, "RPL-P", adlp_rplp_ids },
+ {},
+ },
+ .info = &xe_lpd_display,
+};
+
static const struct intel_display_device_info xe_hpd_display = {
XE_LPD_FEATURES,
.has_cdclk_squash = 1,
@@ -714,6 +1008,32 @@ static const struct intel_display_device_info xe_hpd_display = {
BIT(PORT_TC1),
};
+static const u16 dg2_g10_ids[] = {
+ INTEL_DG2_G10_IDS(ID),
+ 0
+};
+
+static const u16 dg2_g11_ids[] = {
+ INTEL_DG2_G11_IDS(ID),
+ 0
+};
+
+static const u16 dg2_g12_ids[] = {
+ INTEL_DG2_G12_IDS(ID),
+ 0
+};
+
+static const struct platform_desc dg2_desc = {
+ PLATFORM(DG2),
+ .subplatforms = (const struct subplatform_desc[]) {
+ { INTEL_DISPLAY_DG2_G10, "G10", dg2_g10_ids },
+ { INTEL_DISPLAY_DG2_G11, "G11", dg2_g11_ids },
+ { INTEL_DISPLAY_DG2_G12, "G12", dg2_g12_ids },
+ {},
+ },
+ .info = &xe_hpd_display,
+};
+
#define XE_LPDP_FEATURES \
.abox_mask = GENMASK(1, 0), \
.color = { \
@@ -771,6 +1091,29 @@ static const struct intel_display_device_info xe2_lpd_display = {
BIT(INTEL_FBC_C) | BIT(INTEL_FBC_D),
};
+static const struct intel_display_device_info xe2_hpd_display = {
+ XE_LPDP_FEATURES,
+ .__runtime_defaults.port_mask = BIT(PORT_A) |
+ BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4),
+};
+
+/*
+ * Do not initialize the .info member of the platform desc for GMD ID based
+ * platforms. Their display will be probed automatically based on the IP version
+ * reported by the hardware.
+ */
+static const struct platform_desc mtl_desc = {
+ PLATFORM(METEORLAKE),
+};
+
+static const struct platform_desc lnl_desc = {
+ PLATFORM(LUNARLAKE),
+};
+
+static const struct platform_desc bmg_desc = {
+ PLATFORM(BATTLEMAGE),
+};
+
__diag_pop();
/*
@@ -782,68 +1125,64 @@ __diag_pop();
static bool has_no_display(struct pci_dev *pdev)
{
static const struct pci_device_id ids[] = {
- INTEL_IVB_Q_IDS(0),
+ INTEL_IVB_Q_IDS(INTEL_VGA_DEVICE, 0),
{}
};
return pci_match_id(ids, pdev);
}
-#undef INTEL_VGA_DEVICE
-#define INTEL_VGA_DEVICE(id, info) { id, info }
+#define INTEL_DISPLAY_DEVICE(_id, _desc) { .devid = (_id), .desc = (_desc) }
static const struct {
u32 devid;
- const struct intel_display_device_info *info;
+ const struct platform_desc *desc;
} intel_display_ids[] = {
- INTEL_I830_IDS(&i830_display),
- INTEL_I845G_IDS(&i845_display),
- INTEL_I85X_IDS(&i85x_display),
- INTEL_I865G_IDS(&i865g_display),
- INTEL_I915G_IDS(&i915g_display),
- INTEL_I915GM_IDS(&i915gm_display),
- INTEL_I945G_IDS(&i945g_display),
- INTEL_I945GM_IDS(&i945gm_display),
- INTEL_I965G_IDS(&i965g_display),
- INTEL_G33_IDS(&g33_display),
- INTEL_I965GM_IDS(&i965gm_display),
- INTEL_GM45_IDS(&gm45_display),
- INTEL_G45_IDS(&g45_display),
- INTEL_PINEVIEW_G_IDS(&pnv_display),
- INTEL_PINEVIEW_M_IDS(&pnv_display),
- INTEL_IRONLAKE_D_IDS(&ilk_d_display),
- INTEL_IRONLAKE_M_IDS(&ilk_m_display),
- INTEL_SNB_D_IDS(&snb_display),
- INTEL_SNB_M_IDS(&snb_display),
- INTEL_IVB_M_IDS(&ivb_display),
- INTEL_IVB_D_IDS(&ivb_display),
- INTEL_HSW_IDS(&hsw_display),
- INTEL_VLV_IDS(&vlv_display),
- INTEL_BDW_IDS(&bdw_display),
- INTEL_CHV_IDS(&chv_display),
- INTEL_SKL_IDS(&skl_display),
- INTEL_BXT_IDS(&bxt_display),
- INTEL_GLK_IDS(&glk_display),
- INTEL_KBL_IDS(&skl_display),
- INTEL_CFL_IDS(&skl_display),
- INTEL_ICL_11_IDS(&icl_display),
- INTEL_EHL_IDS(&jsl_ehl_display),
- INTEL_JSL_IDS(&jsl_ehl_display),
- INTEL_TGL_12_IDS(&tgl_display),
- INTEL_DG1_IDS(&dg1_display),
- INTEL_RKL_IDS(&rkl_display),
- INTEL_ADLS_IDS(&adl_s_display),
- INTEL_RPLS_IDS(&adl_s_display),
- INTEL_ADLP_IDS(&xe_lpd_display),
- INTEL_ADLN_IDS(&xe_lpd_display),
- INTEL_RPLP_IDS(&xe_lpd_display),
- INTEL_DG2_IDS(&xe_hpd_display),
-
- /*
- * Do not add any GMD_ID-based platforms to this list. They will
- * be probed automatically based on the IP version reported by
- * the hardware.
- */
+ INTEL_I830_IDS(INTEL_DISPLAY_DEVICE, &i830_desc),
+ INTEL_I845G_IDS(INTEL_DISPLAY_DEVICE, &i845_desc),
+ INTEL_I85X_IDS(INTEL_DISPLAY_DEVICE, &i85x_desc),
+ INTEL_I865G_IDS(INTEL_DISPLAY_DEVICE, &i865g_desc),
+ INTEL_I915G_IDS(INTEL_DISPLAY_DEVICE, &i915g_desc),
+ INTEL_I915GM_IDS(INTEL_DISPLAY_DEVICE, &i915gm_desc),
+ INTEL_I945G_IDS(INTEL_DISPLAY_DEVICE, &i945g_desc),
+ INTEL_I945GM_IDS(INTEL_DISPLAY_DEVICE, &i945gm_desc),
+ INTEL_I965G_IDS(INTEL_DISPLAY_DEVICE, &i965g_desc),
+ INTEL_G33_IDS(INTEL_DISPLAY_DEVICE, &g33_desc),
+ INTEL_I965GM_IDS(INTEL_DISPLAY_DEVICE, &i965gm_desc),
+ INTEL_GM45_IDS(INTEL_DISPLAY_DEVICE, &gm45_desc),
+ INTEL_G45_IDS(INTEL_DISPLAY_DEVICE, &g45_desc),
+ INTEL_PNV_IDS(INTEL_DISPLAY_DEVICE, &pnv_desc),
+ INTEL_ILK_D_IDS(INTEL_DISPLAY_DEVICE, &ilk_d_desc),
+ INTEL_ILK_M_IDS(INTEL_DISPLAY_DEVICE, &ilk_m_desc),
+ INTEL_SNB_IDS(INTEL_DISPLAY_DEVICE, &snb_desc),
+ INTEL_IVB_IDS(INTEL_DISPLAY_DEVICE, &ivb_desc),
+ INTEL_HSW_IDS(INTEL_DISPLAY_DEVICE, &hsw_desc),
+ INTEL_VLV_IDS(INTEL_DISPLAY_DEVICE, &vlv_desc),
+ INTEL_BDW_IDS(INTEL_DISPLAY_DEVICE, &bdw_desc),
+ INTEL_CHV_IDS(INTEL_DISPLAY_DEVICE, &chv_desc),
+ INTEL_SKL_IDS(INTEL_DISPLAY_DEVICE, &skl_desc),
+ INTEL_BXT_IDS(INTEL_DISPLAY_DEVICE, &bxt_desc),
+ INTEL_GLK_IDS(INTEL_DISPLAY_DEVICE, &glk_desc),
+ INTEL_KBL_IDS(INTEL_DISPLAY_DEVICE, &kbl_desc),
+ INTEL_CFL_IDS(INTEL_DISPLAY_DEVICE, &cfl_desc),
+ INTEL_WHL_IDS(INTEL_DISPLAY_DEVICE, &cfl_desc),
+ INTEL_CML_IDS(INTEL_DISPLAY_DEVICE, &cml_desc),
+ INTEL_ICL_IDS(INTEL_DISPLAY_DEVICE, &icl_desc),
+ INTEL_EHL_IDS(INTEL_DISPLAY_DEVICE, &ehl_desc),
+ INTEL_JSL_IDS(INTEL_DISPLAY_DEVICE, &jsl_desc),
+ INTEL_TGL_IDS(INTEL_DISPLAY_DEVICE, &tgl_desc),
+ INTEL_DG1_IDS(INTEL_DISPLAY_DEVICE, &dg1_desc),
+ INTEL_RKL_IDS(INTEL_DISPLAY_DEVICE, &rkl_desc),
+ INTEL_ADLS_IDS(INTEL_DISPLAY_DEVICE, &adl_s_desc),
+ INTEL_RPLS_IDS(INTEL_DISPLAY_DEVICE, &adl_s_desc),
+ INTEL_ADLP_IDS(INTEL_DISPLAY_DEVICE, &adl_p_desc),
+ INTEL_ADLN_IDS(INTEL_DISPLAY_DEVICE, &adl_p_desc),
+ INTEL_RPLU_IDS(INTEL_DISPLAY_DEVICE, &adl_p_desc),
+ INTEL_RPLP_IDS(INTEL_DISPLAY_DEVICE, &adl_p_desc),
+ INTEL_DG2_IDS(INTEL_DISPLAY_DEVICE, &dg2_desc),
+ INTEL_MTL_IDS(INTEL_DISPLAY_DEVICE, &mtl_desc),
+ INTEL_LNL_IDS(INTEL_DISPLAY_DEVICE, &lnl_desc),
+ INTEL_BMG_IDS(INTEL_DISPLAY_DEVICE, &bmg_desc),
};
static const struct {
@@ -852,30 +1191,23 @@ static const struct {
const struct intel_display_device_info *display;
} gmdid_display_map[] = {
{ 14, 0, &xe_lpdp_display },
+ { 14, 1, &xe2_hpd_display },
{ 20, 0, &xe2_lpd_display },
};
static const struct intel_display_device_info *
-probe_gmdid_display(struct drm_i915_private *i915, u16 *ver, u16 *rel, u16 *step)
+probe_gmdid_display(struct drm_i915_private *i915, struct intel_display_ip_ver *ip_ver)
{
struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
+ struct intel_display_ip_ver gmd_id;
void __iomem *addr;
u32 val;
int i;
- /* The caller expects to ver, rel and step to be initialized
- * here, and there's no good way to check when there was a
- * failure and no_display was returned. So initialize all these
- * values here zero, to be sure.
- */
- *ver = 0;
- *rel = 0;
- *step = 0;
-
addr = pci_iomap_range(pdev, 0, i915_mmio_reg_offset(GMD_ID_DISPLAY), sizeof(u32));
if (!addr) {
drm_err(&i915->drm, "Cannot map MMIO BAR to read display GMD_ID\n");
- return &no_display;
+ return NULL;
}
val = ioread32(addr);
@@ -883,57 +1215,82 @@ probe_gmdid_display(struct drm_i915_private *i915, u16 *ver, u16 *rel, u16 *step
if (val == 0) {
drm_dbg_kms(&i915->drm, "Device doesn't have display\n");
- return &no_display;
+ return NULL;
}
- *ver = REG_FIELD_GET(GMD_ID_ARCH_MASK, val);
- *rel = REG_FIELD_GET(GMD_ID_RELEASE_MASK, val);
- *step = REG_FIELD_GET(GMD_ID_STEP, val);
+ gmd_id.ver = REG_FIELD_GET(GMD_ID_ARCH_MASK, val);
+ gmd_id.rel = REG_FIELD_GET(GMD_ID_RELEASE_MASK, val);
+ gmd_id.step = REG_FIELD_GET(GMD_ID_STEP, val);
- for (i = 0; i < ARRAY_SIZE(gmdid_display_map); i++)
- if (*ver == gmdid_display_map[i].ver &&
- *rel == gmdid_display_map[i].rel)
+ for (i = 0; i < ARRAY_SIZE(gmdid_display_map); i++) {
+ if (gmd_id.ver == gmdid_display_map[i].ver &&
+ gmd_id.rel == gmdid_display_map[i].rel) {
+ *ip_ver = gmd_id;
return gmdid_display_map[i].display;
+ }
+ }
drm_err(&i915->drm, "Unrecognized display IP version %d.%02d; disabling display.\n",
- *ver, *rel);
- return &no_display;
+ gmd_id.ver, gmd_id.rel);
+ return NULL;
}
-static const struct intel_display_device_info *
-probe_display(struct drm_i915_private *i915)
+static const struct platform_desc *find_platform_desc(struct pci_dev *pdev)
{
- struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
int i;
- if (has_no_display(pdev)) {
- drm_dbg_kms(&i915->drm, "Device doesn't have display\n");
- return &no_display;
- }
-
for (i = 0; i < ARRAY_SIZE(intel_display_ids); i++) {
if (intel_display_ids[i].devid == pdev->device)
- return intel_display_ids[i].info;
+ return intel_display_ids[i].desc;
}
- drm_dbg(&i915->drm, "No display ID found for device ID %04x; disabling display.\n",
- pdev->device);
+ return NULL;
+}
+
+static const struct subplatform_desc *
+find_subplatform_desc(struct pci_dev *pdev, const struct platform_desc *desc)
+{
+ const struct subplatform_desc *sp;
+ const u16 *id;
+
+ for (sp = desc->subplatforms; sp && sp->subplatform; sp++)
+ for (id = sp->pciidlist; *id; id++)
+ if (*id == pdev->device)
+ return sp;
- return &no_display;
+ return NULL;
}
void intel_display_device_probe(struct drm_i915_private *i915)
{
+ struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
const struct intel_display_device_info *info;
- u16 ver, rel, step;
+ struct intel_display_ip_ver ip_ver = {};
+ const struct platform_desc *desc;
+ const struct subplatform_desc *subdesc;
/* Add drm device backpointer as early as possible. */
i915->display.drm = &i915->drm;
- if (HAS_GMD_ID(i915))
- info = probe_gmdid_display(i915, &ver, &rel, &step);
- else
- info = probe_display(i915);
+ intel_display_params_copy(&i915->display.params);
+
+ if (has_no_display(pdev)) {
+ drm_dbg_kms(&i915->drm, "Device doesn't have display\n");
+ goto no_display;
+ }
+
+ desc = find_platform_desc(pdev);
+ if (!desc) {
+ drm_dbg_kms(&i915->drm, "Unknown device ID %04x; disabling display.\n",
+ pdev->device);
+ goto no_display;
+ }
+
+ info = desc->info;
+ if (!info)
+ info = probe_gmdid_display(i915, &ip_ver);
+ if (!info)
+ goto no_display;
DISPLAY_INFO(i915) = info;
@@ -941,13 +1298,27 @@ void intel_display_device_probe(struct drm_i915_private *i915)
&DISPLAY_INFO(i915)->__runtime_defaults,
sizeof(*DISPLAY_RUNTIME_INFO(i915)));
- if (HAS_GMD_ID(i915)) {
- DISPLAY_RUNTIME_INFO(i915)->ip.ver = ver;
- DISPLAY_RUNTIME_INFO(i915)->ip.rel = rel;
- DISPLAY_RUNTIME_INFO(i915)->ip.step = step;
+ drm_WARN_ON(&i915->drm, !desc->platform || !desc->name);
+ DISPLAY_RUNTIME_INFO(i915)->platform = desc->platform;
+
+ subdesc = find_subplatform_desc(pdev, desc);
+ if (subdesc) {
+ drm_WARN_ON(&i915->drm, !subdesc->subplatform || !subdesc->name);
+ DISPLAY_RUNTIME_INFO(i915)->subplatform = subdesc->subplatform;
}
- intel_display_params_copy(&i915->display.params);
+ if (ip_ver.ver || ip_ver.rel || ip_ver.step)
+ DISPLAY_RUNTIME_INFO(i915)->ip = ip_ver;
+
+ drm_info(&i915->drm, "Found %s%s%s (device ID %04x) display version %u.%02u\n",
+ desc->name, subdesc ? "/" : "", subdesc ? subdesc->name : "",
+ pdev->device, DISPLAY_RUNTIME_INFO(i915)->ip.ver,
+ DISPLAY_RUNTIME_INFO(i915)->ip.rel);
+
+ return;
+
+no_display:
+ DISPLAY_INFO(i915) = &no_display;
}
void intel_display_device_remove(struct drm_i915_private *i915)
diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h
index 17ddf82f0b6e..13453ea4daea 100644
--- a/drivers/gpu/drm/i915/display/intel_display_device.h
+++ b/drivers/gpu/drm/i915/display/intel_display_device.h
@@ -14,6 +14,89 @@
struct drm_i915_private;
struct drm_printer;
+/* Keep in gen based order, and chronological order within a gen */
+enum intel_display_platform {
+ INTEL_DISPLAY_PLATFORM_UNINITIALIZED = 0,
+ /* Display ver 2 */
+ INTEL_DISPLAY_I830,
+ INTEL_DISPLAY_I845G,
+ INTEL_DISPLAY_I85X,
+ INTEL_DISPLAY_I865G,
+ /* Display ver 3 */
+ INTEL_DISPLAY_I915G,
+ INTEL_DISPLAY_I915GM,
+ INTEL_DISPLAY_I945G,
+ INTEL_DISPLAY_I945GM,
+ INTEL_DISPLAY_G33,
+ INTEL_DISPLAY_PINEVIEW,
+ /* Display ver 4 */
+ INTEL_DISPLAY_I965G,
+ INTEL_DISPLAY_I965GM,
+ INTEL_DISPLAY_G45,
+ INTEL_DISPLAY_GM45,
+ /* Display ver 5 */
+ INTEL_DISPLAY_IRONLAKE,
+ /* Display ver 6 */
+ INTEL_DISPLAY_SANDYBRIDGE,
+ /* Display ver 7 */
+ INTEL_DISPLAY_IVYBRIDGE,
+ INTEL_DISPLAY_VALLEYVIEW,
+ INTEL_DISPLAY_HASWELL,
+ /* Display ver 8 */
+ INTEL_DISPLAY_BROADWELL,
+ INTEL_DISPLAY_CHERRYVIEW,
+ /* Display ver 9 */
+ INTEL_DISPLAY_SKYLAKE,
+ INTEL_DISPLAY_BROXTON,
+ INTEL_DISPLAY_KABYLAKE,
+ INTEL_DISPLAY_GEMINILAKE,
+ INTEL_DISPLAY_COFFEELAKE,
+ INTEL_DISPLAY_COMETLAKE,
+ /* Display ver 11 */
+ INTEL_DISPLAY_ICELAKE,
+ INTEL_DISPLAY_JASPERLAKE,
+ INTEL_DISPLAY_ELKHARTLAKE,
+ /* Display ver 12 */
+ INTEL_DISPLAY_TIGERLAKE,
+ INTEL_DISPLAY_ROCKETLAKE,
+ INTEL_DISPLAY_DG1,
+ INTEL_DISPLAY_ALDERLAKE_S,
+ /* Display ver 13 */
+ INTEL_DISPLAY_ALDERLAKE_P,
+ INTEL_DISPLAY_DG2,
+ /* Display ver 14 (based on GMD ID) */
+ INTEL_DISPLAY_METEORLAKE,
+ /* Display ver 20 (based on GMD ID) */
+ INTEL_DISPLAY_LUNARLAKE,
+ /* Display ver 14.1 (based on GMD ID) */
+ INTEL_DISPLAY_BATTLEMAGE,
+};
+
+enum intel_display_subplatform {
+ INTEL_DISPLAY_SUBPLATFORM_UNINITIALIZED = 0,
+ INTEL_DISPLAY_HASWELL_ULT,
+ INTEL_DISPLAY_HASWELL_ULX,
+ INTEL_DISPLAY_BROADWELL_ULT,
+ INTEL_DISPLAY_BROADWELL_ULX,
+ INTEL_DISPLAY_SKYLAKE_ULT,
+ INTEL_DISPLAY_SKYLAKE_ULX,
+ INTEL_DISPLAY_KABYLAKE_ULT,
+ INTEL_DISPLAY_KABYLAKE_ULX,
+ INTEL_DISPLAY_COFFEELAKE_ULT,
+ INTEL_DISPLAY_COFFEELAKE_ULX,
+ INTEL_DISPLAY_COMETLAKE_ULT,
+ INTEL_DISPLAY_COMETLAKE_ULX,
+ INTEL_DISPLAY_ICELAKE_PORT_F,
+ INTEL_DISPLAY_TIGERLAKE_UY,
+ INTEL_DISPLAY_ALDERLAKE_S_RAPTORLAKE_S,
+ INTEL_DISPLAY_ALDERLAKE_P_ALDERLAKE_N,
+ INTEL_DISPLAY_ALDERLAKE_P_RAPTORLAKE_P,
+ INTEL_DISPLAY_ALDERLAKE_P_RAPTORLAKE_U,
+ INTEL_DISPLAY_DG2_G10,
+ INTEL_DISPLAY_DG2_G11,
+ INTEL_DISPLAY_DG2_G12,
+};
+
#define DEV_INFO_DISPLAY_FOR_EACH_FLAG(func) \
/* Keep in alphabetical order */ \
func(cursor_needs_physical); \
@@ -71,6 +154,7 @@ struct drm_printer;
BIT(trans)) != 0)
#define HAS_VRR(i915) (DISPLAY_VER(i915) >= 11)
#define HAS_AS_SDP(i915) (DISPLAY_VER(i915) >= 13)
+#define HAS_CMRR(i915) (DISPLAY_VER(i915) >= 20)
#define INTEL_NUM_PIPES(i915) (hweight8(DISPLAY_RUNTIME_INFO(i915)->pipe_mask))
#define I915_HAS_HOTPLUG(i915) (DISPLAY_INFO(i915)->has_hotplug)
#define OVERLAY_NEEDS_PHYSICAL(i915) (DISPLAY_INFO(i915)->overlay_needs_physical)
@@ -111,7 +195,10 @@ struct drm_printer;
(DISPLAY_VER(i915) >= (from) && DISPLAY_VER(i915) <= (until))
struct intel_display_runtime_info {
- struct {
+ enum intel_display_platform platform;
+ enum intel_display_subplatform subplatform;
+
+ struct intel_display_ip_ver {
u16 ver;
u16 rel;
u16 step;
diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c
index c337e0597541..82e1369e5d76 100644
--- a/drivers/gpu/drm/i915/display/intel_display_irq.c
+++ b/drivers/gpu/drm/i915/display/intel_display_irq.c
@@ -18,6 +18,7 @@
#include "intel_fifo_underrun.h"
#include "intel_gmbus.h"
#include "intel_hotplug_irq.h"
+#include "intel_pipe_crc_regs.h"
#include "intel_pmdemand.h"
#include "intel_psr.h"
#include "intel_psr_regs.h"
@@ -224,7 +225,7 @@ out:
void i915_enable_pipestat(struct drm_i915_private *dev_priv,
enum pipe pipe, u32 status_mask)
{
- i915_reg_t reg = PIPESTAT(pipe);
+ i915_reg_t reg = PIPESTAT(dev_priv, pipe);
u32 enable_mask;
drm_WARN_ONCE(&dev_priv->drm, status_mask & ~PIPESTAT_INT_STATUS_MASK,
@@ -247,7 +248,7 @@ void i915_enable_pipestat(struct drm_i915_private *dev_priv,
void i915_disable_pipestat(struct drm_i915_private *dev_priv,
enum pipe pipe, u32 status_mask)
{
- i915_reg_t reg = PIPESTAT(pipe);
+ i915_reg_t reg = PIPESTAT(dev_priv, pipe);
u32 enable_mask;
drm_WARN_ONCE(&dev_priv->drm, status_mask & ~PIPESTAT_INT_STATUS_MASK,
@@ -356,7 +357,7 @@ static void hsw_pipe_crc_irq_handler(struct drm_i915_private *dev_priv,
enum pipe pipe)
{
display_pipe_crc_irq_handler(dev_priv, pipe,
- intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_1_IVB(pipe)),
+ intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_HSW(pipe)),
0, 0, 0, 0);
}
@@ -377,19 +378,21 @@ static void i9xx_pipe_crc_irq_handler(struct drm_i915_private *dev_priv,
u32 res1, res2;
if (DISPLAY_VER(dev_priv) >= 3)
- res1 = intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_RES1_I915(pipe));
+ res1 = intel_uncore_read(&dev_priv->uncore,
+ PIPE_CRC_RES_RES1_I915(dev_priv, pipe));
else
res1 = 0;
if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv))
- res2 = intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_RES2_G4X(pipe));
+ res2 = intel_uncore_read(&dev_priv->uncore,
+ PIPE_CRC_RES_RES2_G4X(dev_priv, pipe));
else
res2 = 0;
display_pipe_crc_irq_handler(dev_priv, pipe,
- intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_RED(pipe)),
- intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_GREEN(pipe)),
- intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_BLUE(pipe)),
+ intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_RED(dev_priv, pipe)),
+ intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_GREEN(dev_priv, pipe)),
+ intel_uncore_read(&dev_priv->uncore, PIPE_CRC_RES_BLUE(dev_priv, pipe)),
res1, res2);
}
@@ -398,7 +401,8 @@ void i9xx_pipestat_irq_reset(struct drm_i915_private *dev_priv)
enum pipe pipe;
for_each_pipe(dev_priv, pipe) {
- intel_uncore_write(&dev_priv->uncore, PIPESTAT(pipe),
+ intel_uncore_write(&dev_priv->uncore,
+ PIPESTAT(dev_priv, pipe),
PIPESTAT_INT_STATUS_MASK |
PIPE_FIFO_UNDERRUN_STATUS);
@@ -451,7 +455,7 @@ void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv,
if (!status_mask)
continue;
- reg = PIPESTAT(pipe);
+ reg = PIPESTAT(dev_priv, pipe);
pipe_stats[pipe] = intel_uncore_read(&dev_priv->uncore, reg) & status_mask;
enable_mask = i915_pipestat_enable_mask(dev_priv, pipe);
@@ -876,7 +880,8 @@ gen8_de_misc_irq_handler(struct drm_i915_private *dev_priv, u32 iir)
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
if (DISPLAY_VER(dev_priv) >= 12)
- iir_reg = TRANS_PSR_IIR(intel_dp->psr.transcoder);
+ iir_reg = TRANS_PSR_IIR(dev_priv,
+ intel_dp->psr.transcoder);
else
iir_reg = EDP_PSR_IIR;
@@ -909,7 +914,8 @@ static void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv,
* Incase of dual link, TE comes from DSI_1
* this is to check if dual link is enabled
*/
- val = intel_uncore_read(&dev_priv->uncore, TRANS_DDI_FUNC_CTL2(TRANSCODER_DSI_0));
+ val = intel_uncore_read(&dev_priv->uncore,
+ TRANS_DDI_FUNC_CTL2(dev_priv, TRANSCODER_DSI_0));
val &= PORT_SYNC_MODE_ENABLE;
/*
@@ -930,7 +936,8 @@ static void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv,
}
/* Get PIPE for handling VBLANK event */
- val = intel_uncore_read(&dev_priv->uncore, TRANS_DDI_FUNC_CTL(dsi_trans));
+ val = intel_uncore_read(&dev_priv->uncore,
+ TRANS_DDI_FUNC_CTL(dev_priv, dsi_trans));
switch (val & TRANS_DDI_EDP_INPUT_MASK) {
case TRANS_DDI_EDP_INPUT_A_ON:
pipe = PIPE_A;
@@ -1374,7 +1381,7 @@ void vlv_display_irq_reset(struct drm_i915_private *dev_priv)
intel_uncore_write(uncore, DPINVGTT, DPINVGTT_STATUS_MASK_VLV);
i915_hotplug_interrupt_update_locked(dev_priv, 0xffffffff, 0);
- intel_uncore_rmw(uncore, PORT_HOTPLUG_STAT, 0, 0);
+ intel_uncore_rmw(uncore, PORT_HOTPLUG_STAT(dev_priv), 0, 0);
i9xx_pipestat_irq_reset(dev_priv);
@@ -1455,8 +1462,12 @@ void gen11_display_irq_reset(struct drm_i915_private *dev_priv)
if (!intel_display_power_is_enabled(dev_priv, domain))
continue;
- intel_uncore_write(uncore, TRANS_PSR_IMR(trans), 0xffffffff);
- intel_uncore_write(uncore, TRANS_PSR_IIR(trans), 0xffffffff);
+ intel_uncore_write(uncore,
+ TRANS_PSR_IMR(dev_priv, trans),
+ 0xffffffff);
+ intel_uncore_write(uncore,
+ TRANS_PSR_IIR(dev_priv, trans),
+ 0xffffffff);
}
} else {
intel_uncore_write(uncore, EDP_PSR_IMR, 0xffffffff);
@@ -1688,7 +1699,8 @@ void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
if (!intel_display_power_is_enabled(dev_priv, domain))
continue;
- gen3_assert_iir_is_zero(uncore, TRANS_PSR_IIR(trans));
+ gen3_assert_iir_is_zero(uncore,
+ TRANS_PSR_IIR(dev_priv, trans));
}
} else {
gen3_assert_iir_is_zero(uncore, EDP_PSR_IIR);
diff --git a/drivers/gpu/drm/i915/display/intel_display_limits.h b/drivers/gpu/drm/i915/display/intel_display_limits.h
index 5126d0b5ae5d..c4775c99dc83 100644
--- a/drivers/gpu/drm/i915/display/intel_display_limits.h
+++ b/drivers/gpu/drm/i915/display/intel_display_limits.h
@@ -60,16 +60,23 @@ enum transcoder {
* (eg. PLANE_CTL(), PS_PLANE_SEL(), etc.) so adjust with care.
*/
enum plane_id {
- PLANE_PRIMARY,
- PLANE_SPRITE0,
- PLANE_SPRITE1,
- PLANE_SPRITE2,
- PLANE_SPRITE3,
- PLANE_SPRITE4,
- PLANE_SPRITE5,
+ /* skl+ universal plane names */
+ PLANE_1,
+ PLANE_2,
+ PLANE_3,
+ PLANE_4,
+ PLANE_5,
+ PLANE_6,
+ PLANE_7,
+
PLANE_CURSOR,
I915_MAX_PLANES,
+
+ /* pre-skl plane names */
+ PLANE_PRIMARY = PLANE_1,
+ PLANE_SPRITE0,
+ PLANE_SPRITE1,
};
enum port {
diff --git a/drivers/gpu/drm/i915/display/intel_display_params.c b/drivers/gpu/drm/i915/display/intel_display_params.c
index 1799a6643128..79107607a6ff 100644
--- a/drivers/gpu/drm/i915/display/intel_display_params.c
+++ b/drivers/gpu/drm/i915/display/intel_display_params.c
@@ -116,7 +116,7 @@ intel_display_param_named(psr_safest_params, bool, 0400,
"Default: 0");
intel_display_param_named_unsafe(enable_psr2_sel_fetch, bool, 0400,
- "Enable PSR2 selective fetch "
+ "Enable PSR2 and Panel Replay selective fetch "
"(0=disabled, 1=enabled) "
"Default: 1");
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c
index 03dc7edcc443..e288a1b21d7e 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -675,6 +675,12 @@ intel_display_power_put_async_work(struct work_struct *work)
release_async_put_domains(power_domains,
&power_domains->async_put_domains[0]);
+ /*
+ * Cancel the work that got queued after this one got dequeued,
+ * since here we released the corresponding async-put reference.
+ */
+ cancel_async_put_work(power_domains, false);
+
/* Requeue the work if more domains were async put meanwhile. */
if (!bitmap_empty(power_domains->async_put_domains[1].bits, POWER_DOMAIN_NUM)) {
bitmap_copy(power_domains->async_put_domains[0].bits,
@@ -686,12 +692,6 @@ intel_display_power_put_async_work(struct work_struct *work)
fetch_and_zero(&new_work_wakeref),
power_domains->async_put_next_delay);
power_domains->async_put_next_delay = 0;
- } else {
- /*
- * Cancel the work that got queued after this one got dequeued,
- * since here we released the corresponding async-put reference.
- */
- cancel_async_put_work(power_domains, false);
}
out_verify:
@@ -1207,7 +1207,7 @@ static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv)
intel_de_read(dev_priv, WRPLL_CTL(1)) & WRPLL_PLL_ENABLE,
"WRPLL2 enabled\n");
I915_STATE_WARN(dev_priv,
- intel_de_read(dev_priv, PP_STATUS(0)) & PP_ON,
+ intel_de_read(dev_priv, PP_STATUS(dev_priv, 0)) & PP_ON,
"Panel power on\n");
I915_STATE_WARN(dev_priv,
intel_de_read(dev_priv, BLC_PWM_CPU_CTL2) & BLM_PWM_ENABLE,
@@ -1688,6 +1688,10 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv,
if (IS_DG2(dev_priv))
intel_snps_phy_wait_for_calibration(dev_priv);
+ /* 9. XE2_HPD: Program CHICKEN_MISC_2 before any cursor or planes are enabled */
+ if (DISPLAY_VER_FULL(dev_priv) == IP_VER(14, 1))
+ intel_de_rmw(dev_priv, CHICKEN_MISC_2, BMG_DARB_HALF_BLK_END_BURST, 1);
+
if (resume)
intel_dmc_load_program(dev_priv);
@@ -1768,7 +1772,7 @@ static void chv_phy_control_init(struct drm_i915_private *dev_priv)
* current lane status.
*/
if (intel_power_well_is_enabled(dev_priv, cmn_bc)) {
- u32 status = intel_de_read(dev_priv, DPLL(PIPE_A));
+ u32 status = intel_de_read(dev_priv, DPLL(dev_priv, PIPE_A));
unsigned int mask;
mask = status & DPLL_PORTB_READY_MASK;
diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.c b/drivers/gpu/drm/i915/display/intel_display_power_well.c
index 83f616097a29..919f712fef13 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power_well.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c
@@ -1044,9 +1044,9 @@ static bool i9xx_always_on_power_well_enabled(struct drm_i915_private *dev_priv,
static void i830_pipes_power_well_enable(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- if ((intel_de_read(dev_priv, TRANSCONF(PIPE_A)) & TRANSCONF_ENABLE) == 0)
+ if ((intel_de_read(dev_priv, TRANSCONF(dev_priv, PIPE_A)) & TRANSCONF_ENABLE) == 0)
i830_enable_pipe(dev_priv, PIPE_A);
- if ((intel_de_read(dev_priv, TRANSCONF(PIPE_B)) & TRANSCONF_ENABLE) == 0)
+ if ((intel_de_read(dev_priv, TRANSCONF(dev_priv, PIPE_B)) & TRANSCONF_ENABLE) == 0)
i830_enable_pipe(dev_priv, PIPE_B);
}
@@ -1060,8 +1060,8 @@ static void i830_pipes_power_well_disable(struct drm_i915_private *dev_priv,
static bool i830_pipes_power_well_enabled(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- return intel_de_read(dev_priv, TRANSCONF(PIPE_A)) & TRANSCONF_ENABLE &&
- intel_de_read(dev_priv, TRANSCONF(PIPE_B)) & TRANSCONF_ENABLE;
+ return intel_de_read(dev_priv, TRANSCONF(dev_priv, PIPE_A)) & TRANSCONF_ENABLE &&
+ intel_de_read(dev_priv, TRANSCONF(dev_priv, PIPE_B)) & TRANSCONF_ENABLE;
}
static void i830_pipes_power_well_sync_hw(struct drm_i915_private *dev_priv,
@@ -1196,13 +1196,13 @@ static void vlv_display_power_well_init(struct drm_i915_private *dev_priv)
* CHV DPLL B/C have some issues if VGA mode is enabled.
*/
for_each_pipe(dev_priv, pipe) {
- u32 val = intel_de_read(dev_priv, DPLL(pipe));
+ u32 val = intel_de_read(dev_priv, DPLL(dev_priv, pipe));
val |= DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
if (pipe != PIPE_A)
val |= DPLL_INTEGRATED_CRI_CLK_VLV;
- intel_de_write(dev_priv, DPLL(pipe), val);
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), val);
}
vlv_init_display_clock_gating(dev_priv);
@@ -1355,7 +1355,7 @@ static void assert_chv_phy_status(struct drm_i915_private *dev_priv)
*/
if (BITS_SET(phy_control,
PHY_CH_POWER_DOWN_OVRD(0xf, DPIO_PHY0, DPIO_CH1)) &&
- (intel_de_read(dev_priv, DPLL(PIPE_B)) & DPLL_VCO_ENABLE) == 0)
+ (intel_de_read(dev_priv, DPLL(dev_priv, PIPE_B)) & DPLL_VCO_ENABLE) == 0)
phy_status |= PHY_STATUS_CMN_LDO(DPIO_PHY0, DPIO_CH1);
if (BITS_SET(phy_control,
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 62f7a30c37dc..8fe7942511f8 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -44,9 +44,10 @@
#include <drm/drm_rect.h>
#include <drm/drm_vblank.h>
#include <drm/drm_vblank_work.h>
-#include <drm/i915_hdcp_interface.h>
+#include <drm/intel/i915_hdcp_interface.h>
#include <media/cec-notifier.h>
+#include "gem/i915_gem_object_types.h" /* for to_intel_bo() */
#include "i915_vma.h"
#include "i915_vma_types.h"
#include "intel_bios.h"
@@ -160,6 +161,11 @@ struct intel_encoder {
enum port port;
u16 cloneable;
u8 pipe_mask;
+
+ /* Check and recover a bad link state. */
+ struct delayed_work link_check_work;
+ void (*link_check)(struct intel_encoder *encoder);
+
enum intel_hotplug_state (*hotplug)(struct intel_encoder *encoder,
struct intel_connector *connector);
enum intel_output_type (*compute_output_type)(struct intel_encoder *,
@@ -305,7 +311,7 @@ enum drrs_type {
};
struct intel_vbt_panel_data {
- struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */
+ struct drm_display_mode *lfp_vbt_mode; /* if any */
struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */
/* Feature bits */
@@ -329,6 +335,7 @@ struct intel_vbt_panel_data {
u8 drrs_msa_timing_delay;
bool low_vswing;
bool hobl;
+ bool dsc_disable;
} edp;
struct {
@@ -401,7 +408,12 @@ struct intel_panel {
} vesa;
struct {
bool sdr_uses_aux;
- } intel;
+ bool supports_2084_decode;
+ bool supports_2020_gamut;
+ bool supports_segmented_backlight;
+ bool supports_sdp_colorimetry;
+ bool supports_tone_mapping;
+ } intel_cap;
} edp;
struct backlight_device *device;
@@ -1042,7 +1054,7 @@ struct intel_crtc_state {
*
* During initial hw readout, they need to be copied to uapi.
*
- * Bigjoiner will allow a transcoder mode that spans 2 pipes;
+ * Joiner will allow a transcoder mode that spans 2 pipes;
* Use the pipe_mode for calculations like watermarks, pipe
* scaler, and bandwidth.
*
@@ -1189,7 +1201,7 @@ struct intel_crtc_state {
/* PSR is supported but might not be enabled due the lack of enabled planes */
bool has_psr;
- bool has_psr2;
+ bool has_sel_update;
bool enable_psr2_sel_fetch;
bool enable_psr2_su_region_et;
bool req_psr2_sdp_prior_scanline;
@@ -1338,8 +1350,8 @@ struct intel_crtc_state {
/* enable vlv/chv wgc csc? */
bool wgc_enable;
- /* big joiner pipe bitmask */
- u8 bigjoiner_pipes;
+ /* joiner pipe bitmask */
+ u8 joiner_pipes;
/* Display Stream compression state */
struct {
@@ -1396,6 +1408,12 @@ struct intel_crtc_state {
u32 vsync_end, vsync_start;
} vrr;
+ /* Content Match Refresh Rate state */
+ struct {
+ bool enable;
+ u64 cmrr_n, cmrr_m;
+ } cmrr;
+
/* Stream Splitter for eDP MSO */
struct {
bool enable;
@@ -1405,6 +1423,9 @@ struct intel_crtc_state {
/* for loading single buffered registers during vblank */
struct drm_vblank_work vblank_work;
+
+ /* LOBF flag */
+ bool has_lobf;
};
enum intel_pipe_crc_source {
@@ -1521,7 +1542,7 @@ struct intel_plane {
enum i9xx_plane_id i9xx_plane;
enum plane_id id;
enum pipe pipe;
- bool need_async_flip_disable_wa;
+ bool need_async_flip_toggle_wa;
u32 frontbuffer_bit;
struct {
@@ -1682,6 +1703,7 @@ struct intel_psr {
#define I915_PSR_DEBUG_ENABLE_SEL_FETCH 0x4
#define I915_PSR_DEBUG_IRQ 0x10
#define I915_PSR_DEBUG_SU_REGION_ET_DISABLE 0x20
+#define I915_PSR_DEBUG_PANEL_REPLAY_DISABLE 0x40
u32 debug;
bool sink_support;
@@ -1695,22 +1717,12 @@ struct intel_psr {
unsigned int busy_frontbuffer_bits;
bool sink_psr2_support;
bool link_standby;
- bool psr2_enabled;
+ bool sel_update_enabled;
bool psr2_sel_fetch_enabled;
bool psr2_sel_fetch_cff_enabled;
+ bool su_region_et_enabled;
bool req_psr2_sdp_prior_scanline;
u8 sink_sync_latency;
-
- struct {
- u8 io_wake_lines;
- u8 fast_wake_lines;
-
- /* LNL and beyond */
- u8 check_entry_lines;
- u8 silence_period_sym_clocks;
- u8 lfps_half_cycle_num_of_syms;
- } alpm_parameters;
-
ktime_t last_entry_attempt;
ktime_t last_exit;
bool sink_not_reliable;
@@ -1719,6 +1731,7 @@ struct intel_psr {
u16 su_y_granularity;
bool source_panel_replay_support;
bool sink_panel_replay_support;
+ bool sink_panel_replay_su_support;
bool panel_replay_enabled;
u32 dc3co_exitline;
u32 dc3co_exit_delay;
@@ -1733,10 +1746,10 @@ struct intel_dp {
u8 lane_count;
u8 sink_count;
bool link_trained;
- bool reset_link_params;
bool use_max_params;
u8 dpcd[DP_RECEIVER_CAP_SIZE];
u8 psr_dpcd[EDP_PSR_RECEIVER_CAP_SIZE];
+ u8 pr_dpcd;
u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE];
u8 lttpr_common_caps[DP_LTTPR_COMMON_CAP_SIZE];
@@ -1754,10 +1767,21 @@ struct intel_dp {
/* intersection of source and sink rates */
int num_common_rates;
int common_rates[DP_MAX_SUPPORTED_RATES];
- /* Max lane count for the current link */
- int max_link_lane_count;
- /* Max rate for the current link */
- int max_link_rate;
+ struct {
+ /* TODO: move the rest of link specific fields to here */
+ /* Max lane count for the current link */
+ int max_lane_count;
+ /* Max rate for the current link */
+ int max_rate;
+ int force_lane_count;
+ int force_rate;
+ bool retrain_disabled;
+ /* Sequential link training failures after a passing LT */
+ int seq_train_failures;
+ int force_train_failure;
+ bool force_retrain;
+ } link;
+ bool reset_link_params;
int mso_link_count;
int mso_pixel_overlap;
/* sink or branch descriptor */
@@ -1840,6 +1864,19 @@ struct intel_dp {
unsigned long last_oui_write;
bool colorimetry_support;
+
+ struct {
+ u8 io_wake_lines;
+ u8 fast_wake_lines;
+
+ /* LNL and beyond */
+ u8 check_entry_lines;
+ u8 aux_less_wake_lines;
+ u8 silence_period_sym_clocks;
+ u8 lfps_half_cycle_num_of_syms;
+ } alpm_parameters;
+
+ u8 alpm_dpcd;
};
enum lspcon_vendor {
diff --git a/drivers/gpu/drm/i915/display/intel_dkl_phy.c b/drivers/gpu/drm/i915/display/intel_dkl_phy.c
index a001232ad445..b146b4c46943 100644
--- a/drivers/gpu/drm/i915/display/intel_dkl_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_dkl_phy.c
@@ -4,7 +4,6 @@
*/
#include "i915_drv.h"
-#include "i915_reg.h"
#include "intel_de.h"
#include "intel_display.h"
diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c
index cbd2ac5671b1..73977b173898 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc.c
+++ b/drivers/gpu/drm/i915/display/intel_dmc.c
@@ -30,6 +30,7 @@
#include "intel_de.h"
#include "intel_dmc.h"
#include "intel_dmc_regs.h"
+#include "intel_step.h"
/**
* DOC: DMC Firmware Support
@@ -115,6 +116,9 @@ static bool dmc_firmware_param_disabled(struct drm_i915_private *i915)
#define XE2LPD_DMC_PATH DMC_PATH(xe2lpd)
MODULE_FIRMWARE(XE2LPD_DMC_PATH);
+#define BMG_DMC_PATH DMC_PATH(bmg)
+MODULE_FIRMWARE(BMG_DMC_PATH);
+
#define MTL_DMC_PATH DMC_PATH(mtl)
MODULE_FIRMWARE(MTL_DMC_PATH);
@@ -166,6 +170,9 @@ static const char *dmc_firmware_default(struct drm_i915_private *i915, u32 *size
if (DISPLAY_VER_FULL(i915) == IP_VER(20, 0)) {
fw_path = XE2LPD_DMC_PATH;
max_fw_size = XE2LPD_DMC_MAX_FW_SIZE;
+ } else if (DISPLAY_VER_FULL(i915) == IP_VER(14, 1)) {
+ fw_path = BMG_DMC_PATH;
+ max_fw_size = XELPDP_DMC_MAX_FW_SIZE;
} else if (DISPLAY_VER_FULL(i915) == IP_VER(14, 0)) {
fw_path = MTL_DMC_PATH;
max_fw_size = XELPDP_DMC_MAX_FW_SIZE;
@@ -1177,7 +1184,7 @@ void intel_dmc_fini(struct drm_i915_private *i915)
}
}
-void intel_dmc_print_error_state(struct drm_i915_error_state_buf *m,
+void intel_dmc_print_error_state(struct drm_printer *p,
struct drm_i915_private *i915)
{
struct intel_dmc *dmc = i915_to_dmc(i915);
@@ -1185,13 +1192,13 @@ void intel_dmc_print_error_state(struct drm_i915_error_state_buf *m,
if (!HAS_DMC(i915))
return;
- i915_error_printf(m, "DMC initialized: %s\n", str_yes_no(dmc));
- i915_error_printf(m, "DMC loaded: %s\n",
- str_yes_no(intel_dmc_has_payload(i915)));
+ drm_printf(p, "DMC initialized: %s\n", str_yes_no(dmc));
+ drm_printf(p, "DMC loaded: %s\n",
+ str_yes_no(intel_dmc_has_payload(i915)));
if (dmc)
- i915_error_printf(m, "DMC fw version: %d.%d\n",
- DMC_VERSION_MAJOR(dmc->version),
- DMC_VERSION_MINOR(dmc->version));
+ drm_printf(p, "DMC fw version: %d.%d\n",
+ DMC_VERSION_MAJOR(dmc->version),
+ DMC_VERSION_MINOR(dmc->version));
}
static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused)
diff --git a/drivers/gpu/drm/i915/display/intel_dmc.h b/drivers/gpu/drm/i915/display/intel_dmc.h
index fd607afff2ef..54cff6002e31 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc.h
+++ b/drivers/gpu/drm/i915/display/intel_dmc.h
@@ -8,9 +8,9 @@
#include <linux/types.h>
-struct drm_i915_error_state_buf;
-struct drm_i915_private;
enum pipe;
+struct drm_i915_private;
+struct drm_printer;
void intel_dmc_init(struct drm_i915_private *i915);
void intel_dmc_load_program(struct drm_i915_private *i915);
@@ -22,7 +22,7 @@ void intel_dmc_suspend(struct drm_i915_private *i915);
void intel_dmc_resume(struct drm_i915_private *i915);
bool intel_dmc_has_payload(struct drm_i915_private *i915);
void intel_dmc_debugfs_register(struct drm_i915_private *i915);
-void intel_dmc_print_error_state(struct drm_i915_error_state_buf *m,
+void intel_dmc_print_error_state(struct drm_printer *p,
struct drm_i915_private *i915);
void assert_dmc_loaded(struct drm_i915_private *i915);
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index e05e25cd4a94..3903f6ead6e6 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -48,6 +48,7 @@
#include "i915_drv.h"
#include "i915_irq.h"
#include "i915_reg.h"
+#include "intel_alpm.h"
#include "intel_atomic.h"
#include "intel_audio.h"
#include "intel_backlight.h"
@@ -68,6 +69,7 @@
#include "intel_dpio_phy.h"
#include "intel_dpll.h"
#include "intel_drrs.h"
+#include "intel_encoder.h"
#include "intel_fifo_underrun.h"
#include "intel_hdcp.h"
#include "intel_hdmi.h"
@@ -75,6 +77,7 @@
#include "intel_hotplug_irq.h"
#include "intel_lspcon.h"
#include "intel_lvds.h"
+#include "intel_modeset_lock.h"
#include "intel_panel.h"
#include "intel_pch_display.h"
#include "intel_pps.h"
@@ -329,7 +332,7 @@ static int intel_dp_common_len_rate_limit(const struct intel_dp *intel_dp,
intel_dp->num_common_rates, max_rate);
}
-static int intel_dp_common_rate(struct intel_dp *intel_dp, int index)
+int intel_dp_common_rate(struct intel_dp *intel_dp, int index)
{
if (drm_WARN_ON(&dp_to_i915(intel_dp)->drm,
index < 0 || index >= intel_dp->num_common_rates))
@@ -344,7 +347,7 @@ int intel_dp_max_common_rate(struct intel_dp *intel_dp)
return intel_dp_common_rate(intel_dp, intel_dp->num_common_rates - 1);
}
-static int intel_dp_max_source_lane_count(struct intel_digital_port *dig_port)
+int intel_dp_max_source_lane_count(struct intel_digital_port *dig_port)
{
int vbt_max_lanes = intel_bios_dp_max_lane_count(dig_port->base.devdata);
int max_lanes = dig_port->max_lanes;
@@ -370,19 +373,39 @@ int intel_dp_max_common_lane_count(struct intel_dp *intel_dp)
return min3(source_max, sink_max, lane_max);
}
+static int forced_lane_count(struct intel_dp *intel_dp)
+{
+ return clamp(intel_dp->link.force_lane_count, 1, intel_dp_max_common_lane_count(intel_dp));
+}
+
int intel_dp_max_lane_count(struct intel_dp *intel_dp)
{
- switch (intel_dp->max_link_lane_count) {
+ int lane_count;
+
+ if (intel_dp->link.force_lane_count)
+ lane_count = forced_lane_count(intel_dp);
+ else
+ lane_count = intel_dp->link.max_lane_count;
+
+ switch (lane_count) {
case 1:
case 2:
case 4:
- return intel_dp->max_link_lane_count;
+ return lane_count;
default:
- MISSING_CASE(intel_dp->max_link_lane_count);
+ MISSING_CASE(lane_count);
return 1;
}
}
+static int intel_dp_min_lane_count(struct intel_dp *intel_dp)
+{
+ if (intel_dp->link.force_lane_count)
+ return forced_lane_count(intel_dp);
+
+ return 1;
+}
+
/*
* The required data bandwidth for a mode with given pixel clock and bpp. This
* is the required net bandwidth independent of the data bandwidth efficiency.
@@ -436,12 +459,16 @@ int intel_dp_max_link_data_rate(struct intel_dp *intel_dp,
return max_rate;
}
-bool intel_dp_has_bigjoiner(struct intel_dp *intel_dp)
+bool intel_dp_has_joiner(struct intel_dp *intel_dp)
{
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
struct intel_encoder *encoder = &intel_dig_port->base;
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+ /* eDP MSO is not compatible with joiner */
+ if (intel_dp->mso_link_count)
+ return false;
+
return DISPLAY_VER(dev_priv) >= 12 ||
(DISPLAY_VER(dev_priv) == 11 &&
encoder->port != PORT_A);
@@ -477,6 +504,9 @@ static int mtl_max_source_rate(struct intel_dp *intel_dp)
if (intel_encoder_is_c10phy(encoder))
return 810000;
+ if (DISPLAY_VER_FULL(to_i915(encoder->base.dev)) == IP_VER(14, 1))
+ return 1350000;
+
return 2000000;
}
@@ -601,7 +631,7 @@ static int intersect_rates(const int *source_rates, int source_len,
}
/* return index of rate in rates array, or -1 if not found */
-static int intel_dp_rate_index(const int *rates, int len, int rate)
+int intel_dp_rate_index(const int *rates, int len, int rate)
{
int i;
@@ -641,7 +671,7 @@ static bool intel_dp_link_params_valid(struct intel_dp *intel_dp, int link_rate,
* boot-up.
*/
if (link_rate == 0 ||
- link_rate > intel_dp->max_link_rate)
+ link_rate > intel_dp->link.max_rate)
return false;
if (lane_count == 0 ||
@@ -651,78 +681,6 @@ static bool intel_dp_link_params_valid(struct intel_dp *intel_dp, int link_rate,
return true;
}
-static bool intel_dp_can_link_train_fallback_for_edp(struct intel_dp *intel_dp,
- int link_rate,
- u8 lane_count)
-{
- /* FIXME figure out what we actually want here */
- const struct drm_display_mode *fixed_mode =
- intel_panel_preferred_fixed_mode(intel_dp->attached_connector);
- int mode_rate, max_rate;
-
- mode_rate = intel_dp_link_required(fixed_mode->clock, 18);
- max_rate = intel_dp_max_link_data_rate(intel_dp, link_rate, lane_count);
- if (mode_rate > max_rate)
- return false;
-
- return true;
-}
-
-int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
- int link_rate, u8 lane_count)
-{
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- int index;
-
- /*
- * TODO: Enable fallback on MST links once MST link compute can handle
- * the fallback params.
- */
- if (intel_dp->is_mst) {
- drm_err(&i915->drm, "Link Training Unsuccessful\n");
- return -1;
- }
-
- if (intel_dp_is_edp(intel_dp) && !intel_dp->use_max_params) {
- drm_dbg_kms(&i915->drm,
- "Retrying Link training for eDP with max parameters\n");
- intel_dp->use_max_params = true;
- return 0;
- }
-
- index = intel_dp_rate_index(intel_dp->common_rates,
- intel_dp->num_common_rates,
- link_rate);
- if (index > 0) {
- if (intel_dp_is_edp(intel_dp) &&
- !intel_dp_can_link_train_fallback_for_edp(intel_dp,
- intel_dp_common_rate(intel_dp, index - 1),
- lane_count)) {
- drm_dbg_kms(&i915->drm,
- "Retrying Link training for eDP with same parameters\n");
- return 0;
- }
- intel_dp->max_link_rate = intel_dp_common_rate(intel_dp, index - 1);
- intel_dp->max_link_lane_count = lane_count;
- } else if (lane_count > 1) {
- if (intel_dp_is_edp(intel_dp) &&
- !intel_dp_can_link_train_fallback_for_edp(intel_dp,
- intel_dp_max_common_rate(intel_dp),
- lane_count >> 1)) {
- drm_dbg_kms(&i915->drm,
- "Retrying Link training for eDP with same parameters\n");
- return 0;
- }
- intel_dp->max_link_rate = intel_dp_max_common_rate(intel_dp);
- intel_dp->max_link_lane_count = lane_count >> 1;
- } else {
- drm_err(&i915->drm, "Link Training Unsuccessful\n");
- return -1;
- }
-
- return 0;
-}
-
u32 intel_dp_mode_to_fec_clock(u32 mode_clock)
{
return div_u64(mul_u32_u32(mode_clock, DP_DSC_FEC_OVERHEAD_FACTOR),
@@ -1204,19 +1162,39 @@ intel_dp_mode_valid_downstream(struct intel_connector *connector,
return MODE_OK;
}
-bool intel_dp_need_bigjoiner(struct intel_dp *intel_dp,
- struct intel_connector *connector,
- int hdisplay, int clock)
+bool intel_dp_need_joiner(struct intel_dp *intel_dp,
+ struct intel_connector *connector,
+ int hdisplay, int clock)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- if (!intel_dp_has_bigjoiner(intel_dp))
+ if (!intel_dp_has_joiner(intel_dp))
return false;
return clock > i915->display.cdclk.max_dotclk_freq || hdisplay > 5120 ||
connector->force_bigjoiner_enable;
}
+bool intel_dp_has_dsc(const struct intel_connector *connector)
+{
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+
+ if (!HAS_DSC(i915))
+ return false;
+
+ if (connector->mst_port && !HAS_DSC_MST(i915))
+ return false;
+
+ if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP &&
+ connector->panel.vbt.edp.dsc_disable)
+ return false;
+
+ if (!drm_dp_sink_supports_dsc(connector->dp.dsc_dpcd))
+ return false;
+
+ return true;
+}
+
static enum drm_mode_status
intel_dp_mode_valid(struct drm_connector *_connector,
struct drm_display_mode *mode)
@@ -1231,7 +1209,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
u16 dsc_max_compressed_bpp = 0;
u8 dsc_slice_count = 0;
enum drm_mode_status status;
- bool dsc = false, bigjoiner = false;
+ bool dsc = false, joiner = false;
status = intel_cpu_transcoder_mode_valid(dev_priv, mode);
if (status != MODE_OK)
@@ -1252,9 +1230,9 @@ intel_dp_mode_valid(struct drm_connector *_connector,
target_clock = fixed_mode->clock;
}
- if (intel_dp_need_bigjoiner(intel_dp, connector,
- mode->hdisplay, target_clock)) {
- bigjoiner = true;
+ if (intel_dp_need_joiner(intel_dp, connector,
+ mode->hdisplay, target_clock)) {
+ joiner = true;
max_dotclk *= 2;
}
if (target_clock > max_dotclk)
@@ -1271,8 +1249,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
mode_rate = intel_dp_link_required(target_clock,
intel_dp_mode_min_output_bpp(connector, mode));
- if (HAS_DSC(dev_priv) &&
- drm_dp_sink_supports_dsc(connector->dp.dsc_dpcd)) {
+ if (intel_dp_has_dsc(connector)) {
enum intel_output_format sink_format, output_format;
int pipe_bpp;
@@ -1301,20 +1278,20 @@ intel_dp_mode_valid(struct drm_connector *_connector,
max_lanes,
target_clock,
mode->hdisplay,
- bigjoiner,
+ joiner,
output_format,
pipe_bpp, 64);
dsc_slice_count =
intel_dp_dsc_get_slice_count(connector,
target_clock,
mode->hdisplay,
- bigjoiner);
+ joiner);
}
dsc = dsc_max_compressed_bpp && dsc_slice_count;
}
- if (intel_dp_joiner_needs_dsc(dev_priv, bigjoiner) && !dsc)
+ if (intel_dp_joiner_needs_dsc(dev_priv, joiner) && !dsc)
return MODE_CLOCK_HIGH;
if (mode_rate > max_rate && !dsc)
@@ -1324,7 +1301,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
if (status != MODE_OK)
return status;
- return intel_mode_valid_max_plane_size(dev_priv, mode, bigjoiner);
+ return intel_mode_valid_max_plane_size(dev_priv, mode, joiner);
}
bool intel_dp_source_supports_tps3(struct drm_i915_private *i915)
@@ -1374,16 +1351,38 @@ static void intel_dp_print_rates(struct intel_dp *intel_dp)
drm_dbg_kms(&i915->drm, "common rates: %s\n", str);
}
+static int forced_link_rate(struct intel_dp *intel_dp)
+{
+ int len = intel_dp_common_len_rate_limit(intel_dp, intel_dp->link.force_rate);
+
+ if (len == 0)
+ return intel_dp_common_rate(intel_dp, 0);
+
+ return intel_dp_common_rate(intel_dp, len - 1);
+}
+
int
intel_dp_max_link_rate(struct intel_dp *intel_dp)
{
int len;
- len = intel_dp_common_len_rate_limit(intel_dp, intel_dp->max_link_rate);
+ if (intel_dp->link.force_rate)
+ return forced_link_rate(intel_dp);
+
+ len = intel_dp_common_len_rate_limit(intel_dp, intel_dp->link.max_rate);
return intel_dp_common_rate(intel_dp, len - 1);
}
+static int
+intel_dp_min_link_rate(struct intel_dp *intel_dp)
+{
+ if (intel_dp->link.force_rate)
+ return forced_link_rate(intel_dp);
+
+ return intel_dp_common_rate(intel_dp, 0);
+}
+
int intel_dp_rate_select(struct intel_dp *intel_dp, int rate)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
@@ -1441,15 +1440,16 @@ bool intel_dp_supports_fec(struct intel_dp *intel_dp,
drm_dp_sink_supports_fec(connector->dp.fec_capability);
}
-static bool intel_dp_supports_dsc(const struct intel_connector *connector,
- const struct intel_crtc_state *crtc_state)
+bool intel_dp_supports_dsc(const struct intel_connector *connector,
+ const struct intel_crtc_state *crtc_state)
{
+ if (!intel_dp_has_dsc(connector))
+ return false;
+
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP) && !crtc_state->fec_enable)
return false;
- return intel_dsc_source_support(crtc_state) &&
- connector->dp.dsc_decompression_aux &&
- drm_dp_sink_supports_dsc(connector->dp.dsc_dpcd);
+ return intel_dsc_source_support(crtc_state);
}
static int intel_dp_hdmi_compute_bpc(struct intel_dp *intel_dp,
@@ -2015,7 +2015,7 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp,
dsc_joiner_max_bpp = get_max_compressed_bpp_with_joiner(i915, adjusted_mode->clock,
adjusted_mode->hdisplay,
- pipe_config->bigjoiner_pipes);
+ pipe_config->joiner_pipes);
dsc_max_bpp = min(dsc_max_bpp, dsc_joiner_max_bpp);
dsc_max_bpp = min(dsc_max_bpp, to_bpp_int(limits->link.max_bpp_x16));
@@ -2249,7 +2249,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
intel_dp_dsc_get_slice_count(connector,
adjusted_mode->crtc_clock,
adjusted_mode->crtc_hdisplay,
- pipe_config->bigjoiner_pipes);
+ pipe_config->joiner_pipes);
if (!dsc_dp_slice_count) {
drm_dbg_kms(&dev_priv->drm,
"Compressed Slice Count not supported\n");
@@ -2263,7 +2263,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
* is greater than the maximum Cdclock and if slice count is even
* then we need to use 2 VDSC instances.
*/
- if (pipe_config->bigjoiner_pipes || pipe_config->dsc.slice_count > 1)
+ if (pipe_config->joiner_pipes || pipe_config->dsc.slice_count > 1)
pipe_config->dsc.dsc_split = true;
ret = intel_dp_dsc_compute_params(connector, pipe_config);
@@ -2353,13 +2353,14 @@ intel_dp_compute_config_limits(struct intel_dp *intel_dp,
bool dsc,
struct link_config_limits *limits)
{
- limits->min_rate = intel_dp_common_rate(intel_dp, 0);
+ limits->min_rate = intel_dp_min_link_rate(intel_dp);
limits->max_rate = intel_dp_max_link_rate(intel_dp);
/* FIXME 128b/132b SST support missing */
limits->max_rate = min(limits->max_rate, 810000);
+ limits->min_rate = min(limits->min_rate, limits->max_rate);
- limits->min_lane_count = 1;
+ limits->min_lane_count = intel_dp_min_lane_count(intel_dp);
limits->max_lane_count = intel_dp_max_lane_count(intel_dp);
limits->pipe.min_bpp = intel_dp_min_bpp(crtc_state->output_format);
@@ -2429,12 +2430,12 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
!intel_dp_supports_fec(intel_dp, connector, pipe_config))
return -EINVAL;
- if (intel_dp_need_bigjoiner(intel_dp, connector,
- adjusted_mode->crtc_hdisplay,
- adjusted_mode->crtc_clock))
- pipe_config->bigjoiner_pipes = GENMASK(crtc->pipe + 1, crtc->pipe);
+ if (intel_dp_need_joiner(intel_dp, connector,
+ adjusted_mode->crtc_hdisplay,
+ adjusted_mode->crtc_clock))
+ pipe_config->joiner_pipes = GENMASK(crtc->pipe + 1, crtc->pipe);
- joiner_needs_dsc = intel_dp_joiner_needs_dsc(i915, pipe_config->bigjoiner_pipes);
+ joiner_needs_dsc = intel_dp_joiner_needs_dsc(i915, pipe_config->joiner_pipes);
dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en ||
!intel_dp_compute_config_limits(intel_dp, pipe_config,
@@ -2633,11 +2634,19 @@ static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp,
/* Currently only DP_AS_SDP_AVT_FIXED_VTOTAL mode supported */
as_sdp->sdp_type = DP_SDP_ADAPTIVE_SYNC;
as_sdp->length = 0x9;
- as_sdp->mode = DP_AS_SDP_AVT_FIXED_VTOTAL;
- as_sdp->vtotal = adjusted_mode->vtotal;
- as_sdp->target_rr = 0;
as_sdp->duration_incr_ms = 0;
as_sdp->duration_incr_ms = 0;
+
+ if (crtc_state->cmrr.enable) {
+ as_sdp->mode = DP_AS_SDP_FAVT_TRR_REACHED;
+ as_sdp->vtotal = adjusted_mode->vtotal;
+ as_sdp->target_rr = drm_mode_vrefresh(adjusted_mode);
+ as_sdp->target_rr_divider = true;
+ } else {
+ as_sdp->mode = DP_AS_SDP_AVT_FIXED_VTOTAL;
+ as_sdp->vtotal = adjusted_mode->vtotal;
+ as_sdp->target_rr = 0;
+ }
}
static void intel_dp_compute_vsc_sdp(struct intel_dp *intel_dp,
@@ -2660,14 +2669,6 @@ static void intel_dp_compute_vsc_sdp(struct intel_dp *intel_dp,
if (intel_dp_needs_vsc_sdp(crtc_state, conn_state)) {
intel_dp_compute_vsc_colorimetry(crtc_state, conn_state,
vsc);
- } else if (crtc_state->has_psr2) {
- /*
- * [PSR2 without colorimetry]
- * Prepare VSC Header for SU as per eDP 1.4 spec, Table 6-11
- * 3D stereo + PSR/PSR2 + Y-coordinate.
- */
- vsc->revision = 0x4;
- vsc->length = 0xe;
} else if (crtc_state->has_panel_replay) {
/*
* [Panel Replay without colorimetry info]
@@ -2676,6 +2677,14 @@ static void intel_dp_compute_vsc_sdp(struct intel_dp *intel_dp,
*/
vsc->revision = 0x6;
vsc->length = 0x10;
+ } else if (crtc_state->has_sel_update) {
+ /*
+ * [PSR2 without colorimetry]
+ * Prepare VSC Header for SU as per eDP 1.4 spec, Table 6-11
+ * 3D stereo + PSR/PSR2 + Y-coordinate.
+ */
+ vsc->revision = 0x4;
+ vsc->length = 0xe;
} else {
/*
* [PSR1]
@@ -2754,7 +2763,7 @@ intel_dp_drrs_compute_config(struct intel_connector *connector,
* FIXME all joined pipes share the same transcoder.
* Need to account for that when updating M/N live.
*/
- if (has_seamless_m_n(connector) && !pipe_config->bigjoiner_pipes)
+ if (has_seamless_m_n(connector) && !pipe_config->joiner_pipes)
pipe_config->update_m_n = true;
if (!can_enable_drrs(connector, pipe_config, downclock_mode)) {
@@ -2783,7 +2792,6 @@ intel_dp_drrs_compute_config(struct intel_connector *connector,
}
static bool intel_dp_has_audio(struct intel_encoder *encoder,
- struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
{
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
@@ -2792,8 +2800,7 @@ static bool intel_dp_has_audio(struct intel_encoder *encoder,
struct intel_connector *connector =
to_intel_connector(conn_state->connector);
- if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) &&
- !intel_dp_port_has_audio(i915, encoder->port))
+ if (!intel_dp_port_has_audio(i915, encoder->port))
return false;
if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO)
@@ -2852,14 +2859,14 @@ intel_dp_audio_compute_config(struct intel_encoder *encoder,
struct drm_connector_state *conn_state)
{
pipe_config->has_audio =
- intel_dp_has_audio(encoder, pipe_config, conn_state) &&
+ intel_dp_has_audio(encoder, conn_state) &&
intel_audio_compute_config(encoder, pipe_config, conn_state);
pipe_config->sdp_split_enable = pipe_config->has_audio &&
intel_dp_is_uhbr(pipe_config);
}
-void intel_dp_queue_modeset_retry_work(struct intel_connector *connector)
+static void intel_dp_queue_modeset_retry_work(struct intel_connector *connector)
{
struct drm_i915_private *i915 = to_i915(connector->base.dev);
@@ -2868,6 +2875,7 @@ void intel_dp_queue_modeset_retry_work(struct intel_connector *connector)
drm_connector_put(&connector->base);
}
+/* NOTE: @state is only valid for MST links and can be %NULL for SST. */
void
intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state,
struct intel_encoder *encoder,
@@ -2876,6 +2884,7 @@ intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state,
struct intel_connector *connector;
struct intel_digital_connector_state *conn_state;
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int i;
if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) {
@@ -2884,6 +2893,9 @@ intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state,
return;
}
+ if (drm_WARN_ON(&i915->drm, !state))
+ return;
+
for_each_new_intel_connector_in_state(state, connector, conn_state, i) {
if (!conn_state->base.crtc)
continue;
@@ -2997,6 +3009,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
intel_vrr_compute_config(pipe_config, conn_state);
intel_dp_compute_as_sdp(intel_dp, pipe_config);
intel_psr_compute_config(intel_dp, pipe_config, conn_state);
+ intel_alpm_lobf_compute_config(intel_dp, pipe_config, conn_state);
intel_dp_drrs_compute_config(connector, pipe_config, link_bpp_x16);
intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state);
intel_dp_compute_hdr_metadata_infoframe_sdp(intel_dp, pipe_config, conn_state);
@@ -3014,10 +3027,12 @@ void intel_dp_set_link_params(struct intel_dp *intel_dp,
intel_dp->lane_count = lane_count;
}
-static void intel_dp_reset_max_link_params(struct intel_dp *intel_dp)
+void intel_dp_reset_link_params(struct intel_dp *intel_dp)
{
- intel_dp->max_link_lane_count = intel_dp_max_common_lane_count(intel_dp);
- intel_dp->max_link_rate = intel_dp_max_common_rate(intel_dp);
+ intel_dp->link.max_lane_count = intel_dp_max_common_lane_count(intel_dp);
+ intel_dp->link.max_rate = intel_dp_max_common_rate(intel_dp);
+ intel_dp->link.retrain_disabled = false;
+ intel_dp->link.seq_train_failures = 0;
}
/* Enable backlight PWM and backlight PP control. */
@@ -3352,7 +3367,7 @@ void intel_dp_sync_state(struct intel_encoder *encoder,
intel_dp_tunnel_resume(intel_dp, crtc_state, dpcd_updated);
if (crtc_state)
- intel_dp_reset_max_link_params(intel_dp);
+ intel_dp_reset_link_params(intel_dp);
}
bool intel_dp_initial_fastset_check(struct intel_encoder *encoder,
@@ -4227,6 +4242,9 @@ static ssize_t intel_dp_as_sdp_pack(const struct drm_dp_as_sdp *as_sdp,
sdp->db[3] = as_sdp->target_rr & 0xFF;
sdp->db[4] = (as_sdp->target_rr >> 8) & 0x3;
+ if (as_sdp->target_rr_divider)
+ sdp->db[4] |= 0x20;
+
return length;
}
@@ -4350,7 +4368,8 @@ void intel_dp_set_infoframes(struct intel_encoder *encoder,
const struct drm_connector_state *conn_state)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- i915_reg_t reg = HSW_TVIDEO_DIP_CTL(crtc_state->cpu_transcoder);
+ i915_reg_t reg = HSW_TVIDEO_DIP_CTL(dev_priv,
+ crtc_state->cpu_transcoder);
u32 dip_enable = VIDEO_DIP_ENABLE_AVI_HSW | VIDEO_DIP_ENABLE_GCP_HSW |
VIDEO_DIP_ENABLE_VS_HSW | VIDEO_DIP_ENABLE_GMP_HSW |
VIDEO_DIP_ENABLE_SPD_HSW | VIDEO_DIP_ENABLE_DRM_GLK;
@@ -4407,6 +4426,7 @@ int intel_dp_as_sdp_unpack(struct drm_dp_as_sdp *as_sdp,
as_sdp->mode = sdp->db[0] & DP_ADAPTIVE_SYNC_SDP_OPERATION_MODE;
as_sdp->vtotal = (sdp->db[2] << 8) | sdp->db[1];
as_sdp->target_rr = (u64)sdp->db[3] | ((u64)sdp->db[4] & 0x3);
+ as_sdp->target_rr_divider = sdp->db[4] & 0x20 ? true : false;
return 0;
}
@@ -4432,7 +4452,8 @@ static int intel_dp_vsc_sdp_unpack(struct drm_dp_vsc_sdp *vsc,
vsc->length = sdp->sdp_header.HB3;
if ((sdp->sdp_header.HB2 == 0x2 && sdp->sdp_header.HB3 == 0x8) ||
- (sdp->sdp_header.HB2 == 0x4 && sdp->sdp_header.HB3 == 0xe)) {
+ (sdp->sdp_header.HB2 == 0x4 && sdp->sdp_header.HB3 == 0xe) ||
+ (sdp->sdp_header.HB2 == 0x6 && sdp->sdp_header.HB3 == 0x10)) {
/*
* - HB2 = 0x2, HB3 = 0x8
* VSC SDP supporting 3D stereo + PSR
@@ -4440,6 +4461,8 @@ static int intel_dp_vsc_sdp_unpack(struct drm_dp_vsc_sdp *vsc,
* VSC SDP supporting 3D stereo + PSR2 with Y-coordinate of
* first scan line of the SU region (applies to eDP v1.4b
* and higher).
+ * - HB2 = 0x6, HB3 = 0x10
+ * VSC SDP supporting 3D stereo + Panel Replay.
*/
return 0;
} else if (sdp->sdp_header.HB2 == 0x5 && sdp->sdp_header.HB3 == 0x13) {
@@ -5017,6 +5040,8 @@ static bool
intel_dp_check_mst_status(struct intel_dp *intel_dp)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+ struct intel_encoder *encoder = &dig_port->base;
bool link_ok = true;
bool reprobe_needed = false;
@@ -5062,7 +5087,10 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp)
drm_dp_mst_hpd_irq_send_new_request(&intel_dp->mst_mgr);
}
- return link_ok && !reprobe_needed;
+ if (!link_ok || intel_dp->link.force_retrain)
+ intel_encoder_link_check_queue_work(encoder, 0);
+
+ return !reprobe_needed;
}
static void
@@ -5108,6 +5136,9 @@ intel_dp_needs_link_retrain(struct intel_dp *intel_dp)
if (intel_psr_enabled(intel_dp))
return false;
+ if (intel_dp->link.force_retrain)
+ return true;
+
if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, DP_PHY_DPRX,
link_status) < 0)
return false;
@@ -5124,6 +5155,12 @@ intel_dp_needs_link_retrain(struct intel_dp *intel_dp)
intel_dp->lane_count))
return false;
+ if (intel_dp->link.retrain_disabled)
+ return false;
+
+ if (intel_dp->link.seq_train_failures)
+ return true;
+
/* Retrain if link not ok */
return !intel_dp_link_ok(intel_dp, link_status);
}
@@ -5209,12 +5246,13 @@ static bool intel_dp_is_connected(struct intel_dp *intel_dp)
intel_dp->is_mst;
}
-int intel_dp_retrain_link(struct intel_encoder *encoder,
- struct drm_modeset_acquire_ctx *ctx)
+static int intel_dp_retrain_link(struct intel_encoder *encoder,
+ struct drm_modeset_acquire_ctx *ctx)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct intel_crtc *crtc;
+ bool mst_output = false;
u8 pipe_mask;
int ret;
@@ -5239,13 +5277,19 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
if (!intel_dp_needs_link_retrain(intel_dp))
return 0;
- drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] retraining link\n",
- encoder->base.base.id, encoder->base.name);
+ drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] retraining link (forced %s)\n",
+ encoder->base.base.id, encoder->base.name,
+ str_yes_no(intel_dp->link.force_retrain));
for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc, pipe_mask) {
const struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) {
+ mst_output = true;
+ break;
+ }
+
/* Suppress underruns caused by re-training */
intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, false);
if (crtc_state->has_pch_encoder)
@@ -5253,19 +5297,26 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
intel_crtc_pch_transcoder(crtc), false);
}
+ /* TODO: use a modeset for SST as well. */
+ if (mst_output) {
+ ret = intel_modeset_commit_pipes(dev_priv, pipe_mask, ctx);
+
+ if (ret && ret != -EDEADLK)
+ drm_dbg_kms(&dev_priv->drm,
+ "[ENCODER:%d:%s] link retraining failed: %pe\n",
+ encoder->base.base.id, encoder->base.name,
+ ERR_PTR(ret));
+
+ goto out;
+ }
+
for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc, pipe_mask) {
const struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
- /* retrain on the MST master transcoder */
- if (DISPLAY_VER(dev_priv) >= 12 &&
- intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) &&
- !intel_dp_mst_is_master_trans(crtc_state))
- continue;
-
intel_dp_check_frl_training(intel_dp);
intel_dp_pcon_dsc_configure(intel_dp, crtc_state);
- intel_dp_start_link_train(intel_dp, crtc_state);
+ intel_dp_start_link_train(NULL, intel_dp, crtc_state);
intel_dp_stop_link_train(intel_dp, crtc_state);
break;
}
@@ -5283,7 +5334,37 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
intel_crtc_pch_transcoder(crtc), true);
}
- return 0;
+out:
+ if (ret != -EDEADLK)
+ intel_dp->link.force_retrain = false;
+
+ return ret;
+}
+
+void intel_dp_link_check(struct intel_encoder *encoder)
+{
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+ struct drm_modeset_acquire_ctx ctx;
+ int ret;
+
+ intel_modeset_lock_ctx_retry(&ctx, NULL, 0, ret)
+ ret = intel_dp_retrain_link(encoder, &ctx);
+
+ drm_WARN_ON(&i915->drm, ret);
+}
+
+void intel_dp_check_link_state(struct intel_dp *intel_dp)
+{
+ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+ struct intel_encoder *encoder = &dig_port->base;
+
+ if (!intel_dp_is_connected(intel_dp))
+ return;
+
+ if (!intel_dp_needs_link_retrain(intel_dp))
+ return;
+
+ intel_encoder_link_check_queue_work(encoder, 0);
}
static int intel_dp_prep_phy_test(struct intel_dp *intel_dp,
@@ -5496,9 +5577,7 @@ intel_dp_short_pulse(struct intel_dp *intel_dp)
/* Handle CEC interrupts, if any */
drm_dp_cec_irq(&intel_dp->aux);
- /* defer to the hotplug work for link retraining if needed */
- if (intel_dp_needs_link_retrain(intel_dp))
- return false;
+ intel_dp_check_link_state(intel_dp);
intel_psr_short_pulse(intel_dp);
@@ -5858,6 +5937,7 @@ intel_dp_detect(struct drm_connector *connector,
memset(&intel_dp->compliance, 0, sizeof(intel_dp->compliance));
memset(intel_connector->dp.dsc_dpcd, 0, sizeof(intel_connector->dp.dsc_dpcd));
intel_dp->psr.sink_panel_replay_support = false;
+ intel_dp->psr.sink_panel_replay_su_support = false;
intel_dp_mst_disconnect(intel_dp);
@@ -5880,12 +5960,8 @@ intel_dp_detect(struct drm_connector *connector,
intel_dp_mst_configure(intel_dp);
- /*
- * TODO: Reset link params when switching to MST mode, until MST
- * supports link training fallback params.
- */
- if (intel_dp->reset_link_params || intel_dp->is_mst) {
- intel_dp_reset_max_link_params(intel_dp);
+ if (intel_dp->reset_link_params) {
+ intel_dp_reset_link_params(intel_dp);
intel_dp->reset_link_params = false;
}
@@ -5904,12 +5980,13 @@ intel_dp_detect(struct drm_connector *connector,
/*
* Some external monitors do not signal loss of link synchronization
* with an IRQ_HPD, so force a link status check.
+ *
+ * TODO: this probably became redundant, so remove it: the link state
+ * is rechecked/recovered now after modesets, where the loss of
+ * synchronization tends to occur.
*/
- if (!intel_dp_is_edp(intel_dp)) {
- ret = intel_dp_retrain_link(encoder, ctx);
- if (ret)
- return ret;
- }
+ if (!intel_dp_is_edp(intel_dp))
+ intel_dp_check_link_state(intel_dp);
/*
* Clearing NACK and defer counts to get their exact values
@@ -6051,11 +6128,14 @@ void intel_dp_connector_sync_state(struct intel_connector *connector,
}
}
-void intel_dp_encoder_flush_work(struct drm_encoder *encoder)
+void intel_dp_encoder_flush_work(struct drm_encoder *_encoder)
{
- struct intel_digital_port *dig_port = enc_to_dig_port(to_intel_encoder(encoder));
+ struct intel_encoder *encoder = to_intel_encoder(_encoder);
+ struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
struct intel_dp *intel_dp = &dig_port->dp;
+ intel_encoder_link_check_flush_work(encoder);
+
intel_dp_mst_encoder_cleanup(dig_port);
intel_dp_tunnel_destroy(intel_dp);
@@ -6361,8 +6441,8 @@ bool intel_dp_is_port_edp(struct drm_i915_private *i915, enum port port)
return _intel_dp_is_port_edp(i915, devdata, port);
}
-static bool
-has_gamut_metadata_dip(struct intel_encoder *encoder)
+bool
+intel_dp_has_gamut_metadata_dip(struct intel_encoder *encoder)
{
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
enum port port = encoder->port;
@@ -6409,7 +6489,7 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect
intel_attach_dp_colorspace_property(connector);
}
- if (has_gamut_metadata_dip(&dp_to_dig_port(intel_dp)->base))
+ if (intel_dp_has_gamut_metadata_dip(&dp_to_dig_port(intel_dp)->base))
drm_connector_attach_hdr_output_metadata_property(connector);
if (HAS_VRR(dev_priv))
@@ -6508,6 +6588,8 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
*/
intel_hpd_enable_detection(encoder);
+ intel_alpm_init_dpcd(intel_dp);
+
/* Cache DPCD and EDID for edp. */
has_dpcd = intel_edp_init_dpcd(intel_dp, intel_connector);
@@ -6737,7 +6819,7 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,
intel_dp_set_source_rates(intel_dp);
intel_dp_set_common_rates(intel_dp);
- intel_dp_reset_max_link_params(intel_dp);
+ intel_dp_reset_link_params(intel_dp);
/* init MST on ports that can support it */
intel_dp_mst_encoder_init(dig_port,
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index 106ecfde36d9..a0f990a95ecc 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -44,7 +44,6 @@ bool intel_dp_limited_color_range(const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state);
int intel_dp_min_bpp(enum intel_output_format output_format);
void intel_dp_init_modeset_retry_work(struct intel_connector *connector);
-void intel_dp_queue_modeset_retry_work(struct intel_connector *connector);
void
intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state,
struct intel_encoder *encoder,
@@ -55,13 +54,11 @@ void intel_dp_connector_sync_state(struct intel_connector *connector,
const struct intel_crtc_state *crtc_state);
void intel_dp_set_link_params(struct intel_dp *intel_dp,
int link_rate, int lane_count);
-int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
- int link_rate, u8 lane_count);
int intel_dp_get_active_pipes(struct intel_dp *intel_dp,
struct drm_modeset_acquire_ctx *ctx,
u8 *pipe_mask);
-int intel_dp_retrain_link(struct intel_encoder *encoder,
- struct drm_modeset_acquire_ctx *ctx);
+void intel_dp_link_check(struct intel_encoder *encoder);
+void intel_dp_check_link_state(struct intel_dp *intel_dp);
void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode);
void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
@@ -90,6 +87,7 @@ bool intel_dp_has_hdmi_sink(struct intel_dp *intel_dp);
bool intel_dp_is_edp(struct intel_dp *intel_dp);
bool intel_dp_as_sdp_supported(struct intel_dp *intel_dp);
bool intel_dp_is_uhbr(const struct intel_crtc_state *crtc_state);
+bool intel_dp_has_dsc(const struct intel_connector *connector);
int intel_dp_link_symbol_size(int rate);
int intel_dp_link_symbol_clock(int rate);
bool intel_dp_is_port_edp(struct drm_i915_private *dev_priv, enum port port);
@@ -101,13 +99,17 @@ void intel_edp_backlight_off(const struct drm_connector_state *conn_state);
void intel_edp_fixup_vbt_bpp(struct intel_encoder *encoder, int pipe_bpp);
void intel_dp_mst_suspend(struct drm_i915_private *dev_priv);
void intel_dp_mst_resume(struct drm_i915_private *dev_priv);
+int intel_dp_max_source_lane_count(struct intel_digital_port *dig_port);
int intel_dp_max_link_rate(struct intel_dp *intel_dp);
int intel_dp_max_lane_count(struct intel_dp *intel_dp);
int intel_dp_config_required_rate(const struct intel_crtc_state *crtc_state);
int intel_dp_rate_select(struct intel_dp *intel_dp, int rate);
int intel_dp_max_common_rate(struct intel_dp *intel_dp);
int intel_dp_max_common_lane_count(struct intel_dp *intel_dp);
+int intel_dp_common_rate(struct intel_dp *intel_dp, int index);
+int intel_dp_rate_index(const int *rates, int len, int rate);
void intel_dp_update_sink_caps(struct intel_dp *intel_dp);
+void intel_dp_reset_link_params(struct intel_dp *intel_dp);
void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
u8 *link_bw, u8 *rate_select);
@@ -121,7 +123,7 @@ int intel_dp_effective_data_rate(int pixel_clock, int bpp_x16,
int intel_dp_max_link_data_rate(struct intel_dp *intel_dp,
int max_dprx_rate, int max_dprx_lanes);
bool intel_dp_joiner_needs_dsc(struct drm_i915_private *i915, bool use_joiner);
-bool intel_dp_has_bigjoiner(struct intel_dp *intel_dp);
+bool intel_dp_has_joiner(struct intel_dp *intel_dp);
bool intel_dp_needs_vsc_sdp(const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state);
void intel_dp_set_infoframes(struct intel_encoder *encoder, bool enable,
@@ -150,9 +152,9 @@ int intel_dp_dsc_sink_max_compressed_bpp(const struct intel_connector *connector
u8 intel_dp_dsc_get_slice_count(const struct intel_connector *connector,
int mode_clock, int mode_hdisplay,
bool bigjoiner);
-bool intel_dp_need_bigjoiner(struct intel_dp *intel_dp,
- struct intel_connector *connector,
- int hdisplay, int clock);
+bool intel_dp_need_joiner(struct intel_dp *intel_dp,
+ struct intel_connector *connector,
+ int hdisplay, int clock);
static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
{
@@ -169,6 +171,9 @@ bool intel_dp_supports_fec(struct intel_dp *intel_dp,
const struct intel_connector *connector,
const struct intel_crtc_state *pipe_config);
+bool intel_dp_supports_dsc(const struct intel_connector *connector,
+ const struct intel_crtc_state *crtc_state);
+
u32 intel_dp_dsc_nearest_valid_bpp(struct drm_i915_private *i915, u32 bpp, u32 pipe_bpp);
void intel_ddi_update_pipe(struct intel_atomic_state *state,
@@ -196,5 +201,6 @@ intel_dp_compute_config_link_bpp_limits(struct intel_dp *intel_dp,
struct link_config_limits *limits);
void intel_dp_get_dsc_sink_cap(u8 dpcd_rev, struct intel_connector *connector);
+bool intel_dp_has_gamut_metadata_dip(struct intel_encoder *encoder);
#endif /* __INTEL_DP_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
index 4f58efdc688a..8ce60d53dcde 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
@@ -40,11 +40,6 @@
#include "intel_dp.h"
#include "intel_dp_aux_backlight.h"
-/* TODO:
- * Implement HDR, right now we just implement the bare minimum to bring us back into SDR mode so we
- * can make people's backlights work in the mean time
- */
-
/*
* DP AUX registers for Intel's proprietary HDR backlight interface. We define
* them here since we'll likely be the only driver to ever use these.
@@ -69,14 +64,14 @@
#define INTEL_EDP_HDR_GETSET_CTRL_PARAMS 0x344
# define INTEL_EDP_HDR_TCON_2084_DECODE_ENABLE BIT(0)
# define INTEL_EDP_HDR_TCON_2020_GAMUT_ENABLE BIT(1)
-# define INTEL_EDP_HDR_TCON_TONE_MAPPING_ENABLE BIT(2) /* Pre-TGL+ */
+# define INTEL_EDP_HDR_TCON_TONE_MAPPING_ENABLE BIT(2)
# define INTEL_EDP_HDR_TCON_SEGMENTED_BACKLIGHT_ENABLE BIT(3)
# define INTEL_EDP_HDR_TCON_BRIGHTNESS_AUX_ENABLE BIT(4)
# define INTEL_EDP_HDR_TCON_SRGB_TO_PANEL_GAMUT_ENABLE BIT(5)
/* Bit 6 is reserved */
-# define INTEL_EDP_HDR_TCON_SDP_COLORIMETRY_ENABLE BIT(7)
+# define INTEL_EDP_HDR_TCON_SDP_OVERRIDE_AUX BIT(7)
-#define INTEL_EDP_HDR_CONTENT_LUMINANCE 0x346 /* Pre-TGL+ */
+#define INTEL_EDP_HDR_CONTENT_LUMINANCE 0x346
#define INTEL_EDP_HDR_PANEL_LUMINANCE_OVERRIDE 0x34A
#define INTEL_EDP_SDR_LUMINANCE_LEVEL 0x352
#define INTEL_EDP_BRIGHTNESS_NITS_LSB 0x354
@@ -127,9 +122,6 @@ intel_dp_aux_supports_hdr_backlight(struct intel_connector *connector)
if (ret != sizeof(tcon_cap))
return false;
- if (!(tcon_cap[1] & INTEL_EDP_HDR_TCON_BRIGHTNESS_NITS_CAP))
- return false;
-
drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] Detected %s HDR backlight interface version %d\n",
connector->base.base.id, connector->base.name,
is_intel_tcon_cap(tcon_cap) ? "Intel" : "unsupported", tcon_cap[0]);
@@ -137,6 +129,9 @@ intel_dp_aux_supports_hdr_backlight(struct intel_connector *connector)
if (!is_intel_tcon_cap(tcon_cap))
return false;
+ if (!(tcon_cap[1] & INTEL_EDP_HDR_TCON_BRIGHTNESS_NITS_CAP))
+ return false;
+
/*
* If we don't have HDR static metadata there is no way to
* runtime detect used range for nits based control. For now
@@ -156,8 +151,18 @@ intel_dp_aux_supports_hdr_backlight(struct intel_connector *connector)
return false;
}
- panel->backlight.edp.intel.sdr_uses_aux =
+ panel->backlight.edp.intel_cap.sdr_uses_aux =
tcon_cap[2] & INTEL_EDP_SDR_TCON_BRIGHTNESS_AUX_CAP;
+ panel->backlight.edp.intel_cap.supports_2084_decode =
+ tcon_cap[1] & INTEL_EDP_HDR_TCON_2084_DECODE_CAP;
+ panel->backlight.edp.intel_cap.supports_2020_gamut =
+ tcon_cap[1] & INTEL_EDP_HDR_TCON_2020_GAMUT_CAP;
+ panel->backlight.edp.intel_cap.supports_segmented_backlight =
+ tcon_cap[1] & INTEL_EDP_HDR_TCON_SEGMENTED_BACKLIGHT_CAP;
+ panel->backlight.edp.intel_cap.supports_sdp_colorimetry =
+ tcon_cap[1] & INTEL_EDP_HDR_TCON_SDP_COLORIMETRY_CAP;
+ panel->backlight.edp.intel_cap.supports_tone_mapping =
+ tcon_cap[1] & INTEL_EDP_HDR_TCON_TONE_MAPPING_CAP;
return true;
}
@@ -178,7 +183,7 @@ intel_dp_aux_hdr_get_backlight(struct intel_connector *connector, enum pipe pipe
}
if (!(tmp & INTEL_EDP_HDR_TCON_BRIGHTNESS_AUX_ENABLE)) {
- if (!panel->backlight.edp.intel.sdr_uses_aux) {
+ if (!panel->backlight.edp.intel_cap.sdr_uses_aux) {
u32 pwm_level = panel->backlight.pwm_funcs->get(connector, pipe);
return intel_backlight_level_from_pwm(connector, pwm_level);
@@ -215,13 +220,27 @@ intel_dp_aux_hdr_set_aux_backlight(const struct drm_connector_state *conn_state,
connector->base.base.id, connector->base.name);
}
+static bool
+intel_dp_in_hdr_mode(const struct drm_connector_state *conn_state)
+{
+ struct hdr_output_metadata *hdr_metadata;
+
+ if (!conn_state->hdr_output_metadata)
+ return false;
+
+ hdr_metadata = conn_state->hdr_output_metadata->data;
+
+ return hdr_metadata->hdmi_metadata_type1.eotf == HDMI_EOTF_SMPTE_ST2084;
+}
+
static void
intel_dp_aux_hdr_set_backlight(const struct drm_connector_state *conn_state, u32 level)
{
struct intel_connector *connector = to_intel_connector(conn_state->connector);
struct intel_panel *panel = &connector->panel;
- if (panel->backlight.edp.intel.sdr_uses_aux) {
+ if (intel_dp_in_hdr_mode(conn_state) ||
+ panel->backlight.edp.intel_cap.sdr_uses_aux) {
intel_dp_aux_hdr_set_aux_backlight(conn_state, level);
} else {
const u32 pwm_level = intel_backlight_level_to_pwm(connector, level);
@@ -231,6 +250,64 @@ intel_dp_aux_hdr_set_backlight(const struct drm_connector_state *conn_state, u32
}
static void
+intel_dp_aux_write_content_luminance(struct intel_connector *connector,
+ struct hdr_output_metadata *hdr_metadata)
+{
+ struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ int ret;
+ u8 buf[4];
+
+ if (!intel_dp_has_gamut_metadata_dip(connector->encoder))
+ return;
+
+ buf[0] = hdr_metadata->hdmi_metadata_type1.max_cll & 0xFF;
+ buf[1] = (hdr_metadata->hdmi_metadata_type1.max_cll & 0xFF00) >> 8;
+ buf[2] = hdr_metadata->hdmi_metadata_type1.max_fall & 0xFF;
+ buf[3] = (hdr_metadata->hdmi_metadata_type1.max_fall & 0xFF00) >> 8;
+
+ ret = drm_dp_dpcd_write(&intel_dp->aux,
+ INTEL_EDP_HDR_CONTENT_LUMINANCE,
+ buf, sizeof(buf));
+ if (ret < 0)
+ drm_dbg_kms(&i915->drm,
+ "Content Luminance DPCD reg write failed, err:-%d\n",
+ ret);
+}
+
+static void
+intel_dp_aux_fill_hdr_tcon_params(const struct drm_connector_state *conn_state, u8 *ctrl)
+{
+ struct intel_connector *connector = to_intel_connector(conn_state->connector);
+ struct intel_panel *panel = &connector->panel;
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+
+ /*
+ * According to spec segmented backlight needs to be set whenever panel is in
+ * HDR mode.
+ */
+ if (intel_dp_in_hdr_mode(conn_state)) {
+ *ctrl |= INTEL_EDP_HDR_TCON_SEGMENTED_BACKLIGHT_ENABLE;
+ *ctrl |= INTEL_EDP_HDR_TCON_2084_DECODE_ENABLE;
+ }
+
+ if (DISPLAY_VER(i915) < 11)
+ *ctrl &= ~INTEL_EDP_HDR_TCON_TONE_MAPPING_ENABLE;
+
+ if (panel->backlight.edp.intel_cap.supports_2020_gamut &&
+ (conn_state->colorspace == DRM_MODE_COLORIMETRY_BT2020_RGB ||
+ conn_state->colorspace == DRM_MODE_COLORIMETRY_BT2020_YCC ||
+ conn_state->colorspace == DRM_MODE_COLORIMETRY_BT2020_CYCC))
+ *ctrl |= INTEL_EDP_HDR_TCON_2020_GAMUT_ENABLE;
+
+ if (panel->backlight.edp.intel_cap.supports_sdp_colorimetry &&
+ intel_dp_has_gamut_metadata_dip(connector->encoder))
+ *ctrl |= INTEL_EDP_HDR_TCON_SDP_OVERRIDE_AUX;
+ else
+ *ctrl &= ~INTEL_EDP_HDR_TCON_SDP_OVERRIDE_AUX;
+}
+
+static void
intel_dp_aux_hdr_enable_backlight(const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state, u32 level)
{
@@ -238,6 +315,7 @@ intel_dp_aux_hdr_enable_backlight(const struct intel_crtc_state *crtc_state,
struct intel_panel *panel = &connector->panel;
struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
+ struct hdr_output_metadata *hdr_metadata;
int ret;
u8 old_ctrl, ctrl;
@@ -251,8 +329,10 @@ intel_dp_aux_hdr_enable_backlight(const struct intel_crtc_state *crtc_state,
}
ctrl = old_ctrl;
- if (panel->backlight.edp.intel.sdr_uses_aux) {
+ if (intel_dp_in_hdr_mode(conn_state) ||
+ panel->backlight.edp.intel_cap.sdr_uses_aux) {
ctrl |= INTEL_EDP_HDR_TCON_BRIGHTNESS_AUX_ENABLE;
+
intel_dp_aux_hdr_set_aux_backlight(conn_state, level);
} else {
u32 pwm_level = intel_backlight_level_to_pwm(connector, level);
@@ -262,10 +342,17 @@ intel_dp_aux_hdr_enable_backlight(const struct intel_crtc_state *crtc_state,
ctrl &= ~INTEL_EDP_HDR_TCON_BRIGHTNESS_AUX_ENABLE;
}
+ intel_dp_aux_fill_hdr_tcon_params(conn_state, &ctrl);
+
if (ctrl != old_ctrl &&
drm_dp_dpcd_writeb(&intel_dp->aux, INTEL_EDP_HDR_GETSET_CTRL_PARAMS, ctrl) != 1)
drm_err(&i915->drm, "[CONNECTOR:%d:%s] Failed to configure DPCD brightness controls\n",
connector->base.base.id, connector->base.name);
+
+ if (intel_dp_in_hdr_mode(conn_state)) {
+ hdr_metadata = conn_state->hdr_output_metadata->data;
+ intel_dp_aux_write_content_luminance(connector, hdr_metadata);
+ }
}
static void
@@ -275,7 +362,7 @@ intel_dp_aux_hdr_disable_backlight(const struct drm_connector_state *conn_state,
struct intel_panel *panel = &connector->panel;
/* Nothing to do for AUX based backlight controls */
- if (panel->backlight.edp.intel.sdr_uses_aux)
+ if (panel->backlight.edp.intel_cap.sdr_uses_aux)
return;
/* Note we want the actual pwm_level to be 0, regardless of pwm_min */
@@ -287,6 +374,29 @@ static const char *dpcd_vs_pwm_str(bool aux)
return aux ? "DPCD" : "PWM";
}
+static void
+intel_dp_aux_write_panel_luminance_override(struct intel_connector *connector)
+{
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_panel *panel = &connector->panel;
+ struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
+ int ret;
+ u8 buf[4] = {};
+
+ buf[0] = panel->backlight.min & 0xFF;
+ buf[1] = (panel->backlight.min & 0xFF00) >> 8;
+ buf[2] = panel->backlight.max & 0xFF;
+ buf[3] = (panel->backlight.max & 0xFF00) >> 8;
+
+ ret = drm_dp_dpcd_write(&intel_dp->aux,
+ INTEL_EDP_HDR_PANEL_LUMINANCE_OVERRIDE,
+ buf, sizeof(buf));
+ if (ret < 0)
+ drm_dbg_kms(&i915->drm,
+ "Panel Luminance DPCD reg write failed, err:-%d\n",
+ ret);
+}
+
static int
intel_dp_aux_hdr_setup_backlight(struct intel_connector *connector, enum pipe pipe)
{
@@ -298,9 +408,9 @@ intel_dp_aux_hdr_setup_backlight(struct intel_connector *connector, enum pipe pi
drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] SDR backlight is controlled through %s\n",
connector->base.base.id, connector->base.name,
- dpcd_vs_pwm_str(panel->backlight.edp.intel.sdr_uses_aux));
+ dpcd_vs_pwm_str(panel->backlight.edp.intel_cap.sdr_uses_aux));
- if (!panel->backlight.edp.intel.sdr_uses_aux) {
+ if (!panel->backlight.edp.intel_cap.sdr_uses_aux) {
ret = panel->backlight.pwm_funcs->setup(connector, pipe);
if (ret < 0) {
drm_err(&i915->drm,
@@ -318,11 +428,12 @@ intel_dp_aux_hdr_setup_backlight(struct intel_connector *connector, enum pipe pi
panel->backlight.min = 0;
}
+ intel_dp_aux_write_panel_luminance_override(connector);
+
drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] Using AUX HDR interface for backlight control (range %d..%d)\n",
connector->base.base.id, connector->base.name,
panel->backlight.min, panel->backlight.max);
-
panel->backlight.level = intel_dp_aux_hdr_get_backlight(connector, pipe);
panel->backlight.enabled = panel->backlight.level != 0;
diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_regs.h b/drivers/gpu/drm/i915/display/intel_dp_aux_regs.h
index e642445364d2..4e109e81409b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_aux_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_aux_regs.h
@@ -23,12 +23,17 @@
#define _DPA_AUX_CH_CTL 0x64010
#define _DPB_AUX_CH_CTL 0x64110
-#define _XELPDP_USBC1_AUX_CH_CTL 0x16f210
-#define _XELPDP_USBC2_AUX_CH_CTL 0x16f410
#define DP_AUX_CH_CTL(aux_ch) _MMIO_PORT(aux_ch, _DPA_AUX_CH_CTL, \
_DPB_AUX_CH_CTL)
#define VLV_DP_AUX_CH_CTL(aux_ch) _MMIO(VLV_DISPLAY_BASE + \
_PORT(aux_ch, _DPA_AUX_CH_CTL, _DPB_AUX_CH_CTL))
+
+#define _PCH_DPB_AUX_CH_CTL 0xe4110
+#define _PCH_DPC_AUX_CH_CTL 0xe4210
+#define PCH_DP_AUX_CH_CTL(aux_ch) _MMIO_PORT((aux_ch) - AUX_CH_B, _PCH_DPB_AUX_CH_CTL, _PCH_DPC_AUX_CH_CTL)
+
+#define _XELPDP_USBC1_AUX_CH_CTL 0x16f210
+#define _XELPDP_USBC2_AUX_CH_CTL 0x16f410
#define _XELPDP_DP_AUX_CH_CTL(aux_ch) \
_MMIO(_PICK_EVEN_2RANGES(aux_ch, AUX_CH_USBC1, \
_DPA_AUX_CH_CTL, _DPB_AUX_CH_CTL, \
@@ -72,12 +77,17 @@
#define _DPA_AUX_CH_DATA1 0x64014
#define _DPB_AUX_CH_DATA1 0x64114
-#define _XELPDP_USBC1_AUX_CH_DATA1 0x16f214
-#define _XELPDP_USBC2_AUX_CH_DATA1 0x16f414
#define DP_AUX_CH_DATA(aux_ch, i) _MMIO(_PORT(aux_ch, _DPA_AUX_CH_DATA1, \
_DPB_AUX_CH_DATA1) + (i) * 4) /* 5 registers */
#define VLV_DP_AUX_CH_DATA(aux_ch, i) _MMIO(VLV_DISPLAY_BASE + _PORT(aux_ch, _DPA_AUX_CH_DATA1, \
_DPB_AUX_CH_DATA1) + (i) * 4) /* 5 registers */
+
+#define _PCH_DPB_AUX_CH_DATA1 0xe4114
+#define _PCH_DPC_AUX_CH_DATA1 0xe4214
+#define PCH_DP_AUX_CH_DATA(aux_ch, i) _MMIO(_PORT((aux_ch) - AUX_CH_B, _PCH_DPB_AUX_CH_DATA1, _PCH_DPC_AUX_CH_DATA1) + (i) * 4) /* 5 registers */
+
+#define _XELPDP_USBC1_AUX_CH_DATA1 0x16f214
+#define _XELPDP_USBC2_AUX_CH_DATA1 0x16f414
#define _XELPDP_DP_AUX_CH_DATA(aux_ch, i) \
_MMIO(_PICK_EVEN_2RANGES(aux_ch, AUX_CH_USBC1, \
_DPA_AUX_CH_DATA1, _DPB_AUX_CH_DATA1, \
diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
index 92b03073acdd..2edffe62f360 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
@@ -687,15 +687,16 @@ int intel_dp_hdcp_get_remote_capability(struct intel_connector *connector,
bool *hdcp2_capable)
{
struct drm_i915_private *i915 = to_i915(connector->base.dev);
- struct drm_dp_aux *aux = &connector->port->aux;
+ struct drm_dp_aux *aux;
u8 bcaps;
int ret;
*hdcp_capable = false;
*hdcp2_capable = false;
- if (!intel_encoder_is_mst(connector->encoder))
+ if (!connector->mst_port)
return -EINVAL;
+ aux = &connector->port->aux;
ret = _intel_dp_hdcp2_get_capability(aux, hdcp2_capable);
if (ret)
drm_dbg_kms(&i915->drm,
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
index 947575140059..1bc4ef84ff3b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -25,6 +25,9 @@
#include "intel_display_types.h"
#include "intel_dp.h"
#include "intel_dp_link_training.h"
+#include "intel_encoder.h"
+#include "intel_hotplug.h"
+#include "intel_panel.h"
#define LT_MSG_PREFIX "[CONNECTOR:%d:%s][ENCODER:%d:%s][%s] "
#define LT_MSG_ARGS(_intel_dp, _dp_phy) (_intel_dp)->attached_connector->base.base.id, \
@@ -1091,28 +1094,129 @@ out:
return ret;
}
-static void intel_dp_schedule_fallback_link_training(struct intel_dp *intel_dp,
+static bool intel_dp_can_link_train_fallback_for_edp(struct intel_dp *intel_dp,
+ int link_rate,
+ u8 lane_count)
+{
+ /* FIXME figure out what we actually want here */
+ const struct drm_display_mode *fixed_mode =
+ intel_panel_preferred_fixed_mode(intel_dp->attached_connector);
+ int mode_rate, max_rate;
+
+ mode_rate = intel_dp_link_required(fixed_mode->clock, 18);
+ max_rate = intel_dp_max_link_data_rate(intel_dp, link_rate, lane_count);
+ if (mode_rate > max_rate)
+ return false;
+
+ return true;
+}
+
+static int reduce_link_rate(struct intel_dp *intel_dp, int current_rate)
+{
+ int rate_index;
+ int new_rate;
+
+ if (intel_dp->link.force_rate)
+ return -1;
+
+ rate_index = intel_dp_rate_index(intel_dp->common_rates,
+ intel_dp->num_common_rates,
+ current_rate);
+
+ if (rate_index <= 0)
+ return -1;
+
+ new_rate = intel_dp_common_rate(intel_dp, rate_index - 1);
+
+ /* TODO: Make switching from UHBR to non-UHBR rates work. */
+ if (drm_dp_is_uhbr_rate(current_rate) != drm_dp_is_uhbr_rate(new_rate))
+ return -1;
+
+ return new_rate;
+}
+
+static int reduce_lane_count(struct intel_dp *intel_dp, int current_lane_count)
+{
+ if (intel_dp->link.force_lane_count)
+ return -1;
+
+ if (current_lane_count == 1)
+ return -1;
+
+ return current_lane_count >> 1;
+}
+
+static int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
+{
+ int new_link_rate;
+ int new_lane_count;
+
+ if (intel_dp_is_edp(intel_dp) && !intel_dp->use_max_params) {
+ lt_dbg(intel_dp, DP_PHY_DPRX,
+ "Retrying Link training for eDP with max parameters\n");
+ intel_dp->use_max_params = true;
+ return 0;
+ }
+
+ new_lane_count = crtc_state->lane_count;
+ new_link_rate = reduce_link_rate(intel_dp, crtc_state->port_clock);
+ if (new_link_rate < 0) {
+ new_lane_count = reduce_lane_count(intel_dp, crtc_state->lane_count);
+ new_link_rate = intel_dp_max_common_rate(intel_dp);
+ }
+
+ if (new_lane_count < 0)
+ return -1;
+
+ if (intel_dp_is_edp(intel_dp) &&
+ !intel_dp_can_link_train_fallback_for_edp(intel_dp, new_link_rate, new_lane_count)) {
+ lt_dbg(intel_dp, DP_PHY_DPRX,
+ "Retrying Link training for eDP with same parameters\n");
+ return 0;
+ }
+
+ lt_dbg(intel_dp, DP_PHY_DPRX,
+ "Reducing link parameters from %dx%d to %dx%d\n",
+ crtc_state->lane_count, crtc_state->port_clock,
+ new_lane_count, new_link_rate);
+
+ intel_dp->link.max_rate = new_link_rate;
+ intel_dp->link.max_lane_count = new_lane_count;
+
+ return 0;
+}
+
+/* NOTE: @state is only valid for MST links and can be %NULL for SST. */
+static bool intel_dp_schedule_fallback_link_training(struct intel_atomic_state *state,
+ struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{
- struct intel_connector *intel_connector = intel_dp->attached_connector;
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
if (!intel_digital_port_connected(&dp_to_dig_port(intel_dp)->base)) {
lt_dbg(intel_dp, DP_PHY_DPRX, "Link Training failed on disconnected sink.\n");
- return;
+ return true;
}
if (intel_dp->hobl_active) {
lt_dbg(intel_dp, DP_PHY_DPRX,
"Link Training failed with HOBL active, not enabling it from now on\n");
intel_dp->hobl_failed = true;
- } else if (intel_dp_get_link_train_fallback_values(intel_dp,
- crtc_state->port_clock,
- crtc_state->lane_count)) {
- return;
+ } else if (intel_dp_get_link_train_fallback_values(intel_dp, crtc_state)) {
+ return false;
}
+ if (drm_WARN_ON(&i915->drm,
+ intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) &&
+ !state))
+ return false;
+
/* Schedule a Hotplug Uevent to userspace to start modeset */
- intel_dp_queue_modeset_retry_work(intel_connector);
+ intel_dp_queue_modeset_retry_for_link(state, encoder, crtc_state);
+
+ return true;
}
/* Perform the link training on all LTTPRs and the DPRX on a link. */
@@ -1359,6 +1463,7 @@ intel_dp_128b132b_link_train(struct intel_dp *intel_dp,
/**
* intel_dp_start_link_train - start link training
+ * @state: Atomic state
* @intel_dp: DP struct
* @crtc_state: state for CRTC attached to the encoder
*
@@ -1366,11 +1471,16 @@ intel_dp_128b132b_link_train(struct intel_dp *intel_dp,
* retraining with reduced link rate/lane parameters if the link training
* fails.
* After calling this function intel_dp_stop_link_train() must be called.
+ *
+ * NOTE: @state is only valid for MST links and can be %NULL for SST.
*/
-void intel_dp_start_link_train(struct intel_dp *intel_dp,
+void intel_dp_start_link_train(struct intel_atomic_state *state,
+ struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+ struct intel_encoder *encoder = &dig_port->base;
bool passed;
/*
@@ -1379,6 +1489,11 @@ void intel_dp_start_link_train(struct intel_dp *intel_dp,
*/
int lttpr_count = intel_dp_init_lttpr_and_dprx_caps(intel_dp);
+ if (drm_WARN_ON(&i915->drm,
+ intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) &&
+ !state))
+ return;
+
if (lttpr_count < 0)
/* Still continue with enabling the port and link training. */
lttpr_count = 0;
@@ -1390,6 +1505,17 @@ void intel_dp_start_link_train(struct intel_dp *intel_dp,
else
passed = intel_dp_link_train_all_phys(intel_dp, crtc_state, lttpr_count);
+ if (intel_dp->link.force_train_failure) {
+ intel_dp->link.force_train_failure--;
+ lt_dbg(intel_dp, DP_PHY_DPRX, "Forcing link training failure\n");
+ } else if (passed) {
+ intel_dp->link.seq_train_failures = 0;
+ intel_encoder_link_check_queue_work(encoder, 2000);
+ return;
+ }
+
+ intel_dp->link.seq_train_failures++;
+
/*
* Ignore the link failure in CI
*
@@ -1402,13 +1528,25 @@ void intel_dp_start_link_train(struct intel_dp *intel_dp,
* For test cases which rely on the link training or processing of HPDs
* ignore_long_hpd flag can unset from the testcase.
*/
- if (!passed && i915->display.hotplug.ignore_long_hpd) {
+ if (i915->display.hotplug.ignore_long_hpd) {
lt_dbg(intel_dp, DP_PHY_DPRX, "Ignore the link failure\n");
return;
}
+ if (intel_dp->link.seq_train_failures < 2) {
+ intel_encoder_link_check_queue_work(encoder, 0);
+ return;
+ }
+
+ if (intel_dp_schedule_fallback_link_training(state, intel_dp, crtc_state))
+ return;
+
+ intel_dp->link.retrain_disabled = true;
+
if (!passed)
- intel_dp_schedule_fallback_link_training(intel_dp, crtc_state);
+ lt_err(intel_dp, DP_PHY_DPRX, "Can't reduce link training parameters after failure\n");
+ else
+ lt_dbg(intel_dp, DP_PHY_DPRX, "Can't reduce link training parameters after forced failure\n");
}
void intel_dp_128b132b_sdp_crc16(struct intel_dp *intel_dp,
@@ -1430,3 +1568,381 @@ void intel_dp_128b132b_sdp_crc16(struct intel_dp *intel_dp,
lt_dbg(intel_dp, DP_PHY_DPRX, "DP2.0 SDP CRC16 for 128b/132b enabled\n");
}
+
+static struct intel_dp *intel_connector_to_intel_dp(struct intel_connector *connector)
+{
+ if (connector->mst_port)
+ return connector->mst_port;
+ else
+ return enc_to_intel_dp(intel_attached_encoder(connector));
+}
+
+static int i915_dp_force_link_rate_show(struct seq_file *m, void *data)
+{
+ struct intel_connector *connector = to_intel_connector(m->private);
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ int current_rate = -1;
+ int force_rate;
+ int err;
+ int i;
+
+ err = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
+ if (err)
+ return err;
+
+ if (intel_dp->link_trained)
+ current_rate = intel_dp->link_rate;
+ force_rate = intel_dp->link.force_rate;
+
+ drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
+
+ seq_printf(m, "%sauto%s",
+ force_rate == 0 ? "[" : "",
+ force_rate == 0 ? "]" : "");
+
+ for (i = 0; i < intel_dp->num_source_rates; i++)
+ seq_printf(m, " %s%d%s%s",
+ intel_dp->source_rates[i] == force_rate ? "[" : "",
+ intel_dp->source_rates[i],
+ intel_dp->source_rates[i] == current_rate ? "*" : "",
+ intel_dp->source_rates[i] == force_rate ? "]" : "");
+
+ seq_putc(m, '\n');
+
+ return 0;
+}
+
+static int parse_link_rate(struct intel_dp *intel_dp, const char __user *ubuf, size_t len)
+{
+ char *kbuf;
+ const char *p;
+ int rate;
+ int ret = 0;
+
+ kbuf = memdup_user_nul(ubuf, len);
+ if (IS_ERR(kbuf))
+ return PTR_ERR(kbuf);
+
+ p = strim(kbuf);
+
+ if (!strcmp(p, "auto")) {
+ rate = 0;
+ } else {
+ ret = kstrtoint(p, 0, &rate);
+ if (ret < 0)
+ goto out_free;
+
+ if (intel_dp_rate_index(intel_dp->source_rates,
+ intel_dp->num_source_rates,
+ rate) < 0)
+ ret = -EINVAL;
+ }
+
+out_free:
+ kfree(kbuf);
+
+ return ret < 0 ? ret : rate;
+}
+
+static ssize_t i915_dp_force_link_rate_write(struct file *file,
+ const char __user *ubuf,
+ size_t len, loff_t *offp)
+{
+ struct seq_file *m = file->private_data;
+ struct intel_connector *connector = to_intel_connector(m->private);
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ int rate;
+ int err;
+
+ rate = parse_link_rate(intel_dp, ubuf, len);
+ if (rate < 0)
+ return rate;
+
+ err = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
+ if (err)
+ return err;
+
+ intel_dp_reset_link_params(intel_dp);
+ intel_dp->link.force_rate = rate;
+
+ drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
+
+ *offp += len;
+
+ return len;
+}
+DEFINE_SHOW_STORE_ATTRIBUTE(i915_dp_force_link_rate);
+
+static int i915_dp_force_lane_count_show(struct seq_file *m, void *data)
+{
+ struct intel_connector *connector = to_intel_connector(m->private);
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ int current_lane_count = -1;
+ int force_lane_count;
+ int err;
+ int i;
+
+ err = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
+ if (err)
+ return err;
+
+ if (intel_dp->link_trained)
+ current_lane_count = intel_dp->lane_count;
+ force_lane_count = intel_dp->link.force_lane_count;
+
+ drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
+
+ seq_printf(m, "%sauto%s",
+ force_lane_count == 0 ? "[" : "",
+ force_lane_count == 0 ? "]" : "");
+
+ for (i = 1; i <= 4; i <<= 1)
+ seq_printf(m, " %s%d%s%s",
+ i == force_lane_count ? "[" : "",
+ i,
+ i == current_lane_count ? "*" : "",
+ i == force_lane_count ? "]" : "");
+
+ seq_putc(m, '\n');
+
+ return 0;
+}
+
+static int parse_lane_count(const char __user *ubuf, size_t len)
+{
+ char *kbuf;
+ const char *p;
+ int lane_count;
+ int ret = 0;
+
+ kbuf = memdup_user_nul(ubuf, len);
+ if (IS_ERR(kbuf))
+ return PTR_ERR(kbuf);
+
+ p = strim(kbuf);
+
+ if (!strcmp(p, "auto")) {
+ lane_count = 0;
+ } else {
+ ret = kstrtoint(p, 0, &lane_count);
+ if (ret < 0)
+ goto out_free;
+
+ switch (lane_count) {
+ case 1:
+ case 2:
+ case 4:
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ }
+
+out_free:
+ kfree(kbuf);
+
+ return ret < 0 ? ret : lane_count;
+}
+
+static ssize_t i915_dp_force_lane_count_write(struct file *file,
+ const char __user *ubuf,
+ size_t len, loff_t *offp)
+{
+ struct seq_file *m = file->private_data;
+ struct intel_connector *connector = to_intel_connector(m->private);
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ int lane_count;
+ int err;
+
+ lane_count = parse_lane_count(ubuf, len);
+ if (lane_count < 0)
+ return lane_count;
+
+ err = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
+ if (err)
+ return err;
+
+ intel_dp_reset_link_params(intel_dp);
+ intel_dp->link.force_lane_count = lane_count;
+
+ drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
+
+ *offp += len;
+
+ return len;
+}
+DEFINE_SHOW_STORE_ATTRIBUTE(i915_dp_force_lane_count);
+
+static int i915_dp_max_link_rate_show(void *data, u64 *val)
+{
+ struct intel_connector *connector = to_intel_connector(data);
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ int err;
+
+ err = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
+ if (err)
+ return err;
+
+ *val = intel_dp->link.max_rate;
+
+ drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
+
+ return 0;
+}
+DEFINE_DEBUGFS_ATTRIBUTE(i915_dp_max_link_rate_fops, i915_dp_max_link_rate_show, NULL, "%llu\n");
+
+static int i915_dp_max_lane_count_show(void *data, u64 *val)
+{
+ struct intel_connector *connector = to_intel_connector(data);
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ int err;
+
+ err = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
+ if (err)
+ return err;
+
+ *val = intel_dp->link.max_lane_count;
+
+ drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
+
+ return 0;
+}
+DEFINE_DEBUGFS_ATTRIBUTE(i915_dp_max_lane_count_fops, i915_dp_max_lane_count_show, NULL, "%llu\n");
+
+static int i915_dp_force_link_training_failure_show(void *data, u64 *val)
+{
+ struct intel_connector *connector = to_intel_connector(data);
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ int err;
+
+ err = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
+ if (err)
+ return err;
+
+ *val = intel_dp->link.force_train_failure;
+
+ drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
+
+ return 0;
+}
+
+static int i915_dp_force_link_training_failure_write(void *data, u64 val)
+{
+ struct intel_connector *connector = to_intel_connector(data);
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ int err;
+
+ if (val > 2)
+ return -EINVAL;
+
+ err = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
+ if (err)
+ return err;
+
+ intel_dp->link.force_train_failure = val;
+
+ drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
+
+ return 0;
+}
+DEFINE_DEBUGFS_ATTRIBUTE(i915_dp_force_link_training_failure_fops,
+ i915_dp_force_link_training_failure_show,
+ i915_dp_force_link_training_failure_write, "%llu\n");
+
+static int i915_dp_force_link_retrain_show(void *data, u64 *val)
+{
+ struct intel_connector *connector = to_intel_connector(data);
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ int err;
+
+ err = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
+ if (err)
+ return err;
+
+ *val = intel_dp->link.force_retrain;
+
+ drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
+
+ return 0;
+}
+
+static int i915_dp_force_link_retrain_write(void *data, u64 val)
+{
+ struct intel_connector *connector = to_intel_connector(data);
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ int err;
+
+ err = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
+ if (err)
+ return err;
+
+ intel_dp->link.force_retrain = val;
+
+ drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
+
+ intel_hpd_trigger_irq(dp_to_dig_port(intel_dp));
+
+ return 0;
+}
+DEFINE_DEBUGFS_ATTRIBUTE(i915_dp_force_link_retrain_fops,
+ i915_dp_force_link_retrain_show,
+ i915_dp_force_link_retrain_write, "%llu\n");
+
+static int i915_dp_link_retrain_disabled_show(struct seq_file *m, void *data)
+{
+ struct intel_connector *connector = to_intel_connector(m->private);
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_dp *intel_dp = intel_connector_to_intel_dp(connector);
+ int err;
+
+ err = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
+ if (err)
+ return err;
+
+ seq_printf(m, "%s\n", str_yes_no(intel_dp->link.retrain_disabled));
+
+ drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
+
+ return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(i915_dp_link_retrain_disabled);
+
+void intel_dp_link_training_debugfs_add(struct intel_connector *connector)
+{
+ struct dentry *root = connector->base.debugfs_entry;
+
+ if (connector->base.connector_type != DRM_MODE_CONNECTOR_DisplayPort &&
+ connector->base.connector_type != DRM_MODE_CONNECTOR_eDP)
+ return;
+
+ debugfs_create_file("i915_dp_force_link_rate", 0644, root,
+ connector, &i915_dp_force_link_rate_fops);
+
+ debugfs_create_file("i915_dp_force_lane_count", 0644, root,
+ connector, &i915_dp_force_lane_count_fops);
+
+ debugfs_create_file("i915_dp_max_link_rate", 0444, root,
+ connector, &i915_dp_max_link_rate_fops);
+
+ debugfs_create_file("i915_dp_max_lane_count", 0444, root,
+ connector, &i915_dp_max_lane_count_fops);
+
+ debugfs_create_file("i915_dp_force_link_training_failure", 0644, root,
+ connector, &i915_dp_force_link_training_failure_fops);
+
+ debugfs_create_file("i915_dp_force_link_retrain", 0644, root,
+ connector, &i915_dp_force_link_retrain_fops);
+
+ debugfs_create_file("i915_dp_link_retrain_disabled", 0444, root,
+ connector, &i915_dp_link_retrain_disabled_fops);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.h b/drivers/gpu/drm/i915/display/intel_dp_link_training.h
index 19836a8a4f90..42e7fc6cb171 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.h
@@ -8,6 +8,8 @@
#include <drm/display/drm_dp_helper.h>
+struct intel_atomic_state;
+struct intel_connector;
struct intel_crtc_state;
struct intel_dp;
@@ -25,7 +27,8 @@ void intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
void intel_dp_set_signal_levels(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state,
enum drm_dp_phy dp_phy);
-void intel_dp_start_link_train(struct intel_dp *intel_dp,
+void intel_dp_start_link_train(struct intel_atomic_state *state,
+ struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
void intel_dp_stop_link_train(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
@@ -42,4 +45,7 @@ static inline u8 intel_dp_training_pattern_symbol(u8 pattern)
void intel_dp_128b132b_sdp_crc16(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
+
+void intel_dp_link_training_debugfs_add(struct intel_connector *connector);
+
#endif /* __INTEL_DP_LINK_TRAINING_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 715d2f59f565..27ce5c3f5951 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -105,7 +105,7 @@ static int intel_dp_mst_bw_overhead(const struct intel_crtc_state *crtc_state,
dsc_slice_count = intel_dp_dsc_get_slice_count(connector,
adjusted_mode->clock,
adjusted_mode->hdisplay,
- crtc_state->bigjoiner_pipes);
+ crtc_state->joiner_pipes);
}
overhead = drm_dp_bw_overhead(crtc_state->lane_count,
@@ -207,6 +207,7 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder,
int remote_bw_overhead;
int link_bpp_x16;
int remote_tu;
+ fixed20_12 pbn;
drm_dbg_kms(&i915->drm, "Trying bpp %d\n", bpp);
@@ -237,11 +238,29 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder,
* crtc_state->dp_m_n.tu), provided that the driver doesn't
* enable SSC on the corresponding link.
*/
- crtc_state->pbn = intel_dp_mst_calc_pbn(adjusted_mode->crtc_clock,
- link_bpp_x16,
- remote_bw_overhead);
+ pbn.full = dfixed_const(intel_dp_mst_calc_pbn(adjusted_mode->crtc_clock,
+ link_bpp_x16,
+ remote_bw_overhead));
+ remote_tu = DIV_ROUND_UP(pbn.full, mst_state->pbn_div.full);
- remote_tu = DIV_ROUND_UP(dfixed_const(crtc_state->pbn), mst_state->pbn_div.full);
+ /*
+ * Aligning the TUs ensures that symbols consisting of multiple
+ * (4) symbol cycles don't get split between two consecutive
+ * MTPs, as required by Bspec.
+ * TODO: remove the alignment restriction for 128b/132b links
+ * on some platforms, where Bspec allows this.
+ */
+ remote_tu = ALIGN(remote_tu, 4 / crtc_state->lane_count);
+
+ /*
+ * Also align PBNs accordingly, since MST core will derive its
+ * own copy of TU from the PBN in drm_dp_atomic_find_time_slots().
+ * The above comment about the difference between the PBN
+ * allocated for the whole path and the TUs allocated for the
+ * first branch device's link also applies here.
+ */
+ pbn.full = remote_tu * mst_state->pbn_div.full;
+ crtc_state->pbn = dfixed_trunc(pbn);
drm_WARN_ON(&i915->drm, remote_tu < crtc_state->dp_m_n.tu);
crtc_state->dp_m_n.tu = remote_tu;
@@ -349,6 +368,8 @@ static int intel_dp_dsc_mst_compute_link_config(struct intel_encoder *encoder,
if (max_bpp > sink_max_bpp)
max_bpp = sink_max_bpp;
+ crtc_state->pipe_bpp = max_bpp;
+
max_compressed_bpp = intel_dp_dsc_sink_max_compressed_bpp(connector,
crtc_state,
max_bpp / 3);
@@ -400,18 +421,6 @@ static int intel_dp_mst_update_slots(struct intel_encoder *encoder,
return 0;
}
-static bool
-intel_dp_mst_dsc_source_support(const struct intel_crtc_state *crtc_state)
-{
- struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
-
- /*
- * FIXME: Enabling DSC on ICL results in blank screen and FIFO pipe /
- * transcoder underruns, re-enable DSC after fixing this issue.
- */
- return DISPLAY_VER(i915) >= 12 && intel_dsc_source_support(crtc_state);
-}
-
static int mode_hblank_period_ns(const struct drm_display_mode *mode)
{
return DIV_ROUND_CLOSEST_ULL(mul_u32_u32(mode->htotal - mode->hdisplay,
@@ -456,7 +465,7 @@ adjust_limits_for_dsc_hblank_expansion_quirk(const struct intel_connector *conne
return true;
if (!dsc) {
- if (intel_dp_mst_dsc_source_support(crtc_state)) {
+ if (intel_dp_supports_dsc(connector, crtc_state)) {
drm_dbg_kms(&i915->drm,
"[CRTC:%d:%s][CONNECTOR:%d:%s] DSC needed by hblank expansion quirk\n",
crtc->base.base.id, crtc->base.name,
@@ -567,16 +576,16 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
return -EINVAL;
- if (intel_dp_need_bigjoiner(intel_dp, connector,
- adjusted_mode->crtc_hdisplay,
- adjusted_mode->crtc_clock))
- pipe_config->bigjoiner_pipes = GENMASK(crtc->pipe + 1, crtc->pipe);
+ if (intel_dp_need_joiner(intel_dp, connector,
+ adjusted_mode->crtc_hdisplay,
+ adjusted_mode->crtc_clock))
+ pipe_config->joiner_pipes = GENMASK(crtc->pipe + 1, crtc->pipe);
pipe_config->sink_format = INTEL_OUTPUT_FORMAT_RGB;
pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
pipe_config->has_pch_encoder = false;
- joiner_needs_dsc = intel_dp_joiner_needs_dsc(dev_priv, pipe_config->bigjoiner_pipes);
+ joiner_needs_dsc = intel_dp_joiner_needs_dsc(dev_priv, pipe_config->joiner_pipes);
dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en ||
!intel_dp_mst_compute_config_limits(intel_dp,
@@ -602,7 +611,7 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
str_yes_no(ret), str_yes_no(joiner_needs_dsc),
str_yes_no(intel_dp->force_dsc_en));
- if (!intel_dp_mst_dsc_source_support(pipe_config))
+ if (!intel_dp_supports_dsc(connector, pipe_config))
return -EINVAL;
if (!intel_dp_mst_compute_config_limits(intel_dp,
@@ -962,6 +971,9 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
drm_dbg_kms(&i915->drm, "active links %d\n",
intel_dp->active_mst_links);
+ if (intel_dp->active_mst_links == 1)
+ intel_dp->link_trained = false;
+
intel_hdcp_disable(intel_mst->connector);
intel_dp_sink_disable_decompression(state, connector, old_crtc_state);
@@ -1009,7 +1021,8 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
clear_act_sent(encoder, old_crtc_state);
- intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(old_crtc_state->cpu_transcoder),
+ intel_de_rmw(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, old_crtc_state->cpu_transcoder),
TRANS_DDI_DP_VC_PAYLOAD_ALLOC, 0);
wait_for_act_sent(encoder, old_crtc_state);
@@ -1230,7 +1243,7 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
clear_act_sent(encoder, pipe_config);
- intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(trans), 0,
+ intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, trans), 0,
TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
drm_dbg_kms(&dev_priv->drm, "active links %d\n",
@@ -1375,7 +1388,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
int max_dotclk = to_i915(connector->dev)->display.cdclk.max_dotclk_freq;
int max_rate, mode_rate, max_lanes, max_link_clock;
int ret;
- bool dsc = false, bigjoiner = false;
+ bool dsc = false, joiner = false;
u16 dsc_max_compressed_bpp = 0;
u8 dsc_slice_count = 0;
int target_clock = mode->clock;
@@ -1418,9 +1431,9 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
* corresponding link capabilities of the sink) in case the
* stream is uncompressed for it by the last branch device.
*/
- if (intel_dp_need_bigjoiner(intel_dp, intel_connector,
- mode->hdisplay, target_clock)) {
- bigjoiner = true;
+ if (intel_dp_need_joiner(intel_dp, intel_connector,
+ mode->hdisplay, target_clock)) {
+ joiner = true;
max_dotclk *= 2;
}
@@ -1434,8 +1447,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
return 0;
}
- if (HAS_DSC_MST(dev_priv) &&
- drm_dp_sink_supports_dsc(intel_connector->dp.dsc_dpcd)) {
+ if (intel_dp_has_dsc(intel_connector)) {
/*
* TBD pass the connector BPC,
* for now U8_MAX so that max BPC on that platform would be picked
@@ -1449,20 +1461,20 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
max_lanes,
target_clock,
mode->hdisplay,
- bigjoiner,
+ joiner,
INTEL_OUTPUT_FORMAT_RGB,
pipe_bpp, 64);
dsc_slice_count =
intel_dp_dsc_get_slice_count(intel_connector,
target_clock,
mode->hdisplay,
- bigjoiner);
+ joiner);
}
dsc = dsc_max_compressed_bpp && dsc_slice_count;
}
- if (intel_dp_joiner_needs_dsc(dev_priv, bigjoiner) && !dsc) {
+ if (intel_dp_joiner_needs_dsc(dev_priv, joiner) && !dsc) {
*status = MODE_CLOCK_HIGH;
return 0;
}
@@ -1472,7 +1484,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
return 0;
}
- *status = intel_mode_valid_max_plane_size(dev_priv, mode, bigjoiner);
+ *status = intel_mode_valid_max_plane_size(dev_priv, mode, joiner);
return 0;
}
diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c
index a981f45facb3..d67d5e2fd570 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll.c
@@ -398,12 +398,13 @@ void i9xx_dpll_get_hw_state(struct intel_crtc *crtc,
if (IS_CHERRYVIEW(dev_priv) && crtc->pipe != PIPE_A)
tmp = dev_priv->display.state.chv_dpll_md[crtc->pipe];
else
- tmp = intel_de_read(dev_priv, DPLL_MD(crtc->pipe));
+ tmp = intel_de_read(dev_priv,
+ DPLL_MD(dev_priv, crtc->pipe));
hw_state->dpll_md = tmp;
}
- hw_state->dpll = intel_de_read(dev_priv, DPLL(crtc->pipe));
+ hw_state->dpll = intel_de_read(dev_priv, DPLL(dev_priv, crtc->pipe));
if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) {
hw_state->fp0 = intel_de_read(dev_priv, FP0(crtc->pipe));
@@ -1842,28 +1843,30 @@ void i9xx_enable_pll(const struct intel_crtc_state *crtc_state)
* the P1/P2 dividers. Otherwise the DPLL will keep using the old
* dividers, even though the register value does change.
*/
- intel_de_write(dev_priv, DPLL(pipe), hw_state->dpll & ~DPLL_VGA_MODE_DIS);
- intel_de_write(dev_priv, DPLL(pipe), hw_state->dpll);
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe),
+ hw_state->dpll & ~DPLL_VGA_MODE_DIS);
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), hw_state->dpll);
/* Wait for the clocks to stabilize. */
- intel_de_posting_read(dev_priv, DPLL(pipe));
+ intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe));
udelay(150);
if (DISPLAY_VER(dev_priv) >= 4) {
- intel_de_write(dev_priv, DPLL_MD(pipe), hw_state->dpll_md);
+ intel_de_write(dev_priv, DPLL_MD(dev_priv, pipe),
+ hw_state->dpll_md);
} else {
/* The pixel multiplier can only be updated once the
* DPLL is enabled and the clocks are stable.
*
* So write it again.
*/
- intel_de_write(dev_priv, DPLL(pipe), hw_state->dpll);
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), hw_state->dpll);
}
/* We do this three times for luck */
for (i = 0; i < 3; i++) {
- intel_de_write(dev_priv, DPLL(pipe), hw_state->dpll);
- intel_de_posting_read(dev_priv, DPLL(pipe));
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), hw_state->dpll);
+ intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe));
udelay(150); /* wait for warmup */
}
}
@@ -1991,11 +1994,11 @@ static void _vlv_enable_pll(const struct intel_crtc_state *crtc_state)
const struct i9xx_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.i9xx;
enum pipe pipe = crtc->pipe;
- intel_de_write(dev_priv, DPLL(pipe), hw_state->dpll);
- intel_de_posting_read(dev_priv, DPLL(pipe));
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), hw_state->dpll);
+ intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe));
udelay(150);
- if (intel_de_wait_for_set(dev_priv, DPLL(pipe), DPLL_LOCK_VLV, 1))
+ if (intel_de_wait_for_set(dev_priv, DPLL(dev_priv, pipe), DPLL_LOCK_VLV, 1))
drm_err(&dev_priv->drm, "DPLL %d failed to lock\n", pipe);
}
@@ -2012,7 +2015,7 @@ void vlv_enable_pll(const struct intel_crtc_state *crtc_state)
assert_pps_unlocked(dev_priv, pipe);
/* Enable Refclk */
- intel_de_write(dev_priv, DPLL(pipe),
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe),
hw_state->dpll & ~(DPLL_VCO_ENABLE | DPLL_EXT_BUFFER_ENABLE_VLV));
if (hw_state->dpll & DPLL_VCO_ENABLE) {
@@ -2020,8 +2023,8 @@ void vlv_enable_pll(const struct intel_crtc_state *crtc_state)
_vlv_enable_pll(crtc_state);
}
- intel_de_write(dev_priv, DPLL_MD(pipe), hw_state->dpll_md);
- intel_de_posting_read(dev_priv, DPLL_MD(pipe));
+ intel_de_write(dev_priv, DPLL_MD(dev_priv, pipe), hw_state->dpll_md);
+ intel_de_posting_read(dev_priv, DPLL_MD(dev_priv, pipe));
}
static void chv_prepare_pll(const struct intel_crtc_state *crtc_state)
@@ -2138,10 +2141,10 @@ static void _chv_enable_pll(const struct intel_crtc_state *crtc_state)
udelay(1);
/* Enable PLL */
- intel_de_write(dev_priv, DPLL(pipe), hw_state->dpll);
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), hw_state->dpll);
/* Check PLL is locked */
- if (intel_de_wait_for_set(dev_priv, DPLL(pipe), DPLL_LOCK_VLV, 1))
+ if (intel_de_wait_for_set(dev_priv, DPLL(dev_priv, pipe), DPLL_LOCK_VLV, 1))
drm_err(&dev_priv->drm, "PLL %d failed to lock\n", pipe);
}
@@ -2158,7 +2161,7 @@ void chv_enable_pll(const struct intel_crtc_state *crtc_state)
assert_pps_unlocked(dev_priv, pipe);
/* Enable Refclk and SSC */
- intel_de_write(dev_priv, DPLL(pipe),
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe),
hw_state->dpll & ~DPLL_VCO_ENABLE);
if (hw_state->dpll & DPLL_VCO_ENABLE) {
@@ -2174,7 +2177,8 @@ void chv_enable_pll(const struct intel_crtc_state *crtc_state)
* the value from DPLLBMD to either pipe B or C.
*/
intel_de_write(dev_priv, CBR4_VLV, CBR_DPLLBMD_PIPE(pipe));
- intel_de_write(dev_priv, DPLL_MD(PIPE_B), hw_state->dpll_md);
+ intel_de_write(dev_priv, DPLL_MD(dev_priv, PIPE_B),
+ hw_state->dpll_md);
intel_de_write(dev_priv, CBR4_VLV, 0);
dev_priv->display.state.chv_dpll_md[pipe] = hw_state->dpll_md;
@@ -2183,11 +2187,12 @@ void chv_enable_pll(const struct intel_crtc_state *crtc_state)
* We should always have it disabled.
*/
drm_WARN_ON(&dev_priv->drm,
- (intel_de_read(dev_priv, DPLL(PIPE_B)) &
+ (intel_de_read(dev_priv, DPLL(dev_priv, PIPE_B)) &
DPLL_VGA_MODE_DIS) == 0);
} else {
- intel_de_write(dev_priv, DPLL_MD(pipe), hw_state->dpll_md);
- intel_de_posting_read(dev_priv, DPLL_MD(pipe));
+ intel_de_write(dev_priv, DPLL_MD(dev_priv, pipe),
+ hw_state->dpll_md);
+ intel_de_posting_read(dev_priv, DPLL_MD(dev_priv, pipe));
}
}
@@ -2241,8 +2246,8 @@ void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
if (pipe != PIPE_A)
val |= DPLL_INTEGRATED_CRI_CLK_VLV;
- intel_de_write(dev_priv, DPLL(pipe), val);
- intel_de_posting_read(dev_priv, DPLL(pipe));
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), val);
+ intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe));
}
void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
@@ -2259,8 +2264,8 @@ void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
if (pipe != PIPE_A)
val |= DPLL_INTEGRATED_CRI_CLK_VLV;
- intel_de_write(dev_priv, DPLL(pipe), val);
- intel_de_posting_read(dev_priv, DPLL(pipe));
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), val);
+ intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe));
vlv_dpio_get(dev_priv);
@@ -2285,8 +2290,8 @@ void i9xx_disable_pll(const struct intel_crtc_state *crtc_state)
/* Make sure the pipe isn't still relying on us */
assert_transcoder_disabled(dev_priv, crtc_state->cpu_transcoder);
- intel_de_write(dev_priv, DPLL(pipe), DPLL_VGA_MODE_DIS);
- intel_de_posting_read(dev_priv, DPLL(pipe));
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), DPLL_VGA_MODE_DIS);
+ intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe));
}
@@ -2312,7 +2317,7 @@ static void assert_pll(struct drm_i915_private *dev_priv,
{
bool cur_state;
- cur_state = intel_de_read(dev_priv, DPLL(pipe)) & DPLL_VCO_ENABLE;
+ cur_state = intel_de_read(dev_priv, DPLL(dev_priv, pipe)) & DPLL_VCO_ENABLE;
I915_STATE_WARN(dev_priv, cur_state != state,
"PLL state assertion failure (expected %s, current %s)\n",
str_on_off(state), str_on_off(cur_state));
diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h
index f09e513ce05b..36baed75b89a 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h
+++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h
@@ -264,6 +264,7 @@ struct intel_cx0pll_state {
struct intel_c20pll_state c20;
};
bool ssc_enabled;
+ bool use_c10;
};
struct intel_dpll_hw_state {
diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c
index b29bceff73f2..73a1918e2537 100644
--- a/drivers/gpu/drm/i915/display/intel_dpt.c
+++ b/drivers/gpu/drm/i915/display/intel_dpt.c
@@ -121,7 +121,8 @@ static void dpt_cleanup(struct i915_address_space *vm)
i915_gem_object_put(dpt->obj);
}
-struct i915_vma *intel_dpt_pin(struct i915_address_space *vm)
+struct i915_vma *intel_dpt_pin_to_ggtt(struct i915_address_space *vm,
+ unsigned int alignment)
{
struct drm_i915_private *i915 = vm->i915;
struct i915_dpt *dpt = i915_vm_to_dpt(vm);
@@ -143,8 +144,8 @@ struct i915_vma *intel_dpt_pin(struct i915_address_space *vm)
if (err)
continue;
- vma = i915_gem_object_ggtt_pin_ww(dpt->obj, &ww, NULL, 0, 4096,
- pin_flags);
+ vma = i915_gem_object_ggtt_pin_ww(dpt->obj, &ww, NULL, 0,
+ alignment, pin_flags);
if (IS_ERR(vma)) {
err = PTR_ERR(vma);
continue;
@@ -172,7 +173,7 @@ struct i915_vma *intel_dpt_pin(struct i915_address_space *vm)
return err ? ERR_PTR(err) : vma;
}
-void intel_dpt_unpin(struct i915_address_space *vm)
+void intel_dpt_unpin_from_ggtt(struct i915_address_space *vm)
{
struct i915_dpt *dpt = i915_vm_to_dpt(vm);
diff --git a/drivers/gpu/drm/i915/display/intel_dpt.h b/drivers/gpu/drm/i915/display/intel_dpt.h
index e18a9f767b11..ff18a525bfbe 100644
--- a/drivers/gpu/drm/i915/display/intel_dpt.h
+++ b/drivers/gpu/drm/i915/display/intel_dpt.h
@@ -13,8 +13,9 @@ struct i915_vma;
struct intel_framebuffer;
void intel_dpt_destroy(struct i915_address_space *vm);
-struct i915_vma *intel_dpt_pin(struct i915_address_space *vm);
-void intel_dpt_unpin(struct i915_address_space *vm);
+struct i915_vma *intel_dpt_pin_to_ggtt(struct i915_address_space *vm,
+ unsigned int alignment);
+void intel_dpt_unpin_from_ggtt(struct i915_address_space *vm);
void intel_dpt_suspend(struct drm_i915_private *i915);
void intel_dpt_resume(struct drm_i915_private *i915);
struct i915_address_space *
diff --git a/drivers/gpu/drm/i915/display/intel_dpt_common.c b/drivers/gpu/drm/i915/display/intel_dpt_common.c
index cdba47165c04..573f72068899 100644
--- a/drivers/gpu/drm/i915/display/intel_dpt_common.c
+++ b/drivers/gpu/drm/i915/display/intel_dpt_common.c
@@ -7,6 +7,7 @@
#include "intel_de.h"
#include "intel_display_types.h"
#include "intel_dpt_common.h"
+#include "skl_universal_plane_regs.h"
void intel_dpt_configure(struct intel_crtc *crtc)
{
diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c
index 597f8bd6aa1a..3ca29afa5422 100644
--- a/drivers/gpu/drm/i915/display/intel_drrs.c
+++ b/drivers/gpu/drm/i915/display/intel_drrs.c
@@ -85,7 +85,7 @@ intel_drrs_set_refresh_rate_pipeconf(struct intel_crtc *crtc,
else
bit = TRANSCONF_REFRESH_RATE_ALT_ILK;
- intel_de_rmw(dev_priv, TRANSCONF(cpu_transcoder),
+ intel_de_rmw(dev_priv, TRANSCONF(dev_priv, cpu_transcoder),
bit, refresh_rate == DRRS_REFRESH_RATE_LOW ? bit : 0);
}
@@ -135,7 +135,7 @@ static unsigned int intel_drrs_frontbuffer_bits(const struct intel_crtc_state *c
frontbuffer_bits = INTEL_FRONTBUFFER_ALL_MASK(crtc->pipe);
for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc,
- crtc_state->bigjoiner_pipes)
+ crtc_state->joiner_pipes)
frontbuffer_bits |= INTEL_FRONTBUFFER_ALL_MASK(crtc->pipe);
return frontbuffer_bits;
@@ -157,7 +157,7 @@ void intel_drrs_activate(const struct intel_crtc_state *crtc_state)
if (!crtc_state->hw.active)
return;
- if (intel_crtc_is_bigjoiner_slave(crtc_state))
+ if (intel_crtc_is_joiner_secondary(crtc_state))
return;
mutex_lock(&crtc->drrs.mutex);
@@ -189,7 +189,7 @@ void intel_drrs_deactivate(const struct intel_crtc_state *old_crtc_state)
if (!old_crtc_state->hw.active)
return;
- if (intel_crtc_is_bigjoiner_slave(old_crtc_state))
+ if (intel_crtc_is_joiner_secondary(old_crtc_state))
return;
mutex_lock(&crtc->drrs.mutex);
diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c
index 4baaa92ceaec..5180b9722046 100644
--- a/drivers/gpu/drm/i915/display/intel_dsb.c
+++ b/drivers/gpu/drm/i915/display/intel_dsb.c
@@ -6,7 +6,6 @@
#include "i915_drv.h"
#include "i915_irq.h"
-#include "i915_reg.h"
#include "intel_crtc.h"
#include "intel_de.h"
#include "intel_display_types.h"
@@ -19,16 +18,8 @@
#define CACHELINE_BYTES 64
-enum dsb_id {
- INVALID_DSB = -1,
- DSB1,
- DSB2,
- DSB3,
- MAX_DSB_PER_PIPE
-};
-
struct intel_dsb {
- enum dsb_id id;
+ enum intel_dsb_id id;
struct intel_dsb_buffer dsb_buf;
struct intel_crtc *crtc;
@@ -121,9 +112,9 @@ static void intel_dsb_dump(struct intel_dsb *dsb)
}
static bool is_dsb_busy(struct drm_i915_private *i915, enum pipe pipe,
- enum dsb_id id)
+ enum intel_dsb_id dsb_id)
{
- return intel_de_read_fw(i915, DSB_CTRL(pipe, id)) & DSB_STATUS_BUSY;
+ return intel_de_read_fw(i915, DSB_CTRL(pipe, dsb_id)) & DSB_STATUS_BUSY;
}
static void intel_dsb_emit(struct intel_dsb *dsb, u32 ldw, u32 udw)
@@ -328,14 +319,10 @@ static int intel_dsb_dewake_scanline(const struct intel_crtc_state *crtc_state)
unsigned int latency = skl_watermark_max_latency(i915, 0);
int vblank_start;
- if (crtc_state->vrr.enable) {
+ if (crtc_state->vrr.enable)
vblank_start = intel_vrr_vmin_vblank_start(crtc_state);
- } else {
- vblank_start = adjusted_mode->crtc_vblank_start;
-
- if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
- vblank_start = DIV_ROUND_UP(vblank_start, 2);
- }
+ else
+ vblank_start = intel_mode_vblank_start(adjusted_mode);
return max(0, vblank_start - intel_usecs_to_scanlines(adjusted_mode, latency));
}
@@ -448,6 +435,7 @@ void intel_dsb_wait(struct intel_dsb *dsb)
/**
* intel_dsb_prepare() - Allocate, pin and map the DSB command buffer.
* @crtc_state: the CRTC state
+ * @dsb_id: the DSB engine to use
* @max_cmds: number of commands we need to fit into command buffer
*
* This function prepare the command buffer which is used to store dsb
@@ -457,6 +445,7 @@ void intel_dsb_wait(struct intel_dsb *dsb)
* DSB context, NULL on failure
*/
struct intel_dsb *intel_dsb_prepare(const struct intel_crtc_state *crtc_state,
+ enum intel_dsb_id dsb_id,
unsigned int max_cmds)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
@@ -486,7 +475,7 @@ struct intel_dsb *intel_dsb_prepare(const struct intel_crtc_state *crtc_state,
intel_runtime_pm_put(&i915->runtime_pm, wakeref);
- dsb->id = DSB1;
+ dsb->id = dsb_id;
dsb->crtc = crtc;
dsb->size = size / 4; /* in dwords */
dsb->free_pos = 0;
@@ -501,7 +490,7 @@ out_put_rpm:
out:
drm_info_once(&i915->drm,
"[CRTC:%d:%s] DSB %d queue setup failed, will fallback to MMIO for display HW programming\n",
- crtc->base.base.id, crtc->base.name, DSB1);
+ crtc->base.base.id, crtc->base.name, dsb_id);
return NULL;
}
diff --git a/drivers/gpu/drm/i915/display/intel_dsb.h b/drivers/gpu/drm/i915/display/intel_dsb.h
index 16d80f434356..36fdb130af6e 100644
--- a/drivers/gpu/drm/i915/display/intel_dsb.h
+++ b/drivers/gpu/drm/i915/display/intel_dsb.h
@@ -14,7 +14,16 @@ struct intel_crtc;
struct intel_crtc_state;
struct intel_dsb;
+enum intel_dsb_id {
+ INTEL_DSB_0,
+ INTEL_DSB_1,
+ INTEL_DSB_2,
+
+ I915_MAX_DSBS,
+};
+
struct intel_dsb *intel_dsb_prepare(const struct intel_crtc_state *crtc_state,
+ enum intel_dsb_id dsb_id,
unsigned int max_cmds);
void intel_dsb_finish(struct intel_dsb *dsb);
void intel_dsb_cleanup(struct intel_dsb *dsb);
diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
index a5d7fc8418c9..072ef1d62bda 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
@@ -353,14 +353,14 @@ static void icl_native_gpio_set_value(struct drm_i915_private *dev_priv,
case MIPI_AVDD_EN_2:
index = gpio == MIPI_AVDD_EN_1 ? 0 : 1;
- intel_de_rmw(dev_priv, PP_CONTROL(index), PANEL_POWER_ON,
+ intel_de_rmw(dev_priv, PP_CONTROL(dev_priv, index), PANEL_POWER_ON,
value ? PANEL_POWER_ON : 0);
break;
case MIPI_BKLT_EN_1:
case MIPI_BKLT_EN_2:
index = gpio == MIPI_BKLT_EN_1 ? 0 : 1;
- intel_de_rmw(dev_priv, PP_CONTROL(index), EDP_BLC_ENABLE,
+ intel_de_rmw(dev_priv, PP_CONTROL(dev_priv, index), EDP_BLC_ENABLE,
value ? EDP_BLC_ENABLE : 0);
break;
case MIPI_AVEE_EN_1:
@@ -751,7 +751,7 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id)
struct intel_connector *connector = intel_dsi->attached_connector;
struct mipi_config *mipi_config = connector->panel.vbt.dsi.config;
struct mipi_pps_data *pps = connector->panel.vbt.dsi.pps;
- struct drm_display_mode *mode = connector->panel.vbt.lfp_lvds_vbt_mode;
+ struct drm_display_mode *mode = connector->panel.vbt.lfp_vbt_mode;
u16 burst_mode_ratio;
enum port port;
diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c
index 1840f5b59229..091824334f26 100644
--- a/drivers/gpu/drm/i915/display/intel_dvo.c
+++ b/drivers/gpu/drm/i915/display/intel_dvo.c
@@ -456,13 +456,14 @@ static bool intel_dvo_init_dev(struct drm_i915_private *dev_priv,
* the device.
*/
for_each_pipe(dev_priv, pipe)
- dpll[pipe] = intel_de_rmw(dev_priv, DPLL(pipe), 0, DPLL_DVO_2X_MODE);
+ dpll[pipe] = intel_de_rmw(dev_priv, DPLL(dev_priv, pipe), 0,
+ DPLL_DVO_2X_MODE);
ret = dvo->dev_ops->init(&intel_dvo->dev, i2c);
/* restore the DVO 2x clock state to original */
for_each_pipe(dev_priv, pipe) {
- intel_de_write(dev_priv, DPLL(pipe), dpll[pipe]);
+ intel_de_write(dev_priv, DPLL(dev_priv, pipe), dpll[pipe]);
}
intel_gmbus_force_bit(i2c, false);
diff --git a/drivers/gpu/drm/i915/display/intel_encoder.c b/drivers/gpu/drm/i915/display/intel_encoder.c
new file mode 100644
index 000000000000..dee55f56960f
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_encoder.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#include <linux/workqueue.h>
+
+#include "i915_drv.h"
+
+#include "intel_display_types.h"
+#include "intel_encoder.h"
+
+static void intel_encoder_link_check_work_fn(struct work_struct *work)
+{
+ struct intel_encoder *encoder =
+ container_of(work, typeof(*encoder), link_check_work.work);
+
+ encoder->link_check(encoder);
+}
+
+void intel_encoder_link_check_init(struct intel_encoder *encoder,
+ void (*callback)(struct intel_encoder *encoder))
+{
+ INIT_DELAYED_WORK(&encoder->link_check_work, intel_encoder_link_check_work_fn);
+ encoder->link_check = callback;
+}
+
+void intel_encoder_link_check_flush_work(struct intel_encoder *encoder)
+{
+ cancel_delayed_work_sync(&encoder->link_check_work);
+}
+
+void intel_encoder_link_check_queue_work(struct intel_encoder *encoder, int delay_ms)
+{
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+
+ mod_delayed_work(i915->unordered_wq,
+ &encoder->link_check_work, msecs_to_jiffies(delay_ms));
+}
diff --git a/drivers/gpu/drm/i915/display/intel_encoder.h b/drivers/gpu/drm/i915/display/intel_encoder.h
new file mode 100644
index 000000000000..2cda054e2b15
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_encoder.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef __INTEL_ENCODER_H__
+#define __INTEL_ENCODER_H__
+
+struct intel_encoder;
+
+void intel_encoder_link_check_init(struct intel_encoder *encoder,
+ void (*callback)(struct intel_encoder *encoder));
+void intel_encoder_link_check_queue_work(struct intel_encoder *encoder, int delay_ms);
+void intel_encoder_link_check_flush_work(struct intel_encoder *encoder);
+
+#endif /* __INTEL_ENCODER_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c
index 86b443433e8b..8069abf91c5e 100644
--- a/drivers/gpu/drm/i915/display/intel_fb.c
+++ b/drivers/gpu/drm/i915/display/intel_fb.c
@@ -9,6 +9,7 @@
#include <linux/dma-fence.h>
#include <linux/dma-resv.h>
+#include "gem/i915_gem_object.h"
#include "i915_drv.h"
#include "intel_display.h"
#include "intel_display_types.h"
@@ -805,8 +806,23 @@ unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
{
struct drm_i915_private *dev_priv = to_i915(fb->dev);
- if (intel_fb_uses_dpt(fb))
+ if (intel_fb_uses_dpt(fb)) {
+ /* AUX_DIST needs only 4K alignment */
+ if (intel_fb_is_ccs_aux_plane(fb, color_plane))
+ return 512 * 4096;
+
+ /*
+ * FIXME ADL sees GGTT/DMAR faults with async
+ * flips unless we align to 16k at least.
+ * Figure out what's going on here...
+ */
+ if (IS_ALDERLAKE_P(dev_priv) &&
+ !intel_fb_is_ccs_modifier(fb->modifier) &&
+ HAS_ASYNC_FLIPS(dev_priv))
+ return 512 * 16 * 1024;
+
return 512 * 4096;
+ }
/* AUX_DIST needs only 4K alignment */
if (intel_fb_is_ccs_aux_plane(fb, color_plane))
@@ -1030,7 +1046,7 @@ static u32 intel_compute_aligned_offset(struct drm_i915_private *i915,
int color_plane,
unsigned int pitch,
unsigned int rotation,
- u32 alignment)
+ unsigned int alignment)
{
unsigned int cpp = fb->format->cpp[color_plane];
u32 offset, offset_aligned;
@@ -1087,8 +1103,8 @@ u32 intel_plane_compute_aligned_offset(int *x, int *y,
struct drm_i915_private *i915 = to_i915(intel_plane->base.dev);
const struct drm_framebuffer *fb = state->hw.fb;
unsigned int rotation = state->hw.rotation;
- int pitch = state->view.color_plane[color_plane].mapping_stride;
- u32 alignment;
+ unsigned int pitch = state->view.color_plane[color_plane].mapping_stride;
+ unsigned int alignment;
if (intel_plane->id == PLANE_CURSOR)
alignment = intel_cursor_alignment(i915);
@@ -1105,8 +1121,7 @@ static int intel_fb_offset_to_xy(int *x, int *y,
int color_plane)
{
struct drm_i915_private *i915 = to_i915(fb->dev);
- unsigned int height;
- u32 alignment, unused;
+ unsigned int height, alignment, unused;
if (DISPLAY_VER(i915) >= 12 &&
!intel_fb_needs_pot_stride_remap(to_intel_framebuffer(fb)) &&
@@ -1493,8 +1508,8 @@ static u32 calc_plane_remap_info(const struct intel_framebuffer *fb, int color_p
check_array_bounds(i915, view->gtt.remapped.plane, color_plane);
if (view->gtt.remapped.plane_alignment) {
- unsigned int aligned_offset = ALIGN(gtt_offset,
- view->gtt.remapped.plane_alignment);
+ u32 aligned_offset = ALIGN(gtt_offset,
+ view->gtt.remapped.plane_alignment);
size += aligned_offset - gtt_offset;
gtt_offset = aligned_offset;
@@ -1780,16 +1795,16 @@ u32 intel_fb_max_stride(struct drm_i915_private *dev_priv,
return 128 * 1024;
}
-static u32
+static unsigned int
intel_fb_stride_alignment(const struct drm_framebuffer *fb, int color_plane)
{
struct drm_i915_private *dev_priv = to_i915(fb->dev);
- u32 tile_width;
+ unsigned int tile_width;
if (is_surface_linear(fb, color_plane)) {
- u32 max_stride = intel_plane_fb_max_stride(dev_priv,
- fb->format->format,
- fb->modifier);
+ unsigned int max_stride = intel_plane_fb_max_stride(dev_priv,
+ fb->format->format,
+ fb->modifier);
/*
* To make remapping with linear generally feasible
@@ -2046,7 +2061,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
drm_helper_mode_fill_fb_struct(&dev_priv->drm, fb, mode_cmd);
for (i = 0; i < fb->format->num_planes; i++) {
- u32 stride_alignment;
+ unsigned int stride_alignment;
if (mode_cmd->handles[i] != mode_cmd->handles[0]) {
drm_dbg_kms(&dev_priv->drm, "bad plane %d handle\n",
@@ -2063,7 +2078,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
}
if (intel_fb_is_gen12_ccs_aux_plane(fb, i)) {
- int ccs_aux_stride = gen12_ccs_aux_stride(intel_fb, i);
+ unsigned int ccs_aux_stride = gen12_ccs_aux_stride(intel_fb, i);
if (fb->pitches[i] != ccs_aux_stride) {
drm_dbg_kms(&dev_priv->drm,
diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c b/drivers/gpu/drm/i915/display/intel_fb_pin.c
index b6df9baf481b..1acc11fa19f4 100644
--- a/drivers/gpu/drm/i915/display/intel_fb_pin.c
+++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c
@@ -11,24 +11,24 @@
#include "gem/i915_gem_object.h"
#include "i915_drv.h"
+#include "intel_atomic_plane.h"
#include "intel_display_types.h"
#include "intel_dpt.h"
#include "intel_fb.h"
#include "intel_fb_pin.h"
static struct i915_vma *
-intel_pin_fb_obj_dpt(struct drm_framebuffer *fb,
- const struct i915_gtt_view *view,
- bool uses_fence,
- unsigned long *out_flags,
- struct i915_address_space *vm)
+intel_fb_pin_to_dpt(const struct drm_framebuffer *fb,
+ const struct i915_gtt_view *view,
+ unsigned int alignment,
+ unsigned long *out_flags,
+ struct i915_address_space *vm)
{
struct drm_device *dev = fb->dev;
struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_i915_gem_object *obj = intel_fb_obj(fb);
struct i915_gem_ww_ctx ww;
struct i915_vma *vma;
- u32 alignment;
int ret;
/*
@@ -41,8 +41,6 @@ intel_pin_fb_obj_dpt(struct drm_framebuffer *fb,
if (WARN_ON(!i915_gem_object_is_framebuffer(obj)))
return ERR_PTR(-EINVAL);
- alignment = 4096 * 512;
-
atomic_inc(&dev_priv->gpu_error.pending_fb_pin);
for_i915_gem_ww(&ww, ret, true) {
@@ -104,20 +102,20 @@ err:
}
struct i915_vma *
-intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
- bool phys_cursor,
- const struct i915_gtt_view *view,
- bool uses_fence,
- unsigned long *out_flags)
+intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb,
+ bool phys_cursor,
+ const struct i915_gtt_view *view,
+ bool uses_fence,
+ unsigned long *out_flags)
{
struct drm_device *dev = fb->dev;
struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_i915_gem_object *obj = intel_fb_obj(fb);
intel_wakeref_t wakeref;
struct i915_gem_ww_ctx ww;
+ unsigned int alignment;
struct i915_vma *vma;
unsigned int pinctl;
- u32 alignment;
int ret;
if (drm_WARN_ON(dev, !i915_gem_object_is_framebuffer(obj)))
@@ -228,7 +226,7 @@ err:
return vma;
}
-void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags)
+void intel_fb_unpin_vma(struct i915_vma *vma, unsigned long flags)
{
if (flags & PLANE_HAS_FENCE)
i915_vma_unpin_fence(vma);
@@ -239,18 +237,15 @@ void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags)
int intel_plane_pin_fb(struct intel_plane_state *plane_state)
{
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
- struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
- struct drm_framebuffer *fb = plane_state->hw.fb;
+ const struct intel_framebuffer *fb =
+ to_intel_framebuffer(plane_state->hw.fb);
struct i915_vma *vma;
- bool phys_cursor =
- plane->id == PLANE_CURSOR &&
- DISPLAY_INFO(dev_priv)->cursor_needs_physical;
-
- if (!intel_fb_uses_dpt(fb)) {
- vma = intel_pin_and_fence_fb_obj(fb, phys_cursor,
- &plane_state->view.gtt,
- intel_plane_uses_fence(plane_state),
- &plane_state->flags);
+
+ if (!intel_fb_uses_dpt(&fb->base)) {
+ vma = intel_fb_pin_to_ggtt(&fb->base, intel_plane_needs_physical(plane),
+ &plane_state->view.gtt,
+ intel_plane_uses_fence(plane_state),
+ &plane_state->flags);
if (IS_ERR(vma))
return PTR_ERR(vma);
@@ -262,22 +257,23 @@ int intel_plane_pin_fb(struct intel_plane_state *plane_state)
* will trigger might_sleep() even if it won't actually sleep,
* which is the case when the fb has already been pinned.
*/
- if (phys_cursor)
+ if (intel_plane_needs_physical(plane))
plane_state->phys_dma_addr =
- i915_gem_object_get_dma_address(intel_fb_obj(fb), 0);
+ i915_gem_object_get_dma_address(intel_fb_obj(&fb->base), 0);
} else {
- struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
+ unsigned int alignment = intel_surf_alignment(&fb->base, 0);
- vma = intel_dpt_pin(intel_fb->dpt_vm);
+ vma = intel_dpt_pin_to_ggtt(fb->dpt_vm, alignment / 512);
if (IS_ERR(vma))
return PTR_ERR(vma);
plane_state->ggtt_vma = vma;
- vma = intel_pin_fb_obj_dpt(fb, &plane_state->view.gtt, false,
- &plane_state->flags, intel_fb->dpt_vm);
+ vma = intel_fb_pin_to_dpt(&fb->base, &plane_state->view.gtt,
+ alignment, &plane_state->flags,
+ fb->dpt_vm);
if (IS_ERR(vma)) {
- intel_dpt_unpin(intel_fb->dpt_vm);
+ intel_dpt_unpin_from_ggtt(fb->dpt_vm);
plane_state->ggtt_vma = NULL;
return PTR_ERR(vma);
}
@@ -292,22 +288,21 @@ int intel_plane_pin_fb(struct intel_plane_state *plane_state)
void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state)
{
- struct drm_framebuffer *fb = old_plane_state->hw.fb;
+ const struct intel_framebuffer *fb =
+ to_intel_framebuffer(old_plane_state->hw.fb);
struct i915_vma *vma;
- if (!intel_fb_uses_dpt(fb)) {
+ if (!intel_fb_uses_dpt(&fb->base)) {
vma = fetch_and_zero(&old_plane_state->ggtt_vma);
if (vma)
- intel_unpin_fb_vma(vma, old_plane_state->flags);
+ intel_fb_unpin_vma(vma, old_plane_state->flags);
} else {
- struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
-
vma = fetch_and_zero(&old_plane_state->dpt_vma);
if (vma)
- intel_unpin_fb_vma(vma, old_plane_state->flags);
+ intel_fb_unpin_vma(vma, old_plane_state->flags);
vma = fetch_and_zero(&old_plane_state->ggtt_vma);
if (vma)
- intel_dpt_unpin(intel_fb->dpt_vm);
+ intel_dpt_unpin_from_ggtt(fb->dpt_vm);
}
}
diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.h b/drivers/gpu/drm/i915/display/intel_fb_pin.h
index de0efaa25905..3f8245edcd15 100644
--- a/drivers/gpu/drm/i915/display/intel_fb_pin.h
+++ b/drivers/gpu/drm/i915/display/intel_fb_pin.h
@@ -14,13 +14,13 @@ struct intel_plane_state;
struct i915_gtt_view;
struct i915_vma *
-intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
- bool phys_cursor,
- const struct i915_gtt_view *view,
- bool uses_fence,
- unsigned long *out_flags);
+intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb,
+ bool phys_cursor,
+ const struct i915_gtt_view *view,
+ bool uses_fence,
+ unsigned long *out_flags);
-void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags);
+void intel_fb_unpin_vma(struct i915_vma *vma, unsigned long flags);
int intel_plane_pin_fb(struct intel_plane_state *plane_state);
void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state);
diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c
index 151dcd0c45b6..67116c9f1464 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.c
+++ b/drivers/gpu/drm/i915/display/intel_fbc.c
@@ -43,11 +43,14 @@
#include <drm/drm_blend.h>
#include <drm/drm_fourcc.h>
+#include "gem/i915_gem_stolen.h"
+#include "gt/intel_gt_types.h"
#include "i915_drv.h"
#include "i915_reg.h"
#include "i915_utils.h"
#include "i915_vgpu.h"
#include "i915_vma.h"
+#include "i9xx_plane_regs.h"
#include "intel_cdclk.h"
#include "intel_de.h"
#include "intel_display_device.h"
@@ -326,8 +329,8 @@ static void i8xx_fbc_nuke(struct intel_fbc *fbc)
enum i9xx_plane_id i9xx_plane = fbc_state->plane->i9xx_plane;
struct drm_i915_private *dev_priv = fbc->i915;
- intel_de_write_fw(dev_priv, DSPADDR(i9xx_plane),
- intel_de_read_fw(dev_priv, DSPADDR(i9xx_plane)));
+ intel_de_write_fw(dev_priv, DSPADDR(dev_priv, i9xx_plane),
+ intel_de_read_fw(dev_priv, DSPADDR(dev_priv, i9xx_plane)));
}
static void i8xx_fbc_program_cfb(struct intel_fbc *fbc)
@@ -363,8 +366,8 @@ static void i965_fbc_nuke(struct intel_fbc *fbc)
enum i9xx_plane_id i9xx_plane = fbc_state->plane->i9xx_plane;
struct drm_i915_private *dev_priv = fbc->i915;
- intel_de_write_fw(dev_priv, DSPSURF(i9xx_plane),
- intel_de_read_fw(dev_priv, DSPSURF(i9xx_plane)));
+ intel_de_write_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane),
+ intel_de_read_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane)));
}
static const struct intel_fbc_funcs i965_fbc_funcs = {
@@ -1234,6 +1237,12 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state,
return 0;
}
+ /* WaFbcTurnOffFbcWhenHyperVisorIsUsed:skl,bxt */
+ if (i915_vtd_active(i915) && (IS_SKYLAKE(i915) || IS_BROXTON(i915))) {
+ plane_state->no_fbc_reason = "VT-d enabled";
+ return 0;
+ }
+
crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
@@ -1251,7 +1260,8 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state,
* Recommendation is to keep this combination disabled
* Bspec: 50422 HSD: 14010260002
*/
- if (IS_DISPLAY_VER(i915, 12, 14) && crtc_state->has_psr2) {
+ if (IS_DISPLAY_VER(i915, 12, 14) && crtc_state->has_sel_update &&
+ !crtc_state->has_panel_replay) {
plane_state->no_fbc_reason = "PSR2 enabled";
return 0;
}
@@ -1259,7 +1269,7 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state,
/* Wa_14016291713 */
if ((IS_DISPLAY_VER(i915, 12, 13) ||
IS_DISPLAY_IP_STEP(i915, IP_VER(14, 0), STEP_A0, STEP_C0)) &&
- crtc_state->has_psr) {
+ crtc_state->has_psr && !crtc_state->has_panel_replay) {
plane_state->no_fbc_reason = "PSR1 enabled (Wa_14016291713)";
return 0;
}
@@ -1818,19 +1828,6 @@ static int intel_sanitize_fbc_option(struct drm_i915_private *i915)
return 0;
}
-static bool need_fbc_vtd_wa(struct drm_i915_private *i915)
-{
- /* WaFbcTurnOffFbcWhenHyperVisorIsUsed:skl,bxt */
- if (i915_vtd_active(i915) &&
- (IS_SKYLAKE(i915) || IS_BROXTON(i915))) {
- drm_info(&i915->drm,
- "Disabling framebuffer compression (FBC) to prevent screen flicker with VT-d enabled\n");
- return true;
- }
-
- return false;
-}
-
void intel_fbc_add_plane(struct intel_fbc *fbc, struct intel_plane *plane)
{
plane->fbc = fbc;
@@ -1876,9 +1873,6 @@ void intel_fbc_init(struct drm_i915_private *i915)
{
enum intel_fbc_id fbc_id;
- if (need_fbc_vtd_wa(i915))
- DISPLAY_RUNTIME_INFO(i915)->fbc_mask = 0;
-
i915->display.params.enable_fbc = intel_sanitize_fbc_option(i915);
drm_dbg_kms(&i915->drm, "Sanitized enable_fbc value: %d\n",
i915->display.params.enable_fbc);
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c
index bda702c2cab8..37ae176bfeb0 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
@@ -44,6 +44,7 @@
#include <drm/drm_gem_framebuffer_helper.h>
#include "gem/i915_gem_mman.h"
+#include "gem/i915_gem_object.h"
#include "i915_drv.h"
#include "intel_display_types.h"
@@ -146,7 +147,7 @@ static void intel_fbdev_fb_destroy(struct fb_info *info)
* the info->screen_base mmaping. Leaking the VMA is simpler than
* trying to rectify all the possible error paths leading here.
*/
- intel_unpin_fb_vma(ifbdev->vma, ifbdev->vma_flags);
+ intel_fb_unpin_vma(ifbdev->vma, ifbdev->vma_flags);
drm_framebuffer_remove(&ifbdev->fb->base);
drm_client_release(&fb_helper->client);
@@ -175,7 +176,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes)
{
struct intel_fbdev *ifbdev = to_intel_fbdev(helper);
- struct intel_framebuffer *intel_fb = ifbdev->fb;
+ struct intel_framebuffer *fb = ifbdev->fb;
struct drm_device *dev = helper->dev;
struct drm_i915_private *dev_priv = to_i915(dev);
const struct i915_gtt_view view = {
@@ -195,30 +196,30 @@ static int intelfb_create(struct drm_fb_helper *helper,
if (ret)
return ret;
- if (intel_fb &&
- (sizes->fb_width > intel_fb->base.width ||
- sizes->fb_height > intel_fb->base.height)) {
+ ifbdev->fb = NULL;
+
+ if (fb &&
+ (sizes->fb_width > fb->base.width ||
+ sizes->fb_height > fb->base.height)) {
drm_dbg_kms(&dev_priv->drm,
"BIOS fb too small (%dx%d), we require (%dx%d),"
" releasing it\n",
- intel_fb->base.width, intel_fb->base.height,
+ fb->base.width, fb->base.height,
sizes->fb_width, sizes->fb_height);
- drm_framebuffer_put(&intel_fb->base);
- intel_fb = ifbdev->fb = NULL;
+ drm_framebuffer_put(&fb->base);
+ fb = NULL;
}
- if (!intel_fb || drm_WARN_ON(dev, !intel_fb_obj(&intel_fb->base))) {
- struct drm_framebuffer *fb;
+ if (!fb || drm_WARN_ON(dev, !intel_fb_obj(&fb->base))) {
drm_dbg_kms(&dev_priv->drm,
"no BIOS fb, allocating a new one\n");
fb = intel_fbdev_fb_alloc(helper, sizes);
if (IS_ERR(fb))
return PTR_ERR(fb);
- intel_fb = ifbdev->fb = to_intel_framebuffer(fb);
} else {
drm_dbg_kms(&dev_priv->drm, "re-using BIOS fb\n");
prealloc = true;
- sizes->fb_width = intel_fb->base.width;
- sizes->fb_height = intel_fb->base.height;
+ sizes->fb_width = fb->base.width;
+ sizes->fb_height = fb->base.height;
}
wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
@@ -227,8 +228,8 @@ static int intelfb_create(struct drm_fb_helper *helper,
* This also validates that any existing fb inherited from the
* BIOS is suitable for own access.
*/
- vma = intel_pin_and_fence_fb_obj(&ifbdev->fb->base, false,
- &view, false, &flags);
+ vma = intel_fb_pin_to_ggtt(&fb->base, false,
+ &view, false, &flags);
if (IS_ERR(vma)) {
ret = PTR_ERR(vma);
goto out_unlock;
@@ -241,11 +242,11 @@ static int intelfb_create(struct drm_fb_helper *helper,
goto out_unpin;
}
- ifbdev->helper.fb = &ifbdev->fb->base;
+ ifbdev->helper.fb = &fb->base;
info->fbops = &intelfb_ops;
- obj = intel_fb_obj(&intel_fb->base);
+ obj = intel_fb_obj(&fb->base);
ret = intel_fbdev_fb_fill_info(dev_priv, info, obj, vma);
if (ret)
@@ -263,8 +264,9 @@ static int intelfb_create(struct drm_fb_helper *helper,
/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
drm_dbg_kms(&dev_priv->drm, "allocated %dx%d fb: 0x%08x\n",
- ifbdev->fb->base.width, ifbdev->fb->base.height,
+ fb->base.width, fb->base.height,
i915_ggtt_offset(vma));
+ ifbdev->fb = fb;
ifbdev->vma = vma;
ifbdev->vma_flags = flags;
@@ -273,7 +275,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
return 0;
out_unpin:
- intel_unpin_fb_vma(vma, flags);
+ intel_fb_unpin_vma(vma, flags);
out_unlock:
intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
return ret;
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev_fb.c b/drivers/gpu/drm/i915/display/intel_fbdev_fb.c
index 0665f943f65f..497525ef9668 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev_fb.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev_fb.c
@@ -11,8 +11,8 @@
#include "intel_display_types.h"
#include "intel_fbdev_fb.h"
-struct drm_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper,
- struct drm_fb_helper_surface_size *sizes)
+struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper,
+ struct drm_fb_helper_surface_size *sizes)
{
struct drm_framebuffer *fb;
struct drm_device *dev = helper->dev;
@@ -63,7 +63,7 @@ struct drm_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper,
fb = intel_framebuffer_create(obj, &mode_cmd);
i915_gem_object_put(obj);
- return fb;
+ return to_intel_framebuffer(fb);
}
int intel_fbdev_fb_fill_info(struct drm_i915_private *i915, struct fb_info *info,
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev_fb.h b/drivers/gpu/drm/i915/display/intel_fbdev_fb.h
index a395b2c65d33..4832fe688fbf 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev_fb.h
+++ b/drivers/gpu/drm/i915/display/intel_fbdev_fb.h
@@ -13,8 +13,8 @@ struct drm_i915_private;
struct fb_info;
struct i915_vma;
-struct drm_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper,
- struct drm_fb_helper_surface_size *sizes);
+struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper,
+ struct drm_fb_helper_surface_size *sizes);
int intel_fbdev_fb_fill_info(struct drm_i915_private *i915, struct fb_info *info,
struct drm_i915_gem_object *obj, struct i915_vma *vma);
diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c
index 295a0f24ebbf..d33befd7994d 100644
--- a/drivers/gpu/drm/i915/display/intel_fdi.c
+++ b/drivers/gpu/drm/i915/display/intel_fdi.c
@@ -34,7 +34,8 @@ static void assert_fdi_tx(struct drm_i915_private *dev_priv,
* so pipe->transcoder cast is fine here.
*/
enum transcoder cpu_transcoder = (enum transcoder)pipe;
- cur_state = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder)) & TRANS_DDI_FUNC_ENABLE;
+ cur_state = intel_de_read(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder)) & TRANS_DDI_FUNC_ENABLE;
} else {
cur_state = intel_de_read(dev_priv, FDI_TX_CTL(pipe)) & FDI_TX_ENABLE;
}
@@ -514,7 +515,7 @@ static void ilk_fdi_link_train(struct intel_crtc *crtc,
* detection works.
*/
intel_de_write(dev_priv, FDI_RX_TUSIZE1(pipe),
- intel_de_read(dev_priv, PIPE_DATA_M1(pipe)) & TU_SIZE_MASK);
+ intel_de_read(dev_priv, PIPE_DATA_M1(dev_priv, pipe)) & TU_SIZE_MASK);
/* FDI needs bits from pipe first */
assert_transcoder_enabled(dev_priv, crtc_state->cpu_transcoder);
@@ -616,7 +617,7 @@ static void gen6_fdi_link_train(struct intel_crtc *crtc,
* detection works.
*/
intel_de_write(dev_priv, FDI_RX_TUSIZE1(pipe),
- intel_de_read(dev_priv, PIPE_DATA_M1(pipe)) & TU_SIZE_MASK);
+ intel_de_read(dev_priv, PIPE_DATA_M1(dev_priv, pipe)) & TU_SIZE_MASK);
/* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
for train result */
@@ -754,7 +755,7 @@ static void ivb_manual_fdi_link_train(struct intel_crtc *crtc,
* detection works.
*/
intel_de_write(dev_priv, FDI_RX_TUSIZE1(pipe),
- intel_de_read(dev_priv, PIPE_DATA_M1(pipe)) & TU_SIZE_MASK);
+ intel_de_read(dev_priv, PIPE_DATA_M1(dev_priv, pipe)) & TU_SIZE_MASK);
/* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
for train result */
@@ -1034,7 +1035,7 @@ void ilk_fdi_pll_enable(const struct intel_crtc_state *crtc_state)
temp = intel_de_read(dev_priv, reg);
temp &= ~(FDI_DP_PORT_WIDTH_MASK | (0x7 << 16));
temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
- temp |= (intel_de_read(dev_priv, TRANSCONF(pipe)) & TRANSCONF_BPC_MASK) << 11;
+ temp |= (intel_de_read(dev_priv, TRANSCONF(dev_priv, pipe)) & TRANSCONF_BPC_MASK) << 11;
intel_de_write(dev_priv, reg, temp | FDI_RX_PLL_ENABLE);
intel_de_posting_read(dev_priv, reg);
@@ -1090,7 +1091,7 @@ void ilk_fdi_disable(struct intel_crtc *crtc)
reg = FDI_RX_CTL(pipe);
temp = intel_de_read(dev_priv, reg);
temp &= ~(0x7 << 16);
- temp |= (intel_de_read(dev_priv, TRANSCONF(pipe)) & TRANSCONF_BPC_MASK) << 11;
+ temp |= (intel_de_read(dev_priv, TRANSCONF(dev_priv, pipe)) & TRANSCONF_BPC_MASK) << 11;
intel_de_write(dev_priv, reg, temp & ~FDI_RX_ENABLE);
intel_de_posting_read(dev_priv, reg);
@@ -1116,7 +1117,7 @@ void ilk_fdi_disable(struct intel_crtc *crtc)
}
/* BPC in FDI rx is consistent with that in TRANSCONF */
temp &= ~(0x07 << 16);
- temp |= (intel_de_read(dev_priv, TRANSCONF(pipe)) & TRANSCONF_BPC_MASK) << 11;
+ temp |= (intel_de_read(dev_priv, TRANSCONF(dev_priv, pipe)) & TRANSCONF_BPC_MASK) << 11;
intel_de_write(dev_priv, reg, temp);
intel_de_posting_read(dev_priv, reg);
diff --git a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
index 09a7fa6c0c37..e5e4ca7cc499 100644
--- a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
+++ b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c
@@ -94,7 +94,7 @@ static bool cpt_can_enable_serr_int(struct drm_device *dev)
static void i9xx_check_fifo_underruns(struct intel_crtc *crtc)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
- i915_reg_t reg = PIPESTAT(crtc->pipe);
+ i915_reg_t reg = PIPESTAT(dev_priv, crtc->pipe);
u32 enable_mask;
lockdep_assert_held(&dev_priv->irq_lock);
@@ -115,7 +115,7 @@ static void i9xx_set_fifo_underrun_reporting(struct drm_device *dev,
bool enable, bool old)
{
struct drm_i915_private *dev_priv = to_i915(dev);
- i915_reg_t reg = PIPESTAT(pipe);
+ i915_reg_t reg = PIPESTAT(dev_priv, pipe);
lockdep_assert_held(&dev_priv->irq_lock);
@@ -209,7 +209,8 @@ static void bdw_set_fifo_underrun_reporting(struct drm_device *dev,
if (enable) {
if (DISPLAY_VER(dev_priv) >= 11)
- intel_de_write(dev_priv, ICL_PIPESTATUS(pipe),
+ intel_de_write(dev_priv,
+ ICL_PIPESTATUS(dev_priv, pipe),
icl_pipe_status_underrun_mask(dev_priv));
bdw_enable_pipe_irq(dev_priv, pipe, mask);
@@ -418,9 +419,11 @@ void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
* the underrun was caused by the downstream port.
*/
if (DISPLAY_VER(dev_priv) >= 11) {
- underruns = intel_de_read(dev_priv, ICL_PIPESTATUS(pipe)) &
+ underruns = intel_de_read(dev_priv,
+ ICL_PIPESTATUS(dev_priv, pipe)) &
icl_pipe_status_underrun_mask(dev_priv);
- intel_de_write(dev_priv, ICL_PIPESTATUS(pipe), underruns);
+ intel_de_write(dev_priv, ICL_PIPESTATUS(dev_priv, pipe),
+ underruns);
}
if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false)) {
diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
index 2ea37c0414a9..4923c340a0b6 100644
--- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c
+++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
@@ -65,6 +65,7 @@
#include "intel_fbc.h"
#include "intel_frontbuffer.h"
#include "intel_psr.h"
+#include "intel_tdf.h"
/**
* frontbuffer_flush - flush frontbuffer
@@ -93,6 +94,7 @@ static void frontbuffer_flush(struct drm_i915_private *i915,
trace_intel_frontbuffer_flush(i915, frontbuffer_bits, origin);
might_sleep();
+ intel_td_flush(i915);
intel_drrs_flush(i915, frontbuffer_bits);
intel_psr_flush(i915, frontbuffer_bits, origin);
intel_fbc_flush(i915, frontbuffer_bits, origin);
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index d5ed4c7dfbc0..3ebe035f382e 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -13,7 +13,7 @@
#include <linux/random.h>
#include <drm/display/drm_hdcp_helper.h>
-#include <drm/i915_component.h>
+#include <drm/intel/i915_component.h>
#include "i915_drv.h"
#include "i915_reg.h"
@@ -30,6 +30,29 @@
#define KEY_LOAD_TRIES 5
#define HDCP2_LC_RETRY_CNT 3
+/* WA: 16022217614 */
+static void
+intel_hdcp_disable_hdcp_line_rekeying(struct intel_encoder *encoder,
+ struct intel_hdcp *hdcp)
+{
+ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+
+ /* Here we assume HDMI is in TMDS mode of operation */
+ if (encoder->type != INTEL_OUTPUT_HDMI)
+ return;
+
+ if (DISPLAY_VER(dev_priv) >= 14) {
+ if (IS_DISPLAY_IP_STEP(dev_priv, IP_VER(14, 0), STEP_D0, STEP_FOREVER))
+ intel_de_rmw(dev_priv, MTL_CHICKEN_TRANS(hdcp->cpu_transcoder),
+ 0, HDCP_LINE_REKEY_DISABLE);
+ else if (IS_DISPLAY_IP_STEP(dev_priv, IP_VER(14, 1), STEP_B0, STEP_FOREVER) ||
+ IS_DISPLAY_IP_STEP(dev_priv, IP_VER(20, 0), STEP_B0, STEP_FOREVER))
+ intel_de_rmw(dev_priv,
+ TRANS_DDI_FUNC_CTL(dev_priv, hdcp->cpu_transcoder),
+ 0, TRANS_DDI_HDCP_LINE_REKEY_DISABLE);
+ }
+}
+
static int intel_conn_to_vcpi(struct intel_atomic_state *state,
struct intel_connector *connector)
{
@@ -2005,6 +2028,8 @@ static int _intel_hdcp2_enable(struct intel_atomic_state *state,
connector->base.base.id, connector->base.name,
hdcp->content_type);
+ intel_hdcp_disable_hdcp_line_rekeying(connector->encoder, hdcp);
+
ret = hdcp2_authenticate_and_encrypt(state, connector);
if (ret) {
drm_dbg_kms(&i915->drm, "HDCP2 Type%d Enabling Failed. (%d)\n",
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c
index 35823e1f65d6..16afeb8a3a8d 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c
@@ -3,7 +3,7 @@
* Copyright 2023, Intel Corporation.
*/
-#include <drm/i915_hdcp_interface.h>
+#include <drm/intel/i915_hdcp_interface.h>
#include "gem/i915_gem_region.h"
#include "gt/intel_gt.h"
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c b/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c
index 240b00849f3d..6548e71b4c49 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c
@@ -4,7 +4,7 @@
*/
#include <linux/err.h>
-#include <drm/i915_hdcp_interface.h>
+#include <drm/intel/i915_hdcp_interface.h>
#include "i915_drv.h"
#include "intel_hdcp_gsc_message.h"
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 5f6deceaf8ba..19498ee455fa 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -38,7 +38,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
-#include <drm/intel_lpe_audio.h>
+#include <drm/intel/intel_lpe_audio.h>
#include "g4x_hdmi.h"
#include "i915_drv.h"
@@ -83,7 +83,7 @@ assert_hdmi_transcoder_func_disabled(struct drm_i915_private *dev_priv,
enum transcoder cpu_transcoder)
{
drm_WARN(&dev_priv->drm,
- intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder)) &
+ intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder)) &
TRANS_DDI_FUNC_ENABLE,
"HDMI transcoder function enabled, expecting disabled\n");
}
@@ -165,21 +165,21 @@ hsw_dip_data_reg(struct drm_i915_private *dev_priv,
{
switch (type) {
case HDMI_PACKET_TYPE_GAMUT_METADATA:
- return HSW_TVIDEO_DIP_GMP_DATA(cpu_transcoder, i);
+ return HSW_TVIDEO_DIP_GMP_DATA(dev_priv, cpu_transcoder, i);
case DP_SDP_VSC:
- return HSW_TVIDEO_DIP_VSC_DATA(cpu_transcoder, i);
+ return HSW_TVIDEO_DIP_VSC_DATA(dev_priv, cpu_transcoder, i);
case DP_SDP_ADAPTIVE_SYNC:
- return ADL_TVIDEO_DIP_AS_SDP_DATA(cpu_transcoder, i);
+ return ADL_TVIDEO_DIP_AS_SDP_DATA(dev_priv, cpu_transcoder, i);
case DP_SDP_PPS:
- return ICL_VIDEO_DIP_PPS_DATA(cpu_transcoder, i);
+ return ICL_VIDEO_DIP_PPS_DATA(dev_priv, cpu_transcoder, i);
case HDMI_INFOFRAME_TYPE_AVI:
- return HSW_TVIDEO_DIP_AVI_DATA(cpu_transcoder, i);
+ return HSW_TVIDEO_DIP_AVI_DATA(dev_priv, cpu_transcoder, i);
case HDMI_INFOFRAME_TYPE_SPD:
- return HSW_TVIDEO_DIP_SPD_DATA(cpu_transcoder, i);
+ return HSW_TVIDEO_DIP_SPD_DATA(dev_priv, cpu_transcoder, i);
case HDMI_INFOFRAME_TYPE_VENDOR:
- return HSW_TVIDEO_DIP_VS_DATA(cpu_transcoder, i);
+ return HSW_TVIDEO_DIP_VS_DATA(dev_priv, cpu_transcoder, i);
case HDMI_INFOFRAME_TYPE_DRM:
- return GLK_TVIDEO_DIP_DRM_DATA(cpu_transcoder, i);
+ return GLK_TVIDEO_DIP_DRM_DATA(dev_priv, cpu_transcoder, i);
default:
MISSING_CASE(type);
return INVALID_MMIO_REG;
@@ -507,7 +507,7 @@ void hsw_write_infoframe(struct intel_encoder *encoder,
const u32 *data = frame;
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
- i915_reg_t ctl_reg = HSW_TVIDEO_DIP_CTL(cpu_transcoder);
+ i915_reg_t ctl_reg = HSW_TVIDEO_DIP_CTL(dev_priv, cpu_transcoder);
int data_size;
int i;
u32 val = intel_de_read(dev_priv, ctl_reg);
@@ -532,7 +532,8 @@ void hsw_write_infoframe(struct intel_encoder *encoder,
0);
/* Wa_14013475917 */
- if (!(IS_DISPLAY_VER(dev_priv, 13, 14) && crtc_state->has_psr && type == DP_SDP_VSC))
+ if (!(IS_DISPLAY_VER(dev_priv, 13, 14) && crtc_state->has_psr &&
+ !crtc_state->has_panel_replay && type == DP_SDP_VSC))
val |= hsw_infoframe_enable(type);
if (type == DP_SDP_VSC)
@@ -561,7 +562,7 @@ static u32 hsw_infoframes_enabled(struct intel_encoder *encoder,
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
u32 val = intel_de_read(dev_priv,
- HSW_TVIDEO_DIP_CTL(pipe_config->cpu_transcoder));
+ HSW_TVIDEO_DIP_CTL(dev_priv, pipe_config->cpu_transcoder));
u32 mask;
mask = (VIDEO_DIP_ENABLE_VSC_HSW | VIDEO_DIP_ENABLE_AVI_HSW |
@@ -985,7 +986,7 @@ static bool intel_hdmi_set_gcp_infoframe(struct intel_encoder *encoder,
return false;
if (HAS_DDI(dev_priv))
- reg = HSW_TVIDEO_DIP_GCP(crtc_state->cpu_transcoder);
+ reg = HSW_TVIDEO_DIP_GCP(dev_priv, crtc_state->cpu_transcoder);
else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
reg = VLV_TVIDEO_DIP_GCP(crtc->pipe);
else if (HAS_PCH_SPLIT(dev_priv))
@@ -1010,7 +1011,7 @@ void intel_hdmi_read_gcp_infoframe(struct intel_encoder *encoder,
return;
if (HAS_DDI(dev_priv))
- reg = HSW_TVIDEO_DIP_GCP(crtc_state->cpu_transcoder);
+ reg = HSW_TVIDEO_DIP_GCP(dev_priv, crtc_state->cpu_transcoder);
else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
reg = VLV_TVIDEO_DIP_GCP(crtc->pipe);
else if (HAS_PCH_SPLIT(dev_priv))
@@ -1215,7 +1216,8 @@ static void hsw_set_infoframes(struct intel_encoder *encoder,
const struct drm_connector_state *conn_state)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- i915_reg_t reg = HSW_TVIDEO_DIP_CTL(crtc_state->cpu_transcoder);
+ i915_reg_t reg = HSW_TVIDEO_DIP_CTL(dev_priv,
+ crtc_state->cpu_transcoder);
u32 val = intel_de_read(dev_priv, reg);
assert_hdmi_transcoder_func_disabled(dev_priv,
@@ -1474,7 +1476,8 @@ static int kbl_repositioning_enc_en_signal(struct intel_connector *connector,
int ret;
for (;;) {
- scanline = intel_de_read(dev_priv, PIPEDSL(crtc->pipe));
+ scanline = intel_de_read(dev_priv,
+ PIPEDSL(dev_priv, crtc->pipe));
if (scanline > 100 && scanline < 200)
break;
usleep_range(25, 50);
@@ -1783,7 +1786,9 @@ static int intel_hdmi_source_max_tmds_clock(struct intel_encoder *encoder)
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
int max_tmds_clock, vbt_max_tmds_clock;
- if (DISPLAY_VER(dev_priv) >= 10)
+ if (DISPLAY_VER(dev_priv) >= 13 || IS_ALDERLAKE_S(dev_priv))
+ max_tmds_clock = 600000;
+ else if (DISPLAY_VER(dev_priv) >= 10)
max_tmds_clock = 594000;
else if (DISPLAY_VER(dev_priv) >= 8 || IS_HASWELL(dev_priv))
max_tmds_clock = 300000;
diff --git a/drivers/gpu/drm/i915/display/intel_hotplug_irq.c b/drivers/gpu/drm/i915/display/intel_hotplug_irq.c
index d270bb7b9462..a1f07ee69a86 100644
--- a/drivers/gpu/drm/i915/display/intel_hotplug_irq.c
+++ b/drivers/gpu/drm/i915/display/intel_hotplug_irq.c
@@ -186,7 +186,8 @@ void i915_hotplug_interrupt_update_locked(struct drm_i915_private *dev_priv,
lockdep_assert_held(&dev_priv->irq_lock);
drm_WARN_ON(&dev_priv->drm, bits & ~mask);
- intel_uncore_rmw(&dev_priv->uncore, PORT_HOTPLUG_EN, mask, bits);
+ intel_uncore_rmw(&dev_priv->uncore, PORT_HOTPLUG_EN(dev_priv), mask,
+ bits);
}
/**
@@ -434,18 +435,21 @@ u32 i9xx_hpd_irq_ack(struct drm_i915_private *dev_priv)
* bits can itself generate a new hotplug interrupt :(
*/
for (i = 0; i < 10; i++) {
- u32 tmp = intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_STAT) & hotplug_status_mask;
+ u32 tmp = intel_uncore_read(&dev_priv->uncore,
+ PORT_HOTPLUG_STAT(dev_priv)) & hotplug_status_mask;
if (tmp == 0)
return hotplug_status;
hotplug_status |= tmp;
- intel_uncore_write(&dev_priv->uncore, PORT_HOTPLUG_STAT, hotplug_status);
+ intel_uncore_write(&dev_priv->uncore,
+ PORT_HOTPLUG_STAT(dev_priv),
+ hotplug_status);
}
drm_WARN_ONCE(&dev_priv->drm, 1,
"PORT_HOTPLUG_STAT did not clear (0x%08x)\n",
- intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_STAT));
+ intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_STAT(dev_priv)));
return hotplug_status;
}
diff --git a/drivers/gpu/drm/i915/display/intel_lpe_audio.c b/drivers/gpu/drm/i915/display/intel_lpe_audio.c
index 93e6cac9a4ed..f11626176fe2 100644
--- a/drivers/gpu/drm/i915/display/intel_lpe_audio.c
+++ b/drivers/gpu/drm/i915/display/intel_lpe_audio.c
@@ -68,7 +68,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
-#include <drm/intel_lpe_audio.h>
+#include <drm/intel/intel_lpe_audio.h>
#include "i915_drv.h"
#include "i915_irq.h"
diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c
index 1d048fa98561..8b26354d6e53 100644
--- a/drivers/gpu/drm/i915/display/intel_lspcon.c
+++ b/drivers/gpu/drm/i915/display/intel_lspcon.c
@@ -641,7 +641,7 @@ u32 lspcon_infoframes_enabled(struct intel_encoder *encoder,
if (lspcon->hdr_supported) {
tmp = intel_de_read(dev_priv,
- HSW_TVIDEO_DIP_CTL(pipe_config->cpu_transcoder));
+ HSW_TVIDEO_DIP_CTL(dev_priv, pipe_config->cpu_transcoder));
mask = VIDEO_DIP_ENABLE_GMP_HSW;
if (tmp & mask)
diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c
index 8b8959073466..9f018503d4fd 100644
--- a/drivers/gpu/drm/i915/display/intel_lvds.c
+++ b/drivers/gpu/drm/i915/display/intel_lvds.c
@@ -148,7 +148,7 @@ static void intel_lvds_get_config(struct intel_encoder *encoder,
/* gen2/3 store dither state in pfit control, needs to match */
if (DISPLAY_VER(dev_priv) < 4) {
- tmp = intel_de_read(dev_priv, PFIT_CONTROL);
+ tmp = intel_de_read(dev_priv, PFIT_CONTROL(dev_priv));
crtc_state->gmch_pfit.control |= tmp & PFIT_PANEL_8TO6_DITHER_ENABLE;
}
@@ -161,18 +161,19 @@ static void intel_lvds_pps_get_hw_state(struct drm_i915_private *dev_priv,
{
u32 val;
- pps->powerdown_on_reset = intel_de_read(dev_priv, PP_CONTROL(0)) & PANEL_POWER_RESET;
+ pps->powerdown_on_reset = intel_de_read(dev_priv,
+ PP_CONTROL(dev_priv, 0)) & PANEL_POWER_RESET;
- val = intel_de_read(dev_priv, PP_ON_DELAYS(0));
+ val = intel_de_read(dev_priv, PP_ON_DELAYS(dev_priv, 0));
pps->port = REG_FIELD_GET(PANEL_PORT_SELECT_MASK, val);
pps->t1_t2 = REG_FIELD_GET(PANEL_POWER_UP_DELAY_MASK, val);
pps->t5 = REG_FIELD_GET(PANEL_LIGHT_ON_DELAY_MASK, val);
- val = intel_de_read(dev_priv, PP_OFF_DELAYS(0));
+ val = intel_de_read(dev_priv, PP_OFF_DELAYS(dev_priv, 0));
pps->t3 = REG_FIELD_GET(PANEL_POWER_DOWN_DELAY_MASK, val);
pps->tx = REG_FIELD_GET(PANEL_LIGHT_OFF_DELAY_MASK, val);
- val = intel_de_read(dev_priv, PP_DIVISOR(0));
+ val = intel_de_read(dev_priv, PP_DIVISOR(dev_priv, 0));
pps->divider = REG_FIELD_GET(PP_REFERENCE_DIVIDER_MASK, val);
val = REG_FIELD_GET(PANEL_POWER_CYCLE_DELAY_MASK, val);
/*
@@ -209,23 +210,23 @@ static void intel_lvds_pps_init_hw(struct drm_i915_private *dev_priv,
{
u32 val;
- val = intel_de_read(dev_priv, PP_CONTROL(0));
+ val = intel_de_read(dev_priv, PP_CONTROL(dev_priv, 0));
drm_WARN_ON(&dev_priv->drm,
(val & PANEL_UNLOCK_MASK) != PANEL_UNLOCK_REGS);
if (pps->powerdown_on_reset)
val |= PANEL_POWER_RESET;
- intel_de_write(dev_priv, PP_CONTROL(0), val);
+ intel_de_write(dev_priv, PP_CONTROL(dev_priv, 0), val);
- intel_de_write(dev_priv, PP_ON_DELAYS(0),
+ intel_de_write(dev_priv, PP_ON_DELAYS(dev_priv, 0),
REG_FIELD_PREP(PANEL_PORT_SELECT_MASK, pps->port) |
REG_FIELD_PREP(PANEL_POWER_UP_DELAY_MASK, pps->t1_t2) |
REG_FIELD_PREP(PANEL_LIGHT_ON_DELAY_MASK, pps->t5));
- intel_de_write(dev_priv, PP_OFF_DELAYS(0),
+ intel_de_write(dev_priv, PP_OFF_DELAYS(dev_priv, 0),
REG_FIELD_PREP(PANEL_POWER_DOWN_DELAY_MASK, pps->t3) |
REG_FIELD_PREP(PANEL_LIGHT_OFF_DELAY_MASK, pps->tx));
- intel_de_write(dev_priv, PP_DIVISOR(0),
+ intel_de_write(dev_priv, PP_DIVISOR(dev_priv, 0),
REG_FIELD_PREP(PP_REFERENCE_DIVIDER_MASK, pps->divider) |
REG_FIELD_PREP(PANEL_POWER_CYCLE_DELAY_MASK, DIV_ROUND_UP(pps->t4, 1000) + 1));
}
@@ -321,10 +322,10 @@ static void intel_enable_lvds(struct intel_atomic_state *state,
intel_de_rmw(dev_priv, lvds_encoder->reg, 0, LVDS_PORT_EN);
- intel_de_rmw(dev_priv, PP_CONTROL(0), 0, PANEL_POWER_ON);
+ intel_de_rmw(dev_priv, PP_CONTROL(dev_priv, 0), 0, PANEL_POWER_ON);
intel_de_posting_read(dev_priv, lvds_encoder->reg);
- if (intel_de_wait_for_set(dev_priv, PP_STATUS(0), PP_ON, 5000))
+ if (intel_de_wait_for_set(dev_priv, PP_STATUS(dev_priv, 0), PP_ON, 5000))
drm_err(&dev_priv->drm,
"timed out waiting for panel to power on\n");
@@ -339,8 +340,8 @@ static void intel_disable_lvds(struct intel_atomic_state *state,
struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- intel_de_rmw(dev_priv, PP_CONTROL(0), PANEL_POWER_ON, 0);
- if (intel_de_wait_for_clear(dev_priv, PP_STATUS(0), PP_ON, 1000))
+ intel_de_rmw(dev_priv, PP_CONTROL(dev_priv, 0), PANEL_POWER_ON, 0);
+ if (intel_de_wait_for_clear(dev_priv, PP_STATUS(dev_priv, 0), PP_ON, 1000))
drm_err(&dev_priv->drm,
"timed out waiting for panel to power off\n");
@@ -379,7 +380,7 @@ static void intel_lvds_shutdown(struct intel_encoder *encoder)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- if (intel_de_wait_for_clear(dev_priv, PP_STATUS(0), PP_CYCLE_DELAY_ACTIVE, 5000))
+ if (intel_de_wait_for_clear(dev_priv, PP_STATUS(dev_priv, 0), PP_CYCLE_DELAY_ACTIVE, 5000))
drm_err(&dev_priv->drm,
"timed out waiting for panel power cycle delay\n");
}
diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c
index caeca3a8442c..7602cb30ebf1 100644
--- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c
+++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c
@@ -68,7 +68,7 @@ static void intel_crtc_disable_noatomic_begin(struct intel_crtc *crtc,
/* Everything's already locked, -EDEADLK can't happen. */
for_each_intel_crtc_in_pipe_mask(&i915->drm, temp_crtc,
BIT(pipe) |
- intel_crtc_bigjoiner_slave_pipes(crtc_state)) {
+ intel_crtc_joiner_secondary_pipes(crtc_state)) {
struct intel_crtc_state *temp_crtc_state =
intel_atomic_get_crtc_state(state, temp_crtc);
int ret;
@@ -189,7 +189,7 @@ static void intel_crtc_disable_noatomic_complete(struct intel_crtc *crtc)
/*
* Return all the pipes using a transcoder in @transcoder_mask.
- * For bigjoiner configs return only the bigjoiner master.
+ * For joiner configs return only the joiner primary.
*/
static u8 get_transcoder_pipes(struct drm_i915_private *i915,
u8 transcoder_mask)
@@ -204,7 +204,7 @@ static u8 get_transcoder_pipes(struct drm_i915_private *i915,
if (temp_crtc_state->cpu_transcoder == INVALID_TRANSCODER)
continue;
- if (intel_crtc_is_bigjoiner_slave(temp_crtc_state))
+ if (intel_crtc_is_joiner_secondary(temp_crtc_state))
continue;
if (transcoder_mask & BIT(temp_crtc_state->cpu_transcoder))
@@ -216,7 +216,7 @@ static u8 get_transcoder_pipes(struct drm_i915_private *i915,
/*
* Return the port sync master and slave pipes linked to @crtc.
- * For bigjoiner configs return only the bigjoiner master pipes.
+ * For joiner configs return only the joiner primary pipes.
*/
static void get_portsync_pipes(struct intel_crtc *crtc,
u8 *master_pipe_mask, u8 *slave_pipes_mask)
@@ -248,16 +248,16 @@ static void get_portsync_pipes(struct intel_crtc *crtc,
*slave_pipes_mask = get_transcoder_pipes(i915, master_crtc_state->sync_mode_slaves_mask);
}
-static u8 get_bigjoiner_slave_pipes(struct drm_i915_private *i915, u8 master_pipes_mask)
+static u8 get_joiner_secondary_pipes(struct drm_i915_private *i915, u8 primary_pipes_mask)
{
- struct intel_crtc *master_crtc;
+ struct intel_crtc *primary_crtc;
u8 pipes = 0;
- for_each_intel_crtc_in_pipe_mask(&i915->drm, master_crtc, master_pipes_mask) {
- struct intel_crtc_state *master_crtc_state =
- to_intel_crtc_state(master_crtc->base.state);
+ for_each_intel_crtc_in_pipe_mask(&i915->drm, primary_crtc, primary_pipes_mask) {
+ struct intel_crtc_state *primary_crtc_state =
+ to_intel_crtc_state(primary_crtc->base.state);
- pipes |= intel_crtc_bigjoiner_slave_pipes(master_crtc_state);
+ pipes |= intel_crtc_joiner_secondary_pipes(primary_crtc_state);
}
return pipes;
@@ -269,21 +269,21 @@ static void intel_crtc_disable_noatomic(struct intel_crtc *crtc,
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
u8 portsync_master_mask;
u8 portsync_slaves_mask;
- u8 bigjoiner_slaves_mask;
+ u8 joiner_secondaries_mask;
struct intel_crtc *temp_crtc;
/* TODO: Add support for MST */
get_portsync_pipes(crtc, &portsync_master_mask, &portsync_slaves_mask);
- bigjoiner_slaves_mask = get_bigjoiner_slave_pipes(i915,
- portsync_master_mask |
- portsync_slaves_mask);
+ joiner_secondaries_mask = get_joiner_secondary_pipes(i915,
+ portsync_master_mask |
+ portsync_slaves_mask);
drm_WARN_ON(&i915->drm,
portsync_master_mask & portsync_slaves_mask ||
- portsync_master_mask & bigjoiner_slaves_mask ||
- portsync_slaves_mask & bigjoiner_slaves_mask);
+ portsync_master_mask & joiner_secondaries_mask ||
+ portsync_slaves_mask & joiner_secondaries_mask);
- for_each_intel_crtc_in_pipe_mask(&i915->drm, temp_crtc, bigjoiner_slaves_mask)
+ for_each_intel_crtc_in_pipe_mask(&i915->drm, temp_crtc, joiner_secondaries_mask)
intel_crtc_disable_noatomic_begin(temp_crtc, ctx);
for_each_intel_crtc_in_pipe_mask(&i915->drm, temp_crtc, portsync_slaves_mask)
@@ -293,7 +293,7 @@ static void intel_crtc_disable_noatomic(struct intel_crtc *crtc,
intel_crtc_disable_noatomic_begin(temp_crtc, ctx);
for_each_intel_crtc_in_pipe_mask(&i915->drm, temp_crtc,
- bigjoiner_slaves_mask |
+ joiner_secondaries_mask |
portsync_slaves_mask |
portsync_master_mask)
intel_crtc_disable_noatomic_complete(temp_crtc);
@@ -326,7 +326,7 @@ static void intel_modeset_update_connector_atomic_state(struct drm_i915_private
static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state)
{
- if (intel_crtc_is_bigjoiner_slave(crtc_state))
+ if (intel_crtc_is_joiner_secondary(crtc_state))
return;
crtc_state->uapi.enable = crtc_state->hw.enable;
@@ -474,7 +474,7 @@ static bool intel_sanitize_crtc(struct intel_crtc *crtc,
}
if (!crtc_state->hw.active ||
- intel_crtc_is_bigjoiner_slave(crtc_state))
+ intel_crtc_is_joiner_secondary(crtc_state))
return false;
needs_link_reset = intel_crtc_needs_link_reset(crtc);
@@ -728,19 +728,19 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915)
encoder->base.crtc = &crtc->base;
intel_encoder_get_config(encoder, crtc_state);
- /* read out to slave crtc as well for bigjoiner */
- if (crtc_state->bigjoiner_pipes) {
- struct intel_crtc *slave_crtc;
+ /* read out to secondary crtc as well for joiner */
+ if (crtc_state->joiner_pipes) {
+ struct intel_crtc *secondary_crtc;
- /* encoder should read be linked to bigjoiner master */
- WARN_ON(intel_crtc_is_bigjoiner_slave(crtc_state));
+ /* encoder should read be linked to joiner primary */
+ WARN_ON(intel_crtc_is_joiner_secondary(crtc_state));
- for_each_intel_crtc_in_pipe_mask(&i915->drm, slave_crtc,
- intel_crtc_bigjoiner_slave_pipes(crtc_state)) {
- struct intel_crtc_state *slave_crtc_state;
+ for_each_intel_crtc_in_pipe_mask(&i915->drm, secondary_crtc,
+ intel_crtc_joiner_secondary_pipes(crtc_state)) {
+ struct intel_crtc_state *secondary_crtc_state;
- slave_crtc_state = to_intel_crtc_state(slave_crtc->base.state);
- intel_encoder_get_config(encoder, slave_crtc_state);
+ secondary_crtc_state = to_intel_crtc_state(secondary_crtc->base.state);
+ intel_encoder_get_config(encoder, secondary_crtc_state);
}
}
diff --git a/drivers/gpu/drm/i915/display/intel_modeset_verify.c b/drivers/gpu/drm/i915/display/intel_modeset_verify.c
index 076298a8d405..3491db5cad31 100644
--- a/drivers/gpu/drm/i915/display/intel_modeset_verify.c
+++ b/drivers/gpu/drm/i915/display/intel_modeset_verify.c
@@ -166,7 +166,7 @@ verify_crtc_state(struct intel_atomic_state *state,
const struct intel_crtc_state *sw_crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
struct intel_crtc_state *hw_crtc_state;
- struct intel_crtc *master_crtc;
+ struct intel_crtc *primary_crtc;
struct intel_encoder *encoder;
hw_crtc_state = intel_crtc_state_alloc(crtc);
@@ -193,9 +193,9 @@ verify_crtc_state(struct intel_atomic_state *state,
"transitional active state does not match atomic hw state (expected %i, found %i)\n",
sw_crtc_state->hw.active, crtc->active);
- master_crtc = intel_master_crtc(sw_crtc_state);
+ primary_crtc = intel_primary_crtc(sw_crtc_state);
- for_each_encoder_on_crtc(dev, &master_crtc->base, encoder) {
+ for_each_encoder_on_crtc(dev, &primary_crtc->base, encoder) {
enum pipe pipe;
bool active;
@@ -205,7 +205,7 @@ verify_crtc_state(struct intel_atomic_state *state,
encoder->base.base.id, active,
sw_crtc_state->hw.active);
- I915_STATE_WARN(i915, active && master_crtc->pipe != pipe,
+ I915_STATE_WARN(i915, active && primary_crtc->pipe != pipe,
"Encoder connected to wrong pipe %c\n",
pipe_name(pipe));
diff --git a/drivers/gpu/drm/i915/display/intel_overlay.c b/drivers/gpu/drm/i915/display/intel_overlay.c
index 1c2099ed5514..06b1122ec13e 100644
--- a/drivers/gpu/drm/i915/display/intel_overlay.c
+++ b/drivers/gpu/drm/i915/display/intel_overlay.c
@@ -943,17 +943,19 @@ static void update_pfit_vscale_ratio(struct intel_overlay *overlay)
* line with the intel documentation for the i965
*/
if (DISPLAY_VER(dev_priv) >= 4) {
- u32 tmp = intel_de_read(dev_priv, PFIT_PGM_RATIOS);
+ u32 tmp = intel_de_read(dev_priv, PFIT_PGM_RATIOS(dev_priv));
/* on i965 use the PGM reg to read out the autoscaler values */
ratio = REG_FIELD_GET(PFIT_VERT_SCALE_MASK_965, tmp);
} else {
u32 tmp;
- if (intel_de_read(dev_priv, PFIT_CONTROL) & PFIT_VERT_AUTO_SCALE)
- tmp = intel_de_read(dev_priv, PFIT_AUTO_RATIOS);
+ if (intel_de_read(dev_priv, PFIT_CONTROL(dev_priv)) & PFIT_VERT_AUTO_SCALE)
+ tmp = intel_de_read(dev_priv,
+ PFIT_AUTO_RATIOS(dev_priv));
else
- tmp = intel_de_read(dev_priv, PFIT_PGM_RATIOS);
+ tmp = intel_de_read(dev_priv,
+ PFIT_PGM_RATIOS(dev_priv));
ratio = REG_FIELD_GET(PFIT_VERT_SCALE_MASK, tmp);
}
@@ -1485,15 +1487,14 @@ intel_overlay_capture_error_state(struct drm_i915_private *dev_priv)
}
void
-intel_overlay_print_error_state(struct drm_i915_error_state_buf *m,
+intel_overlay_print_error_state(struct drm_printer *p,
struct intel_overlay_error_state *error)
{
- i915_error_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
- error->dovsta, error->isr);
- i915_error_printf(m, " Register file at 0x%08lx:\n",
- error->base);
+ drm_printf(p, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
+ error->dovsta, error->isr);
+ drm_printf(p, " Register file at 0x%08lx:\n", error->base);
-#define P(x) i915_error_printf(m, " " #x ": 0x%08x\n", error->regs.x)
+#define P(x) drm_printf(p, " " #x ": 0x%08x\n", error->regs.x)
P(OBUF_0Y);
P(OBUF_1Y);
P(OBUF_0U);
diff --git a/drivers/gpu/drm/i915/display/intel_overlay.h b/drivers/gpu/drm/i915/display/intel_overlay.h
index c3f68fce6f08..f28a09c062d0 100644
--- a/drivers/gpu/drm/i915/display/intel_overlay.h
+++ b/drivers/gpu/drm/i915/display/intel_overlay.h
@@ -8,8 +8,8 @@
struct drm_device;
struct drm_file;
-struct drm_i915_error_state_buf;
struct drm_i915_private;
+struct drm_printer;
struct intel_overlay;
struct intel_overlay_error_state;
@@ -24,7 +24,7 @@ int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data,
void intel_overlay_reset(struct drm_i915_private *dev_priv);
struct intel_overlay_error_state *
intel_overlay_capture_error_state(struct drm_i915_private *dev_priv);
-void intel_overlay_print_error_state(struct drm_i915_error_state_buf *e,
+void intel_overlay_print_error_state(struct drm_printer *p,
struct intel_overlay_error_state *error);
#else
static inline void intel_overlay_setup(struct drm_i915_private *dev_priv)
@@ -55,7 +55,7 @@ intel_overlay_capture_error_state(struct drm_i915_private *dev_priv)
{
return NULL;
}
-static inline void intel_overlay_print_error_state(struct drm_i915_error_state_buf *e,
+static inline void intel_overlay_print_error_state(struct drm_printer *p,
struct intel_overlay_error_state *error)
{
}
diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c
index 6f4ff6a89c32..71454ddef20f 100644
--- a/drivers/gpu/drm/i915/display/intel_panel.c
+++ b/drivers/gpu/drm/i915/display/intel_panel.c
@@ -352,7 +352,7 @@ void intel_panel_add_vbt_lfp_fixed_mode(struct intel_connector *connector)
struct drm_i915_private *i915 = to_i915(connector->base.dev);
const struct drm_display_mode *mode;
- mode = connector->panel.vbt.lfp_lvds_vbt_mode;
+ mode = connector->panel.vbt.lfp_vbt_mode;
if (!mode)
return;
diff --git a/drivers/gpu/drm/i915/display/intel_pch_display.c b/drivers/gpu/drm/i915/display/intel_pch_display.c
index 826e38a9e6a4..0d48b9bec29c 100644
--- a/drivers/gpu/drm/i915/display/intel_pch_display.c
+++ b/drivers/gpu/drm/i915/display/intel_pch_display.c
@@ -224,20 +224,20 @@ static void ilk_pch_transcoder_set_timings(const struct intel_crtc_state *crtc_s
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
intel_de_write(dev_priv, PCH_TRANS_HTOTAL(pch_transcoder),
- intel_de_read(dev_priv, TRANS_HTOTAL(cpu_transcoder)));
+ intel_de_read(dev_priv, TRANS_HTOTAL(dev_priv, cpu_transcoder)));
intel_de_write(dev_priv, PCH_TRANS_HBLANK(pch_transcoder),
- intel_de_read(dev_priv, TRANS_HBLANK(cpu_transcoder)));
+ intel_de_read(dev_priv, TRANS_HBLANK(dev_priv, cpu_transcoder)));
intel_de_write(dev_priv, PCH_TRANS_HSYNC(pch_transcoder),
- intel_de_read(dev_priv, TRANS_HSYNC(cpu_transcoder)));
+ intel_de_read(dev_priv, TRANS_HSYNC(dev_priv, cpu_transcoder)));
intel_de_write(dev_priv, PCH_TRANS_VTOTAL(pch_transcoder),
- intel_de_read(dev_priv, TRANS_VTOTAL(cpu_transcoder)));
+ intel_de_read(dev_priv, TRANS_VTOTAL(dev_priv, cpu_transcoder)));
intel_de_write(dev_priv, PCH_TRANS_VBLANK(pch_transcoder),
- intel_de_read(dev_priv, TRANS_VBLANK(cpu_transcoder)));
+ intel_de_read(dev_priv, TRANS_VBLANK(dev_priv, cpu_transcoder)));
intel_de_write(dev_priv, PCH_TRANS_VSYNC(pch_transcoder),
- intel_de_read(dev_priv, TRANS_VSYNC(cpu_transcoder)));
+ intel_de_read(dev_priv, TRANS_VSYNC(dev_priv, cpu_transcoder)));
intel_de_write(dev_priv, PCH_TRANS_VSYNCSHIFT(pch_transcoder),
- intel_de_read(dev_priv, TRANS_VSYNCSHIFT(cpu_transcoder)));
+ intel_de_read(dev_priv, TRANS_VSYNCSHIFT(dev_priv, cpu_transcoder)));
}
static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state)
@@ -271,7 +271,7 @@ static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state)
reg = PCH_TRANSCONF(pipe);
val = intel_de_read(dev_priv, reg);
- pipeconf_val = intel_de_read(dev_priv, TRANSCONF(pipe));
+ pipeconf_val = intel_de_read(dev_priv, TRANSCONF(dev_priv, pipe));
if (HAS_PCH_IBX(dev_priv)) {
/* Configure frame start delay to match the CPU */
@@ -413,7 +413,7 @@ void ilk_pch_enable(struct intel_atomic_state *state,
intel_crtc_has_dp_encoder(crtc_state)) {
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
- u32 bpc = (intel_de_read(dev_priv, TRANSCONF(pipe)) & TRANSCONF_BPC_MASK) >> 5;
+ u32 bpc = (intel_de_read(dev_priv, TRANSCONF(dev_priv, pipe)) & TRANSCONF_BPC_MASK) >> 5;
i915_reg_t reg = TRANS_DP_CTL(pipe);
enum port port;
@@ -557,7 +557,8 @@ static void lpt_enable_pch_transcoder(const struct intel_crtc_state *crtc_state)
intel_de_write(dev_priv, TRANS_CHICKEN2(PIPE_A), val);
val = TRANS_ENABLE;
- pipeconf_val = intel_de_read(dev_priv, TRANSCONF(cpu_transcoder));
+ pipeconf_val = intel_de_read(dev_priv,
+ TRANSCONF(dev_priv, cpu_transcoder));
if ((pipeconf_val & TRANSCONF_INTERLACE_MASK_HSW) == TRANSCONF_INTERLACE_IF_ID_ILK)
val |= TRANS_INTERLACE_INTERLACED;
diff --git a/drivers/gpu/drm/i915/display/intel_pipe_crc.c b/drivers/gpu/drm/i915/display/intel_pipe_crc.c
index 5a468ed6e26c..82ceede0b2b1 100644
--- a/drivers/gpu/drm/i915/display/intel_pipe_crc.c
+++ b/drivers/gpu/drm/i915/display/intel_pipe_crc.c
@@ -34,6 +34,7 @@
#include "intel_de.h"
#include "intel_display_types.h"
#include "intel_pipe_crc.h"
+#include "intel_pipe_crc_regs.h"
static const char * const pipe_crc_sources[] = {
[INTEL_PIPE_CRC_SOURCE_NONE] = "none",
@@ -167,7 +168,7 @@ static int vlv_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv,
* - DisplayPort scrambling: used for EMI reduction
*/
if (need_stable_symbols) {
- u32 tmp = intel_de_read(dev_priv, PORT_DFT2_G4X);
+ u32 tmp = intel_de_read(dev_priv, PORT_DFT2_G4X(dev_priv));
tmp |= DC_BALANCE_RESET_VLV;
switch (pipe) {
@@ -183,7 +184,7 @@ static int vlv_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv,
default:
return -EINVAL;
}
- intel_de_write(dev_priv, PORT_DFT2_G4X, tmp);
+ intel_de_write(dev_priv, PORT_DFT2_G4X(dev_priv), tmp);
}
return 0;
@@ -229,7 +230,7 @@ static int i9xx_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv,
static void vlv_undo_pipe_scramble_reset(struct drm_i915_private *dev_priv,
enum pipe pipe)
{
- u32 tmp = intel_de_read(dev_priv, PORT_DFT2_G4X);
+ u32 tmp = intel_de_read(dev_priv, PORT_DFT2_G4X(dev_priv));
switch (pipe) {
case PIPE_A:
@@ -246,7 +247,7 @@ static void vlv_undo_pipe_scramble_reset(struct drm_i915_private *dev_priv,
}
if (!(tmp & PIPE_SCRAMBLE_RESET_MASK))
tmp &= ~DC_BALANCE_RESET_VLV;
- intel_de_write(dev_priv, PORT_DFT2_G4X, tmp);
+ intel_de_write(dev_priv, PORT_DFT2_G4X(dev_priv), tmp);
}
static int ilk_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source,
@@ -608,8 +609,8 @@ int intel_crtc_set_crc_source(struct drm_crtc *_crtc, const char *source_name)
goto out;
pipe_crc->source = source;
- intel_de_write(dev_priv, PIPE_CRC_CTL(pipe), val);
- intel_de_posting_read(dev_priv, PIPE_CRC_CTL(pipe));
+ intel_de_write(dev_priv, PIPE_CRC_CTL(dev_priv, pipe), val);
+ intel_de_posting_read(dev_priv, PIPE_CRC_CTL(dev_priv, pipe));
if (!source) {
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
@@ -643,8 +644,8 @@ void intel_crtc_enable_pipe_crc(struct intel_crtc *crtc)
/* Don't need pipe_crc->lock here, IRQs are not generated. */
pipe_crc->skipped = 0;
- intel_de_write(dev_priv, PIPE_CRC_CTL(pipe), val);
- intel_de_posting_read(dev_priv, PIPE_CRC_CTL(pipe));
+ intel_de_write(dev_priv, PIPE_CRC_CTL(dev_priv, pipe), val);
+ intel_de_posting_read(dev_priv, PIPE_CRC_CTL(dev_priv, pipe));
}
void intel_crtc_disable_pipe_crc(struct intel_crtc *crtc)
@@ -658,7 +659,7 @@ void intel_crtc_disable_pipe_crc(struct intel_crtc *crtc)
pipe_crc->skipped = INT_MIN;
spin_unlock_irq(&pipe_crc->lock);
- intel_de_write(dev_priv, PIPE_CRC_CTL(pipe), 0);
- intel_de_posting_read(dev_priv, PIPE_CRC_CTL(pipe));
+ intel_de_write(dev_priv, PIPE_CRC_CTL(dev_priv, pipe), 0);
+ intel_de_posting_read(dev_priv, PIPE_CRC_CTL(dev_priv, pipe));
intel_synchronize_irq(dev_priv);
}
diff --git a/drivers/gpu/drm/i915/display/intel_pipe_crc_regs.h b/drivers/gpu/drm/i915/display/intel_pipe_crc_regs.h
new file mode 100644
index 000000000000..4e65f51d34e6
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_pipe_crc_regs.h
@@ -0,0 +1,152 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef __INTEL_PIPE_CRC_REGS_H__
+#define __INTEL_PIPE_CRC_REGS_H__
+
+#include "intel_display_reg_defs.h"
+
+#define _PIPE_CRC_CTL_A 0x60050
+#define PIPE_CRC_CTL(dev_priv, pipe) _MMIO_TRANS2((dev_priv), (pipe), _PIPE_CRC_CTL_A)
+#define PIPE_CRC_ENABLE REG_BIT(31)
+/* skl+ source selection */
+#define PIPE_CRC_SOURCE_MASK_SKL REG_GENMASK(30, 28)
+#define PIPE_CRC_SOURCE_PLANE_1_SKL REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_SKL, 0)
+#define PIPE_CRC_SOURCE_PLANE_2_SKL REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_SKL, 2)
+#define PIPE_CRC_SOURCE_DMUX_SKL REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_SKL, 4)
+#define PIPE_CRC_SOURCE_PLANE_3_SKL REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_SKL, 6)
+#define PIPE_CRC_SOURCE_PLANE_4_SKL REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_SKL, 7)
+#define PIPE_CRC_SOURCE_PLANE_5_SKL REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_SKL, 5)
+#define PIPE_CRC_SOURCE_PLANE_6_SKL REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_SKL, 3)
+#define PIPE_CRC_SOURCE_PLANE_7_SKL REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_SKL, 1)
+/* ivb+ source selection */
+#define PIPE_CRC_SOURCE_MASK_IVB REG_GENMASK(30, 29)
+#define PIPE_CRC_SOURCE_PRIMARY_IVB REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_IVB, 0)
+#define PIPE_CRC_SOURCE_SPRITE_IVB REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_IVB, 1)
+#define PIPE_CRC_SOURCE_PF_IVB REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_IVB, 2)
+/* ilk+ source selection */
+#define PIPE_CRC_SOURCE_MASK_ILK REG_GENMASK(30, 28)
+#define PIPE_CRC_SOURCE_PRIMARY_ILK REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_ILK, 0)
+#define PIPE_CRC_SOURCE_SPRITE_ILK REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_ILK, 1)
+#define PIPE_CRC_SOURCE_PIPE_ILK REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_ILK, 2)
+/* embedded DP port on the north display block */
+#define PIPE_CRC_SOURCE_PORT_A_ILK REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_ILK, 4)
+#define PIPE_CRC_SOURCE_FDI_ILK REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_ILK, 5)
+/* vlv source selection */
+#define PIPE_CRC_SOURCE_MASK_VLV REG_GENMASK(30, 27)
+#define PIPE_CRC_SOURCE_PIPE_VLV REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_VLV, 0)
+#define PIPE_CRC_SOURCE_HDMIB_VLV REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_VLV, 1)
+#define PIPE_CRC_SOURCE_HDMIC_VLV REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_VLV, 2)
+/* with DP port the pipe source is invalid */
+#define PIPE_CRC_SOURCE_DP_D_VLV REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_VLV, 3)
+#define PIPE_CRC_SOURCE_DP_B_VLV REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_VLV, 6)
+#define PIPE_CRC_SOURCE_DP_C_VLV REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_VLV, 7)
+/* gen3+ source selection */
+#define PIPE_CRC_SOURCE_MASK_I9XX REG_GENMASK(30, 28)
+#define PIPE_CRC_SOURCE_PIPE_I9XX REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_I9XX, 0)
+#define PIPE_CRC_SOURCE_SDVOB_I9XX REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_I9XX, 1)
+#define PIPE_CRC_SOURCE_SDVOC_I9XX REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_I9XX, 2)
+/* with DP/TV port the pipe source is invalid */
+#define PIPE_CRC_SOURCE_DP_D_G4X REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_I9XX, 3)
+#define PIPE_CRC_SOURCE_TV_PRE REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_I9XX, 4)
+#define PIPE_CRC_SOURCE_TV_POST REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_I9XX, 5)
+#define PIPE_CRC_SOURCE_DP_B_G4X REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_I9XX, 6)
+#define PIPE_CRC_SOURCE_DP_C_G4X REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_I9XX, 7)
+/* gen2 doesn't have source selection bits */
+#define PIPE_CRC_INCLUDE_BORDER_I8XX REG_BIT(30)
+#define PIPE_CRC_EXP_RED_MASK REG_BIT(22, 0) /* pre-ivb */
+#define PIPE_CRC_EXP_1_MASK_IVB REG_BIT(22, 0) /* ivb */
+
+#define _PIPE_CRC_EXP_GREEN_A 0x60054
+#define PIPE_CRC_EXP_GREEN(dev_priv, pipe) _MMIO_TRANS2(dev_priv, pipe, _PIPE_CRC_EXP_GREEN_A)
+#define PIPE_CRC_EXP_GREEN_MASK REG_BIT(22, 0) /* pre-ivb */
+
+#define _PIPE_CRC_EXP_BLUE_A 0x60058
+#define PIPE_CRC_EXP_BLUE(dev_priv, pipe) _MMIO_TRANS2(dev_priv, pipe, _PIPE_CRC_EXP_BLUE_A)
+#define PIPE_CRC_EXP_BLUE_MASK REG_BIT(22, 0) /* pre-ivb */
+
+#define _PIPE_CRC_EXP_RES1_A_I915 0x6005c /* i915+ */
+#define PIPE_CRC_EXP_RES1_I915(dev_priv, pipe) _MMIO_TRANS2(dev_priv, pipe, _PIPE_CRC_EXP_RES1_A_I915)
+#define PIPE_CRC_EXP_RES1_MASK REG_BIT(22, 0) /* pre-ivb */
+
+#define _PIPE_CRC_EXP_RES2_A_G4X 0x60080 /* g4x+ */
+#define PIPE_CRC_EXP_RES2_G4X(dev_priv, pipe) _MMIO_TRANS2(dev_priv, pipe, _PIPE_CRC_EXP_RES2_A_G4X)
+#define PIPE_CRC_EXP_RES2_MASK REG_BIT(22, 0) /* pre-ivb */
+
+#define _PIPE_CRC_RES_RED_A 0x60060
+#define PIPE_CRC_RES_RED(dev_priv, pipe) _MMIO_TRANS2((dev_priv), (pipe), _PIPE_CRC_RES_RED_A)
+
+#define _PIPE_CRC_RES_GREEN_A 0x60064
+#define PIPE_CRC_RES_GREEN(dev_priv, pipe) _MMIO_TRANS2((dev_priv), (pipe), _PIPE_CRC_RES_GREEN_A)
+
+#define _PIPE_CRC_RES_BLUE_A 0x60068
+#define PIPE_CRC_RES_BLUE(dev_priv, pipe) _MMIO_TRANS2((dev_priv), (pipe), _PIPE_CRC_RES_BLUE_A)
+
+#define _PIPE_CRC_RES_RES1_A_I915 0x6006c /* i915+ */
+#define PIPE_CRC_RES_RES1_I915(dev_priv, pipe) _MMIO_TRANS2((dev_priv), (pipe), _PIPE_CRC_RES_RES1_A_I915)
+
+#define _PIPE_CRC_RES_RES2_A_G4X 0x60080 /* g4x+ */
+#define PIPE_CRC_RES_RES2_G4X(dev_priv, pipe) _MMIO_TRANS2((dev_priv), (pipe), _PIPE_CRC_RES_RES2_A_G4X)
+
+/* ivb */
+#define _PIPE_CRC_EXP_2_A_IVB 0x60054
+#define _PIPE_CRC_EXP_2_B_IVB 0x61054
+#define PIPE_CRC_EXP_2_IVB(pipe) _MMIO_PIPE(pipe, _PIPE_CRC_EXP_2_A_IVB, _PIPE_CRC_EXP_2_B_IVB)
+#define PIPE_CRC_EXP_2_MASK_IVB REG_BIT(22, 0) /* ivb */
+
+/* ivb */
+#define _PIPE_CRC_EXP_3_A_IVB 0x60058
+#define _PIPE_CRC_EXP_3_B_IVB 0x61058
+#define PIPE_CRC_EXP_3_IVB(pipe) _MMIO_PIPE(pipe, _PIPE_CRC_EXP_3_A_IVB, _PIPE_CRC_EXP_3_B_IVB)
+#define PIPE_CRC_EXP_3_MASK_IVB REG_BIT(22, 0) /* ivb */
+
+/* ivb */
+#define _PIPE_CRC_EXP_4_A_IVB 0x6005c
+#define _PIPE_CRC_EXP_4_B_IVB 0x6105c
+#define PIPE_CRC_EXP_4_IVB(pipe) _MMIO_PIPE(pipe, _PIPE_CRC_EXP_2_A_IVB, _PIPE_CRC_EXP_2_B_IVB)
+#define PIPE_CRC_EXP_4_MASK_IVB REG_BIT(22, 0) /* ivb */
+
+/* ivb */
+#define _PIPE_CRC_EXP_5_A_IVB 0x60060
+#define _PIPE_CRC_EXP_5_B_IVB 0x61060
+#define PIPE_CRC_EXP_5_IVB(pipe) _MMIO_PIPE(pipe, _PIPE_CRC_EXP_2_A_IVB, _PIPE_CRC_EXP_2_B_IVB)
+#define PIPE_CRC_EXP_5_MASK_IVB REG_BIT(22, 0) /* ivb */
+
+/* ivb */
+#define _PIPE_CRC_RES_1_A_IVB 0x60064
+#define _PIPE_CRC_RES_1_B_IVB 0x61064
+#define PIPE_CRC_RES_1_IVB(pipe) _MMIO_PIPE((pipe), _PIPE_CRC_RES_1_A_IVB, _PIPE_CRC_RES_1_B_IVB)
+
+/* ivb */
+#define _PIPE_CRC_RES_2_A_IVB 0x60068
+#define _PIPE_CRC_RES_2_B_IVB 0x61068
+#define PIPE_CRC_RES_2_IVB(pipe) _MMIO_PIPE((pipe), _PIPE_CRC_RES_2_A_IVB, _PIPE_CRC_RES_2_B_IVB)
+
+/* ivb */
+#define _PIPE_CRC_RES_3_A_IVB 0x6006c
+#define _PIPE_CRC_RES_3_B_IVB 0x6106c
+#define PIPE_CRC_RES_3_IVB(pipe) _MMIO_PIPE((pipe), _PIPE_CRC_RES_3_A_IVB, _PIPE_CRC_RES_3_B_IVB)
+
+/* ivb */
+#define _PIPE_CRC_RES_4_A_IVB 0x60070
+#define _PIPE_CRC_RES_4_B_IVB 0x61070
+#define PIPE_CRC_RES_4_IVB(pipe) _MMIO_PIPE((pipe), _PIPE_CRC_RES_4_A_IVB, _PIPE_CRC_RES_4_B_IVB)
+
+/* ivb */
+#define _PIPE_CRC_RES_5_A_IVB 0x60074
+#define _PIPE_CRC_RES_5_B_IVB 0x61074
+#define PIPE_CRC_RES_5_IVB(pipe) _MMIO_PIPE((pipe), _PIPE_CRC_RES_5_A_IVB, _PIPE_CRC_RES_5_B_IVB)
+
+/* hsw+ */
+#define _PIPE_CRC_EXP_A_HSW 0x60054
+#define _PIPE_CRC_EXP_B_HSW 0x61054
+#define PIPE_CRC_EXP_HSW(pipe) _MMIO_PIPE((pipe), _PIPE_CRC_EXP_A_HSW, _PIPE_CRC_EXP_B_HSW)
+
+/* hsw+ */
+#define _PIPE_CRC_RES_A_HSW 0x60064
+#define _PIPE_CRC_RES_B_HSW 0x61064
+#define PIPE_CRC_RES_HSW(pipe) _MMIO_PIPE((pipe), _PIPE_CRC_RES_A_HSW, _PIPE_CRC_RES_B_HSW)
+
+#endif /* __INTEL_PIPE_CRC_REGS_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c
index 0ccbf9a85914..42306bc4ba86 100644
--- a/drivers/gpu/drm/i915/display/intel_pps.c
+++ b/drivers/gpu/drm/i915/display/intel_pps.c
@@ -119,7 +119,7 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp)
else
DP |= DP_PIPE_SEL(pipe);
- pll_enabled = intel_de_read(dev_priv, DPLL(pipe)) & DPLL_VCO_ENABLE;
+ pll_enabled = intel_de_read(dev_priv, DPLL(dev_priv, pipe)) & DPLL_VCO_ENABLE;
/*
* The DPLL for the pipe must be enabled for this to work.
@@ -272,12 +272,12 @@ typedef bool (*pps_check)(struct drm_i915_private *dev_priv, int pps_idx);
static bool pps_has_pp_on(struct drm_i915_private *dev_priv, int pps_idx)
{
- return intel_de_read(dev_priv, PP_STATUS(pps_idx)) & PP_ON;
+ return intel_de_read(dev_priv, PP_STATUS(dev_priv, pps_idx)) & PP_ON;
}
static bool pps_has_vdd_on(struct drm_i915_private *dev_priv, int pps_idx)
{
- return intel_de_read(dev_priv, PP_CONTROL(pps_idx)) & EDP_FORCE_VDD;
+ return intel_de_read(dev_priv, PP_CONTROL(dev_priv, pps_idx)) & EDP_FORCE_VDD;
}
static bool pps_any(struct drm_i915_private *dev_priv, int pps_idx)
@@ -292,7 +292,7 @@ vlv_initial_pps_pipe(struct drm_i915_private *dev_priv,
enum pipe pipe;
for (pipe = PIPE_A; pipe <= PIPE_B; pipe++) {
- u32 port_sel = intel_de_read(dev_priv, PP_ON_DELAYS(pipe)) &
+ u32 port_sel = intel_de_read(dev_priv, PP_ON_DELAYS(dev_priv, pipe)) &
PANEL_PORT_SELECT_MASK;
if (port_sel != PANEL_PORT_SELECT_VLV(port))
@@ -491,17 +491,17 @@ static void intel_pps_get_registers(struct intel_dp *intel_dp,
else
pps_idx = intel_dp->pps.pps_idx;
- regs->pp_ctrl = PP_CONTROL(pps_idx);
- regs->pp_stat = PP_STATUS(pps_idx);
- regs->pp_on = PP_ON_DELAYS(pps_idx);
- regs->pp_off = PP_OFF_DELAYS(pps_idx);
+ regs->pp_ctrl = PP_CONTROL(dev_priv, pps_idx);
+ regs->pp_stat = PP_STATUS(dev_priv, pps_idx);
+ regs->pp_on = PP_ON_DELAYS(dev_priv, pps_idx);
+ regs->pp_off = PP_OFF_DELAYS(dev_priv, pps_idx);
/* Cycle delay moved from PP_DIVISOR to PP_CONTROL */
if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv) ||
INTEL_PCH_TYPE(dev_priv) >= PCH_CNP)
regs->pp_div = INVALID_MMIO_REG;
else
- regs->pp_div = PP_DIVISOR(pps_idx);
+ regs->pp_div = PP_DIVISOR(dev_priv, pps_idx);
}
static i915_reg_t
@@ -1111,7 +1111,7 @@ static void vlv_detach_power_sequencer(struct intel_dp *intel_dp)
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
enum pipe pipe = intel_dp->pps.pps_pipe;
- i915_reg_t pp_on_reg = PP_ON_DELAYS(pipe);
+ i915_reg_t pp_on_reg = PP_ON_DELAYS(dev_priv, pipe);
drm_WARN_ON(&dev_priv->drm, intel_dp->pps.active_pipe != INVALID_PIPE);
@@ -1656,7 +1656,7 @@ void intel_pps_unlock_regs_wa(struct drm_i915_private *dev_priv)
pps_num = intel_num_pps(dev_priv);
for (pps_idx = 0; pps_idx < pps_num; pps_idx++)
- intel_de_rmw(dev_priv, PP_CONTROL(pps_idx),
+ intel_de_rmw(dev_priv, PP_CONTROL(dev_priv, pps_idx),
PANEL_UNLOCK_MASK, PANEL_UNLOCK_REGS);
}
@@ -1714,8 +1714,8 @@ void assert_pps_unlocked(struct drm_i915_private *dev_priv, enum pipe pipe)
if (HAS_PCH_SPLIT(dev_priv)) {
u32 port_sel;
- pp_reg = PP_CONTROL(0);
- port_sel = intel_de_read(dev_priv, PP_ON_DELAYS(0)) & PANEL_PORT_SELECT_MASK;
+ pp_reg = PP_CONTROL(dev_priv, 0);
+ port_sel = intel_de_read(dev_priv, PP_ON_DELAYS(dev_priv, 0)) & PANEL_PORT_SELECT_MASK;
switch (port_sel) {
case PANEL_PORT_SELECT_LVDS:
@@ -1736,13 +1736,13 @@ void assert_pps_unlocked(struct drm_i915_private *dev_priv, enum pipe pipe)
}
} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
/* presumably write lock depends on pipe, not port select */
- pp_reg = PP_CONTROL(pipe);
+ pp_reg = PP_CONTROL(dev_priv, pipe);
panel_pipe = pipe;
} else {
u32 port_sel;
- pp_reg = PP_CONTROL(0);
- port_sel = intel_de_read(dev_priv, PP_ON_DELAYS(0)) & PANEL_PORT_SELECT_MASK;
+ pp_reg = PP_CONTROL(dev_priv, 0);
+ port_sel = intel_de_read(dev_priv, PP_ON_DELAYS(dev_priv, 0)) & PANEL_PORT_SELECT_MASK;
drm_WARN_ON(&dev_priv->drm,
port_sel != PANEL_PORT_SELECT_LVDS);
diff --git a/drivers/gpu/drm/i915/display/intel_pps_regs.h b/drivers/gpu/drm/i915/display/intel_pps_regs.h
index 60edd2a27100..8f9dbfab9523 100644
--- a/drivers/gpu/drm/i915/display/intel_pps_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_pps_regs.h
@@ -6,6 +6,7 @@
#ifndef __INTEL_PPS_REGS_H__
#define __INTEL_PPS_REGS_H__
+#include "intel_display_conversion.h"
#include "intel_display_reg_defs.h"
/* Panel power sequencing */
@@ -13,12 +14,11 @@
#define VLV_PPS_BASE (VLV_DISPLAY_BASE + PPS_BASE)
#define PCH_PPS_BASE 0xC7200
-#define _MMIO_PPS(pps_idx, reg) _MMIO(dev_priv->display.pps.mmio_base - \
- PPS_BASE + (reg) + \
- (pps_idx) * 0x100)
+#define _MMIO_PPS(dev_priv, pps_idx, reg) \
+ _MMIO(__to_intel_display(dev_priv)->pps.mmio_base - PPS_BASE + (reg) + (pps_idx) * 0x100)
#define _PP_STATUS 0x61200
-#define PP_STATUS(pps_idx) _MMIO_PPS(pps_idx, _PP_STATUS)
+#define PP_STATUS(dev_priv, pps_idx) _MMIO_PPS(dev_priv, pps_idx, _PP_STATUS)
#define PP_ON REG_BIT(31)
/*
* Indicates that all dependencies of the panel are on:
@@ -45,7 +45,7 @@
#define PP_SEQUENCE_STATE_RESET REG_FIELD_PREP(PP_SEQUENCE_STATE_MASK, 0xf)
#define _PP_CONTROL 0x61204
-#define PP_CONTROL(pps_idx) _MMIO_PPS(pps_idx, _PP_CONTROL)
+#define PP_CONTROL(dev_priv, pps_idx) _MMIO_PPS(dev_priv, pps_idx, _PP_CONTROL)
#define PANEL_UNLOCK_MASK REG_GENMASK(31, 16)
#define PANEL_UNLOCK_REGS REG_FIELD_PREP(PANEL_UNLOCK_MASK, 0xabcd)
#define BXT_POWER_CYCLE_DELAY_MASK REG_GENMASK(8, 4)
@@ -55,7 +55,7 @@
#define PANEL_POWER_ON REG_BIT(0)
#define _PP_ON_DELAYS 0x61208
-#define PP_ON_DELAYS(pps_idx) _MMIO_PPS(pps_idx, _PP_ON_DELAYS)
+#define PP_ON_DELAYS(dev_priv, pps_idx) _MMIO_PPS(dev_priv, pps_idx, _PP_ON_DELAYS)
#define PANEL_PORT_SELECT_MASK REG_GENMASK(31, 30)
#define PANEL_PORT_SELECT_LVDS REG_FIELD_PREP(PANEL_PORT_SELECT_MASK, 0)
#define PANEL_PORT_SELECT_DPA REG_FIELD_PREP(PANEL_PORT_SELECT_MASK, 1)
@@ -66,12 +66,12 @@
#define PANEL_LIGHT_ON_DELAY_MASK REG_GENMASK(12, 0)
#define _PP_OFF_DELAYS 0x6120C
-#define PP_OFF_DELAYS(pps_idx) _MMIO_PPS(pps_idx, _PP_OFF_DELAYS)
+#define PP_OFF_DELAYS(dev_priv, pps_idx) _MMIO_PPS(dev_priv, pps_idx, _PP_OFF_DELAYS)
#define PANEL_POWER_DOWN_DELAY_MASK REG_GENMASK(28, 16)
#define PANEL_LIGHT_OFF_DELAY_MASK REG_GENMASK(12, 0)
#define _PP_DIVISOR 0x61210
-#define PP_DIVISOR(pps_idx) _MMIO_PPS(pps_idx, _PP_DIVISOR)
+#define PP_DIVISOR(dev_priv, pps_idx) _MMIO_PPS(dev_priv, pps_idx, _PP_DIVISOR)
#define PP_REFERENCE_DIVIDER_MASK REG_GENMASK(31, 8)
#define PANEL_POWER_CYCLE_DELAY_MASK REG_GENMASK(4, 0)
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index f5b33335a9ae..a9d9383e4ee5 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -27,8 +27,10 @@
#include "i915_drv.h"
#include "i915_reg.h"
+#include "intel_alpm.h"
#include "intel_atomic.h"
#include "intel_crtc.h"
+#include "intel_cursor_regs.h"
#include "intel_ddi.h"
#include "intel_de.h"
#include "intel_display_types.h"
@@ -233,6 +235,26 @@ static bool psr2_global_enabled(struct intel_dp *intel_dp)
}
}
+static bool psr2_su_region_et_global_enabled(struct intel_dp *intel_dp)
+{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+
+ if (i915->display.params.enable_psr != -1)
+ return false;
+
+ return true;
+}
+
+static bool panel_replay_global_enabled(struct intel_dp *intel_dp)
+{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+
+ if ((i915->display.params.enable_psr != -1) ||
+ (intel_dp->psr.debug & I915_PSR_DEBUG_PANEL_REPLAY_DISABLE))
+ return false;
+ return true;
+}
+
static u32 psr_irq_psr_error_bit_get(struct intel_dp *intel_dp)
{
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -269,7 +291,7 @@ static i915_reg_t psr_ctl_reg(struct drm_i915_private *dev_priv,
enum transcoder cpu_transcoder)
{
if (DISPLAY_VER(dev_priv) >= 8)
- return EDP_PSR_CTL(cpu_transcoder);
+ return EDP_PSR_CTL(dev_priv, cpu_transcoder);
else
return HSW_SRD_CTL;
}
@@ -278,7 +300,7 @@ static i915_reg_t psr_debug_reg(struct drm_i915_private *dev_priv,
enum transcoder cpu_transcoder)
{
if (DISPLAY_VER(dev_priv) >= 8)
- return EDP_PSR_DEBUG(cpu_transcoder);
+ return EDP_PSR_DEBUG(dev_priv, cpu_transcoder);
else
return HSW_SRD_DEBUG;
}
@@ -287,7 +309,7 @@ static i915_reg_t psr_perf_cnt_reg(struct drm_i915_private *dev_priv,
enum transcoder cpu_transcoder)
{
if (DISPLAY_VER(dev_priv) >= 8)
- return EDP_PSR_PERF_CNT(cpu_transcoder);
+ return EDP_PSR_PERF_CNT(dev_priv, cpu_transcoder);
else
return HSW_SRD_PERF_CNT;
}
@@ -296,7 +318,7 @@ static i915_reg_t psr_status_reg(struct drm_i915_private *dev_priv,
enum transcoder cpu_transcoder)
{
if (DISPLAY_VER(dev_priv) >= 8)
- return EDP_PSR_STATUS(cpu_transcoder);
+ return EDP_PSR_STATUS(dev_priv, cpu_transcoder);
else
return HSW_SRD_STATUS;
}
@@ -305,7 +327,7 @@ static i915_reg_t psr_imr_reg(struct drm_i915_private *dev_priv,
enum transcoder cpu_transcoder)
{
if (DISPLAY_VER(dev_priv) >= 12)
- return TRANS_PSR_IMR(cpu_transcoder);
+ return TRANS_PSR_IMR(dev_priv, cpu_transcoder);
else
return EDP_PSR_IMR;
}
@@ -314,7 +336,7 @@ static i915_reg_t psr_iir_reg(struct drm_i915_private *dev_priv,
enum transcoder cpu_transcoder)
{
if (DISPLAY_VER(dev_priv) >= 12)
- return TRANS_PSR_IIR(cpu_transcoder);
+ return TRANS_PSR_IIR(dev_priv, cpu_transcoder);
else
return EDP_PSR_IIR;
}
@@ -323,7 +345,7 @@ static i915_reg_t psr_aux_ctl_reg(struct drm_i915_private *dev_priv,
enum transcoder cpu_transcoder)
{
if (DISPLAY_VER(dev_priv) >= 8)
- return EDP_PSR_AUX_CTL(cpu_transcoder);
+ return EDP_PSR_AUX_CTL(dev_priv, cpu_transcoder);
else
return HSW_SRD_AUX_CTL;
}
@@ -332,7 +354,7 @@ static i915_reg_t psr_aux_data_reg(struct drm_i915_private *dev_priv,
enum transcoder cpu_transcoder, int i)
{
if (DISPLAY_VER(dev_priv) >= 8)
- return EDP_PSR_AUX_DATA(cpu_transcoder, i);
+ return EDP_PSR_AUX_DATA(dev_priv, cpu_transcoder, i);
else
return HSW_SRD_AUX_DATA(i);
}
@@ -356,12 +378,12 @@ static void psr_irq_control(struct intel_dp *intel_dp)
}
static void psr_event_print(struct drm_i915_private *i915,
- u32 val, bool psr2_enabled)
+ u32 val, bool sel_update_enabled)
{
drm_dbg_kms(&i915->drm, "PSR exit events: 0x%x\n", val);
if (val & PSR_EVENT_PSR2_WD_TIMER_EXPIRE)
drm_dbg_kms(&i915->drm, "\tPSR2 watchdog timer expired\n");
- if ((val & PSR_EVENT_PSR2_DISABLED) && psr2_enabled)
+ if ((val & PSR_EVENT_PSR2_DISABLED) && sel_update_enabled)
drm_dbg_kms(&i915->drm, "\tPSR2 disabled\n");
if (val & PSR_EVENT_SU_DIRTY_FIFO_UNDERRUN)
drm_dbg_kms(&i915->drm, "\tSU dirty FIFO underrun\n");
@@ -389,7 +411,7 @@ static void psr_event_print(struct drm_i915_private *i915,
drm_dbg_kms(&i915->drm, "\tVBI enabled\n");
if (val & PSR_EVENT_LPSP_MODE_EXIT)
drm_dbg_kms(&i915->drm, "\tLPSP mode exited\n");
- if ((val & PSR_EVENT_PSR_DISABLE) && !psr2_enabled)
+ if ((val & PSR_EVENT_PSR_DISABLE) && !sel_update_enabled)
drm_dbg_kms(&i915->drm, "\tPSR disabled\n");
}
@@ -415,9 +437,11 @@ void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir)
if (DISPLAY_VER(dev_priv) >= 9) {
u32 val;
- val = intel_de_rmw(dev_priv, PSR_EVENT(cpu_transcoder), 0, 0);
+ val = intel_de_rmw(dev_priv,
+ PSR_EVENT(dev_priv, cpu_transcoder),
+ 0, 0);
- psr_event_print(dev_priv, val, intel_dp->psr.psr2_enabled);
+ psr_event_print(dev_priv, val, intel_dp->psr.sel_update_enabled);
}
}
@@ -442,16 +466,6 @@ void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir)
}
}
-static bool intel_dp_get_alpm_status(struct intel_dp *intel_dp)
-{
- u8 alpm_caps = 0;
-
- if (drm_dp_dpcd_readb(&intel_dp->aux, DP_RECEIVER_ALPM_CAP,
- &alpm_caps) != 1)
- return false;
- return alpm_caps & DP_ALPM_CAP;
-}
-
static u8 intel_dp_get_sink_sync_latency(struct intel_dp *intel_dp)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
@@ -466,6 +480,40 @@ static u8 intel_dp_get_sink_sync_latency(struct intel_dp *intel_dp)
return val;
}
+static u8 intel_dp_get_su_capability(struct intel_dp *intel_dp)
+{
+ u8 su_capability = 0;
+
+ if (intel_dp->psr.sink_panel_replay_su_support)
+ drm_dp_dpcd_readb(&intel_dp->aux,
+ DP_PANEL_PANEL_REPLAY_CAPABILITY,
+ &su_capability);
+ else
+ su_capability = intel_dp->psr_dpcd[1];
+
+ return su_capability;
+}
+
+static unsigned int
+intel_dp_get_su_x_granularity_offset(struct intel_dp *intel_dp)
+{
+ return intel_dp->psr.sink_panel_replay_su_support ?
+ DP_PANEL_PANEL_REPLAY_X_GRANULARITY :
+ DP_PSR2_SU_X_GRANULARITY;
+}
+
+static unsigned int
+intel_dp_get_su_y_granularity_offset(struct intel_dp *intel_dp)
+{
+ return intel_dp->psr.sink_panel_replay_su_support ?
+ DP_PANEL_PANEL_REPLAY_Y_GRANULARITY :
+ DP_PSR2_SU_Y_GRANULARITY;
+}
+
+/*
+ * Note: Bits related to granularity are same in panel replay and psr
+ * registers. Rely on PSR definitions on these "common" bits.
+ */
static void intel_dp_get_su_granularity(struct intel_dp *intel_dp)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
@@ -473,18 +521,29 @@ static void intel_dp_get_su_granularity(struct intel_dp *intel_dp)
u16 w;
u8 y;
- /* If sink don't have specific granularity requirements set legacy ones */
- if (!(intel_dp->psr_dpcd[1] & DP_PSR2_SU_GRANULARITY_REQUIRED)) {
+ /*
+ * TODO: Do we need to take into account panel supporting both PSR and
+ * Panel replay?
+ */
+
+ /*
+ * If sink don't have specific granularity requirements set legacy
+ * ones.
+ */
+ if (!(intel_dp_get_su_capability(intel_dp) &
+ DP_PSR2_SU_GRANULARITY_REQUIRED)) {
/* As PSR2 HW sends full lines, we do not care about x granularity */
w = 4;
y = 4;
goto exit;
}
- r = drm_dp_dpcd_read(&intel_dp->aux, DP_PSR2_SU_X_GRANULARITY, &w, 2);
+ r = drm_dp_dpcd_read(&intel_dp->aux,
+ intel_dp_get_su_x_granularity_offset(intel_dp),
+ &w, 2);
if (r != 2)
drm_dbg_kms(&i915->drm,
- "Unable to read DP_PSR2_SU_X_GRANULARITY\n");
+ "Unable to read selective update x granularity\n");
/*
* Spec says that if the value read is 0 the default granularity should
* be used instead.
@@ -492,10 +551,12 @@ static void intel_dp_get_su_granularity(struct intel_dp *intel_dp)
if (r != 2 || w == 0)
w = 4;
- r = drm_dp_dpcd_read(&intel_dp->aux, DP_PSR2_SU_Y_GRANULARITY, &y, 1);
+ r = drm_dp_dpcd_read(&intel_dp->aux,
+ intel_dp_get_su_y_granularity_offset(intel_dp),
+ &y, 1);
if (r != 1) {
drm_dbg_kms(&i915->drm,
- "Unable to read DP_PSR2_SU_Y_GRANULARITY\n");
+ "Unable to read selective update y granularity\n");
y = 4;
}
if (y == 0)
@@ -509,20 +570,16 @@ exit:
static void _panel_replay_init_dpcd(struct intel_dp *intel_dp)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- u8 pr_dpcd = 0;
- intel_dp->psr.sink_panel_replay_support = false;
- drm_dp_dpcd_readb(&intel_dp->aux, DP_PANEL_REPLAY_CAP, &pr_dpcd);
+ intel_dp->psr.sink_panel_replay_support = true;
- if (!(pr_dpcd & DP_PANEL_REPLAY_SUPPORT)) {
- drm_dbg_kms(&i915->drm,
- "Panel replay is not supported by panel\n");
- return;
- }
+ if (intel_dp->pr_dpcd & DP_PANEL_REPLAY_SU_SUPPORT)
+ intel_dp->psr.sink_panel_replay_su_support = true;
drm_dbg_kms(&i915->drm,
- "Panel replay is supported by panel\n");
- intel_dp->psr.sink_panel_replay_support = true;
+ "Panel replay %sis supported by panel\n",
+ intel_dp->psr.sink_panel_replay_su_support ?
+ "selective_update " : "");
}
static void _psr_init_dpcd(struct intel_dp *intel_dp)
@@ -553,7 +610,6 @@ static void _psr_init_dpcd(struct intel_dp *intel_dp)
intel_dp->psr_dpcd[0] >= DP_PSR2_WITH_Y_COORD_IS_SUPPORTED) {
bool y_req = intel_dp->psr_dpcd[1] &
DP_PSR2_SU_Y_COORDINATE_REQUIRED;
- bool alpm = intel_dp_get_alpm_status(intel_dp);
/*
* All panels that supports PSR version 03h (PSR2 +
@@ -566,7 +622,8 @@ static void _psr_init_dpcd(struct intel_dp *intel_dp)
* Y-coordinate requirement panels we would need to enable
* GTC first.
*/
- intel_dp->psr.sink_psr2_support = y_req && alpm;
+ intel_dp->psr.sink_psr2_support = y_req &&
+ intel_alpm_aux_wake_supported(intel_dp);
drm_dbg_kms(&i915->drm, "PSR2 %ssupported\n",
intel_dp->psr.sink_psr2_support ? "" : "not ");
}
@@ -574,15 +631,19 @@ static void _psr_init_dpcd(struct intel_dp *intel_dp)
void intel_psr_init_dpcd(struct intel_dp *intel_dp)
{
- _panel_replay_init_dpcd(intel_dp);
-
drm_dp_dpcd_read(&intel_dp->aux, DP_PSR_SUPPORT, intel_dp->psr_dpcd,
sizeof(intel_dp->psr_dpcd));
+ drm_dp_dpcd_readb(&intel_dp->aux, DP_PANEL_REPLAY_CAP,
+ &intel_dp->pr_dpcd);
+
+ if (intel_dp->pr_dpcd & DP_PANEL_REPLAY_SUPPORT)
+ _panel_replay_init_dpcd(intel_dp);
if (intel_dp->psr_dpcd[0])
_psr_init_dpcd(intel_dp);
- if (intel_dp->psr.sink_psr2_support)
+ if (intel_dp->psr.sink_psr2_support ||
+ intel_dp->psr.sink_panel_replay_su_support)
intel_dp_get_su_granularity(intel_dp);
}
@@ -623,68 +684,76 @@ static void hsw_psr_setup_aux(struct intel_dp *intel_dp)
aux_ctl);
}
-static bool psr2_su_region_et_valid(struct intel_dp *intel_dp)
+static bool psr2_su_region_et_valid(struct intel_dp *intel_dp, bool panel_replay)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- if (DISPLAY_VER(i915) >= 20 &&
- intel_dp->psr_dpcd[0] == DP_PSR2_WITH_Y_COORD_ET_SUPPORTED &&
- !(intel_dp->psr.debug & I915_PSR_DEBUG_SU_REGION_ET_DISABLE))
- return true;
+ if (DISPLAY_VER(i915) < 20 || !intel_dp_is_edp(intel_dp) ||
+ intel_dp->psr.debug & I915_PSR_DEBUG_SU_REGION_ET_DISABLE)
+ return false;
- return false;
+ return panel_replay ?
+ intel_dp->pr_dpcd & DP_PANEL_REPLAY_EARLY_TRANSPORT_SUPPORT :
+ intel_dp->psr_dpcd[0] == DP_PSR2_WITH_Y_COORD_ET_SUPPORTED &&
+ psr2_su_region_et_global_enabled(intel_dp);
}
-static unsigned int intel_psr_get_enable_sink_offset(struct intel_dp *intel_dp)
+static void _panel_replay_enable_sink(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
{
- return intel_dp->psr.panel_replay_enabled ?
- PANEL_REPLAY_CONFIG : DP_PSR_EN_CFG;
-}
+ u8 val = DP_PANEL_REPLAY_ENABLE |
+ DP_PANEL_REPLAY_VSC_SDP_CRC_EN |
+ DP_PANEL_REPLAY_UNRECOVERABLE_ERROR_EN |
+ DP_PANEL_REPLAY_RFB_STORAGE_ERROR_EN |
+ DP_PANEL_REPLAY_ACTIVE_FRAME_CRC_ERROR_EN;
-/*
- * Note: Most of the bits are same in PANEL_REPLAY_CONFIG and DP_PSR_EN_CFG. We
- * are relying on PSR definitions on these "common" bits.
- */
-void intel_psr_enable_sink(struct intel_dp *intel_dp,
- const struct intel_crtc_state *crtc_state)
-{
- struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
- u8 dpcd_val = DP_PSR_ENABLE;
+ if (crtc_state->has_sel_update)
+ val |= DP_PANEL_REPLAY_SU_ENABLE;
- if (crtc_state->has_psr2) {
- /* Enable ALPM at sink for psr2 */
- if (!crtc_state->has_panel_replay) {
- drm_dp_dpcd_writeb(&intel_dp->aux,
- DP_RECEIVER_ALPM_CONFIG,
- DP_ALPM_ENABLE |
- DP_ALPM_LOCK_ERROR_IRQ_HPD_ENABLE);
+ if (crtc_state->enable_psr2_su_region_et)
+ val |= DP_PANEL_REPLAY_ENABLE_SU_REGION_ET;
- if (psr2_su_region_et_valid(intel_dp))
- dpcd_val |= DP_PSR_ENABLE_SU_REGION_ET;
- }
+ drm_dp_dpcd_writeb(&intel_dp->aux, PANEL_REPLAY_CONFIG, val);
+}
+
+static void _psr_enable_sink(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ u8 val = DP_PSR_ENABLE;
- dpcd_val |= DP_PSR_ENABLE_PSR2 | DP_PSR_IRQ_HPD_WITH_CRC_ERRORS;
+ if (crtc_state->has_sel_update) {
+ val |= DP_PSR_ENABLE_PSR2 | DP_PSR_IRQ_HPD_WITH_CRC_ERRORS;
} else {
if (intel_dp->psr.link_standby)
- dpcd_val |= DP_PSR_MAIN_LINK_ACTIVE;
+ val |= DP_PSR_MAIN_LINK_ACTIVE;
- if (!crtc_state->has_panel_replay && DISPLAY_VER(dev_priv) >= 8)
- dpcd_val |= DP_PSR_CRC_VERIFICATION;
+ if (DISPLAY_VER(i915) >= 8)
+ val |= DP_PSR_CRC_VERIFICATION;
}
- if (crtc_state->has_panel_replay)
- dpcd_val |= DP_PANEL_REPLAY_UNRECOVERABLE_ERROR_EN |
- DP_PANEL_REPLAY_RFB_STORAGE_ERROR_EN;
-
- if (crtc_state->req_psr2_sdp_prior_scanline)
- dpcd_val |= DP_PSR_SU_REGION_SCANLINE_CAPTURE;
+ if (crtc_state->enable_psr2_su_region_et)
+ val |= DP_PANEL_REPLAY_ENABLE_SU_REGION_ET;
if (intel_dp->psr.entry_setup_frames > 0)
- dpcd_val |= DP_PSR_FRAME_CAPTURE;
+ val |= DP_PSR_FRAME_CAPTURE;
- drm_dp_dpcd_writeb(&intel_dp->aux,
- intel_psr_get_enable_sink_offset(intel_dp),
- dpcd_val);
+ drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, val);
+}
+
+void intel_psr_enable_sink(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
+{
+ /* Enable ALPM at sink for psr2 */
+ if (!crtc_state->has_panel_replay && crtc_state->has_sel_update)
+ drm_dp_dpcd_writeb(&intel_dp->aux,
+ DP_RECEIVER_ALPM_CONFIG,
+ DP_ALPM_ENABLE |
+ DP_ALPM_LOCK_ERROR_IRQ_HPD_ENABLE);
+
+ crtc_state->has_panel_replay ?
+ _panel_replay_enable_sink(intel_dp, crtc_state) :
+ _psr_enable_sink(intel_dp, crtc_state);
if (intel_dp_is_edp(intel_dp))
drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
@@ -814,8 +883,8 @@ static u32 intel_psr2_get_tp_time(struct intel_dp *intel_dp)
static int psr2_block_count_lines(struct intel_dp *intel_dp)
{
- return intel_dp->psr.alpm_parameters.io_wake_lines < 9 &&
- intel_dp->psr.alpm_parameters.fast_wake_lines < 9 ? 8 : 12;
+ return intel_dp->alpm_parameters.io_wake_lines < 9 &&
+ intel_dp->alpm_parameters.fast_wake_lines < 9 ? 8 : 12;
}
static int psr2_block_count(struct intel_dp *intel_dp)
@@ -842,7 +911,8 @@ static void dg2_activate_panel_replay(struct intel_dp *intel_dp)
{
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
- intel_de_rmw(dev_priv, PSR2_MAN_TRK_CTL(intel_dp->psr.transcoder),
+ intel_de_rmw(dev_priv,
+ PSR2_MAN_TRK_CTL(dev_priv, intel_dp->psr.transcoder),
0, ADLP_PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME);
intel_de_rmw(dev_priv, TRANS_DP2_CTL(intel_dp->psr.transcoder), 0,
@@ -852,7 +922,6 @@ static void dg2_activate_panel_replay(struct intel_dp *intel_dp)
static void hsw_activate_psr2(struct intel_dp *intel_dp)
{
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
- struct intel_psr *psr = &intel_dp->psr;
enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
u32 val = EDP_PSR2_ENABLE;
u32 psr_val = 0;
@@ -869,7 +938,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
val |= intel_psr2_get_tp_time(intel_dp);
- if (DISPLAY_VER(dev_priv) >= 12) {
+ if (DISPLAY_VER(dev_priv) >= 12 && DISPLAY_VER(dev_priv) < 20) {
if (psr2_block_count(intel_dp) > 2)
val |= TGL_EDP_PSR2_BLOCK_COUNT_NUM_3;
else
@@ -894,18 +963,20 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
*/
int tmp;
- tmp = map[psr->alpm_parameters.io_wake_lines -
+ tmp = map[intel_dp->alpm_parameters.io_wake_lines -
TGL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES];
val |= TGL_EDP_PSR2_IO_BUFFER_WAKE(tmp + TGL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES);
- tmp = map[psr->alpm_parameters.fast_wake_lines - TGL_EDP_PSR2_FAST_WAKE_MIN_LINES];
+ tmp = map[intel_dp->alpm_parameters.fast_wake_lines - TGL_EDP_PSR2_FAST_WAKE_MIN_LINES];
val |= TGL_EDP_PSR2_FAST_WAKE(tmp + TGL_EDP_PSR2_FAST_WAKE_MIN_LINES);
+ } else if (DISPLAY_VER(dev_priv) >= 20) {
+ val |= LNL_EDP_PSR2_IO_BUFFER_WAKE(intel_dp->alpm_parameters.io_wake_lines);
} else if (DISPLAY_VER(dev_priv) >= 12) {
- val |= TGL_EDP_PSR2_IO_BUFFER_WAKE(psr->alpm_parameters.io_wake_lines);
- val |= TGL_EDP_PSR2_FAST_WAKE(psr->alpm_parameters.fast_wake_lines);
+ val |= TGL_EDP_PSR2_IO_BUFFER_WAKE(intel_dp->alpm_parameters.io_wake_lines);
+ val |= TGL_EDP_PSR2_FAST_WAKE(intel_dp->alpm_parameters.fast_wake_lines);
} else if (DISPLAY_VER(dev_priv) >= 9) {
- val |= EDP_PSR2_IO_BUFFER_WAKE(psr->alpm_parameters.io_wake_lines);
- val |= EDP_PSR2_FAST_WAKE(psr->alpm_parameters.fast_wake_lines);
+ val |= EDP_PSR2_IO_BUFFER_WAKE(intel_dp->alpm_parameters.io_wake_lines);
+ val |= EDP_PSR2_FAST_WAKE(intel_dp->alpm_parameters.fast_wake_lines);
}
if (intel_dp->psr.req_psr2_sdp_prior_scanline)
@@ -917,13 +988,15 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
if (intel_dp->psr.psr2_sel_fetch_enabled) {
u32 tmp;
- tmp = intel_de_read(dev_priv, PSR2_MAN_TRK_CTL(cpu_transcoder));
+ tmp = intel_de_read(dev_priv,
+ PSR2_MAN_TRK_CTL(dev_priv, cpu_transcoder));
drm_WARN_ON(&dev_priv->drm, !(tmp & PSR2_MAN_TRK_CTL_ENABLE));
} else if (HAS_PSR2_SEL_FETCH(dev_priv)) {
- intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(cpu_transcoder), 0);
+ intel_de_write(dev_priv,
+ PSR2_MAN_TRK_CTL(dev_priv, cpu_transcoder), 0);
}
- if (psr2_su_region_et_valid(intel_dp))
+ if (intel_dp->psr.su_region_et_enabled)
val |= LNL_EDP_PSR2_SU_REGION_ET_ENABLE;
/*
@@ -932,7 +1005,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
*/
intel_de_write(dev_priv, psr_ctl_reg(dev_priv, cpu_transcoder), psr_val);
- intel_de_write(dev_priv, EDP_PSR2_CTL(cpu_transcoder), val);
+ intel_de_write(dev_priv, EDP_PSR2_CTL(dev_priv, cpu_transcoder), val);
}
static bool
@@ -963,7 +1036,7 @@ static void psr2_program_idle_frames(struct intel_dp *intel_dp,
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
- intel_de_rmw(dev_priv, EDP_PSR2_CTL(cpu_transcoder),
+ intel_de_rmw(dev_priv, EDP_PSR2_CTL(dev_priv, cpu_transcoder),
EDP_PSR2_IDLE_FRAMES_MASK,
EDP_PSR2_IDLE_FRAMES(idle_frames));
}
@@ -1088,9 +1161,6 @@ static bool intel_psr2_sel_fetch_config_valid(struct intel_dp *intel_dp,
return false;
}
- if (psr2_su_region_et_valid(intel_dp))
- crtc_state->enable_psr2_su_region_et = true;
-
return crtc_state->enable_psr2_sel_fetch = true;
}
@@ -1161,237 +1231,6 @@ static bool _compute_psr2_sdp_prior_scanline_indication(struct intel_dp *intel_d
return true;
}
-/*
- * See Bspec: 71632 for the table
- *
- * Silence_period = tSilence,Min + ((tSilence,Max - tSilence,Min) / 2)
- *
- * Half cycle duration:
- *
- * Link rates 1.62 - 4.32 and tLFPS_Cycle = 70 ns
- * FLOOR( (Link Rate * tLFPS_Cycle) / (2 * 10) )
- *
- * Link rates 5.4 - 8.1
- * PORT_ALPM_LFPS_CTL[ LFPS Cycle Count ] = 10
- * LFPS Period chosen is the mid-point of the min:max values from the table
- * FLOOR( LFPS Period in Symbol clocks /
- * (2 * PORT_ALPM_LFPS_CTL[ LFPS Cycle Count ]) )
- */
-static bool _lnl_get_silence_period_and_lfps_half_cycle(int link_rate,
- int *silence_period,
- int *lfps_half_cycle)
-{
- switch (link_rate) {
- case 162000:
- *silence_period = 20;
- *lfps_half_cycle = 5;
- break;
- case 216000:
- *silence_period = 27;
- *lfps_half_cycle = 7;
- break;
- case 243000:
- *silence_period = 31;
- *lfps_half_cycle = 8;
- break;
- case 270000:
- *silence_period = 34;
- *lfps_half_cycle = 9;
- break;
- case 324000:
- *silence_period = 41;
- *lfps_half_cycle = 11;
- break;
- case 432000:
- *silence_period = 56;
- *lfps_half_cycle = 15;
- break;
- case 540000:
- *silence_period = 69;
- *lfps_half_cycle = 12;
- break;
- case 648000:
- *silence_period = 84;
- *lfps_half_cycle = 15;
- break;
- case 675000:
- *silence_period = 87;
- *lfps_half_cycle = 15;
- break;
- case 810000:
- *silence_period = 104;
- *lfps_half_cycle = 19;
- break;
- default:
- *silence_period = *lfps_half_cycle = -1;
- return false;
- }
- return true;
-}
-
-/*
- * AUX-Less Wake Time = CEILING( ((PHY P2 to P0) + tLFPS_Period, Max+
- * tSilence, Max+ tPHY Establishment + tCDS) / tline)
- * For the "PHY P2 to P0" latency see the PHY Power Control page
- * (PHY P2 to P0) : https://gfxspecs.intel.com/Predator/Home/Index/68965
- * : 12 us
- * The tLFPS_Period, Max term is 800ns
- * The tSilence, Max term is 180ns
- * The tPHY Establishment (a.k.a. t1) term is 50us
- * The tCDS term is 1 or 2 times t2
- * t2 = Number ML_PHY_LOCK * tML_PHY_LOCK
- * Number ML_PHY_LOCK = ( 7 + CEILING( 6.5us / tML_PHY_LOCK ) + 1)
- * Rounding up the 6.5us padding to the next ML_PHY_LOCK boundary and
- * adding the "+ 1" term ensures all ML_PHY_LOCK sequences that start
- * within the CDS period complete within the CDS period regardless of
- * entry into the period
- * tML_PHY_LOCK = TPS4 Length * ( 10 / (Link Rate in MHz) )
- * TPS4 Length = 252 Symbols
- */
-static int _lnl_compute_aux_less_wake_time(int port_clock)
-{
- int tphy2_p2_to_p0 = 12 * 1000;
- int tlfps_period_max = 800;
- int tsilence_max = 180;
- int t1 = 50 * 1000;
- int tps4 = 252;
- int tml_phy_lock = 1000 * 1000 * tps4 * 10 / port_clock;
- int num_ml_phy_lock = 7 + DIV_ROUND_UP(6500, tml_phy_lock) + 1;
- int t2 = num_ml_phy_lock * tml_phy_lock;
- int tcds = 1 * t2;
-
- return DIV_ROUND_UP(tphy2_p2_to_p0 + tlfps_period_max + tsilence_max +
- t1 + tcds, 1000);
-}
-
-static int _lnl_compute_aux_less_alpm_params(struct intel_dp *intel_dp,
- struct intel_crtc_state *crtc_state)
-{
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- int aux_less_wake_time, aux_less_wake_lines, silence_period,
- lfps_half_cycle;
-
- aux_less_wake_time =
- _lnl_compute_aux_less_wake_time(crtc_state->port_clock);
- aux_less_wake_lines = intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode,
- aux_less_wake_time);
-
- if (!_lnl_get_silence_period_and_lfps_half_cycle(crtc_state->port_clock,
- &silence_period,
- &lfps_half_cycle))
- return false;
-
- if (aux_less_wake_lines > ALPM_CTL_AUX_LESS_WAKE_TIME_MASK ||
- silence_period > PORT_ALPM_CTL_SILENCE_PERIOD_MASK ||
- lfps_half_cycle > PORT_ALPM_LFPS_CTL_LAST_LFPS_HALF_CYCLE_DURATION_MASK)
- return false;
-
- if (i915->display.params.psr_safest_params)
- aux_less_wake_lines = ALPM_CTL_AUX_LESS_WAKE_TIME_MASK;
-
- intel_dp->psr.alpm_parameters.fast_wake_lines = aux_less_wake_lines;
- intel_dp->psr.alpm_parameters.silence_period_sym_clocks = silence_period;
- intel_dp->psr.alpm_parameters.lfps_half_cycle_num_of_syms = lfps_half_cycle;
-
- return true;
-}
-
-static bool _lnl_compute_alpm_params(struct intel_dp *intel_dp,
- struct intel_crtc_state *crtc_state)
-{
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- int check_entry_lines;
-
- if (DISPLAY_VER(i915) < 20)
- return true;
-
- /* ALPM Entry Check = 2 + CEILING( 5us /tline ) */
- check_entry_lines = 2 +
- intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, 5);
-
- if (check_entry_lines > 15)
- return false;
-
- if (!_lnl_compute_aux_less_alpm_params(intel_dp, crtc_state))
- return false;
-
- if (i915->display.params.psr_safest_params)
- check_entry_lines = 15;
-
- intel_dp->psr.alpm_parameters.check_entry_lines = check_entry_lines;
-
- return true;
-}
-
-/*
- * IO wake time for DISPLAY_VER < 12 is not directly mentioned in Bspec. There
- * are 50 us io wake time and 32 us fast wake time. Clearly preharge pulses are
- * not (improperly) included in 32 us fast wake time. 50 us - 32 us = 18 us.
- */
-static int skl_io_buffer_wake_time(void)
-{
- return 18;
-}
-
-static int tgl_io_buffer_wake_time(void)
-{
- return 10;
-}
-
-static int io_buffer_wake_time(const struct intel_crtc_state *crtc_state)
-{
- struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
-
- if (DISPLAY_VER(i915) >= 12)
- return tgl_io_buffer_wake_time();
- else
- return skl_io_buffer_wake_time();
-}
-
-static bool _compute_alpm_params(struct intel_dp *intel_dp,
- struct intel_crtc_state *crtc_state)
-{
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- int io_wake_lines, io_wake_time, fast_wake_lines, fast_wake_time;
- int tfw_exit_latency = 20; /* eDP spec */
- int phy_wake = 4; /* eDP spec */
- int preamble = 8; /* eDP spec */
- int precharge = intel_dp_aux_fw_sync_len() - preamble;
- u8 max_wake_lines;
-
- io_wake_time = max(precharge, io_buffer_wake_time(crtc_state)) +
- preamble + phy_wake + tfw_exit_latency;
- fast_wake_time = precharge + preamble + phy_wake +
- tfw_exit_latency;
-
- if (DISPLAY_VER(i915) >= 12)
- /* TODO: Check how we can use ALPM_CTL fast wake extended field */
- max_wake_lines = 12;
- else
- max_wake_lines = 8;
-
- io_wake_lines = intel_usecs_to_scanlines(
- &crtc_state->hw.adjusted_mode, io_wake_time);
- fast_wake_lines = intel_usecs_to_scanlines(
- &crtc_state->hw.adjusted_mode, fast_wake_time);
-
- if (io_wake_lines > max_wake_lines ||
- fast_wake_lines > max_wake_lines)
- return false;
-
- if (!_lnl_compute_alpm_params(intel_dp, crtc_state))
- return false;
-
- if (i915->display.params.psr_safest_params)
- io_wake_lines = fast_wake_lines = max_wake_lines;
-
- /* According to Bspec lower limit should be set as 7 lines. */
- intel_dp->psr.alpm_parameters.io_wake_lines = max(io_wake_lines, 7);
- intel_dp->psr.alpm_parameters.fast_wake_lines = max(fast_wake_lines, 7);
-
- return true;
-}
-
static int intel_psr_entry_setup_frames(struct intel_dp *intel_dp,
const struct drm_display_mode *adjusted_mode)
{
@@ -1425,6 +1264,31 @@ static int intel_psr_entry_setup_frames(struct intel_dp *intel_dp,
return entry_setup_frames;
}
+static bool wake_lines_fit_into_vblank(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ int vblank = crtc_state->hw.adjusted_mode.crtc_vblank_end -
+ crtc_state->hw.adjusted_mode.crtc_vblank_start;
+ int wake_lines;
+
+ if (crtc_state->has_panel_replay)
+ wake_lines = intel_dp->alpm_parameters.aux_less_wake_lines;
+ else
+ wake_lines = DISPLAY_VER(i915) < 20 ?
+ psr2_block_count_lines(intel_dp) :
+ intel_dp->alpm_parameters.io_wake_lines;
+
+ if (crtc_state->req_psr2_sdp_prior_scanline)
+ vblank -= 1;
+
+ /* Vblank >= PSR2_CTL Block Count Number maximum line count */
+ if (vblank < wake_lines)
+ return false;
+
+ return true;
+}
+
static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
struct intel_crtc_state *crtc_state)
{
@@ -1461,11 +1325,6 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
return false;
}
- if (!psr2_global_enabled(intel_dp)) {
- drm_dbg_kms(&dev_priv->drm, "PSR2 disabled by flag\n");
- return false;
- }
-
/*
* DSC and PSR2 cannot be enabled simultaneously. If a requested
* resolution requires DSC to be enabled, priority is given to DSC
@@ -1478,12 +1337,6 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
return false;
}
- if (crtc_state->crc_enabled) {
- drm_dbg_kms(&dev_priv->drm,
- "PSR2 not enabled because it would inhibit pipe CRC calculation\n");
- return false;
- }
-
if (DISPLAY_VER(dev_priv) >= 12) {
psr_max_h = 5120;
psr_max_v = 3200;
@@ -1519,45 +1372,73 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
return false;
}
- if (!_compute_alpm_params(intel_dp, crtc_state)) {
+ if (!intel_alpm_compute_params(intel_dp, crtc_state)) {
drm_dbg_kms(&dev_priv->drm,
"PSR2 not enabled, Unable to use long enough wake times\n");
return false;
}
/* Vblank >= PSR2_CTL Block Count Number maximum line count */
- if (crtc_state->hw.adjusted_mode.crtc_vblank_end -
- crtc_state->hw.adjusted_mode.crtc_vblank_start <
- psr2_block_count_lines(intel_dp)) {
+ if (!wake_lines_fit_into_vblank(intel_dp, crtc_state)) {
drm_dbg_kms(&dev_priv->drm,
"PSR2 not enabled, too short vblank time\n");
return false;
}
- if (HAS_PSR2_SEL_FETCH(dev_priv)) {
- if (!intel_psr2_sel_fetch_config_valid(intel_dp, crtc_state) &&
- !HAS_PSR_HW_TRACKING(dev_priv)) {
- drm_dbg_kms(&dev_priv->drm,
- "PSR2 not enabled, selective fetch not valid and no HW tracking available\n");
- return false;
- }
- }
-
- if (!psr2_granularity_check(intel_dp, crtc_state)) {
- drm_dbg_kms(&dev_priv->drm, "PSR2 not enabled, SU granularity not compatible\n");
- goto unsupported;
- }
-
if (!crtc_state->enable_psr2_sel_fetch &&
(crtc_hdisplay > psr_max_h || crtc_vdisplay > psr_max_v)) {
drm_dbg_kms(&dev_priv->drm,
"PSR2 not enabled, resolution %dx%d > max supported %dx%d\n",
crtc_hdisplay, crtc_vdisplay,
psr_max_h, psr_max_v);
- goto unsupported;
+ return false;
}
tgl_dc3co_exitline_compute_config(intel_dp, crtc_state);
+
+ if (psr2_su_region_et_valid(intel_dp, crtc_state->has_panel_replay))
+ crtc_state->enable_psr2_su_region_et = true;
+
+ return true;
+}
+
+static bool intel_sel_update_config_valid(struct intel_dp *intel_dp,
+ struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+
+ if (HAS_PSR2_SEL_FETCH(dev_priv) &&
+ !intel_psr2_sel_fetch_config_valid(intel_dp, crtc_state) &&
+ !HAS_PSR_HW_TRACKING(dev_priv)) {
+ drm_dbg_kms(&dev_priv->drm,
+ "Selective update not enabled, selective fetch not valid and no HW tracking available\n");
+ goto unsupported;
+ }
+
+ if (!psr2_global_enabled(intel_dp)) {
+ drm_dbg_kms(&dev_priv->drm, "Selective update disabled by flag\n");
+ goto unsupported;
+ }
+
+ if (!crtc_state->has_panel_replay && !intel_psr2_config_valid(intel_dp, crtc_state))
+ goto unsupported;
+
+ if (crtc_state->has_panel_replay && (DISPLAY_VER(dev_priv) < 14 ||
+ !intel_dp->psr.sink_panel_replay_su_support))
+ goto unsupported;
+
+ if (crtc_state->crc_enabled) {
+ drm_dbg_kms(&dev_priv->drm,
+ "Selective update not enabled because it would inhibit pipe CRC calculation\n");
+ goto unsupported;
+ }
+
+ if (!psr2_granularity_check(intel_dp, crtc_state)) {
+ drm_dbg_kms(&dev_priv->drm,
+ "Selective update not enabled, SU granularity not compatible\n");
+ goto unsupported;
+ }
+
return true;
unsupported:
@@ -1595,6 +1476,21 @@ static bool _psr_compute_config(struct intel_dp *intel_dp,
return true;
}
+static bool _panel_replay_compute_config(struct intel_dp *intel_dp)
+{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+
+ if (!CAN_PANEL_REPLAY(intel_dp))
+ return false;
+
+ if (!panel_replay_global_enabled(intel_dp)) {
+ drm_dbg_kms(&i915->drm, "Panel Replay disabled by flag\n");
+ return false;
+ }
+
+ return true;
+}
+
void intel_psr_compute_config(struct intel_dp *intel_dp,
struct intel_crtc_state *crtc_state,
struct drm_connector_state *conn_state)
@@ -1620,18 +1516,17 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
}
/*
- * FIXME figure out what is wrong with PSR+bigjoiner and
+ * FIXME figure out what is wrong with PSR+joiner and
* fix it. Presumably something related to the fact that
* PSR is a transcoder level feature.
*/
- if (crtc_state->bigjoiner_pipes) {
+ if (crtc_state->joiner_pipes) {
drm_dbg_kms(&dev_priv->drm,
- "PSR disabled due to bigjoiner\n");
+ "PSR disabled due to joiner\n");
return;
}
- if (CAN_PANEL_REPLAY(intel_dp))
- crtc_state->has_panel_replay = true;
+ crtc_state->has_panel_replay = _panel_replay_compute_config(intel_dp);
crtc_state->has_psr = crtc_state->has_panel_replay ? true :
_psr_compute_config(intel_dp, crtc_state);
@@ -1639,7 +1534,7 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
if (!crtc_state->has_psr)
return;
- crtc_state->has_psr2 = intel_psr2_config_valid(intel_dp, crtc_state);
+ crtc_state->has_sel_update = intel_sel_update_config_valid(intel_dp, crtc_state);
}
void intel_psr_get_config(struct intel_encoder *encoder,
@@ -1672,20 +1567,24 @@ void intel_psr_get_config(struct intel_encoder *encoder,
pipe_config->has_psr = true;
}
- pipe_config->has_psr2 = intel_dp->psr.psr2_enabled;
+ pipe_config->has_sel_update = intel_dp->psr.sel_update_enabled;
pipe_config->infoframes.enable |= intel_hdmi_infoframe_enable(DP_SDP_VSC);
- if (!intel_dp->psr.psr2_enabled)
+ if (!intel_dp->psr.sel_update_enabled)
goto unlock;
if (HAS_PSR2_SEL_FETCH(dev_priv)) {
- val = intel_de_read(dev_priv, PSR2_MAN_TRK_CTL(cpu_transcoder));
+ val = intel_de_read(dev_priv,
+ PSR2_MAN_TRK_CTL(dev_priv, cpu_transcoder));
if (val & PSR2_MAN_TRK_CTL_ENABLE)
pipe_config->enable_psr2_sel_fetch = true;
}
+ pipe_config->enable_psr2_su_region_et = intel_dp->psr.su_region_et_enabled;
+
if (DISPLAY_VER(dev_priv) >= 12) {
- val = intel_de_read(dev_priv, TRANS_EXITLINE(cpu_transcoder));
+ val = intel_de_read(dev_priv,
+ TRANS_EXITLINE(dev_priv, cpu_transcoder));
pipe_config->dc3co_exitline = REG_FIELD_GET(EXITLINE_MASK, val);
}
unlock:
@@ -1699,7 +1598,7 @@ static void intel_psr_activate(struct intel_dp *intel_dp)
drm_WARN_ON(&dev_priv->drm,
transcoder_has_psr2(dev_priv, cpu_transcoder) &&
- intel_de_read(dev_priv, EDP_PSR2_CTL(cpu_transcoder)) & EDP_PSR2_ENABLE);
+ intel_de_read(dev_priv, EDP_PSR2_CTL(dev_priv, cpu_transcoder)) & EDP_PSR2_ENABLE);
drm_WARN_ON(&dev_priv->drm,
intel_de_read(dev_priv, psr_ctl_reg(dev_priv, cpu_transcoder)) & EDP_PSR_ENABLE);
@@ -1711,7 +1610,7 @@ static void intel_psr_activate(struct intel_dp *intel_dp)
/* psr1, psr2 and panel-replay are mutually exclusive.*/
if (intel_dp->psr.panel_replay_enabled)
dg2_activate_panel_replay(intel_dp);
- else if (intel_dp->psr.psr2_enabled)
+ else if (intel_dp->psr.sel_update_enabled)
hsw_activate_psr2(intel_dp);
else
hsw_activate_psr1(intel_dp);
@@ -1763,51 +1662,6 @@ static void wm_optimization_wa(struct intel_dp *intel_dp,
wa_16013835468_bit_get(intel_dp), 0);
}
-static void lnl_alpm_configure(struct intel_dp *intel_dp)
-{
- struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
- enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
- struct intel_psr *psr = &intel_dp->psr;
- u32 alpm_ctl;
-
- if (DISPLAY_VER(dev_priv) < 20 || (!intel_dp->psr.psr2_enabled &&
- !intel_dp_is_edp(intel_dp)))
- return;
-
- /*
- * Panel Replay on eDP is always using ALPM aux less. I.e. no need to
- * check panel support at this point.
- */
- if (intel_dp->psr.panel_replay_enabled && intel_dp_is_edp(intel_dp)) {
- alpm_ctl = ALPM_CTL_ALPM_ENABLE |
- ALPM_CTL_ALPM_AUX_LESS_ENABLE |
- ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_50_SYMBOLS;
-
- intel_de_write(dev_priv, PORT_ALPM_CTL(cpu_transcoder),
- PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE |
- PORT_ALPM_CTL_MAX_PHY_SWING_SETUP(15) |
- PORT_ALPM_CTL_MAX_PHY_SWING_HOLD(0) |
- PORT_ALPM_CTL_SILENCE_PERIOD(
- psr->alpm_parameters.silence_period_sym_clocks));
-
- intel_de_write(dev_priv, PORT_ALPM_LFPS_CTL(cpu_transcoder),
- PORT_ALPM_LFPS_CTL_LFPS_CYCLE_COUNT(10) |
- PORT_ALPM_LFPS_CTL_LFPS_HALF_CYCLE_DURATION(
- psr->alpm_parameters.lfps_half_cycle_num_of_syms) |
- PORT_ALPM_LFPS_CTL_FIRST_LFPS_HALF_CYCLE_DURATION(
- psr->alpm_parameters.lfps_half_cycle_num_of_syms) |
- PORT_ALPM_LFPS_CTL_LAST_LFPS_HALF_CYCLE_DURATION(
- psr->alpm_parameters.lfps_half_cycle_num_of_syms));
- } else {
- alpm_ctl = ALPM_CTL_EXTENDED_FAST_WAKE_ENABLE |
- ALPM_CTL_EXTENDED_FAST_WAKE_TIME(psr->alpm_parameters.fast_wake_lines);
- }
-
- alpm_ctl |= ALPM_CTL_ALPM_ENTRY_CHECK(psr->alpm_parameters.check_entry_lines);
-
- intel_de_write(dev_priv, ALPM_CTL(cpu_transcoder), alpm_ctl);
-}
-
static void intel_psr_enable_source(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{
@@ -1877,7 +1731,9 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
* transcoder, EXITLINE will need to be unset when disabling PSR
*/
if (intel_dp->psr.dc3co_exitline)
- intel_de_rmw(dev_priv, TRANS_EXITLINE(cpu_transcoder), EXITLINE_MASK,
+ intel_de_rmw(dev_priv,
+ TRANS_EXITLINE(dev_priv, cpu_transcoder),
+ EXITLINE_MASK,
intel_dp->psr.dc3co_exitline << EXITLINE_SHIFT | EXITLINE_ENABLE);
if (HAS_PSR_HW_TRACKING(dev_priv) && HAS_PSR2_SEL_FETCH(dev_priv))
@@ -1886,7 +1742,7 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
IGNORE_PSR2_HW_TRACKING : 0);
if (intel_dp_is_edp(intel_dp))
- lnl_alpm_configure(intel_dp);
+ intel_alpm_configure(intel_dp, crtc_state);
/*
* Wa_16013835468
@@ -1894,7 +1750,7 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
*/
wm_optimization_wa(intel_dp, crtc_state);
- if (intel_dp->psr.psr2_enabled) {
+ if (intel_dp->psr.sel_update_enabled) {
if (DISPLAY_VER(dev_priv) == 9)
intel_de_rmw(dev_priv, CHICKEN_TRANS(cpu_transcoder), 0,
PSR2_VSC_ENABLE_PROG_HEADER |
@@ -1905,15 +1761,18 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
* All supported adlp panels have 1-based X granularity, this may
* cause issues if non-supported panels are used.
*/
- if (IS_DISPLAY_IP_STEP(dev_priv, IP_VER(14, 0), STEP_A0, STEP_B0) ||
- IS_ALDERLAKE_P(dev_priv))
+ if (!intel_dp->psr.panel_replay_enabled &&
+ (IS_DISPLAY_IP_STEP(dev_priv, IP_VER(14, 0), STEP_A0, STEP_B0) ||
+ IS_ALDERLAKE_P(dev_priv)))
intel_de_rmw(dev_priv, hsw_chicken_trans_reg(dev_priv, cpu_transcoder),
0, ADLP_1_BASED_X_GRANULARITY);
/* Wa_16012604467:adlp,mtl[a0,b0] */
- if (IS_DISPLAY_IP_STEP(dev_priv, IP_VER(14, 0), STEP_A0, STEP_B0))
+ if (!intel_dp->psr.panel_replay_enabled &&
+ IS_DISPLAY_IP_STEP(dev_priv, IP_VER(14, 0), STEP_A0, STEP_B0))
intel_de_rmw(dev_priv,
- MTL_CLKGATE_DIS_TRANS(cpu_transcoder), 0,
+ MTL_CLKGATE_DIS_TRANS(dev_priv, cpu_transcoder),
+ 0,
MTL_CLKGATE_DIS_TRANS_DMASC_GATING_DIS);
else if (IS_ALDERLAKE_P(dev_priv))
intel_de_rmw(dev_priv, CLKGATE_DIS_MISC, 0,
@@ -1960,7 +1819,7 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp,
drm_WARN_ON(&dev_priv->drm, intel_dp->psr.enabled);
- intel_dp->psr.psr2_enabled = crtc_state->has_psr2;
+ intel_dp->psr.sel_update_enabled = crtc_state->has_sel_update;
intel_dp->psr.panel_replay_enabled = crtc_state->has_panel_replay;
intel_dp->psr.busy_frontbuffer_bits = 0;
intel_dp->psr.pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
@@ -1970,6 +1829,7 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp,
intel_dp->psr.dc3co_exit_delay = val;
intel_dp->psr.dc3co_exitline = crtc_state->dc3co_exitline;
intel_dp->psr.psr2_sel_fetch_enabled = crtc_state->enable_psr2_sel_fetch;
+ intel_dp->psr.su_region_et_enabled = crtc_state->enable_psr2_su_region_et;
intel_dp->psr.psr2_sel_fetch_cff_enabled = false;
intel_dp->psr.req_psr2_sdp_prior_scanline =
crtc_state->req_psr2_sdp_prior_scanline;
@@ -1981,7 +1841,7 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp,
drm_dbg_kms(&dev_priv->drm, "Enabling Panel Replay\n");
} else {
drm_dbg_kms(&dev_priv->drm, "Enabling PSR%s\n",
- intel_dp->psr.psr2_enabled ? "2" : "1");
+ intel_dp->psr.sel_update_enabled ? "2" : "1");
/*
* Panel replay has to be enabled before link training: doing it
@@ -2008,7 +1868,8 @@ static void intel_psr_exit(struct intel_dp *intel_dp)
if (!intel_dp->psr.active) {
if (transcoder_has_psr2(dev_priv, cpu_transcoder)) {
- val = intel_de_read(dev_priv, EDP_PSR2_CTL(cpu_transcoder));
+ val = intel_de_read(dev_priv,
+ EDP_PSR2_CTL(dev_priv, cpu_transcoder));
drm_WARN_ON(&dev_priv->drm, val & EDP_PSR2_ENABLE);
}
@@ -2021,10 +1882,11 @@ static void intel_psr_exit(struct intel_dp *intel_dp)
if (intel_dp->psr.panel_replay_enabled) {
intel_de_rmw(dev_priv, TRANS_DP2_CTL(intel_dp->psr.transcoder),
TRANS_DP2_PANEL_REPLAY_ENABLE, 0);
- } else if (intel_dp->psr.psr2_enabled) {
+ } else if (intel_dp->psr.sel_update_enabled) {
tgl_disallow_dc3co_on_psr2_exit(intel_dp);
- val = intel_de_rmw(dev_priv, EDP_PSR2_CTL(cpu_transcoder),
+ val = intel_de_rmw(dev_priv,
+ EDP_PSR2_CTL(dev_priv, cpu_transcoder),
EDP_PSR2_ENABLE, 0);
drm_WARN_ON(&dev_priv->drm, !(val & EDP_PSR2_ENABLE));
@@ -2044,8 +1906,9 @@ static void intel_psr_wait_exit_locked(struct intel_dp *intel_dp)
i915_reg_t psr_status;
u32 psr_status_mask;
- if (intel_dp->psr.psr2_enabled) {
- psr_status = EDP_PSR2_STATUS(cpu_transcoder);
+ if (intel_dp_is_edp(intel_dp) && (intel_dp->psr.sel_update_enabled ||
+ intel_dp->psr.panel_replay_enabled)) {
+ psr_status = EDP_PSR2_STATUS(dev_priv, cpu_transcoder);
psr_status_mask = EDP_PSR2_STATUS_STATE_MASK;
} else {
psr_status = psr_status_reg(dev_priv, cpu_transcoder);
@@ -2072,7 +1935,7 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
drm_dbg_kms(&dev_priv->drm, "Disabling Panel Replay\n");
else
drm_dbg_kms(&dev_priv->drm, "Disabling PSR%s\n",
- intel_dp->psr.psr2_enabled ? "2" : "1");
+ intel_dp->psr.sel_update_enabled ? "2" : "1");
intel_psr_exit(intel_dp);
intel_psr_wait_exit_locked(intel_dp);
@@ -2085,11 +1948,12 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
intel_de_rmw(dev_priv, GEN8_CHICKEN_DCPR_1,
wa_16013835468_bit_get(intel_dp), 0);
- if (intel_dp->psr.psr2_enabled) {
+ if (intel_dp->psr.sel_update_enabled) {
/* Wa_16012604467:adlp,mtl[a0,b0] */
- if (IS_DISPLAY_IP_STEP(dev_priv, IP_VER(14, 0), STEP_A0, STEP_B0))
+ if (!intel_dp->psr.panel_replay_enabled &&
+ IS_DISPLAY_IP_STEP(dev_priv, IP_VER(14, 0), STEP_A0, STEP_B0))
intel_de_rmw(dev_priv,
- MTL_CLKGATE_DIS_TRANS(cpu_transcoder),
+ MTL_CLKGATE_DIS_TRANS(dev_priv, cpu_transcoder),
MTL_CLKGATE_DIS_TRANS_DMASC_GATING_DIS, 0);
else if (IS_ALDERLAKE_P(dev_priv))
intel_de_rmw(dev_priv, CLKGATE_DIS_MISC,
@@ -2101,26 +1965,29 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
/* Panel Replay on eDP is always using ALPM aux less. */
if (intel_dp->psr.panel_replay_enabled && intel_dp_is_edp(intel_dp)) {
- intel_de_rmw(dev_priv, ALPM_CTL(cpu_transcoder),
+ intel_de_rmw(dev_priv, ALPM_CTL(dev_priv, cpu_transcoder),
ALPM_CTL_ALPM_ENABLE |
ALPM_CTL_ALPM_AUX_LESS_ENABLE, 0);
- intel_de_rmw(dev_priv, PORT_ALPM_CTL(cpu_transcoder),
+ intel_de_rmw(dev_priv,
+ PORT_ALPM_CTL(dev_priv, cpu_transcoder),
PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE, 0);
}
/* Disable PSR on Sink */
- drm_dp_dpcd_writeb(&intel_dp->aux,
- intel_psr_get_enable_sink_offset(intel_dp), 0);
+ if (!intel_dp->psr.panel_replay_enabled) {
+ drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, 0);
- if (!intel_dp->psr.panel_replay_enabled &&
- intel_dp->psr.psr2_enabled)
- drm_dp_dpcd_writeb(&intel_dp->aux, DP_RECEIVER_ALPM_CONFIG, 0);
+ if (intel_dp->psr.sel_update_enabled)
+ drm_dp_dpcd_writeb(&intel_dp->aux,
+ DP_RECEIVER_ALPM_CONFIG, 0);
+ }
intel_dp->psr.enabled = false;
intel_dp->psr.panel_replay_enabled = false;
- intel_dp->psr.psr2_enabled = false;
+ intel_dp->psr.sel_update_enabled = false;
intel_dp->psr.psr2_sel_fetch_enabled = false;
+ intel_dp->psr.su_region_et_enabled = false;
intel_dp->psr.psr2_sel_fetch_cff_enabled = false;
}
@@ -2244,7 +2111,7 @@ static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp)
if (intel_dp->psr.psr2_sel_fetch_enabled)
intel_de_write(dev_priv,
- PSR2_MAN_TRK_CTL(cpu_transcoder),
+ PSR2_MAN_TRK_CTL(dev_priv, cpu_transcoder),
man_trk_ctl_enable_bit_get(dev_priv) |
man_trk_ctl_partial_frame_bit_get(dev_priv) |
man_trk_ctl_single_full_frame_bit_get(dev_priv) |
@@ -2263,7 +2130,7 @@ static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp)
* but testing proved that it works for up display 13, for newer
* than that testing will be needed.
*/
- intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0);
+ intel_de_write(dev_priv, CURSURFLIVE(dev_priv, intel_dp->psr.pipe), 0);
}
void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_state)
@@ -2286,7 +2153,7 @@ void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_st
break;
}
- intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(cpu_transcoder),
+ intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(dev_priv, cpu_transcoder),
crtc_state->psr2_man_track_ctl);
if (!crtc_state->enable_psr2_su_region_et)
@@ -2332,19 +2199,14 @@ exit:
crtc_state->psr2_man_track_ctl = val;
}
-static u32
-psr2_pipe_srcsz_early_tpt_calc(struct intel_crtc_state *crtc_state,
- bool full_update, bool cursor_in_su_area)
+static u32 psr2_pipe_srcsz_early_tpt_calc(struct intel_crtc_state *crtc_state,
+ bool full_update)
{
int width, height;
if (!crtc_state->enable_psr2_su_region_et || full_update)
return 0;
- if (!cursor_in_su_area)
- return PIPESRC_WIDTH(0) |
- PIPESRC_HEIGHT(drm_rect_height(&crtc_state->pipe_src));
-
width = drm_rect_width(&crtc_state->psr2_su_area);
height = drm_rect_height(&crtc_state->psr2_su_area);
@@ -2484,7 +2346,7 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
crtc_state->psr2_su_area.x1 = 0;
crtc_state->psr2_su_area.y1 = -1;
- crtc_state->psr2_su_area.x2 = INT_MAX;
+ crtc_state->psr2_su_area.x2 = drm_rect_width(&crtc_state->pipe_src);
crtc_state->psr2_su_area.y2 = -1;
/*
@@ -2573,8 +2435,9 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
goto skip_sel_fetch_set_loop;
/* Wa_14014971492 */
- if ((IS_DISPLAY_IP_STEP(dev_priv, IP_VER(14, 0), STEP_A0, STEP_B0) ||
- IS_ALDERLAKE_P(dev_priv) || IS_TIGERLAKE(dev_priv)) &&
+ if (!crtc_state->has_panel_replay &&
+ ((IS_DISPLAY_IP_STEP(dev_priv, IP_VER(14, 0), STEP_A0, STEP_B0) ||
+ IS_ALDERLAKE_P(dev_priv) || IS_TIGERLAKE(dev_priv))) &&
crtc_state->splitter.enable)
crtc_state->psr2_su_area.y1 = 0;
@@ -2652,8 +2515,7 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
skip_sel_fetch_set_loop:
psr2_man_trk_ctl_calc(crtc_state, full_update);
crtc_state->pipe_srcsz_early_tpt =
- psr2_pipe_srcsz_early_tpt_calc(crtc_state, full_update,
- cursor_in_su_area);
+ psr2_pipe_srcsz_early_tpt_calc(crtc_state, full_update);
return 0;
}
@@ -2683,12 +2545,15 @@ void intel_psr_pre_plane_update(struct intel_atomic_state *state,
* - PSR disabled in new state
* - All planes will go inactive
* - Changing between PSR versions
+ * - Region Early Transport changing
* - Display WA #1136: skl, bxt
*/
needs_to_disable |= intel_crtc_needs_modeset(new_crtc_state);
needs_to_disable |= !new_crtc_state->has_psr;
needs_to_disable |= !new_crtc_state->active_planes;
- needs_to_disable |= new_crtc_state->has_psr2 != psr->psr2_enabled;
+ needs_to_disable |= new_crtc_state->has_sel_update != psr->sel_update_enabled;
+ needs_to_disable |= new_crtc_state->enable_psr2_su_region_et !=
+ psr->su_region_et_enabled;
needs_to_disable |= DISPLAY_VER(i915) < 11 &&
new_crtc_state->wm_level_disabled;
@@ -2761,7 +2626,7 @@ static int _psr2_ready_for_pipe_update_locked(struct intel_dp *intel_dp)
* EDP_PSR2_STATUS_STATE_DEEP_SLEEP to be cleared.
*/
return intel_de_wait_for_clear(dev_priv,
- EDP_PSR2_STATUS(cpu_transcoder),
+ EDP_PSR2_STATUS(dev_priv, cpu_transcoder),
EDP_PSR2_STATUS_STATE_DEEP_SLEEP, 50);
}
@@ -2781,6 +2646,13 @@ static int _psr1_ready_for_pipe_update_locked(struct intel_dp *intel_dp)
EDP_PSR_STATUS_STATE_MASK, 50);
}
+static int _panel_replay_ready_for_pipe_update_locked(struct intel_dp *intel_dp)
+{
+ return intel_dp_is_edp(intel_dp) ?
+ _psr2_ready_for_pipe_update_locked(intel_dp) :
+ _psr1_ready_for_pipe_update_locked(intel_dp);
+}
+
/**
* intel_psr_wait_for_idle_locked - wait for PSR be ready for a pipe update
* @new_crtc_state: new CRTC state
@@ -2806,7 +2678,9 @@ void intel_psr_wait_for_idle_locked(const struct intel_crtc_state *new_crtc_stat
if (!intel_dp->psr.enabled)
continue;
- if (intel_dp->psr.psr2_enabled)
+ if (intel_dp->psr.panel_replay_enabled)
+ ret = _panel_replay_ready_for_pipe_update_locked(intel_dp);
+ else if (intel_dp->psr.sel_update_enabled)
ret = _psr2_ready_for_pipe_update_locked(intel_dp);
else
ret = _psr1_ready_for_pipe_update_locked(intel_dp);
@@ -2827,8 +2701,9 @@ static bool __psr_wait_for_idle_locked(struct intel_dp *intel_dp)
if (!intel_dp->psr.enabled)
return false;
- if (intel_dp->psr.psr2_enabled) {
- reg = EDP_PSR2_STATUS(cpu_transcoder);
+ if (intel_dp_is_edp(intel_dp) && (intel_dp->psr.sel_update_enabled ||
+ intel_dp->psr.panel_replay_enabled)) {
+ reg = EDP_PSR2_STATUS(dev_priv, cpu_transcoder);
mask = EDP_PSR2_STATUS_STATE_MASK;
} else {
reg = psr_status_reg(dev_priv, cpu_transcoder);
@@ -2914,10 +2789,14 @@ int intel_psr_debug_set(struct intel_dp *intel_dp, u64 val)
{
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
const u32 mode = val & I915_PSR_DEBUG_MODE_MASK;
- u32 old_mode;
+ const u32 disable_bits = val & (I915_PSR_DEBUG_SU_REGION_ET_DISABLE |
+ I915_PSR_DEBUG_PANEL_REPLAY_DISABLE);
+ u32 old_mode, old_disable_bits;
int ret;
- if (val & ~(I915_PSR_DEBUG_IRQ | I915_PSR_DEBUG_MODE_MASK) ||
+ if (val & ~(I915_PSR_DEBUG_IRQ | I915_PSR_DEBUG_SU_REGION_ET_DISABLE |
+ I915_PSR_DEBUG_PANEL_REPLAY_DISABLE |
+ I915_PSR_DEBUG_MODE_MASK) ||
mode > I915_PSR_DEBUG_ENABLE_SEL_FETCH) {
drm_dbg_kms(&dev_priv->drm, "Invalid debug mask %llx\n", val);
return -EINVAL;
@@ -2928,6 +2807,10 @@ int intel_psr_debug_set(struct intel_dp *intel_dp, u64 val)
return ret;
old_mode = intel_dp->psr.debug & I915_PSR_DEBUG_MODE_MASK;
+ old_disable_bits = intel_dp->psr.debug &
+ (I915_PSR_DEBUG_SU_REGION_ET_DISABLE |
+ I915_PSR_DEBUG_PANEL_REPLAY_DISABLE);
+
intel_dp->psr.debug = val;
/*
@@ -2939,7 +2822,7 @@ int intel_psr_debug_set(struct intel_dp *intel_dp, u64 val)
mutex_unlock(&intel_dp->psr.lock);
- if (old_mode != mode)
+ if (old_mode != mode || old_disable_bits != disable_bits)
ret = intel_psr_fastset_force(dev_priv);
return ret;
@@ -3000,15 +2883,20 @@ static void _psr_invalidate_handle(struct intel_dp *intel_dp)
if (intel_dp->psr.psr2_sel_fetch_cff_enabled) {
/* Send one update otherwise lag is observed in screen */
- intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0);
+ intel_de_write(dev_priv,
+ CURSURFLIVE(dev_priv, intel_dp->psr.pipe),
+ 0);
return;
}
val = man_trk_ctl_enable_bit_get(dev_priv) |
man_trk_ctl_partial_frame_bit_get(dev_priv) |
man_trk_ctl_continuos_full_frame(dev_priv);
- intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(cpu_transcoder), val);
- intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0);
+ intel_de_write(dev_priv,
+ PSR2_MAN_TRK_CTL(dev_priv, cpu_transcoder),
+ val);
+ intel_de_write(dev_priv,
+ CURSURFLIVE(dev_priv, intel_dp->psr.pipe), 0);
intel_dp->psr.psr2_sel_fetch_cff_enabled = true;
} else {
intel_psr_exit(intel_dp);
@@ -3068,7 +2956,7 @@ tgl_dc3co_flush_locked(struct intel_dp *intel_dp, unsigned int frontbuffer_bits,
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- if (!intel_dp->psr.dc3co_exitline || !intel_dp->psr.psr2_enabled ||
+ if (!intel_dp->psr.dc3co_exitline || !intel_dp->psr.sel_update_enabled ||
!intel_dp->psr.active)
return;
@@ -3105,9 +2993,12 @@ static void _psr_flush_handle(struct intel_dp *intel_dp)
* SU configuration in case update is sent for any reason after
* sff bit gets cleared by the HW on next vblank.
*/
- intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(cpu_transcoder),
+ intel_de_write(dev_priv,
+ PSR2_MAN_TRK_CTL(dev_priv, cpu_transcoder),
val);
- intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0);
+ intel_de_write(dev_priv,
+ CURSURFLIVE(dev_priv, intel_dp->psr.pipe),
+ 0);
intel_dp->psr.psr2_sel_fetch_cff_enabled = false;
}
} else {
@@ -3219,9 +3110,6 @@ void intel_psr_init(struct intel_dp *intel_dp)
else
intel_dp->psr.source_support = true;
- /* Disable early transport for now */
- intel_dp->psr.debug |= I915_PSR_DEBUG_SU_REGION_ET_DISABLE;
-
/* Set link_standby x link_off defaults */
if (DISPLAY_VER(dev_priv) < 12)
/* For new platforms up to TGL let's respect VBT back again */
@@ -3266,7 +3154,7 @@ static void psr_alpm_check(struct intel_dp *intel_dp)
u8 val;
int r;
- if (!psr->psr2_enabled)
+ if (!psr->sel_update_enabled)
return;
r = drm_dp_dpcd_readb(aux, DP_RECEIVER_ALPM_STATUS, &val);
@@ -3446,7 +3334,8 @@ psr_source_status(struct intel_dp *intel_dp, struct seq_file *m)
const char *status = "unknown";
u32 val, status_val;
- if (intel_dp->psr.psr2_enabled) {
+ if (intel_dp_is_edp(intel_dp) && (intel_dp->psr.sel_update_enabled ||
+ intel_dp->psr.panel_replay_enabled)) {
static const char * const live_status[] = {
"IDLE",
"CAPTURE",
@@ -3460,7 +3349,8 @@ psr_source_status(struct intel_dp *intel_dp, struct seq_file *m)
"BUF_ON",
"TG_ON"
};
- val = intel_de_read(dev_priv, EDP_PSR2_STATUS(cpu_transcoder));
+ val = intel_de_read(dev_priv,
+ EDP_PSR2_STATUS(dev_priv, cpu_transcoder));
status_val = REG_FIELD_GET(EDP_PSR2_STATUS_STATE_MASK, val);
if (status_val < ARRAY_SIZE(live_status))
status = live_status[status_val];
@@ -3484,22 +3374,66 @@ psr_source_status(struct intel_dp *intel_dp, struct seq_file *m)
seq_printf(m, "Source PSR/PanelReplay status: %s [0x%08x]\n", status, val);
}
-static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp)
+static void intel_psr_sink_capability(struct intel_dp *intel_dp,
+ struct seq_file *m)
{
- struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
- enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
struct intel_psr *psr = &intel_dp->psr;
- intel_wakeref_t wakeref;
- const char *status;
- bool enabled;
- u32 val;
seq_printf(m, "Sink support: PSR = %s",
str_yes_no(psr->sink_support));
if (psr->sink_support)
seq_printf(m, " [0x%02x]", intel_dp->psr_dpcd[0]);
- seq_printf(m, ", Panel Replay = %s\n", str_yes_no(psr->sink_panel_replay_support));
+ if (intel_dp->psr_dpcd[0] == DP_PSR2_WITH_Y_COORD_ET_SUPPORTED)
+ seq_printf(m, " (Early Transport)");
+ seq_printf(m, ", Panel Replay = %s", str_yes_no(psr->sink_panel_replay_support));
+ seq_printf(m, ", Panel Replay Selective Update = %s",
+ str_yes_no(psr->sink_panel_replay_su_support));
+ if (intel_dp->pr_dpcd & DP_PANEL_REPLAY_EARLY_TRANSPORT_SUPPORT)
+ seq_printf(m, " (Early Transport)");
+ seq_printf(m, "\n");
+}
+
+static void intel_psr_print_mode(struct intel_dp *intel_dp,
+ struct seq_file *m)
+{
+ struct intel_psr *psr = &intel_dp->psr;
+ const char *status, *mode, *region_et;
+
+ if (psr->enabled)
+ status = " enabled";
+ else
+ status = "disabled";
+
+ if (psr->panel_replay_enabled && psr->sel_update_enabled)
+ mode = "Panel Replay Selective Update";
+ else if (psr->panel_replay_enabled)
+ mode = "Panel Replay";
+ else if (psr->sel_update_enabled)
+ mode = "PSR2";
+ else if (psr->enabled)
+ mode = "PSR1";
+ else
+ mode = "";
+
+ if (psr->su_region_et_enabled)
+ region_et = " (Early Transport)";
+ else
+ region_et = "";
+
+ seq_printf(m, "PSR mode: %s%s%s\n", mode, status, region_et);
+}
+
+static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp)
+{
+ struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+ enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
+ struct intel_psr *psr = &intel_dp->psr;
+ intel_wakeref_t wakeref;
+ bool enabled;
+ u32 val, psr2_ctl;
+
+ intel_psr_sink_capability(intel_dp, m);
if (!(psr->sink_support || psr->sink_panel_replay_support))
return 0;
@@ -3507,13 +3441,7 @@ static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp)
wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
mutex_lock(&psr->lock);
- if (psr->panel_replay_enabled)
- status = "Panel Replay Enabled";
- else if (psr->enabled)
- status = psr->psr2_enabled ? "PSR2 enabled" : "PSR1 enabled";
- else
- status = "disabled";
- seq_printf(m, "PSR mode: %s\n", status);
+ intel_psr_print_mode(intel_dp, m);
if (!psr->enabled) {
seq_printf(m, "PSR sink not reliable: %s\n",
@@ -3524,9 +3452,16 @@ static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp)
if (psr->panel_replay_enabled) {
val = intel_de_read(dev_priv, TRANS_DP2_CTL(cpu_transcoder));
+
+ if (intel_dp_is_edp(intel_dp))
+ psr2_ctl = intel_de_read(dev_priv,
+ EDP_PSR2_CTL(dev_priv,
+ cpu_transcoder));
+
enabled = val & TRANS_DP2_PANEL_REPLAY_ENABLE;
- } else if (psr->psr2_enabled) {
- val = intel_de_read(dev_priv, EDP_PSR2_CTL(cpu_transcoder));
+ } else if (psr->sel_update_enabled) {
+ val = intel_de_read(dev_priv,
+ EDP_PSR2_CTL(dev_priv, cpu_transcoder));
enabled = val & EDP_PSR2_ENABLE;
} else {
val = intel_de_read(dev_priv, psr_ctl_reg(dev_priv, cpu_transcoder));
@@ -3534,6 +3469,9 @@ static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp)
}
seq_printf(m, "Source PSR/PanelReplay ctl: %s [0x%08x]\n",
str_enabled_disabled(enabled), val);
+ if (psr->panel_replay_enabled && intel_dp_is_edp(intel_dp))
+ seq_printf(m, "PSR2_CTL: 0x%08x\n",
+ psr2_ctl);
psr_source_status(intel_dp, m);
seq_printf(m, "Busy frontbuffer bits: 0x%08x\n",
psr->busy_frontbuffer_bits);
@@ -3551,7 +3489,7 @@ static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp)
seq_printf(m, "Last exit at: %lld\n", psr->last_exit);
}
- if (psr->psr2_enabled) {
+ if (psr->sel_update_enabled) {
u32 su_frames_val[3];
int frame;
@@ -3560,7 +3498,8 @@ static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp)
* frame boundary between register reads
*/
for (frame = 0; frame < PSR2_SU_STATUS_FRAMES; frame += 3) {
- val = intel_de_read(dev_priv, PSR2_SU_STATUS(cpu_transcoder, frame));
+ val = intel_de_read(dev_priv,
+ PSR2_SU_STATUS(dev_priv, cpu_transcoder, frame));
su_frames_val[frame / 3] = val;
}
@@ -3694,16 +3633,9 @@ static int i915_psr_sink_status_show(struct seq_file *m, void *data)
"reserved",
"sink internal error",
};
- static const char * const panel_replay_status[] = {
- "Sink device frame is locked to the Source device",
- "Sink device is coasting, using the VTotal target",
- "Sink device is governing the frame rate (frame rate unlock is granted)",
- "Sink device in the process of re-locking with the Source device",
- };
const char *str;
int ret;
u8 status, error_status;
- u32 idx;
if (!(CAN_PSR(intel_dp) || CAN_PANEL_REPLAY(intel_dp))) {
seq_puts(m, "PSR/Panel-Replay Unsupported\n");
@@ -3717,16 +3649,11 @@ static int i915_psr_sink_status_show(struct seq_file *m, void *data)
if (ret)
return ret;
- str = "unknown";
- if (intel_dp->psr.panel_replay_enabled) {
- idx = (status & DP_SINK_FRAME_LOCKED_MASK) >> DP_SINK_FRAME_LOCKED_SHIFT;
- if (idx < ARRAY_SIZE(panel_replay_status))
- str = panel_replay_status[idx];
- } else if (intel_dp->psr.enabled) {
- idx = status & DP_PSR_SINK_STATE_MASK;
- if (idx < ARRAY_SIZE(sink_status))
- str = sink_status[idx];
- }
+ status &= DP_PSR_SINK_STATE_MASK;
+ if (status < ARRAY_SIZE(sink_status))
+ str = sink_status[status];
+ else
+ str = "unknown";
seq_printf(m, "Sink %s status: 0x%x [%s]\n", psr_mode_str(intel_dp), status, str);
diff --git a/drivers/gpu/drm/i915/display/intel_psr_regs.h b/drivers/gpu/drm/i915/display/intel_psr_regs.h
index ebc22999572c..642bb15fb547 100644
--- a/drivers/gpu/drm/i915/display/intel_psr_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_psr_regs.h
@@ -9,7 +9,7 @@
#include "intel_display_reg_defs.h"
#include "intel_dp_aux_regs.h"
-#define TRANS_EXITLINE(trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_EXITLINE_A)
+#define TRANS_EXITLINE(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_EXITLINE_A)
#define EXITLINE_ENABLE REG_BIT(31)
#define EXITLINE_MASK REG_GENMASK(12, 0)
#define EXITLINE_SHIFT 0
@@ -23,7 +23,7 @@
#define HSW_SRD_CTL _MMIO(0x64800)
#define _SRD_CTL_A 0x60800
#define _SRD_CTL_EDP 0x6f800
-#define EDP_PSR_CTL(tran) _MMIO_TRANS2(dev_priv, tran, _SRD_CTL_A)
+#define EDP_PSR_CTL(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _SRD_CTL_A)
#define EDP_PSR_ENABLE REG_BIT(31)
#define BDW_PSR_SINGLE_FRAME REG_BIT(30)
#define EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK REG_BIT(29) /* SW can't modify */
@@ -66,8 +66,8 @@
#define EDP_PSR_IIR _MMIO(0x64838)
#define _PSR_IMR_A 0x60814
#define _PSR_IIR_A 0x60818
-#define TRANS_PSR_IMR(tran) _MMIO_TRANS2(dev_priv, tran, _PSR_IMR_A)
-#define TRANS_PSR_IIR(tran) _MMIO_TRANS2(dev_priv, tran, _PSR_IIR_A)
+#define TRANS_PSR_IMR(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PSR_IMR_A)
+#define TRANS_PSR_IIR(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PSR_IIR_A)
#define _EDP_PSR_TRANS_SHIFT(trans) ((trans) == TRANSCODER_EDP ? \
0 : ((trans) - TRANSCODER_A + 1) * 8)
#define TGL_PSR_MASK REG_GENMASK(2, 0)
@@ -86,7 +86,7 @@
#define HSW_SRD_AUX_CTL _MMIO(0x64810)
#define _SRD_AUX_CTL_A 0x60810
#define _SRD_AUX_CTL_EDP 0x6f810
-#define EDP_PSR_AUX_CTL(tran) _MMIO_TRANS2(dev_priv, tran, _SRD_AUX_CTL_A)
+#define EDP_PSR_AUX_CTL(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _SRD_AUX_CTL_A)
#define EDP_PSR_AUX_CTL_TIME_OUT_MASK DP_AUX_CH_CTL_TIME_OUT_MASK
#define EDP_PSR_AUX_CTL_MESSAGE_SIZE_MASK DP_AUX_CH_CTL_MESSAGE_SIZE_MASK
#define EDP_PSR_AUX_CTL_PRECHARGE_2US_MASK DP_AUX_CH_CTL_PRECHARGE_2US_MASK
@@ -96,12 +96,12 @@
#define HSW_SRD_AUX_DATA(i) _MMIO(0x64814 + (i) * 4) /* 5 registers */
#define _SRD_AUX_DATA_A 0x60814
#define _SRD_AUX_DATA_EDP 0x6f814
-#define EDP_PSR_AUX_DATA(tran, i) _MMIO_TRANS2(dev_priv, tran, _SRD_AUX_DATA_A + (i) * 4) /* 5 registers */
+#define EDP_PSR_AUX_DATA(dev_priv, tran, i) _MMIO_TRANS2(dev_priv, tran, _SRD_AUX_DATA_A + (i) * 4) /* 5 registers */
#define HSW_SRD_STATUS _MMIO(0x64840)
#define _SRD_STATUS_A 0x60840
#define _SRD_STATUS_EDP 0x6f840
-#define EDP_PSR_STATUS(tran) _MMIO_TRANS2(dev_priv, tran, _SRD_STATUS_A)
+#define EDP_PSR_STATUS(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _SRD_STATUS_A)
#define EDP_PSR_STATUS_STATE_MASK REG_GENMASK(31, 29)
#define EDP_PSR_STATUS_STATE_IDLE REG_FIELD_PREP(EDP_PSR_STATUS_STATE_MASK, 0)
#define EDP_PSR_STATUS_STATE_SRDONACK REG_FIELD_PREP(EDP_PSR_STATUS_STATE_MASK, 1)
@@ -126,14 +126,14 @@
#define HSW_SRD_PERF_CNT _MMIO(0x64844)
#define _SRD_PERF_CNT_A 0x60844
#define _SRD_PERF_CNT_EDP 0x6f844
-#define EDP_PSR_PERF_CNT(tran) _MMIO_TRANS2(dev_priv, tran, _SRD_PERF_CNT_A)
+#define EDP_PSR_PERF_CNT(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _SRD_PERF_CNT_A)
#define EDP_PSR_PERF_CNT_MASK REG_GENMASK(23, 0)
/* PSR_MASK on SKL+ */
#define HSW_SRD_DEBUG _MMIO(0x64860)
#define _SRD_DEBUG_A 0x60860
#define _SRD_DEBUG_EDP 0x6f860
-#define EDP_PSR_DEBUG(tran) _MMIO_TRANS2(dev_priv, tran, _SRD_DEBUG_A)
+#define EDP_PSR_DEBUG(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _SRD_DEBUG_A)
#define EDP_PSR_DEBUG_MASK_MAX_SLEEP REG_BIT(28)
#define EDP_PSR_DEBUG_MASK_LPSP REG_BIT(27)
#define EDP_PSR_DEBUG_MASK_MEMUP REG_BIT(26)
@@ -153,7 +153,7 @@
#define _PSR2_CTL_A 0x60900
#define _PSR2_CTL_EDP 0x6f900
-#define EDP_PSR2_CTL(tran) _MMIO_TRANS2(dev_priv, tran, _PSR2_CTL_A)
+#define EDP_PSR2_CTL(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PSR2_CTL_A)
#define EDP_PSR2_ENABLE REG_BIT(31)
#define EDP_SU_TRACK_ENABLE REG_BIT(30) /* up to adl-p */
#define TGL_EDP_PSR2_BLOCK_COUNT_MASK REG_BIT(28)
@@ -172,6 +172,10 @@
#define TGL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES 5
#define TGL_EDP_PSR2_IO_BUFFER_WAKE(lines) REG_FIELD_PREP(TGL_EDP_PSR2_IO_BUFFER_WAKE_MASK, \
(lines) - TGL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES)
+#define LNL_EDP_PSR2_IO_BUFFER_WAKE_MASK REG_GENMASK(18, 13)
+#define LNL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES 5
+#define LNL_EDP_PSR2_IO_BUFFER_WAKE(lines) REG_FIELD_PREP(LNL_EDP_PSR2_IO_BUFFER_WAKE_MASK, \
+ (lines) - LNL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES)
#define EDP_PSR2_FAST_WAKE_MASK REG_GENMASK(12, 11)
#define EDP_PSR2_FAST_WAKE_MAX_LINES 8
#define EDP_PSR2_FAST_WAKE(lines) REG_FIELD_PREP(EDP_PSR2_FAST_WAKE_MASK, \
@@ -195,7 +199,7 @@
#define _PSR_EVENT_TRANS_C 0x62848
#define _PSR_EVENT_TRANS_D 0x63848
#define _PSR_EVENT_TRANS_EDP 0x6f848
-#define PSR_EVENT(tran) _MMIO_TRANS2(dev_priv, tran, _PSR_EVENT_TRANS_A)
+#define PSR_EVENT(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PSR_EVENT_TRANS_A)
#define PSR_EVENT_PSR2_WD_TIMER_EXPIRE REG_BIT(17)
#define PSR_EVENT_PSR2_DISABLED REG_BIT(16)
#define PSR_EVENT_SU_DIRTY_FIFO_UNDERRUN REG_BIT(15)
@@ -215,21 +219,21 @@
#define _PSR2_STATUS_A 0x60940
#define _PSR2_STATUS_EDP 0x6f940
-#define EDP_PSR2_STATUS(tran) _MMIO_TRANS2(dev_priv, tran, _PSR2_STATUS_A)
+#define EDP_PSR2_STATUS(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PSR2_STATUS_A)
#define EDP_PSR2_STATUS_STATE_MASK REG_GENMASK(31, 28)
#define EDP_PSR2_STATUS_STATE_DEEP_SLEEP REG_FIELD_PREP(EDP_PSR2_STATUS_STATE_MASK, 0x8)
#define _PSR2_SU_STATUS_A 0x60914
#define _PSR2_SU_STATUS_EDP 0x6f914
-#define _PSR2_SU_STATUS(tran, index) _MMIO_TRANS2(dev_priv, tran, _PSR2_SU_STATUS_A + (index) * 4)
-#define PSR2_SU_STATUS(tran, frame) (_PSR2_SU_STATUS(tran, (frame) / 3))
+#define _PSR2_SU_STATUS(dev_priv, tran, index) _MMIO_TRANS2(dev_priv, tran, _PSR2_SU_STATUS_A + (index) * 4)
+#define PSR2_SU_STATUS(dev_priv, tran, frame) (_PSR2_SU_STATUS(dev_priv, tran, (frame) / 3))
#define PSR2_SU_STATUS_SHIFT(frame) (((frame) % 3) * 10)
#define PSR2_SU_STATUS_MASK(frame) (0x3ff << PSR2_SU_STATUS_SHIFT(frame))
#define PSR2_SU_STATUS_FRAMES 8
#define _PSR2_MAN_TRK_CTL_A 0x60910
#define _PSR2_MAN_TRK_CTL_EDP 0x6f910
-#define PSR2_MAN_TRK_CTL(tran) _MMIO_TRANS2(dev_priv, tran, _PSR2_MAN_TRK_CTL_A)
+#define PSR2_MAN_TRK_CTL(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PSR2_MAN_TRK_CTL_A)
#define PSR2_MAN_TRK_CTL_ENABLE REG_BIT(31)
#define PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR_MASK REG_GENMASK(30, 21)
#define PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(val) REG_FIELD_PREP(PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR_MASK, val)
@@ -248,56 +252,11 @@
/* PSR2 Early transport */
#define _PIPE_SRCSZ_ERLY_TPT_A 0x70074
-
-#define PIPE_SRCSZ_ERLY_TPT(trans) _MMIO_TRANS2(dev_priv, trans, _PIPE_SRCSZ_ERLY_TPT_A)
-
-#define _SEL_FETCH_PLANE_BASE_1_A 0x70890
-#define _SEL_FETCH_PLANE_BASE_2_A 0x708B0
-#define _SEL_FETCH_PLANE_BASE_3_A 0x708D0
-#define _SEL_FETCH_PLANE_BASE_4_A 0x708F0
-#define _SEL_FETCH_PLANE_BASE_5_A 0x70920
-#define _SEL_FETCH_PLANE_BASE_6_A 0x70940
-#define _SEL_FETCH_PLANE_BASE_7_A 0x70960
-#define _SEL_FETCH_PLANE_BASE_CUR_A 0x70880
-#define _SEL_FETCH_PLANE_BASE_1_B 0x71890
-
-#define _SEL_FETCH_PLANE_BASE_A(plane) _PICK(plane, \
- _SEL_FETCH_PLANE_BASE_1_A, \
- _SEL_FETCH_PLANE_BASE_2_A, \
- _SEL_FETCH_PLANE_BASE_3_A, \
- _SEL_FETCH_PLANE_BASE_4_A, \
- _SEL_FETCH_PLANE_BASE_5_A, \
- _SEL_FETCH_PLANE_BASE_6_A, \
- _SEL_FETCH_PLANE_BASE_7_A, \
- _SEL_FETCH_PLANE_BASE_CUR_A)
-#define _SEL_FETCH_PLANE_BASE_1(pipe) _PIPE(pipe, _SEL_FETCH_PLANE_BASE_1_A, _SEL_FETCH_PLANE_BASE_1_B)
-#define _SEL_FETCH_PLANE_BASE(pipe, plane) (_SEL_FETCH_PLANE_BASE_1(pipe) - \
- _SEL_FETCH_PLANE_BASE_1_A + \
- _SEL_FETCH_PLANE_BASE_A(plane))
-
-#define _SEL_FETCH_PLANE_CTL_1_A 0x70890
-#define PLANE_SEL_FETCH_CTL(pipe, plane) _MMIO(_SEL_FETCH_PLANE_BASE(pipe, plane) + \
- _SEL_FETCH_PLANE_CTL_1_A - \
- _SEL_FETCH_PLANE_BASE_1_A)
-#define PLANE_SEL_FETCH_CTL_ENABLE REG_BIT(31)
-
-#define _SEL_FETCH_PLANE_POS_1_A 0x70894
-#define PLANE_SEL_FETCH_POS(pipe, plane) _MMIO(_SEL_FETCH_PLANE_BASE(pipe, plane) + \
- _SEL_FETCH_PLANE_POS_1_A - \
- _SEL_FETCH_PLANE_BASE_1_A)
-
-#define _SEL_FETCH_PLANE_SIZE_1_A 0x70898
-#define PLANE_SEL_FETCH_SIZE(pipe, plane) _MMIO(_SEL_FETCH_PLANE_BASE(pipe, plane) + \
- _SEL_FETCH_PLANE_SIZE_1_A - \
- _SEL_FETCH_PLANE_BASE_1_A)
-
-#define _SEL_FETCH_PLANE_OFFSET_1_A 0x7089C
-#define PLANE_SEL_FETCH_OFFSET(pipe, plane) _MMIO(_SEL_FETCH_PLANE_BASE(pipe, plane) + \
- _SEL_FETCH_PLANE_OFFSET_1_A - \
- _SEL_FETCH_PLANE_BASE_1_A)
+#define _PIPE_SRCSZ_ERLY_TPT_B 0x71074
+#define PIPE_SRCSZ_ERLY_TPT(pipe) _MMIO_PIPE((pipe), _PIPE_SRCSZ_ERLY_TPT_A, _PIPE_SRCSZ_ERLY_TPT_B)
#define _ALPM_CTL_A 0x60950
-#define ALPM_CTL(tran) _MMIO_TRANS2(dev_priv, tran, _ALPM_CTL_A)
+#define ALPM_CTL(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _ALPM_CTL_A)
#define ALPM_CTL_ALPM_ENABLE REG_BIT(31)
#define ALPM_CTL_ALPM_AUX_LESS_ENABLE REG_BIT(30)
#define ALPM_CTL_LOBF_ENABLE REG_BIT(29)
@@ -321,7 +280,7 @@
#define ALPM_CTL_AUX_LESS_WAKE_TIME(val) REG_FIELD_PREP(ALPM_CTL_AUX_LESS_WAKE_TIME_MASK, val)
#define _ALPM_CTL2_A 0x60954
-#define ALPM_CTL2(tran) _MMIO_TRANS2(dev_priv, tran, _ALPM_CTL2_A)
+#define ALPM_CTL2(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _ALPM_CTL2_A)
#define ALPM_CTL2_SWITCH_TO_ACTIVE_LATENCY_MASK REG_GENMASK(28, 24)
#define ALPM_CTL2_SWITCH_TO_ACTIVE_LATENCY(val) REG_FIELD_PREP(ALPM_CTL2_SWITCH_TO_ACTIVE_LATENCY_MASK, val)
#define ALPM_CTL2_AUX_LESS_WAKE_TIME_EXTENSION_MASK REG_GENMASK(19, 16)
@@ -335,7 +294,8 @@
#define ALPM_CTL2_NUMBER_AUX_LESS_ML_PHY_SLEEP_SEQUENCES(val) REG_FIELD_PREP(ALPM_CTL2_NUMBER_AUX_LESS_ML_PHY_SLEEP_SEQUENCES_MASK, val)
#define _PORT_ALPM_CTL_A 0x16fa2c
-#define PORT_ALPM_CTL(tran) _MMIO_TRANS2(dev_priv, tran, _PORT_ALPM_CTL_A)
+#define _PORT_ALPM_CTL_B 0x16fc2c
+#define PORT_ALPM_CTL(dev_priv, port) _MMIO_PORT(port, _PORT_ALPM_CTL_A, _PORT_ALPM_CTL_B)
#define PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE REG_BIT(31)
#define PORT_ALPM_CTL_MAX_PHY_SWING_SETUP_MASK REG_GENMASK(23, 20)
#define PORT_ALPM_CTL_MAX_PHY_SWING_SETUP(val) REG_FIELD_PREP(PORT_ALPM_CTL_MAX_PHY_SWING_SETUP_MASK, val)
@@ -345,7 +305,8 @@
#define PORT_ALPM_CTL_SILENCE_PERIOD(val) REG_FIELD_PREP(PORT_ALPM_CTL_SILENCE_PERIOD_MASK, val)
#define _PORT_ALPM_LFPS_CTL_A 0x16fa30
-#define PORT_ALPM_LFPS_CTL(tran) _MMIO_TRANS2(dev_priv, tran, _PORT_ALPM_LFPS_CTL_A)
+#define _PORT_ALPM_LFPS_CTL_B 0x16fc30
+#define PORT_ALPM_LFPS_CTL(dev_priv, port) _MMIO_PORT(port, _PORT_ALPM_LFPS_CTL_A, _PORT_ALPM_LFPS_CTL_B)
#define PORT_ALPM_LFPS_CTL_LFPS_START_POLARITY REG_BIT(31)
#define PORT_ALPM_LFPS_CTL_LFPS_CYCLE_COUNT_MASK REG_GENMASK(27, 24)
#define PORT_ALPM_LFPS_CTL_LFPS_CYCLE_COUNT_MIN 7
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
index 36a253a19c74..e1c907f601da 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -39,7 +39,6 @@
#include <drm/drm_rect.h>
#include "i915_drv.h"
-#include "i915_reg.h"
#include "i9xx_plane.h"
#include "intel_atomic_plane.h"
#include "intel_de.h"
diff --git a/drivers/gpu/drm/i915/display/intel_sprite_regs.h b/drivers/gpu/drm/i915/display/intel_sprite_regs.h
index bb67705652b2..73021e3ced6d 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_sprite_regs.h
@@ -6,7 +6,10 @@
#include "intel_display_reg_defs.h"
+/* g4x/ilk/snb video sprite */
#define _DVSACNTR 0x72180
+#define _DVSBCNTR 0x73180
+#define DVSCNTR(pipe) _MMIO_PIPE(pipe, _DVSACNTR, _DVSBCNTR)
#define DVS_ENABLE REG_BIT(31)
#define DVS_PIPE_GAMMA_ENABLE REG_BIT(30)
#define DVS_YUV_RANGE_CORRECTION_DISABLE REG_BIT(27)
@@ -28,31 +31,67 @@
#define DVS_TRICKLE_FEED_DISABLE REG_BIT(14)
#define DVS_TILED REG_BIT(10)
#define DVS_DEST_KEY REG_BIT(2)
+
#define _DVSALINOFF 0x72184
+#define _DVSBLINOFF 0x73184
+#define DVSLINOFF(pipe) _MMIO_PIPE(pipe, _DVSALINOFF, _DVSBLINOFF)
+
#define _DVSASTRIDE 0x72188
+#define _DVSBSTRIDE 0x73188
+#define DVSSTRIDE(pipe) _MMIO_PIPE(pipe, _DVSASTRIDE, _DVSBSTRIDE)
+
#define _DVSAPOS 0x7218c
+#define _DVSBPOS 0x7318c
+#define DVSPOS(pipe) _MMIO_PIPE(pipe, _DVSAPOS, _DVSBPOS)
#define DVS_POS_Y_MASK REG_GENMASK(31, 16)
#define DVS_POS_Y(y) REG_FIELD_PREP(DVS_POS_Y_MASK, (y))
#define DVS_POS_X_MASK REG_GENMASK(15, 0)
#define DVS_POS_X(x) REG_FIELD_PREP(DVS_POS_X_MASK, (x))
+
#define _DVSASIZE 0x72190
+#define _DVSBSIZE 0x73190
+#define DVSSIZE(pipe) _MMIO_PIPE(pipe, _DVSASIZE, _DVSBSIZE)
#define DVS_HEIGHT_MASK REG_GENMASK(31, 16)
#define DVS_HEIGHT(h) REG_FIELD_PREP(DVS_HEIGHT_MASK, (h))
#define DVS_WIDTH_MASK REG_GENMASK(15, 0)
#define DVS_WIDTH(w) REG_FIELD_PREP(DVS_WIDTH_MASK, (w))
+
#define _DVSAKEYVAL 0x72194
+#define _DVSBKEYVAL 0x73194
+#define DVSKEYVAL(pipe) _MMIO_PIPE(pipe, _DVSAKEYVAL, _DVSBKEYVAL)
+
#define _DVSAKEYMSK 0x72198
+#define _DVSBKEYMSK 0x73198
+#define DVSKEYMSK(pipe) _MMIO_PIPE(pipe, _DVSAKEYMSK, _DVSBKEYMSK)
+
#define _DVSASURF 0x7219c
+#define _DVSBSURF 0x7319c
+#define DVSSURF(pipe) _MMIO_PIPE(pipe, _DVSASURF, _DVSBSURF)
#define DVS_ADDR_MASK REG_GENMASK(31, 12)
+
#define _DVSAKEYMAXVAL 0x721a0
+#define _DVSBKEYMAXVAL 0x731a0
+#define DVSKEYMAX(pipe) _MMIO_PIPE(pipe, _DVSAKEYMAXVAL, _DVSBKEYMAXVAL)
+
#define _DVSATILEOFF 0x721a4
+#define _DVSBTILEOFF 0x731a4
+#define DVSTILEOFF(pipe) _MMIO_PIPE(pipe, _DVSATILEOFF, _DVSBTILEOFF)
#define DVS_OFFSET_Y_MASK REG_GENMASK(31, 16)
#define DVS_OFFSET_Y(y) REG_FIELD_PREP(DVS_OFFSET_Y_MASK, (y))
#define DVS_OFFSET_X_MASK REG_GENMASK(15, 0)
#define DVS_OFFSET_X(x) REG_FIELD_PREP(DVS_OFFSET_X_MASK, (x))
+
#define _DVSASURFLIVE 0x721ac
+#define _DVSBSURFLIVE 0x731ac
+#define DVSSURFLIVE(pipe) _MMIO_PIPE(pipe, _DVSASURFLIVE, _DVSBSURFLIVE)
+
#define _DVSAGAMC_G4X 0x721e0 /* g4x */
+#define _DVSBGAMC_G4X 0x731e0 /* g4x */
+#define DVSGAMC_G4X(pipe, i) _MMIO(_PIPE(pipe, _DVSAGAMC_G4X, _DVSBGAMC_G4X) + (5 - (i)) * 4) /* 6 x u0.8 */
+
#define _DVSASCALE 0x72204
+#define _DVSBSCALE 0x73204
+#define DVSSCALE(pipe) _MMIO_PIPE(pipe, _DVSASCALE, _DVSBSCALE)
#define DVS_SCALE_ENABLE REG_BIT(31)
#define DVS_FILTER_MASK REG_GENMASK(30, 29)
#define DVS_FILTER_MEDIUM REG_FIELD_PREP(DVS_FILTER_MASK, 0)
@@ -64,42 +103,19 @@
#define DVS_SRC_WIDTH(w) REG_FIELD_PREP(DVS_SRC_WIDTH_MASK, (w))
#define DVS_SRC_HEIGHT_MASK REG_GENMASK(10, 0)
#define DVS_SRC_HEIGHT(h) REG_FIELD_PREP(DVS_SRC_HEIGHT_MASK, (h))
-#define _DVSAGAMC_ILK 0x72300 /* ilk/snb */
-#define _DVSAGAMCMAX_ILK 0x72340 /* ilk/snb */
-#define _DVSBCNTR 0x73180
-#define _DVSBLINOFF 0x73184
-#define _DVSBSTRIDE 0x73188
-#define _DVSBPOS 0x7318c
-#define _DVSBSIZE 0x73190
-#define _DVSBKEYVAL 0x73194
-#define _DVSBKEYMSK 0x73198
-#define _DVSBSURF 0x7319c
-#define _DVSBKEYMAXVAL 0x731a0
-#define _DVSBTILEOFF 0x731a4
-#define _DVSBSURFLIVE 0x731ac
-#define _DVSBGAMC_G4X 0x731e0 /* g4x */
-#define _DVSBSCALE 0x73204
+#define _DVSAGAMC_ILK 0x72300 /* ilk/snb */
#define _DVSBGAMC_ILK 0x73300 /* ilk/snb */
-#define _DVSBGAMCMAX_ILK 0x73340 /* ilk/snb */
-
-#define DVSCNTR(pipe) _MMIO_PIPE(pipe, _DVSACNTR, _DVSBCNTR)
-#define DVSLINOFF(pipe) _MMIO_PIPE(pipe, _DVSALINOFF, _DVSBLINOFF)
-#define DVSSTRIDE(pipe) _MMIO_PIPE(pipe, _DVSASTRIDE, _DVSBSTRIDE)
-#define DVSPOS(pipe) _MMIO_PIPE(pipe, _DVSAPOS, _DVSBPOS)
-#define DVSSURF(pipe) _MMIO_PIPE(pipe, _DVSASURF, _DVSBSURF)
-#define DVSKEYMAX(pipe) _MMIO_PIPE(pipe, _DVSAKEYMAXVAL, _DVSBKEYMAXVAL)
-#define DVSSIZE(pipe) _MMIO_PIPE(pipe, _DVSASIZE, _DVSBSIZE)
-#define DVSSCALE(pipe) _MMIO_PIPE(pipe, _DVSASCALE, _DVSBSCALE)
-#define DVSTILEOFF(pipe) _MMIO_PIPE(pipe, _DVSATILEOFF, _DVSBTILEOFF)
-#define DVSKEYVAL(pipe) _MMIO_PIPE(pipe, _DVSAKEYVAL, _DVSBKEYVAL)
-#define DVSKEYMSK(pipe) _MMIO_PIPE(pipe, _DVSAKEYMSK, _DVSBKEYMSK)
-#define DVSSURFLIVE(pipe) _MMIO_PIPE(pipe, _DVSASURFLIVE, _DVSBSURFLIVE)
-#define DVSGAMC_G4X(pipe, i) _MMIO(_PIPE(pipe, _DVSAGAMC_G4X, _DVSBGAMC_G4X) + (5 - (i)) * 4) /* 6 x u0.8 */
#define DVSGAMC_ILK(pipe, i) _MMIO(_PIPE(pipe, _DVSAGAMC_ILK, _DVSBGAMC_ILK) + (i) * 4) /* 16 x u0.10 */
+
+#define _DVSAGAMCMAX_ILK 0x72340 /* ilk/snb */
+#define _DVSBGAMCMAX_ILK 0x73340 /* ilk/snb */
#define DVSGAMCMAX_ILK(pipe, i) _MMIO(_PIPE(pipe, _DVSAGAMCMAX_ILK, _DVSBGAMCMAX_ILK) + (i) * 4) /* 3 x u1.10 */
+/* ivb/hsw/bdw sprite */
#define _SPRA_CTL 0x70280
+#define _SPRB_CTL 0x71280
+#define SPRCTL(pipe) _MMIO_PIPE(pipe, _SPRA_CTL, _SPRB_CTL)
#define SPRITE_ENABLE REG_BIT(31)
#define SPRITE_PIPE_GAMMA_ENABLE REG_BIT(30)
#define SPRITE_YUV_RANGE_CORRECTION_DISABLE REG_BIT(28)
@@ -125,31 +141,67 @@
#define SPRITE_PLANE_GAMMA_DISABLE REG_BIT(13)
#define SPRITE_TILED REG_BIT(10)
#define SPRITE_DEST_KEY REG_BIT(2)
-#define _SPRA_LINOFF 0x70284
+
+#define _SPRA_LINOFF 0x70284 /* ivb */
+#define _SPRB_LINOFF 0x71284 /* ivb */
+#define SPRLINOFF(pipe) _MMIO_PIPE(pipe, _SPRA_LINOFF, _SPRB_LINOFF)
+
#define _SPRA_STRIDE 0x70288
+#define _SPRB_STRIDE 0x71288
+#define SPRSTRIDE(pipe) _MMIO_PIPE(pipe, _SPRA_STRIDE, _SPRB_STRIDE)
+
#define _SPRA_POS 0x7028c
+#define _SPRB_POS 0x7128c
+#define SPRPOS(pipe) _MMIO_PIPE(pipe, _SPRA_POS, _SPRB_POS)
#define SPRITE_POS_Y_MASK REG_GENMASK(31, 16)
#define SPRITE_POS_Y(y) REG_FIELD_PREP(SPRITE_POS_Y_MASK, (y))
#define SPRITE_POS_X_MASK REG_GENMASK(15, 0)
#define SPRITE_POS_X(x) REG_FIELD_PREP(SPRITE_POS_X_MASK, (x))
+
#define _SPRA_SIZE 0x70290
+#define _SPRB_SIZE 0x71290
+#define SPRSIZE(pipe) _MMIO_PIPE(pipe, _SPRA_SIZE, _SPRB_SIZE)
#define SPRITE_HEIGHT_MASK REG_GENMASK(31, 16)
#define SPRITE_HEIGHT(h) REG_FIELD_PREP(SPRITE_HEIGHT_MASK, (h))
#define SPRITE_WIDTH_MASK REG_GENMASK(15, 0)
#define SPRITE_WIDTH(w) REG_FIELD_PREP(SPRITE_WIDTH_MASK, (w))
+
#define _SPRA_KEYVAL 0x70294
+#define _SPRB_KEYVAL 0x71294
+#define SPRKEYVAL(pipe) _MMIO_PIPE(pipe, _SPRA_KEYVAL, _SPRB_KEYVAL)
+
#define _SPRA_KEYMSK 0x70298
+#define _SPRB_KEYMSK 0x71298
+#define SPRKEYMSK(pipe) _MMIO_PIPE(pipe, _SPRA_KEYMSK, _SPRB_KEYMSK)
+
#define _SPRA_SURF 0x7029c
+#define _SPRB_SURF 0x7129c
+#define SPRSURF(pipe) _MMIO_PIPE(pipe, _SPRA_SURF, _SPRB_SURF)
#define SPRITE_ADDR_MASK REG_GENMASK(31, 12)
+
#define _SPRA_KEYMAX 0x702a0
-#define _SPRA_TILEOFF 0x702a4
+#define _SPRB_KEYMAX 0x712a0
+#define SPRKEYMAX(pipe) _MMIO_PIPE(pipe, _SPRA_KEYMAX, _SPRB_KEYMAX)
+
+#define _SPRA_TILEOFF 0x702a4 /* ivb */
+#define _SPRB_TILEOFF 0x712a4 /* ivb */
+#define SPRTILEOFF(pipe) _MMIO_PIPE(pipe, _SPRA_TILEOFF, _SPRB_TILEOFF)
#define SPRITE_OFFSET_Y_MASK REG_GENMASK(31, 16)
#define SPRITE_OFFSET_Y(y) REG_FIELD_PREP(SPRITE_OFFSET_Y_MASK, (y))
#define SPRITE_OFFSET_X_MASK REG_GENMASK(15, 0)
#define SPRITE_OFFSET_X(x) REG_FIELD_PREP(SPRITE_OFFSET_X_MASK, (x))
-#define _SPRA_OFFSET 0x702a4
+
+#define _SPRA_OFFSET 0x702a4 /* hsw/bdw */
+#define _SPRB_OFFSET 0x712a4 /* hsw/bdw */
+#define SPROFFSET(pipe) _MMIO_PIPE(pipe, _SPRA_OFFSET, _SPRB_OFFSET)
+
#define _SPRA_SURFLIVE 0x702ac
-#define _SPRA_SCALE 0x70304
+#define _SPRB_SURFLIVE 0x712ac
+#define SPRSURFLIVE(pipe) _MMIO_PIPE(pipe, _SPRA_SURFLIVE, _SPRB_SURFLIVE)
+
+#define _SPRA_SCALE 0x70304 /* ivb */
+#define _SPRB_SCALE 0x71304 /* ivb */
+#define SPRSCALE(pipe) _MMIO_PIPE(pipe, _SPRA_SCALE, _SPRB_SCALE)
#define SPRITE_SCALE_ENABLE REG_BIT(31)
#define SPRITE_FILTER_MASK REG_GENMASK(30, 29)
#define SPRITE_FILTER_MEDIUM REG_FIELD_PREP(SPRITE_FILTER_MASK, 0)
@@ -161,45 +213,28 @@
#define SPRITE_SRC_WIDTH(w) REG_FIELD_PREP(SPRITE_SRC_WIDTH_MASK, (w))
#define SPRITE_SRC_HEIGHT_MASK REG_GENMASK(10, 0)
#define SPRITE_SRC_HEIGHT(h) REG_FIELD_PREP(SPRITE_SRC_HEIGHT_MASK, (h))
-#define _SPRA_GAMC 0x70400
-#define _SPRA_GAMC16 0x70440
-#define _SPRA_GAMC17 0x7044c
-#define _SPRB_CTL 0x71280
-#define _SPRB_LINOFF 0x71284
-#define _SPRB_STRIDE 0x71288
-#define _SPRB_POS 0x7128c
-#define _SPRB_SIZE 0x71290
-#define _SPRB_KEYVAL 0x71294
-#define _SPRB_KEYMSK 0x71298
-#define _SPRB_SURF 0x7129c
-#define _SPRB_KEYMAX 0x712a0
-#define _SPRB_TILEOFF 0x712a4
-#define _SPRB_OFFSET 0x712a4
-#define _SPRB_SURFLIVE 0x712ac
-#define _SPRB_SCALE 0x71304
+#define _SPRA_GAMC 0x70400
#define _SPRB_GAMC 0x71400
-#define _SPRB_GAMC16 0x71440
-#define _SPRB_GAMC17 0x7144c
-
-#define SPRCTL(pipe) _MMIO_PIPE(pipe, _SPRA_CTL, _SPRB_CTL)
-#define SPRLINOFF(pipe) _MMIO_PIPE(pipe, _SPRA_LINOFF, _SPRB_LINOFF)
-#define SPRSTRIDE(pipe) _MMIO_PIPE(pipe, _SPRA_STRIDE, _SPRB_STRIDE)
-#define SPRPOS(pipe) _MMIO_PIPE(pipe, _SPRA_POS, _SPRB_POS)
-#define SPRSIZE(pipe) _MMIO_PIPE(pipe, _SPRA_SIZE, _SPRB_SIZE)
-#define SPRKEYVAL(pipe) _MMIO_PIPE(pipe, _SPRA_KEYVAL, _SPRB_KEYVAL)
-#define SPRKEYMSK(pipe) _MMIO_PIPE(pipe, _SPRA_KEYMSK, _SPRB_KEYMSK)
-#define SPRSURF(pipe) _MMIO_PIPE(pipe, _SPRA_SURF, _SPRB_SURF)
-#define SPRKEYMAX(pipe) _MMIO_PIPE(pipe, _SPRA_KEYMAX, _SPRB_KEYMAX)
-#define SPRTILEOFF(pipe) _MMIO_PIPE(pipe, _SPRA_TILEOFF, _SPRB_TILEOFF)
-#define SPROFFSET(pipe) _MMIO_PIPE(pipe, _SPRA_OFFSET, _SPRB_OFFSET)
-#define SPRSCALE(pipe) _MMIO_PIPE(pipe, _SPRA_SCALE, _SPRB_SCALE)
#define SPRGAMC(pipe, i) _MMIO(_PIPE(pipe, _SPRA_GAMC, _SPRB_GAMC) + (i) * 4) /* 16 x u0.10 */
+
+#define _SPRA_GAMC16 0x70440
+#define _SPRB_GAMC16 0x71440
#define SPRGAMC16(pipe, i) _MMIO(_PIPE(pipe, _SPRA_GAMC16, _SPRB_GAMC16) + (i) * 4) /* 3 x u1.10 */
+
+#define _SPRA_GAMC17 0x7044c
+#define _SPRB_GAMC17 0x7144c
#define SPRGAMC17(pipe, i) _MMIO(_PIPE(pipe, _SPRA_GAMC17, _SPRB_GAMC17) + (i) * 4) /* 3 x u2.10 */
-#define SPRSURFLIVE(pipe) _MMIO_PIPE(pipe, _SPRA_SURFLIVE, _SPRB_SURFLIVE)
+
+/* vlv/chv sprite */
+#define _VLV_SPR(pipe, plane_id, reg_a, reg_b) \
+ _PIPE((pipe) * 2 + (plane_id) - PLANE_SPRITE0, (reg_a), (reg_b))
+#define _MMIO_VLV_SPR(pipe, plane_id, reg_a, reg_b) \
+ _MMIO(_VLV_SPR((pipe), (plane_id), (reg_a), (reg_b)))
#define _SPACNTR (VLV_DISPLAY_BASE + 0x72180)
+#define _SPBCNTR (VLV_DISPLAY_BASE + 0x72280)
+#define SPCNTR(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPACNTR, _SPBCNTR)
#define SP_ENABLE REG_BIT(31)
#define SP_PIPE_GAMMA_ENABLE REG_BIT(30)
#define SP_FORMAT_MASK REG_GENMASK(29, 26)
@@ -225,80 +260,85 @@
#define SP_ROTATE_180 REG_BIT(15)
#define SP_TILED REG_BIT(10)
#define SP_MIRROR REG_BIT(8) /* CHV pipe B */
+
#define _SPALINOFF (VLV_DISPLAY_BASE + 0x72184)
+#define _SPBLINOFF (VLV_DISPLAY_BASE + 0x72284)
+#define SPLINOFF(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPALINOFF, _SPBLINOFF)
+
#define _SPASTRIDE (VLV_DISPLAY_BASE + 0x72188)
+#define _SPBSTRIDE (VLV_DISPLAY_BASE + 0x72288)
+#define SPSTRIDE(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPASTRIDE, _SPBSTRIDE)
+
#define _SPAPOS (VLV_DISPLAY_BASE + 0x7218c)
+#define _SPBPOS (VLV_DISPLAY_BASE + 0x7228c)
+#define SPPOS(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPAPOS, _SPBPOS)
#define SP_POS_Y_MASK REG_GENMASK(31, 16)
#define SP_POS_Y(y) REG_FIELD_PREP(SP_POS_Y_MASK, (y))
#define SP_POS_X_MASK REG_GENMASK(15, 0)
#define SP_POS_X(x) REG_FIELD_PREP(SP_POS_X_MASK, (x))
+
#define _SPASIZE (VLV_DISPLAY_BASE + 0x72190)
+#define _SPBSIZE (VLV_DISPLAY_BASE + 0x72290)
+#define SPSIZE(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPASIZE, _SPBSIZE)
#define SP_HEIGHT_MASK REG_GENMASK(31, 16)
#define SP_HEIGHT(h) REG_FIELD_PREP(SP_HEIGHT_MASK, (h))
#define SP_WIDTH_MASK REG_GENMASK(15, 0)
#define SP_WIDTH(w) REG_FIELD_PREP(SP_WIDTH_MASK, (w))
+
#define _SPAKEYMINVAL (VLV_DISPLAY_BASE + 0x72194)
+#define _SPBKEYMINVAL (VLV_DISPLAY_BASE + 0x72294)
+#define SPKEYMINVAL(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPAKEYMINVAL, _SPBKEYMINVAL)
+
#define _SPAKEYMSK (VLV_DISPLAY_BASE + 0x72198)
+#define _SPBKEYMSK (VLV_DISPLAY_BASE + 0x72298)
+#define SPKEYMSK(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPAKEYMSK, _SPBKEYMSK)
+
#define _SPASURF (VLV_DISPLAY_BASE + 0x7219c)
+#define _SPBSURF (VLV_DISPLAY_BASE + 0x7229c)
+#define SPSURF(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPASURF, _SPBSURF)
#define SP_ADDR_MASK REG_GENMASK(31, 12)
+
#define _SPAKEYMAXVAL (VLV_DISPLAY_BASE + 0x721a0)
+#define _SPBKEYMAXVAL (VLV_DISPLAY_BASE + 0x722a0)
+#define SPKEYMAXVAL(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPAKEYMAXVAL, _SPBKEYMAXVAL)
+
#define _SPATILEOFF (VLV_DISPLAY_BASE + 0x721a4)
+#define _SPBTILEOFF (VLV_DISPLAY_BASE + 0x722a4)
+#define SPTILEOFF(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPATILEOFF, _SPBTILEOFF)
#define SP_OFFSET_Y_MASK REG_GENMASK(31, 16)
#define SP_OFFSET_Y(y) REG_FIELD_PREP(SP_OFFSET_Y_MASK, (y))
#define SP_OFFSET_X_MASK REG_GENMASK(15, 0)
#define SP_OFFSET_X(x) REG_FIELD_PREP(SP_OFFSET_X_MASK, (x))
+
#define _SPACONSTALPHA (VLV_DISPLAY_BASE + 0x721a8)
+#define _SPBCONSTALPHA (VLV_DISPLAY_BASE + 0x722a8)
+#define SPCONSTALPHA(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPACONSTALPHA, _SPBCONSTALPHA)
#define SP_CONST_ALPHA_ENABLE REG_BIT(31)
#define SP_CONST_ALPHA_MASK REG_GENMASK(7, 0)
#define SP_CONST_ALPHA(alpha) REG_FIELD_PREP(SP_CONST_ALPHA_MASK, (alpha))
+
#define _SPASURFLIVE (VLV_DISPLAY_BASE + 0x721ac)
+#define _SPBSURFLIVE (VLV_DISPLAY_BASE + 0x722ac)
+#define SPSURFLIVE(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPASURFLIVE, _SPBSURFLIVE)
+
#define _SPACLRC0 (VLV_DISPLAY_BASE + 0x721d0)
+#define _SPBCLRC0 (VLV_DISPLAY_BASE + 0x722d0)
+#define SPCLRC0(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPACLRC0, _SPBCLRC0)
#define SP_CONTRAST_MASK REG_GENMASK(26, 18)
#define SP_CONTRAST(x) REG_FIELD_PREP(SP_CONTRAST_MASK, (x)) /* u3.6 */
#define SP_BRIGHTNESS_MASK REG_GENMASK(7, 0)
#define SP_BRIGHTNESS(x) REG_FIELD_PREP(SP_BRIGHTNESS_MASK, (x)) /* s8 */
+
#define _SPACLRC1 (VLV_DISPLAY_BASE + 0x721d4)
+#define _SPBCLRC1 (VLV_DISPLAY_BASE + 0x722d4)
+#define SPCLRC1(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPACLRC1, _SPBCLRC1)
#define SP_SH_SIN_MASK REG_GENMASK(26, 16)
#define SP_SH_SIN(x) REG_FIELD_PREP(SP_SH_SIN_MASK, (x)) /* s4.7 */
#define SP_SH_COS_MASK REG_GENMASK(9, 0)
#define SP_SH_COS(x) REG_FIELD_PREP(SP_SH_COS_MASK, (x)) /* u3.7 */
-#define _SPAGAMC (VLV_DISPLAY_BASE + 0x721e0)
-#define _SPBCNTR (VLV_DISPLAY_BASE + 0x72280)
-#define _SPBLINOFF (VLV_DISPLAY_BASE + 0x72284)
-#define _SPBSTRIDE (VLV_DISPLAY_BASE + 0x72288)
-#define _SPBPOS (VLV_DISPLAY_BASE + 0x7228c)
-#define _SPBSIZE (VLV_DISPLAY_BASE + 0x72290)
-#define _SPBKEYMINVAL (VLV_DISPLAY_BASE + 0x72294)
-#define _SPBKEYMSK (VLV_DISPLAY_BASE + 0x72298)
-#define _SPBSURF (VLV_DISPLAY_BASE + 0x7229c)
-#define _SPBKEYMAXVAL (VLV_DISPLAY_BASE + 0x722a0)
-#define _SPBTILEOFF (VLV_DISPLAY_BASE + 0x722a4)
-#define _SPBCONSTALPHA (VLV_DISPLAY_BASE + 0x722a8)
-#define _SPBSURFLIVE (VLV_DISPLAY_BASE + 0x722ac)
-#define _SPBCLRC0 (VLV_DISPLAY_BASE + 0x722d0)
-#define _SPBCLRC1 (VLV_DISPLAY_BASE + 0x722d4)
+#define _SPAGAMC (VLV_DISPLAY_BASE + 0x721e0)
#define _SPBGAMC (VLV_DISPLAY_BASE + 0x722e0)
-
-#define _VLV_SPR(pipe, plane_id, reg_a, reg_b) \
- _PIPE((pipe) * 2 + (plane_id) - PLANE_SPRITE0, (reg_a), (reg_b))
-#define _MMIO_VLV_SPR(pipe, plane_id, reg_a, reg_b) \
- _MMIO(_VLV_SPR((pipe), (plane_id), (reg_a), (reg_b)))
-
-#define SPCNTR(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPACNTR, _SPBCNTR)
-#define SPLINOFF(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPALINOFF, _SPBLINOFF)
-#define SPSTRIDE(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPASTRIDE, _SPBSTRIDE)
-#define SPPOS(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPAPOS, _SPBPOS)
-#define SPSIZE(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPASIZE, _SPBSIZE)
-#define SPKEYMINVAL(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPAKEYMINVAL, _SPBKEYMINVAL)
-#define SPKEYMSK(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPAKEYMSK, _SPBKEYMSK)
-#define SPSURF(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPASURF, _SPBSURF)
-#define SPKEYMAXVAL(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPAKEYMAXVAL, _SPBKEYMAXVAL)
-#define SPTILEOFF(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPATILEOFF, _SPBTILEOFF)
-#define SPCONSTALPHA(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPACONSTALPHA, _SPBCONSTALPHA)
-#define SPSURFLIVE(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPASURFLIVE, _SPBSURFLIVE)
-#define SPCLRC0(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPACLRC0, _SPBCLRC0)
-#define SPCLRC1(pipe, plane_id) _MMIO_VLV_SPR((pipe), (plane_id), _SPACLRC1, _SPBCLRC1)
#define SPGAMC(pipe, plane_id, i) _MMIO(_VLV_SPR((pipe), (plane_id), _SPAGAMC, _SPBGAMC) + (5 - (i)) * 4) /* 6 x u0.10 */
/*
diff --git a/drivers/gpu/drm/i915/display/intel_sprite_uapi.c b/drivers/gpu/drm/i915/display/intel_sprite_uapi.c
index a76b48ebc2d3..4853c4806004 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite_uapi.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite_uapi.c
@@ -74,7 +74,7 @@ int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
* pipe simultaneously.
*/
if (DISPLAY_VER(dev_priv) >= 9 &&
- to_intel_plane(plane)->id >= PLANE_SPRITE1 &&
+ to_intel_plane(plane)->id >= PLANE_3 &&
set->flags & I915_SET_COLORKEY_DESTINATION)
return -EINVAL;
diff --git a/drivers/gpu/drm/i915/display/intel_tdf.h b/drivers/gpu/drm/i915/display/intel_tdf.h
new file mode 100644
index 000000000000..353cde21f6c2
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_tdf.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef __INTEL_TDF_H__
+#define __INTEL_TDF_H__
+
+/*
+ * TDF (Transient-Data-Flush) is needed for Xe2+ where special L3:XD caching can
+ * be enabled through various PAT index modes. Idea is to use this caching mode
+ * when for example rendering onto the display surface, with the promise that
+ * KMD will ensure transient cache entries are always flushed by the time we do
+ * the display flip, since display engine is never coherent with CPU/GPU caches.
+ */
+
+struct drm_i915_private;
+
+#ifdef I915
+static inline void intel_td_flush(struct drm_i915_private *i915) {}
+#else
+void intel_td_flush(struct drm_i915_private *i915);
+#endif
+
+#endif
diff --git a/drivers/gpu/drm/i915/display/intel_vblank.c b/drivers/gpu/drm/i915/display/intel_vblank.c
index baf7354cb6e2..e5db54b1c632 100644
--- a/drivers/gpu/drm/i915/display/intel_vblank.c
+++ b/drivers/gpu/drm/i915/display/intel_vblank.c
@@ -5,6 +5,7 @@
#include "i915_drv.h"
#include "i915_reg.h"
+#include "intel_color.h"
#include "intel_crtc.h"
#include "intel_de.h"
#include "intel_display_types.h"
@@ -89,9 +90,7 @@ u32 i915_get_vblank_counter(struct drm_crtc *crtc)
htotal = mode->crtc_htotal;
hsync_start = mode->crtc_hsync_start;
- vbl_start = mode->crtc_vblank_start;
- if (mode->flags & DRM_MODE_FLAG_INTERLACE)
- vbl_start = DIV_ROUND_UP(vbl_start, 2);
+ vbl_start = intel_mode_vblank_start(mode);
/* Convert to pixel count */
vbl_start *= htotal;
@@ -104,7 +103,8 @@ u32 i915_get_vblank_counter(struct drm_crtc *crtc)
* we get a low value that's stable across two reads of the high
* register.
*/
- frame = intel_de_read64_2x32(dev_priv, PIPEFRAMEPIXEL(pipe), PIPEFRAME(pipe));
+ frame = intel_de_read64_2x32(dev_priv, PIPEFRAMEPIXEL(dev_priv, pipe),
+ PIPEFRAME(dev_priv, pipe));
pixel = frame & PIPE_PIXEL_MASK;
frame = (frame >> PIPE_FRAME_LOW_SHIFT) & 0xffffff;
@@ -126,14 +126,13 @@ u32 g4x_get_vblank_counter(struct drm_crtc *crtc)
if (!vblank->max_vblank_count)
return 0;
- return intel_de_read(dev_priv, PIPE_FRMCOUNT_G4X(pipe));
+ return intel_de_read(dev_priv, PIPE_FRMCOUNT_G4X(dev_priv, pipe));
}
static u32 intel_crtc_scanlines_since_frame_timestamp(struct intel_crtc *crtc)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
- struct drm_vblank_crtc *vblank =
- &crtc->base.dev->vblank[drm_crtc_index(&crtc->base)];
+ struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(&crtc->base);
const struct drm_display_mode *mode = &vblank->hwmode;
u32 htotal = mode->crtc_htotal;
u32 clock = mode->crtc_clock;
@@ -178,8 +177,7 @@ static u32 intel_crtc_scanlines_since_frame_timestamp(struct intel_crtc *crtc)
*/
static u32 __intel_get_crtc_scanline_from_timestamp(struct intel_crtc *crtc)
{
- struct drm_vblank_crtc *vblank =
- &crtc->base.dev->vblank[drm_crtc_index(&crtc->base)];
+ struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(&crtc->base);
const struct drm_display_mode *mode = &vblank->hwmode;
u32 vblank_start = mode->crtc_vblank_start;
u32 vtotal = mode->crtc_vtotal;
@@ -192,6 +190,44 @@ static u32 __intel_get_crtc_scanline_from_timestamp(struct intel_crtc *crtc)
return scanline;
}
+static int intel_crtc_scanline_offset(const struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+
+ /*
+ * The scanline counter increments at the leading edge of hsync.
+ *
+ * On most platforms it starts counting from vtotal-1 on the
+ * first active line. That means the scanline counter value is
+ * always one less than what we would expect. Ie. just after
+ * start of vblank, which also occurs at start of hsync (on the
+ * last active line), the scanline counter will read vblank_start-1.
+ *
+ * On gen2 the scanline counter starts counting from 1 instead
+ * of vtotal-1, so we have to subtract one.
+ *
+ * On HSW+ the behaviour of the scanline counter depends on the output
+ * type. For DP ports it behaves like most other platforms, but on HDMI
+ * there's an extra 1 line difference. So we need to add two instead of
+ * one to the value.
+ *
+ * On VLV/CHV DSI the scanline counter would appear to increment
+ * approx. 1/3 of a scanline before start of vblank. Unfortunately
+ * that means we can't tell whether we're in vblank or not while
+ * we're on that particular line. We must still set scanline_offset
+ * to 1 so that the vblank timestamps come out correct when we query
+ * the scanline counter from within the vblank interrupt handler.
+ * However if queried just before the start of vblank we'll get an
+ * answer that's slightly in the future.
+ */
+ if (DISPLAY_VER(i915) == 2)
+ return -1;
+ else if (HAS_DDI(i915) && intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+ return 2;
+ else
+ return 1;
+}
+
/*
* intel_de_read_fw(), only for fast reads of display block, no need for
* forcewake etc.
@@ -200,25 +236,20 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = to_i915(dev);
- const struct drm_display_mode *mode;
- struct drm_vblank_crtc *vblank;
+ struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(&crtc->base);
+ const struct drm_display_mode *mode = &vblank->hwmode;
enum pipe pipe = crtc->pipe;
int position, vtotal;
if (!crtc->active)
return 0;
- vblank = &crtc->base.dev->vblank[drm_crtc_index(&crtc->base)];
- mode = &vblank->hwmode;
-
if (crtc->mode_flags & I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP)
return __intel_get_crtc_scanline_from_timestamp(crtc);
- vtotal = mode->crtc_vtotal;
- if (mode->flags & DRM_MODE_FLAG_INTERLACE)
- vtotal /= 2;
+ vtotal = intel_mode_vtotal(mode);
- position = intel_de_read_fw(dev_priv, PIPEDSL(pipe)) & PIPEDSL_LINE_MASK;
+ position = intel_de_read_fw(dev_priv, PIPEDSL(dev_priv, pipe)) & PIPEDSL_LINE_MASK;
/*
* On HSW, the DSL reg (0x70000) appears to return 0 if we
@@ -237,7 +268,8 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc)
for (i = 0; i < 100; i++) {
udelay(1);
- temp = intel_de_read_fw(dev_priv, PIPEDSL(pipe)) & PIPEDSL_LINE_MASK;
+ temp = intel_de_read_fw(dev_priv,
+ PIPEDSL(dev_priv, pipe)) & PIPEDSL_LINE_MASK;
if (temp != position) {
position = temp;
break;
@@ -249,19 +281,14 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc)
* See update_scanline_offset() for the details on the
* scanline_offset adjustment.
*/
- return (position + crtc->scanline_offset) % vtotal;
+ return (position + vtotal + crtc->scanline_offset) % vtotal;
}
int intel_crtc_scanline_to_hw(struct intel_crtc *crtc, int scanline)
{
- const struct drm_vblank_crtc *vblank =
- &crtc->base.dev->vblank[drm_crtc_index(&crtc->base)];
+ const struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(&crtc->base);
const struct drm_display_mode *mode = &vblank->hwmode;
- int vtotal;
-
- vtotal = mode->crtc_vtotal;
- if (mode->flags & DRM_MODE_FLAG_INTERLACE)
- vtotal /= 2;
+ int vtotal = intel_mode_vtotal(mode);
return (scanline + vtotal - crtc->scanline_offset) % vtotal;
}
@@ -318,15 +345,9 @@ static bool i915_get_crtc_scanoutpos(struct drm_crtc *_crtc,
htotal = mode->crtc_htotal;
hsync_start = mode->crtc_hsync_start;
- vtotal = mode->crtc_vtotal;
- vbl_start = mode->crtc_vblank_start;
- vbl_end = mode->crtc_vblank_end;
-
- if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
- vbl_start = DIV_ROUND_UP(vbl_start, 2);
- vbl_end /= 2;
- vtotal /= 2;
- }
+ vtotal = intel_mode_vtotal(mode);
+ vbl_start = intel_mode_vblank_start(mode);
+ vbl_end = intel_mode_vblank_end(mode);
/*
* Enter vblank critical section, as we will do multiple
@@ -366,7 +387,7 @@ static bool i915_get_crtc_scanoutpos(struct drm_crtc *_crtc,
* We can split this into vertical and horizontal
* scanout position.
*/
- position = (intel_de_read_fw(dev_priv, PIPEFRAMEPIXEL(pipe)) & PIPE_PIXEL_MASK) >> PIPE_PIXEL_SHIFT;
+ position = (intel_de_read_fw(dev_priv, PIPEFRAMEPIXEL(dev_priv, pipe)) & PIPE_PIXEL_MASK) >> PIPE_PIXEL_SHIFT;
/* convert to pixel counts */
vbl_start *= htotal;
@@ -455,7 +476,7 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc)
static bool pipe_scanline_is_moving(struct drm_i915_private *dev_priv,
enum pipe pipe)
{
- i915_reg_t reg = PIPEDSL(pipe);
+ i915_reg_t reg = PIPEDSL(dev_priv, pipe);
u32 line1, line2;
line1 = intel_de_read(dev_priv, reg) & PIPEDSL_LINE_MASK;
@@ -487,53 +508,6 @@ void intel_wait_for_pipe_scanline_moving(struct intel_crtc *crtc)
wait_for_pipe_scanline_moving(crtc, true);
}
-static int intel_crtc_scanline_offset(const struct intel_crtc_state *crtc_state)
-{
- struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
- const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
-
- /*
- * The scanline counter increments at the leading edge of hsync.
- *
- * On most platforms it starts counting from vtotal-1 on the
- * first active line. That means the scanline counter value is
- * always one less than what we would expect. Ie. just after
- * start of vblank, which also occurs at start of hsync (on the
- * last active line), the scanline counter will read vblank_start-1.
- *
- * On gen2 the scanline counter starts counting from 1 instead
- * of vtotal-1, so we have to subtract one (or rather add vtotal-1
- * to keep the value positive), instead of adding one.
- *
- * On HSW+ the behaviour of the scanline counter depends on the output
- * type. For DP ports it behaves like most other platforms, but on HDMI
- * there's an extra 1 line difference. So we need to add two instead of
- * one to the value.
- *
- * On VLV/CHV DSI the scanline counter would appear to increment
- * approx. 1/3 of a scanline before start of vblank. Unfortunately
- * that means we can't tell whether we're in vblank or not while
- * we're on that particular line. We must still set scanline_offset
- * to 1 so that the vblank timestamps come out correct when we query
- * the scanline counter from within the vblank interrupt handler.
- * However if queried just before the start of vblank we'll get an
- * answer that's slightly in the future.
- */
- if (DISPLAY_VER(i915) == 2) {
- int vtotal;
-
- vtotal = adjusted_mode->crtc_vtotal;
- if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
- vtotal /= 2;
-
- return vtotal - 1;
- } else if (HAS_DDI(i915) && intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
- return 2;
- } else {
- return 1;
- }
-}
-
void intel_crtc_update_active_timings(const struct intel_crtc_state *crtc_state,
bool vrr_enable)
{
@@ -583,7 +557,7 @@ void intel_crtc_update_active_timings(const struct intel_crtc_state *crtc_state,
spin_unlock_irqrestore(&i915->drm.vblank_time_lock, irqflags);
}
-static int intel_mode_vblank_start(const struct drm_display_mode *mode)
+int intel_mode_vblank_start(const struct drm_display_mode *mode)
{
int vblank_start = mode->crtc_vblank_start;
@@ -593,6 +567,26 @@ static int intel_mode_vblank_start(const struct drm_display_mode *mode)
return vblank_start;
}
+int intel_mode_vblank_end(const struct drm_display_mode *mode)
+{
+ int vblank_end = mode->crtc_vblank_end;
+
+ if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+ vblank_end /= 2;
+
+ return vblank_end;
+}
+
+int intel_mode_vtotal(const struct drm_display_mode *mode)
+{
+ int vtotal = mode->crtc_vtotal;
+
+ if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+ vtotal /= 2;
+
+ return vtotal;
+}
+
void intel_vblank_evade_init(const struct intel_crtc_state *old_crtc_state,
const struct intel_crtc_state *new_crtc_state,
struct intel_vblank_evade_ctx *evade)
@@ -646,7 +640,8 @@ void intel_vblank_evade_init(const struct intel_crtc_state *old_crtc_state,
* DSB execution waits for the transcoder's undelayed vblank,
* hence we must kick off the commit before that.
*/
- if (new_crtc_state->dsb || new_crtc_state->update_m_n || new_crtc_state->update_lrr)
+ if (intel_color_uses_dsb(new_crtc_state) ||
+ new_crtc_state->update_m_n || new_crtc_state->update_lrr)
evade->min -= adjusted_mode->crtc_vblank_start - adjusted_mode->crtc_vdisplay;
}
diff --git a/drivers/gpu/drm/i915/display/intel_vblank.h b/drivers/gpu/drm/i915/display/intel_vblank.h
index ec6c3da3eeac..b51ae2c1039e 100644
--- a/drivers/gpu/drm/i915/display/intel_vblank.h
+++ b/drivers/gpu/drm/i915/display/intel_vblank.h
@@ -10,6 +10,7 @@
#include <linux/types.h>
struct drm_crtc;
+struct drm_display_mode;
struct intel_crtc;
struct intel_crtc_state;
@@ -19,6 +20,10 @@ struct intel_vblank_evade_ctx {
bool need_vlv_dsi_wa;
};
+int intel_mode_vblank_start(const struct drm_display_mode *mode);
+int intel_mode_vblank_end(const struct drm_display_mode *mode);
+int intel_mode_vtotal(const struct drm_display_mode *mode);
+
void intel_vblank_evade_init(const struct intel_crtc_state *old_crtc_state,
const struct intel_crtc_state *new_crtc_state,
struct intel_vblank_evade_ctx *evade);
diff --git a/drivers/gpu/drm/i915/display/intel_vbt_defs.h b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
index 228702c0e492..1af8407e2081 100644
--- a/drivers/gpu/drm/i915/display/intel_vbt_defs.h
+++ b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
@@ -39,6 +39,50 @@
#include "intel_bios.h"
+/* EDID derived structures */
+struct bdb_edid_pnp_id {
+ u16 mfg_name;
+ u16 product_code;
+ u32 serial;
+ u8 mfg_week;
+ u8 mfg_year;
+} __packed;
+
+struct bdb_edid_product_name {
+ char name[13];
+} __packed;
+
+struct bdb_edid_dtd {
+ u16 clock; /**< In 10khz */
+ u8 hactive_lo;
+ u8 hblank_lo;
+ u8 hblank_hi:4;
+ u8 hactive_hi:4;
+ u8 vactive_lo;
+ u8 vblank_lo;
+ u8 vblank_hi:4;
+ u8 vactive_hi:4;
+ u8 hsync_off_lo;
+ u8 hsync_pulse_width_lo;
+ u8 vsync_pulse_width_lo:4;
+ u8 vsync_off_lo:4;
+ u8 vsync_pulse_width_hi:2;
+ u8 vsync_off_hi:2;
+ u8 hsync_pulse_width_hi:2;
+ u8 hsync_off_hi:2;
+ u8 himage_lo;
+ u8 vimage_lo;
+ u8 vimage_hi:4;
+ u8 himage_hi:4;
+ u8 h_border;
+ u8 v_border;
+ u8 rsvd1:3;
+ u8 digital:2;
+ u8 vsync_positive:1;
+ u8 hsync_positive:1;
+ u8 non_interlaced:1;
+} __packed;
+
/**
* struct vbt_header - VBT Header structure
* @signature: VBT signature, always starts with "$VBT"
@@ -97,40 +141,56 @@ struct bdb_header {
enum bdb_block_id {
BDB_GENERAL_FEATURES = 1,
BDB_GENERAL_DEFINITIONS = 2,
- BDB_OLD_TOGGLE_LIST = 3,
+ BDB_DISPLAY_TOGGLE = 3,
BDB_MODE_SUPPORT_LIST = 4,
BDB_GENERIC_MODE_TABLE = 5,
- BDB_EXT_MMIO_REGS = 6,
- BDB_SWF_IO = 7,
- BDB_SWF_MMIO = 8,
- BDB_PSR = 9,
+ BDB_EXT_MMIO_REGS = 6, /* VBIOS only */
+ BDB_SWF_IO = 7, /* VBIOS only */
+ BDB_SWF_MMIO = 8, /* VBIOS only */
+ BDB_DOT_CLOCK_OVERRIDE_ALM = 9,
+ BDB_PSR = 9, /* 165+ */
BDB_MODE_REMOVAL_TABLE = 10,
BDB_CHILD_DEVICE_TABLE = 11,
BDB_DRIVER_FEATURES = 12,
BDB_DRIVER_PERSISTENCE = 13,
- BDB_EXT_TABLE_PTRS = 14,
+ BDB_EXT_TABLE_PTRS = 14, /* VBIOS only */
BDB_DOT_CLOCK_OVERRIDE = 15,
- BDB_DISPLAY_SELECT = 16,
+ BDB_DISPLAY_SELECT_OLD = 16,
+ BDB_SV_TEST_FUNCTIONS = 17,
BDB_DRIVER_ROTATION = 18,
- BDB_DISPLAY_REMOVE = 19,
+ BDB_DISPLAY_REMOVE_OLD = 19,
BDB_OEM_CUSTOM = 20,
BDB_EFP_LIST = 21, /* workarounds for VGA hsync/vsync */
BDB_SDVO_LVDS_OPTIONS = 22,
- BDB_SDVO_PANEL_DTDS = 23,
- BDB_SDVO_LVDS_PNP_IDS = 24,
- BDB_SDVO_LVDS_POWER_SEQ = 25,
+ BDB_SDVO_LVDS_DTD = 23,
+ BDB_SDVO_LVDS_PNP_ID = 24,
+ BDB_SDVO_LVDS_PPS = 25,
BDB_TV_OPTIONS = 26,
BDB_EDP = 27,
- BDB_LVDS_OPTIONS = 40,
- BDB_LVDS_LFP_DATA_PTRS = 41,
- BDB_LVDS_LFP_DATA = 42,
- BDB_LVDS_BACKLIGHT = 43,
+ BDB_EFP_DTD = 28, /* 161+ */
+ BDB_DISPLAY_SELECT_IVB = 29, /* 164+ */
+ BDB_DISPLAY_REMOVE_IVB = 30, /* 164+ */
+ BDB_DISPLAY_SELECT_HSW = 31, /* 166+ */
+ BDB_DISPLAY_REMOVE_HSW = 32, /* 166+ */
+ BDB_LFP_OPTIONS = 40,
+ BDB_LFP_DATA_PTRS = 41,
+ BDB_LFP_DATA = 42,
+ BDB_LFP_BACKLIGHT = 43,
BDB_LFP_POWER = 44,
- BDB_MIPI_CONFIG = 52,
- BDB_MIPI_SEQUENCE = 53,
- BDB_COMPRESSION_PARAMETERS = 56,
- BDB_GENERIC_DTD = 58,
- BDB_SKIP = 254, /* VBIOS private block, ignore */
+ BDB_EDP_BFI = 45, /* 160+ */
+ BDB_CHROMATICITY = 46, /* 169+ */
+ BDB_MIPI = 50, /* 170-172 */
+ BDB_FIXED_SET_MODE = 51, /* 172+ */
+ BDB_MIPI_CONFIG = 52, /* 175+ */
+ BDB_MIPI_SEQUENCE = 53, /* 177+ */
+ BDB_RGB_PALETTE = 54, /* 180+ */
+ BDB_COMPRESSION_PARAMETERS_OLD = 55, /* 198-212 */
+ BDB_COMPRESSION_PARAMETERS = 56, /* 213+ */
+ BDB_VSWING_PREEMPH = 57, /* 218+ */
+ BDB_GENERIC_DTD = 58, /* 229+ */
+ BDB_INT15_HOOK = 252, /* VBIOS only */
+ BDB_PRD_TABLE = 253,
+ BDB_SKIP = 254, /* VBIOS only */
};
/*
@@ -198,10 +258,11 @@ struct bdb_general_features {
/* Device handle */
#define DEVICE_HANDLE_CRT 0x0001
+#define DEVICE_HANDLE_TV 0x0002 /* ???-214 */
#define DEVICE_HANDLE_EFP1 0x0004
#define DEVICE_HANDLE_EFP2 0x0040
#define DEVICE_HANDLE_EFP3 0x0020
-#define DEVICE_HANDLE_EFP4 0x0010 /* 194+ */
+#define DEVICE_HANDLE_EFP4 0x0010
#define DEVICE_HANDLE_EFP5 0x0002 /* 215+ */
#define DEVICE_HANDLE_EFP6 0x0001 /* 217+ */
#define DEVICE_HANDLE_EFP7 0x0100 /* 217+ */
@@ -517,6 +578,114 @@ struct bdb_general_definitions {
} __packed;
/*
+ * Block 3 - Display Toggle Option Block
+ */
+
+struct bdb_display_toggle {
+ u8 feature_bits;
+ u16 num_entries; /* ALM only */
+ u16 list[]; /* ALM only */
+} __packed;
+
+/*
+ * Block 4 - Mode Support List
+ */
+
+struct bdb_mode_support_list {
+ u8 intel_mode_number[0];
+ u16 mode_list_length;
+} __packed;
+
+/*
+ * Block 5 - Generic Mode Table
+ */
+
+struct generic_mode_table {
+ u16 x_res;
+ u16 y_res;
+ u8 color_depths;
+ u8 refresh_rate[3];
+ u8 reserved;
+ u8 text_cols;
+ u8 text_rows;
+ u8 font_height;
+ u16 page_size;
+ u8 misc;
+} __packed;
+
+struct generic_mode_timings {
+ u32 dotclock_khz;
+ u16 hdisplay;
+ u16 htotal;
+ u16 hblank_start;
+ u16 hblank_end;
+ u16 hsync_start;
+ u16 hsync_end;
+ u16 vdisplay;
+ u16 vtotal;
+ u16 vblank_start;
+ u16 vblank_end;
+ u16 vsync_start;
+ u16 vsync_end;
+} __packed;
+
+struct generic_mode_timings_alm {
+ struct generic_mode_timings timings;
+ u8 wm_8bpp;
+ u8 burst_8bpp;
+ u8 wm_16bpp;
+ u8 burst_16bpp;
+ u8 wm_32bpp;
+ u8 burst_32bpp;
+} __packed;
+
+struct bdb_generic_mode_table_alm {
+ struct generic_mode_table table;
+ struct generic_mode_timings_alm timings[3];
+} __packed;
+
+struct bdb_generic_mode_table_mgm {
+ u16 mode_flag;
+ struct generic_mode_table table;
+ struct generic_mode_timings timings[3];
+} __packed;
+
+/*
+ * Block 6 - Extended MMIO Register Table, VBIOS only
+ * Block 7 - IO Software Flag Table, VBIOS only
+ * Block 8 - MMIO SWF Register Table, VBIOS only
+ */
+struct bdb_reg_table {
+ u16 table_id;
+ u8 data_access_size;
+ /*
+ * offset,value tuples:
+ * data_access_size==0xce -> u8,u8
+ * data_access_size==0x02 -> u32,u32
+ */
+ /* u16 table_end_marker; */
+} __packed;
+
+/*
+ * Block 9 - Undocumented table (ALM only)
+ */
+
+struct dot_clock_override_entry_gen2 {
+ u32 dotclock;
+ u8 n;
+ u8 m1;
+ u8 m2;
+ u8 p1:5;
+ u8 p1_div_by_2:1;
+ u8 reserved:1;
+ u8 p2_div_by_4:1;
+} __packed;
+
+struct bdb_dot_clock_override_alm {
+ struct dot_clock_override_entry_gen2 t[0];
+} __packed;
+
+/*
* Block 9 - SRD Feature Block
*/
@@ -544,6 +713,29 @@ struct bdb_psr {
} __packed;
/*
+ * Block 10 - Mode Removal Table
+ */
+
+struct mode_removal_table {
+ u16 x_res;
+ u16 y_res;
+ u8 bpp;
+ u16 refresh_rate;
+ u8 removal_flags;
+ u16 panel_flags;
+} __packed;
+
+struct bdb_mode_removal {
+ u8 row_size; /* 8 or 10 bytes */
+ /*
+ * VBT spec says this is always 20 entries,
+ * but ALM seems to have only 15 entries.
+ */
+ struct mode_removal_table modes[];
+ /* u16 terminator; 0x0000 */
+} __packed;
+
+/*
* Block 12 - Driver Features Data Block
*/
@@ -622,6 +814,139 @@ struct bdb_driver_features {
} __packed;
/*
+ * Block 13 - Driver Persistent Algorithm
+ */
+
+struct bdb_driver_persistence {
+ u16 hotkey_persistent_algorithm:1;
+ u16 lid_switch_persistent_algorithm:1;
+ u16 power_management_persistent_algorithm:1;
+ u16 hotkey_persistent_on_mds_twin:1;
+ u16 hotkey_persistent_on_refresh_rate:1;
+ u16 hotkey_persistent_on_restore_pipe:1;
+ u16 hotkey_persistent_on_mode:1;
+ u16 edid_persistent_on_mode:1;
+ u16 dvo_hotplug_persistent_on_mode:1;
+ u16 docking_persistent_algorithm:1;
+ u16 rsvd:6;
+ u8 persistent_max_config;
+} __packed;
+
+/*
+ * Block 15 - Dot Clock Override Table
+ */
+
+struct dot_clock_override_entry_gen3 {
+ u32 dotclock;
+ u8 n;
+ u8 m1;
+ u8 m2;
+ u8 p1;
+ u8 p2;
+} __packed;
+
+struct bdb_dot_clock_override {
+ u8 row_size; /* 8 == gen2, 9 == gen3+ */
+ u8 num_rows;
+ struct dot_clock_override_entry_gen3 table[]; /* or _gen2 */
+} __packed;
+
+/*
+ * Block 16 - Toggle List Block (pre-HSW)
+ */
+
+struct toggle_list_entry_old {
+ u8 display_select_pipe_a;
+ u8 display_select_pipe_b;
+ u8 caps;
+} __packed;
+
+struct toggle_list_table_old {
+ u16 num_entries;
+ u8 entry_size;
+ struct toggle_list_entry_old list[];
+} __packed;
+
+struct bdb_display_select_old {
+ /* each table has variable size! */
+ struct toggle_list_table_old tables[4];
+} __packed;
+
+/*
+ * Block 17 - SV Test Functions
+ */
+
+struct bdb_sv_test_functions {
+ u8 sv_bits[8];
+} __packed;
+
+/*
+ * Block 18 - Driver Rotation
+ */
+
+struct bdb_driver_rotation {
+ u8 rotation_enable;
+ u8 rotation_flags_1;
+ u16 rotation_flags_2;
+ u32 rotation_flags_3;
+ u32 rotation_flags_4;
+} __packed;
+
+/*
+ * Block 19 - Display Configuration Removal Table (pre-IVB)
+ */
+
+struct display_remove_entry_old {
+ u8 display_select_pipe_a;
+ u8 display_select_pipe_b;
+} __packed;
+
+struct bdb_display_remove_old {
+ u8 num_entries;
+ u8 entry_size;
+ struct display_remove_entry_old table[];
+} __packed;
+
+/*
+ * Block 20 - OEM Customizable Modes
+ */
+
+struct oem_mode {
+ u8 enable_in_vbios:1;
+ u8 enable_in_os:1;
+ u8 enable_in_gop:1; /* 207+ */
+ u8 reserved:5;
+ u8 display_flags; /* ???-216 */
+ u16 x_res;
+ u16 y_res;
+ u8 color_depth;
+ u8 refresh_rate;
+ struct bdb_edid_dtd dtd;
+ u16 display_flags_2; /* 217+ */
+} __packed;
+
+struct bdb_oem_custom {
+ u8 num_entries;
+ u8 entry_size;
+ struct oem_mode modes[];
+} __packed;
+
+/*
+ * Block 21 - EFP List
+ */
+
+struct efp_entry {
+ u16 mfg_name;
+ u16 product_code;
+} __packed;
+
+struct bdb_efp_list {
+ u8 num_entries;
+ u8 entry_size;
+ struct efp_entry efp[];
+} __packed;
+
+/*
* Block 22 - SDVO LVDS General Options
*/
@@ -642,42 +967,47 @@ struct bdb_sdvo_lvds_options {
} __packed;
/*
- * Block 23 - SDVO LVDS Panel DTDs
+ * Block 23 - SDVO LVDS DTD
*/
-struct lvds_dvo_timing {
- u16 clock; /**< In 10khz */
- u8 hactive_lo;
- u8 hblank_lo;
- u8 hblank_hi:4;
- u8 hactive_hi:4;
- u8 vactive_lo;
- u8 vblank_lo;
- u8 vblank_hi:4;
- u8 vactive_hi:4;
- u8 hsync_off_lo;
- u8 hsync_pulse_width_lo;
- u8 vsync_pulse_width_lo:4;
- u8 vsync_off_lo:4;
- u8 vsync_pulse_width_hi:2;
- u8 vsync_off_hi:2;
- u8 hsync_pulse_width_hi:2;
- u8 hsync_off_hi:2;
- u8 himage_lo;
- u8 vimage_lo;
- u8 vimage_hi:4;
- u8 himage_hi:4;
- u8 h_border;
- u8 v_border;
- u8 rsvd1:3;
- u8 digital:2;
- u8 vsync_positive:1;
- u8 hsync_positive:1;
- u8 non_interlaced:1;
+struct bdb_sdvo_lvds_dtd {
+ struct bdb_edid_dtd dtd[4];
} __packed;
-struct bdb_sdvo_panel_dtds {
- struct lvds_dvo_timing dtds[4];
+/*
+ * Block 24 - SDVO LVDS PnP ID
+ */
+
+struct bdb_sdvo_lvds_pnp_id {
+ struct bdb_edid_pnp_id pnp_id[4];
+} __packed;
+
+/*
+ * Block 25 - SDVO LVDS PPS
+ */
+
+struct sdvo_lvds_pps {
+ u16 t0; /* power on */
+ u16 t1; /* backlight on */
+ u16 t2; /* backlight off */
+ u16 t3; /* power off */
+ u16 t4; /* power cycle */
+} __packed;
+
+struct bdb_sdvo_lvds_pps {
+ struct sdvo_lvds_pps pps[4];
+} __packed;
+
+/*
+ * Block 26 - TV Options Block
+ */
+
+struct bdb_tv_options {
+ u16 underscan_overscan_hdtv_component:2;
+ u16 rsvd1:10;
+ u16 underscan_overscan_hdtv_dvi:2;
+ u16 add_modes_to_avoid_overscan_issue:1;
+ u16 d_connector_support:1;
} __packed;
/*
@@ -749,13 +1079,88 @@ struct bdb_edp {
struct edp_apical_params apical_params[16]; /* 203+ */
u16 edp_fast_link_training_rate[16]; /* 224+ */
u16 edp_max_port_link_rate[16]; /* 244+ */
+ u16 edp_dsc_disable; /* 251+ */
+} __packed;
+
+/*
+ * Block 28 - EFP DTD Block
+ */
+
+struct bdb_efp_dtd {
+ struct bdb_edid_dtd dtd[3];
+} __packed;
+
+/*
+ * Block 29 - Toggle List Block (IVB)
+ */
+
+struct toggle_list_entry_ivb {
+ u8 display_select;
+} __packed;
+
+struct toggle_list_table_ivb {
+ u16 num_entries;
+ u8 entry_size;
+ struct toggle_list_entry_ivb list[];
+} __packed;
+
+struct bdb_display_select_ivb {
+ /* each table has variable size! */
+ struct toggle_list_table_ivb tables[4];
+} __packed;
+
+/*
+ * Block 30 - Display Configuration Removal Table (IVB)
+ */
+
+struct display_remove_entry_ivb {
+ u8 display_select;
+} __packed;
+
+struct bdb_display_remove_ivb {
+ u8 num_entries;
+ u8 entry_size;
+ struct display_remove_entry_ivb table[];
+} __packed;
+
+/*
+ * Block 31 - Toggle List Block (HSW+)
+ */
+
+struct toggle_list_entry_hsw {
+ u16 display_select;
+} __packed;
+
+struct toggle_list_table_hsw {
+ u16 num_entries;
+ u8 entry_size;
+ struct toggle_list_entry_hsw list[];
+} __packed;
+
+struct bdb_display_select_hsw {
+ /* each table has variable size! */
+ struct toggle_list_table_hsw tables[4];
+} __packed;
+
+/*
+ * Block 32 - Display Configuration Removal Table (HSW+)
+ */
+
+struct display_remove_entry_hsw {
+ u16 display_select;
+} __packed;
+
+struct bdb_display_remove_hsw {
+ u8 num_entries;
+ u8 entry_size;
+ struct display_remove_entry_hsw table[];
} __packed;
/*
* Block 40 - LFP Data Block
*/
-struct bdb_lvds_options {
+struct bdb_lfp_options {
u8 panel_type;
u8 panel_type2; /* 212+ */
/* LVDS capabilities, stored in a dword */
@@ -788,22 +1193,22 @@ struct bdb_lvds_options {
/*
* Block 41 - LFP Data Table Pointers
*/
-struct lvds_lfp_data_ptr_table {
+struct lfp_data_ptr_table {
u16 offset; /* offsets are from start of bdb */
u8 table_size;
} __packed;
/* LFP pointer table contains entries to the struct below */
-struct lvds_lfp_data_ptr {
- struct lvds_lfp_data_ptr_table fp_timing;
- struct lvds_lfp_data_ptr_table dvo_timing;
- struct lvds_lfp_data_ptr_table panel_pnp_id;
+struct lfp_data_ptr {
+ struct lfp_data_ptr_table fp_timing;
+ struct lfp_data_ptr_table dvo_timing;
+ struct lfp_data_ptr_table panel_pnp_id;
} __packed;
-struct bdb_lvds_lfp_data_ptrs {
- u8 lvds_entries;
- struct lvds_lfp_data_ptr ptr[16];
- struct lvds_lfp_data_ptr_table panel_name; /* (156-163?)+ */
+struct bdb_lfp_data_ptrs {
+ u8 num_entries;
+ struct lfp_data_ptr ptr[16];
+ struct lfp_data_ptr_table panel_name; /* (156-163?)+ */
} __packed;
/*
@@ -811,7 +1216,7 @@ struct bdb_lvds_lfp_data_ptrs {
*/
/* LFP data has 3 blocks per entry */
-struct lvds_fp_timing {
+struct fp_timing {
u16 x_res;
u16 y_res;
u32 lvds_reg;
@@ -827,46 +1232,34 @@ struct lvds_fp_timing {
u16 terminator;
} __packed;
-struct lvds_pnp_id {
- u16 mfg_name;
- u16 product_code;
- u32 serial;
- u8 mfg_week;
- u8 mfg_year;
-} __packed;
-
/*
* For reference only. fp_timing has variable size so
* the data must be accessed using the data table pointers.
* Do not use this directly!
*/
-struct lvds_lfp_data_entry {
- struct lvds_fp_timing fp_timing;
- struct lvds_dvo_timing dvo_timing;
- struct lvds_pnp_id pnp_id;
+struct lfp_data_entry {
+ struct fp_timing fp_timing;
+ struct bdb_edid_dtd dvo_timing;
+ struct bdb_edid_pnp_id pnp_id;
} __packed;
-struct bdb_lvds_lfp_data {
- struct lvds_lfp_data_entry data[16];
+struct bdb_lfp_data {
+ struct lfp_data_entry data[16];
} __packed;
-struct lvds_lfp_panel_name {
- u8 name[13];
-} __packed;
-
-struct lvds_lfp_black_border {
+struct lfp_black_border {
u8 top; /* 227+ */
u8 bottom; /* 227+ */
u8 left; /* 238+ */
u8 right; /* 238+ */
} __packed;
-struct bdb_lvds_lfp_data_tail {
- struct lvds_lfp_panel_name panel_name[16]; /* (156-163?)+ */
+struct bdb_lfp_data_tail {
+ struct bdb_edid_product_name panel_name[16]; /* (156-163?)+ */
u16 scaling_enable; /* 187+ */
u8 seamless_drrs_min_refresh_rate[16]; /* 188+ */
u8 pixel_overlap_count[16]; /* 208+ */
- struct lvds_lfp_black_border black_border[16]; /* 227+ */
+ struct lfp_black_border black_border[16]; /* 227+ */
u16 dual_lfp_port_sync_enable; /* 231+ */
u16 gpu_dithering_for_banding_artifacts; /* 245+ */
} __packed;
@@ -899,7 +1292,7 @@ struct lfp_brightness_level {
u16 reserved;
} __packed;
-struct bdb_lfp_backlight_data {
+struct bdb_lfp_backlight {
u8 entry_size;
struct lfp_backlight_data_entry data[16];
u8 level[16]; /* 162-233 */
@@ -959,6 +1352,122 @@ struct bdb_lfp_power {
} __packed;
/*
+ * Block 45 - eDP BFI Block
+ */
+
+struct edp_bfi {
+ u8 enable_bfi_in_driver:1;
+ u8 enable_brightness_control_in_cui:1;
+ u8 reserved:6;
+ u8 brightness_percentage_when_bfi_disabled;
+} __packed;
+
+struct bdb_edp_bfi {
+ u8 bfi_structure_size;
+ struct edp_bfi bfi[16];
+} __packed;
+
+/*
+ * Block 46 - Chromaticity For Narrow Gamut Panel Configuration Block
+ */
+
+struct chromaticity {
+ u8 chromaticity_enable:1;
+ u8 chromaticity_from_edid_base_block:1;
+ u8 rsvd:6;
+
+ u8 green_y_lo:2;
+ u8 green_x_lo:2;
+ u8 red_y_lo:2;
+ u8 red_x_lo:2;
+ u8 white_y_lo:2;
+ u8 white_x_lo:2;
+ u8 blue_y_lo:2;
+ u8 blue_x_lo:2;
+
+ u8 red_x_hi;
+ u8 red_y_hi;
+ u8 green_x_hi;
+ u8 green_y_hi;
+ u8 blue_x_hi;
+ u8 blue_y_hi;
+ u8 white_x_hi;
+ u8 white_y_hi;
+} __packed;
+
+struct luminance_and_gamma {
+ u8 luminance_enable:1; /* 211+ */
+ u8 gamma_enable:1; /* 211+ */
+ u8 rsvd:6;
+
+ u16 min_luminance; /* 211+ */
+ u16 max_luminance; /* 211+ */
+ u16 one_percent_max_luminance; /* 211+ */
+ u8 gamma; /* 211+ */
+} __packed;
+
+struct bdb_chromaticity {
+ struct chromaticity chromaticity[16];
+ struct luminance_and_gamma luminance_and_gamma[16]; /* 211+ */
+} __packed;
+
+/*
+ * Block 50 - MIPI Block
+ */
+
+struct mipi_data {
+ u16 panel_identifier;
+ u16 bridge_revision;
+
+ u32 dithering:1;
+ u32 pixel_format_18bpp:1;
+ u32 reserved1:1;
+ u32 dphy_params_valid:1;
+ u32 reserved2:28;
+
+ u16 port_info;
+
+ u16 reserved3:2;
+ u16 num_lanes:2;
+ u16 reserved4:12;
+
+ u16 virtual_channel_num:2;
+ u16 video_transfer_mode:2;
+ u16 reserved5:12;
+
+ u32 dsi_ddr_clock;
+ u32 renesas_bridge_ref_clock;
+ u16 power_conservation;
+
+ u32 prepare_count:5;
+ u32 reserved6:3;
+ u32 clk_zero_count:8;
+ u32 trail_count:5;
+ u32 reserved7:3;
+ u32 exit_zero_count:6;
+ u32 reserved8:2;
+
+ u32 high_low_switch_count;
+ u32 lp_byte_clock;
+ u32 clock_lane_switch_time_counter;
+ u32 panel_color_depth;
+} __packed;
+
+struct bdb_mipi {
+ struct mipi_data mipi[16];
+} __packed;
+
+/*
+ * Block 51 - Fixed Set Mode Table
+ */
+
+struct bdb_fixed_set_mode {
+ u8 enable;
+ u32 x_res;
+ u32 y_res;
+} __packed;
+
+/*
* Block 52 - MIPI Configuration Block
*/
@@ -981,6 +1490,17 @@ struct bdb_mipi_sequence {
} __packed;
/*
+ * Block 55 - RGB Palette Table
+ */
+
+struct bdb_rgb_palette {
+ u8 is_enabled;
+ u8 red[256];
+ u8 blue[256];
+ u8 green[256];
+} __packed;
+
+/*
* Block 56 - Compression Parameters
*/
@@ -1032,6 +1552,16 @@ struct bdb_compression_parameters {
} __packed;
/*
+ * Block 57 - Vswing PreEmphasis Table
+ */
+
+struct bdb_vswing_preemph {
+ u8 num_tables;
+ u8 num_columns;
+ u32 tables[];
+} __packed;
+
+/*
* Block 58 - Generic DTD Block
*/
@@ -1061,4 +1591,29 @@ struct bdb_generic_dtd {
struct generic_dtd_entry dtd[]; /* up to 24 DTD's */
} __packed;
+/*
+ * Block 253 - PRD Table
+ */
+
+struct prd_entry_old {
+ u8 displays_attached;
+ u8 display_in_pipe_a;
+ u8 display_in_pipe_b;
+} __packed;
+
+struct bdb_prd_table_old {
+ struct prd_entry_old list[0]; /* ???-216 */
+ u16 num_entries; /* ???-216 */
+} __packed;
+
+struct prd_entry_new {
+ u16 primary_display;
+ u16 secondary_display;
+} __packed;
+
+struct bdb_prd_table_new {
+ u16 num_entries; /* 217+ */
+ struct prd_entry_new list[]; /* 217+ */
+} __packed;
+
#endif /* _INTEL_VBT_DEFS_H_ */
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c
index 17d6572f9d0a..b9687b7692b8 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
@@ -10,7 +10,6 @@
#include <drm/display/drm_dsc_helper.h>
#include "i915_drv.h"
-#include "i915_reg.h"
#include "intel_crtc.h"
#include "intel_de.h"
#include "intel_display_types.h"
@@ -380,7 +379,7 @@ int intel_dsc_get_num_vdsc_instances(const struct intel_crtc_state *crtc_state)
{
int num_vdsc_instances = intel_dsc_get_vdsc_per_pipe(crtc_state);
- if (crtc_state->bigjoiner_pipes)
+ if (crtc_state->joiner_pipes)
num_vdsc_instances *= 2;
return num_vdsc_instances;
@@ -761,11 +760,11 @@ void intel_uncompressed_joiner_enable(const struct intel_crtc_state *crtc_state)
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
u32 dss_ctl1_val = 0;
- if (crtc_state->bigjoiner_pipes && !crtc_state->dsc.compression_enable) {
- if (intel_crtc_is_bigjoiner_slave(crtc_state))
- dss_ctl1_val |= UNCOMPRESSED_JOINER_SLAVE;
+ if (crtc_state->joiner_pipes && !crtc_state->dsc.compression_enable) {
+ if (intel_crtc_is_joiner_secondary(crtc_state))
+ dss_ctl1_val |= UNCOMPRESSED_JOINER_SECONDARY;
else
- dss_ctl1_val |= UNCOMPRESSED_JOINER_MASTER;
+ dss_ctl1_val |= UNCOMPRESSED_JOINER_PRIMARY;
intel_de_write(dev_priv, dss_ctl1_reg(crtc, crtc_state->cpu_transcoder), dss_ctl1_val);
}
@@ -789,10 +788,10 @@ void intel_dsc_enable(const struct intel_crtc_state *crtc_state)
dss_ctl2_val |= RIGHT_BRANCH_VDSC_ENABLE;
dss_ctl1_val |= JOINER_ENABLE;
}
- if (crtc_state->bigjoiner_pipes) {
+ if (crtc_state->joiner_pipes) {
dss_ctl1_val |= BIG_JOINER_ENABLE;
- if (!intel_crtc_is_bigjoiner_slave(crtc_state))
- dss_ctl1_val |= MASTER_BIG_JOINER_ENABLE;
+ if (!intel_crtc_is_joiner_secondary(crtc_state))
+ dss_ctl1_val |= PRIMARY_BIG_JOINER_ENABLE;
}
intel_de_write(dev_priv, dss_ctl1_reg(crtc, crtc_state->cpu_transcoder), dss_ctl1_val);
intel_de_write(dev_priv, dss_ctl2_reg(crtc, crtc_state->cpu_transcoder), dss_ctl2_val);
@@ -805,7 +804,7 @@ void intel_dsc_disable(const struct intel_crtc_state *old_crtc_state)
/* Disable only if either of them is enabled */
if (old_crtc_state->dsc.compression_enable ||
- old_crtc_state->bigjoiner_pipes) {
+ old_crtc_state->joiner_pipes) {
intel_de_write(dev_priv, dss_ctl1_reg(crtc, old_crtc_state->cpu_transcoder), 0);
intel_de_write(dev_priv, dss_ctl2_reg(crtc, old_crtc_state->cpu_transcoder), 0);
}
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc_regs.h b/drivers/gpu/drm/i915/display/intel_vdsc_regs.h
index 8b21dc8e26d5..f921ad67b587 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_vdsc_regs.h
@@ -32,13 +32,13 @@
_ICL_PIPE_DSS_CTL1_PB, \
_ICL_PIPE_DSS_CTL1_PC)
#define BIG_JOINER_ENABLE (1 << 29)
-#define MASTER_BIG_JOINER_ENABLE (1 << 28)
+#define PRIMARY_BIG_JOINER_ENABLE (1 << 28)
#define VGA_CENTERING_ENABLE (1 << 27)
#define SPLITTER_CONFIGURATION_MASK REG_GENMASK(26, 25)
#define SPLITTER_CONFIGURATION_2_SEGMENT REG_FIELD_PREP(SPLITTER_CONFIGURATION_MASK, 0)
#define SPLITTER_CONFIGURATION_4_SEGMENT REG_FIELD_PREP(SPLITTER_CONFIGURATION_MASK, 1)
-#define UNCOMPRESSED_JOINER_MASTER (1 << 21)
-#define UNCOMPRESSED_JOINER_SLAVE (1 << 20)
+#define UNCOMPRESSED_JOINER_PRIMARY (1 << 21)
+#define UNCOMPRESSED_JOINER_SECONDARY (1 << 20)
#define _ICL_PIPE_DSS_CTL2_PB 0x78204
#define _ICL_PIPE_DSS_CTL2_PC 0x78404
diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c
index 894ee97b3e1b..6430da25957d 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -9,8 +9,12 @@
#include "intel_de.h"
#include "intel_display_types.h"
#include "intel_vrr.h"
+#include "intel_vrr_regs.h"
#include "intel_dp.h"
+#define FIXED_POINT_PRECISION 100
+#define CMRR_PRECISION_TOLERANCE 10
+
bool intel_vrr_is_capable(struct intel_connector *connector)
{
const struct drm_display_info *info = &connector->base.display_info;
@@ -106,6 +110,53 @@ int intel_vrr_vmax_vblank_start(const struct intel_crtc_state *crtc_state)
return crtc_state->vrr.vmax - intel_vrr_vblank_exit_length(crtc_state);
}
+static bool
+is_cmrr_frac_required(struct intel_crtc_state *crtc_state)
+{
+ int calculated_refresh_k, actual_refresh_k, pixel_clock_per_line;
+ struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
+ struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+
+ if (!HAS_CMRR(i915))
+ return false;
+
+ actual_refresh_k =
+ drm_mode_vrefresh(adjusted_mode) * FIXED_POINT_PRECISION;
+ pixel_clock_per_line =
+ adjusted_mode->crtc_clock * 1000 / adjusted_mode->crtc_htotal;
+ calculated_refresh_k =
+ pixel_clock_per_line * FIXED_POINT_PRECISION / adjusted_mode->crtc_vtotal;
+
+ if ((actual_refresh_k - calculated_refresh_k) < CMRR_PRECISION_TOLERANCE)
+ return false;
+
+ return true;
+}
+
+static unsigned int
+cmrr_get_vtotal(struct intel_crtc_state *crtc_state, bool video_mode_required)
+{
+ int multiplier_m = 1, multiplier_n = 1, vtotal, desired_refresh_rate;
+ long long adjusted_pixel_rate;
+ struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
+
+ desired_refresh_rate = drm_mode_vrefresh(adjusted_mode);
+
+ if (video_mode_required) {
+ multiplier_m = 1001;
+ multiplier_n = 1000;
+ }
+
+ crtc_state->cmrr.cmrr_n = mul_u32_u32(desired_refresh_rate * adjusted_mode->crtc_htotal,
+ multiplier_n);
+ vtotal = DIV_ROUND_UP_ULL(mul_u32_u32(adjusted_mode->crtc_clock * 1000, multiplier_n),
+ crtc_state->cmrr.cmrr_n);
+ adjusted_pixel_rate = mul_u32_u32(adjusted_mode->crtc_clock * 1000, multiplier_m);
+ crtc_state->cmrr.cmrr_m = do_div(adjusted_pixel_rate, crtc_state->cmrr.cmrr_n);
+
+ return vtotal;
+}
+
void
intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
struct drm_connector_state *conn_state)
@@ -115,6 +166,7 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
struct intel_connector *connector =
to_intel_connector(conn_state->connector);
struct intel_dp *intel_dp = intel_attached_dp(connector);
+ bool is_edp = intel_dp_is_edp(intel_dp);
struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
const struct drm_display_info *info = &connector->base.display_info;
int vmin, vmax;
@@ -123,7 +175,7 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
* FIXME all joined pipes share the same transcoder.
* Need to account for that during VRR toggle/push/etc.
*/
- if (crtc_state->bigjoiner_pipes)
+ if (crtc_state->joiner_pipes)
return;
if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
@@ -159,6 +211,39 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
crtc_state->vrr.flipline = crtc_state->vrr.vmin + 1;
/*
+ * When panel is VRR capable and userspace has
+ * not enabled adaptive sync mode then Fixed Average
+ * Vtotal mode should be enabled.
+ */
+ if (crtc_state->uapi.vrr_enabled) {
+ crtc_state->vrr.enable = true;
+ crtc_state->mode_flags |= I915_MODE_FLAG_VRR;
+ } else if (is_cmrr_frac_required(crtc_state) && is_edp) {
+ crtc_state->vrr.enable = true;
+ crtc_state->cmrr.enable = true;
+ /*
+ * TODO: Compute precise target refresh rate to determine
+ * if video_mode_required should be true. Currently set to
+ * false due to uncertainty about the precise target
+ * refresh Rate.
+ */
+ crtc_state->vrr.vmax = cmrr_get_vtotal(crtc_state, false);
+ crtc_state->vrr.vmin = crtc_state->vrr.vmax;
+ crtc_state->vrr.flipline = crtc_state->vrr.vmin;
+ crtc_state->mode_flags |= I915_MODE_FLAG_VRR;
+ }
+
+ if (intel_dp_as_sdp_supported(intel_dp) &&
+ crtc_state->vrr.enable) {
+ crtc_state->vrr.vsync_start =
+ (crtc_state->hw.adjusted_mode.crtc_vtotal -
+ crtc_state->hw.adjusted_mode.vsync_start);
+ crtc_state->vrr.vsync_end =
+ (crtc_state->hw.adjusted_mode.crtc_vtotal -
+ crtc_state->hw.adjusted_mode.vsync_end);
+ }
+
+ /*
* For XE_LPD+, we use guardband and pipeline override
* is deprecated.
*/
@@ -170,19 +255,6 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
min(255, crtc_state->vrr.vmin - adjusted_mode->crtc_vblank_start -
crtc_state->framestart_delay - 1);
}
-
- if (crtc_state->uapi.vrr_enabled) {
- crtc_state->vrr.enable = true;
- crtc_state->mode_flags |= I915_MODE_FLAG_VRR;
- if (intel_dp_as_sdp_supported(intel_dp)) {
- crtc_state->vrr.vsync_start =
- (crtc_state->hw.adjusted_mode.crtc_vtotal -
- crtc_state->hw.adjusted_mode.vsync_start);
- crtc_state->vrr.vsync_end =
- (crtc_state->hw.adjusted_mode.crtc_vtotal -
- crtc_state->hw.adjusted_mode.vsync_end);
- }
- }
}
static u32 trans_vrr_ctl(const struct intel_crtc_state *crtc_state)
@@ -213,14 +285,30 @@ void intel_vrr_set_transcoder_timings(const struct intel_crtc_state *crtc_state)
0, PIPE_VBLANK_WITH_DELAY);
if (!crtc_state->vrr.flipline) {
- intel_de_write(dev_priv, TRANS_VRR_CTL(cpu_transcoder), 0);
+ intel_de_write(dev_priv,
+ TRANS_VRR_CTL(dev_priv, cpu_transcoder), 0);
return;
}
- intel_de_write(dev_priv, TRANS_VRR_VMIN(cpu_transcoder), crtc_state->vrr.vmin - 1);
- intel_de_write(dev_priv, TRANS_VRR_VMAX(cpu_transcoder), crtc_state->vrr.vmax - 1);
- intel_de_write(dev_priv, TRANS_VRR_CTL(cpu_transcoder), trans_vrr_ctl(crtc_state));
- intel_de_write(dev_priv, TRANS_VRR_FLIPLINE(cpu_transcoder), crtc_state->vrr.flipline - 1);
+ if (crtc_state->cmrr.enable) {
+ intel_de_write(dev_priv, TRANS_CMRR_M_HI(dev_priv, cpu_transcoder),
+ upper_32_bits(crtc_state->cmrr.cmrr_m));
+ intel_de_write(dev_priv, TRANS_CMRR_M_LO(dev_priv, cpu_transcoder),
+ lower_32_bits(crtc_state->cmrr.cmrr_m));
+ intel_de_write(dev_priv, TRANS_CMRR_N_HI(dev_priv, cpu_transcoder),
+ upper_32_bits(crtc_state->cmrr.cmrr_n));
+ intel_de_write(dev_priv, TRANS_CMRR_N_LO(dev_priv, cpu_transcoder),
+ lower_32_bits(crtc_state->cmrr.cmrr_n));
+ }
+
+ intel_de_write(dev_priv, TRANS_VRR_VMIN(dev_priv, cpu_transcoder),
+ crtc_state->vrr.vmin - 1);
+ intel_de_write(dev_priv, TRANS_VRR_VMAX(dev_priv, cpu_transcoder),
+ crtc_state->vrr.vmax - 1);
+ intel_de_write(dev_priv, TRANS_VRR_CTL(dev_priv, cpu_transcoder),
+ trans_vrr_ctl(crtc_state));
+ intel_de_write(dev_priv, TRANS_VRR_FLIPLINE(dev_priv, cpu_transcoder),
+ crtc_state->vrr.flipline - 1);
}
void intel_vrr_send_push(const struct intel_crtc_state *crtc_state)
@@ -232,7 +320,7 @@ void intel_vrr_send_push(const struct intel_crtc_state *crtc_state)
if (!crtc_state->vrr.enable)
return;
- intel_de_write(dev_priv, TRANS_PUSH(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_PUSH(dev_priv, cpu_transcoder),
TRANS_PUSH_EN | TRANS_PUSH_SEND);
}
@@ -245,7 +333,7 @@ bool intel_vrr_is_push_sent(const struct intel_crtc_state *crtc_state)
if (!crtc_state->vrr.enable)
return false;
- return intel_de_read(dev_priv, TRANS_PUSH(cpu_transcoder)) & TRANS_PUSH_SEND;
+ return intel_de_read(dev_priv, TRANS_PUSH(dev_priv, cpu_transcoder)) & TRANS_PUSH_SEND;
}
void intel_vrr_enable(const struct intel_crtc_state *crtc_state)
@@ -256,15 +344,23 @@ void intel_vrr_enable(const struct intel_crtc_state *crtc_state)
if (!crtc_state->vrr.enable)
return;
- intel_de_write(dev_priv, TRANS_PUSH(cpu_transcoder), TRANS_PUSH_EN);
+ intel_de_write(dev_priv, TRANS_PUSH(dev_priv, cpu_transcoder),
+ TRANS_PUSH_EN);
if (HAS_AS_SDP(dev_priv))
- intel_de_write(dev_priv, TRANS_VRR_VSYNC(cpu_transcoder),
+ intel_de_write(dev_priv,
+ TRANS_VRR_VSYNC(dev_priv, cpu_transcoder),
VRR_VSYNC_END(crtc_state->vrr.vsync_end) |
VRR_VSYNC_START(crtc_state->vrr.vsync_start));
- intel_de_write(dev_priv, TRANS_VRR_CTL(cpu_transcoder),
- VRR_CTL_VRR_ENABLE | trans_vrr_ctl(crtc_state));
+ if (crtc_state->cmrr.enable) {
+ intel_de_write(dev_priv, TRANS_VRR_CTL(dev_priv, cpu_transcoder),
+ VRR_CTL_VRR_ENABLE | VRR_CTL_CMRR_ENABLE |
+ trans_vrr_ctl(crtc_state));
+ } else {
+ intel_de_write(dev_priv, TRANS_VRR_CTL(dev_priv, cpu_transcoder),
+ VRR_CTL_VRR_ENABLE | trans_vrr_ctl(crtc_state));
+ }
}
void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state)
@@ -276,14 +372,16 @@ void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state)
if (!old_crtc_state->vrr.enable)
return;
- intel_de_write(dev_priv, TRANS_VRR_CTL(cpu_transcoder),
+ intel_de_write(dev_priv, TRANS_VRR_CTL(dev_priv, cpu_transcoder),
trans_vrr_ctl(old_crtc_state));
- intel_de_wait_for_clear(dev_priv, TRANS_VRR_STATUS(cpu_transcoder),
+ intel_de_wait_for_clear(dev_priv,
+ TRANS_VRR_STATUS(dev_priv, cpu_transcoder),
VRR_STATUS_VRR_EN_LIVE, 1000);
- intel_de_write(dev_priv, TRANS_PUSH(cpu_transcoder), 0);
+ intel_de_write(dev_priv, TRANS_PUSH(dev_priv, cpu_transcoder), 0);
if (HAS_AS_SDP(dev_priv))
- intel_de_write(dev_priv, TRANS_VRR_VSYNC(cpu_transcoder), 0);
+ intel_de_write(dev_priv,
+ TRANS_VRR_VSYNC(dev_priv, cpu_transcoder), 0);
}
void intel_vrr_get_config(struct intel_crtc_state *crtc_state)
@@ -292,9 +390,21 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state)
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
u32 trans_vrr_ctl, trans_vrr_vsync;
- trans_vrr_ctl = intel_de_read(dev_priv, TRANS_VRR_CTL(cpu_transcoder));
+ trans_vrr_ctl = intel_de_read(dev_priv,
+ TRANS_VRR_CTL(dev_priv, cpu_transcoder));
crtc_state->vrr.enable = trans_vrr_ctl & VRR_CTL_VRR_ENABLE;
+ if (HAS_CMRR(dev_priv))
+ crtc_state->cmrr.enable = (trans_vrr_ctl & VRR_CTL_CMRR_ENABLE);
+
+ if (crtc_state->cmrr.enable) {
+ crtc_state->cmrr.cmrr_n =
+ intel_de_read64_2x32(dev_priv, TRANS_CMRR_N_LO(dev_priv, cpu_transcoder),
+ TRANS_CMRR_N_HI(dev_priv, cpu_transcoder));
+ crtc_state->cmrr.cmrr_m =
+ intel_de_read64_2x32(dev_priv, TRANS_CMRR_M_LO(dev_priv, cpu_transcoder),
+ TRANS_CMRR_M_HI(dev_priv, cpu_transcoder));
+ }
if (DISPLAY_VER(dev_priv) >= 13)
crtc_state->vrr.guardband =
@@ -305,9 +415,12 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state)
REG_FIELD_GET(VRR_CTL_PIPELINE_FULL_MASK, trans_vrr_ctl);
if (trans_vrr_ctl & VRR_CTL_FLIP_LINE_EN) {
- crtc_state->vrr.flipline = intel_de_read(dev_priv, TRANS_VRR_FLIPLINE(cpu_transcoder)) + 1;
- crtc_state->vrr.vmax = intel_de_read(dev_priv, TRANS_VRR_VMAX(cpu_transcoder)) + 1;
- crtc_state->vrr.vmin = intel_de_read(dev_priv, TRANS_VRR_VMIN(cpu_transcoder)) + 1;
+ crtc_state->vrr.flipline = intel_de_read(dev_priv,
+ TRANS_VRR_FLIPLINE(dev_priv, cpu_transcoder)) + 1;
+ crtc_state->vrr.vmax = intel_de_read(dev_priv,
+ TRANS_VRR_VMAX(dev_priv, cpu_transcoder)) + 1;
+ crtc_state->vrr.vmin = intel_de_read(dev_priv,
+ TRANS_VRR_VMIN(dev_priv, cpu_transcoder)) + 1;
}
if (crtc_state->vrr.enable) {
@@ -315,7 +428,8 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state)
if (HAS_AS_SDP(dev_priv)) {
trans_vrr_vsync =
- intel_de_read(dev_priv, TRANS_VRR_VSYNC(cpu_transcoder));
+ intel_de_read(dev_priv,
+ TRANS_VRR_VSYNC(dev_priv, cpu_transcoder));
crtc_state->vrr.vsync_start =
REG_FIELD_GET(VRR_VSYNC_START_MASK, trans_vrr_vsync);
crtc_state->vrr.vsync_end =
diff --git a/drivers/gpu/drm/i915/display/intel_vrr_regs.h b/drivers/gpu/drm/i915/display/intel_vrr_regs.h
new file mode 100644
index 000000000000..6ed0e0dc97e7
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_vrr_regs.h
@@ -0,0 +1,127 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef __INTEL_VRR_REGS_H__
+#define __INTEL_VRR_REGS_H__
+
+#include "intel_display_reg_defs.h"
+
+/* VRR registers */
+#define _TRANS_VRR_CTL_A 0x60420
+#define _TRANS_VRR_CTL_B 0x61420
+#define _TRANS_VRR_CTL_C 0x62420
+#define _TRANS_VRR_CTL_D 0x63420
+#define TRANS_VRR_CTL(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_VRR_CTL_A)
+#define VRR_CTL_VRR_ENABLE REG_BIT(31)
+#define VRR_CTL_IGN_MAX_SHIFT REG_BIT(30)
+#define VRR_CTL_FLIP_LINE_EN REG_BIT(29)
+#define VRR_CTL_PIPELINE_FULL_MASK REG_GENMASK(10, 3)
+#define VRR_CTL_PIPELINE_FULL(x) REG_FIELD_PREP(VRR_CTL_PIPELINE_FULL_MASK, (x))
+#define VRR_CTL_PIPELINE_FULL_OVERRIDE REG_BIT(0)
+#define XELPD_VRR_CTL_VRR_GUARDBAND_MASK REG_GENMASK(15, 0)
+#define XELPD_VRR_CTL_VRR_GUARDBAND(x) REG_FIELD_PREP(XELPD_VRR_CTL_VRR_GUARDBAND_MASK, (x))
+
+#define _TRANS_VRR_VMAX_A 0x60424
+#define _TRANS_VRR_VMAX_B 0x61424
+#define _TRANS_VRR_VMAX_C 0x62424
+#define _TRANS_VRR_VMAX_D 0x63424
+#define TRANS_VRR_VMAX(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_VRR_VMAX_A)
+#define VRR_VMAX_MASK REG_GENMASK(19, 0)
+
+#define _TRANS_VRR_VMIN_A 0x60434
+#define _TRANS_VRR_VMIN_B 0x61434
+#define _TRANS_VRR_VMIN_C 0x62434
+#define _TRANS_VRR_VMIN_D 0x63434
+#define TRANS_VRR_VMIN(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_VRR_VMIN_A)
+#define VRR_VMIN_MASK REG_GENMASK(15, 0)
+
+#define _TRANS_VRR_VMAXSHIFT_A 0x60428
+#define _TRANS_VRR_VMAXSHIFT_B 0x61428
+#define _TRANS_VRR_VMAXSHIFT_C 0x62428
+#define _TRANS_VRR_VMAXSHIFT_D 0x63428
+#define TRANS_VRR_VMAXSHIFT(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, \
+ _TRANS_VRR_VMAXSHIFT_A)
+#define VRR_VMAXSHIFT_DEC_MASK REG_GENMASK(29, 16)
+#define VRR_VMAXSHIFT_DEC REG_BIT(16)
+#define VRR_VMAXSHIFT_INC_MASK REG_GENMASK(12, 0)
+
+#define _TRANS_VRR_STATUS_A 0x6042c
+#define _TRANS_VRR_STATUS_B 0x6142c
+#define _TRANS_VRR_STATUS_C 0x6242c
+#define _TRANS_VRR_STATUS_D 0x6342c
+#define TRANS_VRR_STATUS(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_VRR_STATUS_A)
+#define VRR_STATUS_VMAX_REACHED REG_BIT(31)
+#define VRR_STATUS_NOFLIP_TILL_BNDR REG_BIT(30)
+#define VRR_STATUS_FLIP_BEF_BNDR REG_BIT(29)
+#define VRR_STATUS_NO_FLIP_FRAME REG_BIT(28)
+#define VRR_STATUS_VRR_EN_LIVE REG_BIT(27)
+#define VRR_STATUS_FLIPS_SERVICED REG_BIT(26)
+#define VRR_STATUS_VBLANK_MASK REG_GENMASK(22, 20)
+#define STATUS_FSM_IDLE REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 0)
+#define STATUS_FSM_WAIT_TILL_FDB REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 1)
+#define STATUS_FSM_WAIT_TILL_FS REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 2)
+#define STATUS_FSM_WAIT_TILL_FLIP REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 3)
+#define STATUS_FSM_PIPELINE_FILL REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 4)
+#define STATUS_FSM_ACTIVE REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 5)
+#define STATUS_FSM_LEGACY_VBLANK REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 6)
+
+#define _TRANS_VRR_VTOTAL_PREV_A 0x60480
+#define _TRANS_VRR_VTOTAL_PREV_B 0x61480
+#define _TRANS_VRR_VTOTAL_PREV_C 0x62480
+#define _TRANS_VRR_VTOTAL_PREV_D 0x63480
+#define TRANS_VRR_VTOTAL_PREV(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, \
+ _TRANS_VRR_VTOTAL_PREV_A)
+#define VRR_VTOTAL_FLIP_BEFR_BNDR REG_BIT(31)
+#define VRR_VTOTAL_FLIP_AFTER_BNDR REG_BIT(30)
+#define VRR_VTOTAL_FLIP_AFTER_DBLBUF REG_BIT(29)
+#define VRR_VTOTAL_PREV_FRAME_MASK REG_GENMASK(19, 0)
+
+#define _TRANS_VRR_FLIPLINE_A 0x60438
+#define _TRANS_VRR_FLIPLINE_B 0x61438
+#define _TRANS_VRR_FLIPLINE_C 0x62438
+#define _TRANS_VRR_FLIPLINE_D 0x63438
+#define TRANS_VRR_FLIPLINE(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, \
+ _TRANS_VRR_FLIPLINE_A)
+#define VRR_FLIPLINE_MASK REG_GENMASK(19, 0)
+
+#define _TRANS_VRR_STATUS2_A 0x6043c
+#define _TRANS_VRR_STATUS2_B 0x6143c
+#define _TRANS_VRR_STATUS2_C 0x6243c
+#define _TRANS_VRR_STATUS2_D 0x6343c
+#define TRANS_VRR_STATUS2(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_VRR_STATUS2_A)
+#define VRR_STATUS2_VERT_LN_CNT_MASK REG_GENMASK(19, 0)
+
+#define _TRANS_PUSH_A 0x60a70
+#define _TRANS_PUSH_B 0x61a70
+#define _TRANS_PUSH_C 0x62a70
+#define _TRANS_PUSH_D 0x63a70
+#define TRANS_PUSH(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_PUSH_A)
+#define TRANS_PUSH_EN REG_BIT(31)
+#define TRANS_PUSH_SEND REG_BIT(30)
+
+#define _TRANS_VRR_VSYNC_A 0x60078
+#define TRANS_VRR_VSYNC(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_VRR_VSYNC_A)
+#define VRR_VSYNC_END_MASK REG_GENMASK(28, 16)
+#define VRR_VSYNC_END(vsync_end) REG_FIELD_PREP(VRR_VSYNC_END_MASK, (vsync_end))
+#define VRR_VSYNC_START_MASK REG_GENMASK(12, 0)
+#define VRR_VSYNC_START(vsync_start) REG_FIELD_PREP(VRR_VSYNC_START_MASK, (vsync_start))
+
+/*CMRR Registers*/
+
+#define _TRANS_CMRR_M_LO_A 0x604F0
+#define TRANS_CMRR_M_LO(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_CMRR_M_LO_A)
+
+#define _TRANS_CMRR_M_HI_A 0x604F4
+#define TRANS_CMRR_M_HI(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_CMRR_M_HI_A)
+
+#define _TRANS_CMRR_N_LO_A 0x604F8
+#define TRANS_CMRR_N_LO(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_CMRR_N_LO_A)
+
+#define _TRANS_CMRR_N_HI_A 0x604FC
+#define TRANS_CMRR_N_HI(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_CMRR_N_HI_A)
+
+#define VRR_CTL_CMRR_ENABLE REG_BIT(27)
+
+#endif /* __INTEL_VRR_REGS__ */
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 860574d04f88..8a66b1002a74 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -21,6 +21,7 @@
#include "intel_psr_regs.h"
#include "skl_scaler.h"
#include "skl_universal_plane.h"
+#include "skl_universal_plane_regs.h"
#include "skl_watermark.h"
#include "pxp/intel_pxp.h"
@@ -237,9 +238,9 @@ int skl_format_to_fourcc(int format, bool rgb_order, bool alpha)
static u8 icl_nv12_y_plane_mask(struct drm_i915_private *i915)
{
if (DISPLAY_VER(i915) >= 13 || HAS_D12_PLANE_MINIMIZATION(i915))
- return BIT(PLANE_SPRITE2) | BIT(PLANE_SPRITE3);
+ return BIT(PLANE_4) | BIT(PLANE_5);
else
- return BIT(PLANE_SPRITE4) | BIT(PLANE_SPRITE5);
+ return BIT(PLANE_6) | BIT(PLANE_7);
}
bool icl_is_nv12_y_plane(struct drm_i915_private *dev_priv,
@@ -251,7 +252,7 @@ bool icl_is_nv12_y_plane(struct drm_i915_private *dev_priv,
u8 icl_hdr_plane_mask(void)
{
- return BIT(PLANE_PRIMARY) | BIT(PLANE_SPRITE0) | BIT(PLANE_SPRITE1);
+ return BIT(PLANE_1) | BIT(PLANE_2) | BIT(PLANE_3);
}
bool icl_is_hdr_plane(struct drm_i915_private *dev_priv, enum plane_id plane_id)
@@ -461,41 +462,46 @@ static int icl_plane_max_height(const struct drm_framebuffer *fb,
}
static unsigned int
-skl_plane_max_stride(struct intel_plane *plane,
- u32 pixel_format, u64 modifier,
- unsigned int rotation)
+plane_max_stride(struct intel_plane *plane,
+ u32 pixel_format, u64 modifier,
+ unsigned int rotation,
+ unsigned int max_pixels,
+ unsigned int max_bytes)
{
- struct drm_i915_private *i915 = to_i915(plane->base.dev);
const struct drm_format_info *info = drm_format_info(pixel_format);
int cpp = info->cpp[0];
- int max_horizontal_pixels = 8192;
- int max_stride_bytes;
-
- if (DISPLAY_VER(i915) >= 13) {
- /*
- * The stride in bytes must not exceed of the size
- * of 128K bytes. For pixel formats of 64bpp will allow
- * for a 16K pixel surface.
- */
- max_stride_bytes = 131072;
- if (cpp == 8)
- max_horizontal_pixels = 16384;
- else
- max_horizontal_pixels = 65536;
- } else {
- /*
- * "The stride in bytes must not exceed the
- * of the size of 8K pixels and 32K bytes."
- */
- max_stride_bytes = 32768;
- }
if (drm_rotation_90_or_270(rotation))
- return min(max_horizontal_pixels, max_stride_bytes / cpp);
+ return min(max_pixels, max_bytes / cpp);
else
- return min(max_horizontal_pixels * cpp, max_stride_bytes);
+ return min(max_pixels * cpp, max_bytes);
}
+static unsigned int
+adl_plane_max_stride(struct intel_plane *plane,
+ u32 pixel_format, u64 modifier,
+ unsigned int rotation)
+{
+ unsigned int max_pixels = 65536; /* PLANE_OFFSET limit */
+ unsigned int max_bytes = 128 * 1024;
+
+ return plane_max_stride(plane, pixel_format,
+ modifier, rotation,
+ max_pixels, max_bytes);
+}
+
+static unsigned int
+skl_plane_max_stride(struct intel_plane *plane,
+ u32 pixel_format, u64 modifier,
+ unsigned int rotation)
+{
+ unsigned int max_pixels = 8192; /* PLANE_OFFSET limit */
+ unsigned int max_bytes = 32 * 1024;
+
+ return plane_max_stride(plane, pixel_format,
+ modifier, rotation,
+ max_pixels, max_bytes);
+}
/* Preoffset values for YUV to RGB Conversion */
#define PREOFF_YUV_TO_RGB_HI 0x1800
@@ -616,6 +622,66 @@ static u32 skl_plane_stride(const struct intel_plane_state *plane_state,
return stride / skl_plane_stride_mult(fb, color_plane, rotation);
}
+static u32 skl_plane_ddb_reg_val(const struct skl_ddb_entry *entry)
+{
+ if (!entry->end)
+ return 0;
+
+ return PLANE_BUF_END(entry->end - 1) |
+ PLANE_BUF_START(entry->start);
+}
+
+static u32 skl_plane_wm_reg_val(const struct skl_wm_level *level)
+{
+ u32 val = 0;
+
+ if (level->enable)
+ val |= PLANE_WM_EN;
+ if (level->ignore_lines)
+ val |= PLANE_WM_IGNORE_LINES;
+ val |= REG_FIELD_PREP(PLANE_WM_BLOCKS_MASK, level->blocks);
+ val |= REG_FIELD_PREP(PLANE_WM_LINES_MASK, level->lines);
+
+ return val;
+}
+
+static void skl_write_plane_wm(struct intel_plane *plane,
+ const struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *i915 = to_i915(plane->base.dev);
+ enum plane_id plane_id = plane->id;
+ enum pipe pipe = plane->pipe;
+ const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
+ const struct skl_ddb_entry *ddb =
+ &crtc_state->wm.skl.plane_ddb[plane_id];
+ const struct skl_ddb_entry *ddb_y =
+ &crtc_state->wm.skl.plane_ddb_y[plane_id];
+ int level;
+
+ for (level = 0; level < i915->display.wm.num_levels; level++)
+ intel_de_write_fw(i915, PLANE_WM(pipe, plane_id, level),
+ skl_plane_wm_reg_val(skl_plane_wm_level(pipe_wm, plane_id, level)));
+
+ intel_de_write_fw(i915, PLANE_WM_TRANS(pipe, plane_id),
+ skl_plane_wm_reg_val(skl_plane_trans_wm(pipe_wm, plane_id)));
+
+ if (HAS_HW_SAGV_WM(i915)) {
+ const struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
+
+ intel_de_write_fw(i915, PLANE_WM_SAGV(pipe, plane_id),
+ skl_plane_wm_reg_val(&wm->sagv.wm0));
+ intel_de_write_fw(i915, PLANE_WM_SAGV_TRANS(pipe, plane_id),
+ skl_plane_wm_reg_val(&wm->sagv.trans_wm));
+ }
+
+ intel_de_write_fw(i915, PLANE_BUF_CFG(pipe, plane_id),
+ skl_plane_ddb_reg_val(ddb));
+
+ if (DISPLAY_VER(i915) < 11)
+ intel_de_write_fw(i915, PLANE_NV12_BUF_CFG(pipe, plane_id),
+ skl_plane_ddb_reg_val(ddb_y));
+}
+
static void
skl_plane_disable_arm(struct intel_plane *plane,
const struct intel_crtc_state *crtc_state)
@@ -639,7 +705,7 @@ static void icl_plane_disable_sel_fetch_arm(struct intel_plane *plane,
if (!crtc_state->enable_psr2_sel_fetch)
return;
- intel_de_write_fw(i915, PLANE_SEL_FETCH_CTL(pipe, plane->id), 0);
+ intel_de_write_fw(i915, SEL_FETCH_PLANE_CTL(pipe, plane->id), 0);
}
static void
@@ -1174,6 +1240,11 @@ skl_plane_update_arm(struct intel_plane *plane,
plane_ctl = plane_state->ctl |
skl_plane_ctl_crtc(crtc_state);
+ /* see intel_plane_atomic_calc_changes() */
+ if (plane->need_async_flip_toggle_wa &&
+ crtc_state->async_flip_planes & BIT(plane->id))
+ plane_ctl |= PLANE_CTL_ASYNC_FLIP;
+
if (DISPLAY_VER(dev_priv) >= 10)
plane_color_ctl = plane_state->color_ctl |
glk_plane_color_ctl_crtc(crtc_state);
@@ -1231,9 +1302,13 @@ static void icl_plane_update_sel_fetch_noarm(struct intel_plane *plane,
clip = &plane_state->psr2_sel_fetch_area;
- val = (clip->y1 + plane_state->uapi.dst.y1) << 16;
+ if (crtc_state->enable_psr2_su_region_et)
+ y = max(0, plane_state->uapi.dst.y1 - crtc_state->psr2_su_area.y1);
+ else
+ y = (clip->y1 + plane_state->uapi.dst.y1);
+ val = y << 16;
val |= plane_state->uapi.dst.x1;
- intel_de_write_fw(i915, PLANE_SEL_FETCH_POS(pipe, plane->id), val);
+ intel_de_write_fw(i915, SEL_FETCH_PLANE_POS(pipe, plane->id), val);
x = plane_state->view.color_plane[color_plane].x;
@@ -1248,13 +1323,13 @@ static void icl_plane_update_sel_fetch_noarm(struct intel_plane *plane,
val = y << 16 | x;
- intel_de_write_fw(i915, PLANE_SEL_FETCH_OFFSET(pipe, plane->id),
+ intel_de_write_fw(i915, SEL_FETCH_PLANE_OFFSET(pipe, plane->id),
val);
/* Sizes are 0 based */
val = (drm_rect_height(clip) - 1) << 16;
val |= (drm_rect_width(&plane_state->uapi.src) >> 16) - 1;
- intel_de_write_fw(i915, PLANE_SEL_FETCH_SIZE(pipe, plane->id), val);
+ intel_de_write_fw(i915, SEL_FETCH_PLANE_SIZE(pipe, plane->id), val);
}
static void
@@ -1343,8 +1418,8 @@ static void icl_plane_update_sel_fetch_arm(struct intel_plane *plane,
return;
if (drm_rect_height(&plane_state->psr2_sel_fetch_area) > 0)
- intel_de_write_fw(i915, PLANE_SEL_FETCH_CTL(pipe, plane->id),
- PLANE_SEL_FETCH_CTL_ENABLE);
+ intel_de_write_fw(i915, SEL_FETCH_PLANE_CTL(pipe, plane->id),
+ SEL_FETCH_PLANE_CTL_ENABLE);
else
icl_plane_disable_sel_fetch_arm(plane, crtc_state);
}
@@ -1609,7 +1684,7 @@ skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state,
int aux_x = plane_state->view.color_plane[ccs_plane].x;
int aux_y = plane_state->view.color_plane[ccs_plane].y;
u32 aux_offset = plane_state->view.color_plane[ccs_plane].offset;
- u32 alignment = intel_surf_alignment(fb, ccs_plane);
+ unsigned int alignment = intel_surf_alignment(fb, ccs_plane);
int hsub;
int vsub;
@@ -1629,8 +1704,7 @@ skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state,
plane_state,
ccs_plane,
aux_offset,
- aux_offset -
- alignment);
+ aux_offset - alignment);
aux_x = x * hsub + aux_x % hsub;
aux_y = y * vsub + aux_y % vsub;
}
@@ -1652,10 +1726,10 @@ int skl_calc_main_surface_offset(const struct intel_plane_state *plane_state,
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
const struct drm_framebuffer *fb = plane_state->hw.fb;
- const int aux_plane = skl_main_to_aux_plane(fb, 0);
- const u32 aux_offset = plane_state->view.color_plane[aux_plane].offset;
- const u32 alignment = intel_surf_alignment(fb, 0);
- const int w = drm_rect_width(&plane_state->uapi.src) >> 16;
+ int aux_plane = skl_main_to_aux_plane(fb, 0);
+ u32 aux_offset = plane_state->view.color_plane[aux_plane].offset;
+ unsigned int alignment = intel_surf_alignment(fb, 0);
+ int w = drm_rect_width(&plane_state->uapi.src) >> 16;
intel_add_fb_offsets(x, y, plane_state, 0);
*offset = intel_plane_compute_aligned_offset(x, y, plane_state, 0);
@@ -1702,16 +1776,16 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
const struct drm_framebuffer *fb = plane_state->hw.fb;
- const unsigned int rotation = plane_state->hw.rotation;
+ unsigned int rotation = plane_state->hw.rotation;
int x = plane_state->uapi.src.x1 >> 16;
int y = plane_state->uapi.src.y1 >> 16;
- const int w = drm_rect_width(&plane_state->uapi.src) >> 16;
- const int h = drm_rect_height(&plane_state->uapi.src) >> 16;
- const int min_width = intel_plane_min_width(plane, fb, 0, rotation);
- const int max_width = intel_plane_max_width(plane, fb, 0, rotation);
- const int max_height = intel_plane_max_height(plane, fb, 0, rotation);
- const int aux_plane = skl_main_to_aux_plane(fb, 0);
- const u32 alignment = intel_surf_alignment(fb, 0);
+ int w = drm_rect_width(&plane_state->uapi.src) >> 16;
+ int h = drm_rect_height(&plane_state->uapi.src) >> 16;
+ int min_width = intel_plane_min_width(plane, fb, 0, rotation);
+ int max_width = intel_plane_max_width(plane, fb, 0, rotation);
+ int max_height = intel_plane_max_height(plane, fb, 0, rotation);
+ unsigned int alignment = intel_surf_alignment(fb, 0);
+ int aux_plane = skl_main_to_aux_plane(fb, 0);
u32 offset;
int ret;
@@ -1799,7 +1873,7 @@ static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
if (ccs_plane) {
u32 aux_offset = plane_state->view.color_plane[ccs_plane].offset;
- u32 alignment = intel_surf_alignment(fb, uv_plane);
+ unsigned int alignment = intel_surf_alignment(fb, uv_plane);
if (offset > aux_offset)
offset = intel_plane_adjust_aligned_offset(&x, &y,
@@ -2029,7 +2103,7 @@ static bool skl_plane_has_fbc(struct drm_i915_private *i915,
if (DISPLAY_VER(i915) >= 20)
return icl_is_hdr_plane(i915, plane_id);
else
- return plane_id == PLANE_PRIMARY;
+ return plane_id == PLANE_1;
}
static struct intel_fbc *skl_plane_fbc(struct drm_i915_private *dev_priv,
@@ -2053,7 +2127,7 @@ static bool skl_plane_has_planar(struct drm_i915_private *dev_priv,
if (DISPLAY_VER(dev_priv) == 9 && pipe == PIPE_C)
return false;
- if (plane_id != PLANE_PRIMARY && plane_id != PLANE_SPRITE0)
+ if (plane_id != PLANE_1 && plane_id != PLANE_2)
return false;
return true;
@@ -2261,8 +2335,7 @@ static bool skl_plane_has_rc_ccs(struct drm_i915_private *i915,
return pipe != PIPE_C;
return pipe != PIPE_C &&
- (plane_id == PLANE_PRIMARY ||
- plane_id == PLANE_SPRITE0);
+ (plane_id == PLANE_1 || plane_id == PLANE_2);
}
static bool gen12_plane_has_mc_ccs(struct drm_i915_private *i915,
@@ -2280,7 +2353,7 @@ static bool gen12_plane_has_mc_ccs(struct drm_i915_private *i915,
if (IS_ALDERLAKE_P(i915) && IS_DISPLAY_STEP(i915, STEP_A0, STEP_B0))
return false;
- return plane_id < PLANE_SPRITE4;
+ return plane_id < PLANE_6;
}
static u8 skl_get_plane_caps(struct drm_i915_private *i915,
@@ -2352,7 +2425,11 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
plane->min_cdclk = skl_plane_min_cdclk;
}
- plane->max_stride = skl_plane_max_stride;
+ if (DISPLAY_VER(dev_priv) >= 13)
+ plane->max_stride = adl_plane_max_stride;
+ else
+ plane->max_stride = skl_plane_max_stride;
+
if (DISPLAY_VER(dev_priv) >= 11) {
plane->update_noarm = icl_plane_update_noarm;
plane->update_arm = icl_plane_update_arm;
@@ -2365,9 +2442,8 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
plane->get_hw_state = skl_plane_get_hw_state;
plane->check_plane = skl_plane_check;
- if (plane_id == PLANE_PRIMARY) {
- plane->need_async_flip_disable_wa = IS_DISPLAY_VER(dev_priv,
- 9, 10);
+ if (plane_id == PLANE_1) {
+ plane->need_async_flip_toggle_wa = IS_DISPLAY_VER(dev_priv, 9, 10);
plane->async_flip = skl_plane_async_flip;
plane->enable_flip_done = skl_plane_enable_flip_done;
plane->disable_flip_done = skl_plane_disable_flip_done;
@@ -2388,7 +2464,7 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
else
plane_funcs = &skl_plane_funcs;
- if (plane_id == PLANE_PRIMARY)
+ if (plane_id == PLANE_1)
plane_type = DRM_PLANE_TYPE_PRIMARY;
else
plane_type = DRM_PLANE_TYPE_OVERLAY;
@@ -2482,9 +2558,9 @@ skl_get_initial_plane_config(struct intel_crtc *crtc,
drm_WARN_ON(dev, pipe != crtc->pipe);
- if (crtc_state->bigjoiner_pipes) {
+ if (crtc_state->joiner_pipes) {
drm_dbg_kms(&dev_priv->drm,
- "Unsupported bigjoiner configuration for initial FB\n");
+ "Unsupported joiner configuration for initial FB\n");
return;
}
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.h b/drivers/gpu/drm/i915/display/skl_universal_plane.h
index e92e00c01b29..541489479135 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.h
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.h
@@ -12,6 +12,8 @@ struct drm_i915_private;
struct intel_crtc;
struct intel_initial_plane_config;
struct intel_plane_state;
+struct skl_ddb_entry;
+struct skl_wm_level;
enum pipe;
enum plane_id;
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h b/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h
new file mode 100644
index 000000000000..4ddcd7d46bbd
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane_regs.h
@@ -0,0 +1,442 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef __SKL_UNIVERSAL_PLANE_REGS_H__
+#define __SKL_UNIVERSAL_PLANE_REGS_H__
+
+#include "intel_display_reg_defs.h"
+
+#define _SKL_PLANE(pipe, plane, reg_1_a, reg_1_b, reg_2_a, reg_2_b) \
+ _PLANE((plane), _PIPE((pipe), (reg_1_a), (reg_1_b)), _PIPE((pipe), (reg_2_a), (reg_2_b)))
+#define _SKL_PLANE_DW(pipe, plane, dw, reg_1_a, reg_1_b, reg_2_a, reg_2_b) \
+ (_SKL_PLANE((pipe), (plane), (reg_1_a), (reg_1_b), (reg_2_a), (reg_2_b)) + (dw) * 4)
+#define _MMIO_SKL_PLANE(pipe, plane, reg_1_a, reg_1_b, reg_2_a, reg_2_b) \
+ _MMIO(_SKL_PLANE((pipe), (plane), (reg_1_a), (reg_1_b), (reg_2_a), (reg_2_b)))
+#define _MMIO_SKL_PLANE_DW(pipe, plane, dw, reg_1_a, reg_1_b, reg_2_a, reg_2_b) \
+ _MMIO(_SKL_PLANE_DW((pipe), (plane), (dw), (reg_1_a), (reg_1_b), (reg_2_a), (reg_2_b)))
+
+#define _SEL_FETCH(pipe, plane, reg_1_a, reg_1_b, reg_2_a, reg_2_b, reg_5_a, reg_5_b, reg_6_a, reg_6_b) \
+ _PICK_EVEN_2RANGES((plane), PLANE_5, \
+ _PIPE((pipe), (reg_1_a), (reg_1_b)), \
+ _PIPE((pipe), (reg_2_a), (reg_2_b)), \
+ _PIPE((pipe), (reg_5_a), (reg_5_b)), \
+ _PIPE((pipe), (reg_6_a), (reg_6_b)))
+#define _MMIO_SEL_FETCH(pipe, plane, reg_1_a, reg_1_b, reg_2_a, reg_2_b, reg_5_a, reg_5_b, reg_6_a, reg_6_b) \
+ _MMIO(_SEL_FETCH((pipe), (plane), \
+ (reg_1_a), (reg_1_b), (reg_2_a), (reg_2_b), \
+ (reg_5_a), (reg_5_b), (reg_6_a), (reg_6_b)))
+
+#define _PLANE_CTL_1_A 0x70180
+#define _PLANE_CTL_2_A 0x70280
+#define _PLANE_CTL_1_B 0x71180
+#define _PLANE_CTL_2_B 0x71280
+#define PLANE_CTL(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_CTL_1_A, _PLANE_CTL_1_B, \
+ _PLANE_CTL_2_A, _PLANE_CTL_2_B)
+#define PLANE_CTL_ENABLE REG_BIT(31)
+#define PLANE_CTL_ARB_SLOTS_MASK REG_GENMASK(30, 28) /* icl+ */
+#define PLANE_CTL_ARB_SLOTS(x) REG_FIELD_PREP(PLANE_CTL_ARB_SLOTS_MASK, (x)) /* icl+ */
+#define PLANE_CTL_PIPE_GAMMA_ENABLE REG_BIT(30) /* Pre-GLK */
+#define PLANE_CTL_YUV_RANGE_CORRECTION_DISABLE REG_BIT(28)
+/*
+ * ICL+ uses the same PLANE_CTL_FORMAT bits, but the field definition
+ * expanded to include bit 23 as well. However, the shift-24 based values
+ * correctly map to the same formats in ICL, as long as bit 23 is set to 0
+ */
+#define PLANE_CTL_FORMAT_MASK_SKL REG_GENMASK(27, 24) /* pre-icl */
+#define PLANE_CTL_FORMAT_MASK_ICL REG_GENMASK(27, 23) /* icl+ */
+#define PLANE_CTL_FORMAT_YUV422 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 0)
+#define PLANE_CTL_FORMAT_NV12 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 1)
+#define PLANE_CTL_FORMAT_XRGB_2101010 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 2)
+#define PLANE_CTL_FORMAT_P010 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 3)
+#define PLANE_CTL_FORMAT_XRGB_8888 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 4)
+#define PLANE_CTL_FORMAT_P012 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 5)
+#define PLANE_CTL_FORMAT_XRGB_16161616F REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 6)
+#define PLANE_CTL_FORMAT_P016 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 7)
+#define PLANE_CTL_FORMAT_XYUV REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 8)
+#define PLANE_CTL_FORMAT_INDEXED REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 12)
+#define PLANE_CTL_FORMAT_RGB_565 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 14)
+#define PLANE_CTL_FORMAT_Y210 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 1)
+#define PLANE_CTL_FORMAT_Y212 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 3)
+#define PLANE_CTL_FORMAT_Y216 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 5)
+#define PLANE_CTL_FORMAT_Y410 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 7)
+#define PLANE_CTL_FORMAT_Y412 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 9)
+#define PLANE_CTL_FORMAT_Y416 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 11)
+#define PLANE_CTL_PIPE_CSC_ENABLE REG_BIT(23) /* Pre-GLK */
+#define PLANE_CTL_KEY_ENABLE_MASK REG_GENMASK(22, 21)
+#define PLANE_CTL_KEY_ENABLE_SOURCE REG_FIELD_PREP(PLANE_CTL_KEY_ENABLE_MASK, 1)
+#define PLANE_CTL_KEY_ENABLE_DESTINATION REG_FIELD_PREP(PLANE_CTL_KEY_ENABLE_MASK, 2)
+#define PLANE_CTL_ORDER_RGBX REG_BIT(20)
+#define PLANE_CTL_YUV420_Y_PLANE REG_BIT(19)
+#define PLANE_CTL_YUV_TO_RGB_CSC_FORMAT_BT709 REG_BIT(18)
+#define PLANE_CTL_YUV422_ORDER_MASK REG_GENMASK(17, 16)
+#define PLANE_CTL_YUV422_ORDER_YUYV REG_FIELD_PREP(PLANE_CTL_YUV422_ORDER_MASK, 0)
+#define PLANE_CTL_YUV422_ORDER_UYVY REG_FIELD_PREP(PLANE_CTL_YUV422_ORDER_MASK, 1)
+#define PLANE_CTL_YUV422_ORDER_YVYU REG_FIELD_PREP(PLANE_CTL_YUV422_ORDER_MASK, 2)
+#define PLANE_CTL_YUV422_ORDER_VYUY REG_FIELD_PREP(PLANE_CTL_YUV422_ORDER_MASK, 3)
+#define PLANE_CTL_RENDER_DECOMPRESSION_ENABLE REG_BIT(15)
+#define PLANE_CTL_TRICKLE_FEED_DISABLE REG_BIT(14)
+#define PLANE_CTL_CLEAR_COLOR_DISABLE REG_BIT(13) /* TGL+ */
+#define PLANE_CTL_PLANE_GAMMA_DISABLE REG_BIT(13) /* Pre-GLK */
+#define PLANE_CTL_TILED_MASK REG_GENMASK(12, 10)
+#define PLANE_CTL_TILED_LINEAR REG_FIELD_PREP(PLANE_CTL_TILED_MASK, 0)
+#define PLANE_CTL_TILED_X REG_FIELD_PREP(PLANE_CTL_TILED_MASK, 1)
+#define PLANE_CTL_TILED_Y REG_FIELD_PREP(PLANE_CTL_TILED_MASK, 4)
+#define PLANE_CTL_TILED_YF REG_FIELD_PREP(PLANE_CTL_TILED_MASK, 5)
+#define PLANE_CTL_TILED_4 REG_FIELD_PREP(PLANE_CTL_TILED_MASK, 5)
+#define PLANE_CTL_ASYNC_FLIP REG_BIT(9)
+#define PLANE_CTL_FLIP_HORIZONTAL REG_BIT(8)
+#define PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE REG_BIT(4) /* TGL+ */
+#define PLANE_CTL_ALPHA_MASK REG_GENMASK(5, 4) /* Pre-GLK */
+#define PLANE_CTL_ALPHA_DISABLE REG_FIELD_PREP(PLANE_CTL_ALPHA_MASK, 0)
+#define PLANE_CTL_ALPHA_SW_PREMULTIPLY REG_FIELD_PREP(PLANE_CTL_ALPHA_MASK, 2)
+#define PLANE_CTL_ALPHA_HW_PREMULTIPLY REG_FIELD_PREP(PLANE_CTL_ALPHA_MASK, 3)
+#define PLANE_CTL_ROTATE_MASK REG_GENMASK(1, 0)
+#define PLANE_CTL_ROTATE_0 REG_FIELD_PREP(PLANE_CTL_ROTATE_MASK, 0)
+#define PLANE_CTL_ROTATE_90 REG_FIELD_PREP(PLANE_CTL_ROTATE_MASK, 1)
+#define PLANE_CTL_ROTATE_180 REG_FIELD_PREP(PLANE_CTL_ROTATE_MASK, 2)
+#define PLANE_CTL_ROTATE_270 REG_FIELD_PREP(PLANE_CTL_ROTATE_MASK, 3)
+
+#define _PLANE_STRIDE_1_A 0x70188
+#define _PLANE_STRIDE_2_A 0x70288
+#define _PLANE_STRIDE_1_B 0x71188
+#define _PLANE_STRIDE_2_B 0x71288
+#define PLANE_STRIDE(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_STRIDE_1_A, _PLANE_STRIDE_1_B, \
+ _PLANE_STRIDE_2_A, _PLANE_STRIDE_2_B)
+#define PLANE_STRIDE__MASK REG_GENMASK(11, 0)
+#define PLANE_STRIDE_(stride) REG_FIELD_PREP(PLANE_STRIDE__MASK, (stride))
+
+#define _PLANE_POS_1_A 0x7018c
+#define _PLANE_POS_2_A 0x7028c
+#define _PLANE_POS_1_B 0x7118c
+#define _PLANE_POS_2_B 0x7128c
+#define PLANE_POS(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_POS_1_A, _PLANE_POS_1_B, \
+ _PLANE_POS_2_A, _PLANE_POS_2_B)
+#define PLANE_POS_Y_MASK REG_GENMASK(31, 16)
+#define PLANE_POS_Y(y) REG_FIELD_PREP(PLANE_POS_Y_MASK, (y))
+#define PLANE_POS_X_MASK REG_GENMASK(15, 0)
+#define PLANE_POS_X(x) REG_FIELD_PREP(PLANE_POS_X_MASK, (x))
+
+#define _PLANE_SIZE_1_A 0x70190
+#define _PLANE_SIZE_2_A 0x70290
+#define _PLANE_SIZE_1_B 0x71190
+#define _PLANE_SIZE_2_B 0x71290
+#define PLANE_SIZE(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_SIZE_1_A, _PLANE_SIZE_1_B, \
+ _PLANE_SIZE_2_A, _PLANE_SIZE_2_B)
+#define PLANE_HEIGHT_MASK REG_GENMASK(31, 16)
+#define PLANE_HEIGHT(h) REG_FIELD_PREP(PLANE_HEIGHT_MASK, (h))
+#define PLANE_WIDTH_MASK REG_GENMASK(15, 0)
+#define PLANE_WIDTH(w) REG_FIELD_PREP(PLANE_WIDTH_MASK, (w))
+
+#define _PLANE_KEYVAL_1_A 0x70194
+#define _PLANE_KEYVAL_2_A 0x70294
+#define _PLANE_KEYVAL_1_B 0x71194
+#define _PLANE_KEYVAL_2_B 0x71294
+#define PLANE_KEYVAL(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane),\
+ _PLANE_KEYVAL_1_A, _PLANE_KEYVAL_1_B, \
+ _PLANE_KEYVAL_2_A, _PLANE_KEYVAL_2_B)
+
+#define _PLANE_KEYMSK_1_A 0x70198
+#define _PLANE_KEYMSK_2_A 0x70298
+#define _PLANE_KEYMSK_1_B 0x71198
+#define _PLANE_KEYMSK_2_B 0x71298
+#define PLANE_KEYMSK(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_KEYMSK_1_A, _PLANE_KEYMSK_1_B, \
+ _PLANE_KEYMSK_2_A, _PLANE_KEYMSK_2_B)
+#define PLANE_KEYMSK_ALPHA_ENABLE REG_BIT(31)
+
+#define _PLANE_SURF_1_A 0x7019c
+#define _PLANE_SURF_2_A 0x7029c
+#define _PLANE_SURF_1_B 0x7119c
+#define _PLANE_SURF_2_B 0x7129c
+#define PLANE_SURF(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_SURF_1_A, _PLANE_SURF_1_B, \
+ _PLANE_SURF_2_A, _PLANE_SURF_2_B)
+#define PLANE_SURF_ADDR_MASK REG_GENMASK(31, 12)
+#define PLANE_SURF_DECRYPT REG_BIT(2)
+
+#define _PLANE_KEYMAX_1_A 0x701a0
+#define _PLANE_KEYMAX_2_A 0x702a0
+#define _PLANE_KEYMAX_1_B 0x711a0
+#define _PLANE_KEYMAX_2_B 0x712a0
+#define PLANE_KEYMAX(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_KEYMAX_1_A, _PLANE_KEYMAX_1_B, \
+ _PLANE_KEYMAX_2_A, _PLANE_KEYMAX_2_B)
+#define PLANE_KEYMAX_ALPHA_MASK REG_GENMASK(31, 24)
+#define PLANE_KEYMAX_ALPHA(a) REG_FIELD_PREP(PLANE_KEYMAX_ALPHA_MASK, (a))
+
+#define _PLANE_OFFSET_1_A 0x701a4
+#define _PLANE_OFFSET_2_A 0x702a4
+#define _PLANE_OFFSET_1_B 0x711a4
+#define _PLANE_OFFSET_2_B 0x712a4
+#define PLANE_OFFSET(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_OFFSET_1_A, _PLANE_OFFSET_1_B, \
+ _PLANE_OFFSET_2_A, _PLANE_OFFSET_2_B)
+#define PLANE_OFFSET_Y_MASK REG_GENMASK(31, 16)
+#define PLANE_OFFSET_Y(y) REG_FIELD_PREP(PLANE_OFFSET_Y_MASK, (y))
+#define PLANE_OFFSET_X_MASK REG_GENMASK(15, 0)
+#define PLANE_OFFSET_X(x) REG_FIELD_PREP(PLANE_OFFSET_X_MASK, (x))
+
+#define _PLANE_SURFLIVE_1_A 0x701ac
+#define _PLANE_SURFLIVE_2_A 0x702ac
+#define _PLANE_SURFLIVE_1_B 0x711ac
+#define _PLANE_SURFLIVE_2_B 0x712ac
+#define PLANE_SURFLIVE(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_SURFLIVE_1_A, _PLANE_SURFLIVE_1_B, \
+ _PLANE_SURFLIVE_2_A, _PLANE_SURFLIVE_2_B)
+
+#define _PLANE_CC_VAL_1_A 0x701b4
+#define _PLANE_CC_VAL_2_A 0x702b4
+#define _PLANE_CC_VAL_1_B 0x711b4
+#define _PLANE_CC_VAL_2_B 0x712b4
+#define PLANE_CC_VAL(pipe, plane, dw) _MMIO_SKL_PLANE_DW((pipe), (plane), (dw), \
+ _PLANE_CC_VAL_1_A, _PLANE_CC_VAL_1_B, \
+ _PLANE_CC_VAL_2_A, _PLANE_CC_VAL_2_B)
+
+#define _PLANE_AUX_DIST_1_A 0x701c0
+#define _PLANE_AUX_DIST_2_A 0x702c0
+#define _PLANE_AUX_DIST_1_B 0x711c0
+#define _PLANE_AUX_DIST_2_B 0x712c0
+#define PLANE_AUX_DIST(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_AUX_DIST_1_A, _PLANE_AUX_DIST_1_B, \
+ _PLANE_AUX_DIST_2_A, _PLANE_AUX_DIST_2_B)
+#define PLANE_AUX_DISTANCE_MASK REG_GENMASK(31, 12)
+#define PLANE_AUX_STRIDE_MASK REG_GENMASK(11, 0)
+#define PLANE_AUX_STRIDE(stride) REG_FIELD_PREP(PLANE_AUX_STRIDE_MASK, (stride))
+
+#define _PLANE_AUX_OFFSET_1_A 0x701c4
+#define _PLANE_AUX_OFFSET_2_A 0x702c4
+#define _PLANE_AUX_OFFSET_1_B 0x711c4
+#define _PLANE_AUX_OFFSET_2_B 0x712c4
+#define PLANE_AUX_OFFSET(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_AUX_OFFSET_1_A, _PLANE_AUX_OFFSET_1_B, \
+ _PLANE_AUX_OFFSET_2_A, _PLANE_AUX_OFFSET_2_B)
+
+#define _PLANE_CUS_CTL_1_A 0x701c8
+#define _PLANE_CUS_CTL_2_A 0x702c8
+#define _PLANE_CUS_CTL_1_B 0x711c8
+#define _PLANE_CUS_CTL_2_B 0x712c8
+#define PLANE_CUS_CTL(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_CUS_CTL_1_A, _PLANE_CUS_CTL_1_B, \
+ _PLANE_CUS_CTL_2_A, _PLANE_CUS_CTL_2_B)
+#define PLANE_CUS_ENABLE REG_BIT(31)
+#define PLANE_CUS_Y_PLANE_MASK REG_BIT(30)
+#define PLANE_CUS_Y_PLANE_4_RKL REG_FIELD_PREP(PLANE_CUS_Y_PLANE_MASK, 0)
+#define PLANE_CUS_Y_PLANE_5_RKL REG_FIELD_PREP(PLANE_CUS_Y_PLANE_MASK, 1)
+#define PLANE_CUS_Y_PLANE_6_ICL REG_FIELD_PREP(PLANE_CUS_Y_PLANE_MASK, 0)
+#define PLANE_CUS_Y_PLANE_7_ICL REG_FIELD_PREP(PLANE_CUS_Y_PLANE_MASK, 1)
+#define PLANE_CUS_HPHASE_SIGN_NEGATIVE REG_BIT(19)
+#define PLANE_CUS_HPHASE_MASK REG_GENMASK(17, 16)
+#define PLANE_CUS_HPHASE_0 REG_FIELD_PREP(PLANE_CUS_HPHASE_MASK, 0)
+#define PLANE_CUS_HPHASE_0_25 REG_FIELD_PREP(PLANE_CUS_HPHASE_MASK, 1)
+#define PLANE_CUS_HPHASE_0_5 REG_FIELD_PREP(PLANE_CUS_HPHASE_MASK, 2)
+#define PLANE_CUS_VPHASE_SIGN_NEGATIVE REG_BIT(15)
+#define PLANE_CUS_VPHASE_MASK REG_GENMASK(13, 12)
+#define PLANE_CUS_VPHASE_0 REG_FIELD_PREP(PLANE_CUS_VPHASE_MASK, 0)
+#define PLANE_CUS_VPHASE_0_25 REG_FIELD_PREP(PLANE_CUS_VPHASE_MASK, 1)
+#define PLANE_CUS_VPHASE_0_5 REG_FIELD_PREP(PLANE_CUS_VPHASE_MASK, 2)
+
+#define _PLANE_COLOR_CTL_1_A 0x701cc /* GLK+ */
+#define _PLANE_COLOR_CTL_2_A 0x702cc
+#define _PLANE_COLOR_CTL_1_B 0x711cc
+#define _PLANE_COLOR_CTL_2_B 0x712cc
+#define PLANE_COLOR_CTL(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_COLOR_CTL_1_A, _PLANE_COLOR_CTL_1_B, \
+ _PLANE_COLOR_CTL_2_A, _PLANE_COLOR_CTL_2_B)
+#define PLANE_COLOR_PIPE_GAMMA_ENABLE REG_BIT(30) /* Pre-ICL */
+#define PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE REG_BIT(28)
+#define PLANE_COLOR_PIPE_CSC_ENABLE REG_BIT(23) /* Pre-ICL */
+#define PLANE_COLOR_PLANE_CSC_ENABLE REG_BIT(21) /* ICL+ */
+#define PLANE_COLOR_INPUT_CSC_ENABLE REG_BIT(20) /* ICL+ */
+#define PLANE_COLOR_CSC_MODE_MASK REG_GENMASK(19, 17)
+#define PLANE_COLOR_CSC_MODE_BYPASS REG_FIELD_PREP(PLANE_COLOR_CSC_MODE_MASK, 0)
+#define PLANE_COLOR_CSC_MODE_YUV601_TO_RGB601 REG_FIELD_PREP(PLANE_COLOR_CSC_MODE_MASK, 1)
+#define PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709 REG_FIELD_PREP(PLANE_COLOR_CSC_MODE_MASK, 2)
+#define PLANE_COLOR_CSC_MODE_YUV2020_TO_RGB2020 REG_FIELD_PREP(PLANE_COLOR_CSC_MODE_MASK, 3)
+#define PLANE_COLOR_CSC_MODE_RGB709_TO_RGB2020 REG_FIELD_PREP(PLANE_COLOR_CSC_MODE_MASK, 4)
+#define PLANE_COLOR_PLANE_GAMMA_DISABLE REG_BIT(13)
+#define PLANE_COLOR_ALPHA_MASK REG_GENMASK(5, 4)
+#define PLANE_COLOR_ALPHA_DISABLE REG_FIELD_PREP(PLANE_COLOR_ALPHA_MASK, 0)
+#define PLANE_COLOR_ALPHA_SW_PREMULTIPLY REG_FIELD_PREP(PLANE_COLOR_ALPHA_MASK, 2)
+#define PLANE_COLOR_ALPHA_HW_PREMULTIPLY REG_FIELD_PREP(PLANE_COLOR_ALPHA_MASK, 3)
+
+#define _PLANE_INPUT_CSC_RY_GY_1_A 0x701e0
+#define _PLANE_INPUT_CSC_RY_GY_2_A 0x702e0
+#define _PLANE_INPUT_CSC_RY_GY_1_B 0x711e0
+#define _PLANE_INPUT_CSC_RY_GY_2_B 0x712e0
+#define PLANE_INPUT_CSC_COEFF(pipe, plane, index) _MMIO_SKL_PLANE_DW((pipe), (plane), (index), \
+ _PLANE_INPUT_CSC_RY_GY_1_A, _PLANE_INPUT_CSC_RY_GY_1_B, \
+ _PLANE_INPUT_CSC_RY_GY_2_A, _PLANE_INPUT_CSC_RY_GY_2_B)
+
+#define _PLANE_INPUT_CSC_PREOFF_HI_1_A 0x701f8
+#define _PLANE_INPUT_CSC_PREOFF_HI_2_A 0x702f8
+#define _PLANE_INPUT_CSC_PREOFF_HI_1_B 0x711f8
+#define _PLANE_INPUT_CSC_PREOFF_HI_2_B 0x712f8
+#define PLANE_INPUT_CSC_PREOFF(pipe, plane, index) _MMIO_SKL_PLANE_DW((pipe), (plane), (index), \
+ _PLANE_INPUT_CSC_PREOFF_HI_1_A, _PLANE_INPUT_CSC_PREOFF_HI_1_B, \
+ _PLANE_INPUT_CSC_PREOFF_HI_2_A, _PLANE_INPUT_CSC_PREOFF_HI_2_B)
+
+#define _PLANE_INPUT_CSC_POSTOFF_HI_1_A 0x70204
+#define _PLANE_INPUT_CSC_POSTOFF_HI_2_A 0x70304
+#define _PLANE_INPUT_CSC_POSTOFF_HI_1_B 0x71204
+#define _PLANE_INPUT_CSC_POSTOFF_HI_2_B 0x71304
+#define PLANE_INPUT_CSC_POSTOFF(pipe, plane, index) _MMIO_SKL_PLANE_DW((pipe), (plane), (index), \
+ _PLANE_INPUT_CSC_POSTOFF_HI_1_A, _PLANE_INPUT_CSC_POSTOFF_HI_1_B, \
+ _PLANE_INPUT_CSC_POSTOFF_HI_2_A, _PLANE_INPUT_CSC_POSTOFF_HI_2_B)
+
+#define _PLANE_CSC_RY_GY_1_A 0x70210
+#define _PLANE_CSC_RY_GY_2_A 0x70310
+#define _PLANE_CSC_RY_GY_1_B 0x71210
+#define _PLANE_CSC_RY_GY_2_B 0x71310
+#define PLANE_CSC_COEFF(pipe, plane, index) _MMIO_SKL_PLANE_DW((pipe), (plane), (index), \
+ _PLANE_CSC_RY_GY_1_A, _PLANE_CSC_RY_GY_1_B, \
+ _PLANE_CSC_RY_GY_2_A, _PLANE_CSC_RY_GY_2_B)
+
+#define _PLANE_CSC_PREOFF_HI_1_A 0x70228
+#define _PLANE_CSC_PREOFF_HI_2_A 0x70328
+#define _PLANE_CSC_PREOFF_HI_1_B 0x71228
+#define _PLANE_CSC_PREOFF_HI_2_B 0x71328
+#define PLANE_CSC_PREOFF(pipe, plane, index) _MMIO_SKL_PLANE_DW((pipe), (plane), (index), \
+ _PLANE_CSC_PREOFF_HI_1_A, _PLANE_CSC_PREOFF_HI_1_B, \
+ _PLANE_CSC_PREOFF_HI_2_A, _PLANE_CSC_PREOFF_HI_2_B)
+
+#define _PLANE_CSC_POSTOFF_HI_1_A 0x70234
+#define _PLANE_CSC_POSTOFF_HI_2_A 0x70334
+#define _PLANE_CSC_POSTOFF_HI_1_B 0x71234
+#define _PLANE_CSC_POSTOFF_HI_2_B 0x71334
+#define PLANE_CSC_POSTOFF(pipe, plane, index) _MMIO_SKL_PLANE_DW((pipe), (plane), (index), \
+ _PLANE_CSC_POSTOFF_HI_1_A, _PLANE_CSC_POSTOFF_HI_1_B, \
+ _PLANE_CSC_POSTOFF_HI_2_A, _PLANE_CSC_POSTOFF_HI_2_B)
+#define _PLANE_WM_1_A_0 0x70240
+#define _PLANE_WM_1_B_0 0x71240
+#define _PLANE_WM_2_A_0 0x70340
+#define _PLANE_WM_2_B_0 0x71340
+#define PLANE_WM(pipe, plane, level) _MMIO_SKL_PLANE_DW((pipe), (plane), (level), \
+ _PLANE_WM_1_A_0, _PLANE_WM_1_B_0, \
+ _PLANE_WM_2_A_0, _PLANE_WM_2_B_0)
+#define PLANE_WM_EN REG_BIT(31)
+#define PLANE_WM_IGNORE_LINES REG_BIT(30)
+#define PLANE_WM_LINES_MASK REG_GENMASK(26, 14)
+#define PLANE_WM_BLOCKS_MASK REG_GENMASK(11, 0)
+
+#define _PLANE_WM_SAGV_1_A 0x70258
+#define _PLANE_WM_SAGV_1_B 0x71258
+#define _PLANE_WM_SAGV_2_A 0x70358
+#define _PLANE_WM_SAGV_2_B 0x71358
+#define PLANE_WM_SAGV(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_WM_SAGV_1_A, _PLANE_WM_SAGV_1_B, \
+ _PLANE_WM_SAGV_2_A, _PLANE_WM_SAGV_2_B)
+
+#define _PLANE_WM_SAGV_TRANS_1_A 0x7025c
+#define _PLANE_WM_SAGV_TRANS_1_B 0x7125c
+#define _PLANE_WM_SAGV_TRANS_2_A 0x7035c
+#define _PLANE_WM_SAGV_TRANS_2_B 0x7135c
+#define PLANE_WM_SAGV_TRANS(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_WM_SAGV_TRANS_1_A, _PLANE_WM_SAGV_TRANS_1_B, \
+ _PLANE_WM_SAGV_TRANS_2_A, _PLANE_WM_SAGV_TRANS_2_B)
+
+#define _PLANE_WM_TRANS_1_A 0x70268
+#define _PLANE_WM_TRANS_1_B 0x71268
+#define _PLANE_WM_TRANS_2_A 0x70368
+#define _PLANE_WM_TRANS_2_B 0x71368
+#define PLANE_WM_TRANS(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_WM_TRANS_1_A, _PLANE_WM_TRANS_1_B, \
+ _PLANE_WM_TRANS_2_A, _PLANE_WM_TRANS_2_B)
+
+#define _PLANE_CHICKEN_1_A 0x7026c /* tgl+ */
+#define _PLANE_CHICKEN_2_A 0x7036c
+#define _PLANE_CHICKEN_1_B 0x7126c
+#define _PLANE_CHICKEN_2_B 0x7136c
+#define PLANE_CHICKEN(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_CHICKEN_1_A, _PLANE_CHICKEN_1_B, \
+ _PLANE_CHICKEN_2_A, _PLANE_CHICKEN_2_B)
+#define PLANE_CHICKEN_DISABLE_DPT REG_BIT(19) /* mtl+ */
+
+#define _PLANE_NV12_BUF_CFG_1_A 0x70278
+#define _PLANE_NV12_BUF_CFG_2_A 0x70378
+#define _PLANE_NV12_BUF_CFG_1_B 0x71278
+#define _PLANE_NV12_BUF_CFG_2_B 0x71378
+#define PLANE_NV12_BUF_CFG(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_NV12_BUF_CFG_1_A, _PLANE_NV12_BUF_CFG_1_B, \
+ _PLANE_NV12_BUF_CFG_2_A, _PLANE_NV12_BUF_CFG_2_B)
+
+#define _PLANE_BUF_CFG_1_A 0x7027c
+#define _PLANE_BUF_CFG_2_A 0x7037c
+#define _PLANE_BUF_CFG_1_B 0x7127c
+#define _PLANE_BUF_CFG_2_B 0x7137c
+#define PLANE_BUF_CFG(pipe, plane) _MMIO_SKL_PLANE((pipe), (plane), \
+ _PLANE_BUF_CFG_1_A, _PLANE_BUF_CFG_1_B, \
+ _PLANE_BUF_CFG_2_A, _PLANE_BUF_CFG_2_B)
+/* skl+: 10 bits, icl+ 11 bits, adlp+ 12 bits */
+#define PLANE_BUF_END_MASK REG_GENMASK(27, 16)
+#define PLANE_BUF_END(end) REG_FIELD_PREP(PLANE_BUF_END_MASK, (end))
+#define PLANE_BUF_START_MASK REG_GENMASK(11, 0)
+#define PLANE_BUF_START(start) REG_FIELD_PREP(PLANE_BUF_START_MASK, (start))
+
+/* tgl+ */
+#define _SEL_FETCH_PLANE_CTL_1_A 0x70890
+#define _SEL_FETCH_PLANE_CTL_2_A 0x708b0
+#define _SEL_FETCH_PLANE_CTL_5_A 0x70920
+#define _SEL_FETCH_PLANE_CTL_6_A 0x70940
+#define _SEL_FETCH_PLANE_CTL_1_B 0x71890
+#define _SEL_FETCH_PLANE_CTL_2_B 0x718b0
+#define _SEL_FETCH_PLANE_CTL_5_B 0x71920
+#define _SEL_FETCH_PLANE_CTL_6_B 0x71940
+#define SEL_FETCH_PLANE_CTL(pipe, plane) _MMIO_SEL_FETCH((pipe), (plane),\
+ _SEL_FETCH_PLANE_CTL_1_A, _SEL_FETCH_PLANE_CTL_1_B, \
+ _SEL_FETCH_PLANE_CTL_2_A, _SEL_FETCH_PLANE_CTL_2_B, \
+ _SEL_FETCH_PLANE_CTL_5_A, _SEL_FETCH_PLANE_CTL_5_B, \
+ _SEL_FETCH_PLANE_CTL_6_A, _SEL_FETCH_PLANE_CTL_6_B)
+#define SEL_FETCH_PLANE_CTL_ENABLE REG_BIT(31)
+
+/* tgl+ */
+#define _SEL_FETCH_PLANE_POS_1_A 0x70894
+#define _SEL_FETCH_PLANE_POS_2_A 0x708b4
+#define _SEL_FETCH_PLANE_POS_5_A 0x70924
+#define _SEL_FETCH_PLANE_POS_6_A 0x70944
+#define _SEL_FETCH_PLANE_POS_1_B 0x71894
+#define _SEL_FETCH_PLANE_POS_2_B 0x718b4
+#define _SEL_FETCH_PLANE_POS_5_B 0x71924
+#define _SEL_FETCH_PLANE_POS_6_B 0x71944
+#define SEL_FETCH_PLANE_POS(pipe, plane) _MMIO_SEL_FETCH((pipe), (plane),\
+ _SEL_FETCH_PLANE_POS_1_A, _SEL_FETCH_PLANE_POS_1_B, \
+ _SEL_FETCH_PLANE_POS_2_A, _SEL_FETCH_PLANE_POS_2_B, \
+ _SEL_FETCH_PLANE_POS_5_A, _SEL_FETCH_PLANE_POS_5_B, \
+ _SEL_FETCH_PLANE_POS_6_A, _SEL_FETCH_PLANE_POS_6_B)
+
+/* tgl+ */
+#define _SEL_FETCH_PLANE_SIZE_1_A 0x70898
+#define _SEL_FETCH_PLANE_SIZE_2_A 0x708b8
+#define _SEL_FETCH_PLANE_SIZE_5_A 0x70928
+#define _SEL_FETCH_PLANE_SIZE_6_A 0x70948
+#define _SEL_FETCH_PLANE_SIZE_1_B 0x71898
+#define _SEL_FETCH_PLANE_SIZE_2_B 0x718b8
+#define _SEL_FETCH_PLANE_SIZE_5_B 0x71928
+#define _SEL_FETCH_PLANE_SIZE_6_B 0x71948
+#define SEL_FETCH_PLANE_SIZE(pipe, plane) _MMIO_SEL_FETCH((pipe), (plane),\
+ _SEL_FETCH_PLANE_SIZE_1_A, _SEL_FETCH_PLANE_SIZE_1_B, \
+ _SEL_FETCH_PLANE_SIZE_2_A, _SEL_FETCH_PLANE_SIZE_2_B, \
+ _SEL_FETCH_PLANE_SIZE_5_A, _SEL_FETCH_PLANE_SIZE_5_B, \
+ _SEL_FETCH_PLANE_SIZE_6_A, _SEL_FETCH_PLANE_SIZE_6_B)
+
+/* tgl+ */
+#define _SEL_FETCH_PLANE_OFFSET_1_A 0x7089c
+#define _SEL_FETCH_PLANE_OFFSET_2_A 0x708bc
+#define _SEL_FETCH_PLANE_OFFSET_5_A 0x7092c
+#define _SEL_FETCH_PLANE_OFFSET_6_A 0x7094c
+#define _SEL_FETCH_PLANE_OFFSET_1_B 0x7189c
+#define _SEL_FETCH_PLANE_OFFSET_2_B 0x718bc
+#define _SEL_FETCH_PLANE_OFFSET_5_B 0x7192c
+#define _SEL_FETCH_PLANE_OFFSET_6_B 0x7194c
+#define SEL_FETCH_PLANE_OFFSET(pipe, plane) _MMIO_SEL_FETCH((pipe), (plane),\
+ _SEL_FETCH_PLANE_OFFSET_1_A, _SEL_FETCH_PLANE_OFFSET_1_B, \
+ _SEL_FETCH_PLANE_OFFSET_2_A, _SEL_FETCH_PLANE_OFFSET_2_B, \
+ _SEL_FETCH_PLANE_OFFSET_5_A, _SEL_FETCH_PLANE_OFFSET_5_B, \
+ _SEL_FETCH_PLANE_OFFSET_6_A, _SEL_FETCH_PLANE_OFFSET_6_B)
+
+#endif /* __SKL_UNIVERSAL_PLANE_REGS_H__ */
diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c
index 7c6187b4479f..a2726364b34d 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.c
+++ b/drivers/gpu/drm/i915/display/skl_watermark.c
@@ -13,6 +13,7 @@
#include "intel_bw.h"
#include "intel_cdclk.h"
#include "intel_crtc.h"
+#include "intel_cursor_regs.h"
#include "intel_de.h"
#include "intel_display.h"
#include "intel_display_power.h"
@@ -21,6 +22,7 @@
#include "intel_fixed.h"
#include "intel_pcode.h"
#include "intel_wm.h"
+#include "skl_universal_plane_regs.h"
#include "skl_watermark.h"
#include "skl_watermark_regs.h"
@@ -1394,7 +1396,7 @@ skl_total_relative_data_rate(const struct intel_crtc_state *crtc_state)
return data_rate;
}
-static const struct skl_wm_level *
+const struct skl_wm_level *
skl_plane_wm_level(const struct skl_pipe_wm *pipe_wm,
enum plane_id plane_id,
int level)
@@ -1407,7 +1409,7 @@ skl_plane_wm_level(const struct skl_pipe_wm *pipe_wm,
return &wm->wm[level];
}
-static const struct skl_wm_level *
+const struct skl_wm_level *
skl_plane_trans_wm(const struct skl_pipe_wm *pipe_wm,
enum plane_id plane_id)
{
@@ -2363,101 +2365,6 @@ static int skl_build_pipe_wm(struct intel_atomic_state *state,
return skl_wm_check_vblank(crtc_state);
}
-static void skl_ddb_entry_write(struct drm_i915_private *i915,
- i915_reg_t reg,
- const struct skl_ddb_entry *entry)
-{
- if (entry->end)
- intel_de_write_fw(i915, reg,
- PLANE_BUF_END(entry->end - 1) |
- PLANE_BUF_START(entry->start));
- else
- intel_de_write_fw(i915, reg, 0);
-}
-
-static void skl_write_wm_level(struct drm_i915_private *i915,
- i915_reg_t reg,
- const struct skl_wm_level *level)
-{
- u32 val = 0;
-
- if (level->enable)
- val |= PLANE_WM_EN;
- if (level->ignore_lines)
- val |= PLANE_WM_IGNORE_LINES;
- val |= REG_FIELD_PREP(PLANE_WM_BLOCKS_MASK, level->blocks);
- val |= REG_FIELD_PREP(PLANE_WM_LINES_MASK, level->lines);
-
- intel_de_write_fw(i915, reg, val);
-}
-
-void skl_write_plane_wm(struct intel_plane *plane,
- const struct intel_crtc_state *crtc_state)
-{
- struct drm_i915_private *i915 = to_i915(plane->base.dev);
- enum plane_id plane_id = plane->id;
- enum pipe pipe = plane->pipe;
- const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
- const struct skl_ddb_entry *ddb =
- &crtc_state->wm.skl.plane_ddb[plane_id];
- const struct skl_ddb_entry *ddb_y =
- &crtc_state->wm.skl.plane_ddb_y[plane_id];
- int level;
-
- for (level = 0; level < i915->display.wm.num_levels; level++)
- skl_write_wm_level(i915, PLANE_WM(pipe, plane_id, level),
- skl_plane_wm_level(pipe_wm, plane_id, level));
-
- skl_write_wm_level(i915, PLANE_WM_TRANS(pipe, plane_id),
- skl_plane_trans_wm(pipe_wm, plane_id));
-
- if (HAS_HW_SAGV_WM(i915)) {
- const struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
-
- skl_write_wm_level(i915, PLANE_WM_SAGV(pipe, plane_id),
- &wm->sagv.wm0);
- skl_write_wm_level(i915, PLANE_WM_SAGV_TRANS(pipe, plane_id),
- &wm->sagv.trans_wm);
- }
-
- skl_ddb_entry_write(i915,
- PLANE_BUF_CFG(pipe, plane_id), ddb);
-
- if (DISPLAY_VER(i915) < 11)
- skl_ddb_entry_write(i915,
- PLANE_NV12_BUF_CFG(pipe, plane_id), ddb_y);
-}
-
-void skl_write_cursor_wm(struct intel_plane *plane,
- const struct intel_crtc_state *crtc_state)
-{
- struct drm_i915_private *i915 = to_i915(plane->base.dev);
- enum plane_id plane_id = plane->id;
- enum pipe pipe = plane->pipe;
- const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
- const struct skl_ddb_entry *ddb =
- &crtc_state->wm.skl.plane_ddb[plane_id];
- int level;
-
- for (level = 0; level < i915->display.wm.num_levels; level++)
- skl_write_wm_level(i915, CUR_WM(pipe, level),
- skl_plane_wm_level(pipe_wm, plane_id, level));
-
- skl_write_wm_level(i915, CUR_WM_TRANS(pipe),
- skl_plane_trans_wm(pipe_wm, plane_id));
-
- if (HAS_HW_SAGV_WM(i915)) {
- const struct skl_plane_wm *wm = &pipe_wm->planes[plane_id];
-
- skl_write_wm_level(i915, CUR_WM_SAGV(pipe),
- &wm->sagv.wm0);
- skl_write_wm_level(i915, CUR_WM_SAGV_TRANS(pipe),
- &wm->sagv.trans_wm);
- }
-
- skl_ddb_entry_write(i915, CUR_BUF_CFG(pipe), ddb);
-}
-
static bool skl_wm_level_equals(const struct skl_wm_level *l1,
const struct skl_wm_level *l2)
{
@@ -2522,12 +2429,14 @@ bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb,
}
static int
-skl_ddb_add_affected_planes(const struct intel_crtc_state *old_crtc_state,
- struct intel_crtc_state *new_crtc_state)
+skl_ddb_add_affected_planes(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
- struct intel_atomic_state *state = to_intel_atomic_state(new_crtc_state->uapi.state);
- struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
- struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
+ const struct intel_crtc_state *old_crtc_state =
+ intel_atomic_get_old_crtc_state(state, crtc);
+ struct intel_crtc_state *new_crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
struct intel_plane *plane;
for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) {
@@ -2540,6 +2449,12 @@ skl_ddb_add_affected_planes(const struct intel_crtc_state *old_crtc_state,
&new_crtc_state->wm.skl.plane_ddb_y[plane_id]))
continue;
+ if (new_crtc_state->do_async_flip) {
+ drm_dbg_kms(&i915->drm, "[PLANE:%d:%s] Can't change DDB during async flip\n",
+ plane->base.base.id, plane->base.name);
+ return -EINVAL;
+ }
+
plane_state = intel_atomic_get_plane_state(state, plane);
if (IS_ERR(plane_state))
return PTR_ERR(plane_state);
@@ -2576,7 +2491,6 @@ skl_compute_ddb(struct intel_atomic_state *state)
struct drm_i915_private *i915 = to_i915(state->base.dev);
const struct intel_dbuf_state *old_dbuf_state;
struct intel_dbuf_state *new_dbuf_state = NULL;
- const struct intel_crtc_state *old_crtc_state;
struct intel_crtc_state *new_crtc_state;
struct intel_crtc *crtc;
int ret, i;
@@ -2664,14 +2578,12 @@ skl_compute_ddb(struct intel_atomic_state *state)
return ret;
}
- for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
- new_crtc_state, i) {
+ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
ret = skl_crtc_allocate_plane_ddb(state, crtc);
if (ret)
return ret;
- ret = skl_ddb_add_affected_planes(old_crtc_state,
- new_crtc_state);
+ ret = skl_ddb_add_affected_planes(state, crtc);
if (ret)
return ret;
}
@@ -2899,6 +2811,12 @@ static int skl_wm_add_affected_planes(struct intel_atomic_state *state,
&new_crtc_state->wm.skl.optimal))
continue;
+ if (new_crtc_state->do_async_flip) {
+ drm_dbg_kms(&i915->drm, "[PLANE:%d:%s] Can't change watermarks during async flip\n",
+ plane->base.base.id, plane->base.name);
+ return -EINVAL;
+ }
+
plane_state = intel_atomic_get_plane_state(state, plane);
if (IS_ERR(plane_state))
return PTR_ERR(plane_state);
@@ -3604,7 +3522,7 @@ static void intel_mbus_dbox_update(struct intel_atomic_state *state)
for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, new_dbuf_state->active_pipes) {
u32 pipe_val = val;
- if (DISPLAY_VER(i915) >= 14) {
+ if (DISPLAY_VER_FULL(i915) == IP_VER(14, 0)) {
if (xelpdp_is_only_pipe_per_dbuf_bank(crtc->pipe,
new_dbuf_state->active_pipes))
pipe_val |= MBUS_DBOX_BW_8CREDITS_MTL;
diff --git a/drivers/gpu/drm/i915/display/skl_watermark.h b/drivers/gpu/drm/i915/display/skl_watermark.h
index 91f92c0e706e..78b121941237 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.h
+++ b/drivers/gpu/drm/i915/display/skl_watermark.h
@@ -18,6 +18,8 @@ struct intel_bw_state;
struct intel_crtc;
struct intel_crtc_state;
struct intel_plane;
+struct skl_pipe_wm;
+struct skl_wm_level;
u8 intel_enabled_dbuf_slices_mask(struct drm_i915_private *i915);
@@ -30,11 +32,6 @@ bool intel_has_sagv(struct drm_i915_private *i915);
u32 skl_ddb_dbuf_slice_mask(struct drm_i915_private *i915,
const struct skl_ddb_entry *entry);
-void skl_write_plane_wm(struct intel_plane *plane,
- const struct intel_crtc_state *crtc_state);
-void skl_write_cursor_wm(struct intel_plane *plane,
- const struct intel_crtc_state *crtc_state);
-
bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb,
const struct skl_ddb_entry *entries,
int num_entries, int ignore_idx);
@@ -51,6 +48,12 @@ unsigned int skl_watermark_max_latency(struct drm_i915_private *i915,
int initial_wm_level);
void skl_wm_init(struct drm_i915_private *i915);
+const struct skl_wm_level *skl_plane_wm_level(const struct skl_pipe_wm *pipe_wm,
+ enum plane_id plane_id,
+ int level);
+const struct skl_wm_level *skl_plane_trans_wm(const struct skl_pipe_wm *pipe_wm,
+ enum plane_id plane_id);
+
struct intel_dbuf_state {
struct intel_global_state base;
diff --git a/drivers/gpu/drm/i915/display/skl_watermark_regs.h b/drivers/gpu/drm/i915/display/skl_watermark_regs.h
index 269163fa3350..c5572fc0e847 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark_regs.h
+++ b/drivers/gpu/drm/i915/display/skl_watermark_regs.h
@@ -43,89 +43,6 @@
#define MBUS_TRANSLATION_THROTTLE_MIN_MASK REG_GENMASK(15, 13)
#define MBUS_TRANSLATION_THROTTLE_MIN(val) REG_FIELD_PREP(MBUS_TRANSLATION_THROTTLE_MIN_MASK, val)
-/* Watermark register definitions for SKL */
-#define _CUR_WM_A_0 0x70140
-#define _CUR_WM_B_0 0x71140
-#define _CUR_WM_SAGV_A 0x70158
-#define _CUR_WM_SAGV_B 0x71158
-#define _CUR_WM_SAGV_TRANS_A 0x7015C
-#define _CUR_WM_SAGV_TRANS_B 0x7115C
-#define _CUR_WM_TRANS_A 0x70168
-#define _CUR_WM_TRANS_B 0x71168
-#define _PLANE_WM_1_A_0 0x70240
-#define _PLANE_WM_1_B_0 0x71240
-#define _PLANE_WM_2_A_0 0x70340
-#define _PLANE_WM_2_B_0 0x71340
-#define _PLANE_WM_SAGV_1_A 0x70258
-#define _PLANE_WM_SAGV_1_B 0x71258
-#define _PLANE_WM_SAGV_2_A 0x70358
-#define _PLANE_WM_SAGV_2_B 0x71358
-#define _PLANE_WM_SAGV_TRANS_1_A 0x7025C
-#define _PLANE_WM_SAGV_TRANS_1_B 0x7125C
-#define _PLANE_WM_SAGV_TRANS_2_A 0x7035C
-#define _PLANE_WM_SAGV_TRANS_2_B 0x7135C
-#define _PLANE_WM_TRANS_1_A 0x70268
-#define _PLANE_WM_TRANS_1_B 0x71268
-#define _PLANE_WM_TRANS_2_A 0x70368
-#define _PLANE_WM_TRANS_2_B 0x71368
-#define PLANE_WM_EN (1 << 31)
-#define PLANE_WM_IGNORE_LINES (1 << 30)
-#define PLANE_WM_LINES_MASK REG_GENMASK(26, 14)
-#define PLANE_WM_BLOCKS_MASK REG_GENMASK(11, 0)
-
-#define _CUR_WM_0(pipe) _PIPE(pipe, _CUR_WM_A_0, _CUR_WM_B_0)
-#define CUR_WM(pipe, level) _MMIO(_CUR_WM_0(pipe) + ((4) * (level)))
-#define CUR_WM_SAGV(pipe) _MMIO_PIPE(pipe, _CUR_WM_SAGV_A, _CUR_WM_SAGV_B)
-#define CUR_WM_SAGV_TRANS(pipe) _MMIO_PIPE(pipe, _CUR_WM_SAGV_TRANS_A, _CUR_WM_SAGV_TRANS_B)
-#define CUR_WM_TRANS(pipe) _MMIO_PIPE(pipe, _CUR_WM_TRANS_A, _CUR_WM_TRANS_B)
-#define _PLANE_WM_1(pipe) _PIPE(pipe, _PLANE_WM_1_A_0, _PLANE_WM_1_B_0)
-#define _PLANE_WM_2(pipe) _PIPE(pipe, _PLANE_WM_2_A_0, _PLANE_WM_2_B_0)
-#define _PLANE_WM_BASE(pipe, plane) \
- _PLANE(plane, _PLANE_WM_1(pipe), _PLANE_WM_2(pipe))
-#define PLANE_WM(pipe, plane, level) \
- _MMIO(_PLANE_WM_BASE(pipe, plane) + ((4) * (level)))
-#define _PLANE_WM_SAGV_1(pipe) \
- _PIPE(pipe, _PLANE_WM_SAGV_1_A, _PLANE_WM_SAGV_1_B)
-#define _PLANE_WM_SAGV_2(pipe) \
- _PIPE(pipe, _PLANE_WM_SAGV_2_A, _PLANE_WM_SAGV_2_B)
-#define PLANE_WM_SAGV(pipe, plane) \
- _MMIO(_PLANE(plane, _PLANE_WM_SAGV_1(pipe), _PLANE_WM_SAGV_2(pipe)))
-#define _PLANE_WM_SAGV_TRANS_1(pipe) \
- _PIPE(pipe, _PLANE_WM_SAGV_TRANS_1_A, _PLANE_WM_SAGV_TRANS_1_B)
-#define _PLANE_WM_SAGV_TRANS_2(pipe) \
- _PIPE(pipe, _PLANE_WM_SAGV_TRANS_2_A, _PLANE_WM_SAGV_TRANS_2_B)
-#define PLANE_WM_SAGV_TRANS(pipe, plane) \
- _MMIO(_PLANE(plane, _PLANE_WM_SAGV_TRANS_1(pipe), _PLANE_WM_SAGV_TRANS_2(pipe)))
-#define _PLANE_WM_TRANS_1(pipe) \
- _PIPE(pipe, _PLANE_WM_TRANS_1_A, _PLANE_WM_TRANS_1_B)
-#define _PLANE_WM_TRANS_2(pipe) \
- _PIPE(pipe, _PLANE_WM_TRANS_2_A, _PLANE_WM_TRANS_2_B)
-#define PLANE_WM_TRANS(pipe, plane) \
- _MMIO(_PLANE(plane, _PLANE_WM_TRANS_1(pipe), _PLANE_WM_TRANS_2(pipe)))
-
-#define _PLANE_BUF_CFG_1_B 0x7127c
-#define _PLANE_BUF_CFG_2_B 0x7137c
-#define _PLANE_BUF_CFG_1(pipe) \
- _PIPE(pipe, _PLANE_BUF_CFG_1_A, _PLANE_BUF_CFG_1_B)
-#define _PLANE_BUF_CFG_2(pipe) \
- _PIPE(pipe, _PLANE_BUF_CFG_2_A, _PLANE_BUF_CFG_2_B)
-#define PLANE_BUF_CFG(pipe, plane) \
- _MMIO_PLANE(plane, _PLANE_BUF_CFG_1(pipe), _PLANE_BUF_CFG_2(pipe))
-
-#define _PLANE_NV12_BUF_CFG_1_B 0x71278
-#define _PLANE_NV12_BUF_CFG_2_B 0x71378
-#define _PLANE_NV12_BUF_CFG_1(pipe) \
- _PIPE(pipe, _PLANE_NV12_BUF_CFG_1_A, _PLANE_NV12_BUF_CFG_1_B)
-#define _PLANE_NV12_BUF_CFG_2(pipe) \
- _PIPE(pipe, _PLANE_NV12_BUF_CFG_2_A, _PLANE_NV12_BUF_CFG_2_B)
-#define PLANE_NV12_BUF_CFG(pipe, plane) \
- _MMIO_PLANE(plane, _PLANE_NV12_BUF_CFG_1(pipe), _PLANE_NV12_BUF_CFG_2(pipe))
-
-/* SKL new cursor registers */
-#define _CUR_BUF_CFG_A 0x7017c
-#define _CUR_BUF_CFG_B 0x7117c
-#define CUR_BUF_CFG(pipe) _MMIO_PIPE(pipe, _CUR_BUF_CFG_A, _CUR_BUF_CFG_B)
-
/*
* The below are numbered starting from "S1" on gen11/gen12, but starting
* with display 13, the bspec switches to a 0-based numbering scheme
diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c
index ee9923c7b115..eae5b5e09aa8 100644
--- a/drivers/gpu/drm/i915/display/vlv_dsi.c
+++ b/drivers/gpu/drm/i915/display/vlv_dsi.c
@@ -972,7 +972,8 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder,
*/
if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
port == PORT_C)
- enabled = intel_de_read(display, TRANSCONF(PIPE_B)) & TRANSCONF_ENABLE;
+ enabled = intel_de_read(display,
+ TRANSCONF(dev_priv, PIPE_B)) & TRANSCONF_ENABLE;
/* Try command mode if video mode not enabled */
if (!enabled) {
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
index ad6dd7f3259b..30595b2b63e1 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
@@ -8,7 +8,7 @@
#include <linux/mutex.h>
#include <drm/drm_mm.h>
-#include <drm/i915_drm.h>
+#include <drm/intel/i915_drm.h>
#include "gem/i915_gem_lmem.h"
#include "gem/i915_gem_region.h"
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index 0d0a0dc9f610..206a5e0fedf1 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -9,8 +9,8 @@
#include <linux/stop_machine.h>
#include <drm/drm_managed.h>
-#include <drm/i915_drm.h>
-#include <drm/intel-gtt.h>
+#include <drm/intel/i915_drm.h>
+#include <drm/intel/intel-gtt.h>
#include "display/intel_display.h"
#include "gem/i915_gem_lmem.h"
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt_gmch.c b/drivers/gpu/drm/i915/gt/intel_ggtt_gmch.c
index 866c416afb73..59eed0a0ce90 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt_gmch.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt_gmch.c
@@ -5,7 +5,7 @@
#include "intel_ggtt_gmch.h"
-#include <drm/intel-gtt.h>
+#include <drm/intel/intel-gtt.h>
#include <linux/agp_backend.h>
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c
index 626b166e67ef..a6c69a706fd7 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -4,7 +4,7 @@
*/
#include <drm/drm_managed.h>
-#include <drm/intel-gtt.h>
+#include <drm/intel/intel-gtt.h>
#include "gem/i915_gem_internal.h"
#include "gem/i915_gem_lmem.h"
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c b/drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c
index 7c9be4fd1c8c..6e63505fe478 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c
@@ -9,6 +9,7 @@
#include "intel_gt_clock_utils.h"
#include "intel_gt_print.h"
#include "intel_gt_regs.h"
+#include "soc/intel_dram.h"
static u32 read_reference_ts_freq(struct intel_uncore *uncore)
{
@@ -151,7 +152,7 @@ static u32 gen4_read_clock_frequency(struct intel_uncore *uncore)
*
* Testing on actual hardware has shown there is no /16.
*/
- return RUNTIME_INFO(uncore->i915)->rawclk_freq * 1000;
+ return DIV_ROUND_CLOSEST(i9xx_fsb_freq(uncore->i915), 4) * 1000;
}
static u32 read_clock_frequency(struct intel_uncore *uncore)
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c b/drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c
index 4fcba42cfe34..c1ce6258e55c 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c
@@ -367,7 +367,6 @@ void intel_gt_pm_frequency_dump(struct intel_gt *gt, struct drm_printer *p)
vlv_punit_put(i915);
drm_printf(p, "PUNIT_REG_GPU_FREQ_STS: 0x%08x\n", freq_sts);
- drm_printf(p, "DDR freq: %d MHz\n", i915->mem_freq);
drm_printf(p, "actual GPU freq: %d MHz\n",
intel_gpu_freq(rps, (freq_sts >> 8) & 0xff));
diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c b/drivers/gpu/drm/i915/gt/intel_reset.c
index 6161f7a3ff70..735cd23a43c6 100644
--- a/drivers/gpu/drm/i915/gt/intel_reset.c
+++ b/drivers/gpu/drm/i915/gt/intel_reset.c
@@ -1025,7 +1025,7 @@ void intel_gt_set_wedged(struct intel_gt *gt)
if (GEM_SHOW_DEBUG()) {
struct drm_printer p = drm_dbg_printer(&gt->i915->drm,
- DRM_UT_DRIVER, __func__);
+ DRM_UT_DRIVER, NULL);
struct intel_engine_cs *engine;
enum intel_engine_id id;
diff --git a/drivers/gpu/drm/i915/gt/intel_rps.c b/drivers/gpu/drm/i915/gt/intel_rps.c
index c9cb2a391942..fa304ea088e4 100644
--- a/drivers/gpu/drm/i915/gt/intel_rps.c
+++ b/drivers/gpu/drm/i915/gt/intel_rps.c
@@ -5,7 +5,7 @@
#include <linux/string_helpers.h>
-#include <drm/i915_drm.h>
+#include <drm/intel/i915_drm.h>
#include "display/intel_display.h"
#include "display/intel_display_irq.h"
@@ -265,10 +265,10 @@ static const struct cparams {
u16 c;
} cparams[] = {
{ 1, 1333, 301, 28664 },
- { 1, 1066, 294, 24460 },
+ { 1, 1067, 294, 24460 },
{ 1, 800, 294, 25192 },
{ 0, 1333, 276, 27605 },
- { 0, 1066, 276, 27605 },
+ { 0, 1067, 276, 27605 },
{ 0, 800, 231, 23784 },
};
@@ -280,15 +280,16 @@ static void gen5_rps_init(struct intel_rps *rps)
u32 rgvmodectl;
int c_m, i;
- if (i915->fsb_freq <= 3200)
+ if (i915->fsb_freq <= 3200000)
c_m = 0;
- else if (i915->fsb_freq <= 4800)
+ else if (i915->fsb_freq <= 4800000)
c_m = 1;
else
c_m = 2;
for (i = 0; i < ARRAY_SIZE(cparams); i++) {
- if (cparams[i].i == c_m && cparams[i].t == i915->mem_freq) {
+ if (cparams[i].i == c_m &&
+ cparams[i].t == DIV_ROUND_CLOSEST(i915->mem_freq, 1000)) {
rps->ips.m = cparams[i].m;
rps->ips.c = cparams[i].c;
break;
diff --git a/drivers/gpu/drm/i915/gt/selftest_context.c b/drivers/gpu/drm/i915/gt/selftest_context.c
index 12eca750f7d0..5eb46700dc4e 100644
--- a/drivers/gpu/drm/i915/gt/selftest_context.c
+++ b/drivers/gpu/drm/i915/gt/selftest_context.c
@@ -286,7 +286,7 @@ out_engine:
if (intel_engine_pm_is_awake(engine)) {
struct drm_printer p = drm_dbg_printer(&engine->i915->drm,
- DRM_UT_DRIVER, __func__);
+ DRM_UT_DRIVER, NULL);
intel_engine_dump(engine, &p,
"%s is still awake:%d after idle-barriers\n",
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c b/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c
index a7d5465655f9..d8edd7c054c8 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c
@@ -5,8 +5,8 @@
#include <linux/component.h>
-#include <drm/i915_component.h>
-#include <drm/i915_gsc_proxy_mei_interface.h>
+#include <drm/intel/i915_component.h>
+#include <drm/intel/i915_gsc_proxy_mei_interface.h>
#include "gt/intel_gt.h"
#include "gt/intel_gt_print.h"
diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c
index 4be8cb65fb7e..2f4c9c66b40b 100644
--- a/drivers/gpu/drm/i915/gvt/cmd_parser.c
+++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c
@@ -49,6 +49,7 @@
#include "i915_pvinfo.h"
#include "trace.h"
+#include "display/i9xx_plane_regs.h"
#include "display/intel_display.h"
#include "display/intel_sprite_regs.h"
#include "gem/i915_gem_context.h"
@@ -1314,9 +1315,9 @@ static int gen8_decode_mi_display_flip(struct parser_exec_state *s,
info->async_flip = ((dword2 & GENMASK(1, 0)) == 0x1);
if (info->plane == PLANE_A) {
- info->ctrl_reg = DSPCNTR(info->pipe);
- info->stride_reg = DSPSTRIDE(info->pipe);
- info->surf_reg = DSPSURF(info->pipe);
+ info->ctrl_reg = DSPCNTR(dev_priv, info->pipe);
+ info->stride_reg = DSPSTRIDE(dev_priv, info->pipe);
+ info->surf_reg = DSPSURF(dev_priv, info->pipe);
} else if (info->plane == PLANE_B) {
info->ctrl_reg = SPRCTL(info->pipe);
info->stride_reg = SPRSTRIDE(info->pipe);
@@ -1380,9 +1381,9 @@ static int skl_decode_mi_display_flip(struct parser_exec_state *s,
info->surf_val = (dword2 & GENMASK(31, 12)) >> 12;
info->async_flip = ((dword2 & GENMASK(1, 0)) == 0x1);
- info->ctrl_reg = DSPCNTR(info->pipe);
- info->stride_reg = DSPSTRIDE(info->pipe);
- info->surf_reg = DSPSURF(info->pipe);
+ info->ctrl_reg = DSPCNTR(dev_priv, info->pipe);
+ info->stride_reg = DSPSTRIDE(dev_priv, info->pipe);
+ info->surf_reg = DSPSURF(dev_priv, info->pipe);
return 0;
}
@@ -1436,7 +1437,7 @@ static int gen8_update_plane_mmio_from_mi_display_flip(
}
if (info->plane == PLANE_PRIMARY)
- vgpu_vreg_t(vgpu, PIPE_FLIPCOUNT_G4X(info->pipe))++;
+ vgpu_vreg_t(vgpu, PIPE_FLIPCOUNT_G4X(dev_priv, info->pipe))++;
if (info->async_flip)
intel_vgpu_trigger_virtual_event(vgpu, info->event);
diff --git a/drivers/gpu/drm/i915/gvt/display.c b/drivers/gpu/drm/i915/gvt/display.c
index 2b7df7fcf369..c66d6d3177c8 100644
--- a/drivers/gpu/drm/i915/gvt/display.c
+++ b/drivers/gpu/drm/i915/gvt/display.c
@@ -37,6 +37,8 @@
#include "gvt.h"
#include "display/bxt_dpio_phy_regs.h"
+#include "display/i9xx_plane_regs.h"
+#include "display/intel_cursor_regs.h"
#include "display/intel_display.h"
#include "display/intel_dpio_phy.h"
#include "display/intel_sprite_regs.h"
@@ -65,7 +67,7 @@ static int edp_pipe_is_enabled(struct intel_vgpu *vgpu)
{
struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915;
- if (!(vgpu_vreg_t(vgpu, TRANSCONF(TRANSCODER_EDP)) & TRANSCONF_ENABLE))
+ if (!(vgpu_vreg_t(vgpu, TRANSCONF(dev_priv, TRANSCODER_EDP)) & TRANSCONF_ENABLE))
return 0;
if (!(vgpu_vreg(vgpu, _TRANS_DDI_FUNC_CTL_EDP) & TRANS_DDI_FUNC_ENABLE))
@@ -81,7 +83,7 @@ int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
pipe < PIPE_A || pipe >= I915_MAX_PIPES))
return -EINVAL;
- if (vgpu_vreg_t(vgpu, TRANSCONF(pipe)) & TRANSCONF_ENABLE)
+ if (vgpu_vreg_t(vgpu, TRANSCONF(dev_priv, pipe)) & TRANSCONF_ENABLE)
return 1;
if (edp_pipe_is_enabled(vgpu) &&
@@ -189,20 +191,20 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
GEN8_DE_PORT_HOTPLUG(HPD_PORT_C));
for_each_pipe(dev_priv, pipe) {
- vgpu_vreg_t(vgpu, TRANSCONF(pipe)) &=
+ vgpu_vreg_t(vgpu, TRANSCONF(dev_priv, pipe)) &=
~(TRANSCONF_ENABLE | TRANSCONF_STATE_ENABLE);
- vgpu_vreg_t(vgpu, DSPCNTR(pipe)) &= ~DISP_ENABLE;
+ vgpu_vreg_t(vgpu, DSPCNTR(dev_priv, pipe)) &= ~DISP_ENABLE;
vgpu_vreg_t(vgpu, SPRCTL(pipe)) &= ~SPRITE_ENABLE;
- vgpu_vreg_t(vgpu, CURCNTR(pipe)) &= ~MCURSOR_MODE_MASK;
- vgpu_vreg_t(vgpu, CURCNTR(pipe)) |= MCURSOR_MODE_DISABLE;
+ vgpu_vreg_t(vgpu, CURCNTR(dev_priv, pipe)) &= ~MCURSOR_MODE_MASK;
+ vgpu_vreg_t(vgpu, CURCNTR(dev_priv, pipe)) |= MCURSOR_MODE_DISABLE;
}
for (trans = TRANSCODER_A; trans <= TRANSCODER_EDP; trans++) {
- vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(trans)) &=
+ vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(dev_priv, trans)) &=
~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK |
TRANS_DDI_PORT_MASK | TRANS_DDI_FUNC_ENABLE);
}
- vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &=
+ vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(dev_priv, TRANSCODER_A)) &=
~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK |
TRANS_DDI_PORT_MASK);
@@ -250,8 +252,8 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
* TRANSCODER_A can be enabled. PORT_x depends on the input of
* setup_virtual_dp_monitor.
*/
- vgpu_vreg_t(vgpu, TRANSCONF(TRANSCODER_A)) |= TRANSCONF_ENABLE;
- vgpu_vreg_t(vgpu, TRANSCONF(TRANSCODER_A)) |= TRANSCONF_STATE_ENABLE;
+ vgpu_vreg_t(vgpu, TRANSCONF(dev_priv, TRANSCODER_A)) |= TRANSCONF_ENABLE;
+ vgpu_vreg_t(vgpu, TRANSCONF(dev_priv, TRANSCODER_A)) |= TRANSCONF_STATE_ENABLE;
/*
* Golden M/N are calculated based on:
@@ -259,11 +261,11 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
* DP link clk 1620 MHz and non-constant_n.
* TODO: calculate DP link symbol clk and stream clk m/n.
*/
- vgpu_vreg_t(vgpu, PIPE_DATA_M1(TRANSCODER_A)) = TU_SIZE(64);
- vgpu_vreg_t(vgpu, PIPE_DATA_M1(TRANSCODER_A)) |= 0x5b425e;
- vgpu_vreg_t(vgpu, PIPE_DATA_N1(TRANSCODER_A)) = 0x800000;
- vgpu_vreg_t(vgpu, PIPE_LINK_M1(TRANSCODER_A)) = 0x3cd6e;
- vgpu_vreg_t(vgpu, PIPE_LINK_N1(TRANSCODER_A)) = 0x80000;
+ vgpu_vreg_t(vgpu, PIPE_DATA_M1(dev_priv, TRANSCODER_A)) = TU_SIZE(64);
+ vgpu_vreg_t(vgpu, PIPE_DATA_M1(dev_priv, TRANSCODER_A)) |= 0x5b425e;
+ vgpu_vreg_t(vgpu, PIPE_DATA_N1(dev_priv, TRANSCODER_A)) = 0x800000;
+ vgpu_vreg_t(vgpu, PIPE_LINK_M1(dev_priv, TRANSCODER_A)) = 0x3cd6e;
+ vgpu_vreg_t(vgpu, PIPE_LINK_N1(dev_priv, TRANSCODER_A)) = 0x80000;
/* Enable per-DDI/PORT vreg */
if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) {
@@ -285,7 +287,8 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
(DDI_BUF_CTL_ENABLE | DDI_INIT_DISPLAY_DETECTED);
vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_A)) &=
~DDI_BUF_IS_IDLE;
- vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)) |=
+ vgpu_vreg_t(vgpu,
+ TRANS_DDI_FUNC_CTL(dev_priv, TRANSCODER_EDP)) |=
(TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
TRANS_DDI_FUNC_ENABLE);
vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
@@ -314,7 +317,8 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
DDI_BUF_CTL_ENABLE;
vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_B)) &=
~DDI_BUF_IS_IDLE;
- vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) |=
+ vgpu_vreg_t(vgpu,
+ TRANS_DDI_FUNC_CTL(dev_priv, TRANSCODER_A)) |=
(TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
(PORT_B << TRANS_DDI_PORT_SHIFT) |
TRANS_DDI_FUNC_ENABLE);
@@ -344,7 +348,8 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
DDI_BUF_CTL_ENABLE;
vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_C)) &=
~DDI_BUF_IS_IDLE;
- vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) |=
+ vgpu_vreg_t(vgpu,
+ TRANS_DDI_FUNC_CTL(dev_priv, TRANSCODER_A)) |=
(TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
(PORT_B << TRANS_DDI_PORT_SHIFT) |
TRANS_DDI_FUNC_ENABLE);
@@ -393,11 +398,11 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
* DP link clk 1620 MHz and non-constant_n.
* TODO: calculate DP link symbol clk and stream clk m/n.
*/
- vgpu_vreg_t(vgpu, PIPE_DATA_M1(TRANSCODER_A)) = TU_SIZE(64);
- vgpu_vreg_t(vgpu, PIPE_DATA_M1(TRANSCODER_A)) |= 0x5b425e;
- vgpu_vreg_t(vgpu, PIPE_DATA_N1(TRANSCODER_A)) = 0x800000;
- vgpu_vreg_t(vgpu, PIPE_LINK_M1(TRANSCODER_A)) = 0x3cd6e;
- vgpu_vreg_t(vgpu, PIPE_LINK_N1(TRANSCODER_A)) = 0x80000;
+ vgpu_vreg_t(vgpu, PIPE_DATA_M1(dev_priv, TRANSCODER_A)) = TU_SIZE(64);
+ vgpu_vreg_t(vgpu, PIPE_DATA_M1(dev_priv, TRANSCODER_A)) |= 0x5b425e;
+ vgpu_vreg_t(vgpu, PIPE_DATA_N1(dev_priv, TRANSCODER_A)) = 0x800000;
+ vgpu_vreg_t(vgpu, PIPE_LINK_M1(dev_priv, TRANSCODER_A)) = 0x3cd6e;
+ vgpu_vreg_t(vgpu, PIPE_LINK_N1(dev_priv, TRANSCODER_A)) = 0x80000;
}
if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) {
@@ -408,10 +413,10 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
vgpu_vreg_t(vgpu, DPLL_CTRL2) |=
DPLL_CTRL2_DDI_SEL_OVERRIDE(PORT_B);
vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIB_DETECTED;
- vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &=
+ vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(dev_priv, TRANSCODER_A)) &=
~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK |
TRANS_DDI_PORT_MASK);
- vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) |=
+ vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(dev_priv, TRANSCODER_A)) |=
(TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
(PORT_B << TRANS_DDI_PORT_SHIFT) |
TRANS_DDI_FUNC_ENABLE);
@@ -434,10 +439,10 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
vgpu_vreg_t(vgpu, DPLL_CTRL2) |=
DPLL_CTRL2_DDI_SEL_OVERRIDE(PORT_C);
vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTC_HOTPLUG_CPT;
- vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &=
+ vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(dev_priv, TRANSCODER_A)) &=
~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK |
TRANS_DDI_PORT_MASK);
- vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) |=
+ vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(dev_priv, TRANSCODER_A)) |=
(TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
(PORT_C << TRANS_DDI_PORT_SHIFT) |
TRANS_DDI_FUNC_ENABLE);
@@ -460,10 +465,10 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
vgpu_vreg_t(vgpu, DPLL_CTRL2) |=
DPLL_CTRL2_DDI_SEL_OVERRIDE(PORT_D);
vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTD_HOTPLUG_CPT;
- vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &=
+ vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(dev_priv, TRANSCODER_A)) &=
~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK |
TRANS_DDI_PORT_MASK);
- vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) |=
+ vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(dev_priv, TRANSCODER_A)) |=
(TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
(PORT_D << TRANS_DDI_PORT_SHIFT) |
TRANS_DDI_FUNC_ENABLE);
@@ -502,13 +507,13 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
/* Disable Primary/Sprite/Cursor plane */
for_each_pipe(dev_priv, pipe) {
- vgpu_vreg_t(vgpu, DSPCNTR(pipe)) &= ~DISP_ENABLE;
+ vgpu_vreg_t(vgpu, DSPCNTR(dev_priv, pipe)) &= ~DISP_ENABLE;
vgpu_vreg_t(vgpu, SPRCTL(pipe)) &= ~SPRITE_ENABLE;
- vgpu_vreg_t(vgpu, CURCNTR(pipe)) &= ~MCURSOR_MODE_MASK;
- vgpu_vreg_t(vgpu, CURCNTR(pipe)) |= MCURSOR_MODE_DISABLE;
+ vgpu_vreg_t(vgpu, CURCNTR(dev_priv, pipe)) &= ~MCURSOR_MODE_MASK;
+ vgpu_vreg_t(vgpu, CURCNTR(dev_priv, pipe)) |= MCURSOR_MODE_DISABLE;
}
- vgpu_vreg_t(vgpu, TRANSCONF(TRANSCODER_A)) |= TRANSCONF_ENABLE;
+ vgpu_vreg_t(vgpu, TRANSCONF(dev_priv, TRANSCODER_A)) |= TRANSCONF_ENABLE;
}
static void clean_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num)
@@ -645,7 +650,7 @@ static void emulate_vblank_on_pipe(struct intel_vgpu *vgpu, int pipe)
}
if (pipe_is_enabled(vgpu, pipe)) {
- vgpu_vreg_t(vgpu, PIPE_FRMCOUNT_G4X(pipe))++;
+ vgpu_vreg_t(vgpu, PIPE_FRMCOUNT_G4X(dev_priv, pipe))++;
intel_vgpu_trigger_virtual_event(vgpu, vblank_event[pipe]);
}
}
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c b/drivers/gpu/drm/i915/gvt/dmabuf.c
index 6834f9fe40cf..9efc3ca0ce82 100644
--- a/drivers/gpu/drm/i915/gvt/dmabuf.c
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -37,9 +37,10 @@
#include "gem/i915_gem_dmabuf.h"
#include "i915_drv.h"
-#include "i915_reg.h"
#include "gvt.h"
+#include "display/skl_universal_plane_regs.h"
+
#define GEN8_DECODE_PTE(pte) (pte & GENMASK_ULL(63, 12))
static int vgpu_gem_get_pages(struct drm_i915_gem_object *obj)
diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.c b/drivers/gpu/drm/i915/gvt/fb_decoder.c
index 4140da68aabb..c454e25b2b0f 100644
--- a/drivers/gpu/drm/i915/gvt/fb_decoder.c
+++ b/drivers/gpu/drm/i915/gvt/fb_decoder.c
@@ -40,7 +40,10 @@
#include "i915_pvinfo.h"
#include "i915_reg.h"
+#include "display/i9xx_plane_regs.h"
+#include "display/intel_cursor_regs.h"
#include "display/intel_sprite_regs.h"
+#include "display/skl_universal_plane_regs.h"
#define PRIMARY_FORMAT_NUM 16
struct pixel_format {
@@ -152,7 +155,7 @@ static u32 intel_vgpu_get_stride(struct intel_vgpu *vgpu, int pipe,
{
struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915;
- u32 stride_reg = vgpu_vreg_t(vgpu, DSPSTRIDE(pipe)) & stride_mask;
+ u32 stride_reg = vgpu_vreg_t(vgpu, DSPSTRIDE(dev_priv, pipe)) & stride_mask;
u32 stride = stride_reg;
if (GRAPHICS_VER(dev_priv) >= 9) {
@@ -214,7 +217,7 @@ int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu,
if (pipe >= I915_MAX_PIPES)
return -ENODEV;
- val = vgpu_vreg_t(vgpu, DSPCNTR(pipe));
+ val = vgpu_vreg_t(vgpu, DSPCNTR(dev_priv, pipe));
plane->enabled = !!(val & DISP_ENABLE);
if (!plane->enabled)
return -ENODEV;
@@ -248,7 +251,7 @@ int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu,
plane->hw_format = fmt;
- plane->base = vgpu_vreg_t(vgpu, DSPSURF(pipe)) & I915_GTT_PAGE_MASK;
+ plane->base = vgpu_vreg_t(vgpu, DSPSURF(dev_priv, pipe)) & I915_GTT_PAGE_MASK;
if (!vgpu_gmadr_is_valid(vgpu, plane->base))
return -EINVAL;
@@ -264,14 +267,14 @@ int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu,
(_PRI_PLANE_STRIDE_MASK >> 6) :
_PRI_PLANE_STRIDE_MASK, plane->bpp);
- plane->width = (vgpu_vreg_t(vgpu, PIPESRC(pipe)) & _PIPE_H_SRCSZ_MASK) >>
+ plane->width = (vgpu_vreg_t(vgpu, PIPESRC(dev_priv, pipe)) & _PIPE_H_SRCSZ_MASK) >>
_PIPE_H_SRCSZ_SHIFT;
plane->width += 1;
- plane->height = (vgpu_vreg_t(vgpu, PIPESRC(pipe)) &
- _PIPE_V_SRCSZ_MASK) >> _PIPE_V_SRCSZ_SHIFT;
+ plane->height = (vgpu_vreg_t(vgpu, PIPESRC(dev_priv, pipe)) &
+ _PIPE_V_SRCSZ_MASK) >> _PIPE_V_SRCSZ_SHIFT;
plane->height += 1; /* raw height is one minus the real value */
- val = vgpu_vreg_t(vgpu, DSPTILEOFF(pipe));
+ val = vgpu_vreg_t(vgpu, DSPTILEOFF(dev_priv, pipe));
plane->x_offset = (val & _PRI_PLANE_X_OFF_MASK) >>
_PRI_PLANE_X_OFF_SHIFT;
plane->y_offset = (val & _PRI_PLANE_Y_OFF_MASK) >>
@@ -345,7 +348,7 @@ int intel_vgpu_decode_cursor_plane(struct intel_vgpu *vgpu,
if (pipe >= I915_MAX_PIPES)
return -ENODEV;
- val = vgpu_vreg_t(vgpu, CURCNTR(pipe));
+ val = vgpu_vreg_t(vgpu, CURCNTR(dev_priv, pipe));
mode = val & MCURSOR_MODE_MASK;
plane->enabled = (mode != MCURSOR_MODE_DISABLE);
if (!plane->enabled)
@@ -371,7 +374,7 @@ int intel_vgpu_decode_cursor_plane(struct intel_vgpu *vgpu,
gvt_dbg_core("alpha_plane=0x%x, alpha_force=0x%x\n",
alpha_plane, alpha_force);
- plane->base = vgpu_vreg_t(vgpu, CURBASE(pipe)) & I915_GTT_PAGE_MASK;
+ plane->base = vgpu_vreg_t(vgpu, CURBASE(dev_priv, pipe)) & I915_GTT_PAGE_MASK;
if (!vgpu_gmadr_is_valid(vgpu, plane->base))
return -EINVAL;
@@ -382,7 +385,7 @@ int intel_vgpu_decode_cursor_plane(struct intel_vgpu *vgpu,
return -EINVAL;
}
- val = vgpu_vreg_t(vgpu, CURPOS(pipe));
+ val = vgpu_vreg_t(vgpu, CURPOS(dev_priv, pipe));
plane->x_pos = (val & _CURSOR_POS_X_MASK) >> _CURSOR_POS_X_SHIFT;
plane->x_sign = (val & _CURSOR_SIGN_X_MASK) >> _CURSOR_SIGN_X_SHIFT;
plane->y_pos = (val & _CURSOR_POS_Y_MASK) >> _CURSOR_POS_Y_SHIFT;
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c
index 22fbddbe3e23..0f09344d3c20 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -42,6 +42,8 @@
#include "i915_pvinfo.h"
#include "intel_mchbar_regs.h"
#include "display/bxt_dpio_phy_regs.h"
+#include "display/i9xx_plane_regs.h"
+#include "display/intel_cursor_regs.h"
#include "display/intel_display_types.h"
#include "display/intel_dmc_regs.h"
#include "display/intel_dp_aux_regs.h"
@@ -51,6 +53,7 @@
#include "display/intel_pps_regs.h"
#include "display/intel_psr_regs.h"
#include "display/intel_sprite_regs.h"
+#include "display/skl_universal_plane_regs.h"
#include "display/skl_watermark_regs.h"
#include "display/vlv_dsi_pll_regs.h"
#include "gt/intel_gt_regs.h"
@@ -654,7 +657,7 @@ static void vgpu_update_refresh_rate(struct intel_vgpu *vgpu)
u32 dp_br, link_m, link_n, htotal, vtotal;
/* Find DDI/PORT assigned to TRANSCODER_A, expect B or D */
- port = (vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &
+ port = (vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(dev_priv, TRANSCODER_A)) &
TRANS_DDI_PORT_MASK) >> TRANS_DDI_PORT_SHIFT;
if (port != PORT_B && port != PORT_D) {
gvt_dbg_dpy("vgpu-%d unsupported PORT_%c\n", vgpu->id, port_name(port));
@@ -670,12 +673,12 @@ static void vgpu_update_refresh_rate(struct intel_vgpu *vgpu)
dp_br = skl_vgpu_get_dp_bitrate(vgpu, port);
/* Get DP link symbol clock M/N */
- link_m = vgpu_vreg_t(vgpu, PIPE_LINK_M1(TRANSCODER_A));
- link_n = vgpu_vreg_t(vgpu, PIPE_LINK_N1(TRANSCODER_A));
+ link_m = vgpu_vreg_t(vgpu, PIPE_LINK_M1(dev_priv, TRANSCODER_A));
+ link_n = vgpu_vreg_t(vgpu, PIPE_LINK_N1(dev_priv, TRANSCODER_A));
/* Get H/V total from transcoder timing */
- htotal = (vgpu_vreg_t(vgpu, TRANS_HTOTAL(TRANSCODER_A)) >> TRANS_HTOTAL_SHIFT);
- vtotal = (vgpu_vreg_t(vgpu, TRANS_VTOTAL(TRANSCODER_A)) >> TRANS_VTOTAL_SHIFT);
+ htotal = (vgpu_vreg_t(vgpu, TRANS_HTOTAL(dev_priv, TRANSCODER_A)) >> TRANS_HTOTAL_SHIFT);
+ vtotal = (vgpu_vreg_t(vgpu, TRANS_VTOTAL(dev_priv, TRANSCODER_A)) >> TRANS_VTOTAL_SHIFT);
if (dp_br && link_n && htotal && vtotal) {
u64 pixel_clk = 0;
@@ -878,27 +881,28 @@ static int check_fdi_rx_train_status(struct intel_vgpu *vgpu,
#define INVALID_INDEX (~0U)
-static unsigned int calc_index(unsigned int offset, unsigned int start,
- unsigned int next, unsigned int end, i915_reg_t i915_end)
+static unsigned int calc_index(unsigned int offset, i915_reg_t _start,
+ i915_reg_t _next, i915_reg_t _end)
{
- unsigned int range = next - start;
+ u32 start = i915_mmio_reg_offset(_start);
+ u32 next = i915_mmio_reg_offset(_next);
+ u32 end = i915_mmio_reg_offset(_end);
+ u32 stride = next - start;
- if (!end)
- end = i915_mmio_reg_offset(i915_end);
if (offset < start || offset > end)
return INVALID_INDEX;
offset -= start;
- return offset / range;
+ return offset / stride;
}
#define FDI_RX_CTL_TO_PIPE(offset) \
- calc_index(offset, _FDI_RXA_CTL, _FDI_RXB_CTL, 0, FDI_RX_CTL(PIPE_C))
+ calc_index(offset, FDI_RX_CTL(PIPE_A), FDI_RX_CTL(PIPE_B), FDI_RX_CTL(PIPE_C))
#define FDI_TX_CTL_TO_PIPE(offset) \
- calc_index(offset, _FDI_TXA_CTL, _FDI_TXB_CTL, 0, FDI_TX_CTL(PIPE_C))
+ calc_index(offset, FDI_TX_CTL(PIPE_A), FDI_TX_CTL(PIPE_B), FDI_TX_CTL(PIPE_C))
#define FDI_RX_IMR_TO_PIPE(offset) \
- calc_index(offset, _FDI_RXA_IMR, _FDI_RXB_IMR, 0, FDI_RX_IMR(PIPE_C))
+ calc_index(offset, FDI_RX_IMR(PIPE_A), FDI_RX_IMR(PIPE_B), FDI_RX_IMR(PIPE_C))
static int update_fdi_rx_iir_status(struct intel_vgpu *vgpu,
unsigned int offset, void *p_data, unsigned int bytes)
@@ -942,7 +946,7 @@ static int update_fdi_rx_iir_status(struct intel_vgpu *vgpu,
}
#define DP_TP_CTL_TO_PORT(offset) \
- calc_index(offset, _DP_TP_CTL_A, _DP_TP_CTL_B, 0, DP_TP_CTL(PORT_E))
+ calc_index(offset, DP_TP_CTL(PORT_A), DP_TP_CTL(PORT_B), DP_TP_CTL(PORT_E))
static int dp_tp_ctl_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
void *p_data, unsigned int bytes)
@@ -1005,22 +1009,22 @@ static int south_chicken2_mmio_write(struct intel_vgpu *vgpu,
return 0;
}
-#define DSPSURF_TO_PIPE(offset) \
- calc_index(offset, _DSPASURF, _DSPBSURF, 0, DSPSURF(PIPE_C))
+#define DSPSURF_TO_PIPE(dev_priv, offset) \
+ calc_index(offset, DSPSURF(dev_priv, PIPE_A), DSPSURF(dev_priv, PIPE_B), DSPSURF(dev_priv, PIPE_C))
static int pri_surf_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
void *p_data, unsigned int bytes)
{
struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915;
- u32 pipe = DSPSURF_TO_PIPE(offset);
+ u32 pipe = DSPSURF_TO_PIPE(dev_priv, offset);
int event = SKL_FLIP_EVENT(pipe, PLANE_PRIMARY);
write_vreg(vgpu, offset, p_data, bytes);
- vgpu_vreg_t(vgpu, DSPSURFLIVE(pipe)) = vgpu_vreg(vgpu, offset);
+ vgpu_vreg_t(vgpu, DSPSURFLIVE(dev_priv, pipe)) = vgpu_vreg(vgpu, offset);
- vgpu_vreg_t(vgpu, PIPE_FLIPCOUNT_G4X(pipe))++;
+ vgpu_vreg_t(vgpu, PIPE_FLIPCOUNT_G4X(dev_priv, pipe))++;
- if (vgpu_vreg_t(vgpu, DSPCNTR(pipe)) & PLANE_CTL_ASYNC_FLIP)
+ if (vgpu_vreg_t(vgpu, DSPCNTR(dev_priv, pipe)) & PLANE_CTL_ASYNC_FLIP)
intel_vgpu_trigger_virtual_event(vgpu, event);
else
set_bit(event, vgpu->irq.flip_done_event[pipe]);
@@ -1029,7 +1033,7 @@ static int pri_surf_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
}
#define SPRSURF_TO_PIPE(offset) \
- calc_index(offset, _SPRA_SURF, _SPRB_SURF, 0, SPRSURF(PIPE_C))
+ calc_index(offset, SPRSURF(PIPE_A), SPRSURF(PIPE_B), SPRSURF(PIPE_C))
static int spr_surf_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
void *p_data, unsigned int bytes)
@@ -1059,8 +1063,8 @@ static int reg50080_mmio_write(struct intel_vgpu *vgpu,
write_vreg(vgpu, offset, p_data, bytes);
if (plane == PLANE_PRIMARY) {
- vgpu_vreg_t(vgpu, DSPSURFLIVE(pipe)) = vgpu_vreg(vgpu, offset);
- vgpu_vreg_t(vgpu, PIPE_FLIPCOUNT_G4X(pipe))++;
+ vgpu_vreg_t(vgpu, DSPSURFLIVE(dev_priv, pipe)) = vgpu_vreg(vgpu, offset);
+ vgpu_vreg_t(vgpu, PIPE_FLIPCOUNT_G4X(dev_priv, pipe))++;
} else {
vgpu_vreg_t(vgpu, SPRSURFLIVE(pipe)) = vgpu_vreg(vgpu, offset);
}
@@ -1081,13 +1085,13 @@ static int trigger_aux_channel_interrupt(struct intel_vgpu *vgpu,
if (reg == i915_mmio_reg_offset(DP_AUX_CH_CTL(AUX_CH_A)))
event = AUX_CHANNEL_A;
- else if (reg == _PCH_DPB_AUX_CH_CTL ||
+ else if (reg == i915_mmio_reg_offset(PCH_DP_AUX_CH_CTL(AUX_CH_B)) ||
reg == i915_mmio_reg_offset(DP_AUX_CH_CTL(AUX_CH_B)))
event = AUX_CHANNEL_B;
- else if (reg == _PCH_DPC_AUX_CH_CTL ||
+ else if (reg == i915_mmio_reg_offset(PCH_DP_AUX_CH_CTL(AUX_CH_C)) ||
reg == i915_mmio_reg_offset(DP_AUX_CH_CTL(AUX_CH_C)))
event = AUX_CHANNEL_C;
- else if (reg == _PCH_DPD_AUX_CH_CTL ||
+ else if (reg == i915_mmio_reg_offset(PCH_DP_AUX_CH_CTL(AUX_CH_D)) ||
reg == i915_mmio_reg_offset(DP_AUX_CH_CTL(AUX_CH_D)))
event = AUX_CHANNEL_D;
else {
@@ -1151,11 +1155,6 @@ static void dp_aux_ch_ctl_link_training(struct intel_vgpu_dpcd_data *dpcd,
}
}
-#define _REG_HSW_DP_AUX_CH_CTL(dp) \
- ((dp) ? (_PCH_DPB_AUX_CH_CTL + ((dp)-1)*0x100) : 0x64010)
-
-#define _REG_SKL_DP_AUX_CH_CTL(dp) (0x64010 + (dp) * 0x100)
-
#define OFFSET_TO_DP_AUX_PORT(offset) (((offset) & 0xF00) >> 8)
#define dpy_is_valid_port(port) \
@@ -1179,12 +1178,14 @@ static int dp_aux_ch_ctl_mmio_write(struct intel_vgpu *vgpu,
write_vreg(vgpu, offset, p_data, bytes);
data = vgpu_vreg(vgpu, offset);
- if ((GRAPHICS_VER(vgpu->gvt->gt->i915) >= 9)
- && offset != _REG_SKL_DP_AUX_CH_CTL(port_index)) {
+ if (GRAPHICS_VER(vgpu->gvt->gt->i915) >= 9 &&
+ offset != i915_mmio_reg_offset(DP_AUX_CH_CTL(port_index))) {
/* SKL DPB/C/D aux ctl register changed */
return 0;
} else if (IS_BROADWELL(vgpu->gvt->gt->i915) &&
- offset != _REG_HSW_DP_AUX_CH_CTL(port_index)) {
+ offset != i915_mmio_reg_offset(port_index ?
+ PCH_DP_AUX_CH_CTL(port_index) :
+ DP_AUX_CH_CTL(port_index))) {
/* write to the data registers */
return 0;
}
@@ -2270,17 +2271,21 @@ static int init_generic_mmio_info(struct intel_gvt *gvt)
MMIO_DFH(GEN7_HALF_SLICE_CHICKEN1, D_ALL, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL);
/* display */
- MMIO_DH(TRANSCONF(TRANSCODER_A), D_ALL, NULL, pipeconf_mmio_write);
- MMIO_DH(TRANSCONF(TRANSCODER_B), D_ALL, NULL, pipeconf_mmio_write);
- MMIO_DH(TRANSCONF(TRANSCODER_C), D_ALL, NULL, pipeconf_mmio_write);
- MMIO_DH(TRANSCONF(TRANSCODER_EDP), D_ALL, NULL, pipeconf_mmio_write);
- MMIO_DH(DSPSURF(PIPE_A), D_ALL, NULL, pri_surf_mmio_write);
+ MMIO_DH(TRANSCONF(dev_priv, TRANSCODER_A), D_ALL, NULL,
+ pipeconf_mmio_write);
+ MMIO_DH(TRANSCONF(dev_priv, TRANSCODER_B), D_ALL, NULL,
+ pipeconf_mmio_write);
+ MMIO_DH(TRANSCONF(dev_priv, TRANSCODER_C), D_ALL, NULL,
+ pipeconf_mmio_write);
+ MMIO_DH(TRANSCONF(dev_priv, TRANSCODER_EDP), D_ALL, NULL,
+ pipeconf_mmio_write);
+ MMIO_DH(DSPSURF(dev_priv, PIPE_A), D_ALL, NULL, pri_surf_mmio_write);
MMIO_DH(REG_50080(PIPE_A, PLANE_PRIMARY), D_ALL, NULL,
reg50080_mmio_write);
- MMIO_DH(DSPSURF(PIPE_B), D_ALL, NULL, pri_surf_mmio_write);
+ MMIO_DH(DSPSURF(dev_priv, PIPE_B), D_ALL, NULL, pri_surf_mmio_write);
MMIO_DH(REG_50080(PIPE_B, PLANE_PRIMARY), D_ALL, NULL,
reg50080_mmio_write);
- MMIO_DH(DSPSURF(PIPE_C), D_ALL, NULL, pri_surf_mmio_write);
+ MMIO_DH(DSPSURF(dev_priv, PIPE_C), D_ALL, NULL, pri_surf_mmio_write);
MMIO_DH(REG_50080(PIPE_C, PLANE_PRIMARY), D_ALL, NULL,
reg50080_mmio_write);
MMIO_DH(SPRSURF(PIPE_A), D_ALL, NULL, spr_surf_mmio_write);
@@ -2297,12 +2302,12 @@ static int init_generic_mmio_info(struct intel_gvt *gvt)
gmbus_mmio_write);
MMIO_F(PCH_GPIO_BASE, 6 * 4, F_UNALIGN, 0, 0, D_ALL, NULL, NULL);
- MMIO_F(_MMIO(_PCH_DPB_AUX_CH_CTL), 6 * 4, 0, 0, 0, D_PRE_SKL, NULL,
- dp_aux_ch_ctl_mmio_write);
- MMIO_F(_MMIO(_PCH_DPC_AUX_CH_CTL), 6 * 4, 0, 0, 0, D_PRE_SKL, NULL,
- dp_aux_ch_ctl_mmio_write);
- MMIO_F(_MMIO(_PCH_DPD_AUX_CH_CTL), 6 * 4, 0, 0, 0, D_PRE_SKL, NULL,
- dp_aux_ch_ctl_mmio_write);
+ MMIO_F(PCH_DP_AUX_CH_CTL(AUX_CH_B), 6 * 4, 0, 0, 0, D_PRE_SKL, NULL,
+ dp_aux_ch_ctl_mmio_write);
+ MMIO_F(PCH_DP_AUX_CH_CTL(AUX_CH_C), 6 * 4, 0, 0, 0, D_PRE_SKL, NULL,
+ dp_aux_ch_ctl_mmio_write);
+ MMIO_F(PCH_DP_AUX_CH_CTL(AUX_CH_D), 6 * 4, 0, 0, 0, D_PRE_SKL, NULL,
+ dp_aux_ch_ctl_mmio_write);
MMIO_DH(PCH_ADPA, D_PRE_SKL, NULL, pch_adpa_mmio_write);
@@ -2339,8 +2344,8 @@ static int init_generic_mmio_info(struct intel_gvt *gvt)
MMIO_DH(SBI_DATA, D_ALL, sbi_data_mmio_read, NULL);
MMIO_DH(SBI_CTL_STAT, D_ALL, NULL, sbi_ctl_mmio_write);
- MMIO_F(_MMIO(_DPA_AUX_CH_CTL), 6 * 4, 0, 0, 0, D_ALL, NULL,
- dp_aux_ch_ctl_mmio_write);
+ MMIO_F(DP_AUX_CH_CTL(AUX_CH_A), 6 * 4, 0, 0, 0, D_ALL, NULL,
+ dp_aux_ch_ctl_mmio_write);
MMIO_DH(DDI_BUF_CTL(PORT_A), D_ALL, NULL, ddi_buf_ctl_mmio_write);
MMIO_DH(DDI_BUF_CTL(PORT_B), D_ALL, NULL, ddi_buf_ctl_mmio_write);
@@ -2677,35 +2682,35 @@ static int init_skl_mmio_info(struct intel_gvt *gvt)
MMIO_DH(PLANE_NV12_BUF_CFG(PIPE_C, 2), D_SKL_PLUS, NULL, NULL);
MMIO_DH(PLANE_NV12_BUF_CFG(PIPE_C, 3), D_SKL_PLUS, NULL, NULL);
- MMIO_DH(_MMIO(_REG_701C0(PIPE_A, 1)), D_SKL_PLUS, NULL, NULL);
- MMIO_DH(_MMIO(_REG_701C0(PIPE_A, 2)), D_SKL_PLUS, NULL, NULL);
- MMIO_DH(_MMIO(_REG_701C0(PIPE_A, 3)), D_SKL_PLUS, NULL, NULL);
- MMIO_DH(_MMIO(_REG_701C0(PIPE_A, 4)), D_SKL_PLUS, NULL, NULL);
-
- MMIO_DH(_MMIO(_REG_701C0(PIPE_B, 1)), D_SKL_PLUS, NULL, NULL);
- MMIO_DH(_MMIO(_REG_701C0(PIPE_B, 2)), D_SKL_PLUS, NULL, NULL);
- MMIO_DH(_MMIO(_REG_701C0(PIPE_B, 3)), D_SKL_PLUS, NULL, NULL);
- MMIO_DH(_MMIO(_REG_701C0(PIPE_B, 4)), D_SKL_PLUS, NULL, NULL);
-
- MMIO_DH(_MMIO(_REG_701C0(PIPE_C, 1)), D_SKL_PLUS, NULL, NULL);
- MMIO_DH(_MMIO(_REG_701C0(PIPE_C, 2)), D_SKL_PLUS, NULL, NULL);
- MMIO_DH(_MMIO(_REG_701C0(PIPE_C, 3)), D_SKL_PLUS, NULL, NULL);
- MMIO_DH(_MMIO(_REG_701C0(PIPE_C, 4)), D_SKL_PLUS, NULL, NULL);
-
- MMIO_DH(_MMIO(_REG_701C4(PIPE_A, 1)), D_SKL_PLUS, NULL, NULL);
- MMIO_DH(_MMIO(_REG_701C4(PIPE_A, 2)), D_SKL_PLUS, NULL, NULL);
- MMIO_DH(_MMIO(_REG_701C4(PIPE_A, 3)), D_SKL_PLUS, NULL, NULL);
- MMIO_DH(_MMIO(_REG_701C4(PIPE_A, 4)), D_SKL_PLUS, NULL, NULL);
-
- MMIO_DH(_MMIO(_REG_701C4(PIPE_B, 1)), D_SKL_PLUS, NULL, NULL);
- MMIO_DH(_MMIO(_REG_701C4(PIPE_B, 2)), D_SKL_PLUS, NULL, NULL);
- MMIO_DH(_MMIO(_REG_701C4(PIPE_B, 3)), D_SKL_PLUS, NULL, NULL);
- MMIO_DH(_MMIO(_REG_701C4(PIPE_B, 4)), D_SKL_PLUS, NULL, NULL);
-
- MMIO_DH(_MMIO(_REG_701C4(PIPE_C, 1)), D_SKL_PLUS, NULL, NULL);
- MMIO_DH(_MMIO(_REG_701C4(PIPE_C, 2)), D_SKL_PLUS, NULL, NULL);
- MMIO_DH(_MMIO(_REG_701C4(PIPE_C, 3)), D_SKL_PLUS, NULL, NULL);
- MMIO_DH(_MMIO(_REG_701C4(PIPE_C, 4)), D_SKL_PLUS, NULL, NULL);
+ MMIO_DH(PLANE_AUX_DIST(PIPE_A, 0), D_SKL_PLUS, NULL, NULL);
+ MMIO_DH(PLANE_AUX_DIST(PIPE_A, 1), D_SKL_PLUS, NULL, NULL);
+ MMIO_DH(PLANE_AUX_DIST(PIPE_A, 2), D_SKL_PLUS, NULL, NULL);
+ MMIO_DH(PLANE_AUX_DIST(PIPE_A, 3), D_SKL_PLUS, NULL, NULL);
+
+ MMIO_DH(PLANE_AUX_DIST(PIPE_B, 0), D_SKL_PLUS, NULL, NULL);
+ MMIO_DH(PLANE_AUX_DIST(PIPE_B, 1), D_SKL_PLUS, NULL, NULL);
+ MMIO_DH(PLANE_AUX_DIST(PIPE_B, 2), D_SKL_PLUS, NULL, NULL);
+ MMIO_DH(PLANE_AUX_DIST(PIPE_B, 3), D_SKL_PLUS, NULL, NULL);
+
+ MMIO_DH(PLANE_AUX_DIST(PIPE_C, 0), D_SKL_PLUS, NULL, NULL);
+ MMIO_DH(PLANE_AUX_DIST(PIPE_C, 1), D_SKL_PLUS, NULL, NULL);
+ MMIO_DH(PLANE_AUX_DIST(PIPE_C, 2), D_SKL_PLUS, NULL, NULL);
+ MMIO_DH(PLANE_AUX_DIST(PIPE_C, 3), D_SKL_PLUS, NULL, NULL);
+
+ MMIO_DH(PLANE_AUX_OFFSET(PIPE_A, 0), D_SKL_PLUS, NULL, NULL);
+ MMIO_DH(PLANE_AUX_OFFSET(PIPE_A, 1), D_SKL_PLUS, NULL, NULL);
+ MMIO_DH(PLANE_AUX_OFFSET(PIPE_A, 2), D_SKL_PLUS, NULL, NULL);
+ MMIO_DH(PLANE_AUX_OFFSET(PIPE_A, 3), D_SKL_PLUS, NULL, NULL);
+
+ MMIO_DH(PLANE_AUX_OFFSET(PIPE_B, 0), D_SKL_PLUS, NULL, NULL);
+ MMIO_DH(PLANE_AUX_OFFSET(PIPE_B, 1), D_SKL_PLUS, NULL, NULL);
+ MMIO_DH(PLANE_AUX_OFFSET(PIPE_B, 2), D_SKL_PLUS, NULL, NULL);
+ MMIO_DH(PLANE_AUX_OFFSET(PIPE_B, 3), D_SKL_PLUS, NULL, NULL);
+
+ MMIO_DH(PLANE_AUX_OFFSET(PIPE_C, 0), D_SKL_PLUS, NULL, NULL);
+ MMIO_DH(PLANE_AUX_OFFSET(PIPE_C, 1), D_SKL_PLUS, NULL, NULL);
+ MMIO_DH(PLANE_AUX_OFFSET(PIPE_C, 2), D_SKL_PLUS, NULL, NULL);
+ MMIO_DH(PLANE_AUX_OFFSET(PIPE_C, 3), D_SKL_PLUS, NULL, NULL);
MMIO_DFH(BDW_SCRATCH1, D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL);
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 4f74d867fe1a..38830818c120 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -1985,5 +1985,6 @@ static void __exit kvmgt_exit(void)
module_init(kvmgt_init);
module_exit(kvmgt_exit);
+MODULE_DESCRIPTION("Intel mediated pass-through framework for KVM");
MODULE_LICENSE("GPL and additional rights");
MODULE_AUTHOR("Intel Corporation");
diff --git a/drivers/gpu/drm/i915/gvt/reg.h b/drivers/gpu/drm/i915/gvt/reg.h
index d8216c63c39a..90d8eb1761a3 100644
--- a/drivers/gpu/drm/i915/gvt/reg.h
+++ b/drivers/gpu/drm/i915/gvt/reg.h
@@ -57,9 +57,6 @@
#define VGT_SPRSTRIDE(pipe) _PIPE(pipe, _SPRA_STRIDE, _PLANE_STRIDE_2_B)
-#define _REG_701C0(pipe, plane) (0x701c0 + pipe * 0x1000 + (plane - 1) * 0x100)
-#define _REG_701C4(pipe, plane) (0x701c4 + pipe * 0x1000 + (plane - 1) * 0x100)
-
#define SKL_FLIP_EVENT(pipe, plane) (PRIMARY_A_FLIP_DONE + (plane) * 3 + (pipe))
#define REG50080_FLIP_TYPE_MASK 0x3
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index ee0d7d5f135d..d1d21d433766 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -305,6 +305,7 @@ struct drm_i915_private {
INTEL_DRAM_LPDDR4,
INTEL_DRAM_DDR5,
INTEL_DRAM_LPDDR5,
+ INTEL_DRAM_GDDR,
} type;
u8 num_qgv_points;
u8 num_psf_gv_points;
@@ -535,7 +536,15 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
#define IS_ALDERLAKE_P(i915) IS_PLATFORM(i915, INTEL_ALDERLAKE_P)
#define IS_DG2(i915) IS_PLATFORM(i915, INTEL_DG2)
#define IS_METEORLAKE(i915) IS_PLATFORM(i915, INTEL_METEORLAKE)
-#define IS_LUNARLAKE(i915) 0
+/*
+ * Display code shared by i915 and Xe relies on macros like IS_LUNARLAKE,
+ * so we need to define these even on platforms that the i915 base driver
+ * doesn't support. Ensure the parameter is used in the definition to
+ * avoid 'unused variable' warnings when compiling the shared display code
+ * for i915.
+ */
+#define IS_LUNARLAKE(i915) (0 && i915)
+#define IS_BATTLEMAGE(i915) (0 && i915)
#define IS_DG2_G10(i915) \
IS_SUBPLATFORM(i915, INTEL_DG2, INTEL_SUBPLATFORM_G10)
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 625b3c024540..96c6cafd5b9e 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -836,6 +836,7 @@ static void err_print_gt_engines(struct drm_i915_error_state_buf *m,
static void __err_print_to_sgl(struct drm_i915_error_state_buf *m,
struct i915_gpu_coredump *error)
{
+ struct drm_printer p = i915_error_printer(m);
const struct intel_engine_coredump *ee;
struct timespec64 ts;
@@ -873,7 +874,7 @@ static void __err_print_to_sgl(struct drm_i915_error_state_buf *m,
err_printf(m, "IOMMU enabled?: %d\n", error->iommu);
- intel_dmc_print_error_state(m, m->i915);
+ intel_dmc_print_error_state(&p, m->i915);
err_printf(m, "RPM wakelock: %s\n", str_yes_no(error->wakelock));
err_printf(m, "PM suspended: %s\n", str_yes_no(error->suspended));
@@ -904,7 +905,7 @@ static void __err_print_to_sgl(struct drm_i915_error_state_buf *m,
}
if (error->overlay)
- intel_overlay_print_error_state(m, error->overlay);
+ intel_overlay_print_error_state(&p, error->overlay);
err_print_capabilities(m, error);
err_print_params(m, &error->params);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 678d632ed043..8059ac7e15fe 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1040,7 +1040,8 @@ static void i915_irq_reset(struct drm_i915_private *dev_priv)
if (I915_HAS_HOTPLUG(dev_priv)) {
i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0);
- intel_uncore_rmw(&dev_priv->uncore, PORT_HOTPLUG_STAT, 0, 0);
+ intel_uncore_rmw(&dev_priv->uncore,
+ PORT_HOTPLUG_STAT(dev_priv), 0, 0);
}
i9xx_pipestat_irq_reset(dev_priv);
@@ -1149,7 +1150,7 @@ static void i965_irq_reset(struct drm_i915_private *dev_priv)
struct intel_uncore *uncore = &dev_priv->uncore;
i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0);
- intel_uncore_rmw(uncore, PORT_HOTPLUG_STAT, 0, 0);
+ intel_uncore_rmw(uncore, PORT_HOTPLUG_STAT(dev_priv), 0, 0);
i9xx_pipestat_irq_reset(dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 405ca17a990b..7058efa75324 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -24,7 +24,7 @@
#include <drm/drm_color_mgmt.h>
#include <drm/drm_drv.h>
-#include <drm/i915_pciids.h>
+#include <drm/intel/i915_pciids.h>
#include "display/intel_display.h"
#include "display/intel_display_driver.h"
@@ -797,80 +797,81 @@ __diag_pop();
* PCI ID matches, otherwise we'll use the wrong info struct above.
*/
static const struct pci_device_id pciidlist[] = {
- INTEL_I830_IDS(&i830_info),
- INTEL_I845G_IDS(&i845g_info),
- INTEL_I85X_IDS(&i85x_info),
- INTEL_I865G_IDS(&i865g_info),
- INTEL_I915G_IDS(&i915g_info),
- INTEL_I915GM_IDS(&i915gm_info),
- INTEL_I945G_IDS(&i945g_info),
- INTEL_I945GM_IDS(&i945gm_info),
- INTEL_I965G_IDS(&i965g_info),
- INTEL_G33_IDS(&g33_info),
- INTEL_I965GM_IDS(&i965gm_info),
- INTEL_GM45_IDS(&gm45_info),
- INTEL_G45_IDS(&g45_info),
- INTEL_PINEVIEW_G_IDS(&pnv_g_info),
- INTEL_PINEVIEW_M_IDS(&pnv_m_info),
- INTEL_IRONLAKE_D_IDS(&ilk_d_info),
- INTEL_IRONLAKE_M_IDS(&ilk_m_info),
- INTEL_SNB_D_GT1_IDS(&snb_d_gt1_info),
- INTEL_SNB_D_GT2_IDS(&snb_d_gt2_info),
- INTEL_SNB_M_GT1_IDS(&snb_m_gt1_info),
- INTEL_SNB_M_GT2_IDS(&snb_m_gt2_info),
- INTEL_IVB_Q_IDS(&ivb_q_info), /* must be first IVB */
- INTEL_IVB_M_GT1_IDS(&ivb_m_gt1_info),
- INTEL_IVB_M_GT2_IDS(&ivb_m_gt2_info),
- INTEL_IVB_D_GT1_IDS(&ivb_d_gt1_info),
- INTEL_IVB_D_GT2_IDS(&ivb_d_gt2_info),
- INTEL_HSW_GT1_IDS(&hsw_gt1_info),
- INTEL_HSW_GT2_IDS(&hsw_gt2_info),
- INTEL_HSW_GT3_IDS(&hsw_gt3_info),
- INTEL_VLV_IDS(&vlv_info),
- INTEL_BDW_GT1_IDS(&bdw_gt1_info),
- INTEL_BDW_GT2_IDS(&bdw_gt2_info),
- INTEL_BDW_GT3_IDS(&bdw_gt3_info),
- INTEL_BDW_RSVD_IDS(&bdw_rsvd_info),
- INTEL_CHV_IDS(&chv_info),
- INTEL_SKL_GT1_IDS(&skl_gt1_info),
- INTEL_SKL_GT2_IDS(&skl_gt2_info),
- INTEL_SKL_GT3_IDS(&skl_gt3_info),
- INTEL_SKL_GT4_IDS(&skl_gt4_info),
- INTEL_BXT_IDS(&bxt_info),
- INTEL_GLK_IDS(&glk_info),
- INTEL_KBL_GT1_IDS(&kbl_gt1_info),
- INTEL_KBL_GT2_IDS(&kbl_gt2_info),
- INTEL_KBL_GT3_IDS(&kbl_gt3_info),
- INTEL_KBL_GT4_IDS(&kbl_gt3_info),
- INTEL_AML_KBL_GT2_IDS(&kbl_gt2_info),
- INTEL_CFL_S_GT1_IDS(&cfl_gt1_info),
- INTEL_CFL_S_GT2_IDS(&cfl_gt2_info),
- INTEL_CFL_H_GT1_IDS(&cfl_gt1_info),
- INTEL_CFL_H_GT2_IDS(&cfl_gt2_info),
- INTEL_CFL_U_GT2_IDS(&cfl_gt2_info),
- INTEL_CFL_U_GT3_IDS(&cfl_gt3_info),
- INTEL_WHL_U_GT1_IDS(&cfl_gt1_info),
- INTEL_WHL_U_GT2_IDS(&cfl_gt2_info),
- INTEL_AML_CFL_GT2_IDS(&cfl_gt2_info),
- INTEL_WHL_U_GT3_IDS(&cfl_gt3_info),
- INTEL_CML_GT1_IDS(&cml_gt1_info),
- INTEL_CML_GT2_IDS(&cml_gt2_info),
- INTEL_CML_U_GT1_IDS(&cml_gt1_info),
- INTEL_CML_U_GT2_IDS(&cml_gt2_info),
- INTEL_ICL_11_IDS(&icl_info),
- INTEL_EHL_IDS(&ehl_info),
- INTEL_JSL_IDS(&jsl_info),
- INTEL_TGL_12_IDS(&tgl_info),
- INTEL_RKL_IDS(&rkl_info),
- INTEL_ADLS_IDS(&adl_s_info),
- INTEL_ADLP_IDS(&adl_p_info),
- INTEL_ADLN_IDS(&adl_p_info),
- INTEL_DG1_IDS(&dg1_info),
- INTEL_RPLS_IDS(&adl_s_info),
- INTEL_RPLP_IDS(&adl_p_info),
- INTEL_DG2_IDS(&dg2_info),
- INTEL_ATS_M_IDS(&ats_m_info),
- INTEL_MTL_IDS(&mtl_info),
+ INTEL_I830_IDS(INTEL_VGA_DEVICE, &i830_info),
+ INTEL_I845G_IDS(INTEL_VGA_DEVICE, &i845g_info),
+ INTEL_I85X_IDS(INTEL_VGA_DEVICE, &i85x_info),
+ INTEL_I865G_IDS(INTEL_VGA_DEVICE, &i865g_info),
+ INTEL_I915G_IDS(INTEL_VGA_DEVICE, &i915g_info),
+ INTEL_I915GM_IDS(INTEL_VGA_DEVICE, &i915gm_info),
+ INTEL_I945G_IDS(INTEL_VGA_DEVICE, &i945g_info),
+ INTEL_I945GM_IDS(INTEL_VGA_DEVICE, &i945gm_info),
+ INTEL_I965G_IDS(INTEL_VGA_DEVICE, &i965g_info),
+ INTEL_G33_IDS(INTEL_VGA_DEVICE, &g33_info),
+ INTEL_I965GM_IDS(INTEL_VGA_DEVICE, &i965gm_info),
+ INTEL_GM45_IDS(INTEL_VGA_DEVICE, &gm45_info),
+ INTEL_G45_IDS(INTEL_VGA_DEVICE, &g45_info),
+ INTEL_PNV_G_IDS(INTEL_VGA_DEVICE, &pnv_g_info),
+ INTEL_PNV_M_IDS(INTEL_VGA_DEVICE, &pnv_m_info),
+ INTEL_ILK_D_IDS(INTEL_VGA_DEVICE, &ilk_d_info),
+ INTEL_ILK_M_IDS(INTEL_VGA_DEVICE, &ilk_m_info),
+ INTEL_SNB_D_GT1_IDS(INTEL_VGA_DEVICE, &snb_d_gt1_info),
+ INTEL_SNB_D_GT2_IDS(INTEL_VGA_DEVICE, &snb_d_gt2_info),
+ INTEL_SNB_M_GT1_IDS(INTEL_VGA_DEVICE, &snb_m_gt1_info),
+ INTEL_SNB_M_GT2_IDS(INTEL_VGA_DEVICE, &snb_m_gt2_info),
+ INTEL_IVB_Q_IDS(INTEL_VGA_DEVICE, &ivb_q_info), /* must be first IVB */
+ INTEL_IVB_M_GT1_IDS(INTEL_VGA_DEVICE, &ivb_m_gt1_info),
+ INTEL_IVB_M_GT2_IDS(INTEL_VGA_DEVICE, &ivb_m_gt2_info),
+ INTEL_IVB_D_GT1_IDS(INTEL_VGA_DEVICE, &ivb_d_gt1_info),
+ INTEL_IVB_D_GT2_IDS(INTEL_VGA_DEVICE, &ivb_d_gt2_info),
+ INTEL_HSW_GT1_IDS(INTEL_VGA_DEVICE, &hsw_gt1_info),
+ INTEL_HSW_GT2_IDS(INTEL_VGA_DEVICE, &hsw_gt2_info),
+ INTEL_HSW_GT3_IDS(INTEL_VGA_DEVICE, &hsw_gt3_info),
+ INTEL_VLV_IDS(INTEL_VGA_DEVICE, &vlv_info),
+ INTEL_BDW_GT1_IDS(INTEL_VGA_DEVICE, &bdw_gt1_info),
+ INTEL_BDW_GT2_IDS(INTEL_VGA_DEVICE, &bdw_gt2_info),
+ INTEL_BDW_GT3_IDS(INTEL_VGA_DEVICE, &bdw_gt3_info),
+ INTEL_BDW_RSVD_IDS(INTEL_VGA_DEVICE, &bdw_rsvd_info),
+ INTEL_CHV_IDS(INTEL_VGA_DEVICE, &chv_info),
+ INTEL_SKL_GT1_IDS(INTEL_VGA_DEVICE, &skl_gt1_info),
+ INTEL_SKL_GT2_IDS(INTEL_VGA_DEVICE, &skl_gt2_info),
+ INTEL_SKL_GT3_IDS(INTEL_VGA_DEVICE, &skl_gt3_info),
+ INTEL_SKL_GT4_IDS(INTEL_VGA_DEVICE, &skl_gt4_info),
+ INTEL_BXT_IDS(INTEL_VGA_DEVICE, &bxt_info),
+ INTEL_GLK_IDS(INTEL_VGA_DEVICE, &glk_info),
+ INTEL_KBL_GT1_IDS(INTEL_VGA_DEVICE, &kbl_gt1_info),
+ INTEL_KBL_GT2_IDS(INTEL_VGA_DEVICE, &kbl_gt2_info),
+ INTEL_KBL_GT3_IDS(INTEL_VGA_DEVICE, &kbl_gt3_info),
+ INTEL_KBL_GT4_IDS(INTEL_VGA_DEVICE, &kbl_gt3_info),
+ INTEL_AML_KBL_GT2_IDS(INTEL_VGA_DEVICE, &kbl_gt2_info),
+ INTEL_CFL_S_GT1_IDS(INTEL_VGA_DEVICE, &cfl_gt1_info),
+ INTEL_CFL_S_GT2_IDS(INTEL_VGA_DEVICE, &cfl_gt2_info),
+ INTEL_CFL_H_GT1_IDS(INTEL_VGA_DEVICE, &cfl_gt1_info),
+ INTEL_CFL_H_GT2_IDS(INTEL_VGA_DEVICE, &cfl_gt2_info),
+ INTEL_CFL_U_GT2_IDS(INTEL_VGA_DEVICE, &cfl_gt2_info),
+ INTEL_CFL_U_GT3_IDS(INTEL_VGA_DEVICE, &cfl_gt3_info),
+ INTEL_WHL_U_GT1_IDS(INTEL_VGA_DEVICE, &cfl_gt1_info),
+ INTEL_WHL_U_GT2_IDS(INTEL_VGA_DEVICE, &cfl_gt2_info),
+ INTEL_AML_CFL_GT2_IDS(INTEL_VGA_DEVICE, &cfl_gt2_info),
+ INTEL_WHL_U_GT3_IDS(INTEL_VGA_DEVICE, &cfl_gt3_info),
+ INTEL_CML_GT1_IDS(INTEL_VGA_DEVICE, &cml_gt1_info),
+ INTEL_CML_GT2_IDS(INTEL_VGA_DEVICE, &cml_gt2_info),
+ INTEL_CML_U_GT1_IDS(INTEL_VGA_DEVICE, &cml_gt1_info),
+ INTEL_CML_U_GT2_IDS(INTEL_VGA_DEVICE, &cml_gt2_info),
+ INTEL_ICL_IDS(INTEL_VGA_DEVICE, &icl_info),
+ INTEL_EHL_IDS(INTEL_VGA_DEVICE, &ehl_info),
+ INTEL_JSL_IDS(INTEL_VGA_DEVICE, &jsl_info),
+ INTEL_TGL_IDS(INTEL_VGA_DEVICE, &tgl_info),
+ INTEL_RKL_IDS(INTEL_VGA_DEVICE, &rkl_info),
+ INTEL_ADLS_IDS(INTEL_VGA_DEVICE, &adl_s_info),
+ INTEL_ADLP_IDS(INTEL_VGA_DEVICE, &adl_p_info),
+ INTEL_ADLN_IDS(INTEL_VGA_DEVICE, &adl_p_info),
+ INTEL_DG1_IDS(INTEL_VGA_DEVICE, &dg1_info),
+ INTEL_RPLS_IDS(INTEL_VGA_DEVICE, &adl_s_info),
+ INTEL_RPLU_IDS(INTEL_VGA_DEVICE, &adl_p_info),
+ INTEL_RPLP_IDS(INTEL_VGA_DEVICE, &adl_p_info),
+ INTEL_DG2_IDS(INTEL_VGA_DEVICE, &dg2_info),
+ INTEL_ATS_M_IDS(INTEL_VGA_DEVICE, &ats_m_info),
+ INTEL_MTL_IDS(INTEL_VGA_DEVICE, &mtl_info),
{}
};
MODULE_DEVICE_TABLE(pci, pciidlist);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index e22a82a5ddd7..8e4478194d11 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -668,7 +668,7 @@
#define _DPLL_A 0x6014
#define _DPLL_B 0x6018
#define _CHV_DPLL_C 0x6030
-#define DPLL(pipe) _MMIO_BASE_PIPE3(DISPLAY_MMIO_BASE(dev_priv), \
+#define DPLL(dev_priv, pipe) _MMIO_BASE_PIPE3(DISPLAY_MMIO_BASE(dev_priv), \
(pipe), _DPLL_A, _DPLL_B, _CHV_DPLL_C)
#define VGA0 _MMIO(0x6000)
@@ -768,7 +768,7 @@
#define _DPLL_A_MD 0x601c
#define _DPLL_B_MD 0x6020
#define _CHV_DPLL_C_MD 0x603c
-#define DPLL_MD(pipe) _MMIO_BASE_PIPE3(DISPLAY_MMIO_BASE(dev_priv), \
+#define DPLL_MD(dev_priv, pipe) _MMIO_BASE_PIPE3(DISPLAY_MMIO_BASE(dev_priv), \
(pipe), _DPLL_A_MD, _DPLL_B_MD, _CHV_DPLL_C_MD)
/*
@@ -1069,87 +1069,6 @@
* Display engine regs
*/
-/* Pipe A CRC regs */
-#define _PIPE_CRC_CTL_A 0x60050
-#define PIPE_CRC_ENABLE REG_BIT(31)
-/* skl+ source selection */
-#define PIPE_CRC_SOURCE_MASK_SKL REG_GENMASK(30, 28)
-#define PIPE_CRC_SOURCE_PLANE_1_SKL REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_SKL, 0)
-#define PIPE_CRC_SOURCE_PLANE_2_SKL REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_SKL, 2)
-#define PIPE_CRC_SOURCE_DMUX_SKL REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_SKL, 4)
-#define PIPE_CRC_SOURCE_PLANE_3_SKL REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_SKL, 6)
-#define PIPE_CRC_SOURCE_PLANE_4_SKL REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_SKL, 7)
-#define PIPE_CRC_SOURCE_PLANE_5_SKL REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_SKL, 5)
-#define PIPE_CRC_SOURCE_PLANE_6_SKL REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_SKL, 3)
-#define PIPE_CRC_SOURCE_PLANE_7_SKL REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_SKL, 1)
-/* ivb+ source selection */
-#define PIPE_CRC_SOURCE_MASK_IVB REG_GENMASK(30, 29)
-#define PIPE_CRC_SOURCE_PRIMARY_IVB REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_IVB, 0)
-#define PIPE_CRC_SOURCE_SPRITE_IVB REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_IVB, 1)
-#define PIPE_CRC_SOURCE_PF_IVB REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_IVB, 2)
-/* ilk+ source selection */
-#define PIPE_CRC_SOURCE_MASK_ILK REG_GENMASK(30, 28)
-#define PIPE_CRC_SOURCE_PRIMARY_ILK REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_ILK, 0)
-#define PIPE_CRC_SOURCE_SPRITE_ILK REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_ILK, 1)
-#define PIPE_CRC_SOURCE_PIPE_ILK REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_ILK, 2)
-/* embedded DP port on the north display block */
-#define PIPE_CRC_SOURCE_PORT_A_ILK REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_ILK, 4)
-#define PIPE_CRC_SOURCE_FDI_ILK REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_ILK, 5)
-/* vlv source selection */
-#define PIPE_CRC_SOURCE_MASK_VLV REG_GENMASK(30, 27)
-#define PIPE_CRC_SOURCE_PIPE_VLV REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_VLV, 0)
-#define PIPE_CRC_SOURCE_HDMIB_VLV REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_VLV, 1)
-#define PIPE_CRC_SOURCE_HDMIC_VLV REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_VLV, 2)
-/* with DP port the pipe source is invalid */
-#define PIPE_CRC_SOURCE_DP_D_VLV REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_VLV, 3)
-#define PIPE_CRC_SOURCE_DP_B_VLV REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_VLV, 6)
-#define PIPE_CRC_SOURCE_DP_C_VLV REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_VLV, 7)
-/* gen3+ source selection */
-#define PIPE_CRC_SOURCE_MASK_I9XX REG_GENMASK(30, 28)
-#define PIPE_CRC_SOURCE_PIPE_I9XX REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_I9XX, 0)
-#define PIPE_CRC_SOURCE_SDVOB_I9XX REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_I9XX, 1)
-#define PIPE_CRC_SOURCE_SDVOC_I9XX REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_I9XX, 2)
-/* with DP/TV port the pipe source is invalid */
-#define PIPE_CRC_SOURCE_DP_D_G4X REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_I9XX, 3)
-#define PIPE_CRC_SOURCE_TV_PRE REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_I9XX, 4)
-#define PIPE_CRC_SOURCE_TV_POST REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_I9XX, 5)
-#define PIPE_CRC_SOURCE_DP_B_G4X REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_I9XX, 6)
-#define PIPE_CRC_SOURCE_DP_C_G4X REG_FIELD_PREP(PIPE_CRC_SOURCE_MASK_I9XX, 7)
-/* gen2 doesn't have source selection bits */
-#define PIPE_CRC_INCLUDE_BORDER_I8XX REG_BIT(30)
-
-#define _PIPE_CRC_RES_1_A_IVB 0x60064
-#define _PIPE_CRC_RES_2_A_IVB 0x60068
-#define _PIPE_CRC_RES_3_A_IVB 0x6006c
-#define _PIPE_CRC_RES_4_A_IVB 0x60070
-#define _PIPE_CRC_RES_5_A_IVB 0x60074
-
-#define _PIPE_CRC_RES_RED_A 0x60060
-#define _PIPE_CRC_RES_GREEN_A 0x60064
-#define _PIPE_CRC_RES_BLUE_A 0x60068
-#define _PIPE_CRC_RES_RES1_A_I915 0x6006c
-#define _PIPE_CRC_RES_RES2_A_G4X 0x60080
-
-/* Pipe B CRC regs */
-#define _PIPE_CRC_RES_1_B_IVB 0x61064
-#define _PIPE_CRC_RES_2_B_IVB 0x61068
-#define _PIPE_CRC_RES_3_B_IVB 0x6106c
-#define _PIPE_CRC_RES_4_B_IVB 0x61070
-#define _PIPE_CRC_RES_5_B_IVB 0x61074
-
-#define PIPE_CRC_CTL(pipe) _MMIO_TRANS2(dev_priv, pipe, _PIPE_CRC_CTL_A)
-#define PIPE_CRC_RES_1_IVB(pipe) _MMIO_TRANS2(dev_priv, pipe, _PIPE_CRC_RES_1_A_IVB)
-#define PIPE_CRC_RES_2_IVB(pipe) _MMIO_TRANS2(dev_priv, pipe, _PIPE_CRC_RES_2_A_IVB)
-#define PIPE_CRC_RES_3_IVB(pipe) _MMIO_TRANS2(dev_priv, pipe, _PIPE_CRC_RES_3_A_IVB)
-#define PIPE_CRC_RES_4_IVB(pipe) _MMIO_TRANS2(dev_priv, pipe, _PIPE_CRC_RES_4_A_IVB)
-#define PIPE_CRC_RES_5_IVB(pipe) _MMIO_TRANS2(dev_priv, pipe, _PIPE_CRC_RES_5_A_IVB)
-
-#define PIPE_CRC_RES_RED(pipe) _MMIO_TRANS2(dev_priv, pipe, _PIPE_CRC_RES_RED_A)
-#define PIPE_CRC_RES_GREEN(pipe) _MMIO_TRANS2(dev_priv, pipe, _PIPE_CRC_RES_GREEN_A)
-#define PIPE_CRC_RES_BLUE(pipe) _MMIO_TRANS2(dev_priv, pipe, _PIPE_CRC_RES_BLUE_A)
-#define PIPE_CRC_RES_RES1_I915(pipe) _MMIO_TRANS2(dev_priv, pipe, _PIPE_CRC_RES_RES1_A_I915)
-#define PIPE_CRC_RES_RES2_G4X(pipe) _MMIO_TRANS2(dev_priv, pipe, _PIPE_CRC_RES_RES2_A_G4X)
-
/* Pipe/transcoder A timing regs */
#define _TRANS_HTOTAL_A 0x60000
#define HTOTAL_MASK REG_GENMASK(31, 16)
@@ -1217,116 +1136,16 @@
#define _TRANS_VSYNC_DSI1 0x6b814
#define _TRANS_VSYNCSHIFT_DSI1 0x6b828
-#define TRANS_HTOTAL(trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_HTOTAL_A)
-#define TRANS_HBLANK(trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_HBLANK_A)
-#define TRANS_HSYNC(trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_HSYNC_A)
-#define TRANS_VTOTAL(trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_VTOTAL_A)
-#define TRANS_VBLANK(trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_VBLANK_A)
-#define TRANS_VSYNC(trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_VSYNC_A)
-#define BCLRPAT(trans) _MMIO_TRANS2(dev_priv, (trans), _BCLRPAT_A)
-#define TRANS_VSYNCSHIFT(trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_VSYNCSHIFT_A)
-#define PIPESRC(pipe) _MMIO_TRANS2(dev_priv, (pipe), _PIPEASRC)
-#define TRANS_MULT(trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_MULT_A)
-
-/* VRR registers */
-#define _TRANS_VRR_CTL_A 0x60420
-#define _TRANS_VRR_CTL_B 0x61420
-#define _TRANS_VRR_CTL_C 0x62420
-#define _TRANS_VRR_CTL_D 0x63420
-#define TRANS_VRR_CTL(trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_VRR_CTL_A)
-#define VRR_CTL_VRR_ENABLE REG_BIT(31)
-#define VRR_CTL_IGN_MAX_SHIFT REG_BIT(30)
-#define VRR_CTL_FLIP_LINE_EN REG_BIT(29)
-#define VRR_CTL_PIPELINE_FULL_MASK REG_GENMASK(10, 3)
-#define VRR_CTL_PIPELINE_FULL(x) REG_FIELD_PREP(VRR_CTL_PIPELINE_FULL_MASK, (x))
-#define VRR_CTL_PIPELINE_FULL_OVERRIDE REG_BIT(0)
-#define XELPD_VRR_CTL_VRR_GUARDBAND_MASK REG_GENMASK(15, 0)
-#define XELPD_VRR_CTL_VRR_GUARDBAND(x) REG_FIELD_PREP(XELPD_VRR_CTL_VRR_GUARDBAND_MASK, (x))
-
-#define _TRANS_VRR_VMAX_A 0x60424
-#define _TRANS_VRR_VMAX_B 0x61424
-#define _TRANS_VRR_VMAX_C 0x62424
-#define _TRANS_VRR_VMAX_D 0x63424
-#define TRANS_VRR_VMAX(trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_VRR_VMAX_A)
-#define VRR_VMAX_MASK REG_GENMASK(19, 0)
-
-#define _TRANS_VRR_VMIN_A 0x60434
-#define _TRANS_VRR_VMIN_B 0x61434
-#define _TRANS_VRR_VMIN_C 0x62434
-#define _TRANS_VRR_VMIN_D 0x63434
-#define TRANS_VRR_VMIN(trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_VRR_VMIN_A)
-#define VRR_VMIN_MASK REG_GENMASK(15, 0)
-
-#define _TRANS_VRR_VMAXSHIFT_A 0x60428
-#define _TRANS_VRR_VMAXSHIFT_B 0x61428
-#define _TRANS_VRR_VMAXSHIFT_C 0x62428
-#define _TRANS_VRR_VMAXSHIFT_D 0x63428
-#define TRANS_VRR_VMAXSHIFT(trans) _MMIO_TRANS2(dev_priv, trans, \
- _TRANS_VRR_VMAXSHIFT_A)
-#define VRR_VMAXSHIFT_DEC_MASK REG_GENMASK(29, 16)
-#define VRR_VMAXSHIFT_DEC REG_BIT(16)
-#define VRR_VMAXSHIFT_INC_MASK REG_GENMASK(12, 0)
-
-#define _TRANS_VRR_STATUS_A 0x6042C
-#define _TRANS_VRR_STATUS_B 0x6142C
-#define _TRANS_VRR_STATUS_C 0x6242C
-#define _TRANS_VRR_STATUS_D 0x6342C
-#define TRANS_VRR_STATUS(trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_VRR_STATUS_A)
-#define VRR_STATUS_VMAX_REACHED REG_BIT(31)
-#define VRR_STATUS_NOFLIP_TILL_BNDR REG_BIT(30)
-#define VRR_STATUS_FLIP_BEF_BNDR REG_BIT(29)
-#define VRR_STATUS_NO_FLIP_FRAME REG_BIT(28)
-#define VRR_STATUS_VRR_EN_LIVE REG_BIT(27)
-#define VRR_STATUS_FLIPS_SERVICED REG_BIT(26)
-#define VRR_STATUS_VBLANK_MASK REG_GENMASK(22, 20)
-#define STATUS_FSM_IDLE REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 0)
-#define STATUS_FSM_WAIT_TILL_FDB REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 1)
-#define STATUS_FSM_WAIT_TILL_FS REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 2)
-#define STATUS_FSM_WAIT_TILL_FLIP REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 3)
-#define STATUS_FSM_PIPELINE_FILL REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 4)
-#define STATUS_FSM_ACTIVE REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 5)
-#define STATUS_FSM_LEGACY_VBLANK REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 6)
-
-#define _TRANS_VRR_VTOTAL_PREV_A 0x60480
-#define _TRANS_VRR_VTOTAL_PREV_B 0x61480
-#define _TRANS_VRR_VTOTAL_PREV_C 0x62480
-#define _TRANS_VRR_VTOTAL_PREV_D 0x63480
-#define TRANS_VRR_VTOTAL_PREV(trans) _MMIO_TRANS2(dev_priv, trans, \
- _TRANS_VRR_VTOTAL_PREV_A)
-#define VRR_VTOTAL_FLIP_BEFR_BNDR REG_BIT(31)
-#define VRR_VTOTAL_FLIP_AFTER_BNDR REG_BIT(30)
-#define VRR_VTOTAL_FLIP_AFTER_DBLBUF REG_BIT(29)
-#define VRR_VTOTAL_PREV_FRAME_MASK REG_GENMASK(19, 0)
-
-#define _TRANS_VRR_FLIPLINE_A 0x60438
-#define _TRANS_VRR_FLIPLINE_B 0x61438
-#define _TRANS_VRR_FLIPLINE_C 0x62438
-#define _TRANS_VRR_FLIPLINE_D 0x63438
-#define TRANS_VRR_FLIPLINE(trans) _MMIO_TRANS2(dev_priv, trans, \
- _TRANS_VRR_FLIPLINE_A)
-#define VRR_FLIPLINE_MASK REG_GENMASK(19, 0)
-
-#define _TRANS_VRR_STATUS2_A 0x6043C
-#define _TRANS_VRR_STATUS2_B 0x6143C
-#define _TRANS_VRR_STATUS2_C 0x6243C
-#define _TRANS_VRR_STATUS2_D 0x6343C
-#define TRANS_VRR_STATUS2(trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_VRR_STATUS2_A)
-#define VRR_STATUS2_VERT_LN_CNT_MASK REG_GENMASK(19, 0)
-
-#define _TRANS_PUSH_A 0x60A70
-#define _TRANS_PUSH_B 0x61A70
-#define _TRANS_PUSH_C 0x62A70
-#define _TRANS_PUSH_D 0x63A70
-#define TRANS_PUSH(trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_PUSH_A)
-#define TRANS_PUSH_EN REG_BIT(31)
-#define TRANS_PUSH_SEND REG_BIT(30)
-
-#define _TRANS_VRR_VSYNC_A 0x60078
-#define TRANS_VRR_VSYNC(trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_VRR_VSYNC_A)
-#define VRR_VSYNC_END_MASK REG_GENMASK(28, 16)
-#define VRR_VSYNC_END(vsync_end) REG_FIELD_PREP(VRR_VSYNC_END_MASK, (vsync_end))
-#define VRR_VSYNC_START_MASK REG_GENMASK(12, 0)
-#define VRR_VSYNC_START(vsync_start) REG_FIELD_PREP(VRR_VSYNC_START_MASK, (vsync_start))
+#define TRANS_HTOTAL(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_HTOTAL_A)
+#define TRANS_HBLANK(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_HBLANK_A)
+#define TRANS_HSYNC(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_HSYNC_A)
+#define TRANS_VTOTAL(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_VTOTAL_A)
+#define TRANS_VBLANK(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_VBLANK_A)
+#define TRANS_VSYNC(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_VSYNC_A)
+#define BCLRPAT(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _BCLRPAT_A)
+#define TRANS_VSYNCSHIFT(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_VSYNCSHIFT_A)
+#define PIPESRC(dev_priv, pipe) _MMIO_TRANS2(dev_priv, (pipe), _PIPEASRC)
+#define TRANS_MULT(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_MULT_A)
/* VGA port control */
#define ADPA _MMIO(0x61100)
@@ -1378,7 +1197,7 @@
/* Hotplug control (945+ only) */
-#define PORT_HOTPLUG_EN _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x61110)
+#define PORT_HOTPLUG_EN(dev_priv) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x61110)
#define PORTB_HOTPLUG_INT_EN (1 << 29)
#define PORTC_HOTPLUG_INT_EN (1 << 28)
#define PORTD_HOTPLUG_INT_EN (1 << 27)
@@ -1408,7 +1227,7 @@
#define CRT_HOTPLUG_DETECT_VOLTAGE_325MV (0 << 2)
#define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2)
-#define PORT_HOTPLUG_STAT _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x61114)
+#define PORT_HOTPLUG_STAT(dev_priv) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x61114)
/* HDMI/DP bits are g4x+ */
#define PORTD_HOTPLUG_LIVE_STATUS_G4X (1 << 27)
#define PORTC_HOTPLUG_LIVE_STATUS_G4X (1 << 28)
@@ -1479,7 +1298,7 @@
#define PORT_DFT_I9XX _MMIO(0x61150)
#define DC_BALANCE_RESET (1 << 25)
-#define PORT_DFT2_G4X _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x61154)
+#define PORT_DFT2_G4X(dev_priv) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x61154)
#define DC_BALANCE_RESET_VLV (1 << 31)
#define PIPE_SCRAMBLE_RESET_MASK ((1 << 14) | (0x3 << 0))
#define PIPE_C_SCRAMBLE_RESET REG_BIT(14) /* chv */
@@ -1588,7 +1407,7 @@
#define VIDEO_DIP_ENABLE_AS_ADL REG_BIT(23)
/* Panel fitting */
-#define PFIT_CONTROL _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x61230)
+#define PFIT_CONTROL(dev_priv) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x61230)
#define PFIT_ENABLE REG_BIT(31)
#define PFIT_PIPE_MASK REG_GENMASK(30, 29) /* 965+ */
#define PFIT_PIPE(pipe) REG_FIELD_PREP(PFIT_PIPE_MASK, (pipe))
@@ -1609,7 +1428,7 @@
#define PFIT_HORIZ_AUTO_SCALE REG_BIT(5) /* pre-965 */
#define PFIT_PANEL_8TO6_DITHER_ENABLE REG_BIT(3) /* pre-965 */
-#define PFIT_PGM_RATIOS _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x61234)
+#define PFIT_PGM_RATIOS(dev_priv) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x61234)
#define PFIT_VERT_SCALE_MASK REG_GENMASK(31, 20) /* pre-965 */
#define PFIT_VERT_SCALE(x) REG_FIELD_PREP(PFIT_VERT_SCALE_MASK, (x))
#define PFIT_HORIZ_SCALE_MASK REG_GENMASK(15, 4) /* pre-965 */
@@ -1617,7 +1436,7 @@
#define PFIT_VERT_SCALE_MASK_965 REG_GENMASK(28, 16) /* 965+ */
#define PFIT_HORIZ_SCALE_MASK_965 REG_GENMASK(12, 0) /* 965+ */
-#define PFIT_AUTO_RATIOS _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x61238)
+#define PFIT_AUTO_RATIOS(dev_priv) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x61238)
#define PCH_GTC_CTL _MMIO(0xe7000)
#define PCH_GTC_ENABLE (1 << 31)
@@ -1762,8 +1581,6 @@
#define PIPE_LINK_M_G4X(pipe) _MMIO_PIPE(pipe, _PIPEA_LINK_M_G4X, _PIPEB_LINK_M_G4X)
#define PIPE_LINK_N_G4X(pipe) _MMIO_PIPE(pipe, _PIPEA_LINK_N_G4X, _PIPEB_LINK_N_G4X)
-/* Display & cursor control */
-
/* Pipe A */
#define _PIPEADSL 0x70000
#define PIPEDSL_CURR_FIELD REG_BIT(31) /* ctg+ */
@@ -1878,18 +1695,14 @@
#define PIPESTAT_INT_ENABLE_MASK 0x7fff0000
#define PIPESTAT_INT_STATUS_MASK 0x0000ffff
-#define TRANSCONF(trans) _MMIO_PIPE2(dev_priv, (trans), _TRANSACONF)
-#define PIPEDSL(pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEADSL)
-#define PIPEFRAME(pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEAFRAMEHIGH)
-#define PIPEFRAMEPIXEL(pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEAFRAMEPIXEL)
-#define PIPESTAT(pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEASTAT)
-
-#define _PIPEAGCMAX 0x70010
-#define _PIPEBGCMAX 0x71010
-#define PIPEGCMAX(pipe, i) _MMIO_PIPE2(dev_priv, pipe, _PIPEAGCMAX + (i) * 4) /* u1.16 */
+#define TRANSCONF(dev_priv, trans) _MMIO_PIPE2(dev_priv, (trans), _TRANSACONF)
+#define PIPEDSL(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEADSL)
+#define PIPEFRAME(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEAFRAMEHIGH)
+#define PIPEFRAMEPIXEL(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEAFRAMEPIXEL)
+#define PIPESTAT(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEASTAT)
#define _PIPE_ARB_CTL_A 0x70028 /* icl+ */
-#define PIPE_ARB_CTL(pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPE_ARB_CTL_A)
+#define PIPE_ARB_CTL(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPE_ARB_CTL_A)
#define PIPE_ARB_USE_PROG_SLOTS REG_BIT(13)
#define _PIPE_MISC_A 0x70030
@@ -1933,7 +1746,7 @@
#define PIPE_MISC2(pipe) _MMIO_PIPE(pipe, _PIPE_MISC2_A, _PIPE_MISC2_B)
#define _ICL_PIPE_A_STATUS 0x70058
-#define ICL_PIPESTATUS(pipe) _MMIO_PIPE2(dev_priv, pipe, _ICL_PIPE_A_STATUS)
+#define ICL_PIPESTATUS(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _ICL_PIPE_A_STATUS)
#define PIPE_STATUS_UNDERRUN REG_BIT(31)
#define PIPE_STATUS_SOFT_UNDERRUN_XELPD REG_BIT(28)
#define PIPE_STATUS_HARD_UNDERRUN_XELPD REG_BIT(27)
@@ -1990,7 +1803,7 @@
#define SPRITEA_INVALID_GTT_STATUS REG_BIT(1)
#define PLANEA_INVALID_GTT_STATUS REG_BIT(0)
-#define DSPARB _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x70030)
+#define DSPARB(dev_priv) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x70030)
#define DSPARB_CSTART_MASK (0x7f << 7)
#define DSPARB_CSTART_SHIFT 7
#define DSPARB_BSTART_MASK (0x7f)
@@ -2025,7 +1838,7 @@
#define DSPARB_SPRITEF_MASK_VLV (0xff << 8)
/* pnv/gen4/g4x/vlv/chv */
-#define DSPFW1 _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x70034)
+#define DSPFW1(dev_priv) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x70034)
#define DSPFW_SR_SHIFT 23
#define DSPFW_SR_MASK (0x1ff << 23)
#define DSPFW_CURSORB_SHIFT 16
@@ -2036,7 +1849,7 @@
#define DSPFW_PLANEA_SHIFT 0
#define DSPFW_PLANEA_MASK (0x7f << 0)
#define DSPFW_PLANEA_MASK_VLV (0xff << 0) /* vlv/chv */
-#define DSPFW2 _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x70038)
+#define DSPFW2(dev_priv) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x70038)
#define DSPFW_FBC_SR_EN (1 << 31) /* g4x */
#define DSPFW_FBC_SR_SHIFT 28
#define DSPFW_FBC_SR_MASK (0x7 << 28) /* g4x */
@@ -2052,7 +1865,7 @@
#define DSPFW_SPRITEA_SHIFT 0
#define DSPFW_SPRITEA_MASK (0x7f << 0) /* g4x */
#define DSPFW_SPRITEA_MASK_VLV (0xff << 0) /* vlv/chv */
-#define DSPFW3 _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x7003c)
+#define DSPFW3(dev_priv) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x7003c)
#define DSPFW_HPLL_SR_EN (1 << 31)
#define PINEVIEW_SELF_REFRESH_EN (1 << 30)
#define DSPFW_CURSOR_SR_SHIFT 24
@@ -2263,146 +2076,10 @@
/* GM45+ just has to be different */
#define _PIPEA_FRMCOUNT_G4X 0x70040
#define _PIPEA_FLIPCOUNT_G4X 0x70044
-#define PIPE_FRMCOUNT_G4X(pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEA_FRMCOUNT_G4X)
-#define PIPE_FLIPCOUNT_G4X(pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEA_FLIPCOUNT_G4X)
-
-/* Cursor A & B regs */
-#define _CURACNTR 0x70080
-/* Old style CUR*CNTR flags (desktop 8xx) */
-#define CURSOR_ENABLE REG_BIT(31)
-#define CURSOR_PIPE_GAMMA_ENABLE REG_BIT(30)
-#define CURSOR_STRIDE_MASK REG_GENMASK(29, 28)
-#define CURSOR_STRIDE(stride) REG_FIELD_PREP(CURSOR_STRIDE_MASK, ffs(stride) - 9) /* 256,512,1k,2k */
-#define CURSOR_FORMAT_MASK REG_GENMASK(26, 24)
-#define CURSOR_FORMAT_2C REG_FIELD_PREP(CURSOR_FORMAT_MASK, 0)
-#define CURSOR_FORMAT_3C REG_FIELD_PREP(CURSOR_FORMAT_MASK, 1)
-#define CURSOR_FORMAT_4C REG_FIELD_PREP(CURSOR_FORMAT_MASK, 2)
-#define CURSOR_FORMAT_ARGB REG_FIELD_PREP(CURSOR_FORMAT_MASK, 4)
-#define CURSOR_FORMAT_XRGB REG_FIELD_PREP(CURSOR_FORMAT_MASK, 5)
-/* New style CUR*CNTR flags */
-#define MCURSOR_ARB_SLOTS_MASK REG_GENMASK(30, 28) /* icl+ */
-#define MCURSOR_ARB_SLOTS(x) REG_FIELD_PREP(MCURSOR_ARB_SLOTS_MASK, (x)) /* icl+ */
-#define MCURSOR_PIPE_SEL_MASK REG_GENMASK(29, 28)
-#define MCURSOR_PIPE_SEL(pipe) REG_FIELD_PREP(MCURSOR_PIPE_SEL_MASK, (pipe))
-#define MCURSOR_PIPE_GAMMA_ENABLE REG_BIT(26)
-#define MCURSOR_PIPE_CSC_ENABLE REG_BIT(24) /* ilk+ */
-#define MCURSOR_ROTATE_180 REG_BIT(15)
-#define MCURSOR_TRICKLE_FEED_DISABLE REG_BIT(14)
-#define MCURSOR_MODE_MASK 0x27
-#define MCURSOR_MODE_DISABLE 0x00
-#define MCURSOR_MODE_128_32B_AX 0x02
-#define MCURSOR_MODE_256_32B_AX 0x03
-#define MCURSOR_MODE_64_2B 0x04
-#define MCURSOR_MODE_64_32B_AX 0x07
-#define MCURSOR_MODE_128_ARGB_AX (0x20 | MCURSOR_MODE_128_32B_AX)
-#define MCURSOR_MODE_256_ARGB_AX (0x20 | MCURSOR_MODE_256_32B_AX)
-#define MCURSOR_MODE_64_ARGB_AX (0x20 | MCURSOR_MODE_64_32B_AX)
-#define _CURABASE 0x70084
-#define _CURAPOS 0x70088
-#define _CURAPOS_ERLY_TPT 0x7008c
-#define CURSOR_POS_Y_SIGN REG_BIT(31)
-#define CURSOR_POS_Y_MASK REG_GENMASK(30, 16)
-#define CURSOR_POS_Y(y) REG_FIELD_PREP(CURSOR_POS_Y_MASK, (y))
-#define CURSOR_POS_X_SIGN REG_BIT(15)
-#define CURSOR_POS_X_MASK REG_GENMASK(14, 0)
-#define CURSOR_POS_X(x) REG_FIELD_PREP(CURSOR_POS_X_MASK, (x))
-#define _CURASIZE 0x700a0 /* 845/865 */
-#define CURSOR_HEIGHT_MASK REG_GENMASK(21, 12)
-#define CURSOR_HEIGHT(h) REG_FIELD_PREP(CURSOR_HEIGHT_MASK, (h))
-#define CURSOR_WIDTH_MASK REG_GENMASK(9, 0)
-#define CURSOR_WIDTH(w) REG_FIELD_PREP(CURSOR_WIDTH_MASK, (w))
-#define _CUR_FBC_CTL_A 0x700a0 /* ivb+ */
-#define CUR_FBC_EN REG_BIT(31)
-#define CUR_FBC_HEIGHT_MASK REG_GENMASK(7, 0)
-#define CUR_FBC_HEIGHT(h) REG_FIELD_PREP(CUR_FBC_HEIGHT_MASK, (h))
-#define _CUR_CHICKEN_A 0x700a4 /* mtl+ */
-#define _CURASURFLIVE 0x700ac /* g4x+ */
-#define _CURBCNTR 0x700c0
-#define _CURBBASE 0x700c4
-#define _CURBPOS 0x700c8
-
-#define _CURBCNTR_IVB 0x71080
-#define _CURBBASE_IVB 0x71084
-#define _CURBPOS_IVB 0x71088
-
-#define CURCNTR(pipe) _MMIO_CURSOR2(dev_priv, pipe, _CURACNTR)
-#define CURBASE(pipe) _MMIO_CURSOR2(dev_priv, pipe, _CURABASE)
-#define CURPOS(pipe) _MMIO_CURSOR2(dev_priv, pipe, _CURAPOS)
-#define CURPOS_ERLY_TPT(pipe) _MMIO_CURSOR2(dev_priv, pipe, _CURAPOS_ERLY_TPT)
-#define CURSIZE(pipe) _MMIO_CURSOR2(dev_priv, pipe, _CURASIZE)
-#define CUR_FBC_CTL(pipe) _MMIO_CURSOR2(dev_priv, pipe, _CUR_FBC_CTL_A)
-#define CUR_CHICKEN(pipe) _MMIO_CURSOR2(dev_priv, pipe, _CUR_CHICKEN_A)
-#define CURSURFLIVE(pipe) _MMIO_CURSOR2(dev_priv, pipe, _CURASURFLIVE)
-
-/* Display A control */
-#define _DSPAADDR_VLV 0x7017C /* vlv/chv */
-#define _DSPACNTR 0x70180
-#define DISP_ENABLE REG_BIT(31)
-#define DISP_PIPE_GAMMA_ENABLE REG_BIT(30)
-#define DISP_FORMAT_MASK REG_GENMASK(29, 26)
-#define DISP_FORMAT_8BPP REG_FIELD_PREP(DISP_FORMAT_MASK, 2)
-#define DISP_FORMAT_BGRA555 REG_FIELD_PREP(DISP_FORMAT_MASK, 3)
-#define DISP_FORMAT_BGRX555 REG_FIELD_PREP(DISP_FORMAT_MASK, 4)
-#define DISP_FORMAT_BGRX565 REG_FIELD_PREP(DISP_FORMAT_MASK, 5)
-#define DISP_FORMAT_BGRX888 REG_FIELD_PREP(DISP_FORMAT_MASK, 6)
-#define DISP_FORMAT_BGRA888 REG_FIELD_PREP(DISP_FORMAT_MASK, 7)
-#define DISP_FORMAT_RGBX101010 REG_FIELD_PREP(DISP_FORMAT_MASK, 8)
-#define DISP_FORMAT_RGBA101010 REG_FIELD_PREP(DISP_FORMAT_MASK, 9)
-#define DISP_FORMAT_BGRX101010 REG_FIELD_PREP(DISP_FORMAT_MASK, 10)
-#define DISP_FORMAT_BGRA101010 REG_FIELD_PREP(DISP_FORMAT_MASK, 11)
-#define DISP_FORMAT_RGBX161616 REG_FIELD_PREP(DISP_FORMAT_MASK, 12)
-#define DISP_FORMAT_RGBX888 REG_FIELD_PREP(DISP_FORMAT_MASK, 14)
-#define DISP_FORMAT_RGBA888 REG_FIELD_PREP(DISP_FORMAT_MASK, 15)
-#define DISP_STEREO_ENABLE REG_BIT(25)
-#define DISP_PIPE_CSC_ENABLE REG_BIT(24) /* ilk+ */
-#define DISP_PIPE_SEL_MASK REG_GENMASK(25, 24)
-#define DISP_PIPE_SEL(pipe) REG_FIELD_PREP(DISP_PIPE_SEL_MASK, (pipe))
-#define DISP_SRC_KEY_ENABLE REG_BIT(22)
-#define DISP_LINE_DOUBLE REG_BIT(20)
-#define DISP_STEREO_POLARITY_SECOND REG_BIT(18)
-#define DISP_ALPHA_PREMULTIPLY REG_BIT(16) /* CHV pipe B */
-#define DISP_ROTATE_180 REG_BIT(15)
-#define DISP_TRICKLE_FEED_DISABLE REG_BIT(14) /* g4x+ */
-#define DISP_TILED REG_BIT(10)
-#define DISP_ASYNC_FLIP REG_BIT(9) /* g4x+ */
-#define DISP_MIRROR REG_BIT(8) /* CHV pipe B */
-#define _DSPAADDR 0x70184
-#define _DSPASTRIDE 0x70188
-#define _DSPAPOS 0x7018C /* reserved */
-#define DISP_POS_Y_MASK REG_GENMASK(31, 16)
-#define DISP_POS_Y(y) REG_FIELD_PREP(DISP_POS_Y_MASK, (y))
-#define DISP_POS_X_MASK REG_GENMASK(15, 0)
-#define DISP_POS_X(x) REG_FIELD_PREP(DISP_POS_X_MASK, (x))
-#define _DSPASIZE 0x70190
-#define DISP_HEIGHT_MASK REG_GENMASK(31, 16)
-#define DISP_HEIGHT(h) REG_FIELD_PREP(DISP_HEIGHT_MASK, (h))
-#define DISP_WIDTH_MASK REG_GENMASK(15, 0)
-#define DISP_WIDTH(w) REG_FIELD_PREP(DISP_WIDTH_MASK, (w))
-#define _DSPASURF 0x7019C /* 965+ only */
-#define DISP_ADDR_MASK REG_GENMASK(31, 12)
-#define _DSPATILEOFF 0x701A4 /* 965+ only */
-#define DISP_OFFSET_Y_MASK REG_GENMASK(31, 16)
-#define DISP_OFFSET_Y(y) REG_FIELD_PREP(DISP_OFFSET_Y_MASK, (y))
-#define DISP_OFFSET_X_MASK REG_GENMASK(15, 0)
-#define DISP_OFFSET_X(x) REG_FIELD_PREP(DISP_OFFSET_X_MASK, (x))
-#define _DSPAOFFSET 0x701A4 /* HSW */
-#define _DSPASURFLIVE 0x701AC
-#define _DSPAGAMC 0x701E0
-
-#define DSPADDR_VLV(plane) _MMIO_PIPE2(dev_priv, plane, _DSPAADDR_VLV)
-#define DSPCNTR(plane) _MMIO_PIPE2(dev_priv, plane, _DSPACNTR)
-#define DSPADDR(plane) _MMIO_PIPE2(dev_priv, plane, _DSPAADDR)
-#define DSPSTRIDE(plane) _MMIO_PIPE2(dev_priv, plane, _DSPASTRIDE)
-#define DSPPOS(plane) _MMIO_PIPE2(dev_priv, plane, _DSPAPOS)
-#define DSPSIZE(plane) _MMIO_PIPE2(dev_priv, plane, _DSPASIZE)
-#define DSPSURF(plane) _MMIO_PIPE2(dev_priv, plane, _DSPASURF)
-#define DSPTILEOFF(plane) _MMIO_PIPE2(dev_priv, plane, _DSPATILEOFF)
-#define DSPLINOFF(plane) DSPADDR(plane)
-#define DSPOFFSET(plane) _MMIO_PIPE2(dev_priv, plane, _DSPAOFFSET)
-#define DSPSURFLIVE(plane) _MMIO_PIPE2(dev_priv, plane, _DSPASURFLIVE)
-#define DSPGAMC(plane, i) _MMIO_PIPE2(dev_priv, plane, _DSPAGAMC + (5 - (i)) * 4) /* plane C only, 6 x u0.8 */
-
-/* CHV pipe B blender and primary plane */
+#define PIPE_FRMCOUNT_G4X(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEA_FRMCOUNT_G4X)
+#define PIPE_FLIPCOUNT_G4X(dev_priv, pipe) _MMIO_PIPE2(dev_priv, pipe, _PIPEA_FLIPCOUNT_G4X)
+
+/* CHV pipe B blender */
#define _CHV_BLEND_A 0x60a00
#define CHV_BLEND_MASK REG_GENMASK(31, 30)
#define CHV_BLEND_LEGACY REG_FIELD_PREP(CHV_BLEND_MASK, 0)
@@ -2412,26 +2089,9 @@
#define CHV_CANVAS_RED_MASK REG_GENMASK(29, 20)
#define CHV_CANVAS_GREEN_MASK REG_GENMASK(19, 10)
#define CHV_CANVAS_BLUE_MASK REG_GENMASK(9, 0)
-#define _PRIMPOS_A 0x60a08
-#define PRIM_POS_Y_MASK REG_GENMASK(31, 16)
-#define PRIM_POS_Y(y) REG_FIELD_PREP(PRIM_POS_Y_MASK, (y))
-#define PRIM_POS_X_MASK REG_GENMASK(15, 0)
-#define PRIM_POS_X(x) REG_FIELD_PREP(PRIM_POS_X_MASK, (x))
-#define _PRIMSIZE_A 0x60a0c
-#define PRIM_HEIGHT_MASK REG_GENMASK(31, 16)
-#define PRIM_HEIGHT(h) REG_FIELD_PREP(PRIM_HEIGHT_MASK, (h))
-#define PRIM_WIDTH_MASK REG_GENMASK(15, 0)
-#define PRIM_WIDTH(w) REG_FIELD_PREP(PRIM_WIDTH_MASK, (w))
-#define _PRIMCNSTALPHA_A 0x60a10
-#define PRIM_CONST_ALPHA_ENABLE REG_BIT(31)
-#define PRIM_CONST_ALPHA_MASK REG_GENMASK(7, 0)
-#define PRIM_CONST_ALPHA(alpha) REG_FIELD_PREP(PRIM_CONST_ALPHA_MASK, (alpha))
-
-#define CHV_BLEND(pipe) _MMIO_TRANS2(dev_priv, pipe, _CHV_BLEND_A)
-#define CHV_CANVAS(pipe) _MMIO_TRANS2(dev_priv, pipe, _CHV_CANVAS_A)
-#define PRIMPOS(plane) _MMIO_TRANS2(dev_priv, plane, _PRIMPOS_A)
-#define PRIMSIZE(plane) _MMIO_TRANS2(dev_priv, plane, _PRIMSIZE_A)
-#define PRIMCNSTALPHA(plane) _MMIO_TRANS2(dev_priv, plane, _PRIMCNSTALPHA_A)
+
+#define CHV_BLEND(dev_priv, pipe) _MMIO_TRANS2(dev_priv, pipe, _CHV_BLEND_A)
+#define CHV_CANVAS(dev_priv, pipe) _MMIO_TRANS2(dev_priv, pipe, _CHV_CANVAS_A)
/* Display/Sprite base address macros */
#define DISP_BASEADDR_MASK (0xfffff000)
@@ -2449,390 +2109,15 @@
* [10:1f] all
* [30:32] all
*/
-#define SWF0(i) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x70410 + (i) * 4)
-#define SWF1(i) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x71410 + (i) * 4)
-#define SWF3(i) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x72414 + (i) * 4)
+#define SWF0(dev_priv, i) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x70410 + (i) * 4)
+#define SWF1(dev_priv, i) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x71410 + (i) * 4)
+#define SWF3(dev_priv, i) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x72414 + (i) * 4)
#define SWF_ILK(i) _MMIO(0x4F000 + (i) * 4)
-/* Pipe B */
-#define _PIPEBDSL (DISPLAY_MMIO_BASE(dev_priv) + 0x71000)
-#define _TRANSBCONF (DISPLAY_MMIO_BASE(dev_priv) + 0x71008)
-#define _PIPEBSTAT (DISPLAY_MMIO_BASE(dev_priv) + 0x71024)
-#define _PIPEBFRAMEHIGH 0x71040
-#define _PIPEBFRAMEPIXEL 0x71044
-#define _PIPEB_FRMCOUNT_G4X (DISPLAY_MMIO_BASE(dev_priv) + 0x71040)
-#define _PIPEB_FLIPCOUNT_G4X (DISPLAY_MMIO_BASE(dev_priv) + 0x71044)
-
-
-/* Display B control */
-#define _DSPBCNTR (DISPLAY_MMIO_BASE(dev_priv) + 0x71180)
-#define DISP_ALPHA_TRANS_ENABLE REG_BIT(15)
-#define DISP_SPRITE_ABOVE_OVERLAY REG_BIT(0)
-#define _DSPBADDR (DISPLAY_MMIO_BASE(dev_priv) + 0x71184)
-#define _DSPBSTRIDE (DISPLAY_MMIO_BASE(dev_priv) + 0x71188)
-#define _DSPBPOS (DISPLAY_MMIO_BASE(dev_priv) + 0x7118C)
-#define _DSPBSIZE (DISPLAY_MMIO_BASE(dev_priv) + 0x71190)
-#define _DSPBSURF (DISPLAY_MMIO_BASE(dev_priv) + 0x7119C)
-#define _DSPBTILEOFF (DISPLAY_MMIO_BASE(dev_priv) + 0x711A4)
-#define _DSPBOFFSET (DISPLAY_MMIO_BASE(dev_priv) + 0x711A4)
-#define _DSPBSURFLIVE (DISPLAY_MMIO_BASE(dev_priv) + 0x711AC)
-
/* ICL DSI 0 and 1 */
#define _PIPEDSI0CONF 0x7b008
#define _PIPEDSI1CONF 0x7b808
-/* Skylake plane registers */
-
-#define _PLANE_CTL_1_A 0x70180
-#define _PLANE_CTL_2_A 0x70280
-#define _PLANE_CTL_3_A 0x70380
-#define PLANE_CTL_ENABLE REG_BIT(31)
-#define PLANE_CTL_ARB_SLOTS_MASK REG_GENMASK(30, 28) /* icl+ */
-#define PLANE_CTL_ARB_SLOTS(x) REG_FIELD_PREP(PLANE_CTL_ARB_SLOTS_MASK, (x)) /* icl+ */
-#define PLANE_CTL_PIPE_GAMMA_ENABLE REG_BIT(30) /* Pre-GLK */
-#define PLANE_CTL_YUV_RANGE_CORRECTION_DISABLE REG_BIT(28)
-/*
- * ICL+ uses the same PLANE_CTL_FORMAT bits, but the field definition
- * expanded to include bit 23 as well. However, the shift-24 based values
- * correctly map to the same formats in ICL, as long as bit 23 is set to 0
- */
-#define PLANE_CTL_FORMAT_MASK_SKL REG_GENMASK(27, 24) /* pre-icl */
-#define PLANE_CTL_FORMAT_MASK_ICL REG_GENMASK(27, 23) /* icl+ */
-#define PLANE_CTL_FORMAT_YUV422 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 0)
-#define PLANE_CTL_FORMAT_NV12 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 1)
-#define PLANE_CTL_FORMAT_XRGB_2101010 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 2)
-#define PLANE_CTL_FORMAT_P010 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 3)
-#define PLANE_CTL_FORMAT_XRGB_8888 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 4)
-#define PLANE_CTL_FORMAT_P012 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 5)
-#define PLANE_CTL_FORMAT_XRGB_16161616F REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 6)
-#define PLANE_CTL_FORMAT_P016 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 7)
-#define PLANE_CTL_FORMAT_XYUV REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 8)
-#define PLANE_CTL_FORMAT_INDEXED REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 12)
-#define PLANE_CTL_FORMAT_RGB_565 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_SKL, 14)
-#define PLANE_CTL_FORMAT_Y210 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 1)
-#define PLANE_CTL_FORMAT_Y212 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 3)
-#define PLANE_CTL_FORMAT_Y216 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 5)
-#define PLANE_CTL_FORMAT_Y410 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 7)
-#define PLANE_CTL_FORMAT_Y412 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 9)
-#define PLANE_CTL_FORMAT_Y416 REG_FIELD_PREP(PLANE_CTL_FORMAT_MASK_ICL, 11)
-#define PLANE_CTL_PIPE_CSC_ENABLE REG_BIT(23) /* Pre-GLK */
-#define PLANE_CTL_KEY_ENABLE_MASK REG_GENMASK(22, 21)
-#define PLANE_CTL_KEY_ENABLE_SOURCE REG_FIELD_PREP(PLANE_CTL_KEY_ENABLE_MASK, 1)
-#define PLANE_CTL_KEY_ENABLE_DESTINATION REG_FIELD_PREP(PLANE_CTL_KEY_ENABLE_MASK, 2)
-#define PLANE_CTL_ORDER_RGBX REG_BIT(20)
-#define PLANE_CTL_YUV420_Y_PLANE REG_BIT(19)
-#define PLANE_CTL_YUV_TO_RGB_CSC_FORMAT_BT709 REG_BIT(18)
-#define PLANE_CTL_YUV422_ORDER_MASK REG_GENMASK(17, 16)
-#define PLANE_CTL_YUV422_ORDER_YUYV REG_FIELD_PREP(PLANE_CTL_YUV422_ORDER_MASK, 0)
-#define PLANE_CTL_YUV422_ORDER_UYVY REG_FIELD_PREP(PLANE_CTL_YUV422_ORDER_MASK, 1)
-#define PLANE_CTL_YUV422_ORDER_YVYU REG_FIELD_PREP(PLANE_CTL_YUV422_ORDER_MASK, 2)
-#define PLANE_CTL_YUV422_ORDER_VYUY REG_FIELD_PREP(PLANE_CTL_YUV422_ORDER_MASK, 3)
-#define PLANE_CTL_RENDER_DECOMPRESSION_ENABLE REG_BIT(15)
-#define PLANE_CTL_TRICKLE_FEED_DISABLE REG_BIT(14)
-#define PLANE_CTL_CLEAR_COLOR_DISABLE REG_BIT(13) /* TGL+ */
-#define PLANE_CTL_PLANE_GAMMA_DISABLE REG_BIT(13) /* Pre-GLK */
-#define PLANE_CTL_TILED_MASK REG_GENMASK(12, 10)
-#define PLANE_CTL_TILED_LINEAR REG_FIELD_PREP(PLANE_CTL_TILED_MASK, 0)
-#define PLANE_CTL_TILED_X REG_FIELD_PREP(PLANE_CTL_TILED_MASK, 1)
-#define PLANE_CTL_TILED_Y REG_FIELD_PREP(PLANE_CTL_TILED_MASK, 4)
-#define PLANE_CTL_TILED_YF REG_FIELD_PREP(PLANE_CTL_TILED_MASK, 5)
-#define PLANE_CTL_TILED_4 REG_FIELD_PREP(PLANE_CTL_TILED_MASK, 5)
-#define PLANE_CTL_ASYNC_FLIP REG_BIT(9)
-#define PLANE_CTL_FLIP_HORIZONTAL REG_BIT(8)
-#define PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE REG_BIT(4) /* TGL+ */
-#define PLANE_CTL_ALPHA_MASK REG_GENMASK(5, 4) /* Pre-GLK */
-#define PLANE_CTL_ALPHA_DISABLE REG_FIELD_PREP(PLANE_CTL_ALPHA_MASK, 0)
-#define PLANE_CTL_ALPHA_SW_PREMULTIPLY REG_FIELD_PREP(PLANE_CTL_ALPHA_MASK, 2)
-#define PLANE_CTL_ALPHA_HW_PREMULTIPLY REG_FIELD_PREP(PLANE_CTL_ALPHA_MASK, 3)
-#define PLANE_CTL_ROTATE_MASK REG_GENMASK(1, 0)
-#define PLANE_CTL_ROTATE_0 REG_FIELD_PREP(PLANE_CTL_ROTATE_MASK, 0)
-#define PLANE_CTL_ROTATE_90 REG_FIELD_PREP(PLANE_CTL_ROTATE_MASK, 1)
-#define PLANE_CTL_ROTATE_180 REG_FIELD_PREP(PLANE_CTL_ROTATE_MASK, 2)
-#define PLANE_CTL_ROTATE_270 REG_FIELD_PREP(PLANE_CTL_ROTATE_MASK, 3)
-#define _PLANE_STRIDE_1_A 0x70188
-#define _PLANE_STRIDE_2_A 0x70288
-#define _PLANE_STRIDE_3_A 0x70388
-#define PLANE_STRIDE__MASK REG_GENMASK(11, 0)
-#define PLANE_STRIDE_(stride) REG_FIELD_PREP(PLANE_STRIDE__MASK, (stride))
-#define _PLANE_POS_1_A 0x7018c
-#define _PLANE_POS_2_A 0x7028c
-#define _PLANE_POS_3_A 0x7038c
-#define PLANE_POS_Y_MASK REG_GENMASK(31, 16)
-#define PLANE_POS_Y(y) REG_FIELD_PREP(PLANE_POS_Y_MASK, (y))
-#define PLANE_POS_X_MASK REG_GENMASK(15, 0)
-#define PLANE_POS_X(x) REG_FIELD_PREP(PLANE_POS_X_MASK, (x))
-#define _PLANE_SIZE_1_A 0x70190
-#define _PLANE_SIZE_2_A 0x70290
-#define _PLANE_SIZE_3_A 0x70390
-#define PLANE_HEIGHT_MASK REG_GENMASK(31, 16)
-#define PLANE_HEIGHT(h) REG_FIELD_PREP(PLANE_HEIGHT_MASK, (h))
-#define PLANE_WIDTH_MASK REG_GENMASK(15, 0)
-#define PLANE_WIDTH(w) REG_FIELD_PREP(PLANE_WIDTH_MASK, (w))
-#define _PLANE_SURF_1_A 0x7019c
-#define _PLANE_SURF_2_A 0x7029c
-#define _PLANE_SURF_3_A 0x7039c
-#define PLANE_SURF_ADDR_MASK REG_GENMASK(31, 12)
-#define PLANE_SURF_DECRYPT REG_BIT(2)
-#define _PLANE_OFFSET_1_A 0x701a4
-#define _PLANE_OFFSET_2_A 0x702a4
-#define _PLANE_OFFSET_3_A 0x703a4
-#define PLANE_OFFSET_Y_MASK REG_GENMASK(31, 16)
-#define PLANE_OFFSET_Y(y) REG_FIELD_PREP(PLANE_OFFSET_Y_MASK, (y))
-#define PLANE_OFFSET_X_MASK REG_GENMASK(15, 0)
-#define PLANE_OFFSET_X(x) REG_FIELD_PREP(PLANE_OFFSET_X_MASK, (x))
-#define _PLANE_KEYVAL_1_A 0x70194
-#define _PLANE_KEYVAL_2_A 0x70294
-#define _PLANE_KEYMSK_1_A 0x70198
-#define _PLANE_KEYMSK_2_A 0x70298
-#define PLANE_KEYMSK_ALPHA_ENABLE REG_BIT(31)
-#define _PLANE_KEYMAX_1_A 0x701a0
-#define _PLANE_KEYMAX_2_A 0x702a0
-#define PLANE_KEYMAX_ALPHA_MASK REG_GENMASK(31, 24)
-#define PLANE_KEYMAX_ALPHA(a) REG_FIELD_PREP(PLANE_KEYMAX_ALPHA_MASK, (a))
-#define _PLANE_SURFLIVE_1_A 0x701ac
-#define _PLANE_SURFLIVE_2_A 0x702ac
-#define _PLANE_CC_VAL_1_A 0x701b4
-#define _PLANE_CC_VAL_2_A 0x702b4
-#define _PLANE_AUX_DIST_1_A 0x701c0
-#define PLANE_AUX_DISTANCE_MASK REG_GENMASK(31, 12)
-#define PLANE_AUX_STRIDE_MASK REG_GENMASK(11, 0)
-#define PLANE_AUX_STRIDE(stride) REG_FIELD_PREP(PLANE_AUX_STRIDE_MASK, (stride))
-#define _PLANE_AUX_DIST_2_A 0x702c0
-#define _PLANE_AUX_OFFSET_1_A 0x701c4
-#define _PLANE_AUX_OFFSET_2_A 0x702c4
-#define _PLANE_CUS_CTL_1_A 0x701c8
-#define _PLANE_CUS_CTL_2_A 0x702c8
-#define PLANE_CUS_ENABLE REG_BIT(31)
-#define PLANE_CUS_Y_PLANE_MASK REG_BIT(30)
-#define PLANE_CUS_Y_PLANE_4_RKL REG_FIELD_PREP(PLANE_CUS_Y_PLANE_MASK, 0)
-#define PLANE_CUS_Y_PLANE_5_RKL REG_FIELD_PREP(PLANE_CUS_Y_PLANE_MASK, 1)
-#define PLANE_CUS_Y_PLANE_6_ICL REG_FIELD_PREP(PLANE_CUS_Y_PLANE_MASK, 0)
-#define PLANE_CUS_Y_PLANE_7_ICL REG_FIELD_PREP(PLANE_CUS_Y_PLANE_MASK, 1)
-#define PLANE_CUS_HPHASE_SIGN_NEGATIVE REG_BIT(19)
-#define PLANE_CUS_HPHASE_MASK REG_GENMASK(17, 16)
-#define PLANE_CUS_HPHASE_0 REG_FIELD_PREP(PLANE_CUS_HPHASE_MASK, 0)
-#define PLANE_CUS_HPHASE_0_25 REG_FIELD_PREP(PLANE_CUS_HPHASE_MASK, 1)
-#define PLANE_CUS_HPHASE_0_5 REG_FIELD_PREP(PLANE_CUS_HPHASE_MASK, 2)
-#define PLANE_CUS_VPHASE_SIGN_NEGATIVE REG_BIT(15)
-#define PLANE_CUS_VPHASE_MASK REG_GENMASK(13, 12)
-#define PLANE_CUS_VPHASE_0 REG_FIELD_PREP(PLANE_CUS_VPHASE_MASK, 0)
-#define PLANE_CUS_VPHASE_0_25 REG_FIELD_PREP(PLANE_CUS_VPHASE_MASK, 1)
-#define PLANE_CUS_VPHASE_0_5 REG_FIELD_PREP(PLANE_CUS_VPHASE_MASK, 2)
-#define _PLANE_COLOR_CTL_1_A 0x701CC /* GLK+ */
-#define _PLANE_COLOR_CTL_2_A 0x702CC /* GLK+ */
-#define _PLANE_COLOR_CTL_3_A 0x703CC /* GLK+ */
-#define PLANE_COLOR_PIPE_GAMMA_ENABLE REG_BIT(30) /* Pre-ICL */
-#define PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE REG_BIT(28)
-#define PLANE_COLOR_PIPE_CSC_ENABLE REG_BIT(23) /* Pre-ICL */
-#define PLANE_COLOR_PLANE_CSC_ENABLE REG_BIT(21) /* ICL+ */
-#define PLANE_COLOR_INPUT_CSC_ENABLE REG_BIT(20) /* ICL+ */
-#define PLANE_COLOR_CSC_MODE_MASK REG_GENMASK(19, 17)
-#define PLANE_COLOR_CSC_MODE_BYPASS REG_FIELD_PREP(PLANE_COLOR_CSC_MODE_MASK, 0)
-#define PLANE_COLOR_CSC_MODE_YUV601_TO_RGB601 REG_FIELD_PREP(PLANE_COLOR_CSC_MODE_MASK, 1)
-#define PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709 REG_FIELD_PREP(PLANE_COLOR_CSC_MODE_MASK, 2)
-#define PLANE_COLOR_CSC_MODE_YUV2020_TO_RGB2020 REG_FIELD_PREP(PLANE_COLOR_CSC_MODE_MASK, 3)
-#define PLANE_COLOR_CSC_MODE_RGB709_TO_RGB2020 REG_FIELD_PREP(PLANE_COLOR_CSC_MODE_MASK, 4)
-#define PLANE_COLOR_PLANE_GAMMA_DISABLE REG_BIT(13)
-#define PLANE_COLOR_ALPHA_MASK REG_GENMASK(5, 4)
-#define PLANE_COLOR_ALPHA_DISABLE REG_FIELD_PREP(PLANE_COLOR_ALPHA_MASK, 0)
-#define PLANE_COLOR_ALPHA_SW_PREMULTIPLY REG_FIELD_PREP(PLANE_COLOR_ALPHA_MASK, 2)
-#define PLANE_COLOR_ALPHA_HW_PREMULTIPLY REG_FIELD_PREP(PLANE_COLOR_ALPHA_MASK, 3)
-#define _PLANE_CHICKEN_1_A 0x7026C /* tgl+ */
-#define _PLANE_CHICKEN_2_A 0x7036C /* tgl+ */
-#define PLANE_CHICKEN_DISABLE_DPT REG_BIT(19) /* mtl+ */
-#define _PLANE_BUF_CFG_1_A 0x7027c
-#define _PLANE_BUF_CFG_2_A 0x7037c
-/* skl+: 10 bits, icl+ 11 bits, adlp+ 12 bits */
-#define PLANE_BUF_END_MASK REG_GENMASK(27, 16)
-#define PLANE_BUF_END(end) REG_FIELD_PREP(PLANE_BUF_END_MASK, (end))
-#define PLANE_BUF_START_MASK REG_GENMASK(11, 0)
-#define PLANE_BUF_START(start) REG_FIELD_PREP(PLANE_BUF_START_MASK, (start))
-#define _PLANE_NV12_BUF_CFG_1_A 0x70278
-#define _PLANE_NV12_BUF_CFG_2_A 0x70378
-
-#define _PLANE_CC_VAL_1_B 0x711b4
-#define _PLANE_CC_VAL_2_B 0x712b4
-#define _PLANE_CC_VAL_1(pipe, dw) (_PIPE(pipe, _PLANE_CC_VAL_1_A, _PLANE_CC_VAL_1_B) + (dw) * 4)
-#define _PLANE_CC_VAL_2(pipe, dw) (_PIPE(pipe, _PLANE_CC_VAL_2_A, _PLANE_CC_VAL_2_B) + (dw) * 4)
-#define PLANE_CC_VAL(pipe, plane, dw) \
- _MMIO_PLANE((plane), _PLANE_CC_VAL_1((pipe), (dw)), _PLANE_CC_VAL_2((pipe), (dw)))
-
-/* Input CSC Register Definitions */
-#define _PLANE_INPUT_CSC_RY_GY_1_A 0x701E0
-#define _PLANE_INPUT_CSC_RY_GY_2_A 0x702E0
-
-#define _PLANE_INPUT_CSC_RY_GY_1_B 0x711E0
-#define _PLANE_INPUT_CSC_RY_GY_2_B 0x712E0
-
-#define _PLANE_INPUT_CSC_RY_GY_1(pipe) \
- _PIPE(pipe, _PLANE_INPUT_CSC_RY_GY_1_A, \
- _PLANE_INPUT_CSC_RY_GY_1_B)
-#define _PLANE_INPUT_CSC_RY_GY_2(pipe) \
- _PIPE(pipe, _PLANE_INPUT_CSC_RY_GY_2_A, \
- _PLANE_INPUT_CSC_RY_GY_2_B)
-
-#define PLANE_INPUT_CSC_COEFF(pipe, plane, index) \
- _MMIO_PLANE(plane, _PLANE_INPUT_CSC_RY_GY_1(pipe) + (index) * 4, \
- _PLANE_INPUT_CSC_RY_GY_2(pipe) + (index) * 4)
-
-#define _PLANE_INPUT_CSC_PREOFF_HI_1_A 0x701F8
-#define _PLANE_INPUT_CSC_PREOFF_HI_2_A 0x702F8
-
-#define _PLANE_INPUT_CSC_PREOFF_HI_1_B 0x711F8
-#define _PLANE_INPUT_CSC_PREOFF_HI_2_B 0x712F8
-
-#define _PLANE_INPUT_CSC_PREOFF_HI_1(pipe) \
- _PIPE(pipe, _PLANE_INPUT_CSC_PREOFF_HI_1_A, \
- _PLANE_INPUT_CSC_PREOFF_HI_1_B)
-#define _PLANE_INPUT_CSC_PREOFF_HI_2(pipe) \
- _PIPE(pipe, _PLANE_INPUT_CSC_PREOFF_HI_2_A, \
- _PLANE_INPUT_CSC_PREOFF_HI_2_B)
-#define PLANE_INPUT_CSC_PREOFF(pipe, plane, index) \
- _MMIO_PLANE(plane, _PLANE_INPUT_CSC_PREOFF_HI_1(pipe) + (index) * 4, \
- _PLANE_INPUT_CSC_PREOFF_HI_2(pipe) + (index) * 4)
-
-#define _PLANE_INPUT_CSC_POSTOFF_HI_1_A 0x70204
-#define _PLANE_INPUT_CSC_POSTOFF_HI_2_A 0x70304
-
-#define _PLANE_INPUT_CSC_POSTOFF_HI_1_B 0x71204
-#define _PLANE_INPUT_CSC_POSTOFF_HI_2_B 0x71304
-
-#define _PLANE_INPUT_CSC_POSTOFF_HI_1(pipe) \
- _PIPE(pipe, _PLANE_INPUT_CSC_POSTOFF_HI_1_A, \
- _PLANE_INPUT_CSC_POSTOFF_HI_1_B)
-#define _PLANE_INPUT_CSC_POSTOFF_HI_2(pipe) \
- _PIPE(pipe, _PLANE_INPUT_CSC_POSTOFF_HI_2_A, \
- _PLANE_INPUT_CSC_POSTOFF_HI_2_B)
-#define PLANE_INPUT_CSC_POSTOFF(pipe, plane, index) \
- _MMIO_PLANE(plane, _PLANE_INPUT_CSC_POSTOFF_HI_1(pipe) + (index) * 4, \
- _PLANE_INPUT_CSC_POSTOFF_HI_2(pipe) + (index) * 4)
-
-#define _PLANE_CTL_1_B 0x71180
-#define _PLANE_CTL_2_B 0x71280
-#define _PLANE_CTL_3_B 0x71380
-#define _PLANE_CTL_1(pipe) _PIPE(pipe, _PLANE_CTL_1_A, _PLANE_CTL_1_B)
-#define _PLANE_CTL_2(pipe) _PIPE(pipe, _PLANE_CTL_2_A, _PLANE_CTL_2_B)
-#define _PLANE_CTL_3(pipe) _PIPE(pipe, _PLANE_CTL_3_A, _PLANE_CTL_3_B)
-#define PLANE_CTL(pipe, plane) \
- _MMIO_PLANE(plane, _PLANE_CTL_1(pipe), _PLANE_CTL_2(pipe))
-
-#define _PLANE_STRIDE_1_B 0x71188
-#define _PLANE_STRIDE_2_B 0x71288
-#define _PLANE_STRIDE_3_B 0x71388
-#define _PLANE_STRIDE_1(pipe) \
- _PIPE(pipe, _PLANE_STRIDE_1_A, _PLANE_STRIDE_1_B)
-#define _PLANE_STRIDE_2(pipe) \
- _PIPE(pipe, _PLANE_STRIDE_2_A, _PLANE_STRIDE_2_B)
-#define _PLANE_STRIDE_3(pipe) \
- _PIPE(pipe, _PLANE_STRIDE_3_A, _PLANE_STRIDE_3_B)
-#define PLANE_STRIDE(pipe, plane) \
- _MMIO_PLANE(plane, _PLANE_STRIDE_1(pipe), _PLANE_STRIDE_2(pipe))
-
-#define _PLANE_POS_1_B 0x7118c
-#define _PLANE_POS_2_B 0x7128c
-#define _PLANE_POS_3_B 0x7138c
-#define _PLANE_POS_1(pipe) _PIPE(pipe, _PLANE_POS_1_A, _PLANE_POS_1_B)
-#define _PLANE_POS_2(pipe) _PIPE(pipe, _PLANE_POS_2_A, _PLANE_POS_2_B)
-#define _PLANE_POS_3(pipe) _PIPE(pipe, _PLANE_POS_3_A, _PLANE_POS_3_B)
-#define PLANE_POS(pipe, plane) \
- _MMIO_PLANE(plane, _PLANE_POS_1(pipe), _PLANE_POS_2(pipe))
-
-#define _PLANE_SIZE_1_B 0x71190
-#define _PLANE_SIZE_2_B 0x71290
-#define _PLANE_SIZE_3_B 0x71390
-#define _PLANE_SIZE_1(pipe) _PIPE(pipe, _PLANE_SIZE_1_A, _PLANE_SIZE_1_B)
-#define _PLANE_SIZE_2(pipe) _PIPE(pipe, _PLANE_SIZE_2_A, _PLANE_SIZE_2_B)
-#define _PLANE_SIZE_3(pipe) _PIPE(pipe, _PLANE_SIZE_3_A, _PLANE_SIZE_3_B)
-#define PLANE_SIZE(pipe, plane) \
- _MMIO_PLANE(plane, _PLANE_SIZE_1(pipe), _PLANE_SIZE_2(pipe))
-
-#define _PLANE_SURF_1_B 0x7119c
-#define _PLANE_SURF_2_B 0x7129c
-#define _PLANE_SURF_3_B 0x7139c
-#define _PLANE_SURF_1(pipe) _PIPE(pipe, _PLANE_SURF_1_A, _PLANE_SURF_1_B)
-#define _PLANE_SURF_2(pipe) _PIPE(pipe, _PLANE_SURF_2_A, _PLANE_SURF_2_B)
-#define _PLANE_SURF_3(pipe) _PIPE(pipe, _PLANE_SURF_3_A, _PLANE_SURF_3_B)
-#define PLANE_SURF(pipe, plane) \
- _MMIO_PLANE(plane, _PLANE_SURF_1(pipe), _PLANE_SURF_2(pipe))
-
-#define _PLANE_OFFSET_1_B 0x711a4
-#define _PLANE_OFFSET_2_B 0x712a4
-#define _PLANE_OFFSET_1(pipe) _PIPE(pipe, _PLANE_OFFSET_1_A, _PLANE_OFFSET_1_B)
-#define _PLANE_OFFSET_2(pipe) _PIPE(pipe, _PLANE_OFFSET_2_A, _PLANE_OFFSET_2_B)
-#define PLANE_OFFSET(pipe, plane) \
- _MMIO_PLANE(plane, _PLANE_OFFSET_1(pipe), _PLANE_OFFSET_2(pipe))
-
-#define _PLANE_KEYVAL_1_B 0x71194
-#define _PLANE_KEYVAL_2_B 0x71294
-#define _PLANE_KEYVAL_1(pipe) _PIPE(pipe, _PLANE_KEYVAL_1_A, _PLANE_KEYVAL_1_B)
-#define _PLANE_KEYVAL_2(pipe) _PIPE(pipe, _PLANE_KEYVAL_2_A, _PLANE_KEYVAL_2_B)
-#define PLANE_KEYVAL(pipe, plane) \
- _MMIO_PLANE(plane, _PLANE_KEYVAL_1(pipe), _PLANE_KEYVAL_2(pipe))
-
-#define _PLANE_KEYMSK_1_B 0x71198
-#define _PLANE_KEYMSK_2_B 0x71298
-#define _PLANE_KEYMSK_1(pipe) _PIPE(pipe, _PLANE_KEYMSK_1_A, _PLANE_KEYMSK_1_B)
-#define _PLANE_KEYMSK_2(pipe) _PIPE(pipe, _PLANE_KEYMSK_2_A, _PLANE_KEYMSK_2_B)
-#define PLANE_KEYMSK(pipe, plane) \
- _MMIO_PLANE(plane, _PLANE_KEYMSK_1(pipe), _PLANE_KEYMSK_2(pipe))
-
-#define _PLANE_KEYMAX_1_B 0x711a0
-#define _PLANE_KEYMAX_2_B 0x712a0
-#define _PLANE_KEYMAX_1(pipe) _PIPE(pipe, _PLANE_KEYMAX_1_A, _PLANE_KEYMAX_1_B)
-#define _PLANE_KEYMAX_2(pipe) _PIPE(pipe, _PLANE_KEYMAX_2_A, _PLANE_KEYMAX_2_B)
-#define PLANE_KEYMAX(pipe, plane) \
- _MMIO_PLANE(plane, _PLANE_KEYMAX_1(pipe), _PLANE_KEYMAX_2(pipe))
-
-#define _PLANE_SURFLIVE_1_B 0x711ac
-#define _PLANE_SURFLIVE_2_B 0x712ac
-#define _PLANE_SURFLIVE_1(pipe) _PIPE(pipe, _PLANE_SURFLIVE_1_A, _PLANE_SURFLIVE_1_B)
-#define _PLANE_SURFLIVE_2(pipe) _PIPE(pipe, _PLANE_SURFLIVE_2_A, _PLANE_SURFLIVE_2_B)
-#define PLANE_SURFLIVE(pipe, plane) \
- _MMIO_PLANE(plane, _PLANE_SURFLIVE_1(pipe), _PLANE_SURFLIVE_2(pipe))
-
-#define _PLANE_CHICKEN_1_B 0x7126c
-#define _PLANE_CHICKEN_2_B 0x7136c
-#define _PLANE_CHICKEN_1(pipe) _PIPE(pipe, _PLANE_CHICKEN_1_A, _PLANE_CHICKEN_1_B)
-#define _PLANE_CHICKEN_2(pipe) _PIPE(pipe, _PLANE_CHICKEN_2_A, _PLANE_CHICKEN_2_B)
-#define PLANE_CHICKEN(pipe, plane) \
- _MMIO_PLANE(plane, _PLANE_CHICKEN_1(pipe), _PLANE_CHICKEN_2(pipe))
-
-#define _PLANE_AUX_DIST_1_B 0x711c0
-#define _PLANE_AUX_DIST_2_B 0x712c0
-#define _PLANE_AUX_DIST_1(pipe) \
- _PIPE(pipe, _PLANE_AUX_DIST_1_A, _PLANE_AUX_DIST_1_B)
-#define _PLANE_AUX_DIST_2(pipe) \
- _PIPE(pipe, _PLANE_AUX_DIST_2_A, _PLANE_AUX_DIST_2_B)
-#define PLANE_AUX_DIST(pipe, plane) \
- _MMIO_PLANE(plane, _PLANE_AUX_DIST_1(pipe), _PLANE_AUX_DIST_2(pipe))
-
-#define _PLANE_AUX_OFFSET_1_B 0x711c4
-#define _PLANE_AUX_OFFSET_2_B 0x712c4
-#define _PLANE_AUX_OFFSET_1(pipe) \
- _PIPE(pipe, _PLANE_AUX_OFFSET_1_A, _PLANE_AUX_OFFSET_1_B)
-#define _PLANE_AUX_OFFSET_2(pipe) \
- _PIPE(pipe, _PLANE_AUX_OFFSET_2_A, _PLANE_AUX_OFFSET_2_B)
-#define PLANE_AUX_OFFSET(pipe, plane) \
- _MMIO_PLANE(plane, _PLANE_AUX_OFFSET_1(pipe), _PLANE_AUX_OFFSET_2(pipe))
-
-#define _PLANE_CUS_CTL_1_B 0x711c8
-#define _PLANE_CUS_CTL_2_B 0x712c8
-#define _PLANE_CUS_CTL_1(pipe) \
- _PIPE(pipe, _PLANE_CUS_CTL_1_A, _PLANE_CUS_CTL_1_B)
-#define _PLANE_CUS_CTL_2(pipe) \
- _PIPE(pipe, _PLANE_CUS_CTL_2_A, _PLANE_CUS_CTL_2_B)
-#define PLANE_CUS_CTL(pipe, plane) \
- _MMIO_PLANE(plane, _PLANE_CUS_CTL_1(pipe), _PLANE_CUS_CTL_2(pipe))
-
-#define _PLANE_COLOR_CTL_1_B 0x711CC
-#define _PLANE_COLOR_CTL_2_B 0x712CC
-#define _PLANE_COLOR_CTL_3_B 0x713CC
-#define _PLANE_COLOR_CTL_1(pipe) \
- _PIPE(pipe, _PLANE_COLOR_CTL_1_A, _PLANE_COLOR_CTL_1_B)
-#define _PLANE_COLOR_CTL_2(pipe) \
- _PIPE(pipe, _PLANE_COLOR_CTL_2_A, _PLANE_COLOR_CTL_2_B)
-#define PLANE_COLOR_CTL(pipe, plane) \
- _MMIO_PLANE(plane, _PLANE_COLOR_CTL_1(pipe), _PLANE_COLOR_CTL_2(pipe))
/* VBIOS regs */
#define VGACNTRL _MMIO(0x71400)
@@ -2890,14 +2175,14 @@
#define _PIPEB_LINK_M2 0x61048
#define _PIPEB_LINK_N2 0x6104c
-#define PIPE_DATA_M1(tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_DATA_M1)
-#define PIPE_DATA_N1(tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_DATA_N1)
-#define PIPE_DATA_M2(tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_DATA_M2)
-#define PIPE_DATA_N2(tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_DATA_N2)
-#define PIPE_LINK_M1(tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_LINK_M1)
-#define PIPE_LINK_N1(tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_LINK_N1)
-#define PIPE_LINK_M2(tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_LINK_M2)
-#define PIPE_LINK_N2(tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_LINK_N2)
+#define PIPE_DATA_M1(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_DATA_M1)
+#define PIPE_DATA_N1(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_DATA_N1)
+#define PIPE_DATA_M2(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_DATA_M2)
+#define PIPE_DATA_N2(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_DATA_N2)
+#define PIPE_LINK_M1(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_LINK_M1)
+#define PIPE_LINK_N1(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_LINK_N1)
+#define PIPE_LINK_M2(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_LINK_M2)
+#define PIPE_LINK_N2(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_LINK_N2)
/* CPU panel fitter */
/* IVB+ has 3 fitters, 0 is 7x5 capable, the other two only 3x3 */
@@ -3449,6 +2734,7 @@
#define CHICKEN_MISC_2 _MMIO(0x42084)
#define CHICKEN_MISC_DISABLE_DPT REG_BIT(30) /* adl,dg2 */
+#define BMG_DARB_HALF_BLK_END_BURST REG_BIT(27)
#define KBL_ARB_FILL_SPARE_14 REG_BIT(14)
#define KBL_ARB_FILL_SPARE_13 REG_BIT(13)
#define GLK_CL2_PWR_DOWN REG_BIT(12)
@@ -3519,6 +2805,7 @@
#define DP_FEC_BS_JITTER_WA REG_BIT(15)
#define PSR2_VSC_ENABLE_PROG_HEADER REG_BIT(12)
#define DP_DSC_INSERT_SF_AT_EOL_WA REG_BIT(4)
+#define HDCP_LINE_REKEY_DISABLE REG_BIT(0)
#define DISP_ARB_CTL _MMIO(0x45000)
#define DISP_FBC_MEMORY_WAKE REG_BIT(31)
@@ -3984,25 +3271,25 @@
#define _ICL_VIDEO_DIP_PPS_ECC_A 0x603D4
#define _ICL_VIDEO_DIP_PPS_ECC_B 0x613D4
-#define HSW_TVIDEO_DIP_CTL(trans) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_CTL_A)
-#define HSW_TVIDEO_DIP_GCP(trans) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_GCP_A)
-#define HSW_TVIDEO_DIP_AVI_DATA(trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_AVI_DATA_A + (i) * 4)
-#define HSW_TVIDEO_DIP_VS_DATA(trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_VS_DATA_A + (i) * 4)
-#define HSW_TVIDEO_DIP_SPD_DATA(trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_SPD_DATA_A + (i) * 4)
-#define HSW_TVIDEO_DIP_GMP_DATA(trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_GMP_DATA_A + (i) * 4)
-#define HSW_TVIDEO_DIP_VSC_DATA(trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_VSC_DATA_A + (i) * 4)
-#define GLK_TVIDEO_DIP_DRM_DATA(trans, i) _MMIO_TRANS2(dev_priv, trans, _GLK_VIDEO_DIP_DRM_DATA_A + (i) * 4)
-#define ICL_VIDEO_DIP_PPS_DATA(trans, i) _MMIO_TRANS2(dev_priv, trans, _ICL_VIDEO_DIP_PPS_DATA_A + (i) * 4)
-#define ICL_VIDEO_DIP_PPS_ECC(trans, i) _MMIO_TRANS2(dev_priv, trans, _ICL_VIDEO_DIP_PPS_ECC_A + (i) * 4)
+#define HSW_TVIDEO_DIP_CTL(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_CTL_A)
+#define HSW_TVIDEO_DIP_GCP(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_GCP_A)
+#define HSW_TVIDEO_DIP_AVI_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_AVI_DATA_A + (i) * 4)
+#define HSW_TVIDEO_DIP_VS_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_VS_DATA_A + (i) * 4)
+#define HSW_TVIDEO_DIP_SPD_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_SPD_DATA_A + (i) * 4)
+#define HSW_TVIDEO_DIP_GMP_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_GMP_DATA_A + (i) * 4)
+#define HSW_TVIDEO_DIP_VSC_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _HSW_VIDEO_DIP_VSC_DATA_A + (i) * 4)
+#define GLK_TVIDEO_DIP_DRM_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _GLK_VIDEO_DIP_DRM_DATA_A + (i) * 4)
+#define ICL_VIDEO_DIP_PPS_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _ICL_VIDEO_DIP_PPS_DATA_A + (i) * 4)
+#define ICL_VIDEO_DIP_PPS_ECC(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans, _ICL_VIDEO_DIP_PPS_ECC_A + (i) * 4)
/*ADLP and later: */
-#define ADL_TVIDEO_DIP_AS_SDP_DATA(trans, i) _MMIO_TRANS2(dev_priv, trans,\
+#define ADL_TVIDEO_DIP_AS_SDP_DATA(dev_priv, trans, i) _MMIO_TRANS2(dev_priv, trans,\
_ADL_VIDEO_DIP_AS_DATA_A + (i) * 4)
#define _HSW_STEREO_3D_CTL_A 0x70020
#define S3D_ENABLE (1 << 31)
#define _HSW_STEREO_3D_CTL_B 0x71020
-#define HSW_STEREO_3D_CTL(trans) _MMIO_PIPE2(dev_priv, trans, _HSW_STEREO_3D_CTL_A)
+#define HSW_STEREO_3D_CTL(dev_priv, trans) _MMIO_PIPE2(dev_priv, trans, _HSW_STEREO_3D_CTL_A)
#define _PCH_TRANS_HTOTAL_B 0xe1000
#define _PCH_TRANS_HBLANK_B 0xe1004
@@ -4108,35 +3395,9 @@
#define CNP_PWM_CGE_GATING_DISABLE (1 << 13)
#define PCH_LP_PARTITION_LEVEL_DISABLE (1 << 12)
-#define _PCH_DP_B 0xe4100
-#define PCH_DP_B _MMIO(_PCH_DP_B)
-#define _PCH_DPB_AUX_CH_CTL 0xe4110
-#define _PCH_DPB_AUX_CH_DATA1 0xe4114
-#define _PCH_DPB_AUX_CH_DATA2 0xe4118
-#define _PCH_DPB_AUX_CH_DATA3 0xe411c
-#define _PCH_DPB_AUX_CH_DATA4 0xe4120
-#define _PCH_DPB_AUX_CH_DATA5 0xe4124
-
-#define _PCH_DP_C 0xe4200
-#define PCH_DP_C _MMIO(_PCH_DP_C)
-#define _PCH_DPC_AUX_CH_CTL 0xe4210
-#define _PCH_DPC_AUX_CH_DATA1 0xe4214
-#define _PCH_DPC_AUX_CH_DATA2 0xe4218
-#define _PCH_DPC_AUX_CH_DATA3 0xe421c
-#define _PCH_DPC_AUX_CH_DATA4 0xe4220
-#define _PCH_DPC_AUX_CH_DATA5 0xe4224
-
-#define _PCH_DP_D 0xe4300
-#define PCH_DP_D _MMIO(_PCH_DP_D)
-#define _PCH_DPD_AUX_CH_CTL 0xe4310
-#define _PCH_DPD_AUX_CH_DATA1 0xe4314
-#define _PCH_DPD_AUX_CH_DATA2 0xe4318
-#define _PCH_DPD_AUX_CH_DATA3 0xe431c
-#define _PCH_DPD_AUX_CH_DATA4 0xe4320
-#define _PCH_DPD_AUX_CH_DATA5 0xe4324
-
-#define PCH_DP_AUX_CH_CTL(aux_ch) _MMIO_PORT((aux_ch) - AUX_CH_B, _PCH_DPB_AUX_CH_CTL, _PCH_DPC_AUX_CH_CTL)
-#define PCH_DP_AUX_CH_DATA(aux_ch, i) _MMIO(_PORT((aux_ch) - AUX_CH_B, _PCH_DPB_AUX_CH_DATA1, _PCH_DPC_AUX_CH_DATA1) + (i) * 4) /* 5 registers */
+#define PCH_DP_B _MMIO(0xe4100)
+#define PCH_DP_C _MMIO(0xe4200)
+#define PCH_DP_D _MMIO(0xe4300)
/* CPT */
#define _TRANS_DP_CTL_A 0xe0300
@@ -4488,7 +3749,7 @@ enum skl_power_gate {
#define _TRANS_DDI_FUNC_CTL_EDP 0x6F400
#define _TRANS_DDI_FUNC_CTL_DSI0 0x6b400
#define _TRANS_DDI_FUNC_CTL_DSI1 0x6bc00
-#define TRANS_DDI_FUNC_CTL(tran) _MMIO_TRANS2(dev_priv, tran, _TRANS_DDI_FUNC_CTL_A)
+#define TRANS_DDI_FUNC_CTL(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _TRANS_DDI_FUNC_CTL_A)
#define TRANS_DDI_FUNC_ENABLE (1 << 31)
/* Those bits are ignored by pipe EDP since it can only connect to DDI A */
@@ -4520,6 +3781,7 @@ enum skl_power_gate {
#define TRANS_DDI_EDP_INPUT_B_ONOFF (5 << 12)
#define TRANS_DDI_EDP_INPUT_C_ONOFF (6 << 12)
#define TRANS_DDI_EDP_INPUT_D_ONOFF (7 << 12)
+#define TRANS_DDI_HDCP_LINE_REKEY_DISABLE REG_BIT(12)
#define TRANS_DDI_MST_TRANSPORT_SELECT_MASK REG_GENMASK(11, 10)
#define TRANS_DDI_MST_TRANSPORT_SELECT(trans) \
REG_FIELD_PREP(TRANS_DDI_MST_TRANSPORT_SELECT_MASK, trans)
@@ -4543,7 +3805,7 @@ enum skl_power_gate {
#define _TRANS_DDI_FUNC_CTL2_EDP 0x6f404
#define _TRANS_DDI_FUNC_CTL2_DSI0 0x6b404
#define _TRANS_DDI_FUNC_CTL2_DSI1 0x6bc04
-#define TRANS_DDI_FUNC_CTL2(tran) _MMIO_TRANS2(dev_priv, tran, _TRANS_DDI_FUNC_CTL2_A)
+#define TRANS_DDI_FUNC_CTL2(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _TRANS_DDI_FUNC_CTL2_A)
#define PORT_SYNC_MODE_ENABLE REG_BIT(4)
#define PORT_SYNC_MODE_MASTER_SELECT_MASK REG_GENMASK(2, 0)
#define PORT_SYNC_MODE_MASTER_SELECT(x) REG_FIELD_PREP(PORT_SYNC_MODE_MASTER_SELECT_MASK, (x))
@@ -4556,7 +3818,7 @@ enum skl_power_gate {
#define _DP_TP_CTL_B 0x64140
#define _TGL_DP_TP_CTL_A 0x60540
#define DP_TP_CTL(port) _MMIO_PORT(port, _DP_TP_CTL_A, _DP_TP_CTL_B)
-#define TGL_DP_TP_CTL(tran) _MMIO_TRANS2(dev_priv, (tran), _TGL_DP_TP_CTL_A)
+#define TGL_DP_TP_CTL(dev_priv, tran) _MMIO_TRANS2(dev_priv, (tran), _TGL_DP_TP_CTL_A)
#define DP_TP_CTL_ENABLE (1 << 31)
#define DP_TP_CTL_FEC_ENABLE (1 << 30)
#define DP_TP_CTL_MODE_SST (0 << 27)
@@ -4582,7 +3844,7 @@ enum skl_power_gate {
#define _DP_TP_STATUS_B 0x64144
#define _TGL_DP_TP_STATUS_A 0x60544
#define DP_TP_STATUS(port) _MMIO_PORT(port, _DP_TP_STATUS_A, _DP_TP_STATUS_B)
-#define TGL_DP_TP_STATUS(tran) _MMIO_TRANS2(dev_priv, (tran), _TGL_DP_TP_STATUS_A)
+#define TGL_DP_TP_STATUS(dev_priv, tran) _MMIO_TRANS2(dev_priv, (tran), _TGL_DP_TP_STATUS_A)
#define DP_TP_STATUS_FEC_ENABLE_LIVE (1 << 28)
#define DP_TP_STATUS_IDLE_DONE (1 << 25)
#define DP_TP_STATUS_ACT_SENT (1 << 24)
@@ -4763,14 +4025,14 @@ enum skl_power_gate {
#define _TRANSB_MSA_MISC 0x61410
#define _TRANSC_MSA_MISC 0x62410
#define _TRANS_EDP_MSA_MISC 0x6f410
-#define TRANS_MSA_MISC(tran) _MMIO_TRANS2(dev_priv, tran, _TRANSA_MSA_MISC)
+#define TRANS_MSA_MISC(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _TRANSA_MSA_MISC)
/* See DP_MSA_MISC_* for the bit definitions */
#define _TRANS_A_SET_CONTEXT_LATENCY 0x6007C
#define _TRANS_B_SET_CONTEXT_LATENCY 0x6107C
#define _TRANS_C_SET_CONTEXT_LATENCY 0x6207C
#define _TRANS_D_SET_CONTEXT_LATENCY 0x6307C
-#define TRANS_SET_CONTEXT_LATENCY(tran) _MMIO_TRANS2(dev_priv, tran, _TRANS_A_SET_CONTEXT_LATENCY)
+#define TRANS_SET_CONTEXT_LATENCY(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _TRANS_A_SET_CONTEXT_LATENCY)
#define TRANS_SET_CONTEXT_LATENCY_MASK REG_GENMASK(15, 0)
#define TRANS_SET_CONTEXT_LATENCY_VALUE(x) REG_FIELD_PREP(TRANS_SET_CONTEXT_LATENCY_MASK, (x))
@@ -5148,51 +4410,6 @@ enum skl_power_gate {
#define WM_DBG_DISALLOW_MAXFIFO (1 << 1)
#define WM_DBG_DISALLOW_SPRITE (1 << 2)
-#define _MMIO_PLANE_GAMC(plane, i, a, b) _MMIO(_PIPE(plane, a, b) + (i) * 4)
-
-/* Plane CSC Registers */
-#define _PLANE_CSC_RY_GY_1_A 0x70210
-#define _PLANE_CSC_RY_GY_2_A 0x70310
-
-#define _PLANE_CSC_RY_GY_1_B 0x71210
-#define _PLANE_CSC_RY_GY_2_B 0x71310
-
-#define _PLANE_CSC_RY_GY_1(pipe) _PIPE(pipe, _PLANE_CSC_RY_GY_1_A, \
- _PLANE_CSC_RY_GY_1_B)
-#define _PLANE_CSC_RY_GY_2(pipe) _PIPE(pipe, _PLANE_CSC_RY_GY_2_A, \
- _PLANE_CSC_RY_GY_2_B)
-#define PLANE_CSC_COEFF(pipe, plane, index) _MMIO_PLANE(plane, \
- _PLANE_CSC_RY_GY_1(pipe) + (index) * 4, \
- _PLANE_CSC_RY_GY_2(pipe) + (index) * 4)
-
-#define _PLANE_CSC_PREOFF_HI_1_A 0x70228
-#define _PLANE_CSC_PREOFF_HI_2_A 0x70328
-
-#define _PLANE_CSC_PREOFF_HI_1_B 0x71228
-#define _PLANE_CSC_PREOFF_HI_2_B 0x71328
-
-#define _PLANE_CSC_PREOFF_HI_1(pipe) _PIPE(pipe, _PLANE_CSC_PREOFF_HI_1_A, \
- _PLANE_CSC_PREOFF_HI_1_B)
-#define _PLANE_CSC_PREOFF_HI_2(pipe) _PIPE(pipe, _PLANE_CSC_PREOFF_HI_2_A, \
- _PLANE_CSC_PREOFF_HI_2_B)
-#define PLANE_CSC_PREOFF(pipe, plane, index) _MMIO_PLANE(plane, _PLANE_CSC_PREOFF_HI_1(pipe) + \
- (index) * 4, _PLANE_CSC_PREOFF_HI_2(pipe) + \
- (index) * 4)
-
-#define _PLANE_CSC_POSTOFF_HI_1_A 0x70234
-#define _PLANE_CSC_POSTOFF_HI_2_A 0x70334
-
-#define _PLANE_CSC_POSTOFF_HI_1_B 0x71234
-#define _PLANE_CSC_POSTOFF_HI_2_B 0x71334
-
-#define _PLANE_CSC_POSTOFF_HI_1(pipe) _PIPE(pipe, _PLANE_CSC_POSTOFF_HI_1_A, \
- _PLANE_CSC_POSTOFF_HI_1_B)
-#define _PLANE_CSC_POSTOFF_HI_2(pipe) _PIPE(pipe, _PLANE_CSC_POSTOFF_HI_2_A, \
- _PLANE_CSC_POSTOFF_HI_2_B)
-#define PLANE_CSC_POSTOFF(pipe, plane, index) _MMIO_PLANE(plane, _PLANE_CSC_POSTOFF_HI_1(pipe) + \
- (index) * 4, _PLANE_CSC_POSTOFF_HI_2(pipe) + \
- (index) * 4)
-
/* Gen4+ Timestamp and Pipe Frame time stamp registers */
#define GEN4_TIMESTAMP _MMIO(0x2358)
#define ILK_TIMESTAMP_HI _MMIO(0x70070)
@@ -5297,7 +4514,7 @@ enum skl_power_gate {
#define _MTL_CLKGATE_DIS_TRANS_A 0x604E8
#define _MTL_CLKGATE_DIS_TRANS_B 0x614E8
-#define MTL_CLKGATE_DIS_TRANS(trans) _MMIO_TRANS2(dev_priv, trans, _MTL_CLKGATE_DIS_TRANS_A)
+#define MTL_CLKGATE_DIS_TRANS(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _MTL_CLKGATE_DIS_TRANS_A)
#define MTL_CLKGATE_DIS_TRANS_DMASC_GATING_DIS REG_BIT(7)
#define MTL_MEM_SS_INFO_GLOBAL _MMIO(0x45700)
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
index 81def10eb58f..f8373a461f17 100644
--- a/drivers/gpu/drm/i915/i915_suspend.c
+++ b/drivers/gpu/drm/i915/i915_suspend.c
@@ -40,21 +40,28 @@ static void intel_save_swf(struct drm_i915_private *dev_priv)
/* Scratch space */
if (GRAPHICS_VER(dev_priv) == 2 && IS_MOBILE(dev_priv)) {
for (i = 0; i < 7; i++) {
- dev_priv->regfile.saveSWF0[i] = intel_de_read(dev_priv, SWF0(i));
- dev_priv->regfile.saveSWF1[i] = intel_de_read(dev_priv, SWF1(i));
+ dev_priv->regfile.saveSWF0[i] = intel_de_read(dev_priv,
+ SWF0(dev_priv, i));
+ dev_priv->regfile.saveSWF1[i] = intel_de_read(dev_priv,
+ SWF1(dev_priv, i));
}
for (i = 0; i < 3; i++)
- dev_priv->regfile.saveSWF3[i] = intel_de_read(dev_priv, SWF3(i));
+ dev_priv->regfile.saveSWF3[i] = intel_de_read(dev_priv,
+ SWF3(dev_priv, i));
} else if (GRAPHICS_VER(dev_priv) == 2) {
for (i = 0; i < 7; i++)
- dev_priv->regfile.saveSWF1[i] = intel_de_read(dev_priv, SWF1(i));
+ dev_priv->regfile.saveSWF1[i] = intel_de_read(dev_priv,
+ SWF1(dev_priv, i));
} else if (HAS_GMCH(dev_priv)) {
for (i = 0; i < 16; i++) {
- dev_priv->regfile.saveSWF0[i] = intel_de_read(dev_priv, SWF0(i));
- dev_priv->regfile.saveSWF1[i] = intel_de_read(dev_priv, SWF1(i));
+ dev_priv->regfile.saveSWF0[i] = intel_de_read(dev_priv,
+ SWF0(dev_priv, i));
+ dev_priv->regfile.saveSWF1[i] = intel_de_read(dev_priv,
+ SWF1(dev_priv, i));
}
for (i = 0; i < 3; i++)
- dev_priv->regfile.saveSWF3[i] = intel_de_read(dev_priv, SWF3(i));
+ dev_priv->regfile.saveSWF3[i] = intel_de_read(dev_priv,
+ SWF3(dev_priv, i));
}
}
@@ -65,21 +72,28 @@ static void intel_restore_swf(struct drm_i915_private *dev_priv)
/* Scratch space */
if (GRAPHICS_VER(dev_priv) == 2 && IS_MOBILE(dev_priv)) {
for (i = 0; i < 7; i++) {
- intel_de_write(dev_priv, SWF0(i), dev_priv->regfile.saveSWF0[i]);
- intel_de_write(dev_priv, SWF1(i), dev_priv->regfile.saveSWF1[i]);
+ intel_de_write(dev_priv, SWF0(dev_priv, i),
+ dev_priv->regfile.saveSWF0[i]);
+ intel_de_write(dev_priv, SWF1(dev_priv, i),
+ dev_priv->regfile.saveSWF1[i]);
}
for (i = 0; i < 3; i++)
- intel_de_write(dev_priv, SWF3(i), dev_priv->regfile.saveSWF3[i]);
+ intel_de_write(dev_priv, SWF3(dev_priv, i),
+ dev_priv->regfile.saveSWF3[i]);
} else if (GRAPHICS_VER(dev_priv) == 2) {
for (i = 0; i < 7; i++)
- intel_de_write(dev_priv, SWF1(i), dev_priv->regfile.saveSWF1[i]);
+ intel_de_write(dev_priv, SWF1(dev_priv, i),
+ dev_priv->regfile.saveSWF1[i]);
} else if (HAS_GMCH(dev_priv)) {
for (i = 0; i < 16; i++) {
- intel_de_write(dev_priv, SWF0(i), dev_priv->regfile.saveSWF0[i]);
- intel_de_write(dev_priv, SWF1(i), dev_priv->regfile.saveSWF1[i]);
+ intel_de_write(dev_priv, SWF0(dev_priv, i),
+ dev_priv->regfile.saveSWF0[i]);
+ intel_de_write(dev_priv, SWF1(dev_priv, i),
+ dev_priv->regfile.saveSWF1[i]);
}
for (i = 0; i < 3; i++)
- intel_de_write(dev_priv, SWF3(i), dev_priv->regfile.saveSWF3[i]);
+ intel_de_write(dev_priv, SWF3(dev_priv, i),
+ dev_priv->regfile.saveSWF3[i]);
}
}
@@ -92,7 +106,8 @@ void i915_save_display(struct drm_i915_private *dev_priv)
/* Display arbitration control */
if (GRAPHICS_VER(dev_priv) <= 4)
- dev_priv->regfile.saveDSPARB = intel_de_read(dev_priv, DSPARB);
+ dev_priv->regfile.saveDSPARB = intel_de_read(dev_priv,
+ DSPARB(dev_priv));
if (GRAPHICS_VER(dev_priv) == 4)
pci_read_config_word(pdev, GCDGMBUS,
@@ -116,7 +131,8 @@ void i915_restore_display(struct drm_i915_private *dev_priv)
/* Display arbitration */
if (GRAPHICS_VER(dev_priv) <= 4)
- intel_de_write(dev_priv, DSPARB, dev_priv->regfile.saveDSPARB);
+ intel_de_write(dev_priv, DSPARB(dev_priv),
+ dev_priv->regfile.saveDSPARB);
intel_vga_redisable(dev_priv);
diff --git a/drivers/gpu/drm/i915/intel_clock_gating.c b/drivers/gpu/drm/i915/intel_clock_gating.c
index 1dc5281b2ade..26c4dbda076e 100644
--- a/drivers/gpu/drm/i915/intel_clock_gating.c
+++ b/drivers/gpu/drm/i915/intel_clock_gating.c
@@ -25,11 +25,8 @@
*
*/
-#include "display/intel_de.h"
+#include "display/i9xx_plane_regs.h"
#include "display/intel_display.h"
-#include "display/intel_display_trace.h"
-#include "display/intel_fbc_regs.h"
-#include "display/skl_watermark.h"
#include "gt/intel_engine_regs.h"
#include "gt/intel_gt.h"
@@ -137,10 +134,13 @@ static void g4x_disable_trickle_feed(struct drm_i915_private *dev_priv)
enum pipe pipe;
for_each_pipe(dev_priv, pipe) {
- intel_uncore_rmw(&dev_priv->uncore, DSPCNTR(pipe), 0, DISP_TRICKLE_FEED_DISABLE);
+ intel_uncore_rmw(&dev_priv->uncore, DSPCNTR(dev_priv, pipe),
+ 0, DISP_TRICKLE_FEED_DISABLE);
- intel_uncore_rmw(&dev_priv->uncore, DSPSURF(pipe), 0, 0);
- intel_uncore_posting_read(&dev_priv->uncore, DSPSURF(pipe));
+ intel_uncore_rmw(&dev_priv->uncore, DSPSURF(dev_priv, pipe),
+ 0, 0);
+ intel_uncore_posting_read(&dev_priv->uncore,
+ DSPSURF(dev_priv, pipe));
}
}
diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c
index a0a43ea07f11..d26de37719a7 100644
--- a/drivers/gpu/drm/i915/intel_device_info.c
+++ b/drivers/gpu/drm/i915/intel_device_info.c
@@ -25,7 +25,7 @@
#include <linux/string_helpers.h>
#include <drm/drm_print.h>
-#include <drm/i915_pciids.h>
+#include <drm/intel/i915_pciids.h>
#include "gt/intel_gt_regs.h"
#include "i915_drv.h"
@@ -127,80 +127,80 @@ void intel_device_info_print(const struct intel_device_info *info,
drm_printf(p, "rawclk rate: %u kHz\n", runtime->rawclk_freq);
}
-#undef INTEL_VGA_DEVICE
-#define INTEL_VGA_DEVICE(id, info) (id)
+#define ID(id) (id)
static const u16 subplatform_ult_ids[] = {
- INTEL_HSW_ULT_GT1_IDS(0),
- INTEL_HSW_ULT_GT2_IDS(0),
- INTEL_HSW_ULT_GT3_IDS(0),
- INTEL_BDW_ULT_GT1_IDS(0),
- INTEL_BDW_ULT_GT2_IDS(0),
- INTEL_BDW_ULT_GT3_IDS(0),
- INTEL_BDW_ULT_RSVD_IDS(0),
- INTEL_SKL_ULT_GT1_IDS(0),
- INTEL_SKL_ULT_GT2_IDS(0),
- INTEL_SKL_ULT_GT3_IDS(0),
- INTEL_KBL_ULT_GT1_IDS(0),
- INTEL_KBL_ULT_GT2_IDS(0),
- INTEL_KBL_ULT_GT3_IDS(0),
- INTEL_CFL_U_GT2_IDS(0),
- INTEL_CFL_U_GT3_IDS(0),
- INTEL_WHL_U_GT1_IDS(0),
- INTEL_WHL_U_GT2_IDS(0),
- INTEL_WHL_U_GT3_IDS(0),
- INTEL_CML_U_GT1_IDS(0),
- INTEL_CML_U_GT2_IDS(0),
+ INTEL_HSW_ULT_GT1_IDS(ID),
+ INTEL_HSW_ULT_GT2_IDS(ID),
+ INTEL_HSW_ULT_GT3_IDS(ID),
+ INTEL_BDW_ULT_GT1_IDS(ID),
+ INTEL_BDW_ULT_GT2_IDS(ID),
+ INTEL_BDW_ULT_GT3_IDS(ID),
+ INTEL_BDW_ULT_RSVD_IDS(ID),
+ INTEL_SKL_ULT_GT1_IDS(ID),
+ INTEL_SKL_ULT_GT2_IDS(ID),
+ INTEL_SKL_ULT_GT3_IDS(ID),
+ INTEL_KBL_ULT_GT1_IDS(ID),
+ INTEL_KBL_ULT_GT2_IDS(ID),
+ INTEL_KBL_ULT_GT3_IDS(ID),
+ INTEL_CFL_U_GT2_IDS(ID),
+ INTEL_CFL_U_GT3_IDS(ID),
+ INTEL_WHL_U_GT1_IDS(ID),
+ INTEL_WHL_U_GT2_IDS(ID),
+ INTEL_WHL_U_GT3_IDS(ID),
+ INTEL_CML_U_GT1_IDS(ID),
+ INTEL_CML_U_GT2_IDS(ID),
};
static const u16 subplatform_ulx_ids[] = {
- INTEL_HSW_ULX_GT1_IDS(0),
- INTEL_HSW_ULX_GT2_IDS(0),
- INTEL_BDW_ULX_GT1_IDS(0),
- INTEL_BDW_ULX_GT2_IDS(0),
- INTEL_BDW_ULX_GT3_IDS(0),
- INTEL_BDW_ULX_RSVD_IDS(0),
- INTEL_SKL_ULX_GT1_IDS(0),
- INTEL_SKL_ULX_GT2_IDS(0),
- INTEL_KBL_ULX_GT1_IDS(0),
- INTEL_KBL_ULX_GT2_IDS(0),
- INTEL_AML_KBL_GT2_IDS(0),
- INTEL_AML_CFL_GT2_IDS(0),
+ INTEL_HSW_ULX_GT1_IDS(ID),
+ INTEL_HSW_ULX_GT2_IDS(ID),
+ INTEL_BDW_ULX_GT1_IDS(ID),
+ INTEL_BDW_ULX_GT2_IDS(ID),
+ INTEL_BDW_ULX_GT3_IDS(ID),
+ INTEL_BDW_ULX_RSVD_IDS(ID),
+ INTEL_SKL_ULX_GT1_IDS(ID),
+ INTEL_SKL_ULX_GT2_IDS(ID),
+ INTEL_KBL_ULX_GT1_IDS(ID),
+ INTEL_KBL_ULX_GT2_IDS(ID),
+ INTEL_AML_KBL_GT2_IDS(ID),
+ INTEL_AML_CFL_GT2_IDS(ID),
};
static const u16 subplatform_portf_ids[] = {
- INTEL_ICL_PORT_F_IDS(0),
+ INTEL_ICL_PORT_F_IDS(ID),
};
static const u16 subplatform_uy_ids[] = {
- INTEL_TGL_12_GT2_IDS(0),
+ INTEL_TGL_GT2_IDS(ID),
};
static const u16 subplatform_n_ids[] = {
- INTEL_ADLN_IDS(0),
+ INTEL_ADLN_IDS(ID),
};
static const u16 subplatform_rpl_ids[] = {
- INTEL_RPLS_IDS(0),
- INTEL_RPLP_IDS(0),
+ INTEL_RPLS_IDS(ID),
+ INTEL_RPLU_IDS(ID),
+ INTEL_RPLP_IDS(ID),
};
static const u16 subplatform_rplu_ids[] = {
- INTEL_RPLU_IDS(0),
+ INTEL_RPLU_IDS(ID),
};
static const u16 subplatform_g10_ids[] = {
- INTEL_DG2_G10_IDS(0),
- INTEL_ATS_M150_IDS(0),
+ INTEL_DG2_G10_IDS(ID),
+ INTEL_ATS_M150_IDS(ID),
};
static const u16 subplatform_g11_ids[] = {
- INTEL_DG2_G11_IDS(0),
- INTEL_ATS_M75_IDS(0),
+ INTEL_DG2_G11_IDS(ID),
+ INTEL_ATS_M75_IDS(ID),
};
static const u16 subplatform_g12_ids[] = {
- INTEL_DG2_G12_IDS(0),
+ INTEL_DG2_G12_IDS(ID),
};
static bool find_devid(u16 id, const u16 *p, unsigned int num)
diff --git a/drivers/gpu/drm/i915/intel_gvt_mmio_table.c b/drivers/gpu/drm/i915/intel_gvt_mmio_table.c
index e1a35f70b544..955c9a33212a 100644
--- a/drivers/gpu/drm/i915/intel_gvt_mmio_table.c
+++ b/drivers/gpu/drm/i915/intel_gvt_mmio_table.c
@@ -4,9 +4,11 @@
*/
#include "display/bxt_dpio_phy_regs.h"
+#include "display/i9xx_plane_regs.h"
#include "display/intel_audio_regs.h"
#include "display/intel_backlight_regs.h"
#include "display/intel_color_regs.h"
+#include "display/intel_cursor_regs.h"
#include "display/intel_display_types.h"
#include "display/intel_dmc_regs.h"
#include "display/intel_dp_aux_regs.h"
@@ -16,6 +18,7 @@
#include "display/intel_lvds_regs.h"
#include "display/intel_psr_regs.h"
#include "display/intel_sprite_regs.h"
+#include "display/skl_universal_plane_regs.h"
#include "display/skl_watermark_regs.h"
#include "display/vlv_dsi_pll_regs.h"
#include "gt/intel_engine_regs.h"
@@ -123,38 +126,38 @@ static int iterate_generic_mmio(struct intel_gvt_mmio_table_iter *iter)
MMIO_D(_MMIO(0x650b4));
MMIO_D(_MMIO(0xc4040));
MMIO_D(DERRMR);
- MMIO_D(PIPEDSL(PIPE_A));
- MMIO_D(PIPEDSL(PIPE_B));
- MMIO_D(PIPEDSL(PIPE_C));
- MMIO_D(PIPEDSL(_PIPE_EDP));
- MMIO_D(TRANSCONF(TRANSCODER_A));
- MMIO_D(TRANSCONF(TRANSCODER_B));
- MMIO_D(TRANSCONF(TRANSCODER_C));
- MMIO_D(TRANSCONF(TRANSCODER_EDP));
- MMIO_D(PIPESTAT(PIPE_A));
- MMIO_D(PIPESTAT(PIPE_B));
- MMIO_D(PIPESTAT(PIPE_C));
- MMIO_D(PIPESTAT(_PIPE_EDP));
- MMIO_D(PIPE_FLIPCOUNT_G4X(PIPE_A));
- MMIO_D(PIPE_FLIPCOUNT_G4X(PIPE_B));
- MMIO_D(PIPE_FLIPCOUNT_G4X(PIPE_C));
- MMIO_D(PIPE_FLIPCOUNT_G4X(_PIPE_EDP));
- MMIO_D(PIPE_FRMCOUNT_G4X(PIPE_A));
- MMIO_D(PIPE_FRMCOUNT_G4X(PIPE_B));
- MMIO_D(PIPE_FRMCOUNT_G4X(PIPE_C));
- MMIO_D(PIPE_FRMCOUNT_G4X(_PIPE_EDP));
- MMIO_D(CURCNTR(PIPE_A));
- MMIO_D(CURCNTR(PIPE_B));
- MMIO_D(CURCNTR(PIPE_C));
- MMIO_D(CURPOS(PIPE_A));
- MMIO_D(CURPOS(PIPE_B));
- MMIO_D(CURPOS(PIPE_C));
- MMIO_D(CURBASE(PIPE_A));
- MMIO_D(CURBASE(PIPE_B));
- MMIO_D(CURBASE(PIPE_C));
- MMIO_D(CUR_FBC_CTL(PIPE_A));
- MMIO_D(CUR_FBC_CTL(PIPE_B));
- MMIO_D(CUR_FBC_CTL(PIPE_C));
+ MMIO_D(PIPEDSL(dev_priv, PIPE_A));
+ MMIO_D(PIPEDSL(dev_priv, PIPE_B));
+ MMIO_D(PIPEDSL(dev_priv, PIPE_C));
+ MMIO_D(PIPEDSL(dev_priv, _PIPE_EDP));
+ MMIO_D(TRANSCONF(dev_priv, TRANSCODER_A));
+ MMIO_D(TRANSCONF(dev_priv, TRANSCODER_B));
+ MMIO_D(TRANSCONF(dev_priv, TRANSCODER_C));
+ MMIO_D(TRANSCONF(dev_priv, TRANSCODER_EDP));
+ MMIO_D(PIPESTAT(dev_priv, PIPE_A));
+ MMIO_D(PIPESTAT(dev_priv, PIPE_B));
+ MMIO_D(PIPESTAT(dev_priv, PIPE_C));
+ MMIO_D(PIPESTAT(dev_priv, _PIPE_EDP));
+ MMIO_D(PIPE_FLIPCOUNT_G4X(dev_priv, PIPE_A));
+ MMIO_D(PIPE_FLIPCOUNT_G4X(dev_priv, PIPE_B));
+ MMIO_D(PIPE_FLIPCOUNT_G4X(dev_priv, PIPE_C));
+ MMIO_D(PIPE_FLIPCOUNT_G4X(dev_priv, _PIPE_EDP));
+ MMIO_D(PIPE_FRMCOUNT_G4X(dev_priv, PIPE_A));
+ MMIO_D(PIPE_FRMCOUNT_G4X(dev_priv, PIPE_B));
+ MMIO_D(PIPE_FRMCOUNT_G4X(dev_priv, PIPE_C));
+ MMIO_D(PIPE_FRMCOUNT_G4X(dev_priv, _PIPE_EDP));
+ MMIO_D(CURCNTR(dev_priv, PIPE_A));
+ MMIO_D(CURCNTR(dev_priv, PIPE_B));
+ MMIO_D(CURCNTR(dev_priv, PIPE_C));
+ MMIO_D(CURPOS(dev_priv, PIPE_A));
+ MMIO_D(CURPOS(dev_priv, PIPE_B));
+ MMIO_D(CURPOS(dev_priv, PIPE_C));
+ MMIO_D(CURBASE(dev_priv, PIPE_A));
+ MMIO_D(CURBASE(dev_priv, PIPE_B));
+ MMIO_D(CURBASE(dev_priv, PIPE_C));
+ MMIO_D(CUR_FBC_CTL(dev_priv, PIPE_A));
+ MMIO_D(CUR_FBC_CTL(dev_priv, PIPE_B));
+ MMIO_D(CUR_FBC_CTL(dev_priv, PIPE_C));
MMIO_D(_MMIO(0x700ac));
MMIO_D(_MMIO(0x710ac));
MMIO_D(_MMIO(0x720ac));
@@ -162,32 +165,32 @@ static int iterate_generic_mmio(struct intel_gvt_mmio_table_iter *iter)
MMIO_D(_MMIO(0x70094));
MMIO_D(_MMIO(0x70098));
MMIO_D(_MMIO(0x7009c));
- MMIO_D(DSPCNTR(PIPE_A));
- MMIO_D(DSPADDR(PIPE_A));
- MMIO_D(DSPSTRIDE(PIPE_A));
- MMIO_D(DSPPOS(PIPE_A));
- MMIO_D(DSPSIZE(PIPE_A));
- MMIO_D(DSPSURF(PIPE_A));
- MMIO_D(DSPOFFSET(PIPE_A));
- MMIO_D(DSPSURFLIVE(PIPE_A));
+ MMIO_D(DSPCNTR(dev_priv, PIPE_A));
+ MMIO_D(DSPADDR(dev_priv, PIPE_A));
+ MMIO_D(DSPSTRIDE(dev_priv, PIPE_A));
+ MMIO_D(DSPPOS(dev_priv, PIPE_A));
+ MMIO_D(DSPSIZE(dev_priv, PIPE_A));
+ MMIO_D(DSPSURF(dev_priv, PIPE_A));
+ MMIO_D(DSPOFFSET(dev_priv, PIPE_A));
+ MMIO_D(DSPSURFLIVE(dev_priv, PIPE_A));
MMIO_D(REG_50080(PIPE_A, PLANE_PRIMARY));
- MMIO_D(DSPCNTR(PIPE_B));
- MMIO_D(DSPADDR(PIPE_B));
- MMIO_D(DSPSTRIDE(PIPE_B));
- MMIO_D(DSPPOS(PIPE_B));
- MMIO_D(DSPSIZE(PIPE_B));
- MMIO_D(DSPSURF(PIPE_B));
- MMIO_D(DSPOFFSET(PIPE_B));
- MMIO_D(DSPSURFLIVE(PIPE_B));
+ MMIO_D(DSPCNTR(dev_priv, PIPE_B));
+ MMIO_D(DSPADDR(dev_priv, PIPE_B));
+ MMIO_D(DSPSTRIDE(dev_priv, PIPE_B));
+ MMIO_D(DSPPOS(dev_priv, PIPE_B));
+ MMIO_D(DSPSIZE(dev_priv, PIPE_B));
+ MMIO_D(DSPSURF(dev_priv, PIPE_B));
+ MMIO_D(DSPOFFSET(dev_priv, PIPE_B));
+ MMIO_D(DSPSURFLIVE(dev_priv, PIPE_B));
MMIO_D(REG_50080(PIPE_B, PLANE_PRIMARY));
- MMIO_D(DSPCNTR(PIPE_C));
- MMIO_D(DSPADDR(PIPE_C));
- MMIO_D(DSPSTRIDE(PIPE_C));
- MMIO_D(DSPPOS(PIPE_C));
- MMIO_D(DSPSIZE(PIPE_C));
- MMIO_D(DSPSURF(PIPE_C));
- MMIO_D(DSPOFFSET(PIPE_C));
- MMIO_D(DSPSURFLIVE(PIPE_C));
+ MMIO_D(DSPCNTR(dev_priv, PIPE_C));
+ MMIO_D(DSPADDR(dev_priv, PIPE_C));
+ MMIO_D(DSPSTRIDE(dev_priv, PIPE_C));
+ MMIO_D(DSPPOS(dev_priv, PIPE_C));
+ MMIO_D(DSPSIZE(dev_priv, PIPE_C));
+ MMIO_D(DSPSURF(dev_priv, PIPE_C));
+ MMIO_D(DSPOFFSET(dev_priv, PIPE_C));
+ MMIO_D(DSPSURFLIVE(dev_priv, PIPE_C));
MMIO_D(REG_50080(PIPE_C, PLANE_PRIMARY));
MMIO_D(SPRCTL(PIPE_A));
MMIO_D(SPRLINOFF(PIPE_A));
@@ -228,73 +231,73 @@ static int iterate_generic_mmio(struct intel_gvt_mmio_table_iter *iter)
MMIO_D(SPRSCALE(PIPE_C));
MMIO_D(SPRSURFLIVE(PIPE_C));
MMIO_D(REG_50080(PIPE_C, PLANE_SPRITE0));
- MMIO_D(TRANS_HTOTAL(TRANSCODER_A));
- MMIO_D(TRANS_HBLANK(TRANSCODER_A));
- MMIO_D(TRANS_HSYNC(TRANSCODER_A));
- MMIO_D(TRANS_VTOTAL(TRANSCODER_A));
- MMIO_D(TRANS_VBLANK(TRANSCODER_A));
- MMIO_D(TRANS_VSYNC(TRANSCODER_A));
- MMIO_D(BCLRPAT(TRANSCODER_A));
- MMIO_D(TRANS_VSYNCSHIFT(TRANSCODER_A));
- MMIO_D(PIPESRC(TRANSCODER_A));
- MMIO_D(TRANS_HTOTAL(TRANSCODER_B));
- MMIO_D(TRANS_HBLANK(TRANSCODER_B));
- MMIO_D(TRANS_HSYNC(TRANSCODER_B));
- MMIO_D(TRANS_VTOTAL(TRANSCODER_B));
- MMIO_D(TRANS_VBLANK(TRANSCODER_B));
- MMIO_D(TRANS_VSYNC(TRANSCODER_B));
- MMIO_D(BCLRPAT(TRANSCODER_B));
- MMIO_D(TRANS_VSYNCSHIFT(TRANSCODER_B));
- MMIO_D(PIPESRC(TRANSCODER_B));
- MMIO_D(TRANS_HTOTAL(TRANSCODER_C));
- MMIO_D(TRANS_HBLANK(TRANSCODER_C));
- MMIO_D(TRANS_HSYNC(TRANSCODER_C));
- MMIO_D(TRANS_VTOTAL(TRANSCODER_C));
- MMIO_D(TRANS_VBLANK(TRANSCODER_C));
- MMIO_D(TRANS_VSYNC(TRANSCODER_C));
- MMIO_D(BCLRPAT(TRANSCODER_C));
- MMIO_D(TRANS_VSYNCSHIFT(TRANSCODER_C));
- MMIO_D(PIPESRC(TRANSCODER_C));
- MMIO_D(TRANS_HTOTAL(TRANSCODER_EDP));
- MMIO_D(TRANS_HBLANK(TRANSCODER_EDP));
- MMIO_D(TRANS_HSYNC(TRANSCODER_EDP));
- MMIO_D(TRANS_VTOTAL(TRANSCODER_EDP));
- MMIO_D(TRANS_VBLANK(TRANSCODER_EDP));
- MMIO_D(TRANS_VSYNC(TRANSCODER_EDP));
- MMIO_D(BCLRPAT(TRANSCODER_EDP));
- MMIO_D(TRANS_VSYNCSHIFT(TRANSCODER_EDP));
- MMIO_D(PIPE_DATA_M1(TRANSCODER_A));
- MMIO_D(PIPE_DATA_N1(TRANSCODER_A));
- MMIO_D(PIPE_DATA_M2(TRANSCODER_A));
- MMIO_D(PIPE_DATA_N2(TRANSCODER_A));
- MMIO_D(PIPE_LINK_M1(TRANSCODER_A));
- MMIO_D(PIPE_LINK_N1(TRANSCODER_A));
- MMIO_D(PIPE_LINK_M2(TRANSCODER_A));
- MMIO_D(PIPE_LINK_N2(TRANSCODER_A));
- MMIO_D(PIPE_DATA_M1(TRANSCODER_B));
- MMIO_D(PIPE_DATA_N1(TRANSCODER_B));
- MMIO_D(PIPE_DATA_M2(TRANSCODER_B));
- MMIO_D(PIPE_DATA_N2(TRANSCODER_B));
- MMIO_D(PIPE_LINK_M1(TRANSCODER_B));
- MMIO_D(PIPE_LINK_N1(TRANSCODER_B));
- MMIO_D(PIPE_LINK_M2(TRANSCODER_B));
- MMIO_D(PIPE_LINK_N2(TRANSCODER_B));
- MMIO_D(PIPE_DATA_M1(TRANSCODER_C));
- MMIO_D(PIPE_DATA_N1(TRANSCODER_C));
- MMIO_D(PIPE_DATA_M2(TRANSCODER_C));
- MMIO_D(PIPE_DATA_N2(TRANSCODER_C));
- MMIO_D(PIPE_LINK_M1(TRANSCODER_C));
- MMIO_D(PIPE_LINK_N1(TRANSCODER_C));
- MMIO_D(PIPE_LINK_M2(TRANSCODER_C));
- MMIO_D(PIPE_LINK_N2(TRANSCODER_C));
- MMIO_D(PIPE_DATA_M1(TRANSCODER_EDP));
- MMIO_D(PIPE_DATA_N1(TRANSCODER_EDP));
- MMIO_D(PIPE_DATA_M2(TRANSCODER_EDP));
- MMIO_D(PIPE_DATA_N2(TRANSCODER_EDP));
- MMIO_D(PIPE_LINK_M1(TRANSCODER_EDP));
- MMIO_D(PIPE_LINK_N1(TRANSCODER_EDP));
- MMIO_D(PIPE_LINK_M2(TRANSCODER_EDP));
- MMIO_D(PIPE_LINK_N2(TRANSCODER_EDP));
+ MMIO_D(TRANS_HTOTAL(dev_priv, TRANSCODER_A));
+ MMIO_D(TRANS_HBLANK(dev_priv, TRANSCODER_A));
+ MMIO_D(TRANS_HSYNC(dev_priv, TRANSCODER_A));
+ MMIO_D(TRANS_VTOTAL(dev_priv, TRANSCODER_A));
+ MMIO_D(TRANS_VBLANK(dev_priv, TRANSCODER_A));
+ MMIO_D(TRANS_VSYNC(dev_priv, TRANSCODER_A));
+ MMIO_D(BCLRPAT(dev_priv, TRANSCODER_A));
+ MMIO_D(TRANS_VSYNCSHIFT(dev_priv, TRANSCODER_A));
+ MMIO_D(PIPESRC(dev_priv, TRANSCODER_A));
+ MMIO_D(TRANS_HTOTAL(dev_priv, TRANSCODER_B));
+ MMIO_D(TRANS_HBLANK(dev_priv, TRANSCODER_B));
+ MMIO_D(TRANS_HSYNC(dev_priv, TRANSCODER_B));
+ MMIO_D(TRANS_VTOTAL(dev_priv, TRANSCODER_B));
+ MMIO_D(TRANS_VBLANK(dev_priv, TRANSCODER_B));
+ MMIO_D(TRANS_VSYNC(dev_priv, TRANSCODER_B));
+ MMIO_D(BCLRPAT(dev_priv, TRANSCODER_B));
+ MMIO_D(TRANS_VSYNCSHIFT(dev_priv, TRANSCODER_B));
+ MMIO_D(PIPESRC(dev_priv, TRANSCODER_B));
+ MMIO_D(TRANS_HTOTAL(dev_priv, TRANSCODER_C));
+ MMIO_D(TRANS_HBLANK(dev_priv, TRANSCODER_C));
+ MMIO_D(TRANS_HSYNC(dev_priv, TRANSCODER_C));
+ MMIO_D(TRANS_VTOTAL(dev_priv, TRANSCODER_C));
+ MMIO_D(TRANS_VBLANK(dev_priv, TRANSCODER_C));
+ MMIO_D(TRANS_VSYNC(dev_priv, TRANSCODER_C));
+ MMIO_D(BCLRPAT(dev_priv, TRANSCODER_C));
+ MMIO_D(TRANS_VSYNCSHIFT(dev_priv, TRANSCODER_C));
+ MMIO_D(PIPESRC(dev_priv, TRANSCODER_C));
+ MMIO_D(TRANS_HTOTAL(dev_priv, TRANSCODER_EDP));
+ MMIO_D(TRANS_HBLANK(dev_priv, TRANSCODER_EDP));
+ MMIO_D(TRANS_HSYNC(dev_priv, TRANSCODER_EDP));
+ MMIO_D(TRANS_VTOTAL(dev_priv, TRANSCODER_EDP));
+ MMIO_D(TRANS_VBLANK(dev_priv, TRANSCODER_EDP));
+ MMIO_D(TRANS_VSYNC(dev_priv, TRANSCODER_EDP));
+ MMIO_D(BCLRPAT(dev_priv, TRANSCODER_EDP));
+ MMIO_D(TRANS_VSYNCSHIFT(dev_priv, TRANSCODER_EDP));
+ MMIO_D(PIPE_DATA_M1(dev_priv, TRANSCODER_A));
+ MMIO_D(PIPE_DATA_N1(dev_priv, TRANSCODER_A));
+ MMIO_D(PIPE_DATA_M2(dev_priv, TRANSCODER_A));
+ MMIO_D(PIPE_DATA_N2(dev_priv, TRANSCODER_A));
+ MMIO_D(PIPE_LINK_M1(dev_priv, TRANSCODER_A));
+ MMIO_D(PIPE_LINK_N1(dev_priv, TRANSCODER_A));
+ MMIO_D(PIPE_LINK_M2(dev_priv, TRANSCODER_A));
+ MMIO_D(PIPE_LINK_N2(dev_priv, TRANSCODER_A));
+ MMIO_D(PIPE_DATA_M1(dev_priv, TRANSCODER_B));
+ MMIO_D(PIPE_DATA_N1(dev_priv, TRANSCODER_B));
+ MMIO_D(PIPE_DATA_M2(dev_priv, TRANSCODER_B));
+ MMIO_D(PIPE_DATA_N2(dev_priv, TRANSCODER_B));
+ MMIO_D(PIPE_LINK_M1(dev_priv, TRANSCODER_B));
+ MMIO_D(PIPE_LINK_N1(dev_priv, TRANSCODER_B));
+ MMIO_D(PIPE_LINK_M2(dev_priv, TRANSCODER_B));
+ MMIO_D(PIPE_LINK_N2(dev_priv, TRANSCODER_B));
+ MMIO_D(PIPE_DATA_M1(dev_priv, TRANSCODER_C));
+ MMIO_D(PIPE_DATA_N1(dev_priv, TRANSCODER_C));
+ MMIO_D(PIPE_DATA_M2(dev_priv, TRANSCODER_C));
+ MMIO_D(PIPE_DATA_N2(dev_priv, TRANSCODER_C));
+ MMIO_D(PIPE_LINK_M1(dev_priv, TRANSCODER_C));
+ MMIO_D(PIPE_LINK_N1(dev_priv, TRANSCODER_C));
+ MMIO_D(PIPE_LINK_M2(dev_priv, TRANSCODER_C));
+ MMIO_D(PIPE_LINK_N2(dev_priv, TRANSCODER_C));
+ MMIO_D(PIPE_DATA_M1(dev_priv, TRANSCODER_EDP));
+ MMIO_D(PIPE_DATA_N1(dev_priv, TRANSCODER_EDP));
+ MMIO_D(PIPE_DATA_M2(dev_priv, TRANSCODER_EDP));
+ MMIO_D(PIPE_DATA_N2(dev_priv, TRANSCODER_EDP));
+ MMIO_D(PIPE_LINK_M1(dev_priv, TRANSCODER_EDP));
+ MMIO_D(PIPE_LINK_N1(dev_priv, TRANSCODER_EDP));
+ MMIO_D(PIPE_LINK_M2(dev_priv, TRANSCODER_EDP));
+ MMIO_D(PIPE_LINK_N2(dev_priv, TRANSCODER_EDP));
MMIO_D(PF_CTL(PIPE_A));
MMIO_D(PF_WIN_SZ(PIPE_A));
MMIO_D(PF_WIN_POS(PIPE_A));
@@ -503,18 +506,18 @@ static int iterate_generic_mmio(struct intel_gvt_mmio_table_iter *iter)
MMIO_D(GAMMA_MODE(PIPE_A));
MMIO_D(GAMMA_MODE(PIPE_B));
MMIO_D(GAMMA_MODE(PIPE_C));
- MMIO_D(TRANS_MULT(TRANSCODER_A));
- MMIO_D(TRANS_MULT(TRANSCODER_B));
- MMIO_D(TRANS_MULT(TRANSCODER_C));
- MMIO_D(HSW_TVIDEO_DIP_CTL(TRANSCODER_A));
- MMIO_D(HSW_TVIDEO_DIP_CTL(TRANSCODER_B));
- MMIO_D(HSW_TVIDEO_DIP_CTL(TRANSCODER_C));
+ MMIO_D(TRANS_MULT(dev_priv, TRANSCODER_A));
+ MMIO_D(TRANS_MULT(dev_priv, TRANSCODER_B));
+ MMIO_D(TRANS_MULT(dev_priv, TRANSCODER_C));
+ MMIO_D(HSW_TVIDEO_DIP_CTL(dev_priv, TRANSCODER_A));
+ MMIO_D(HSW_TVIDEO_DIP_CTL(dev_priv, TRANSCODER_B));
+ MMIO_D(HSW_TVIDEO_DIP_CTL(dev_priv, TRANSCODER_C));
MMIO_D(SFUSE_STRAP);
MMIO_D(SBI_ADDR);
MMIO_D(SBI_DATA);
MMIO_D(SBI_CTL_STAT);
MMIO_D(PIXCLK_GATE);
- MMIO_F(_MMIO(_DPA_AUX_CH_CTL), 6 * 4);
+ MMIO_F(DP_AUX_CH_CTL(AUX_CH_A), 6 * 4);
MMIO_D(DDI_BUF_CTL(PORT_A));
MMIO_D(DDI_BUF_CTL(PORT_B));
MMIO_D(DDI_BUF_CTL(PORT_C));
@@ -885,9 +888,9 @@ static int iterate_pre_skl_mmio(struct intel_gvt_mmio_table_iter *iter)
MMIO_D(FORCEWAKE_MT);
MMIO_D(PCH_ADPA);
- MMIO_F(_MMIO(_PCH_DPB_AUX_CH_CTL), 6 * 4);
- MMIO_F(_MMIO(_PCH_DPC_AUX_CH_CTL), 6 * 4);
- MMIO_F(_MMIO(_PCH_DPD_AUX_CH_CTL), 6 * 4);
+ MMIO_F(PCH_DP_AUX_CH_CTL(AUX_CH_B), 6 * 4);
+ MMIO_F(PCH_DP_AUX_CH_CTL(AUX_CH_C), 6 * 4);
+ MMIO_F(PCH_DP_AUX_CH_CTL(AUX_CH_D), 6 * 4);
MMIO_F(_MMIO(0x70440), 0xc);
MMIO_F(_MMIO(0x71440), 0xc);
@@ -1004,36 +1007,36 @@ static int iterate_skl_plus_mmio(struct intel_gvt_mmio_table_iter *iter)
MMIO_D(PLANE_NV12_BUF_CFG(PIPE_C, 1));
MMIO_D(PLANE_NV12_BUF_CFG(PIPE_C, 2));
MMIO_D(PLANE_NV12_BUF_CFG(PIPE_C, 3));
- MMIO_D(_MMIO(_REG_701C0(PIPE_A, 1)));
- MMIO_D(_MMIO(_REG_701C0(PIPE_A, 2)));
- MMIO_D(_MMIO(_REG_701C0(PIPE_A, 3)));
- MMIO_D(_MMIO(_REG_701C0(PIPE_A, 4)));
- MMIO_D(_MMIO(_REG_701C0(PIPE_B, 1)));
- MMIO_D(_MMIO(_REG_701C0(PIPE_B, 2)));
- MMIO_D(_MMIO(_REG_701C0(PIPE_B, 3)));
- MMIO_D(_MMIO(_REG_701C0(PIPE_B, 4)));
- MMIO_D(_MMIO(_REG_701C0(PIPE_C, 1)));
- MMIO_D(_MMIO(_REG_701C0(PIPE_C, 2)));
- MMIO_D(_MMIO(_REG_701C0(PIPE_C, 3)));
- MMIO_D(_MMIO(_REG_701C0(PIPE_C, 4)));
- MMIO_D(_MMIO(_REG_701C4(PIPE_A, 1)));
- MMIO_D(_MMIO(_REG_701C4(PIPE_A, 2)));
- MMIO_D(_MMIO(_REG_701C4(PIPE_A, 3)));
- MMIO_D(_MMIO(_REG_701C4(PIPE_A, 4)));
- MMIO_D(_MMIO(_REG_701C4(PIPE_B, 1)));
- MMIO_D(_MMIO(_REG_701C4(PIPE_B, 2)));
- MMIO_D(_MMIO(_REG_701C4(PIPE_B, 3)));
- MMIO_D(_MMIO(_REG_701C4(PIPE_B, 4)));
- MMIO_D(_MMIO(_REG_701C4(PIPE_C, 1)));
- MMIO_D(_MMIO(_REG_701C4(PIPE_C, 2)));
- MMIO_D(_MMIO(_REG_701C4(PIPE_C, 3)));
- MMIO_D(_MMIO(_REG_701C4(PIPE_C, 4)));
- MMIO_D(_MMIO(_PLANE_CTL_3_A));
- MMIO_D(_MMIO(_PLANE_CTL_3_B));
- MMIO_D(_MMIO(0x72380));
- MMIO_D(_MMIO(0x7239c));
- MMIO_D(_MMIO(_PLANE_SURF_3_A));
- MMIO_D(_MMIO(_PLANE_SURF_3_B));
+ MMIO_D(PLANE_AUX_DIST(PIPE_A, 0));
+ MMIO_D(PLANE_AUX_DIST(PIPE_A, 1));
+ MMIO_D(PLANE_AUX_DIST(PIPE_A, 2));
+ MMIO_D(PLANE_AUX_DIST(PIPE_A, 3));
+ MMIO_D(PLANE_AUX_DIST(PIPE_B, 0));
+ MMIO_D(PLANE_AUX_DIST(PIPE_B, 1));
+ MMIO_D(PLANE_AUX_DIST(PIPE_B, 2));
+ MMIO_D(PLANE_AUX_DIST(PIPE_B, 3));
+ MMIO_D(PLANE_AUX_DIST(PIPE_C, 0));
+ MMIO_D(PLANE_AUX_DIST(PIPE_C, 1));
+ MMIO_D(PLANE_AUX_DIST(PIPE_C, 2));
+ MMIO_D(PLANE_AUX_DIST(PIPE_C, 3));
+ MMIO_D(PLANE_AUX_OFFSET(PIPE_A, 0));
+ MMIO_D(PLANE_AUX_OFFSET(PIPE_A, 1));
+ MMIO_D(PLANE_AUX_OFFSET(PIPE_A, 2));
+ MMIO_D(PLANE_AUX_OFFSET(PIPE_A, 3));
+ MMIO_D(PLANE_AUX_OFFSET(PIPE_B, 0));
+ MMIO_D(PLANE_AUX_OFFSET(PIPE_B, 1));
+ MMIO_D(PLANE_AUX_OFFSET(PIPE_B, 2));
+ MMIO_D(PLANE_AUX_OFFSET(PIPE_B, 3));
+ MMIO_D(PLANE_AUX_OFFSET(PIPE_C, 0));
+ MMIO_D(PLANE_AUX_OFFSET(PIPE_C, 1));
+ MMIO_D(PLANE_AUX_OFFSET(PIPE_C, 2));
+ MMIO_D(PLANE_AUX_OFFSET(PIPE_C, 3));
+ MMIO_D(PLANE_CTL(PIPE_A, 2));
+ MMIO_D(PLANE_CTL(PIPE_B, 2));
+ MMIO_D(PLANE_CTL(PIPE_C, 2));
+ MMIO_D(PLANE_SURF(PIPE_A, 2));
+ MMIO_D(PLANE_SURF(PIPE_B, 2));
+ MMIO_D(PLANE_SURF(PIPE_C, 2));
MMIO_D(DMC_SSP_BASE);
MMIO_D(DMC_HTP_SKL);
MMIO_D(DMC_LAST_WRITE);
@@ -1073,15 +1076,15 @@ static int iterate_skl_plus_mmio(struct intel_gvt_mmio_table_iter *iter)
MMIO_D(_MMIO(0x70034));
MMIO_D(_MMIO(0x71034));
MMIO_D(_MMIO(0x72034));
- MMIO_D(_MMIO(_PLANE_KEYVAL_1(PIPE_A)));
- MMIO_D(_MMIO(_PLANE_KEYVAL_1(PIPE_B)));
- MMIO_D(_MMIO(_PLANE_KEYVAL_1(PIPE_C)));
- MMIO_D(_MMIO(_PLANE_KEYMAX_1(PIPE_A)));
- MMIO_D(_MMIO(_PLANE_KEYMAX_1(PIPE_B)));
- MMIO_D(_MMIO(_PLANE_KEYMAX_1(PIPE_C)));
- MMIO_D(_MMIO(_PLANE_KEYMSK_1(PIPE_A)));
- MMIO_D(_MMIO(_PLANE_KEYMSK_1(PIPE_B)));
- MMIO_D(_MMIO(_PLANE_KEYMSK_1(PIPE_C)));
+ MMIO_D(PLANE_KEYVAL(PIPE_A, 0));
+ MMIO_D(PLANE_KEYVAL(PIPE_B, 0));
+ MMIO_D(PLANE_KEYVAL(PIPE_C, 0));
+ MMIO_D(PLANE_KEYMAX(PIPE_A, 0));
+ MMIO_D(PLANE_KEYMAX(PIPE_B, 0));
+ MMIO_D(PLANE_KEYMAX(PIPE_C, 0));
+ MMIO_D(PLANE_KEYMSK(PIPE_A, 0));
+ MMIO_D(PLANE_KEYMSK(PIPE_B, 0));
+ MMIO_D(PLANE_KEYMSK(PIPE_C, 0));
MMIO_D(_MMIO(0x44500));
#define CSFE_CHICKEN1_REG(base) _MMIO((base) + 0xD4)
MMIO_RING_D(CSFE_CHICKEN1_REG);
@@ -1232,9 +1235,9 @@ static int iterate_bxt_mmio(struct intel_gvt_mmio_table_iter *iter)
MMIO_D(BXT_DSI_PLL_ENABLE);
MMIO_D(GEN9_CLKGATE_DIS_0);
MMIO_D(GEN9_CLKGATE_DIS_4);
- MMIO_D(HSW_TVIDEO_DIP_GCP(TRANSCODER_A));
- MMIO_D(HSW_TVIDEO_DIP_GCP(TRANSCODER_B));
- MMIO_D(HSW_TVIDEO_DIP_GCP(TRANSCODER_C));
+ MMIO_D(HSW_TVIDEO_DIP_GCP(dev_priv, TRANSCODER_A));
+ MMIO_D(HSW_TVIDEO_DIP_GCP(dev_priv, TRANSCODER_B));
+ MMIO_D(HSW_TVIDEO_DIP_GCP(dev_priv, TRANSCODER_C));
MMIO_D(RC6_CTX_BASE);
MMIO_D(GEN8_PUSHBUS_CONTROL);
MMIO_D(GEN8_PUSHBUS_ENABLE);
diff --git a/drivers/gpu/drm/i915/intel_pci_config.h b/drivers/gpu/drm/i915/intel_pci_config.h
index 23b8e519f333..ebe040828e20 100644
--- a/drivers/gpu/drm/i915/intel_pci_config.h
+++ b/drivers/gpu/drm/i915/intel_pci_config.h
@@ -31,7 +31,7 @@ static inline int intel_mmio_bar(int graphics_ver)
}
}
-/* BSM in include/drm/i915_drm.h */
+/* BSM in include/drm/intel/i915_drm.h */
#define MCHBAR_I915 0x44
#define MCHBAR_I965 0x48
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
index b00d6c280159..1784153f0cf8 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -5,8 +5,8 @@
#include <linux/component.h>
-#include <drm/i915_pxp_tee_interface.h>
-#include <drm/i915_component.h>
+#include <drm/intel/i915_pxp_tee_interface.h>
+#include <drm/intel/i915_component.h>
#include "gem/i915_gem_lmem.h"
#include "gt/intel_gt_print.h"
diff --git a/drivers/gpu/drm/i915/soc/intel_dram.c b/drivers/gpu/drm/i915/soc/intel_dram.c
index e3287f1de774..4aba47bccc63 100644
--- a/drivers/gpu/drm/i915/soc/intel_dram.c
+++ b/drivers/gpu/drm/i915/soc/intel_dram.c
@@ -43,101 +43,51 @@ static const char *intel_dram_type_str(enum intel_dram_type type)
#undef DRAM_TYPE_STR
-static void pnv_detect_mem_freq(struct drm_i915_private *dev_priv)
+static bool pnv_is_ddr3(struct drm_i915_private *i915)
+{
+ return intel_uncore_read(&i915->uncore, CSHRDDR3CTL) & CSHRDDR3CTL_DDR3;
+}
+
+static unsigned int pnv_mem_freq(struct drm_i915_private *dev_priv)
{
u32 tmp;
tmp = intel_uncore_read(&dev_priv->uncore, CLKCFG);
- switch (tmp & CLKCFG_FSB_MASK) {
- case CLKCFG_FSB_533:
- dev_priv->fsb_freq = 533; /* 133*4 */
- break;
- case CLKCFG_FSB_800:
- dev_priv->fsb_freq = 800; /* 200*4 */
- break;
- case CLKCFG_FSB_667:
- dev_priv->fsb_freq = 667; /* 167*4 */
- break;
- case CLKCFG_FSB_400:
- dev_priv->fsb_freq = 400; /* 100*4 */
- break;
- }
-
switch (tmp & CLKCFG_MEM_MASK) {
case CLKCFG_MEM_533:
- dev_priv->mem_freq = 533;
- break;
+ return 533333;
case CLKCFG_MEM_667:
- dev_priv->mem_freq = 667;
- break;
+ return 666667;
case CLKCFG_MEM_800:
- dev_priv->mem_freq = 800;
- break;
+ return 800000;
}
- /* detect pineview DDR3 setting */
- tmp = intel_uncore_read(&dev_priv->uncore, CSHRDDR3CTL);
- dev_priv->is_ddr3 = (tmp & CSHRDDR3CTL_DDR3) ? 1 : 0;
+ return 0;
}
-static void ilk_detect_mem_freq(struct drm_i915_private *dev_priv)
+static unsigned int ilk_mem_freq(struct drm_i915_private *dev_priv)
{
- u16 ddrpll, csipll;
+ u16 ddrpll;
ddrpll = intel_uncore_read16(&dev_priv->uncore, DDRMPLL1);
switch (ddrpll & 0xff) {
case 0xc:
- dev_priv->mem_freq = 800;
- break;
+ return 800000;
case 0x10:
- dev_priv->mem_freq = 1066;
- break;
+ return 1066667;
case 0x14:
- dev_priv->mem_freq = 1333;
- break;
+ return 1333333;
case 0x18:
- dev_priv->mem_freq = 1600;
- break;
+ return 1600000;
default:
drm_dbg(&dev_priv->drm, "unknown memory frequency 0x%02x\n",
ddrpll & 0xff);
- dev_priv->mem_freq = 0;
- break;
- }
-
- csipll = intel_uncore_read16(&dev_priv->uncore, CSIPLL0);
- switch (csipll & 0x3ff) {
- case 0x00c:
- dev_priv->fsb_freq = 3200;
- break;
- case 0x00e:
- dev_priv->fsb_freq = 3733;
- break;
- case 0x010:
- dev_priv->fsb_freq = 4266;
- break;
- case 0x012:
- dev_priv->fsb_freq = 4800;
- break;
- case 0x014:
- dev_priv->fsb_freq = 5333;
- break;
- case 0x016:
- dev_priv->fsb_freq = 5866;
- break;
- case 0x018:
- dev_priv->fsb_freq = 6400;
- break;
- default:
- drm_dbg(&dev_priv->drm, "unknown fsb frequency 0x%04x\n",
- csipll & 0x3ff);
- dev_priv->fsb_freq = 0;
- break;
+ return 0;
}
}
-static void chv_detect_mem_freq(struct drm_i915_private *i915)
+static unsigned int chv_mem_freq(struct drm_i915_private *i915)
{
u32 val;
@@ -147,15 +97,13 @@ static void chv_detect_mem_freq(struct drm_i915_private *i915)
switch ((val >> 2) & 0x7) {
case 3:
- i915->mem_freq = 2000;
- break;
+ return 2000000;
default:
- i915->mem_freq = 1600;
- break;
+ return 1600000;
}
}
-static void vlv_detect_mem_freq(struct drm_i915_private *i915)
+static unsigned int vlv_mem_freq(struct drm_i915_private *i915)
{
u32 val;
@@ -166,30 +114,125 @@ static void vlv_detect_mem_freq(struct drm_i915_private *i915)
switch ((val >> 6) & 3) {
case 0:
case 1:
- i915->mem_freq = 800;
- break;
+ return 800000;
case 2:
- i915->mem_freq = 1066;
- break;
+ return 1066667;
case 3:
- i915->mem_freq = 1333;
- break;
+ return 1333333;
}
+
+ return 0;
}
static void detect_mem_freq(struct drm_i915_private *i915)
{
if (IS_PINEVIEW(i915))
- pnv_detect_mem_freq(i915);
+ i915->mem_freq = pnv_mem_freq(i915);
else if (GRAPHICS_VER(i915) == 5)
- ilk_detect_mem_freq(i915);
+ i915->mem_freq = ilk_mem_freq(i915);
else if (IS_CHERRYVIEW(i915))
- chv_detect_mem_freq(i915);
+ i915->mem_freq = chv_mem_freq(i915);
else if (IS_VALLEYVIEW(i915))
- vlv_detect_mem_freq(i915);
+ i915->mem_freq = vlv_mem_freq(i915);
+
+ if (IS_PINEVIEW(i915))
+ i915->is_ddr3 = pnv_is_ddr3(i915);
if (i915->mem_freq)
- drm_dbg(&i915->drm, "DDR speed: %d MHz\n", i915->mem_freq);
+ drm_dbg(&i915->drm, "DDR speed: %d kHz\n", i915->mem_freq);
+}
+
+unsigned int i9xx_fsb_freq(struct drm_i915_private *i915)
+{
+ u32 fsb;
+
+ /*
+ * Note that this only reads the state of the FSB
+ * straps, not the actual FSB frequency. Some BIOSen
+ * let you configure each independently. Ideally we'd
+ * read out the actual FSB frequency but sadly we
+ * don't know which registers have that information,
+ * and all the relevant docs have gone to bit heaven :(
+ */
+ fsb = intel_uncore_read(&i915->uncore, CLKCFG) & CLKCFG_FSB_MASK;
+
+ if (IS_PINEVIEW(i915) || IS_MOBILE(i915)) {
+ switch (fsb) {
+ case CLKCFG_FSB_400:
+ return 400000;
+ case CLKCFG_FSB_533:
+ return 533333;
+ case CLKCFG_FSB_667:
+ return 666667;
+ case CLKCFG_FSB_800:
+ return 800000;
+ case CLKCFG_FSB_1067:
+ return 1066667;
+ case CLKCFG_FSB_1333:
+ return 1333333;
+ default:
+ MISSING_CASE(fsb);
+ return 1333333;
+ }
+ } else {
+ switch (fsb) {
+ case CLKCFG_FSB_400_ALT:
+ return 400000;
+ case CLKCFG_FSB_533:
+ return 533333;
+ case CLKCFG_FSB_667:
+ return 666667;
+ case CLKCFG_FSB_800:
+ return 800000;
+ case CLKCFG_FSB_1067_ALT:
+ return 1066667;
+ case CLKCFG_FSB_1333_ALT:
+ return 1333333;
+ case CLKCFG_FSB_1600_ALT:
+ return 1600000;
+ default:
+ MISSING_CASE(fsb);
+ return 1333333;
+ }
+ }
+}
+
+static unsigned int ilk_fsb_freq(struct drm_i915_private *dev_priv)
+{
+ u16 fsb;
+
+ fsb = intel_uncore_read16(&dev_priv->uncore, CSIPLL0) & 0x3ff;
+
+ switch (fsb) {
+ case 0x00c:
+ return 3200000;
+ case 0x00e:
+ return 3733333;
+ case 0x010:
+ return 4266667;
+ case 0x012:
+ return 4800000;
+ case 0x014:
+ return 5333333;
+ case 0x016:
+ return 5866667;
+ case 0x018:
+ return 6400000;
+ default:
+ drm_dbg(&dev_priv->drm, "unknown fsb frequency 0x%04x\n", fsb);
+ return 0;
+ }
+}
+
+static void detect_fsb_freq(struct drm_i915_private *i915)
+{
+ if (GRAPHICS_VER(i915) == 5)
+ i915->fsb_freq = ilk_fsb_freq(i915);
+ else if (GRAPHICS_VER(i915) == 3 || GRAPHICS_VER(i915) == 4)
+ i915->fsb_freq = i9xx_fsb_freq(i915);
+
+ if (i915->fsb_freq)
+ drm_dbg(&i915->drm, "FSB frequency: %d kHz\n", i915->fsb_freq);
}
static int intel_dimm_num_devices(const struct dram_dimm_info *dimm)
@@ -640,6 +683,10 @@ static int xelpdp_get_dram_info(struct drm_i915_private *i915)
case 5:
dram_info->type = INTEL_DRAM_LPDDR3;
break;
+ case 8:
+ drm_WARN_ON(&i915->drm, !IS_DGFX(i915));
+ dram_info->type = INTEL_DRAM_GDDR;
+ break;
default:
MISSING_CASE(val);
return -EINVAL;
@@ -657,6 +704,7 @@ void intel_dram_detect(struct drm_i915_private *i915)
struct dram_info *dram_info = &i915->dram_info;
int ret;
+ detect_fsb_freq(i915);
detect_mem_freq(i915);
if (GRAPHICS_VER(i915) < 9 || IS_DG2(i915) || !HAS_DISPLAY(i915))
diff --git a/drivers/gpu/drm/i915/soc/intel_dram.h b/drivers/gpu/drm/i915/soc/intel_dram.h
index 4ba13c13162c..a10136eda674 100644
--- a/drivers/gpu/drm/i915/soc/intel_dram.h
+++ b/drivers/gpu/drm/i915/soc/intel_dram.h
@@ -10,5 +10,6 @@ struct drm_i915_private;
void intel_dram_edram_detect(struct drm_i915_private *i915);
void intel_dram_detect(struct drm_i915_private *i915);
+unsigned int i9xx_fsb_freq(struct drm_i915_private *i915);
#endif /* __INTEL_DRAM_H__ */
diff --git a/drivers/gpu/drm/i915/soc/intel_gmch.c b/drivers/gpu/drm/i915/soc/intel_gmch.c
index 40874ebfb64c..734e9f2801ea 100644
--- a/drivers/gpu/drm/i915/soc/intel_gmch.c
+++ b/drivers/gpu/drm/i915/soc/intel_gmch.c
@@ -8,7 +8,7 @@
#include <linux/vgaarb.h>
#include <drm/drm_managed.h>
-#include <drm/i915_drm.h>
+#include <drm/intel/i915_drm.h>
#include "i915_drv.h"
#include "intel_gmch.h"
diff --git a/drivers/gpu/drm/i915/soc/intel_pch.c b/drivers/gpu/drm/i915/soc/intel_pch.c
index 3cad6dac06b0..542eea50093c 100644
--- a/drivers/gpu/drm/i915/soc/intel_pch.c
+++ b/drivers/gpu/drm/i915/soc/intel_pch.c
@@ -218,10 +218,10 @@ void intel_detect_pch(struct drm_i915_private *dev_priv)
if (DISPLAY_VER(dev_priv) >= 20) {
dev_priv->pch_type = PCH_LNL;
return;
- } else if (IS_METEORLAKE(dev_priv)) {
+ } else if (IS_BATTLEMAGE(dev_priv) || IS_METEORLAKE(dev_priv)) {
/*
* Both north display and south display are on the SoC die.
- * The real PCH is uninvolved in display.
+ * The real PCH (if it even exists) is uninvolved in display.
*/
dev_priv->pch_type = PCH_MTL;
return;
diff --git a/drivers/gpu/drm/imx/ipuv3/imx-ldb.c b/drivers/gpu/drm/imx/ipuv3/imx-ldb.c
index 71d70194fcbd..793dfb1a3ed0 100644
--- a/drivers/gpu/drm/imx/ipuv3/imx-ldb.c
+++ b/drivers/gpu/drm/imx/ipuv3/imx-ldb.c
@@ -72,7 +72,7 @@ struct imx_ldb_channel {
struct device_node *child;
struct i2c_adapter *ddc;
int chno;
- void *edid;
+ const struct drm_edid *drm_edid;
struct drm_display_mode mode;
int mode_valid;
u32 bus_format;
@@ -142,15 +142,15 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector)
if (num_modes > 0)
return num_modes;
- if (!imx_ldb_ch->edid && imx_ldb_ch->ddc)
- imx_ldb_ch->edid = drm_get_edid(connector, imx_ldb_ch->ddc);
-
- if (imx_ldb_ch->edid) {
- drm_connector_update_edid_property(connector,
- imx_ldb_ch->edid);
- num_modes = drm_add_edid_modes(connector, imx_ldb_ch->edid);
+ if (!imx_ldb_ch->drm_edid && imx_ldb_ch->ddc) {
+ imx_ldb_ch->drm_edid = drm_edid_read_ddc(connector,
+ imx_ldb_ch->ddc);
+ drm_edid_connector_update(connector, imx_ldb_ch->drm_edid);
}
+ if (imx_ldb_ch->drm_edid)
+ num_modes = drm_edid_connector_add_modes(connector);
+
if (imx_ldb_ch->mode_valid) {
struct drm_display_mode *mode;
@@ -553,7 +553,6 @@ static int imx_ldb_panel_ddc(struct device *dev,
struct imx_ldb_channel *channel, struct device_node *child)
{
struct device_node *ddc_node;
- const u8 *edidp;
int ret;
ddc_node = of_parse_phandle(child, "ddc-i2c-bus", 0);
@@ -567,6 +566,7 @@ static int imx_ldb_panel_ddc(struct device *dev,
}
if (!channel->ddc) {
+ const void *edidp;
int edid_len;
/* if no DDC available, fallback to hardcoded EDID */
@@ -574,8 +574,8 @@ static int imx_ldb_panel_ddc(struct device *dev,
edidp = of_get_property(child, "edid", &edid_len);
if (edidp) {
- channel->edid = kmemdup(edidp, edid_len, GFP_KERNEL);
- if (!channel->edid)
+ channel->drm_edid = drm_edid_alloc(edidp, edid_len);
+ if (!channel->drm_edid)
return -ENOMEM;
} else if (!channel->panel) {
/* fallback to display-timings node */
@@ -744,7 +744,7 @@ static void imx_ldb_remove(struct platform_device *pdev)
for (i = 0; i < 2; i++) {
struct imx_ldb_channel *channel = &imx_ldb->channel[i];
- kfree(channel->edid);
+ drm_edid_free(channel->drm_edid);
i2c_put_adapter(channel->ddc);
}
diff --git a/drivers/gpu/drm/imx/ipuv3/imx-tve.c b/drivers/gpu/drm/imx/ipuv3/imx-tve.c
index b49bddb85535..29f494bfff67 100644
--- a/drivers/gpu/drm/imx/ipuv3/imx-tve.c
+++ b/drivers/gpu/drm/imx/ipuv3/imx-tve.c
@@ -201,18 +201,16 @@ static int tve_setup_vga(struct imx_tve *tve)
static int imx_tve_connector_get_modes(struct drm_connector *connector)
{
struct imx_tve *tve = con_to_tve(connector);
- struct edid *edid;
- int ret = 0;
+ const struct drm_edid *drm_edid;
+ int ret;
if (!tve->ddc)
return 0;
- edid = drm_get_edid(connector, tve->ddc);
- if (edid) {
- drm_connector_update_edid_property(connector, edid);
- ret = drm_add_edid_modes(connector, edid);
- kfree(edid);
- }
+ drm_edid = drm_edid_read_ddc(connector, tve->ddc);
+ drm_edid_connector_update(connector, drm_edid);
+ ret = drm_edid_connector_add_modes(connector);
+ drm_edid_free(drm_edid);
return ret;
}
diff --git a/drivers/gpu/drm/imx/lcdc/imx-lcdc.c b/drivers/gpu/drm/imx/lcdc/imx-lcdc.c
index 43ddf3a9810b..36668455aee8 100644
--- a/drivers/gpu/drm/imx/lcdc/imx-lcdc.c
+++ b/drivers/gpu/drm/imx/lcdc/imx-lcdc.c
@@ -5,7 +5,7 @@
#include <drm/drm_bridge_connector.h>
#include <drm/drm_damage_helper.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_dma.h>
#include <drm/drm_fb_dma_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
@@ -501,7 +501,7 @@ static int imx_lcdc_probe(struct platform_device *pdev)
if (ret)
return dev_err_probe(dev, ret, "Cannot register device\n");
- drm_fbdev_generic_setup(drm, 0);
+ drm_fbdev_dma_setup(drm, 0);
return 0;
}
diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
index 0751235007a7..39fa291f43dd 100644
--- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
+++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
@@ -31,7 +31,7 @@
#include <drm/drm_encoder.h>
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_fb_dma_helper.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_dma.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_atomic_helper.h>
@@ -1399,7 +1399,7 @@ static int ingenic_drm_bind(struct device *dev, bool has_components)
goto err_clk_notifier_unregister;
}
- drm_fbdev_generic_setup(drm, 32);
+ drm_fbdev_dma_setup(drm, 32);
return 0;
diff --git a/drivers/gpu/drm/loongson/Kconfig b/drivers/gpu/drm/loongson/Kconfig
index 8e59753e532d..9ed463a76ae2 100644
--- a/drivers/gpu/drm/loongson/Kconfig
+++ b/drivers/gpu/drm/loongson/Kconfig
@@ -6,6 +6,7 @@ config DRM_LOONGSON
depends on LOONGARCH || MIPS || COMPILE_TEST
select DRM_KMS_HELPER
select DRM_TTM
+ select DRM_TTM_HELPER
select I2C
select I2C_ALGOBIT
help
diff --git a/drivers/gpu/drm/loongson/lsdc_drv.c b/drivers/gpu/drm/loongson/lsdc_drv.c
index d8ff60b46abe..adc7344d2f80 100644
--- a/drivers/gpu/drm/loongson/lsdc_drv.c
+++ b/drivers/gpu/drm/loongson/lsdc_drv.c
@@ -10,7 +10,7 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_ttm.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_ioctl.h>
#include <drm/drm_modeset_helper.h>
@@ -314,7 +314,7 @@ static int lsdc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (ret)
return ret;
- drm_fbdev_generic_setup(ddev, 32);
+ drm_fbdev_ttm_setup(ddev, 32);
return 0;
}
diff --git a/drivers/gpu/drm/loongson/lsdc_output_7a1000.c b/drivers/gpu/drm/loongson/lsdc_output_7a1000.c
index 6fc8dd1c7d9a..600ed4fb0884 100644
--- a/drivers/gpu/drm/loongson/lsdc_output_7a1000.c
+++ b/drivers/gpu/drm/loongson/lsdc_output_7a1000.c
@@ -40,16 +40,15 @@
static int ls7a1000_dpi_connector_get_modes(struct drm_connector *conn)
{
- unsigned int num = 0;
- struct edid *edid;
+ int num;
if (conn->ddc) {
- edid = drm_get_edid(conn, conn->ddc);
- if (edid) {
- drm_connector_update_edid_property(conn, edid);
- num = drm_add_edid_modes(conn, edid);
- kfree(edid);
- }
+ const struct drm_edid *drm_edid;
+
+ drm_edid = drm_edid_read(conn);
+ drm_edid_connector_update(conn, drm_edid);
+ num = drm_edid_connector_add_modes(conn);
+ drm_edid_free(drm_edid);
return num;
}
diff --git a/drivers/gpu/drm/loongson/lsdc_output_7a2000.c b/drivers/gpu/drm/loongson/lsdc_output_7a2000.c
index ce3dabec887e..2bd797a9b9ff 100644
--- a/drivers/gpu/drm/loongson/lsdc_output_7a2000.c
+++ b/drivers/gpu/drm/loongson/lsdc_output_7a2000.c
@@ -44,16 +44,15 @@
static int ls7a2000_connector_get_modes(struct drm_connector *connector)
{
- unsigned int num = 0;
- struct edid *edid;
+ int num;
if (connector->ddc) {
- edid = drm_get_edid(connector, connector->ddc);
- if (edid) {
- drm_connector_update_edid_property(connector, edid);
- num = drm_add_edid_modes(connector, edid);
- kfree(edid);
- }
+ const struct drm_edid *drm_edid;
+
+ drm_edid = drm_edid_read(connector);
+ drm_edid_connector_update(connector, drm_edid);
+ num = drm_edid_connector_add_modes(connector);
+ drm_edid_free(drm_edid);
return num;
}
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index b5f605751b0a..c0aa3e4e2219 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -15,7 +15,7 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_dma.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_gem.h>
#include <drm/drm_gem_framebuffer_helper.h>
@@ -644,7 +644,7 @@ static int mtk_drm_bind(struct device *dev)
if (ret < 0)
goto err_deinit;
- drm_fbdev_generic_setup(drm, 32);
+ drm_fbdev_dma_setup(drm, 32);
return 0;
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 6e1cca97a654..0a90fe448d14 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1208,22 +1208,11 @@ mtk_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
const struct drm_display_mode *mode)
{
struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
- struct drm_bridge *next_bridge;
dev_dbg(hdmi->dev, "xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
mode->hdisplay, mode->vdisplay, drm_mode_vrefresh(mode),
!!(mode->flags & DRM_MODE_FLAG_INTERLACE), mode->clock * 1000);
- next_bridge = drm_bridge_get_next_bridge(&hdmi->bridge);
- if (next_bridge) {
- struct drm_display_mode adjusted_mode;
-
- drm_mode_init(&adjusted_mode, mode);
- if (!drm_bridge_chain_mode_fixup(next_bridge, mode,
- &adjusted_mode))
- return MODE_BAD;
- }
-
if (hdmi->conf) {
if (hdmi->conf->cea_modes_only && !drm_match_cea_mode(mode))
return MODE_BAD;
diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c
index 815dfe30492b..b43ac61201f3 100644
--- a/drivers/gpu/drm/meson/meson_plane.c
+++ b/drivers/gpu/drm/meson/meson_plane.c
@@ -534,6 +534,7 @@ int meson_plane_create(struct meson_drm *priv)
struct meson_plane *meson_plane;
struct drm_plane *plane;
const uint64_t *format_modifiers = format_modifiers_default;
+ int ret;
meson_plane = devm_kzalloc(priv->drm->dev, sizeof(*meson_plane),
GFP_KERNEL);
@@ -548,12 +549,16 @@ int meson_plane_create(struct meson_drm *priv)
else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
format_modifiers = format_modifiers_afbc_g12a;
- drm_universal_plane_init(priv->drm, plane, 0xFF,
- &meson_plane_funcs,
- supported_drm_formats,
- ARRAY_SIZE(supported_drm_formats),
- format_modifiers,
- DRM_PLANE_TYPE_PRIMARY, "meson_primary_plane");
+ ret = drm_universal_plane_init(priv->drm, plane, 0xFF,
+ &meson_plane_funcs,
+ supported_drm_formats,
+ ARRAY_SIZE(supported_drm_formats),
+ format_modifiers,
+ DRM_PLANE_TYPE_PRIMARY, "meson_primary_plane");
+ if (ret) {
+ devm_kfree(priv->drm->dev, meson_plane);
+ return ret;
+ }
drm_plane_helper_add(plane, &meson_plane_helper_funcs);
diff --git a/drivers/gpu/drm/mgag200/Kconfig b/drivers/gpu/drm/mgag200/Kconfig
index 5e4d48df4854..3096944a8f0a 100644
--- a/drivers/gpu/drm/mgag200/Kconfig
+++ b/drivers/gpu/drm/mgag200/Kconfig
@@ -12,14 +12,12 @@ config DRM_MGAG200
of the modesetting userspace driver, and a version of mga driver
that will fail on KMS enabled devices.
-config DRM_MGAG200_IOBURST_WORKAROUND
- bool "Disable buffer caching"
- depends on DRM_MGAG200 && PREEMPT_RT && X86
+config DRM_MGAG200_DISABLE_WRITECOMBINE
+ bool "Disable Write Combine mapping of VRAM"
+ depends on DRM_MGAG200 && PREEMPT_RT
help
- Enable a workaround to avoid I/O bursts within the mgag200 driver at
- the expense of overall display performance.
- It restores the <v5.10 behavior, by mapping the framebuffer in system
- RAM as Write-Combining, and flushing the cache after each write.
- This is only useful on x86_64 if you want to run processes with
- deterministic latency.
- If unsure, say N.
+ The VRAM of the G200 is mapped with Write-Combine to improve
+ performances. This can interfere with real-time tasks; even if they
+ are running on other CPU cores than the graphics output.
+ Enable this option only if you run realtime tasks on a server with a
+ Matrox G200. \ No newline at end of file
diff --git a/drivers/gpu/drm/mgag200/Makefile b/drivers/gpu/drm/mgag200/Makefile
index 182e224c460d..d1b25f9f6586 100644
--- a/drivers/gpu/drm/mgag200/Makefile
+++ b/drivers/gpu/drm/mgag200/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
mgag200-y := \
mgag200_bmc.o \
+ mgag200_ddc.o \
mgag200_drv.o \
mgag200_g200.o \
mgag200_g200eh.o \
@@ -10,7 +11,7 @@ mgag200-y := \
mgag200_g200ew3.o \
mgag200_g200se.o \
mgag200_g200wb.o \
- mgag200_i2c.o \
- mgag200_mode.o
+ mgag200_mode.o \
+ mgag200_vga.o
obj-$(CONFIG_DRM_MGAG200) += mgag200.o
diff --git a/drivers/gpu/drm/mgag200/mgag200_bmc.c b/drivers/gpu/drm/mgag200/mgag200_bmc.c
index 2ba2e3c5086a..23ef85aa7e37 100644
--- a/drivers/gpu/drm/mgag200/mgag200_bmc.c
+++ b/drivers/gpu/drm/mgag200/mgag200_bmc.c
@@ -2,8 +2,18 @@
#include <linux/delay.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_managed.h>
+#include <drm/drm_probe_helper.h>
+
#include "mgag200_drv.h"
+static struct mgag200_bmc_connector *to_mgag200_bmc_connector(struct drm_connector *connector)
+{
+ return container_of(connector, struct mgag200_bmc_connector, base);
+}
+
void mgag200_bmc_disable_vidrst(struct mga_device *mdev)
{
u8 tmp;
@@ -97,3 +107,100 @@ void mgag200_bmc_enable_vidrst(struct mga_device *mdev)
tmp &= ~0x10;
WREG_DAC(MGA1064_GEN_IO_DATA, tmp);
}
+
+static const struct drm_encoder_funcs mgag200_bmc_encoder_funcs = {
+ .destroy = drm_encoder_cleanup,
+};
+
+static int mgag200_bmc_connector_helper_detect_ctx(struct drm_connector *connector,
+ struct drm_modeset_acquire_ctx *ctx,
+ bool force)
+{
+ struct mgag200_bmc_connector *bmc_connector = to_mgag200_bmc_connector(connector);
+ struct drm_connector *physical_connector = bmc_connector->physical_connector;
+
+ /*
+ * Most user-space compositors cannot handle more than one connected
+ * connector per CRTC. Hence, we only mark the BMC as connected if the
+ * physical connector is disconnected. If the physical connector's status
+ * is connected or unknown, the BMC remains disconnected. This has no
+ * effect on the output of the BMC.
+ *
+ * FIXME: Remove this logic once user-space compositors can handle more
+ * than one connector per CRTC. The BMC should always be connected.
+ */
+
+ if (physical_connector && physical_connector->status == connector_status_disconnected)
+ return connector_status_connected;
+
+ return connector_status_disconnected;
+}
+
+static int mgag200_bmc_connector_helper_get_modes(struct drm_connector *connector)
+{
+ struct drm_device *dev = connector->dev;
+ struct mga_device *mdev = to_mga_device(dev);
+ const struct mgag200_device_info *minfo = mdev->info;
+
+ return drm_add_modes_noedid(connector, minfo->max_hdisplay, minfo->max_vdisplay);
+}
+
+static const struct drm_connector_helper_funcs mgag200_bmc_connector_helper_funcs = {
+ .get_modes = mgag200_bmc_connector_helper_get_modes,
+ .detect_ctx = mgag200_bmc_connector_helper_detect_ctx,
+};
+
+static const struct drm_connector_funcs mgag200_bmc_connector_funcs = {
+ .reset = drm_atomic_helper_connector_reset,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .destroy = drm_connector_cleanup,
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static int mgag200_bmc_connector_init(struct drm_device *dev,
+ struct mgag200_bmc_connector *bmc_connector,
+ struct drm_connector *physical_connector)
+{
+ struct drm_connector *connector = &bmc_connector->base;
+ int ret;
+
+ ret = drm_connector_init(dev, connector, &mgag200_bmc_connector_funcs,
+ DRM_MODE_CONNECTOR_VIRTUAL);
+ if (ret)
+ return ret;
+ drm_connector_helper_add(connector, &mgag200_bmc_connector_helper_funcs);
+
+ bmc_connector->physical_connector = physical_connector;
+
+ return 0;
+}
+
+int mgag200_bmc_output_init(struct mga_device *mdev, struct drm_connector *physical_connector)
+{
+ struct drm_device *dev = &mdev->base;
+ struct drm_crtc *crtc = &mdev->crtc;
+ struct drm_encoder *encoder;
+ struct mgag200_bmc_connector *bmc_connector;
+ struct drm_connector *connector;
+ int ret;
+
+ encoder = &mdev->output.bmc.encoder;
+ ret = drm_encoder_init(dev, encoder, &mgag200_bmc_encoder_funcs,
+ DRM_MODE_ENCODER_VIRTUAL, NULL);
+ if (ret)
+ return ret;
+ encoder->possible_crtcs = drm_crtc_mask(crtc);
+
+ bmc_connector = &mdev->output.bmc.bmc_connector;
+ ret = mgag200_bmc_connector_init(dev, bmc_connector, physical_connector);
+ if (ret)
+ return ret;
+ connector = &bmc_connector->base;
+
+ ret = drm_connector_attach_encoder(connector, encoder);
+ if (ret)
+ return ret;
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/mgag200/mgag200_ddc.c b/drivers/gpu/drm/mgag200/mgag200_ddc.c
new file mode 100644
index 000000000000..6d81ea8931e8
--- /dev/null
+++ b/drivers/gpu/drm/mgag200/mgag200_ddc.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ */
+/*
+ * Authors: Dave Airlie <airlied@redhat.com>
+ */
+
+#include <linux/export.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/i2c.h>
+#include <linux/pci.h>
+
+#include <drm/drm_managed.h>
+
+#include "mgag200_ddc.h"
+#include "mgag200_drv.h"
+
+struct mgag200_ddc {
+ struct mga_device *mdev;
+
+ int data;
+ int clock;
+
+ struct i2c_algo_bit_data bit;
+ struct i2c_adapter adapter;
+};
+
+static int mga_i2c_read_gpio(struct mga_device *mdev)
+{
+ WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA);
+ return RREG8(DAC_DATA);
+}
+
+static void mga_i2c_set_gpio(struct mga_device *mdev, int mask, int val)
+{
+ int tmp;
+
+ WREG8(DAC_INDEX, MGA1064_GEN_IO_CTL);
+ tmp = (RREG8(DAC_DATA) & mask) | val;
+ WREG_DAC(MGA1064_GEN_IO_CTL, tmp);
+ WREG_DAC(MGA1064_GEN_IO_DATA, 0);
+}
+
+static inline void mga_i2c_set(struct mga_device *mdev, int mask, int state)
+{
+ if (state)
+ state = 0;
+ else
+ state = mask;
+ mga_i2c_set_gpio(mdev, ~mask, state);
+}
+
+static void mgag200_ddc_algo_bit_data_setsda(void *data, int state)
+{
+ struct mgag200_ddc *ddc = data;
+
+ mga_i2c_set(ddc->mdev, ddc->data, state);
+}
+
+static void mgag200_ddc_algo_bit_data_setscl(void *data, int state)
+{
+ struct mgag200_ddc *ddc = data;
+
+ mga_i2c_set(ddc->mdev, ddc->clock, state);
+}
+
+static int mgag200_ddc_algo_bit_data_getsda(void *data)
+{
+ struct mgag200_ddc *ddc = data;
+
+ return (mga_i2c_read_gpio(ddc->mdev) & ddc->data) ? 1 : 0;
+}
+
+static int mgag200_ddc_algo_bit_data_getscl(void *data)
+{
+ struct mgag200_ddc *ddc = data;
+
+ return (mga_i2c_read_gpio(ddc->mdev) & ddc->clock) ? 1 : 0;
+}
+
+static int mgag200_ddc_algo_bit_data_pre_xfer(struct i2c_adapter *adapter)
+{
+ struct mgag200_ddc *ddc = i2c_get_adapdata(adapter);
+ struct mga_device *mdev = ddc->mdev;
+
+ /*
+ * Protect access to I/O registers from concurrent modesetting
+ * by acquiring the I/O-register lock.
+ */
+ mutex_lock(&mdev->rmmio_lock);
+
+ return 0;
+}
+
+static void mgag200_ddc_algo_bit_data_post_xfer(struct i2c_adapter *adapter)
+{
+ struct mgag200_ddc *ddc = i2c_get_adapdata(adapter);
+ struct mga_device *mdev = ddc->mdev;
+
+ mutex_unlock(&mdev->rmmio_lock);
+}
+
+static void mgag200_ddc_release(struct drm_device *dev, void *res)
+{
+ struct mgag200_ddc *ddc = res;
+
+ i2c_del_adapter(&ddc->adapter);
+}
+
+struct i2c_adapter *mgag200_ddc_create(struct mga_device *mdev)
+{
+ struct drm_device *dev = &mdev->base;
+ const struct mgag200_device_info *info = mdev->info;
+ struct mgag200_ddc *ddc;
+ struct i2c_algo_bit_data *bit;
+ struct i2c_adapter *adapter;
+ int ret;
+
+ ddc = drmm_kzalloc(dev, sizeof(*ddc), GFP_KERNEL);
+ if (!ddc)
+ return ERR_PTR(-ENOMEM);
+
+ WREG_DAC(MGA1064_GEN_IO_CTL2, 1);
+ WREG_DAC(MGA1064_GEN_IO_DATA, 0xff);
+ WREG_DAC(MGA1064_GEN_IO_CTL, 0);
+
+ ddc->mdev = mdev;
+ ddc->data = BIT(info->i2c.data_bit);
+ ddc->clock = BIT(info->i2c.clock_bit);
+
+ bit = &ddc->bit;
+ bit->data = ddc;
+ bit->setsda = mgag200_ddc_algo_bit_data_setsda;
+ bit->setscl = mgag200_ddc_algo_bit_data_setscl;
+ bit->getsda = mgag200_ddc_algo_bit_data_getsda;
+ bit->getscl = mgag200_ddc_algo_bit_data_getscl;
+ bit->pre_xfer = mgag200_ddc_algo_bit_data_pre_xfer;
+ bit->post_xfer = mgag200_ddc_algo_bit_data_post_xfer;
+ bit->udelay = 10;
+ bit->timeout = usecs_to_jiffies(2200);
+
+ adapter = &ddc->adapter;
+ adapter->owner = THIS_MODULE;
+ adapter->algo_data = bit;
+ adapter->dev.parent = dev->dev;
+ snprintf(adapter->name, sizeof(adapter->name), "Matrox DDC bus");
+ i2c_set_adapdata(adapter, ddc);
+
+ ret = i2c_bit_add_bus(adapter);
+ if (ret)
+ return ERR_PTR(ret);
+
+ ret = drmm_add_action_or_reset(dev, mgag200_ddc_release, ddc);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return adapter;
+}
diff --git a/drivers/gpu/drm/mgag200/mgag200_ddc.h b/drivers/gpu/drm/mgag200/mgag200_ddc.h
new file mode 100644
index 000000000000..fa21d197cc78
--- /dev/null
+++ b/drivers/gpu/drm/mgag200/mgag200_ddc.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __MGAG200_DDC_H__
+#define __MGAG200_DDC_H__
+
+struct i2c_adapter;
+struct mga_device;
+
+struct i2c_adapter *mgag200_ddc_create(struct mga_device *mdev);
+
+#endif
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
index 573dbe256aa8..62080cf0f2da 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -12,7 +12,7 @@
#include <drm/drm_aperture.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_shmem.h>
#include <drm/drm_file.h>
#include <drm/drm_ioctl.h>
#include <drm/drm_managed.h>
@@ -84,20 +84,6 @@ resource_size_t mgag200_probe_vram(void __iomem *mem, resource_size_t size)
return offset - 65536;
}
-#if defined(CONFIG_DRM_MGAG200_IOBURST_WORKAROUND)
-static struct drm_gem_object *mgag200_create_object(struct drm_device *dev, size_t size)
-{
- struct drm_gem_shmem_object *shmem;
-
- shmem = kzalloc(sizeof(*shmem), GFP_KERNEL);
- if (!shmem)
- return NULL;
-
- shmem->map_wc = true;
- return &shmem->base;
-}
-#endif
-
/*
* DRM driver
*/
@@ -113,9 +99,6 @@ static const struct drm_driver mgag200_driver = {
.major = DRIVER_MAJOR,
.minor = DRIVER_MINOR,
.patchlevel = DRIVER_PATCHLEVEL,
-#if defined(CONFIG_DRM_MGAG200_IOBURST_WORKAROUND)
- .gem_create_object = mgag200_create_object,
-#endif
DRM_GEM_SHMEM_DRIVER_OPS,
};
@@ -163,12 +146,18 @@ int mgag200_device_preinit(struct mga_device *mdev)
}
mdev->vram_res = res;
+#if defined(CONFIG_DRM_MGAG200_DISABLE_WRITECOMBINE)
+ mdev->vram = devm_ioremap(dev->dev, res->start, resource_size(res));
+ if (!mdev->vram)
+ return -ENOMEM;
+#else
mdev->vram = devm_ioremap_wc(dev->dev, res->start, resource_size(res));
if (!mdev->vram)
return -ENOMEM;
/* Don't fail on errors, but performance might be reduced. */
devm_arch_phys_wc_add(dev->dev, res->start, resource_size(res));
+#endif
return 0;
}
@@ -285,7 +274,7 @@ mgag200_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
* FIXME: A 24-bit color depth does not work with 24 bpp on
* G200ER. Force 32 bpp.
*/
- drm_fbdev_generic_setup(dev, 32);
+ drm_fbdev_shmem_setup(dev, 32);
return 0;
}
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index 58a0e62eaf18..7f7dfbd0f013 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -10,9 +10,6 @@
#ifndef __MGAG200_DRV_H__
#define __MGAG200_DRV_H__
-#include <linux/i2c-algo-bit.h>
-#include <linux/i2c.h>
-
#include <video/vga.h>
#include <drm/drm_connector.h>
@@ -189,11 +186,9 @@ static inline struct mgag200_crtc_state *to_mgag200_crtc_state(struct drm_crtc_s
return container_of(base, struct mgag200_crtc_state, base);
}
-struct mga_i2c_chan {
- struct i2c_adapter adapter;
- struct drm_device *dev;
- struct i2c_algo_bit_data bit;
- int data, clock;
+struct mgag200_bmc_connector {
+ struct drm_connector base;
+ struct drm_connector *physical_connector;
};
enum mga_type {
@@ -293,9 +288,16 @@ struct mga_device {
struct drm_plane primary_plane;
struct drm_crtc crtc;
- struct drm_encoder encoder;
- struct mga_i2c_chan i2c;
- struct drm_connector connector;
+ struct {
+ struct {
+ struct drm_encoder encoder;
+ struct drm_connector connector;
+ } vga;
+ struct {
+ struct drm_encoder encoder;
+ struct mgag200_bmc_connector bmc_connector;
+ } bmc;
+ } output;
};
static inline struct mga_device *to_mga_device(struct drm_device *dev)
@@ -428,32 +430,18 @@ void mgag200_crtc_atomic_destroy_state(struct drm_crtc *crtc, struct drm_crtc_st
.atomic_duplicate_state = mgag200_crtc_atomic_duplicate_state, \
.atomic_destroy_state = mgag200_crtc_atomic_destroy_state
-#define MGAG200_DAC_ENCODER_FUNCS \
- .destroy = drm_encoder_cleanup
-
-int mgag200_vga_connector_helper_get_modes(struct drm_connector *connector);
-
-#define MGAG200_VGA_CONNECTOR_HELPER_FUNCS \
- .get_modes = mgag200_vga_connector_helper_get_modes
-
-#define MGAG200_VGA_CONNECTOR_FUNCS \
- .reset = drm_atomic_helper_connector_reset, \
- .fill_modes = drm_helper_probe_single_connector_modes, \
- .destroy = drm_connector_cleanup, \
- .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, \
- .atomic_destroy_state = drm_atomic_helper_connector_destroy_state
-
void mgag200_set_mode_regs(struct mga_device *mdev, const struct drm_display_mode *mode);
void mgag200_set_format_regs(struct mga_device *mdev, const struct drm_format_info *format);
void mgag200_enable_display(struct mga_device *mdev);
void mgag200_init_registers(struct mga_device *mdev);
int mgag200_mode_config_init(struct mga_device *mdev, resource_size_t vram_available);
+/* mgag200_vga.c */
+int mgag200_vga_output_init(struct mga_device *mdev);
+
/* mgag200_bmc.c */
void mgag200_bmc_disable_vidrst(struct mga_device *mdev);
void mgag200_bmc_enable_vidrst(struct mga_device *mdev);
-
- /* mgag200_i2c.c */
-int mgag200_i2c_init(struct mga_device *mdev, struct mga_i2c_chan *i2c);
+int mgag200_bmc_output_init(struct mga_device *mdev, struct drm_connector *physical_connector);
#endif /* __MGAG200_DRV_H__ */
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200.c b/drivers/gpu/drm/mgag200/mgag200_g200.c
index bf5d7fe525a3..f874e2949840 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200.c
@@ -183,26 +183,11 @@ static const struct drm_crtc_funcs mgag200_g200_crtc_funcs = {
MGAG200_CRTC_FUNCS,
};
-static const struct drm_encoder_funcs mgag200_g200_dac_encoder_funcs = {
- MGAG200_DAC_ENCODER_FUNCS,
-};
-
-static const struct drm_connector_helper_funcs mgag200_g200_vga_connector_helper_funcs = {
- MGAG200_VGA_CONNECTOR_HELPER_FUNCS,
-};
-
-static const struct drm_connector_funcs mgag200_g200_vga_connector_funcs = {
- MGAG200_VGA_CONNECTOR_FUNCS,
-};
-
static int mgag200_g200_pipeline_init(struct mga_device *mdev)
{
struct drm_device *dev = &mdev->base;
struct drm_plane *primary_plane = &mdev->primary_plane;
struct drm_crtc *crtc = &mdev->crtc;
- struct drm_encoder *encoder = &mdev->encoder;
- struct mga_i2c_chan *i2c = &mdev->i2c;
- struct drm_connector *connector = &mdev->connector;
int ret;
ret = drm_universal_plane_init(dev, primary_plane, 0,
@@ -230,35 +215,9 @@ static int mgag200_g200_pipeline_init(struct mga_device *mdev)
drm_mode_crtc_set_gamma_size(crtc, MGAG200_LUT_SIZE);
drm_crtc_enable_color_mgmt(crtc, 0, false, MGAG200_LUT_SIZE);
- encoder->possible_crtcs = drm_crtc_mask(crtc);
- ret = drm_encoder_init(dev, encoder, &mgag200_g200_dac_encoder_funcs,
- DRM_MODE_ENCODER_DAC, NULL);
- if (ret) {
- drm_err(dev, "drm_encoder_init() failed: %d\n", ret);
- return ret;
- }
-
- ret = mgag200_i2c_init(mdev, i2c);
- if (ret) {
- drm_err(dev, "failed to add DDC bus: %d\n", ret);
- return ret;
- }
-
- ret = drm_connector_init_with_ddc(dev, connector,
- &mgag200_g200_vga_connector_funcs,
- DRM_MODE_CONNECTOR_VGA,
- &i2c->adapter);
- if (ret) {
- drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret);
- return ret;
- }
- drm_connector_helper_add(connector, &mgag200_g200_vga_connector_helper_funcs);
-
- ret = drm_connector_attach_encoder(connector, encoder);
- if (ret) {
- drm_err(dev, "drm_connector_attach_encoder() failed: %d\n", ret);
+ ret = mgag200_vga_output_init(mdev);
+ if (ret)
return ret;
- }
return 0;
}
@@ -442,6 +401,7 @@ struct mga_device *mgag200_g200_device_create(struct pci_dev *pdev, const struct
return ERR_PTR(ret);
drm_mode_config_reset(dev);
+ drm_kms_helper_poll_init(dev);
return mdev;
}
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200eh.c b/drivers/gpu/drm/mgag200/mgag200_g200eh.c
index fad62453a91d..52bf49ead5c5 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200eh.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200eh.c
@@ -182,26 +182,11 @@ static const struct drm_crtc_funcs mgag200_g200eh_crtc_funcs = {
MGAG200_CRTC_FUNCS,
};
-static const struct drm_encoder_funcs mgag200_g200eh_dac_encoder_funcs = {
- MGAG200_DAC_ENCODER_FUNCS,
-};
-
-static const struct drm_connector_helper_funcs mgag200_g200eh_vga_connector_helper_funcs = {
- MGAG200_VGA_CONNECTOR_HELPER_FUNCS,
-};
-
-static const struct drm_connector_funcs mgag200_g200eh_vga_connector_funcs = {
- MGAG200_VGA_CONNECTOR_FUNCS,
-};
-
static int mgag200_g200eh_pipeline_init(struct mga_device *mdev)
{
struct drm_device *dev = &mdev->base;
struct drm_plane *primary_plane = &mdev->primary_plane;
struct drm_crtc *crtc = &mdev->crtc;
- struct drm_encoder *encoder = &mdev->encoder;
- struct mga_i2c_chan *i2c = &mdev->i2c;
- struct drm_connector *connector = &mdev->connector;
int ret;
ret = drm_universal_plane_init(dev, primary_plane, 0,
@@ -229,35 +214,13 @@ static int mgag200_g200eh_pipeline_init(struct mga_device *mdev)
drm_mode_crtc_set_gamma_size(crtc, MGAG200_LUT_SIZE);
drm_crtc_enable_color_mgmt(crtc, 0, false, MGAG200_LUT_SIZE);
- encoder->possible_crtcs = drm_crtc_mask(crtc);
- ret = drm_encoder_init(dev, encoder, &mgag200_g200eh_dac_encoder_funcs,
- DRM_MODE_ENCODER_DAC, NULL);
- if (ret) {
- drm_err(dev, "drm_encoder_init() failed: %d\n", ret);
- return ret;
- }
-
- ret = mgag200_i2c_init(mdev, i2c);
- if (ret) {
- drm_err(dev, "failed to add DDC bus: %d\n", ret);
- return ret;
- }
-
- ret = drm_connector_init_with_ddc(dev, connector,
- &mgag200_g200eh_vga_connector_funcs,
- DRM_MODE_CONNECTOR_VGA,
- &i2c->adapter);
- if (ret) {
- drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret);
+ ret = mgag200_vga_output_init(mdev);
+ if (ret)
return ret;
- }
- drm_connector_helper_add(connector, &mgag200_g200eh_vga_connector_helper_funcs);
- ret = drm_connector_attach_encoder(connector, encoder);
- if (ret) {
- drm_err(dev, "drm_connector_attach_encoder() failed: %d\n", ret);
+ ret = mgag200_bmc_output_init(mdev, &mdev->output.vga.connector);
+ if (ret)
return ret;
- }
return 0;
}
@@ -314,6 +277,7 @@ struct mga_device *mgag200_g200eh_device_create(struct pci_dev *pdev, const stru
return ERR_PTR(ret);
drm_mode_config_reset(dev);
+ drm_kms_helper_poll_init(dev);
return mdev;
}
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200eh3.c b/drivers/gpu/drm/mgag200/mgag200_g200eh3.c
index 0f7d8112cd49..e7f89b2a59fd 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200eh3.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200eh3.c
@@ -86,26 +86,11 @@ static const struct drm_crtc_funcs mgag200_g200eh3_crtc_funcs = {
MGAG200_CRTC_FUNCS,
};
-static const struct drm_encoder_funcs mgag200_g200eh3_dac_encoder_funcs = {
- MGAG200_DAC_ENCODER_FUNCS,
-};
-
-static const struct drm_connector_helper_funcs mgag200_g200eh3_vga_connector_helper_funcs = {
- MGAG200_VGA_CONNECTOR_HELPER_FUNCS,
-};
-
-static const struct drm_connector_funcs mgag200_g200eh3_vga_connector_funcs = {
- MGAG200_VGA_CONNECTOR_FUNCS,
-};
-
static int mgag200_g200eh3_pipeline_init(struct mga_device *mdev)
{
struct drm_device *dev = &mdev->base;
struct drm_plane *primary_plane = &mdev->primary_plane;
struct drm_crtc *crtc = &mdev->crtc;
- struct drm_encoder *encoder = &mdev->encoder;
- struct mga_i2c_chan *i2c = &mdev->i2c;
- struct drm_connector *connector = &mdev->connector;
int ret;
ret = drm_universal_plane_init(dev, primary_plane, 0,
@@ -133,35 +118,13 @@ static int mgag200_g200eh3_pipeline_init(struct mga_device *mdev)
drm_mode_crtc_set_gamma_size(crtc, MGAG200_LUT_SIZE);
drm_crtc_enable_color_mgmt(crtc, 0, false, MGAG200_LUT_SIZE);
- encoder->possible_crtcs = drm_crtc_mask(crtc);
- ret = drm_encoder_init(dev, encoder, &mgag200_g200eh3_dac_encoder_funcs,
- DRM_MODE_ENCODER_DAC, NULL);
- if (ret) {
- drm_err(dev, "drm_encoder_init() failed: %d\n", ret);
- return ret;
- }
-
- ret = mgag200_i2c_init(mdev, i2c);
- if (ret) {
- drm_err(dev, "failed to add DDC bus: %d\n", ret);
- return ret;
- }
-
- ret = drm_connector_init_with_ddc(dev, connector,
- &mgag200_g200eh3_vga_connector_funcs,
- DRM_MODE_CONNECTOR_VGA,
- &i2c->adapter);
- if (ret) {
- drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret);
+ ret = mgag200_vga_output_init(mdev);
+ if (ret)
return ret;
- }
- drm_connector_helper_add(connector, &mgag200_g200eh3_vga_connector_helper_funcs);
- ret = drm_connector_attach_encoder(connector, encoder);
- if (ret) {
- drm_err(dev, "drm_connector_attach_encoder() failed: %d\n", ret);
+ ret = mgag200_bmc_output_init(mdev, &mdev->output.vga.connector);
+ if (ret)
return ret;
- }
return 0;
}
@@ -219,6 +182,7 @@ struct mga_device *mgag200_g200eh3_device_create(struct pci_dev *pdev,
return ERR_PTR(ret);
drm_mode_config_reset(dev);
+ drm_kms_helper_poll_init(dev);
return mdev;
}
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200er.c b/drivers/gpu/drm/mgag200/mgag200_g200er.c
index 8d4538b71047..4e8a1756138d 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200er.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200er.c
@@ -225,26 +225,11 @@ static const struct drm_crtc_funcs mgag200_g200er_crtc_funcs = {
MGAG200_CRTC_FUNCS,
};
-static const struct drm_encoder_funcs mgag200_g200er_dac_encoder_funcs = {
- MGAG200_DAC_ENCODER_FUNCS,
-};
-
-static const struct drm_connector_helper_funcs mgag200_g200er_vga_connector_helper_funcs = {
- MGAG200_VGA_CONNECTOR_HELPER_FUNCS,
-};
-
-static const struct drm_connector_funcs mgag200_g200er_vga_connector_funcs = {
- MGAG200_VGA_CONNECTOR_FUNCS,
-};
-
static int mgag200_g200er_pipeline_init(struct mga_device *mdev)
{
struct drm_device *dev = &mdev->base;
struct drm_plane *primary_plane = &mdev->primary_plane;
struct drm_crtc *crtc = &mdev->crtc;
- struct drm_encoder *encoder = &mdev->encoder;
- struct mga_i2c_chan *i2c = &mdev->i2c;
- struct drm_connector *connector = &mdev->connector;
int ret;
ret = drm_universal_plane_init(dev, primary_plane, 0,
@@ -272,35 +257,13 @@ static int mgag200_g200er_pipeline_init(struct mga_device *mdev)
drm_mode_crtc_set_gamma_size(crtc, MGAG200_LUT_SIZE);
drm_crtc_enable_color_mgmt(crtc, 0, false, MGAG200_LUT_SIZE);
- encoder->possible_crtcs = drm_crtc_mask(crtc);
- ret = drm_encoder_init(dev, encoder, &mgag200_g200er_dac_encoder_funcs,
- DRM_MODE_ENCODER_DAC, NULL);
- if (ret) {
- drm_err(dev, "drm_encoder_init() failed: %d\n", ret);
- return ret;
- }
-
- ret = mgag200_i2c_init(mdev, i2c);
- if (ret) {
- drm_err(dev, "failed to add DDC bus: %d\n", ret);
- return ret;
- }
-
- ret = drm_connector_init_with_ddc(dev, connector,
- &mgag200_g200er_vga_connector_funcs,
- DRM_MODE_CONNECTOR_VGA,
- &i2c->adapter);
- if (ret) {
- drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret);
+ ret = mgag200_vga_output_init(mdev);
+ if (ret)
return ret;
- }
- drm_connector_helper_add(connector, &mgag200_g200er_vga_connector_helper_funcs);
- ret = drm_connector_attach_encoder(connector, encoder);
- if (ret) {
- drm_err(dev, "drm_connector_attach_encoder() failed: %d\n", ret);
+ ret = mgag200_bmc_output_init(mdev, &mdev->output.vga.connector);
+ if (ret)
return ret;
- }
return 0;
}
@@ -353,6 +316,7 @@ struct mga_device *mgag200_g200er_device_create(struct pci_dev *pdev, const stru
return ERR_PTR(ret);
drm_mode_config_reset(dev);
+ drm_kms_helper_poll_init(dev);
return mdev;
}
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200ev.c b/drivers/gpu/drm/mgag200/mgag200_g200ev.c
index 56e6f986bff3..d884f3cb0ec7 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200ev.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200ev.c
@@ -226,26 +226,11 @@ static const struct drm_crtc_funcs mgag200_g200ev_crtc_funcs = {
MGAG200_CRTC_FUNCS,
};
-static const struct drm_encoder_funcs mgag200_g200ev_dac_encoder_funcs = {
- MGAG200_DAC_ENCODER_FUNCS,
-};
-
-static const struct drm_connector_helper_funcs mgag200_g200ev_vga_connector_helper_funcs = {
- MGAG200_VGA_CONNECTOR_HELPER_FUNCS,
-};
-
-static const struct drm_connector_funcs mgag200_g200ev_vga_connector_funcs = {
- MGAG200_VGA_CONNECTOR_FUNCS,
-};
-
static int mgag200_g200ev_pipeline_init(struct mga_device *mdev)
{
struct drm_device *dev = &mdev->base;
struct drm_plane *primary_plane = &mdev->primary_plane;
struct drm_crtc *crtc = &mdev->crtc;
- struct drm_encoder *encoder = &mdev->encoder;
- struct mga_i2c_chan *i2c = &mdev->i2c;
- struct drm_connector *connector = &mdev->connector;
int ret;
ret = drm_universal_plane_init(dev, primary_plane, 0,
@@ -273,35 +258,13 @@ static int mgag200_g200ev_pipeline_init(struct mga_device *mdev)
drm_mode_crtc_set_gamma_size(crtc, MGAG200_LUT_SIZE);
drm_crtc_enable_color_mgmt(crtc, 0, false, MGAG200_LUT_SIZE);
- encoder->possible_crtcs = drm_crtc_mask(crtc);
- ret = drm_encoder_init(dev, encoder, &mgag200_g200ev_dac_encoder_funcs,
- DRM_MODE_ENCODER_DAC, NULL);
- if (ret) {
- drm_err(dev, "drm_encoder_init() failed: %d\n", ret);
- return ret;
- }
-
- ret = mgag200_i2c_init(mdev, i2c);
- if (ret) {
- drm_err(dev, "failed to add DDC bus: %d\n", ret);
- return ret;
- }
-
- ret = drm_connector_init_with_ddc(dev, connector,
- &mgag200_g200ev_vga_connector_funcs,
- DRM_MODE_CONNECTOR_VGA,
- &i2c->adapter);
- if (ret) {
- drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret);
+ ret = mgag200_vga_output_init(mdev);
+ if (ret)
return ret;
- }
- drm_connector_helper_add(connector, &mgag200_g200ev_vga_connector_helper_funcs);
- ret = drm_connector_attach_encoder(connector, encoder);
- if (ret) {
- drm_err(dev, "drm_connector_attach_encoder() failed: %d\n", ret);
+ ret = mgag200_bmc_output_init(mdev, &mdev->output.vga.connector);
+ if (ret)
return ret;
- }
return 0;
}
@@ -358,6 +321,7 @@ struct mga_device *mgag200_g200ev_device_create(struct pci_dev *pdev, const stru
return ERR_PTR(ret);
drm_mode_config_reset(dev);
+ drm_kms_helper_poll_init(dev);
return mdev;
}
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200ew3.c b/drivers/gpu/drm/mgag200/mgag200_g200ew3.c
index 170934414d7d..839401e8b465 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200ew3.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200ew3.c
@@ -95,26 +95,11 @@ static const struct drm_crtc_funcs mgag200_g200ew3_crtc_funcs = {
MGAG200_CRTC_FUNCS,
};
-static const struct drm_encoder_funcs mgag200_g200ew3_dac_encoder_funcs = {
- MGAG200_DAC_ENCODER_FUNCS,
-};
-
-static const struct drm_connector_helper_funcs mgag200_g200ew3_vga_connector_helper_funcs = {
- MGAG200_VGA_CONNECTOR_HELPER_FUNCS,
-};
-
-static const struct drm_connector_funcs mgag200_g200ew3_vga_connector_funcs = {
- MGAG200_VGA_CONNECTOR_FUNCS,
-};
-
static int mgag200_g200ew3_pipeline_init(struct mga_device *mdev)
{
struct drm_device *dev = &mdev->base;
struct drm_plane *primary_plane = &mdev->primary_plane;
struct drm_crtc *crtc = &mdev->crtc;
- struct drm_encoder *encoder = &mdev->encoder;
- struct mga_i2c_chan *i2c = &mdev->i2c;
- struct drm_connector *connector = &mdev->connector;
int ret;
ret = drm_universal_plane_init(dev, primary_plane, 0,
@@ -142,35 +127,13 @@ static int mgag200_g200ew3_pipeline_init(struct mga_device *mdev)
drm_mode_crtc_set_gamma_size(crtc, MGAG200_LUT_SIZE);
drm_crtc_enable_color_mgmt(crtc, 0, false, MGAG200_LUT_SIZE);
- encoder->possible_crtcs = drm_crtc_mask(crtc);
- ret = drm_encoder_init(dev, encoder, &mgag200_g200ew3_dac_encoder_funcs,
- DRM_MODE_ENCODER_DAC, NULL);
- if (ret) {
- drm_err(dev, "drm_encoder_init() failed: %d\n", ret);
- return ret;
- }
-
- ret = mgag200_i2c_init(mdev, i2c);
- if (ret) {
- drm_err(dev, "failed to add DDC bus: %d\n", ret);
- return ret;
- }
-
- ret = drm_connector_init_with_ddc(dev, connector,
- &mgag200_g200ew3_vga_connector_funcs,
- DRM_MODE_CONNECTOR_VGA,
- &i2c->adapter);
- if (ret) {
- drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret);
+ ret = mgag200_vga_output_init(mdev);
+ if (ret)
return ret;
- }
- drm_connector_helper_add(connector, &mgag200_g200ew3_vga_connector_helper_funcs);
- ret = drm_connector_attach_encoder(connector, encoder);
- if (ret) {
- drm_err(dev, "drm_connector_attach_encoder() failed: %d\n", ret);
+ ret = mgag200_bmc_output_init(mdev, &mdev->output.vga.connector);
+ if (ret)
return ret;
- }
return 0;
}
@@ -239,6 +202,7 @@ struct mga_device *mgag200_g200ew3_device_create(struct pci_dev *pdev,
return ERR_PTR(ret);
drm_mode_config_reset(dev);
+ drm_kms_helper_poll_init(dev);
return mdev;
}
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200se.c b/drivers/gpu/drm/mgag200/mgag200_g200se.c
index ff2b3c6622e7..a824bb8ad579 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200se.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200se.c
@@ -357,26 +357,11 @@ static const struct drm_crtc_funcs mgag200_g200se_crtc_funcs = {
MGAG200_CRTC_FUNCS,
};
-static const struct drm_encoder_funcs mgag200_g200se_dac_encoder_funcs = {
- MGAG200_DAC_ENCODER_FUNCS,
-};
-
-static const struct drm_connector_helper_funcs mgag200_g200se_vga_connector_helper_funcs = {
- MGAG200_VGA_CONNECTOR_HELPER_FUNCS,
-};
-
-static const struct drm_connector_funcs mgag200_g200se_vga_connector_funcs = {
- MGAG200_VGA_CONNECTOR_FUNCS,
-};
-
static int mgag200_g200se_pipeline_init(struct mga_device *mdev)
{
struct drm_device *dev = &mdev->base;
struct drm_plane *primary_plane = &mdev->primary_plane;
struct drm_crtc *crtc = &mdev->crtc;
- struct drm_encoder *encoder = &mdev->encoder;
- struct mga_i2c_chan *i2c = &mdev->i2c;
- struct drm_connector *connector = &mdev->connector;
int ret;
ret = drm_universal_plane_init(dev, primary_plane, 0,
@@ -404,35 +389,13 @@ static int mgag200_g200se_pipeline_init(struct mga_device *mdev)
drm_mode_crtc_set_gamma_size(crtc, MGAG200_LUT_SIZE);
drm_crtc_enable_color_mgmt(crtc, 0, false, MGAG200_LUT_SIZE);
- encoder->possible_crtcs = drm_crtc_mask(crtc);
- ret = drm_encoder_init(dev, encoder, &mgag200_g200se_dac_encoder_funcs,
- DRM_MODE_ENCODER_DAC, NULL);
- if (ret) {
- drm_err(dev, "drm_encoder_init() failed: %d\n", ret);
- return ret;
- }
-
- ret = mgag200_i2c_init(mdev, i2c);
- if (ret) {
- drm_err(dev, "failed to add DDC bus: %d\n", ret);
- return ret;
- }
-
- ret = drm_connector_init_with_ddc(dev, connector,
- &mgag200_g200se_vga_connector_funcs,
- DRM_MODE_CONNECTOR_VGA,
- &i2c->adapter);
- if (ret) {
- drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret);
+ ret = mgag200_vga_output_init(mdev);
+ if (ret)
return ret;
- }
- drm_connector_helper_add(connector, &mgag200_g200se_vga_connector_helper_funcs);
- ret = drm_connector_attach_encoder(connector, encoder);
- if (ret) {
- drm_err(dev, "drm_connector_attach_encoder() failed: %d\n", ret);
+ ret = mgag200_bmc_output_init(mdev, &mdev->output.vga.connector);
+ if (ret)
return ret;
- }
return 0;
}
@@ -558,6 +521,7 @@ struct mga_device *mgag200_g200se_device_create(struct pci_dev *pdev, const stru
return ERR_PTR(ret);
drm_mode_config_reset(dev);
+ drm_kms_helper_poll_init(dev);
return mdev;
}
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200wb.c b/drivers/gpu/drm/mgag200/mgag200_g200wb.c
index 9baa727ac6f9..835df0f4fc13 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200wb.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200wb.c
@@ -229,26 +229,11 @@ static const struct drm_crtc_funcs mgag200_g200wb_crtc_funcs = {
MGAG200_CRTC_FUNCS,
};
-static const struct drm_encoder_funcs mgag200_g200wb_dac_encoder_funcs = {
- MGAG200_DAC_ENCODER_FUNCS,
-};
-
-static const struct drm_connector_helper_funcs mgag200_g200wb_vga_connector_helper_funcs = {
- MGAG200_VGA_CONNECTOR_HELPER_FUNCS,
-};
-
-static const struct drm_connector_funcs mgag200_g200wb_vga_connector_funcs = {
- MGAG200_VGA_CONNECTOR_FUNCS,
-};
-
static int mgag200_g200wb_pipeline_init(struct mga_device *mdev)
{
struct drm_device *dev = &mdev->base;
struct drm_plane *primary_plane = &mdev->primary_plane;
struct drm_crtc *crtc = &mdev->crtc;
- struct drm_encoder *encoder = &mdev->encoder;
- struct mga_i2c_chan *i2c = &mdev->i2c;
- struct drm_connector *connector = &mdev->connector;
int ret;
ret = drm_universal_plane_init(dev, primary_plane, 0,
@@ -276,35 +261,13 @@ static int mgag200_g200wb_pipeline_init(struct mga_device *mdev)
drm_mode_crtc_set_gamma_size(crtc, MGAG200_LUT_SIZE);
drm_crtc_enable_color_mgmt(crtc, 0, false, MGAG200_LUT_SIZE);
- encoder->possible_crtcs = drm_crtc_mask(crtc);
- ret = drm_encoder_init(dev, encoder, &mgag200_g200wb_dac_encoder_funcs,
- DRM_MODE_ENCODER_DAC, NULL);
- if (ret) {
- drm_err(dev, "drm_encoder_init() failed: %d\n", ret);
- return ret;
- }
-
- ret = mgag200_i2c_init(mdev, i2c);
- if (ret) {
- drm_err(dev, "failed to add DDC bus: %d\n", ret);
- return ret;
- }
-
- ret = drm_connector_init_with_ddc(dev, connector,
- &mgag200_g200wb_vga_connector_funcs,
- DRM_MODE_CONNECTOR_VGA,
- &i2c->adapter);
- if (ret) {
- drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret);
+ ret = mgag200_vga_output_init(mdev);
+ if (ret)
return ret;
- }
- drm_connector_helper_add(connector, &mgag200_g200wb_vga_connector_helper_funcs);
- ret = drm_connector_attach_encoder(connector, encoder);
- if (ret) {
- drm_err(dev, "drm_connector_attach_encoder() failed: %d\n", ret);
+ ret = mgag200_bmc_output_init(mdev, &mdev->output.vga.connector);
+ if (ret)
return ret;
- }
return 0;
}
@@ -363,6 +326,7 @@ struct mga_device *mgag200_g200wb_device_create(struct pci_dev *pdev, const stru
return ERR_PTR(ret);
drm_mode_config_reset(dev);
+ drm_kms_helper_poll_init(dev);
return mdev;
}
diff --git a/drivers/gpu/drm/mgag200/mgag200_i2c.c b/drivers/gpu/drm/mgag200/mgag200_i2c.c
deleted file mode 100644
index 423eb302be7e..000000000000
--- a/drivers/gpu/drm/mgag200/mgag200_i2c.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- */
-/*
- * Authors: Dave Airlie <airlied@redhat.com>
- */
-
-#include <linux/export.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/i2c.h>
-#include <linux/pci.h>
-
-#include "mgag200_drv.h"
-
-static int mga_i2c_read_gpio(struct mga_device *mdev)
-{
- WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA);
- return RREG8(DAC_DATA);
-}
-
-static void mga_i2c_set_gpio(struct mga_device *mdev, int mask, int val)
-{
- int tmp;
-
- WREG8(DAC_INDEX, MGA1064_GEN_IO_CTL);
- tmp = (RREG8(DAC_DATA) & mask) | val;
- WREG_DAC(MGA1064_GEN_IO_CTL, tmp);
- WREG_DAC(MGA1064_GEN_IO_DATA, 0);
-}
-
-static inline void mga_i2c_set(struct mga_device *mdev, int mask, int state)
-{
- if (state)
- state = 0;
- else
- state = mask;
- mga_i2c_set_gpio(mdev, ~mask, state);
-}
-
-static void mga_gpio_setsda(void *data, int state)
-{
- struct mga_i2c_chan *i2c = data;
- struct mga_device *mdev = to_mga_device(i2c->dev);
- mga_i2c_set(mdev, i2c->data, state);
-}
-
-static void mga_gpio_setscl(void *data, int state)
-{
- struct mga_i2c_chan *i2c = data;
- struct mga_device *mdev = to_mga_device(i2c->dev);
- mga_i2c_set(mdev, i2c->clock, state);
-}
-
-static int mga_gpio_getsda(void *data)
-{
- struct mga_i2c_chan *i2c = data;
- struct mga_device *mdev = to_mga_device(i2c->dev);
- return (mga_i2c_read_gpio(mdev) & i2c->data) ? 1 : 0;
-}
-
-static int mga_gpio_getscl(void *data)
-{
- struct mga_i2c_chan *i2c = data;
- struct mga_device *mdev = to_mga_device(i2c->dev);
- return (mga_i2c_read_gpio(mdev) & i2c->clock) ? 1 : 0;
-}
-
-static void mgag200_i2c_release(void *res)
-{
- struct mga_i2c_chan *i2c = res;
-
- i2c_del_adapter(&i2c->adapter);
-}
-
-int mgag200_i2c_init(struct mga_device *mdev, struct mga_i2c_chan *i2c)
-{
- struct drm_device *dev = &mdev->base;
- const struct mgag200_device_info *info = mdev->info;
- int ret;
-
- WREG_DAC(MGA1064_GEN_IO_CTL2, 1);
- WREG_DAC(MGA1064_GEN_IO_DATA, 0xff);
- WREG_DAC(MGA1064_GEN_IO_CTL, 0);
-
- i2c->data = BIT(info->i2c.data_bit);
- i2c->clock = BIT(info->i2c.clock_bit);
- i2c->adapter.owner = THIS_MODULE;
- i2c->adapter.dev.parent = dev->dev;
- i2c->dev = dev;
- i2c_set_adapdata(&i2c->adapter, i2c);
- snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), "mga i2c");
-
- i2c->adapter.algo_data = &i2c->bit;
-
- i2c->bit.udelay = 10;
- i2c->bit.timeout = 2;
- i2c->bit.data = i2c;
- i2c->bit.setsda = mga_gpio_setsda;
- i2c->bit.setscl = mga_gpio_setscl;
- i2c->bit.getsda = mga_gpio_getsda;
- i2c->bit.getscl = mga_gpio_getscl;
-
- ret = i2c_bit_add_bus(&i2c->adapter);
- if (ret)
- return ret;
-
- return devm_add_action_or_reset(dev->dev, mgag200_i2c_release, i2c);
-}
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index fc54851d3384..bb6204002cb3 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -13,7 +13,6 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
-#include <drm/drm_cache.h>
#include <drm/drm_damage_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_format_helper.h>
@@ -24,6 +23,7 @@
#include <drm/drm_panic.h>
#include <drm/drm_print.h>
+#include "mgag200_ddc.h"
#include "mgag200_drv.h"
/*
@@ -438,13 +438,6 @@ static void mgag200_handle_damage(struct mga_device *mdev, const struct iosys_ma
iosys_map_incr(&dst, drm_fb_clip_offset(fb->pitches[0], fb->format, clip));
drm_fb_memcpy(&dst, fb->pitches, vmap, fb, clip);
-
- /* Flushing the cache greatly improves latency on x86_64 */
-#if defined(CONFIG_DRM_MGAG200_IOBURST_WORKAROUND)
- if (!vmap->is_iomem)
- drm_clflush_virt_range(vmap->vaddr + clip->y1 * fb->pitches[0],
- drm_rect_height(clip) * fb->pitches[0]);
-#endif
}
/*
@@ -737,32 +730,6 @@ void mgag200_crtc_atomic_destroy_state(struct drm_crtc *crtc, struct drm_crtc_st
}
/*
- * Connector
- */
-
-int mgag200_vga_connector_helper_get_modes(struct drm_connector *connector)
-{
- struct mga_device *mdev = to_mga_device(connector->dev);
- const struct drm_edid *drm_edid;
- int count;
-
- /*
- * Protect access to I/O registers from concurrent modesetting
- * by acquiring the I/O-register lock.
- */
- mutex_lock(&mdev->rmmio_lock);
-
- drm_edid = drm_edid_read(connector);
- drm_edid_connector_update(connector, drm_edid);
- count = drm_edid_connector_add_modes(connector);
- drm_edid_free(drm_edid);
-
- mutex_unlock(&mdev->rmmio_lock);
-
- return count;
-}
-
-/*
* Mode config
*/
diff --git a/drivers/gpu/drm/mgag200/mgag200_vga.c b/drivers/gpu/drm/mgag200/mgag200_vga.c
new file mode 100644
index 000000000000..60568f32736d
--- /dev/null
+++ b/drivers/gpu/drm/mgag200/mgag200_vga.c
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_modeset_helper_vtables.h>
+#include <drm/drm_probe_helper.h>
+
+#include "mgag200_ddc.h"
+#include "mgag200_drv.h"
+
+static const struct drm_encoder_funcs mgag200_dac_encoder_funcs = {
+ .destroy = drm_encoder_cleanup
+};
+
+static const struct drm_connector_helper_funcs mgag200_vga_connector_helper_funcs = {
+ .get_modes = drm_connector_helper_get_modes,
+ .detect_ctx = drm_connector_helper_detect_from_ddc
+};
+
+static const struct drm_connector_funcs mgag200_vga_connector_funcs = {
+ .reset = drm_atomic_helper_connector_reset,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .destroy = drm_connector_cleanup,
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state
+};
+
+int mgag200_vga_output_init(struct mga_device *mdev)
+{
+ struct drm_device *dev = &mdev->base;
+ struct drm_crtc *crtc = &mdev->crtc;
+ struct drm_encoder *encoder;
+ struct drm_connector *connector;
+ struct i2c_adapter *ddc;
+ int ret;
+
+ encoder = &mdev->output.vga.encoder;
+ ret = drm_encoder_init(dev, encoder, &mgag200_dac_encoder_funcs,
+ DRM_MODE_ENCODER_DAC, NULL);
+ if (ret) {
+ drm_err(dev, "drm_encoder_init() failed: %d\n", ret);
+ return ret;
+ }
+ encoder->possible_crtcs = drm_crtc_mask(crtc);
+
+ ddc = mgag200_ddc_create(mdev);
+ if (IS_ERR(ddc)) {
+ ret = PTR_ERR(ddc);
+ drm_err(dev, "failed to add DDC bus: %d\n", ret);
+ return ret;
+ }
+
+ connector = &mdev->output.vga.connector;
+ ret = drm_connector_init_with_ddc(dev, connector,
+ &mgag200_vga_connector_funcs,
+ DRM_MODE_CONNECTOR_VGA, ddc);
+ if (ret) {
+ drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret);
+ return ret;
+ }
+ drm_connector_helper_add(connector, &mgag200_vga_connector_helper_funcs);
+
+ connector->polled = DRM_CONNECTOR_POLL_CONNECT |
+ DRM_CONNECTOR_POLL_DISCONNECT;
+
+ ret = drm_connector_attach_encoder(connector, encoder);
+ if (ret) {
+ drm_err(dev, "drm_connector_attach_encoder() failed: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 88728a0b2c25..ac9657d7e92d 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -751,7 +751,7 @@ nv50_audio_enable(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc,
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nvif_outp *outp = &nv_encoder->outp;
- if (!nv50_audio_supported(encoder) || !drm_detect_monitor_audio(nv_connector->edid))
+ if (!nv50_audio_supported(encoder) || !nv_connector->base.display_info.has_audio)
return;
mutex_lock(&drm->audio.lock);
@@ -1765,7 +1765,7 @@ nv50_sor_atomic_enable(struct drm_encoder *encoder, struct drm_atomic_state *sta
if ((disp->disp->object.oclass == GT214_DISP ||
disp->disp->object.oclass >= GF110_DISP) &&
nv_encoder->dcb->type != DCB_OUTPUT_LVDS &&
- drm_detect_monitor_audio(nv_connector->edid))
+ nv_connector->base.display_info.has_audio)
hda = true;
if (!nvif_outp_acquired(outp))
@@ -1774,7 +1774,7 @@ nv50_sor_atomic_enable(struct drm_encoder *encoder, struct drm_atomic_state *sta
switch (nv_encoder->dcb->type) {
case DCB_OUTPUT_TMDS:
if (disp->disp->object.oclass != NV50_DISP &&
- drm_detect_hdmi_monitor(nv_connector->edid))
+ nv_connector->base.display_info.is_hdmi)
nv50_hdmi_enable(encoder, nv_crtc, nv_connector, state, mode, hda);
if (nv_encoder->outp.or.link & 1) {
@@ -1787,7 +1787,7 @@ nv50_sor_atomic_enable(struct drm_encoder *encoder, struct drm_atomic_state *sta
*/
if (mode->clock >= 165000 &&
nv_encoder->dcb->duallink_possible &&
- !drm_detect_hdmi_monitor(nv_connector->edid))
+ !nv_connector->base.display_info.is_hdmi)
proto = NV507D_SOR_SET_CONTROL_PROTOCOL_DUAL_TMDS;
} else {
proto = NV507D_SOR_SET_CONTROL_PROTOCOL_SINGLE_TMDS_B;
diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.c b/drivers/gpu/drm/nouveau/dispnv50/head.c
index 83355dbc15ee..d7c74cc43ba5 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/head.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/head.c
@@ -127,14 +127,8 @@ nv50_head_atomic_check_view(struct nv50_head_atom *armh,
struct drm_display_mode *omode = &asyh->state.adjusted_mode;
struct drm_display_mode *umode = &asyh->state.mode;
int mode = asyc->scaler.mode;
- struct edid *edid;
int umode_vdisplay, omode_hdisplay, omode_vdisplay;
- if (connector->edid_blob_ptr)
- edid = (struct edid *)connector->edid_blob_ptr->data;
- else
- edid = NULL;
-
if (!asyc->scaler.full) {
if (mode == DRM_MODE_SCALE_NONE)
omode = umode;
@@ -162,7 +156,7 @@ nv50_head_atomic_check_view(struct nv50_head_atom *armh,
*/
if ((asyc->scaler.underscan.mode == UNDERSCAN_ON ||
(asyc->scaler.underscan.mode == UNDERSCAN_AUTO &&
- drm_detect_hdmi_monitor(edid)))) {
+ connector->display_info.is_hdmi))) {
u32 bX = asyc->scaler.underscan.hborder;
u32 bY = asyc->scaler.underscan.vborder;
u32 r = (asyh->view.oH << 19) / asyh->view.oW;
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
index a11d16a16c3b..9e6f39912368 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
@@ -213,6 +213,12 @@ struct nvkm_gsp {
struct mutex mutex;;
struct idr idr;
} client_id;
+
+ /* A linked list of registry items. The registry RPC will be built from it. */
+ struct list_head registry_list;
+
+ /* The size of the registry RPC */
+ size_t registry_rpc_size;
};
static inline bool
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 70fb003a6666..0712d0b15170 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -898,7 +898,7 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict,
* Without this the operation can timeout and we'll fallback to a
* software copy, which might take several minutes to finish.
*/
- nouveau_fence_wait(fence, false, false);
+ nouveau_fence_wait(fence, false);
ret = ttm_bo_move_accel_cleanup(bo, &fence->base, evict, false,
new_reg);
nouveau_fence_unref(&fence);
diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c
index 7c97b2886807..66fca95c10c7 100644
--- a/drivers/gpu/drm/nouveau/nouveau_chan.c
+++ b/drivers/gpu/drm/nouveau/nouveau_chan.c
@@ -72,7 +72,7 @@ nouveau_channel_idle(struct nouveau_channel *chan)
ret = nouveau_fence_new(&fence, chan);
if (!ret) {
- ret = nouveau_fence_wait(fence, false, false);
+ ret = nouveau_fence_wait(fence, false);
nouveau_fence_unref(&fence);
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 856b3ef5edb8..938832a6af15 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -1034,7 +1034,7 @@ get_tmds_link_bandwidth(struct drm_connector *connector)
unsigned duallink_scale =
nouveau_duallink && nv_encoder->dcb->duallink_possible ? 2 : 1;
- if (drm_detect_hdmi_monitor(nv_connector->edid)) {
+ if (nv_connector->base.display_info.is_hdmi) {
info = &nv_connector->base.display_info;
duallink_scale = 1;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_dmem.c b/drivers/gpu/drm/nouveau/nouveau_dmem.c
index 6fb65b01d778..6719353e2e13 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dmem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dmem.c
@@ -128,7 +128,7 @@ static void nouveau_dmem_page_free(struct page *page)
static void nouveau_dmem_fence_done(struct nouveau_fence **fence)
{
if (fence) {
- nouveau_fence_wait(*fence, true, false);
+ nouveau_fence_wait(*fence, false);
nouveau_fence_unref(fence);
} else {
/*
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index a947e1d5f309..a58c31089613 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -32,7 +32,7 @@
#include <drm/drm_aperture.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_ttm.h>
#include <drm/drm_gem_ttm_helper.h>
#include <drm/drm_ioctl.h>
#include <drm/drm_vblank.h>
@@ -846,9 +846,9 @@ static int nouveau_drm_probe(struct pci_dev *pdev,
goto fail_drm_dev_init;
if (nouveau_drm(drm_dev)->client.device.info.ram_size <= 32 * 1024 * 1024)
- drm_fbdev_generic_setup(drm_dev, 8);
+ drm_fbdev_ttm_setup(drm_dev, 8);
else
- drm_fbdev_generic_setup(drm_dev, 32);
+ drm_fbdev_ttm_setup(drm_dev, 32);
quirk_broken_nv_runpm(pdev);
return 0;
diff --git a/drivers/gpu/drm/nouveau/nouveau_exec.c b/drivers/gpu/drm/nouveau/nouveau_exec.c
index e65c0ef23bc7..a0b5f1b16e8b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_exec.c
+++ b/drivers/gpu/drm/nouveau/nouveau_exec.c
@@ -188,7 +188,7 @@ nouveau_exec_job_timeout(struct nouveau_job *job)
return DRM_GPU_SCHED_STAT_NOMINAL;
}
-static struct nouveau_job_ops nouveau_exec_job_ops = {
+static const struct nouveau_job_ops nouveau_exec_job_ops = {
.submit = nouveau_exec_job_submit,
.armed_submit = nouveau_exec_job_armed_submit,
.run = nouveau_exec_job_run,
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c
index 93f08f9479d8..ba469767a20f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
@@ -311,39 +311,11 @@ nouveau_fence_wait_legacy(struct dma_fence *f, bool intr, long wait)
return timeout - t;
}
-static int
-nouveau_fence_wait_busy(struct nouveau_fence *fence, bool intr)
-{
- int ret = 0;
-
- while (!nouveau_fence_done(fence)) {
- if (time_after_eq(jiffies, fence->timeout)) {
- ret = -EBUSY;
- break;
- }
-
- __set_current_state(intr ?
- TASK_INTERRUPTIBLE :
- TASK_UNINTERRUPTIBLE);
-
- if (intr && signal_pending(current)) {
- ret = -ERESTARTSYS;
- break;
- }
- }
-
- __set_current_state(TASK_RUNNING);
- return ret;
-}
-
int
-nouveau_fence_wait(struct nouveau_fence *fence, bool lazy, bool intr)
+nouveau_fence_wait(struct nouveau_fence *fence, bool intr)
{
long ret;
- if (!lazy)
- return nouveau_fence_wait_busy(fence, intr);
-
ret = dma_fence_wait_timeout(&fence->base, intr, 15 * HZ);
if (ret < 0)
return ret;
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.h b/drivers/gpu/drm/nouveau/nouveau_fence.h
index 8bc065acfe35..1b63197b744a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.h
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.h
@@ -23,7 +23,7 @@ void nouveau_fence_unref(struct nouveau_fence **);
int nouveau_fence_emit(struct nouveau_fence *);
bool nouveau_fence_done(struct nouveau_fence *);
-int nouveau_fence_wait(struct nouveau_fence *, bool lazy, bool intr);
+int nouveau_fence_wait(struct nouveau_fence *, bool intr);
int nouveau_fence_sync(struct nouveau_bo *, struct nouveau_channel *, bool exclusive, bool intr);
struct nouveau_fence_chan {
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index 5a887d67dc0e..2e535caa7d6e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -928,7 +928,7 @@ revalidate:
}
if (sync) {
- if (!(ret = nouveau_fence_wait(fence, false, false))) {
+ if (!(ret = nouveau_fence_wait(fence, false))) {
if ((ret = dma_fence_get_status(&fence->base)) == 1)
ret = 0;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_sched.h b/drivers/gpu/drm/nouveau/nouveau_sched.h
index e1f01a23e6f6..20cd1da8db73 100644
--- a/drivers/gpu/drm/nouveau/nouveau_sched.h
+++ b/drivers/gpu/drm/nouveau/nouveau_sched.h
@@ -42,7 +42,7 @@ struct nouveau_job_args {
u32 count;
} out_sync;
- struct nouveau_job_ops *ops;
+ const struct nouveau_job_ops *ops;
};
struct nouveau_job {
@@ -73,7 +73,7 @@ struct nouveau_job {
u32 count;
} out_sync;
- struct nouveau_job_ops {
+ const struct nouveau_job_ops {
/* If .submit() returns without any error, it is guaranteed that
* armed_submit() is called.
*/
diff --git a/drivers/gpu/drm/nouveau/nouveau_uvmm.c b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
index ee02cd833c5e..9402fa320a7e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
@@ -1534,7 +1534,7 @@ nouveau_uvmm_bind_job_cleanup(struct nouveau_job *job)
nouveau_uvmm_bind_job_put(bind_job);
}
-static struct nouveau_job_ops nouveau_bind_job_ops = {
+static const struct nouveau_job_ops nouveau_bind_job_ops = {
.submit = nouveau_uvmm_bind_job_submit,
.armed_submit = nouveau_uvmm_bind_job_armed_submit,
.run = nouveau_uvmm_bind_job_run,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c
index abe41f7a3404..cf58f9da9139 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c
@@ -54,6 +54,8 @@
#include <nvrm/535.113.01/nvidia/kernel/inc/vgpu/rpc_global_enums.h>
#include <linux/acpi.h>
+#include <linux/ctype.h>
+#include <linux/parser.h>
#define GSP_MSG_MIN_SIZE GSP_PAGE_SIZE
#define GSP_MSG_MAX_SIZE GSP_PAGE_MIN_SIZE * 16
@@ -1080,53 +1082,365 @@ r535_gsp_rpc_unloading_guest_driver(struct nvkm_gsp *gsp, bool suspend)
return nvkm_gsp_rpc_wr(gsp, rpc, true);
}
+enum registry_type {
+ REGISTRY_TABLE_ENTRY_TYPE_DWORD = 1, /* 32-bit unsigned integer */
+ REGISTRY_TABLE_ENTRY_TYPE_BINARY = 2, /* Binary blob */
+ REGISTRY_TABLE_ENTRY_TYPE_STRING = 3, /* Null-terminated string */
+};
+
+/* An arbitrary limit to the length of a registry key */
+#define REGISTRY_MAX_KEY_LENGTH 64
+
+/**
+ * registry_list_entry - linked list member for a registry key/value
+ * @head: list_head struct
+ * @type: dword, binary, or string
+ * @klen: the length of name of the key
+ * @vlen: the length of the value
+ * @key: the key name
+ * @dword: the data, if REGISTRY_TABLE_ENTRY_TYPE_DWORD
+ * @binary: the data, if TYPE_BINARY or TYPE_STRING
+ *
+ * Every registry key/value is represented internally by this struct.
+ *
+ * Type DWORD is a simple 32-bit unsigned integer, and its value is stored in
+ * @dword.
+ *
+ * Types BINARY and STRING are variable-length binary blobs. The only real
+ * difference between BINARY and STRING is that STRING is null-terminated and
+ * is expected to contain only printable characters.
+ *
+ * Note: it is technically possible to have multiple keys with the same name
+ * but different types, but this is not useful since GSP-RM expects keys to
+ * have only one specific type.
+ */
+struct registry_list_entry {
+ struct list_head head;
+ enum registry_type type;
+ size_t klen;
+ char key[REGISTRY_MAX_KEY_LENGTH];
+ size_t vlen;
+ u32 dword; /* TYPE_DWORD */
+ u8 binary[] __counted_by(vlen); /* TYPE_BINARY or TYPE_STRING */
+};
+
+/**
+ * add_registry -- adds a registry entry
+ * @gsp: gsp pointer
+ * @key: name of the registry key
+ * @type: type of data
+ * @data: pointer to value
+ * @length: size of data, in bytes
+ *
+ * Adds a registry key/value pair to the registry database.
+ *
+ * This function collects the registry information in a linked list. After
+ * all registry keys have been added, build_registry() is used to create the
+ * RPC data structure.
+ *
+ * registry_rpc_size is a running total of the size of all registry keys.
+ * It's used to avoid an O(n) calculation of the size when the RPC is built.
+ *
+ * Returns 0 on success, or negative error code on error.
+ */
+static int add_registry(struct nvkm_gsp *gsp, const char *key,
+ enum registry_type type, const void *data, size_t length)
+{
+ struct registry_list_entry *reg;
+ const size_t nlen = strnlen(key, REGISTRY_MAX_KEY_LENGTH) + 1;
+ size_t alloc_size; /* extra bytes to alloc for binary or string value */
+
+ if (nlen > REGISTRY_MAX_KEY_LENGTH)
+ return -EINVAL;
+
+ alloc_size = (type == REGISTRY_TABLE_ENTRY_TYPE_DWORD) ? 0 : length;
+
+ reg = kmalloc(sizeof(*reg) + alloc_size, GFP_KERNEL);
+ if (!reg)
+ return -ENOMEM;
+
+ switch (type) {
+ case REGISTRY_TABLE_ENTRY_TYPE_DWORD:
+ reg->dword = *(const u32 *)(data);
+ break;
+ case REGISTRY_TABLE_ENTRY_TYPE_BINARY:
+ case REGISTRY_TABLE_ENTRY_TYPE_STRING:
+ memcpy(reg->binary, data, alloc_size);
+ break;
+ default:
+ nvkm_error(&gsp->subdev, "unrecognized registry type %u for '%s'\n",
+ type, key);
+ kfree(reg);
+ return -EINVAL;
+ }
+
+ memcpy(reg->key, key, nlen);
+ reg->klen = nlen;
+ reg->vlen = length;
+ reg->type = type;
+
+ list_add_tail(&reg->head, &gsp->registry_list);
+ gsp->registry_rpc_size += sizeof(PACKED_REGISTRY_ENTRY) + nlen + alloc_size;
+
+ return 0;
+}
+
+static int add_registry_num(struct nvkm_gsp *gsp, const char *key, u32 value)
+{
+ return add_registry(gsp, key, REGISTRY_TABLE_ENTRY_TYPE_DWORD,
+ &value, sizeof(u32));
+}
+
+static int add_registry_string(struct nvkm_gsp *gsp, const char *key, const char *value)
+{
+ return add_registry(gsp, key, REGISTRY_TABLE_ENTRY_TYPE_STRING,
+ value, strlen(value) + 1);
+}
+
+/**
+ * build_registry -- create the registry RPC data
+ * @gsp: gsp pointer
+ * @registry: pointer to the RPC payload to fill
+ *
+ * After all registry key/value pairs have been added, call this function to
+ * build the RPC.
+ *
+ * The registry RPC looks like this:
+ *
+ * +-----------------+
+ * |NvU32 size; |
+ * |NvU32 numEntries;|
+ * +-----------------+
+ * +----------------------------------------+
+ * |PACKED_REGISTRY_ENTRY |
+ * +----------------------------------------+
+ * |Null-terminated key (string) for entry 0|
+ * +----------------------------------------+
+ * |Binary/string data value for entry 0 | (only if necessary)
+ * +----------------------------------------+
+ *
+ * +----------------------------------------+
+ * |PACKED_REGISTRY_ENTRY |
+ * +----------------------------------------+
+ * |Null-terminated key (string) for entry 1|
+ * +----------------------------------------+
+ * |Binary/string data value for entry 1 | (only if necessary)
+ * +----------------------------------------+
+ * ... (and so on, one copy for each entry)
+ *
+ *
+ * The 'data' field of an entry is either a 32-bit integer (for type DWORD)
+ * or an offset into the PACKED_REGISTRY_TABLE (for types BINARY and STRING).
+ *
+ * All memory allocated by add_registry() is released.
+ */
+static void build_registry(struct nvkm_gsp *gsp, PACKED_REGISTRY_TABLE *registry)
+{
+ struct registry_list_entry *reg, *n;
+ size_t str_offset;
+ unsigned int i = 0;
+
+ registry->numEntries = list_count_nodes(&gsp->registry_list);
+ str_offset = struct_size(registry, entries, registry->numEntries);
+
+ list_for_each_entry_safe(reg, n, &gsp->registry_list, head) {
+ registry->entries[i].type = reg->type;
+ registry->entries[i].length = reg->vlen;
+
+ /* Append the key name to the table */
+ registry->entries[i].nameOffset = str_offset;
+ memcpy((void *)registry + str_offset, reg->key, reg->klen);
+ str_offset += reg->klen;
+
+ switch (reg->type) {
+ case REGISTRY_TABLE_ENTRY_TYPE_DWORD:
+ registry->entries[i].data = reg->dword;
+ break;
+ case REGISTRY_TABLE_ENTRY_TYPE_BINARY:
+ case REGISTRY_TABLE_ENTRY_TYPE_STRING:
+ /* If the type is binary or string, also append the value */
+ memcpy((void *)registry + str_offset, reg->binary, reg->vlen);
+ registry->entries[i].data = str_offset;
+ str_offset += reg->vlen;
+ break;
+ default:
+ break;
+ }
+
+ i++;
+ list_del(&reg->head);
+ kfree(reg);
+ }
+
+ /* Double-check that we calculated the sizes correctly */
+ WARN_ON(gsp->registry_rpc_size != str_offset);
+
+ registry->size = gsp->registry_rpc_size;
+}
+
+/**
+ * clean_registry -- clean up registry memory in case of error
+ * @gsp: gsp pointer
+ *
+ * Call this function to clean up all memory allocated by add_registry()
+ * in case of error and build_registry() is not called.
+ */
+static void clean_registry(struct nvkm_gsp *gsp)
+{
+ struct registry_list_entry *reg, *n;
+
+ list_for_each_entry_safe(reg, n, &gsp->registry_list, head) {
+ list_del(&reg->head);
+ kfree(reg);
+ }
+
+ gsp->registry_rpc_size = sizeof(PACKED_REGISTRY_TABLE);
+}
+
+MODULE_PARM_DESC(NVreg_RegistryDwords,
+ "A semicolon-separated list of key=integer pairs of GSP-RM registry keys");
+static char *NVreg_RegistryDwords;
+module_param(NVreg_RegistryDwords, charp, 0400);
+
/* dword only */
struct nv_gsp_registry_entries {
const char *name;
u32 value;
};
+/**
+ * r535_registry_entries - required registry entries for GSP-RM
+ *
+ * This array lists registry entries that are required for GSP-RM to
+ * function correctly.
+ *
+ * RMSecBusResetEnable - enables PCI secondary bus reset
+ * RMForcePcieConfigSave - forces GSP-RM to preserve PCI configuration
+ * registers on any PCI reset.
+ */
static const struct nv_gsp_registry_entries r535_registry_entries[] = {
{ "RMSecBusResetEnable", 1 },
{ "RMForcePcieConfigSave", 1 },
};
#define NV_GSP_REG_NUM_ENTRIES ARRAY_SIZE(r535_registry_entries)
+/**
+ * strip - strips all characters in 'reject' from 's'
+ * @s: string to strip
+ * @reject: string of characters to remove
+ *
+ * 's' is modified.
+ *
+ * Returns the length of the new string.
+ */
+static size_t strip(char *s, const char *reject)
+{
+ char *p = s, *p2 = s;
+ size_t length = 0;
+ char c;
+
+ do {
+ while ((c = *p2) && strchr(reject, c))
+ p2++;
+
+ *p++ = c = *p2++;
+ length++;
+ } while (c);
+
+ return length;
+}
+
+/**
+ * r535_gsp_rpc_set_registry - build registry RPC and call GSP-RM
+ * @gsp: gsp pointer
+ *
+ * The GSP-RM registry is a set of key/value pairs that configure some aspects
+ * of GSP-RM. The keys are strings, and the values are 32-bit integers.
+ *
+ * The registry is built from a combination of a static hard-coded list (see
+ * above) and entries passed on the driver's command line.
+ */
static int
r535_gsp_rpc_set_registry(struct nvkm_gsp *gsp)
{
PACKED_REGISTRY_TABLE *rpc;
- char *strings;
- int str_offset;
- int i;
- size_t rpc_size = struct_size(rpc, entries, NV_GSP_REG_NUM_ENTRIES);
+ unsigned int i;
+ int ret;
- /* add strings + null terminator */
- for (i = 0; i < NV_GSP_REG_NUM_ENTRIES; i++)
- rpc_size += strlen(r535_registry_entries[i].name) + 1;
+ INIT_LIST_HEAD(&gsp->registry_list);
+ gsp->registry_rpc_size = sizeof(PACKED_REGISTRY_TABLE);
- rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_SET_REGISTRY, rpc_size);
- if (IS_ERR(rpc))
- return PTR_ERR(rpc);
+ for (i = 0; i < NV_GSP_REG_NUM_ENTRIES; i++) {
+ ret = add_registry_num(gsp, r535_registry_entries[i].name,
+ r535_registry_entries[i].value);
+ if (ret)
+ goto fail;
+ }
- rpc->numEntries = NV_GSP_REG_NUM_ENTRIES;
+ /*
+ * The NVreg_RegistryDwords parameter is a string of key=value
+ * pairs separated by semicolons. We need to extract and trim each
+ * substring, and then parse the substring to extract the key and
+ * value.
+ */
+ if (NVreg_RegistryDwords) {
+ char *p = kstrdup(NVreg_RegistryDwords, GFP_KERNEL);
+ char *start, *next = p, *equal;
+
+ if (!p) {
+ ret = -ENOMEM;
+ goto fail;
+ }
- str_offset = offsetof(typeof(*rpc), entries[NV_GSP_REG_NUM_ENTRIES]);
- strings = (char *)rpc + str_offset;
- for (i = 0; i < NV_GSP_REG_NUM_ENTRIES; i++) {
- int name_len = strlen(r535_registry_entries[i].name) + 1;
-
- rpc->entries[i].nameOffset = str_offset;
- rpc->entries[i].type = 1;
- rpc->entries[i].data = r535_registry_entries[i].value;
- rpc->entries[i].length = 4;
- memcpy(strings, r535_registry_entries[i].name, name_len);
- strings += name_len;
- str_offset += name_len;
+ /* Remove any whitespace from the parameter string */
+ strip(p, " \t\n");
+
+ while ((start = strsep(&next, ";"))) {
+ long value;
+
+ equal = strchr(start, '=');
+ if (!equal || equal == start || equal[1] == 0) {
+ nvkm_error(&gsp->subdev,
+ "ignoring invalid registry string '%s'\n",
+ start);
+ continue;
+ }
+
+ /* Truncate the key=value string to just key */
+ *equal = 0;
+
+ ret = kstrtol(equal + 1, 0, &value);
+ if (!ret) {
+ ret = add_registry_num(gsp, start, value);
+ } else {
+ /* Not a number, so treat it as a string */
+ ret = add_registry_string(gsp, start, equal + 1);
+ }
+
+ if (ret) {
+ nvkm_error(&gsp->subdev,
+ "ignoring invalid registry key/value '%s=%s'\n",
+ start, equal + 1);
+ continue;
+ }
+ }
+
+ kfree(p);
+ }
+
+ rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_SET_REGISTRY, gsp->registry_rpc_size);
+ if (IS_ERR(rpc)) {
+ ret = PTR_ERR(rpc);
+ goto fail;
}
- rpc->size = str_offset;
+
+ build_registry(gsp, rpc);
return nvkm_gsp_rpc_wr(gsp, rpc, false);
+
+fail:
+ clean_registry(gsp);
+ return ret;
}
#if defined(CONFIG_ACPI) && defined(CONFIG_X86)
diff --git a/drivers/gpu/drm/omapdrm/Kconfig b/drivers/gpu/drm/omapdrm/Kconfig
index 6c49270cb290..85ed92042b74 100644
--- a/drivers/gpu/drm/omapdrm/Kconfig
+++ b/drivers/gpu/drm/omapdrm/Kconfig
@@ -2,7 +2,7 @@
config DRM_OMAP
tristate "OMAP DRM"
depends on DRM && OF
- depends on ARCH_OMAP2PLUS
+ depends on ARCH_OMAP2PLUS || COMPILE_TEST
select DRM_KMS_HELPER
select FB_DMAMEM_HELPERS_DEFERRED if DRM_FBDEV_EMULATION
select VIDEOMODE_HELPERS
diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c
index 9ea0c64c26b5..fdae677558f3 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem.c
@@ -1023,8 +1023,8 @@ struct sg_table *omap_gem_get_sg(struct drm_gem_object *obj,
if (addr) {
for_each_sg(sgt->sgl, sg, count, i) {
- sg_set_page(sg, phys_to_page(addr), len,
- offset_in_page(addr));
+ sg_set_page(sg, pfn_to_page(__phys_to_pfn(addr)),
+ len, offset_in_page(addr));
sg_dma_address(sg) = addr;
sg_dma_len(sg) = len;
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 2ae0eb0638f3..bf4eadfe21cb 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -145,6 +145,15 @@ config DRM_PANEL_LVDS
handling of power supplies or control signals. It implements automatic
backlight handling if the panel is attached to a backlight controller.
+config DRM_PANEL_HIMAX_HX83102
+ tristate "Himax HX83102-based panels"
+ depends on OF
+ depends on DRM_MIPI_DSI
+ depends on BACKLIGHT_CLASS_DEVICE
+ help
+ Say Y if you want to enable support for panels based on the
+ Himax HX83102 controller.
+
config DRM_PANEL_HIMAX_HX83112A
tristate "Himax HX83112A-based DSI panel"
depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index f0203f6e02f4..051b75b3df7b 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_DRM_PANEL_EBBG_FT8719) += panel-ebbg-ft8719.o
obj-$(CONFIG_DRM_PANEL_ELIDA_KD35T133) += panel-elida-kd35t133.o
obj-$(CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02) += panel-feixin-k101-im2ba02.o
obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += panel-feiyang-fy07024di26a30d.o
+obj-$(CONFIG_DRM_PANEL_HIMAX_HX83102) += panel-himax-hx83102.o
obj-$(CONFIG_DRM_PANEL_HIMAX_HX83112A) += panel-himax-hx83112a.o
obj-$(CONFIG_DRM_PANEL_HIMAX_HX8394) += panel-himax-hx8394.o
obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o
diff --git a/drivers/gpu/drm/panel/panel-abt-y030xx067a.c b/drivers/gpu/drm/panel/panel-abt-y030xx067a.c
index 662c7bcbe6e5..4692c36fe217 100644
--- a/drivers/gpu/drm/panel/panel-abt-y030xx067a.c
+++ b/drivers/gpu/drm/panel/panel-abt-y030xx067a.c
@@ -381,4 +381,5 @@ module_spi_driver(y030xx067a_driver);
MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
MODULE_AUTHOR("Christophe Branchereau <cbranchereau@gmail.com>");
+MODULE_DESCRIPTION("Asia Better Technology Ltd. Y030XX067A IPS LCD panel driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/panel/panel-auo-a030jtn01.c b/drivers/gpu/drm/panel/panel-auo-a030jtn01.c
index 6c86ebf2cad7..77604d6a4e72 100644
--- a/drivers/gpu/drm/panel/panel-auo-a030jtn01.c
+++ b/drivers/gpu/drm/panel/panel-auo-a030jtn01.c
@@ -305,4 +305,5 @@ module_spi_driver(a030jtn01_driver);
MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
MODULE_AUTHOR("Christophe Branchereau <cbranchereau@gmail.com>");
+MODULE_DESCRIPTION("AU Optronics A030JTN01.0 TFT LCD panel driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/panel/panel-boe-himax8279d.c b/drivers/gpu/drm/panel/panel-boe-himax8279d.c
index e225840b0d67..df746baae301 100644
--- a/drivers/gpu/drm/panel/panel-boe-himax8279d.c
+++ b/drivers/gpu/drm/panel/panel-boe-himax8279d.c
@@ -47,9 +47,6 @@ struct panel_info {
struct gpio_desc *enable_gpio;
struct gpio_desc *pp33_gpio;
struct gpio_desc *pp18_gpio;
-
- bool prepared;
- bool enabled;
};
static inline struct panel_info *to_panel_info(struct drm_panel *panel)
@@ -86,17 +83,12 @@ static int boe_panel_disable(struct drm_panel *panel)
struct panel_info *pinfo = to_panel_info(panel);
int err;
- if (!pinfo->enabled)
- return 0;
-
err = mipi_dsi_dcs_set_display_off(pinfo->link);
if (err < 0) {
dev_err(panel->dev, "failed to set display off: %d\n", err);
return err;
}
- pinfo->enabled = false;
-
return 0;
}
@@ -105,9 +97,6 @@ static int boe_panel_unprepare(struct drm_panel *panel)
struct panel_info *pinfo = to_panel_info(panel);
int err;
- if (!pinfo->prepared)
- return 0;
-
err = mipi_dsi_dcs_set_display_off(pinfo->link);
if (err < 0)
dev_err(panel->dev, "failed to set display off: %d\n", err);
@@ -121,8 +110,6 @@ static int boe_panel_unprepare(struct drm_panel *panel)
disable_gpios(pinfo);
- pinfo->prepared = false;
-
return 0;
}
@@ -131,9 +118,6 @@ static int boe_panel_prepare(struct drm_panel *panel)
struct panel_info *pinfo = to_panel_info(panel);
int err;
- if (pinfo->prepared)
- return 0;
-
gpiod_set_value(pinfo->pp18_gpio, 1);
/* T1: 5ms - 6ms */
usleep_range(5000, 6000);
@@ -180,8 +164,6 @@ static int boe_panel_prepare(struct drm_panel *panel)
/* T7: 20ms - 21ms */
usleep_range(20000, 21000);
- pinfo->prepared = true;
-
return 0;
poweroff:
@@ -194,9 +176,6 @@ static int boe_panel_enable(struct drm_panel *panel)
struct panel_info *pinfo = to_panel_info(panel);
int ret;
- if (pinfo->enabled)
- return 0;
-
usleep_range(120000, 121000);
ret = mipi_dsi_dcs_set_display_on(pinfo->link);
@@ -205,8 +184,6 @@ static int boe_panel_enable(struct drm_panel *panel)
return ret;
}
- pinfo->enabled = true;
-
return 0;
}
@@ -917,14 +894,6 @@ static void panel_remove(struct mipi_dsi_device *dsi)
struct panel_info *pinfo = mipi_dsi_get_drvdata(dsi);
int err;
- err = boe_panel_disable(&pinfo->base);
- if (err < 0)
- dev_err(&dsi->dev, "failed to disable panel: %d\n", err);
-
- err = boe_panel_unprepare(&pinfo->base);
- if (err < 0)
- dev_err(&dsi->dev, "failed to unprepare panel: %d\n", err);
-
err = mipi_dsi_detach(dsi);
if (err < 0)
dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", err);
@@ -932,14 +901,6 @@ static void panel_remove(struct mipi_dsi_device *dsi)
drm_panel_remove(&pinfo->base);
}
-static void panel_shutdown(struct mipi_dsi_device *dsi)
-{
- struct panel_info *pinfo = mipi_dsi_get_drvdata(dsi);
-
- boe_panel_disable(&pinfo->base);
- boe_panel_unprepare(&pinfo->base);
-}
-
static struct mipi_dsi_driver panel_driver = {
.driver = {
.name = "panel-boe-himax8279d",
@@ -947,7 +908,6 @@ static struct mipi_dsi_driver panel_driver = {
},
.probe = panel_probe,
.remove = panel_remove,
- .shutdown = panel_shutdown,
};
module_mipi_dsi_driver(panel_driver);
diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
index 0ffe8f8c01de..ce919a980875 100644
--- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
+++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
@@ -17,6 +17,8 @@
#include <video/mipi_display.h>
+struct boe_panel;
+
struct panel_desc {
const struct drm_display_mode *modes;
unsigned int bpc;
@@ -32,7 +34,7 @@ struct panel_desc {
unsigned long mode_flags;
enum mipi_dsi_pixel_format format;
- const struct panel_init_cmd *init_cmds;
+ int (*init)(struct boe_panel *boe);
unsigned int lanes;
bool discharge_on_disable;
bool lp11_before_reset;
@@ -50,1409 +52,1351 @@ struct boe_panel {
struct regulator *avee;
struct regulator *avdd;
struct gpio_desc *enable_gpio;
-
- bool prepared;
};
-enum dsi_cmd_type {
- INIT_DCS_CMD,
- DELAY_CMD,
-};
+static int boe_tv110c9m_init(struct boe_panel *boe)
+{
+ struct mipi_dsi_multi_context ctx = { .dsi = boe->dsi };
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x20);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x05, 0xd9);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x78);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x08, 0x5a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0d, 0x63);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0e, 0x91);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0f, 0x73);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x95, 0xe6);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x96, 0xf0);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x30, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x6d, 0x66);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x75, 0xa2);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x77, 0x3b);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x00, 0x08, 0x00, 0x23, 0x00, 0x4d, 0x00, 0x6d,
+ 0x00, 0x89, 0x00, 0xa1, 0x00, 0xb6, 0x00, 0xc9);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x00, 0xda, 0x01, 0x13, 0x01, 0x3c, 0x01, 0x7e,
+ 0x01, 0xab, 0x01, 0xf7, 0x02, 0x2f, 0x02, 0x31);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb2, 0x02, 0x67, 0x02, 0xa6, 0x02, 0xd1, 0x03, 0x08,
+ 0x03, 0x2e, 0x03, 0x5b, 0x03, 0x6b, 0x03, 0x7b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x03, 0x8e, 0x03, 0xa2, 0x03, 0xb7, 0x03, 0xe7,
+ 0x03, 0xfd, 0x03, 0xff);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x00, 0x08, 0x00, 0x23, 0x00, 0x4d, 0x00, 0x6d,
+ 0x00, 0x89, 0x00, 0xa1, 0x00, 0xb6, 0x00, 0xc9);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, 0x00, 0xda, 0x01, 0x13, 0x01, 0x3c, 0x01, 0x7e,
+ 0x01, 0xab, 0x01, 0xf7, 0x02, 0x2f, 0x02, 0x31);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x02, 0x67, 0x02, 0xa6, 0x02, 0xd1, 0x03, 0x08,
+ 0x03, 0x2e, 0x03, 0x5b, 0x03, 0x6b, 0x03, 0x7b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb7, 0x03, 0x8e, 0x03, 0xa2, 0x03, 0xb7, 0x03, 0xe7,
+ 0x03, 0xfd, 0x03, 0xff);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x00, 0x08, 0x00, 0x23, 0x00, 0x4d, 0x00, 0x6d,
+ 0x00, 0x89, 0x00, 0xa1, 0x00, 0xb6, 0x00, 0xc9);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0x00, 0xda, 0x01, 0x13, 0x01, 0x3c, 0x01, 0x7e,
+ 0x01, 0xab, 0x01, 0xf7, 0x02, 0x2f, 0x02, 0x31);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x02, 0x67, 0x02, 0xa6, 0x02, 0xd1, 0x03, 0x08,
+ 0x03, 0x2e, 0x03, 0x5b, 0x03, 0x6b, 0x03, 0x7b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbb, 0x03, 0x8e, 0x03, 0xa2, 0x03, 0xb7, 0x03, 0xe7,
+ 0x03, 0xfd, 0x03, 0xff);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x21);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x45, 0x00, 0x65,
+ 0x00, 0x81, 0x00, 0x99, 0x00, 0xae, 0x00, 0xc1);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x00, 0xd2, 0x01, 0x0b, 0x01, 0x34, 0x01, 0x76,
+ 0x01, 0xa3, 0x01, 0xef, 0x02, 0x27, 0x02, 0x29);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb2, 0x02, 0x5f, 0x02, 0x9e, 0x02, 0xc9, 0x03, 0x00,
+ 0x03, 0x26, 0x03, 0x53, 0x03, 0x63, 0x03, 0x73);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x03, 0x86, 0x03, 0x9a, 0x03, 0xaf, 0x03, 0xdf,
+ 0x03, 0xf5, 0x03, 0xe0);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x45, 0x00, 0x65,
+ 0x00, 0x81, 0x00, 0x99, 0x00, 0xae, 0x00, 0xc1);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, 0x00, 0xd2, 0x01, 0x0b, 0x01, 0x34, 0x01, 0x76,
+ 0x01, 0xa3, 0x01, 0xef, 0x02, 0x27, 0x02, 0x29);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x02, 0x5f, 0x02, 0x9e, 0x02, 0xc9, 0x03, 0x00,
+ 0x03, 0x26, 0x03, 0x53, 0x03, 0x63, 0x03, 0x73);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb7, 0x03, 0x86, 0x03, 0x9a, 0x03, 0xaf, 0x03, 0xdf,
+ 0x03, 0xf5, 0x03, 0xe0);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x45, 0x00, 0x65,
+ 0x00, 0x81, 0x00, 0x99, 0x00, 0xae, 0x00, 0xc1);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0x00, 0xd2, 0x01, 0x0b, 0x01, 0x34, 0x01, 0x76,
+ 0x01, 0xa3, 0x01, 0xef, 0x02, 0x27, 0x02, 0x29);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x02, 0x5f, 0x02, 0x9e, 0x02, 0xc9, 0x03, 0x00,
+ 0x03, 0x26, 0x03, 0x53, 0x03, 0x63, 0x03, 0x73);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbb, 0x03, 0x86, 0x03, 0x9a, 0x03, 0xaf, 0x03, 0xdf,
+ 0x03, 0xf5, 0x03, 0xe0);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x24);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x01, 0x00);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x02, 0x1c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x03, 0x1c);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x04, 0x1d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x05, 0x1d);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x06, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x04);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x08, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x09, 0x0f);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0a, 0x0e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0b, 0x0e);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0c, 0x0d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0d, 0x0d);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0e, 0x0c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0f, 0x0c);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x10, 0x08);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x11, 0x08);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x12, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x13, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x14, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x15, 0x00);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x16, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x17, 0x00);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x18, 0x1c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x19, 0x1c);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1a, 0x1d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1b, 0x1d);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1c, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1d, 0x04);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1e, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1f, 0x0f);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x0e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x21, 0x0e);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x22, 0x0d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x23, 0x0d);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x24, 0x0c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x0c);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x26, 0x08);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x27, 0x08);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x28, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x29, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2b, 0x00);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2d, 0x20);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2f, 0x0a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x30, 0x44);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x33, 0x0c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x34, 0x32);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x37, 0x44);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x38, 0x40);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x39, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3a, 0x5d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3b, 0x60);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3d, 0x42);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3f, 0x06);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x43, 0x06);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x47, 0x66);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x4a, 0x5d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x4b, 0x60);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x4c, 0x91);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x4d, 0x21);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x4e, 0x43);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x51, 0x12);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x52, 0x34);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x55, 0x82, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x56, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x58, 0x21);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x59, 0x30);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5a, 0x60);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5b, 0x50);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5e, 0x00, 0x06);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5f, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x65, 0x82);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x7e, 0x20);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x7f, 0x3c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x82, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x97, 0xc0);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x05, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x05, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x91, 0x44);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x92, 0xa9);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x93, 0x1a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x94, 0x96);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd7, 0x55);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xda, 0x0a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xde, 0x08);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdb, 0x05);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdc, 0xa9);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdd, 0x22);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdf, 0x05);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe0, 0xa9);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe1, 0x05);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe2, 0xa9);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe3, 0x05);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe4, 0xa9);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe5, 0x05);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe6, 0xa9);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5c, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5d, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x8d, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x8e, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, 0x90);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x25);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x05, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x19, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1f, 0x60);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x50);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x26, 0x60);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x27, 0x50);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x33, 0x60);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x34, 0x50);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3f, 0xe0);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x40, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x44, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x45, 0x40);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x48, 0x60);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x49, 0x50);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5b, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5c, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5d, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5e, 0xd0);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x61, 0x60);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x62, 0x50);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xf1, 0x10);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x2a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x64, 0x16);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x67, 0x16);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x6a, 0x16);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x70, 0x30);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xa2, 0xf3);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xa3, 0xff);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xa4, 0xff);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xa5, 0xff);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd6, 0x08);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x26);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0xa1);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x02, 0x31);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x04, 0x28);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x06, 0x30);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0c, 0x16);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0d, 0x0d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0f, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x11, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x12, 0x50);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x13, 0x56);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x14, 0x57);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x15, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x16, 0x10);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x17, 0xa0);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x18, 0x86);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x19, 0x0d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1a, 0x7f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1b, 0x0c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1c, 0xbf);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x22, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x23, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x0d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2b, 0x7f);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1d, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1e, 0x65);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1f, 0x65);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x24, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x65);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2f, 0x05);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x30, 0x65);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x31, 0x05);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x32, 0x7d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x39, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3a, 0x65);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x33, 0x11);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x34, 0x78);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x35, 0x16);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x9e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x4e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x00);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xa9, 0x49);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xaa, 0x4b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xab, 0x48);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xac, 0x43);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xad, 0x40);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xae, 0x50);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xaf, 0x44);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x54);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x4e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb2, 0x4d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x4c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x41);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, 0x47);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x53);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb7, 0x3e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x51);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0x3c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x3b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbb, 0x46);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbc, 0x45);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbd, 0x55);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbe, 0x3d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbf, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x52);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x4a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0x39);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0x4f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0x3a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0x42);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x27);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x56, 0x06);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x58, 0x80);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x59, 0x75);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5a, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5b, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5c, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5d, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5e, 0x20);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5f, 0x10);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x60, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x61, 0x2e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x62, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x63, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x64, 0x43);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x65, 0x2d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x66, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x67, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x68, 0x44);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x78, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0x00);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x2a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x22, 0x2f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x23, 0x08);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x24, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x65);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x26, 0xf8);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x27, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x28, 0x1a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x29, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x1a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2b, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2d, 0x1a);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x23);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0x80);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x00);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0xe0);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x14, 0x60);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x16, 0xc0);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0xf0);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3a, 0x08);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x10);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x20);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x18, 0x40);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x10);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x35, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x51, 0x00, 0xff);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x53, 0x24);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x55, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbb, 0x13);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3b, 0x03, 0x96, 0x1a, 0x04, 0x04);
+
+ mipi_dsi_msleep(&ctx, 100);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x11);
+
+ mipi_dsi_msleep(&ctx, 200);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x29);
+
+ mipi_dsi_msleep(&ctx, 100);
-struct panel_init_cmd {
- enum dsi_cmd_type type;
- size_t len;
- const char *data;
+ return 0;
};
-#define _INIT_DCS_CMD(...) { \
- .type = INIT_DCS_CMD, \
- .len = sizeof((char[]){__VA_ARGS__}), \
- .data = (char[]){__VA_ARGS__} }
-
-#define _INIT_DELAY_CMD(...) { \
- .type = DELAY_CMD,\
- .len = sizeof((char[]){__VA_ARGS__}), \
- .data = (char[]){__VA_ARGS__} }
-
-static const struct panel_init_cmd boe_tv110c9m_init_cmd[] = {
- _INIT_DCS_CMD(0xFF, 0x20),
- _INIT_DCS_CMD(0xFB, 0x01),
- _INIT_DCS_CMD(0x05, 0xD9),
- _INIT_DCS_CMD(0x07, 0x78),
- _INIT_DCS_CMD(0x08, 0x5A),
- _INIT_DCS_CMD(0x0D, 0x63),
- _INIT_DCS_CMD(0x0E, 0x91),
- _INIT_DCS_CMD(0x0F, 0x73),
- _INIT_DCS_CMD(0x95, 0xE6),
- _INIT_DCS_CMD(0x96, 0xF0),
- _INIT_DCS_CMD(0x30, 0x00),
- _INIT_DCS_CMD(0x6D, 0x66),
- _INIT_DCS_CMD(0x75, 0xA2),
- _INIT_DCS_CMD(0x77, 0x3B),
+static int inx_hj110iz_init(struct boe_panel *boe)
+{
+ struct mipi_dsi_multi_context ctx = { .dsi = boe->dsi };
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x20);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x05, 0xd1);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x06, 0xc0);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x87);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x08, 0x4b);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0d, 0x63);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0e, 0x91);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0f, 0x69);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x94, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x95, 0xf5);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x96, 0xf5);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x9d, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x9e, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x69, 0x98);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x75, 0xa2);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x77, 0xb3);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x58, 0x43);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x24);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x91, 0x44);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x92, 0x4c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x94, 0x86);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x60, 0x96);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x61, 0xd0);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x63, 0x70);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0xca);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x01, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x02, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x03, 0x29);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x04, 0x22);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x05, 0x22);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x06, 0x0b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x1d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x08, 0x1c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x09, 0x05);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0a, 0x08);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0b, 0x09);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0c, 0x0a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0d, 0x0c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0e, 0x0d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0f, 0x0e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x10, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x11, 0x10);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x12, 0x11);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x13, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x14, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x15, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x16, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x17, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x18, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x19, 0x29);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1a, 0x22);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1b, 0x22);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1c, 0x0b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1d, 0x1d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1e, 0x1c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1f, 0x05);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x08);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x21, 0x09);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x22, 0x0a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x23, 0x0c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x24, 0x0d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x0e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x26, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x27, 0x10);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x28, 0x11);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x29, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2b, 0x03);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2f, 0x0a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x30, 0x35);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x37, 0xa7);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x39, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3a, 0x46);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3b, 0x32);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3d, 0x12);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3f, 0x33);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x40, 0x31);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x41, 0x40);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x42, 0x42);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x47, 0x77);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x48, 0x77);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x4a, 0x45);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x4b, 0x45);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x4c, 0x14);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x4d, 0x21);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x4e, 0x43);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x4f, 0x65);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x55, 0x06);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x56, 0x06);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x58, 0x21);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x59, 0x70);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5a, 0x46);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5b, 0x32);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5c, 0x88);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5e, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5f, 0x00);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x7a, 0xff);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x7b, 0xff);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x7c, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x7d, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x7e, 0x20);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x7f, 0x3c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x80, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x81, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x82, 0x08);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x97, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0x10);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd7, 0x55);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd8, 0x55);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd9, 0x23);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xda, 0x05);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdc, 0x65);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdd, 0x55);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xde, 0x27);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdf, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe0, 0x65);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe1, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe2, 0x65);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe3, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe4, 0x65);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe5, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe6, 0x65);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe7, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe8, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe9, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xea, 0x65);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xeb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xee, 0x65);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xef, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xf0, 0x65);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x05, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x05, 0x00, 0x00);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x25);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x05, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xf1, 0x10);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1e, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1f, 0x46);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x32);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x26, 0x46);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x27, 0x32);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3f, 0x80);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x40, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x43, 0x00);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x44, 0x46);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x45, 0x46);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x48, 0x46);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x49, 0x32);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5b, 0x80);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5c, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5d, 0x46);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5e, 0x32);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5f, 0x46);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x60, 0x32);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x61, 0x46);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x62, 0x32);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x68, 0x0c);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x6c, 0x0d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x6e, 0x0d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x78, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x79, 0xc5);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x7a, 0x0c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x7b, 0xb0);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x26);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0xa1);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x02, 0x31);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0a, 0xf4);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x04, 0x50);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x06, 0x30);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0c, 0x16);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0d, 0x0d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0f, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x11, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x12, 0x50);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x13, 0x40);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x14, 0x58);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x15, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x16, 0x10);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x17, 0xa0);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x18, 0x86);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x22, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x23, 0x00);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x19, 0x0e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1a, 0x31);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1b, 0x0d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1c, 0x29);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x0e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2b, 0x31);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1d, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1e, 0x62);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1f, 0x62);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2f, 0x06);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x30, 0x62);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x31, 0x06);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x32, 0x7f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x33, 0x11);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x34, 0x89);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x35, 0x67);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x39, 0x0b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3a, 0x62);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3b, 0x06);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x89);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x4e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xa9, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xaa, 0x3e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xab, 0x3d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xac, 0x3c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xad, 0x3b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xae, 0x3a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xaf, 0x39);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x38);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x27);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd0, 0x11);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd1, 0x54);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xde, 0x43);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdf, 0x02);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x18);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x56, 0x06);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x58, 0x80);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x59, 0x78);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5a, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5b, 0x18);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5c, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5d, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5e, 0x20);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5f, 0x10);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x60, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x61, 0x1c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x62, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x63, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x64, 0x44);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x65, 0x1b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x66, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x67, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x68, 0x44);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x98, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x9b, 0xbe);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xab, 0x14);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbc, 0x08);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbd, 0x28);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x2a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x22, 0x2f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x23, 0x08);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x24, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x62);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x26, 0xf8);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x27, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x28, 0x1a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x29, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x1a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2b, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2d, 0x1a);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x64, 0x96);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x65, 0x10);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x66, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x67, 0x96);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x68, 0x10);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x69, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x6a, 0x96);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x6b, 0x10);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x6c, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x70, 0x92);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x71, 0x10);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x72, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x79, 0x96);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x7a, 0x10);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x88, 0x96);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x89, 0x10);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xa2, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xa3, 0x30);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xa4, 0xc0);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xa5, 0x03);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe8, 0x00);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x97, 0x3c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x98, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x99, 0x95);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x9a, 0x06);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x9b, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x9c, 0x0b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x9d, 0x0a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x9e, 0x90);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x25);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x13, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x14, 0xd7);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdb, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdc, 0xd7);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x17, 0xcf);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x19, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1b, 0x5b);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x20);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x24, 0x00, 0x38,
+ 0x00, 0x4c, 0x00, 0x5e, 0x00, 0x6f, 0x00, 0x7e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x00, 0x8c, 0x00, 0xbe, 0x00, 0xe5, 0x01, 0x27,
+ 0x01, 0x58, 0x01, 0xa8, 0x01, 0xe8, 0x01, 0xea);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb2, 0x02, 0x28, 0x02, 0x71, 0x02, 0x9e, 0x02, 0xda,
+ 0x03, 0x00, 0x03, 0x31, 0x03, 0x40, 0x03, 0x51);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x03, 0x62, 0x03, 0x75, 0x03, 0x89, 0x03, 0x9c,
+ 0x03, 0xaa, 0x03, 0xb2);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x27, 0x00, 0x3d,
+ 0x00, 0x52, 0x00, 0x64, 0x00, 0x75, 0x00, 0x84);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, 0x00, 0x93, 0x00, 0xc5, 0x00, 0xec, 0x01, 0x2c,
+ 0x01, 0x5d, 0x01, 0xac, 0x01, 0xec, 0x01, 0xee);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x02, 0x2b, 0x02, 0x73, 0x02, 0xa0, 0x02, 0xdb,
+ 0x03, 0x01, 0x03, 0x31, 0x03, 0x41, 0x03, 0x51);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb7, 0x03, 0x63, 0x03, 0x75, 0x03, 0x89, 0x03, 0x9c,
+ 0x03, 0xaa, 0x03, 0xb2);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x2a, 0x00, 0x40,
+ 0x00, 0x56, 0x00, 0x68, 0x00, 0x7a, 0x00, 0x89);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0x00, 0x98, 0x00, 0xc9, 0x00, 0xf1, 0x01, 0x30,
+ 0x01, 0x61, 0x01, 0xb0, 0x01, 0xef, 0x01, 0xf1);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x02, 0x2e, 0x02, 0x76, 0x02, 0xa3, 0x02, 0xdd,
+ 0x03, 0x02, 0x03, 0x32, 0x03, 0x42, 0x03, 0x53);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbb, 0x03, 0x66, 0x03, 0x75, 0x03, 0x89, 0x03, 0x9c,
+ 0x03, 0xaa, 0x03, 0xb2);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x21);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x24, 0x00, 0x38,
+ 0x00, 0x4c, 0x00, 0x5e, 0x00, 0x6f, 0x00, 0x7e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x00, 0x8c, 0x00, 0xbe, 0x00, 0xe5, 0x01, 0x27,
+ 0x01, 0x58, 0x01, 0xa8, 0x01, 0xe8, 0x01, 0xea);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb2, 0x02, 0x28, 0x02, 0x71, 0x02, 0x9e, 0x02, 0xda,
+ 0x03, 0x00, 0x03, 0x31, 0x03, 0x40, 0x03, 0x51);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x03, 0x62, 0x03, 0x77, 0x03, 0x90, 0x03, 0xac,
+ 0x03, 0xca, 0x03, 0xda);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x27, 0x00, 0x3d,
+ 0x00, 0x52, 0x00, 0x64, 0x00, 0x75, 0x00, 0x84);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, 0x00, 0x93, 0x00, 0xc5, 0x00, 0xec, 0x01, 0x2c,
+ 0x01, 0x5d, 0x01, 0xac, 0x01, 0xec, 0x01, 0xee);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x02, 0x2b, 0x02, 0x73, 0x02, 0xa0, 0x02, 0xdb,
+ 0x03, 0x01, 0x03, 0x31, 0x03, 0x41, 0x03, 0x51);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb7, 0x03, 0x63, 0x03, 0x77, 0x03, 0x90, 0x03, 0xac,
+ 0x03, 0xca, 0x03, 0xda);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x2a, 0x00, 0x40,
+ 0x00, 0x56, 0x00, 0x68, 0x00, 0x7a, 0x00, 0x89);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0x00, 0x98, 0x00, 0xc9, 0x00, 0xf1, 0x01, 0x30,
+ 0x01, 0x61, 0x01, 0xb0, 0x01, 0xef, 0x01, 0xf1);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x02, 0x2e, 0x02, 0x76, 0x02, 0xa3, 0x02, 0xdd,
+ 0x03, 0x02, 0x03, 0x32, 0x03, 0x42, 0x03, 0x53);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbb, 0x03, 0x66, 0x03, 0x77, 0x03, 0x90, 0x03, 0xac,
+ 0x03, 0xca, 0x03, 0xda);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0xf0);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3a, 0x08);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x10);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0x01);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x20);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x18, 0x40);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x10);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xff, 0x10);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x35, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3b, 0x03, 0xae, 0x1a, 0x04, 0x04);
+
+ mipi_dsi_msleep(&ctx, 100);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x11);
+
+ mipi_dsi_msleep(&ctx, 200);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x29);
+
+ mipi_dsi_msleep(&ctx, 100);
- _INIT_DCS_CMD(0xB0, 0x00, 0x08, 0x00, 0x23, 0x00, 0x4D, 0x00, 0x6D, 0x00, 0x89, 0x00, 0xA1, 0x00, 0xB6, 0x00, 0xC9),
- _INIT_DCS_CMD(0xB1, 0x00, 0xDA, 0x01, 0x13, 0x01, 0x3C, 0x01, 0x7E, 0x01, 0xAB, 0x01, 0xF7, 0x02, 0x2F, 0x02, 0x31),
- _INIT_DCS_CMD(0xB2, 0x02, 0x67, 0x02, 0xA6, 0x02, 0xD1, 0x03, 0x08, 0x03, 0x2E, 0x03, 0x5B, 0x03, 0x6B, 0x03, 0x7B),
- _INIT_DCS_CMD(0xB3, 0x03, 0x8E, 0x03, 0xA2, 0x03, 0xB7, 0x03, 0xE7, 0x03, 0xFD, 0x03, 0xFF),
-
- _INIT_DCS_CMD(0xB4, 0x00, 0x08, 0x00, 0x23, 0x00, 0x4D, 0x00, 0x6D, 0x00, 0x89, 0x00, 0xA1, 0x00, 0xB6, 0x00, 0xC9),
- _INIT_DCS_CMD(0xB5, 0x00, 0xDA, 0x01, 0x13, 0x01, 0x3C, 0x01, 0x7E, 0x01, 0xAB, 0x01, 0xF7, 0x02, 0x2F, 0x02, 0x31),
- _INIT_DCS_CMD(0xB6, 0x02, 0x67, 0x02, 0xA6, 0x02, 0xD1, 0x03, 0x08, 0x03, 0x2E, 0x03, 0x5B, 0x03, 0x6B, 0x03, 0x7B),
- _INIT_DCS_CMD(0xB7, 0x03, 0x8E, 0x03, 0xA2, 0x03, 0xB7, 0x03, 0xE7, 0x03, 0xFD, 0x03, 0xFF),
- _INIT_DCS_CMD(0xB8, 0x00, 0x08, 0x00, 0x23, 0x00, 0x4D, 0x00, 0x6D, 0x00, 0x89, 0x00, 0xA1, 0x00, 0xB6, 0x00, 0xC9),
- _INIT_DCS_CMD(0xB9, 0x00, 0xDA, 0x01, 0x13, 0x01, 0x3C, 0x01, 0x7E, 0x01, 0xAB, 0x01, 0xF7, 0x02, 0x2F, 0x02, 0x31),
- _INIT_DCS_CMD(0xBA, 0x02, 0x67, 0x02, 0xA6, 0x02, 0xD1, 0x03, 0x08, 0x03, 0x2E, 0x03, 0x5B, 0x03, 0x6B, 0x03, 0x7B),
- _INIT_DCS_CMD(0xBB, 0x03, 0x8E, 0x03, 0xA2, 0x03, 0xB7, 0x03, 0xE7, 0x03, 0xFD, 0x03, 0xFF),
-
- _INIT_DCS_CMD(0xFF, 0x21),
- _INIT_DCS_CMD(0xFB, 0x01),
-
- _INIT_DCS_CMD(0xB0, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x45, 0x00, 0x65, 0x00, 0x81, 0x00, 0x99, 0x00, 0xAE, 0x00, 0xC1),
- _INIT_DCS_CMD(0xB1, 0x00, 0xD2, 0x01, 0x0B, 0x01, 0x34, 0x01, 0x76, 0x01, 0xA3, 0x01, 0xEF, 0x02, 0x27, 0x02, 0x29),
- _INIT_DCS_CMD(0xB2, 0x02, 0x5F, 0x02, 0x9E, 0x02, 0xC9, 0x03, 0x00, 0x03, 0x26, 0x03, 0x53, 0x03, 0x63, 0x03, 0x73),
-
- _INIT_DCS_CMD(0xB3, 0x03, 0x86, 0x03, 0x9A, 0x03, 0xAF, 0x03, 0xDF, 0x03, 0xF5, 0x03, 0xE0),
- _INIT_DCS_CMD(0xB4, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x45, 0x00, 0x65, 0x00, 0x81, 0x00, 0x99, 0x00, 0xAE, 0x00, 0xC1),
- _INIT_DCS_CMD(0xB5, 0x00, 0xD2, 0x01, 0x0B, 0x01, 0x34, 0x01, 0x76, 0x01, 0xA3, 0x01, 0xEF, 0x02, 0x27, 0x02, 0x29),
- _INIT_DCS_CMD(0xB6, 0x02, 0x5F, 0x02, 0x9E, 0x02, 0xC9, 0x03, 0x00, 0x03, 0x26, 0x03, 0x53, 0x03, 0x63, 0x03, 0x73),
- _INIT_DCS_CMD(0xB7, 0x03, 0x86, 0x03, 0x9A, 0x03, 0xAF, 0x03, 0xDF, 0x03, 0xF5, 0x03, 0xE0),
-
- _INIT_DCS_CMD(0xB8, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x45, 0x00, 0x65, 0x00, 0x81, 0x00, 0x99, 0x00, 0xAE, 0x00, 0xC1),
- _INIT_DCS_CMD(0xB9, 0x00, 0xD2, 0x01, 0x0B, 0x01, 0x34, 0x01, 0x76, 0x01, 0xA3, 0x01, 0xEF, 0x02, 0x27, 0x02, 0x29),
- _INIT_DCS_CMD(0xBA, 0x02, 0x5F, 0x02, 0x9E, 0x02, 0xC9, 0x03, 0x00, 0x03, 0x26, 0x03, 0x53, 0x03, 0x63, 0x03, 0x73),
-
- _INIT_DCS_CMD(0xBB, 0x03, 0x86, 0x03, 0x9A, 0x03, 0xAF, 0x03, 0xDF, 0x03, 0xF5, 0x03, 0xE0),
- _INIT_DCS_CMD(0xFF, 0x24),
- _INIT_DCS_CMD(0xFB, 0x01),
-
- _INIT_DCS_CMD(0x00, 0x00),
- _INIT_DCS_CMD(0x01, 0x00),
-
- _INIT_DCS_CMD(0x02, 0x1C),
- _INIT_DCS_CMD(0x03, 0x1C),
-
- _INIT_DCS_CMD(0x04, 0x1D),
- _INIT_DCS_CMD(0x05, 0x1D),
-
- _INIT_DCS_CMD(0x06, 0x04),
- _INIT_DCS_CMD(0x07, 0x04),
-
- _INIT_DCS_CMD(0x08, 0x0F),
- _INIT_DCS_CMD(0x09, 0x0F),
-
- _INIT_DCS_CMD(0x0A, 0x0E),
- _INIT_DCS_CMD(0x0B, 0x0E),
-
- _INIT_DCS_CMD(0x0C, 0x0D),
- _INIT_DCS_CMD(0x0D, 0x0D),
-
- _INIT_DCS_CMD(0x0E, 0x0C),
- _INIT_DCS_CMD(0x0F, 0x0C),
-
- _INIT_DCS_CMD(0x10, 0x08),
- _INIT_DCS_CMD(0x11, 0x08),
-
- _INIT_DCS_CMD(0x12, 0x00),
- _INIT_DCS_CMD(0x13, 0x00),
- _INIT_DCS_CMD(0x14, 0x00),
- _INIT_DCS_CMD(0x15, 0x00),
-
- _INIT_DCS_CMD(0x16, 0x00),
- _INIT_DCS_CMD(0x17, 0x00),
-
- _INIT_DCS_CMD(0x18, 0x1C),
- _INIT_DCS_CMD(0x19, 0x1C),
-
- _INIT_DCS_CMD(0x1A, 0x1D),
- _INIT_DCS_CMD(0x1B, 0x1D),
-
- _INIT_DCS_CMD(0x1C, 0x04),
- _INIT_DCS_CMD(0x1D, 0x04),
-
- _INIT_DCS_CMD(0x1E, 0x0F),
- _INIT_DCS_CMD(0x1F, 0x0F),
-
- _INIT_DCS_CMD(0x20, 0x0E),
- _INIT_DCS_CMD(0x21, 0x0E),
-
- _INIT_DCS_CMD(0x22, 0x0D),
- _INIT_DCS_CMD(0x23, 0x0D),
-
- _INIT_DCS_CMD(0x24, 0x0C),
- _INIT_DCS_CMD(0x25, 0x0C),
-
- _INIT_DCS_CMD(0x26, 0x08),
- _INIT_DCS_CMD(0x27, 0x08),
-
- _INIT_DCS_CMD(0x28, 0x00),
- _INIT_DCS_CMD(0x29, 0x00),
- _INIT_DCS_CMD(0x2A, 0x00),
- _INIT_DCS_CMD(0x2B, 0x00),
-
- _INIT_DCS_CMD(0x2D, 0x20),
- _INIT_DCS_CMD(0x2F, 0x0A),
- _INIT_DCS_CMD(0x30, 0x44),
- _INIT_DCS_CMD(0x33, 0x0C),
- _INIT_DCS_CMD(0x34, 0x32),
-
- _INIT_DCS_CMD(0x37, 0x44),
- _INIT_DCS_CMD(0x38, 0x40),
- _INIT_DCS_CMD(0x39, 0x00),
- _INIT_DCS_CMD(0x3A, 0x5D),
- _INIT_DCS_CMD(0x3B, 0x60),
- _INIT_DCS_CMD(0x3D, 0x42),
- _INIT_DCS_CMD(0x3F, 0x06),
- _INIT_DCS_CMD(0x43, 0x06),
- _INIT_DCS_CMD(0x47, 0x66),
- _INIT_DCS_CMD(0x4A, 0x5D),
- _INIT_DCS_CMD(0x4B, 0x60),
- _INIT_DCS_CMD(0x4C, 0x91),
- _INIT_DCS_CMD(0x4D, 0x21),
- _INIT_DCS_CMD(0x4E, 0x43),
- _INIT_DCS_CMD(0x51, 0x12),
- _INIT_DCS_CMD(0x52, 0x34),
- _INIT_DCS_CMD(0x55, 0x82, 0x02),
- _INIT_DCS_CMD(0x56, 0x04),
- _INIT_DCS_CMD(0x58, 0x21),
- _INIT_DCS_CMD(0x59, 0x30),
- _INIT_DCS_CMD(0x5A, 0x60),
- _INIT_DCS_CMD(0x5B, 0x50),
- _INIT_DCS_CMD(0x5E, 0x00, 0x06),
- _INIT_DCS_CMD(0x5F, 0x00),
- _INIT_DCS_CMD(0x65, 0x82),
- _INIT_DCS_CMD(0x7E, 0x20),
- _INIT_DCS_CMD(0x7F, 0x3C),
- _INIT_DCS_CMD(0x82, 0x04),
- _INIT_DCS_CMD(0x97, 0xC0),
-
- _INIT_DCS_CMD(0xB6, 0x05, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x05, 0x00, 0x00),
- _INIT_DCS_CMD(0x91, 0x44),
- _INIT_DCS_CMD(0x92, 0xA9),
- _INIT_DCS_CMD(0x93, 0x1A),
- _INIT_DCS_CMD(0x94, 0x96),
- _INIT_DCS_CMD(0xD7, 0x55),
- _INIT_DCS_CMD(0xDA, 0x0A),
- _INIT_DCS_CMD(0xDE, 0x08),
- _INIT_DCS_CMD(0xDB, 0x05),
- _INIT_DCS_CMD(0xDC, 0xA9),
- _INIT_DCS_CMD(0xDD, 0x22),
-
- _INIT_DCS_CMD(0xDF, 0x05),
- _INIT_DCS_CMD(0xE0, 0xA9),
- _INIT_DCS_CMD(0xE1, 0x05),
- _INIT_DCS_CMD(0xE2, 0xA9),
- _INIT_DCS_CMD(0xE3, 0x05),
- _INIT_DCS_CMD(0xE4, 0xA9),
- _INIT_DCS_CMD(0xE5, 0x05),
- _INIT_DCS_CMD(0xE6, 0xA9),
- _INIT_DCS_CMD(0x5C, 0x00),
- _INIT_DCS_CMD(0x5D, 0x00),
- _INIT_DCS_CMD(0x8D, 0x00),
- _INIT_DCS_CMD(0x8E, 0x00),
- _INIT_DCS_CMD(0xB5, 0x90),
- _INIT_DCS_CMD(0xFF, 0x25),
- _INIT_DCS_CMD(0xFB, 0x01),
- _INIT_DCS_CMD(0x05, 0x00),
- _INIT_DCS_CMD(0x19, 0x07),
- _INIT_DCS_CMD(0x1F, 0x60),
- _INIT_DCS_CMD(0x20, 0x50),
- _INIT_DCS_CMD(0x26, 0x60),
- _INIT_DCS_CMD(0x27, 0x50),
- _INIT_DCS_CMD(0x33, 0x60),
- _INIT_DCS_CMD(0x34, 0x50),
- _INIT_DCS_CMD(0x3F, 0xE0),
- _INIT_DCS_CMD(0x40, 0x00),
- _INIT_DCS_CMD(0x44, 0x00),
- _INIT_DCS_CMD(0x45, 0x40),
- _INIT_DCS_CMD(0x48, 0x60),
- _INIT_DCS_CMD(0x49, 0x50),
- _INIT_DCS_CMD(0x5B, 0x00),
- _INIT_DCS_CMD(0x5C, 0x00),
- _INIT_DCS_CMD(0x5D, 0x00),
- _INIT_DCS_CMD(0x5E, 0xD0),
- _INIT_DCS_CMD(0x61, 0x60),
- _INIT_DCS_CMD(0x62, 0x50),
- _INIT_DCS_CMD(0xF1, 0x10),
- _INIT_DCS_CMD(0xFF, 0x2A),
- _INIT_DCS_CMD(0xFB, 0x01),
-
- _INIT_DCS_CMD(0x64, 0x16),
- _INIT_DCS_CMD(0x67, 0x16),
- _INIT_DCS_CMD(0x6A, 0x16),
-
- _INIT_DCS_CMD(0x70, 0x30),
-
- _INIT_DCS_CMD(0xA2, 0xF3),
- _INIT_DCS_CMD(0xA3, 0xFF),
- _INIT_DCS_CMD(0xA4, 0xFF),
- _INIT_DCS_CMD(0xA5, 0xFF),
-
- _INIT_DCS_CMD(0xD6, 0x08),
-
- _INIT_DCS_CMD(0xFF, 0x26),
- _INIT_DCS_CMD(0xFB, 0x01),
- _INIT_DCS_CMD(0x00, 0xA1),
-
- _INIT_DCS_CMD(0x02, 0x31),
- _INIT_DCS_CMD(0x04, 0x28),
- _INIT_DCS_CMD(0x06, 0x30),
- _INIT_DCS_CMD(0x0C, 0x16),
- _INIT_DCS_CMD(0x0D, 0x0D),
- _INIT_DCS_CMD(0x0F, 0x00),
- _INIT_DCS_CMD(0x11, 0x00),
- _INIT_DCS_CMD(0x12, 0x50),
- _INIT_DCS_CMD(0x13, 0x56),
- _INIT_DCS_CMD(0x14, 0x57),
- _INIT_DCS_CMD(0x15, 0x00),
- _INIT_DCS_CMD(0x16, 0x10),
- _INIT_DCS_CMD(0x17, 0xA0),
- _INIT_DCS_CMD(0x18, 0x86),
- _INIT_DCS_CMD(0x19, 0x0D),
- _INIT_DCS_CMD(0x1A, 0x7F),
- _INIT_DCS_CMD(0x1B, 0x0C),
- _INIT_DCS_CMD(0x1C, 0xBF),
- _INIT_DCS_CMD(0x22, 0x00),
- _INIT_DCS_CMD(0x23, 0x00),
- _INIT_DCS_CMD(0x2A, 0x0D),
- _INIT_DCS_CMD(0x2B, 0x7F),
-
- _INIT_DCS_CMD(0x1D, 0x00),
- _INIT_DCS_CMD(0x1E, 0x65),
- _INIT_DCS_CMD(0x1F, 0x65),
- _INIT_DCS_CMD(0x24, 0x00),
- _INIT_DCS_CMD(0x25, 0x65),
- _INIT_DCS_CMD(0x2F, 0x05),
- _INIT_DCS_CMD(0x30, 0x65),
- _INIT_DCS_CMD(0x31, 0x05),
- _INIT_DCS_CMD(0x32, 0x7D),
- _INIT_DCS_CMD(0x39, 0x00),
- _INIT_DCS_CMD(0x3A, 0x65),
- _INIT_DCS_CMD(0x20, 0x01),
- _INIT_DCS_CMD(0x33, 0x11),
- _INIT_DCS_CMD(0x34, 0x78),
- _INIT_DCS_CMD(0x35, 0x16),
- _INIT_DCS_CMD(0xC8, 0x04),
- _INIT_DCS_CMD(0xC9, 0x9E),
- _INIT_DCS_CMD(0xCA, 0x4E),
- _INIT_DCS_CMD(0xCB, 0x00),
-
- _INIT_DCS_CMD(0xA9, 0x49),
- _INIT_DCS_CMD(0xAA, 0x4B),
- _INIT_DCS_CMD(0xAB, 0x48),
- _INIT_DCS_CMD(0xAC, 0x43),
- _INIT_DCS_CMD(0xAD, 0x40),
- _INIT_DCS_CMD(0xAE, 0x50),
- _INIT_DCS_CMD(0xAF, 0x44),
- _INIT_DCS_CMD(0xB0, 0x54),
- _INIT_DCS_CMD(0xB1, 0x4E),
- _INIT_DCS_CMD(0xB2, 0x4D),
- _INIT_DCS_CMD(0xB3, 0x4C),
- _INIT_DCS_CMD(0xB4, 0x41),
- _INIT_DCS_CMD(0xB5, 0x47),
- _INIT_DCS_CMD(0xB6, 0x53),
- _INIT_DCS_CMD(0xB7, 0x3E),
- _INIT_DCS_CMD(0xB8, 0x51),
- _INIT_DCS_CMD(0xB9, 0x3C),
- _INIT_DCS_CMD(0xBA, 0x3B),
- _INIT_DCS_CMD(0xBB, 0x46),
- _INIT_DCS_CMD(0xBC, 0x45),
- _INIT_DCS_CMD(0xBD, 0x55),
- _INIT_DCS_CMD(0xBE, 0x3D),
- _INIT_DCS_CMD(0xBF, 0x3F),
- _INIT_DCS_CMD(0xC0, 0x52),
- _INIT_DCS_CMD(0xC1, 0x4A),
- _INIT_DCS_CMD(0xC2, 0x39),
- _INIT_DCS_CMD(0xC3, 0x4F),
- _INIT_DCS_CMD(0xC4, 0x3A),
- _INIT_DCS_CMD(0xC5, 0x42),
- _INIT_DCS_CMD(0xFF, 0x27),
- _INIT_DCS_CMD(0xFB, 0x01),
-
- _INIT_DCS_CMD(0x56, 0x06),
- _INIT_DCS_CMD(0x58, 0x80),
- _INIT_DCS_CMD(0x59, 0x75),
- _INIT_DCS_CMD(0x5A, 0x00),
- _INIT_DCS_CMD(0x5B, 0x02),
- _INIT_DCS_CMD(0x5C, 0x00),
- _INIT_DCS_CMD(0x5D, 0x00),
- _INIT_DCS_CMD(0x5E, 0x20),
- _INIT_DCS_CMD(0x5F, 0x10),
- _INIT_DCS_CMD(0x60, 0x00),
- _INIT_DCS_CMD(0x61, 0x2E),
- _INIT_DCS_CMD(0x62, 0x00),
- _INIT_DCS_CMD(0x63, 0x01),
- _INIT_DCS_CMD(0x64, 0x43),
- _INIT_DCS_CMD(0x65, 0x2D),
- _INIT_DCS_CMD(0x66, 0x00),
- _INIT_DCS_CMD(0x67, 0x01),
- _INIT_DCS_CMD(0x68, 0x44),
-
- _INIT_DCS_CMD(0x00, 0x00),
- _INIT_DCS_CMD(0x78, 0x00),
- _INIT_DCS_CMD(0xC3, 0x00),
-
- _INIT_DCS_CMD(0xFF, 0x2A),
- _INIT_DCS_CMD(0xFB, 0x01),
-
- _INIT_DCS_CMD(0x22, 0x2F),
- _INIT_DCS_CMD(0x23, 0x08),
-
- _INIT_DCS_CMD(0x24, 0x00),
- _INIT_DCS_CMD(0x25, 0x65),
- _INIT_DCS_CMD(0x26, 0xF8),
- _INIT_DCS_CMD(0x27, 0x00),
- _INIT_DCS_CMD(0x28, 0x1A),
- _INIT_DCS_CMD(0x29, 0x00),
- _INIT_DCS_CMD(0x2A, 0x1A),
- _INIT_DCS_CMD(0x2B, 0x00),
- _INIT_DCS_CMD(0x2D, 0x1A),
-
- _INIT_DCS_CMD(0xFF, 0x23),
- _INIT_DCS_CMD(0xFB, 0x01),
-
- _INIT_DCS_CMD(0x00, 0x80),
- _INIT_DCS_CMD(0x07, 0x00),
-
- _INIT_DCS_CMD(0xFF, 0xE0),
- _INIT_DCS_CMD(0xFB, 0x01),
- _INIT_DCS_CMD(0x14, 0x60),
- _INIT_DCS_CMD(0x16, 0xC0),
-
- _INIT_DCS_CMD(0xFF, 0xF0),
- _INIT_DCS_CMD(0xFB, 0x01),
- _INIT_DCS_CMD(0x3A, 0x08),
-
- _INIT_DCS_CMD(0xFF, 0x10),
- _INIT_DCS_CMD(0xFB, 0x01),
- _INIT_DCS_CMD(0xB9, 0x01),
- _INIT_DCS_CMD(0xFF, 0x20),
- _INIT_DCS_CMD(0xFB, 0x01),
- _INIT_DCS_CMD(0x18, 0x40),
-
- _INIT_DCS_CMD(0xFF, 0x10),
- _INIT_DCS_CMD(0xFB, 0x01),
- _INIT_DCS_CMD(0xB9, 0x02),
- _INIT_DCS_CMD(0x35, 0x00),
- _INIT_DCS_CMD(0x51, 0x00, 0xFF),
- _INIT_DCS_CMD(0x53, 0x24),
- _INIT_DCS_CMD(0x55, 0x00),
- _INIT_DCS_CMD(0xBB, 0x13),
- _INIT_DCS_CMD(0x3B, 0x03, 0x96, 0x1A, 0x04, 0x04),
- _INIT_DELAY_CMD(100),
- _INIT_DCS_CMD(0x11),
- _INIT_DELAY_CMD(200),
- _INIT_DCS_CMD(0x29),
- _INIT_DELAY_CMD(100),
- {},
+ return 0;
};
-static const struct panel_init_cmd inx_hj110iz_init_cmd[] = {
- _INIT_DCS_CMD(0xFF, 0x20),
- _INIT_DCS_CMD(0xFB, 0x01),
- _INIT_DCS_CMD(0x05, 0xD1),
- _INIT_DCS_CMD(0x06, 0xC0),
- _INIT_DCS_CMD(0x07, 0x87),
- _INIT_DCS_CMD(0x08, 0x4B),
-
- _INIT_DCS_CMD(0x0D, 0x63),
- _INIT_DCS_CMD(0x0E, 0x91),
- _INIT_DCS_CMD(0x0F, 0x69),
- _INIT_DCS_CMD(0x94, 0x00),
- _INIT_DCS_CMD(0x95, 0xF5),
- _INIT_DCS_CMD(0x96, 0xF5),
- _INIT_DCS_CMD(0x9D, 0x00),
- _INIT_DCS_CMD(0x9E, 0x00),
- _INIT_DCS_CMD(0x69, 0x98),
- _INIT_DCS_CMD(0x75, 0xA2),
- _INIT_DCS_CMD(0x77, 0xB3),
-
- _INIT_DCS_CMD(0x58, 0x43),
- _INIT_DCS_CMD(0xFF, 0x24),
- _INIT_DCS_CMD(0xFB, 0x01),
- _INIT_DCS_CMD(0x91, 0x44),
- _INIT_DCS_CMD(0x92, 0x4C),
- _INIT_DCS_CMD(0x94, 0x86),
- _INIT_DCS_CMD(0x60, 0x96),
- _INIT_DCS_CMD(0x61, 0xD0),
- _INIT_DCS_CMD(0x63, 0x70),
- _INIT_DCS_CMD(0xC2, 0xCA),
-
- _INIT_DCS_CMD(0x00, 0x03),
- _INIT_DCS_CMD(0x01, 0x03),
- _INIT_DCS_CMD(0x02, 0x03),
- _INIT_DCS_CMD(0x03, 0x29),
- _INIT_DCS_CMD(0x04, 0x22),
- _INIT_DCS_CMD(0x05, 0x22),
- _INIT_DCS_CMD(0x06, 0x0B),
- _INIT_DCS_CMD(0x07, 0x1D),
- _INIT_DCS_CMD(0x08, 0x1C),
- _INIT_DCS_CMD(0x09, 0x05),
- _INIT_DCS_CMD(0x0A, 0x08),
- _INIT_DCS_CMD(0x0B, 0x09),
- _INIT_DCS_CMD(0x0C, 0x0A),
- _INIT_DCS_CMD(0x0D, 0x0C),
- _INIT_DCS_CMD(0x0E, 0x0D),
- _INIT_DCS_CMD(0x0F, 0x0E),
- _INIT_DCS_CMD(0x10, 0x0F),
- _INIT_DCS_CMD(0x11, 0x10),
- _INIT_DCS_CMD(0x12, 0x11),
- _INIT_DCS_CMD(0x13, 0x04),
- _INIT_DCS_CMD(0x14, 0x00),
- _INIT_DCS_CMD(0x15, 0x03),
- _INIT_DCS_CMD(0x16, 0x03),
- _INIT_DCS_CMD(0x17, 0x03),
- _INIT_DCS_CMD(0x18, 0x03),
- _INIT_DCS_CMD(0x19, 0x29),
- _INIT_DCS_CMD(0x1A, 0x22),
- _INIT_DCS_CMD(0x1B, 0x22),
- _INIT_DCS_CMD(0x1C, 0x0B),
- _INIT_DCS_CMD(0x1D, 0x1D),
- _INIT_DCS_CMD(0x1E, 0x1C),
- _INIT_DCS_CMD(0x1F, 0x05),
- _INIT_DCS_CMD(0x20, 0x08),
- _INIT_DCS_CMD(0x21, 0x09),
- _INIT_DCS_CMD(0x22, 0x0A),
- _INIT_DCS_CMD(0x23, 0x0C),
- _INIT_DCS_CMD(0x24, 0x0D),
- _INIT_DCS_CMD(0x25, 0x0E),
- _INIT_DCS_CMD(0x26, 0x0F),
- _INIT_DCS_CMD(0x27, 0x10),
- _INIT_DCS_CMD(0x28, 0x11),
- _INIT_DCS_CMD(0x29, 0x04),
- _INIT_DCS_CMD(0x2A, 0x00),
- _INIT_DCS_CMD(0x2B, 0x03),
-
- _INIT_DCS_CMD(0x2F, 0x0A),
- _INIT_DCS_CMD(0x30, 0x35),
- _INIT_DCS_CMD(0x37, 0xA7),
- _INIT_DCS_CMD(0x39, 0x00),
- _INIT_DCS_CMD(0x3A, 0x46),
- _INIT_DCS_CMD(0x3B, 0x32),
- _INIT_DCS_CMD(0x3D, 0x12),
-
- _INIT_DCS_CMD(0x3F, 0x33),
- _INIT_DCS_CMD(0x40, 0x31),
- _INIT_DCS_CMD(0x41, 0x40),
- _INIT_DCS_CMD(0x42, 0x42),
- _INIT_DCS_CMD(0x47, 0x77),
- _INIT_DCS_CMD(0x48, 0x77),
- _INIT_DCS_CMD(0x4A, 0x45),
- _INIT_DCS_CMD(0x4B, 0x45),
- _INIT_DCS_CMD(0x4C, 0x14),
-
- _INIT_DCS_CMD(0x4D, 0x21),
- _INIT_DCS_CMD(0x4E, 0x43),
- _INIT_DCS_CMD(0x4F, 0x65),
- _INIT_DCS_CMD(0x55, 0x06),
- _INIT_DCS_CMD(0x56, 0x06),
- _INIT_DCS_CMD(0x58, 0x21),
- _INIT_DCS_CMD(0x59, 0x70),
- _INIT_DCS_CMD(0x5A, 0x46),
- _INIT_DCS_CMD(0x5B, 0x32),
- _INIT_DCS_CMD(0x5C, 0x88),
- _INIT_DCS_CMD(0x5E, 0x00, 0x00),
- _INIT_DCS_CMD(0x5F, 0x00),
-
- _INIT_DCS_CMD(0x7A, 0xFF),
- _INIT_DCS_CMD(0x7B, 0xFF),
- _INIT_DCS_CMD(0x7C, 0x00),
- _INIT_DCS_CMD(0x7D, 0x00),
- _INIT_DCS_CMD(0x7E, 0x20),
- _INIT_DCS_CMD(0x7F, 0x3C),
- _INIT_DCS_CMD(0x80, 0x00),
- _INIT_DCS_CMD(0x81, 0x00),
- _INIT_DCS_CMD(0x82, 0x08),
- _INIT_DCS_CMD(0x97, 0x02),
- _INIT_DCS_CMD(0xC5, 0x10),
-
- _INIT_DCS_CMD(0xD7, 0x55),
- _INIT_DCS_CMD(0xD8, 0x55),
- _INIT_DCS_CMD(0xD9, 0x23),
- _INIT_DCS_CMD(0xDA, 0x05),
- _INIT_DCS_CMD(0xDB, 0x01),
- _INIT_DCS_CMD(0xDC, 0x65),
- _INIT_DCS_CMD(0xDD, 0x55),
- _INIT_DCS_CMD(0xDE, 0x27),
- _INIT_DCS_CMD(0xDF, 0x01),
- _INIT_DCS_CMD(0xE0, 0x65),
- _INIT_DCS_CMD(0xE1, 0x01),
- _INIT_DCS_CMD(0xE2, 0x65),
- _INIT_DCS_CMD(0xE3, 0x01),
- _INIT_DCS_CMD(0xE4, 0x65),
- _INIT_DCS_CMD(0xE5, 0x01),
- _INIT_DCS_CMD(0xE6, 0x65),
- _INIT_DCS_CMD(0xE7, 0x00),
- _INIT_DCS_CMD(0xE8, 0x00),
- _INIT_DCS_CMD(0xE9, 0x01),
- _INIT_DCS_CMD(0xEA, 0x65),
- _INIT_DCS_CMD(0xEB, 0x01),
- _INIT_DCS_CMD(0xEE, 0x65),
- _INIT_DCS_CMD(0xEF, 0x01),
- _INIT_DCS_CMD(0xF0, 0x65),
- _INIT_DCS_CMD(0xB6, 0x05, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x05, 0x00, 0x00),
-
- _INIT_DCS_CMD(0xFF, 0x25),
-
- _INIT_DCS_CMD(0xFB, 0x01),
- _INIT_DCS_CMD(0x05, 0x00),
- _INIT_DCS_CMD(0xF1, 0x10),
-
- _INIT_DCS_CMD(0x1E, 0x00),
- _INIT_DCS_CMD(0x1F, 0x46),
- _INIT_DCS_CMD(0x20, 0x32),
-
- _INIT_DCS_CMD(0x25, 0x00),
- _INIT_DCS_CMD(0x26, 0x46),
- _INIT_DCS_CMD(0x27, 0x32),
-
- _INIT_DCS_CMD(0x3F, 0x80),
- _INIT_DCS_CMD(0x40, 0x00),
- _INIT_DCS_CMD(0x43, 0x00),
-
- _INIT_DCS_CMD(0x44, 0x46),
- _INIT_DCS_CMD(0x45, 0x46),
-
- _INIT_DCS_CMD(0x48, 0x46),
- _INIT_DCS_CMD(0x49, 0x32),
-
- _INIT_DCS_CMD(0x5B, 0x80),
-
- _INIT_DCS_CMD(0x5C, 0x00),
- _INIT_DCS_CMD(0x5D, 0x46),
- _INIT_DCS_CMD(0x5E, 0x32),
-
- _INIT_DCS_CMD(0x5F, 0x46),
- _INIT_DCS_CMD(0x60, 0x32),
-
- _INIT_DCS_CMD(0x61, 0x46),
- _INIT_DCS_CMD(0x62, 0x32),
- _INIT_DCS_CMD(0x68, 0x0C),
-
- _INIT_DCS_CMD(0x6C, 0x0D),
- _INIT_DCS_CMD(0x6E, 0x0D),
- _INIT_DCS_CMD(0x78, 0x00),
- _INIT_DCS_CMD(0x79, 0xC5),
- _INIT_DCS_CMD(0x7A, 0x0C),
- _INIT_DCS_CMD(0x7B, 0xB0),
-
- _INIT_DCS_CMD(0xFF, 0x26),
- _INIT_DCS_CMD(0xFB, 0x01),
-
- _INIT_DCS_CMD(0x00, 0xA1),
- _INIT_DCS_CMD(0x02, 0x31),
- _INIT_DCS_CMD(0x0A, 0xF4),
- _INIT_DCS_CMD(0x04, 0x50),
- _INIT_DCS_CMD(0x06, 0x30),
- _INIT_DCS_CMD(0x0C, 0x16),
- _INIT_DCS_CMD(0x0D, 0x0D),
- _INIT_DCS_CMD(0x0F, 0x00),
- _INIT_DCS_CMD(0x11, 0x00),
- _INIT_DCS_CMD(0x12, 0x50),
- _INIT_DCS_CMD(0x13, 0x40),
- _INIT_DCS_CMD(0x14, 0x58),
- _INIT_DCS_CMD(0x15, 0x00),
- _INIT_DCS_CMD(0x16, 0x10),
- _INIT_DCS_CMD(0x17, 0xA0),
- _INIT_DCS_CMD(0x18, 0x86),
- _INIT_DCS_CMD(0x22, 0x00),
- _INIT_DCS_CMD(0x23, 0x00),
-
- _INIT_DCS_CMD(0x19, 0x0E),
- _INIT_DCS_CMD(0x1A, 0x31),
- _INIT_DCS_CMD(0x1B, 0x0D),
- _INIT_DCS_CMD(0x1C, 0x29),
- _INIT_DCS_CMD(0x2A, 0x0E),
- _INIT_DCS_CMD(0x2B, 0x31),
-
- _INIT_DCS_CMD(0x1D, 0x00),
- _INIT_DCS_CMD(0x1E, 0x62),
- _INIT_DCS_CMD(0x1F, 0x62),
-
- _INIT_DCS_CMD(0x2F, 0x06),
- _INIT_DCS_CMD(0x30, 0x62),
- _INIT_DCS_CMD(0x31, 0x06),
- _INIT_DCS_CMD(0x32, 0x7F),
- _INIT_DCS_CMD(0x33, 0x11),
- _INIT_DCS_CMD(0x34, 0x89),
- _INIT_DCS_CMD(0x35, 0x67),
-
- _INIT_DCS_CMD(0x39, 0x0B),
- _INIT_DCS_CMD(0x3A, 0x62),
- _INIT_DCS_CMD(0x3B, 0x06),
-
- _INIT_DCS_CMD(0xC8, 0x04),
- _INIT_DCS_CMD(0xC9, 0x89),
- _INIT_DCS_CMD(0xCA, 0x4E),
- _INIT_DCS_CMD(0xCB, 0x00),
- _INIT_DCS_CMD(0xA9, 0x3F),
- _INIT_DCS_CMD(0xAA, 0x3E),
- _INIT_DCS_CMD(0xAB, 0x3D),
- _INIT_DCS_CMD(0xAC, 0x3C),
- _INIT_DCS_CMD(0xAD, 0x3B),
- _INIT_DCS_CMD(0xAE, 0x3A),
- _INIT_DCS_CMD(0xAF, 0x39),
- _INIT_DCS_CMD(0xB0, 0x38),
-
- _INIT_DCS_CMD(0xFF, 0x27),
- _INIT_DCS_CMD(0xFB, 0x01),
-
- _INIT_DCS_CMD(0xD0, 0x11),
- _INIT_DCS_CMD(0xD1, 0x54),
- _INIT_DCS_CMD(0xDE, 0x43),
- _INIT_DCS_CMD(0xDF, 0x02),
-
- _INIT_DCS_CMD(0xC0, 0x18),
- _INIT_DCS_CMD(0xC1, 0x00),
- _INIT_DCS_CMD(0xC2, 0x00),
- _INIT_DCS_CMD(0x00, 0x00),
- _INIT_DCS_CMD(0xC3, 0x00),
- _INIT_DCS_CMD(0x56, 0x06),
-
- _INIT_DCS_CMD(0x58, 0x80),
- _INIT_DCS_CMD(0x59, 0x78),
- _INIT_DCS_CMD(0x5A, 0x00),
- _INIT_DCS_CMD(0x5B, 0x18),
- _INIT_DCS_CMD(0x5C, 0x00),
- _INIT_DCS_CMD(0x5D, 0x01),
- _INIT_DCS_CMD(0x5E, 0x20),
- _INIT_DCS_CMD(0x5F, 0x10),
- _INIT_DCS_CMD(0x60, 0x00),
- _INIT_DCS_CMD(0x61, 0x1C),
- _INIT_DCS_CMD(0x62, 0x00),
- _INIT_DCS_CMD(0x63, 0x01),
- _INIT_DCS_CMD(0x64, 0x44),
- _INIT_DCS_CMD(0x65, 0x1B),
- _INIT_DCS_CMD(0x66, 0x00),
- _INIT_DCS_CMD(0x67, 0x01),
- _INIT_DCS_CMD(0x68, 0x44),
-
- _INIT_DCS_CMD(0x98, 0x01),
- _INIT_DCS_CMD(0xB4, 0x03),
- _INIT_DCS_CMD(0x9B, 0xBE),
-
- _INIT_DCS_CMD(0xAB, 0x14),
- _INIT_DCS_CMD(0xBC, 0x08),
- _INIT_DCS_CMD(0xBD, 0x28),
-
- _INIT_DCS_CMD(0xFF, 0x2A),
- _INIT_DCS_CMD(0xFB, 0x01),
- _INIT_DCS_CMD(0x22, 0x2F),
- _INIT_DCS_CMD(0x23, 0x08),
-
- _INIT_DCS_CMD(0x24, 0x00),
- _INIT_DCS_CMD(0x25, 0x62),
- _INIT_DCS_CMD(0x26, 0xF8),
- _INIT_DCS_CMD(0x27, 0x00),
- _INIT_DCS_CMD(0x28, 0x1A),
- _INIT_DCS_CMD(0x29, 0x00),
- _INIT_DCS_CMD(0x2A, 0x1A),
- _INIT_DCS_CMD(0x2B, 0x00),
- _INIT_DCS_CMD(0x2D, 0x1A),
-
- _INIT_DCS_CMD(0x64, 0x96),
- _INIT_DCS_CMD(0x65, 0x10),
- _INIT_DCS_CMD(0x66, 0x00),
- _INIT_DCS_CMD(0x67, 0x96),
- _INIT_DCS_CMD(0x68, 0x10),
- _INIT_DCS_CMD(0x69, 0x00),
- _INIT_DCS_CMD(0x6A, 0x96),
- _INIT_DCS_CMD(0x6B, 0x10),
- _INIT_DCS_CMD(0x6C, 0x00),
- _INIT_DCS_CMD(0x70, 0x92),
- _INIT_DCS_CMD(0x71, 0x10),
- _INIT_DCS_CMD(0x72, 0x00),
- _INIT_DCS_CMD(0x79, 0x96),
- _INIT_DCS_CMD(0x7A, 0x10),
- _INIT_DCS_CMD(0x88, 0x96),
- _INIT_DCS_CMD(0x89, 0x10),
-
- _INIT_DCS_CMD(0xA2, 0x3F),
- _INIT_DCS_CMD(0xA3, 0x30),
- _INIT_DCS_CMD(0xA4, 0xC0),
- _INIT_DCS_CMD(0xA5, 0x03),
-
- _INIT_DCS_CMD(0xE8, 0x00),
-
- _INIT_DCS_CMD(0x97, 0x3C),
- _INIT_DCS_CMD(0x98, 0x02),
- _INIT_DCS_CMD(0x99, 0x95),
- _INIT_DCS_CMD(0x9A, 0x06),
- _INIT_DCS_CMD(0x9B, 0x00),
- _INIT_DCS_CMD(0x9C, 0x0B),
- _INIT_DCS_CMD(0x9D, 0x0A),
- _INIT_DCS_CMD(0x9E, 0x90),
-
- _INIT_DCS_CMD(0xFF, 0x25),
- _INIT_DCS_CMD(0x13, 0x02),
- _INIT_DCS_CMD(0x14, 0xD7),
- _INIT_DCS_CMD(0xDB, 0x02),
- _INIT_DCS_CMD(0xDC, 0xD7),
- _INIT_DCS_CMD(0x17, 0xCF),
- _INIT_DCS_CMD(0x19, 0x0F),
- _INIT_DCS_CMD(0x1B, 0x5B),
-
- _INIT_DCS_CMD(0xFF, 0x20),
-
- _INIT_DCS_CMD(0xB0, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x24, 0x00, 0x38, 0x00, 0x4C, 0x00, 0x5E, 0x00, 0x6F, 0x00, 0x7E),
- _INIT_DCS_CMD(0xB1, 0x00, 0x8C, 0x00, 0xBE, 0x00, 0xE5, 0x01, 0x27, 0x01, 0x58, 0x01, 0xA8, 0x01, 0xE8, 0x01, 0xEA),
- _INIT_DCS_CMD(0xB2, 0x02, 0x28, 0x02, 0x71, 0x02, 0x9E, 0x02, 0xDA, 0x03, 0x00, 0x03, 0x31, 0x03, 0x40, 0x03, 0x51),
- _INIT_DCS_CMD(0xB3, 0x03, 0x62, 0x03, 0x75, 0x03, 0x89, 0x03, 0x9C, 0x03, 0xAA, 0x03, 0xB2),
-
- _INIT_DCS_CMD(0xB4, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x27, 0x00, 0x3D, 0x00, 0x52, 0x00, 0x64, 0x00, 0x75, 0x00, 0x84),
- _INIT_DCS_CMD(0xB5, 0x00, 0x93, 0x00, 0xC5, 0x00, 0xEC, 0x01, 0x2C, 0x01, 0x5D, 0x01, 0xAC, 0x01, 0xEC, 0x01, 0xEE),
- _INIT_DCS_CMD(0xB6, 0x02, 0x2B, 0x02, 0x73, 0x02, 0xA0, 0x02, 0xDB, 0x03, 0x01, 0x03, 0x31, 0x03, 0x41, 0x03, 0x51),
- _INIT_DCS_CMD(0xB7, 0x03, 0x63, 0x03, 0x75, 0x03, 0x89, 0x03, 0x9C, 0x03, 0xAA, 0x03, 0xB2),
-
- _INIT_DCS_CMD(0xB8, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x2A, 0x00, 0x40, 0x00, 0x56, 0x00, 0x68, 0x00, 0x7A, 0x00, 0x89),
- _INIT_DCS_CMD(0xB9, 0x00, 0x98, 0x00, 0xC9, 0x00, 0xF1, 0x01, 0x30, 0x01, 0x61, 0x01, 0xB0, 0x01, 0xEF, 0x01, 0xF1),
- _INIT_DCS_CMD(0xBA, 0x02, 0x2E, 0x02, 0x76, 0x02, 0xA3, 0x02, 0xDD, 0x03, 0x02, 0x03, 0x32, 0x03, 0x42, 0x03, 0x53),
- _INIT_DCS_CMD(0xBB, 0x03, 0x66, 0x03, 0x75, 0x03, 0x89, 0x03, 0x9C, 0x03, 0xAA, 0x03, 0xB2),
-
- _INIT_DCS_CMD(0xFF, 0x21),
- _INIT_DCS_CMD(0xB0, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x24, 0x00, 0x38, 0x00, 0x4C, 0x00, 0x5E, 0x00, 0x6F, 0x00, 0x7E),
- _INIT_DCS_CMD(0xB1, 0x00, 0x8C, 0x00, 0xBE, 0x00, 0xE5, 0x01, 0x27, 0x01, 0x58, 0x01, 0xA8, 0x01, 0xE8, 0x01, 0xEA),
- _INIT_DCS_CMD(0xB2, 0x02, 0x28, 0x02, 0x71, 0x02, 0x9E, 0x02, 0xDA, 0x03, 0x00, 0x03, 0x31, 0x03, 0x40, 0x03, 0x51),
- _INIT_DCS_CMD(0xB3, 0x03, 0x62, 0x03, 0x77, 0x03, 0x90, 0x03, 0xAC, 0x03, 0xCA, 0x03, 0xDA),
-
- _INIT_DCS_CMD(0xB4, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x27, 0x00, 0x3D, 0x00, 0x52, 0x00, 0x64, 0x00, 0x75, 0x00, 0x84),
- _INIT_DCS_CMD(0xB5, 0x00, 0x93, 0x00, 0xC5, 0x00, 0xEC, 0x01, 0x2C, 0x01, 0x5D, 0x01, 0xAC, 0x01, 0xEC, 0x01, 0xEE),
- _INIT_DCS_CMD(0xB6, 0x02, 0x2B, 0x02, 0x73, 0x02, 0xA0, 0x02, 0xDB, 0x03, 0x01, 0x03, 0x31, 0x03, 0x41, 0x03, 0x51),
- _INIT_DCS_CMD(0xB7, 0x03, 0x63, 0x03, 0x77, 0x03, 0x90, 0x03, 0xAC, 0x03, 0xCA, 0x03, 0xDA),
-
- _INIT_DCS_CMD(0xB8, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x2A, 0x00, 0x40, 0x00, 0x56, 0x00, 0x68, 0x00, 0x7A, 0x00, 0x89),
- _INIT_DCS_CMD(0xB9, 0x00, 0x98, 0x00, 0xC9, 0x00, 0xF1, 0x01, 0x30, 0x01, 0x61, 0x01, 0xB0, 0x01, 0xEF, 0x01, 0xF1),
- _INIT_DCS_CMD(0xBA, 0x02, 0x2E, 0x02, 0x76, 0x02, 0xA3, 0x02, 0xDD, 0x03, 0x02, 0x03, 0x32, 0x03, 0x42, 0x03, 0x53),
- _INIT_DCS_CMD(0xBB, 0x03, 0x66, 0x03, 0x77, 0x03, 0x90, 0x03, 0xAC, 0x03, 0xCA, 0x03, 0xDA),
-
- _INIT_DCS_CMD(0xFF, 0xF0),
- _INIT_DCS_CMD(0xFB, 0x01),
- _INIT_DCS_CMD(0x3A, 0x08),
-
- _INIT_DCS_CMD(0xFF, 0x10),
- _INIT_DCS_CMD(0xB9, 0x01),
-
- _INIT_DCS_CMD(0xFF, 0x20),
-
- _INIT_DCS_CMD(0x18, 0x40),
- _INIT_DCS_CMD(0xFF, 0x10),
-
- _INIT_DCS_CMD(0xB9, 0x02),
- _INIT_DCS_CMD(0xFF, 0x10),
-
- _INIT_DCS_CMD(0xFB, 0x01),
- _INIT_DCS_CMD(0xB0, 0x01),
- _INIT_DCS_CMD(0x35, 0x00),
- _INIT_DCS_CMD(0x3B, 0x03, 0xAE, 0x1A, 0x04, 0x04),
- _INIT_DELAY_CMD(100),
- _INIT_DCS_CMD(0x11),
- _INIT_DELAY_CMD(200),
- _INIT_DCS_CMD(0x29),
- _INIT_DELAY_CMD(100),
- {},
-};
+static int boe_init(struct boe_panel *boe)
+{
+ struct mipi_dsi_multi_context ctx = { .dsi = boe->dsi };
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x05);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0xe5);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x52);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x88);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x8b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbf, 0x1a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0x0c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0x0c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe0, 0x26);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe1, 0x26);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdc, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdd, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcc, 0x26);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcd, 0x26);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd2, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd3, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe6, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe7, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0x09);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0x09);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd8, 0x0a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd9, 0x0a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0x0b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0x0b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd6, 0x0c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd7, 0x0c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x05);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x05);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd4, 0x06);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd5, 0x06);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xde, 0x08);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdf, 0x08);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x0d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0x17);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0x26);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0x31);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0x1c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc6, 0x2c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0x33);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0x31);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x37);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x37);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x37);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcc, 0x39);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcd, 0x2e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xce, 0x2f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcf, 0x2f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd0, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd2, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd3, 0x0d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd4, 0x17);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd5, 0x26);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd6, 0x31);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd7, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd8, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd9, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xda, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdb, 0x37);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdc, 0x37);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdd, 0x37);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xde, 0x39);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdf, 0x2e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe0, 0x2f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe1, 0x2f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe2, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0x0b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe7, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0x2a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xde, 0x2a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x43);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe4, 0xc0);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe5, 0x0d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x06);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0xa5);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0xa5);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd5, 0x32);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbc, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb2, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x25);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, 0x39);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x4e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb7, 0x72);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x97);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0xdc);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x22);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbb, 0xa4);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbc, 0x2b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbd, 0x2f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbe, 0xa9);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbf, 0x25);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x61);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x97);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0xb2);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0xcd);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0xd9);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0xe7);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc6, 0xf4);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0xfa);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0xfc);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x16);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcc, 0xaf);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcd, 0xff);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xce, 0xff);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x08);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb2, 0x05);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x11);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x24);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, 0x39);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x4f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb7, 0x72);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x98);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0xdc);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x23);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbb, 0xa6);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbc, 0x2c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbd, 0x30);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbe, 0xaa);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbf, 0x26);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x62);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x9b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0xb5);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0xcf);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0xdb);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0xe8);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc6, 0xf5);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0xfa);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0xfc);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x16);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcc, 0xaf);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcd, 0xff);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xce, 0xff);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x09);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb2, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x16);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x24);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, 0x3b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x4f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb7, 0x73);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x99);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0xe0);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x26);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbb, 0xad);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbc, 0x36);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbd, 0x3a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbe, 0xae);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbf, 0x2a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x66);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x9e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0xb8);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0xd1);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0xdd);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0xe9);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc6, 0xf6);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0xfa);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0xfc);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x16);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcc, 0xaf);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcd, 0xff);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xce, 0xff);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x0a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb2, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x25);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, 0x39);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x4e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb7, 0x72);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x97);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0xdc);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x22);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbb, 0xa4);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbc, 0x2b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbd, 0x2f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbe, 0xa9);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbf, 0x25);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x61);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x97);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0xb2);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0xcd);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0xd9);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0xe7);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc6, 0xf4);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0xfa);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0xfc);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x16);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcc, 0xaf);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcd, 0xff);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xce, 0xff);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x0b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb2, 0x05);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x11);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x24);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, 0x39);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x4f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb7, 0x72);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x98);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0xdc);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x23);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbb, 0xa6);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbc, 0x2c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbd, 0x30);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbe, 0xaa);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbf, 0x26);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x62);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x9b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0xb5);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0xcf);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0xdb);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0xe8);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc6, 0xf5);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0xfa);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0xfc);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x16);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcc, 0xaf);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcd, 0xff);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xce, 0xff);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x0c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb2, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x16);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb4, 0x24);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5, 0x3b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb6, 0x4f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb7, 0x73);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x99);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0xe0);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x26);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbb, 0xad);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbc, 0x36);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbd, 0x3a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbe, 0xae);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbf, 0x2a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x66);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x9e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0xb8);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0xd1);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0xdd);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0xe9);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc6, 0xf6);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0xfa);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0xfc);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x16);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcc, 0xaf);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcd, 0xff);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xce, 0xff);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb3, 0x08);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb8, 0x68);
+
+ mipi_dsi_msleep(&ctx, 150);
-static const struct panel_init_cmd boe_init_cmd[] = {
- _INIT_DCS_CMD(0xB0, 0x05),
- _INIT_DCS_CMD(0xB1, 0xE5),
- _INIT_DCS_CMD(0xB3, 0x52),
- _INIT_DCS_CMD(0xB0, 0x00),
- _INIT_DCS_CMD(0xB3, 0x88),
- _INIT_DCS_CMD(0xB0, 0x04),
- _INIT_DCS_CMD(0xB8, 0x00),
- _INIT_DCS_CMD(0xB0, 0x00),
- _INIT_DCS_CMD(0xB6, 0x03),
- _INIT_DCS_CMD(0xBA, 0x8B),
- _INIT_DCS_CMD(0xBF, 0x1A),
- _INIT_DCS_CMD(0xC0, 0x0F),
- _INIT_DCS_CMD(0xC2, 0x0C),
- _INIT_DCS_CMD(0xC3, 0x02),
- _INIT_DCS_CMD(0xC4, 0x0C),
- _INIT_DCS_CMD(0xC5, 0x02),
- _INIT_DCS_CMD(0xB0, 0x01),
- _INIT_DCS_CMD(0xE0, 0x26),
- _INIT_DCS_CMD(0xE1, 0x26),
- _INIT_DCS_CMD(0xDC, 0x00),
- _INIT_DCS_CMD(0xDD, 0x00),
- _INIT_DCS_CMD(0xCC, 0x26),
- _INIT_DCS_CMD(0xCD, 0x26),
- _INIT_DCS_CMD(0xC8, 0x00),
- _INIT_DCS_CMD(0xC9, 0x00),
- _INIT_DCS_CMD(0xD2, 0x03),
- _INIT_DCS_CMD(0xD3, 0x03),
- _INIT_DCS_CMD(0xE6, 0x04),
- _INIT_DCS_CMD(0xE7, 0x04),
- _INIT_DCS_CMD(0xC4, 0x09),
- _INIT_DCS_CMD(0xC5, 0x09),
- _INIT_DCS_CMD(0xD8, 0x0A),
- _INIT_DCS_CMD(0xD9, 0x0A),
- _INIT_DCS_CMD(0xC2, 0x0B),
- _INIT_DCS_CMD(0xC3, 0x0B),
- _INIT_DCS_CMD(0xD6, 0x0C),
- _INIT_DCS_CMD(0xD7, 0x0C),
- _INIT_DCS_CMD(0xC0, 0x05),
- _INIT_DCS_CMD(0xC1, 0x05),
- _INIT_DCS_CMD(0xD4, 0x06),
- _INIT_DCS_CMD(0xD5, 0x06),
- _INIT_DCS_CMD(0xCA, 0x07),
- _INIT_DCS_CMD(0xCB, 0x07),
- _INIT_DCS_CMD(0xDE, 0x08),
- _INIT_DCS_CMD(0xDF, 0x08),
- _INIT_DCS_CMD(0xB0, 0x02),
- _INIT_DCS_CMD(0xC0, 0x00),
- _INIT_DCS_CMD(0xC1, 0x0D),
- _INIT_DCS_CMD(0xC2, 0x17),
- _INIT_DCS_CMD(0xC3, 0x26),
- _INIT_DCS_CMD(0xC4, 0x31),
- _INIT_DCS_CMD(0xC5, 0x1C),
- _INIT_DCS_CMD(0xC6, 0x2C),
- _INIT_DCS_CMD(0xC7, 0x33),
- _INIT_DCS_CMD(0xC8, 0x31),
- _INIT_DCS_CMD(0xC9, 0x37),
- _INIT_DCS_CMD(0xCA, 0x37),
- _INIT_DCS_CMD(0xCB, 0x37),
- _INIT_DCS_CMD(0xCC, 0x39),
- _INIT_DCS_CMD(0xCD, 0x2E),
- _INIT_DCS_CMD(0xCE, 0x2F),
- _INIT_DCS_CMD(0xCF, 0x2F),
- _INIT_DCS_CMD(0xD0, 0x07),
- _INIT_DCS_CMD(0xD2, 0x00),
- _INIT_DCS_CMD(0xD3, 0x0D),
- _INIT_DCS_CMD(0xD4, 0x17),
- _INIT_DCS_CMD(0xD5, 0x26),
- _INIT_DCS_CMD(0xD6, 0x31),
- _INIT_DCS_CMD(0xD7, 0x3F),
- _INIT_DCS_CMD(0xD8, 0x3F),
- _INIT_DCS_CMD(0xD9, 0x3F),
- _INIT_DCS_CMD(0xDA, 0x3F),
- _INIT_DCS_CMD(0xDB, 0x37),
- _INIT_DCS_CMD(0xDC, 0x37),
- _INIT_DCS_CMD(0xDD, 0x37),
- _INIT_DCS_CMD(0xDE, 0x39),
- _INIT_DCS_CMD(0xDF, 0x2E),
- _INIT_DCS_CMD(0xE0, 0x2F),
- _INIT_DCS_CMD(0xE1, 0x2F),
- _INIT_DCS_CMD(0xE2, 0x07),
- _INIT_DCS_CMD(0xB0, 0x03),
- _INIT_DCS_CMD(0xC8, 0x0B),
- _INIT_DCS_CMD(0xC9, 0x07),
- _INIT_DCS_CMD(0xC3, 0x00),
- _INIT_DCS_CMD(0xE7, 0x00),
- _INIT_DCS_CMD(0xC5, 0x2A),
- _INIT_DCS_CMD(0xDE, 0x2A),
- _INIT_DCS_CMD(0xCA, 0x43),
- _INIT_DCS_CMD(0xC9, 0x07),
- _INIT_DCS_CMD(0xE4, 0xC0),
- _INIT_DCS_CMD(0xE5, 0x0D),
- _INIT_DCS_CMD(0xCB, 0x00),
- _INIT_DCS_CMD(0xB0, 0x06),
- _INIT_DCS_CMD(0xB8, 0xA5),
- _INIT_DCS_CMD(0xC0, 0xA5),
- _INIT_DCS_CMD(0xC7, 0x0F),
- _INIT_DCS_CMD(0xD5, 0x32),
- _INIT_DCS_CMD(0xB8, 0x00),
- _INIT_DCS_CMD(0xC0, 0x00),
- _INIT_DCS_CMD(0xBC, 0x00),
- _INIT_DCS_CMD(0xB0, 0x07),
- _INIT_DCS_CMD(0xB1, 0x00),
- _INIT_DCS_CMD(0xB2, 0x02),
- _INIT_DCS_CMD(0xB3, 0x0F),
- _INIT_DCS_CMD(0xB4, 0x25),
- _INIT_DCS_CMD(0xB5, 0x39),
- _INIT_DCS_CMD(0xB6, 0x4E),
- _INIT_DCS_CMD(0xB7, 0x72),
- _INIT_DCS_CMD(0xB8, 0x97),
- _INIT_DCS_CMD(0xB9, 0xDC),
- _INIT_DCS_CMD(0xBA, 0x22),
- _INIT_DCS_CMD(0xBB, 0xA4),
- _INIT_DCS_CMD(0xBC, 0x2B),
- _INIT_DCS_CMD(0xBD, 0x2F),
- _INIT_DCS_CMD(0xBE, 0xA9),
- _INIT_DCS_CMD(0xBF, 0x25),
- _INIT_DCS_CMD(0xC0, 0x61),
- _INIT_DCS_CMD(0xC1, 0x97),
- _INIT_DCS_CMD(0xC2, 0xB2),
- _INIT_DCS_CMD(0xC3, 0xCD),
- _INIT_DCS_CMD(0xC4, 0xD9),
- _INIT_DCS_CMD(0xC5, 0xE7),
- _INIT_DCS_CMD(0xC6, 0xF4),
- _INIT_DCS_CMD(0xC7, 0xFA),
- _INIT_DCS_CMD(0xC8, 0xFC),
- _INIT_DCS_CMD(0xC9, 0x00),
- _INIT_DCS_CMD(0xCA, 0x00),
- _INIT_DCS_CMD(0xCB, 0x16),
- _INIT_DCS_CMD(0xCC, 0xAF),
- _INIT_DCS_CMD(0xCD, 0xFF),
- _INIT_DCS_CMD(0xCE, 0xFF),
- _INIT_DCS_CMD(0xB0, 0x08),
- _INIT_DCS_CMD(0xB1, 0x04),
- _INIT_DCS_CMD(0xB2, 0x05),
- _INIT_DCS_CMD(0xB3, 0x11),
- _INIT_DCS_CMD(0xB4, 0x24),
- _INIT_DCS_CMD(0xB5, 0x39),
- _INIT_DCS_CMD(0xB6, 0x4F),
- _INIT_DCS_CMD(0xB7, 0x72),
- _INIT_DCS_CMD(0xB8, 0x98),
- _INIT_DCS_CMD(0xB9, 0xDC),
- _INIT_DCS_CMD(0xBA, 0x23),
- _INIT_DCS_CMD(0xBB, 0xA6),
- _INIT_DCS_CMD(0xBC, 0x2C),
- _INIT_DCS_CMD(0xBD, 0x30),
- _INIT_DCS_CMD(0xBE, 0xAA),
- _INIT_DCS_CMD(0xBF, 0x26),
- _INIT_DCS_CMD(0xC0, 0x62),
- _INIT_DCS_CMD(0xC1, 0x9B),
- _INIT_DCS_CMD(0xC2, 0xB5),
- _INIT_DCS_CMD(0xC3, 0xCF),
- _INIT_DCS_CMD(0xC4, 0xDB),
- _INIT_DCS_CMD(0xC5, 0xE8),
- _INIT_DCS_CMD(0xC6, 0xF5),
- _INIT_DCS_CMD(0xC7, 0xFA),
- _INIT_DCS_CMD(0xC8, 0xFC),
- _INIT_DCS_CMD(0xC9, 0x00),
- _INIT_DCS_CMD(0xCA, 0x00),
- _INIT_DCS_CMD(0xCB, 0x16),
- _INIT_DCS_CMD(0xCC, 0xAF),
- _INIT_DCS_CMD(0xCD, 0xFF),
- _INIT_DCS_CMD(0xCE, 0xFF),
- _INIT_DCS_CMD(0xB0, 0x09),
- _INIT_DCS_CMD(0xB1, 0x04),
- _INIT_DCS_CMD(0xB2, 0x02),
- _INIT_DCS_CMD(0xB3, 0x16),
- _INIT_DCS_CMD(0xB4, 0x24),
- _INIT_DCS_CMD(0xB5, 0x3B),
- _INIT_DCS_CMD(0xB6, 0x4F),
- _INIT_DCS_CMD(0xB7, 0x73),
- _INIT_DCS_CMD(0xB8, 0x99),
- _INIT_DCS_CMD(0xB9, 0xE0),
- _INIT_DCS_CMD(0xBA, 0x26),
- _INIT_DCS_CMD(0xBB, 0xAD),
- _INIT_DCS_CMD(0xBC, 0x36),
- _INIT_DCS_CMD(0xBD, 0x3A),
- _INIT_DCS_CMD(0xBE, 0xAE),
- _INIT_DCS_CMD(0xBF, 0x2A),
- _INIT_DCS_CMD(0xC0, 0x66),
- _INIT_DCS_CMD(0xC1, 0x9E),
- _INIT_DCS_CMD(0xC2, 0xB8),
- _INIT_DCS_CMD(0xC3, 0xD1),
- _INIT_DCS_CMD(0xC4, 0xDD),
- _INIT_DCS_CMD(0xC5, 0xE9),
- _INIT_DCS_CMD(0xC6, 0xF6),
- _INIT_DCS_CMD(0xC7, 0xFA),
- _INIT_DCS_CMD(0xC8, 0xFC),
- _INIT_DCS_CMD(0xC9, 0x00),
- _INIT_DCS_CMD(0xCA, 0x00),
- _INIT_DCS_CMD(0xCB, 0x16),
- _INIT_DCS_CMD(0xCC, 0xAF),
- _INIT_DCS_CMD(0xCD, 0xFF),
- _INIT_DCS_CMD(0xCE, 0xFF),
- _INIT_DCS_CMD(0xB0, 0x0A),
- _INIT_DCS_CMD(0xB1, 0x00),
- _INIT_DCS_CMD(0xB2, 0x02),
- _INIT_DCS_CMD(0xB3, 0x0F),
- _INIT_DCS_CMD(0xB4, 0x25),
- _INIT_DCS_CMD(0xB5, 0x39),
- _INIT_DCS_CMD(0xB6, 0x4E),
- _INIT_DCS_CMD(0xB7, 0x72),
- _INIT_DCS_CMD(0xB8, 0x97),
- _INIT_DCS_CMD(0xB9, 0xDC),
- _INIT_DCS_CMD(0xBA, 0x22),
- _INIT_DCS_CMD(0xBB, 0xA4),
- _INIT_DCS_CMD(0xBC, 0x2B),
- _INIT_DCS_CMD(0xBD, 0x2F),
- _INIT_DCS_CMD(0xBE, 0xA9),
- _INIT_DCS_CMD(0xBF, 0x25),
- _INIT_DCS_CMD(0xC0, 0x61),
- _INIT_DCS_CMD(0xC1, 0x97),
- _INIT_DCS_CMD(0xC2, 0xB2),
- _INIT_DCS_CMD(0xC3, 0xCD),
- _INIT_DCS_CMD(0xC4, 0xD9),
- _INIT_DCS_CMD(0xC5, 0xE7),
- _INIT_DCS_CMD(0xC6, 0xF4),
- _INIT_DCS_CMD(0xC7, 0xFA),
- _INIT_DCS_CMD(0xC8, 0xFC),
- _INIT_DCS_CMD(0xC9, 0x00),
- _INIT_DCS_CMD(0xCA, 0x00),
- _INIT_DCS_CMD(0xCB, 0x16),
- _INIT_DCS_CMD(0xCC, 0xAF),
- _INIT_DCS_CMD(0xCD, 0xFF),
- _INIT_DCS_CMD(0xCE, 0xFF),
- _INIT_DCS_CMD(0xB0, 0x0B),
- _INIT_DCS_CMD(0xB1, 0x04),
- _INIT_DCS_CMD(0xB2, 0x05),
- _INIT_DCS_CMD(0xB3, 0x11),
- _INIT_DCS_CMD(0xB4, 0x24),
- _INIT_DCS_CMD(0xB5, 0x39),
- _INIT_DCS_CMD(0xB6, 0x4F),
- _INIT_DCS_CMD(0xB7, 0x72),
- _INIT_DCS_CMD(0xB8, 0x98),
- _INIT_DCS_CMD(0xB9, 0xDC),
- _INIT_DCS_CMD(0xBA, 0x23),
- _INIT_DCS_CMD(0xBB, 0xA6),
- _INIT_DCS_CMD(0xBC, 0x2C),
- _INIT_DCS_CMD(0xBD, 0x30),
- _INIT_DCS_CMD(0xBE, 0xAA),
- _INIT_DCS_CMD(0xBF, 0x26),
- _INIT_DCS_CMD(0xC0, 0x62),
- _INIT_DCS_CMD(0xC1, 0x9B),
- _INIT_DCS_CMD(0xC2, 0xB5),
- _INIT_DCS_CMD(0xC3, 0xCF),
- _INIT_DCS_CMD(0xC4, 0xDB),
- _INIT_DCS_CMD(0xC5, 0xE8),
- _INIT_DCS_CMD(0xC6, 0xF5),
- _INIT_DCS_CMD(0xC7, 0xFA),
- _INIT_DCS_CMD(0xC8, 0xFC),
- _INIT_DCS_CMD(0xC9, 0x00),
- _INIT_DCS_CMD(0xCA, 0x00),
- _INIT_DCS_CMD(0xCB, 0x16),
- _INIT_DCS_CMD(0xCC, 0xAF),
- _INIT_DCS_CMD(0xCD, 0xFF),
- _INIT_DCS_CMD(0xCE, 0xFF),
- _INIT_DCS_CMD(0xB0, 0x0C),
- _INIT_DCS_CMD(0xB1, 0x04),
- _INIT_DCS_CMD(0xB2, 0x02),
- _INIT_DCS_CMD(0xB3, 0x16),
- _INIT_DCS_CMD(0xB4, 0x24),
- _INIT_DCS_CMD(0xB5, 0x3B),
- _INIT_DCS_CMD(0xB6, 0x4F),
- _INIT_DCS_CMD(0xB7, 0x73),
- _INIT_DCS_CMD(0xB8, 0x99),
- _INIT_DCS_CMD(0xB9, 0xE0),
- _INIT_DCS_CMD(0xBA, 0x26),
- _INIT_DCS_CMD(0xBB, 0xAD),
- _INIT_DCS_CMD(0xBC, 0x36),
- _INIT_DCS_CMD(0xBD, 0x3A),
- _INIT_DCS_CMD(0xBE, 0xAE),
- _INIT_DCS_CMD(0xBF, 0x2A),
- _INIT_DCS_CMD(0xC0, 0x66),
- _INIT_DCS_CMD(0xC1, 0x9E),
- _INIT_DCS_CMD(0xC2, 0xB8),
- _INIT_DCS_CMD(0xC3, 0xD1),
- _INIT_DCS_CMD(0xC4, 0xDD),
- _INIT_DCS_CMD(0xC5, 0xE9),
- _INIT_DCS_CMD(0xC6, 0xF6),
- _INIT_DCS_CMD(0xC7, 0xFA),
- _INIT_DCS_CMD(0xC8, 0xFC),
- _INIT_DCS_CMD(0xC9, 0x00),
- _INIT_DCS_CMD(0xCA, 0x00),
- _INIT_DCS_CMD(0xCB, 0x16),
- _INIT_DCS_CMD(0xCC, 0xAF),
- _INIT_DCS_CMD(0xCD, 0xFF),
- _INIT_DCS_CMD(0xCE, 0xFF),
- _INIT_DCS_CMD(0xB0, 0x00),
- _INIT_DCS_CMD(0xB3, 0x08),
- _INIT_DCS_CMD(0xB0, 0x04),
- _INIT_DCS_CMD(0xB8, 0x68),
- _INIT_DELAY_CMD(150),
- {},
+ return 0;
};
-static const struct panel_init_cmd auo_kd101n80_45na_init_cmd[] = {
- _INIT_DELAY_CMD(24),
- _INIT_DCS_CMD(0x11),
- _INIT_DELAY_CMD(120),
- _INIT_DCS_CMD(0x29),
- _INIT_DELAY_CMD(120),
- {},
-};
+static int auo_kd101n80_45na_init(struct boe_panel *boe)
+{
+ struct mipi_dsi_multi_context ctx = { .dsi = boe->dsi };
-static const struct panel_init_cmd auo_b101uan08_3_init_cmd[] = {
- _INIT_DELAY_CMD(24),
- _INIT_DCS_CMD(0xB0, 0x01),
- _INIT_DCS_CMD(0xC0, 0x48),
- _INIT_DCS_CMD(0xC1, 0x48),
- _INIT_DCS_CMD(0xC2, 0x47),
- _INIT_DCS_CMD(0xC3, 0x47),
- _INIT_DCS_CMD(0xC4, 0x46),
- _INIT_DCS_CMD(0xC5, 0x46),
- _INIT_DCS_CMD(0xC6, 0x45),
- _INIT_DCS_CMD(0xC7, 0x45),
- _INIT_DCS_CMD(0xC8, 0x64),
- _INIT_DCS_CMD(0xC9, 0x64),
- _INIT_DCS_CMD(0xCA, 0x4F),
- _INIT_DCS_CMD(0xCB, 0x4F),
- _INIT_DCS_CMD(0xCC, 0x40),
- _INIT_DCS_CMD(0xCD, 0x40),
- _INIT_DCS_CMD(0xCE, 0x66),
- _INIT_DCS_CMD(0xCF, 0x66),
- _INIT_DCS_CMD(0xD0, 0x4F),
- _INIT_DCS_CMD(0xD1, 0x4F),
- _INIT_DCS_CMD(0xD2, 0x41),
- _INIT_DCS_CMD(0xD3, 0x41),
- _INIT_DCS_CMD(0xD4, 0x48),
- _INIT_DCS_CMD(0xD5, 0x48),
- _INIT_DCS_CMD(0xD6, 0x47),
- _INIT_DCS_CMD(0xD7, 0x47),
- _INIT_DCS_CMD(0xD8, 0x46),
- _INIT_DCS_CMD(0xD9, 0x46),
- _INIT_DCS_CMD(0xDA, 0x45),
- _INIT_DCS_CMD(0xDB, 0x45),
- _INIT_DCS_CMD(0xDC, 0x64),
- _INIT_DCS_CMD(0xDD, 0x64),
- _INIT_DCS_CMD(0xDE, 0x4F),
- _INIT_DCS_CMD(0xDF, 0x4F),
- _INIT_DCS_CMD(0xE0, 0x40),
- _INIT_DCS_CMD(0xE1, 0x40),
- _INIT_DCS_CMD(0xE2, 0x66),
- _INIT_DCS_CMD(0xE3, 0x66),
- _INIT_DCS_CMD(0xE4, 0x4F),
- _INIT_DCS_CMD(0xE5, 0x4F),
- _INIT_DCS_CMD(0xE6, 0x41),
- _INIT_DCS_CMD(0xE7, 0x41),
- _INIT_DELAY_CMD(150),
- {},
-};
+ msleep(24);
-static const struct panel_init_cmd starry_qfh032011_53g_init_cmd[] = {
- _INIT_DCS_CMD(0xB0, 0x01),
- _INIT_DCS_CMD(0xC3, 0x4F),
- _INIT_DCS_CMD(0xC4, 0x40),
- _INIT_DCS_CMD(0xC5, 0x40),
- _INIT_DCS_CMD(0xC6, 0x40),
- _INIT_DCS_CMD(0xC7, 0x40),
- _INIT_DCS_CMD(0xC8, 0x4D),
- _INIT_DCS_CMD(0xC9, 0x52),
- _INIT_DCS_CMD(0xCA, 0x51),
- _INIT_DCS_CMD(0xCD, 0x5D),
- _INIT_DCS_CMD(0xCE, 0x5B),
- _INIT_DCS_CMD(0xCF, 0x4B),
- _INIT_DCS_CMD(0xD0, 0x49),
- _INIT_DCS_CMD(0xD1, 0x47),
- _INIT_DCS_CMD(0xD2, 0x45),
- _INIT_DCS_CMD(0xD3, 0x41),
- _INIT_DCS_CMD(0xD7, 0x50),
- _INIT_DCS_CMD(0xD8, 0x40),
- _INIT_DCS_CMD(0xD9, 0x40),
- _INIT_DCS_CMD(0xDA, 0x40),
- _INIT_DCS_CMD(0xDB, 0x40),
- _INIT_DCS_CMD(0xDC, 0x4E),
- _INIT_DCS_CMD(0xDD, 0x52),
- _INIT_DCS_CMD(0xDE, 0x51),
- _INIT_DCS_CMD(0xE1, 0x5E),
- _INIT_DCS_CMD(0xE2, 0x5C),
- _INIT_DCS_CMD(0xE3, 0x4C),
- _INIT_DCS_CMD(0xE4, 0x4A),
- _INIT_DCS_CMD(0xE5, 0x48),
- _INIT_DCS_CMD(0xE6, 0x46),
- _INIT_DCS_CMD(0xE7, 0x42),
- _INIT_DCS_CMD(0xB0, 0x03),
- _INIT_DCS_CMD(0xBE, 0x03),
- _INIT_DCS_CMD(0xCC, 0x44),
- _INIT_DCS_CMD(0xC8, 0x07),
- _INIT_DCS_CMD(0xC9, 0x05),
- _INIT_DCS_CMD(0xCA, 0x42),
- _INIT_DCS_CMD(0xCD, 0x3E),
- _INIT_DCS_CMD(0xCF, 0x60),
- _INIT_DCS_CMD(0xD2, 0x04),
- _INIT_DCS_CMD(0xD3, 0x04),
- _INIT_DCS_CMD(0xD4, 0x01),
- _INIT_DCS_CMD(0xD5, 0x00),
- _INIT_DCS_CMD(0xD6, 0x03),
- _INIT_DCS_CMD(0xD7, 0x04),
- _INIT_DCS_CMD(0xD9, 0x01),
- _INIT_DCS_CMD(0xDB, 0x01),
- _INIT_DCS_CMD(0xE4, 0xF0),
- _INIT_DCS_CMD(0xE5, 0x0A),
- _INIT_DCS_CMD(0xB0, 0x00),
- _INIT_DCS_CMD(0xCC, 0x08),
- _INIT_DCS_CMD(0xC2, 0x08),
- _INIT_DCS_CMD(0xC4, 0x10),
- _INIT_DCS_CMD(0xB0, 0x02),
- _INIT_DCS_CMD(0xC0, 0x00),
- _INIT_DCS_CMD(0xC1, 0x0A),
- _INIT_DCS_CMD(0xC2, 0x20),
- _INIT_DCS_CMD(0xC3, 0x24),
- _INIT_DCS_CMD(0xC4, 0x23),
- _INIT_DCS_CMD(0xC5, 0x29),
- _INIT_DCS_CMD(0xC6, 0x23),
- _INIT_DCS_CMD(0xC7, 0x1C),
- _INIT_DCS_CMD(0xC8, 0x19),
- _INIT_DCS_CMD(0xC9, 0x17),
- _INIT_DCS_CMD(0xCA, 0x17),
- _INIT_DCS_CMD(0xCB, 0x18),
- _INIT_DCS_CMD(0xCC, 0x1A),
- _INIT_DCS_CMD(0xCD, 0x1E),
- _INIT_DCS_CMD(0xCE, 0x20),
- _INIT_DCS_CMD(0xCF, 0x23),
- _INIT_DCS_CMD(0xD0, 0x07),
- _INIT_DCS_CMD(0xD1, 0x00),
- _INIT_DCS_CMD(0xD2, 0x00),
- _INIT_DCS_CMD(0xD3, 0x0A),
- _INIT_DCS_CMD(0xD4, 0x13),
- _INIT_DCS_CMD(0xD5, 0x1C),
- _INIT_DCS_CMD(0xD6, 0x1A),
- _INIT_DCS_CMD(0xD7, 0x13),
- _INIT_DCS_CMD(0xD8, 0x17),
- _INIT_DCS_CMD(0xD9, 0x1C),
- _INIT_DCS_CMD(0xDA, 0x19),
- _INIT_DCS_CMD(0xDB, 0x17),
- _INIT_DCS_CMD(0xDC, 0x17),
- _INIT_DCS_CMD(0xDD, 0x18),
- _INIT_DCS_CMD(0xDE, 0x1A),
- _INIT_DCS_CMD(0xDF, 0x1E),
- _INIT_DCS_CMD(0xE0, 0x20),
- _INIT_DCS_CMD(0xE1, 0x23),
- _INIT_DCS_CMD(0xE2, 0x07),
- _INIT_DCS_CMD(0X11),
- _INIT_DELAY_CMD(120),
- _INIT_DCS_CMD(0X29),
- _INIT_DELAY_CMD(80),
- {},
-};
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x11);
-static const struct panel_init_cmd starry_himax83102_j02_init_cmd[] = {
- _INIT_DCS_CMD(0xB9, 0x83, 0x10, 0x21, 0x55, 0x00),
- _INIT_DCS_CMD(0xB1, 0x2C, 0xB5, 0xB5, 0x31, 0xF1, 0x31, 0xD7, 0x2F, 0x36, 0x36, 0x36, 0x36, 0x1A, 0x8B, 0x11,
- 0x65, 0x00, 0x88, 0xFA, 0xFF, 0xFF, 0x8F, 0xFF, 0x08, 0x74, 0x33),
- _INIT_DCS_CMD(0xB2, 0x00, 0x47, 0xB0, 0x80, 0x00, 0x12, 0x72, 0x3C, 0xA3, 0x03, 0x03, 0x00, 0x00, 0x88, 0xF5),
- _INIT_DCS_CMD(0xB4, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x63, 0x5C, 0x63, 0x5C, 0x01, 0x9E),
- _INIT_DCS_CMD(0xE9, 0xCD),
- _INIT_DCS_CMD(0xBA, 0x84),
- _INIT_DCS_CMD(0xE9, 0x3F),
- _INIT_DCS_CMD(0xBC, 0x1B, 0x04),
- _INIT_DCS_CMD(0xBE, 0x20),
- _INIT_DCS_CMD(0xBF, 0xFC, 0xC4),
- _INIT_DCS_CMD(0xC0, 0x36, 0x36, 0x22, 0x11, 0x22, 0xA0, 0x61, 0x08, 0xF5, 0x03),
- _INIT_DCS_CMD(0xE9, 0xCC),
- _INIT_DCS_CMD(0xC7, 0x80),
- _INIT_DCS_CMD(0xE9, 0x3F),
- _INIT_DCS_CMD(0xE9, 0xC6),
- _INIT_DCS_CMD(0xC8, 0x97),
- _INIT_DCS_CMD(0xE9, 0x3F),
- _INIT_DCS_CMD(0xC9, 0x00, 0x1E, 0x13, 0x88, 0x01),
- _INIT_DCS_CMD(0xCB, 0x08, 0x13, 0x07, 0x00, 0x0F, 0x33),
- _INIT_DCS_CMD(0xCC, 0x02),
- _INIT_DCS_CMD(0xE9, 0xC4),
- _INIT_DCS_CMD(0xD0, 0x03),
- _INIT_DCS_CMD(0xE9, 0x3F),
- _INIT_DCS_CMD(0xD1, 0x37, 0x06, 0x00, 0x02, 0x04, 0x0C, 0xFF),
- _INIT_DCS_CMD(0xD2, 0x1F, 0x11, 0x1F),
- _INIT_DCS_CMD(0xD3, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x37, 0x47, 0x34, 0x3B, 0x12, 0x12, 0x03,
- 0x03, 0x32, 0x10, 0x10, 0x00, 0x10, 0x32, 0x10, 0x08, 0x00, 0x08, 0x32, 0x17, 0x94, 0x07, 0x94, 0x00, 0x00),
- _INIT_DCS_CMD(0xD5, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x40, 0x40, 0x1A, 0x1A,
- 0x1B, 0x1B, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x20, 0x21, 0x28, 0x29, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18),
- _INIT_DCS_CMD(0xD6, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x40, 0x40, 0x19, 0x19, 0x1A, 0x1A,
- 0x1B, 0x1B, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x29, 0x28, 0x21, 0x20, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18),
- _INIT_DCS_CMD(0xD8, 0xAA, 0xBA, 0xEA, 0xAA, 0xAA, 0xA0, 0xAA, 0xBA, 0xEA, 0xAA, 0xAA, 0xA0, 0xAA, 0xBA, 0xEA, 0xAA,
- 0xAA, 0xA0, 0xAA, 0xBA, 0xEA, 0xAA, 0xAA, 0xA0, 0xAA, 0xBA, 0xEA, 0xAA, 0xAA, 0xA0, 0xAA, 0xBA, 0xEA, 0xAA, 0xAA, 0xA0),
- _INIT_DCS_CMD(0xE0, 0x00, 0x09, 0x14, 0x1E, 0x26, 0x48, 0x61, 0x67, 0x6C, 0x67, 0x7D, 0x7F, 0x80, 0x8B, 0x87, 0x8F, 0x98, 0xAB,
- 0xAB, 0x55, 0x5C, 0x68, 0x73, 0x00, 0x09, 0x14, 0x1E, 0x26, 0x48, 0x61, 0x67, 0x6C, 0x67, 0x7D, 0x7F, 0x80, 0x8B, 0x87, 0x8F, 0x98, 0xAB, 0xAB, 0x55, 0x5C, 0x68, 0x73),
- _INIT_DCS_CMD(0xE7, 0x0E, 0x10, 0x10, 0x21, 0x2B, 0x9A, 0x02, 0x54, 0x9A, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x12, 0x05, 0x02, 0x02, 0x10),
- _INIT_DCS_CMD(0xBD, 0x01),
- _INIT_DCS_CMD(0xB1, 0x01, 0xBF, 0x11),
- _INIT_DCS_CMD(0xCB, 0x86),
- _INIT_DCS_CMD(0xD2, 0x3C, 0xFA),
- _INIT_DCS_CMD(0xD3, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0C, 0x01),
- _INIT_DCS_CMD(0xE7, 0x02, 0x00, 0x28, 0x01, 0x7E, 0x0F, 0x7E, 0x10, 0xA0, 0x00, 0x00, 0x20, 0x40, 0x50, 0x40),
- _INIT_DCS_CMD(0xBD, 0x02),
- _INIT_DCS_CMD(0xD8, 0xFF, 0xFF, 0xBF, 0xFE, 0xAA, 0xA0, 0xFF, 0xFF, 0xBF, 0xFE, 0xAA, 0xA0),
- _INIT_DCS_CMD(0xE7, 0xFE, 0x04, 0xFE, 0x04, 0xFE, 0x04, 0x03, 0x03, 0x03, 0x26, 0x00, 0x26, 0x81, 0x02, 0x40, 0x00, 0x20, 0x9E, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00),
- _INIT_DCS_CMD(0xBD, 0x03),
- _INIT_DCS_CMD(0xE9, 0xC6),
- _INIT_DCS_CMD(0xB4, 0x03, 0xFF, 0xF8),
- _INIT_DCS_CMD(0xE9, 0x3F),
- _INIT_DCS_CMD(0xD8, 0x00, 0x2A, 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xA8,
- 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xA8, 0x00, 0x00),
- _INIT_DCS_CMD(0xBD, 0x00),
- _INIT_DCS_CMD(0xE9, 0xC4),
- _INIT_DCS_CMD(0xBA, 0x96),
- _INIT_DCS_CMD(0xE9, 0x3F),
- _INIT_DCS_CMD(0xBD, 0x01),
- _INIT_DCS_CMD(0xE9, 0xC5),
- _INIT_DCS_CMD(0xBA, 0x4F),
- _INIT_DCS_CMD(0xE9, 0x3F),
- _INIT_DCS_CMD(0xBD, 0x00),
- _INIT_DCS_CMD(0x11),
- _INIT_DELAY_CMD(120),
- _INIT_DCS_CMD(0x29),
- {},
-};
+ mipi_dsi_msleep(&ctx, 120);
-static inline struct boe_panel *to_boe_panel(struct drm_panel *panel)
-{
- return container_of(panel, struct boe_panel, base);
-}
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x29);
+
+ mipi_dsi_msleep(&ctx, 120);
-static int boe_panel_init_dcs_cmd(struct boe_panel *boe)
-{
- struct mipi_dsi_device *dsi = boe->dsi;
- struct drm_panel *panel = &boe->base;
- int i, err = 0;
-
- if (boe->desc->init_cmds) {
- const struct panel_init_cmd *init_cmds = boe->desc->init_cmds;
-
- for (i = 0; init_cmds[i].len != 0; i++) {
- const struct panel_init_cmd *cmd = &init_cmds[i];
-
- switch (cmd->type) {
- case DELAY_CMD:
- msleep(cmd->data[0]);
- err = 0;
- break;
-
- case INIT_DCS_CMD:
- err = mipi_dsi_dcs_write(dsi, cmd->data[0],
- cmd->len <= 1 ? NULL :
- &cmd->data[1],
- cmd->len - 1);
- break;
-
- default:
- err = -EINVAL;
- }
-
- if (err < 0) {
- dev_err(panel->dev,
- "failed to write command %u\n", i);
- return err;
- }
- }
- }
return 0;
-}
+};
-static int boe_panel_enter_sleep_mode(struct boe_panel *boe)
+static int auo_b101uan08_3_init(struct boe_panel *boe)
{
- struct mipi_dsi_device *dsi = boe->dsi;
- int ret;
-
- dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
+ struct mipi_dsi_multi_context ctx = { .dsi = boe->dsi };
+
+ msleep(24);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x48);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x48);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0x47);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0x47);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0x46);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0x46);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc6, 0x45);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0x45);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0x64);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x64);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x4f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x4f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcc, 0x40);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcd, 0x40);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xce, 0x66);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcf, 0x66);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd0, 0x4f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd1, 0x4f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd2, 0x41);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd3, 0x41);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd4, 0x48);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd5, 0x48);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd6, 0x47);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd7, 0x47);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd8, 0x46);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd9, 0x46);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xda, 0x45);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdb, 0x45);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdc, 0x64);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdd, 0x64);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xde, 0x4f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdf, 0x4f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe0, 0x40);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe1, 0x40);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe2, 0x66);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe3, 0x66);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe4, 0x4f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe5, 0x4f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe6, 0x41);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe7, 0x41);
+
+ mipi_dsi_msleep(&ctx, 150);
- ret = mipi_dsi_dcs_set_display_off(dsi);
- if (ret < 0)
- return ret;
+ return 0;
+};
- ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
- if (ret < 0)
- return ret;
+static int starry_qfh032011_53g_init(struct boe_panel *boe)
+{
+ struct mipi_dsi_multi_context ctx = { .dsi = boe->dsi };
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0x4f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0x40);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0x40);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc6, 0x40);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0x40);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0x4d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x52);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x51);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcd, 0x5d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xce, 0x5b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcf, 0x4b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd0, 0x49);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd1, 0x47);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd2, 0x45);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd3, 0x41);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd7, 0x50);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd8, 0x40);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd9, 0x40);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xda, 0x40);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdb, 0x40);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdc, 0x4e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdd, 0x52);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xde, 0x51);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe1, 0x5e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe2, 0x5c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe3, 0x4c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe4, 0x4a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe5, 0x48);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe6, 0x46);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe7, 0x42);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbe, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcc, 0x44);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x05);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x42);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcd, 0x3e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcf, 0x60);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd2, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd3, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd4, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd5, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd6, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd7, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd9, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe4, 0xf0);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe5, 0x0a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcc, 0x08);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0x08);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0x10);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x0a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0x20);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0x24);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0x23);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0x29);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc6, 0x23);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0x1c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0x19);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0x17);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x17);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x18);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcc, 0x1a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcd, 0x1e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xce, 0x20);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcf, 0x23);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd0, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd1, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd2, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd3, 0x0a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd4, 0x13);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd5, 0x1c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd6, 0x1a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd7, 0x13);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd8, 0x17);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd9, 0x1c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xda, 0x19);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdb, 0x17);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdc, 0x17);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdd, 0x18);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xde, 0x1a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdf, 0x1e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe0, 0x20);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe1, 0x23);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe2, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0X11);
+
+ mipi_dsi_msleep(&ctx, 120);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0X29);
+
+ mipi_dsi_msleep(&ctx, 80);
return 0;
+};
+
+static inline struct boe_panel *to_boe_panel(struct drm_panel *panel)
+{
+ return container_of(panel, struct boe_panel, base);
}
static int boe_panel_disable(struct drm_panel *panel)
{
struct boe_panel *boe = to_boe_panel(panel);
- int ret;
+ struct mipi_dsi_multi_context ctx = { .dsi = boe->dsi };
- ret = boe_panel_enter_sleep_mode(boe);
- if (ret < 0) {
- dev_err(panel->dev, "failed to set panel off: %d\n", ret);
- return ret;
- }
+ boe->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
- msleep(150);
+ mipi_dsi_dcs_set_display_off_multi(&ctx);
+ mipi_dsi_dcs_enter_sleep_mode_multi(&ctx);
- return 0;
+ mipi_dsi_msleep(&ctx, 150);
+
+ return ctx.accum_err;
}
static int boe_panel_unprepare(struct drm_panel *panel)
{
struct boe_panel *boe = to_boe_panel(panel);
- if (!boe->prepared)
- return 0;
-
if (boe->desc->discharge_on_disable) {
regulator_disable(boe->avee);
regulator_disable(boe->avdd);
@@ -1471,8 +1415,6 @@ static int boe_panel_unprepare(struct drm_panel *panel)
regulator_disable(boe->pp3300);
}
- boe->prepared = false;
-
return 0;
}
@@ -1481,9 +1423,6 @@ static int boe_panel_prepare(struct drm_panel *panel)
struct boe_panel *boe = to_boe_panel(panel);
int ret;
- if (boe->prepared)
- return 0;
-
gpiod_set_value(boe->enable_gpio, 0);
usleep_range(1000, 1500);
@@ -1507,7 +1446,11 @@ static int boe_panel_prepare(struct drm_panel *panel)
usleep_range(10000, 11000);
if (boe->desc->lp11_before_reset) {
- mipi_dsi_dcs_nop(boe->dsi);
+ ret = mipi_dsi_dcs_nop(boe->dsi);
+ if (ret < 0) {
+ dev_err(&boe->dsi->dev, "Failed to send NOP: %d\n", ret);
+ goto poweroff;
+ }
usleep_range(1000, 2000);
}
gpiod_set_value(boe->enable_gpio, 1);
@@ -1517,24 +1460,20 @@ static int boe_panel_prepare(struct drm_panel *panel)
gpiod_set_value(boe->enable_gpio, 1);
usleep_range(6000, 10000);
- ret = boe_panel_init_dcs_cmd(boe);
- if (ret < 0) {
- dev_err(panel->dev, "failed to init panel: %d\n", ret);
+ ret = boe->desc->init(boe);
+ if (ret < 0)
goto poweroff;
- }
-
- boe->prepared = true;
return 0;
poweroff:
+ gpiod_set_value(boe->enable_gpio, 0);
regulator_disable(boe->avee);
poweroffavdd:
regulator_disable(boe->avdd);
poweroff1v8:
usleep_range(5000, 7000);
regulator_disable(boe->pp1800);
- gpiod_set_value(boe->enable_gpio, 0);
return ret;
}
@@ -1571,7 +1510,7 @@ static const struct panel_desc boe_tv110c9m_desc = {
| MIPI_DSI_MODE_VIDEO_HSE
| MIPI_DSI_CLOCK_NON_CONTINUOUS
| MIPI_DSI_MODE_VIDEO_BURST,
- .init_cmds = boe_tv110c9m_init_cmd,
+ .init = boe_tv110c9m_init,
};
static const struct drm_display_mode inx_hj110iz_default_mode = {
@@ -1600,7 +1539,7 @@ static const struct panel_desc inx_hj110iz_desc = {
| MIPI_DSI_MODE_VIDEO_HSE
| MIPI_DSI_CLOCK_NON_CONTINUOUS
| MIPI_DSI_MODE_VIDEO_BURST,
- .init_cmds = inx_hj110iz_init_cmd,
+ .init = inx_hj110iz_init,
};
static const struct drm_display_mode boe_tv101wum_nl6_default_mode = {
@@ -1626,7 +1565,7 @@ static const struct panel_desc boe_tv101wum_nl6_desc = {
.format = MIPI_DSI_FMT_RGB888,
.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
MIPI_DSI_MODE_LPM,
- .init_cmds = boe_init_cmd,
+ .init = boe_init,
.discharge_on_disable = false,
};
@@ -1653,7 +1592,7 @@ static const struct panel_desc auo_kd101n80_45na_desc = {
.format = MIPI_DSI_FMT_RGB888,
.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
MIPI_DSI_MODE_LPM,
- .init_cmds = auo_kd101n80_45na_init_cmd,
+ .init = auo_kd101n80_45na_init,
.discharge_on_disable = true,
};
@@ -1681,7 +1620,7 @@ static const struct panel_desc boe_tv101wum_n53_desc = {
.format = MIPI_DSI_FMT_RGB888,
.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
MIPI_DSI_MODE_LPM,
- .init_cmds = boe_init_cmd,
+ .init = boe_init,
};
static const struct drm_display_mode auo_b101uan08_3_default_mode = {
@@ -1708,7 +1647,7 @@ static const struct panel_desc auo_b101uan08_3_desc = {
.format = MIPI_DSI_FMT_RGB888,
.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
MIPI_DSI_MODE_LPM,
- .init_cmds = auo_b101uan08_3_init_cmd,
+ .init = auo_b101uan08_3_init,
.lp11_before_reset = true,
};
@@ -1736,7 +1675,7 @@ static const struct panel_desc boe_tv105wum_nw0_desc = {
.format = MIPI_DSI_FMT_RGB888,
.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
MIPI_DSI_MODE_LPM,
- .init_cmds = boe_init_cmd,
+ .init = boe_init,
.lp11_before_reset = true,
};
@@ -1763,35 +1702,7 @@ static const struct panel_desc starry_qfh032011_53g_desc = {
.format = MIPI_DSI_FMT_RGB888,
.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
MIPI_DSI_MODE_LPM,
- .init_cmds = starry_qfh032011_53g_init_cmd,
- .lp11_before_reset = true,
-};
-
-static const struct drm_display_mode starry_himax83102_j02_default_mode = {
- .clock = 162680,
- .hdisplay = 1200,
- .hsync_start = 1200 + 60,
- .hsync_end = 1200 + 60 + 20,
- .htotal = 1200 + 60 + 20 + 40,
- .vdisplay = 1920,
- .vsync_start = 1920 + 116,
- .vsync_end = 1920 + 116 + 8,
- .vtotal = 1920 + 116 + 8 + 12,
- .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
-};
-
-static const struct panel_desc starry_himax83102_j02_desc = {
- .modes = &starry_himax83102_j02_default_mode,
- .bpc = 8,
- .size = {
- .width_mm = 141,
- .height_mm = 226,
- },
- .lanes = 4,
- .format = MIPI_DSI_FMT_RGB888,
- .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
- MIPI_DSI_MODE_LPM,
- .init_cmds = starry_himax83102_j02_init_cmd,
+ .init = starry_qfh032011_53g_init,
.lp11_before_reset = true,
};
@@ -1922,21 +1833,11 @@ static int boe_panel_probe(struct mipi_dsi_device *dsi)
return ret;
}
-static void boe_panel_shutdown(struct mipi_dsi_device *dsi)
-{
- struct boe_panel *boe = mipi_dsi_get_drvdata(dsi);
-
- drm_panel_disable(&boe->base);
- drm_panel_unprepare(&boe->base);
-}
-
static void boe_panel_remove(struct mipi_dsi_device *dsi)
{
struct boe_panel *boe = mipi_dsi_get_drvdata(dsi);
int ret;
- boe_panel_shutdown(dsi);
-
ret = mipi_dsi_detach(dsi);
if (ret < 0)
dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret);
@@ -1970,9 +1871,6 @@ static const struct of_device_id boe_of_match[] = {
{ .compatible = "starry,2081101qfh032011-53g",
.data = &starry_qfh032011_53g_desc
},
- { .compatible = "starry,himax83102-j02",
- .data = &starry_himax83102_j02_desc
- },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, boe_of_match);
@@ -1984,7 +1882,6 @@ static struct mipi_dsi_driver boe_panel_driver = {
},
.probe = boe_panel_probe,
.remove = boe_panel_remove,
- .shutdown = boe_panel_shutdown,
};
module_mipi_dsi_driver(boe_panel_driver);
diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c
index 6db277efcbb7..3a574a9b46e7 100644
--- a/drivers/gpu/drm/panel/panel-edp.c
+++ b/drivers/gpu/drm/panel/panel-edp.c
@@ -222,11 +222,8 @@ struct edp_panel_entry {
struct panel_edp {
struct drm_panel base;
- bool enabled;
bool no_hpd;
- bool prepared;
-
ktime_t prepared_time;
ktime_t powered_on_time;
ktime_t unprepared_time;
@@ -395,14 +392,9 @@ static int panel_edp_disable(struct drm_panel *panel)
{
struct panel_edp *p = to_panel_edp(panel);
- if (!p->enabled)
- return 0;
-
if (p->desc->delay.disable)
msleep(p->desc->delay.disable);
- p->enabled = false;
-
return 0;
}
@@ -420,17 +412,11 @@ static int panel_edp_suspend(struct device *dev)
static int panel_edp_unprepare(struct drm_panel *panel)
{
- struct panel_edp *p = to_panel_edp(panel);
int ret;
- /* Unpreparing when already unprepared is a no-op */
- if (!p->prepared)
- return 0;
-
ret = pm_runtime_put_sync_suspend(panel->dev);
if (ret < 0)
return ret;
- p->prepared = false;
return 0;
}
@@ -542,21 +528,14 @@ static int panel_edp_resume(struct device *dev)
static int panel_edp_prepare(struct drm_panel *panel)
{
- struct panel_edp *p = to_panel_edp(panel);
int ret;
- /* Preparing when already prepared is a no-op */
- if (p->prepared)
- return 0;
-
ret = pm_runtime_get_sync(panel->dev);
if (ret < 0) {
pm_runtime_put_autosuspend(panel->dev);
return ret;
}
- p->prepared = true;
-
return 0;
}
@@ -565,9 +544,6 @@ static int panel_edp_enable(struct drm_panel *panel)
struct panel_edp *p = to_panel_edp(panel);
unsigned int delay;
- if (p->enabled)
- return 0;
-
delay = p->desc->delay.enable;
/*
@@ -598,8 +574,6 @@ static int panel_edp_enable(struct drm_panel *panel)
panel_edp_wait(p->powered_on_time, p->desc->delay.powered_on_to_enable);
- p->enabled = true;
-
return 0;
}
@@ -869,7 +843,6 @@ static int panel_edp_probe(struct device *dev, const struct panel_desc *desc,
if (!panel)
return -ENOMEM;
- panel->enabled = false;
panel->prepared_time = 0;
panel->desc = desc;
panel->aux = aux;
@@ -971,13 +944,34 @@ err_finished_ddc_init:
return err;
}
-static void panel_edp_remove(struct device *dev)
+static void panel_edp_shutdown(struct device *dev)
{
struct panel_edp *panel = dev_get_drvdata(dev);
- drm_panel_remove(&panel->base);
+ /*
+ * NOTE: the following two calls don't really belong here. It is the
+ * responsibility of a correctly written DRM modeset driver to call
+ * drm_atomic_helper_shutdown() at shutdown time and that should
+ * cause the panel to be disabled / unprepared if needed. For now,
+ * however, we'll keep these calls due to the sheer number of
+ * different DRM modeset drivers used with panel-edp. The fact that
+ * we're calling these and _also_ the drm_atomic_helper_shutdown()
+ * will try to disable/unprepare means that we can get a warning about
+ * trying to disable/unprepare an already disabled/unprepared panel,
+ * but that's something we'll have to live with until we've confirmed
+ * that all DRM modeset drivers are properly calling
+ * drm_atomic_helper_shutdown().
+ */
drm_panel_disable(&panel->base);
drm_panel_unprepare(&panel->base);
+}
+
+static void panel_edp_remove(struct device *dev)
+{
+ struct panel_edp *panel = dev_get_drvdata(dev);
+
+ drm_panel_remove(&panel->base);
+ panel_edp_shutdown(dev);
pm_runtime_dont_use_autosuspend(dev);
pm_runtime_disable(dev);
@@ -988,14 +982,6 @@ static void panel_edp_remove(struct device *dev)
panel->drm_edid = NULL;
}
-static void panel_edp_shutdown(struct device *dev)
-{
- struct panel_edp *panel = dev_get_drvdata(dev);
-
- drm_panel_disable(&panel->base);
- drm_panel_unprepare(&panel->base);
-}
-
static const struct display_timing auo_b101ean01_timing = {
.pixelclock = { 65300000, 72500000, 75000000 },
.hactive = { 1280, 1280, 1280 },
@@ -1059,33 +1045,6 @@ static const struct panel_desc auo_b116xak01 = {
},
};
-static const struct drm_display_mode auo_b133han05_mode = {
- .clock = 142600,
- .hdisplay = 1920,
- .hsync_start = 1920 + 58,
- .hsync_end = 1920 + 58 + 42,
- .htotal = 1920 + 58 + 42 + 60,
- .vdisplay = 1080,
- .vsync_start = 1080 + 3,
- .vsync_end = 1080 + 3 + 5,
- .vtotal = 1080 + 3 + 5 + 54,
-};
-
-static const struct panel_desc auo_b133han05 = {
- .modes = &auo_b133han05_mode,
- .num_modes = 1,
- .bpc = 8,
- .size = {
- .width = 293,
- .height = 165,
- },
- .delay = {
- .hpd_reliable = 100,
- .enable = 20,
- .unprepare = 50,
- },
-};
-
static const struct drm_display_mode auo_b133htn01_mode = {
.clock = 150660,
.hdisplay = 1920,
@@ -1135,33 +1094,6 @@ static const struct panel_desc auo_b133xtn01 = {
},
};
-static const struct drm_display_mode auo_b140han06_mode = {
- .clock = 141000,
- .hdisplay = 1920,
- .hsync_start = 1920 + 16,
- .hsync_end = 1920 + 16 + 16,
- .htotal = 1920 + 16 + 16 + 152,
- .vdisplay = 1080,
- .vsync_start = 1080 + 3,
- .vsync_end = 1080 + 3 + 14,
- .vtotal = 1080 + 3 + 14 + 19,
-};
-
-static const struct panel_desc auo_b140han06 = {
- .modes = &auo_b140han06_mode,
- .num_modes = 1,
- .bpc = 8,
- .size = {
- .width = 309,
- .height = 174,
- },
- .delay = {
- .hpd_reliable = 100,
- .enable = 20,
- .unprepare = 50,
- },
-};
-
static const struct drm_display_mode boe_nv101wxmn51_modes[] = {
{
.clock = 71900,
@@ -1428,33 +1360,6 @@ static const struct panel_desc innolux_p120zdg_bf1 = {
},
};
-static const struct drm_display_mode ivo_m133nwf4_r0_mode = {
- .clock = 138778,
- .hdisplay = 1920,
- .hsync_start = 1920 + 24,
- .hsync_end = 1920 + 24 + 48,
- .htotal = 1920 + 24 + 48 + 88,
- .vdisplay = 1080,
- .vsync_start = 1080 + 3,
- .vsync_end = 1080 + 3 + 12,
- .vtotal = 1080 + 3 + 12 + 17,
- .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC,
-};
-
-static const struct panel_desc ivo_m133nwf4_r0 = {
- .modes = &ivo_m133nwf4_r0_mode,
- .num_modes = 1,
- .bpc = 8,
- .size = {
- .width = 294,
- .height = 165,
- },
- .delay = {
- .hpd_absent = 200,
- .unprepare = 500,
- },
-};
-
static const struct drm_display_mode kingdisplay_kd116n21_30nv_a010_mode = {
.clock = 81000,
.hdisplay = 1366,
@@ -1703,98 +1608,40 @@ static const struct panel_desc sharp_lq123p1jx31 = {
},
};
-static const struct drm_display_mode sharp_lq140m1jw46_mode[] = {
- {
- .clock = 346500,
- .hdisplay = 1920,
- .hsync_start = 1920 + 48,
- .hsync_end = 1920 + 48 + 32,
- .htotal = 1920 + 48 + 32 + 80,
- .vdisplay = 1080,
- .vsync_start = 1080 + 3,
- .vsync_end = 1080 + 3 + 5,
- .vtotal = 1080 + 3 + 5 + 69,
- .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
- }, {
- .clock = 144370,
- .hdisplay = 1920,
- .hsync_start = 1920 + 48,
- .hsync_end = 1920 + 48 + 32,
- .htotal = 1920 + 48 + 32 + 80,
- .vdisplay = 1080,
- .vsync_start = 1080 + 3,
- .vsync_end = 1080 + 3 + 5,
- .vtotal = 1080 + 3 + 5 + 69,
- .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
- },
-};
-
-static const struct panel_desc sharp_lq140m1jw46 = {
- .modes = sharp_lq140m1jw46_mode,
- .num_modes = ARRAY_SIZE(sharp_lq140m1jw46_mode),
- .bpc = 8,
- .size = {
- .width = 309,
- .height = 174,
- },
- .delay = {
- .hpd_absent = 80,
- .enable = 50,
- .unprepare = 500,
- },
-};
-
-static const struct drm_display_mode starry_kr122ea0sra_mode = {
- .clock = 147000,
- .hdisplay = 1920,
- .hsync_start = 1920 + 16,
- .hsync_end = 1920 + 16 + 16,
- .htotal = 1920 + 16 + 16 + 32,
- .vdisplay = 1200,
- .vsync_start = 1200 + 15,
- .vsync_end = 1200 + 15 + 2,
- .vtotal = 1200 + 15 + 2 + 18,
- .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
-};
-
-static const struct panel_desc starry_kr122ea0sra = {
- .modes = &starry_kr122ea0sra_mode,
- .num_modes = 1,
- .size = {
- .width = 263,
- .height = 164,
- },
- .delay = {
- /* TODO: should be hpd-absent and no-hpd should be set? */
- .hpd_reliable = 10 + 200,
- .enable = 50,
- .unprepare = 10 + 500,
- },
-};
-
static const struct of_device_id platform_of_match[] = {
{
/* Must be first */
.compatible = "edp-panel",
- }, {
+ },
+ /*
+ * Do not add panels to the list below unless they cannot be handled by
+ * the generic edp-panel compatible.
+ *
+ * The only two valid reasons are:
+ * - Because of the panel issues (e.g. broken EDID or broken
+ * identification).
+ * - Because the eDP drivers didn't wire up the AUX bus properly.
+ * NOTE that, though this is a marginally valid reason,
+ * some justification needs to be made for why the platform can't
+ * wire up the AUX bus properly.
+ *
+ * In all other cases the platform should use the aux-bus and declare
+ * the panel using the 'edp-panel' compatible as a device on the AUX
+ * bus.
+ */
+ {
.compatible = "auo,b101ean01",
.data = &auo_b101ean01,
}, {
.compatible = "auo,b116xa01",
.data = &auo_b116xak01,
}, {
- .compatible = "auo,b133han05",
- .data = &auo_b133han05,
- }, {
.compatible = "auo,b133htn01",
.data = &auo_b133htn01,
}, {
.compatible = "auo,b133xtn01",
.data = &auo_b133xtn01,
}, {
- .compatible = "auo,b140han06",
- .data = &auo_b140han06,
- }, {
.compatible = "boe,nv101wxmn51",
.data = &boe_nv101wxmn51,
}, {
@@ -1822,9 +1669,6 @@ static const struct of_device_id platform_of_match[] = {
.compatible = "innolux,p120zdg-bf1",
.data = &innolux_p120zdg_bf1,
}, {
- .compatible = "ivo,m133nwf4-r0",
- .data = &ivo_m133nwf4_r0,
- }, {
.compatible = "kingdisplay,kd116n21-30nv-a010",
.data = &kingdisplay_kd116n21_30nv_a010,
}, {
@@ -1855,12 +1699,6 @@ static const struct of_device_id platform_of_match[] = {
.compatible = "sharp,lq123p1jx31",
.data = &sharp_lq123p1jx31,
}, {
- .compatible = "sharp,lq140m1jw46",
- .data = &sharp_lq140m1jw46,
- }, {
- .compatible = "starry,kr122ea0sra",
- .data = &starry_kr122ea0sra,
- }, {
/* sentinel */
}
};
@@ -1911,6 +1749,12 @@ static const struct panel_delay delay_200_500_e80_d50 = {
.disable = 50,
};
+static const struct panel_delay delay_80_500_e50 = {
+ .hpd_absent = 80,
+ .unprepare = 500,
+ .enable = 50,
+};
+
static const struct panel_delay delay_100_500_e200 = {
.hpd_absent = 100,
.unprepare = 500,
@@ -1983,8 +1827,10 @@ static const struct edp_panel_entry edp_panels[] = {
EDP_PANEL_ENTRY('A', 'U', 'O', 0x1062, &delay_200_500_e50, "B120XAN01.0"),
EDP_PANEL_ENTRY('A', 'U', 'O', 0x125c, &delay_200_500_e50, "Unknown"),
EDP_PANEL_ENTRY('A', 'U', 'O', 0x145c, &delay_200_500_e50, "B116XAB01.4"),
+ EDP_PANEL_ENTRY('A', 'U', 'O', 0x1999, &delay_200_500_e50, "Unknown"),
EDP_PANEL_ENTRY('A', 'U', 'O', 0x1e9b, &delay_200_500_e50, "B133UAN02.1"),
EDP_PANEL_ENTRY('A', 'U', 'O', 0x1ea5, &delay_200_500_e50, "B116XAK01.6"),
+ EDP_PANEL_ENTRY('A', 'U', 'O', 0x203d, &delay_200_500_e50, "B140HTN02.0"),
EDP_PANEL_ENTRY('A', 'U', 'O', 0x208d, &delay_200_500_e50, "B140HTN02.1"),
EDP_PANEL_ENTRY('A', 'U', 'O', 0x235c, &delay_200_500_e50, "B116XTN02.3"),
EDP_PANEL_ENTRY('A', 'U', 'O', 0x239b, &delay_200_500_e50, "B116XAN06.1"),
@@ -2005,6 +1851,8 @@ static const struct edp_panel_entry edp_panels[] = {
EDP_PANEL_ENTRY('B', 'O', 'E', 0x0607, &delay_200_500_e200, "Unknown"),
EDP_PANEL_ENTRY('B', 'O', 'E', 0x0608, &delay_200_500_e50, "NT116WHM-N11"),
+ EDP_PANEL_ENTRY('B', 'O', 'E', 0x0609, &delay_200_500_e50_po2e200, "NT116WHM-N21 V4.1"),
+ EDP_PANEL_ENTRY('B', 'O', 'E', 0x0623, &delay_200_500_e200, "NT116WHM-N21 V4.0"),
EDP_PANEL_ENTRY('B', 'O', 'E', 0x0668, &delay_200_500_e200, "Unknown"),
EDP_PANEL_ENTRY('B', 'O', 'E', 0x068f, &delay_200_500_e200, "Unknown"),
EDP_PANEL_ENTRY('B', 'O', 'E', 0x06e5, &delay_200_500_e200, "Unknown"),
@@ -2020,6 +1868,7 @@ static const struct edp_panel_entry edp_panels[] = {
EDP_PANEL_ENTRY('B', 'O', 'E', 0x0771, &delay_200_500_e200, "Unknown"),
EDP_PANEL_ENTRY('B', 'O', 'E', 0x0786, &delay_200_500_p2e80, "NV116WHM-T01"),
EDP_PANEL_ENTRY('B', 'O', 'E', 0x0797, &delay_200_500_e200, "Unknown"),
+ EDP_PANEL_ENTRY('B', 'O', 'E', 0x07a8, &delay_200_500_e50_po2e200, "NT116WHM-N21"),
EDP_PANEL_ENTRY('B', 'O', 'E', 0x07d1, &boe_nv133fhm_n61.delay, "NV133FHM-N61"),
EDP_PANEL_ENTRY('B', 'O', 'E', 0x07d3, &delay_200_500_e200, "Unknown"),
EDP_PANEL_ENTRY('B', 'O', 'E', 0x07f6, &delay_200_500_e200, "NT140FHM-N44"),
@@ -2067,6 +1916,7 @@ static const struct edp_panel_entry edp_panels[] = {
EDP_PANEL_ENTRY('C', 'M', 'N', 0x1157, &delay_200_500_e80_d50, "N116BGE-EA2"),
EDP_PANEL_ENTRY('C', 'M', 'N', 0x115b, &delay_200_500_e80_d50, "N116BCN-EB1"),
EDP_PANEL_ENTRY('C', 'M', 'N', 0x115e, &delay_200_500_e80_d50, "N116BCA-EA1"),
+ EDP_PANEL_ENTRY('C', 'M', 'N', 0x1160, &delay_200_500_e80_d50, "N116BCJ-EAK"),
EDP_PANEL_ENTRY('C', 'M', 'N', 0x1247, &delay_200_500_e80_d50, "N120ACA-EA1"),
EDP_PANEL_ENTRY('C', 'M', 'N', 0x142b, &delay_200_500_e80_d50, "N140HCA-EAC"),
EDP_PANEL_ENTRY('C', 'M', 'N', 0x142e, &delay_200_500_e80_d50, "N140BGA-EA4"),
@@ -2094,6 +1944,7 @@ static const struct edp_panel_entry edp_panels[] = {
EDP_PANEL_ENTRY('K', 'D', 'B', 0x0624, &kingdisplay_kd116n21_30nv_a010.delay, "116N21-30NV-A010"),
EDP_PANEL_ENTRY('K', 'D', 'B', 0x1118, &delay_200_500_e50, "KD116N29-30NK-A005"),
EDP_PANEL_ENTRY('K', 'D', 'B', 0x1120, &delay_200_500_e80_d50, "116N29-30NK-C007"),
+ EDP_PANEL_ENTRY('K', 'D', 'B', 0x1212, &delay_200_500_e50, "KD116N0930A16"),
EDP_PANEL_ENTRY('K', 'D', 'C', 0x044f, &delay_200_500_e50, "KD116N9-30NH-F3"),
EDP_PANEL_ENTRY('K', 'D', 'C', 0x05f1, &delay_200_500_e80_d50, "KD116N5-30NV-G7"),
@@ -2112,7 +1963,8 @@ static const struct edp_panel_entry edp_panels[] = {
EDP_PANEL_ENTRY('S', 'D', 'C', 0x416d, &delay_100_500_e200, "ATNA45AF01"),
EDP_PANEL_ENTRY('S', 'H', 'P', 0x1511, &delay_200_500_e50, "LQ140M1JW48"),
- EDP_PANEL_ENTRY('S', 'H', 'P', 0x1523, &sharp_lq140m1jw46.delay, "LQ140M1JW46"),
+ EDP_PANEL_ENTRY('S', 'H', 'P', 0x1523, &delay_80_500_e50, "LQ140M1JW46"),
+ EDP_PANEL_ENTRY('S', 'H', 'P', 0x153a, &delay_200_500_e50, "LQ140T1JH01"),
EDP_PANEL_ENTRY('S', 'H', 'P', 0x154c, &delay_200_500_p2e100, "LQ116M1JW10"),
EDP_PANEL_ENTRY('S', 'T', 'A', 0x0100, &delay_100_500_e200, "2081116HHD028001-51D"),
diff --git a/drivers/gpu/drm/panel/panel-himax-hx83102.c b/drivers/gpu/drm/panel/panel-himax-hx83102.c
new file mode 100644
index 000000000000..6e4b7e4644ce
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-himax-hx83102.c
@@ -0,0 +1,706 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for panels based on Himax HX83102 controller, such as:
+ *
+ * - Starry 10.51" WUXGA MIPI-DSI panel
+ *
+ * Based on drivers/gpu/drm/panel/panel-himax-hx8394.c
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regulator/consumer.h>
+
+#include <drm/drm_connector.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_panel.h>
+
+#include <video/mipi_display.h>
+
+/* Manufacturer specific DSI commands */
+#define HX83102_SETPOWER 0xb1
+#define HX83102_SETDISP 0xb2
+#define HX83102_SETCYC 0xb4
+#define HX83102_SETEXTC 0xb9
+#define HX83102_SETMIPI 0xba
+#define HX83102_SETVDC 0xbc
+#define HX83102_SETBANK 0xbd
+#define HX83102_UNKNOWN_BE 0xbe
+#define HX83102_SETPTBA 0xbf
+#define HX83102_SETSTBA 0xc0
+#define HX83102_SETTCON 0xc7
+#define HX83102_SETRAMDMY 0xc8
+#define HX83102_SETPWM 0xc9
+#define HX83102_SETCLOCK 0xcb
+#define HX83102_SETPANEL 0xcc
+#define HX83102_SETCASCADE 0xd0
+#define HX83102_SETPCTRL 0xd1
+#define HX83102_UNKNOWN_D2 0xd2
+#define HX83102_SETGIP0 0xd3
+#define HX83102_SETGIP1 0xd5
+#define HX83102_SETGIP2 0xd6
+#define HX83102_SETGIP3 0xd8
+#define HX83102_SETGMA 0xe0
+#define HX83102_UNKNOWN_E1 0xe1
+#define HX83102_SETTP1 0xe7
+#define HX83102_SETSPCCMD 0xe9
+
+struct hx83102 {
+ struct drm_panel base;
+ struct mipi_dsi_device *dsi;
+
+ const struct hx83102_panel_desc *desc;
+
+ enum drm_panel_orientation orientation;
+ struct regulator *pp1800;
+ struct regulator *avee;
+ struct regulator *avdd;
+ struct gpio_desc *enable_gpio;
+};
+
+struct hx83102_panel_desc {
+ const struct drm_display_mode *modes;
+
+ /**
+ * @width_mm: width of the panel's active display area
+ * @height_mm: height of the panel's active display area
+ */
+ struct {
+ unsigned int width_mm;
+ unsigned int height_mm;
+ } size;
+
+ int (*init)(struct hx83102 *ctx);
+};
+
+static inline struct hx83102 *panel_to_hx83102(struct drm_panel *panel)
+{
+ return container_of(panel, struct hx83102, base);
+}
+
+static void hx83102_enable_extended_cmds(struct mipi_dsi_multi_context *dsi_ctx, bool enable)
+{
+ if (enable)
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX83102_SETEXTC, 0x83, 0x10, 0x21, 0x55, 0x00);
+ else
+ mipi_dsi_dcs_write_seq_multi(dsi_ctx, HX83102_SETEXTC, 0x00, 0x00, 0x00);
+}
+
+static int starry_himax83102_j02_init(struct hx83102 *ctx)
+{
+ struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi };
+
+ hx83102_enable_extended_cmds(&dsi_ctx, true);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPOWER, 0x2c, 0xb5, 0xb5, 0x31, 0xf1,
+ 0x31, 0xd7, 0x2f, 0x36, 0x36, 0x36, 0x36, 0x1a, 0x8b, 0x11,
+ 0x65, 0x00, 0x88, 0xfa, 0xff, 0xff, 0x8f, 0xff, 0x08, 0x74,
+ 0x33);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETDISP, 0x00, 0x47, 0xb0, 0x80, 0x00,
+ 0x12, 0x72, 0x3c, 0xa3, 0x03, 0x03, 0x00, 0x00, 0x88, 0xf5);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETCYC, 0x76, 0x76, 0x76, 0x76, 0x76,
+ 0x76, 0x63, 0x5c, 0x63, 0x5c, 0x01, 0x9e);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0xcd);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETMIPI, 0x84);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETVDC, 0x1b, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_UNKNOWN_BE, 0x20);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPTBA, 0xfc, 0xc4);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSTBA, 0x36, 0x36, 0x22, 0x11, 0x22,
+ 0xa0, 0x61, 0x08, 0xf5, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0xcc);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETTCON, 0x80);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0xc6);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETRAMDMY, 0x97);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPWM, 0x00, 0x1e, 0x13, 0x88, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETCLOCK, 0x08, 0x13, 0x07, 0x00, 0x0f, 0x33);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPANEL, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0xc4);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETCASCADE, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPCTRL, 0x37, 0x06, 0x00, 0x02, 0x04, 0x0c,
+ 0xff);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_UNKNOWN_D2, 0x1f, 0x11, 0x1f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP0, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x08, 0x37, 0x47, 0x34, 0x3b, 0x12, 0x12, 0x03, 0x03,
+ 0x32, 0x10, 0x10, 0x00, 0x10, 0x32, 0x10, 0x08, 0x00, 0x08, 0x32,
+ 0x17, 0x94, 0x07, 0x94, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP1, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x40, 0x40, 0x1a, 0x1a, 0x1b,
+ 0x1b, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x20, 0x21,
+ 0x28, 0x29, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP2, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x40, 0x40, 0x19, 0x19, 0x1a, 0x1a, 0x1b,
+ 0x1b, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x29, 0x28,
+ 0x21, 0x20, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP3, 0xaa, 0xba, 0xea, 0xaa, 0xaa, 0xa0,
+ 0xaa, 0xba, 0xea, 0xaa, 0xaa, 0xa0, 0xaa, 0xba, 0xea, 0xaa, 0xaa,
+ 0xa0, 0xaa, 0xba, 0xea, 0xaa, 0xaa, 0xa0, 0xaa, 0xba, 0xea, 0xaa,
+ 0xaa, 0xa0, 0xaa, 0xba, 0xea, 0xaa, 0xaa, 0xa0);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGMA, 0x00, 0x09, 0x14, 0x1e, 0x26, 0x48,
+ 0x61, 0x67, 0x6c, 0x67, 0x7d, 0x7f, 0x80, 0x8b, 0x87, 0x8f, 0x98,
+ 0xab, 0xab, 0x55, 0x5c, 0x68, 0x73, 0x00, 0x09, 0x14, 0x1e, 0x26,
+ 0x48, 0x61, 0x67, 0x6c, 0x67, 0x7d, 0x7f, 0x80, 0x8b, 0x87, 0x8f,
+ 0x98, 0xab, 0xab, 0x55, 0x5c, 0x68, 0x73);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETTP1, 0x0e, 0x10, 0x10, 0x21, 0x2b, 0x9a,
+ 0x02, 0x54, 0x9a, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x12, 0x05,
+ 0x02, 0x02, 0x10);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPOWER, 0x01, 0xbf, 0x11);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETCLOCK, 0x86);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_UNKNOWN_D2, 0x3c, 0xfa);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP0, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x0c, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETTP1, 0x02, 0x00, 0x28, 0x01, 0x7e, 0x0f,
+ 0x7e, 0x10, 0xa0, 0x00, 0x00, 0x20, 0x40, 0x50, 0x40);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP3, 0xff, 0xff, 0xbf, 0xfe, 0xaa, 0xa0,
+ 0xff, 0xff, 0xbf, 0xfe, 0xaa, 0xa0);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETTP1, 0xfe, 0x04, 0xfe, 0x04, 0xfe, 0x04,
+ 0x03, 0x03, 0x03, 0x26, 0x00, 0x26, 0x81, 0x02, 0x40, 0x00, 0x20,
+ 0x9e, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0xc6);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETCYC, 0x03, 0xff, 0xf8);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP3, 0x00, 0x2a, 0xaa, 0xa8, 0x00, 0x00,
+ 0x00, 0x2a, 0xaa, 0xa8, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xfc, 0x00,
+ 0x00, 0x00, 0x3f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x2a, 0xaa, 0xa8,
+ 0x00, 0x00, 0x00, 0x2a, 0xaa, 0xa8, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0xc4);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETMIPI, 0x96);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0xc5);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETMIPI, 0x4f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x00);
+
+ return dsi_ctx.accum_err;
+};
+
+static int boe_nv110wum_init(struct hx83102 *ctx)
+{
+ struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi };
+
+ msleep(60);
+
+ hx83102_enable_extended_cmds(&dsi_ctx, true);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPOWER, 0x2c, 0xaf, 0xaf, 0x2b, 0xeb, 0x42,
+ 0xe1, 0x4d, 0x36, 0x36, 0x36, 0x36, 0x1a, 0x8b, 0x11, 0x65, 0x00,
+ 0x88, 0xfa, 0xff, 0xff, 0x8f, 0xff, 0x08, 0x9a, 0x33);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETDISP, 0x00, 0x47, 0xb0, 0x80, 0x00, 0x12,
+ 0x71, 0x3c, 0xa3, 0x11, 0x00, 0x00, 0x00, 0x88, 0xf5, 0x22, 0x8f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETCYC, 0x49, 0x49, 0x32, 0x32, 0x14, 0x32,
+ 0x84, 0x6e, 0x84, 0x6e, 0x01, 0x9c);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0xcd);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETMIPI, 0x84);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETVDC, 0x1b, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_UNKNOWN_BE, 0x20);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPTBA, 0xfc, 0x84);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSTBA, 0x36, 0x36, 0x22, 0x00, 0x00, 0xa0,
+ 0x61, 0x08, 0xf5, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0xcc);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETTCON, 0x80);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0xc6);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETRAMDMY, 0x97);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPWM, 0x00, 0x1e, 0x30, 0xd4, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETCLOCK, 0x08, 0x13, 0x07, 0x00, 0x0f, 0x34);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPANEL, 0x02, 0x03, 0x44);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0xc4);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETCASCADE, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPCTRL, 0x37, 0x06, 0x00, 0x02, 0x04, 0x0c, 0xff);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_UNKNOWN_D2, 0x1f, 0x11, 0x1f, 0x11);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP0, 0x06, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x08, 0x04, 0x08, 0x37, 0x37, 0x64, 0x4b, 0x11, 0x11, 0x03, 0x03, 0x32,
+ 0x10, 0x0e, 0x00, 0x0e, 0x32, 0x10, 0x0a, 0x00, 0x0a, 0x32, 0x17, 0x98,
+ 0x07, 0x98, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP1, 0x18, 0x18, 0x18, 0x18, 0x1e, 0x1e,
+ 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x24, 0x24, 0x24, 0x24, 0x07, 0x06,
+ 0x07, 0x06, 0x05, 0x04, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x01, 0x00,
+ 0x01, 0x00, 0x21, 0x20, 0x21, 0x20, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP3, 0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xa0,
+ 0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xa0);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGMA, 0x00, 0x05, 0x0d, 0x14, 0x1b, 0x2c,
+ 0x44, 0x49, 0x51, 0x4c, 0x67, 0x6c, 0x71, 0x80, 0x7d, 0x84, 0x8d, 0xa0,
+ 0xa0, 0x4f, 0x58, 0x64, 0x73, 0x00, 0x05, 0x0d, 0x14, 0x1b, 0x2c, 0x44,
+ 0x49, 0x51, 0x4c, 0x67, 0x6c, 0x71, 0x80, 0x7d, 0x84, 0x8d, 0xa0, 0xa0,
+ 0x4f, 0x58, 0x64, 0x73);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETTP1, 0x07, 0x10, 0x10, 0x1a, 0x26, 0x9e,
+ 0x00, 0x53, 0x9b, 0x14, 0x14);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_UNKNOWN_E1, 0x11, 0x00, 0x00, 0x89, 0x30, 0x80,
+ 0x07, 0x80, 0x02, 0x58, 0x00, 0x14, 0x02, 0x58, 0x02, 0x58, 0x02, 0x00,
+ 0x02, 0x2c, 0x00, 0x20, 0x02, 0x02, 0x00, 0x08, 0x00, 0x0c, 0x05, 0x0e,
+ 0x04, 0x94, 0x18, 0x00, 0x10, 0xf0, 0x03, 0x0c, 0x20, 0x00, 0x06, 0x0b,
+ 0x0b, 0x33, 0x0e);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP3, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xa0,
+ 0xff, 0xff, 0xff, 0xff, 0xfa, 0xa0);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPOWER, 0x01, 0xbf, 0x11);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETCLOCK, 0x86);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_UNKNOWN_D2, 0x96);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0xc9);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP0, 0x84);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0xd1);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_UNKNOWN_E1, 0xf6, 0x2b, 0x34, 0x2b, 0x74, 0x3b,
+ 0x74, 0x6b, 0x74);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETTP1, 0x02, 0x00, 0x2b, 0x01, 0x7e, 0x0f,
+ 0x7e, 0x10, 0xa0, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETCYC, 0x02, 0x00, 0xbb, 0x11);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP3, 0xff, 0xaf, 0xff, 0xff, 0xfa, 0xa0,
+ 0xff, 0xaf, 0xff, 0xff, 0xfa, 0xa0);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETTP1, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01,
+ 0x00, 0x00, 0x00, 0x23, 0x00, 0x23, 0x81, 0x02, 0x40, 0x00, 0x20, 0x65,
+ 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP3, 0xaa, 0xaf, 0xaa, 0xaa, 0xa0, 0x00,
+ 0xaa, 0xaf, 0xaa, 0xaa, 0xa0, 0x00, 0xaa, 0xaf, 0xaa, 0xaa, 0xa0, 0x00,
+ 0xaa, 0xaf, 0xaa, 0xaa, 0xa0, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0xc6);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETCYC, 0x03, 0xff, 0xf8);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_UNKNOWN_E1, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0xc4);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETMIPI, 0x96);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0xc5);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETMIPI, 0x4f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x00);
+ hx83102_enable_extended_cmds(&dsi_ctx, false);
+
+ mipi_dsi_msleep(&dsi_ctx, 50);
+
+ return dsi_ctx.accum_err;
+};
+
+static int ivo_t109nw41_init(struct hx83102 *ctx)
+{
+ struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi };
+
+ msleep(60);
+
+ hx83102_enable_extended_cmds(&dsi_ctx, true);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPOWER, 0x2c, 0xed, 0xed, 0x0f, 0xcf, 0x42,
+ 0xf5, 0x39, 0x36, 0x36, 0x36, 0x36, 0x32, 0x8b, 0x11, 0x65, 0x00, 0x88,
+ 0xfa, 0xff, 0xff, 0x8f, 0xff, 0x08, 0xd6, 0x33);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETDISP, 0x00, 0x47, 0xb0, 0x80, 0x00, 0x12,
+ 0x71, 0x3c, 0xa3, 0x22, 0x20, 0x00, 0x00, 0x88, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETCYC, 0x35, 0x35, 0x43, 0x43, 0x35, 0x35,
+ 0x30, 0x7a, 0x30, 0x7a, 0x01, 0x9d);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0xcd);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETMIPI, 0x84);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETVDC, 0x1b, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_UNKNOWN_BE, 0x20);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPTBA, 0xfc, 0xc4);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSTBA, 0x34, 0x34, 0x22, 0x11, 0x22, 0xa0,
+ 0x31, 0x08, 0xf5, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0xcc);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETTCON, 0x80);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0xd3);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETTCON, 0x22);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0xc6);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETRAMDMY, 0x97);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPWM, 0x00, 0x1e, 0x13, 0x88, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETCLOCK, 0x08, 0x13, 0x07, 0x00, 0x0f, 0x34);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPANEL, 0x02, 0x03, 0x44);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0xc4);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETCASCADE, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPCTRL, 0x07, 0x06, 0x00, 0x02, 0x04, 0x2c,
+ 0xff);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP0, 0x06, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x08, 0x08, 0x08, 0x37, 0x07, 0x64, 0x7c, 0x11, 0x11, 0x03, 0x03, 0x32,
+ 0x10, 0x0e, 0x00, 0x0e, 0x32, 0x17, 0x97, 0x07, 0x97, 0x32, 0x00, 0x02,
+ 0x00, 0x02, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP1, 0x25, 0x24, 0x25, 0x24, 0x18, 0x18,
+ 0x18, 0x18, 0x07, 0x06, 0x07, 0x06, 0x05, 0x04, 0x05, 0x04, 0x03, 0x02,
+ 0x03, 0x02, 0x01, 0x00, 0x01, 0x00, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f,
+ 0x1f, 0x1f, 0x21, 0x20, 0x21, 0x20, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP3, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa0,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGMA, 0x04, 0x04, 0x06, 0x0a, 0x0a, 0x05,
+ 0x12, 0x14, 0x17, 0x13, 0x2c, 0x33, 0x39, 0x4b, 0x4c, 0x56, 0x61, 0x78,
+ 0x7a, 0x41, 0x50, 0x68, 0x73, 0x04, 0x04, 0x06, 0x0a, 0x0a, 0x05, 0x12,
+ 0x14, 0x17, 0x13, 0x2c, 0x33, 0x39, 0x4b, 0x4c, 0x56, 0x61, 0x78, 0x7a,
+ 0x41, 0x50, 0x68, 0x73);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETTP1, 0x07, 0x10, 0x10, 0x1a, 0x26, 0x9e,
+ 0x00, 0x4f, 0xa0, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x12, 0x0a, 0x02,
+ 0x02, 0x00, 0x33, 0x02, 0x04, 0x18, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPOWER, 0x01, 0x7f, 0x11, 0xfd);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETCLOCK, 0x86);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP0, 0x00, 0x00, 0x04, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa0,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETTP1, 0x02, 0x00, 0x2b, 0x01, 0x7e, 0x0f,
+ 0x7e, 0x10, 0xa0, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPTBA, 0xf2);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETCLOCK, 0x03, 0x07, 0x00, 0x10, 0x79);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGIP3, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xa0,
+ 0xff, 0xff, 0xff, 0xff, 0xfa, 0xa0);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETTP1, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01,
+ 0x00, 0x00, 0x00, 0x23, 0x00, 0x23, 0x81, 0x02, 0x40, 0x00, 0x20, 0x6e,
+ 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa0,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa0, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xa0,
+ 0xff, 0xff, 0xff, 0xff, 0xfa, 0xa0, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa0,
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0xc6);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETCYC, 0x03, 0xff, 0xf8);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_UNKNOWN_E1, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_UNKNOWN_D2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0xc4);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETMIPI, 0x96);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0xc5);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETMIPI, 0x4f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETSPCCMD, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETBANK, 0x00);
+ hx83102_enable_extended_cmds(&dsi_ctx, false);
+
+ mipi_dsi_msleep(&dsi_ctx, 60);
+
+ return dsi_ctx.accum_err;
+};
+
+static const struct drm_display_mode starry_mode = {
+ .clock = 162680,
+ .hdisplay = 1200,
+ .hsync_start = 1200 + 60,
+ .hsync_end = 1200 + 60 + 20,
+ .htotal = 1200 + 60 + 20 + 40,
+ .vdisplay = 1920,
+ .vsync_start = 1920 + 116,
+ .vsync_end = 1920 + 116 + 8,
+ .vtotal = 1920 + 116 + 8 + 12,
+ .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
+};
+
+static const struct hx83102_panel_desc starry_desc = {
+ .modes = &starry_mode,
+ .size = {
+ .width_mm = 141,
+ .height_mm = 226,
+ },
+ .init = starry_himax83102_j02_init,
+};
+
+static const struct drm_display_mode boe_tv110wum_default_mode = {
+ .clock = 167700,
+ .hdisplay = 1200,
+ .hsync_start = 1200 + 75,
+ .hsync_end = 1200 + 75 + 20,
+ .htotal = 1200 + 75 + 20 + 65,
+ .vdisplay = 1920,
+ .vsync_start = 1920 + 115,
+ .vsync_end = 1920 + 115 + 8,
+ .vtotal = 1920 + 115 + 8 + 12,
+ .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
+};
+
+static const struct hx83102_panel_desc boe_nv110wum_desc = {
+ .modes = &boe_tv110wum_default_mode,
+ .size = {
+ .width_mm = 147,
+ .height_mm = 235,
+ },
+ .init = boe_nv110wum_init,
+};
+
+static const struct drm_display_mode ivo_t109nw41_default_mode = {
+ .clock = 167700,
+ .hdisplay = 1200,
+ .hsync_start = 1200 + 75,
+ .hsync_end = 1200 + 75 + 20,
+ .htotal = 1200 + 75 + 20 + 65,
+ .vdisplay = 1920,
+ .vsync_start = 1920 + 115,
+ .vsync_end = 1920 + 115 + 8,
+ .vtotal = 1920 + 115 + 8 + 12,
+ .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
+};
+
+static const struct hx83102_panel_desc ivo_t109nw41_desc = {
+ .modes = &ivo_t109nw41_default_mode,
+ .size = {
+ .width_mm = 147,
+ .height_mm = 235,
+ },
+ .init = ivo_t109nw41_init,
+};
+
+static int hx83102_enable(struct drm_panel *panel)
+{
+ msleep(130);
+ return 0;
+}
+
+static int hx83102_disable(struct drm_panel *panel)
+{
+ struct hx83102 *ctx = panel_to_hx83102(panel);
+ struct mipi_dsi_device *dsi = ctx->dsi;
+ struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi };
+
+ dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
+
+ mipi_dsi_dcs_set_display_off_multi(&dsi_ctx);
+ mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx);
+
+ mipi_dsi_msleep(&dsi_ctx, 150);
+
+ return dsi_ctx.accum_err;
+}
+
+static int hx83102_unprepare(struct drm_panel *panel)
+{
+ struct hx83102 *ctx = panel_to_hx83102(panel);
+
+ gpiod_set_value(ctx->enable_gpio, 0);
+ usleep_range(1000, 2000);
+ regulator_disable(ctx->avee);
+ regulator_disable(ctx->avdd);
+ usleep_range(5000, 7000);
+ regulator_disable(ctx->pp1800);
+
+ return 0;
+}
+
+static int hx83102_prepare(struct drm_panel *panel)
+{
+ struct hx83102 *ctx = panel_to_hx83102(panel);
+ struct mipi_dsi_device *dsi = ctx->dsi;
+ struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi };
+
+ gpiod_set_value(ctx->enable_gpio, 0);
+ usleep_range(1000, 1500);
+
+ dsi_ctx.accum_err = regulator_enable(ctx->pp1800);
+ if (dsi_ctx.accum_err)
+ return dsi_ctx.accum_err;
+
+ usleep_range(3000, 5000);
+
+ dsi_ctx.accum_err = regulator_enable(ctx->avdd);
+ if (dsi_ctx.accum_err)
+ goto poweroff1v8;
+ dsi_ctx.accum_err = regulator_enable(ctx->avee);
+ if (dsi_ctx.accum_err)
+ goto poweroffavdd;
+
+ usleep_range(10000, 11000);
+
+ mipi_dsi_dcs_nop_multi(&dsi_ctx);
+ if (dsi_ctx.accum_err)
+ goto poweroff;
+
+ usleep_range(1000, 2000);
+
+ gpiod_set_value(ctx->enable_gpio, 1);
+ usleep_range(1000, 2000);
+ gpiod_set_value(ctx->enable_gpio, 0);
+ usleep_range(1000, 2000);
+ gpiod_set_value(ctx->enable_gpio, 1);
+ usleep_range(6000, 10000);
+
+ dsi_ctx.accum_err = ctx->desc->init(ctx);
+
+ mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);
+ mipi_dsi_msleep(&dsi_ctx, 120);
+ mipi_dsi_dcs_set_display_on_multi(&dsi_ctx);
+ if (dsi_ctx.accum_err)
+ goto poweroff;
+
+ return 0;
+
+poweroff:
+ gpiod_set_value(ctx->enable_gpio, 0);
+ regulator_disable(ctx->avee);
+poweroffavdd:
+ regulator_disable(ctx->avdd);
+poweroff1v8:
+ usleep_range(5000, 7000);
+ regulator_disable(ctx->pp1800);
+
+ return dsi_ctx.accum_err;
+}
+
+static int hx83102_get_modes(struct drm_panel *panel,
+ struct drm_connector *connector)
+{
+ struct hx83102 *ctx = panel_to_hx83102(panel);
+ const struct drm_display_mode *m = ctx->desc->modes;
+ struct drm_display_mode *mode;
+
+ mode = drm_mode_duplicate(connector->dev, m);
+
+ mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+ drm_mode_set_name(mode);
+ drm_mode_probed_add(connector, mode);
+
+ connector->display_info.width_mm = ctx->desc->size.width_mm;
+ connector->display_info.height_mm = ctx->desc->size.height_mm;
+ connector->display_info.bpc = 8;
+
+ return 1;
+}
+
+static enum drm_panel_orientation hx83102_get_orientation(struct drm_panel *panel)
+{
+ struct hx83102 *ctx = panel_to_hx83102(panel);
+
+ return ctx->orientation;
+}
+
+static const struct drm_panel_funcs hx83102_drm_funcs = {
+ .disable = hx83102_disable,
+ .unprepare = hx83102_unprepare,
+ .prepare = hx83102_prepare,
+ .enable = hx83102_enable,
+ .get_modes = hx83102_get_modes,
+ .get_orientation = hx83102_get_orientation,
+};
+
+static int hx83102_panel_add(struct hx83102 *ctx)
+{
+ struct device *dev = &ctx->dsi->dev;
+ int err;
+
+ ctx->avdd = devm_regulator_get(dev, "avdd");
+ if (IS_ERR(ctx->avdd))
+ return PTR_ERR(ctx->avdd);
+
+ ctx->avee = devm_regulator_get(dev, "avee");
+ if (IS_ERR(ctx->avee))
+ return PTR_ERR(ctx->avee);
+
+ ctx->pp1800 = devm_regulator_get(dev, "pp1800");
+ if (IS_ERR(ctx->pp1800))
+ return PTR_ERR(ctx->pp1800);
+
+ ctx->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
+ if (IS_ERR(ctx->enable_gpio))
+ return dev_err_probe(dev, PTR_ERR(ctx->enable_gpio), "Cannot get enable GPIO\n");
+
+ ctx->base.prepare_prev_first = true;
+
+ drm_panel_init(&ctx->base, dev, &hx83102_drm_funcs,
+ DRM_MODE_CONNECTOR_DSI);
+ err = of_drm_get_panel_orientation(dev->of_node, &ctx->orientation);
+ if (err < 0)
+ return dev_err_probe(dev, err, "failed to get orientation\n");
+
+ err = drm_panel_of_backlight(&ctx->base);
+ if (err)
+ return err;
+
+ ctx->base.funcs = &hx83102_drm_funcs;
+ ctx->base.dev = &ctx->dsi->dev;
+
+ drm_panel_add(&ctx->base);
+
+ return 0;
+}
+
+static int hx83102_probe(struct mipi_dsi_device *dsi)
+{
+ struct hx83102 *ctx;
+ int ret;
+ const struct hx83102_panel_desc *desc;
+
+ ctx = devm_kzalloc(&dsi->dev, sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ desc = of_device_get_match_data(&dsi->dev);
+ dsi->lanes = 4;
+ dsi->format = MIPI_DSI_FMT_RGB888;
+ dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
+ MIPI_DSI_MODE_LPM;
+ ctx->desc = desc;
+ ctx->dsi = dsi;
+ ret = hx83102_panel_add(ctx);
+ if (ret < 0)
+ return ret;
+
+ mipi_dsi_set_drvdata(dsi, ctx);
+
+ ret = mipi_dsi_attach(dsi);
+ if (ret)
+ drm_panel_remove(&ctx->base);
+
+ return ret;
+}
+
+static void hx83102_remove(struct mipi_dsi_device *dsi)
+{
+ struct hx83102 *ctx = mipi_dsi_get_drvdata(dsi);
+ int ret;
+
+ ret = mipi_dsi_detach(dsi);
+ if (ret < 0)
+ dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret);
+
+ if (ctx->base.dev)
+ drm_panel_remove(&ctx->base);
+}
+
+static const struct of_device_id hx83102_of_match[] = {
+ { .compatible = "boe,nv110wum-l60",
+ .data = &boe_nv110wum_desc
+ },
+ { .compatible = "ivo,t109nw41",
+ .data = &ivo_t109nw41_desc
+ },
+ { .compatible = "starry,himax83102-j02",
+ .data = &starry_desc
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, hx83102_of_match);
+
+static struct mipi_dsi_driver hx83102_driver = {
+ .probe = hx83102_probe,
+ .remove = hx83102_remove,
+ .driver = {
+ .name = "panel-himax-hx83102",
+ .of_match_table = hx83102_of_match,
+ },
+};
+module_mipi_dsi_driver(hx83102_driver);
+
+MODULE_AUTHOR("Cong Yang <yangcong5@huaqin.corp-partner.google.com>");
+MODULE_DESCRIPTION("DRM driver for Himax HX83102 based MIPI DSI panels");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/panel/panel-himax-hx8394.c b/drivers/gpu/drm/panel/panel-himax-hx8394.c
index ff0dc08b9829..cb9f46e853de 100644
--- a/drivers/gpu/drm/panel/panel-himax-hx8394.c
+++ b/drivers/gpu/drm/panel/panel-himax-hx8394.c
@@ -370,8 +370,7 @@ static int hx8394_enable(struct drm_panel *panel)
sleep_in:
/* This will probably fail, but let's try orderly power off anyway. */
- ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
- if (!ret)
+ if (!mipi_dsi_dcs_enter_sleep_mode(dsi))
msleep(50);
return ret;
diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
index b933380b7eb7..775d5d5e828c 100644
--- a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
@@ -32,7 +32,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_dma.h>
#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
@@ -651,7 +651,7 @@ static int ili9341_dbi_probe(struct spi_device *spi, struct gpio_desc *dc,
spi_set_drvdata(spi, drm);
- drm_fbdev_generic_setup(drm, 0);
+ drm_fbdev_dma_setup(drm, 0);
return 0;
}
@@ -723,7 +723,8 @@ static int ili9341_probe(struct spi_device *spi)
if (!strcmp(id->name, "sf-tc240t-9370-t"))
return ili9341_dpi_probe(spi, dc, reset);
- else if (!strcmp(id->name, "yx240qv29"))
+
+ if (!strcmp(id->name, "yx240qv29"))
return ili9341_dbi_probe(spi, dc, reset);
return -ENODEV;
diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
index 267a5307041c..266a087fe14c 100644
--- a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
@@ -15,6 +15,8 @@
#include <video/mipi_display.h>
+struct ili9882t;
+
/*
* Use this descriptor struct to describe different panels using the
* Ilitek ILI9882T display controller.
@@ -34,7 +36,7 @@ struct panel_desc {
unsigned long mode_flags;
enum mipi_dsi_pixel_format format;
- const struct panel_init_cmd *init_cmds;
+ int (*init)(struct ili9882t *boe);
unsigned int lanes;
};
@@ -52,371 +54,363 @@ struct ili9882t {
struct gpio_desc *enable_gpio;
};
-enum dsi_cmd_type {
- INIT_DCS_CMD,
- DELAY_CMD,
-};
-
-struct panel_init_cmd {
- enum dsi_cmd_type type;
- size_t len;
- const char *data;
-};
-
-#define _INIT_DCS_CMD(...) { \
- .type = INIT_DCS_CMD, \
- .len = sizeof((char[]){__VA_ARGS__}), \
- .data = (char[]){__VA_ARGS__} }
-
-#define _INIT_DELAY_CMD(...) { \
- .type = DELAY_CMD,\
- .len = sizeof((char[]){__VA_ARGS__}), \
- .data = (char[]){__VA_ARGS__} }
-
/* ILI9882-specific commands, add new commands as you decode them */
#define ILI9882T_DCS_SWITCH_PAGE 0xFF
-#define _INIT_SWITCH_PAGE_CMD(page) \
- _INIT_DCS_CMD(ILI9882T_DCS_SWITCH_PAGE, 0x98, 0x82, (page))
-
-static const struct panel_init_cmd starry_ili9882t_init_cmd[] = {
- _INIT_DELAY_CMD(5),
- _INIT_SWITCH_PAGE_CMD(0x01),
- _INIT_DCS_CMD(0x00, 0x42),
- _INIT_DCS_CMD(0x01, 0x11),
- _INIT_DCS_CMD(0x02, 0x00),
- _INIT_DCS_CMD(0x03, 0x00),
-
- _INIT_DCS_CMD(0x04, 0x01),
- _INIT_DCS_CMD(0x05, 0x11),
- _INIT_DCS_CMD(0x06, 0x00),
- _INIT_DCS_CMD(0x07, 0x00),
-
- _INIT_DCS_CMD(0x08, 0x80),
- _INIT_DCS_CMD(0x09, 0x81),
- _INIT_DCS_CMD(0x0A, 0x71),
- _INIT_DCS_CMD(0x0B, 0x00),
-
- _INIT_DCS_CMD(0x0C, 0x00),
- _INIT_DCS_CMD(0x0E, 0x1A),
-
- _INIT_DCS_CMD(0x24, 0x00),
- _INIT_DCS_CMD(0x25, 0x00),
- _INIT_DCS_CMD(0x26, 0x00),
- _INIT_DCS_CMD(0x27, 0x00),
-
- _INIT_DCS_CMD(0x2C, 0xD4),
- _INIT_DCS_CMD(0xB9, 0x40),
-
- _INIT_DCS_CMD(0xB0, 0x11),
-
- _INIT_DCS_CMD(0xE6, 0x32),
- _INIT_DCS_CMD(0xD1, 0x30),
-
- _INIT_DCS_CMD(0xD6, 0x55),
-
- _INIT_DCS_CMD(0xD0, 0x01),
- _INIT_DCS_CMD(0xE3, 0x93),
- _INIT_DCS_CMD(0xE4, 0x00),
- _INIT_DCS_CMD(0xE5, 0x80),
-
- _INIT_DCS_CMD(0x31, 0x07),
- _INIT_DCS_CMD(0x32, 0x07),
- _INIT_DCS_CMD(0x33, 0x07),
- _INIT_DCS_CMD(0x34, 0x07),
- _INIT_DCS_CMD(0x35, 0x07),
- _INIT_DCS_CMD(0x36, 0x01),
- _INIT_DCS_CMD(0x37, 0x00),
- _INIT_DCS_CMD(0x38, 0x28),
- _INIT_DCS_CMD(0x39, 0x29),
- _INIT_DCS_CMD(0x3A, 0x11),
- _INIT_DCS_CMD(0x3B, 0x13),
- _INIT_DCS_CMD(0x3C, 0x15),
- _INIT_DCS_CMD(0x3D, 0x17),
- _INIT_DCS_CMD(0x3E, 0x09),
- _INIT_DCS_CMD(0x3F, 0x0D),
- _INIT_DCS_CMD(0x40, 0x02),
- _INIT_DCS_CMD(0x41, 0x02),
- _INIT_DCS_CMD(0x42, 0x02),
- _INIT_DCS_CMD(0x43, 0x02),
- _INIT_DCS_CMD(0x44, 0x02),
- _INIT_DCS_CMD(0x45, 0x02),
- _INIT_DCS_CMD(0x46, 0x02),
-
- _INIT_DCS_CMD(0x47, 0x07),
- _INIT_DCS_CMD(0x48, 0x07),
- _INIT_DCS_CMD(0x49, 0x07),
- _INIT_DCS_CMD(0x4A, 0x07),
- _INIT_DCS_CMD(0x4B, 0x07),
- _INIT_DCS_CMD(0x4C, 0x01),
- _INIT_DCS_CMD(0x4D, 0x00),
- _INIT_DCS_CMD(0x4E, 0x28),
- _INIT_DCS_CMD(0x4F, 0x29),
- _INIT_DCS_CMD(0x50, 0x10),
- _INIT_DCS_CMD(0x51, 0x12),
- _INIT_DCS_CMD(0x52, 0x14),
- _INIT_DCS_CMD(0x53, 0x16),
- _INIT_DCS_CMD(0x54, 0x08),
- _INIT_DCS_CMD(0x55, 0x0C),
- _INIT_DCS_CMD(0x56, 0x02),
- _INIT_DCS_CMD(0x57, 0x02),
- _INIT_DCS_CMD(0x58, 0x02),
- _INIT_DCS_CMD(0x59, 0x02),
- _INIT_DCS_CMD(0x5A, 0x02),
- _INIT_DCS_CMD(0x5B, 0x02),
- _INIT_DCS_CMD(0x5C, 0x02),
-
- _INIT_DCS_CMD(0x61, 0x07),
- _INIT_DCS_CMD(0x62, 0x07),
- _INIT_DCS_CMD(0x63, 0x07),
- _INIT_DCS_CMD(0x64, 0x07),
- _INIT_DCS_CMD(0x65, 0x07),
- _INIT_DCS_CMD(0x66, 0x01),
- _INIT_DCS_CMD(0x67, 0x00),
- _INIT_DCS_CMD(0x68, 0x28),
- _INIT_DCS_CMD(0x69, 0x29),
- _INIT_DCS_CMD(0x6A, 0x16),
- _INIT_DCS_CMD(0x6B, 0x14),
- _INIT_DCS_CMD(0x6C, 0x12),
- _INIT_DCS_CMD(0x6D, 0x10),
- _INIT_DCS_CMD(0x6E, 0x0C),
- _INIT_DCS_CMD(0x6F, 0x08),
- _INIT_DCS_CMD(0x70, 0x02),
- _INIT_DCS_CMD(0x71, 0x02),
- _INIT_DCS_CMD(0x72, 0x02),
- _INIT_DCS_CMD(0x73, 0x02),
- _INIT_DCS_CMD(0x74, 0x02),
- _INIT_DCS_CMD(0x75, 0x02),
- _INIT_DCS_CMD(0x76, 0x02),
-
- _INIT_DCS_CMD(0x77, 0x07),
- _INIT_DCS_CMD(0x78, 0x07),
- _INIT_DCS_CMD(0x79, 0x07),
- _INIT_DCS_CMD(0x7A, 0x07),
- _INIT_DCS_CMD(0x7B, 0x07),
- _INIT_DCS_CMD(0x7C, 0x01),
- _INIT_DCS_CMD(0x7D, 0x00),
- _INIT_DCS_CMD(0x7E, 0x28),
- _INIT_DCS_CMD(0x7F, 0x29),
- _INIT_DCS_CMD(0x80, 0x17),
- _INIT_DCS_CMD(0x81, 0x15),
- _INIT_DCS_CMD(0x82, 0x13),
- _INIT_DCS_CMD(0x83, 0x11),
- _INIT_DCS_CMD(0x84, 0x0D),
- _INIT_DCS_CMD(0x85, 0x09),
- _INIT_DCS_CMD(0x86, 0x02),
- _INIT_DCS_CMD(0x87, 0x07),
- _INIT_DCS_CMD(0x88, 0x07),
- _INIT_DCS_CMD(0x89, 0x07),
- _INIT_DCS_CMD(0x8A, 0x07),
- _INIT_DCS_CMD(0x8B, 0x07),
- _INIT_DCS_CMD(0x8C, 0x07),
-
- _INIT_SWITCH_PAGE_CMD(0x02),
- _INIT_DCS_CMD(0x29, 0x3A),
- _INIT_DCS_CMD(0x2A, 0x3B),
-
- _INIT_DCS_CMD(0x06, 0x01),
- _INIT_DCS_CMD(0x07, 0x01),
- _INIT_DCS_CMD(0x08, 0x0C),
- _INIT_DCS_CMD(0x09, 0x44),
-
- _INIT_DCS_CMD(0x3C, 0x0A),
- _INIT_DCS_CMD(0x39, 0x11),
- _INIT_DCS_CMD(0x3D, 0x00),
- _INIT_DCS_CMD(0x3A, 0x0C),
- _INIT_DCS_CMD(0x3B, 0x44),
-
- _INIT_DCS_CMD(0x53, 0x1F),
- _INIT_DCS_CMD(0x5E, 0x40),
- _INIT_DCS_CMD(0x84, 0x00),
-
- _INIT_SWITCH_PAGE_CMD(0x03),
- _INIT_DCS_CMD(0x20, 0x01),
- _INIT_DCS_CMD(0x21, 0x3C),
- _INIT_DCS_CMD(0x22, 0xFA),
-
- _INIT_SWITCH_PAGE_CMD(0x0A),
- _INIT_DCS_CMD(0xE0, 0x01),
- _INIT_DCS_CMD(0xE2, 0x01),
- _INIT_DCS_CMD(0xE5, 0x91),
- _INIT_DCS_CMD(0xE6, 0x3C),
- _INIT_DCS_CMD(0xE7, 0x00),
- _INIT_DCS_CMD(0xE8, 0xFA),
-
- _INIT_SWITCH_PAGE_CMD(0x12),
- _INIT_DCS_CMD(0x87, 0x2C),
-
- _INIT_SWITCH_PAGE_CMD(0x05),
- _INIT_DCS_CMD(0x73, 0xE5),
- _INIT_DCS_CMD(0x7F, 0x6B),
- _INIT_DCS_CMD(0x6D, 0xA4),
- _INIT_DCS_CMD(0x79, 0x54),
- _INIT_DCS_CMD(0x69, 0x97),
- _INIT_DCS_CMD(0x6A, 0x97),
- _INIT_DCS_CMD(0xA5, 0x3F),
- _INIT_DCS_CMD(0x61, 0xDA),
- _INIT_DCS_CMD(0xA7, 0xF1),
- _INIT_DCS_CMD(0x5F, 0x01),
- _INIT_DCS_CMD(0x62, 0x3F),
- _INIT_DCS_CMD(0x1D, 0x90),
- _INIT_DCS_CMD(0x86, 0x87),
-
- _INIT_SWITCH_PAGE_CMD(0x06),
- _INIT_DCS_CMD(0xC0, 0x80),
- _INIT_DCS_CMD(0xC1, 0x07),
- _INIT_DCS_CMD(0xCA, 0x58),
- _INIT_DCS_CMD(0xCB, 0x02),
- _INIT_DCS_CMD(0xCE, 0x58),
- _INIT_DCS_CMD(0xCF, 0x02),
- _INIT_DCS_CMD(0x67, 0x60),
- _INIT_DCS_CMD(0x10, 0x00),
- _INIT_DCS_CMD(0x92, 0x22),
- _INIT_DCS_CMD(0xD3, 0x08),
- _INIT_DCS_CMD(0xD6, 0x55),
- _INIT_DCS_CMD(0xDC, 0x38),
-
- _INIT_SWITCH_PAGE_CMD(0x08),
- _INIT_DCS_CMD(0xE0, 0x00, 0x10, 0x2A, 0x4D, 0x61, 0x56, 0x6A, 0x6E, 0x79, 0x76, 0x8F, 0x95, 0x98, 0xAE, 0xAA, 0xB2, 0xBB, 0xCE, 0xC6, 0xBD, 0xD5, 0xE2, 0xE8),
- _INIT_DCS_CMD(0xE1, 0x00, 0x10, 0x2A, 0x4D, 0x61, 0x56, 0x6A, 0x6E, 0x79, 0x76, 0x8F, 0x95, 0x98, 0xAE, 0xAA, 0xB2, 0xBB, 0xCE, 0xC6, 0xBD, 0xD5, 0xE2, 0xE8),
-
- _INIT_SWITCH_PAGE_CMD(0x04),
- _INIT_DCS_CMD(0xBA, 0x81),
-
- _INIT_SWITCH_PAGE_CMD(0x0C),
- _INIT_DCS_CMD(0x00, 0x02),
- _INIT_DCS_CMD(0x01, 0x00),
- _INIT_DCS_CMD(0x02, 0x03),
- _INIT_DCS_CMD(0x03, 0x01),
- _INIT_DCS_CMD(0x04, 0x03),
- _INIT_DCS_CMD(0x05, 0x02),
- _INIT_DCS_CMD(0x06, 0x04),
- _INIT_DCS_CMD(0x07, 0x03),
- _INIT_DCS_CMD(0x08, 0x03),
- _INIT_DCS_CMD(0x09, 0x04),
- _INIT_DCS_CMD(0x0A, 0x04),
- _INIT_DCS_CMD(0x0B, 0x05),
- _INIT_DCS_CMD(0x0C, 0x04),
- _INIT_DCS_CMD(0x0D, 0x06),
- _INIT_DCS_CMD(0x0E, 0x05),
- _INIT_DCS_CMD(0x0F, 0x07),
- _INIT_DCS_CMD(0x10, 0x04),
- _INIT_DCS_CMD(0x11, 0x08),
- _INIT_DCS_CMD(0x12, 0x05),
- _INIT_DCS_CMD(0x13, 0x09),
- _INIT_DCS_CMD(0x14, 0x05),
- _INIT_DCS_CMD(0x15, 0x0A),
- _INIT_DCS_CMD(0x16, 0x06),
- _INIT_DCS_CMD(0x17, 0x0B),
- _INIT_DCS_CMD(0x18, 0x05),
- _INIT_DCS_CMD(0x19, 0x0C),
- _INIT_DCS_CMD(0x1A, 0x06),
- _INIT_DCS_CMD(0x1B, 0x0D),
- _INIT_DCS_CMD(0x1C, 0x06),
- _INIT_DCS_CMD(0x1D, 0x0E),
- _INIT_DCS_CMD(0x1E, 0x07),
- _INIT_DCS_CMD(0x1F, 0x0F),
- _INIT_DCS_CMD(0x20, 0x06),
- _INIT_DCS_CMD(0x21, 0x10),
- _INIT_DCS_CMD(0x22, 0x07),
- _INIT_DCS_CMD(0x23, 0x11),
- _INIT_DCS_CMD(0x24, 0x07),
- _INIT_DCS_CMD(0x25, 0x12),
- _INIT_DCS_CMD(0x26, 0x08),
- _INIT_DCS_CMD(0x27, 0x13),
- _INIT_DCS_CMD(0x28, 0x07),
- _INIT_DCS_CMD(0x29, 0x14),
- _INIT_DCS_CMD(0x2A, 0x08),
- _INIT_DCS_CMD(0x2B, 0x15),
- _INIT_DCS_CMD(0x2C, 0x08),
- _INIT_DCS_CMD(0x2D, 0x16),
- _INIT_DCS_CMD(0x2E, 0x09),
- _INIT_DCS_CMD(0x2F, 0x17),
- _INIT_DCS_CMD(0x30, 0x08),
- _INIT_DCS_CMD(0x31, 0x18),
- _INIT_DCS_CMD(0x32, 0x09),
- _INIT_DCS_CMD(0x33, 0x19),
- _INIT_DCS_CMD(0x34, 0x09),
- _INIT_DCS_CMD(0x35, 0x1A),
- _INIT_DCS_CMD(0x36, 0x0A),
- _INIT_DCS_CMD(0x37, 0x1B),
- _INIT_DCS_CMD(0x38, 0x0A),
- _INIT_DCS_CMD(0x39, 0x1C),
- _INIT_DCS_CMD(0x3A, 0x0A),
- _INIT_DCS_CMD(0x3B, 0x1D),
- _INIT_DCS_CMD(0x3C, 0x0A),
- _INIT_DCS_CMD(0x3D, 0x1E),
- _INIT_DCS_CMD(0x3E, 0x0A),
- _INIT_DCS_CMD(0x3F, 0x1F),
-
- _INIT_SWITCH_PAGE_CMD(0x04),
- _INIT_DCS_CMD(0xBA, 0x01),
-
- _INIT_SWITCH_PAGE_CMD(0x0E),
- _INIT_DCS_CMD(0x02, 0x0C),
- _INIT_DCS_CMD(0x20, 0x10),
- _INIT_DCS_CMD(0x25, 0x16),
- _INIT_DCS_CMD(0x26, 0xE0),
- _INIT_DCS_CMD(0x27, 0x00),
- _INIT_DCS_CMD(0x29, 0x71),
- _INIT_DCS_CMD(0x2A, 0x46),
- _INIT_DCS_CMD(0x2B, 0x1F),
- _INIT_DCS_CMD(0x2D, 0xC7),
- _INIT_DCS_CMD(0x31, 0x02),
- _INIT_DCS_CMD(0x32, 0xDF),
- _INIT_DCS_CMD(0x33, 0x5A),
- _INIT_DCS_CMD(0x34, 0xC0),
- _INIT_DCS_CMD(0x35, 0x5A),
- _INIT_DCS_CMD(0x36, 0xC0),
- _INIT_DCS_CMD(0x38, 0x65),
- _INIT_DCS_CMD(0x80, 0x3E),
- _INIT_DCS_CMD(0x81, 0xA0),
- _INIT_DCS_CMD(0xB0, 0x01),
- _INIT_DCS_CMD(0xB1, 0xCC),
- _INIT_DCS_CMD(0xC0, 0x12),
- _INIT_DCS_CMD(0xC2, 0xCC),
- _INIT_DCS_CMD(0xC3, 0xCC),
- _INIT_DCS_CMD(0xC4, 0xCC),
- _INIT_DCS_CMD(0xC5, 0xCC),
- _INIT_DCS_CMD(0xC6, 0xCC),
- _INIT_DCS_CMD(0xC7, 0xCC),
- _INIT_DCS_CMD(0xC8, 0xCC),
- _INIT_DCS_CMD(0xC9, 0xCC),
- _INIT_DCS_CMD(0x30, 0x00),
- _INIT_DCS_CMD(0x00, 0x81),
- _INIT_DCS_CMD(0x08, 0x02),
- _INIT_DCS_CMD(0x09, 0x00),
- _INIT_DCS_CMD(0x07, 0x21),
- _INIT_DCS_CMD(0x04, 0x10),
-
- _INIT_SWITCH_PAGE_CMD(0x1E),
- _INIT_DCS_CMD(0x60, 0x00),
- _INIT_DCS_CMD(0x64, 0x00),
- _INIT_DCS_CMD(0x6D, 0x00),
-
- _INIT_SWITCH_PAGE_CMD(0x0B),
- _INIT_DCS_CMD(0xA6, 0x44),
- _INIT_DCS_CMD(0xA7, 0xB6),
- _INIT_DCS_CMD(0xA8, 0x03),
- _INIT_DCS_CMD(0xA9, 0x03),
- _INIT_DCS_CMD(0xAA, 0x51),
- _INIT_DCS_CMD(0xAB, 0x51),
- _INIT_DCS_CMD(0xAC, 0x04),
- _INIT_DCS_CMD(0xBD, 0x92),
- _INIT_DCS_CMD(0xBE, 0xA1),
-
- _INIT_SWITCH_PAGE_CMD(0x05),
- _INIT_DCS_CMD(0x86, 0x87),
-
- _INIT_SWITCH_PAGE_CMD(0x06),
- _INIT_DCS_CMD(0x92, 0x22),
-
- _INIT_SWITCH_PAGE_CMD(0x00),
- _INIT_DCS_CMD(MIPI_DCS_EXIT_SLEEP_MODE),
- _INIT_DELAY_CMD(120),
- _INIT_DCS_CMD(MIPI_DCS_SET_DISPLAY_ON),
- _INIT_DELAY_CMD(20),
- {},
+#define ili9882t_switch_page(ctx, page) \
+ mipi_dsi_dcs_write_seq_multi(ctx, ILI9882T_DCS_SWITCH_PAGE, \
+ 0x98, 0x82, (page))
+
+static int starry_ili9882t_init(struct ili9882t *ili)
+{
+ struct mipi_dsi_multi_context ctx = { .dsi = ili->dsi };
+
+ usleep_range(5000, 5100);
+
+ ili9882t_switch_page(&ctx, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0x42);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x01, 0x11);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x02, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x03, 0x00);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x04, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x05, 0x11);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x06, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x00);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x08, 0x80);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x09, 0x81);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0a, 0x71);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0b, 0x00);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0c, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0e, 0x1a);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x24, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x26, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x27, 0x00);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2c, 0xd4);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb9, 0x40);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x11);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe6, 0x32);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd1, 0x30);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd6, 0x55);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd0, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe3, 0x93);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe4, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe5, 0x80);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x31, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x32, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x33, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x34, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x35, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x36, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x37, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x38, 0x28);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x39, 0x29);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3a, 0x11);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3b, 0x13);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3c, 0x15);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3d, 0x17);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3e, 0x09);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3f, 0x0d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x40, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x41, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x42, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x43, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x44, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x45, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x46, 0x02);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x47, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x48, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x49, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x4a, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x4b, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x4c, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x4d, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x4e, 0x28);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x4f, 0x29);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x50, 0x10);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x51, 0x12);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x52, 0x14);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x53, 0x16);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x54, 0x08);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x55, 0x0c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x56, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x57, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x58, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x59, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5a, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5b, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5c, 0x02);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x61, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x62, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x63, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x64, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x65, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x66, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x67, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x68, 0x28);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x69, 0x29);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x6a, 0x16);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x6b, 0x14);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x6c, 0x12);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x6d, 0x10);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x6e, 0x0c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x6f, 0x08);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x70, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x71, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x72, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x73, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x74, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x75, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x76, 0x02);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x77, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x78, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x79, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x7a, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x7b, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x7c, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x7d, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x7e, 0x28);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x7f, 0x29);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x80, 0x17);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x81, 0x15);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x82, 0x13);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x83, 0x11);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x84, 0x0d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x85, 0x09);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x86, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x87, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x88, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x89, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x8a, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x8b, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x8c, 0x07);
+
+ ili9882t_switch_page(&ctx, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x29, 0x3a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x3b);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x06, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x08, 0x0c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x09, 0x44);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3c, 0x0a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x39, 0x11);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3d, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3a, 0x0c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3b, 0x44);
+
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x53, 0x1f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5e, 0x40);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x84, 0x00);
+
+ ili9882t_switch_page(&ctx, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x21, 0x3c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x22, 0xfa);
+
+ ili9882t_switch_page(&ctx, 0x0a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe0, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe2, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe5, 0x91);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe6, 0x3c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe7, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe8, 0xfa);
+
+ ili9882t_switch_page(&ctx, 0x12);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x87, 0x2c);
+
+ ili9882t_switch_page(&ctx, 0x05);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x73, 0xe5);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x7f, 0x6b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x6d, 0xa4);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x79, 0x54);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x69, 0x97);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x6a, 0x97);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xa5, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x61, 0xda);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xa7, 0xf1);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x5f, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x62, 0x3f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1d, 0x90);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x86, 0x87);
+
+ ili9882t_switch_page(&ctx, 0x06);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x80);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc1, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xca, 0x58);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xce, 0x58);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcf, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x67, 0x60);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x10, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x92, 0x22);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd3, 0x08);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xd6, 0x55);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xdc, 0x38);
+
+ ili9882t_switch_page(&ctx, 0x08);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe0, 0x00, 0x10, 0x2a, 0x4d, 0x61, 0x56, 0x6a, 0x6e,
+ 0x79, 0x76, 0x8f, 0x95, 0x98, 0xae, 0xaa, 0xb2, 0xbb, 0xce,
+ 0xc6, 0xbd, 0xd5, 0xe2, 0xe8);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe1, 0x00, 0x10, 0x2a, 0x4d, 0x61, 0x56, 0x6a, 0x6e,
+ 0x79, 0x76, 0x8f, 0x95, 0x98, 0xae, 0xaa, 0xb2, 0xbb, 0xce,
+ 0xc6, 0xbd, 0xd5, 0xe2, 0xe8);
+
+ ili9882t_switch_page(&ctx, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x81);
+
+ ili9882t_switch_page(&ctx, 0x0c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x01, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x02, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x03, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x04, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x05, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x06, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x08, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x09, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0a, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0b, 0x05);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0c, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0d, 0x06);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0e, 0x05);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x0f, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x10, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x11, 0x08);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x12, 0x05);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x13, 0x09);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x14, 0x05);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x15, 0x0a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x16, 0x06);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x17, 0x0b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x18, 0x05);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x19, 0x0c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1a, 0x06);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1b, 0x0d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1c, 0x06);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1d, 0x0e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1e, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x1f, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x06);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x21, 0x10);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x22, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x23, 0x11);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x24, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x12);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x26, 0x08);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x27, 0x13);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x28, 0x07);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x29, 0x14);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x08);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2b, 0x15);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2c, 0x08);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2d, 0x16);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2e, 0x09);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2f, 0x17);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x30, 0x08);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x31, 0x18);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x32, 0x09);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x33, 0x19);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x34, 0x09);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x35, 0x1a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x36, 0x0a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x37, 0x1b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x38, 0x0a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x39, 0x1c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3a, 0x0a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3b, 0x1d);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3c, 0x0a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3d, 0x1e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3e, 0x0a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x3f, 0x1f);
+
+ ili9882t_switch_page(&ctx, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xba, 0x01);
+
+ ili9882t_switch_page(&ctx, 0x0e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x02, 0x0c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x20, 0x10);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x25, 0x16);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x26, 0xe0);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x27, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x29, 0x71);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2a, 0x46);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2b, 0x1f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x2d, 0xc7);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x31, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x32, 0xdf);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x33, 0x5a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x34, 0xc0);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x35, 0x5a);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x36, 0xc0);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x38, 0x65);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x80, 0x3e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x81, 0xa0);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb1, 0xcc);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x12);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc2, 0xcc);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc3, 0xcc);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc4, 0xcc);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc5, 0xcc);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc6, 0xcc);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc7, 0xcc);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc8, 0xcc);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc9, 0xcc);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x30, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x00, 0x81);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x08, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x09, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x07, 0x21);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x04, 0x10);
+
+ ili9882t_switch_page(&ctx, 0x1e);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x60, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x64, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x6d, 0x00);
+
+ ili9882t_switch_page(&ctx, 0x0b);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xa6, 0x44);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xa7, 0xb6);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xa8, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xa9, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xaa, 0x51);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xab, 0x51);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xac, 0x04);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbd, 0x92);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xbe, 0xa1);
+
+ ili9882t_switch_page(&ctx, 0x05);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x86, 0x87);
+
+ ili9882t_switch_page(&ctx, 0x06);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x92, 0x22);
+
+ ili9882t_switch_page(&ctx, 0x00);
+ mipi_dsi_dcs_exit_sleep_mode_multi(&ctx);
+
+ mipi_dsi_msleep(&ctx, 120);
+
+ mipi_dsi_dcs_set_display_on_multi(&ctx);
+
+ mipi_dsi_msleep(&ctx, 20);
+
+ return ctx.accum_err;
};
static inline struct ili9882t *to_ili9882t(struct drm_panel *panel)
@@ -424,97 +418,21 @@ static inline struct ili9882t *to_ili9882t(struct drm_panel *panel)
return container_of(panel, struct ili9882t, base);
}
-static int ili9882t_init_dcs_cmd(struct ili9882t *ili)
-{
- struct mipi_dsi_device *dsi = ili->dsi;
- struct drm_panel *panel = &ili->base;
- int i, err = 0;
-
- if (ili->desc->init_cmds) {
- const struct panel_init_cmd *init_cmds = ili->desc->init_cmds;
-
- for (i = 0; init_cmds[i].len != 0; i++) {
- const struct panel_init_cmd *cmd = &init_cmds[i];
-
- switch (cmd->type) {
- case DELAY_CMD:
- msleep(cmd->data[0]);
- err = 0;
- break;
-
- case INIT_DCS_CMD:
- err = mipi_dsi_dcs_write(dsi, cmd->data[0],
- cmd->len <= 1 ? NULL :
- &cmd->data[1],
- cmd->len - 1);
- break;
-
- default:
- err = -EINVAL;
- }
-
- if (err < 0) {
- dev_err(panel->dev,
- "failed to write command %u\n", i);
- return err;
- }
- }
- }
- return 0;
-}
-
-static int ili9882t_switch_page(struct mipi_dsi_device *dsi, u8 page)
-{
- int ret;
- const struct panel_init_cmd cmd = _INIT_SWITCH_PAGE_CMD(page);
-
- ret = mipi_dsi_dcs_write(dsi, cmd.data[0],
- cmd.len <= 1 ? NULL :
- &cmd.data[1],
- cmd.len - 1);
- if (ret) {
- dev_err(&dsi->dev,
- "error switching panel controller page (%d)\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-static int ili9882t_enter_sleep_mode(struct ili9882t *ili)
-{
- struct mipi_dsi_device *dsi = ili->dsi;
- int ret;
-
- dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
-
- ret = mipi_dsi_dcs_set_display_off(dsi);
- if (ret < 0)
- return ret;
-
- ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
static int ili9882t_disable(struct drm_panel *panel)
{
struct ili9882t *ili = to_ili9882t(panel);
- struct mipi_dsi_device *dsi = ili->dsi;
- int ret;
+ struct mipi_dsi_multi_context ctx = { .dsi = ili->dsi };
- ili9882t_switch_page(dsi, 0x00);
- ret = ili9882t_enter_sleep_mode(ili);
- if (ret < 0) {
- dev_err(panel->dev, "failed to set panel off: %d\n", ret);
- return ret;
- }
+ ili9882t_switch_page(&ctx, 0x00);
- msleep(150);
+ ili->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
- return 0;
+ mipi_dsi_dcs_set_display_off_multi(&ctx);
+ mipi_dsi_dcs_enter_sleep_mode_multi(&ctx);
+
+ mipi_dsi_msleep(&ctx, 150);
+
+ return ctx.accum_err;
}
static int ili9882t_unprepare(struct drm_panel *panel)
@@ -560,7 +478,11 @@ static int ili9882t_prepare(struct drm_panel *panel)
usleep_range(10000, 11000);
// MIPI needs to keep the LP11 state before the lcm_reset pin is pulled high
- mipi_dsi_dcs_nop(ili->dsi);
+ ret = mipi_dsi_dcs_nop(ili->dsi);
+ if (ret < 0) {
+ dev_err(&ili->dsi->dev, "Failed to send NOP: %d\n", ret);
+ goto poweroff;
+ }
usleep_range(1000, 2000);
gpiod_set_value(ili->enable_gpio, 1);
@@ -570,22 +492,20 @@ static int ili9882t_prepare(struct drm_panel *panel)
gpiod_set_value(ili->enable_gpio, 1);
usleep_range(6000, 10000);
- ret = ili9882t_init_dcs_cmd(ili);
- if (ret < 0) {
- dev_err(panel->dev, "failed to init panel: %d\n", ret);
+ ret = ili->desc->init(ili);
+ if (ret < 0)
goto poweroff;
- }
return 0;
poweroff:
+ gpiod_set_value(ili->enable_gpio, 0);
regulator_disable(ili->avee);
poweroffavdd:
regulator_disable(ili->avdd);
poweroff1v8:
usleep_range(5000, 7000);
regulator_disable(ili->pp1800);
- gpiod_set_value(ili->enable_gpio, 0);
return ret;
}
@@ -620,7 +540,7 @@ static const struct panel_desc starry_ili9882t_desc = {
.format = MIPI_DSI_FMT_RGB888,
.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
MIPI_DSI_MODE_LPM,
- .init_cmds = starry_ili9882t_init_cmd,
+ .init = starry_ili9882t_init,
};
static int ili9882t_get_modes(struct drm_panel *panel,
diff --git a/drivers/gpu/drm/panel/panel-innolux-ej030na.c b/drivers/gpu/drm/panel/panel-innolux-ej030na.c
index 8fdbda59be48..f85b7a4cbb42 100644
--- a/drivers/gpu/drm/panel/panel-innolux-ej030na.c
+++ b/drivers/gpu/drm/panel/panel-innolux-ej030na.c
@@ -306,4 +306,5 @@ module_spi_driver(ej030na_driver);
MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
MODULE_AUTHOR("Christophe Branchereau <cbranchereau@gmail.com>");
+MODULE_DESCRIPTION("Innolux/Chimei EJ030NA TFT LCD panel driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/panel/panel-innolux-p079zca.c b/drivers/gpu/drm/panel/panel-innolux-p079zca.c
index 485178a99910..d95c0d4f3e35 100644
--- a/drivers/gpu/drm/panel/panel-innolux-p079zca.c
+++ b/drivers/gpu/drm/panel/panel-innolux-p079zca.c
@@ -17,14 +17,7 @@
#include <drm/drm_modes.h>
#include <drm/drm_panel.h>
-struct panel_init_cmd {
- size_t len;
- const char *data;
-};
-
-#define _INIT_CMD(...) { \
- .len = sizeof((char[]){__VA_ARGS__}), \
- .data = (char[]){__VA_ARGS__} }
+struct innolux_panel;
struct panel_desc {
const struct drm_display_mode *mode;
@@ -36,7 +29,7 @@ struct panel_desc {
unsigned long flags;
enum mipi_dsi_pixel_format format;
- const struct panel_init_cmd *init_cmds;
+ int (*init)(struct innolux_panel *innolux);
unsigned int lanes;
const char * const *supply_names;
unsigned int num_supplies;
@@ -51,9 +44,6 @@ struct innolux_panel {
struct regulator_bulk_data *supplies;
struct gpio_desc *enable_gpio;
-
- bool prepared;
- bool enabled;
};
static inline struct innolux_panel *to_innolux_panel(struct drm_panel *panel)
@@ -61,26 +51,11 @@ static inline struct innolux_panel *to_innolux_panel(struct drm_panel *panel)
return container_of(panel, struct innolux_panel, base);
}
-static int innolux_panel_disable(struct drm_panel *panel)
-{
- struct innolux_panel *innolux = to_innolux_panel(panel);
-
- if (!innolux->enabled)
- return 0;
-
- innolux->enabled = false;
-
- return 0;
-}
-
static int innolux_panel_unprepare(struct drm_panel *panel)
{
struct innolux_panel *innolux = to_innolux_panel(panel);
int err;
- if (!innolux->prepared)
- return 0;
-
err = mipi_dsi_dcs_set_display_off(innolux->link);
if (err < 0)
dev_err(panel->dev, "failed to set display off: %d\n", err);
@@ -104,8 +79,6 @@ static int innolux_panel_unprepare(struct drm_panel *panel)
if (err < 0)
return err;
- innolux->prepared = false;
-
return 0;
}
@@ -114,9 +87,6 @@ static int innolux_panel_prepare(struct drm_panel *panel)
struct innolux_panel *innolux = to_innolux_panel(panel);
int err;
- if (innolux->prepared)
- return 0;
-
gpiod_set_value_cansleep(innolux->enable_gpio, 0);
err = regulator_bulk_enable(innolux->desc->num_supplies,
@@ -132,32 +102,10 @@ static int innolux_panel_prepare(struct drm_panel *panel)
/* p079zca: t4, p097pfg: t5 */
usleep_range(20000, 21000);
- if (innolux->desc->init_cmds) {
- const struct panel_init_cmd *cmds =
- innolux->desc->init_cmds;
- unsigned int i;
-
- for (i = 0; cmds[i].len != 0; i++) {
- const struct panel_init_cmd *cmd = &cmds[i];
-
- err = mipi_dsi_generic_write(innolux->link, cmd->data,
- cmd->len);
- if (err < 0) {
- dev_err(panel->dev, "failed to write command %u\n", i);
- goto poweroff;
- }
-
- /*
- * Included by random guessing, because without this
- * (or at least, some delay), the panel sometimes
- * didn't appear to pick up the command sequence.
- */
- err = mipi_dsi_dcs_nop(innolux->link);
- if (err < 0) {
- dev_err(panel->dev, "failed to send DCS nop: %d\n", err);
- goto poweroff;
- }
- }
+ if (innolux->desc->init) {
+ err = innolux->desc->init(innolux);
+ if (err < 0)
+ goto poweroff;
}
err = mipi_dsi_dcs_exit_sleep_mode(innolux->link);
@@ -178,8 +126,6 @@ static int innolux_panel_prepare(struct drm_panel *panel)
/* T7: 5ms */
usleep_range(5000, 6000);
- innolux->prepared = true;
-
return 0;
poweroff:
@@ -189,18 +135,6 @@ poweroff:
return err;
}
-static int innolux_panel_enable(struct drm_panel *panel)
-{
- struct innolux_panel *innolux = to_innolux_panel(panel);
-
- if (innolux->enabled)
- return 0;
-
- innolux->enabled = true;
-
- return 0;
-}
-
static const char * const innolux_p079zca_supply_names[] = {
"power",
};
@@ -250,119 +184,137 @@ static const struct drm_display_mode innolux_p097pfg_mode = {
.vtotal = 2048 + 100 + 2 + 18,
};
+static void innolux_panel_write_multi(struct mipi_dsi_multi_context *ctx,
+ const void *payload, size_t size)
+{
+ mipi_dsi_generic_write_multi(ctx, payload, size);
+
+ /*
+ * Included by random guessing, because without this
+ * (or at least, some delay), the panel sometimes
+ * didn't appear to pick up the command sequence.
+ */
+ mipi_dsi_dcs_nop_multi(ctx);
+}
+
+#define innolux_panel_init_cmd_multi(ctx, seq...) \
+ do { \
+ static const u8 d[] = { seq }; \
+ innolux_panel_write_multi(ctx, d, ARRAY_SIZE(d)); \
+ } while (0)
+
+#define innolux_panel_switch_page(ctx, page) \
+ innolux_panel_init_cmd_multi(ctx, 0xf0, 0x55, 0xaa, 0x52, 0x08, (page))
+
/*
* Display manufacturer failed to provide init sequencing according to
* https://chromium-review.googlesource.com/c/chromiumos/third_party/coreboot/+/892065/
* so the init sequence stems from a register dump of a working panel.
*/
-static const struct panel_init_cmd innolux_p097pfg_init_cmds[] = {
- /* page 0 */
- _INIT_CMD(0xF0, 0x55, 0xAA, 0x52, 0x08, 0x00),
- _INIT_CMD(0xB1, 0xE8, 0x11),
- _INIT_CMD(0xB2, 0x25, 0x02),
- _INIT_CMD(0xB5, 0x08, 0x00),
- _INIT_CMD(0xBC, 0x0F, 0x00),
- _INIT_CMD(0xB8, 0x03, 0x06, 0x00, 0x00),
- _INIT_CMD(0xBD, 0x01, 0x90, 0x14, 0x14),
- _INIT_CMD(0x6F, 0x01),
- _INIT_CMD(0xC0, 0x03),
- _INIT_CMD(0x6F, 0x02),
- _INIT_CMD(0xC1, 0x0D),
- _INIT_CMD(0xD9, 0x01, 0x09, 0x70),
- _INIT_CMD(0xC5, 0x12, 0x21, 0x00),
- _INIT_CMD(0xBB, 0x93, 0x93),
-
- /* page 1 */
- _INIT_CMD(0xF0, 0x55, 0xAA, 0x52, 0x08, 0x01),
- _INIT_CMD(0xB3, 0x3C, 0x3C),
- _INIT_CMD(0xB4, 0x0F, 0x0F),
- _INIT_CMD(0xB9, 0x45, 0x45),
- _INIT_CMD(0xBA, 0x14, 0x14),
- _INIT_CMD(0xCA, 0x02),
- _INIT_CMD(0xCE, 0x04),
- _INIT_CMD(0xC3, 0x9B, 0x9B),
- _INIT_CMD(0xD8, 0xC0, 0x03),
- _INIT_CMD(0xBC, 0x82, 0x01),
- _INIT_CMD(0xBD, 0x9E, 0x01),
-
- /* page 2 */
- _INIT_CMD(0xF0, 0x55, 0xAA, 0x52, 0x08, 0x02),
- _INIT_CMD(0xB0, 0x82),
- _INIT_CMD(0xD1, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x82, 0x00, 0xA5,
- 0x00, 0xC1, 0x00, 0xEA, 0x01, 0x0D, 0x01, 0x40),
- _INIT_CMD(0xD2, 0x01, 0x6A, 0x01, 0xA8, 0x01, 0xDC, 0x02, 0x29,
- 0x02, 0x67, 0x02, 0x68, 0x02, 0xA8, 0x02, 0xF0),
- _INIT_CMD(0xD3, 0x03, 0x19, 0x03, 0x49, 0x03, 0x67, 0x03, 0x8C,
- 0x03, 0xA6, 0x03, 0xC7, 0x03, 0xDE, 0x03, 0xEC),
- _INIT_CMD(0xD4, 0x03, 0xFF, 0x03, 0xFF),
- _INIT_CMD(0xE0, 0x00, 0x00, 0x00, 0x86, 0x00, 0xC5, 0x00, 0xE5,
- 0x00, 0xFF, 0x01, 0x26, 0x01, 0x45, 0x01, 0x75),
- _INIT_CMD(0xE1, 0x01, 0x9C, 0x01, 0xD5, 0x02, 0x05, 0x02, 0x4D,
- 0x02, 0x86, 0x02, 0x87, 0x02, 0xC3, 0x03, 0x03),
- _INIT_CMD(0xE2, 0x03, 0x2A, 0x03, 0x56, 0x03, 0x72, 0x03, 0x94,
- 0x03, 0xAC, 0x03, 0xCB, 0x03, 0xE0, 0x03, 0xED),
- _INIT_CMD(0xE3, 0x03, 0xFF, 0x03, 0xFF),
-
- /* page 3 */
- _INIT_CMD(0xF0, 0x55, 0xAA, 0x52, 0x08, 0x03),
- _INIT_CMD(0xB0, 0x00, 0x00, 0x00, 0x00),
- _INIT_CMD(0xB1, 0x00, 0x00, 0x00, 0x00),
- _INIT_CMD(0xB2, 0x00, 0x00, 0x06, 0x04, 0x01, 0x40, 0x85),
- _INIT_CMD(0xB3, 0x10, 0x07, 0xFC, 0x04, 0x01, 0x40, 0x80),
- _INIT_CMD(0xB6, 0xF0, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
- 0x40, 0x80),
- _INIT_CMD(0xBA, 0xC5, 0x07, 0x00, 0x04, 0x11, 0x25, 0x8C),
- _INIT_CMD(0xBB, 0xC5, 0x07, 0x00, 0x03, 0x11, 0x25, 0x8C),
- _INIT_CMD(0xC0, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x80, 0x80),
- _INIT_CMD(0xC1, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x80, 0x80),
- _INIT_CMD(0xC4, 0x00, 0x00),
- _INIT_CMD(0xEF, 0x41),
-
- /* page 4 */
- _INIT_CMD(0xF0, 0x55, 0xAA, 0x52, 0x08, 0x04),
- _INIT_CMD(0xEC, 0x4C),
-
- /* page 5 */
- _INIT_CMD(0xF0, 0x55, 0xAA, 0x52, 0x08, 0x05),
- _INIT_CMD(0xB0, 0x13, 0x03, 0x03, 0x01),
- _INIT_CMD(0xB1, 0x30, 0x00),
- _INIT_CMD(0xB2, 0x02, 0x02, 0x00),
- _INIT_CMD(0xB3, 0x82, 0x23, 0x82, 0x9D),
- _INIT_CMD(0xB4, 0xC5, 0x75, 0x24, 0x57),
- _INIT_CMD(0xB5, 0x00, 0xD4, 0x72, 0x11, 0x11, 0xAB, 0x0A),
- _INIT_CMD(0xB6, 0x00, 0x00, 0xD5, 0x72, 0x24, 0x56),
- _INIT_CMD(0xB7, 0x5C, 0xDC, 0x5C, 0x5C),
- _INIT_CMD(0xB9, 0x0C, 0x00, 0x00, 0x01, 0x00),
- _INIT_CMD(0xC0, 0x75, 0x11, 0x11, 0x54, 0x05),
- _INIT_CMD(0xC6, 0x00, 0x00, 0x00, 0x00),
- _INIT_CMD(0xD0, 0x00, 0x48, 0x08, 0x00, 0x00),
- _INIT_CMD(0xD1, 0x00, 0x48, 0x09, 0x00, 0x00),
-
- /* page 6 */
- _INIT_CMD(0xF0, 0x55, 0xAA, 0x52, 0x08, 0x06),
- _INIT_CMD(0xB0, 0x02, 0x32, 0x32, 0x08, 0x2F),
- _INIT_CMD(0xB1, 0x2E, 0x15, 0x14, 0x13, 0x12),
- _INIT_CMD(0xB2, 0x11, 0x10, 0x00, 0x3D, 0x3D),
- _INIT_CMD(0xB3, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D),
- _INIT_CMD(0xB4, 0x3D, 0x32),
- _INIT_CMD(0xB5, 0x03, 0x32, 0x32, 0x09, 0x2F),
- _INIT_CMD(0xB6, 0x2E, 0x1B, 0x1A, 0x19, 0x18),
- _INIT_CMD(0xB7, 0x17, 0x16, 0x01, 0x3D, 0x3D),
- _INIT_CMD(0xB8, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D),
- _INIT_CMD(0xB9, 0x3D, 0x32),
- _INIT_CMD(0xC0, 0x01, 0x32, 0x32, 0x09, 0x2F),
- _INIT_CMD(0xC1, 0x2E, 0x1A, 0x1B, 0x16, 0x17),
- _INIT_CMD(0xC2, 0x18, 0x19, 0x03, 0x3D, 0x3D),
- _INIT_CMD(0xC3, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D),
- _INIT_CMD(0xC4, 0x3D, 0x32),
- _INIT_CMD(0xC5, 0x00, 0x32, 0x32, 0x08, 0x2F),
- _INIT_CMD(0xC6, 0x2E, 0x14, 0x15, 0x10, 0x11),
- _INIT_CMD(0xC7, 0x12, 0x13, 0x02, 0x3D, 0x3D),
- _INIT_CMD(0xC8, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D),
- _INIT_CMD(0xC9, 0x3D, 0x32),
-
- {},
-};
+static int innolux_p097pfg_init(struct innolux_panel *innolux)
+{
+ struct mipi_dsi_multi_context ctx = { .dsi = innolux->link };
+
+ innolux_panel_switch_page(&ctx, 0x00);
+ innolux_panel_init_cmd_multi(&ctx, 0xb1, 0xe8, 0x11);
+ innolux_panel_init_cmd_multi(&ctx, 0xb2, 0x25, 0x02);
+ innolux_panel_init_cmd_multi(&ctx, 0xb5, 0x08, 0x00);
+ innolux_panel_init_cmd_multi(&ctx, 0xbc, 0x0f, 0x00);
+ innolux_panel_init_cmd_multi(&ctx, 0xb8, 0x03, 0x06, 0x00, 0x00);
+ innolux_panel_init_cmd_multi(&ctx, 0xbd, 0x01, 0x90, 0x14, 0x14);
+ innolux_panel_init_cmd_multi(&ctx, 0x6f, 0x01);
+ innolux_panel_init_cmd_multi(&ctx, 0xc0, 0x03);
+ innolux_panel_init_cmd_multi(&ctx, 0x6f, 0x02);
+ innolux_panel_init_cmd_multi(&ctx, 0xc1, 0x0d);
+ innolux_panel_init_cmd_multi(&ctx, 0xd9, 0x01, 0x09, 0x70);
+ innolux_panel_init_cmd_multi(&ctx, 0xc5, 0x12, 0x21, 0x00);
+ innolux_panel_init_cmd_multi(&ctx, 0xbb, 0x93, 0x93);
+
+ innolux_panel_switch_page(&ctx, 0x01);
+ innolux_panel_init_cmd_multi(&ctx, 0xb3, 0x3c, 0x3c);
+ innolux_panel_init_cmd_multi(&ctx, 0xb4, 0x0f, 0x0f);
+ innolux_panel_init_cmd_multi(&ctx, 0xb9, 0x45, 0x45);
+ innolux_panel_init_cmd_multi(&ctx, 0xba, 0x14, 0x14);
+ innolux_panel_init_cmd_multi(&ctx, 0xca, 0x02);
+ innolux_panel_init_cmd_multi(&ctx, 0xce, 0x04);
+ innolux_panel_init_cmd_multi(&ctx, 0xc3, 0x9b, 0x9b);
+ innolux_panel_init_cmd_multi(&ctx, 0xd8, 0xc0, 0x03);
+ innolux_panel_init_cmd_multi(&ctx, 0xbc, 0x82, 0x01);
+ innolux_panel_init_cmd_multi(&ctx, 0xbd, 0x9e, 0x01);
+
+ innolux_panel_switch_page(&ctx, 0x02);
+ innolux_panel_init_cmd_multi(&ctx, 0xb0, 0x82);
+ innolux_panel_init_cmd_multi(&ctx, 0xd1, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x82, 0x00, 0xa5,
+ 0x00, 0xc1, 0x00, 0xea, 0x01, 0x0d, 0x01, 0x40);
+ innolux_panel_init_cmd_multi(&ctx, 0xd2, 0x01, 0x6a, 0x01, 0xa8, 0x01, 0xdc, 0x02, 0x29,
+ 0x02, 0x67, 0x02, 0x68, 0x02, 0xa8, 0x02, 0xf0);
+ innolux_panel_init_cmd_multi(&ctx, 0xd3, 0x03, 0x19, 0x03, 0x49, 0x03, 0x67, 0x03, 0x8c,
+ 0x03, 0xa6, 0x03, 0xc7, 0x03, 0xde, 0x03, 0xec);
+ innolux_panel_init_cmd_multi(&ctx, 0xd4, 0x03, 0xff, 0x03, 0xff);
+ innolux_panel_init_cmd_multi(&ctx, 0xe0, 0x00, 0x00, 0x00, 0x86, 0x00, 0xc5, 0x00, 0xe5,
+ 0x00, 0xff, 0x01, 0x26, 0x01, 0x45, 0x01, 0x75);
+ innolux_panel_init_cmd_multi(&ctx, 0xe1, 0x01, 0x9c, 0x01, 0xd5, 0x02, 0x05, 0x02, 0x4d,
+ 0x02, 0x86, 0x02, 0x87, 0x02, 0xc3, 0x03, 0x03);
+ innolux_panel_init_cmd_multi(&ctx, 0xe2, 0x03, 0x2a, 0x03, 0x56, 0x03, 0x72, 0x03, 0x94,
+ 0x03, 0xac, 0x03, 0xcb, 0x03, 0xe0, 0x03, 0xed);
+ innolux_panel_init_cmd_multi(&ctx, 0xe3, 0x03, 0xff, 0x03, 0xff);
+
+ innolux_panel_switch_page(&ctx, 0x03);
+ innolux_panel_init_cmd_multi(&ctx, 0xb0, 0x00, 0x00, 0x00, 0x00);
+ innolux_panel_init_cmd_multi(&ctx, 0xb1, 0x00, 0x00, 0x00, 0x00);
+ innolux_panel_init_cmd_multi(&ctx, 0xb2, 0x00, 0x00, 0x06, 0x04, 0x01, 0x40, 0x85);
+ innolux_panel_init_cmd_multi(&ctx, 0xb3, 0x10, 0x07, 0xfc, 0x04, 0x01, 0x40, 0x80);
+ innolux_panel_init_cmd_multi(&ctx, 0xb6, 0xf0, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01,
+ 0x40, 0x80);
+ innolux_panel_init_cmd_multi(&ctx, 0xba, 0xc5, 0x07, 0x00, 0x04, 0x11, 0x25, 0x8c);
+ innolux_panel_init_cmd_multi(&ctx, 0xbb, 0xc5, 0x07, 0x00, 0x03, 0x11, 0x25, 0x8c);
+ innolux_panel_init_cmd_multi(&ctx, 0xc0, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x80, 0x80);
+ innolux_panel_init_cmd_multi(&ctx, 0xc1, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x80, 0x80);
+ innolux_panel_init_cmd_multi(&ctx, 0xc4, 0x00, 0x00);
+ innolux_panel_init_cmd_multi(&ctx, 0xef, 0x41);
+
+ innolux_panel_switch_page(&ctx, 0x04);
+ innolux_panel_init_cmd_multi(&ctx, 0xec, 0x4c);
+
+ innolux_panel_switch_page(&ctx, 0x05);
+ innolux_panel_init_cmd_multi(&ctx, 0xb0, 0x13, 0x03, 0x03, 0x01);
+ innolux_panel_init_cmd_multi(&ctx, 0xb1, 0x30, 0x00);
+ innolux_panel_init_cmd_multi(&ctx, 0xb2, 0x02, 0x02, 0x00);
+ innolux_panel_init_cmd_multi(&ctx, 0xb3, 0x82, 0x23, 0x82, 0x9d);
+ innolux_panel_init_cmd_multi(&ctx, 0xb4, 0xc5, 0x75, 0x24, 0x57);
+ innolux_panel_init_cmd_multi(&ctx, 0xb5, 0x00, 0xd4, 0x72, 0x11, 0x11, 0xab, 0x0a);
+ innolux_panel_init_cmd_multi(&ctx, 0xb6, 0x00, 0x00, 0xd5, 0x72, 0x24, 0x56);
+ innolux_panel_init_cmd_multi(&ctx, 0xb7, 0x5c, 0xdc, 0x5c, 0x5c);
+ innolux_panel_init_cmd_multi(&ctx, 0xb9, 0x0c, 0x00, 0x00, 0x01, 0x00);
+ innolux_panel_init_cmd_multi(&ctx, 0xc0, 0x75, 0x11, 0x11, 0x54, 0x05);
+ innolux_panel_init_cmd_multi(&ctx, 0xc6, 0x00, 0x00, 0x00, 0x00);
+ innolux_panel_init_cmd_multi(&ctx, 0xd0, 0x00, 0x48, 0x08, 0x00, 0x00);
+ innolux_panel_init_cmd_multi(&ctx, 0xd1, 0x00, 0x48, 0x09, 0x00, 0x00);
+
+ innolux_panel_switch_page(&ctx, 0x06);
+ innolux_panel_init_cmd_multi(&ctx, 0xb0, 0x02, 0x32, 0x32, 0x08, 0x2f);
+ innolux_panel_init_cmd_multi(&ctx, 0xb1, 0x2e, 0x15, 0x14, 0x13, 0x12);
+ innolux_panel_init_cmd_multi(&ctx, 0xb2, 0x11, 0x10, 0x00, 0x3d, 0x3d);
+ innolux_panel_init_cmd_multi(&ctx, 0xb3, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d);
+ innolux_panel_init_cmd_multi(&ctx, 0xb4, 0x3d, 0x32);
+ innolux_panel_init_cmd_multi(&ctx, 0xb5, 0x03, 0x32, 0x32, 0x09, 0x2f);
+ innolux_panel_init_cmd_multi(&ctx, 0xb6, 0x2e, 0x1b, 0x1a, 0x19, 0x18);
+ innolux_panel_init_cmd_multi(&ctx, 0xb7, 0x17, 0x16, 0x01, 0x3d, 0x3d);
+ innolux_panel_init_cmd_multi(&ctx, 0xb8, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d);
+ innolux_panel_init_cmd_multi(&ctx, 0xb9, 0x3d, 0x32);
+ innolux_panel_init_cmd_multi(&ctx, 0xc0, 0x01, 0x32, 0x32, 0x09, 0x2f);
+ innolux_panel_init_cmd_multi(&ctx, 0xc1, 0x2e, 0x1a, 0x1b, 0x16, 0x17);
+ innolux_panel_init_cmd_multi(&ctx, 0xc2, 0x18, 0x19, 0x03, 0x3d, 0x3d);
+ innolux_panel_init_cmd_multi(&ctx, 0xc3, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d);
+ innolux_panel_init_cmd_multi(&ctx, 0xc4, 0x3d, 0x32);
+ innolux_panel_init_cmd_multi(&ctx, 0xc5, 0x00, 0x32, 0x32, 0x08, 0x2f);
+ innolux_panel_init_cmd_multi(&ctx, 0xc6, 0x2e, 0x14, 0x15, 0x10, 0x11);
+ innolux_panel_init_cmd_multi(&ctx, 0xc7, 0x12, 0x13, 0x02, 0x3d, 0x3d);
+ innolux_panel_init_cmd_multi(&ctx, 0xc8, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d);
+ innolux_panel_init_cmd_multi(&ctx, 0xc9, 0x3d, 0x32);
+
+ return ctx.accum_err;
+}
static const struct panel_desc innolux_p097pfg_panel_desc = {
.mode = &innolux_p097pfg_mode,
@@ -374,7 +326,7 @@ static const struct panel_desc innolux_p097pfg_panel_desc = {
.flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
MIPI_DSI_MODE_LPM,
.format = MIPI_DSI_FMT_RGB888,
- .init_cmds = innolux_p097pfg_init_cmds,
+ .init = innolux_p097pfg_init,
.lanes = 4,
.supply_names = innolux_p097pfg_supply_names,
.num_supplies = ARRAY_SIZE(innolux_p097pfg_supply_names),
@@ -407,10 +359,8 @@ static int innolux_panel_get_modes(struct drm_panel *panel,
}
static const struct drm_panel_funcs innolux_panel_funcs = {
- .disable = innolux_panel_disable,
.unprepare = innolux_panel_unprepare,
.prepare = innolux_panel_prepare,
- .enable = innolux_panel_enable,
.get_modes = innolux_panel_get_modes,
};
@@ -510,13 +460,6 @@ static void innolux_panel_remove(struct mipi_dsi_device *dsi)
struct innolux_panel *innolux = mipi_dsi_get_drvdata(dsi);
int err;
- err = drm_panel_unprepare(&innolux->base);
- if (err < 0)
- dev_err(&dsi->dev, "failed to unprepare panel: %d\n", err);
-
- err = drm_panel_disable(&innolux->base);
- if (err < 0)
- dev_err(&dsi->dev, "failed to disable panel: %d\n", err);
err = mipi_dsi_detach(dsi);
if (err < 0)
@@ -525,14 +468,6 @@ static void innolux_panel_remove(struct mipi_dsi_device *dsi)
innolux_panel_del(innolux);
}
-static void innolux_panel_shutdown(struct mipi_dsi_device *dsi)
-{
- struct innolux_panel *innolux = mipi_dsi_get_drvdata(dsi);
-
- drm_panel_unprepare(&innolux->base);
- drm_panel_disable(&innolux->base);
-}
-
static struct mipi_dsi_driver innolux_panel_driver = {
.driver = {
.name = "panel-innolux-p079zca",
@@ -540,7 +475,6 @@ static struct mipi_dsi_driver innolux_panel_driver = {
},
.probe = innolux_panel_probe,
.remove = innolux_panel_remove,
- .shutdown = innolux_panel_shutdown,
};
module_mipi_dsi_driver(innolux_panel_driver);
diff --git a/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c b/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c
index f9a69f347068..b1ce186de261 100644
--- a/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c
+++ b/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c
@@ -37,9 +37,6 @@ struct jdi_panel {
struct gpio_desc *dcdc_en_gpio;
struct backlight_device *backlight;
- bool prepared;
- bool enabled;
-
const struct drm_display_mode *mode;
};
@@ -176,13 +173,8 @@ static int jdi_panel_disable(struct drm_panel *panel)
{
struct jdi_panel *jdi = to_jdi_panel(panel);
- if (!jdi->enabled)
- return 0;
-
backlight_disable(jdi->backlight);
- jdi->enabled = false;
-
return 0;
}
@@ -192,9 +184,6 @@ static int jdi_panel_unprepare(struct drm_panel *panel)
struct device *dev = &jdi->dsi->dev;
int ret;
- if (!jdi->prepared)
- return 0;
-
jdi_panel_off(jdi);
ret = regulator_bulk_disable(ARRAY_SIZE(jdi->supplies), jdi->supplies);
@@ -207,8 +196,6 @@ static int jdi_panel_unprepare(struct drm_panel *panel)
gpiod_set_value(jdi->dcdc_en_gpio, 0);
- jdi->prepared = false;
-
return 0;
}
@@ -218,9 +205,6 @@ static int jdi_panel_prepare(struct drm_panel *panel)
struct device *dev = &jdi->dsi->dev;
int ret;
- if (jdi->prepared)
- return 0;
-
ret = regulator_bulk_enable(ARRAY_SIZE(jdi->supplies), jdi->supplies);
if (ret < 0) {
dev_err(dev, "regulator enable failed, %d\n", ret);
@@ -250,8 +234,6 @@ static int jdi_panel_prepare(struct drm_panel *panel)
goto poweroff;
}
- jdi->prepared = true;
-
return 0;
poweroff:
@@ -272,13 +254,8 @@ static int jdi_panel_enable(struct drm_panel *panel)
{
struct jdi_panel *jdi = to_jdi_panel(panel);
- if (jdi->enabled)
- return 0;
-
backlight_enable(jdi->backlight);
- jdi->enabled = true;
-
return 0;
}
@@ -475,10 +452,6 @@ static void jdi_panel_remove(struct mipi_dsi_device *dsi)
struct jdi_panel *jdi = mipi_dsi_get_drvdata(dsi);
int ret;
- ret = jdi_panel_disable(&jdi->base);
- if (ret < 0)
- dev_err(&dsi->dev, "failed to disable panel: %d\n", ret);
-
ret = mipi_dsi_detach(dsi);
if (ret < 0)
dev_err(&dsi->dev, "failed to detach from DSI host: %d\n",
@@ -487,13 +460,6 @@ static void jdi_panel_remove(struct mipi_dsi_device *dsi)
jdi_panel_del(jdi);
}
-static void jdi_panel_shutdown(struct mipi_dsi_device *dsi)
-{
- struct jdi_panel *jdi = mipi_dsi_get_drvdata(dsi);
-
- jdi_panel_disable(&jdi->base);
-}
-
static struct mipi_dsi_driver jdi_panel_driver = {
.driver = {
.name = "panel-jdi-lt070me05000",
@@ -501,7 +467,6 @@ static struct mipi_dsi_driver jdi_panel_driver = {
},
.probe = jdi_panel_probe,
.remove = jdi_panel_remove,
- .shutdown = jdi_panel_shutdown,
};
module_mipi_dsi_driver(jdi_panel_driver);
diff --git a/drivers/gpu/drm/panel/panel-khadas-ts050.c b/drivers/gpu/drm/panel/panel-khadas-ts050.c
index c54be0cc3f08..14932cb3defc 100644
--- a/drivers/gpu/drm/panel/panel-khadas-ts050.c
+++ b/drivers/gpu/drm/panel/panel-khadas-ts050.c
@@ -26,9 +26,6 @@ struct khadas_ts050_panel {
struct gpio_desc *reset_gpio;
struct gpio_desc *enable_gpio;
struct khadas_ts050_panel_data *panel_data;
-
- bool prepared;
- bool enabled;
};
struct khadas_ts050_panel_cmd {
@@ -642,9 +639,6 @@ static int khadas_ts050_panel_prepare(struct drm_panel *panel)
unsigned int i;
int err;
- if (khadas_ts050->prepared)
- return 0;
-
gpiod_set_value_cansleep(khadas_ts050->enable_gpio, 0);
err = regulator_enable(khadas_ts050->supply);
@@ -708,8 +702,6 @@ static int khadas_ts050_panel_prepare(struct drm_panel *panel)
usleep_range(10000, 11000);
- khadas_ts050->prepared = true;
-
return 0;
poweroff:
@@ -726,11 +718,6 @@ static int khadas_ts050_panel_unprepare(struct drm_panel *panel)
struct khadas_ts050_panel *khadas_ts050 = to_khadas_ts050_panel(panel);
int err;
- if (!khadas_ts050->prepared)
- return 0;
-
- khadas_ts050->prepared = false;
-
err = mipi_dsi_dcs_enter_sleep_mode(khadas_ts050->link);
if (err < 0)
dev_err(panel->dev, "failed to enter sleep mode: %d\n", err);
@@ -747,31 +734,17 @@ static int khadas_ts050_panel_unprepare(struct drm_panel *panel)
return 0;
}
-static int khadas_ts050_panel_enable(struct drm_panel *panel)
-{
- struct khadas_ts050_panel *khadas_ts050 = to_khadas_ts050_panel(panel);
-
- khadas_ts050->enabled = true;
-
- return 0;
-}
-
static int khadas_ts050_panel_disable(struct drm_panel *panel)
{
struct khadas_ts050_panel *khadas_ts050 = to_khadas_ts050_panel(panel);
int err;
- if (!khadas_ts050->enabled)
- return 0;
-
err = mipi_dsi_dcs_set_display_off(khadas_ts050->link);
if (err < 0)
dev_err(panel->dev, "failed to set display off: %d\n", err);
usleep_range(10000, 11000);
- khadas_ts050->enabled = false;
-
return 0;
}
@@ -815,7 +788,6 @@ static int khadas_ts050_panel_get_modes(struct drm_panel *panel,
static const struct drm_panel_funcs khadas_ts050_panel_funcs = {
.prepare = khadas_ts050_panel_prepare,
.unprepare = khadas_ts050_panel_unprepare,
- .enable = khadas_ts050_panel_enable,
.disable = khadas_ts050_panel_disable,
.get_modes = khadas_ts050_panel_get_modes,
};
@@ -908,16 +880,6 @@ static void khadas_ts050_panel_remove(struct mipi_dsi_device *dsi)
dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", err);
drm_panel_remove(&khadas_ts050->base);
- drm_panel_disable(&khadas_ts050->base);
- drm_panel_unprepare(&khadas_ts050->base);
-}
-
-static void khadas_ts050_panel_shutdown(struct mipi_dsi_device *dsi)
-{
- struct khadas_ts050_panel *khadas_ts050 = mipi_dsi_get_drvdata(dsi);
-
- drm_panel_disable(&khadas_ts050->base);
- drm_panel_unprepare(&khadas_ts050->base);
}
static struct mipi_dsi_driver khadas_ts050_panel_driver = {
@@ -927,7 +889,6 @@ static struct mipi_dsi_driver khadas_ts050_panel_driver = {
},
.probe = khadas_ts050_panel_probe,
.remove = khadas_ts050_panel_remove,
- .shutdown = khadas_ts050_panel_shutdown,
};
module_mipi_dsi_driver(khadas_ts050_panel_driver);
diff --git a/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c b/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c
index 17f8d80cf2b3..d6b912277196 100644
--- a/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c
+++ b/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c
@@ -23,9 +23,6 @@ struct kingdisplay_panel {
struct regulator *supply;
struct gpio_desc *enable_gpio;
-
- bool prepared;
- bool enabled;
};
struct kingdisplay_panel_cmd {
@@ -185,15 +182,10 @@ static int kingdisplay_panel_disable(struct drm_panel *panel)
struct kingdisplay_panel *kingdisplay = to_kingdisplay_panel(panel);
int err;
- if (!kingdisplay->enabled)
- return 0;
-
err = mipi_dsi_dcs_set_display_off(kingdisplay->link);
if (err < 0)
dev_err(panel->dev, "failed to set display off: %d\n", err);
- kingdisplay->enabled = false;
-
return 0;
}
@@ -202,9 +194,6 @@ static int kingdisplay_panel_unprepare(struct drm_panel *panel)
struct kingdisplay_panel *kingdisplay = to_kingdisplay_panel(panel);
int err;
- if (!kingdisplay->prepared)
- return 0;
-
err = mipi_dsi_dcs_enter_sleep_mode(kingdisplay->link);
if (err < 0) {
dev_err(panel->dev, "failed to enter sleep mode: %d\n", err);
@@ -220,8 +209,6 @@ static int kingdisplay_panel_unprepare(struct drm_panel *panel)
if (err < 0)
return err;
- kingdisplay->prepared = false;
-
return 0;
}
@@ -231,9 +218,6 @@ static int kingdisplay_panel_prepare(struct drm_panel *panel)
int err, regulator_err;
unsigned int i;
- if (kingdisplay->prepared)
- return 0;
-
gpiod_set_value_cansleep(kingdisplay->enable_gpio, 0);
err = regulator_enable(kingdisplay->supply);
@@ -275,8 +259,6 @@ static int kingdisplay_panel_prepare(struct drm_panel *panel)
/* T7: 10ms */
usleep_range(10000, 11000);
- kingdisplay->prepared = true;
-
return 0;
poweroff:
@@ -289,18 +271,6 @@ poweroff:
return err;
}
-static int kingdisplay_panel_enable(struct drm_panel *panel)
-{
- struct kingdisplay_panel *kingdisplay = to_kingdisplay_panel(panel);
-
- if (kingdisplay->enabled)
- return 0;
-
- kingdisplay->enabled = true;
-
- return 0;
-}
-
static const struct drm_display_mode default_mode = {
.clock = 229000,
.hdisplay = 1536,
@@ -341,7 +311,6 @@ static const struct drm_panel_funcs kingdisplay_panel_funcs = {
.disable = kingdisplay_panel_disable,
.unprepare = kingdisplay_panel_unprepare,
.prepare = kingdisplay_panel_prepare,
- .enable = kingdisplay_panel_enable,
.get_modes = kingdisplay_panel_get_modes,
};
@@ -420,14 +389,6 @@ static void kingdisplay_panel_remove(struct mipi_dsi_device *dsi)
struct kingdisplay_panel *kingdisplay = mipi_dsi_get_drvdata(dsi);
int err;
- err = drm_panel_unprepare(&kingdisplay->base);
- if (err < 0)
- dev_err(&dsi->dev, "failed to unprepare panel: %d\n", err);
-
- err = drm_panel_disable(&kingdisplay->base);
- if (err < 0)
- dev_err(&dsi->dev, "failed to disable panel: %d\n", err);
-
err = mipi_dsi_detach(dsi);
if (err < 0)
dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", err);
@@ -435,14 +396,6 @@ static void kingdisplay_panel_remove(struct mipi_dsi_device *dsi)
kingdisplay_panel_del(kingdisplay);
}
-static void kingdisplay_panel_shutdown(struct mipi_dsi_device *dsi)
-{
- struct kingdisplay_panel *kingdisplay = mipi_dsi_get_drvdata(dsi);
-
- drm_panel_unprepare(&kingdisplay->base);
- drm_panel_disable(&kingdisplay->base);
-}
-
static struct mipi_dsi_driver kingdisplay_panel_driver = {
.driver = {
.name = "panel-kingdisplay-kd097d04",
@@ -450,7 +403,6 @@ static struct mipi_dsi_driver kingdisplay_panel_driver = {
},
.probe = kingdisplay_panel_probe,
.remove = kingdisplay_panel_remove,
- .shutdown = kingdisplay_panel_shutdown,
};
module_mipi_dsi_driver(kingdisplay_panel_driver);
diff --git a/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c b/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c
index 1a26205701b5..292aa26a456d 100644
--- a/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c
+++ b/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c
@@ -36,7 +36,6 @@ struct ltk050h3146w {
struct regulator *vci;
struct regulator *iovcc;
const struct ltk050h3146w_desc *panel_desc;
- bool prepared;
};
static const struct ltk050h3146w_cmd page1_cmds[] = {
@@ -521,9 +520,6 @@ static int ltk050h3146w_unprepare(struct drm_panel *panel)
struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
int ret;
- if (!ctx->prepared)
- return 0;
-
ret = mipi_dsi_dcs_set_display_off(dsi);
if (ret < 0) {
dev_err(ctx->dev, "failed to set display off: %d\n", ret);
@@ -539,8 +535,6 @@ static int ltk050h3146w_unprepare(struct drm_panel *panel)
regulator_disable(ctx->iovcc);
regulator_disable(ctx->vci);
- ctx->prepared = false;
-
return 0;
}
@@ -550,9 +544,6 @@ static int ltk050h3146w_prepare(struct drm_panel *panel)
struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
int ret;
- if (ctx->prepared)
- return 0;
-
dev_dbg(ctx->dev, "Resetting the panel\n");
ret = regulator_enable(ctx->vci);
if (ret < 0) {
@@ -593,8 +584,6 @@ static int ltk050h3146w_prepare(struct drm_panel *panel)
msleep(50);
- ctx->prepared = true;
-
return 0;
disable_iovcc:
@@ -684,27 +673,11 @@ static int ltk050h3146w_probe(struct mipi_dsi_device *dsi)
return 0;
}
-static void ltk050h3146w_shutdown(struct mipi_dsi_device *dsi)
-{
- struct ltk050h3146w *ctx = mipi_dsi_get_drvdata(dsi);
- int ret;
-
- ret = drm_panel_unprepare(&ctx->panel);
- if (ret < 0)
- dev_err(&dsi->dev, "Failed to unprepare panel: %d\n", ret);
-
- ret = drm_panel_disable(&ctx->panel);
- if (ret < 0)
- dev_err(&dsi->dev, "Failed to disable panel: %d\n", ret);
-}
-
static void ltk050h3146w_remove(struct mipi_dsi_device *dsi)
{
struct ltk050h3146w *ctx = mipi_dsi_get_drvdata(dsi);
int ret;
- ltk050h3146w_shutdown(dsi);
-
ret = mipi_dsi_detach(dsi);
if (ret < 0)
dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret);
@@ -736,7 +709,6 @@ static struct mipi_dsi_driver ltk050h3146w_driver = {
},
.probe = ltk050h3146w_probe,
.remove = ltk050h3146w_remove,
- .shutdown = ltk050h3146w_shutdown,
};
module_mipi_dsi_driver(ltk050h3146w_driver);
diff --git a/drivers/gpu/drm/panel/panel-leadtek-ltk500hd1829.c b/drivers/gpu/drm/panel/panel-leadtek-ltk500hd1829.c
index a4c9a5cb9811..6b18cf00fd4a 100644
--- a/drivers/gpu/drm/panel/panel-leadtek-ltk500hd1829.c
+++ b/drivers/gpu/drm/panel/panel-leadtek-ltk500hd1829.c
@@ -40,7 +40,6 @@ struct ltk500hd1829 {
struct regulator *vcc;
struct regulator *iovcc;
const struct ltk500hd1829_desc *panel_desc;
- bool prepared;
};
static const struct ltk500hd1829_cmd ltk101b4029w_init[] = {
@@ -492,9 +491,6 @@ static int ltk500hd1829_unprepare(struct drm_panel *panel)
struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
int ret;
- if (!ctx->prepared)
- return 0;
-
ret = mipi_dsi_dcs_set_display_off(dsi);
if (ret < 0)
dev_err(panel->dev, "failed to set display off: %d\n", ret);
@@ -510,8 +506,6 @@ static int ltk500hd1829_unprepare(struct drm_panel *panel)
regulator_disable(ctx->iovcc);
regulator_disable(ctx->vcc);
- ctx->prepared = false;
-
return 0;
}
@@ -522,9 +516,6 @@ static int ltk500hd1829_prepare(struct drm_panel *panel)
unsigned int i;
int ret;
- if (ctx->prepared)
- return 0;
-
ret = regulator_enable(ctx->vcc);
if (ret < 0) {
dev_err(ctx->dev, "Failed to enable vci supply: %d\n", ret);
@@ -568,8 +559,6 @@ static int ltk500hd1829_prepare(struct drm_panel *panel)
goto disable_iovcc;
}
- ctx->prepared = true;
-
return 0;
disable_iovcc:
@@ -673,27 +662,11 @@ static int ltk500hd1829_probe(struct mipi_dsi_device *dsi)
return 0;
}
-static void ltk500hd1829_shutdown(struct mipi_dsi_device *dsi)
-{
- struct ltk500hd1829 *ctx = mipi_dsi_get_drvdata(dsi);
- int ret;
-
- ret = drm_panel_unprepare(&ctx->panel);
- if (ret < 0)
- dev_err(&dsi->dev, "Failed to unprepare panel: %d\n", ret);
-
- ret = drm_panel_disable(&ctx->panel);
- if (ret < 0)
- dev_err(&dsi->dev, "Failed to disable panel: %d\n", ret);
-}
-
static void ltk500hd1829_remove(struct mipi_dsi_device *dsi)
{
struct ltk500hd1829 *ctx = mipi_dsi_get_drvdata(dsi);
int ret;
- ltk500hd1829_shutdown(dsi);
-
ret = mipi_dsi_detach(dsi);
if (ret < 0)
dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret);
@@ -721,7 +694,6 @@ static struct mipi_dsi_driver ltk500hd1829_driver = {
},
.probe = ltk500hd1829_probe,
.remove = ltk500hd1829_remove,
- .shutdown = ltk500hd1829_shutdown,
};
module_mipi_dsi_driver(ltk500hd1829_driver);
diff --git a/drivers/gpu/drm/panel/panel-lg-sw43408.c b/drivers/gpu/drm/panel/panel-lg-sw43408.c
index 2b3a73696dce..f3dcc39670ea 100644
--- a/drivers/gpu/drm/panel/panel-lg-sw43408.c
+++ b/drivers/gpu/drm/panel/panel-lg-sw43408.c
@@ -40,83 +40,83 @@ static inline struct sw43408_panel *to_panel_info(struct drm_panel *panel)
static int sw43408_unprepare(struct drm_panel *panel)
{
- struct sw43408_panel *ctx = to_panel_info(panel);
+ struct sw43408_panel *sw43408 = to_panel_info(panel);
+ struct mipi_dsi_multi_context ctx = { .dsi = sw43408->link };
int ret;
- ret = mipi_dsi_dcs_set_display_off(ctx->link);
- if (ret < 0)
- dev_err(panel->dev, "set_display_off cmd failed ret = %d\n", ret);
+ mipi_dsi_dcs_set_display_off_multi(&ctx);
- ret = mipi_dsi_dcs_enter_sleep_mode(ctx->link);
- if (ret < 0)
- dev_err(panel->dev, "enter_sleep cmd failed ret = %d\n", ret);
+ mipi_dsi_dcs_enter_sleep_mode_multi(&ctx);
- msleep(100);
+ mipi_dsi_msleep(&ctx, 100);
- gpiod_set_value(ctx->reset_gpio, 1);
+ gpiod_set_value(sw43408->reset_gpio, 1);
+
+ ret = regulator_bulk_disable(ARRAY_SIZE(sw43408->supplies), sw43408->supplies);
- return regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+ return ret ? : ctx.accum_err;
}
static int sw43408_program(struct drm_panel *panel)
{
- struct sw43408_panel *ctx = to_panel_info(panel);
+ struct sw43408_panel *sw43408 = to_panel_info(panel);
+ struct mipi_dsi_multi_context ctx = { .dsi = sw43408->link };
struct drm_dsc_picture_parameter_set pps;
- mipi_dsi_dcs_write_seq(ctx->link, MIPI_DCS_SET_GAMMA_CURVE, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&ctx, MIPI_DCS_SET_GAMMA_CURVE, 0x02);
- mipi_dsi_dcs_set_tear_on(ctx->link, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
+ mipi_dsi_dcs_set_tear_on_multi(&ctx, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
- mipi_dsi_dcs_write_seq(ctx->link, 0x53, 0x0c, 0x30);
- mipi_dsi_dcs_write_seq(ctx->link, 0x55, 0x00, 0x70, 0xdf, 0x00, 0x70, 0xdf);
- mipi_dsi_dcs_write_seq(ctx->link, 0xf7, 0x01, 0x49, 0x0c);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x53, 0x0c, 0x30);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x55, 0x00, 0x70, 0xdf, 0x00, 0x70, 0xdf);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xf7, 0x01, 0x49, 0x0c);
- mipi_dsi_dcs_exit_sleep_mode(ctx->link);
+ mipi_dsi_dcs_exit_sleep_mode_multi(&ctx);
- msleep(135);
+ mipi_dsi_msleep(&ctx, 135);
/* COMPRESSION_MODE moved after setting the PPS */
- mipi_dsi_dcs_write_seq(ctx->link, 0xb0, 0xac);
- mipi_dsi_dcs_write_seq(ctx->link, 0xe5,
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0xac);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xe5,
0x00, 0x3a, 0x00, 0x3a, 0x00, 0x0e, 0x10);
- mipi_dsi_dcs_write_seq(ctx->link, 0xb5,
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb5,
0x75, 0x60, 0x2d, 0x5d, 0x80, 0x00, 0x0a, 0x0b,
0x00, 0x05, 0x0b, 0x00, 0x80, 0x0d, 0x0e, 0x40,
0x00, 0x0c, 0x00, 0x16, 0x00, 0xb8, 0x00, 0x80,
0x0d, 0x0e, 0x40, 0x00, 0x0c, 0x00, 0x16, 0x00,
0xb8, 0x00, 0x81, 0x00, 0x03, 0x03, 0x03, 0x01,
0x01);
- msleep(85);
- mipi_dsi_dcs_write_seq(ctx->link, 0xcd,
+ mipi_dsi_msleep(&ctx, 85);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcd,
0x00, 0x00, 0x00, 0x19, 0x19, 0x19, 0x19, 0x19,
0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
0x16, 0x16);
- mipi_dsi_dcs_write_seq(ctx->link, 0xcb, 0x80, 0x5c, 0x07, 0x03, 0x28);
- mipi_dsi_dcs_write_seq(ctx->link, 0xc0, 0x02, 0x02, 0x0f);
- mipi_dsi_dcs_write_seq(ctx->link, 0x55, 0x04, 0x61, 0xdb, 0x04, 0x70, 0xdb);
- mipi_dsi_dcs_write_seq(ctx->link, 0xb0, 0xca);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xcb, 0x80, 0x5c, 0x07, 0x03, 0x28);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xc0, 0x02, 0x02, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0x55, 0x04, 0x61, 0xdb, 0x04, 0x70, 0xdb);
+ mipi_dsi_dcs_write_seq_multi(&ctx, 0xb0, 0xca);
+
+ mipi_dsi_dcs_set_display_on_multi(&ctx);
- mipi_dsi_dcs_set_display_on(ctx->link);
+ mipi_dsi_msleep(&ctx, 50);
- msleep(50);
+ sw43408->link->mode_flags &= ~MIPI_DSI_MODE_LPM;
- ctx->link->mode_flags &= ~MIPI_DSI_MODE_LPM;
+ drm_dsc_pps_payload_pack(&pps, sw43408->link->dsc);
- drm_dsc_pps_payload_pack(&pps, ctx->link->dsc);
- mipi_dsi_picture_parameter_set(ctx->link, &pps);
+ mipi_dsi_picture_parameter_set_multi(&ctx, &pps);
- ctx->link->mode_flags |= MIPI_DSI_MODE_LPM;
+ sw43408->link->mode_flags |= MIPI_DSI_MODE_LPM;
/*
* This panel uses PPS selectors with offset:
* PPS 1 if pps_identifier is 0
* PPS 2 if pps_identifier is 1
*/
- mipi_dsi_compression_mode_ext(ctx->link, true,
- MIPI_DSI_COMPRESSION_DSC, 1);
-
- return 0;
+ mipi_dsi_compression_mode_ext_multi(&ctx, true,
+ MIPI_DSI_COMPRESSION_DSC, 1);
+ return ctx.accum_err;
}
static int sw43408_prepare(struct drm_panel *panel)
diff --git a/drivers/gpu/drm/panel/panel-newvision-nv3052c.c b/drivers/gpu/drm/panel/panel-newvision-nv3052c.c
index 1aab0c9ae52f..c5d3ead38555 100644
--- a/drivers/gpu/drm/panel/panel-newvision-nv3052c.c
+++ b/drivers/gpu/drm/panel/panel-newvision-nv3052c.c
@@ -433,6 +433,202 @@ static const struct nv3052c_reg fs035vg158_panel_regs[] = {
{ 0x36, 0x0a }, // bgr = 1, ss = 1, gs = 0
};
+
+static const struct nv3052c_reg wl_355608_a8_panel_regs[] = {
+ // EXTC Command set enable, select page 1
+ { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x01 },
+ // Mostly unknown registers
+ { 0xe3, 0x00 },
+ { 0x40, 0x00 },
+ { 0x03, 0x40 },
+ { 0x04, 0x00 },
+ { 0x05, 0x03 },
+ { 0x08, 0x00 },
+ { 0x09, 0x07 },
+ { 0x0a, 0x01 },
+ { 0x0b, 0x32 },
+ { 0x0c, 0x32 },
+ { 0x0d, 0x0b },
+ { 0x0e, 0x00 },
+ { 0x23, 0xa0 },
+ { 0x24, 0x0c },
+ { 0x25, 0x06 },
+ { 0x26, 0x14 },
+ { 0x27, 0x14 },
+ { 0x38, 0xcc }, // VCOM_ADJ1
+ { 0x39, 0xd7 }, // VCOM_ADJ2
+ { 0x3a, 0x44 }, // VCOM_ADJ3
+ { 0x28, 0x40 },
+ { 0x29, 0x01 },
+ { 0x2a, 0xdf },
+ { 0x49, 0x3c },
+ { 0x91, 0x77 }, // EXTPW_CTRL2
+ { 0x92, 0x77 }, // EXTPW_CTRL3
+ { 0xa0, 0x55 },
+ { 0xa1, 0x50 },
+ { 0xa4, 0x9c },
+ { 0xa7, 0x02 },
+ { 0xa8, 0x01 },
+ { 0xa9, 0x01 },
+ { 0xaa, 0xfc },
+ { 0xab, 0x28 },
+ { 0xac, 0x06 },
+ { 0xad, 0x06 },
+ { 0xae, 0x06 },
+ { 0xaf, 0x03 },
+ { 0xb0, 0x08 },
+ { 0xb1, 0x26 },
+ { 0xb2, 0x28 },
+ { 0xb3, 0x28 },
+ { 0xb4, 0x33 },
+ { 0xb5, 0x08 },
+ { 0xb6, 0x26 },
+ { 0xb7, 0x08 },
+ { 0xb8, 0x26 },
+ { 0xf0, 0x00 },
+ { 0xf6, 0xc0 },
+ // EXTC Command set enable, select page 2
+ { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x02 },
+ // Set gray scale voltage to adjust gamma
+ { 0xb0, 0x0b }, // PGAMVR0
+ { 0xb1, 0x16 }, // PGAMVR1
+ { 0xb2, 0x17 }, // PGAMVR2
+ { 0xb3, 0x2c }, // PGAMVR3
+ { 0xb4, 0x32 }, // PGAMVR4
+ { 0xb5, 0x3b }, // PGAMVR5
+ { 0xb6, 0x29 }, // PGAMPR0
+ { 0xb7, 0x40 }, // PGAMPR1
+ { 0xb8, 0x0d }, // PGAMPK0
+ { 0xb9, 0x05 }, // PGAMPK1
+ { 0xba, 0x12 }, // PGAMPK2
+ { 0xbb, 0x10 }, // PGAMPK3
+ { 0xbc, 0x12 }, // PGAMPK4
+ { 0xbd, 0x15 }, // PGAMPK5
+ { 0xbe, 0x19 }, // PGAMPK6
+ { 0xbf, 0x0e }, // PGAMPK7
+ { 0xc0, 0x16 }, // PGAMPK8
+ { 0xc1, 0x0a }, // PGAMPK9
+ // Set gray scale voltage to adjust gamma
+ { 0xd0, 0x0c }, // NGAMVR0
+ { 0xd1, 0x17 }, // NGAMVR0
+ { 0xd2, 0x14 }, // NGAMVR1
+ { 0xd3, 0x2e }, // NGAMVR2
+ { 0xd4, 0x32 }, // NGAMVR3
+ { 0xd5, 0x3c }, // NGAMVR4
+ { 0xd6, 0x22 }, // NGAMPR0
+ { 0xd7, 0x3d }, // NGAMPR1
+ { 0xd8, 0x0d }, // NGAMPK0
+ { 0xd9, 0x07 }, // NGAMPK1
+ { 0xda, 0x13 }, // NGAMPK2
+ { 0xdb, 0x13 }, // NGAMPK3
+ { 0xdc, 0x11 }, // NGAMPK4
+ { 0xdd, 0x15 }, // NGAMPK5
+ { 0xde, 0x19 }, // NGAMPK6
+ { 0xdf, 0x10 }, // NGAMPK7
+ { 0xe0, 0x17 }, // NGAMPK8
+ { 0xe1, 0x0a }, // NGAMPK9
+ // EXTC Command set enable, select page 3
+ { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x03 },
+ // Set various timing settings
+ { 0x00, 0x2a }, // GIP_VST_1
+ { 0x01, 0x2a }, // GIP_VST_2
+ { 0x02, 0x2a }, // GIP_VST_3
+ { 0x03, 0x2a }, // GIP_VST_4
+ { 0x04, 0x61 }, // GIP_VST_5
+ { 0x05, 0x80 }, // GIP_VST_6
+ { 0x06, 0xc7 }, // GIP_VST_7
+ { 0x07, 0x01 }, // GIP_VST_8
+ { 0x08, 0x03 }, // GIP_VST_9
+ { 0x09, 0x04 }, // GIP_VST_10
+ { 0x70, 0x22 }, // GIP_ECLK1
+ { 0x71, 0x80 }, // GIP_ECLK2
+ { 0x30, 0x2a }, // GIP_CLK_1
+ { 0x31, 0x2a }, // GIP_CLK_2
+ { 0x32, 0x2a }, // GIP_CLK_3
+ { 0x33, 0x2a }, // GIP_CLK_4
+ { 0x34, 0x61 }, // GIP_CLK_5
+ { 0x35, 0xc5 }, // GIP_CLK_6
+ { 0x36, 0x80 }, // GIP_CLK_7
+ { 0x37, 0x23 }, // GIP_CLK_8
+ { 0x40, 0x03 }, // GIP_CLKA_1
+ { 0x41, 0x04 }, // GIP_CLKA_2
+ { 0x42, 0x05 }, // GIP_CLKA_3
+ { 0x43, 0x06 }, // GIP_CLKA_4
+ { 0x44, 0x11 }, // GIP_CLKA_5
+ { 0x45, 0xe8 }, // GIP_CLKA_6
+ { 0x46, 0xe9 }, // GIP_CLKA_7
+ { 0x47, 0x11 }, // GIP_CLKA_8
+ { 0x48, 0xea }, // GIP_CLKA_9
+ { 0x49, 0xeb }, // GIP_CLKA_10
+ { 0x50, 0x07 }, // GIP_CLKB_1
+ { 0x51, 0x08 }, // GIP_CLKB_2
+ { 0x52, 0x09 }, // GIP_CLKB_3
+ { 0x53, 0x0a }, // GIP_CLKB_4
+ { 0x54, 0x11 }, // GIP_CLKB_5
+ { 0x55, 0xec }, // GIP_CLKB_6
+ { 0x56, 0xed }, // GIP_CLKB_7
+ { 0x57, 0x11 }, // GIP_CLKB_8
+ { 0x58, 0xef }, // GIP_CLKB_9
+ { 0x59, 0xf0 }, // GIP_CLKB_10
+ // Map internal GOA signals to GOA output pad
+ { 0xb1, 0x01 }, // PANELD2U2
+ { 0xb4, 0x15 }, // PANELD2U5
+ { 0xb5, 0x16 }, // PANELD2U6
+ { 0xb6, 0x09 }, // PANELD2U7
+ { 0xb7, 0x0f }, // PANELD2U8
+ { 0xb8, 0x0d }, // PANELD2U9
+ { 0xb9, 0x0b }, // PANELD2U10
+ { 0xba, 0x00 }, // PANELD2U11
+ { 0xc7, 0x02 }, // PANELD2U24
+ { 0xca, 0x17 }, // PANELD2U27
+ { 0xcb, 0x18 }, // PANELD2U28
+ { 0xcc, 0x0a }, // PANELD2U29
+ { 0xcd, 0x10 }, // PANELD2U30
+ { 0xce, 0x0e }, // PANELD2U31
+ { 0xcf, 0x0c }, // PANELD2U32
+ { 0xd0, 0x00 }, // PANELD2U33
+ // Map internal GOA signals to GOA output pad
+ { 0x81, 0x00 }, // PANELU2D2
+ { 0x84, 0x15 }, // PANELU2D5
+ { 0x85, 0x16 }, // PANELU2D6
+ { 0x86, 0x10 }, // PANELU2D7
+ { 0x87, 0x0a }, // PANELU2D8
+ { 0x88, 0x0c }, // PANELU2D9
+ { 0x89, 0x0e }, // PANELU2D10
+ { 0x8a, 0x02 }, // PANELU2D11
+ { 0x97, 0x00 }, // PANELU2D24
+ { 0x9a, 0x17 }, // PANELU2D27
+ { 0x9b, 0x18 }, // PANELU2D28
+ { 0x9c, 0x0f }, // PANELU2D29
+ { 0x9d, 0x09 }, // PANELU2D30
+ { 0x9e, 0x0b }, // PANELU2D31
+ { 0x9f, 0x0d }, // PANELU2D32
+ { 0xa0, 0x01 }, // PANELU2D33
+ // EXTC Command set enable, select page 2
+ { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x02 },
+ // Unknown registers
+ { 0x01, 0x01 },
+ { 0x02, 0xda },
+ { 0x03, 0xba },
+ { 0x04, 0xa8 },
+ { 0x05, 0x9a },
+ { 0x06, 0x70 },
+ { 0x07, 0xff },
+ { 0x08, 0x91 },
+ { 0x09, 0x90 },
+ { 0x0a, 0xff },
+ { 0x0b, 0x8f },
+ { 0x0c, 0x60 },
+ { 0x0d, 0x58 },
+ { 0x0e, 0x48 },
+ { 0x0f, 0x38 },
+ { 0x10, 0x2b },
+ // EXTC Command set enable, select page 0
+ { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x00 },
+ // Display Access Control
+ { 0x36, 0x0a }, // bgr = 1, ss = 1, gs = 0
+};
+
static inline struct nv3052c *to_nv3052c(struct drm_panel *panel)
{
return container_of(panel, struct nv3052c, panel);
@@ -670,6 +866,21 @@ static const struct drm_display_mode fs035vg158_modes[] = {
},
};
+static const struct drm_display_mode wl_355608_a8_mode[] = {
+ {
+ .clock = 24000,
+ .hdisplay = 640,
+ .hsync_start = 640 + 64,
+ .hsync_end = 640 + 64 + 20,
+ .htotal = 640 + 64 + 20 + 46,
+ .vdisplay = 480,
+ .vsync_start = 480 + 21,
+ .vsync_end = 480 + 21 + 4,
+ .vtotal = 480 + 21 + 4 + 15,
+ .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
+ },
+};
+
static const struct nv3052c_panel_info ltk035c5444t_panel_info = {
.display_modes = ltk035c5444t_modes,
.num_modes = ARRAY_SIZE(ltk035c5444t_modes),
@@ -692,9 +903,21 @@ static const struct nv3052c_panel_info fs035vg158_panel_info = {
.panel_regs_len = ARRAY_SIZE(fs035vg158_panel_regs),
};
+static const struct nv3052c_panel_info wl_355608_a8_panel_info = {
+ .display_modes = wl_355608_a8_mode,
+ .num_modes = ARRAY_SIZE(wl_355608_a8_mode),
+ .width_mm = 150,
+ .height_mm = 94,
+ .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
+ .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE,
+ .panel_regs = wl_355608_a8_panel_regs,
+ .panel_regs_len = ARRAY_SIZE(wl_355608_a8_panel_regs),
+};
+
static const struct spi_device_id nv3052c_ids[] = {
{ "ltk035c5444t", },
{ "fs035vg158", },
+ { "wl-355608-a8", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(spi, nv3052c_ids);
@@ -702,6 +925,7 @@ MODULE_DEVICE_TABLE(spi, nv3052c_ids);
static const struct of_device_id nv3052c_of_match[] = {
{ .compatible = "leadtek,ltk035c5444t", .data = &ltk035c5444t_panel_info },
{ .compatible = "fascontek,fs035vg158", .data = &fs035vg158_panel_info },
+ { .compatible = "wl-355608-a8", .data = &wl_355608_a8_panel_info },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, nv3052c_of_match);
@@ -719,4 +943,6 @@ module_spi_driver(nv3052c_driver);
MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
MODULE_AUTHOR("Christophe Branchereau <cbranchereau@gmail.com>");
+MODULE_AUTHOR("Ryan Walklin <ryan@testtoast.com");
+MODULE_DESCRIPTION("NewVision NV3052C IPS LCD panel driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36672a.c b/drivers/gpu/drm/panel/panel-novatek-nt36672a.c
index 3886372415c2..c2abd20e0734 100644
--- a/drivers/gpu/drm/panel/panel-novatek-nt36672a.c
+++ b/drivers/gpu/drm/panel/panel-novatek-nt36672a.c
@@ -72,8 +72,6 @@ struct nt36672a_panel {
struct regulator_bulk_data supplies[ARRAY_SIZE(nt36672a_regulator_names)];
struct gpio_desc *reset_gpio;
-
- bool prepared;
};
static inline struct nt36672a_panel *to_nt36672a_panel(struct drm_panel *panel)
@@ -119,9 +117,6 @@ static int nt36672a_panel_unprepare(struct drm_panel *panel)
struct nt36672a_panel *pinfo = to_nt36672a_panel(panel);
int ret;
- if (!pinfo->prepared)
- return 0;
-
/* send off cmds */
ret = nt36672a_send_cmds(panel, pinfo->desc->off_cmds,
pinfo->desc->num_off_cmds);
@@ -147,8 +142,6 @@ static int nt36672a_panel_unprepare(struct drm_panel *panel)
if (ret < 0)
dev_err(panel->dev, "power_off failed ret = %d\n", ret);
- pinfo->prepared = false;
-
return ret;
}
@@ -179,9 +172,6 @@ static int nt36672a_panel_prepare(struct drm_panel *panel)
struct nt36672a_panel *pinfo = to_nt36672a_panel(panel);
int err;
- if (pinfo->prepared)
- return 0;
-
err = nt36672a_panel_power_on(pinfo);
if (err < 0)
goto poweroff;
@@ -221,8 +211,6 @@ static int nt36672a_panel_prepare(struct drm_panel *panel)
msleep(120);
- pinfo->prepared = true;
-
return 0;
poweroff:
@@ -668,14 +656,6 @@ static void nt36672a_panel_remove(struct mipi_dsi_device *dsi)
struct nt36672a_panel *pinfo = mipi_dsi_get_drvdata(dsi);
int err;
- err = drm_panel_unprepare(&pinfo->base);
- if (err < 0)
- dev_err(&dsi->dev, "failed to unprepare panel: %d\n", err);
-
- err = drm_panel_disable(&pinfo->base);
- if (err < 0)
- dev_err(&dsi->dev, "failed to disable panel: %d\n", err);
-
err = mipi_dsi_detach(dsi);
if (err < 0)
dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", err);
@@ -683,14 +663,6 @@ static void nt36672a_panel_remove(struct mipi_dsi_device *dsi)
drm_panel_remove(&pinfo->base);
}
-static void nt36672a_panel_shutdown(struct mipi_dsi_device *dsi)
-{
- struct nt36672a_panel *pinfo = mipi_dsi_get_drvdata(dsi);
-
- drm_panel_disable(&pinfo->base);
- drm_panel_unprepare(&pinfo->base);
-}
-
static const struct of_device_id tianma_fhd_video_of_match[] = {
{ .compatible = "tianma,fhd-video", .data = &tianma_fhd_video_panel_desc },
{ },
@@ -704,7 +676,6 @@ static struct mipi_dsi_driver nt36672a_panel_driver = {
},
.probe = nt36672a_panel_probe,
.remove = nt36672a_panel_remove,
- .shutdown = nt36672a_panel_shutdown,
};
module_mipi_dsi_driver(nt36672a_panel_driver);
diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36672e.c b/drivers/gpu/drm/panel/panel-novatek-nt36672e.c
index 20b7bfe4aa12..e81a70147259 100644
--- a/drivers/gpu/drm/panel/panel-novatek-nt36672e.c
+++ b/drivers/gpu/drm/panel/panel-novatek-nt36672e.c
@@ -33,7 +33,7 @@ struct panel_desc {
enum mipi_dsi_pixel_format format;
unsigned int lanes;
const char *panel_name;
- int (*init_sequence)(struct mipi_dsi_device *dsi);
+ void (*init_sequence)(struct mipi_dsi_multi_context *ctx);
};
struct nt36672e_panel {
@@ -49,295 +49,293 @@ static inline struct nt36672e_panel *to_nt36672e_panel(struct drm_panel *panel)
return container_of(panel, struct nt36672e_panel, panel);
}
-static int nt36672e_1080x2408_60hz_init(struct mipi_dsi_device *dsi)
+static void nt36672e_1080x2408_60hz_init(struct mipi_dsi_multi_context *ctx)
{
- mipi_dsi_dcs_write_seq(dsi, 0xff, 0x10);
- mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
- mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0xc0, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0xc1, 0x89, 0x28, 0x00, 0x08, 0x00, 0xaa, 0x02,
- 0x0e, 0x00, 0x2b, 0x00, 0x07, 0x0d, 0xb7, 0x0c, 0xb7);
-
- mipi_dsi_dcs_write_seq(dsi, 0xc2, 0x1b, 0xa0);
- mipi_dsi_dcs_write_seq(dsi, 0xff, 0x20);
- mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
- mipi_dsi_dcs_write_seq(dsi, 0x01, 0x66);
- mipi_dsi_dcs_write_seq(dsi, 0x06, 0x40);
- mipi_dsi_dcs_write_seq(dsi, 0x07, 0x38);
- mipi_dsi_dcs_write_seq(dsi, 0x2f, 0x83);
- mipi_dsi_dcs_write_seq(dsi, 0x69, 0x91);
- mipi_dsi_dcs_write_seq(dsi, 0x95, 0xd1);
- mipi_dsi_dcs_write_seq(dsi, 0x96, 0xd1);
- mipi_dsi_dcs_write_seq(dsi, 0xf2, 0x64);
- mipi_dsi_dcs_write_seq(dsi, 0xf3, 0x54);
- mipi_dsi_dcs_write_seq(dsi, 0xf4, 0x64);
- mipi_dsi_dcs_write_seq(dsi, 0xf5, 0x54);
- mipi_dsi_dcs_write_seq(dsi, 0xf6, 0x64);
- mipi_dsi_dcs_write_seq(dsi, 0xf7, 0x54);
- mipi_dsi_dcs_write_seq(dsi, 0xf8, 0x64);
- mipi_dsi_dcs_write_seq(dsi, 0xf9, 0x54);
- mipi_dsi_dcs_write_seq(dsi, 0xff, 0x24);
- mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
- mipi_dsi_dcs_write_seq(dsi, 0x01, 0x0f);
- mipi_dsi_dcs_write_seq(dsi, 0x03, 0x0c);
- mipi_dsi_dcs_write_seq(dsi, 0x05, 0x1d);
- mipi_dsi_dcs_write_seq(dsi, 0x08, 0x2f);
- mipi_dsi_dcs_write_seq(dsi, 0x09, 0x2e);
- mipi_dsi_dcs_write_seq(dsi, 0x0a, 0x2d);
- mipi_dsi_dcs_write_seq(dsi, 0x0b, 0x2c);
- mipi_dsi_dcs_write_seq(dsi, 0x11, 0x17);
- mipi_dsi_dcs_write_seq(dsi, 0x12, 0x13);
- mipi_dsi_dcs_write_seq(dsi, 0x13, 0x15);
- mipi_dsi_dcs_write_seq(dsi, 0x15, 0x14);
- mipi_dsi_dcs_write_seq(dsi, 0x16, 0x16);
- mipi_dsi_dcs_write_seq(dsi, 0x17, 0x18);
- mipi_dsi_dcs_write_seq(dsi, 0x1b, 0x01);
- mipi_dsi_dcs_write_seq(dsi, 0x1d, 0x1d);
- mipi_dsi_dcs_write_seq(dsi, 0x20, 0x2f);
- mipi_dsi_dcs_write_seq(dsi, 0x21, 0x2e);
- mipi_dsi_dcs_write_seq(dsi, 0x22, 0x2d);
- mipi_dsi_dcs_write_seq(dsi, 0x23, 0x2c);
- mipi_dsi_dcs_write_seq(dsi, 0x29, 0x17);
- mipi_dsi_dcs_write_seq(dsi, 0x2a, 0x13);
- mipi_dsi_dcs_write_seq(dsi, 0x2b, 0x15);
- mipi_dsi_dcs_write_seq(dsi, 0x2f, 0x14);
- mipi_dsi_dcs_write_seq(dsi, 0x30, 0x16);
- mipi_dsi_dcs_write_seq(dsi, 0x31, 0x18);
- mipi_dsi_dcs_write_seq(dsi, 0x32, 0x04);
- mipi_dsi_dcs_write_seq(dsi, 0x34, 0x10);
- mipi_dsi_dcs_write_seq(dsi, 0x35, 0x1f);
- mipi_dsi_dcs_write_seq(dsi, 0x36, 0x1f);
- mipi_dsi_dcs_write_seq(dsi, 0x4d, 0x14);
- mipi_dsi_dcs_write_seq(dsi, 0x4e, 0x36);
- mipi_dsi_dcs_write_seq(dsi, 0x4f, 0x36);
- mipi_dsi_dcs_write_seq(dsi, 0x53, 0x36);
- mipi_dsi_dcs_write_seq(dsi, 0x71, 0x30);
- mipi_dsi_dcs_write_seq(dsi, 0x79, 0x11);
- mipi_dsi_dcs_write_seq(dsi, 0x7a, 0x82);
- mipi_dsi_dcs_write_seq(dsi, 0x7b, 0x8f);
- mipi_dsi_dcs_write_seq(dsi, 0x7d, 0x04);
- mipi_dsi_dcs_write_seq(dsi, 0x80, 0x04);
- mipi_dsi_dcs_write_seq(dsi, 0x81, 0x04);
- mipi_dsi_dcs_write_seq(dsi, 0x82, 0x13);
- mipi_dsi_dcs_write_seq(dsi, 0x84, 0x31);
- mipi_dsi_dcs_write_seq(dsi, 0x85, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0x86, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0x87, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0x90, 0x13);
- mipi_dsi_dcs_write_seq(dsi, 0x92, 0x31);
- mipi_dsi_dcs_write_seq(dsi, 0x93, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0x94, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0x95, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0x9c, 0xf4);
- mipi_dsi_dcs_write_seq(dsi, 0x9d, 0x01);
- mipi_dsi_dcs_write_seq(dsi, 0xa0, 0x0f);
- mipi_dsi_dcs_write_seq(dsi, 0xa2, 0x0f);
- mipi_dsi_dcs_write_seq(dsi, 0xa3, 0x02);
- mipi_dsi_dcs_write_seq(dsi, 0xa4, 0x04);
- mipi_dsi_dcs_write_seq(dsi, 0xa5, 0x04);
- mipi_dsi_dcs_write_seq(dsi, 0xc6, 0xc0);
- mipi_dsi_dcs_write_seq(dsi, 0xc9, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0xd9, 0x80);
- mipi_dsi_dcs_write_seq(dsi, 0xe9, 0x02);
- mipi_dsi_dcs_write_seq(dsi, 0xff, 0x25);
- mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
- mipi_dsi_dcs_write_seq(dsi, 0x18, 0x22);
- mipi_dsi_dcs_write_seq(dsi, 0x19, 0xe4);
- mipi_dsi_dcs_write_seq(dsi, 0x21, 0x40);
- mipi_dsi_dcs_write_seq(dsi, 0x66, 0xd8);
- mipi_dsi_dcs_write_seq(dsi, 0x68, 0x50);
- mipi_dsi_dcs_write_seq(dsi, 0x69, 0x10);
- mipi_dsi_dcs_write_seq(dsi, 0x6b, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0x6d, 0x0d);
- mipi_dsi_dcs_write_seq(dsi, 0x6e, 0x48);
- mipi_dsi_dcs_write_seq(dsi, 0x72, 0x41);
- mipi_dsi_dcs_write_seq(dsi, 0x73, 0x4a);
- mipi_dsi_dcs_write_seq(dsi, 0x74, 0xd0);
- mipi_dsi_dcs_write_seq(dsi, 0x77, 0x62);
- mipi_dsi_dcs_write_seq(dsi, 0x79, 0x7e);
- mipi_dsi_dcs_write_seq(dsi, 0x7d, 0x03);
- mipi_dsi_dcs_write_seq(dsi, 0x7e, 0x15);
- mipi_dsi_dcs_write_seq(dsi, 0x7f, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0x84, 0x4d);
- mipi_dsi_dcs_write_seq(dsi, 0xcf, 0x80);
- mipi_dsi_dcs_write_seq(dsi, 0xd6, 0x80);
- mipi_dsi_dcs_write_seq(dsi, 0xd7, 0x80);
- mipi_dsi_dcs_write_seq(dsi, 0xef, 0x20);
- mipi_dsi_dcs_write_seq(dsi, 0xf0, 0x84);
- mipi_dsi_dcs_write_seq(dsi, 0xff, 0x26);
- mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
- mipi_dsi_dcs_write_seq(dsi, 0x81, 0x0f);
- mipi_dsi_dcs_write_seq(dsi, 0x83, 0x01);
- mipi_dsi_dcs_write_seq(dsi, 0x84, 0x03);
- mipi_dsi_dcs_write_seq(dsi, 0x85, 0x01);
- mipi_dsi_dcs_write_seq(dsi, 0x86, 0x03);
- mipi_dsi_dcs_write_seq(dsi, 0x87, 0x01);
- mipi_dsi_dcs_write_seq(dsi, 0x88, 0x05);
- mipi_dsi_dcs_write_seq(dsi, 0x8a, 0x1a);
- mipi_dsi_dcs_write_seq(dsi, 0x8b, 0x11);
- mipi_dsi_dcs_write_seq(dsi, 0x8c, 0x24);
- mipi_dsi_dcs_write_seq(dsi, 0x8e, 0x42);
- mipi_dsi_dcs_write_seq(dsi, 0x8f, 0x11);
- mipi_dsi_dcs_write_seq(dsi, 0x90, 0x11);
- mipi_dsi_dcs_write_seq(dsi, 0x91, 0x11);
- mipi_dsi_dcs_write_seq(dsi, 0x9a, 0x80);
- mipi_dsi_dcs_write_seq(dsi, 0x9b, 0x04);
- mipi_dsi_dcs_write_seq(dsi, 0x9c, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0x9d, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0x9e, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0xff, 0x27);
- mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
- mipi_dsi_dcs_write_seq(dsi, 0x01, 0x68);
- mipi_dsi_dcs_write_seq(dsi, 0x20, 0x81);
- mipi_dsi_dcs_write_seq(dsi, 0x21, 0x6a);
- mipi_dsi_dcs_write_seq(dsi, 0x25, 0x81);
- mipi_dsi_dcs_write_seq(dsi, 0x26, 0x94);
- mipi_dsi_dcs_write_seq(dsi, 0x6e, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0x6f, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0x70, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0x71, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0x72, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0x75, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0x76, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0x77, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0x7d, 0x09);
- mipi_dsi_dcs_write_seq(dsi, 0x7e, 0x67);
- mipi_dsi_dcs_write_seq(dsi, 0x80, 0x23);
- mipi_dsi_dcs_write_seq(dsi, 0x82, 0x09);
- mipi_dsi_dcs_write_seq(dsi, 0x83, 0x67);
- mipi_dsi_dcs_write_seq(dsi, 0x88, 0x01);
- mipi_dsi_dcs_write_seq(dsi, 0x89, 0x10);
- mipi_dsi_dcs_write_seq(dsi, 0xa5, 0x10);
- mipi_dsi_dcs_write_seq(dsi, 0xa6, 0x23);
- mipi_dsi_dcs_write_seq(dsi, 0xa7, 0x01);
- mipi_dsi_dcs_write_seq(dsi, 0xb6, 0x40);
- mipi_dsi_dcs_write_seq(dsi, 0xe5, 0x02);
- mipi_dsi_dcs_write_seq(dsi, 0xe6, 0xd3);
- mipi_dsi_dcs_write_seq(dsi, 0xeb, 0x03);
- mipi_dsi_dcs_write_seq(dsi, 0xec, 0x28);
- mipi_dsi_dcs_write_seq(dsi, 0xff, 0x2a);
- mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
- mipi_dsi_dcs_write_seq(dsi, 0x00, 0x91);
- mipi_dsi_dcs_write_seq(dsi, 0x03, 0x20);
- mipi_dsi_dcs_write_seq(dsi, 0x07, 0x50);
- mipi_dsi_dcs_write_seq(dsi, 0x0a, 0x70);
- mipi_dsi_dcs_write_seq(dsi, 0x0c, 0x04);
- mipi_dsi_dcs_write_seq(dsi, 0x0d, 0x40);
- mipi_dsi_dcs_write_seq(dsi, 0x0f, 0x01);
- mipi_dsi_dcs_write_seq(dsi, 0x11, 0xe0);
- mipi_dsi_dcs_write_seq(dsi, 0x15, 0x0f);
- mipi_dsi_dcs_write_seq(dsi, 0x16, 0xa4);
- mipi_dsi_dcs_write_seq(dsi, 0x19, 0x0f);
- mipi_dsi_dcs_write_seq(dsi, 0x1a, 0x78);
- mipi_dsi_dcs_write_seq(dsi, 0x1b, 0x23);
- mipi_dsi_dcs_write_seq(dsi, 0x1d, 0x36);
- mipi_dsi_dcs_write_seq(dsi, 0x1e, 0x3e);
- mipi_dsi_dcs_write_seq(dsi, 0x1f, 0x3e);
- mipi_dsi_dcs_write_seq(dsi, 0x20, 0x3e);
- mipi_dsi_dcs_write_seq(dsi, 0x28, 0xfd);
- mipi_dsi_dcs_write_seq(dsi, 0x29, 0x12);
- mipi_dsi_dcs_write_seq(dsi, 0x2a, 0xe1);
- mipi_dsi_dcs_write_seq(dsi, 0x2d, 0x0a);
- mipi_dsi_dcs_write_seq(dsi, 0x30, 0x49);
- mipi_dsi_dcs_write_seq(dsi, 0x33, 0x96);
- mipi_dsi_dcs_write_seq(dsi, 0x34, 0xff);
- mipi_dsi_dcs_write_seq(dsi, 0x35, 0x40);
- mipi_dsi_dcs_write_seq(dsi, 0x36, 0xde);
- mipi_dsi_dcs_write_seq(dsi, 0x37, 0xf9);
- mipi_dsi_dcs_write_seq(dsi, 0x38, 0x45);
- mipi_dsi_dcs_write_seq(dsi, 0x39, 0xd9);
- mipi_dsi_dcs_write_seq(dsi, 0x3a, 0x49);
- mipi_dsi_dcs_write_seq(dsi, 0x4a, 0xf0);
- mipi_dsi_dcs_write_seq(dsi, 0x7a, 0x09);
- mipi_dsi_dcs_write_seq(dsi, 0x7b, 0x40);
- mipi_dsi_dcs_write_seq(dsi, 0x7f, 0xf0);
- mipi_dsi_dcs_write_seq(dsi, 0x83, 0x0f);
- mipi_dsi_dcs_write_seq(dsi, 0x84, 0xa4);
- mipi_dsi_dcs_write_seq(dsi, 0x87, 0x0f);
- mipi_dsi_dcs_write_seq(dsi, 0x88, 0x78);
- mipi_dsi_dcs_write_seq(dsi, 0x89, 0x23);
- mipi_dsi_dcs_write_seq(dsi, 0x8b, 0x36);
- mipi_dsi_dcs_write_seq(dsi, 0x8c, 0x7d);
- mipi_dsi_dcs_write_seq(dsi, 0x8d, 0x7d);
- mipi_dsi_dcs_write_seq(dsi, 0x8e, 0x7d);
- mipi_dsi_dcs_write_seq(dsi, 0xff, 0x20);
- mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
- mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x00, 0x00, 0x00, 0x17, 0x00, 0x49, 0x00,
- 0x6a, 0x00, 0x89, 0x00, 0x9f, 0x00, 0xb6, 0x00, 0xc8);
- mipi_dsi_dcs_write_seq(dsi, 0xb1, 0x00, 0xd9, 0x01, 0x10, 0x01, 0x3a, 0x01,
- 0x7a, 0x01, 0xa9, 0x01, 0xf2, 0x02, 0x2d, 0x02, 0x2e);
- mipi_dsi_dcs_write_seq(dsi, 0xb2, 0x02, 0x64, 0x02, 0xa3, 0x02, 0xca, 0x03,
- 0x00, 0x03, 0x1e, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
- mipi_dsi_dcs_write_seq(dsi, 0xb3, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
- 0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0xb4, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
- 0x71, 0x00, 0x90, 0x00, 0xa7, 0x00, 0xbf, 0x00, 0xd1);
- mipi_dsi_dcs_write_seq(dsi, 0xb5, 0x00, 0xe2, 0x01, 0x1a, 0x01, 0x43, 0x01,
- 0x83, 0x01, 0xb2, 0x01, 0xfa, 0x02, 0x34, 0x02, 0x36);
- mipi_dsi_dcs_write_seq(dsi, 0xb6, 0x02, 0x6b, 0x02, 0xa8, 0x02, 0xd0, 0x03,
- 0x03, 0x03, 0x21, 0x03, 0x4d, 0x03, 0x5b, 0x03, 0x6b);
- mipi_dsi_dcs_write_seq(dsi, 0xb7, 0x03, 0x7e, 0x03, 0x94, 0x03, 0xac, 0x03,
- 0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0xb8, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
- 0x72, 0x00, 0x92, 0x00, 0xa8, 0x00, 0xbf, 0x00, 0xd1);
- mipi_dsi_dcs_write_seq(dsi, 0xb9, 0x00, 0xe2, 0x01, 0x18, 0x01, 0x42, 0x01,
- 0x81, 0x01, 0xaf, 0x01, 0xf5, 0x02, 0x2f, 0x02, 0x31);
- mipi_dsi_dcs_write_seq(dsi, 0xba, 0x02, 0x68, 0x02, 0xa6, 0x02, 0xcd, 0x03,
- 0x01, 0x03, 0x1f, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
- mipi_dsi_dcs_write_seq(dsi, 0xbb, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
- 0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0xff, 0x21);
- mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
- mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x00, 0x00, 0x00, 0x17, 0x00, 0x49, 0x00,
- 0x6a, 0x00, 0x89, 0x00, 0x9f, 0x00, 0xb6, 0x00, 0xc8);
- mipi_dsi_dcs_write_seq(dsi, 0xb1, 0x00, 0xd9, 0x01, 0x10, 0x01, 0x3a, 0x01,
- 0x7a, 0x01, 0xa9, 0x01, 0xf2, 0x02, 0x2d, 0x02, 0x2e);
- mipi_dsi_dcs_write_seq(dsi, 0xb2, 0x02, 0x64, 0x02, 0xa3, 0x02, 0xca, 0x03,
- 0x00, 0x03, 0x1e, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
- mipi_dsi_dcs_write_seq(dsi, 0xb3, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
- 0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0xb4, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
- 0x71, 0x00, 0x90, 0x00, 0xa7, 0x00, 0xbf, 0x00, 0xd1);
- mipi_dsi_dcs_write_seq(dsi, 0xb5, 0x00, 0xe2, 0x01, 0x1a, 0x01, 0x43, 0x01,
- 0x83, 0x01, 0xb2, 0x01, 0xfa, 0x02, 0x34, 0x02, 0x36);
- mipi_dsi_dcs_write_seq(dsi, 0xb6, 0x02, 0x6b, 0x02, 0xa8, 0x02, 0xd0, 0x03,
- 0x03, 0x03, 0x21, 0x03, 0x4d, 0x03, 0x5b, 0x03, 0x6b);
- mipi_dsi_dcs_write_seq(dsi, 0xb7, 0x03, 0x7e, 0x03, 0x94, 0x03, 0xac, 0x03,
- 0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0xb8, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
- 0x72, 0x00, 0x92, 0x00, 0xa8, 0x00, 0xbf, 0x00, 0xd1);
- mipi_dsi_dcs_write_seq(dsi, 0xb9, 0x00, 0xe2, 0x01, 0x18, 0x01, 0x42, 0x01,
- 0x81, 0x01, 0xaf, 0x01, 0xf5, 0x02, 0x2f, 0x02, 0x31);
- mipi_dsi_dcs_write_seq(dsi, 0xba, 0x02, 0x68, 0x02, 0xa6, 0x02, 0xcd, 0x03,
- 0x01, 0x03, 0x1f, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
- mipi_dsi_dcs_write_seq(dsi, 0xbb, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
- 0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
- mipi_dsi_dcs_write_seq(dsi, 0xff, 0x2c);
- mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
- mipi_dsi_dcs_write_seq(dsi, 0x61, 0x1f);
- mipi_dsi_dcs_write_seq(dsi, 0x62, 0x1f);
- mipi_dsi_dcs_write_seq(dsi, 0x7e, 0x03);
- mipi_dsi_dcs_write_seq(dsi, 0x6a, 0x14);
- mipi_dsi_dcs_write_seq(dsi, 0x6b, 0x36);
- mipi_dsi_dcs_write_seq(dsi, 0x6c, 0x36);
- mipi_dsi_dcs_write_seq(dsi, 0x6d, 0x36);
- mipi_dsi_dcs_write_seq(dsi, 0x53, 0x04);
- mipi_dsi_dcs_write_seq(dsi, 0x54, 0x04);
- mipi_dsi_dcs_write_seq(dsi, 0x55, 0x04);
- mipi_dsi_dcs_write_seq(dsi, 0x56, 0x0f);
- mipi_dsi_dcs_write_seq(dsi, 0x58, 0x0f);
- mipi_dsi_dcs_write_seq(dsi, 0x59, 0x0f);
- mipi_dsi_dcs_write_seq(dsi, 0xff, 0xf0);
- mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
- mipi_dsi_dcs_write_seq(dsi, 0x5a, 0x00);
-
- mipi_dsi_dcs_write_seq(dsi, 0xff, 0x10);
- mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
- mipi_dsi_dcs_write_seq(dsi, 0x51, 0xff);
- mipi_dsi_dcs_write_seq(dsi, 0x53, 0x24);
- mipi_dsi_dcs_write_seq(dsi, 0x55, 0x01);
-
- return 0;
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0x10);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xb0, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xc0, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xc1, 0x89, 0x28, 0x00, 0x08, 0x00, 0xaa, 0x02,
+ 0x0e, 0x00, 0x2b, 0x00, 0x07, 0x0d, 0xb7, 0x0c, 0xb7);
+
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xc2, 0x1b, 0xa0);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0x20);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x01, 0x66);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x06, 0x40);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x07, 0x38);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x2f, 0x83);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x69, 0x91);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x95, 0xd1);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x96, 0xd1);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xf2, 0x64);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xf3, 0x54);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xf4, 0x64);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xf5, 0x54);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xf6, 0x64);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xf7, 0x54);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xf8, 0x64);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xf9, 0x54);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0x24);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x01, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x03, 0x0c);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x05, 0x1d);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x08, 0x2f);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x09, 0x2e);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x0a, 0x2d);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x0b, 0x2c);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x11, 0x17);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x12, 0x13);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x13, 0x15);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x15, 0x14);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x16, 0x16);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x17, 0x18);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x1b, 0x01);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x1d, 0x1d);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x20, 0x2f);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x21, 0x2e);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x22, 0x2d);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x23, 0x2c);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x29, 0x17);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x2a, 0x13);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x2b, 0x15);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x2f, 0x14);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x30, 0x16);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x31, 0x18);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x32, 0x04);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x34, 0x10);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x35, 0x1f);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x36, 0x1f);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x4d, 0x14);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x4e, 0x36);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x4f, 0x36);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x53, 0x36);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x71, 0x30);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x79, 0x11);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x7a, 0x82);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x7b, 0x8f);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x7d, 0x04);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x80, 0x04);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x81, 0x04);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x82, 0x13);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x84, 0x31);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x85, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x86, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x87, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x90, 0x13);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x92, 0x31);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x93, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x94, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x95, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x9c, 0xf4);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x9d, 0x01);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xa0, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xa2, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xa3, 0x02);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xa4, 0x04);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xa5, 0x04);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xc6, 0xc0);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xc9, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xd9, 0x80);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xe9, 0x02);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0x25);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x18, 0x22);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x19, 0xe4);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x21, 0x40);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x66, 0xd8);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x68, 0x50);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x69, 0x10);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x6b, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x6d, 0x0d);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x6e, 0x48);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x72, 0x41);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x73, 0x4a);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x74, 0xd0);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x77, 0x62);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x79, 0x7e);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x7d, 0x03);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x7e, 0x15);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x7f, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x84, 0x4d);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xcf, 0x80);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xd6, 0x80);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xd7, 0x80);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xef, 0x20);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xf0, 0x84);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0x26);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x81, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x83, 0x01);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x84, 0x03);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x85, 0x01);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x86, 0x03);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x87, 0x01);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x88, 0x05);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x8a, 0x1a);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x8b, 0x11);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x8c, 0x24);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x8e, 0x42);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x8f, 0x11);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x90, 0x11);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x91, 0x11);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x9a, 0x80);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x9b, 0x04);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x9c, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x9d, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x9e, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0x27);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x01, 0x68);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x20, 0x81);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x21, 0x6a);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x25, 0x81);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x26, 0x94);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x6e, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x6f, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x70, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x71, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x72, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x75, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x76, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x77, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x7d, 0x09);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x7e, 0x67);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x80, 0x23);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x82, 0x09);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x83, 0x67);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x88, 0x01);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x89, 0x10);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xa5, 0x10);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xa6, 0x23);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xa7, 0x01);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xb6, 0x40);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xe5, 0x02);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xe6, 0xd3);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xeb, 0x03);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xec, 0x28);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0x2a);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x00, 0x91);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x03, 0x20);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x07, 0x50);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x0a, 0x70);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x0c, 0x04);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x0d, 0x40);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x0f, 0x01);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x11, 0xe0);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x15, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x16, 0xa4);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x19, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x1a, 0x78);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x1b, 0x23);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x1d, 0x36);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x1e, 0x3e);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x1f, 0x3e);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x20, 0x3e);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x28, 0xfd);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x29, 0x12);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x2a, 0xe1);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x2d, 0x0a);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x30, 0x49);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x33, 0x96);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x34, 0xff);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x35, 0x40);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x36, 0xde);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x37, 0xf9);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x38, 0x45);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x39, 0xd9);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x3a, 0x49);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x4a, 0xf0);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x7a, 0x09);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x7b, 0x40);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x7f, 0xf0);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x83, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x84, 0xa4);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x87, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x88, 0x78);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x89, 0x23);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x8b, 0x36);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x8c, 0x7d);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x8d, 0x7d);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x8e, 0x7d);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0x20);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xb0, 0x00, 0x00, 0x00, 0x17, 0x00, 0x49, 0x00,
+ 0x6a, 0x00, 0x89, 0x00, 0x9f, 0x00, 0xb6, 0x00, 0xc8);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xb1, 0x00, 0xd9, 0x01, 0x10, 0x01, 0x3a, 0x01,
+ 0x7a, 0x01, 0xa9, 0x01, 0xf2, 0x02, 0x2d, 0x02, 0x2e);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xb2, 0x02, 0x64, 0x02, 0xa3, 0x02, 0xca, 0x03,
+ 0x00, 0x03, 0x1e, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xb3, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
+ 0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xb4, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
+ 0x71, 0x00, 0x90, 0x00, 0xa7, 0x00, 0xbf, 0x00, 0xd1);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xb5, 0x00, 0xe2, 0x01, 0x1a, 0x01, 0x43, 0x01,
+ 0x83, 0x01, 0xb2, 0x01, 0xfa, 0x02, 0x34, 0x02, 0x36);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xb6, 0x02, 0x6b, 0x02, 0xa8, 0x02, 0xd0, 0x03,
+ 0x03, 0x03, 0x21, 0x03, 0x4d, 0x03, 0x5b, 0x03, 0x6b);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xb7, 0x03, 0x7e, 0x03, 0x94, 0x03, 0xac, 0x03,
+ 0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xb8, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
+ 0x72, 0x00, 0x92, 0x00, 0xa8, 0x00, 0xbf, 0x00, 0xd1);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xb9, 0x00, 0xe2, 0x01, 0x18, 0x01, 0x42, 0x01,
+ 0x81, 0x01, 0xaf, 0x01, 0xf5, 0x02, 0x2f, 0x02, 0x31);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xba, 0x02, 0x68, 0x02, 0xa6, 0x02, 0xcd, 0x03,
+ 0x01, 0x03, 0x1f, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xbb, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
+ 0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0x21);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xb0, 0x00, 0x00, 0x00, 0x17, 0x00, 0x49, 0x00,
+ 0x6a, 0x00, 0x89, 0x00, 0x9f, 0x00, 0xb6, 0x00, 0xc8);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xb1, 0x00, 0xd9, 0x01, 0x10, 0x01, 0x3a, 0x01,
+ 0x7a, 0x01, 0xa9, 0x01, 0xf2, 0x02, 0x2d, 0x02, 0x2e);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xb2, 0x02, 0x64, 0x02, 0xa3, 0x02, 0xca, 0x03,
+ 0x00, 0x03, 0x1e, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xb3, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
+ 0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xb4, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
+ 0x71, 0x00, 0x90, 0x00, 0xa7, 0x00, 0xbf, 0x00, 0xd1);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xb5, 0x00, 0xe2, 0x01, 0x1a, 0x01, 0x43, 0x01,
+ 0x83, 0x01, 0xb2, 0x01, 0xfa, 0x02, 0x34, 0x02, 0x36);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xb6, 0x02, 0x6b, 0x02, 0xa8, 0x02, 0xd0, 0x03,
+ 0x03, 0x03, 0x21, 0x03, 0x4d, 0x03, 0x5b, 0x03, 0x6b);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xb7, 0x03, 0x7e, 0x03, 0x94, 0x03, 0xac, 0x03,
+ 0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xb8, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
+ 0x72, 0x00, 0x92, 0x00, 0xa8, 0x00, 0xbf, 0x00, 0xd1);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xb9, 0x00, 0xe2, 0x01, 0x18, 0x01, 0x42, 0x01,
+ 0x81, 0x01, 0xaf, 0x01, 0xf5, 0x02, 0x2f, 0x02, 0x31);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xba, 0x02, 0x68, 0x02, 0xa6, 0x02, 0xcd, 0x03,
+ 0x01, 0x03, 0x1f, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xbb, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
+ 0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0x2c);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x61, 0x1f);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x62, 0x1f);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x7e, 0x03);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x6a, 0x14);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x6b, 0x36);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x6c, 0x36);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x6d, 0x36);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x53, 0x04);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x54, 0x04);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x55, 0x04);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x56, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x58, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x59, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0xf0);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x5a, 0x00);
+
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0x10);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0xfb, 0x01);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x51, 0xff);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x53, 0x24);
+ mipi_dsi_dcs_write_seq_multi(ctx, 0x55, 0x01);
}
static int nt36672e_power_on(struct nt36672e_panel *ctx)
@@ -379,68 +377,46 @@ static int nt36672e_power_off(struct nt36672e_panel *ctx)
return ret;
}
-static int nt36672e_on(struct nt36672e_panel *ctx)
+static int nt36672e_on(struct nt36672e_panel *nt36672e)
{
- struct mipi_dsi_device *dsi = ctx->dsi;
- const struct panel_desc *desc = ctx->desc;
- int ret = 0;
+ struct mipi_dsi_multi_context ctx = { .dsi = nt36672e->dsi };
+ const struct panel_desc *desc = nt36672e->desc;
- dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+ nt36672e->dsi->mode_flags |= MIPI_DSI_MODE_LPM;
- if (desc->init_sequence) {
- ret = desc->init_sequence(dsi);
- if (ret < 0) {
- dev_err(&dsi->dev, "panel init sequence failed: %d\n", ret);
- return ret;
- }
- }
+ if (desc->init_sequence)
+ desc->init_sequence(&ctx);
- ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
- if (ret < 0) {
- dev_err(&dsi->dev, "Failed to exit sleep mode: %d\n", ret);
- return ret;
- }
- msleep(120);
+ mipi_dsi_dcs_exit_sleep_mode_multi(&ctx);
+ mipi_dsi_msleep(&ctx, 120);
- ret = mipi_dsi_dcs_set_display_on(dsi);
- if (ret < 0) {
- dev_err(&dsi->dev, "Failed to set display on: %d\n", ret);
- return ret;
- }
- msleep(100);
+ mipi_dsi_dcs_set_display_on_multi(&ctx);
- return 0;
+ mipi_dsi_msleep(&ctx, 100);
+
+ return ctx.accum_err;
}
-static int nt36672e_off(struct nt36672e_panel *ctx)
+static int nt36672e_off(struct nt36672e_panel *panel)
{
- struct mipi_dsi_device *dsi = ctx->dsi;
- int ret = 0;
+ struct mipi_dsi_multi_context ctx = { .dsi = panel->dsi };
- dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
+ panel->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
- ret = mipi_dsi_dcs_set_display_off(dsi);
- if (ret < 0) {
- dev_err(&dsi->dev, "Failed to set display off: %d\n", ret);
- return ret;
- }
- msleep(20);
+ mipi_dsi_dcs_set_display_off_multi(&ctx);
+ mipi_dsi_msleep(&ctx, 20);
- ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
- if (ret < 0) {
- dev_err(&dsi->dev, "Failed to enter sleep mode: %d\n", ret);
- return ret;
- }
- msleep(60);
+ mipi_dsi_dcs_enter_sleep_mode_multi(&ctx);
+ mipi_dsi_msleep(&ctx, 60);
- return 0;
+ return ctx.accum_err;
}
static int nt36672e_panel_prepare(struct drm_panel *panel)
{
struct nt36672e_panel *ctx = to_nt36672e_panel(panel);
struct mipi_dsi_device *dsi = ctx->dsi;
- int ret = 0;
+ int ret;
ret = nt36672e_power_on(ctx);
if (ret < 0)
@@ -448,7 +424,6 @@ static int nt36672e_panel_prepare(struct drm_panel *panel)
ret = nt36672e_on(ctx);
if (ret < 0) {
- dev_err(&dsi->dev, "Failed to initialize panel: %d\n", ret);
if (nt36672e_power_off(ctx))
dev_err(&dsi->dev, "power off failed\n");
return ret;
@@ -461,11 +436,9 @@ static int nt36672e_panel_unprepare(struct drm_panel *panel)
{
struct nt36672e_panel *ctx = to_nt36672e_panel(panel);
struct mipi_dsi_device *dsi = ctx->dsi;
- int ret = 0;
+ int ret;
- ret = nt36672e_off(ctx);
- if (ret < 0)
- dev_err(&dsi->dev, "Failed to un-initialize panel: %d\n", ret);
+ nt36672e_off(ctx);
ret = nt36672e_power_off(ctx);
if (ret < 0)
diff --git a/drivers/gpu/drm/panel/panel-novatek-nt39016.c b/drivers/gpu/drm/panel/panel-novatek-nt39016.c
index 059260262b5a..9fa7654e2b67 100644
--- a/drivers/gpu/drm/panel/panel-novatek-nt39016.c
+++ b/drivers/gpu/drm/panel/panel-novatek-nt39016.c
@@ -356,4 +356,5 @@ module_spi_driver(nt39016_driver);
MODULE_AUTHOR("Maarten ter Huurne <maarten@treewalker.org>");
MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
+MODULE_DESCRIPTION("Novatek NT39016 TFT LCD panel driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c b/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c
index 4819ada69482..94ae8c8270b8 100644
--- a/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c
+++ b/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c
@@ -64,9 +64,6 @@ struct lcd_olinuxino {
struct i2c_client *client;
struct mutex mutex;
- bool prepared;
- bool enabled;
-
struct regulator *supply;
struct gpio_desc *enable_gpio;
@@ -78,30 +75,13 @@ static inline struct lcd_olinuxino *to_lcd_olinuxino(struct drm_panel *panel)
return container_of(panel, struct lcd_olinuxino, panel);
}
-static int lcd_olinuxino_disable(struct drm_panel *panel)
-{
- struct lcd_olinuxino *lcd = to_lcd_olinuxino(panel);
-
- if (!lcd->enabled)
- return 0;
-
- lcd->enabled = false;
-
- return 0;
-}
-
static int lcd_olinuxino_unprepare(struct drm_panel *panel)
{
struct lcd_olinuxino *lcd = to_lcd_olinuxino(panel);
- if (!lcd->prepared)
- return 0;
-
gpiod_set_value_cansleep(lcd->enable_gpio, 0);
regulator_disable(lcd->supply);
- lcd->prepared = false;
-
return 0;
}
@@ -110,27 +90,11 @@ static int lcd_olinuxino_prepare(struct drm_panel *panel)
struct lcd_olinuxino *lcd = to_lcd_olinuxino(panel);
int ret;
- if (lcd->prepared)
- return 0;
-
ret = regulator_enable(lcd->supply);
if (ret < 0)
return ret;
gpiod_set_value_cansleep(lcd->enable_gpio, 1);
- lcd->prepared = true;
-
- return 0;
-}
-
-static int lcd_olinuxino_enable(struct drm_panel *panel)
-{
- struct lcd_olinuxino *lcd = to_lcd_olinuxino(panel);
-
- if (lcd->enabled)
- return 0;
-
- lcd->enabled = true;
return 0;
}
@@ -195,10 +159,8 @@ static int lcd_olinuxino_get_modes(struct drm_panel *panel,
}
static const struct drm_panel_funcs lcd_olinuxino_funcs = {
- .disable = lcd_olinuxino_disable,
.unprepare = lcd_olinuxino_unprepare,
.prepare = lcd_olinuxino_prepare,
- .enable = lcd_olinuxino_enable,
.get_modes = lcd_olinuxino_get_modes,
};
@@ -264,9 +226,6 @@ static int lcd_olinuxino_probe(struct i2c_client *client)
lcd->eeprom.num_modes = 4;
}
- lcd->enabled = false;
- lcd->prepared = false;
-
lcd->supply = devm_regulator_get(dev, "power");
if (IS_ERR(lcd->supply))
return PTR_ERR(lcd->supply);
@@ -292,9 +251,6 @@ static void lcd_olinuxino_remove(struct i2c_client *client)
struct lcd_olinuxino *panel = i2c_get_clientdata(client);
drm_panel_remove(&panel->panel);
-
- drm_panel_disable(&panel->panel);
- drm_panel_unprepare(&panel->panel);
}
static const struct of_device_id lcd_olinuxino_of_ids[] = {
diff --git a/drivers/gpu/drm/panel/panel-orisetech-ota5601a.c b/drivers/gpu/drm/panel/panel-orisetech-ota5601a.c
index c415dacf1816..fc87f61d4400 100644
--- a/drivers/gpu/drm/panel/panel-orisetech-ota5601a.c
+++ b/drivers/gpu/drm/panel/panel-orisetech-ota5601a.c
@@ -360,4 +360,5 @@ static struct spi_driver ota5601a_driver = {
module_spi_driver(ota5601a_driver);
MODULE_AUTHOR("Christophe Branchereau <cbranchereau@gmail.com>");
+MODULE_DESCRIPTION("Orisetech OTA5601A TFT LCD panel driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c b/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c
index 493e0504f6f7..dbea84f51514 100644
--- a/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c
+++ b/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c
@@ -21,9 +21,6 @@ struct osd101t2587_panel {
struct regulator *supply;
- bool prepared;
- bool enabled;
-
const struct drm_display_mode *default_mode;
};
@@ -37,13 +34,8 @@ static int osd101t2587_panel_disable(struct drm_panel *panel)
struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);
int ret;
- if (!osd101t2587->enabled)
- return 0;
-
ret = mipi_dsi_shutdown_peripheral(osd101t2587->dsi);
- osd101t2587->enabled = false;
-
return ret;
}
@@ -51,11 +43,7 @@ static int osd101t2587_panel_unprepare(struct drm_panel *panel)
{
struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);
- if (!osd101t2587->prepared)
- return 0;
-
regulator_disable(osd101t2587->supply);
- osd101t2587->prepared = false;
return 0;
}
@@ -63,16 +51,8 @@ static int osd101t2587_panel_unprepare(struct drm_panel *panel)
static int osd101t2587_panel_prepare(struct drm_panel *panel)
{
struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);
- int ret;
- if (osd101t2587->prepared)
- return 0;
-
- ret = regulator_enable(osd101t2587->supply);
- if (!ret)
- osd101t2587->prepared = true;
-
- return ret;
+ return regulator_enable(osd101t2587->supply);
}
static int osd101t2587_panel_enable(struct drm_panel *panel)
@@ -80,15 +60,10 @@ static int osd101t2587_panel_enable(struct drm_panel *panel)
struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);
int ret;
- if (osd101t2587->enabled)
- return 0;
-
ret = mipi_dsi_turn_on_peripheral(osd101t2587->dsi);
if (ret)
return ret;
- osd101t2587->enabled = true;
-
return ret;
}
@@ -211,11 +186,6 @@ static void osd101t2587_panel_remove(struct mipi_dsi_device *dsi)
struct osd101t2587_panel *osd101t2587 = mipi_dsi_get_drvdata(dsi);
int ret;
- ret = drm_panel_disable(&osd101t2587->base);
- if (ret < 0)
- dev_warn(&dsi->dev, "failed to disable panel: %d\n", ret);
-
- drm_panel_unprepare(&osd101t2587->base);
drm_panel_remove(&osd101t2587->base);
ret = mipi_dsi_detach(dsi);
@@ -223,14 +193,6 @@ static void osd101t2587_panel_remove(struct mipi_dsi_device *dsi)
dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret);
}
-static void osd101t2587_panel_shutdown(struct mipi_dsi_device *dsi)
-{
- struct osd101t2587_panel *osd101t2587 = mipi_dsi_get_drvdata(dsi);
-
- drm_panel_disable(&osd101t2587->base);
- drm_panel_unprepare(&osd101t2587->base);
-}
-
static struct mipi_dsi_driver osd101t2587_panel_driver = {
.driver = {
.name = "panel-osd-osd101t2587-53ts",
@@ -238,7 +200,6 @@ static struct mipi_dsi_driver osd101t2587_panel_driver = {
},
.probe = osd101t2587_panel_probe,
.remove = osd101t2587_panel_remove,
- .shutdown = osd101t2587_panel_shutdown,
};
module_mipi_dsi_driver(osd101t2587_panel_driver);
diff --git a/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c b/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c
index 8ba6d8287938..d1c5c9bc3c56 100644
--- a/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c
+++ b/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c
@@ -32,9 +32,6 @@ struct wuxga_nt_panel {
struct regulator *supply;
- bool prepared;
- bool enabled;
-
ktime_t earliest_wake;
const struct drm_display_mode *mode;
@@ -53,28 +50,16 @@ static int wuxga_nt_panel_on(struct wuxga_nt_panel *wuxga_nt)
static int wuxga_nt_panel_disable(struct drm_panel *panel)
{
struct wuxga_nt_panel *wuxga_nt = to_wuxga_nt_panel(panel);
- int mipi_ret, bl_ret = 0;
-
- if (!wuxga_nt->enabled)
- return 0;
-
- mipi_ret = mipi_dsi_shutdown_peripheral(wuxga_nt->dsi);
- wuxga_nt->enabled = false;
-
- return mipi_ret ? mipi_ret : bl_ret;
+ return mipi_dsi_shutdown_peripheral(wuxga_nt->dsi);
}
static int wuxga_nt_panel_unprepare(struct drm_panel *panel)
{
struct wuxga_nt_panel *wuxga_nt = to_wuxga_nt_panel(panel);
- if (!wuxga_nt->prepared)
- return 0;
-
regulator_disable(wuxga_nt->supply);
wuxga_nt->earliest_wake = ktime_add_ms(ktime_get_real(), MIN_POFF_MS);
- wuxga_nt->prepared = false;
return 0;
}
@@ -85,9 +70,6 @@ static int wuxga_nt_panel_prepare(struct drm_panel *panel)
int ret;
s64 enablewait;
- if (wuxga_nt->prepared)
- return 0;
-
/*
* If the user re-enabled the panel before the required off-time then
* we need to wait the remaining period before re-enabling regulator
@@ -117,8 +99,6 @@ static int wuxga_nt_panel_prepare(struct drm_panel *panel)
goto poweroff;
}
- wuxga_nt->prepared = true;
-
return 0;
poweroff:
@@ -127,18 +107,6 @@ poweroff:
return ret;
}
-static int wuxga_nt_panel_enable(struct drm_panel *panel)
-{
- struct wuxga_nt_panel *wuxga_nt = to_wuxga_nt_panel(panel);
-
- if (wuxga_nt->enabled)
- return 0;
-
- wuxga_nt->enabled = true;
-
- return 0;
-}
-
static const struct drm_display_mode default_mode = {
.clock = 164402,
.hdisplay = 1920,
@@ -178,7 +146,6 @@ static const struct drm_panel_funcs wuxga_nt_panel_funcs = {
.disable = wuxga_nt_panel_disable,
.unprepare = wuxga_nt_panel_unprepare,
.prepare = wuxga_nt_panel_prepare,
- .enable = wuxga_nt_panel_enable,
.get_modes = wuxga_nt_panel_get_modes,
};
@@ -255,10 +222,6 @@ static void wuxga_nt_panel_remove(struct mipi_dsi_device *dsi)
struct wuxga_nt_panel *wuxga_nt = mipi_dsi_get_drvdata(dsi);
int ret;
- ret = drm_panel_disable(&wuxga_nt->base);
- if (ret < 0)
- dev_err(&dsi->dev, "failed to disable panel: %d\n", ret);
-
ret = mipi_dsi_detach(dsi);
if (ret < 0)
dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret);
@@ -266,13 +229,6 @@ static void wuxga_nt_panel_remove(struct mipi_dsi_device *dsi)
wuxga_nt_panel_del(wuxga_nt);
}
-static void wuxga_nt_panel_shutdown(struct mipi_dsi_device *dsi)
-{
- struct wuxga_nt_panel *wuxga_nt = mipi_dsi_get_drvdata(dsi);
-
- drm_panel_disable(&wuxga_nt->base);
-}
-
static struct mipi_dsi_driver wuxga_nt_panel_driver = {
.driver = {
.name = "panel-panasonic-vvx10f034n00",
@@ -280,7 +236,6 @@ static struct mipi_dsi_driver wuxga_nt_panel_driver = {
},
.probe = wuxga_nt_panel_probe,
.remove = wuxga_nt_panel_remove,
- .shutdown = wuxga_nt_panel_shutdown,
};
module_mipi_dsi_driver(wuxga_nt_panel_driver);
diff --git a/drivers/gpu/drm/panel/panel-raydium-rm67191.c b/drivers/gpu/drm/panel/panel-raydium-rm67191.c
index dbb1ed4efbed..b2029e035635 100644
--- a/drivers/gpu/drm/panel/panel-raydium-rm67191.c
+++ b/drivers/gpu/drm/panel/panel-raydium-rm67191.c
@@ -205,7 +205,6 @@ struct rad_panel {
unsigned int num_supplies;
bool prepared;
- bool enabled;
};
static const struct drm_display_mode default_mode = {
@@ -267,9 +266,6 @@ static int rad_panel_prepare(struct drm_panel *panel)
struct rad_panel *rad = to_rad_panel(panel);
int ret;
- if (rad->prepared)
- return 0;
-
ret = regulator_bulk_enable(rad->num_supplies, rad->supplies);
if (ret)
return ret;
@@ -291,9 +287,6 @@ static int rad_panel_unprepare(struct drm_panel *panel)
struct rad_panel *rad = to_rad_panel(panel);
int ret;
- if (!rad->prepared)
- return 0;
-
/*
* Right after asserting the reset, we need to release it, so that the
* touch driver can have an active connection with the touch controller
@@ -322,9 +315,6 @@ static int rad_panel_enable(struct drm_panel *panel)
int color_format = color_format_from_dsi_format(dsi->format);
int ret;
- if (rad->enabled)
- return 0;
-
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
ret = rad_panel_push_cmd_list(dsi);
@@ -389,8 +379,6 @@ static int rad_panel_enable(struct drm_panel *panel)
backlight_enable(rad->backlight);
- rad->enabled = true;
-
return 0;
fail:
@@ -406,9 +394,6 @@ static int rad_panel_disable(struct drm_panel *panel)
struct device *dev = &dsi->dev;
int ret;
- if (!rad->enabled)
- return 0;
-
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
backlight_disable(rad->backlight);
@@ -429,8 +414,6 @@ static int rad_panel_disable(struct drm_panel *panel)
return ret;
}
- rad->enabled = false;
-
return 0;
}
@@ -629,14 +612,6 @@ static void rad_panel_remove(struct mipi_dsi_device *dsi)
drm_panel_remove(&rad->panel);
}
-static void rad_panel_shutdown(struct mipi_dsi_device *dsi)
-{
- struct rad_panel *rad = mipi_dsi_get_drvdata(dsi);
-
- rad_panel_disable(&rad->panel);
- rad_panel_unprepare(&rad->panel);
-}
-
static const struct of_device_id rad_of_match[] = {
{ .compatible = "raydium,rm67191", },
{ /* sentinel */ }
@@ -650,7 +625,6 @@ static struct mipi_dsi_driver rad_panel_driver = {
},
.probe = rad_panel_probe,
.remove = rad_panel_remove,
- .shutdown = rad_panel_shutdown,
};
module_mipi_dsi_driver(rad_panel_driver);
diff --git a/drivers/gpu/drm/panel/panel-raydium-rm692e5.c b/drivers/gpu/drm/panel/panel-raydium-rm692e5.c
index a613ba5b816c..21d97f6b8a2f 100644
--- a/drivers/gpu/drm/panel/panel-raydium-rm692e5.c
+++ b/drivers/gpu/drm/panel/panel-raydium-rm692e5.c
@@ -23,7 +23,6 @@ struct rm692e5_panel {
struct drm_dsc_config dsc;
struct regulator_bulk_data supplies[3];
struct gpio_desc *reset_gpio;
- bool prepared;
};
static inline struct rm692e5_panel *to_rm692e5_panel(struct drm_panel *panel)
@@ -171,9 +170,6 @@ static int rm692e5_prepare(struct drm_panel *panel)
struct device *dev = &ctx->dsi->dev;
int ret;
- if (ctx->prepared)
- return 0;
-
ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
if (ret < 0) {
dev_err(dev, "Failed to enable regulators: %d\n", ret);
@@ -213,8 +209,6 @@ static int rm692e5_prepare(struct drm_panel *panel)
mipi_dsi_generic_write_seq(ctx->dsi, 0xfe, 0x00);
- ctx->prepared = true;
-
return 0;
}
@@ -222,13 +216,9 @@ static int rm692e5_unprepare(struct drm_panel *panel)
{
struct rm692e5_panel *ctx = to_rm692e5_panel(panel);
- if (!ctx->prepared)
- return 0;
-
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
- ctx->prepared = false;
return 0;
}
diff --git a/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c b/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c
index a9f0d214a900..9a482a744b8c 100644
--- a/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c
+++ b/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c
@@ -25,8 +25,6 @@
struct atana33xc20_panel {
struct drm_panel base;
- bool prepared;
- bool enabled;
bool el3_was_on;
bool no_hpd;
@@ -143,13 +141,8 @@ static int atana33xc20_disable(struct drm_panel *panel)
{
struct atana33xc20_panel *p = to_atana33xc20(panel);
- /* Disabling when already disabled is a no-op */
- if (!p->enabled)
- return 0;
-
gpiod_set_value_cansleep(p->el_on3_gpio, 0);
p->el_on3_off_time = ktime_get_boottime();
- p->enabled = false;
/*
* Keep track of the fact that EL_ON3 was on but we haven't power
@@ -173,10 +166,6 @@ static int atana33xc20_enable(struct drm_panel *panel)
{
struct atana33xc20_panel *p = to_atana33xc20(panel);
- /* Enabling when already enabled is a no-op */
- if (p->enabled)
- return 0;
-
/*
* Once EL_ON3 drops we absolutely need a power cycle before the next
* enable or the backlight will never come on again. The code ensures
@@ -195,20 +184,14 @@ static int atana33xc20_enable(struct drm_panel *panel)
atana33xc20_wait(p->powered_on_time, 400);
gpiod_set_value_cansleep(p->el_on3_gpio, 1);
- p->enabled = true;
return 0;
}
static int atana33xc20_unprepare(struct drm_panel *panel)
{
- struct atana33xc20_panel *p = to_atana33xc20(panel);
int ret;
- /* Unpreparing when already unprepared is a no-op */
- if (!p->prepared)
- return 0;
-
/*
* Purposely do a put_sync, don't use autosuspend. The panel's tcon
* seems to sometimes crash when you stop giving it data and this is
@@ -220,26 +203,19 @@ static int atana33xc20_unprepare(struct drm_panel *panel)
ret = pm_runtime_put_sync_suspend(panel->dev);
if (ret < 0)
return ret;
- p->prepared = false;
return 0;
}
static int atana33xc20_prepare(struct drm_panel *panel)
{
- struct atana33xc20_panel *p = to_atana33xc20(panel);
int ret;
- /* Preparing when already prepared is a no-op */
- if (p->prepared)
- return 0;
-
ret = pm_runtime_get_sync(panel->dev);
if (ret < 0) {
pm_runtime_put_autosuspend(panel->dev);
return ret;
}
- p->prepared = true;
return 0;
}
@@ -351,21 +327,10 @@ static void atana33xc20_remove(struct dp_aux_ep_device *aux_ep)
struct atana33xc20_panel *panel = dev_get_drvdata(dev);
drm_panel_remove(&panel->base);
- drm_panel_disable(&panel->base);
- drm_panel_unprepare(&panel->base);
drm_edid_free(panel->drm_edid);
}
-static void atana33xc20_shutdown(struct dp_aux_ep_device *aux_ep)
-{
- struct device *dev = &aux_ep->dev;
- struct atana33xc20_panel *panel = dev_get_drvdata(dev);
-
- drm_panel_disable(&panel->base);
- drm_panel_unprepare(&panel->base);
-}
-
static const struct of_device_id atana33xc20_dt_match[] = {
{ .compatible = "samsung,atna33xc20", },
{ /* sentinal */ }
@@ -386,7 +351,6 @@ static struct dp_aux_ep_driver atana33xc20_driver = {
},
.probe = atana33xc20_probe,
.remove = atana33xc20_remove,
- .shutdown = atana33xc20_shutdown,
};
static int __init atana33xc20_init(void)
diff --git a/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c b/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c
index 658c7c040570..8a3fe531c641 100644
--- a/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c
+++ b/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c
@@ -44,8 +44,6 @@ struct seiko_panel_desc {
struct seiko_panel {
struct drm_panel base;
- bool prepared;
- bool enabled;
const struct seiko_panel_desc *desc;
struct regulator *dvdd;
struct regulator *avdd;
@@ -122,25 +120,10 @@ static int seiko_panel_get_fixed_modes(struct seiko_panel *panel,
return num;
}
-static int seiko_panel_disable(struct drm_panel *panel)
-{
- struct seiko_panel *p = to_seiko_panel(panel);
-
- if (!p->enabled)
- return 0;
-
- p->enabled = false;
-
- return 0;
-}
-
static int seiko_panel_unprepare(struct drm_panel *panel)
{
struct seiko_panel *p = to_seiko_panel(panel);
- if (!p->prepared)
- return 0;
-
gpiod_set_value_cansleep(p->enable_gpio, 0);
regulator_disable(p->avdd);
@@ -150,8 +133,6 @@ static int seiko_panel_unprepare(struct drm_panel *panel)
regulator_disable(p->dvdd);
- p->prepared = false;
-
return 0;
}
@@ -160,9 +141,6 @@ static int seiko_panel_prepare(struct drm_panel *panel)
struct seiko_panel *p = to_seiko_panel(panel);
int err;
- if (p->prepared)
- return 0;
-
err = regulator_enable(p->dvdd);
if (err < 0) {
dev_err(panel->dev, "failed to enable dvdd: %d\n", err);
@@ -180,8 +158,6 @@ static int seiko_panel_prepare(struct drm_panel *panel)
gpiod_set_value_cansleep(p->enable_gpio, 1);
- p->prepared = true;
-
return 0;
disable_dvdd:
@@ -189,18 +165,6 @@ disable_dvdd:
return err;
}
-static int seiko_panel_enable(struct drm_panel *panel)
-{
- struct seiko_panel *p = to_seiko_panel(panel);
-
- if (p->enabled)
- return 0;
-
- p->enabled = true;
-
- return 0;
-}
-
static int seiko_panel_get_modes(struct drm_panel *panel,
struct drm_connector *connector)
{
@@ -228,10 +192,8 @@ static int seiko_panel_get_timings(struct drm_panel *panel,
}
static const struct drm_panel_funcs seiko_panel_funcs = {
- .disable = seiko_panel_disable,
.unprepare = seiko_panel_unprepare,
.prepare = seiko_panel_prepare,
- .enable = seiko_panel_enable,
.get_modes = seiko_panel_get_modes,
.get_timings = seiko_panel_get_timings,
};
@@ -246,8 +208,6 @@ static int seiko_panel_probe(struct device *dev,
if (!panel)
return -ENOMEM;
- panel->enabled = false;
- panel->prepared = false;
panel->desc = desc;
panel->dvdd = devm_regulator_get(dev, "dvdd");
@@ -283,14 +243,6 @@ static void seiko_panel_remove(struct platform_device *pdev)
struct seiko_panel *panel = platform_get_drvdata(pdev);
drm_panel_remove(&panel->base);
- drm_panel_disable(&panel->base);
-}
-
-static void seiko_panel_shutdown(struct platform_device *pdev)
-{
- struct seiko_panel *panel = platform_get_drvdata(pdev);
-
- drm_panel_disable(&panel->base);
}
static const struct display_timing seiko_43wvf1g_timing = {
@@ -346,7 +298,6 @@ static struct platform_driver seiko_panel_platform_driver = {
},
.probe = seiko_panel_platform_probe,
.remove_new = seiko_panel_remove,
- .shutdown = seiko_panel_shutdown,
};
module_platform_driver(seiko_panel_platform_driver);
diff --git a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
index 14851408a5e1..edc9425bb143 100644
--- a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
+++ b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
@@ -24,9 +24,6 @@ struct sharp_panel {
struct regulator *supply;
- bool prepared;
- bool enabled;
-
const struct drm_display_mode *mode;
};
@@ -85,26 +82,11 @@ static __maybe_unused int sharp_panel_read(struct sharp_panel *sharp,
return err;
}
-static int sharp_panel_disable(struct drm_panel *panel)
-{
- struct sharp_panel *sharp = to_sharp_panel(panel);
-
- if (!sharp->enabled)
- return 0;
-
- sharp->enabled = false;
-
- return 0;
-}
-
static int sharp_panel_unprepare(struct drm_panel *panel)
{
struct sharp_panel *sharp = to_sharp_panel(panel);
int err;
- if (!sharp->prepared)
- return 0;
-
sharp_wait_frames(sharp, 4);
err = mipi_dsi_dcs_set_display_off(sharp->link1);
@@ -119,8 +101,6 @@ static int sharp_panel_unprepare(struct drm_panel *panel)
regulator_disable(sharp->supply);
- sharp->prepared = false;
-
return 0;
}
@@ -164,9 +144,6 @@ static int sharp_panel_prepare(struct drm_panel *panel)
u8 format = MIPI_DCS_PIXEL_FMT_24BIT;
int err;
- if (sharp->prepared)
- return 0;
-
err = regulator_enable(sharp->supply);
if (err < 0)
return err;
@@ -235,8 +212,6 @@ static int sharp_panel_prepare(struct drm_panel *panel)
goto poweroff;
}
- sharp->prepared = true;
-
/* wait for 6 frames before continuing */
sharp_wait_frames(sharp, 6);
@@ -247,18 +222,6 @@ poweroff:
return err;
}
-static int sharp_panel_enable(struct drm_panel *panel)
-{
- struct sharp_panel *sharp = to_sharp_panel(panel);
-
- if (sharp->enabled)
- return 0;
-
- sharp->enabled = true;
-
- return 0;
-}
-
static const struct drm_display_mode default_mode = {
.clock = 278000,
.hdisplay = 2560,
@@ -295,10 +258,8 @@ static int sharp_panel_get_modes(struct drm_panel *panel,
}
static const struct drm_panel_funcs sharp_panel_funcs = {
- .disable = sharp_panel_disable,
.unprepare = sharp_panel_unprepare,
.prepare = sharp_panel_prepare,
- .enable = sharp_panel_enable,
.get_modes = sharp_panel_get_modes,
};
@@ -396,32 +357,13 @@ static void sharp_panel_remove(struct mipi_dsi_device *dsi)
struct sharp_panel *sharp = mipi_dsi_get_drvdata(dsi);
int err;
- /* only detach from host for the DSI-LINK2 interface */
- if (!sharp) {
- mipi_dsi_detach(dsi);
- return;
- }
-
- err = drm_panel_disable(&sharp->base);
- if (err < 0)
- dev_err(&dsi->dev, "failed to disable panel: %d\n", err);
-
err = mipi_dsi_detach(dsi);
if (err < 0)
dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", err);
- sharp_panel_del(sharp);
-}
-
-static void sharp_panel_shutdown(struct mipi_dsi_device *dsi)
-{
- struct sharp_panel *sharp = mipi_dsi_get_drvdata(dsi);
-
- /* nothing to do for DSI-LINK2 */
+ /* only detach from host for the DSI-LINK2 interface */
if (!sharp)
- return;
-
- drm_panel_disable(&sharp->base);
+ sharp_panel_del(sharp);
}
static struct mipi_dsi_driver sharp_panel_driver = {
@@ -431,7 +373,6 @@ static struct mipi_dsi_driver sharp_panel_driver = {
},
.probe = sharp_panel_probe,
.remove = sharp_panel_remove,
- .shutdown = sharp_panel_shutdown,
};
module_mipi_dsi_driver(sharp_panel_driver);
diff --git a/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c b/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c
index 855e64444daa..729cbb0d8403 100644
--- a/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c
+++ b/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c
@@ -26,8 +26,6 @@ struct sharp_nt_panel {
struct regulator *supply;
struct gpio_desc *reset_gpio;
-
- bool prepared;
};
static inline struct sharp_nt_panel *to_sharp_nt_panel(struct drm_panel *panel)
@@ -99,9 +97,6 @@ static int sharp_nt_panel_unprepare(struct drm_panel *panel)
struct sharp_nt_panel *sharp_nt = to_sharp_nt_panel(panel);
int ret;
- if (!sharp_nt->prepared)
- return 0;
-
ret = sharp_nt_panel_off(sharp_nt);
if (ret < 0) {
dev_err(panel->dev, "failed to set panel off: %d\n", ret);
@@ -112,8 +107,6 @@ static int sharp_nt_panel_unprepare(struct drm_panel *panel)
if (sharp_nt->reset_gpio)
gpiod_set_value(sharp_nt->reset_gpio, 0);
- sharp_nt->prepared = false;
-
return 0;
}
@@ -122,9 +115,6 @@ static int sharp_nt_panel_prepare(struct drm_panel *panel)
struct sharp_nt_panel *sharp_nt = to_sharp_nt_panel(panel);
int ret;
- if (sharp_nt->prepared)
- return 0;
-
ret = regulator_enable(sharp_nt->supply);
if (ret < 0)
return ret;
@@ -152,8 +142,6 @@ static int sharp_nt_panel_prepare(struct drm_panel *panel)
goto poweroff;
}
- sharp_nt->prepared = true;
-
return 0;
poweroff:
@@ -279,10 +267,6 @@ static void sharp_nt_panel_remove(struct mipi_dsi_device *dsi)
struct sharp_nt_panel *sharp_nt = mipi_dsi_get_drvdata(dsi);
int ret;
- ret = drm_panel_disable(&sharp_nt->base);
- if (ret < 0)
- dev_err(&dsi->dev, "failed to disable panel: %d\n", ret);
-
ret = mipi_dsi_detach(dsi);
if (ret < 0)
dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret);
@@ -290,13 +274,6 @@ static void sharp_nt_panel_remove(struct mipi_dsi_device *dsi)
sharp_nt_panel_del(sharp_nt);
}
-static void sharp_nt_panel_shutdown(struct mipi_dsi_device *dsi)
-{
- struct sharp_nt_panel *sharp_nt = mipi_dsi_get_drvdata(dsi);
-
- drm_panel_disable(&sharp_nt->base);
-}
-
static const struct of_device_id sharp_nt_of_match[] = {
{ .compatible = "sharp,ls043t1le01-qhd", },
{ }
@@ -310,7 +287,6 @@ static struct mipi_dsi_driver sharp_nt_panel_driver = {
},
.probe = sharp_nt_panel_probe,
.remove = sharp_nt_panel_remove,
- .shutdown = sharp_nt_panel_shutdown,
};
module_mipi_dsi_driver(sharp_nt_panel_driver);
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index dcb6d0b6ced0..8345ed891f5a 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -138,9 +138,6 @@ struct panel_desc {
struct panel_simple {
struct drm_panel base;
- bool enabled;
-
- bool prepared;
ktime_t unprepared_time;
@@ -290,14 +287,9 @@ static int panel_simple_disable(struct drm_panel *panel)
{
struct panel_simple *p = to_panel_simple(panel);
- if (!p->enabled)
- return 0;
-
if (p->desc->delay.disable)
msleep(p->desc->delay.disable);
- p->enabled = false;
-
return 0;
}
@@ -317,18 +309,12 @@ static int panel_simple_suspend(struct device *dev)
static int panel_simple_unprepare(struct drm_panel *panel)
{
- struct panel_simple *p = to_panel_simple(panel);
int ret;
- /* Unpreparing when already unprepared is a no-op */
- if (!p->prepared)
- return 0;
-
pm_runtime_mark_last_busy(panel->dev);
ret = pm_runtime_put_autosuspend(panel->dev);
if (ret < 0)
return ret;
- p->prepared = false;
return 0;
}
@@ -356,21 +342,14 @@ static int panel_simple_resume(struct device *dev)
static int panel_simple_prepare(struct drm_panel *panel)
{
- struct panel_simple *p = to_panel_simple(panel);
int ret;
- /* Preparing when already prepared is a no-op */
- if (p->prepared)
- return 0;
-
ret = pm_runtime_get_sync(panel->dev);
if (ret < 0) {
pm_runtime_put_autosuspend(panel->dev);
return ret;
}
- p->prepared = true;
-
return 0;
}
@@ -378,14 +357,9 @@ static int panel_simple_enable(struct drm_panel *panel)
{
struct panel_simple *p = to_panel_simple(panel);
- if (p->enabled)
- return 0;
-
if (p->desc->delay.enable)
msleep(p->desc->delay.enable);
- p->enabled = true;
-
return 0;
}
@@ -609,7 +583,6 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
if (!panel)
return -ENOMEM;
- panel->enabled = false;
panel->desc = desc;
panel->supply = devm_regulator_get(dev, "power");
@@ -743,26 +716,39 @@ free_ddc:
return err;
}
-static void panel_simple_remove(struct device *dev)
+static void panel_simple_shutdown(struct device *dev)
{
struct panel_simple *panel = dev_get_drvdata(dev);
- drm_panel_remove(&panel->base);
+ /*
+ * NOTE: the following two calls don't really belong here. It is the
+ * responsibility of a correctly written DRM modeset driver to call
+ * drm_atomic_helper_shutdown() at shutdown time and that should
+ * cause the panel to be disabled / unprepared if needed. For now,
+ * however, we'll keep these calls due to the sheer number of
+ * different DRM modeset drivers used with panel-simple. The fact that
+ * we're calling these and _also_ the drm_atomic_helper_shutdown()
+ * will try to disable/unprepare means that we can get a warning about
+ * trying to disable/unprepare an already disabled/unprepared panel,
+ * but that's something we'll have to live with until we've confirmed
+ * that all DRM modeset drivers are properly calling
+ * drm_atomic_helper_shutdown().
+ */
drm_panel_disable(&panel->base);
drm_panel_unprepare(&panel->base);
-
- pm_runtime_dont_use_autosuspend(dev);
- pm_runtime_disable(dev);
- if (panel->ddc)
- put_device(&panel->ddc->dev);
}
-static void panel_simple_shutdown(struct device *dev)
+static void panel_simple_remove(struct device *dev)
{
struct panel_simple *panel = dev_get_drvdata(dev);
- drm_panel_disable(&panel->base);
- drm_panel_unprepare(&panel->base);
+ drm_panel_remove(&panel->base);
+ panel_simple_shutdown(dev);
+
+ pm_runtime_dont_use_autosuspend(dev);
+ pm_runtime_disable(dev);
+ if (panel->ddc)
+ put_device(&panel->ddc->dev);
}
static const struct drm_display_mode ampire_am_1280800n3tzqw_t00h_mode = {
@@ -2870,6 +2856,35 @@ static const struct panel_desc lg_lb070wv8 = {
.connector_type = DRM_MODE_CONNECTOR_LVDS,
};
+static const struct drm_display_mode lincolntech_lcd185_101ct_mode = {
+ .clock = 155127,
+ .hdisplay = 1920,
+ .hsync_start = 1920 + 128,
+ .hsync_end = 1920 + 128 + 20,
+ .htotal = 1920 + 128 + 20 + 12,
+ .vdisplay = 1200,
+ .vsync_start = 1200 + 19,
+ .vsync_end = 1200 + 19 + 4,
+ .vtotal = 1200 + 19 + 4 + 20,
+};
+
+static const struct panel_desc lincolntech_lcd185_101ct = {
+ .modes = &lincolntech_lcd185_101ct_mode,
+ .bpc = 8,
+ .num_modes = 1,
+ .size = {
+ .width = 217,
+ .height = 136,
+ },
+ .delay = {
+ .prepare = 50,
+ .disable = 50,
+ },
+ .bus_flags = DRM_BUS_FLAG_DE_HIGH,
+ .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
+ .connector_type = DRM_MODE_CONNECTOR_LVDS,
+};
+
static const struct display_timing logictechno_lt161010_2nh_timing = {
.pixelclock = { 26400000, 33300000, 46800000 },
.hactive = { 800, 800, 800 },
@@ -3026,6 +3041,64 @@ static const struct panel_desc logicpd_type_28 = {
.connector_type = DRM_MODE_CONNECTOR_DPI,
};
+static const struct drm_display_mode microtips_mf_101hiebcaf0_c_mode = {
+ .clock = 150275,
+ .hdisplay = 1920,
+ .hsync_start = 1920 + 32,
+ .hsync_end = 1920 + 32 + 52,
+ .htotal = 1920 + 32 + 52 + 24,
+ .vdisplay = 1200,
+ .vsync_start = 1200 + 24,
+ .vsync_end = 1200 + 24 + 8,
+ .vtotal = 1200 + 24 + 8 + 3,
+};
+
+static const struct panel_desc microtips_mf_101hiebcaf0_c = {
+ .modes = &microtips_mf_101hiebcaf0_c_mode,
+ .bpc = 8,
+ .num_modes = 1,
+ .size = {
+ .width = 217,
+ .height = 136,
+ },
+ .delay = {
+ .prepare = 50,
+ .disable = 50,
+ },
+ .bus_flags = DRM_BUS_FLAG_DE_HIGH,
+ .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
+ .connector_type = DRM_MODE_CONNECTOR_LVDS,
+};
+
+static const struct drm_display_mode microtips_mf_103hieb0ga0_mode = {
+ .clock = 93301,
+ .hdisplay = 1920,
+ .hsync_start = 1920 + 72,
+ .hsync_end = 1920 + 72 + 72,
+ .htotal = 1920 + 72 + 72 + 72,
+ .vdisplay = 720,
+ .vsync_start = 720 + 3,
+ .vsync_end = 720 + 3 + 3,
+ .vtotal = 720 + 3 + 3 + 2,
+};
+
+static const struct panel_desc microtips_mf_103hieb0ga0 = {
+ .modes = &microtips_mf_103hieb0ga0_mode,
+ .bpc = 8,
+ .num_modes = 1,
+ .size = {
+ .width = 244,
+ .height = 92,
+ },
+ .delay = {
+ .prepare = 50,
+ .disable = 50,
+ },
+ .bus_flags = DRM_BUS_FLAG_DE_HIGH,
+ .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
+ .connector_type = DRM_MODE_CONNECTOR_LVDS,
+};
+
static const struct drm_display_mode mitsubishi_aa070mc01_mode = {
.clock = 30400,
.hdisplay = 800,
@@ -3567,6 +3640,32 @@ static const struct panel_desc powertip_ph800480t013_idf02 = {
.connector_type = DRM_MODE_CONNECTOR_DPI,
};
+static const struct drm_display_mode primeview_pm070wl4_mode = {
+ .clock = 32000,
+ .hdisplay = 800,
+ .hsync_start = 800 + 42,
+ .hsync_end = 800 + 42 + 128,
+ .htotal = 800 + 42 + 128 + 86,
+ .vdisplay = 480,
+ .vsync_start = 480 + 10,
+ .vsync_end = 480 + 10 + 2,
+ .vtotal = 480 + 10 + 2 + 33,
+ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
+};
+
+static const struct panel_desc primeview_pm070wl4 = {
+ .modes = &primeview_pm070wl4_mode,
+ .num_modes = 1,
+ .bpc = 6,
+ .size = {
+ .width = 152,
+ .height = 91,
+ },
+ .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE,
+ .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
+ .connector_type = DRM_MODE_CONNECTOR_DPI,
+};
+
static const struct drm_display_mode qd43003c0_40_mode = {
.clock = 9000,
.hdisplay = 480,
@@ -4645,6 +4744,9 @@ static const struct of_device_id platform_of_match[] = {
.compatible = "lg,lb070wv8",
.data = &lg_lb070wv8,
}, {
+ .compatible = "lincolntech,lcd185-101ct",
+ .data = &lincolntech_lcd185_101ct,
+ }, {
.compatible = "logicpd,type28",
.data = &logicpd_type_28,
}, {
@@ -4663,6 +4765,12 @@ static const struct of_device_id platform_of_match[] = {
.compatible = "logictechno,lttd800480070-l6wh-rt",
.data = &logictechno_lttd800480070_l6wh_rt,
}, {
+ .compatible = "microtips,mf-101hiebcaf0",
+ .data = &microtips_mf_101hiebcaf0_c,
+ }, {
+ .compatible = "microtips,mf-103hieb0ga0",
+ .data = &microtips_mf_103hieb0ga0,
+ }, {
.compatible = "mitsubishi,aa070mc01-ca1",
.data = &mitsubishi_aa070mc01,
}, {
@@ -4726,6 +4834,9 @@ static const struct of_device_id platform_of_match[] = {
.compatible = "powertip,ph800480t013-idf02",
.data = &powertip_ph800480t013_idf02,
}, {
+ .compatible = "primeview,pm070wl4",
+ .data = &primeview_pm070wl4,
+ }, {
.compatible = "qiaodian,qd43003c0-40",
.data = &qd43003c0_40,
}, {
diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c b/drivers/gpu/drm/panel/panel-sitronix-st7703.c
index 7d8302cca091..77b30e045a57 100644
--- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c
+++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c
@@ -58,7 +58,6 @@ struct st7703 {
struct gpio_desc *reset_gpio;
struct regulator *vcc;
struct regulator *iovcc;
- bool prepared;
struct dentry *debugfs;
const struct st7703_panel_desc *desc;
@@ -752,13 +751,9 @@ static int st7703_unprepare(struct drm_panel *panel)
{
struct st7703 *ctx = panel_to_st7703(panel);
- if (!ctx->prepared)
- return 0;
-
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
regulator_disable(ctx->iovcc);
regulator_disable(ctx->vcc);
- ctx->prepared = false;
return 0;
}
@@ -768,9 +763,6 @@ static int st7703_prepare(struct drm_panel *panel)
struct st7703 *ctx = panel_to_st7703(panel);
int ret;
- if (ctx->prepared)
- return 0;
-
dev_dbg(ctx->dev, "Resetting the panel\n");
gpiod_set_value_cansleep(ctx->reset_gpio, 1);
@@ -793,8 +785,6 @@ static int st7703_prepare(struct drm_panel *panel)
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
usleep_range(15000, 20000);
- ctx->prepared = true;
-
return 0;
}
@@ -854,7 +844,13 @@ static int allpixelson_set(void *data, u64 val)
dev_dbg(ctx->dev, "Setting all pixels on\n");
mipi_dsi_generic_write_seq(dsi, ST7703_CMD_ALL_PIXEL_ON);
msleep(val * 1000);
- /* Reset the panel to get video back */
+
+ /*
+ * Reset the panel to get video back. NOTE: This isn't a
+ * particularly safe thing to do in general because it assumes
+ * that the screen was on to begin with, but this is just a
+ * debugfs file so it's not a huge deal.
+ */
drm_panel_disable(&ctx->panel);
drm_panel_unprepare(&ctx->panel);
drm_panel_prepare(&ctx->panel);
@@ -941,27 +937,11 @@ static int st7703_probe(struct mipi_dsi_device *dsi)
return 0;
}
-static void st7703_shutdown(struct mipi_dsi_device *dsi)
-{
- struct st7703 *ctx = mipi_dsi_get_drvdata(dsi);
- int ret;
-
- ret = drm_panel_unprepare(&ctx->panel);
- if (ret < 0)
- dev_err(&dsi->dev, "Failed to unprepare panel: %d\n", ret);
-
- ret = drm_panel_disable(&ctx->panel);
- if (ret < 0)
- dev_err(&dsi->dev, "Failed to disable panel: %d\n", ret);
-}
-
static void st7703_remove(struct mipi_dsi_device *dsi)
{
struct st7703 *ctx = mipi_dsi_get_drvdata(dsi);
int ret;
- st7703_shutdown(dsi);
-
ret = mipi_dsi_detach(dsi);
if (ret < 0)
dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret);
@@ -985,7 +965,6 @@ MODULE_DEVICE_TABLE(of, st7703_of_match);
static struct mipi_dsi_driver st7703_driver = {
.probe = st7703_probe,
.remove = st7703_remove,
- .shutdown = st7703_shutdown,
.driver = {
.name = DRV_NAME,
.of_match_table = st7703_of_match,
diff --git a/drivers/gpu/drm/panel/panel-sony-acx565akm.c b/drivers/gpu/drm/panel/panel-sony-acx565akm.c
index 3d6a286056a0..73ba93ff00fe 100644
--- a/drivers/gpu/drm/panel/panel-sony-acx565akm.c
+++ b/drivers/gpu/drm/panel/panel-sony-acx565akm.c
@@ -454,9 +454,6 @@ static int acx565akm_power_on(struct acx565akm_panel *lcd)
static void acx565akm_power_off(struct acx565akm_panel *lcd)
{
- if (!lcd->enabled)
- return;
-
acx565akm_set_display_state(lcd, 0);
acx565akm_set_sleep_mode(lcd, 1);
lcd->enabled = false;
@@ -655,9 +652,6 @@ static void acx565akm_remove(struct spi_device *spi)
if (lcd->has_bc)
acx565akm_backlight_cleanup(lcd);
-
- drm_panel_disable(&lcd->panel);
- drm_panel_unprepare(&lcd->panel);
}
static const struct of_device_id acx565akm_of_match[] = {
diff --git a/drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c b/drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c
index d8487bc6d611..227f97f9b136 100644
--- a/drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c
+++ b/drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c
@@ -24,8 +24,6 @@ struct tdo_tl070wsh30_panel {
struct regulator *supply;
struct gpio_desc *reset_gpio;
-
- bool prepared;
};
static inline
@@ -39,9 +37,6 @@ static int tdo_tl070wsh30_panel_prepare(struct drm_panel *panel)
struct tdo_tl070wsh30_panel *tdo_tl070wsh30 = to_tdo_tl070wsh30_panel(panel);
int err;
- if (tdo_tl070wsh30->prepared)
- return 0;
-
err = regulator_enable(tdo_tl070wsh30->supply);
if (err < 0)
return err;
@@ -74,8 +69,6 @@ static int tdo_tl070wsh30_panel_prepare(struct drm_panel *panel)
msleep(20);
- tdo_tl070wsh30->prepared = true;
-
return 0;
}
@@ -84,9 +77,6 @@ static int tdo_tl070wsh30_panel_unprepare(struct drm_panel *panel)
struct tdo_tl070wsh30_panel *tdo_tl070wsh30 = to_tdo_tl070wsh30_panel(panel);
int err;
- if (!tdo_tl070wsh30->prepared)
- return 0;
-
err = mipi_dsi_dcs_set_display_off(tdo_tl070wsh30->link);
if (err < 0)
dev_err(panel->dev, "failed to set display off: %d\n", err);
@@ -103,8 +93,6 @@ static int tdo_tl070wsh30_panel_unprepare(struct drm_panel *panel)
regulator_disable(tdo_tl070wsh30->supply);
- tdo_tl070wsh30->prepared = false;
-
return 0;
}
@@ -220,16 +208,6 @@ static void tdo_tl070wsh30_panel_remove(struct mipi_dsi_device *dsi)
dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", err);
drm_panel_remove(&tdo_tl070wsh30->base);
- drm_panel_disable(&tdo_tl070wsh30->base);
- drm_panel_unprepare(&tdo_tl070wsh30->base);
-}
-
-static void tdo_tl070wsh30_panel_shutdown(struct mipi_dsi_device *dsi)
-{
- struct tdo_tl070wsh30_panel *tdo_tl070wsh30 = mipi_dsi_get_drvdata(dsi);
-
- drm_panel_disable(&tdo_tl070wsh30->base);
- drm_panel_unprepare(&tdo_tl070wsh30->base);
}
static struct mipi_dsi_driver tdo_tl070wsh30_panel_driver = {
@@ -239,7 +217,6 @@ static struct mipi_dsi_driver tdo_tl070wsh30_panel_driver = {
},
.probe = tdo_tl070wsh30_panel_probe,
.remove = tdo_tl070wsh30_panel_remove,
- .shutdown = tdo_tl070wsh30_panel_shutdown,
};
module_mipi_dsi_driver(tdo_tl070wsh30_panel_driver);
diff --git a/drivers/gpu/drm/panel/panel-xinpeng-xpp055c272.c b/drivers/gpu/drm/panel/panel-xinpeng-xpp055c272.c
index 8670386498a4..22a14006765e 100644
--- a/drivers/gpu/drm/panel/panel-xinpeng-xpp055c272.c
+++ b/drivers/gpu/drm/panel/panel-xinpeng-xpp055c272.c
@@ -52,7 +52,6 @@ struct xpp055c272 {
struct gpio_desc *reset_gpio;
struct regulator *vci;
struct regulator *iovcc;
- bool prepared;
};
static inline struct xpp055c272 *panel_to_xpp055c272(struct drm_panel *panel)
@@ -136,9 +135,6 @@ static int xpp055c272_unprepare(struct drm_panel *panel)
struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
int ret;
- if (!ctx->prepared)
- return 0;
-
ret = mipi_dsi_dcs_set_display_off(dsi);
if (ret < 0)
dev_err(ctx->dev, "failed to set display off: %d\n", ret);
@@ -152,8 +148,6 @@ static int xpp055c272_unprepare(struct drm_panel *panel)
regulator_disable(ctx->iovcc);
regulator_disable(ctx->vci);
- ctx->prepared = false;
-
return 0;
}
@@ -163,9 +157,6 @@ static int xpp055c272_prepare(struct drm_panel *panel)
struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
int ret;
- if (ctx->prepared)
- return 0;
-
dev_dbg(ctx->dev, "Resetting the panel\n");
ret = regulator_enable(ctx->vci);
if (ret < 0) {
@@ -209,8 +200,6 @@ static int xpp055c272_prepare(struct drm_panel *panel)
msleep(50);
- ctx->prepared = true;
-
return 0;
disable_iovcc:
@@ -317,27 +306,11 @@ static int xpp055c272_probe(struct mipi_dsi_device *dsi)
return 0;
}
-static void xpp055c272_shutdown(struct mipi_dsi_device *dsi)
-{
- struct xpp055c272 *ctx = mipi_dsi_get_drvdata(dsi);
- int ret;
-
- ret = drm_panel_unprepare(&ctx->panel);
- if (ret < 0)
- dev_err(&dsi->dev, "Failed to unprepare panel: %d\n", ret);
-
- ret = drm_panel_disable(&ctx->panel);
- if (ret < 0)
- dev_err(&dsi->dev, "Failed to disable panel: %d\n", ret);
-}
-
static void xpp055c272_remove(struct mipi_dsi_device *dsi)
{
struct xpp055c272 *ctx = mipi_dsi_get_drvdata(dsi);
int ret;
- xpp055c272_shutdown(dsi);
-
ret = mipi_dsi_detach(dsi);
if (ret < 0)
dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret);
@@ -358,7 +331,6 @@ static struct mipi_dsi_driver xpp055c272_driver = {
},
.probe = xpp055c272_probe,
.remove = xpp055c272_remove,
- .shutdown = xpp055c272_shutdown,
};
module_mipi_dsi_driver(xpp055c272_driver);
diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c
index ef9f6c0716d5..b43557b10ae3 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -777,6 +777,15 @@ static const struct panfrost_compatible mediatek_mt8186_data = {
.pm_features = BIT(GPU_PM_CLK_DIS) | BIT(GPU_PM_VREG_OFF),
};
+/* MT8188 uses the same power domains and power supplies as MT8183 */
+static const struct panfrost_compatible mediatek_mt8188_data = {
+ .num_supplies = ARRAY_SIZE(mediatek_mt8183_b_supplies) - 1,
+ .supply_names = mediatek_mt8183_b_supplies,
+ .num_pm_domains = ARRAY_SIZE(mediatek_mt8183_pm_domains),
+ .pm_domain_names = mediatek_mt8183_pm_domains,
+ .pm_features = BIT(GPU_PM_CLK_DIS) | BIT(GPU_PM_VREG_OFF),
+};
+
static const char * const mediatek_mt8192_supplies[] = { "mali", NULL };
static const char * const mediatek_mt8192_pm_domains[] = { "core0", "core1", "core2",
"core3", "core4" };
@@ -808,6 +817,7 @@ static const struct of_device_id dt_match[] = {
{ .compatible = "mediatek,mt8183-mali", .data = &mediatek_mt8183_data },
{ .compatible = "mediatek,mt8183b-mali", .data = &mediatek_mt8183_b_data },
{ .compatible = "mediatek,mt8186-mali", .data = &mediatek_mt8186_data },
+ { .compatible = "mediatek,mt8188-mali", .data = &mediatek_mt8188_data },
{ .compatible = "mediatek,mt8192-mali", .data = &mediatek_mt8192_data },
{}
};
diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c
index beee5563031a..5eb3f5719fdf 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.c
+++ b/drivers/gpu/drm/qxl/qxl_drv.c
@@ -37,7 +37,7 @@
#include <drm/drm_aperture.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_ttm.h>
#include <drm/drm_file.h>
#include <drm/drm_gem_ttm_helper.h>
#include <drm/drm_module.h>
@@ -118,7 +118,7 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (ret)
goto modeset_cleanup;
- drm_fbdev_generic_setup(&qdev->ddev, 32);
+ drm_fbdev_ttm_setup(&qdev->ddev, 32);
return 0;
modeset_cleanup:
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c
index 7b11674f5d45..03e6871b3065 100644
--- a/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -701,7 +701,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
if (radeon_connector->use_digital &&
(radeon_connector->audio == RADEON_AUDIO_ENABLE))
return ATOM_ENCODER_MODE_HDMI;
- else if (drm_detect_hdmi_monitor(radeon_connector_edid(connector)) &&
+ else if (connector->display_info.is_hdmi &&
(radeon_connector->audio == RADEON_AUDIO_AUTO))
return ATOM_ENCODER_MODE_HDMI;
else if (radeon_connector->use_digital)
@@ -720,7 +720,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
if (radeon_audio != 0) {
if (radeon_connector->audio == RADEON_AUDIO_ENABLE)
return ATOM_ENCODER_MODE_HDMI;
- else if (drm_detect_hdmi_monitor(radeon_connector_edid(connector)) &&
+ else if (connector->display_info.is_hdmi &&
(radeon_connector->audio == RADEON_AUDIO_AUTO))
return ATOM_ENCODER_MODE_HDMI;
else
@@ -737,14 +737,14 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
(dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {
if (radeon_audio != 0 &&
- drm_detect_monitor_audio(radeon_connector_edid(connector)) &&
+ connector->display_info.has_audio &&
ASIC_IS_DCE4(rdev) && !ASIC_IS_DCE5(rdev))
return ATOM_ENCODER_MODE_DP_AUDIO;
return ATOM_ENCODER_MODE_DP;
} else if (radeon_audio != 0) {
if (radeon_connector->audio == RADEON_AUDIO_ENABLE)
return ATOM_ENCODER_MODE_HDMI;
- else if (drm_detect_hdmi_monitor(radeon_connector_edid(connector)) &&
+ else if (connector->display_info.is_hdmi &&
(radeon_connector->audio == RADEON_AUDIO_AUTO))
return ATOM_ENCODER_MODE_HDMI;
else
@@ -755,7 +755,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
break;
case DRM_MODE_CONNECTOR_eDP:
if (radeon_audio != 0 &&
- drm_detect_monitor_audio(radeon_connector_edid(connector)) &&
+ connector->display_info.has_audio &&
ASIC_IS_DCE4(rdev) && !ASIC_IS_DCE5(rdev))
return ATOM_ENCODER_MODE_DP_AUDIO;
return ATOM_ENCODER_MODE_DP;
diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c
index 681119c91d94..09dda114e218 100644
--- a/drivers/gpu/drm/radeon/evergreen_hdmi.c
+++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c
@@ -412,7 +412,7 @@ void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable)
if (enable) {
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
- if (connector && drm_detect_monitor_audio(radeon_connector_edid(connector))) {
+ if (connector && connector->display_info.has_audio) {
WREG32(HDMI_INFOFRAME_CONTROL0 + dig->afmt->offset,
HDMI_AVI_INFO_SEND | /* enable AVI info frames */
HDMI_AVI_INFO_CONT | /* required for audio info values to be updated */
@@ -450,8 +450,7 @@ void evergreen_dp_enable(struct drm_encoder *encoder, bool enable)
if (!dig || !dig->afmt)
return;
- if (enable && connector &&
- drm_detect_monitor_audio(radeon_connector_edid(connector))) {
+ if (enable && connector && connector->display_info.has_audio) {
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
struct radeon_connector_atom_dig *dig_connector;
diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c
index 74753bb26d33..0bcd767b9f47 100644
--- a/drivers/gpu/drm/radeon/radeon_audio.c
+++ b/drivers/gpu/drm/radeon/radeon_audio.c
@@ -303,6 +303,7 @@ void radeon_audio_endpoint_wreg(struct radeon_device *rdev, u32 offset,
static void radeon_audio_write_sad_regs(struct drm_encoder *encoder)
{
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+ struct radeon_connector *radeon_connector = to_radeon_connector(connector);
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct cea_sad *sads;
int sad_count;
@@ -310,7 +311,7 @@ static void radeon_audio_write_sad_regs(struct drm_encoder *encoder)
if (!connector)
return;
- sad_count = drm_edid_to_sad(radeon_connector_edid(connector), &sads);
+ sad_count = drm_edid_to_sad(radeon_connector->edid, &sads);
if (sad_count < 0)
DRM_ERROR("Couldn't read SADs: %d\n", sad_count);
if (sad_count <= 0)
@@ -326,6 +327,7 @@ static void radeon_audio_write_sad_regs(struct drm_encoder *encoder)
static void radeon_audio_write_speaker_allocation(struct drm_encoder *encoder)
{
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+ struct radeon_connector *radeon_connector = to_radeon_connector(connector);
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
u8 *sadb = NULL;
int sad_count;
@@ -333,8 +335,7 @@ static void radeon_audio_write_speaker_allocation(struct drm_encoder *encoder)
if (!connector)
return;
- sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector),
- &sadb);
+ sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb);
if (sad_count < 0) {
DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n",
sad_count);
@@ -409,7 +410,7 @@ void radeon_audio_detect(struct drm_connector *connector,
radeon_encoder->audio = rdev->audio.hdmi_funcs;
}
- if (drm_detect_monitor_audio(radeon_connector_edid(connector))) {
+ if (connector->display_info.has_audio) {
if (!dig->pin)
dig->pin = radeon_audio_get_pin(encoder);
radeon_audio_enable(rdev, dig->pin, 0xf);
@@ -646,7 +647,7 @@ static void radeon_audio_hdmi_mode_set(struct drm_encoder *encoder,
if (!connector)
return;
- if (drm_detect_monitor_audio(radeon_connector_edid(connector))) {
+ if (connector->display_info.has_audio) {
radeon_audio_set_mute(encoder, true);
radeon_audio_write_speaker_allocation(encoder);
@@ -686,7 +687,7 @@ static void radeon_audio_dp_mode_set(struct drm_encoder *encoder,
if (!connector)
return;
- if (drm_detect_monitor_audio(radeon_connector_edid(connector))) {
+ if (connector->display_info.has_audio) {
radeon_audio_write_speaker_allocation(encoder);
radeon_audio_write_sad_regs(encoder);
radeon_audio_write_latency_fields(encoder, mode);
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index cf0114ca59a4..69693ba5949e 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -109,7 +109,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector)
case DRM_MODE_CONNECTOR_DVII:
case DRM_MODE_CONNECTOR_HDMIB:
if (radeon_connector->use_digital) {
- if (drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
+ if (connector->display_info.is_hdmi) {
if (connector->display_info.bpc)
bpc = connector->display_info.bpc;
}
@@ -117,7 +117,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector)
break;
case DRM_MODE_CONNECTOR_DVID:
case DRM_MODE_CONNECTOR_HDMIA:
- if (drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
+ if (connector->display_info.is_hdmi) {
if (connector->display_info.bpc)
bpc = connector->display_info.bpc;
}
@@ -126,7 +126,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector)
dig_connector = radeon_connector->con_priv;
if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
(dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) ||
- drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
+ connector->display_info.is_hdmi) {
if (connector->display_info.bpc)
bpc = connector->display_info.bpc;
}
@@ -150,7 +150,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector)
break;
}
- if (drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
+ if (connector->display_info.is_hdmi) {
/* hdmi deep color only implemented on DCE4+ */
if ((bpc > 8) && !ASIC_IS_DCE4(rdev)) {
DRM_DEBUG("%s: HDMI deep color %d bpc unsupported. Using 8 bpc.\n",
@@ -255,21 +255,6 @@ static struct drm_encoder *radeon_find_encoder(struct drm_connector *connector,
return NULL;
}
-struct edid *radeon_connector_edid(struct drm_connector *connector)
-{
- struct radeon_connector *radeon_connector = to_radeon_connector(connector);
- struct drm_property_blob *edid_blob = connector->edid_blob_ptr;
-
- if (radeon_connector->edid) {
- return radeon_connector->edid;
- } else if (edid_blob) {
- struct edid *edid = kmemdup(edid_blob->data, edid_blob->length, GFP_KERNEL);
- if (edid)
- radeon_connector->edid = edid;
- }
- return radeon_connector->edid;
-}
-
static void radeon_connector_get_edid(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
@@ -1488,7 +1473,7 @@ static enum drm_mode_status radeon_dvi_mode_valid(struct drm_connector *connecto
(radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) ||
(radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B))
return MODE_OK;
- else if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
+ else if (ASIC_IS_DCE6(rdev) && connector->display_info.is_hdmi) {
/* HDMI 1.3+ supports max clock of 340 Mhz */
if (mode->clock > 340000)
return MODE_CLOCK_HIGH;
@@ -1784,7 +1769,7 @@ static enum drm_mode_status radeon_dp_mode_valid(struct drm_connector *connector
(radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {
return radeon_dp_mode_valid_helper(connector, mode);
} else {
- if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
+ if (ASIC_IS_DCE6(rdev) && connector->display_info.is_hdmi) {
/* HDMI 1.3+ supports max clock of 340 Mhz */
if (mode->clock > 340000)
return MODE_CLOCK_HIGH;
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 5f1d24d3120c..843383f7237f 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -1722,7 +1722,7 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
(!(mode->flags & DRM_MODE_FLAG_INTERLACE)) &&
((radeon_encoder->underscan_type == UNDERSCAN_ON) ||
((radeon_encoder->underscan_type == UNDERSCAN_AUTO) &&
- drm_detect_hdmi_monitor(radeon_connector_edid(connector)) &&
+ connector->display_info.is_hdmi &&
is_hdtv_mode(mode)))) {
if (radeon_encoder->underscan_hborder != 0)
radeon_crtc->h_border = radeon_encoder->underscan_hborder;
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c
index 3de3dce9e89d..0f723292409e 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -386,7 +386,7 @@ bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder,
case DRM_MODE_CONNECTOR_HDMIB:
if (radeon_connector->use_digital) {
/* HDMI 1.3 supports up to 340 Mhz over single link */
- if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
+ if (ASIC_IS_DCE6(rdev) && connector->display_info.is_hdmi) {
if (pixel_clock > 340000)
return true;
else
@@ -408,7 +408,7 @@ bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder,
return false;
else {
/* HDMI 1.3 supports up to 340 Mhz over single link */
- if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
+ if (ASIC_IS_DCE6(rdev) && connector->display_info.is_hdmi) {
if (pixel_clock > 340000)
return true;
else
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 546381a5c918..e0a5af180801 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -701,8 +701,6 @@ extern u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connecto
extern bool radeon_connector_is_dp12_capable(struct drm_connector *connector);
extern int radeon_get_monitor_bpc(struct drm_connector *connector);
-extern struct edid *radeon_connector_edid(struct drm_connector *connector);
-
extern void radeon_connector_hotplug(struct drm_connector *connector);
extern int radeon_dp_mode_valid_helper(struct drm_connector *connector,
struct drm_display_mode *mode);
diff --git a/drivers/gpu/drm/renesas/rcar-du/Kconfig b/drivers/gpu/drm/renesas/rcar-du/Kconfig
index 53c356aed5d5..c17e7c50492c 100644
--- a/drivers/gpu/drm/renesas/rcar-du/Kconfig
+++ b/drivers/gpu/drm/renesas/rcar-du/Kconfig
@@ -2,7 +2,7 @@
config DRM_RCAR_DU
tristate "DRM Support for R-Car Display Unit"
depends on DRM && OF
- depends on ARM || ARM64
+ depends on ARM || ARM64 || COMPILE_TEST
depends on ARCH_RENESAS || COMPILE_TEST
select DRM_KMS_HELPER
select DRM_GEM_DMA_HELPER
diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c
index dee530e4c8b2..fb719d9aff10 100644
--- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c
@@ -20,7 +20,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_dma.h>
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_managed.h>
#include <drm/drm_probe_helper.h>
@@ -716,7 +716,7 @@ static int rcar_du_probe(struct platform_device *pdev)
drm_info(&rcdu->ddev, "Device %s probed\n", dev_name(&pdev->dev));
- drm_fbdev_generic_setup(&rcdu->ddev, 32);
+ drm_fbdev_dma_setup(&rcdu->ddev, 32);
return 0;
diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c
index 470d34da1d6c..e5eca8691a33 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c
@@ -14,7 +14,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_dma.h>
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_probe_helper.h>
@@ -149,7 +149,7 @@ static int rzg2l_du_probe(struct platform_device *pdev)
drm_info(&rcdu->ddev, "Device %s probed\n", dev_name(&pdev->dev));
- drm_fbdev_generic_setup(&rcdu->ddev, 32);
+ drm_fbdev_dma_setup(&rcdu->ddev, 32);
return 0;
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
index e83c3e52251d..890cc2f6408d 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
@@ -19,7 +19,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_dma.h>
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_modeset_helper.h>
#include <drm/drm_module.h>
@@ -250,7 +250,7 @@ static int shmob_drm_probe(struct platform_device *pdev)
if (ret < 0)
goto err_modeset_cleanup;
- drm_fbdev_generic_setup(ddev, 16);
+ drm_fbdev_dma_setup(ddev, 16);
return 0;
diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 1bf3e2829cd0..7df875e38517 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -74,6 +74,9 @@ config ROCKCHIP_DW_MIPI_DSI
config ROCKCHIP_INNO_HDMI
bool "Rockchip specific extensions for Innosilicon HDMI"
+ select DRM_DISPLAY_HDMI_HELPER
+ select DRM_DISPLAY_HDMI_STATE_HELPER
+ select DRM_DISPLAY_HELPER
help
This selects support for Rockchip SoC specific extensions
for the Innosilicon HDMI driver. If you want to enable
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index 4cc8ed8f4fbd..58a44af0e9ad 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -153,6 +153,11 @@
#define PX30_DSI_TURNDISABLE BIT(5)
#define PX30_DSI_LCDC_SEL BIT(0)
+#define RK3128_GRF_LVDS_CON0 0x0150
+#define RK3128_DSI_FORCETXSTOPMODE GENMASK(13, 10)
+#define RK3128_DSI_FORCERXMODE BIT(9)
+#define RK3128_DSI_TURNDISABLE BIT(8)
+
#define RK3288_GRF_SOC_CON6 0x025c
#define RK3288_DSI0_LCDC_SEL BIT(6)
#define RK3288_DSI1_LCDC_SEL BIT(9)
@@ -1493,6 +1498,18 @@ static const struct rockchip_dw_dsi_chip_data px30_chip_data[] = {
{ /* sentinel */ }
};
+static const struct rockchip_dw_dsi_chip_data rk3128_chip_data[] = {
+ {
+ .reg = 0x10110000,
+ .lanecfg1_grf_reg = RK3128_GRF_LVDS_CON0,
+ .lanecfg1 = HIWORD_UPDATE(0, RK3128_DSI_TURNDISABLE |
+ RK3128_DSI_FORCERXMODE |
+ RK3128_DSI_FORCETXSTOPMODE),
+ .max_data_lanes = 4,
+ },
+ { /* sentinel */ }
+};
+
static const struct rockchip_dw_dsi_chip_data rk3288_chip_data[] = {
{
.reg = 0xff960000,
@@ -1671,6 +1688,9 @@ static const struct of_device_id dw_mipi_dsi_rockchip_dt_ids[] = {
.compatible = "rockchip,px30-mipi-dsi",
.data = &px30_chip_data,
}, {
+ .compatible = "rockchip,rk3128-mipi-dsi",
+ .data = &rk3128_chip_data,
+ }, {
.compatible = "rockchip,rk3288-mipi-dsi",
.data = &rk3288_chip_data,
}, {
diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 3df2cfcf9998..2241e53a2946 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -22,6 +22,9 @@
#include <drm/drm_probe_helper.h>
#include <drm/drm_simple_kms_helper.h>
+#include <drm/display/drm_hdmi_helper.h>
+#include <drm/display/drm_hdmi_state_helper.h>
+
#include "rockchip_drm_drv.h"
#include "inno_hdmi.h"
@@ -67,9 +70,7 @@ struct inno_hdmi {
struct inno_hdmi_connector_state {
struct drm_connector_state base;
- unsigned int enc_out_format;
unsigned int colorimetry;
- bool rgb_limited_range;
};
static struct inno_hdmi *encoder_to_inno_hdmi(struct drm_encoder *encoder)
@@ -257,26 +258,29 @@ static void inno_hdmi_reset(struct inno_hdmi *hdmi)
inno_hdmi_standby(hdmi);
}
-static void inno_hdmi_disable_frame(struct inno_hdmi *hdmi,
- enum hdmi_infoframe_type type)
+static int inno_hdmi_disable_frame(struct drm_connector *connector,
+ enum hdmi_infoframe_type type)
{
- struct drm_connector *connector = &hdmi->connector;
+ struct inno_hdmi *hdmi = connector_to_inno_hdmi(connector);
if (type != HDMI_INFOFRAME_TYPE_AVI) {
drm_err(connector->dev,
"Unsupported infoframe type: %u\n", type);
- return;
+ return 0;
}
hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI);
+
+ return 0;
}
-static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi,
- union hdmi_infoframe *frame, enum hdmi_infoframe_type type)
+static int inno_hdmi_upload_frame(struct drm_connector *connector,
+ enum hdmi_infoframe_type type,
+ const u8 *buffer, size_t len)
{
- struct drm_connector *connector = &hdmi->connector;
+ struct inno_hdmi *hdmi = connector_to_inno_hdmi(connector);
u8 packed_frame[HDMI_MAXIMUM_INFO_FRAME_SIZE];
- ssize_t rc, i;
+ ssize_t i;
if (type != HDMI_INFOFRAME_TYPE_AVI) {
drm_err(connector->dev,
@@ -284,59 +288,19 @@ static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi,
return 0;
}
- inno_hdmi_disable_frame(hdmi, type);
-
- rc = hdmi_infoframe_pack(frame, packed_frame,
- sizeof(packed_frame));
- if (rc < 0)
- return rc;
+ inno_hdmi_disable_frame(connector, type);
- for (i = 0; i < rc; i++)
+ for (i = 0; i < len; i++)
hdmi_writeb(hdmi, HDMI_CONTROL_PACKET_ADDR + i,
packed_frame[i]);
return 0;
}
-static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
- struct drm_display_mode *mode)
-{
- struct drm_connector *connector = &hdmi->connector;
- struct drm_connector_state *conn_state = connector->state;
- struct inno_hdmi_connector_state *inno_conn_state =
- to_inno_hdmi_conn_state(conn_state);
- union hdmi_infoframe frame;
- int rc;
-
- rc = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
- &hdmi->connector,
- mode);
- if (rc) {
- inno_hdmi_disable_frame(hdmi, HDMI_INFOFRAME_TYPE_AVI);
- return rc;
- }
-
- if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444)
- frame.avi.colorspace = HDMI_COLORSPACE_YUV444;
- else if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV422)
- frame.avi.colorspace = HDMI_COLORSPACE_YUV422;
- else
- frame.avi.colorspace = HDMI_COLORSPACE_RGB;
-
- if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_RGB) {
- drm_hdmi_avi_infoframe_quant_range(&frame.avi,
- connector, mode,
- inno_conn_state->rgb_limited_range ?
- HDMI_QUANTIZATION_RANGE_LIMITED :
- HDMI_QUANTIZATION_RANGE_FULL);
- } else {
- frame.avi.quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
- frame.avi.ycc_quantization_range =
- HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
- }
-
- return inno_hdmi_upload_frame(hdmi, &frame, HDMI_INFOFRAME_TYPE_AVI);
-}
+static const struct drm_connector_hdmi_funcs inno_hdmi_hdmi_connector_funcs = {
+ .clear_infoframe = inno_hdmi_disable_frame,
+ .write_infoframe = inno_hdmi_upload_frame,
+};
static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
{
@@ -361,8 +325,8 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
v_VIDEO_INPUT_CSP(0);
hdmi_writeb(hdmi, HDMI_VIDEO_CONTRL2, value);
- if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_RGB) {
- if (inno_conn_state->rgb_limited_range) {
+ if (conn_state->hdmi.output_format == HDMI_COLORSPACE_RGB) {
+ if (conn_state->hdmi.is_limited_range) {
csc_mode = CSC_RGB_0_255_TO_RGB_16_235_8BIT;
auto_csc = AUTO_CSC_DISABLE;
c0_c2_change = C0_C2_CHANGE_DISABLE;
@@ -380,14 +344,14 @@ static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
}
} else {
if (inno_conn_state->colorimetry == HDMI_COLORIMETRY_ITU_601) {
- if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) {
+ if (conn_state->hdmi.output_format == HDMI_COLORSPACE_YUV444) {
csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
auto_csc = AUTO_CSC_DISABLE;
c0_c2_change = C0_C2_CHANGE_DISABLE;
csc_enable = v_CSC_ENABLE;
}
} else {
- if (inno_conn_state->enc_out_format == HDMI_COLORSPACE_YUV444) {
+ if (conn_state->hdmi.output_format == HDMI_COLORSPACE_YUV444) {
csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
auto_csc = AUTO_CSC_DISABLE;
c0_c2_change = C0_C2_CHANGE_DISABLE;
@@ -462,10 +426,20 @@ static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi,
}
static int inno_hdmi_setup(struct inno_hdmi *hdmi,
- struct drm_display_mode *mode)
+ struct drm_atomic_state *state)
{
- struct drm_display_info *display = &hdmi->connector.display_info;
- unsigned long mpixelclock = mode->clock * 1000;
+ struct drm_connector *connector = &hdmi->connector;
+ struct drm_display_info *display = &connector->display_info;
+ struct drm_connector_state *new_conn_state;
+ struct drm_crtc_state *new_crtc_state;
+
+ new_conn_state = drm_atomic_get_new_connector_state(state, connector);
+ if (WARN_ON(!new_conn_state))
+ return -EINVAL;
+
+ new_crtc_state = drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
+ if (WARN_ON(!new_crtc_state))
+ return -EINVAL;
/* Mute video and audio output */
hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
@@ -475,12 +449,11 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
hdmi_writeb(hdmi, HDMI_HDCP_CTRL,
v_HDMI_DVI(display->is_hdmi));
- inno_hdmi_config_video_timing(hdmi, mode);
+ inno_hdmi_config_video_timing(hdmi, &new_crtc_state->adjusted_mode);
inno_hdmi_config_video_csc(hdmi);
- if (display->is_hdmi)
- inno_hdmi_config_video_avi(hdmi, mode);
+ drm_atomic_helper_connector_hdmi_update_infoframes(connector, state);
/*
* When IP controller have configured to an accurate video
@@ -488,13 +461,13 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi,
* DCLK_LCDC, so we need to init the TMDS rate to mode pixel
* clock rate, and reconfigure the DDC clock.
*/
- inno_hdmi_i2c_init(hdmi, mpixelclock);
+ inno_hdmi_i2c_init(hdmi, new_conn_state->hdmi.tmds_char_rate);
/* Unmute video and audio output */
hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK,
v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0));
- inno_hdmi_power_up(hdmi, mpixelclock);
+ inno_hdmi_power_up(hdmi, new_conn_state->hdmi.tmds_char_rate);
return 0;
}
@@ -535,18 +508,8 @@ static void inno_hdmi_encoder_enable(struct drm_encoder *encoder,
struct drm_atomic_state *state)
{
struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);
- struct drm_connector_state *conn_state;
- struct drm_crtc_state *crtc_state;
- conn_state = drm_atomic_get_new_connector_state(state, &hdmi->connector);
- if (WARN_ON(!conn_state))
- return;
-
- crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
- if (WARN_ON(!crtc_state))
- return;
-
- inno_hdmi_setup(hdmi, &crtc_state->adjusted_mode);
+ inno_hdmi_setup(hdmi, state);
}
static void inno_hdmi_encoder_disable(struct drm_encoder *encoder,
@@ -563,7 +526,6 @@ inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
struct drm_connector_state *conn_state)
{
struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
- struct inno_hdmi *hdmi = encoder_to_inno_hdmi(encoder);
struct drm_display_mode *mode = &crtc_state->adjusted_mode;
u8 vic = drm_match_cea_mode(mode);
struct inno_hdmi_connector_state *inno_conn_state =
@@ -580,12 +542,7 @@ inno_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
else
inno_conn_state->colorimetry = HDMI_COLORIMETRY_ITU_709;
- inno_conn_state->enc_out_format = HDMI_COLORSPACE_RGB;
- inno_conn_state->rgb_limited_range =
- drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_LIMITED;
-
- return inno_hdmi_display_mode_valid(hdmi,
- &crtc_state->adjusted_mode) == MODE_OK ? 0 : -EINVAL;
+ return 0;
}
static struct drm_encoder_helper_funcs inno_hdmi_encoder_helper_funcs = {
@@ -629,12 +586,6 @@ inno_hdmi_connector_mode_valid(struct drm_connector *connector,
return inno_hdmi_display_mode_valid(hdmi, mode);
}
-static void inno_hdmi_connector_destroy(struct drm_connector *connector)
-{
- drm_connector_unregister(connector);
- drm_connector_cleanup(connector);
-}
-
static void
inno_hdmi_connector_destroy_state(struct drm_connector *connector,
struct drm_connector_state *state)
@@ -660,10 +611,9 @@ static void inno_hdmi_connector_reset(struct drm_connector *connector)
return;
__drm_atomic_helper_connector_reset(connector, &inno_conn_state->base);
+ __drm_atomic_helper_connector_hdmi_reset(connector, connector->state);
inno_conn_state->colorimetry = HDMI_COLORIMETRY_ITU_709;
- inno_conn_state->enc_out_format = HDMI_COLORSPACE_RGB;
- inno_conn_state->rgb_limited_range = false;
}
static struct drm_connector_state *
@@ -689,13 +639,13 @@ inno_hdmi_connector_duplicate_state(struct drm_connector *connector)
static const struct drm_connector_funcs inno_hdmi_connector_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = inno_hdmi_connector_detect,
- .destroy = inno_hdmi_connector_destroy,
.reset = inno_hdmi_connector_reset,
.atomic_duplicate_state = inno_hdmi_connector_duplicate_state,
.atomic_destroy_state = inno_hdmi_connector_destroy_state,
};
static struct drm_connector_helper_funcs inno_hdmi_connector_helper_funcs = {
+ .atomic_check = drm_atomic_helper_connector_hdmi_check,
.get_modes = inno_hdmi_connector_get_modes,
.mode_valid = inno_hdmi_connector_mode_valid,
};
@@ -723,10 +673,14 @@ static int inno_hdmi_register(struct drm_device *drm, struct inno_hdmi *hdmi)
drm_connector_helper_add(&hdmi->connector,
&inno_hdmi_connector_helper_funcs);
- drm_connector_init_with_ddc(drm, &hdmi->connector,
- &inno_hdmi_connector_funcs,
- DRM_MODE_CONNECTOR_HDMIA,
- hdmi->ddc);
+ drmm_connector_hdmi_init(drm, &hdmi->connector,
+ "Rockchip", "Inno HDMI",
+ &inno_hdmi_connector_funcs,
+ &inno_hdmi_hdmi_connector_funcs,
+ DRM_MODE_CONNECTOR_HDMIA,
+ hdmi->ddc,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
drm_connector_attach_encoder(&hdmi->connector, encoder);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index ab55d7132550..44d769d9234d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -18,7 +18,7 @@
#include <drm/drm_aperture.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_dma.h>
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_of.h>
#include <drm/drm_probe_helper.h>
@@ -191,7 +191,7 @@ static int rockchip_drm_bind(struct device *dev)
if (ret)
goto err_kms_helper_poll_fini;
- drm_fbdev_generic_setup(drm_dev, 0);
+ drm_fbdev_dma_setup(drm_dev, 0);
return 0;
err_kms_helper_poll_fini:
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 62ebbdb16253..9873172e3fd3 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -2344,7 +2344,7 @@ static void vop2_setup_layer_mixer(struct vop2_video_port *vp)
port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX,
(vp2->nlayers + vp1->nlayers + vp0->nlayers - 1));
else
- port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX, 8);
+ port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX, 8);
layer_sel = vop2_readl(vop2, RK3568_OVL_LAYER_SEL);
diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c
index ebd943b9e357..6f51bcf774e2 100644
--- a/drivers/gpu/drm/solomon/ssd130x.c
+++ b/drivers/gpu/drm/solomon/ssd130x.c
@@ -23,7 +23,7 @@
#include <drm/drm_crtc_helper.h>
#include <drm/drm_damage_helper.h>
#include <drm/drm_edid.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_shmem.h>
#include <drm/drm_format_helper.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_atomic_helper.h>
@@ -2029,7 +2029,7 @@ struct ssd130x_device *ssd130x_probe(struct device *dev, struct regmap *regmap)
if (ret)
return ERR_PTR(dev_err_probe(dev, ret, "DRM device register failed\n"));
- drm_fbdev_generic_setup(drm, 32);
+ drm_fbdev_shmem_setup(drm, 32);
return ssd130x;
}
diff --git a/drivers/gpu/drm/sti/Kconfig b/drivers/gpu/drm/sti/Kconfig
index 3c7a5feff8de..75c301aadcbc 100644
--- a/drivers/gpu/drm/sti/Kconfig
+++ b/drivers/gpu/drm/sti/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config DRM_STI
tristate "DRM Support for STMicroelectronics SoC stiH4xx Series"
- depends on OF && DRM && ARCH_STI
+ depends on OF && DRM && (ARCH_STI || COMPILE_TEST)
select RESET_CONTROLLER
select DRM_KMS_HELPER
select DRM_GEM_DMA_HELPER
diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c
index fd1df4ce3852..48a5d49fc131 100644
--- a/drivers/gpu/drm/sti/sti_dvo.c
+++ b/drivers/gpu/drm/sti/sti_dvo.c
@@ -7,6 +7,7 @@
#include <linux/clk.h>
#include <linux/component.h>
#include <linux/debugfs.h>
+#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
diff --git a/drivers/gpu/drm/stm/Kconfig b/drivers/gpu/drm/stm/Kconfig
index fa49cde43bb2..4c906d602825 100644
--- a/drivers/gpu/drm/stm/Kconfig
+++ b/drivers/gpu/drm/stm/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config DRM_STM
tristate "DRM Support for STMicroelectronics SoC Series"
- depends on DRM && ARCH_STM32
+ depends on DRM && (ARCH_STM32 || COMPILE_TEST)
select DRM_KMS_HELPER
select DRM_GEM_DMA_HELPER
select DRM_PANEL_BRIDGE
diff --git a/drivers/gpu/drm/sun4i/Kconfig b/drivers/gpu/drm/sun4i/Kconfig
index 4741d9f6544c..4037e085430e 100644
--- a/drivers/gpu/drm/sun4i/Kconfig
+++ b/drivers/gpu/drm/sun4i/Kconfig
@@ -18,6 +18,9 @@ if DRM_SUN4I
config DRM_SUN4I_HDMI
tristate "Allwinner A10/A10s/A20/A31 HDMI Controller Support"
depends on ARM || COMPILE_TEST
+ select DRM_DISPLAY_HDMI_HELPER
+ select DRM_DISPLAY_HDMI_STATE_HELPER
+ select DRM_DISPLAY_HELPER
default DRM_SUN4I
help
Choose this option if you have an Allwinner A10/A10s/A20/A31
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c
index 335fd0edb904..e89eb96d3131 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.c
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.c
@@ -69,7 +69,9 @@ static void sun4i_backend_disable_color_correction(struct sunxi_engine *engine)
SUN4I_BACKEND_OCCTL_ENABLE, 0);
}
-static void sun4i_backend_commit(struct sunxi_engine *engine)
+static void sun4i_backend_commit(struct sunxi_engine *engine,
+ struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
{
DRM_DEBUG_DRIVER("Committing changes\n");
diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c b/drivers/gpu/drm/sun4i/sun4i_crtc.c
index c06d7cd45388..18e74047b0f5 100644
--- a/drivers/gpu/drm/sun4i/sun4i_crtc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c
@@ -91,7 +91,7 @@ static void sun4i_crtc_atomic_flush(struct drm_crtc *crtc,
DRM_DEBUG_DRIVER("Committing plane changes\n");
- sunxi_engine_commit(scrtc->engine);
+ sunxi_engine_commit(scrtc->engine, crtc, state);
if (event) {
crtc->state->event = NULL;
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index 245b34adca5a..b3649449de30 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -26,6 +26,9 @@
#include <drm/drm_probe_helper.h>
#include <drm/drm_simple_kms_helper.h>
+#include <drm/display/drm_hdmi_helper.h>
+#include <drm/display/drm_hdmi_state_helper.h>
+
#include "sun4i_backend.h"
#include "sun4i_crtc.h"
#include "sun4i_drv.h"
@@ -37,30 +40,24 @@
#define drm_connector_to_sun4i_hdmi(c) \
container_of_const(c, struct sun4i_hdmi, connector)
-static int sun4i_hdmi_setup_avi_infoframes(struct sun4i_hdmi *hdmi,
- struct drm_display_mode *mode)
+static int sun4i_hdmi_write_infoframe(struct drm_connector *connector,
+ enum hdmi_infoframe_type type,
+ const u8 *buffer, size_t len)
{
- struct hdmi_avi_infoframe frame;
- u8 buffer[17];
- int i, ret;
-
- ret = drm_hdmi_avi_infoframe_from_display_mode(&frame,
- &hdmi->connector, mode);
- if (ret < 0) {
- DRM_ERROR("Failed to get infoframes from mode\n");
- return ret;
- }
+ struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector);
+ int i;
- ret = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer));
- if (ret < 0) {
- DRM_ERROR("Failed to pack infoframes\n");
- return ret;
+ if (type != HDMI_INFOFRAME_TYPE_AVI) {
+ drm_err(connector->dev,
+ "Unsupported infoframe type: %u\n", type);
+ return 0;
}
- for (i = 0; i < sizeof(buffer); i++)
+ for (i = 0; i < len; i++)
writeb(buffer[i], hdmi->base + SUN4I_HDMI_AVI_INFOFRAME_REG(i));
return 0;
+
}
static void sun4i_hdmi_disable(struct drm_encoder *encoder,
@@ -83,14 +80,18 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder,
{
struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
- struct drm_display_info *display = &hdmi->connector.display_info;
+ struct drm_connector *connector = &hdmi->connector;
+ struct drm_display_info *display = &connector->display_info;
+ struct drm_connector_state *conn_state =
+ drm_atomic_get_new_connector_state(state, connector);
+ unsigned long long tmds_rate = conn_state->hdmi.tmds_char_rate;
unsigned int x, y;
u32 val = 0;
DRM_DEBUG_DRIVER("Enabling the HDMI Output\n");
- clk_set_rate(hdmi->mod_clk, mode->crtc_clock * 1000);
- clk_set_rate(hdmi->tmds_clk, mode->crtc_clock * 1000);
+ clk_set_rate(hdmi->mod_clk, tmds_rate);
+ clk_set_rate(hdmi->tmds_clk, tmds_rate);
/* Set input sync enable */
writel(SUN4I_HDMI_UNKNOWN_INPUT_SYNC,
@@ -143,7 +144,8 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder,
clk_prepare_enable(hdmi->tmds_clk);
- sun4i_hdmi_setup_avi_infoframes(hdmi, mode);
+ drm_atomic_helper_connector_hdmi_update_infoframes(connector, state);
+
val |= SUN4I_HDMI_PKT_CTRL_TYPE(0, SUN4I_HDMI_PKT_AVI);
val |= SUN4I_HDMI_PKT_CTRL_TYPE(1, SUN4I_HDMI_PKT_END);
writel(val, hdmi->base + SUN4I_HDMI_PKT_CTRL_REG(0));
@@ -196,7 +198,7 @@ static int sun4i_hdmi_connector_atomic_check(struct drm_connector *connector,
enum drm_mode_status status;
status = sun4i_hdmi_connector_clock_valid(connector, mode,
- mode->clock * 1000);
+ conn_state->hdmi.tmds_char_rate);
if (status != MODE_OK)
return -EINVAL;
@@ -207,8 +209,10 @@ static enum drm_mode_status
sun4i_hdmi_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
- return sun4i_hdmi_connector_clock_valid(connector, mode,
- mode->clock * 1000);
+ unsigned long long rate = drm_hdmi_compute_mode_clock(mode, 8,
+ HDMI_COLORSPACE_RGB);
+
+ return sun4i_hdmi_connector_clock_valid(connector, mode, rate);
}
static int sun4i_hdmi_get_modes(struct drm_connector *connector)
@@ -258,6 +262,11 @@ static struct i2c_adapter *sun4i_hdmi_get_ddc(struct device *dev)
return ddc;
}
+static const struct drm_connector_hdmi_funcs sun4i_hdmi_hdmi_connector_funcs = {
+ .tmds_char_rate_valid = sun4i_hdmi_connector_clock_valid,
+ .write_infoframe = sun4i_hdmi_write_infoframe,
+};
+
static const struct drm_connector_helper_funcs sun4i_hdmi_connector_helper_funcs = {
.atomic_check = sun4i_hdmi_connector_atomic_check,
.mode_valid = sun4i_hdmi_connector_mode_valid,
@@ -279,11 +288,16 @@ sun4i_hdmi_connector_detect(struct drm_connector *connector, bool force)
return connector_status_connected;
}
+static void sun4i_hdmi_connector_reset(struct drm_connector *connector)
+{
+ drm_atomic_helper_connector_reset(connector);
+ __drm_atomic_helper_connector_hdmi_reset(connector, connector->state);
+}
+
static const struct drm_connector_funcs sun4i_hdmi_connector_funcs = {
.detect = sun4i_hdmi_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
- .destroy = drm_connector_cleanup,
- .reset = drm_atomic_helper_connector_reset,
+ .reset = sun4i_hdmi_connector_reset,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
@@ -642,10 +656,19 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
drm_connector_helper_add(&hdmi->connector,
&sun4i_hdmi_connector_helper_funcs);
- ret = drm_connector_init_with_ddc(drm, &hdmi->connector,
- &sun4i_hdmi_connector_funcs,
- DRM_MODE_CONNECTOR_HDMIA,
- hdmi->ddc_i2c);
+ ret = drmm_connector_hdmi_init(drm, &hdmi->connector,
+ /*
+ * NOTE: Those are likely to be
+ * wrong, but I couldn't find the
+ * actual ones in the BSP.
+ */
+ "AW", "HDMI",
+ &sun4i_hdmi_connector_funcs,
+ &sun4i_hdmi_hdmi_connector_funcs,
+ DRM_MODE_CONNECTOR_HDMIA,
+ hdmi->ddc_i2c,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
if (ret) {
dev_err(dev,
"Couldn't initialise the HDMI connector\n");
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index 01382860aaee..bd0fe2c6624e 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -16,6 +16,7 @@
#include <linux/platform_device.h>
#include <linux/reset.h>
+#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_framebuffer.h>
@@ -249,10 +250,73 @@ int sun8i_mixer_drm_format_to_hw(u32 format, u32 *hw_format)
return -EINVAL;
}
-static void sun8i_mixer_commit(struct sunxi_engine *engine)
+static void sun8i_layer_enable(struct sun8i_layer *layer, bool enable)
{
+ u32 ch_base = sun8i_channel_base(layer->mixer, layer->channel);
+ u32 val, reg, mask;
+
+ if (layer->type == SUN8I_LAYER_TYPE_UI) {
+ val = enable ? SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN : 0;
+ mask = SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN;
+ reg = SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ch_base, layer->overlay);
+ } else {
+ val = enable ? SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN : 0;
+ mask = SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN;
+ reg = SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, layer->overlay);
+ }
+
+ regmap_update_bits(layer->mixer->engine.regs, reg, mask, val);
+}
+
+static void sun8i_mixer_commit(struct sunxi_engine *engine,
+ struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
+{
+ struct sun8i_mixer *mixer = engine_to_sun8i_mixer(engine);
+ u32 bld_base = sun8i_blender_base(mixer);
+ struct drm_plane_state *plane_state;
+ struct drm_plane *plane;
+ u32 route = 0, pipe_en = 0;
+
DRM_DEBUG_DRIVER("Committing changes\n");
+ drm_for_each_plane(plane, state->dev) {
+ struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
+ bool enable;
+ int zpos;
+
+ if (!(plane->possible_crtcs & drm_crtc_mask(crtc)) || layer->mixer != mixer)
+ continue;
+
+ plane_state = drm_atomic_get_new_plane_state(state, plane);
+ if (!plane_state)
+ plane_state = plane->state;
+
+ enable = plane_state->crtc && plane_state->visible;
+ zpos = plane_state->normalized_zpos;
+
+ DRM_DEBUG_DRIVER(" plane %d: chan=%d ovl=%d en=%d zpos=%d\n",
+ plane->base.id, layer->channel, layer->overlay,
+ enable, zpos);
+
+ /*
+ * We always update the layer enable bit, because it can clear
+ * spontaneously for unknown reasons.
+ */
+ sun8i_layer_enable(layer, enable);
+
+ if (!enable)
+ continue;
+
+ /* Route layer to pipe based on zpos */
+ route |= layer->channel << SUN8I_MIXER_BLEND_ROUTE_PIPE_SHIFT(zpos);
+ pipe_en |= SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos);
+ }
+
+ regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ROUTE(bld_base), route);
+ regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
+ pipe_en | SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(0));
+
regmap_write(engine->regs, SUN8I_MIXER_GLOBAL_DBUFF,
SUN8I_MIXER_GLOBAL_DBUFF_ENABLE);
}
@@ -271,7 +335,7 @@ static struct drm_plane **sun8i_layers_init(struct drm_device *drm,
return ERR_PTR(-ENOMEM);
for (i = 0; i < mixer->cfg->vi_num; i++) {
- struct sun8i_vi_layer *layer;
+ struct sun8i_layer *layer;
layer = sun8i_vi_layer_init_one(drm, mixer, i);
if (IS_ERR(layer)) {
@@ -284,7 +348,7 @@ static struct drm_plane **sun8i_layers_init(struct drm_device *drm,
}
for (i = 0; i < mixer->cfg->ui_num; i++) {
- struct sun8i_ui_layer *layer;
+ struct sun8i_layer *layer;
layer = sun8i_ui_layer_init_one(drm, mixer, i);
if (IS_ERR(layer)) {
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h
index 85c94884fb9a..d7898c9c9cc0 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
@@ -9,6 +9,7 @@
#include <linux/clk.h>
#include <linux/regmap.h>
#include <linux/reset.h>
+#include <drm/drm_plane.h>
#include "sunxi_engine.h"
@@ -185,6 +186,25 @@ struct sun8i_mixer {
struct clk *mod_clk;
};
+enum {
+ SUN8I_LAYER_TYPE_UI,
+ SUN8I_LAYER_TYPE_VI,
+};
+
+struct sun8i_layer {
+ struct drm_plane plane;
+ struct sun8i_mixer *mixer;
+ int type;
+ int channel;
+ int overlay;
+};
+
+static inline struct sun8i_layer *
+plane_to_sun8i_layer(struct drm_plane *plane)
+{
+ return container_of(plane, struct sun8i_layer, plane);
+}
+
static inline struct sun8i_mixer *
engine_to_sun8i_mixer(struct sunxi_engine *engine)
{
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
index ca75ca0835a6..b90e5edef4e8 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
@@ -24,55 +24,6 @@
#include "sun8i_ui_layer.h"
#include "sun8i_ui_scaler.h"
-static void sun8i_ui_layer_enable(struct sun8i_mixer *mixer, int channel,
- int overlay, bool enable, unsigned int zpos,
- unsigned int old_zpos)
-{
- u32 val, bld_base, ch_base;
-
- bld_base = sun8i_blender_base(mixer);
- ch_base = sun8i_channel_base(mixer, channel);
-
- DRM_DEBUG_DRIVER("%sabling channel %d overlay %d\n",
- enable ? "En" : "Dis", channel, overlay);
-
- if (enable)
- val = SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN;
- else
- val = 0;
-
- regmap_update_bits(mixer->engine.regs,
- SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ch_base, overlay),
- SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN, val);
-
- if (!enable || zpos != old_zpos) {
- regmap_update_bits(mixer->engine.regs,
- SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
- SUN8I_MIXER_BLEND_PIPE_CTL_EN(old_zpos),
- 0);
-
- regmap_update_bits(mixer->engine.regs,
- SUN8I_MIXER_BLEND_ROUTE(bld_base),
- SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(old_zpos),
- 0);
- }
-
- if (enable) {
- val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos);
-
- regmap_update_bits(mixer->engine.regs,
- SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
- val, val);
-
- val = channel << SUN8I_MIXER_BLEND_ROUTE_PIPE_SHIFT(zpos);
-
- regmap_update_bits(mixer->engine.regs,
- SUN8I_MIXER_BLEND_ROUTE(bld_base),
- SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(zpos),
- val);
- }
-}
-
static void sun8i_ui_layer_update_alpha(struct sun8i_mixer *mixer, int channel,
int overlay, struct drm_plane *plane)
{
@@ -232,7 +183,7 @@ static int sun8i_ui_layer_atomic_check(struct drm_plane *plane,
{
struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
plane);
- struct sun8i_ui_layer *layer = plane_to_sun8i_ui_layer(plane);
+ struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
struct drm_crtc *crtc = new_plane_state->crtc;
struct drm_crtc_state *crtc_state;
int min_scale, max_scale;
@@ -259,36 +210,18 @@ static int sun8i_ui_layer_atomic_check(struct drm_plane *plane,
true, true);
}
-static void sun8i_ui_layer_atomic_disable(struct drm_plane *plane,
- struct drm_atomic_state *state)
-{
- struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
- plane);
- struct sun8i_ui_layer *layer = plane_to_sun8i_ui_layer(plane);
- unsigned int old_zpos = old_state->normalized_zpos;
- struct sun8i_mixer *mixer = layer->mixer;
-
- sun8i_ui_layer_enable(mixer, layer->channel, layer->overlay, false, 0,
- old_zpos);
-}
static void sun8i_ui_layer_atomic_update(struct drm_plane *plane,
struct drm_atomic_state *state)
{
- struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
- plane);
struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
plane);
- struct sun8i_ui_layer *layer = plane_to_sun8i_ui_layer(plane);
+ struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
unsigned int zpos = new_state->normalized_zpos;
- unsigned int old_zpos = old_state->normalized_zpos;
struct sun8i_mixer *mixer = layer->mixer;
- if (!new_state->visible) {
- sun8i_ui_layer_enable(mixer, layer->channel,
- layer->overlay, false, 0, old_zpos);
+ if (!new_state->crtc || !new_state->visible)
return;
- }
sun8i_ui_layer_update_coord(mixer, layer->channel,
layer->overlay, plane, zpos);
@@ -298,13 +231,10 @@ static void sun8i_ui_layer_atomic_update(struct drm_plane *plane,
layer->overlay, plane);
sun8i_ui_layer_update_buffer(mixer, layer->channel,
layer->overlay, plane);
- sun8i_ui_layer_enable(mixer, layer->channel, layer->overlay,
- true, zpos, old_zpos);
}
static const struct drm_plane_helper_funcs sun8i_ui_layer_helper_funcs = {
.atomic_check = sun8i_ui_layer_atomic_check,
- .atomic_disable = sun8i_ui_layer_atomic_disable,
.atomic_update = sun8i_ui_layer_atomic_update,
};
@@ -345,13 +275,13 @@ static const uint64_t sun8i_layer_modifiers[] = {
DRM_FORMAT_MOD_INVALID
};
-struct sun8i_ui_layer *sun8i_ui_layer_init_one(struct drm_device *drm,
- struct sun8i_mixer *mixer,
- int index)
+struct sun8i_layer *sun8i_ui_layer_init_one(struct drm_device *drm,
+ struct sun8i_mixer *mixer,
+ int index)
{
enum drm_plane_type type = DRM_PLANE_TYPE_OVERLAY;
int channel = mixer->cfg->vi_num + index;
- struct sun8i_ui_layer *layer;
+ struct sun8i_layer *layer;
unsigned int plane_cnt;
int ret;
@@ -390,6 +320,7 @@ struct sun8i_ui_layer *sun8i_ui_layer_init_one(struct drm_device *drm,
drm_plane_helper_add(&layer->plane, &sun8i_ui_layer_helper_funcs);
layer->mixer = mixer;
+ layer->type = SUN8I_LAYER_TYPE_UI;
layer->channel = channel;
layer->overlay = 0;
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.h b/drivers/gpu/drm/sun4i/sun8i_ui_layer.h
index e3e32ee1178d..83892f6ff211 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.h
@@ -47,21 +47,9 @@
#define SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MODE_COMBINED ((2) << 1)
struct sun8i_mixer;
+struct sun8i_layer;
-struct sun8i_ui_layer {
- struct drm_plane plane;
- struct sun8i_mixer *mixer;
- int channel;
- int overlay;
-};
-
-static inline struct sun8i_ui_layer *
-plane_to_sun8i_ui_layer(struct drm_plane *plane)
-{
- return container_of(plane, struct sun8i_ui_layer, plane);
-}
-
-struct sun8i_ui_layer *sun8i_ui_layer_init_one(struct drm_device *drm,
- struct sun8i_mixer *mixer,
- int index);
+struct sun8i_layer *sun8i_ui_layer_init_one(struct drm_device *drm,
+ struct sun8i_mixer *mixer,
+ int index);
#endif /* _SUN8I_UI_LAYER_H_ */
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
index f9c0a56d3a14..9c09d9c08496 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
@@ -18,55 +18,6 @@
#include "sun8i_vi_layer.h"
#include "sun8i_vi_scaler.h"
-static void sun8i_vi_layer_enable(struct sun8i_mixer *mixer, int channel,
- int overlay, bool enable, unsigned int zpos,
- unsigned int old_zpos)
-{
- u32 val, bld_base, ch_base;
-
- bld_base = sun8i_blender_base(mixer);
- ch_base = sun8i_channel_base(mixer, channel);
-
- DRM_DEBUG_DRIVER("%sabling VI channel %d overlay %d\n",
- enable ? "En" : "Dis", channel, overlay);
-
- if (enable)
- val = SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN;
- else
- val = 0;
-
- regmap_update_bits(mixer->engine.regs,
- SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, overlay),
- SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN, val);
-
- if (!enable || zpos != old_zpos) {
- regmap_update_bits(mixer->engine.regs,
- SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
- SUN8I_MIXER_BLEND_PIPE_CTL_EN(old_zpos),
- 0);
-
- regmap_update_bits(mixer->engine.regs,
- SUN8I_MIXER_BLEND_ROUTE(bld_base),
- SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(old_zpos),
- 0);
- }
-
- if (enable) {
- val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos);
-
- regmap_update_bits(mixer->engine.regs,
- SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
- val, val);
-
- val = channel << SUN8I_MIXER_BLEND_ROUTE_PIPE_SHIFT(zpos);
-
- regmap_update_bits(mixer->engine.regs,
- SUN8I_MIXER_BLEND_ROUTE(bld_base),
- SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(zpos),
- val);
- }
-}
-
static void sun8i_vi_layer_update_alpha(struct sun8i_mixer *mixer, int channel,
int overlay, struct drm_plane *plane)
{
@@ -366,7 +317,7 @@ static int sun8i_vi_layer_atomic_check(struct drm_plane *plane,
{
struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
plane);
- struct sun8i_vi_layer *layer = plane_to_sun8i_vi_layer(plane);
+ struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
struct drm_crtc *crtc = new_plane_state->crtc;
struct drm_crtc_state *crtc_state;
int min_scale, max_scale;
@@ -393,36 +344,17 @@ static int sun8i_vi_layer_atomic_check(struct drm_plane *plane,
true, true);
}
-static void sun8i_vi_layer_atomic_disable(struct drm_plane *plane,
- struct drm_atomic_state *state)
-{
- struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
- plane);
- struct sun8i_vi_layer *layer = plane_to_sun8i_vi_layer(plane);
- unsigned int old_zpos = old_state->normalized_zpos;
- struct sun8i_mixer *mixer = layer->mixer;
-
- sun8i_vi_layer_enable(mixer, layer->channel, layer->overlay, false, 0,
- old_zpos);
-}
-
static void sun8i_vi_layer_atomic_update(struct drm_plane *plane,
struct drm_atomic_state *state)
{
- struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
- plane);
struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
plane);
- struct sun8i_vi_layer *layer = plane_to_sun8i_vi_layer(plane);
+ struct sun8i_layer *layer = plane_to_sun8i_layer(plane);
unsigned int zpos = new_state->normalized_zpos;
- unsigned int old_zpos = old_state->normalized_zpos;
struct sun8i_mixer *mixer = layer->mixer;
- if (!new_state->visible) {
- sun8i_vi_layer_enable(mixer, layer->channel,
- layer->overlay, false, 0, old_zpos);
+ if (!new_state->crtc || !new_state->visible)
return;
- }
sun8i_vi_layer_update_coord(mixer, layer->channel,
layer->overlay, plane, zpos);
@@ -432,13 +364,10 @@ static void sun8i_vi_layer_atomic_update(struct drm_plane *plane,
layer->overlay, plane);
sun8i_vi_layer_update_buffer(mixer, layer->channel,
layer->overlay, plane);
- sun8i_vi_layer_enable(mixer, layer->channel, layer->overlay,
- true, zpos, old_zpos);
}
static const struct drm_plane_helper_funcs sun8i_vi_layer_helper_funcs = {
.atomic_check = sun8i_vi_layer_atomic_check,
- .atomic_disable = sun8i_vi_layer_atomic_disable,
.atomic_update = sun8i_vi_layer_atomic_update,
};
@@ -539,14 +468,14 @@ static const uint64_t sun8i_layer_modifiers[] = {
DRM_FORMAT_MOD_INVALID
};
-struct sun8i_vi_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
- struct sun8i_mixer *mixer,
- int index)
+struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
+ struct sun8i_mixer *mixer,
+ int index)
{
enum drm_plane_type type = DRM_PLANE_TYPE_OVERLAY;
u32 supported_encodings, supported_ranges;
unsigned int plane_cnt, format_count;
- struct sun8i_vi_layer *layer;
+ struct sun8i_layer *layer;
const u32 *formats;
int ret;
@@ -613,6 +542,7 @@ struct sun8i_vi_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
drm_plane_helper_add(&layer->plane, &sun8i_vi_layer_helper_funcs);
layer->mixer = mixer;
+ layer->type = SUN8I_LAYER_TYPE_VI;
layer->channel = index;
layer->overlay = 0;
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
index 48c399e1c86d..655440cdc78f 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h
@@ -52,21 +52,9 @@
#define SUN8I_MIXER_CHAN_VI_DS_M(x) ((x) << 0)
struct sun8i_mixer;
+struct sun8i_layer;
-struct sun8i_vi_layer {
- struct drm_plane plane;
- struct sun8i_mixer *mixer;
- int channel;
- int overlay;
-};
-
-static inline struct sun8i_vi_layer *
-plane_to_sun8i_vi_layer(struct drm_plane *plane)
-{
- return container_of(plane, struct sun8i_vi_layer, plane);
-}
-
-struct sun8i_vi_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
- struct sun8i_mixer *mixer,
- int index);
+struct sun8i_layer *sun8i_vi_layer_init_one(struct drm_device *drm,
+ struct sun8i_mixer *mixer,
+ int index);
#endif /* _SUN8I_VI_LAYER_H_ */
diff --git a/drivers/gpu/drm/sun4i/sunxi_engine.h b/drivers/gpu/drm/sun4i/sunxi_engine.h
index ec8cf9b2bda4..ec0c4932f15c 100644
--- a/drivers/gpu/drm/sun4i/sunxi_engine.h
+++ b/drivers/gpu/drm/sun4i/sunxi_engine.h
@@ -7,6 +7,7 @@
#define _SUNXI_ENGINE_H_
struct drm_plane;
+struct drm_crtc;
struct drm_device;
struct drm_crtc_state;
struct drm_display_mode;
@@ -59,7 +60,9 @@ struct sunxi_engine_ops {
*
* This function is optional.
*/
- void (*commit)(struct sunxi_engine *engine);
+ void (*commit)(struct sunxi_engine *engine,
+ struct drm_crtc *crtc,
+ struct drm_atomic_state *state);
/**
* @layers_init:
@@ -144,12 +147,16 @@ struct sunxi_engine {
/**
* sunxi_engine_commit() - commit all changes of the engine
* @engine: pointer to the engine
+ * @crtc: pointer to crtc the engine is associated with
+ * @state: atomic state
*/
static inline void
-sunxi_engine_commit(struct sunxi_engine *engine)
+sunxi_engine_commit(struct sunxi_engine *engine,
+ struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
{
if (engine->ops && engine->ops->commit)
- engine->ops->commit(engine);
+ engine->ops->commit(engine, crtc, state);
}
/**
diff --git a/drivers/gpu/drm/tests/Makefile b/drivers/gpu/drm/tests/Makefile
index d6183b3d7688..56dab563abd7 100644
--- a/drivers/gpu/drm/tests/Makefile
+++ b/drivers/gpu/drm/tests/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_DRM_KUNIT_TEST) += \
drm_format_test.o \
drm_framebuffer_test.o \
drm_gem_shmem_test.o \
+ drm_hdmi_state_helper_test.o \
drm_managed_test.o \
drm_mm_test.o \
drm_modes_test.o \
diff --git a/drivers/gpu/drm/tests/drm_buddy_test.c b/drivers/gpu/drm/tests/drm_buddy_test.c
index dd8fb9f8341a..9662c949d0e3 100644
--- a/drivers/gpu/drm/tests/drm_buddy_test.c
+++ b/drivers/gpu/drm/tests/drm_buddy_test.c
@@ -774,4 +774,5 @@ static struct kunit_suite drm_buddy_test_suite = {
kunit_test_suite(drm_buddy_test_suite);
MODULE_AUTHOR("Intel Corporation");
+MODULE_DESCRIPTION("Kunit test for drm_buddy functions");
MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/tests/drm_cmdline_parser_test.c b/drivers/gpu/drm/tests/drm_cmdline_parser_test.c
index 88f7f518ffb3..6f1457bd21d9 100644
--- a/drivers/gpu/drm/tests/drm_cmdline_parser_test.c
+++ b/drivers/gpu/drm/tests/drm_cmdline_parser_test.c
@@ -1056,4 +1056,5 @@ static struct kunit_suite drm_cmdline_parser_test_suite = {
kunit_test_suite(drm_cmdline_parser_test_suite);
MODULE_AUTHOR("Maxime Ripard <maxime.ripard@bootlin.com>");
+MODULE_DESCRIPTION("Kunit test for drm_cmdline_parser functions");
MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c
index 44f82ed2a958..2812b123a79c 100644
--- a/drivers/gpu/drm/tests/drm_connector_test.c
+++ b/drivers/gpu/drm/tests/drm_connector_test.c
@@ -8,16 +8,25 @@
#include <drm/drm_atomic_state_helper.h>
#include <drm/drm_connector.h>
#include <drm/drm_drv.h>
+#include <drm/drm_edid.h>
#include <drm/drm_kunit_helpers.h>
+#include <drm/drm_modes.h>
+
+#include <drm/display/drm_hdmi_helper.h>
#include <kunit/test.h>
+#include "../drm_crtc_internal.h"
+
struct drm_connector_init_priv {
struct drm_device drm;
struct drm_connector connector;
struct i2c_adapter ddc;
};
+static const struct drm_connector_hdmi_funcs dummy_hdmi_funcs = {
+};
+
static const struct drm_connector_funcs dummy_funcs = {
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
@@ -172,6 +181,573 @@ static struct kunit_suite drmm_connector_init_test_suite = {
.test_cases = drmm_connector_init_tests,
};
+/*
+ * Test that the registration of a bog standard connector works as
+ * expected and doesn't report any error.
+ */
+static void drm_test_connector_hdmi_init_valid(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ int ret;
+
+ ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+ "Vendor", "Product",
+ &dummy_funcs,
+ &dummy_hdmi_funcs,
+ DRM_MODE_CONNECTOR_HDMIA,
+ &priv->ddc,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+}
+
+/*
+ * Test that the registration of a connector without a DDC adapter
+ * doesn't report any error.
+ */
+static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ int ret;
+
+ ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+ "Vendor", "Product",
+ &dummy_funcs,
+ &dummy_hdmi_funcs,
+ DRM_MODE_CONNECTOR_HDMIA,
+ NULL,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+}
+
+/*
+ * Test that the registration of an HDMI connector with a NULL vendor
+ * fails.
+ */
+static void drm_test_connector_hdmi_init_null_vendor(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ int ret;
+
+ ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+ NULL, "Product",
+ &dummy_funcs,
+ &dummy_hdmi_funcs,
+ DRM_MODE_CONNECTOR_HDMIA,
+ &priv->ddc,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+/*
+ * Test that the registration of an HDMI connector with a NULL product
+ * fails.
+ */
+static void drm_test_connector_hdmi_init_null_product(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ int ret;
+
+ ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+ "Vendor", NULL,
+ &dummy_funcs,
+ &dummy_hdmi_funcs,
+ DRM_MODE_CONNECTOR_HDMIA,
+ &priv->ddc,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+/*
+ * Test that the registration of a connector with a valid, shorter than
+ * the max length, product name succeeds, and is stored padded with 0.
+ */
+static void drm_test_connector_hdmi_init_product_valid(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ const unsigned char expected_product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] = {
+ 'P', 'r', 'o', 'd',
+ };
+ const char *product_name = "Prod";
+ int ret;
+
+ KUNIT_ASSERT_LT(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN);
+
+ ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+ "Vendor", product_name,
+ &dummy_funcs,
+ &dummy_hdmi_funcs,
+ DRM_MODE_CONNECTOR_HDMIA,
+ &priv->ddc,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_MEMEQ(test,
+ priv->connector.hdmi.product,
+ expected_product,
+ sizeof(priv->connector.hdmi.product));
+}
+
+/*
+ * Test that the registration of a connector with a valid, at max
+ * length, product name succeeds, and is stored padded without any
+ * trailing \0.
+ */
+static void drm_test_connector_hdmi_init_product_length_exact(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ const unsigned char expected_product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] = {
+ 'P', 'r', 'o', 'd', 'u', 'c', 't',
+ 'P', 'r', 'o', 'd', 'u', 'c', 't',
+ 'P', 'r',
+ };
+ const char *product_name = "ProductProductPr";
+ int ret;
+
+ KUNIT_ASSERT_EQ(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN);
+
+ ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+ "Vendor", product_name,
+ &dummy_funcs,
+ &dummy_hdmi_funcs,
+ DRM_MODE_CONNECTOR_HDMIA,
+ &priv->ddc,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_MEMEQ(test,
+ priv->connector.hdmi.product,
+ expected_product,
+ sizeof(priv->connector.hdmi.product));
+}
+
+/*
+ * Test that the registration of a connector with a product name larger
+ * than the maximum length fails.
+ */
+static void drm_test_connector_hdmi_init_product_length_too_long(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ const char *product_name = "ProductProductProduct";
+ int ret;
+
+ KUNIT_ASSERT_GT(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN);
+
+ ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+ "Vendor", product_name,
+ &dummy_funcs,
+ &dummy_hdmi_funcs,
+ DRM_MODE_CONNECTOR_HDMIA,
+ &priv->ddc,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+/*
+ * Test that the registration of a connector with a vendor name smaller
+ * than the maximum length succeeds, and is stored padded with zeros.
+ */
+static void drm_test_connector_hdmi_init_vendor_valid(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ const char expected_vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] = {
+ 'V', 'e', 'n', 'd',
+ };
+ const char *vendor_name = "Vend";
+ int ret;
+
+ KUNIT_ASSERT_LT(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN);
+
+ ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+ vendor_name, "Product",
+ &dummy_funcs,
+ &dummy_hdmi_funcs,
+ DRM_MODE_CONNECTOR_HDMIA,
+ &priv->ddc,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_MEMEQ(test,
+ priv->connector.hdmi.vendor,
+ expected_vendor,
+ sizeof(priv->connector.hdmi.vendor));
+}
+
+/*
+ * Test that the registration of a connector with a vendor name at the
+ * maximum length succeeds, and is stored padded without the trailing
+ * zero.
+ */
+static void drm_test_connector_hdmi_init_vendor_length_exact(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ const char expected_vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] = {
+ 'V', 'e', 'n', 'd', 'o', 'r',
+ 'V', 'e',
+ };
+ const char *vendor_name = "VendorVe";
+ int ret;
+
+ KUNIT_ASSERT_EQ(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN);
+
+ ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+ vendor_name, "Product",
+ &dummy_funcs,
+ &dummy_hdmi_funcs,
+ DRM_MODE_CONNECTOR_HDMIA,
+ &priv->ddc,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_MEMEQ(test,
+ priv->connector.hdmi.vendor,
+ expected_vendor,
+ sizeof(priv->connector.hdmi.vendor));
+}
+
+/*
+ * Test that the registration of a connector with a vendor name larger
+ * than the maximum length fails.
+ */
+static void drm_test_connector_hdmi_init_vendor_length_too_long(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ const char *vendor_name = "VendorVendor";
+ int ret;
+
+ KUNIT_ASSERT_GT(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN);
+
+ ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+ vendor_name, "Product",
+ &dummy_funcs,
+ &dummy_hdmi_funcs,
+ DRM_MODE_CONNECTOR_HDMIA,
+ &priv->ddc,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+/*
+ * Test that the registration of a connector with an invalid maximum bpc
+ * count fails.
+ */
+static void drm_test_connector_hdmi_init_bpc_invalid(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ int ret;
+
+ ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+ "Vendor", "Product",
+ &dummy_funcs,
+ &dummy_hdmi_funcs,
+ DRM_MODE_CONNECTOR_HDMIA,
+ &priv->ddc,
+ BIT(HDMI_COLORSPACE_RGB),
+ 9);
+ KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+/*
+ * Test that the registration of a connector with a null maximum bpc
+ * count fails.
+ */
+static void drm_test_connector_hdmi_init_bpc_null(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ int ret;
+
+ ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+ "Vendor", "Product",
+ &dummy_funcs,
+ &dummy_hdmi_funcs,
+ DRM_MODE_CONNECTOR_HDMIA,
+ &priv->ddc,
+ BIT(HDMI_COLORSPACE_RGB),
+ 0);
+ KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+/*
+ * Test that the registration of a connector with a maximum bpc count of
+ * 8 succeeds, registers the max bpc property, but doesn't register the
+ * HDR output metadata one.
+ */
+static void drm_test_connector_hdmi_init_bpc_8(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ struct drm_connector_state *state;
+ struct drm_connector *connector = &priv->connector;
+ struct drm_property *prop;
+ uint64_t val;
+ int ret;
+
+ ret = drmm_connector_hdmi_init(&priv->drm, connector,
+ "Vendor", "Product",
+ &dummy_funcs,
+ &dummy_hdmi_funcs,
+ DRM_MODE_CONNECTOR_HDMIA,
+ &priv->ddc,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+
+ prop = connector->max_bpc_property;
+ KUNIT_ASSERT_NOT_NULL(test, prop);
+ KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
+
+ ret = drm_object_property_get_default_value(&connector->base, prop, &val);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_EQ(test, val, 8);
+
+ state = connector->state;
+ KUNIT_EXPECT_EQ(test, state->max_bpc, 8);
+ KUNIT_EXPECT_EQ(test, state->max_requested_bpc, 8);
+
+ prop = priv->drm.mode_config.hdr_output_metadata_property;
+ KUNIT_ASSERT_NOT_NULL(test, prop);
+ KUNIT_EXPECT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
+}
+
+/*
+ * Test that the registration of a connector with a maximum bpc count of
+ * 10 succeeds and registers the max bpc and HDR output metadata
+ * properties.
+ */
+static void drm_test_connector_hdmi_init_bpc_10(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ struct drm_connector_state *state;
+ struct drm_connector *connector = &priv->connector;
+ struct drm_property *prop;
+ uint64_t val;
+ int ret;
+
+ ret = drmm_connector_hdmi_init(&priv->drm, connector,
+ "Vendor", "Product",
+ &dummy_funcs,
+ &dummy_hdmi_funcs,
+ DRM_MODE_CONNECTOR_HDMIA,
+ &priv->ddc,
+ BIT(HDMI_COLORSPACE_RGB),
+ 10);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+
+ prop = connector->max_bpc_property;
+ KUNIT_ASSERT_NOT_NULL(test, prop);
+ KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
+
+ ret = drm_object_property_get_default_value(&connector->base, prop, &val);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_EQ(test, val, 10);
+
+ state = connector->state;
+ KUNIT_EXPECT_EQ(test, state->max_bpc, 10);
+ KUNIT_EXPECT_EQ(test, state->max_requested_bpc, 10);
+
+ prop = priv->drm.mode_config.hdr_output_metadata_property;
+ KUNIT_ASSERT_NOT_NULL(test, prop);
+ KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
+}
+
+/*
+ * Test that the registration of a connector with a maximum bpc count of
+ * 12 succeeds and registers the max bpc and HDR output metadata
+ * properties.
+ */
+static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ struct drm_connector_state *state;
+ struct drm_connector *connector = &priv->connector;
+ struct drm_property *prop;
+ uint64_t val;
+ int ret;
+
+ ret = drmm_connector_hdmi_init(&priv->drm, connector,
+ "Vendor", "Product",
+ &dummy_funcs,
+ &dummy_hdmi_funcs,
+ DRM_MODE_CONNECTOR_HDMIA,
+ &priv->ddc,
+ BIT(HDMI_COLORSPACE_RGB),
+ 12);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+
+ prop = connector->max_bpc_property;
+ KUNIT_ASSERT_NOT_NULL(test, prop);
+ KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
+
+ ret = drm_object_property_get_default_value(&connector->base, prop, &val);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+ KUNIT_EXPECT_EQ(test, val, 12);
+
+ state = connector->state;
+ KUNIT_EXPECT_EQ(test, state->max_bpc, 12);
+ KUNIT_EXPECT_EQ(test, state->max_requested_bpc, 12);
+
+ prop = priv->drm.mode_config.hdr_output_metadata_property;
+ KUNIT_ASSERT_NOT_NULL(test, prop);
+ KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
+}
+
+/*
+ * Test that the registration of an HDMI connector with no supported
+ * format fails.
+ */
+static void drm_test_connector_hdmi_init_formats_empty(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ int ret;
+
+ ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+ "Vendor", "Product",
+ &dummy_funcs,
+ &dummy_hdmi_funcs,
+ DRM_MODE_CONNECTOR_HDMIA,
+ &priv->ddc,
+ 0,
+ 8);
+ KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+/*
+ * Test that the registration of an HDMI connector not listing RGB as a
+ * supported format fails.
+ */
+static void drm_test_connector_hdmi_init_formats_no_rgb(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ int ret;
+
+ ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+ "Vendor", "Product",
+ &dummy_funcs,
+ &dummy_hdmi_funcs,
+ DRM_MODE_CONNECTOR_HDMIA,
+ &priv->ddc,
+ BIT(HDMI_COLORSPACE_YUV422),
+ 8);
+ KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+/*
+ * Test that the registration of an HDMI connector with an HDMI
+ * connector type succeeds.
+ */
+static void drm_test_connector_hdmi_init_type_valid(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ unsigned int connector_type = *(unsigned int *)test->param_value;
+ int ret;
+
+ ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+ "Vendor", "Product",
+ &dummy_funcs,
+ &dummy_hdmi_funcs,
+ connector_type,
+ &priv->ddc,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+}
+
+static const unsigned int drm_connector_hdmi_init_type_valid_tests[] = {
+ DRM_MODE_CONNECTOR_HDMIA,
+ DRM_MODE_CONNECTOR_HDMIB,
+};
+
+static void drm_connector_hdmi_init_type_desc(const unsigned int *type, char *desc)
+{
+ sprintf(desc, "%s", drm_get_connector_type_name(*type));
+}
+
+KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_valid,
+ drm_connector_hdmi_init_type_valid_tests,
+ drm_connector_hdmi_init_type_desc);
+
+/*
+ * Test that the registration of an HDMI connector with an !HDMI
+ * connector type fails.
+ */
+static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ unsigned int connector_type = *(unsigned int *)test->param_value;
+ int ret;
+
+ ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
+ "Vendor", "Product",
+ &dummy_funcs,
+ &dummy_hdmi_funcs,
+ connector_type,
+ &priv->ddc,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+static const unsigned int drm_connector_hdmi_init_type_invalid_tests[] = {
+ DRM_MODE_CONNECTOR_Unknown,
+ DRM_MODE_CONNECTOR_VGA,
+ DRM_MODE_CONNECTOR_DVII,
+ DRM_MODE_CONNECTOR_DVID,
+ DRM_MODE_CONNECTOR_DVIA,
+ DRM_MODE_CONNECTOR_Composite,
+ DRM_MODE_CONNECTOR_SVIDEO,
+ DRM_MODE_CONNECTOR_LVDS,
+ DRM_MODE_CONNECTOR_Component,
+ DRM_MODE_CONNECTOR_9PinDIN,
+ DRM_MODE_CONNECTOR_DisplayPort,
+ DRM_MODE_CONNECTOR_TV,
+ DRM_MODE_CONNECTOR_eDP,
+ DRM_MODE_CONNECTOR_VIRTUAL,
+ DRM_MODE_CONNECTOR_DSI,
+ DRM_MODE_CONNECTOR_DPI,
+ DRM_MODE_CONNECTOR_WRITEBACK,
+ DRM_MODE_CONNECTOR_SPI,
+ DRM_MODE_CONNECTOR_USB,
+};
+
+KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_invalid,
+ drm_connector_hdmi_init_type_invalid_tests,
+ drm_connector_hdmi_init_type_desc);
+
+static struct kunit_case drmm_connector_hdmi_init_tests[] = {
+ KUNIT_CASE(drm_test_connector_hdmi_init_valid),
+ KUNIT_CASE(drm_test_connector_hdmi_init_bpc_8),
+ KUNIT_CASE(drm_test_connector_hdmi_init_bpc_10),
+ KUNIT_CASE(drm_test_connector_hdmi_init_bpc_12),
+ KUNIT_CASE(drm_test_connector_hdmi_init_bpc_invalid),
+ KUNIT_CASE(drm_test_connector_hdmi_init_bpc_null),
+ KUNIT_CASE(drm_test_connector_hdmi_init_formats_empty),
+ KUNIT_CASE(drm_test_connector_hdmi_init_formats_no_rgb),
+ KUNIT_CASE(drm_test_connector_hdmi_init_null_ddc),
+ KUNIT_CASE(drm_test_connector_hdmi_init_null_product),
+ KUNIT_CASE(drm_test_connector_hdmi_init_null_vendor),
+ KUNIT_CASE(drm_test_connector_hdmi_init_product_length_exact),
+ KUNIT_CASE(drm_test_connector_hdmi_init_product_length_too_long),
+ KUNIT_CASE(drm_test_connector_hdmi_init_product_valid),
+ KUNIT_CASE(drm_test_connector_hdmi_init_vendor_length_exact),
+ KUNIT_CASE(drm_test_connector_hdmi_init_vendor_length_too_long),
+ KUNIT_CASE(drm_test_connector_hdmi_init_vendor_valid),
+ KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_valid,
+ drm_connector_hdmi_init_type_valid_gen_params),
+ KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_invalid,
+ drm_connector_hdmi_init_type_invalid_gen_params),
+ { }
+};
+
+static struct kunit_suite drmm_connector_hdmi_init_test_suite = {
+ .name = "drmm_connector_hdmi_init",
+ .init = drm_test_connector_init,
+ .test_cases = drmm_connector_hdmi_init_tests,
+};
+
struct drm_get_tv_mode_from_name_test {
const char *name;
enum drm_connector_tv_mode expected_mode;
@@ -235,10 +811,484 @@ static struct kunit_suite drm_get_tv_mode_from_name_test_suite = {
.test_cases = drm_get_tv_mode_from_name_tests,
};
+struct drm_hdmi_connector_get_broadcast_rgb_name_test {
+ unsigned int kind;
+ const char *expected_name;
+};
+
+#define BROADCAST_RGB_TEST(_kind, _name) \
+ { \
+ .kind = _kind, \
+ .expected_name = _name, \
+ }
+
+static void drm_test_drm_hdmi_connector_get_broadcast_rgb_name(struct kunit *test)
+{
+ const struct drm_hdmi_connector_get_broadcast_rgb_name_test *params =
+ test->param_value;
+
+ KUNIT_EXPECT_STREQ(test,
+ drm_hdmi_connector_get_broadcast_rgb_name(params->kind),
+ params->expected_name);
+}
+
+static const
+struct drm_hdmi_connector_get_broadcast_rgb_name_test
+drm_hdmi_connector_get_broadcast_rgb_name_valid_tests[] = {
+ BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_AUTO, "Automatic"),
+ BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_FULL, "Full"),
+ BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_LIMITED, "Limited 16:235"),
+};
+
+static void
+drm_hdmi_connector_get_broadcast_rgb_name_valid_desc(const struct drm_hdmi_connector_get_broadcast_rgb_name_test *t,
+ char *desc)
+{
+ sprintf(desc, "%s", t->expected_name);
+}
+
+KUNIT_ARRAY_PARAM(drm_hdmi_connector_get_broadcast_rgb_name_valid,
+ drm_hdmi_connector_get_broadcast_rgb_name_valid_tests,
+ drm_hdmi_connector_get_broadcast_rgb_name_valid_desc);
+
+static void drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid(struct kunit *test)
+{
+ KUNIT_EXPECT_NULL(test, drm_hdmi_connector_get_broadcast_rgb_name(3));
+};
+
+static struct kunit_case drm_hdmi_connector_get_broadcast_rgb_name_tests[] = {
+ KUNIT_CASE_PARAM(drm_test_drm_hdmi_connector_get_broadcast_rgb_name,
+ drm_hdmi_connector_get_broadcast_rgb_name_valid_gen_params),
+ KUNIT_CASE(drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid),
+ { }
+};
+
+static struct kunit_suite drm_hdmi_connector_get_broadcast_rgb_name_test_suite = {
+ .name = "drm_hdmi_connector_get_broadcast_rgb_name",
+ .test_cases = drm_hdmi_connector_get_broadcast_rgb_name_tests,
+};
+
+struct drm_hdmi_connector_get_output_format_name_test {
+ unsigned int kind;
+ const char *expected_name;
+};
+
+#define OUTPUT_FORMAT_TEST(_kind, _name) \
+ { \
+ .kind = _kind, \
+ .expected_name = _name, \
+ }
+
+static void drm_test_drm_hdmi_connector_get_output_format_name(struct kunit *test)
+{
+ const struct drm_hdmi_connector_get_output_format_name_test *params =
+ test->param_value;
+
+ KUNIT_EXPECT_STREQ(test,
+ drm_hdmi_connector_get_output_format_name(params->kind),
+ params->expected_name);
+}
+
+static const
+struct drm_hdmi_connector_get_output_format_name_test
+drm_hdmi_connector_get_output_format_name_valid_tests[] = {
+ OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_RGB, "RGB"),
+ OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV420, "YUV 4:2:0"),
+ OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV422, "YUV 4:2:2"),
+ OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV444, "YUV 4:4:4"),
+};
+
+static void
+drm_hdmi_connector_get_output_format_name_valid_desc(const struct drm_hdmi_connector_get_output_format_name_test *t,
+ char *desc)
+{
+ sprintf(desc, "%s", t->expected_name);
+}
+
+KUNIT_ARRAY_PARAM(drm_hdmi_connector_get_output_format_name_valid,
+ drm_hdmi_connector_get_output_format_name_valid_tests,
+ drm_hdmi_connector_get_output_format_name_valid_desc);
+
+static void drm_test_drm_hdmi_connector_get_output_format_name_invalid(struct kunit *test)
+{
+ KUNIT_EXPECT_NULL(test, drm_hdmi_connector_get_output_format_name(4));
+};
+
+static struct kunit_case drm_hdmi_connector_get_output_format_name_tests[] = {
+ KUNIT_CASE_PARAM(drm_test_drm_hdmi_connector_get_output_format_name,
+ drm_hdmi_connector_get_output_format_name_valid_gen_params),
+ KUNIT_CASE(drm_test_drm_hdmi_connector_get_output_format_name_invalid),
+ { }
+};
+
+static struct kunit_suite drm_hdmi_connector_get_output_format_name_test_suite = {
+ .name = "drm_hdmi_connector_get_output_format_name",
+ .test_cases = drm_hdmi_connector_get_output_format_name_tests,
+};
+
+static void drm_test_drm_connector_attach_broadcast_rgb_property(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ struct drm_connector *connector = &priv->connector;
+ struct drm_property *prop;
+ int ret;
+
+ ret = drmm_connector_init(&priv->drm, connector,
+ &dummy_funcs,
+ DRM_MODE_CONNECTOR_HDMIA,
+ &priv->ddc);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ ret = drm_connector_attach_broadcast_rgb_property(connector);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ prop = connector->broadcast_rgb_property;
+ KUNIT_ASSERT_NOT_NULL(test, prop);
+ KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
+}
+
+static void drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ struct drm_connector *connector = &priv->connector;
+ struct drm_property *prop;
+ int ret;
+
+ ret = drmm_connector_hdmi_init(&priv->drm, connector,
+ "Vendor", "Product",
+ &dummy_funcs,
+ &dummy_hdmi_funcs,
+ DRM_MODE_CONNECTOR_HDMIA,
+ &priv->ddc,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+
+ ret = drm_connector_attach_broadcast_rgb_property(connector);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ prop = connector->broadcast_rgb_property;
+ KUNIT_ASSERT_NOT_NULL(test, prop);
+ KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
+}
+
+static struct kunit_case drm_connector_attach_broadcast_rgb_property_tests[] = {
+ KUNIT_CASE(drm_test_drm_connector_attach_broadcast_rgb_property),
+ KUNIT_CASE(drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector),
+ { }
+};
+
+static struct kunit_suite drm_connector_attach_broadcast_rgb_property_test_suite = {
+ .name = "drm_connector_attach_broadcast_rgb_property",
+ .init = drm_test_connector_init,
+ .test_cases = drm_connector_attach_broadcast_rgb_property_tests,
+};
+
+/*
+ * Test that for a given mode, with 8bpc and an RGB output the TMDS
+ * character rate is equal to the mode pixel clock.
+ */
+static void drm_test_drm_hdmi_compute_mode_clock_rgb(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ const struct drm_display_mode *mode;
+ unsigned long long rate;
+ struct drm_device *drm = &priv->drm;
+
+ mode = drm_display_mode_from_cea_vic(drm, 16);
+ KUNIT_ASSERT_NOT_NULL(test, mode);
+
+ KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+ rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
+ KUNIT_ASSERT_GT(test, rate, 0);
+ KUNIT_EXPECT_EQ(test, mode->clock * 1000ULL, rate);
+}
+
+/*
+ * Test that for a given mode, with 10bpc and an RGB output the TMDS
+ * character rate is equal to 1.25 times the mode pixel clock.
+ */
+static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ const struct drm_display_mode *mode;
+ unsigned long long rate;
+ struct drm_device *drm = &priv->drm;
+
+ mode = drm_display_mode_from_cea_vic(drm, 16);
+ KUNIT_ASSERT_NOT_NULL(test, mode);
+
+ KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+ rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB);
+ KUNIT_ASSERT_GT(test, rate, 0);
+ KUNIT_EXPECT_EQ(test, mode->clock * 1250, rate);
+}
+
+/*
+ * Test that for the VIC-1 mode, with 10bpc and an RGB output the TMDS
+ * character rate computation fails.
+ */
+static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ const struct drm_display_mode *mode;
+ unsigned long long rate;
+ struct drm_device *drm = &priv->drm;
+
+ mode = drm_display_mode_from_cea_vic(drm, 1);
+ KUNIT_ASSERT_NOT_NULL(test, mode);
+
+ rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB);
+ KUNIT_EXPECT_EQ(test, rate, 0);
+}
+
+/*
+ * Test that for a given mode, with 12bpc and an RGB output the TMDS
+ * character rate is equal to 1.5 times the mode pixel clock.
+ */
+static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ const struct drm_display_mode *mode;
+ unsigned long long rate;
+ struct drm_device *drm = &priv->drm;
+
+ mode = drm_display_mode_from_cea_vic(drm, 16);
+ KUNIT_ASSERT_NOT_NULL(test, mode);
+
+ KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+ rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB);
+ KUNIT_ASSERT_GT(test, rate, 0);
+ KUNIT_EXPECT_EQ(test, mode->clock * 1500, rate);
+}
+
+/*
+ * Test that for the VIC-1 mode, with 12bpc and an RGB output the TMDS
+ * character rate computation fails.
+ */
+static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ const struct drm_display_mode *mode;
+ unsigned long long rate;
+ struct drm_device *drm = &priv->drm;
+
+ mode = drm_display_mode_from_cea_vic(drm, 1);
+ KUNIT_ASSERT_NOT_NULL(test, mode);
+
+ rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB);
+ KUNIT_EXPECT_EQ(test, rate, 0);
+}
+
+/*
+ * Test that for a mode with the pixel repetition flag, the TMDS
+ * character rate is indeed double the mode pixel clock.
+ */
+static void drm_test_drm_hdmi_compute_mode_clock_rgb_double(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ const struct drm_display_mode *mode;
+ unsigned long long rate;
+ struct drm_device *drm = &priv->drm;
+
+ mode = drm_display_mode_from_cea_vic(drm, 6);
+ KUNIT_ASSERT_NOT_NULL(test, mode);
+
+ KUNIT_ASSERT_TRUE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+ rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
+ KUNIT_ASSERT_GT(test, rate, 0);
+ KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) * 2, rate);
+}
+
+/*
+ * Test that the TMDS character rate computation for the VIC modes
+ * explicitly listed in the spec as supporting YUV420 succeed and return
+ * half the mode pixel clock.
+ */
+static void drm_test_connector_hdmi_compute_mode_clock_yuv420_valid(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ const struct drm_display_mode *mode;
+ struct drm_device *drm = &priv->drm;
+ unsigned long long rate;
+ unsigned int vic = *(unsigned int *)test->param_value;
+
+ mode = drm_display_mode_from_cea_vic(drm, vic);
+ KUNIT_ASSERT_NOT_NULL(test, mode);
+
+ KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+ rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV420);
+ KUNIT_ASSERT_GT(test, rate, 0);
+ KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) / 2, rate);
+}
+
+static const unsigned int drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[] = {
+ 96, 97, 101, 102, 106, 107,
+};
+
+static void drm_hdmi_compute_mode_clock_yuv420_vic_desc(const unsigned int *vic, char *desc)
+{
+ sprintf(desc, "VIC %u", *vic);
+}
+
+KUNIT_ARRAY_PARAM(drm_hdmi_compute_mode_clock_yuv420_valid,
+ drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests,
+ drm_hdmi_compute_mode_clock_yuv420_vic_desc);
+
+/*
+ * Test that for a given mode listed supporting it and an YUV420 output
+ * with 10bpc, the TMDS character rate is equal to 0.625 times the mode
+ * pixel clock.
+ */
+static void drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ const struct drm_display_mode *mode;
+ struct drm_device *drm = &priv->drm;
+ unsigned int vic =
+ drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0];
+ unsigned long long rate;
+
+ mode = drm_display_mode_from_cea_vic(drm, vic);
+ KUNIT_ASSERT_NOT_NULL(test, mode);
+
+ KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+ rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV420);
+ KUNIT_ASSERT_GT(test, rate, 0);
+
+ KUNIT_EXPECT_EQ(test, mode->clock * 625, rate);
+}
+
+/*
+ * Test that for a given mode listed supporting it and an YUV420 output
+ * with 12bpc, the TMDS character rate is equal to 0.75 times the mode
+ * pixel clock.
+ */
+static void drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ const struct drm_display_mode *mode;
+ struct drm_device *drm = &priv->drm;
+ unsigned int vic =
+ drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0];
+ unsigned long long rate;
+
+ mode = drm_display_mode_from_cea_vic(drm, vic);
+ KUNIT_ASSERT_NOT_NULL(test, mode);
+
+ KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+ rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV420);
+ KUNIT_ASSERT_GT(test, rate, 0);
+
+ KUNIT_EXPECT_EQ(test, mode->clock * 750, rate);
+}
+
+/*
+ * Test that for a given mode, the computation of the TMDS character
+ * rate with 8bpc and a YUV422 output succeeds and returns a rate equal
+ * to the mode pixel clock.
+ */
+static void drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ const struct drm_display_mode *mode;
+ struct drm_device *drm = &priv->drm;
+ unsigned long long rate;
+
+ mode = drm_display_mode_from_cea_vic(drm, 16);
+ KUNIT_ASSERT_NOT_NULL(test, mode);
+
+ KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+ rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV422);
+ KUNIT_ASSERT_GT(test, rate, 0);
+ KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate);
+}
+
+/*
+ * Test that for a given mode, the computation of the TMDS character
+ * rate with 10bpc and a YUV422 output succeeds and returns a rate equal
+ * to the mode pixel clock.
+ */
+static void drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ const struct drm_display_mode *mode;
+ struct drm_device *drm = &priv->drm;
+ unsigned long long rate;
+
+ mode = drm_display_mode_from_cea_vic(drm, 16);
+ KUNIT_ASSERT_NOT_NULL(test, mode);
+
+ KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+ rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV422);
+ KUNIT_ASSERT_GT(test, rate, 0);
+ KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate);
+}
+
+/*
+ * Test that for a given mode, the computation of the TMDS character
+ * rate with 12bpc and a YUV422 output succeeds and returns a rate equal
+ * to the mode pixel clock.
+ */
+static void drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc(struct kunit *test)
+{
+ struct drm_connector_init_priv *priv = test->priv;
+ const struct drm_display_mode *mode;
+ struct drm_device *drm = &priv->drm;
+ unsigned long long rate;
+
+ mode = drm_display_mode_from_cea_vic(drm, 16);
+ KUNIT_ASSERT_NOT_NULL(test, mode);
+
+ KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
+
+ rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV422);
+ KUNIT_ASSERT_GT(test, rate, 0);
+ KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate);
+}
+
+static struct kunit_case drm_hdmi_compute_mode_clock_tests[] = {
+ KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb),
+ KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc),
+ KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1),
+ KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc),
+ KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1),
+ KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_double),
+ KUNIT_CASE_PARAM(drm_test_connector_hdmi_compute_mode_clock_yuv420_valid,
+ drm_hdmi_compute_mode_clock_yuv420_valid_gen_params),
+ KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc),
+ KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc),
+ KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc),
+ KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc),
+ KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc),
+ { }
+};
+
+static struct kunit_suite drm_hdmi_compute_mode_clock_test_suite = {
+ .name = "drm_test_connector_hdmi_compute_mode_clock",
+ .init = drm_test_connector_init,
+ .test_cases = drm_hdmi_compute_mode_clock_tests,
+};
+
kunit_test_suites(
+ &drmm_connector_hdmi_init_test_suite,
&drmm_connector_init_test_suite,
- &drm_get_tv_mode_from_name_test_suite
+ &drm_connector_attach_broadcast_rgb_property_test_suite,
+ &drm_get_tv_mode_from_name_test_suite,
+ &drm_hdmi_compute_mode_clock_test_suite,
+ &drm_hdmi_connector_get_broadcast_rgb_name_test_suite,
+ &drm_hdmi_connector_get_output_format_name_test_suite
);
MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
+MODULE_DESCRIPTION("Kunit test for drm_modes functions");
MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/tests/drm_damage_helper_test.c b/drivers/gpu/drm/tests/drm_damage_helper_test.c
index 115034fc3421..0df2e1a54b0d 100644
--- a/drivers/gpu/drm/tests/drm_damage_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_damage_helper_test.c
@@ -636,4 +636,5 @@ static struct kunit_suite drm_damage_helper_test_suite = {
kunit_test_suite(drm_damage_helper_test_suite);
+MODULE_DESCRIPTION("Test case for drm_damage_helper functions");
MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c b/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c
index d916e548fcb1..89cd9e4f4d32 100644
--- a/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c
@@ -588,4 +588,5 @@ static struct kunit_suite drm_dp_mst_helper_test_suite = {
kunit_test_suite(drm_dp_mst_helper_test_suite);
+MODULE_DESCRIPTION("Test cases for the DRM DP MST helpers");
MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/tests/drm_exec_test.c b/drivers/gpu/drm/tests/drm_exec_test.c
index 81f928a429ba..d6c4dd1194a0 100644
--- a/drivers/gpu/drm/tests/drm_exec_test.c
+++ b/drivers/gpu/drm/tests/drm_exec_test.c
@@ -210,4 +210,5 @@ static struct kunit_suite drm_exec_test_suite = {
kunit_test_suite(drm_exec_test_suite);
MODULE_AUTHOR("AMD");
+MODULE_DESCRIPTION("Kunit test for drm_exec functions");
MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/gpu/drm/tests/drm_format_test.c b/drivers/gpu/drm/tests/drm_format_test.c
index ec6996ce819a..22e2371fd66a 100644
--- a/drivers/gpu/drm/tests/drm_format_test.c
+++ b/drivers/gpu/drm/tests/drm_format_test.c
@@ -356,4 +356,5 @@ static struct kunit_suite drm_format_test_suite = {
kunit_test_suite(drm_format_test_suite);
+MODULE_DESCRIPTION("Test cases for the drm_format functions");
MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/tests/drm_framebuffer_test.c b/drivers/gpu/drm/tests/drm_framebuffer_test.c
index f759d9f3b76e..06f03b78c9c4 100644
--- a/drivers/gpu/drm/tests/drm_framebuffer_test.c
+++ b/drivers/gpu/drm/tests/drm_framebuffer_test.c
@@ -379,4 +379,5 @@ static struct kunit_suite drm_framebuffer_test_suite = {
kunit_test_suite(drm_framebuffer_test_suite);
+MODULE_DESCRIPTION("Test cases for the drm_framebuffer functions");
MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/tests/drm_gem_shmem_test.c b/drivers/gpu/drm/tests/drm_gem_shmem_test.c
index 91202e40cde9..c3758faa1b83 100644
--- a/drivers/gpu/drm/tests/drm_gem_shmem_test.c
+++ b/drivers/gpu/drm/tests/drm_gem_shmem_test.c
@@ -380,4 +380,5 @@ static struct kunit_suite drm_gem_shmem_suite = {
kunit_test_suite(drm_gem_shmem_suite);
+MODULE_DESCRIPTION("KUnit test suite for GEM objects backed by shmem buffers");
MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
new file mode 100644
index 000000000000..2d3abc71dc16
--- /dev/null
+++ b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
@@ -0,0 +1,1743 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Kunit test for drm_hdmi_state_helper functions
+ */
+
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_state_helper.h>
+#include <drm/drm_atomic_uapi.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_connector.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_kunit_helpers.h>
+#include <drm/drm_managed.h>
+#include <drm/drm_modeset_helper_vtables.h>
+#include <drm/drm_print.h>
+#include <drm/drm_probe_helper.h>
+
+#include <drm/display/drm_hdmi_helper.h>
+#include <drm/display/drm_hdmi_state_helper.h>
+
+#include "../drm_crtc_internal.h"
+
+#include <kunit/test.h>
+
+#include "drm_kunit_edid.h"
+
+struct drm_atomic_helper_connector_hdmi_priv {
+ struct drm_device drm;
+ struct drm_plane *plane;
+ struct drm_crtc *crtc;
+ struct drm_encoder encoder;
+ struct drm_connector connector;
+
+ const char *current_edid;
+ size_t current_edid_len;
+};
+
+#define connector_to_priv(c) \
+ container_of_const(c, struct drm_atomic_helper_connector_hdmi_priv, connector)
+
+static struct drm_display_mode *find_preferred_mode(struct drm_connector *connector)
+{
+ struct drm_device *drm = connector->dev;
+ struct drm_display_mode *mode, *preferred;
+
+ mutex_lock(&drm->mode_config.mutex);
+ preferred = list_first_entry(&connector->modes, struct drm_display_mode, head);
+ list_for_each_entry(mode, &connector->modes, head)
+ if (mode->type & DRM_MODE_TYPE_PREFERRED)
+ preferred = mode;
+ mutex_unlock(&drm->mode_config.mutex);
+
+ return preferred;
+}
+
+static int light_up_connector(struct kunit *test,
+ struct drm_device *drm,
+ struct drm_crtc *crtc,
+ struct drm_connector *connector,
+ struct drm_display_mode *mode,
+ struct drm_modeset_acquire_ctx *ctx)
+{
+ struct drm_atomic_state *state;
+ struct drm_connector_state *conn_state;
+ struct drm_crtc_state *crtc_state;
+ int ret;
+
+ state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+ conn_state = drm_atomic_get_connector_state(state, connector);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+ ret = drm_atomic_set_crtc_for_connector(conn_state, crtc);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+
+ crtc_state = drm_atomic_get_crtc_state(state, crtc);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+
+ ret = drm_atomic_set_mode_for_crtc(crtc_state, mode);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+
+ crtc_state->enable = true;
+ crtc_state->active = true;
+
+ ret = drm_atomic_commit(state);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ return 0;
+}
+
+static int set_connector_edid(struct kunit *test, struct drm_connector *connector,
+ const char *edid, size_t edid_len)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv =
+ connector_to_priv(connector);
+ struct drm_device *drm = connector->dev;
+ int ret;
+
+ priv->current_edid = edid;
+ priv->current_edid_len = edid_len;
+
+ mutex_lock(&drm->mode_config.mutex);
+ ret = connector->funcs->fill_modes(connector, 4096, 4096);
+ mutex_unlock(&drm->mode_config.mutex);
+ KUNIT_ASSERT_GT(test, ret, 0);
+
+ return 0;
+}
+
+static const struct drm_connector_hdmi_funcs dummy_connector_hdmi_funcs = {
+};
+
+static enum drm_mode_status
+reject_connector_tmds_char_rate_valid(const struct drm_connector *connector,
+ const struct drm_display_mode *mode,
+ unsigned long long tmds_rate)
+{
+ return MODE_BAD;
+}
+
+static const struct drm_connector_hdmi_funcs reject_connector_hdmi_funcs = {
+ .tmds_char_rate_valid = reject_connector_tmds_char_rate_valid,
+};
+
+static int dummy_connector_get_modes(struct drm_connector *connector)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv =
+ connector_to_priv(connector);
+ const struct drm_edid *edid;
+ unsigned int num_modes;
+
+ edid = drm_edid_alloc(priv->current_edid, priv->current_edid_len);
+ if (!edid)
+ return -EINVAL;
+
+ drm_edid_connector_update(connector, edid);
+ num_modes = drm_edid_connector_add_modes(connector);
+
+ drm_edid_free(edid);
+
+ return num_modes;
+}
+
+static const struct drm_connector_helper_funcs dummy_connector_helper_funcs = {
+ .atomic_check = drm_atomic_helper_connector_hdmi_check,
+ .get_modes = dummy_connector_get_modes,
+};
+
+static void dummy_hdmi_connector_reset(struct drm_connector *connector)
+{
+ drm_atomic_helper_connector_reset(connector);
+ __drm_atomic_helper_connector_hdmi_reset(connector, connector->state);
+}
+
+static const struct drm_connector_funcs dummy_connector_funcs = {
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .reset = dummy_hdmi_connector_reset,
+};
+
+static
+struct drm_atomic_helper_connector_hdmi_priv *
+drm_atomic_helper_connector_hdmi_init(struct kunit *test,
+ unsigned int formats,
+ unsigned int max_bpc)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_connector *conn;
+ struct drm_encoder *enc;
+ struct drm_device *drm;
+ struct device *dev;
+ int ret;
+
+ dev = drm_kunit_helper_alloc_device(test);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+
+ priv = drm_kunit_helper_alloc_drm_device(test, dev,
+ struct drm_atomic_helper_connector_hdmi_priv, drm,
+ DRIVER_MODESET | DRIVER_ATOMIC);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
+ test->priv = priv;
+
+ drm = &priv->drm;
+ priv->plane = drm_kunit_helper_create_primary_plane(test, drm,
+ NULL,
+ NULL,
+ NULL, 0,
+ NULL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->plane);
+
+ priv->crtc = drm_kunit_helper_create_crtc(test, drm,
+ priv->plane, NULL,
+ NULL,
+ NULL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->crtc);
+
+ enc = &priv->encoder;
+ ret = drmm_encoder_init(drm, enc, NULL, DRM_MODE_ENCODER_TMDS, NULL);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ enc->possible_crtcs = drm_crtc_mask(priv->crtc);
+
+ conn = &priv->connector;
+ ret = drmm_connector_hdmi_init(drm, conn,
+ "Vendor", "Product",
+ &dummy_connector_funcs,
+ &dummy_connector_hdmi_funcs,
+ DRM_MODE_CONNECTOR_HDMIA,
+ NULL,
+ formats,
+ max_bpc);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ drm_connector_helper_add(conn, &dummy_connector_helper_funcs);
+ drm_connector_attach_encoder(conn, enc);
+
+ drm_mode_config_reset(drm);
+
+ ret = set_connector_edid(test, conn,
+ test_edid_hdmi_1080p_rgb_max_200mhz,
+ ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz));
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ return priv;
+}
+
+/*
+ * Test that if we change the RGB quantization property to a different
+ * value, we trigger a mode change on the connector's CRTC, which will
+ * in turn disable/enable the connector.
+ */
+static void drm_test_check_broadcast_rgb_crtc_mode_changed(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_modeset_acquire_ctx *ctx;
+ struct drm_connector_state *old_conn_state;
+ struct drm_connector_state *new_conn_state;
+ struct drm_crtc_state *crtc_state;
+ struct drm_atomic_state *state;
+ struct drm_display_mode *preferred;
+ struct drm_connector *conn;
+ struct drm_device *drm;
+ struct drm_crtc *crtc;
+ int ret;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+ conn = &priv->connector;
+ preferred = find_preferred_mode(conn);
+ KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+ drm = &priv->drm;
+ crtc = priv->crtc;
+ ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+ new_conn_state = drm_atomic_get_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
+
+ old_conn_state = drm_atomic_get_old_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
+
+ new_conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL;
+
+ KUNIT_ASSERT_NE(test,
+ old_conn_state->hdmi.broadcast_rgb,
+ new_conn_state->hdmi.broadcast_rgb);
+
+ ret = drm_atomic_check_only(state);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ new_conn_state = drm_atomic_get_new_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
+ KUNIT_EXPECT_EQ(test, new_conn_state->hdmi.broadcast_rgb, DRM_HDMI_BROADCAST_RGB_FULL);
+
+ crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+ KUNIT_EXPECT_TRUE(test, crtc_state->mode_changed);
+}
+
+/*
+ * Test that if we set the RGB quantization property to the same value,
+ * we don't trigger a mode change on the connector's CRTC and leave the
+ * connector unaffected.
+ */
+static void drm_test_check_broadcast_rgb_crtc_mode_not_changed(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_modeset_acquire_ctx *ctx;
+ struct drm_connector_state *old_conn_state;
+ struct drm_connector_state *new_conn_state;
+ struct drm_crtc_state *crtc_state;
+ struct drm_atomic_state *state;
+ struct drm_display_mode *preferred;
+ struct drm_connector *conn;
+ struct drm_device *drm;
+ struct drm_crtc *crtc;
+ int ret;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+ conn = &priv->connector;
+ preferred = find_preferred_mode(conn);
+ KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+ drm = &priv->drm;
+ crtc = priv->crtc;
+ ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+ new_conn_state = drm_atomic_get_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
+
+ old_conn_state = drm_atomic_get_old_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
+
+ new_conn_state->hdmi.broadcast_rgb = old_conn_state->hdmi.broadcast_rgb;
+
+ ret = drm_atomic_check_only(state);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ old_conn_state = drm_atomic_get_old_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
+
+ new_conn_state = drm_atomic_get_new_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
+
+ KUNIT_EXPECT_EQ(test,
+ old_conn_state->hdmi.broadcast_rgb,
+ new_conn_state->hdmi.broadcast_rgb);
+
+ crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+ KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed);
+}
+
+/*
+ * Test that for an HDMI connector, with an HDMI monitor, if the
+ * Broadcast RGB property is set to auto with a mode that isn't the
+ * VIC-1 mode, we will get a limited RGB Quantization Range.
+ */
+static void drm_test_check_broadcast_rgb_auto_cea_mode(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_modeset_acquire_ctx *ctx;
+ struct drm_connector_state *conn_state;
+ struct drm_atomic_state *state;
+ struct drm_display_mode *preferred;
+ struct drm_connector *conn;
+ struct drm_device *drm;
+ struct drm_crtc *crtc;
+ int ret;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ conn = &priv->connector;
+ KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
+
+ ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+ preferred = find_preferred_mode(conn);
+ KUNIT_ASSERT_NOT_NULL(test, preferred);
+ KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1);
+
+ drm = &priv->drm;
+ crtc = priv->crtc;
+ ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+ conn_state = drm_atomic_get_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+ KUNIT_ASSERT_EQ(test,
+ conn_state->hdmi.broadcast_rgb,
+ DRM_HDMI_BROADCAST_RGB_AUTO);
+
+ ret = drm_atomic_check_only(state);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ conn_state = drm_atomic_get_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+ KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_limited_range);
+}
+
+/*
+ * Test that for an HDMI connector, with an HDMI monitor, if the
+ * Broadcast RGB property is set to auto with a VIC-1 mode, we will get
+ * a full RGB Quantization Range.
+ */
+static void drm_test_check_broadcast_rgb_auto_cea_mode_vic_1(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_modeset_acquire_ctx *ctx;
+ struct drm_connector_state *conn_state;
+ struct drm_atomic_state *state;
+ struct drm_display_mode *mode;
+ struct drm_connector *conn;
+ struct drm_device *drm;
+ struct drm_crtc *crtc;
+ int ret;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ drm = &priv->drm;
+ conn = &priv->connector;
+ KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
+
+ ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+ mode = drm_display_mode_from_cea_vic(drm, 1);
+ KUNIT_ASSERT_NOT_NULL(test, mode);
+
+ drm = &priv->drm;
+ crtc = priv->crtc;
+ ret = light_up_connector(test, drm, crtc, conn, mode, ctx);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+ conn_state = drm_atomic_get_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+ KUNIT_ASSERT_EQ(test,
+ conn_state->hdmi.broadcast_rgb,
+ DRM_HDMI_BROADCAST_RGB_AUTO);
+
+ ret = drm_atomic_check_only(state);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ conn_state = drm_atomic_get_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+ KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_limited_range);
+}
+
+/*
+ * Test that for an HDMI connector, with an HDMI monitor, if the
+ * Broadcast RGB property is set to full with a mode that isn't the
+ * VIC-1 mode, we will get a full RGB Quantization Range.
+ */
+static void drm_test_check_broadcast_rgb_full_cea_mode(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_modeset_acquire_ctx *ctx;
+ struct drm_connector_state *conn_state;
+ struct drm_atomic_state *state;
+ struct drm_display_mode *preferred;
+ struct drm_connector *conn;
+ struct drm_device *drm;
+ struct drm_crtc *crtc;
+ int ret;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ conn = &priv->connector;
+ KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
+
+ ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+ preferred = find_preferred_mode(conn);
+ KUNIT_ASSERT_NOT_NULL(test, preferred);
+ KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1);
+
+ drm = &priv->drm;
+ crtc = priv->crtc;
+ ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+ conn_state = drm_atomic_get_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+ conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL;
+
+ ret = drm_atomic_check_only(state);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ conn_state = drm_atomic_get_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+ KUNIT_ASSERT_EQ(test,
+ conn_state->hdmi.broadcast_rgb,
+ DRM_HDMI_BROADCAST_RGB_FULL);
+
+ KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_limited_range);
+}
+
+/*
+ * Test that for an HDMI connector, with an HDMI monitor, if the
+ * Broadcast RGB property is set to full with a VIC-1 mode, we will get
+ * a full RGB Quantization Range.
+ */
+static void drm_test_check_broadcast_rgb_full_cea_mode_vic_1(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_modeset_acquire_ctx *ctx;
+ struct drm_connector_state *conn_state;
+ struct drm_atomic_state *state;
+ struct drm_display_mode *mode;
+ struct drm_connector *conn;
+ struct drm_device *drm;
+ struct drm_crtc *crtc;
+ int ret;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ drm = &priv->drm;
+ conn = &priv->connector;
+ KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
+
+ ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+ mode = drm_display_mode_from_cea_vic(drm, 1);
+ KUNIT_ASSERT_NOT_NULL(test, mode);
+
+ drm = &priv->drm;
+ crtc = priv->crtc;
+ ret = light_up_connector(test, drm, crtc, conn, mode, ctx);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+ conn_state = drm_atomic_get_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+ conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL;
+
+ ret = drm_atomic_check_only(state);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ conn_state = drm_atomic_get_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+ KUNIT_ASSERT_EQ(test,
+ conn_state->hdmi.broadcast_rgb,
+ DRM_HDMI_BROADCAST_RGB_FULL);
+
+ KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_limited_range);
+}
+
+/*
+ * Test that for an HDMI connector, with an HDMI monitor, if the
+ * Broadcast RGB property is set to limited with a mode that isn't the
+ * VIC-1 mode, we will get a limited RGB Quantization Range.
+ */
+static void drm_test_check_broadcast_rgb_limited_cea_mode(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_modeset_acquire_ctx *ctx;
+ struct drm_connector_state *conn_state;
+ struct drm_atomic_state *state;
+ struct drm_display_mode *preferred;
+ struct drm_connector *conn;
+ struct drm_device *drm;
+ struct drm_crtc *crtc;
+ int ret;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ conn = &priv->connector;
+ KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
+
+ ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+ preferred = find_preferred_mode(conn);
+ KUNIT_ASSERT_NOT_NULL(test, preferred);
+ KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1);
+
+ drm = &priv->drm;
+ crtc = priv->crtc;
+ ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+ conn_state = drm_atomic_get_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+ conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED;
+
+ ret = drm_atomic_check_only(state);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ conn_state = drm_atomic_get_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+ KUNIT_ASSERT_EQ(test,
+ conn_state->hdmi.broadcast_rgb,
+ DRM_HDMI_BROADCAST_RGB_LIMITED);
+
+ KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_limited_range);
+}
+
+/*
+ * Test that for an HDMI connector, with an HDMI monitor, if the
+ * Broadcast RGB property is set to limited with a VIC-1 mode, we will
+ * get a limited RGB Quantization Range.
+ */
+static void drm_test_check_broadcast_rgb_limited_cea_mode_vic_1(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_modeset_acquire_ctx *ctx;
+ struct drm_connector_state *conn_state;
+ struct drm_atomic_state *state;
+ struct drm_display_mode *mode;
+ struct drm_connector *conn;
+ struct drm_device *drm;
+ struct drm_crtc *crtc;
+ int ret;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ drm = &priv->drm;
+ conn = &priv->connector;
+ KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
+
+ ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+ mode = drm_display_mode_from_cea_vic(drm, 1);
+ KUNIT_ASSERT_NOT_NULL(test, mode);
+
+ drm = &priv->drm;
+ crtc = priv->crtc;
+ ret = light_up_connector(test, drm, crtc, conn, mode, ctx);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+ conn_state = drm_atomic_get_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+ conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED;
+
+ ret = drm_atomic_check_only(state);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ conn_state = drm_atomic_get_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
+
+ KUNIT_ASSERT_EQ(test,
+ conn_state->hdmi.broadcast_rgb,
+ DRM_HDMI_BROADCAST_RGB_LIMITED);
+
+ KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_limited_range);
+}
+
+/*
+ * Test that if we change the maximum bpc property to a different value,
+ * we trigger a mode change on the connector's CRTC, which will in turn
+ * disable/enable the connector.
+ */
+static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_modeset_acquire_ctx *ctx;
+ struct drm_connector_state *old_conn_state;
+ struct drm_connector_state *new_conn_state;
+ struct drm_crtc_state *crtc_state;
+ struct drm_atomic_state *state;
+ struct drm_display_mode *preferred;
+ struct drm_connector *conn;
+ struct drm_device *drm;
+ struct drm_crtc *crtc;
+ int ret;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB),
+ 10);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ conn = &priv->connector;
+ ret = set_connector_edid(test, conn,
+ test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
+ ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+ preferred = find_preferred_mode(conn);
+ KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+ drm = &priv->drm;
+ crtc = priv->crtc;
+ ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+ new_conn_state = drm_atomic_get_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
+
+ old_conn_state = drm_atomic_get_old_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
+
+ new_conn_state->max_requested_bpc = 8;
+
+ KUNIT_ASSERT_NE(test,
+ old_conn_state->max_requested_bpc,
+ new_conn_state->max_requested_bpc);
+
+ ret = drm_atomic_check_only(state);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ old_conn_state = drm_atomic_get_old_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
+
+ new_conn_state = drm_atomic_get_new_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
+
+ KUNIT_ASSERT_NE(test,
+ old_conn_state->hdmi.output_bpc,
+ new_conn_state->hdmi.output_bpc);
+
+ crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+ KUNIT_EXPECT_TRUE(test, crtc_state->mode_changed);
+}
+
+/*
+ * Test that if we set the output bpc property to the same value, we
+ * don't trigger a mode change on the connector's CRTC and leave the
+ * connector unaffected.
+ */
+static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_modeset_acquire_ctx *ctx;
+ struct drm_connector_state *old_conn_state;
+ struct drm_connector_state *new_conn_state;
+ struct drm_crtc_state *crtc_state;
+ struct drm_atomic_state *state;
+ struct drm_display_mode *preferred;
+ struct drm_connector *conn;
+ struct drm_device *drm;
+ struct drm_crtc *crtc;
+ int ret;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB),
+ 10);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ conn = &priv->connector;
+ ret = set_connector_edid(test, conn,
+ test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
+ ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+ preferred = find_preferred_mode(conn);
+ KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+ drm = &priv->drm;
+ crtc = priv->crtc;
+ ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+ new_conn_state = drm_atomic_get_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
+
+ old_conn_state = drm_atomic_get_old_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
+
+ KUNIT_ASSERT_EQ(test,
+ new_conn_state->hdmi.output_bpc,
+ old_conn_state->hdmi.output_bpc);
+
+ ret = drm_atomic_check_only(state);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ old_conn_state = drm_atomic_get_old_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
+
+ new_conn_state = drm_atomic_get_new_connector_state(state, conn);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
+
+ KUNIT_EXPECT_EQ(test,
+ old_conn_state->hdmi.output_bpc,
+ new_conn_state->hdmi.output_bpc);
+
+ crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+ KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed);
+}
+
+/*
+ * Test that if we have an HDMI connector but a !HDMI display, we always
+ * output RGB with 8 bpc.
+ */
+static void drm_test_check_output_bpc_dvi(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_modeset_acquire_ctx *ctx;
+ struct drm_connector_state *conn_state;
+ struct drm_display_info *info;
+ struct drm_display_mode *preferred;
+ struct drm_connector *conn;
+ struct drm_device *drm;
+ struct drm_crtc *crtc;
+ int ret;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB) |
+ BIT(HDMI_COLORSPACE_YUV422) |
+ BIT(HDMI_COLORSPACE_YUV444),
+ 12);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ conn = &priv->connector;
+ ret = set_connector_edid(test, conn,
+ test_edid_dvi_1080p,
+ ARRAY_SIZE(test_edid_dvi_1080p));
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ info = &conn->display_info;
+ KUNIT_ASSERT_FALSE(test, info->is_hdmi);
+
+ ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+ preferred = find_preferred_mode(conn);
+ KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+ drm = &priv->drm;
+ crtc = priv->crtc;
+ ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ conn_state = conn->state;
+ KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+}
+
+/*
+ * Test that when doing a commit which would use RGB 8bpc, the TMDS
+ * clock rate stored in the connector state is equal to the mode clock
+ */
+static void drm_test_check_tmds_char_rate_rgb_8bpc(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_modeset_acquire_ctx *ctx;
+ struct drm_connector_state *conn_state;
+ struct drm_display_mode *preferred;
+ struct drm_connector *conn;
+ struct drm_device *drm;
+ struct drm_crtc *crtc;
+ int ret;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ conn = &priv->connector;
+ ret = set_connector_edid(test, conn,
+ test_edid_hdmi_1080p_rgb_max_200mhz,
+ ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz));
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+ preferred = find_preferred_mode(conn);
+ KUNIT_ASSERT_NOT_NULL(test, preferred);
+ KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
+
+ drm = &priv->drm;
+ crtc = priv->crtc;
+ ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ conn_state = conn->state;
+ KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+ KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 8);
+ KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1000);
+}
+
+/*
+ * Test that when doing a commit which would use RGB 10bpc, the TMDS
+ * clock rate stored in the connector state is equal to 1.25 times the
+ * mode pixel clock
+ */
+static void drm_test_check_tmds_char_rate_rgb_10bpc(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_modeset_acquire_ctx *ctx;
+ struct drm_connector_state *conn_state;
+ struct drm_display_mode *preferred;
+ struct drm_connector *conn;
+ struct drm_device *drm;
+ struct drm_crtc *crtc;
+ int ret;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB),
+ 10);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ conn = &priv->connector;
+ ret = set_connector_edid(test, conn,
+ test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz,
+ ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz));
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+ preferred = find_preferred_mode(conn);
+ KUNIT_ASSERT_NOT_NULL(test, preferred);
+ KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
+
+ drm = &priv->drm;
+ crtc = priv->crtc;
+ ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ conn_state = conn->state;
+ KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+ KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 10);
+ KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1250);
+}
+
+/*
+ * Test that when doing a commit which would use RGB 12bpc, the TMDS
+ * clock rate stored in the connector state is equal to 1.5 times the
+ * mode pixel clock
+ */
+static void drm_test_check_tmds_char_rate_rgb_12bpc(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_modeset_acquire_ctx *ctx;
+ struct drm_connector_state *conn_state;
+ struct drm_display_mode *preferred;
+ struct drm_connector *conn;
+ struct drm_device *drm;
+ struct drm_crtc *crtc;
+ int ret;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB),
+ 12);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ conn = &priv->connector;
+ ret = set_connector_edid(test, conn,
+ test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz,
+ ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz));
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+ preferred = find_preferred_mode(conn);
+ KUNIT_ASSERT_NOT_NULL(test, preferred);
+ KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
+
+ drm = &priv->drm;
+ crtc = priv->crtc;
+ ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ conn_state = conn->state;
+ KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+ KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 12);
+ KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1500);
+}
+
+/*
+ * Test that if we filter a rate through our hook, it's indeed rejected
+ * by the whole atomic_check logic.
+ *
+ * We do so by first doing a commit on the pipeline to make sure that it
+ * works, change the HDMI helpers pointer, and then try the same commit
+ * again to see if it fails as it should.
+ */
+static void drm_test_check_hdmi_funcs_reject_rate(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_modeset_acquire_ctx *ctx;
+ struct drm_atomic_state *state;
+ struct drm_display_mode *preferred;
+ struct drm_crtc_state *crtc_state;
+ struct drm_connector *conn;
+ struct drm_device *drm;
+ struct drm_crtc *crtc;
+ int ret;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+ conn = &priv->connector;
+ preferred = find_preferred_mode(conn);
+ KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+ drm = &priv->drm;
+ crtc = priv->crtc;
+ ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ /* You shouldn't be doing that at home. */
+ conn->hdmi.funcs = &reject_connector_hdmi_funcs;
+
+ state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
+
+ crtc_state = drm_atomic_get_crtc_state(state, crtc);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
+
+ crtc_state->connectors_changed = true;
+
+ ret = drm_atomic_check_only(state);
+ KUNIT_EXPECT_LT(test, ret, 0);
+}
+
+/*
+ * Test that if:
+ * - We have an HDMI connector supporting RGB only
+ * - The chosen mode has a TMDS character rate higher than the display
+ * supports in RGB/12bpc
+ * - The chosen mode has a TMDS character rate lower than the display
+ * supports in RGB/10bpc.
+ *
+ * Then we will pick the latter, and the computed TMDS character rate
+ * will be equal to 1.25 times the mode pixel clock.
+ */
+static void drm_test_check_max_tmds_rate_bpc_fallback(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_modeset_acquire_ctx *ctx;
+ struct drm_connector_state *conn_state;
+ struct drm_display_info *info;
+ struct drm_display_mode *preferred;
+ unsigned long long rate;
+ struct drm_connector *conn;
+ struct drm_device *drm;
+ struct drm_crtc *crtc;
+ int ret;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB),
+ 12);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ conn = &priv->connector;
+ ret = set_connector_edid(test, conn,
+ test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
+ ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ info = &conn->display_info;
+ KUNIT_ASSERT_TRUE(test, info->is_hdmi);
+ KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
+
+ ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+ preferred = find_preferred_mode(conn);
+ KUNIT_ASSERT_NOT_NULL(test, preferred);
+ KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
+
+ rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
+ KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
+
+ rate = drm_hdmi_compute_mode_clock(preferred, 10, HDMI_COLORSPACE_RGB);
+ KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
+
+ drm = &priv->drm;
+ crtc = priv->crtc;
+ ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+
+ conn_state = conn->state;
+ KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 10);
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1250);
+}
+
+/*
+ * Test that if:
+ * - We have an HDMI connector supporting both RGB and YUV422 and up to
+ * 12 bpc
+ * - The chosen mode has a TMDS character rate higher than the display
+ * supports in RGB/12bpc but lower than the display supports in
+ * RGB/10bpc
+ * - The chosen mode has a TMDS character rate lower than the display
+ * supports in YUV422/12bpc.
+ *
+ * Then we will prefer to keep the RGB format with a lower bpc over
+ * picking YUV422.
+ */
+static void drm_test_check_max_tmds_rate_format_fallback(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_modeset_acquire_ctx *ctx;
+ struct drm_connector_state *conn_state;
+ struct drm_display_info *info;
+ struct drm_display_mode *preferred;
+ unsigned long long rate;
+ struct drm_connector *conn;
+ struct drm_device *drm;
+ struct drm_crtc *crtc;
+ int ret;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB) |
+ BIT(HDMI_COLORSPACE_YUV422) |
+ BIT(HDMI_COLORSPACE_YUV444),
+ 12);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ conn = &priv->connector;
+ ret = set_connector_edid(test, conn,
+ test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
+ ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ info = &conn->display_info;
+ KUNIT_ASSERT_TRUE(test, info->is_hdmi);
+ KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
+
+ ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+ preferred = find_preferred_mode(conn);
+ KUNIT_ASSERT_NOT_NULL(test, preferred);
+ KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
+
+ rate = drm_hdmi_compute_mode_clock(preferred, 10, HDMI_COLORSPACE_RGB);
+ KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
+
+ rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
+ KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
+
+ rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422);
+ KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
+
+ drm = &priv->drm;
+ crtc = priv->crtc;
+ ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+
+ conn_state = conn->state;
+ KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 10);
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+}
+
+/*
+ * Test that if a driver and screen supports RGB and YUV formats, and we
+ * try to set the VIC 1 mode, we end up with 8bpc RGB even if we could
+ * have had a higher bpc.
+ */
+static void drm_test_check_output_bpc_format_vic_1(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_modeset_acquire_ctx *ctx;
+ struct drm_connector_state *conn_state;
+ struct drm_display_info *info;
+ struct drm_display_mode *mode;
+ unsigned long long rate;
+ struct drm_connector *conn;
+ struct drm_device *drm;
+ struct drm_crtc *crtc;
+ int ret;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB) |
+ BIT(HDMI_COLORSPACE_YUV422) |
+ BIT(HDMI_COLORSPACE_YUV444),
+ 12);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ drm = &priv->drm;
+ conn = &priv->connector;
+ ret = set_connector_edid(test, conn,
+ test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
+ ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ info = &conn->display_info;
+ KUNIT_ASSERT_TRUE(test, info->is_hdmi);
+ KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
+
+ ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+ mode = drm_display_mode_from_cea_vic(drm, 1);
+ KUNIT_ASSERT_NOT_NULL(test, mode);
+
+ /*
+ * NOTE: We can't use drm_hdmi_compute_mode_clock()
+ * here because we're trying to get the rate of an invalid
+ * configuration.
+ *
+ * Thus, we have to calculate the rate by hand.
+ */
+ rate = mode->clock * 1500;
+ KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
+
+ drm = &priv->drm;
+ crtc = priv->crtc;
+ ret = light_up_connector(test, drm, crtc, conn, mode, ctx);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+
+ conn_state = conn->state;
+ KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+}
+
+/*
+ * Test that if a driver supports only RGB but the screen also supports
+ * YUV formats, we only end up with an RGB format.
+ */
+static void drm_test_check_output_bpc_format_driver_rgb_only(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_modeset_acquire_ctx *ctx;
+ struct drm_connector_state *conn_state;
+ struct drm_display_info *info;
+ struct drm_display_mode *preferred;
+ unsigned long long rate;
+ struct drm_connector *conn;
+ struct drm_device *drm;
+ struct drm_crtc *crtc;
+ int ret;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB),
+ 12);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ conn = &priv->connector;
+ ret = set_connector_edid(test, conn,
+ test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
+ ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ info = &conn->display_info;
+ KUNIT_ASSERT_TRUE(test, info->is_hdmi);
+ KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
+
+ ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+ preferred = find_preferred_mode(conn);
+ KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+ /*
+ * We're making sure that YUV422 would be the preferred option
+ * here: we're always favouring higher bpc, we can't have RGB
+ * because the TMDS character rate exceeds the maximum supported
+ * by the display, and YUV422 works for that display.
+ *
+ * But since the driver only supports RGB, we should fallback to
+ * a lower bpc with RGB.
+ */
+ rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
+ KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
+
+ rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422);
+ KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
+
+ drm = &priv->drm;
+ crtc = priv->crtc;
+ ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+
+ conn_state = conn->state;
+ KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+ KUNIT_EXPECT_LT(test, conn_state->hdmi.output_bpc, 12);
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+}
+
+/*
+ * Test that if a screen supports only RGB but the driver also supports
+ * YUV formats, we only end up with an RGB format.
+ */
+static void drm_test_check_output_bpc_format_display_rgb_only(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_modeset_acquire_ctx *ctx;
+ struct drm_connector_state *conn_state;
+ struct drm_display_info *info;
+ struct drm_display_mode *preferred;
+ unsigned long long rate;
+ struct drm_connector *conn;
+ struct drm_device *drm;
+ struct drm_crtc *crtc;
+ int ret;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB) |
+ BIT(HDMI_COLORSPACE_YUV422) |
+ BIT(HDMI_COLORSPACE_YUV444),
+ 12);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ conn = &priv->connector;
+ ret = set_connector_edid(test, conn,
+ test_edid_hdmi_1080p_rgb_max_200mhz,
+ ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz));
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ info = &conn->display_info;
+ KUNIT_ASSERT_TRUE(test, info->is_hdmi);
+ KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
+
+ ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+ preferred = find_preferred_mode(conn);
+ KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+ /*
+ * We're making sure that YUV422 would be the preferred option
+ * here: we're always favouring higher bpc, we can't have RGB
+ * because the TMDS character rate exceeds the maximum supported
+ * by the display, and YUV422 works for that display.
+ *
+ * But since the display only supports RGB, we should fallback to
+ * a lower bpc with RGB.
+ */
+ rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
+ KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
+
+ rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422);
+ KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
+
+ drm = &priv->drm;
+ crtc = priv->crtc;
+ ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+
+ conn_state = conn->state;
+ KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+ KUNIT_EXPECT_LT(test, conn_state->hdmi.output_bpc, 12);
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+}
+
+/*
+ * Test that if a display supports higher bpc but the driver only
+ * supports 8 bpc, we only end up with 8 bpc even if we could have had a
+ * higher bpc.
+ */
+static void drm_test_check_output_bpc_format_driver_8bpc_only(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_modeset_acquire_ctx *ctx;
+ struct drm_connector_state *conn_state;
+ struct drm_display_info *info;
+ struct drm_display_mode *preferred;
+ unsigned long long rate;
+ struct drm_connector *conn;
+ struct drm_device *drm;
+ struct drm_crtc *crtc;
+ int ret;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ conn = &priv->connector;
+ ret = set_connector_edid(test, conn,
+ test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz,
+ ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz));
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ info = &conn->display_info;
+ KUNIT_ASSERT_TRUE(test, info->is_hdmi);
+ KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
+
+ ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+ preferred = find_preferred_mode(conn);
+ KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+ /*
+ * We're making sure that we have headroom on the TMDS character
+ * clock to actually use 12bpc.
+ */
+ rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
+ KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
+
+ drm = &priv->drm;
+ crtc = priv->crtc;
+ ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+
+ conn_state = conn->state;
+ KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+}
+
+/*
+ * Test that if a driver supports higher bpc but the display only
+ * supports 8 bpc, we only end up with 8 bpc even if we could have had a
+ * higher bpc.
+ */
+static void drm_test_check_output_bpc_format_display_8bpc_only(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_modeset_acquire_ctx *ctx;
+ struct drm_connector_state *conn_state;
+ struct drm_display_info *info;
+ struct drm_display_mode *preferred;
+ unsigned long long rate;
+ struct drm_connector *conn;
+ struct drm_device *drm;
+ struct drm_crtc *crtc;
+ int ret;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB) |
+ BIT(HDMI_COLORSPACE_YUV422) |
+ BIT(HDMI_COLORSPACE_YUV444),
+ 12);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ conn = &priv->connector;
+ ret = set_connector_edid(test, conn,
+ test_edid_hdmi_1080p_rgb_max_340mhz,
+ ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_340mhz));
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ info = &conn->display_info;
+ KUNIT_ASSERT_TRUE(test, info->is_hdmi);
+ KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
+
+ ctx = drm_kunit_helper_acquire_ctx_alloc(test);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+ preferred = find_preferred_mode(conn);
+ KUNIT_ASSERT_NOT_NULL(test, preferred);
+
+ /*
+ * We're making sure that we have headroom on the TMDS character
+ * clock to actually use 12bpc.
+ */
+ rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
+ KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
+
+ drm = &priv->drm;
+ crtc = priv->crtc;
+ ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
+ KUNIT_EXPECT_EQ(test, ret, 0);
+
+ conn_state = conn->state;
+ KUNIT_ASSERT_NOT_NULL(test, conn_state);
+
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
+}
+
+static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
+ KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode),
+ KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode_vic_1),
+ KUNIT_CASE(drm_test_check_broadcast_rgb_full_cea_mode),
+ KUNIT_CASE(drm_test_check_broadcast_rgb_full_cea_mode_vic_1),
+ KUNIT_CASE(drm_test_check_broadcast_rgb_limited_cea_mode),
+ KUNIT_CASE(drm_test_check_broadcast_rgb_limited_cea_mode_vic_1),
+ /*
+ * TODO: When we'll have YUV output support, we need to check
+ * that the limited range is always set to limited no matter
+ * what the value of Broadcast RGB is.
+ */
+ KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_changed),
+ KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_not_changed),
+ KUNIT_CASE(drm_test_check_hdmi_funcs_reject_rate),
+ KUNIT_CASE(drm_test_check_max_tmds_rate_bpc_fallback),
+ KUNIT_CASE(drm_test_check_max_tmds_rate_format_fallback),
+ KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_changed),
+ KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_not_changed),
+ KUNIT_CASE(drm_test_check_output_bpc_dvi),
+ KUNIT_CASE(drm_test_check_output_bpc_format_vic_1),
+ KUNIT_CASE(drm_test_check_output_bpc_format_display_8bpc_only),
+ KUNIT_CASE(drm_test_check_output_bpc_format_display_rgb_only),
+ KUNIT_CASE(drm_test_check_output_bpc_format_driver_8bpc_only),
+ KUNIT_CASE(drm_test_check_output_bpc_format_driver_rgb_only),
+ KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_8bpc),
+ KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_10bpc),
+ KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_12bpc),
+ /*
+ * TODO: We should have tests to check that a change in the
+ * format triggers a CRTC mode change just like we do for the
+ * RGB Quantization and BPC.
+ *
+ * However, we don't have any way to control which format gets
+ * picked up aside from changing the BPC or mode which would
+ * already trigger a mode change.
+ */
+ { }
+};
+
+static struct kunit_suite drm_atomic_helper_connector_hdmi_check_test_suite = {
+ .name = "drm_atomic_helper_connector_hdmi_check",
+ .test_cases = drm_atomic_helper_connector_hdmi_check_tests,
+};
+
+/*
+ * Test that the value of the Broadcast RGB property out of reset is set
+ * to auto.
+ */
+static void drm_test_check_broadcast_rgb_value(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_connector_state *conn_state;
+ struct drm_connector *conn;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ conn = &priv->connector;
+ conn_state = conn->state;
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.broadcast_rgb, DRM_HDMI_BROADCAST_RGB_AUTO);
+}
+
+/*
+ * Test that if the connector was initialised with a maximum bpc of 8,
+ * the value of the max_bpc and max_requested_bpc properties out of
+ * reset are also set to 8, and output_bpc is set to 0 and will be
+ * filled at atomic_check time.
+ */
+static void drm_test_check_bpc_8_value(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_connector_state *conn_state;
+ struct drm_connector *conn;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB),
+ 8);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ conn = &priv->connector;
+ conn_state = conn->state;
+ KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 8);
+ KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 8);
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0);
+}
+
+/*
+ * Test that if the connector was initialised with a maximum bpc of 10,
+ * the value of the max_bpc and max_requested_bpc properties out of
+ * reset are also set to 10, and output_bpc is set to 0 and will be
+ * filled at atomic_check time.
+ */
+static void drm_test_check_bpc_10_value(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_connector_state *conn_state;
+ struct drm_connector *conn;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB),
+ 10);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ conn = &priv->connector;
+ conn_state = conn->state;
+ KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 10);
+ KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 10);
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0);
+}
+
+/*
+ * Test that if the connector was initialised with a maximum bpc of 12,
+ * the value of the max_bpc and max_requested_bpc properties out of
+ * reset are also set to 12, and output_bpc is set to 0 and will be
+ * filled at atomic_check time.
+ */
+static void drm_test_check_bpc_12_value(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_connector_state *conn_state;
+ struct drm_connector *conn;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB),
+ 12);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ conn = &priv->connector;
+ conn_state = conn->state;
+ KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 12);
+ KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 12);
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0);
+}
+
+/*
+ * Test that the value of the output format property out of reset is set
+ * to RGB, even if the driver supports more than that.
+ */
+static void drm_test_check_format_value(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_connector_state *conn_state;
+ struct drm_connector *conn;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB) |
+ BIT(HDMI_COLORSPACE_YUV422) |
+ BIT(HDMI_COLORSPACE_YUV444),
+ 8);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ conn = &priv->connector;
+ conn_state = conn->state;
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, 0);
+}
+
+/*
+ * Test that the value of the output format property out of reset is set
+ * to 0, and will be computed at atomic_check time.
+ */
+static void drm_test_check_tmds_char_value(struct kunit *test)
+{
+ struct drm_atomic_helper_connector_hdmi_priv *priv;
+ struct drm_connector_state *conn_state;
+ struct drm_connector *conn;
+
+ priv = drm_atomic_helper_connector_hdmi_init(test,
+ BIT(HDMI_COLORSPACE_RGB) |
+ BIT(HDMI_COLORSPACE_YUV422) |
+ BIT(HDMI_COLORSPACE_YUV444),
+ 12);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ conn = &priv->connector;
+ conn_state = conn->state;
+ KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, 0);
+}
+
+static struct kunit_case drm_atomic_helper_connector_hdmi_reset_tests[] = {
+ KUNIT_CASE(drm_test_check_broadcast_rgb_value),
+ KUNIT_CASE(drm_test_check_bpc_8_value),
+ KUNIT_CASE(drm_test_check_bpc_10_value),
+ KUNIT_CASE(drm_test_check_bpc_12_value),
+ KUNIT_CASE(drm_test_check_format_value),
+ KUNIT_CASE(drm_test_check_tmds_char_value),
+ { }
+};
+
+static struct kunit_suite drm_atomic_helper_connector_hdmi_reset_test_suite = {
+ .name = "drm_atomic_helper_connector_hdmi_reset",
+ .test_cases = drm_atomic_helper_connector_hdmi_reset_tests,
+};
+
+kunit_test_suites(
+ &drm_atomic_helper_connector_hdmi_check_test_suite,
+ &drm_atomic_helper_connector_hdmi_reset_test_suite,
+);
+
+MODULE_AUTHOR("Maxime Ripard <mripard@kernel.org>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/tests/drm_kunit_edid.h b/drivers/gpu/drm/tests/drm_kunit_edid.h
new file mode 100644
index 000000000000..107559900e97
--- /dev/null
+++ b/drivers/gpu/drm/tests/drm_kunit_edid.h
@@ -0,0 +1,484 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef DRM_KUNIT_EDID_H_
+#define DRM_KUNIT_EDID_H_
+
+/*
+ * edid-decode (hex):
+ *
+ * 00 ff ff ff ff ff ff 00 31 d8 2a 00 00 00 00 00
+ * 00 21 01 03 81 a0 5a 78 0a 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 01 01 01 01 01 01 01 01 01 01
+ * 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c
+ * 45 00 40 84 63 00 00 1e 00 00 00 fc 00 54 65 73
+ * 74 20 45 44 49 44 0a 20 20 20 00 00 00 fd 00 32
+ * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ab
+ *
+ * ----------------
+ *
+ * Block 0, Base EDID:
+ * EDID Structure Version & Revision: 1.3
+ * Vendor & Product Identification:
+ * Manufacturer: LNX
+ * Model: 42
+ * Made in: 2023
+ * Basic Display Parameters & Features:
+ * Digital display
+ * DFP 1.x compatible TMDS
+ * Maximum image size: 160 cm x 90 cm
+ * Gamma: 2.20
+ * RGB color display
+ * First detailed timing is the preferred timing
+ * Color Characteristics:
+ * Red : 0.0000, 0.0000
+ * Green: 0.0000, 0.0000
+ * Blue : 0.0000, 0.0000
+ * White: 0.0000, 0.0000
+ * Established Timings I & II: none
+ * Standard Timings: none
+ * Detailed Timing Descriptors:
+ * DTD 1: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz (1600 mm x 900 mm)
+ * Hfront 88 Hsync 44 Hback 148 Hpol P
+ * Vfront 4 Vsync 5 Vback 36 Vpol P
+ * Display Product Name: 'Test EDID'
+ * Display Range Limits:
+ * Monitor ranges (GTF): 50-70 Hz V, 30-70 kHz H, max dotclock 150 MHz
+ * Dummy Descriptor:
+ * Checksum: 0xab
+ */
+static const unsigned char test_edid_dvi_1080p[] = {
+ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x03, 0x81, 0xa0, 0x5a, 0x78,
+ 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
+ 0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e,
+ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44,
+ 0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32,
+ 0x46, 0x1e, 0x46, 0x0f, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xab
+};
+
+/*
+ * edid-decode (hex):
+ *
+ * 00 ff ff ff ff ff ff 00 31 d8 2a 00 00 00 00 00
+ * 00 21 01 03 81 a0 5a 78 02 00 00 00 00 00 00 00
+ * 00 00 00 20 00 00 01 01 01 01 01 01 01 01 01 01
+ * 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c
+ * 45 00 40 84 63 00 00 1e 00 00 00 fc 00 54 65 73
+ * 74 20 45 44 49 44 0a 20 20 20 00 00 00 fd 00 32
+ * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 92
+ *
+ * 02 03 1b 81 e3 05 00 20 41 10 e2 00 4a 6d 03 0c
+ * 00 12 34 00 28 20 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d0
+ *
+ * ----------------
+ *
+ * Block 0, Base EDID:
+ * EDID Structure Version & Revision: 1.3
+ * Vendor & Product Identification:
+ * Manufacturer: LNX
+ * Model: 42
+ * Made in: 2023
+ * Basic Display Parameters & Features:
+ * Digital display
+ * DFP 1.x compatible TMDS
+ * Maximum image size: 160 cm x 90 cm
+ * Gamma: 2.20
+ * Monochrome or grayscale display
+ * First detailed timing is the preferred timing
+ * Color Characteristics:
+ * Red : 0.0000, 0.0000
+ * Green: 0.0000, 0.0000
+ * Blue : 0.0000, 0.0000
+ * White: 0.0000, 0.0000
+ * Established Timings I & II:
+ * DMT 0x04: 640x480 59.940476 Hz 4:3 31.469 kHz 25.175000 MHz
+ * Standard Timings: none
+ * Detailed Timing Descriptors:
+ * DTD 1: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz (1600 mm x 900 mm)
+ * Hfront 88 Hsync 44 Hback 148 Hpol P
+ * Vfront 4 Vsync 5 Vback 36 Vpol P
+ * Display Product Name: 'Test EDID'
+ * Display Range Limits:
+ * Monitor ranges (GTF): 50-70 Hz V, 30-70 kHz H, max dotclock 150 MHz
+ * Dummy Descriptor:
+ * Extension blocks: 1
+ * Checksum: 0x92
+ *
+ * ----------------
+ *
+ * Block 1, CTA-861 Extension Block:
+ * Revision: 3
+ * Underscans IT Video Formats by default
+ * Native detailed modes: 1
+ * Colorimetry Data Block:
+ * sRGB
+ * Video Data Block:
+ * VIC 16: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz
+ * Video Capability Data Block:
+ * YCbCr quantization: No Data
+ * RGB quantization: Selectable (via AVI Q)
+ * PT scan behavior: No Data
+ * IT scan behavior: Always Underscanned
+ * CE scan behavior: Always Underscanned
+ * Vendor-Specific Data Block (HDMI), OUI 00-0C-03:
+ * Source physical address: 1.2.3.4
+ * Maximum TMDS clock: 200 MHz
+ * Extended HDMI video details:
+ * Checksum: 0xd0 Unused space in Extension Block: 100 bytes
+ */
+static const unsigned char test_edid_hdmi_1080p_rgb_max_200mhz[] = {
+ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x03, 0x81, 0xa0, 0x5a, 0x78,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
+ 0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e,
+ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44,
+ 0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32,
+ 0x46, 0x00, 0x00, 0xc4, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x41, 0x02, 0x03, 0x1b, 0x81,
+ 0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0x4a, 0x6d, 0x03, 0x0c,
+ 0x00, 0x12, 0x34, 0x00, 0x28, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xd0
+};
+
+/*
+ * edid-decode (hex):
+ *
+ * 00 ff ff ff ff ff ff 00 31 d8 2a 00 00 00 00 00
+ * 00 21 01 03 81 a0 5a 78 02 00 00 00 00 00 00 00
+ * 00 00 00 20 00 00 01 01 01 01 01 01 01 01 01 01
+ * 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c
+ * 45 00 40 84 63 00 00 1e 00 00 00 fc 00 54 65 73
+ * 74 20 45 44 49 44 0a 20 20 20 00 00 00 fd 00 32
+ * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 92
+ *
+ * 02 03 1b 81 e3 05 00 20 41 10 e2 00 4a 6d 03 0c
+ * 00 12 34 00 28 20 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d0
+ *
+ * ----------------
+ *
+ * Block 0, Base EDID:
+ * EDID Structure Version & Revision: 1.3
+ * Vendor & Product Identification:
+ * Manufacturer: LNX
+ * Model: 42
+ * Made in: 2023
+ * Basic Display Parameters & Features:
+ * Digital display
+ * DFP 1.x compatible TMDS
+ * Maximum image size: 160 cm x 90 cm
+ * Gamma: 2.20
+ * Monochrome or grayscale display
+ * First detailed timing is the preferred timing
+ * Color Characteristics:
+ * Red : 0.0000, 0.0000
+ * Green: 0.0000, 0.0000
+ * Blue : 0.0000, 0.0000
+ * White: 0.0000, 0.0000
+ * Established Timings I & II:
+ * DMT 0x04: 640x480 59.940476 Hz 4:3 31.469 kHz 25.175000 MHz
+ * Standard Timings: none
+ * Detailed Timing Descriptors:
+ * DTD 1: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz (1600 mm x 900 mm)
+ * Hfront 88 Hsync 44 Hback 148 Hpol P
+ * Vfront 4 Vsync 5 Vback 36 Vpol P
+ * Display Product Name: 'Test EDID'
+ * Display Range Limits:
+ * Monitor ranges (GTF): 50-70 Hz V, 30-70 kHz H, max dotclock 150 MHz
+ * Dummy Descriptor:
+ * Extension blocks: 1
+ * Checksum: 0x92
+ *
+ * ----------------
+ *
+ * Block 1, CTA-861 Extension Block:
+ * Revision: 3
+ * Underscans IT Video Formats by default
+ * Native detailed modes: 1
+ * Colorimetry Data Block:
+ * sRGB
+ * Video Data Block:
+ * VIC 16: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz
+ * Video Capability Data Block:
+ * YCbCr quantization: No Data
+ * RGB quantization: Selectable (via AVI Q)
+ * PT scan behavior: No Data
+ * IT scan behavior: Always Underscanned
+ * CE scan behavior: Always Underscanned
+ * Vendor-Specific Data Block (HDMI), OUI 00-0C-03:
+ * Source physical address: 1.2.3.4
+ * Maximum TMDS clock: 340 MHz
+ * Extended HDMI video details:
+ * Checksum: 0xd0 Unused space in Extension Block: 100 bytes
+ */
+static const unsigned char test_edid_hdmi_1080p_rgb_max_340mhz[] = {
+ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x03, 0x81, 0xa0, 0x5a, 0x78,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
+ 0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e,
+ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44,
+ 0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32,
+ 0x46, 0x00, 0x00, 0xc4, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x41, 0x02, 0x03, 0x1b, 0x81,
+ 0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0x4a, 0x6d, 0x03, 0x0c,
+ 0x00, 0x12, 0x34, 0x00, 0x44, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xd0
+};
+
+/*
+ * edid-decode (hex):
+ *
+ * 00 ff ff ff ff ff ff 00 31 d8 2a 00 00 00 00 00
+ * 00 21 01 03 81 a0 5a 78 1a 00 00 00 00 00 00 00
+ * 00 00 00 20 00 00 01 01 01 01 01 01 01 01 01 01
+ * 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c
+ * 45 00 40 84 63 00 00 1e 00 00 00 fc 00 54 65 73
+ * 74 20 45 44 49 44 0a 20 20 20 00 00 00 fd 00 32
+ * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 7a
+ *
+ * 02 03 1b b1 e3 05 00 20 41 10 e2 00 ca 6d 03 0c
+ * 00 12 34 78 28 20 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a8
+ *
+ * ----------------
+ *
+ * Block 0, Base EDID:
+ * EDID Structure Version & Revision: 1.3
+ * Vendor & Product Identification:
+ * Manufacturer: LNX
+ * Model: 42
+ * Made in: 2023
+ * Basic Display Parameters & Features:
+ * Digital display
+ * DFP 1.x compatible TMDS
+ * Maximum image size: 160 cm x 90 cm
+ * Gamma: 2.20
+ * Undefined display color type
+ * First detailed timing is the preferred timing
+ * Color Characteristics:
+ * Red : 0.0000, 0.0000
+ * Green: 0.0000, 0.0000
+ * Blue : 0.0000, 0.0000
+ * White: 0.0000, 0.0000
+ * Established Timings I & II:
+ * DMT 0x04: 640x480 59.940476 Hz 4:3 31.469 kHz 25.175000 MHz
+ * Standard Timings: none
+ * Detailed Timing Descriptors:
+ * DTD 1: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz (1600 mm x 900 mm)
+ * Hfront 88 Hsync 44 Hback 148 Hpol P
+ * Vfront 4 Vsync 5 Vback 36 Vpol P
+ * Display Product Name: 'Test EDID'
+ * Display Range Limits:
+ * Monitor ranges (GTF): 50-70 Hz V, 30-70 kHz H, max dotclock 150 MHz
+ * Dummy Descriptor:
+ * Extension blocks: 1
+ * Checksum: 0x7a
+ *
+ * ----------------
+ *
+ * Block 1, CTA-861 Extension Block:
+ * Revision: 3
+ * Underscans IT Video Formats by default
+ * Supports YCbCr 4:4:4
+ * Supports YCbCr 4:2:2
+ * Native detailed modes: 1
+ * Colorimetry Data Block:
+ * sRGB
+ * Video Data Block:
+ * VIC 16: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz
+ * Video Capability Data Block:
+ * YCbCr quantization: Selectable (via AVI YQ)
+ * RGB quantization: Selectable (via AVI Q)
+ * PT scan behavior: No Data
+ * IT scan behavior: Always Underscanned
+ * CE scan behavior: Always Underscanned
+ * Vendor-Specific Data Block (HDMI), OUI 00-0C-03:
+ * Source physical address: 1.2.3.4
+ * DC_48bit
+ * DC_36bit
+ * DC_30bit
+ * DC_Y444
+ * Maximum TMDS clock: 200 MHz
+ * Extended HDMI video details:
+ * Checksum: 0xa8 Unused space in Extension Block: 100 bytes
+ */
+static const unsigned char test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz[] = {
+ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x03, 0x81, 0xa0, 0x5a, 0x78,
+ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
+ 0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e,
+ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44,
+ 0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32,
+ 0x46, 0x1e, 0x46, 0x0f, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7a, 0x02, 0x03, 0x1b, 0xb1,
+ 0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0xca, 0x6d, 0x03, 0x0c,
+ 0x00, 0x12, 0x34, 0x78, 0x28, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xa8
+};
+
+/*
+ * edid-decode (hex):
+ *
+ * 00 ff ff ff ff ff ff 00 31 d8 2a 00 00 00 00 00
+ * 00 21 01 03 81 a0 5a 78 0a 00 00 00 00 00 00 00
+ * 00 00 00 20 00 00 01 01 01 01 01 01 01 01 01 01
+ * 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c
+ * 45 00 40 84 63 00 00 1e 00 00 00 fc 00 54 65 73
+ * 74 20 45 44 49 44 0a 20 20 20 00 00 00 fd 00 32
+ * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 8a
+ *
+ * 02 03 1b b1 e3 05 00 20 41 10 e2 00 ca 6d 03 0c
+ * 00 12 34 78 44 20 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 8c
+ *
+ * ----------------
+ *
+ * Block 0, Base EDID:
+ * EDID Structure Version & Revision: 1.3
+ * Vendor & Product Identification:
+ * Manufacturer: LNX
+ * Model: 42
+ * Made in: 2023
+ * Basic Display Parameters & Features:
+ * Digital display
+ * DFP 1.x compatible TMDS
+ * Maximum image size: 160 cm x 90 cm
+ * Gamma: 2.20
+ * RGB color display
+ * First detailed timing is the preferred timing
+ * Color Characteristics:
+ * Red : 0.0000, 0.0000
+ * Green: 0.0000, 0.0000
+ * Blue : 0.0000, 0.0000
+ * White: 0.0000, 0.0000
+ * Established Timings I & II:
+ * DMT 0x04: 640x480 59.940476 Hz 4:3 31.469 kHz 25.175000 MHz
+ * Standard Timings: none
+ * Detailed Timing Descriptors:
+ * DTD 1: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz (1600 mm x 900 mm)
+ * Hfront 88 Hsync 44 Hback 148 Hpol P
+ * Vfront 4 Vsync 5 Vback 36 Vpol P
+ * Display Product Name: 'Test EDID'
+ * Display Range Limits:
+ * Monitor ranges (GTF): 50-70 Hz V, 30-70 kHz H, max dotclock 150 MHz
+ * Dummy Descriptor:
+ * Extension blocks: 1
+ * Checksum: 0x8a
+ *
+ * ----------------
+ *
+ * Block 1, CTA-861 Extension Block:
+ * Revision: 3
+ * Underscans IT Video Formats by default
+ * Supports YCbCr 4:4:4
+ * Supports YCbCr 4:2:2
+ * Native detailed modes: 1
+ * Colorimetry Data Block:
+ * sRGB
+ * Video Data Block:
+ * VIC 16: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz
+ * Video Capability Data Block:
+ * YCbCr quantization: Selectable (via AVI YQ)
+ * RGB quantization: Selectable (via AVI Q)
+ * PT scan behavior: No Data
+ * IT scan behavior: Always Underscanned
+ * CE scan behavior: Always Underscanned
+ * Vendor-Specific Data Block (HDMI), OUI 00-0C-03:
+ * Source physical address: 1.2.3.4
+ * DC_48bit
+ * DC_36bit
+ * DC_30bit
+ * DC_Y444
+ * Maximum TMDS clock: 340 MHz
+ * Extended HDMI video details:
+ * Checksum: 0x8c Unused space in Extension Block: 100 bytes
+ */
+static const unsigned char test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz[] = {
+ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x03, 0x81, 0xa0, 0x5a, 0x78,
+ 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
+ 0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e,
+ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44,
+ 0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32,
+ 0x46, 0x1e, 0x46, 0x0f, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8a, 0x02, 0x03, 0x1b, 0xb1,
+ 0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0xca, 0x6d, 0x03, 0x0c,
+ 0x00, 0x12, 0x34, 0x78, 0x44, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x8c
+};
+
+#endif // DRM_KUNIT_EDID_H_
diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c b/drivers/gpu/drm/tests/drm_kunit_helpers.c
index d5317d13d3fc..aa62719dab0e 100644
--- a/drivers/gpu/drm/tests/drm_kunit_helpers.c
+++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c
@@ -312,4 +312,5 @@ drm_kunit_helper_create_crtc(struct kunit *test,
EXPORT_SYMBOL_GPL(drm_kunit_helper_create_crtc);
MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
+MODULE_DESCRIPTION("KUnit test suite helper functions");
MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/tests/drm_managed_test.c b/drivers/gpu/drm/tests/drm_managed_test.c
index 76eb273c9b36..d40c7ef7f9e1 100644
--- a/drivers/gpu/drm/tests/drm_managed_test.c
+++ b/drivers/gpu/drm/tests/drm_managed_test.c
@@ -113,4 +113,5 @@ static struct kunit_suite drm_managed_test_suite = {
kunit_test_suite(drm_managed_test_suite);
MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
+MODULE_DESCRIPTION("KUnit DRM managed test suite");
MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/tests/drm_mm_test.c b/drivers/gpu/drm/tests/drm_mm_test.c
index 8497d9990b96..6174d0929020 100644
--- a/drivers/gpu/drm/tests/drm_mm_test.c
+++ b/drivers/gpu/drm/tests/drm_mm_test.c
@@ -356,4 +356,5 @@ static struct kunit_suite drm_mm_test_suite = {
kunit_test_suite(drm_mm_test_suite);
MODULE_AUTHOR("Intel Corporation");
+MODULE_DESCRIPTION("Test cases for the drm_mm range manager");
MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/tests/drm_modes_test.c b/drivers/gpu/drm/tests/drm_modes_test.c
index 1e9f63fbfead..7029f7a2eb4d 100644
--- a/drivers/gpu/drm/tests/drm_modes_test.c
+++ b/drivers/gpu/drm/tests/drm_modes_test.c
@@ -147,4 +147,5 @@ static struct kunit_suite drm_modes_analog_tv_test_suite = {
kunit_test_suite(drm_modes_analog_tv_test_suite);
MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
+MODULE_DESCRIPTION("Kunit test for drm_modes functions");
MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/tests/drm_plane_helper_test.c b/drivers/gpu/drm/tests/drm_plane_helper_test.c
index 0f392146b233..7e975a3f4a71 100644
--- a/drivers/gpu/drm/tests/drm_plane_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_plane_helper_test.c
@@ -315,4 +315,5 @@ static struct kunit_suite drm_plane_helper_test_suite = {
kunit_test_suite(drm_plane_helper_test_suite);
+MODULE_DESCRIPTION("Test cases for the drm_plane_helper functions");
MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/tests/drm_probe_helper_test.c b/drivers/gpu/drm/tests/drm_probe_helper_test.c
index 1a2044070a6c..bc09ff38aca1 100644
--- a/drivers/gpu/drm/tests/drm_probe_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_probe_helper_test.c
@@ -207,4 +207,5 @@ static struct kunit_suite drm_test_connector_helper_tv_get_modes_suite = {
kunit_test_suite(drm_test_connector_helper_tv_get_modes_suite);
MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
+MODULE_DESCRIPTION("Kunit test for drm_probe_helper functions");
MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/tests/drm_rect_test.c b/drivers/gpu/drm/tests/drm_rect_test.c
index 76332cd2ead8..17e1f34b7610 100644
--- a/drivers/gpu/drm/tests/drm_rect_test.c
+++ b/drivers/gpu/drm/tests/drm_rect_test.c
@@ -526,4 +526,5 @@ static struct kunit_suite drm_rect_test_suite = {
kunit_test_suite(drm_rect_test_suite);
+MODULE_DESCRIPTION("Test cases for the drm_rect functions");
MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/tidss/tidss_plane.c b/drivers/gpu/drm/tidss/tidss_plane.c
index 68fed531f6a7..a5d86822c9e3 100644
--- a/drivers/gpu/drm/tidss/tidss_plane.c
+++ b/drivers/gpu/drm/tidss/tidss_plane.c
@@ -8,6 +8,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_blend.h>
#include <drm/drm_crtc.h>
+#include <drm/drm_fb_dma_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_atomic_helper.h>
@@ -166,6 +167,14 @@ static const struct drm_plane_helper_funcs tidss_plane_helper_funcs = {
.atomic_disable = tidss_plane_atomic_disable,
};
+static const struct drm_plane_helper_funcs tidss_primary_plane_helper_funcs = {
+ .atomic_check = tidss_plane_atomic_check,
+ .atomic_update = tidss_plane_atomic_update,
+ .atomic_enable = tidss_plane_atomic_enable,
+ .atomic_disable = tidss_plane_atomic_disable,
+ .get_scanout_buffer = drm_fb_dma_get_scanout_buffer,
+};
+
static const struct drm_plane_funcs tidss_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
@@ -211,7 +220,10 @@ struct tidss_plane *tidss_plane_create(struct tidss_device *tidss,
if (ret < 0)
goto err;
- drm_plane_helper_add(&tplane->plane, &tidss_plane_helper_funcs);
+ if (type == DRM_PLANE_TYPE_PRIMARY)
+ drm_plane_helper_add(&tplane->plane, &tidss_primary_plane_helper_funcs);
+ else
+ drm_plane_helper_add(&tplane->plane, &tidss_plane_helper_funcs);
drm_plane_create_zpos_property(&tplane->plane, tidss->num_planes, 0,
num_planes - 1);
diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c
index c23c9f0cf49c..31fc5d839e10 100644
--- a/drivers/gpu/drm/tiny/bochs.c
+++ b/drivers/gpu/drm/tiny/bochs.c
@@ -7,7 +7,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
#include <drm/drm_edid.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_ttm.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_framebuffer_helper.h>
@@ -85,7 +85,7 @@ struct bochs_device {
u16 yres_virtual;
u32 stride;
u32 bpp;
- struct edid *edid;
+ const struct drm_edid *drm_edid;
/* drm */
struct drm_device *dev;
@@ -199,10 +199,10 @@ static int bochs_hw_load_edid(struct bochs_device *bochs)
if (drm_edid_header_is_valid(header) != 8)
return -1;
- kfree(bochs->edid);
- bochs->edid = drm_do_get_edid(&bochs->connector,
- bochs_get_edid_block, bochs);
- if (bochs->edid == NULL)
+ drm_edid_free(bochs->drm_edid);
+ bochs->drm_edid = drm_edid_read_custom(&bochs->connector,
+ bochs_get_edid_block, bochs);
+ if (!bochs->drm_edid)
return -1;
return 0;
@@ -303,7 +303,7 @@ static void bochs_hw_fini(struct drm_device *dev)
if (bochs->fb_map)
iounmap(bochs->fb_map);
pci_release_regions(to_pci_dev(dev->dev));
- kfree(bochs->edid);
+ drm_edid_free(bochs->drm_edid);
}
static void bochs_hw_blank(struct bochs_device *bochs, bool blank)
@@ -471,12 +471,9 @@ static const struct drm_simple_display_pipe_funcs bochs_pipe_funcs = {
static int bochs_connector_get_modes(struct drm_connector *connector)
{
- struct bochs_device *bochs =
- container_of(connector, struct bochs_device, connector);
- int count = 0;
+ int count;
- if (bochs->edid)
- count = drm_add_edid_modes(connector, bochs->edid);
+ count = drm_edid_connector_add_modes(connector);
if (!count) {
count = drm_add_modes_noedid(connector, 8192, 8192);
@@ -507,10 +504,10 @@ static void bochs_connector_init(struct drm_device *dev)
drm_connector_helper_add(connector, &bochs_connector_connector_helper_funcs);
bochs_hw_load_edid(bochs);
- if (bochs->edid) {
+ if (bochs->drm_edid) {
DRM_INFO("Found EDID data blob.\n");
drm_connector_attach_edid_property(connector);
- drm_connector_update_edid_property(connector, bochs->edid);
+ drm_edid_connector_update(&bochs->connector, bochs->drm_edid);
}
}
@@ -670,7 +667,7 @@ static int bochs_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent
if (ret)
goto err_hw_fini;
- drm_fbdev_generic_setup(dev, 32);
+ drm_fbdev_ttm_setup(dev, 32);
return ret;
err_hw_fini:
@@ -736,4 +733,5 @@ drm_module_pci_driver_if_modeset(bochs_pci_driver, bochs_modeset);
MODULE_DEVICE_TABLE(pci, bochs_pci_tbl);
MODULE_AUTHOR("Gerd Hoffmann <kraxel@redhat.com>");
+MODULE_DESCRIPTION("DRM Support for bochs dispi vga interface (qemu stdvga)");
MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/tiny/cirrus.c b/drivers/gpu/drm/tiny/cirrus.c
index 4e3a152f897a..751326e3d9c3 100644
--- a/drivers/gpu/drm/tiny/cirrus.c
+++ b/drivers/gpu/drm/tiny/cirrus.c
@@ -31,7 +31,7 @@
#include <drm/drm_damage_helper.h>
#include <drm/drm_drv.h>
#include <drm/drm_edid.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_shmem.h>
#include <drm/drm_file.h>
#include <drm/drm_format_helper.h>
#include <drm/drm_fourcc.h>
@@ -716,7 +716,7 @@ static int cirrus_pci_probe(struct pci_dev *pdev,
if (ret)
return ret;
- drm_fbdev_generic_setup(dev, 16);
+ drm_fbdev_shmem_setup(dev, 16);
return 0;
}
@@ -760,4 +760,5 @@ static struct pci_driver cirrus_pci_driver = {
drm_module_pci_driver(cirrus_pci_driver)
MODULE_DEVICE_TABLE(pci, pciidlist);
+MODULE_DESCRIPTION("Cirrus driver for QEMU emulated device");
MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c
index 0187539ff5ea..e0defb1d134f 100644
--- a/drivers/gpu/drm/tiny/gm12u320.c
+++ b/drivers/gpu/drm/tiny/gm12u320.c
@@ -13,7 +13,7 @@
#include <drm/drm_damage_helper.h>
#include <drm/drm_drv.h>
#include <drm/drm_edid.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_shmem.h>
#include <drm/drm_file.h>
#include <drm/drm_format_helper.h>
#include <drm/drm_fourcc.h>
@@ -699,7 +699,7 @@ static int gm12u320_usb_probe(struct usb_interface *interface,
if (ret)
goto err_put_device;
- drm_fbdev_generic_setup(dev, 0);
+ drm_fbdev_shmem_setup(dev, 0);
return 0;
@@ -755,4 +755,5 @@ static struct usb_driver gm12u320_usb_driver = {
module_usb_driver(gm12u320_usb_driver);
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
+MODULE_DESCRIPTION("GM12U320 driver for USB projectors");
MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/tiny/hx8357d.c b/drivers/gpu/drm/tiny/hx8357d.c
index cdc4486e059b..2e631282edeb 100644
--- a/drivers/gpu/drm/tiny/hx8357d.c
+++ b/drivers/gpu/drm/tiny/hx8357d.c
@@ -18,7 +18,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_dma.h>
#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_managed.h>
@@ -256,7 +256,7 @@ static int hx8357d_probe(struct spi_device *spi)
spi_set_drvdata(spi, drm);
- drm_fbdev_generic_setup(drm, 0);
+ drm_fbdev_dma_setup(drm, 0);
return 0;
}
diff --git a/drivers/gpu/drm/tiny/ili9163.c b/drivers/gpu/drm/tiny/ili9163.c
index bc4384d410fc..86f9d8834901 100644
--- a/drivers/gpu/drm/tiny/ili9163.c
+++ b/drivers/gpu/drm/tiny/ili9163.c
@@ -9,7 +9,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_dma.h>
#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_mipi_dbi.h>
@@ -185,7 +185,7 @@ static int ili9163_probe(struct spi_device *spi)
if (ret)
return ret;
- drm_fbdev_generic_setup(drm, 0);
+ drm_fbdev_dma_setup(drm, 0);
return 0;
}
diff --git a/drivers/gpu/drm/tiny/ili9225.c b/drivers/gpu/drm/tiny/ili9225.c
index dd8b0a181be9..b6b7a49147bf 100644
--- a/drivers/gpu/drm/tiny/ili9225.c
+++ b/drivers/gpu/drm/tiny/ili9225.c
@@ -20,7 +20,7 @@
#include <drm/drm_damage_helper.h>
#include <drm/drm_drv.h>
#include <drm/drm_fb_dma_helper.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_dma.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_atomic_helper.h>
@@ -426,7 +426,7 @@ static int ili9225_probe(struct spi_device *spi)
spi_set_drvdata(spi, drm);
- drm_fbdev_generic_setup(drm, 0);
+ drm_fbdev_dma_setup(drm, 0);
return 0;
}
@@ -447,7 +447,6 @@ static void ili9225_shutdown(struct spi_device *spi)
static struct spi_driver ili9225_spi_driver = {
.driver = {
.name = "ili9225",
- .owner = THIS_MODULE,
.of_match_table = ili9225_of_match,
},
.id_table = ili9225_id,
diff --git a/drivers/gpu/drm/tiny/ili9341.c b/drivers/gpu/drm/tiny/ili9341.c
index 47b61c3bf145..8bcada30af71 100644
--- a/drivers/gpu/drm/tiny/ili9341.c
+++ b/drivers/gpu/drm/tiny/ili9341.c
@@ -17,7 +17,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_dma.h>
#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_managed.h>
@@ -218,7 +218,7 @@ static int ili9341_probe(struct spi_device *spi)
spi_set_drvdata(spi, drm);
- drm_fbdev_generic_setup(drm, 0);
+ drm_fbdev_dma_setup(drm, 0);
return 0;
}
diff --git a/drivers/gpu/drm/tiny/ili9486.c b/drivers/gpu/drm/tiny/ili9486.c
index 938bceed5999..70d366260041 100644
--- a/drivers/gpu/drm/tiny/ili9486.c
+++ b/drivers/gpu/drm/tiny/ili9486.c
@@ -16,7 +16,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_dma.h>
#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_managed.h>
@@ -247,7 +247,7 @@ static int ili9486_probe(struct spi_device *spi)
spi_set_drvdata(spi, drm);
- drm_fbdev_generic_setup(drm, 0);
+ drm_fbdev_dma_setup(drm, 0);
return 0;
}
diff --git a/drivers/gpu/drm/tiny/mi0283qt.c b/drivers/gpu/drm/tiny/mi0283qt.c
index 01ff43c8ac3f..cdc5423990ca 100644
--- a/drivers/gpu/drm/tiny/mi0283qt.c
+++ b/drivers/gpu/drm/tiny/mi0283qt.c
@@ -15,7 +15,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_dma.h>
#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_managed.h>
@@ -226,7 +226,7 @@ static int mi0283qt_probe(struct spi_device *spi)
spi_set_drvdata(spi, drm);
- drm_fbdev_generic_setup(drm, 0);
+ drm_fbdev_dma_setup(drm, 0);
return 0;
}
@@ -263,7 +263,6 @@ static const struct dev_pm_ops mi0283qt_pm_ops = {
static struct spi_driver mi0283qt_spi_driver = {
.driver = {
.name = "mi0283qt",
- .owner = THIS_MODULE,
.of_match_table = mi0283qt_of_match,
.pm = &mi0283qt_pm_ops,
},
diff --git a/drivers/gpu/drm/tiny/ofdrm.c b/drivers/gpu/drm/tiny/ofdrm.c
index ab89b7fc7bf6..35996f7eedac 100644
--- a/drivers/gpu/drm/tiny/ofdrm.c
+++ b/drivers/gpu/drm/tiny/ofdrm.c
@@ -11,7 +11,7 @@
#include <drm/drm_damage_helper.h>
#include <drm/drm_device.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_shmem.h>
#include <drm/drm_format_helper.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_atomic_helper.h>
@@ -1377,7 +1377,7 @@ static int ofdrm_probe(struct platform_device *pdev)
if (color_mode == 16)
color_mode = odev->format->depth; // can be 15 or 16
- drm_fbdev_generic_setup(dev, color_mode);
+ drm_fbdev_shmem_setup(dev, color_mode);
return 0;
}
diff --git a/drivers/gpu/drm/tiny/panel-mipi-dbi.c b/drivers/gpu/drm/tiny/panel-mipi-dbi.c
index f80a141fcf36..f753cdffe6f8 100644
--- a/drivers/gpu/drm/tiny/panel-mipi-dbi.c
+++ b/drivers/gpu/drm/tiny/panel-mipi-dbi.c
@@ -16,7 +16,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_dma.h>
#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_managed.h>
@@ -26,6 +26,49 @@
#include <video/mipi_display.h>
+struct panel_mipi_dbi_format {
+ const char *name;
+ u32 fourcc;
+ unsigned int bpp;
+};
+
+static const struct panel_mipi_dbi_format panel_mipi_dbi_formats[] = {
+ { "r5g6b5", DRM_FORMAT_RGB565, 16 },
+ { "b6x2g6x2r6x2", DRM_FORMAT_RGB888, 24 },
+};
+
+static int panel_mipi_dbi_get_format(struct device *dev, u32 *formats, unsigned int *bpp)
+{
+ const char *format_name;
+ unsigned int i;
+ int ret;
+
+ formats[1] = DRM_FORMAT_XRGB8888;
+
+ ret = device_property_read_string(dev, "format", &format_name);
+ if (ret) {
+ /* Old Device Trees don't have this property */
+ formats[0] = DRM_FORMAT_RGB565;
+ *bpp = 16;
+ return 0;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(panel_mipi_dbi_formats); i++) {
+ const struct panel_mipi_dbi_format *format = &panel_mipi_dbi_formats[i];
+
+ if (strcmp(format_name, format->name))
+ continue;
+
+ formats[0] = format->fourcc;
+ *bpp = format->bpp;
+ return 0;
+ }
+
+ dev_err(dev, "Pixel format is not supported: '%s'\n", format_name);
+
+ return -EINVAL;
+}
+
static const u8 panel_mipi_dbi_magic[15] = { 'M', 'I', 'P', 'I', ' ', 'D', 'B', 'I',
0, 0, 0, 0, 0, 0, 0 };
@@ -276,6 +319,9 @@ static int panel_mipi_dbi_spi_probe(struct spi_device *spi)
struct drm_device *drm;
struct mipi_dbi *dbi;
struct gpio_desc *dc;
+ unsigned int bpp;
+ size_t buf_size;
+ u32 formats[2];
int ret;
dbidev = devm_drm_dev_alloc(dev, &panel_mipi_dbi_driver, struct mipi_dbi_dev, drm);
@@ -323,7 +369,14 @@ static int panel_mipi_dbi_spi_probe(struct spi_device *spi)
if (IS_ERR(dbidev->driver_private))
return PTR_ERR(dbidev->driver_private);
- ret = mipi_dbi_dev_init(dbidev, &panel_mipi_dbi_pipe_funcs, &mode, 0);
+ ret = panel_mipi_dbi_get_format(dev, formats, &bpp);
+ if (ret)
+ return ret;
+
+ buf_size = DIV_ROUND_UP(mode.hdisplay * mode.vdisplay * bpp, 8);
+ ret = mipi_dbi_dev_init_with_formats(dbidev, &panel_mipi_dbi_pipe_funcs,
+ formats, ARRAY_SIZE(formats),
+ &mode, 0, buf_size);
if (ret)
return ret;
@@ -335,7 +388,7 @@ static int panel_mipi_dbi_spi_probe(struct spi_device *spi)
spi_set_drvdata(spi, drm);
- drm_fbdev_generic_setup(drm, 0);
+ drm_fbdev_dma_setup(drm, 0);
return 0;
}
@@ -384,7 +437,6 @@ MODULE_DEVICE_TABLE(spi, panel_mipi_dbi_spi_id);
static struct spi_driver panel_mipi_dbi_spi_driver = {
.driver = {
.name = "panel-mipi-dbi-spi",
- .owner = THIS_MODULE,
.of_match_table = panel_mipi_dbi_spi_of_match,
.pm = &panel_mipi_dbi_pm_ops,
},
diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c
index 8fd6758f5725..1f78aa3d26bb 100644
--- a/drivers/gpu/drm/tiny/repaper.c
+++ b/drivers/gpu/drm/tiny/repaper.c
@@ -26,7 +26,7 @@
#include <drm/drm_damage_helper.h>
#include <drm/drm_drv.h>
#include <drm/drm_fb_dma_helper.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_dma.h>
#include <drm/drm_format_helper.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_atomic_helper.h>
@@ -1118,7 +1118,7 @@ static int repaper_probe(struct spi_device *spi)
DRM_DEBUG_DRIVER("SPI speed: %uMHz\n", spi->max_speed_hz / 1000000);
- drm_fbdev_generic_setup(drm, 0);
+ drm_fbdev_dma_setup(drm, 0);
return 0;
}
diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c
index 1d8fa07572c5..d19e10289428 100644
--- a/drivers/gpu/drm/tiny/simpledrm.c
+++ b/drivers/gpu/drm/tiny/simpledrm.c
@@ -17,7 +17,7 @@
#include <drm/drm_damage_helper.h>
#include <drm/drm_device.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_shmem.h>
#include <drm/drm_format_helper.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_atomic_helper.h>
@@ -1042,7 +1042,7 @@ static int simpledrm_probe(struct platform_device *pdev)
if (color_mode == 16)
color_mode = sdev->format->depth; // can be 15 or 16
- drm_fbdev_generic_setup(dev, color_mode);
+ drm_fbdev_shmem_setup(dev, color_mode);
return 0;
}
diff --git a/drivers/gpu/drm/tiny/st7586.c b/drivers/gpu/drm/tiny/st7586.c
index 7336fa1ddaed..b9c6ed352182 100644
--- a/drivers/gpu/drm/tiny/st7586.c
+++ b/drivers/gpu/drm/tiny/st7586.c
@@ -16,7 +16,7 @@
#include <drm/drm_damage_helper.h>
#include <drm/drm_drv.h>
#include <drm/drm_fb_dma_helper.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_dma.h>
#include <drm/drm_format_helper.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_atomic_helper.h>
@@ -371,7 +371,7 @@ static int st7586_probe(struct spi_device *spi)
spi_set_drvdata(spi, drm);
- drm_fbdev_generic_setup(drm, 0);
+ drm_fbdev_dma_setup(drm, 0);
return 0;
}
@@ -392,7 +392,6 @@ static void st7586_shutdown(struct spi_device *spi)
static struct spi_driver st7586_spi_driver = {
.driver = {
.name = "st7586",
- .owner = THIS_MODULE,
.of_match_table = st7586_of_match,
},
.id_table = st7586_id,
diff --git a/drivers/gpu/drm/tiny/st7735r.c b/drivers/gpu/drm/tiny/st7735r.c
index 477eb36fbb70..1676da00883d 100644
--- a/drivers/gpu/drm/tiny/st7735r.c
+++ b/drivers/gpu/drm/tiny/st7735r.c
@@ -18,7 +18,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_dma.h>
#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_managed.h>
@@ -241,7 +241,7 @@ static int st7735r_probe(struct spi_device *spi)
spi_set_drvdata(spi, drm);
- drm_fbdev_generic_setup(drm, 0);
+ drm_fbdev_dma_setup(drm, 0);
return 0;
}
diff --git a/drivers/gpu/drm/udl/Makefile b/drivers/gpu/drm/udl/Makefile
index 3f6db179455d..43d69a16af18 100644
--- a/drivers/gpu/drm/udl/Makefile
+++ b/drivers/gpu/drm/udl/Makefile
@@ -1,4 +1,10 @@
# SPDX-License-Identifier: GPL-2.0-only
-udl-y := udl_drv.o udl_modeset.o udl_main.o udl_transfer.o
+
+udl-y := \
+ udl_drv.o \
+ udl_edid.o \
+ udl_main.o \
+ udl_modeset.o \
+ udl_transfer.o
obj-$(CONFIG_DRM_UDL) := udl.o
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index 1506094a8009..280a09a6e2ad 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -6,7 +6,7 @@
#include <linux/module.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_shmem.h>
#include <drm/drm_file.h>
#include <drm/drm_gem_shmem_helper.h>
#include <drm/drm_managed.h>
@@ -117,7 +117,7 @@ static int udl_usb_probe(struct usb_interface *interface,
DRM_INFO("Initialized udl on minor %d\n", udl->drm.primary->index);
- drm_fbdev_generic_setup(&udl->drm, 0);
+ drm_fbdev_shmem_setup(&udl->drm, 0);
return 0;
}
@@ -160,4 +160,5 @@ static struct usb_driver udl_driver = {
.id_table = id_table,
};
module_usb_driver(udl_driver);
+MODULE_DESCRIPTION("KMS driver for the USB displaylink video adapters");
MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
index 282ebd6c02fd..1eb716d9dad5 100644
--- a/drivers/gpu/drm/udl/udl_drv.h
+++ b/drivers/gpu/drm/udl/udl_drv.h
@@ -49,17 +49,6 @@ struct urb_list {
size_t size;
};
-struct udl_connector {
- struct drm_connector connector;
- /* last udl_detect edid */
- struct edid *edid;
-};
-
-static inline struct udl_connector *to_udl_connector(struct drm_connector *connector)
-{
- return container_of(connector, struct udl_connector, connector);
-}
-
struct udl_device {
struct drm_device drm;
struct device *dev;
@@ -68,6 +57,7 @@ struct udl_device {
struct drm_plane primary_plane;
struct drm_crtc crtc;
struct drm_encoder encoder;
+ struct drm_connector connector;
struct mutex gem_lock;
diff --git a/drivers/gpu/drm/udl/udl_edid.c b/drivers/gpu/drm/udl/udl_edid.c
new file mode 100644
index 000000000000..d67e6bf1f2ae
--- /dev/null
+++ b/drivers/gpu/drm/udl/udl_edid.c
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/string.h>
+
+#include <drm/drm_drv.h>
+#include <drm/drm_edid.h>
+
+#include "udl_drv.h"
+#include "udl_edid.h"
+
+static int udl_read_edid_block(void *data, u8 *buf, unsigned int block, size_t len)
+{
+ struct udl_device *udl = data;
+ struct drm_device *dev = &udl->drm;
+ struct usb_device *udev = udl_to_usb_device(udl);
+ u8 *read_buff;
+ int idx, ret;
+ size_t i;
+
+ read_buff = kmalloc(2, GFP_KERNEL);
+ if (!read_buff)
+ return -ENOMEM;
+
+ if (!drm_dev_enter(dev, &idx)) {
+ ret = -ENODEV;
+ goto err_kfree;
+ }
+
+ for (i = 0; i < len; i++) {
+ int bval = (i + block * EDID_LENGTH) << 8;
+
+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+ 0x02, (0x80 | (0x02 << 5)), bval,
+ 0xA1, read_buff, 2, USB_CTRL_GET_TIMEOUT);
+ if (ret < 0) {
+ drm_err(dev, "Read EDID byte %zu failed err %x\n", i, ret);
+ goto err_drm_dev_exit;
+ } else if (ret < 1) {
+ ret = -EIO;
+ drm_err(dev, "Read EDID byte %zu failed\n", i);
+ goto err_drm_dev_exit;
+ }
+
+ buf[i] = read_buff[1];
+ }
+
+ drm_dev_exit(idx);
+ kfree(read_buff);
+
+ return 0;
+
+err_drm_dev_exit:
+ drm_dev_exit(idx);
+err_kfree:
+ kfree(read_buff);
+ return ret;
+}
+
+bool udl_probe_edid(struct udl_device *udl)
+{
+ u8 hdr[8];
+ int ret;
+
+ ret = udl_read_edid_block(udl, hdr, 0, sizeof(hdr));
+ if (ret)
+ return false;
+
+ /*
+ * The adapter sends all-zeros if no monitor has been
+ * connected. We consider anything else a connection.
+ */
+ return !!memchr_inv(hdr, 0, sizeof(hdr));
+}
+
+const struct drm_edid *udl_edid_read(struct drm_connector *connector)
+{
+ struct udl_device *udl = to_udl(connector->dev);
+
+ return drm_edid_read_custom(connector, udl_read_edid_block, udl);
+}
diff --git a/drivers/gpu/drm/udl/udl_edid.h b/drivers/gpu/drm/udl/udl_edid.h
new file mode 100644
index 000000000000..fe15ff3752b7
--- /dev/null
+++ b/drivers/gpu/drm/udl/udl_edid.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef UDL_EDID_H
+#define UDL_EDID_H
+
+#include <linux/types.h>
+
+struct drm_connector;
+struct drm_edid;
+struct udl_device;
+
+bool udl_probe_edid(struct udl_device *udl);
+const struct drm_edid *udl_edid_read(struct drm_connector *connector);
+
+#endif
diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c
index 7702359c90c2..bbb04f98886a 100644
--- a/drivers/gpu/drm/udl/udl_modeset.c
+++ b/drivers/gpu/drm/udl/udl_modeset.c
@@ -25,6 +25,7 @@
#include <drm/drm_vblank.h>
#include "udl_drv.h"
+#include "udl_edid.h"
#include "udl_proto.h"
/*
@@ -415,129 +416,42 @@ static const struct drm_encoder_funcs udl_encoder_funcs = {
static int udl_connector_helper_get_modes(struct drm_connector *connector)
{
- struct udl_connector *udl_connector = to_udl_connector(connector);
+ const struct drm_edid *drm_edid;
+ int count;
- drm_connector_update_edid_property(connector, udl_connector->edid);
- if (udl_connector->edid)
- return drm_add_edid_modes(connector, udl_connector->edid);
+ drm_edid = udl_edid_read(connector);
+ drm_edid_connector_update(connector, drm_edid);
+ count = drm_edid_connector_add_modes(connector);
+ drm_edid_free(drm_edid);
- return 0;
-}
-
-static const struct drm_connector_helper_funcs udl_connector_helper_funcs = {
- .get_modes = udl_connector_helper_get_modes,
-};
-
-static int udl_get_edid_block(void *data, u8 *buf, unsigned int block, size_t len)
-{
- struct udl_device *udl = data;
- struct drm_device *dev = &udl->drm;
- struct usb_device *udev = udl_to_usb_device(udl);
- u8 *read_buff;
- int ret;
- size_t i;
-
- read_buff = kmalloc(2, GFP_KERNEL);
- if (!read_buff)
- return -ENOMEM;
-
- for (i = 0; i < len; i++) {
- int bval = (i + block * EDID_LENGTH) << 8;
-
- ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- 0x02, (0x80 | (0x02 << 5)), bval,
- 0xA1, read_buff, 2, USB_CTRL_GET_TIMEOUT);
- if (ret < 0) {
- drm_err(dev, "Read EDID byte %zu failed err %x\n", i, ret);
- goto err_kfree;
- } else if (ret < 1) {
- ret = -EIO;
- drm_err(dev, "Read EDID byte %zu failed\n", i);
- goto err_kfree;
- }
-
- buf[i] = read_buff[1];
- }
-
- kfree(read_buff);
-
- return 0;
-
-err_kfree:
- kfree(read_buff);
- return ret;
+ return count;
}
-static enum drm_connector_status udl_connector_detect(struct drm_connector *connector, bool force)
+static int udl_connector_helper_detect_ctx(struct drm_connector *connector,
+ struct drm_modeset_acquire_ctx *ctx,
+ bool force)
{
- struct drm_device *dev = connector->dev;
- struct udl_device *udl = to_udl(dev);
- struct udl_connector *udl_connector = to_udl_connector(connector);
- enum drm_connector_status status = connector_status_disconnected;
- int idx;
+ struct udl_device *udl = to_udl(connector->dev);
- /* cleanup previous EDID */
- kfree(udl_connector->edid);
- udl_connector->edid = NULL;
+ if (udl_probe_edid(udl))
+ return connector_status_connected;
- if (!drm_dev_enter(dev, &idx))
- return connector_status_disconnected;
-
- udl_connector->edid = drm_do_get_edid(connector, udl_get_edid_block, udl);
- if (udl_connector->edid)
- status = connector_status_connected;
-
- drm_dev_exit(idx);
-
- return status;
+ return connector_status_disconnected;
}
-static void udl_connector_destroy(struct drm_connector *connector)
-{
- struct udl_connector *udl_connector = to_udl_connector(connector);
-
- drm_connector_cleanup(connector);
- kfree(udl_connector->edid);
- kfree(udl_connector);
-}
+static const struct drm_connector_helper_funcs udl_connector_helper_funcs = {
+ .get_modes = udl_connector_helper_get_modes,
+ .detect_ctx = udl_connector_helper_detect_ctx,
+};
static const struct drm_connector_funcs udl_connector_funcs = {
.reset = drm_atomic_helper_connector_reset,
- .detect = udl_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
- .destroy = udl_connector_destroy,
+ .destroy = drm_connector_cleanup,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
-struct drm_connector *udl_connector_init(struct drm_device *dev)
-{
- struct udl_connector *udl_connector;
- struct drm_connector *connector;
- int ret;
-
- udl_connector = kzalloc(sizeof(*udl_connector), GFP_KERNEL);
- if (!udl_connector)
- return ERR_PTR(-ENOMEM);
-
- connector = &udl_connector->connector;
- ret = drm_connector_init(dev, connector, &udl_connector_funcs, DRM_MODE_CONNECTOR_VGA);
- if (ret)
- goto err_kfree;
-
- drm_connector_helper_add(connector, &udl_connector_helper_funcs);
-
- connector->polled = DRM_CONNECTOR_POLL_HPD |
- DRM_CONNECTOR_POLL_CONNECT |
- DRM_CONNECTOR_POLL_DISCONNECT;
-
- return connector;
-
-err_kfree:
- kfree(udl_connector);
- return ERR_PTR(ret);
-}
-
/*
* Modesetting
*/
@@ -607,9 +521,15 @@ int udl_modeset_init(struct drm_device *dev)
return ret;
encoder->possible_crtcs = drm_crtc_mask(crtc);
- connector = udl_connector_init(dev);
- if (IS_ERR(connector))
- return PTR_ERR(connector);
+ connector = &udl->connector;
+ ret = drm_connector_init(dev, connector, &udl_connector_funcs, DRM_MODE_CONNECTOR_VGA);
+ if (ret)
+ return ret;
+ drm_connector_helper_add(connector, &udl_connector_helper_funcs);
+
+ connector->polled = DRM_CONNECTOR_POLL_CONNECT |
+ DRM_CONNECTOR_POLL_DISCONNECT;
+
ret = drm_connector_attach_encoder(connector, encoder);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c
index 28b7ddce7747..a47f00b443d3 100644
--- a/drivers/gpu/drm/v3d/v3d_drv.c
+++ b/drivers/gpu/drm/v3d/v3d_drv.c
@@ -94,6 +94,9 @@ static int v3d_get_param_ioctl(struct drm_device *dev, void *data,
case DRM_V3D_PARAM_SUPPORTS_CPU_QUEUE:
args->value = 1;
return 0;
+ case DRM_V3D_PARAM_MAX_PERF_COUNTERS:
+ args->value = v3d->max_counters;
+ return 0;
default:
DRM_DEBUG("Unknown parameter %d\n", args->param);
return -EINVAL;
@@ -208,6 +211,7 @@ static const struct drm_ioctl_desc v3d_drm_ioctls[] = {
DRM_IOCTL_DEF_DRV(V3D_PERFMON_DESTROY, v3d_perfmon_destroy_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(V3D_PERFMON_GET_VALUES, v3d_perfmon_get_values_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(V3D_SUBMIT_CPU, v3d_submit_cpu_ioctl, DRM_RENDER_ALLOW | DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(V3D_PERFMON_GET_COUNTER, v3d_perfmon_get_counter_ioctl, DRM_RENDER_ALLOW),
};
static const struct drm_driver v3d_drm_driver = {
@@ -294,6 +298,13 @@ static int v3d_platform_drm_probe(struct platform_device *pdev)
v3d->cores = V3D_GET_FIELD(ident1, V3D_HUB_IDENT1_NCORES);
WARN_ON(v3d->cores > 1); /* multicore not yet implemented */
+ if (v3d->ver >= 71)
+ v3d->max_counters = V3D_V71_NUM_PERFCOUNTERS;
+ else if (v3d->ver >= 42)
+ v3d->max_counters = V3D_V42_NUM_PERFCOUNTERS;
+ else
+ v3d->max_counters = 0;
+
v3d->reset = devm_reset_control_get_exclusive(dev, NULL);
if (IS_ERR(v3d->reset)) {
ret = PTR_ERR(v3d->reset);
diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h
index a2c516fe6d79..099b962bdfde 100644
--- a/drivers/gpu/drm/v3d/v3d_drv.h
+++ b/drivers/gpu/drm/v3d/v3d_drv.h
@@ -11,6 +11,8 @@
#include <drm/drm_gem_shmem_helper.h>
#include <drm/gpu_scheduler.h>
+#include "v3d_performance_counters.h"
+
#include "uapi/drm/v3d_drm.h"
struct clk;
@@ -102,6 +104,11 @@ struct v3d_dev {
int ver;
bool single_irq_line;
+ /* Different revisions of V3D have different total number of performance
+ * counters
+ */
+ unsigned int max_counters;
+
void __iomem *hub_regs;
void __iomem *core_regs[3];
void __iomem *bridge_regs;
@@ -345,7 +352,7 @@ struct v3d_timestamp_query {
};
/* Number of perfmons required to handle all supported performance counters */
-#define V3D_MAX_PERFMONS DIV_ROUND_UP(V3D_PERFCNT_NUM, \
+#define V3D_MAX_PERFMONS DIV_ROUND_UP(V3D_MAX_COUNTERS, \
DRM_V3D_MAX_PERF_COUNTERS)
struct v3d_performance_query {
@@ -575,6 +582,8 @@ int v3d_perfmon_destroy_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
int v3d_perfmon_get_values_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+int v3d_perfmon_get_counter_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
/* v3d_sysfs.c */
int v3d_sysfs_init(struct device *dev);
diff --git a/drivers/gpu/drm/v3d/v3d_perfmon.c b/drivers/gpu/drm/v3d/v3d_perfmon.c
index e1be7368b87d..b7d0b02e1a95 100644
--- a/drivers/gpu/drm/v3d/v3d_perfmon.c
+++ b/drivers/gpu/drm/v3d/v3d_perfmon.c
@@ -9,6 +9,192 @@
#define V3D_PERFMONID_MIN 1
#define V3D_PERFMONID_MAX U32_MAX
+static const struct v3d_perf_counter_desc v3d_v42_performance_counters[] = {
+ {"FEP", "FEP-valid-primitives-no-rendered-pixels", "[FEP] Valid primitives that result in no rendered pixels, for all rendered tiles"},
+ {"FEP", "FEP-valid-primitives-rendered-pixels", "[FEP] Valid primitives for all rendered tiles (primitives may be counted in more than one tile)"},
+ {"FEP", "FEP-clipped-quads", "[FEP] Early-Z/Near/Far clipped quads"},
+ {"FEP", "FEP-valid-quads", "[FEP] Valid quads"},
+ {"TLB", "TLB-quads-not-passing-stencil-test", "[TLB] Quads with no pixels passing the stencil test"},
+ {"TLB", "TLB-quads-not-passing-z-and-stencil-test", "[TLB] Quads with no pixels passing the Z and stencil tests"},
+ {"TLB", "TLB-quads-passing-z-and-stencil-test", "[TLB] Quads with any pixels passing the Z and stencil tests"},
+ {"TLB", "TLB-quads-with-zero-coverage", "[TLB] Quads with all pixels having zero coverage"},
+ {"TLB", "TLB-quads-with-non-zero-coverage", "[TLB] Quads with any pixels having non-zero coverage"},
+ {"TLB", "TLB-quads-written-to-color-buffer", "[TLB] Quads with valid pixels written to colour buffer"},
+ {"PTB", "PTB-primitives-discarded-outside-viewport", "[PTB] Primitives discarded by being outside the viewport"},
+ {"PTB", "PTB-primitives-need-clipping", "[PTB] Primitives that need clipping"},
+ {"PTB", "PTB-primitives-discarded-reversed", "[PTB] Primitives that are discarded because they are reversed"},
+ {"QPU", "QPU-total-idle-clk-cycles", "[QPU] Total idle clock cycles for all QPUs"},
+ {"QPU", "QPU-total-active-clk-cycles-vertex-coord-shading", "[QPU] Total active clock cycles for all QPUs doing vertex/coordinate/user shading (counts only when QPU is not stalled)"},
+ {"QPU", "QPU-total-active-clk-cycles-fragment-shading", "[QPU] Total active clock cycles for all QPUs doing fragment shading (counts only when QPU is not stalled)"},
+ {"QPU", "QPU-total-clk-cycles-executing-valid-instr", "[QPU] Total clock cycles for all QPUs executing valid instructions"},
+ {"QPU", "QPU-total-clk-cycles-waiting-TMU", "[QPU] Total clock cycles for all QPUs stalled waiting for TMUs only (counter won't increment if QPU also stalling for another reason)"},
+ {"QPU", "QPU-total-clk-cycles-waiting-scoreboard", "[QPU] Total clock cycles for all QPUs stalled waiting for Scoreboard only (counter won't increment if QPU also stalling for another reason)"},
+ {"QPU", "QPU-total-clk-cycles-waiting-varyings", "[QPU] Total clock cycles for all QPUs stalled waiting for Varyings only (counter won't increment if QPU also stalling for another reason)"},
+ {"QPU", "QPU-total-instr-cache-hit", "[QPU] Total instruction cache hits for all slices"},
+ {"QPU", "QPU-total-instr-cache-miss", "[QPU] Total instruction cache misses for all slices"},
+ {"QPU", "QPU-total-uniform-cache-hit", "[QPU] Total uniforms cache hits for all slices"},
+ {"QPU", "QPU-total-uniform-cache-miss", "[QPU] Total uniforms cache misses for all slices"},
+ {"TMU", "TMU-total-text-quads-access", "[TMU] Total texture cache accesses"},
+ {"TMU", "TMU-total-text-cache-miss", "[TMU] Total texture cache misses (number of fetches from memory/L2cache)"},
+ {"VPM", "VPM-total-clk-cycles-VDW-stalled", "[VPM] Total clock cycles VDW is stalled waiting for VPM access"},
+ {"VPM", "VPM-total-clk-cycles-VCD-stalled", "[VPM] Total clock cycles VCD is stalled waiting for VPM access"},
+ {"CLE", "CLE-bin-thread-active-cycles", "[CLE] Bin thread active cycles"},
+ {"CLE", "CLE-render-thread-active-cycles", "[CLE] Render thread active cycles"},
+ {"L2T", "L2T-total-cache-hit", "[L2T] Total Level 2 cache hits"},
+ {"L2T", "L2T-total-cache-miss", "[L2T] Total Level 2 cache misses"},
+ {"CORE", "cycle-count", "[CORE] Cycle counter"},
+ {"QPU", "QPU-total-clk-cycles-waiting-vertex-coord-shading", "[QPU] Total stalled clock cycles for all QPUs doing vertex/coordinate/user shading"},
+ {"QPU", "QPU-total-clk-cycles-waiting-fragment-shading", "[QPU] Total stalled clock cycles for all QPUs doing fragment shading"},
+ {"PTB", "PTB-primitives-binned", "[PTB] Total primitives binned"},
+ {"AXI", "AXI-writes-seen-watch-0", "[AXI] Writes seen by watch 0"},
+ {"AXI", "AXI-reads-seen-watch-0", "[AXI] Reads seen by watch 0"},
+ {"AXI", "AXI-writes-stalled-seen-watch-0", "[AXI] Write stalls seen by watch 0"},
+ {"AXI", "AXI-reads-stalled-seen-watch-0", "[AXI] Read stalls seen by watch 0"},
+ {"AXI", "AXI-write-bytes-seen-watch-0", "[AXI] Total bytes written seen by watch 0"},
+ {"AXI", "AXI-read-bytes-seen-watch-0", "[AXI] Total bytes read seen by watch 0"},
+ {"AXI", "AXI-writes-seen-watch-1", "[AXI] Writes seen by watch 1"},
+ {"AXI", "AXI-reads-seen-watch-1", "[AXI] Reads seen by watch 1"},
+ {"AXI", "AXI-writes-stalled-seen-watch-1", "[AXI] Write stalls seen by watch 1"},
+ {"AXI", "AXI-reads-stalled-seen-watch-1", "[AXI] Read stalls seen by watch 1"},
+ {"AXI", "AXI-write-bytes-seen-watch-1", "[AXI] Total bytes written seen by watch 1"},
+ {"AXI", "AXI-read-bytes-seen-watch-1", "[AXI] Total bytes read seen by watch 1"},
+ {"TLB", "TLB-partial-quads-written-to-color-buffer", "[TLB] Partial quads written to the colour buffer"},
+ {"TMU", "TMU-total-config-access", "[TMU] Total config accesses"},
+ {"L2T", "L2T-no-id-stalled", "[L2T] No ID stall"},
+ {"L2T", "L2T-command-queue-stalled", "[L2T] Command queue full stall"},
+ {"L2T", "L2T-TMU-writes", "[L2T] TMU write accesses"},
+ {"TMU", "TMU-active-cycles", "[TMU] Active cycles"},
+ {"TMU", "TMU-stalled-cycles", "[TMU] Stalled cycles"},
+ {"CLE", "CLE-thread-active-cycles", "[CLE] Bin or render thread active cycles"},
+ {"L2T", "L2T-TMU-reads", "[L2T] TMU read accesses"},
+ {"L2T", "L2T-CLE-reads", "[L2T] CLE read accesses"},
+ {"L2T", "L2T-VCD-reads", "[L2T] VCD read accesses"},
+ {"L2T", "L2T-TMU-config-reads", "[L2T] TMU CFG read accesses"},
+ {"L2T", "L2T-SLC0-reads", "[L2T] SLC0 read accesses"},
+ {"L2T", "L2T-SLC1-reads", "[L2T] SLC1 read accesses"},
+ {"L2T", "L2T-SLC2-reads", "[L2T] SLC2 read accesses"},
+ {"L2T", "L2T-TMU-write-miss", "[L2T] TMU write misses"},
+ {"L2T", "L2T-TMU-read-miss", "[L2T] TMU read misses"},
+ {"L2T", "L2T-CLE-read-miss", "[L2T] CLE read misses"},
+ {"L2T", "L2T-VCD-read-miss", "[L2T] VCD read misses"},
+ {"L2T", "L2T-TMU-config-read-miss", "[L2T] TMU CFG read misses"},
+ {"L2T", "L2T-SLC0-read-miss", "[L2T] SLC0 read misses"},
+ {"L2T", "L2T-SLC1-read-miss", "[L2T] SLC1 read misses"},
+ {"L2T", "L2T-SLC2-read-miss", "[L2T] SLC2 read misses"},
+ {"CORE", "core-memory-writes", "[CORE] Total memory writes"},
+ {"L2T", "L2T-memory-writes", "[L2T] Total memory writes"},
+ {"PTB", "PTB-memory-writes", "[PTB] Total memory writes"},
+ {"TLB", "TLB-memory-writes", "[TLB] Total memory writes"},
+ {"CORE", "core-memory-reads", "[CORE] Total memory reads"},
+ {"L2T", "L2T-memory-reads", "[L2T] Total memory reads"},
+ {"PTB", "PTB-memory-reads", "[PTB] Total memory reads"},
+ {"PSE", "PSE-memory-reads", "[PSE] Total memory reads"},
+ {"TLB", "TLB-memory-reads", "[TLB] Total memory reads"},
+ {"GMP", "GMP-memory-reads", "[GMP] Total memory reads"},
+ {"PTB", "PTB-memory-words-writes", "[PTB] Total memory words written"},
+ {"TLB", "TLB-memory-words-writes", "[TLB] Total memory words written"},
+ {"PSE", "PSE-memory-words-reads", "[PSE] Total memory words read"},
+ {"TLB", "TLB-memory-words-reads", "[TLB] Total memory words read"},
+ {"TMU", "TMU-MRU-hits", "[TMU] Total MRU hits"},
+ {"CORE", "compute-active-cycles", "[CORE] Compute active cycles"},
+};
+
+static const struct v3d_perf_counter_desc v3d_v71_performance_counters[] = {
+ {"CORE", "cycle-count", "[CORE] Cycle counter"},
+ {"CORE", "core-active", "[CORE] Bin/Render/Compute active cycles"},
+ {"CLE", "CLE-bin-thread-active-cycles", "[CLE] Bin thread active cycles"},
+ {"CLE", "CLE-render-thread-active-cycles", "[CLE] Render thread active cycles"},
+ {"CORE", "compute-active-cycles", "[CORE] Compute active cycles"},
+ {"FEP", "FEP-valid-primitives-no-rendered-pixels", "[FEP] Valid primitives that result in no rendered pixels, for all rendered tiles"},
+ {"FEP", "FEP-valid-primitives-rendered-pixels", "[FEP] Valid primitives for all rendered tiles (primitives may be counted in more than one tile)"},
+ {"FEP", "FEP-clipped-quads", "[FEP] Early-Z/Near/Far clipped quads"},
+ {"FEP", "FEP-valid-quads", "[FEP] Valid quads"},
+ {"TLB", "TLB-quads-not-passing-stencil-test", "[TLB] Quads with no pixels passing the stencil test"},
+ {"TLB", "TLB-quads-not-passing-z-and-stencil-test", "[TLB] Quads with no pixels passing the Z and stencil tests"},
+ {"TLB", "TLB-quads-passing-z-and-stencil-test", "[TLB] Quads with any pixels passing the Z and stencil tests"},
+ {"TLB", "TLB-quads-written-to-color-buffer", "[TLB] Quads with valid pixels written to colour buffer"},
+ {"TLB", "TLB-partial-quads-written-to-color-buffer", "[TLB] Partial quads written to the colour buffer"},
+ {"PTB", "PTB-primitives-need-clipping", "[PTB] Primitives that need clipping"},
+ {"PTB", "PTB-primitives-discarded-outside-viewport", "[PTB] Primitives discarded by being outside the viewport"},
+ {"PTB", "PTB-primitives-binned", "[PTB] Total primitives binned"},
+ {"PTB", "PTB-primitives-discarded-reversed", "[PTB] Primitives that are discarded because they are reversed"},
+ {"QPU", "QPU-total-instr-cache-hit", "[QPU] Total instruction cache hits for all slices"},
+ {"QPU", "QPU-total-instr-cache-miss", "[QPU] Total instruction cache misses for all slices"},
+ {"QPU", "QPU-total-uniform-cache-hit", "[QPU] Total uniforms cache hits for all slices"},
+ {"QPU", "QPU-total-uniform-cache-miss", "[QPU] Total uniforms cache misses for all slices"},
+ {"TMU", "TMU-active-cycles", "[TMU] Active cycles"},
+ {"TMU", "TMU-stalled-cycles", "[TMU] Stalled cycles"},
+ {"TMU", "TMU-total-text-quads-access", "[TMU] Total texture cache accesses"},
+ {"TMU", "TMU-cache-x4-active-cycles", "[TMU] Cache active cycles for x4 access"},
+ {"TMU", "TMU-cache-x4-stalled-cycles", "[TMU] Cache stalled cycles for x4 access"},
+ {"TMU", "TMU-total-text-quads-x4-access", "[TMU] Total texture cache x4 access"},
+ {"L2T", "L2T-total-cache-hit", "[L2T] Total Level 2 cache hits"},
+ {"L2T", "L2T-total-cache-miss", "[L2T] Total Level 2 cache misses"},
+ {"L2T", "L2T-local", "[L2T] Local mode access"},
+ {"L2T", "L2T-writeback", "[L2T] Writeback"},
+ {"L2T", "L2T-zero", "[L2T] Zero"},
+ {"L2T", "L2T-merge", "[L2T] Merge"},
+ {"L2T", "L2T-fill", "[L2T] Fill"},
+ {"L2T", "L2T-stalls-no-wid", "[L2T] Stalls because no WID available"},
+ {"L2T", "L2T-stalls-no-rid", "[L2T] Stalls because no RID available"},
+ {"L2T", "L2T-stalls-queue-full", "[L2T] Stalls because internal queue full"},
+ {"L2T", "L2T-stalls-wrightback", "[L2T] Stalls because writeback in flight"},
+ {"L2T", "L2T-stalls-mem", "[L2T] Stalls because AXI blocks read"},
+ {"L2T", "L2T-stalls-fill", "[L2T] Stalls because fill pending for victim cache-line"},
+ {"L2T", "L2T-hitq", "[L2T] Sent request via hit queue"},
+ {"L2T", "L2T-hitq-full", "[L2T] Sent request via main queue because hit queue is full"},
+ {"L2T", "L2T-stalls-read-data", "[L2T] Stalls because waiting for data from SDRAM"},
+ {"L2T", "L2T-TMU-read-hits", "[L2T] TMU read hits"},
+ {"L2T", "L2T-TMU-read-miss", "[L2T] TMU read misses"},
+ {"L2T", "L2T-VCD-read-hits", "[L2T] VCD read hits"},
+ {"L2T", "L2T-VCD-read-miss", "[L2T] VCD read misses"},
+ {"L2T", "L2T-SLC-read-hits", "[L2T] SLC read hits (all slices)"},
+ {"L2T", "L2T-SLC-read-miss", "[L2T] SLC read misses (all slices)"},
+ {"AXI", "AXI-writes-seen-watch-0", "[AXI] Writes seen by watch 0"},
+ {"AXI", "AXI-reads-seen-watch-0", "[AXI] Reads seen by watch 0"},
+ {"AXI", "AXI-writes-stalled-seen-watch-0", "[AXI] Write stalls seen by watch 0"},
+ {"AXI", "AXI-reads-stalled-seen-watch-0", "[AXI] Read stalls seen by watch 0"},
+ {"AXI", "AXI-write-bytes-seen-watch-0", "[AXI] Total bytes written seen by watch 0"},
+ {"AXI", "AXI-read-bytes-seen-watch-0", "[AXI] Total bytes read seen by watch 0"},
+ {"AXI", "AXI-writes-seen-watch-1", "[AXI] Writes seen by watch 1"},
+ {"AXI", "AXI-reads-seen-watch-1", "[AXI] Reads seen by watch 1"},
+ {"AXI", "AXI-writes-stalled-seen-watch-1", "[AXI] Write stalls seen by watch 1"},
+ {"AXI", "AXI-reads-stalled-seen-watch-1", "[AXI] Read stalls seen by watch 1"},
+ {"AXI", "AXI-write-bytes-seen-watch-1", "[AXI] Total bytes written seen by watch 1"},
+ {"AXI", "AXI-read-bytes-seen-watch-1", "[AXI] Total bytes read seen by watch 1"},
+ {"CORE", "core-memory-writes", "[CORE] Total memory writes"},
+ {"L2T", "L2T-memory-writes", "[L2T] Total memory writes"},
+ {"PTB", "PTB-memory-writes", "[PTB] Total memory writes"},
+ {"TLB", "TLB-memory-writes", "[TLB] Total memory writes"},
+ {"CORE", "core-memory-reads", "[CORE] Total memory reads"},
+ {"L2T", "L2T-memory-reads", "[L2T] Total memory reads"},
+ {"PTB", "PTB-memory-reads", "[PTB] Total memory reads"},
+ {"PSE", "PSE-memory-reads", "[PSE] Total memory reads"},
+ {"TLB", "TLB-memory-reads", "[TLB] Total memory reads"},
+ {"PTB", "PTB-memory-words-writes", "[PTB] Total memory words written"},
+ {"TLB", "TLB-memory-words-writes", "[TLB] Total memory words written"},
+ {"PSE", "PSE-memory-words-reads", "[PSE] Total memory words read"},
+ {"TLB", "TLB-memory-words-reads", "[TLB] Total memory words read"},
+ {"AXI", "AXI-read-trans", "[AXI] Read transaction count"},
+ {"AXI", "AXI-write-trans", "[AXI] Write transaction count"},
+ {"AXI", "AXI-read-wait-cycles", "[AXI] Read total wait cycles"},
+ {"AXI", "AXI-write-wait-cycles", "[AXI] Write total wait cycles"},
+ {"AXI", "AXI-max-outstanding-reads", "[AXI] Maximum outstanding read transactions"},
+ {"AXI", "AXI-max-outstanding-writes", "[AXI] Maximum outstanding write transactions"},
+ {"QPU", "QPU-wait-bubble", "[QPU] Pipeline bubble in qcycles due all threads waiting"},
+ {"QPU", "QPU-ic-miss-bubble", "[QPU] Pipeline bubble in qcycles due instruction-cache miss"},
+ {"QPU", "QPU-active", "[QPU] Executed shader instruction"},
+ {"QPU", "QPU-total-active-clk-cycles-fragment-shading", "[QPU] Total active clock cycles for all QPUs doing fragment shading (counts only when QPU is not stalled)"},
+ {"QPU", "QPU-stalls", "[QPU] Stalled qcycles executing shader instruction"},
+ {"QPU", "QPU-total-clk-cycles-waiting-fragment-shading", "[QPU] Total stalled clock cycles for all QPUs doing fragment shading"},
+ {"QPU", "QPU-stalls-TMU", "[QPU] Stalled qcycles waiting for TMU"},
+ {"QPU", "QPU-stalls-TLB", "[QPU] Stalled qcycles waiting for TLB"},
+ {"QPU", "QPU-stalls-VPM", "[QPU] Stalled qcycles waiting for VPM"},
+ {"QPU", "QPU-stalls-uniforms", "[QPU] Stalled qcycles waiting for uniforms"},
+ {"QPU", "QPU-stalls-SFU", "[QPU] Stalled qcycles waiting for SFU"},
+ {"QPU", "QPU-stalls-other", "[QPU] Stalled qcycles waiting for any other reason (vary/W/Z)"},
+};
+
void v3d_perfmon_get(struct v3d_perfmon *perfmon)
{
if (perfmon)
@@ -123,6 +309,7 @@ int v3d_perfmon_create_ioctl(struct drm_device *dev, void *data,
{
struct v3d_file_priv *v3d_priv = file_priv->driver_priv;
struct drm_v3d_perfmon_create *req = data;
+ struct v3d_dev *v3d = v3d_priv->v3d;
struct v3d_perfmon *perfmon;
unsigned int i;
int ret;
@@ -134,7 +321,7 @@ int v3d_perfmon_create_ioctl(struct drm_device *dev, void *data,
/* Make sure all counters are valid. */
for (i = 0; i < req->ncounters; i++) {
- if (req->counters[i] >= V3D_PERFCNT_NUM)
+ if (req->counters[i] >= v3d->max_counters)
return -EINVAL;
}
@@ -216,3 +403,42 @@ int v3d_perfmon_get_values_ioctl(struct drm_device *dev, void *data,
return ret;
}
+
+int v3d_perfmon_get_counter_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_v3d_perfmon_get_counter *req = data;
+ struct v3d_dev *v3d = to_v3d_dev(dev);
+ const struct v3d_perf_counter_desc *counter;
+
+ for (int i = 0; i < ARRAY_SIZE(req->reserved); i++) {
+ if (req->reserved[i] != 0)
+ return -EINVAL;
+ }
+
+ /* Make sure that the counter ID is valid */
+ if (req->counter >= v3d->max_counters)
+ return -EINVAL;
+
+ BUILD_BUG_ON(ARRAY_SIZE(v3d_v42_performance_counters) !=
+ V3D_V42_NUM_PERFCOUNTERS);
+ BUILD_BUG_ON(ARRAY_SIZE(v3d_v71_performance_counters) !=
+ V3D_V71_NUM_PERFCOUNTERS);
+ BUILD_BUG_ON(V3D_MAX_COUNTERS < V3D_V42_NUM_PERFCOUNTERS);
+ BUILD_BUG_ON(V3D_MAX_COUNTERS < V3D_V71_NUM_PERFCOUNTERS);
+ BUILD_BUG_ON((V3D_MAX_COUNTERS != V3D_V42_NUM_PERFCOUNTERS) &&
+ (V3D_MAX_COUNTERS != V3D_V71_NUM_PERFCOUNTERS));
+
+ if (v3d->ver >= 71)
+ counter = &v3d_v71_performance_counters[req->counter];
+ else if (v3d->ver >= 42)
+ counter = &v3d_v42_performance_counters[req->counter];
+ else
+ return -EOPNOTSUPP;
+
+ strscpy(req->name, counter->name, sizeof(req->name));
+ strscpy(req->category, counter->category, sizeof(req->category));
+ strscpy(req->description, counter->description, sizeof(req->description));
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/v3d/v3d_performance_counters.h b/drivers/gpu/drm/v3d/v3d_performance_counters.h
new file mode 100644
index 000000000000..131b2909522a
--- /dev/null
+++ b/drivers/gpu/drm/v3d/v3d_performance_counters.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2024 Raspberry Pi
+ */
+#ifndef V3D_PERFORMANCE_COUNTERS_H
+#define V3D_PERFORMANCE_COUNTERS_H
+
+/* Holds a description of a given performance counter. The index of performance
+ * counter is given by the array on v3d_performance_counter.h
+ */
+struct v3d_perf_counter_desc {
+ /* Category of the counter */
+ char category[32];
+
+ /* Name of the counter */
+ char name[64];
+
+ /* Description of the counter */
+ char description[256];
+};
+
+
+#define V3D_V42_NUM_PERFCOUNTERS (87)
+#define V3D_V71_NUM_PERFCOUNTERS (93)
+
+/* Maximum number of performance counters supported by any version of V3D */
+#define V3D_MAX_COUNTERS (93)
+
+#endif
diff --git a/drivers/gpu/drm/v3d/v3d_sched.c b/drivers/gpu/drm/v3d/v3d_sched.c
index 7cd8c335cd9b..03df37a3acf5 100644
--- a/drivers/gpu/drm/v3d/v3d_sched.c
+++ b/drivers/gpu/drm/v3d/v3d_sched.c
@@ -490,7 +490,7 @@ v3d_write_performance_query_result(struct v3d_cpu_job *job, void *data, u32 quer
struct v3d_file_priv *v3d_priv = job->base.file->driver_priv;
struct v3d_dev *v3d = job->base.v3d;
struct v3d_perfmon *perfmon;
- u64 counter_values[V3D_PERFCNT_NUM];
+ u64 counter_values[V3D_MAX_COUNTERS];
for (int i = 0; i < performance_query->nperfmons; i++) {
perfmon = v3d_perfmon_find(v3d_priv,
diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c
index cd9e66a06596..ef36834c8673 100644
--- a/drivers/gpu/drm/vboxvideo/vbox_drv.c
+++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c
@@ -14,7 +14,7 @@
#include <drm/drm_aperture.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_ttm.h>
#include <drm/drm_file.h>
#include <drm/drm_ioctl.h>
#include <drm/drm_managed.h>
@@ -80,7 +80,7 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (ret)
goto err_irq_fini;
- drm_fbdev_generic_setup(&vbox->ddev, 32);
+ drm_fbdev_ttm_setup(&vbox->ddev, 32);
return 0;
diff --git a/drivers/gpu/drm/vc4/Kconfig b/drivers/gpu/drm/vc4/Kconfig
index 91dcf8d174d6..269b5f26b2ea 100644
--- a/drivers/gpu/drm/vc4/Kconfig
+++ b/drivers/gpu/drm/vc4/Kconfig
@@ -10,6 +10,7 @@ config DRM_VC4
depends on COMMON_CLK
depends on PM
select DRM_DISPLAY_HDMI_HELPER
+ select DRM_DISPLAY_HDMI_STATE_HELPER
select DRM_DISPLAY_HELPER
select DRM_KMS_HELPER
select DRM_GEM_DMA_HELPER
diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock.c b/drivers/gpu/drm/vc4/tests/vc4_mock.c
index becb3dbaa548..0731a7d85d7a 100644
--- a/drivers/gpu/drm/vc4/tests/vc4_mock.c
+++ b/drivers/gpu/drm/vc4/tests/vc4_mock.c
@@ -109,16 +109,14 @@ static const struct vc4_mock_desc vc5_mock =
static int __build_one_pipe(struct kunit *test, struct drm_device *drm,
const struct vc4_mock_pipe_desc *pipe)
{
- struct vc4_dummy_plane *dummy_plane;
struct drm_plane *plane;
struct vc4_dummy_crtc *dummy_crtc;
struct drm_crtc *crtc;
unsigned int i;
- dummy_plane = vc4_dummy_plane(test, drm, DRM_PLANE_TYPE_PRIMARY);
- KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_plane);
+ plane = vc4_dummy_plane(test, drm, DRM_PLANE_TYPE_PRIMARY);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane);
- plane = &dummy_plane->plane.base;
dummy_crtc = vc4_mock_pv(test, drm, plane, pipe->data);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_crtc);
diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock.h b/drivers/gpu/drm/vc4/tests/vc4_mock.h
index 2d0b339bd9f3..002b6218960c 100644
--- a/drivers/gpu/drm/vc4/tests/vc4_mock.h
+++ b/drivers/gpu/drm/vc4/tests/vc4_mock.h
@@ -21,13 +21,8 @@ struct drm_crtc *vc4_find_crtc_for_encoder(struct kunit *test,
return NULL;
}
-struct vc4_dummy_plane {
- struct vc4_plane plane;
-};
-
-struct vc4_dummy_plane *vc4_dummy_plane(struct kunit *test,
- struct drm_device *drm,
- enum drm_plane_type type);
+struct drm_plane *vc4_dummy_plane(struct kunit *test, struct drm_device *drm,
+ enum drm_plane_type type);
struct vc4_dummy_crtc {
struct vc4_crtc crtc;
diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c b/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
index 62b18f5f41db..14357db82238 100644
--- a/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
+++ b/drivers/gpu/drm/vc4/tests/vc4_mock_plane.c
@@ -1,47 +1,25 @@
// SPDX-License-Identifier: GPL-2.0
-#include <drm/drm_atomic_state_helper.h>
-#include <drm/drm_fourcc.h>
-#include <drm/drm_modeset_helper_vtables.h>
+#include <drm/drm_kunit_helpers.h>
#include <drm/drm_plane.h>
#include <kunit/test.h>
#include "vc4_mock.h"
-static const struct drm_plane_helper_funcs vc4_dummy_plane_helper_funcs = {
-};
-
-static const struct drm_plane_funcs vc4_dummy_plane_funcs = {
- .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
- .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
- .reset = drm_atomic_helper_plane_reset,
-};
-
-static const uint32_t vc4_dummy_plane_formats[] = {
- DRM_FORMAT_XRGB8888,
-};
-
-struct vc4_dummy_plane *vc4_dummy_plane(struct kunit *test,
- struct drm_device *drm,
- enum drm_plane_type type)
+struct drm_plane *vc4_dummy_plane(struct kunit *test, struct drm_device *drm,
+ enum drm_plane_type type)
{
- struct vc4_dummy_plane *dummy_plane;
struct drm_plane *plane;
- dummy_plane = drmm_universal_plane_alloc(drm,
- struct vc4_dummy_plane, plane.base,
- 0,
- &vc4_dummy_plane_funcs,
- vc4_dummy_plane_formats,
- ARRAY_SIZE(vc4_dummy_plane_formats),
- NULL,
- DRM_PLANE_TYPE_PRIMARY,
- NULL);
- KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_plane);
+ KUNIT_ASSERT_EQ(test, type, DRM_PLANE_TYPE_PRIMARY);
- plane = &dummy_plane->plane.base;
- drm_plane_helper_add(plane, &vc4_dummy_plane_helper_funcs);
+ plane = drm_kunit_helper_create_primary_plane(test, drm,
+ NULL,
+ NULL,
+ NULL, 0,
+ NULL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane);
- return dummy_plane;
+ return plane;
}
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index d30f8e8e8967..d57c4a5948c8 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -32,6 +32,7 @@
*/
#include <drm/display/drm_hdmi_helper.h>
+#include <drm/display/drm_hdmi_state_helper.h>
#include <drm/display/drm_scdc_helper.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
@@ -110,25 +111,6 @@
#define HDMI_14_MAX_TMDS_CLK (340 * 1000 * 1000)
-static const char * const output_format_str[] = {
- [VC4_HDMI_OUTPUT_RGB] = "RGB",
- [VC4_HDMI_OUTPUT_YUV420] = "YUV 4:2:0",
- [VC4_HDMI_OUTPUT_YUV422] = "YUV 4:2:2",
- [VC4_HDMI_OUTPUT_YUV444] = "YUV 4:4:4",
-};
-
-static const char *vc4_hdmi_output_fmt_str(enum vc4_hdmi_output_format fmt)
-{
- if (fmt >= ARRAY_SIZE(output_format_str))
- return "invalid";
-
- return output_format_str[fmt];
-}
-
-static unsigned long long
-vc4_hdmi_encoder_compute_mode_clock(const struct drm_display_mode *mode,
- unsigned int bpc, enum vc4_hdmi_output_format fmt);
-
static bool vc4_hdmi_supports_scrambling(struct vc4_hdmi *vc4_hdmi)
{
struct drm_display_info *display = &vc4_hdmi->connector.display_info;
@@ -147,28 +129,13 @@ static bool vc4_hdmi_supports_scrambling(struct vc4_hdmi *vc4_hdmi)
static bool vc4_hdmi_mode_needs_scrambling(const struct drm_display_mode *mode,
unsigned int bpc,
- enum vc4_hdmi_output_format fmt)
+ enum hdmi_colorspace fmt)
{
- unsigned long long clock = vc4_hdmi_encoder_compute_mode_clock(mode, bpc, fmt);
+ unsigned long long clock = drm_hdmi_compute_mode_clock(mode, bpc, fmt);
return clock > HDMI_14_MAX_TMDS_CLK;
}
-static bool vc4_hdmi_is_full_range(struct vc4_hdmi *vc4_hdmi,
- struct vc4_hdmi_connector_state *vc4_state)
-{
- const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
- struct drm_display_info *display = &vc4_hdmi->connector.display_info;
-
- if (vc4_state->broadcast_rgb == VC4_HDMI_BROADCAST_RGB_LIMITED)
- return false;
- else if (vc4_state->broadcast_rgb == VC4_HDMI_BROADCAST_RGB_FULL)
- return true;
-
- return !display->is_hdmi ||
- drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_FULL;
-}
-
static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
{
struct drm_debugfs_entry *entry = m->private;
@@ -524,7 +491,7 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
const struct drm_display_mode *mode;
list_for_each_entry(mode, &connector->probed_modes, head) {
- if (vc4_hdmi_mode_needs_scrambling(mode, 8, VC4_HDMI_OUTPUT_RGB)) {
+ if (vc4_hdmi_mode_needs_scrambling(mode, 8, HDMI_COLORSPACE_RGB)) {
drm_warn_once(drm, "The core clock cannot reach frequencies high enough to support 4k @ 60Hz.");
drm_warn_once(drm, "Please change your config.txt file to add hdmi_enable_4kp60.");
}
@@ -539,12 +506,8 @@ static int vc4_hdmi_connector_atomic_check(struct drm_connector *connector,
{
struct drm_connector_state *old_state =
drm_atomic_get_old_connector_state(state, connector);
- struct vc4_hdmi_connector_state *old_vc4_state =
- conn_state_to_vc4_hdmi_conn_state(old_state);
struct drm_connector_state *new_state =
drm_atomic_get_new_connector_state(state, connector);
- struct vc4_hdmi_connector_state *new_vc4_state =
- conn_state_to_vc4_hdmi_conn_state(new_state);
struct drm_crtc *crtc = new_state->crtc;
if (!crtc)
@@ -576,9 +539,7 @@ static int vc4_hdmi_connector_atomic_check(struct drm_connector *connector,
return ret;
}
- if (old_state->colorspace != new_state->colorspace ||
- old_vc4_state->broadcast_rgb != new_vc4_state->broadcast_rgb ||
- !drm_connector_atomic_hdr_metadata_equal(old_state, new_state)) {
+ if (old_state->colorspace != new_state->colorspace) {
struct drm_crtc_state *crtc_state;
crtc_state = drm_atomic_get_crtc_state(state, crtc);
@@ -588,112 +549,21 @@ static int vc4_hdmi_connector_atomic_check(struct drm_connector *connector,
crtc_state->mode_changed = true;
}
- return 0;
-}
-
-static int vc4_hdmi_connector_get_property(struct drm_connector *connector,
- const struct drm_connector_state *state,
- struct drm_property *property,
- uint64_t *val)
-{
- struct drm_device *drm = connector->dev;
- struct vc4_hdmi *vc4_hdmi =
- connector_to_vc4_hdmi(connector);
- const struct vc4_hdmi_connector_state *vc4_conn_state =
- conn_state_to_vc4_hdmi_conn_state(state);
-
- if (property == vc4_hdmi->broadcast_rgb_property) {
- *val = vc4_conn_state->broadcast_rgb;
- } else {
- drm_dbg(drm, "Unknown property [PROP:%d:%s]\n",
- property->base.id, property->name);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int vc4_hdmi_connector_set_property(struct drm_connector *connector,
- struct drm_connector_state *state,
- struct drm_property *property,
- uint64_t val)
-{
- struct drm_device *drm = connector->dev;
- struct vc4_hdmi *vc4_hdmi =
- connector_to_vc4_hdmi(connector);
- struct vc4_hdmi_connector_state *vc4_conn_state =
- conn_state_to_vc4_hdmi_conn_state(state);
-
- if (property == vc4_hdmi->broadcast_rgb_property) {
- vc4_conn_state->broadcast_rgb = val;
- return 0;
- }
-
- drm_dbg(drm, "Unknown property [PROP:%d:%s]\n",
- property->base.id, property->name);
- return -EINVAL;
+ return drm_atomic_helper_connector_hdmi_check(connector, state);
}
static void vc4_hdmi_connector_reset(struct drm_connector *connector)
{
- struct vc4_hdmi_connector_state *old_state =
- conn_state_to_vc4_hdmi_conn_state(connector->state);
- struct vc4_hdmi_connector_state *new_state =
- kzalloc(sizeof(*new_state), GFP_KERNEL);
-
- if (connector->state)
- __drm_atomic_helper_connector_destroy_state(connector->state);
-
- kfree(old_state);
- __drm_atomic_helper_connector_reset(connector, &new_state->base);
-
- if (!new_state)
- return;
-
- new_state->base.max_bpc = 8;
- new_state->base.max_requested_bpc = 8;
- new_state->output_format = VC4_HDMI_OUTPUT_RGB;
- new_state->broadcast_rgb = VC4_HDMI_BROADCAST_RGB_AUTO;
+ drm_atomic_helper_connector_reset(connector);
+ __drm_atomic_helper_connector_hdmi_reset(connector, connector->state);
drm_atomic_helper_connector_tv_margins_reset(connector);
}
-static struct drm_connector_state *
-vc4_hdmi_connector_duplicate_state(struct drm_connector *connector)
-{
- struct drm_connector_state *conn_state = connector->state;
- struct vc4_hdmi_connector_state *vc4_state = conn_state_to_vc4_hdmi_conn_state(conn_state);
- struct vc4_hdmi_connector_state *new_state;
-
- new_state = kzalloc(sizeof(*new_state), GFP_KERNEL);
- if (!new_state)
- return NULL;
-
- new_state->tmds_char_rate = vc4_state->tmds_char_rate;
- new_state->output_bpc = vc4_state->output_bpc;
- new_state->output_format = vc4_state->output_format;
- new_state->broadcast_rgb = vc4_state->broadcast_rgb;
- __drm_atomic_helper_connector_duplicate_state(connector, &new_state->base);
-
- return &new_state->base;
-}
-
-static void vc4_hdmi_connector_destroy_state(struct drm_connector *connector,
- struct drm_connector_state *state)
-{
- struct vc4_hdmi_connector_state *vc4_state =
- conn_state_to_vc4_hdmi_conn_state(state);
-
- __drm_atomic_helper_connector_destroy_state(state);
- kfree(vc4_state);
-}
-
static const struct drm_connector_funcs vc4_hdmi_connector_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes,
.reset = vc4_hdmi_connector_reset,
- .atomic_duplicate_state = vc4_hdmi_connector_duplicate_state,
- .atomic_destroy_state = vc4_hdmi_connector_destroy_state,
- .atomic_get_property = vc4_hdmi_connector_get_property,
- .atomic_set_property = vc4_hdmi_connector_set_property,
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs = {
@@ -702,44 +572,29 @@ static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs =
.atomic_check = vc4_hdmi_connector_atomic_check,
};
-static const struct drm_prop_enum_list broadcast_rgb_names[] = {
- { VC4_HDMI_BROADCAST_RGB_AUTO, "Automatic" },
- { VC4_HDMI_BROADCAST_RGB_FULL, "Full" },
- { VC4_HDMI_BROADCAST_RGB_LIMITED, "Limited 16:235" },
-};
-
-static void
-vc4_hdmi_attach_broadcast_rgb_property(struct drm_device *dev,
- struct vc4_hdmi *vc4_hdmi)
-{
- struct drm_property *prop = vc4_hdmi->broadcast_rgb_property;
-
- if (!prop) {
- prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM,
- "Broadcast RGB",
- broadcast_rgb_names,
- ARRAY_SIZE(broadcast_rgb_names));
- if (!prop)
- return;
-
- vc4_hdmi->broadcast_rgb_property = prop;
- }
-
- drm_object_attach_property(&vc4_hdmi->connector.base, prop,
- VC4_HDMI_BROADCAST_RGB_AUTO);
-}
+static const struct drm_connector_hdmi_funcs vc4_hdmi_hdmi_connector_funcs;
static int vc4_hdmi_connector_init(struct drm_device *dev,
struct vc4_hdmi *vc4_hdmi)
{
struct drm_connector *connector = &vc4_hdmi->connector;
struct drm_encoder *encoder = &vc4_hdmi->encoder.base;
+ unsigned int max_bpc = 8;
int ret;
- ret = drmm_connector_init(dev, connector,
- &vc4_hdmi_connector_funcs,
- DRM_MODE_CONNECTOR_HDMIA,
- vc4_hdmi->ddc);
+ if (vc4_hdmi->variant->supports_hdr)
+ max_bpc = 12;
+
+ ret = drmm_connector_hdmi_init(dev, connector,
+ "Broadcom", "Videocore",
+ &vc4_hdmi_connector_funcs,
+ &vc4_hdmi_hdmi_connector_funcs,
+ DRM_MODE_CONNECTOR_HDMIA,
+ vc4_hdmi->ddc,
+ BIT(HDMI_COLORSPACE_RGB) |
+ BIT(HDMI_COLORSPACE_YUV422) |
+ BIT(HDMI_COLORSPACE_YUV444),
+ max_bpc);
if (ret)
return ret;
@@ -763,7 +618,6 @@ static int vc4_hdmi_connector_init(struct drm_device *dev,
drm_connector_attach_colorspace_property(connector);
drm_connector_attach_tv_margin_properties(connector);
- drm_connector_attach_max_bpc_property(connector, 8, 12);
connector->polled = (DRM_CONNECTOR_POLL_CONNECT |
DRM_CONNECTOR_POLL_DISCONNECT);
@@ -772,21 +626,19 @@ static int vc4_hdmi_connector_init(struct drm_device *dev,
connector->doublescan_allowed = 0;
connector->stereo_allowed = 1;
- if (vc4_hdmi->variant->supports_hdr)
- drm_connector_attach_hdr_output_metadata_property(connector);
-
- vc4_hdmi_attach_broadcast_rgb_property(dev, vc4_hdmi);
+ ret = drm_connector_attach_broadcast_rgb_property(connector);
+ if (ret)
+ return ret;
drm_connector_attach_encoder(connector, encoder);
return 0;
}
-static int vc4_hdmi_stop_packet(struct drm_encoder *encoder,
+static int vc4_hdmi_stop_packet(struct vc4_hdmi *vc4_hdmi,
enum hdmi_infoframe_type type,
bool poll)
{
- struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
struct drm_device *drm = vc4_hdmi->connector.dev;
u32 packet_id = type - 0x80;
unsigned long flags;
@@ -810,12 +662,13 @@ static int vc4_hdmi_stop_packet(struct drm_encoder *encoder,
return ret;
}
-static void vc4_hdmi_write_infoframe(struct drm_encoder *encoder,
- union hdmi_infoframe *frame)
+static int vc4_hdmi_write_infoframe(struct drm_connector *connector,
+ enum hdmi_infoframe_type type,
+ const u8 *infoframe, size_t len)
{
- struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
- struct drm_device *drm = vc4_hdmi->connector.dev;
- u32 packet_id = frame->any.type - 0x80;
+ struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
+ struct drm_device *drm = connector->dev;
+ u32 packet_id = type - 0x80;
const struct vc4_hdmi_register *ram_packet_start =
&vc4_hdmi->variant->registers[HDMI_RAM_PACKET_START];
u32 packet_reg = ram_packet_start->offset + VC4_HDMI_PACKET_STRIDE * packet_id;
@@ -825,22 +678,25 @@ static void vc4_hdmi_write_infoframe(struct drm_encoder *encoder,
ram_packet_start->reg);
uint8_t buffer[VC4_HDMI_PACKET_STRIDE] = {};
unsigned long flags;
- ssize_t len, i;
+ ssize_t i;
int ret;
int idx;
if (!drm_dev_enter(drm, &idx))
- return;
+ return 0;
+
+ if (len > sizeof(buffer)) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ memcpy(buffer, infoframe, len);
WARN_ONCE(!(HDMI_READ(HDMI_RAM_PACKET_CONFIG) &
VC4_HDMI_RAM_PACKET_ENABLE),
"Packet RAM has to be on to store the packet.");
- len = hdmi_infoframe_pack(frame, buffer, sizeof(buffer));
- if (len < 0)
- goto out;
-
- ret = vc4_hdmi_stop_packet(encoder, frame->any.type, true);
+ ret = vc4_hdmi_stop_packet(vc4_hdmi, type, true);
if (ret) {
DRM_ERROR("Failed to wait for infoframe to go idle: %d\n", ret);
goto out;
@@ -882,130 +738,7 @@ static void vc4_hdmi_write_infoframe(struct drm_encoder *encoder,
out:
drm_dev_exit(idx);
-}
-
-static void vc4_hdmi_avi_infoframe_colorspace(struct hdmi_avi_infoframe *frame,
- enum vc4_hdmi_output_format fmt)
-{
- switch (fmt) {
- case VC4_HDMI_OUTPUT_RGB:
- frame->colorspace = HDMI_COLORSPACE_RGB;
- break;
-
- case VC4_HDMI_OUTPUT_YUV420:
- frame->colorspace = HDMI_COLORSPACE_YUV420;
- break;
-
- case VC4_HDMI_OUTPUT_YUV422:
- frame->colorspace = HDMI_COLORSPACE_YUV422;
- break;
-
- case VC4_HDMI_OUTPUT_YUV444:
- frame->colorspace = HDMI_COLORSPACE_YUV444;
- break;
-
- default:
- break;
- }
-}
-
-static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder)
-{
- struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
- struct drm_connector *connector = &vc4_hdmi->connector;
- struct drm_connector_state *cstate = connector->state;
- struct vc4_hdmi_connector_state *vc4_state =
- conn_state_to_vc4_hdmi_conn_state(cstate);
- const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
- union hdmi_infoframe frame;
- int ret;
-
- lockdep_assert_held(&vc4_hdmi->mutex);
-
- ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
- connector, mode);
- if (ret < 0) {
- DRM_ERROR("couldn't fill AVI infoframe\n");
- return;
- }
-
- drm_hdmi_avi_infoframe_quant_range(&frame.avi,
- connector, mode,
- vc4_hdmi_is_full_range(vc4_hdmi, vc4_state) ?
- HDMI_QUANTIZATION_RANGE_FULL :
- HDMI_QUANTIZATION_RANGE_LIMITED);
- drm_hdmi_avi_infoframe_colorimetry(&frame.avi, cstate);
- vc4_hdmi_avi_infoframe_colorspace(&frame.avi, vc4_state->output_format);
- drm_hdmi_avi_infoframe_bars(&frame.avi, cstate);
-
- vc4_hdmi_write_infoframe(encoder, &frame);
-}
-
-static void vc4_hdmi_set_spd_infoframe(struct drm_encoder *encoder)
-{
- union hdmi_infoframe frame;
- int ret;
-
- ret = hdmi_spd_infoframe_init(&frame.spd, "Broadcom", "Videocore");
- if (ret < 0) {
- DRM_ERROR("couldn't fill SPD infoframe\n");
- return;
- }
-
- frame.spd.sdi = HDMI_SPD_SDI_PC;
-
- vc4_hdmi_write_infoframe(encoder, &frame);
-}
-
-static void vc4_hdmi_set_audio_infoframe(struct drm_encoder *encoder)
-{
- struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
- struct hdmi_audio_infoframe *audio = &vc4_hdmi->audio.infoframe;
- union hdmi_infoframe frame;
-
- memcpy(&frame.audio, audio, sizeof(*audio));
-
- if (vc4_hdmi->packet_ram_enabled)
- vc4_hdmi_write_infoframe(encoder, &frame);
-}
-
-static void vc4_hdmi_set_hdr_infoframe(struct drm_encoder *encoder)
-{
- struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
- struct drm_connector *connector = &vc4_hdmi->connector;
- struct drm_connector_state *conn_state = connector->state;
- union hdmi_infoframe frame;
-
- lockdep_assert_held(&vc4_hdmi->mutex);
-
- if (!vc4_hdmi->variant->supports_hdr)
- return;
-
- if (!conn_state->hdr_output_metadata)
- return;
-
- if (drm_hdmi_infoframe_set_hdr_metadata(&frame.drm, conn_state))
- return;
-
- vc4_hdmi_write_infoframe(encoder, &frame);
-}
-
-static void vc4_hdmi_set_infoframes(struct drm_encoder *encoder)
-{
- struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
-
- lockdep_assert_held(&vc4_hdmi->mutex);
-
- vc4_hdmi_set_avi_infoframe(encoder);
- vc4_hdmi_set_spd_infoframe(encoder);
- /*
- * If audio was streaming, then we need to reenabled the audio
- * infoframe here during encoder_enable.
- */
- if (vc4_hdmi->audio.streaming)
- vc4_hdmi_set_audio_infoframe(encoder);
-
- vc4_hdmi_set_hdr_infoframe(encoder);
+ return ret;
}
#define SCRAMBLING_POLLING_DELAY_MS 1000
@@ -1174,8 +907,6 @@ static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
struct drm_connector_state *state,
const struct drm_display_mode *mode)
{
- struct vc4_hdmi_connector_state *vc4_state =
- conn_state_to_vc4_hdmi_conn_state(state);
struct drm_device *drm = vc4_hdmi->connector.dev;
unsigned long flags;
u32 csc_ctl;
@@ -1189,7 +920,7 @@ static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
csc_ctl = VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR,
VC4_HD_CSC_CTL_ORDER);
- if (!vc4_hdmi_is_full_range(vc4_hdmi, vc4_state)) {
+ if (state->hdmi.is_limited_range) {
/* CEA VICs other than #1 requre limited range RGB
* output unless overridden by an AVI infoframe.
* Apply a colorspace conversion to squash 0-255 down
@@ -1412,9 +1143,7 @@ static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
const struct drm_display_mode *mode)
{
struct drm_device *drm = vc4_hdmi->connector.dev;
- struct vc4_hdmi_connector_state *vc4_state =
- conn_state_to_vc4_hdmi_conn_state(state);
- unsigned int lim_range = vc4_hdmi_is_full_range(vc4_hdmi, vc4_state) ? 0 : 1;
+ unsigned int lim_range = state->hdmi.is_limited_range ? 1 : 0;
unsigned long flags;
const u16 (*csc)[4];
u32 if_cfg = 0;
@@ -1429,14 +1158,14 @@ static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
- switch (vc4_state->output_format) {
- case VC4_HDMI_OUTPUT_YUV444:
+ switch (state->hdmi.output_format) {
+ case HDMI_COLORSPACE_YUV444:
csc = vc5_hdmi_find_yuv_csc_coeffs(vc4_hdmi, state->colorspace, !!lim_range);
vc5_hdmi_set_csc_coeffs_swap(vc4_hdmi, csc);
break;
- case VC4_HDMI_OUTPUT_YUV422:
+ case HDMI_COLORSPACE_YUV422:
csc = vc5_hdmi_find_yuv_csc_coeffs(vc4_hdmi, state->colorspace, !!lim_range);
csc_ctl |= VC4_SET_FIELD(VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422_STANDARD,
@@ -1453,7 +1182,7 @@ static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
vc5_hdmi_set_csc_coeffs(vc4_hdmi, csc);
break;
- case VC4_HDMI_OUTPUT_RGB:
+ case HDMI_COLORSPACE_RGB:
if_xbar = 0x354021;
vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_rgb[lim_range]);
@@ -1542,8 +1271,6 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
const struct drm_display_mode *mode)
{
struct drm_device *drm = vc4_hdmi->connector.dev;
- const struct vc4_hdmi_connector_state *vc4_state =
- conn_state_to_vc4_hdmi_conn_state(state);
bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
@@ -1595,7 +1322,7 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
HDMI_WRITE(HDMI_VERTB0, vertb_even);
HDMI_WRITE(HDMI_VERTB1, vertb);
- switch (vc4_state->output_bpc) {
+ switch (state->hdmi.output_bpc) {
case 12:
gcp = 6;
break;
@@ -1612,7 +1339,7 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
* YCC422 is always 36-bit and not considered deep colour so
* doesn't signal in GCP.
*/
- if (vc4_state->output_format == VC4_HDMI_OUTPUT_YUV422) {
+ if (state->hdmi.output_format == HDMI_COLORSPACE_YUV422) {
gcp = 0;
}
@@ -1696,10 +1423,8 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder,
struct drm_connector *connector = &vc4_hdmi->connector;
struct drm_connector_state *conn_state =
drm_atomic_get_new_connector_state(state, connector);
- struct vc4_hdmi_connector_state *vc4_conn_state =
- conn_state_to_vc4_hdmi_conn_state(conn_state);
const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
- unsigned long tmds_char_rate = vc4_conn_state->tmds_char_rate;
+ unsigned long long tmds_char_rate = conn_state->hdmi.tmds_char_rate;
unsigned long bvb_rate, hsm_rate;
unsigned long flags;
int ret;
@@ -1734,7 +1459,7 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder,
*/
hsm_rate = max_t(unsigned long,
HSM_MIN_CLOCK_FREQ,
- (tmds_char_rate / 100) * 101);
+ div_u64(tmds_char_rate, 100) * 101);
ret = clk_set_min_rate(vc4_hdmi->hsm_clock, hsm_rate);
if (ret) {
DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
@@ -1776,7 +1501,7 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder,
}
if (vc4_hdmi->variant->phy_init)
- vc4_hdmi->variant->phy_init(vc4_hdmi, vc4_conn_state);
+ vc4_hdmi->variant->phy_init(vc4_hdmi, conn_state);
spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
@@ -1841,7 +1566,8 @@ static void vc4_hdmi_encoder_post_crtc_enable(struct drm_encoder *encoder,
struct drm_atomic_state *state)
{
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
- struct drm_device *drm = vc4_hdmi->connector.dev;
+ struct drm_connector *connector = &vc4_hdmi->connector;
+ struct drm_device *drm = connector->dev;
const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
struct drm_display_info *display = &vc4_hdmi->connector.display_info;
bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
@@ -1907,7 +1633,7 @@ static void vc4_hdmi_encoder_post_crtc_enable(struct drm_encoder *encoder,
spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
vc4_hdmi->packet_ram_enabled = true;
- vc4_hdmi_set_infoframes(encoder);
+ drm_atomic_helper_connector_hdmi_update_infoframes(connector, state);
}
vc4_hdmi_recenter_fifo(vc4_hdmi);
@@ -1924,108 +1650,21 @@ static void vc4_hdmi_encoder_atomic_mode_set(struct drm_encoder *encoder,
struct drm_connector_state *conn_state)
{
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
- struct vc4_hdmi_connector_state *vc4_state =
- conn_state_to_vc4_hdmi_conn_state(conn_state);
mutex_lock(&vc4_hdmi->mutex);
drm_mode_copy(&vc4_hdmi->saved_adjusted_mode,
&crtc_state->adjusted_mode);
- vc4_hdmi->output_bpc = vc4_state->output_bpc;
- vc4_hdmi->output_format = vc4_state->output_format;
+ vc4_hdmi->output_bpc = conn_state->hdmi.output_bpc;
+ vc4_hdmi->output_format = conn_state->hdmi.output_format;
mutex_unlock(&vc4_hdmi->mutex);
}
-static bool
-vc4_hdmi_sink_supports_format_bpc(const struct vc4_hdmi *vc4_hdmi,
- const struct drm_display_info *info,
- const struct drm_display_mode *mode,
- unsigned int format, unsigned int bpc)
-{
- struct drm_device *dev = vc4_hdmi->connector.dev;
- u8 vic = drm_match_cea_mode(mode);
-
- if (vic == 1 && bpc != 8) {
- drm_dbg(dev, "VIC1 requires a bpc of 8, got %u\n", bpc);
- return false;
- }
-
- if (!info->is_hdmi &&
- (format != VC4_HDMI_OUTPUT_RGB || bpc != 8)) {
- drm_dbg(dev, "DVI Monitors require an RGB output at 8 bpc\n");
- return false;
- }
-
- switch (format) {
- case VC4_HDMI_OUTPUT_RGB:
- drm_dbg(dev, "RGB Format, checking the constraints.\n");
-
- if (!(info->color_formats & DRM_COLOR_FORMAT_RGB444))
- return false;
-
- if (bpc == 10 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_30)) {
- drm_dbg(dev, "10 BPC but sink doesn't support Deep Color 30.\n");
- return false;
- }
-
- if (bpc == 12 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_36)) {
- drm_dbg(dev, "12 BPC but sink doesn't support Deep Color 36.\n");
- return false;
- }
-
- drm_dbg(dev, "RGB format supported in that configuration.\n");
-
- return true;
-
- case VC4_HDMI_OUTPUT_YUV422:
- drm_dbg(dev, "YUV422 format, checking the constraints.\n");
-
- if (!(info->color_formats & DRM_COLOR_FORMAT_YCBCR422)) {
- drm_dbg(dev, "Sink doesn't support YUV422.\n");
- return false;
- }
-
- if (bpc != 12) {
- drm_dbg(dev, "YUV422 only supports 12 bpc.\n");
- return false;
- }
-
- drm_dbg(dev, "YUV422 format supported in that configuration.\n");
-
- return true;
-
- case VC4_HDMI_OUTPUT_YUV444:
- drm_dbg(dev, "YUV444 format, checking the constraints.\n");
-
- if (!(info->color_formats & DRM_COLOR_FORMAT_YCBCR444)) {
- drm_dbg(dev, "Sink doesn't support YUV444.\n");
- return false;
- }
-
- if (bpc == 10 && !(info->edid_hdmi_ycbcr444_dc_modes & DRM_EDID_HDMI_DC_30)) {
- drm_dbg(dev, "10 BPC but sink doesn't support Deep Color 30.\n");
- return false;
- }
-
- if (bpc == 12 && !(info->edid_hdmi_ycbcr444_dc_modes & DRM_EDID_HDMI_DC_36)) {
- drm_dbg(dev, "12 BPC but sink doesn't support Deep Color 36.\n");
- return false;
- }
-
- drm_dbg(dev, "YUV444 format supported in that configuration.\n");
-
- return true;
- }
-
- return false;
-}
-
static enum drm_mode_status
-vc4_hdmi_encoder_clock_valid(const struct vc4_hdmi *vc4_hdmi,
- const struct drm_display_mode *mode,
- unsigned long long clock)
+vc4_hdmi_connector_clock_valid(const struct drm_connector *connector,
+ const struct drm_display_mode *mode,
+ unsigned long long clock)
{
- const struct drm_connector *connector = &vc4_hdmi->connector;
- const struct drm_display_info *info = &connector->display_info;
+ const struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
struct vc4_dev *vc4 = to_vc4_dev(connector->dev);
if (clock > vc4_hdmi->variant->max_pixel_clock)
@@ -2040,125 +1679,13 @@ vc4_hdmi_encoder_clock_valid(const struct vc4_hdmi *vc4_hdmi,
drm_mode_vrefresh(mode) >= 50)
return MODE_CLOCK_HIGH;
- if (info->max_tmds_clock && clock > (info->max_tmds_clock * 1000))
- return MODE_CLOCK_HIGH;
-
return MODE_OK;
}
-static unsigned long long
-vc4_hdmi_encoder_compute_mode_clock(const struct drm_display_mode *mode,
- unsigned int bpc,
- enum vc4_hdmi_output_format fmt)
-{
- unsigned long long clock = mode->clock * 1000ULL;
-
- if (mode->flags & DRM_MODE_FLAG_DBLCLK)
- clock = clock * 2;
-
- if (fmt == VC4_HDMI_OUTPUT_YUV422)
- bpc = 8;
-
- clock = clock * bpc;
- do_div(clock, 8);
-
- return clock;
-}
-
-static int
-vc4_hdmi_encoder_compute_clock(const struct vc4_hdmi *vc4_hdmi,
- struct vc4_hdmi_connector_state *vc4_state,
- const struct drm_display_mode *mode,
- unsigned int bpc, unsigned int fmt)
-{
- unsigned long long clock;
-
- clock = vc4_hdmi_encoder_compute_mode_clock(mode, bpc, fmt);
- if (vc4_hdmi_encoder_clock_valid(vc4_hdmi, mode, clock) != MODE_OK)
- return -EINVAL;
-
- vc4_state->tmds_char_rate = clock;
-
- return 0;
-}
-
-static int
-vc4_hdmi_encoder_compute_format(const struct vc4_hdmi *vc4_hdmi,
- struct vc4_hdmi_connector_state *vc4_state,
- const struct drm_display_mode *mode,
- unsigned int bpc)
-{
- struct drm_device *dev = vc4_hdmi->connector.dev;
- const struct drm_connector *connector = &vc4_hdmi->connector;
- const struct drm_display_info *info = &connector->display_info;
- unsigned int format;
-
- drm_dbg(dev, "Trying with an RGB output\n");
-
- format = VC4_HDMI_OUTPUT_RGB;
- if (vc4_hdmi_sink_supports_format_bpc(vc4_hdmi, info, mode, format, bpc)) {
- int ret;
-
- ret = vc4_hdmi_encoder_compute_clock(vc4_hdmi, vc4_state,
- mode, bpc, format);
- if (!ret) {
- vc4_state->output_format = format;
- return 0;
- }
- }
-
- drm_dbg(dev, "Failed, Trying with an YUV422 output\n");
-
- format = VC4_HDMI_OUTPUT_YUV422;
- if (vc4_hdmi_sink_supports_format_bpc(vc4_hdmi, info, mode, format, bpc)) {
- int ret;
-
- ret = vc4_hdmi_encoder_compute_clock(vc4_hdmi, vc4_state,
- mode, bpc, format);
- if (!ret) {
- vc4_state->output_format = format;
- return 0;
- }
- }
-
- drm_dbg(dev, "Failed. No Format Supported for that bpc count.\n");
-
- return -EINVAL;
-}
-
-static int
-vc4_hdmi_encoder_compute_config(const struct vc4_hdmi *vc4_hdmi,
- struct vc4_hdmi_connector_state *vc4_state,
- const struct drm_display_mode *mode)
-{
- struct drm_device *dev = vc4_hdmi->connector.dev;
- struct drm_connector_state *conn_state = &vc4_state->base;
- unsigned int max_bpc = clamp_t(unsigned int, conn_state->max_bpc, 8, 12);
- unsigned int bpc;
- int ret;
-
- for (bpc = max_bpc; bpc >= 8; bpc -= 2) {
- drm_dbg(dev, "Trying with a %d bpc output\n", bpc);
-
- ret = vc4_hdmi_encoder_compute_format(vc4_hdmi, vc4_state,
- mode, bpc);
- if (ret)
- continue;
-
- vc4_state->output_bpc = bpc;
-
- drm_dbg(dev,
- "Mode %ux%u @ %uHz: Found configuration: bpc: %u, fmt: %s, clock: %llu\n",
- mode->hdisplay, mode->vdisplay, drm_mode_vrefresh(mode),
- vc4_state->output_bpc,
- vc4_hdmi_output_fmt_str(vc4_state->output_format),
- vc4_state->tmds_char_rate);
-
- break;
- }
-
- return ret;
-}
+static const struct drm_connector_hdmi_funcs vc4_hdmi_hdmi_connector_funcs = {
+ .tmds_char_rate_valid = vc4_hdmi_connector_clock_valid,
+ .write_infoframe = vc4_hdmi_write_infoframe,
+};
#define WIFI_2_4GHz_CH1_MIN_FREQ 2400000000ULL
#define WIFI_2_4GHz_CH1_MAX_FREQ 2422000000ULL
@@ -2168,16 +1695,9 @@ static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
struct drm_connector_state *conn_state)
{
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
- struct drm_connector *connector = &vc4_hdmi->connector;
- struct drm_connector_state *old_conn_state =
- drm_atomic_get_old_connector_state(conn_state->state, connector);
- struct vc4_hdmi_connector_state *old_vc4_state =
- conn_state_to_vc4_hdmi_conn_state(old_conn_state);
- struct vc4_hdmi_connector_state *vc4_state = conn_state_to_vc4_hdmi_conn_state(conn_state);
struct drm_display_mode *mode = &crtc_state->adjusted_mode;
unsigned long long tmds_char_rate = mode->clock * 1000;
unsigned long long tmds_bit_rate;
- int ret;
if (vc4_hdmi->variant->unsupported_odd_h_timings) {
if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
@@ -2213,15 +1733,6 @@ static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
tmds_char_rate = mode->clock * 1000;
}
- ret = vc4_hdmi_encoder_compute_config(vc4_hdmi, vc4_state, mode);
- if (ret)
- return ret;
-
- /* vc4_hdmi_encoder_compute_config may have changed output_bpc and/or output_format */
- if (vc4_state->output_bpc != old_vc4_state->output_bpc ||
- vc4_state->output_format != old_vc4_state->output_format)
- crtc_state->mode_changed = true;
-
return 0;
}
@@ -2230,6 +1741,7 @@ vc4_hdmi_encoder_mode_valid(struct drm_encoder *encoder,
const struct drm_display_mode *mode)
{
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
+ unsigned long long rate;
if (vc4_hdmi->variant->unsupported_odd_h_timings &&
!(mode->flags & DRM_MODE_FLAG_DBLCLK) &&
@@ -2237,7 +1749,8 @@ vc4_hdmi_encoder_mode_valid(struct drm_encoder *encoder,
(mode->hsync_end % 2) || (mode->htotal % 2)))
return MODE_H_ILLEGAL;
- return vc4_hdmi_encoder_clock_valid(vc4_hdmi, mode, mode->clock * 1000);
+ rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
+ return vc4_hdmi_connector_clock_valid(&vc4_hdmi->connector, mode, rate);
}
static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = {
@@ -2429,7 +1942,6 @@ out:
static void vc4_hdmi_audio_reset(struct vc4_hdmi *vc4_hdmi)
{
- struct drm_encoder *encoder = &vc4_hdmi->encoder.base;
struct device *dev = &vc4_hdmi->pdev->dev;
unsigned long flags;
int ret;
@@ -2437,7 +1949,7 @@ static void vc4_hdmi_audio_reset(struct vc4_hdmi *vc4_hdmi)
lockdep_assert_held(&vc4_hdmi->mutex);
vc4_hdmi->audio.streaming = false;
- ret = vc4_hdmi_stop_packet(encoder, HDMI_INFOFRAME_TYPE_AUDIO, false);
+ ret = vc4_hdmi_stop_packet(vc4_hdmi, HDMI_INFOFRAME_TYPE_AUDIO, false);
if (ret)
dev_err(dev, "Failed to stop audio infoframe: %d\n", ret);
@@ -2528,7 +2040,7 @@ static int vc4_hdmi_audio_prepare(struct device *dev, void *data,
{
struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
struct drm_device *drm = vc4_hdmi->connector.dev;
- struct drm_encoder *encoder = &vc4_hdmi->encoder.base;
+ struct drm_connector *connector = &vc4_hdmi->connector;
unsigned int sample_rate = params->sample_rate;
unsigned int channels = params->channels;
unsigned long flags;
@@ -2605,8 +2117,10 @@ static int vc4_hdmi_audio_prepare(struct device *dev, void *data,
spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
- memcpy(&vc4_hdmi->audio.infoframe, &params->cea, sizeof(params->cea));
- vc4_hdmi_set_audio_infoframe(encoder);
+ ret = drm_atomic_helper_connector_hdmi_update_audio_infoframe(connector,
+ &params->cea);
+ if (ret)
+ goto out_dev_exit;
out_dev_exit:
drm_dev_exit(idx);
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
index 934d5d61485a..b37f1d2c3fe5 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
@@ -10,7 +10,6 @@
struct vc4_hdmi;
struct vc4_hdmi_register;
-struct vc4_hdmi_connector_state;
enum vc4_hdmi_phy_channel {
PHY_LANE_0 = 0,
@@ -76,7 +75,7 @@ struct vc4_hdmi_variant {
/* Callback to initialize the PHY according to the connector state */
void (*phy_init)(struct vc4_hdmi *vc4_hdmi,
- struct vc4_hdmi_connector_state *vc4_conn_state);
+ struct drm_connector_state *conn_state);
/* Callback to disable the PHY */
void (*phy_disable)(struct vc4_hdmi *vc4_hdmi);
@@ -110,19 +109,6 @@ struct vc4_hdmi_audio {
bool streaming;
};
-enum vc4_hdmi_output_format {
- VC4_HDMI_OUTPUT_RGB,
- VC4_HDMI_OUTPUT_YUV422,
- VC4_HDMI_OUTPUT_YUV444,
- VC4_HDMI_OUTPUT_YUV420,
-};
-
-enum vc4_hdmi_broadcast_rgb {
- VC4_HDMI_BROADCAST_RGB_AUTO,
- VC4_HDMI_BROADCAST_RGB_FULL,
- VC4_HDMI_BROADCAST_RGB_LIMITED,
-};
-
/* General HDMI hardware state. */
struct vc4_hdmi {
struct vc4_hdmi_audio audio;
@@ -135,8 +121,6 @@ struct vc4_hdmi {
struct delayed_work scrambling_work;
- struct drm_property *broadcast_rgb_property;
-
struct i2c_adapter *ddc;
void __iomem *hdmicore_regs;
void __iomem *hd_regs;
@@ -218,16 +202,17 @@ struct vc4_hdmi {
bool scdc_enabled;
/**
- * @output_bpc: Copy of @vc4_connector_state.output_bpc for use
- * outside of KMS hooks. Protected by @mutex.
+ * @output_bpc: Copy of @drm_connector_state.hdmi.output_bpc for
+ * use outside of KMS hooks. Protected by @mutex.
*/
unsigned int output_bpc;
/**
- * @output_format: Copy of @vc4_connector_state.output_format
- * for use outside of KMS hooks. Protected by @mutex.
+ * @output_format: Copy of
+ * @drm_connector_state.hdmi.output_format for use outside of
+ * KMS hooks. Protected by @mutex.
*/
- enum vc4_hdmi_output_format output_format;
+ enum hdmi_colorspace output_format;
};
#define connector_to_vc4_hdmi(_connector) \
@@ -240,25 +225,14 @@ encoder_to_vc4_hdmi(struct drm_encoder *encoder)
return container_of_const(_encoder, struct vc4_hdmi, encoder);
}
-struct vc4_hdmi_connector_state {
- struct drm_connector_state base;
- unsigned long long tmds_char_rate;
- unsigned int output_bpc;
- enum vc4_hdmi_output_format output_format;
- enum vc4_hdmi_broadcast_rgb broadcast_rgb;
-};
-
-#define conn_state_to_vc4_hdmi_conn_state(_state) \
- container_of_const(_state, struct vc4_hdmi_connector_state, base)
-
void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
- struct vc4_hdmi_connector_state *vc4_conn_state);
+ struct drm_connector_state *conn_state);
void vc4_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);
void vc4_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi);
void vc4_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi);
void vc5_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
- struct vc4_hdmi_connector_state *vc4_conn_state);
+ struct drm_connector_state *conn_state);
void vc5_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi);
void vc5_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi);
void vc5_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi);
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi_phy.c b/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
index ec24999bf96d..1f5507fc7a03 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
@@ -128,7 +128,7 @@
#define OSCILLATOR_FREQUENCY 54000000
void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
- struct vc4_hdmi_connector_state *conn_state)
+ struct drm_connector_state *conn_state)
{
unsigned long flags;
@@ -361,11 +361,11 @@ static void vc5_hdmi_reset_phy(struct vc4_hdmi *vc4_hdmi)
}
void vc5_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
- struct vc4_hdmi_connector_state *conn_state)
+ struct drm_connector_state *conn_state)
{
const struct phy_lane_settings *chan0_settings, *chan1_settings, *chan2_settings, *clock_settings;
const struct vc4_hdmi_variant *variant = vc4_hdmi->variant;
- unsigned long long pixel_freq = conn_state->tmds_char_rate;
+ unsigned long long pixel_freq = conn_state->hdmi.tmds_char_rate;
unsigned long long vco_freq;
unsigned char word_sel;
unsigned long flags;
diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c
index ad924a8502e9..64baf2f22d9f 100644
--- a/drivers/gpu/drm/virtio/virtgpu_display.c
+++ b/drivers/gpu/drm/virtio/virtgpu_display.c
@@ -164,11 +164,9 @@ static int virtio_gpu_conn_get_modes(struct drm_connector *connector)
struct drm_display_mode *mode = NULL;
int count, width, height;
- if (output->edid) {
- count = drm_add_edid_modes(connector, output->edid);
- if (count)
- return count;
- }
+ count = drm_edid_connector_add_modes(connector);
+ if (count)
+ return count;
width = le32_to_cpu(output->info.r.width);
height = le32_to_cpu(output->info.r.height);
@@ -369,5 +367,5 @@ void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev)
return;
for (i = 0 ; i < vgdev->num_scanouts; ++i)
- kfree(vgdev->outputs[i].edid);
+ drm_edid_free(vgdev->outputs[i].drm_edid);
}
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c
index 188e126383c2..e5a2665e50ea 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.c
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
@@ -35,7 +35,7 @@
#include <drm/drm_aperture.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_shmem.h>
#include <drm/drm_file.h>
#include "virtgpu_drv.h"
@@ -103,7 +103,7 @@ static int virtio_gpu_probe(struct virtio_device *vdev)
if (ret)
goto err_deinit;
- drm_fbdev_generic_setup(vdev->priv, 32);
+ drm_fbdev_shmem_setup(vdev->priv, 32);
return 0;
err_deinit:
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
index bb7d86a0c6a1..64c236169db8 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -179,7 +179,7 @@ struct virtio_gpu_output {
struct drm_encoder enc;
struct virtio_gpu_display_one info;
struct virtio_gpu_update_cursor cursor;
- struct edid *edid;
+ const struct drm_edid *drm_edid;
int cur_x;
int cur_y;
bool needs_modeset;
diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
index b1a00c0c25a7..0d3d0d09f39b 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
@@ -741,21 +741,21 @@ static void virtio_gpu_cmd_get_edid_cb(struct virtio_gpu_device *vgdev,
(struct virtio_gpu_resp_edid *)vbuf->resp_buf;
uint32_t scanout = le32_to_cpu(cmd->scanout);
struct virtio_gpu_output *output;
- struct edid *new_edid, *old_edid;
+ const struct drm_edid *new_edid, *old_edid;
if (scanout >= vgdev->num_scanouts)
return;
output = vgdev->outputs + scanout;
- new_edid = drm_do_get_edid(&output->conn, virtio_get_edid_block, resp);
- drm_connector_update_edid_property(&output->conn, new_edid);
+ new_edid = drm_edid_read_custom(&output->conn, virtio_get_edid_block, resp);
+ drm_edid_connector_update(&output->conn, new_edid);
spin_lock(&vgdev->display_info_lock);
- old_edid = output->edid;
- output->edid = new_edid;
+ old_edid = output->drm_edid;
+ output->drm_edid = new_edid;
spin_unlock(&vgdev->display_info_lock);
- kfree(old_edid);
+ drm_edid_free(old_edid);
wake_up(&vgdev->resp_wq);
}
diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index dd0af086e7fa..8dc9dc13896e 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -17,7 +17,7 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_shmem.h>
#include <drm/drm_file.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_ioctl.h>
@@ -223,7 +223,7 @@ static int vkms_create(struct vkms_config *config)
if (ret)
goto out_devres;
- drm_fbdev_generic_setup(&vkms_device->drm, 0);
+ drm_fbdev_shmem_setup(&vkms_device->drm, 0);
return 0;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 823d8d2da17c..50ad3105c16e 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -37,7 +37,7 @@
#include <drm/drm_aperture.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fbdev_generic.h>
+#include <drm/drm_fbdev_ttm.h>
#include <drm/drm_gem_ttm_helper.h>
#include <drm/drm_ioctl.h>
#include <drm/drm_module.h>
@@ -1679,7 +1679,7 @@ static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
vmw_fifo_resource_inc(vmw);
vmw_svga_enable(vmw);
- drm_fbdev_generic_setup(&vmw->drm, 0);
+ drm_fbdev_ttm_setup(&vmw->drm, 0);
vmw_debugfs_gem_init(vmw);
vmw_debugfs_resource_managers_init(vmw);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_vkms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_vkms.c
index 7e93a45948f7..3bfcf671fcd5 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_vkms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_vkms.c
@@ -31,7 +31,6 @@
#include "vmwgfx_bo.h"
#include "vmwgfx_drv.h"
#include "vmwgfx_kms.h"
-#include "vmwgfx_vkms.h"
#include "vmw_surface_cache.h"
diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile
index 7039008be234..20dc9759bb3c 100644
--- a/drivers/gpu/drm/xe/Makefile
+++ b/drivers/gpu/drm/xe/Makefile
@@ -192,7 +192,8 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \
display/xe_dsb_buffer.o \
display/xe_fb_pin.o \
display/xe_hdcp_gsc.o \
- display/xe_plane_initial.o
+ display/xe_plane_initial.o \
+ display/xe_tdf.o
# SOC code shared with i915
xe-$(CONFIG_DRM_XE_DISPLAY) += \
@@ -202,6 +203,7 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \
# Display code shared with i915
xe-$(CONFIG_DRM_XE_DISPLAY) += \
i915-display/icl_dsi.o \
+ i915-display/intel_alpm.o \
i915-display/intel_atomic.o \
i915-display/intel_atomic_plane.o \
i915-display/intel_audio.o \
@@ -244,6 +246,7 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \
i915-display/intel_dsi.o \
i915-display/intel_dsi_dcs_backlight.o \
i915-display/intel_dsi_vbt.o \
+ i915-display/intel_encoder.o \
i915-display/intel_fb.o \
i915-display/intel_fbc.o \
i915-display/intel_fdi.o \
diff --git a/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object_types.h b/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object_types.h
new file mode 100644
index 000000000000..7d6bb1abab73
--- /dev/null
+++ b/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_object_types.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: MIT */
+/* Copyright © 2024 Intel Corporation */
+
+#ifndef __I915_GEM_OBJECT_TYPES_H__
+#define __I915_GEM_OBJECT_TYPES_H__
+
+#include "xe_bo.h"
+
+#define to_intel_bo(x) gem_to_xe_bo((x))
+
+#endif
diff --git a/drivers/gpu/drm/xe/compat-i915-headers/i915_gem_stolen.h b/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_stolen.h
index cb6c7598824b..cb6c7598824b 100644
--- a/drivers/gpu/drm/xe/compat-i915-headers/i915_gem_stolen.h
+++ b/drivers/gpu/drm/xe/compat-i915-headers/gem/i915_gem_stolen.h
diff --git a/drivers/gpu/drm/xe/compat-i915-headers/intel_gt_types.h b/drivers/gpu/drm/xe/compat-i915-headers/gt/intel_gt_types.h
index c15806d6c4f7..c15806d6c4f7 100644
--- a/drivers/gpu/drm/xe/compat-i915-headers/intel_gt_types.h
+++ b/drivers/gpu/drm/xe/compat-i915-headers/gt/intel_gt_types.h
diff --git a/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h b/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h
index cd4632276141..2feedddf1e40 100644
--- a/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h
+++ b/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h
@@ -12,22 +12,9 @@
#include <drm/drm_drv.h>
-#include "gem/i915_gem_object.h"
-
-#include "soc/intel_pch.h"
-#include "xe_device.h"
-#include "xe_bo.h"
-#include "xe_pm.h"
-#include "xe_step.h"
-#include "i915_gem_stolen.h"
-#include "i915_gpu_error.h"
-#include "i915_reg_defs.h"
#include "i915_utils.h"
-#include "intel_gt_types.h"
-#include "intel_step.h"
-#include "intel_uncore.h"
#include "intel_runtime_pm.h"
-#include <linux/pm_runtime.h>
+#include "xe_device_types.h"
static inline struct drm_i915_private *to_i915(const struct drm_device *dev)
{
@@ -119,67 +106,15 @@ static inline struct drm_i915_private *kdev_to_i915(struct device *kdev)
#define IS_RAPTORLAKE_U(xe) ((xe)->info.subplatform == XE_SUBPLATFORM_ALDERLAKE_P_RPLU)
#define IS_ICL_WITH_PORT_F(xe) (xe && 0)
#define HAS_FLAT_CCS(xe) (xe_device_has_flat_ccs(xe))
-#define to_intel_bo(x) gem_to_xe_bo((x))
#define HAS_128_BYTE_Y_TILING(xe) (xe || 1)
-#include "intel_wakeref.h"
-
-static inline intel_wakeref_t intel_runtime_pm_get(struct xe_runtime_pm *pm)
-{
- struct xe_device *xe = container_of(pm, struct xe_device, runtime_pm);
-
- return xe_pm_runtime_resume_and_get(xe);
-}
-
-static inline intel_wakeref_t intel_runtime_pm_get_if_in_use(struct xe_runtime_pm *pm)
-{
- struct xe_device *xe = container_of(pm, struct xe_device, runtime_pm);
-
- return xe_pm_runtime_get_if_in_use(xe);
-}
-
-static inline intel_wakeref_t intel_runtime_pm_get_noresume(struct xe_runtime_pm *pm)
-{
- struct xe_device *xe = container_of(pm, struct xe_device, runtime_pm);
-
- xe_pm_runtime_get_noresume(xe);
- return true;
-}
-
-static inline void intel_runtime_pm_put_unchecked(struct xe_runtime_pm *pm)
-{
- struct xe_device *xe = container_of(pm, struct xe_device, runtime_pm);
-
- xe_pm_runtime_put(xe);
-}
-
-static inline void intel_runtime_pm_put(struct xe_runtime_pm *pm, intel_wakeref_t wakeref)
-{
- if (wakeref)
- intel_runtime_pm_put_unchecked(pm);
-}
-
-#define intel_runtime_pm_get_raw intel_runtime_pm_get
-#define intel_runtime_pm_put_raw intel_runtime_pm_put
-#define assert_rpm_wakelock_held(x) do { } while (0)
-#define assert_rpm_raw_wakeref_held(x) do { } while (0)
-
-#define intel_uncore_forcewake_get(x, y) do { } while (0)
-#define intel_uncore_forcewake_put(x, y) do { } while (0)
-
-#define intel_uncore_arm_unclaimed_mmio_detection(x) do { } while (0)
-
#define I915_PRIORITY_DISPLAY 0
struct i915_sched_attr {
int priority;
};
#define i915_gem_fence_wait_priority(fence, attr) do { (void) attr; } while (0)
-#define with_intel_runtime_pm(rpm, wf) \
- for ((wf) = intel_runtime_pm_get(rpm); (wf); \
- intel_runtime_pm_put((rpm), (wf)), (wf) = 0)
-
#define pdev_to_i915 pdev_to_xe_device
#define RUNTIME_INFO(xe) (&(xe)->info.i915_runtime)
diff --git a/drivers/gpu/drm/xe/compat-i915-headers/intel_runtime_pm.h b/drivers/gpu/drm/xe/compat-i915-headers/intel_runtime_pm.h
index 89da3cc62f39..8c7b315aa8ac 100644
--- a/drivers/gpu/drm/xe/compat-i915-headers/intel_runtime_pm.h
+++ b/drivers/gpu/drm/xe/compat-i915-headers/intel_runtime_pm.h
@@ -3,7 +3,12 @@
* Copyright © 2023 Intel Corporation
*/
+#ifndef __INTEL_RUNTIME_PM_H__
+#define __INTEL_RUNTIME_PM_H__
+
#include "intel_wakeref.h"
+#include "xe_device_types.h"
+#include "xe_pm.h"
#define intel_runtime_pm xe_runtime_pm
@@ -14,3 +19,49 @@ static inline void disable_rpm_wakeref_asserts(void *rpm)
static inline void enable_rpm_wakeref_asserts(void *rpm)
{
}
+
+static inline intel_wakeref_t intel_runtime_pm_get(struct xe_runtime_pm *pm)
+{
+ struct xe_device *xe = container_of(pm, struct xe_device, runtime_pm);
+
+ return xe_pm_runtime_resume_and_get(xe);
+}
+
+static inline intel_wakeref_t intel_runtime_pm_get_if_in_use(struct xe_runtime_pm *pm)
+{
+ struct xe_device *xe = container_of(pm, struct xe_device, runtime_pm);
+
+ return xe_pm_runtime_get_if_in_use(xe);
+}
+
+static inline intel_wakeref_t intel_runtime_pm_get_noresume(struct xe_runtime_pm *pm)
+{
+ struct xe_device *xe = container_of(pm, struct xe_device, runtime_pm);
+
+ xe_pm_runtime_get_noresume(xe);
+ return true;
+}
+
+static inline void intel_runtime_pm_put_unchecked(struct xe_runtime_pm *pm)
+{
+ struct xe_device *xe = container_of(pm, struct xe_device, runtime_pm);
+
+ xe_pm_runtime_put(xe);
+}
+
+static inline void intel_runtime_pm_put(struct xe_runtime_pm *pm, intel_wakeref_t wakeref)
+{
+ if (wakeref)
+ intel_runtime_pm_put_unchecked(pm);
+}
+
+#define intel_runtime_pm_get_raw intel_runtime_pm_get
+#define intel_runtime_pm_put_raw intel_runtime_pm_put
+#define assert_rpm_wakelock_held(x) do { } while (0)
+#define assert_rpm_raw_wakeref_held(x) do { } while (0)
+
+#define with_intel_runtime_pm(rpm, wf) \
+ for ((wf) = intel_runtime_pm_get(rpm); (wf); \
+ intel_runtime_pm_put((rpm), (wf)), (wf) = 0)
+
+#endif
diff --git a/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h b/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h
index ef79793caa72..083c4da2ea41 100644
--- a/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h
+++ b/drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h
@@ -172,4 +172,9 @@ static inline void __iomem *intel_uncore_regs(struct intel_uncore *uncore)
#define raw_reg_write(base, reg, value) \
writel(value, base + i915_mmio_reg_offset(reg))
+#define intel_uncore_forcewake_get(x, y) do { } while (0)
+#define intel_uncore_forcewake_put(x, y) do { } while (0)
+
+#define intel_uncore_arm_unclaimed_mmio_detection(x) do { } while (0)
+
#endif /* __INTEL_UNCORE_H__ */
diff --git a/drivers/gpu/drm/xe/display/ext/i915_irq.c b/drivers/gpu/drm/xe/display/ext/i915_irq.c
index bee191a4a97d..eb40f1cb44f6 100644
--- a/drivers/gpu/drm/xe/display/ext/i915_irq.c
+++ b/drivers/gpu/drm/xe/display/ext/i915_irq.c
@@ -3,7 +3,6 @@
* Copyright © 2023 Intel Corporation
*/
-#include "i915_drv.h"
#include "i915_irq.h"
#include "i915_reg.h"
#include "intel_uncore.h"
diff --git a/drivers/gpu/drm/xe/display/intel_fb_bo.c b/drivers/gpu/drm/xe/display/intel_fb_bo.c
index e18521acc516..f835492f73fb 100644
--- a/drivers/gpu/drm/xe/display/intel_fb_bo.c
+++ b/drivers/gpu/drm/xe/display/intel_fb_bo.c
@@ -4,10 +4,11 @@
*/
#include <drm/drm_modeset_helper.h>
+#include <drm/ttm/ttm_bo.h>
-#include "i915_drv.h"
#include "intel_display_types.h"
#include "intel_fb_bo.h"
+#include "xe_bo.h"
void intel_fb_bo_framebuffer_fini(struct xe_bo *bo)
{
@@ -24,7 +25,7 @@ int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb,
struct xe_bo *bo,
struct drm_mode_fb_cmd2 *mode_cmd)
{
- struct drm_i915_private *i915 = to_i915(bo->ttm.base.dev);
+ struct xe_device *xe = to_xe_device(bo->ttm.base.dev);
int ret;
xe_bo_get(bo);
@@ -40,7 +41,7 @@ int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb,
* mode when the boect is VM_BINDed, so we can only set
* coherency with display when unbound.
*/
- if (XE_IOCTL_DBG(i915, !list_empty(&bo->ttm.base.gpuva.list))) {
+ if (XE_IOCTL_DBG(xe, !list_empty(&bo->ttm.base.gpuva.list))) {
ttm_bo_unreserve(&bo->ttm);
ret = -EINVAL;
goto err;
diff --git a/drivers/gpu/drm/xe/display/intel_fbdev_fb.c b/drivers/gpu/drm/xe/display/intel_fbdev_fb.c
index 9e4bcfdbc7e5..816ad13821a8 100644
--- a/drivers/gpu/drm/xe/display/intel_fbdev_fb.c
+++ b/drivers/gpu/drm/xe/display/intel_fbdev_fb.c
@@ -3,22 +3,20 @@
* Copyright © 2023 Intel Corporation
*/
-#include "intel_fbdev_fb.h"
-
#include <drm/drm_fb_helper.h>
+#include "intel_display_types.h"
+#include "intel_fbdev_fb.h"
+#include "xe_bo.h"
#include "xe_gt.h"
#include "xe_ttm_stolen_mgr.h"
-#include "i915_drv.h"
-#include "intel_display_types.h"
-
-struct drm_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper,
- struct drm_fb_helper_surface_size *sizes)
+struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper,
+ struct drm_fb_helper_surface_size *sizes)
{
struct drm_framebuffer *fb;
struct drm_device *dev = helper->dev;
- struct drm_i915_private *dev_priv = to_i915(dev);
+ struct xe_device *xe = to_xe_device(dev);
struct drm_mode_fb_cmd2 mode_cmd = {};
struct drm_i915_gem_object *obj;
int size;
@@ -39,26 +37,26 @@ struct drm_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper,
size = PAGE_ALIGN(size);
obj = ERR_PTR(-ENODEV);
- if (!IS_DGFX(dev_priv)) {
- obj = xe_bo_create_pin_map(dev_priv, xe_device_get_root_tile(dev_priv),
+ if (!IS_DGFX(xe)) {
+ obj = xe_bo_create_pin_map(xe, xe_device_get_root_tile(xe),
NULL, size,
ttm_bo_type_kernel, XE_BO_FLAG_SCANOUT |
XE_BO_FLAG_STOLEN |
XE_BO_FLAG_PINNED);
if (!IS_ERR(obj))
- drm_info(&dev_priv->drm, "Allocated fbdev into stolen\n");
+ drm_info(&xe->drm, "Allocated fbdev into stolen\n");
else
- drm_info(&dev_priv->drm, "Allocated fbdev into stolen failed: %li\n", PTR_ERR(obj));
+ drm_info(&xe->drm, "Allocated fbdev into stolen failed: %li\n", PTR_ERR(obj));
}
if (IS_ERR(obj)) {
- obj = xe_bo_create_pin_map(dev_priv, xe_device_get_root_tile(dev_priv), NULL, size,
- ttm_bo_type_kernel, XE_BO_FLAG_SCANOUT |
- XE_BO_FLAG_VRAM_IF_DGFX(xe_device_get_root_tile(dev_priv)) |
- XE_BO_FLAG_PINNED);
+ obj = xe_bo_create_pin_map(xe, xe_device_get_root_tile(xe), NULL, size,
+ ttm_bo_type_kernel, XE_BO_FLAG_SCANOUT |
+ XE_BO_FLAG_VRAM_IF_DGFX(xe_device_get_root_tile(xe)) |
+ XE_BO_FLAG_PINNED);
}
if (IS_ERR(obj)) {
- drm_err(&dev_priv->drm, "failed to allocate framebuffer (%pe)\n", obj);
+ drm_err(&xe->drm, "failed to allocate framebuffer (%pe)\n", obj);
fb = ERR_PTR(-ENOMEM);
goto err;
}
@@ -70,10 +68,11 @@ struct drm_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper,
}
drm_gem_object_put(intel_bo_to_drm_bo(obj));
- return fb;
+
+ return to_intel_framebuffer(fb);
err:
- return fb;
+ return ERR_CAST(fb);
}
int intel_fbdev_fb_fill_info(struct drm_i915_private *i915, struct fb_info *info,
diff --git a/drivers/gpu/drm/xe/display/intel_fbdev_fb.h b/drivers/gpu/drm/xe/display/intel_fbdev_fb.h
deleted file mode 100644
index ea186772e0bb..000000000000
--- a/drivers/gpu/drm/xe/display/intel_fbdev_fb.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2023 Intel Corporation
- */
-
-#ifndef __INTEL_FBDEV_FB_H__
-#define __INTEL_FBDEV_FB_H__
-
-struct drm_fb_helper;
-struct drm_fb_helper_surface_size;
-struct drm_i915_gem_object;
-struct drm_i915_private;
-struct fb_info;
-struct i915_vma;
-
-struct drm_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper,
- struct drm_fb_helper_surface_size *sizes);
-int intel_fbdev_fb_fill_info(struct drm_i915_private *i915, struct fb_info *info,
- struct drm_i915_gem_object *obj, struct i915_vma *vma);
-
-#endif
diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c
index ff8863979065..78cccbe28947 100644
--- a/drivers/gpu/drm/xe/display/xe_display.c
+++ b/drivers/gpu/drm/xe/display/xe_display.c
@@ -96,9 +96,6 @@ int xe_display_create(struct xe_device *xe)
xe->display.hotplug.dp_wq = alloc_ordered_workqueue("xe-dp", 0);
- drmm_mutex_init(&xe->drm, &xe->sb_lock);
- xe->enabled_irq_mask = ~0;
-
return drmm_add_action_or_reset(&xe->drm, display_destroy, NULL);
}
diff --git a/drivers/gpu/drm/xe/display/xe_dsb_buffer.c b/drivers/gpu/drm/xe/display/xe_dsb_buffer.c
index 44c9fd2143cc..9e860c61f4b3 100644
--- a/drivers/gpu/drm/xe/display/xe_dsb_buffer.c
+++ b/drivers/gpu/drm/xe/display/xe_dsb_buffer.c
@@ -3,7 +3,6 @@
* Copyright 2023, Intel Corporation.
*/
-#include "i915_drv.h"
#include "i915_vma.h"
#include "intel_display_types.h"
#include "intel_dsb_buffer.h"
@@ -34,18 +33,18 @@ void intel_dsb_buffer_memset(struct intel_dsb_buffer *dsb_buf, u32 idx, u32 val,
bool intel_dsb_buffer_create(struct intel_crtc *crtc, struct intel_dsb_buffer *dsb_buf, size_t size)
{
- struct drm_i915_private *i915 = to_i915(crtc->base.dev);
- struct drm_i915_gem_object *obj;
+ struct xe_device *xe = to_xe_device(crtc->base.dev);
+ struct xe_bo *obj;
struct i915_vma *vma;
vma = kzalloc(sizeof(*vma), GFP_KERNEL);
if (!vma)
return false;
- obj = xe_bo_create_pin_map(i915, xe_device_get_root_tile(i915),
+ obj = xe_bo_create_pin_map(xe, xe_device_get_root_tile(xe),
NULL, PAGE_ALIGN(size),
ttm_bo_type_kernel,
- XE_BO_FLAG_VRAM_IF_DGFX(xe_device_get_root_tile(i915)) |
+ XE_BO_FLAG_VRAM_IF_DGFX(xe_device_get_root_tile(xe)) |
XE_BO_FLAG_GGTT);
if (IS_ERR(obj)) {
kfree(vma);
diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c
index 3e1ae37c4c8b..a2f417209124 100644
--- a/drivers/gpu/drm/xe/display/xe_fb_pin.c
+++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c
@@ -3,17 +3,17 @@
* Copyright © 2021 Intel Corporation
*/
-#include "i915_drv.h"
+#include <drm/ttm/ttm_bo.h>
+
#include "intel_display_types.h"
#include "intel_dpt.h"
#include "intel_fb.h"
#include "intel_fb_pin.h"
+#include "xe_bo.h"
#include "xe_ggtt.h"
#include "xe_gt.h"
#include "xe_pm.h"
-#include <drm/ttm/ttm_bo.h>
-
static void
write_dpt_rotated(struct xe_bo *bo, struct iosys_map *map, u32 *dpt_ofs, u32 bo_ofs,
u32 width, u32 height, u32 src_stride, u32 dst_stride)
@@ -77,7 +77,7 @@ write_dpt_remapped(struct xe_bo *bo, struct iosys_map *map, u32 *dpt_ofs,
*dpt_ofs = ALIGN(*dpt_ofs, 4096);
}
-static int __xe_pin_fb_vma_dpt(struct intel_framebuffer *fb,
+static int __xe_pin_fb_vma_dpt(const struct intel_framebuffer *fb,
const struct i915_gtt_view *view,
struct i915_vma *vma)
{
@@ -181,7 +181,7 @@ write_ggtt_rotated(struct xe_bo *bo, struct xe_ggtt *ggtt, u32 *ggtt_ofs, u32 bo
}
}
-static int __xe_pin_fb_vma_ggtt(struct intel_framebuffer *fb,
+static int __xe_pin_fb_vma_ggtt(const struct intel_framebuffer *fb,
const struct i915_gtt_view *view,
struct i915_vma *vma)
{
@@ -249,7 +249,7 @@ out:
return ret;
}
-static struct i915_vma *__xe_pin_fb_vma(struct intel_framebuffer *fb,
+static struct i915_vma *__xe_pin_fb_vma(const struct intel_framebuffer *fb,
const struct i915_gtt_view *view)
{
struct drm_device *dev = fb->base.dev;
@@ -333,18 +333,18 @@ static void __xe_unpin_fb_vma(struct i915_vma *vma)
}
struct i915_vma *
-intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
- bool phys_cursor,
- const struct i915_gtt_view *view,
- bool uses_fence,
- unsigned long *out_flags)
+intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb,
+ bool phys_cursor,
+ const struct i915_gtt_view *view,
+ bool uses_fence,
+ unsigned long *out_flags)
{
*out_flags = 0;
return __xe_pin_fb_vma(to_intel_framebuffer(fb), view);
}
-void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags)
+void intel_fb_unpin_vma(struct i915_vma *vma, unsigned long flags)
{
__xe_unpin_fb_vma(vma);
}
diff --git a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
index eb67ecf08db2..14b8b4278317 100644
--- a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
+++ b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
@@ -4,7 +4,7 @@
*/
#include <drm/drm_print.h>
-#include <drm/i915_hdcp_interface.h>
+#include <drm/intel/i915_hdcp_interface.h>
#include <linux/delay.h>
#include "abi/gsc_command_header_abi.h"
diff --git a/drivers/gpu/drm/xe/display/xe_plane_initial.c b/drivers/gpu/drm/xe/display/xe_plane_initial.c
index 9693c56d386b..e135b20962d9 100644
--- a/drivers/gpu/drm/xe/display/xe_plane_initial.c
+++ b/drivers/gpu/drm/xe/display/xe_plane_initial.c
@@ -9,7 +9,6 @@
#include "regs/xe_gtt_defs.h"
#include "xe_ggtt.h"
-#include "i915_drv.h"
#include "intel_atomic_plane.h"
#include "intel_crtc.h"
#include "intel_display.h"
@@ -18,16 +17,17 @@
#include "intel_fb_pin.h"
#include "intel_frontbuffer.h"
#include "intel_plane_initial.h"
+#include "xe_bo.h"
static bool
intel_reuse_initial_plane_obj(struct intel_crtc *this,
const struct intel_initial_plane_config plane_configs[],
struct drm_framebuffer **fb)
{
- struct drm_i915_private *i915 = to_i915(this->base.dev);
+ struct xe_device *xe = to_xe_device(this->base.dev);
struct intel_crtc *crtc;
- for_each_intel_crtc(&i915->drm, crtc) {
+ for_each_intel_crtc(&xe->drm, crtc) {
struct intel_plane *plane =
to_intel_plane(crtc->base.primary);
const struct intel_plane_state *plane_state =
@@ -134,8 +134,7 @@ static bool
intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
struct intel_initial_plane_config *plane_config)
{
- struct drm_device *dev = crtc->base.dev;
- struct drm_i915_private *dev_priv = to_i915(dev);
+ struct xe_device *xe = to_xe_device(crtc->base.dev);
struct drm_mode_fb_cmd2 mode_cmd = { 0 };
struct drm_framebuffer *fb = &plane_config->fb->base;
struct xe_bo *bo;
@@ -147,9 +146,9 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
case I915_FORMAT_MOD_4_TILED:
break;
default:
- drm_dbg(&dev_priv->drm,
- "Unsupported modifier for initial FB: 0x%llx\n",
- fb->modifier);
+ drm_dbg_kms(&xe->drm,
+ "Unsupported modifier for initial FB: 0x%llx\n",
+ fb->modifier);
return false;
}
@@ -160,13 +159,13 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
mode_cmd.modifier[0] = fb->modifier;
mode_cmd.flags = DRM_MODE_FB_MODIFIERS;
- bo = initial_plane_bo(dev_priv, plane_config);
+ bo = initial_plane_bo(xe, plane_config);
if (!bo)
return false;
if (intel_framebuffer_init(to_intel_framebuffer(fb),
bo, &mode_cmd)) {
- drm_dbg_kms(&dev_priv->drm, "intel fb init failed\n");
+ drm_dbg_kms(&xe->drm, "intel fb init failed\n");
goto err_bo;
}
/* Reference handed over to fb */
@@ -211,8 +210,8 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc,
intel_fb_fill_view(to_intel_framebuffer(fb),
plane_state->uapi.rotation, &plane_state->view);
- vma = intel_pin_and_fence_fb_obj(fb, false, &plane_state->view.gtt,
- false, &plane_state->flags);
+ vma = intel_fb_pin_to_ggtt(fb, false, &plane_state->view.gtt,
+ false, &plane_state->flags);
if (IS_ERR(vma))
goto nofb;
diff --git a/drivers/gpu/drm/xe/display/xe_tdf.c b/drivers/gpu/drm/xe/display/xe_tdf.c
new file mode 100644
index 000000000000..2c0d4e144e09
--- /dev/null
+++ b/drivers/gpu/drm/xe/display/xe_tdf.c
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#include "xe_device.h"
+#include "intel_display_types.h"
+#include "intel_tdf.h"
+
+void intel_td_flush(struct drm_i915_private *i915)
+{
+ xe_device_td_flush(i915);
+}
diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
index 6a7bbb410613..d44564bad009 100644
--- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h
+++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
@@ -374,6 +374,9 @@
#define XE2LPM_L3SQCREG5 XE_REG_MCR(0xb658)
+#define XE2_TDF_CTRL XE_REG(0xb418)
+#define TRANSIENT_FLUSH_REQUEST REG_BIT(0)
+
#define XEHP_MERT_MOD_CTRL XE_REG_MCR(0xcf28)
#define RENDER_MOD_CTRL XE_REG_MCR(0xcf2c)
#define COMP_MOD_CTRL XE_REG_MCR(0xcf30)
diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
index e25c37ac7d14..0d57eea8f083 100644
--- a/drivers/gpu/drm/xe/xe_device.c
+++ b/drivers/gpu/drm/xe/xe_device.c
@@ -754,6 +754,55 @@ void xe_device_wmb(struct xe_device *xe)
xe_mmio_write32(gt, SOFTWARE_FLAGS_SPR33, 0);
}
+/**
+ * xe_device_td_flush() - Flush transient L3 cache entries
+ * @xe: The device
+ *
+ * Display engine has direct access to memory and is never coherent with L3/L4
+ * caches (or CPU caches), however KMD is responsible for specifically flushing
+ * transient L3 GPU cache entries prior to the flip sequence to ensure scanout
+ * can happen from such a surface without seeing corruption.
+ *
+ * Display surfaces can be tagged as transient by mapping it using one of the
+ * various L3:XD PAT index modes on Xe2.
+ *
+ * Note: On non-discrete xe2 platforms, like LNL, the entire L3 cache is flushed
+ * at the end of each submission via PIPE_CONTROL for compute/render, since SA
+ * Media is not coherent with L3 and we want to support render-vs-media
+ * usescases. For other engines like copy/blt the HW internally forces uncached
+ * behaviour, hence why we can skip the TDF on such platforms.
+ */
+void xe_device_td_flush(struct xe_device *xe)
+{
+ struct xe_gt *gt;
+ u8 id;
+
+ if (!IS_DGFX(xe) || GRAPHICS_VER(xe) < 20)
+ return;
+
+ for_each_gt(gt, xe, id) {
+ if (xe_gt_is_media_type(gt))
+ continue;
+
+ if (xe_force_wake_get(gt_to_fw(gt), XE_FW_GT))
+ return;
+
+ xe_mmio_write32(gt, XE2_TDF_CTRL, TRANSIENT_FLUSH_REQUEST);
+ /*
+ * FIXME: We can likely do better here with our choice of
+ * timeout. Currently we just assume the worst case, i.e. 150us,
+ * which is believed to be sufficient to cover the worst case
+ * scenario on current platforms if all cache entries are
+ * transient and need to be flushed..
+ */
+ if (xe_mmio_wait32(gt, XE2_TDF_CTRL, TRANSIENT_FLUSH_REQUEST, 0,
+ 150, NULL, false))
+ xe_gt_err_once(gt, "TD flush timeout\n");
+
+ xe_force_wake_put(gt_to_fw(gt), XE_FW_GT);
+ }
+}
+
u32 xe_device_ccs_bytes(struct xe_device *xe, u64 size)
{
return xe_device_has_flat_ccs(xe) ?
diff --git a/drivers/gpu/drm/xe/xe_device.h b/drivers/gpu/drm/xe/xe_device.h
index 3ed14072d8d1..bb07f5669dbb 100644
--- a/drivers/gpu/drm/xe/xe_device.h
+++ b/drivers/gpu/drm/xe/xe_device.h
@@ -161,6 +161,8 @@ void xe_device_snapshot_print(struct xe_device *xe, struct drm_printer *p);
u64 xe_device_canonicalize_addr(struct xe_device *xe, u64 address);
u64 xe_device_uncanonicalize_addr(struct xe_device *xe, u64 address);
+void xe_device_td_flush(struct xe_device *xe);
+
static inline bool xe_device_wedged(struct xe_device *xe)
{
return atomic_read(&xe->wedged.flag);
diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
index 185986e1d586..c37be471d11c 100644
--- a/drivers/gpu/drm/xe/xe_device_types.h
+++ b/drivers/gpu/drm/xe/xe_device_types.h
@@ -502,6 +502,7 @@ struct xe_device {
INTEL_DRAM_LPDDR4,
INTEL_DRAM_DDR5,
INTEL_DRAM_LPDDR5,
+ INTEL_DRAM_GDDR,
} type;
u8 num_qgv_points;
u8 num_psf_gv_points;
@@ -516,14 +517,9 @@ struct xe_device {
/* To shut up runtime pm macros.. */
struct xe_runtime_pm {} runtime_pm;
- /* For pcode */
- struct mutex sb_lock;
-
/* only to allow build, not used functionally */
u32 irq_mask;
- u32 enabled_irq_mask;
-
struct intel_uncore {
spinlock_t lock;
} uncore;
diff --git a/drivers/gpu/drm/xe/xe_ggtt.c b/drivers/gpu/drm/xe/xe_ggtt.c
index b01a670fecb8..8ff91fd1b7c8 100644
--- a/drivers/gpu/drm/xe/xe_ggtt.c
+++ b/drivers/gpu/drm/xe/xe_ggtt.c
@@ -10,7 +10,7 @@
#include <drm/drm_drv.h>
#include <drm/drm_managed.h>
-#include <drm/i915_drm.h>
+#include <drm/intel/i915_drm.h>
#include "regs/xe_gt_regs.h"
#include "regs/xe_gtt_defs.h"
diff --git a/drivers/gpu/drm/xe/xe_gsc_proxy.c b/drivers/gpu/drm/xe/xe_gsc_proxy.c
index 6d6d1068cf23..aa812a2bc3ed 100644
--- a/drivers/gpu/drm/xe/xe_gsc_proxy.c
+++ b/drivers/gpu/drm/xe/xe_gsc_proxy.c
@@ -9,8 +9,8 @@
#include <linux/delay.h>
#include <drm/drm_managed.h>
-#include <drm/i915_component.h>
-#include <drm/i915_gsc_proxy_mei_interface.h>
+#include <drm/intel/i915_component.h>
+#include <drm/intel/i915_gsc_proxy_mei_interface.h>
#include "abi/gsc_proxy_commands_abi.h"
#include "regs/xe_gsc_regs.h"
diff --git a/drivers/gpu/drm/xe/xe_gt_printk.h b/drivers/gpu/drm/xe/xe_gt_printk.h
index c2b004d3f48e..d6228baaff1e 100644
--- a/drivers/gpu/drm/xe/xe_gt_printk.h
+++ b/drivers/gpu/drm/xe/xe_gt_printk.h
@@ -13,6 +13,9 @@
#define xe_gt_printk(_gt, _level, _fmt, ...) \
drm_##_level(&gt_to_xe(_gt)->drm, "GT%u: " _fmt, (_gt)->info.id, ##__VA_ARGS__)
+#define xe_gt_err_once(_gt, _fmt, ...) \
+ xe_gt_printk((_gt), err_once, _fmt, ##__VA_ARGS__)
+
#define xe_gt_err(_gt, _fmt, ...) \
xe_gt_printk((_gt), err, _fmt, ##__VA_ARGS__)
diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c
index 08583fdd7643..21a1b7d2b2a9 100644
--- a/drivers/gpu/drm/xe/xe_pci.c
+++ b/drivers/gpu/drm/xe/xe_pci.c
@@ -13,7 +13,7 @@
#include <drm/drm_color_mgmt.h>
#include <drm/drm_drv.h>
-#include <drm/xe_pciids.h>
+#include <drm/intel/xe_pciids.h>
#include "display/xe_display.h"
#include "regs/xe_gt_regs.h"
@@ -343,6 +343,7 @@ static const struct xe_device_desc lnl_desc = {
static const struct xe_device_desc bmg_desc = {
DGFX_FEATURES,
PLATFORM(BATTLEMAGE),
+ .has_display = true,
.require_force_probe = true,
};
diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c b/drivers/gpu/drm/xlnx/zynqmp_disp.c
index c9fb432d4cbd..9368acf56eaf 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
@@ -141,24 +141,18 @@ struct zynqmp_disp_layer {
* struct zynqmp_disp - Display controller
* @dev: Device structure
* @dpsub: Display subsystem
- * @blend.base: Register I/O base address for the blender
- * @avbuf.base: Register I/O base address for the audio/video buffer manager
- * @audio.base: Registers I/O base address for the audio mixer
+ * @blend: Register I/O base address for the blender
+ * @avbuf: Register I/O base address for the audio/video buffer manager
+ * @audio: Registers I/O base address for the audio mixer
* @layers: Layers (planes)
*/
struct zynqmp_disp {
struct device *dev;
struct zynqmp_dpsub *dpsub;
- struct {
- void __iomem *base;
- } blend;
- struct {
- void __iomem *base;
- } avbuf;
- struct {
- void __iomem *base;
- } audio;
+ void __iomem *blend;
+ void __iomem *avbuf;
+ void __iomem *audio;
struct zynqmp_disp_layer layers[ZYNQMP_DPSUB_NUM_LAYERS];
};
@@ -410,12 +404,12 @@ static const struct zynqmp_disp_format avbuf_live_fmts[] = {
static u32 zynqmp_disp_avbuf_read(struct zynqmp_disp *disp, int reg)
{
- return readl(disp->avbuf.base + reg);
+ return readl(disp->avbuf + reg);
}
static void zynqmp_disp_avbuf_write(struct zynqmp_disp *disp, int reg, u32 val)
{
- writel(val, disp->avbuf.base + reg);
+ writel(val, disp->avbuf + reg);
}
static bool zynqmp_disp_layer_is_video(const struct zynqmp_disp_layer *layer)
@@ -651,7 +645,7 @@ static void zynqmp_disp_avbuf_disable(struct zynqmp_disp *disp)
static void zynqmp_disp_blend_write(struct zynqmp_disp *disp, int reg, u32 val)
{
- writel(val, disp->blend.base + reg);
+ writel(val, disp->blend + reg);
}
/*
@@ -877,7 +871,7 @@ static void zynqmp_disp_blend_layer_disable(struct zynqmp_disp *disp,
static void zynqmp_disp_audio_write(struct zynqmp_disp *disp, int reg, u32 val)
{
- writel(val, disp->audio.base + reg);
+ writel(val, disp->audio + reg);
}
/**
@@ -1412,21 +1406,21 @@ int zynqmp_disp_probe(struct zynqmp_dpsub *dpsub)
disp->dev = &pdev->dev;
disp->dpsub = dpsub;
- disp->blend.base = devm_platform_ioremap_resource_byname(pdev, "blend");
- if (IS_ERR(disp->blend.base)) {
- ret = PTR_ERR(disp->blend.base);
+ disp->blend = devm_platform_ioremap_resource_byname(pdev, "blend");
+ if (IS_ERR(disp->blend)) {
+ ret = PTR_ERR(disp->blend);
goto error;
}
- disp->avbuf.base = devm_platform_ioremap_resource_byname(pdev, "av_buf");
- if (IS_ERR(disp->avbuf.base)) {
- ret = PTR_ERR(disp->avbuf.base);
+ disp->avbuf = devm_platform_ioremap_resource_byname(pdev, "av_buf");
+ if (IS_ERR(disp->avbuf)) {
+ ret = PTR_ERR(disp->avbuf);
goto error;
}
- disp->audio.base = devm_platform_ioremap_resource_byname(pdev, "aud");
- if (IS_ERR(disp->audio.base)) {
- ret = PTR_ERR(disp->audio.base);
+ disp->audio = devm_platform_ioremap_resource_byname(pdev, "aud");
+ if (IS_ERR(disp->audio)) {
+ ret = PTR_ERR(disp->audio);
goto error;
}
diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c
index 8c2d24809014..129beac4c073 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
@@ -256,10 +256,10 @@ struct zynqmp_dp_link_config {
* @fmt: format identifier string
*/
struct zynqmp_dp_mode {
+ const char *fmt;
+ int pclock;
u8 bw_code;
u8 lane_cnt;
- int pclock;
- const char *fmt;
};
/**
@@ -296,27 +296,27 @@ struct zynqmp_dp_config {
* @train_set: set of training data
*/
struct zynqmp_dp {
+ struct drm_dp_aux aux;
+ struct drm_bridge bridge;
+ struct work_struct hpd_work;
+
+ struct drm_bridge *next_bridge;
struct device *dev;
struct zynqmp_dpsub *dpsub;
void __iomem *iomem;
struct reset_control *reset;
- int irq;
-
- struct drm_bridge bridge;
- struct drm_bridge *next_bridge;
-
- struct zynqmp_dp_config config;
- struct drm_dp_aux aux;
struct phy *phy[ZYNQMP_DP_MAX_LANES];
- u8 num_lanes;
- struct delayed_work hpd_work;
+
enum drm_connector_status status;
+ int irq;
bool enabled;
- u8 dpcd[DP_RECEIVER_CAP_SIZE];
- struct zynqmp_dp_link_config link_config;
struct zynqmp_dp_mode mode;
+ struct zynqmp_dp_link_config link_config;
+ struct zynqmp_dp_config config;
+ u8 dpcd[DP_RECEIVER_CAP_SIZE];
u8 train_set[ZYNQMP_DP_MAX_LANES];
+ u8 num_lanes;
};
static inline struct zynqmp_dp *bridge_to_dp(struct drm_bridge *bridge)
@@ -606,28 +606,21 @@ static void zynqmp_dp_adjust_train(struct zynqmp_dp *dp,
u8 link_status[DP_LINK_STATUS_SIZE])
{
u8 *train_set = dp->train_set;
- u8 voltage = 0, preemphasis = 0;
u8 i;
for (i = 0; i < dp->mode.lane_cnt; i++) {
- u8 v = drm_dp_get_adjust_request_voltage(link_status, i);
- u8 p = drm_dp_get_adjust_request_pre_emphasis(link_status, i);
+ u8 voltage = drm_dp_get_adjust_request_voltage(link_status, i);
+ u8 preemphasis =
+ drm_dp_get_adjust_request_pre_emphasis(link_status, i);
- if (v > voltage)
- voltage = v;
+ if (voltage >= DP_TRAIN_VOLTAGE_SWING_LEVEL_3)
+ voltage |= DP_TRAIN_MAX_SWING_REACHED;
- if (p > preemphasis)
- preemphasis = p;
- }
+ if (preemphasis >= DP_TRAIN_PRE_EMPH_LEVEL_2)
+ preemphasis |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
- if (voltage >= DP_TRAIN_VOLTAGE_SWING_LEVEL_3)
- voltage |= DP_TRAIN_MAX_SWING_REACHED;
-
- if (preemphasis >= DP_TRAIN_PRE_EMPH_LEVEL_2)
- preemphasis |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
-
- for (i = 0; i < dp->mode.lane_cnt; i++)
train_set[i] = voltage | preemphasis;
+ }
}
/**
@@ -1007,7 +1000,7 @@ zynqmp_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
msg->buffer, msg->size,
&msg->reply);
if (!ret) {
- dev_dbg(dp->dev, "aux %d retries\n", i);
+ dev_vdbg(dp->dev, "aux %d retries\n", i);
return msg->size;
}
@@ -1489,7 +1482,7 @@ static void zynqmp_dp_bridge_atomic_disable(struct drm_bridge *bridge,
struct zynqmp_dp *dp = bridge_to_dp(bridge);
dp->enabled = false;
- cancel_delayed_work(&dp->hpd_work);
+ cancel_work(&dp->hpd_work);
zynqmp_dp_write(dp, ZYNQMP_DP_MAIN_STREAM_ENABLE, 0);
drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, DP_SET_POWER_D3);
zynqmp_dp_write(dp, ZYNQMP_DP_TX_PHY_POWER_DOWN,
@@ -1655,8 +1648,7 @@ void zynqmp_dp_disable_vblank(struct zynqmp_dp *dp)
static void zynqmp_dp_hpd_work_func(struct work_struct *work)
{
- struct zynqmp_dp *dp = container_of(work, struct zynqmp_dp,
- hpd_work.work);
+ struct zynqmp_dp *dp = container_of(work, struct zynqmp_dp, hpd_work);
enum drm_connector_status status;
status = zynqmp_dp_bridge_detect(&dp->bridge);
@@ -1692,7 +1684,7 @@ static irqreturn_t zynqmp_dp_irq_handler(int irq, void *data)
zynqmp_dpsub_drm_handle_vblank(dp->dpsub);
if (status & ZYNQMP_DP_INT_HPD_EVENT)
- schedule_delayed_work(&dp->hpd_work, 0);
+ schedule_work(&dp->hpd_work);
if (status & ZYNQMP_DP_INT_HPD_IRQ) {
int ret;
@@ -1734,7 +1726,7 @@ int zynqmp_dp_probe(struct zynqmp_dpsub *dpsub)
dp->dpsub = dpsub;
dp->status = connector_status_disconnected;
- INIT_DELAYED_WORK(&dp->hpd_work, zynqmp_dp_hpd_work_func);
+ INIT_WORK(&dp->hpd_work, zynqmp_dp_hpd_work_func);
/* Acquire all resources (IOMEM, IRQ and PHYs). */
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dp");
@@ -1839,7 +1831,7 @@ void zynqmp_dp_remove(struct zynqmp_dpsub *dpsub)
zynqmp_dp_write(dp, ZYNQMP_DP_INT_DS, ZYNQMP_DP_INT_ALL);
disable_irq(dp->irq);
- cancel_delayed_work_sync(&dp->hpd_work);
+ cancel_work_sync(&dp->hpd_work);
zynqmp_dp_write(dp, ZYNQMP_DP_TRANSMITTER_ENABLE, 0);
zynqmp_dp_write(dp, ZYNQMP_DP_INT_DS, 0xffffffff);
diff --git a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
index face8d6b2a6f..f5781939de9c 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
@@ -269,6 +269,7 @@ static int zynqmp_dpsub_probe(struct platform_device *pdev)
return 0;
err_disp:
+ drm_bridge_remove(dpsub->bridge);
zynqmp_disp_remove(dpsub);
err_dp:
zynqmp_dp_remove(dpsub);
diff --git a/drivers/gpu/drm/xlnx/zynqmp_dpsub.h b/drivers/gpu/drm/xlnx/zynqmp_dpsub.h
index 09ea01878f2a..b18554467e9c 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_dpsub.h
+++ b/drivers/gpu/drm/xlnx/zynqmp_dpsub.h
@@ -53,6 +53,7 @@ enum zynqmp_dpsub_format {
* @drm: The DRM/KMS device data
* @bridge: The DP encoder bridge
* @disp: The display controller
+ * @layers: Video and graphics layers
* @dp: The DisplayPort controller
* @dma_align: DMA alignment constraint (must be a power of 2)
*/
diff --git a/drivers/gpu/drm/xlnx/zynqmp_kms.c b/drivers/gpu/drm/xlnx/zynqmp_kms.c
index 43bf416b33d5..bd1368df7870 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_kms.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_kms.c
@@ -120,9 +120,13 @@ static void zynqmp_dpsub_plane_atomic_update(struct drm_plane *plane,
zynqmp_disp_blend_set_global_alpha(dpsub->disp, true,
plane->state->alpha >> 8);
- /* Enable or re-enable the plane if the format has changed. */
- if (format_changed)
- zynqmp_disp_layer_enable(layer);
+ /*
+ * Unconditionally enable the layer, as it may have been disabled
+ * previously either explicitly to reconfigure layer format, or
+ * implicitly after DPSUB reset during display mode change. DRM
+ * framework calls this callback for enabled planes only.
+ */
+ zynqmp_disp_layer_enable(layer);
}
static const struct drm_plane_helper_funcs zynqmp_dpsub_plane_helper_funcs = {
@@ -433,23 +437,28 @@ static int zynqmp_dpsub_kms_init(struct zynqmp_dpsub *dpsub)
DRM_BRIDGE_ATTACH_NO_CONNECTOR);
if (ret) {
dev_err(dpsub->dev, "failed to attach bridge to encoder\n");
- return ret;
+ goto err_encoder;
}
/* Create the connector for the chain of bridges. */
connector = drm_bridge_connector_init(&dpsub->drm->dev, encoder);
if (IS_ERR(connector)) {
dev_err(dpsub->dev, "failed to created connector\n");
- return PTR_ERR(connector);
+ ret = PTR_ERR(connector);
+ goto err_encoder;
}
ret = drm_connector_attach_encoder(connector, encoder);
if (ret < 0) {
dev_err(dpsub->dev, "failed to attach connector to encoder\n");
- return ret;
+ goto err_encoder;
}
return 0;
+
+err_encoder:
+ drm_encoder_cleanup(encoder);
+ return ret;
}
static void zynqmp_dpsub_drm_release(struct drm_device *drm, void *res)
@@ -529,5 +538,6 @@ void zynqmp_dpsub_drm_cleanup(struct zynqmp_dpsub *dpsub)
drm_dev_unregister(drm);
drm_atomic_helper_shutdown(drm);
+ drm_encoder_cleanup(&dpsub->drm->encoder);
drm_kms_helper_poll_fini(drm);
}
diff --git a/drivers/gpu/drm/xlnx/zynqmp_kms.h b/drivers/gpu/drm/xlnx/zynqmp_kms.h
index 01be96b00e3f..cb13c6b8008e 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_kms.h
+++ b/drivers/gpu/drm/xlnx/zynqmp_kms.h
@@ -22,9 +22,9 @@
struct zynqmp_dpsub;
/**
- * struct zynqmp_dpsub - ZynqMP DisplayPort Subsystem DRM/KMS data
+ * struct zynqmp_dpsub_drm - ZynqMP DisplayPort Subsystem DRM/KMS data
* @dpsub: Backpointer to the DisplayPort subsystem
- * @drm: The DRM/KMS device
+ * @dev: The DRM/KMS device
* @planes: The DRM planes
* @crtc: The DRM CRTC
* @encoder: The dummy DRM encoder
diff --git a/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c b/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c
index 89364bdbb129..f52fe23a6c0b 100644
--- a/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c
+++ b/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c
@@ -17,8 +17,8 @@
#include <linux/slab.h>
#include <linux/uuid.h>
#include <drm/drm_connector.h>
-#include <drm/i915_component.h>
-#include <drm/i915_gsc_proxy_mei_interface.h>
+#include <drm/intel/i915_component.h>
+#include <drm/intel/i915_gsc_proxy_mei_interface.h>
/**
* mei_gsc_proxy_send - Sends a proxy message to ME FW.
diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c
index f8759a6c9ed3..323f10620d90 100644
--- a/drivers/misc/mei/hdcp/mei_hdcp.c
+++ b/drivers/misc/mei/hdcp/mei_hdcp.c
@@ -23,8 +23,8 @@
#include <linux/mei_cl_bus.h>
#include <linux/component.h>
#include <drm/drm_connector.h>
-#include <drm/i915_component.h>
-#include <drm/i915_hdcp_interface.h>
+#include <drm/intel/i915_component.h>
+#include <drm/intel/i915_hdcp_interface.h>
#include "mei_hdcp.h"
diff --git a/drivers/misc/mei/pxp/mei_pxp.c b/drivers/misc/mei/pxp/mei_pxp.c
index 49abc95677cd..2820d389c88e 100644
--- a/drivers/misc/mei/pxp/mei_pxp.c
+++ b/drivers/misc/mei/pxp/mei_pxp.c
@@ -19,8 +19,8 @@
#include <linux/mei_cl_bus.h>
#include <linux/component.h>
#include <drm/drm_connector.h>
-#include <drm/i915_component.h>
-#include <drm/i915_pxp_tee_interface.h>
+#include <drm/intel/i915_component.h>
+#include <drm/intel/i915_pxp_tee_interface.h>
#include "mei_pxp.h"
diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c
index 73ec4460a151..523fb18a7ace 100644
--- a/drivers/platform/x86/intel_ips.c
+++ b/drivers/platform/x86/intel_ips.c
@@ -59,7 +59,7 @@
#include <linux/tick.h>
#include <linux/timer.h>
#include <linux/dmi.h>
-#include <drm/i915_drm.h>
+#include <drm/intel/i915_drm.h>
#include <asm/msr.h>
#include <asm/processor.h>
#include "intel_ips.h"
diff --git a/drivers/video/fbdev/core/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c
index 806ecd32219b..5ee7e78c2cea 100644
--- a/drivers/video/fbdev/core/fb_defio.c
+++ b/drivers/video/fbdev/core/fb_defio.c
@@ -23,33 +23,71 @@
#include <linux/rmap.h>
#include <linux/pagemap.h>
-static struct page *fb_deferred_io_page(struct fb_info *info, unsigned long offs)
+static struct page *fb_deferred_io_get_page(struct fb_info *info, unsigned long offs)
{
- void *screen_base = (void __force *) info->screen_base;
- struct page *page;
+ struct fb_deferred_io *fbdefio = info->fbdefio;
+ const void *screen_buffer = info->screen_buffer;
+ struct page *page = NULL;
- if (is_vmalloc_addr(screen_base + offs))
- page = vmalloc_to_page(screen_base + offs);
- else
+ if (fbdefio->get_page)
+ return fbdefio->get_page(info, offs);
+
+ if (is_vmalloc_addr(screen_buffer + offs))
+ page = vmalloc_to_page(screen_buffer + offs);
+ else if (info->fix.smem_start)
page = pfn_to_page((info->fix.smem_start + offs) >> PAGE_SHIFT);
+ if (page)
+ get_page(page);
+
return page;
}
+static struct fb_deferred_io_pageref *fb_deferred_io_pageref_lookup(struct fb_info *info,
+ unsigned long offset,
+ struct page *page)
+{
+ unsigned long pgoff = offset >> PAGE_SHIFT;
+ struct fb_deferred_io_pageref *pageref;
+
+ if (fb_WARN_ON_ONCE(info, pgoff >= info->npagerefs))
+ return NULL; /* incorrect allocation size */
+
+ /* 1:1 mapping between pageref and page offset */
+ pageref = &info->pagerefs[pgoff];
+
+ if (pageref->page)
+ goto out;
+
+ pageref->page = page;
+ pageref->offset = pgoff << PAGE_SHIFT;
+ INIT_LIST_HEAD(&pageref->list);
+
+out:
+ if (fb_WARN_ON_ONCE(info, pageref->page != page))
+ return NULL; /* inconsistent state */
+ return pageref;
+}
+
+static void fb_deferred_io_pageref_clear(struct fb_deferred_io_pageref *pageref)
+{
+ struct page *page = pageref->page;
+
+ if (page)
+ page->mapping = NULL;
+}
+
static struct fb_deferred_io_pageref *fb_deferred_io_pageref_get(struct fb_info *info,
unsigned long offset,
struct page *page)
{
struct fb_deferred_io *fbdefio = info->fbdefio;
struct list_head *pos = &fbdefio->pagereflist;
- unsigned long pgoff = offset >> PAGE_SHIFT;
struct fb_deferred_io_pageref *pageref, *cur;
- if (WARN_ON_ONCE(pgoff >= info->npagerefs))
- return NULL; /* incorrect allocation size */
-
- /* 1:1 mapping between pageref and page offset */
- pageref = &info->pagerefs[pgoff];
+ pageref = fb_deferred_io_pageref_lookup(info, offset, page);
+ if (!pageref)
+ return NULL;
/*
* This check is to catch the case where a new process could start
@@ -60,9 +98,6 @@ static struct fb_deferred_io_pageref *fb_deferred_io_pageref_get(struct fb_info
if (!list_empty(&pageref->list))
goto pageref_already_added;
- pageref->page = page;
- pageref->offset = pgoff << PAGE_SHIFT;
-
if (unlikely(fbdefio->sort_pagereflist)) {
/*
* We loop through the list of pagerefs before adding in
@@ -101,12 +136,10 @@ static vm_fault_t fb_deferred_io_fault(struct vm_fault *vmf)
if (offset >= info->fix.smem_len)
return VM_FAULT_SIGBUS;
- page = fb_deferred_io_page(info, offset);
+ page = fb_deferred_io_get_page(info, offset);
if (!page)
return VM_FAULT_SIGBUS;
- get_page(page);
-
if (vmf->vma->vm_file)
page->mapping = vmf->vma->vm_file->f_mapping;
else
@@ -264,7 +297,7 @@ int fb_deferred_io_init(struct fb_info *info)
{
struct fb_deferred_io *fbdefio = info->fbdefio;
struct fb_deferred_io_pageref *pagerefs;
- unsigned long npagerefs, i;
+ unsigned long npagerefs;
int ret;
BUG_ON(!fbdefio);
@@ -286,8 +319,6 @@ int fb_deferred_io_init(struct fb_info *info)
ret = -ENOMEM;
goto err;
}
- for (i = 0; i < npagerefs; ++i)
- INIT_LIST_HEAD(&pagerefs[i].list);
info->npagerefs = npagerefs;
info->pagerefs = pagerefs;
@@ -312,16 +343,13 @@ EXPORT_SYMBOL_GPL(fb_deferred_io_open);
static void fb_deferred_io_lastclose(struct fb_info *info)
{
- struct page *page;
- int i;
+ unsigned long i;
flush_delayed_work(&info->deferred_work);
/* clear out the mapping that we setup */
- for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) {
- page = fb_deferred_io_page(info, i);
- page->mapping = NULL;
- }
+ for (i = 0; i < info->npagerefs; ++i)
+ fb_deferred_io_pageref_clear(&info->pagerefs[i]);
}
void fb_deferred_io_release(struct fb_info *info)
diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
index 0b032faa8cf2..173548c6473a 100644
--- a/include/drm/display/drm_dp.h
+++ b/include/drm/display/drm_dp.h
@@ -232,6 +232,8 @@
#define DP_RECEIVER_ALPM_CAP 0x02e /* eDP 1.4 */
# define DP_ALPM_CAP (1 << 0)
+# define DP_ALPM_PM_STATE_2A_SUPPORT (1 << 1) /* eDP 1.5 */
+# define DP_ALPM_AUX_LESS_CAP (1 << 2) /* eDP 1.5 */
#define DP_SINK_DEVICE_AUX_FRAME_SYNC_CAP 0x02f /* eDP 1.4 */
# define DP_AUX_FRAME_SYNC_CAP (1 << 0)
@@ -544,9 +546,16 @@
/* DFP Capability Extension */
#define DP_DFP_CAPABILITY_EXTENSION_SUPPORT 0x0a3 /* 2.0 */
-#define DP_PANEL_REPLAY_CAP 0x0b0 /* DP 2.0 */
-# define DP_PANEL_REPLAY_SUPPORT (1 << 0)
-# define DP_PANEL_REPLAY_SU_SUPPORT (1 << 1)
+#define DP_PANEL_REPLAY_CAP 0x0b0 /* DP 2.0 */
+# define DP_PANEL_REPLAY_SUPPORT (1 << 0)
+# define DP_PANEL_REPLAY_SU_SUPPORT (1 << 1)
+# define DP_PANEL_REPLAY_EARLY_TRANSPORT_SUPPORT (1 << 2) /* eDP 1.5 */
+
+#define DP_PANEL_PANEL_REPLAY_CAPABILITY 0xb1
+# define DP_PANEL_PANEL_REPLAY_SU_GRANULARITY_REQUIRED (1 << 5)
+
+#define DP_PANEL_PANEL_REPLAY_X_GRANULARITY 0xb2
+#define DP_PANEL_PANEL_REPLAY_Y_GRANULARITY 0xb4
/* Link Configuration */
#define DP_LINK_BW_SET 0x100
@@ -677,7 +686,8 @@
#define DP_RECEIVER_ALPM_CONFIG 0x116 /* eDP 1.4 */
# define DP_ALPM_ENABLE (1 << 0)
-# define DP_ALPM_LOCK_ERROR_IRQ_HPD_ENABLE (1 << 1)
+# define DP_ALPM_LOCK_ERROR_IRQ_HPD_ENABLE (1 << 1) /* eDP 1.5 */
+# define DP_ALPM_MODE_AUX_LESS (1 << 2) /* eDP 1.5 */
#define DP_SINK_DEVICE_AUX_FRAME_SYNC_CONF 0x117 /* eDP 1.4 */
# define DP_AUX_FRAME_SYNC_ENABLE (1 << 0)
@@ -728,10 +738,20 @@
#define PANEL_REPLAY_CONFIG 0x1b0 /* DP 2.0 */
# define DP_PANEL_REPLAY_ENABLE (1 << 0)
+# define DP_PANEL_REPLAY_VSC_SDP_CRC_EN (1 << 1) /* eDP 1.5 */
# define DP_PANEL_REPLAY_UNRECOVERABLE_ERROR_EN (1 << 3)
# define DP_PANEL_REPLAY_RFB_STORAGE_ERROR_EN (1 << 4)
# define DP_PANEL_REPLAY_ACTIVE_FRAME_CRC_ERROR_EN (1 << 5)
# define DP_PANEL_REPLAY_SU_ENABLE (1 << 6)
+# define DP_PANEL_REPLAY_ENABLE_SU_REGION_ET (1 << 7) /* DP 2.1 */
+
+#define PANEL_REPLAY_CONFIG2 0x1b1 /* eDP 1.5 */
+# define DP_PANEL_REPLAY_SINK_REFRESH_RATE_UNLOCK_GRANTED (1 << 0)
+# define DP_PANEL_REPLAY_CRC_VERIFICATION (1 << 1)
+# define DP_PANEL_REPLAY_SU_Y_GRANULARITY_EXTENDED_EN (1 << 2)
+# define DP_PANEL_REPLAY_SU_Y_GRANULARITY_EXTENDED_VAL_SEL_SHIFT 3
+# define DP_PANEL_REPLAY_SU_Y_GRANULARITY_EXTENDED_VAL_SEL_MASK (0xf << 3)
+# define DP_PANEL_REPLAY_SU_REGION_SCANLINE_CAPTURE (1 << 7)
#define DP_PAYLOAD_ALLOCATE_SET 0x1c0
#define DP_PAYLOAD_ALLOCATE_START_TIME_SLOT 0x1c1
diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h
index 8bed890eec2c..ea03e1dd26ba 100644
--- a/include/drm/display/drm_dp_helper.h
+++ b/include/drm/display/drm_dp_helper.h
@@ -112,7 +112,7 @@ struct drm_dp_vsc_sdp {
* @target_rr: Target Refresh
* @duration_incr_ms: Successive frame duration increase
* @duration_decr_ms: Successive frame duration decrease
- * @operation_mode: Adaptive Sync Operation Mode
+ * @mode: Adaptive Sync Operation Mode
*/
struct drm_dp_as_sdp {
unsigned char sdp_type;
@@ -122,6 +122,7 @@ struct drm_dp_as_sdp {
int target_rr;
int duration_incr_ms;
int duration_decr_ms;
+ bool target_rr_divider;
enum operation_mode mode;
};
diff --git a/include/drm/display/drm_hdmi_helper.h b/include/drm/display/drm_hdmi_helper.h
index 76d234826e22..57e3b18c15ec 100644
--- a/include/drm/display/drm_hdmi_helper.h
+++ b/include/drm/display/drm_hdmi_helper.h
@@ -24,4 +24,8 @@ drm_hdmi_infoframe_set_hdr_metadata(struct hdmi_drm_infoframe *frame,
void drm_hdmi_avi_infoframe_content_type(struct hdmi_avi_infoframe *frame,
const struct drm_connector_state *conn_state);
+unsigned long long
+drm_hdmi_compute_mode_clock(const struct drm_display_mode *mode,
+ unsigned int bpc, enum hdmi_colorspace fmt);
+
#endif
diff --git a/include/drm/display/drm_hdmi_state_helper.h b/include/drm/display/drm_hdmi_state_helper.h
new file mode 100644
index 000000000000..285f366cf716
--- /dev/null
+++ b/include/drm/display/drm_hdmi_state_helper.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: MIT */
+
+#ifndef DRM_HDMI_STATE_HELPER_H_
+#define DRM_HDMI_STATE_HELPER_H_
+
+struct drm_atomic_state;
+struct drm_connector;
+struct drm_connector_state;
+struct hdmi_audio_infoframe;
+
+void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector,
+ struct drm_connector_state *new_conn_state);
+
+int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
+ struct drm_atomic_state *state);
+
+int drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector *connector,
+ struct hdmi_audio_infoframe *frame);
+int drm_atomic_helper_connector_hdmi_disable_audio_infoframe(struct drm_connector *connector);
+int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector,
+ struct drm_atomic_state *state);
+
+#endif // DRM_HDMI_STATE_HELPER_H_
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 4baca0d9107b..75019d16be64 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -631,6 +631,52 @@ struct drm_bridge_funcs {
void (*hpd_disable)(struct drm_bridge *bridge);
/**
+ * @hdmi_tmds_char_rate_valid:
+ *
+ * Check whether a particular TMDS character rate is supported by the
+ * driver.
+ *
+ * This callback is optional and should only be implemented by the
+ * bridges that take part in the HDMI connector implementation. Bridges
+ * that implement it shall set the DRM_BRIDGE_OP_HDMI flag in their
+ * &drm_bridge->ops.
+ *
+ * Returns:
+ *
+ * Either &drm_mode_status.MODE_OK or one of the failure reasons
+ * in &enum drm_mode_status.
+ */
+ enum drm_mode_status
+ (*hdmi_tmds_char_rate_valid)(const struct drm_bridge *bridge,
+ const struct drm_display_mode *mode,
+ unsigned long long tmds_rate);
+
+ /**
+ * @hdmi_clear_infoframe:
+ *
+ * This callback clears the infoframes in the hardware during commit.
+ * It will be called multiple times, once for every disabled infoframe
+ * type.
+ *
+ * This callback is optional but it must be implemented by bridges that
+ * set the DRM_BRIDGE_OP_HDMI flag in their &drm_bridge->ops.
+ */
+ int (*hdmi_clear_infoframe)(struct drm_bridge *bridge,
+ enum hdmi_infoframe_type type);
+ /**
+ * @hdmi_write_infoframe:
+ *
+ * Program the infoframe into the hardware. It will be called multiple
+ * times, once for every updated infoframe type.
+ *
+ * This callback is optional but it must be implemented by bridges that
+ * set the DRM_BRIDGE_OP_HDMI flag in their &drm_bridge->ops.
+ */
+ int (*hdmi_write_infoframe)(struct drm_bridge *bridge,
+ enum hdmi_infoframe_type type,
+ const u8 *buffer, size_t len);
+
+ /**
* @debugfs_init:
*
* Allows bridges to create bridge-specific debugfs files.
@@ -705,6 +751,16 @@ enum drm_bridge_ops {
* this flag shall implement the &drm_bridge_funcs->get_modes callback.
*/
DRM_BRIDGE_OP_MODES = BIT(3),
+ /**
+ * @DRM_BRIDGE_OP_HDMI: The bridge provides HDMI connector operations,
+ * including infoframes support. Bridges that set this flag must
+ * implement the &drm_bridge_funcs->write_infoframe callback.
+ *
+ * Note: currently there can be at most one bridge in a chain that sets
+ * this bit. This is to simplify corresponding glue code in connector
+ * drivers.
+ */
+ DRM_BRIDGE_OP_HDMI = BIT(4),
};
/**
@@ -773,6 +829,31 @@ struct drm_bridge {
* @hpd_cb.
*/
void *hpd_data;
+
+ /**
+ * @vendor: Vendor of the product to be used for the SPD InfoFrame
+ * generation. This is required if @DRM_BRIDGE_OP_HDMI is set.
+ */
+ const char *vendor;
+
+ /**
+ * @product: Name of the product to be used for the SPD InfoFrame
+ * generation. This is required if @DRM_BRIDGE_OP_HDMI is set.
+ */
+ const char *product;
+
+ /**
+ * @supported_formats: Bitmask of @hdmi_colorspace listing supported
+ * output formats. This is only relevant if @DRM_BRIDGE_OP_HDMI is set.
+ */
+ unsigned int supported_formats;
+
+ /**
+ * @max_bpc: Maximum bits per char the HDMI bridge supports. Allowed
+ * values are 8, 10 and 12. This is only relevant if
+ * @DRM_BRIDGE_OP_HDMI is set.
+ */
+ unsigned int max_bpc;
};
static inline struct drm_bridge *
@@ -855,9 +936,6 @@ drm_bridge_chain_get_first_bridge(struct drm_encoder *encoder)
#define drm_for_each_bridge_in_chain(encoder, bridge) \
list_for_each_entry(bridge, &(encoder)->bridge_chain, chain_node)
-bool drm_bridge_chain_mode_fixup(struct drm_bridge *bridge,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode);
enum drm_mode_status
drm_bridge_chain_mode_valid(struct drm_bridge *bridge,
const struct drm_display_info *info,
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index fe88d7fc6b8f..c754651044d4 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -38,6 +38,7 @@ struct drm_connector_helper_funcs;
struct drm_modeset_acquire_ctx;
struct drm_device;
struct drm_crtc;
+struct drm_display_mode;
struct drm_encoder;
struct drm_panel;
struct drm_property;
@@ -201,6 +202,13 @@ enum drm_connector_tv_mode {
DRM_MODE_TV_MODE_SECAM,
/**
+ * @DRM_MODE_TV_MODE_MONOCHROME: Use timings appropriate to
+ * the DRM mode, including equalizing pulses for a 525-line
+ * or 625-line mode, with no pedestal or color encoding.
+ */
+ DRM_MODE_TV_MODE_MONOCHROME,
+
+ /**
* @DRM_MODE_TV_MODE_MAX: Number of analog TV output modes.
*
* Internal implementation detail; this is not uABI.
@@ -369,6 +377,32 @@ enum drm_panel_orientation {
};
/**
+ * enum drm_hdmi_broadcast_rgb - Broadcast RGB Selection for an HDMI @drm_connector
+ */
+enum drm_hdmi_broadcast_rgb {
+ /**
+ * @DRM_HDMI_BROADCAST_RGB_AUTO: The RGB range is selected
+ * automatically based on the mode.
+ */
+ DRM_HDMI_BROADCAST_RGB_AUTO,
+
+ /**
+ * @DRM_HDMI_BROADCAST_RGB_FULL: Full range RGB is forced.
+ */
+ DRM_HDMI_BROADCAST_RGB_FULL,
+
+ /**
+ * @DRM_HDMI_BROADCAST_RGB_LIMITED: Limited range RGB is forced.
+ */
+ DRM_HDMI_BROADCAST_RGB_LIMITED,
+};
+
+const char *
+drm_hdmi_connector_get_broadcast_rgb_name(enum drm_hdmi_broadcast_rgb broadcast_rgb);
+const char *
+drm_hdmi_connector_get_output_format_name(enum hdmi_colorspace fmt);
+
+/**
* struct drm_monitor_range_info - Panel's Monitor range in EDID for
* &drm_display_info
*
@@ -888,6 +922,82 @@ struct drm_tv_connector_state {
};
/**
+ * struct drm_connector_hdmi_infoframe - HDMI Infoframe container
+ */
+struct drm_connector_hdmi_infoframe {
+ /**
+ * @data: HDMI Infoframe structure
+ */
+ union hdmi_infoframe data;
+
+ /**
+ * @set: Is the content of @data valid?
+ */
+ bool set;
+};
+
+/*
+ * struct drm_connector_hdmi_state - HDMI state container
+ */
+struct drm_connector_hdmi_state {
+ /**
+ * @broadcast_rgb: Connector property to pass the
+ * Broadcast RGB selection value.
+ */
+ enum drm_hdmi_broadcast_rgb broadcast_rgb;
+
+ /**
+ * @infoframes: HDMI Infoframes matching that state
+ */
+ struct {
+ /**
+ * @avi: AVI Infoframes structure matching our
+ * state.
+ */
+ struct drm_connector_hdmi_infoframe avi;
+
+ /**
+ * @hdr_drm: DRM (Dynamic Range and Mastering)
+ * Infoframes structure matching our state.
+ */
+ struct drm_connector_hdmi_infoframe hdr_drm;
+
+ /**
+ * @spd: SPD Infoframes structure matching our
+ * state.
+ */
+ struct drm_connector_hdmi_infoframe spd;
+
+ /**
+ * @vendor: HDMI Vendor Infoframes structure
+ * matching our state.
+ */
+ struct drm_connector_hdmi_infoframe hdmi;
+ } infoframes;
+
+ /**
+ * @is_limited_range: Is the output supposed to use a limited
+ * RGB Quantization Range or not?
+ */
+ bool is_limited_range;
+
+ /**
+ * @output_bpc: Bits per color channel to output.
+ */
+ unsigned int output_bpc;
+
+ /**
+ * @output_format: Pixel format to output in.
+ */
+ enum hdmi_colorspace output_format;
+
+ /**
+ * @tmds_char_rate: TMDS Character Rate, in Hz.
+ */
+ unsigned long long tmds_char_rate;
+};
+
+/**
* struct drm_connector_state - mutable connector state
*/
struct drm_connector_state {
@@ -1031,6 +1141,71 @@ struct drm_connector_state {
* DRM blob property for HDR output metadata
*/
struct drm_property_blob *hdr_output_metadata;
+
+ /**
+ * @hdmi: HDMI-related variable and properties. Filled by
+ * @drm_atomic_helper_connector_hdmi_check().
+ */
+ struct drm_connector_hdmi_state hdmi;
+};
+
+/**
+ * struct drm_connector_hdmi_funcs - drm_hdmi_connector control functions
+ */
+struct drm_connector_hdmi_funcs {
+ /**
+ * @tmds_char_rate_valid:
+ *
+ * This callback is invoked at atomic_check time to figure out
+ * whether a particular TMDS character rate is supported by the
+ * driver.
+ *
+ * The @tmds_char_rate_valid callback is optional.
+ *
+ * Returns:
+ *
+ * Either &drm_mode_status.MODE_OK or one of the failure reasons
+ * in &enum drm_mode_status.
+ */
+ enum drm_mode_status
+ (*tmds_char_rate_valid)(const struct drm_connector *connector,
+ const struct drm_display_mode *mode,
+ unsigned long long tmds_rate);
+
+ /**
+ * @clear_infoframe:
+ *
+ * This callback is invoked through
+ * @drm_atomic_helper_connector_hdmi_update_infoframes during a
+ * commit to clear the infoframes into the hardware. It will be
+ * called multiple times, once for every disabled infoframe
+ * type.
+ *
+ * The @clear_infoframe callback is optional.
+ *
+ * Returns:
+ * 0 on success, a negative error code otherwise
+ */
+ int (*clear_infoframe)(struct drm_connector *connector,
+ enum hdmi_infoframe_type type);
+
+ /**
+ * @write_infoframe:
+ *
+ * This callback is invoked through
+ * @drm_atomic_helper_connector_hdmi_update_infoframes during a
+ * commit to program the infoframes into the hardware. It will
+ * be called multiple times, once for every updated infoframe
+ * type.
+ *
+ * The @write_infoframe callback is mandatory.
+ *
+ * Returns:
+ * 0 on success, a negative error code otherwise
+ */
+ int (*write_infoframe)(struct drm_connector *connector,
+ enum hdmi_infoframe_type type,
+ const u8 *buffer, size_t len);
};
/**
@@ -1493,6 +1668,51 @@ struct drm_cmdline_mode {
bool tv_mode_specified;
};
+/*
+ * struct drm_connector_hdmi - DRM Connector HDMI-related structure
+ */
+struct drm_connector_hdmi {
+#define DRM_CONNECTOR_HDMI_VENDOR_LEN 8
+ /**
+ * @vendor: HDMI Controller Vendor Name
+ */
+ unsigned char vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] __nonstring;
+
+#define DRM_CONNECTOR_HDMI_PRODUCT_LEN 16
+ /**
+ * @product: HDMI Controller Product Name
+ */
+ unsigned char product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] __nonstring;
+
+ /**
+ * @supported_formats: Bitmask of @hdmi_colorspace
+ * supported by the controller.
+ */
+ unsigned long supported_formats;
+
+ /**
+ * @funcs: HDMI connector Control Functions
+ */
+ const struct drm_connector_hdmi_funcs *funcs;
+
+ /**
+ * @infoframes: Current Infoframes output by the connector
+ */
+ struct {
+ /**
+ * @lock: Mutex protecting against concurrent access to
+ * the infoframes, most notably between KMS and ALSA.
+ */
+ struct mutex lock;
+
+ /**
+ * @audio: Current Audio Infoframes structure. Protected
+ * by @lock.
+ */
+ struct drm_connector_hdmi_infoframe audio;
+ } infoframes;
+};
+
/**
* struct drm_connector - central DRM connector control structure
*
@@ -1636,8 +1856,12 @@ struct drm_connector {
/**
* @edid_blob_ptr: DRM property containing EDID if present. Protected by
- * &drm_mode_config.mutex. This should be updated only by calling
+ * &drm_mode_config.mutex.
+ *
+ * This must be updated only by calling drm_edid_connector_update() or
* drm_connector_update_edid_property().
+ *
+ * This must not be used by drivers directly.
*/
struct drm_property_blob *edid_blob_ptr;
@@ -1676,6 +1900,11 @@ struct drm_connector {
struct drm_property_blob *path_blob_ptr;
/**
+ * @max_bpc: Maximum bits per color channel the connector supports.
+ */
+ unsigned int max_bpc;
+
+ /**
* @max_bpc_property: Default connector property for the max bpc to be
* driven out of the connector.
*/
@@ -1699,6 +1928,12 @@ struct drm_connector {
*/
struct drm_property *privacy_screen_hw_state_property;
+ /**
+ * @broadcast_rgb_property: Connector property to set the
+ * Broadcast RGB selection to output with.
+ */
+ struct drm_property *broadcast_rgb_property;
+
#define DRM_CONNECTOR_POLL_HPD (1 << 0)
#define DRM_CONNECTOR_POLL_CONNECT (1 << 1)
#define DRM_CONNECTOR_POLL_DISCONNECT (1 << 2)
@@ -1886,6 +2121,11 @@ struct drm_connector {
/** @hdr_sink_metadata: HDR Metadata Information read from sink */
struct hdr_sink_metadata hdr_sink_metadata;
+
+ /**
+ * @hdmi: HDMI-related variable and properties.
+ */
+ struct drm_connector_hdmi hdmi;
};
#define obj_to_connector(x) container_of(x, struct drm_connector, base)
@@ -1904,6 +2144,15 @@ int drmm_connector_init(struct drm_device *dev,
const struct drm_connector_funcs *funcs,
int connector_type,
struct i2c_adapter *ddc);
+int drmm_connector_hdmi_init(struct drm_device *dev,
+ struct drm_connector *connector,
+ const char *vendor, const char *product,
+ const struct drm_connector_funcs *funcs,
+ const struct drm_connector_hdmi_funcs *hdmi_funcs,
+ int connector_type,
+ struct i2c_adapter *ddc,
+ unsigned long supported_formats,
+ unsigned int max_bpc);
void drm_connector_attach_edid_property(struct drm_connector *connector);
int drm_connector_register(struct drm_connector *connector);
void drm_connector_unregister(struct drm_connector *connector);
@@ -2014,6 +2263,7 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
u32 scaling_mode_mask);
int drm_connector_attach_vrr_capable_property(
struct drm_connector *connector);
+int drm_connector_attach_broadcast_rgb_property(struct drm_connector *connector);
int drm_connector_attach_colorspace_property(struct drm_connector *connector);
int drm_connector_attach_hdr_output_metadata_property(struct drm_connector *connector);
bool drm_connector_atomic_hdr_metadata_equal(struct drm_connector_state *old_state,
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index 8878260d7529..cd37936c3926 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -411,7 +411,7 @@ struct drm_driver {
char *name;
/** @desc: driver description */
char *desc;
- /** @date: driver date */
+ /** @date: driver date, unused, to be removed */
char *date;
/**
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index b085525e53e2..6bdfa254a1c1 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -423,10 +423,6 @@ static inline void drm_edid_decode_panel_id(u32 panel_id, char vend[4], u16 *pro
}
bool drm_probe_ddc(struct i2c_adapter *adapter);
-struct edid *drm_do_get_edid(struct drm_connector *connector,
- int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
- size_t len),
- void *data);
struct edid *drm_get_edid(struct drm_connector *connector,
struct i2c_adapter *adapter);
struct edid *drm_get_edid_switcheroo(struct drm_connector *connector,
diff --git a/include/drm/drm_fbdev_generic.h b/include/drm/drm_fbdev_generic.h
deleted file mode 100644
index 75799342098d..000000000000
--- a/include/drm/drm_fbdev_generic.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-
-#ifndef DRM_FBDEV_GENERIC_H
-#define DRM_FBDEV_GENERIC_H
-
-struct drm_device;
-
-#ifdef CONFIG_DRM_FBDEV_EMULATION
-void drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp);
-#else
-static inline void drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp)
-{ }
-#endif
-
-#endif
diff --git a/include/drm/drm_fbdev_shmem.h b/include/drm/drm_fbdev_shmem.h
new file mode 100644
index 000000000000..fb43cadd1950
--- /dev/null
+++ b/include/drm/drm_fbdev_shmem.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: MIT */
+
+#ifndef DRM_FBDEV_SHMEM_H
+#define DRM_FBDEV_SHMEM_H
+
+struct drm_device;
+
+#ifdef CONFIG_DRM_FBDEV_EMULATION
+void drm_fbdev_shmem_setup(struct drm_device *dev, unsigned int preferred_bpp);
+#else
+static inline void drm_fbdev_shmem_setup(struct drm_device *dev, unsigned int preferred_bpp)
+{ }
+#endif
+
+#endif
diff --git a/include/drm/drm_fbdev_ttm.h b/include/drm/drm_fbdev_ttm.h
new file mode 100644
index 000000000000..9e6c3bdf3537
--- /dev/null
+++ b/include/drm/drm_fbdev_ttm.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: MIT */
+
+#ifndef DRM_FBDEV_TTM_H
+#define DRM_FBDEV_TTM_H
+
+struct drm_device;
+
+#ifdef CONFIG_DRM_FBDEV_EMULATION
+void drm_fbdev_ttm_setup(struct drm_device *dev, unsigned int preferred_bpp);
+#else
+static inline void drm_fbdev_ttm_setup(struct drm_device *dev, unsigned int preferred_bpp)
+{ }
+#endif
+
+#endif
diff --git a/include/drm/drm_mipi_dbi.h b/include/drm/drm_mipi_dbi.h
index e8e0f8d39f3a..f45f9612c0bc 100644
--- a/include/drm/drm_mipi_dbi.h
+++ b/include/drm/drm_mipi_dbi.h
@@ -57,6 +57,11 @@ struct mipi_dbi {
struct spi_device *spi;
/**
+ * @write_memory_bpw: Bits per word used on a MIPI_DCS_WRITE_MEMORY_START transfer
+ */
+ unsigned int write_memory_bpw;
+
+ /**
* @dc: Optional D/C gpio.
*/
struct gpio_desc *dc;
@@ -97,6 +102,11 @@ struct mipi_dbi_dev {
struct drm_display_mode mode;
/**
+ * @pixel_format: Native pixel format (DRM_FORMAT\_\*)
+ */
+ u32 pixel_format;
+
+ /**
* @tx_buf: Buffer used for transfer (copy clip rect area)
*/
u16 *tx_buf;
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 82b1cc434ea3..71d121aeef24 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -197,6 +197,27 @@ struct mipi_dsi_device {
struct drm_dsc_config *dsc;
};
+/**
+ * struct mipi_dsi_multi_context - Context to call multiple MIPI DSI funcs in a row
+ */
+struct mipi_dsi_multi_context {
+ /**
+ * @dsi: Pointer to the MIPI DSI device
+ */
+ struct mipi_dsi_device *dsi;
+
+ /**
+ * @accum_err: Storage for the accumulated error over the multiple calls
+ *
+ * Init to 0. If a function encounters an error then the error code
+ * will be stored here. If you call a function and this points to a
+ * non-zero value then the function will be a noop. This allows calling
+ * a function many times in a row and just checking the error at the
+ * end to see if any of them failed.
+ */
+ int accum_err;
+};
+
#define MIPI_DSI_MODULE_PREFIX "mipi-dsi:"
#define to_mipi_dsi_device(__dev) container_of_const(__dev, struct mipi_dsi_device, dev)
@@ -254,11 +275,28 @@ int mipi_dsi_compression_mode_ext(struct mipi_dsi_device *dsi, bool enable,
int mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi,
const struct drm_dsc_picture_parameter_set *pps);
+void mipi_dsi_compression_mode_ext_multi(struct mipi_dsi_multi_context *ctx,
+ bool enable,
+ enum mipi_dsi_compression_algo algo,
+ unsigned int pps_selector);
+void mipi_dsi_picture_parameter_set_multi(struct mipi_dsi_multi_context *ctx,
+ const struct drm_dsc_picture_parameter_set *pps);
+
ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload,
size_t size);
+int mipi_dsi_generic_write_chatty(struct mipi_dsi_device *dsi,
+ const void *payload, size_t size);
+void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx,
+ const void *payload, size_t size);
ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
size_t num_params, void *data, size_t size);
+#define mipi_dsi_msleep(ctx, delay) \
+ do { \
+ if (!(ctx)->accum_err) \
+ msleep(delay); \
+ } while (0)
+
/**
* enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode
* @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking
@@ -279,6 +317,10 @@ enum mipi_dsi_dcs_tear_mode {
ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi,
const void *data, size_t len);
+int mipi_dsi_dcs_write_buffer_chatty(struct mipi_dsi_device *dsi,
+ const void *data, size_t len);
+void mipi_dsi_dcs_write_buffer_multi(struct mipi_dsi_multi_context *ctx,
+ const void *data, size_t len);
ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd,
const void *data, size_t len);
ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data,
@@ -309,42 +351,86 @@ int mipi_dsi_dcs_set_display_brightness_large(struct mipi_dsi_device *dsi,
int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi,
u16 *brightness);
+void mipi_dsi_dcs_nop_multi(struct mipi_dsi_multi_context *ctx);
+void mipi_dsi_dcs_enter_sleep_mode_multi(struct mipi_dsi_multi_context *ctx);
+void mipi_dsi_dcs_exit_sleep_mode_multi(struct mipi_dsi_multi_context *ctx);
+void mipi_dsi_dcs_set_display_off_multi(struct mipi_dsi_multi_context *ctx);
+void mipi_dsi_dcs_set_display_on_multi(struct mipi_dsi_multi_context *ctx);
+void mipi_dsi_dcs_set_tear_on_multi(struct mipi_dsi_multi_context *ctx,
+ enum mipi_dsi_dcs_tear_mode mode);
+
/**
* mipi_dsi_generic_write_seq - transmit data using a generic write packet
+ *
+ * This macro will print errors for you and will RETURN FROM THE CALLING
+ * FUNCTION (yes this is non-intuitive) upon error.
+ *
+ * Because of the non-intuitive return behavior, THIS MACRO IS DEPRECATED.
+ * Please replace calls of it with mipi_dsi_generic_write_seq_multi().
+ *
* @dsi: DSI peripheral device
* @seq: buffer containing the payload
*/
#define mipi_dsi_generic_write_seq(dsi, seq...) \
do { \
static const u8 d[] = { seq }; \
- struct device *dev = &dsi->dev; \
int ret; \
- ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d)); \
- if (ret < 0) { \
- dev_err_ratelimited(dev, "transmit data failed: %d\n", \
- ret); \
+ ret = mipi_dsi_generic_write_chatty(dsi, d, ARRAY_SIZE(d)); \
+ if (ret < 0) \
return ret; \
- } \
+ } while (0)
+
+/**
+ * mipi_dsi_generic_write_seq_multi - transmit data using a generic write packet
+ *
+ * This macro will print errors for you and error handling is optimized for
+ * callers that call this multiple times in a row.
+ *
+ * @ctx: Context for multiple DSI transactions
+ * @seq: buffer containing the payload
+ */
+#define mipi_dsi_generic_write_seq_multi(ctx, seq...) \
+ do { \
+ static const u8 d[] = { seq }; \
+ mipi_dsi_generic_write_multi(ctx, d, ARRAY_SIZE(d)); \
} while (0)
/**
* mipi_dsi_dcs_write_seq - transmit a DCS command with payload
+ *
+ * This macro will print errors for you and will RETURN FROM THE CALLING
+ * FUNCTION (yes this is non-intuitive) upon error.
+ *
+ * Because of the non-intuitive return behavior, THIS MACRO IS DEPRECATED.
+ * Please replace calls of it with mipi_dsi_dcs_write_seq_multi().
+ *
* @dsi: DSI peripheral device
* @cmd: Command
* @seq: buffer containing data to be transmitted
*/
-#define mipi_dsi_dcs_write_seq(dsi, cmd, seq...) \
- do { \
- static const u8 d[] = { cmd, seq }; \
- struct device *dev = &dsi->dev; \
- int ret; \
- ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d)); \
- if (ret < 0) { \
- dev_err_ratelimited( \
- dev, "sending command %#02x failed: %d\n", \
- cmd, ret); \
- return ret; \
- } \
+#define mipi_dsi_dcs_write_seq(dsi, cmd, seq...) \
+ do { \
+ static const u8 d[] = { cmd, seq }; \
+ int ret; \
+ ret = mipi_dsi_dcs_write_buffer_chatty(dsi, d, ARRAY_SIZE(d)); \
+ if (ret < 0) \
+ return ret; \
+ } while (0)
+
+/**
+ * mipi_dsi_dcs_write_seq_multi - transmit a DCS command with payload
+ *
+ * This macro will print errors for you and error handling is optimized for
+ * callers that call this multiple times in a row.
+ *
+ * @ctx: Context for multiple DSI transactions
+ * @cmd: Command
+ * @seq: buffer containing data to be transmitted
+ */
+#define mipi_dsi_dcs_write_seq_multi(ctx, cmd, seq...) \
+ do { \
+ static const u8 d[] = { cmd, seq }; \
+ mipi_dsi_dcs_write_buffer_multi(ctx, d, ARRAY_SIZE(d)); \
} while (0)
/**
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h
index ac33ba1b18bc..f654874c4ce6 100644
--- a/include/drm/drm_mm.h
+++ b/include/drm/drm_mm.h
@@ -463,7 +463,6 @@ static inline int drm_mm_insert_node(struct drm_mm *mm,
}
void drm_mm_remove_node(struct drm_mm_node *node);
-void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new);
void drm_mm_init(struct drm_mm *mm, u64 start, u64 size);
void drm_mm_takedown(struct drm_mm *mm);
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 8de3c9a5f61b..ab0f167474b1 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -106,8 +106,8 @@ struct drm_mode_config_funcs {
* Drivers implementing fbdev emulation use drm_kms_helper_hotplug_event()
* to call this hook to inform the fbdev helper of output changes.
*
- * This hook is deprecated, drivers should instead use
- * drm_fbdev_generic_setup() which takes care of any necessary
+ * This hook is deprecated, drivers should instead implement fbdev
+ * support with struct drm_client, which takes care of any necessary
* hotplug event forwarding already without further involvement by
* the driver.
*/
diff --git a/include/drm/drm_panic.h b/include/drm/drm_panic.h
index 822dbb1aa9d6..73bb3f3d9ed9 100644
--- a/include/drm/drm_panic.h
+++ b/include/drm/drm_panic.h
@@ -50,6 +50,15 @@ struct drm_scanout_buffer {
* @pitch: Length in bytes between the start of two consecutive lines.
*/
unsigned int pitch[DRM_FORMAT_MAX_PLANES];
+
+ /**
+ * @set_pixel: Optional function, to set a pixel color on the
+ * framebuffer. It allows to handle special tiling format inside the
+ * driver.
+ */
+ void (*set_pixel)(struct drm_scanout_buffer *sb, unsigned int x,
+ unsigned int y, u32 color);
+
};
/**
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index 089950ad8681..5d9dff5149c9 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -175,6 +175,7 @@ struct drm_printer {
void (*printfn)(struct drm_printer *p, struct va_format *vaf);
void (*puts)(struct drm_printer *p, const char *str);
void *arg;
+ const void *origin;
const char *prefix;
enum drm_debug_category category;
};
@@ -332,6 +333,7 @@ static inline struct drm_printer drm_dbg_printer(struct drm_device *drm,
struct drm_printer p = {
.printfn = __drm_printfn_dbg,
.arg = drm,
+ .origin = (const void *)_THIS_IP_, /* it's fine as we will be inlined */
.prefix = prefix,
.category = category,
};
@@ -527,17 +529,15 @@ void __drm_dev_dbg(struct _ddebug *desc, const struct device *dev,
* Prefer drm_device based logging over device or prink based logging.
*/
-__printf(3, 4)
-void ___drm_dbg(struct _ddebug *desc, enum drm_debug_category category, const char *format, ...);
__printf(1, 2)
void __drm_err(const char *format, ...);
#if !defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
-#define __drm_dbg(cat, fmt, ...) ___drm_dbg(NULL, cat, fmt, ##__VA_ARGS__)
+#define __drm_dbg(cat, fmt, ...) __drm_dev_dbg(NULL, NULL, cat, fmt, ##__VA_ARGS__)
#else
#define __drm_dbg(cat, fmt, ...) \
- _dynamic_func_call_cls(cat, fmt, ___drm_dbg, \
- cat, fmt, ##__VA_ARGS__)
+ _dynamic_func_call_cls(cat, fmt, __drm_dev_dbg, \
+ NULL, cat, fmt, ##__VA_ARGS__)
#endif
/* Macros to make printk easier */
@@ -632,12 +632,12 @@ void __drm_err(const char *format, ...);
/* Helper for struct drm_device based WARNs */
#define drm_WARN(drm, condition, format, arg...) \
- WARN(condition, "%s %s: " format, \
+ WARN(condition, "%s %s: [drm] " format, \
dev_driver_string((drm)->dev), \
dev_name((drm)->dev), ## arg)
#define drm_WARN_ONCE(drm, condition, format, arg...) \
- WARN_ONCE(condition, "%s %s: " format, \
+ WARN_ONCE(condition, "%s %s: [drm] " format, \
dev_driver_string((drm)->dev), \
dev_name((drm)->dev), ## arg)
diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h
deleted file mode 100644
index 85ce33ad6e26..000000000000
--- a/include/drm/i915_pciids.h
+++ /dev/null
@@ -1,767 +0,0 @@
-/*
- * Copyright 2013 Intel Corporation
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-#ifndef _I915_PCIIDS_H
-#define _I915_PCIIDS_H
-
-/*
- * A pci_device_id struct {
- * __u32 vendor, device;
- * __u32 subvendor, subdevice;
- * __u32 class, class_mask;
- * kernel_ulong_t driver_data;
- * };
- * Don't use C99 here because "class" is reserved and we want to
- * give userspace flexibility.
- */
-#define INTEL_VGA_DEVICE(id, info) { \
- 0x8086, id, \
- ~0, ~0, \
- 0x030000, 0xff0000, \
- (unsigned long) info }
-
-#define INTEL_QUANTA_VGA_DEVICE(info) { \
- 0x8086, 0x16a, \
- 0x152d, 0x8990, \
- 0x030000, 0xff0000, \
- (unsigned long) info }
-
-#define INTEL_I810_IDS(info) \
- INTEL_VGA_DEVICE(0x7121, info), /* I810 */ \
- INTEL_VGA_DEVICE(0x7123, info), /* I810_DC100 */ \
- INTEL_VGA_DEVICE(0x7125, info) /* I810_E */
-
-#define INTEL_I815_IDS(info) \
- INTEL_VGA_DEVICE(0x1132, info) /* I815*/
-
-#define INTEL_I830_IDS(info) \
- INTEL_VGA_DEVICE(0x3577, info)
-
-#define INTEL_I845G_IDS(info) \
- INTEL_VGA_DEVICE(0x2562, info)
-
-#define INTEL_I85X_IDS(info) \
- INTEL_VGA_DEVICE(0x3582, info), /* I855_GM */ \
- INTEL_VGA_DEVICE(0x358e, info)
-
-#define INTEL_I865G_IDS(info) \
- INTEL_VGA_DEVICE(0x2572, info) /* I865_G */
-
-#define INTEL_I915G_IDS(info) \
- INTEL_VGA_DEVICE(0x2582, info), /* I915_G */ \
- INTEL_VGA_DEVICE(0x258a, info) /* E7221_G */
-
-#define INTEL_I915GM_IDS(info) \
- INTEL_VGA_DEVICE(0x2592, info) /* I915_GM */
-
-#define INTEL_I945G_IDS(info) \
- INTEL_VGA_DEVICE(0x2772, info) /* I945_G */
-
-#define INTEL_I945GM_IDS(info) \
- INTEL_VGA_DEVICE(0x27a2, info), /* I945_GM */ \
- INTEL_VGA_DEVICE(0x27ae, info) /* I945_GME */
-
-#define INTEL_I965G_IDS(info) \
- INTEL_VGA_DEVICE(0x2972, info), /* I946_GZ */ \
- INTEL_VGA_DEVICE(0x2982, info), /* G35_G */ \
- INTEL_VGA_DEVICE(0x2992, info), /* I965_Q */ \
- INTEL_VGA_DEVICE(0x29a2, info) /* I965_G */
-
-#define INTEL_G33_IDS(info) \
- INTEL_VGA_DEVICE(0x29b2, info), /* Q35_G */ \
- INTEL_VGA_DEVICE(0x29c2, info), /* G33_G */ \
- INTEL_VGA_DEVICE(0x29d2, info) /* Q33_G */
-
-#define INTEL_I965GM_IDS(info) \
- INTEL_VGA_DEVICE(0x2a02, info), /* I965_GM */ \
- INTEL_VGA_DEVICE(0x2a12, info) /* I965_GME */
-
-#define INTEL_GM45_IDS(info) \
- INTEL_VGA_DEVICE(0x2a42, info) /* GM45_G */
-
-#define INTEL_G45_IDS(info) \
- INTEL_VGA_DEVICE(0x2e02, info), /* IGD_E_G */ \
- INTEL_VGA_DEVICE(0x2e12, info), /* Q45_G */ \
- INTEL_VGA_DEVICE(0x2e22, info), /* G45_G */ \
- INTEL_VGA_DEVICE(0x2e32, info), /* G41_G */ \
- INTEL_VGA_DEVICE(0x2e42, info), /* B43_G */ \
- INTEL_VGA_DEVICE(0x2e92, info) /* B43_G.1 */
-
-#define INTEL_PINEVIEW_G_IDS(info) \
- INTEL_VGA_DEVICE(0xa001, info)
-
-#define INTEL_PINEVIEW_M_IDS(info) \
- INTEL_VGA_DEVICE(0xa011, info)
-
-#define INTEL_IRONLAKE_D_IDS(info) \
- INTEL_VGA_DEVICE(0x0042, info)
-
-#define INTEL_IRONLAKE_M_IDS(info) \
- INTEL_VGA_DEVICE(0x0046, info)
-
-#define INTEL_SNB_D_GT1_IDS(info) \
- INTEL_VGA_DEVICE(0x0102, info), \
- INTEL_VGA_DEVICE(0x010A, info)
-
-#define INTEL_SNB_D_GT2_IDS(info) \
- INTEL_VGA_DEVICE(0x0112, info), \
- INTEL_VGA_DEVICE(0x0122, info)
-
-#define INTEL_SNB_D_IDS(info) \
- INTEL_SNB_D_GT1_IDS(info), \
- INTEL_SNB_D_GT2_IDS(info)
-
-#define INTEL_SNB_M_GT1_IDS(info) \
- INTEL_VGA_DEVICE(0x0106, info)
-
-#define INTEL_SNB_M_GT2_IDS(info) \
- INTEL_VGA_DEVICE(0x0116, info), \
- INTEL_VGA_DEVICE(0x0126, info)
-
-#define INTEL_SNB_M_IDS(info) \
- INTEL_SNB_M_GT1_IDS(info), \
- INTEL_SNB_M_GT2_IDS(info)
-
-#define INTEL_IVB_M_GT1_IDS(info) \
- INTEL_VGA_DEVICE(0x0156, info) /* GT1 mobile */
-
-#define INTEL_IVB_M_GT2_IDS(info) \
- INTEL_VGA_DEVICE(0x0166, info) /* GT2 mobile */
-
-#define INTEL_IVB_M_IDS(info) \
- INTEL_IVB_M_GT1_IDS(info), \
- INTEL_IVB_M_GT2_IDS(info)
-
-#define INTEL_IVB_D_GT1_IDS(info) \
- INTEL_VGA_DEVICE(0x0152, info), /* GT1 desktop */ \
- INTEL_VGA_DEVICE(0x015a, info) /* GT1 server */
-
-#define INTEL_IVB_D_GT2_IDS(info) \
- INTEL_VGA_DEVICE(0x0162, info), /* GT2 desktop */ \
- INTEL_VGA_DEVICE(0x016a, info) /* GT2 server */
-
-#define INTEL_IVB_D_IDS(info) \
- INTEL_IVB_D_GT1_IDS(info), \
- INTEL_IVB_D_GT2_IDS(info)
-
-#define INTEL_IVB_Q_IDS(info) \
- INTEL_QUANTA_VGA_DEVICE(info) /* Quanta transcode */
-
-#define INTEL_HSW_ULT_GT1_IDS(info) \
- INTEL_VGA_DEVICE(0x0A02, info), /* ULT GT1 desktop */ \
- INTEL_VGA_DEVICE(0x0A06, info), /* ULT GT1 mobile */ \
- INTEL_VGA_DEVICE(0x0A0A, info), /* ULT GT1 server */ \
- INTEL_VGA_DEVICE(0x0A0B, info) /* ULT GT1 reserved */
-
-#define INTEL_HSW_ULX_GT1_IDS(info) \
- INTEL_VGA_DEVICE(0x0A0E, info) /* ULX GT1 mobile */
-
-#define INTEL_HSW_GT1_IDS(info) \
- INTEL_HSW_ULT_GT1_IDS(info), \
- INTEL_HSW_ULX_GT1_IDS(info), \
- INTEL_VGA_DEVICE(0x0402, info), /* GT1 desktop */ \
- INTEL_VGA_DEVICE(0x0406, info), /* GT1 mobile */ \
- INTEL_VGA_DEVICE(0x040A, info), /* GT1 server */ \
- INTEL_VGA_DEVICE(0x040B, info), /* GT1 reserved */ \
- INTEL_VGA_DEVICE(0x040E, info), /* GT1 reserved */ \
- INTEL_VGA_DEVICE(0x0C02, info), /* SDV GT1 desktop */ \
- INTEL_VGA_DEVICE(0x0C06, info), /* SDV GT1 mobile */ \
- INTEL_VGA_DEVICE(0x0C0A, info), /* SDV GT1 server */ \
- INTEL_VGA_DEVICE(0x0C0B, info), /* SDV GT1 reserved */ \
- INTEL_VGA_DEVICE(0x0C0E, info), /* SDV GT1 reserved */ \
- INTEL_VGA_DEVICE(0x0D02, info), /* CRW GT1 desktop */ \
- INTEL_VGA_DEVICE(0x0D06, info), /* CRW GT1 mobile */ \
- INTEL_VGA_DEVICE(0x0D0A, info), /* CRW GT1 server */ \
- INTEL_VGA_DEVICE(0x0D0B, info), /* CRW GT1 reserved */ \
- INTEL_VGA_DEVICE(0x0D0E, info) /* CRW GT1 reserved */
-
-#define INTEL_HSW_ULT_GT2_IDS(info) \
- INTEL_VGA_DEVICE(0x0A12, info), /* ULT GT2 desktop */ \
- INTEL_VGA_DEVICE(0x0A16, info), /* ULT GT2 mobile */ \
- INTEL_VGA_DEVICE(0x0A1A, info), /* ULT GT2 server */ \
- INTEL_VGA_DEVICE(0x0A1B, info) /* ULT GT2 reserved */ \
-
-#define INTEL_HSW_ULX_GT2_IDS(info) \
- INTEL_VGA_DEVICE(0x0A1E, info) /* ULX GT2 mobile */ \
-
-#define INTEL_HSW_GT2_IDS(info) \
- INTEL_HSW_ULT_GT2_IDS(info), \
- INTEL_HSW_ULX_GT2_IDS(info), \
- INTEL_VGA_DEVICE(0x0412, info), /* GT2 desktop */ \
- INTEL_VGA_DEVICE(0x0416, info), /* GT2 mobile */ \
- INTEL_VGA_DEVICE(0x041A, info), /* GT2 server */ \
- INTEL_VGA_DEVICE(0x041B, info), /* GT2 reserved */ \
- INTEL_VGA_DEVICE(0x041E, info), /* GT2 reserved */ \
- INTEL_VGA_DEVICE(0x0C12, info), /* SDV GT2 desktop */ \
- INTEL_VGA_DEVICE(0x0C16, info), /* SDV GT2 mobile */ \
- INTEL_VGA_DEVICE(0x0C1A, info), /* SDV GT2 server */ \
- INTEL_VGA_DEVICE(0x0C1B, info), /* SDV GT2 reserved */ \
- INTEL_VGA_DEVICE(0x0C1E, info), /* SDV GT2 reserved */ \
- INTEL_VGA_DEVICE(0x0D12, info), /* CRW GT2 desktop */ \
- INTEL_VGA_DEVICE(0x0D16, info), /* CRW GT2 mobile */ \
- INTEL_VGA_DEVICE(0x0D1A, info), /* CRW GT2 server */ \
- INTEL_VGA_DEVICE(0x0D1B, info), /* CRW GT2 reserved */ \
- INTEL_VGA_DEVICE(0x0D1E, info) /* CRW GT2 reserved */
-
-#define INTEL_HSW_ULT_GT3_IDS(info) \
- INTEL_VGA_DEVICE(0x0A22, info), /* ULT GT3 desktop */ \
- INTEL_VGA_DEVICE(0x0A26, info), /* ULT GT3 mobile */ \
- INTEL_VGA_DEVICE(0x0A2A, info), /* ULT GT3 server */ \
- INTEL_VGA_DEVICE(0x0A2B, info), /* ULT GT3 reserved */ \
- INTEL_VGA_DEVICE(0x0A2E, info) /* ULT GT3 reserved */
-
-#define INTEL_HSW_GT3_IDS(info) \
- INTEL_HSW_ULT_GT3_IDS(info), \
- INTEL_VGA_DEVICE(0x0422, info), /* GT3 desktop */ \
- INTEL_VGA_DEVICE(0x0426, info), /* GT3 mobile */ \
- INTEL_VGA_DEVICE(0x042A, info), /* GT3 server */ \
- INTEL_VGA_DEVICE(0x042B, info), /* GT3 reserved */ \
- INTEL_VGA_DEVICE(0x042E, info), /* GT3 reserved */ \
- INTEL_VGA_DEVICE(0x0C22, info), /* SDV GT3 desktop */ \
- INTEL_VGA_DEVICE(0x0C26, info), /* SDV GT3 mobile */ \
- INTEL_VGA_DEVICE(0x0C2A, info), /* SDV GT3 server */ \
- INTEL_VGA_DEVICE(0x0C2B, info), /* SDV GT3 reserved */ \
- INTEL_VGA_DEVICE(0x0C2E, info), /* SDV GT3 reserved */ \
- INTEL_VGA_DEVICE(0x0D22, info), /* CRW GT3 desktop */ \
- INTEL_VGA_DEVICE(0x0D26, info), /* CRW GT3 mobile */ \
- INTEL_VGA_DEVICE(0x0D2A, info), /* CRW GT3 server */ \
- INTEL_VGA_DEVICE(0x0D2B, info), /* CRW GT3 reserved */ \
- INTEL_VGA_DEVICE(0x0D2E, info) /* CRW GT3 reserved */
-
-#define INTEL_HSW_IDS(info) \
- INTEL_HSW_GT1_IDS(info), \
- INTEL_HSW_GT2_IDS(info), \
- INTEL_HSW_GT3_IDS(info)
-
-#define INTEL_VLV_IDS(info) \
- INTEL_VGA_DEVICE(0x0f30, info), \
- INTEL_VGA_DEVICE(0x0f31, info), \
- INTEL_VGA_DEVICE(0x0f32, info), \
- INTEL_VGA_DEVICE(0x0f33, info)
-
-#define INTEL_BDW_ULT_GT1_IDS(info) \
- INTEL_VGA_DEVICE(0x1606, info), /* GT1 ULT */ \
- INTEL_VGA_DEVICE(0x160B, info) /* GT1 Iris */
-
-#define INTEL_BDW_ULX_GT1_IDS(info) \
- INTEL_VGA_DEVICE(0x160E, info) /* GT1 ULX */
-
-#define INTEL_BDW_GT1_IDS(info) \
- INTEL_BDW_ULT_GT1_IDS(info), \
- INTEL_BDW_ULX_GT1_IDS(info), \
- INTEL_VGA_DEVICE(0x1602, info), /* GT1 ULT */ \
- INTEL_VGA_DEVICE(0x160A, info), /* GT1 Server */ \
- INTEL_VGA_DEVICE(0x160D, info) /* GT1 Workstation */
-
-#define INTEL_BDW_ULT_GT2_IDS(info) \
- INTEL_VGA_DEVICE(0x1616, info), /* GT2 ULT */ \
- INTEL_VGA_DEVICE(0x161B, info) /* GT2 ULT */
-
-#define INTEL_BDW_ULX_GT2_IDS(info) \
- INTEL_VGA_DEVICE(0x161E, info) /* GT2 ULX */
-
-#define INTEL_BDW_GT2_IDS(info) \
- INTEL_BDW_ULT_GT2_IDS(info), \
- INTEL_BDW_ULX_GT2_IDS(info), \
- INTEL_VGA_DEVICE(0x1612, info), /* GT2 Halo */ \
- INTEL_VGA_DEVICE(0x161A, info), /* GT2 Server */ \
- INTEL_VGA_DEVICE(0x161D, info) /* GT2 Workstation */
-
-#define INTEL_BDW_ULT_GT3_IDS(info) \
- INTEL_VGA_DEVICE(0x1626, info), /* ULT */ \
- INTEL_VGA_DEVICE(0x162B, info) /* Iris */ \
-
-#define INTEL_BDW_ULX_GT3_IDS(info) \
- INTEL_VGA_DEVICE(0x162E, info) /* ULX */
-
-#define INTEL_BDW_GT3_IDS(info) \
- INTEL_BDW_ULT_GT3_IDS(info), \
- INTEL_BDW_ULX_GT3_IDS(info), \
- INTEL_VGA_DEVICE(0x1622, info), /* ULT */ \
- INTEL_VGA_DEVICE(0x162A, info), /* Server */ \
- INTEL_VGA_DEVICE(0x162D, info) /* Workstation */
-
-#define INTEL_BDW_ULT_RSVD_IDS(info) \
- INTEL_VGA_DEVICE(0x1636, info), /* ULT */ \
- INTEL_VGA_DEVICE(0x163B, info) /* Iris */
-
-#define INTEL_BDW_ULX_RSVD_IDS(info) \
- INTEL_VGA_DEVICE(0x163E, info) /* ULX */
-
-#define INTEL_BDW_RSVD_IDS(info) \
- INTEL_BDW_ULT_RSVD_IDS(info), \
- INTEL_BDW_ULX_RSVD_IDS(info), \
- INTEL_VGA_DEVICE(0x1632, info), /* ULT */ \
- INTEL_VGA_DEVICE(0x163A, info), /* Server */ \
- INTEL_VGA_DEVICE(0x163D, info) /* Workstation */
-
-#define INTEL_BDW_IDS(info) \
- INTEL_BDW_GT1_IDS(info), \
- INTEL_BDW_GT2_IDS(info), \
- INTEL_BDW_GT3_IDS(info), \
- INTEL_BDW_RSVD_IDS(info)
-
-#define INTEL_CHV_IDS(info) \
- INTEL_VGA_DEVICE(0x22b0, info), \
- INTEL_VGA_DEVICE(0x22b1, info), \
- INTEL_VGA_DEVICE(0x22b2, info), \
- INTEL_VGA_DEVICE(0x22b3, info)
-
-#define INTEL_SKL_ULT_GT1_IDS(info) \
- INTEL_VGA_DEVICE(0x1906, info), /* ULT GT1 */ \
- INTEL_VGA_DEVICE(0x1913, info) /* ULT GT1.5 */
-
-#define INTEL_SKL_ULX_GT1_IDS(info) \
- INTEL_VGA_DEVICE(0x190E, info), /* ULX GT1 */ \
- INTEL_VGA_DEVICE(0x1915, info) /* ULX GT1.5 */
-
-#define INTEL_SKL_GT1_IDS(info) \
- INTEL_SKL_ULT_GT1_IDS(info), \
- INTEL_SKL_ULX_GT1_IDS(info), \
- INTEL_VGA_DEVICE(0x1902, info), /* DT GT1 */ \
- INTEL_VGA_DEVICE(0x190A, info), /* SRV GT1 */ \
- INTEL_VGA_DEVICE(0x190B, info), /* Halo GT1 */ \
- INTEL_VGA_DEVICE(0x1917, info) /* DT GT1.5 */
-
-#define INTEL_SKL_ULT_GT2_IDS(info) \
- INTEL_VGA_DEVICE(0x1916, info), /* ULT GT2 */ \
- INTEL_VGA_DEVICE(0x1921, info) /* ULT GT2F */
-
-#define INTEL_SKL_ULX_GT2_IDS(info) \
- INTEL_VGA_DEVICE(0x191E, info) /* ULX GT2 */
-
-#define INTEL_SKL_GT2_IDS(info) \
- INTEL_SKL_ULT_GT2_IDS(info), \
- INTEL_SKL_ULX_GT2_IDS(info), \
- INTEL_VGA_DEVICE(0x1912, info), /* DT GT2 */ \
- INTEL_VGA_DEVICE(0x191A, info), /* SRV GT2 */ \
- INTEL_VGA_DEVICE(0x191B, info), /* Halo GT2 */ \
- INTEL_VGA_DEVICE(0x191D, info) /* WKS GT2 */
-
-#define INTEL_SKL_ULT_GT3_IDS(info) \
- INTEL_VGA_DEVICE(0x1923, info), /* ULT GT3 */ \
- INTEL_VGA_DEVICE(0x1926, info), /* ULT GT3e */ \
- INTEL_VGA_DEVICE(0x1927, info) /* ULT GT3e */
-
-#define INTEL_SKL_GT3_IDS(info) \
- INTEL_SKL_ULT_GT3_IDS(info), \
- INTEL_VGA_DEVICE(0x192A, info), /* SRV GT3 */ \
- INTEL_VGA_DEVICE(0x192B, info), /* Halo GT3e */ \
- INTEL_VGA_DEVICE(0x192D, info) /* SRV GT3e */
-
-#define INTEL_SKL_GT4_IDS(info) \
- INTEL_VGA_DEVICE(0x1932, info), /* DT GT4 */ \
- INTEL_VGA_DEVICE(0x193A, info), /* SRV GT4e */ \
- INTEL_VGA_DEVICE(0x193B, info), /* Halo GT4e */ \
- INTEL_VGA_DEVICE(0x193D, info) /* WKS GT4e */
-
-#define INTEL_SKL_IDS(info) \
- INTEL_SKL_GT1_IDS(info), \
- INTEL_SKL_GT2_IDS(info), \
- INTEL_SKL_GT3_IDS(info), \
- INTEL_SKL_GT4_IDS(info)
-
-#define INTEL_BXT_IDS(info) \
- INTEL_VGA_DEVICE(0x0A84, info), \
- INTEL_VGA_DEVICE(0x1A84, info), \
- INTEL_VGA_DEVICE(0x1A85, info), \
- INTEL_VGA_DEVICE(0x5A84, info), /* APL HD Graphics 505 */ \
- INTEL_VGA_DEVICE(0x5A85, info) /* APL HD Graphics 500 */
-
-#define INTEL_GLK_IDS(info) \
- INTEL_VGA_DEVICE(0x3184, info), \
- INTEL_VGA_DEVICE(0x3185, info)
-
-#define INTEL_KBL_ULT_GT1_IDS(info) \
- INTEL_VGA_DEVICE(0x5906, info), /* ULT GT1 */ \
- INTEL_VGA_DEVICE(0x5913, info) /* ULT GT1.5 */
-
-#define INTEL_KBL_ULX_GT1_IDS(info) \
- INTEL_VGA_DEVICE(0x590E, info), /* ULX GT1 */ \
- INTEL_VGA_DEVICE(0x5915, info) /* ULX GT1.5 */
-
-#define INTEL_KBL_GT1_IDS(info) \
- INTEL_KBL_ULT_GT1_IDS(info), \
- INTEL_KBL_ULX_GT1_IDS(info), \
- INTEL_VGA_DEVICE(0x5902, info), /* DT GT1 */ \
- INTEL_VGA_DEVICE(0x5908, info), /* Halo GT1 */ \
- INTEL_VGA_DEVICE(0x590A, info), /* SRV GT1 */ \
- INTEL_VGA_DEVICE(0x590B, info) /* Halo GT1 */
-
-#define INTEL_KBL_ULT_GT2_IDS(info) \
- INTEL_VGA_DEVICE(0x5916, info), /* ULT GT2 */ \
- INTEL_VGA_DEVICE(0x5921, info) /* ULT GT2F */
-
-#define INTEL_KBL_ULX_GT2_IDS(info) \
- INTEL_VGA_DEVICE(0x591E, info) /* ULX GT2 */
-
-#define INTEL_KBL_GT2_IDS(info) \
- INTEL_KBL_ULT_GT2_IDS(info), \
- INTEL_KBL_ULX_GT2_IDS(info), \
- INTEL_VGA_DEVICE(0x5912, info), /* DT GT2 */ \
- INTEL_VGA_DEVICE(0x5917, info), /* Mobile GT2 */ \
- INTEL_VGA_DEVICE(0x591A, info), /* SRV GT2 */ \
- INTEL_VGA_DEVICE(0x591B, info), /* Halo GT2 */ \
- INTEL_VGA_DEVICE(0x591D, info) /* WKS GT2 */
-
-#define INTEL_KBL_ULT_GT3_IDS(info) \
- INTEL_VGA_DEVICE(0x5926, info) /* ULT GT3 */
-
-#define INTEL_KBL_GT3_IDS(info) \
- INTEL_KBL_ULT_GT3_IDS(info), \
- INTEL_VGA_DEVICE(0x5923, info), /* ULT GT3 */ \
- INTEL_VGA_DEVICE(0x5927, info) /* ULT GT3 */
-
-#define INTEL_KBL_GT4_IDS(info) \
- INTEL_VGA_DEVICE(0x593B, info) /* Halo GT4 */
-
-/* AML/KBL Y GT2 */
-#define INTEL_AML_KBL_GT2_IDS(info) \
- INTEL_VGA_DEVICE(0x591C, info), /* ULX GT2 */ \
- INTEL_VGA_DEVICE(0x87C0, info) /* ULX GT2 */
-
-/* AML/CFL Y GT2 */
-#define INTEL_AML_CFL_GT2_IDS(info) \
- INTEL_VGA_DEVICE(0x87CA, info)
-
-/* CML GT1 */
-#define INTEL_CML_GT1_IDS(info) \
- INTEL_VGA_DEVICE(0x9BA2, info), \
- INTEL_VGA_DEVICE(0x9BA4, info), \
- INTEL_VGA_DEVICE(0x9BA5, info), \
- INTEL_VGA_DEVICE(0x9BA8, info)
-
-#define INTEL_CML_U_GT1_IDS(info) \
- INTEL_VGA_DEVICE(0x9B21, info), \
- INTEL_VGA_DEVICE(0x9BAA, info), \
- INTEL_VGA_DEVICE(0x9BAC, info)
-
-/* CML GT2 */
-#define INTEL_CML_GT2_IDS(info) \
- INTEL_VGA_DEVICE(0x9BC2, info), \
- INTEL_VGA_DEVICE(0x9BC4, info), \
- INTEL_VGA_DEVICE(0x9BC5, info), \
- INTEL_VGA_DEVICE(0x9BC6, info), \
- INTEL_VGA_DEVICE(0x9BC8, info), \
- INTEL_VGA_DEVICE(0x9BE6, info), \
- INTEL_VGA_DEVICE(0x9BF6, info)
-
-#define INTEL_CML_U_GT2_IDS(info) \
- INTEL_VGA_DEVICE(0x9B41, info), \
- INTEL_VGA_DEVICE(0x9BCA, info), \
- INTEL_VGA_DEVICE(0x9BCC, info)
-
-#define INTEL_KBL_IDS(info) \
- INTEL_KBL_GT1_IDS(info), \
- INTEL_KBL_GT2_IDS(info), \
- INTEL_KBL_GT3_IDS(info), \
- INTEL_KBL_GT4_IDS(info), \
- INTEL_AML_KBL_GT2_IDS(info)
-
-/* CFL S */
-#define INTEL_CFL_S_GT1_IDS(info) \
- INTEL_VGA_DEVICE(0x3E90, info), /* SRV GT1 */ \
- INTEL_VGA_DEVICE(0x3E93, info), /* SRV GT1 */ \
- INTEL_VGA_DEVICE(0x3E99, info) /* SRV GT1 */
-
-#define INTEL_CFL_S_GT2_IDS(info) \
- INTEL_VGA_DEVICE(0x3E91, info), /* SRV GT2 */ \
- INTEL_VGA_DEVICE(0x3E92, info), /* SRV GT2 */ \
- INTEL_VGA_DEVICE(0x3E96, info), /* SRV GT2 */ \
- INTEL_VGA_DEVICE(0x3E98, info), /* SRV GT2 */ \
- INTEL_VGA_DEVICE(0x3E9A, info) /* SRV GT2 */
-
-/* CFL H */
-#define INTEL_CFL_H_GT1_IDS(info) \
- INTEL_VGA_DEVICE(0x3E9C, info)
-
-#define INTEL_CFL_H_GT2_IDS(info) \
- INTEL_VGA_DEVICE(0x3E94, info), /* Halo GT2 */ \
- INTEL_VGA_DEVICE(0x3E9B, info) /* Halo GT2 */
-
-/* CFL U GT2 */
-#define INTEL_CFL_U_GT2_IDS(info) \
- INTEL_VGA_DEVICE(0x3EA9, info)
-
-/* CFL U GT3 */
-#define INTEL_CFL_U_GT3_IDS(info) \
- INTEL_VGA_DEVICE(0x3EA5, info), /* ULT GT3 */ \
- INTEL_VGA_DEVICE(0x3EA6, info), /* ULT GT3 */ \
- INTEL_VGA_DEVICE(0x3EA7, info), /* ULT GT3 */ \
- INTEL_VGA_DEVICE(0x3EA8, info) /* ULT GT3 */
-
-/* WHL/CFL U GT1 */
-#define INTEL_WHL_U_GT1_IDS(info) \
- INTEL_VGA_DEVICE(0x3EA1, info), \
- INTEL_VGA_DEVICE(0x3EA4, info)
-
-/* WHL/CFL U GT2 */
-#define INTEL_WHL_U_GT2_IDS(info) \
- INTEL_VGA_DEVICE(0x3EA0, info), \
- INTEL_VGA_DEVICE(0x3EA3, info)
-
-/* WHL/CFL U GT3 */
-#define INTEL_WHL_U_GT3_IDS(info) \
- INTEL_VGA_DEVICE(0x3EA2, info)
-
-#define INTEL_CFL_IDS(info) \
- INTEL_CFL_S_GT1_IDS(info), \
- INTEL_CFL_S_GT2_IDS(info), \
- INTEL_CFL_H_GT1_IDS(info), \
- INTEL_CFL_H_GT2_IDS(info), \
- INTEL_CFL_U_GT2_IDS(info), \
- INTEL_CFL_U_GT3_IDS(info), \
- INTEL_WHL_U_GT1_IDS(info), \
- INTEL_WHL_U_GT2_IDS(info), \
- INTEL_WHL_U_GT3_IDS(info), \
- INTEL_AML_CFL_GT2_IDS(info), \
- INTEL_CML_GT1_IDS(info), \
- INTEL_CML_GT2_IDS(info), \
- INTEL_CML_U_GT1_IDS(info), \
- INTEL_CML_U_GT2_IDS(info)
-
-/* CNL */
-#define INTEL_CNL_PORT_F_IDS(info) \
- INTEL_VGA_DEVICE(0x5A44, info), \
- INTEL_VGA_DEVICE(0x5A4C, info), \
- INTEL_VGA_DEVICE(0x5A54, info), \
- INTEL_VGA_DEVICE(0x5A5C, info)
-
-#define INTEL_CNL_IDS(info) \
- INTEL_CNL_PORT_F_IDS(info), \
- INTEL_VGA_DEVICE(0x5A40, info), \
- INTEL_VGA_DEVICE(0x5A41, info), \
- INTEL_VGA_DEVICE(0x5A42, info), \
- INTEL_VGA_DEVICE(0x5A49, info), \
- INTEL_VGA_DEVICE(0x5A4A, info), \
- INTEL_VGA_DEVICE(0x5A50, info), \
- INTEL_VGA_DEVICE(0x5A51, info), \
- INTEL_VGA_DEVICE(0x5A52, info), \
- INTEL_VGA_DEVICE(0x5A59, info), \
- INTEL_VGA_DEVICE(0x5A5A, info)
-
-/* ICL */
-#define INTEL_ICL_PORT_F_IDS(info) \
- INTEL_VGA_DEVICE(0x8A50, info), \
- INTEL_VGA_DEVICE(0x8A52, info), \
- INTEL_VGA_DEVICE(0x8A53, info), \
- INTEL_VGA_DEVICE(0x8A54, info), \
- INTEL_VGA_DEVICE(0x8A56, info), \
- INTEL_VGA_DEVICE(0x8A57, info), \
- INTEL_VGA_DEVICE(0x8A58, info), \
- INTEL_VGA_DEVICE(0x8A59, info), \
- INTEL_VGA_DEVICE(0x8A5A, info), \
- INTEL_VGA_DEVICE(0x8A5B, info), \
- INTEL_VGA_DEVICE(0x8A5C, info), \
- INTEL_VGA_DEVICE(0x8A70, info), \
- INTEL_VGA_DEVICE(0x8A71, info)
-
-#define INTEL_ICL_11_IDS(info) \
- INTEL_ICL_PORT_F_IDS(info), \
- INTEL_VGA_DEVICE(0x8A51, info), \
- INTEL_VGA_DEVICE(0x8A5D, info)
-
-/* EHL */
-#define INTEL_EHL_IDS(info) \
- INTEL_VGA_DEVICE(0x4541, info), \
- INTEL_VGA_DEVICE(0x4551, info), \
- INTEL_VGA_DEVICE(0x4555, info), \
- INTEL_VGA_DEVICE(0x4557, info), \
- INTEL_VGA_DEVICE(0x4570, info), \
- INTEL_VGA_DEVICE(0x4571, info)
-
-/* JSL */
-#define INTEL_JSL_IDS(info) \
- INTEL_VGA_DEVICE(0x4E51, info), \
- INTEL_VGA_DEVICE(0x4E55, info), \
- INTEL_VGA_DEVICE(0x4E57, info), \
- INTEL_VGA_DEVICE(0x4E61, info), \
- INTEL_VGA_DEVICE(0x4E71, info)
-
-/* TGL */
-#define INTEL_TGL_12_GT1_IDS(info) \
- INTEL_VGA_DEVICE(0x9A60, info), \
- INTEL_VGA_DEVICE(0x9A68, info), \
- INTEL_VGA_DEVICE(0x9A70, info)
-
-#define INTEL_TGL_12_GT2_IDS(info) \
- INTEL_VGA_DEVICE(0x9A40, info), \
- INTEL_VGA_DEVICE(0x9A49, info), \
- INTEL_VGA_DEVICE(0x9A59, info), \
- INTEL_VGA_DEVICE(0x9A78, info), \
- INTEL_VGA_DEVICE(0x9AC0, info), \
- INTEL_VGA_DEVICE(0x9AC9, info), \
- INTEL_VGA_DEVICE(0x9AD9, info), \
- INTEL_VGA_DEVICE(0x9AF8, info)
-
-#define INTEL_TGL_12_IDS(info) \
- INTEL_TGL_12_GT1_IDS(info), \
- INTEL_TGL_12_GT2_IDS(info)
-
-/* RKL */
-#define INTEL_RKL_IDS(info) \
- INTEL_VGA_DEVICE(0x4C80, info), \
- INTEL_VGA_DEVICE(0x4C8A, info), \
- INTEL_VGA_DEVICE(0x4C8B, info), \
- INTEL_VGA_DEVICE(0x4C8C, info), \
- INTEL_VGA_DEVICE(0x4C90, info), \
- INTEL_VGA_DEVICE(0x4C9A, info)
-
-/* DG1 */
-#define INTEL_DG1_IDS(info) \
- INTEL_VGA_DEVICE(0x4905, info), \
- INTEL_VGA_DEVICE(0x4906, info), \
- INTEL_VGA_DEVICE(0x4907, info), \
- INTEL_VGA_DEVICE(0x4908, info), \
- INTEL_VGA_DEVICE(0x4909, info)
-
-/* ADL-S */
-#define INTEL_ADLS_IDS(info) \
- INTEL_VGA_DEVICE(0x4680, info), \
- INTEL_VGA_DEVICE(0x4682, info), \
- INTEL_VGA_DEVICE(0x4688, info), \
- INTEL_VGA_DEVICE(0x468A, info), \
- INTEL_VGA_DEVICE(0x468B, info), \
- INTEL_VGA_DEVICE(0x4690, info), \
- INTEL_VGA_DEVICE(0x4692, info), \
- INTEL_VGA_DEVICE(0x4693, info)
-
-/* ADL-P */
-#define INTEL_ADLP_IDS(info) \
- INTEL_VGA_DEVICE(0x46A0, info), \
- INTEL_VGA_DEVICE(0x46A1, info), \
- INTEL_VGA_DEVICE(0x46A2, info), \
- INTEL_VGA_DEVICE(0x46A3, info), \
- INTEL_VGA_DEVICE(0x46A6, info), \
- INTEL_VGA_DEVICE(0x46A8, info), \
- INTEL_VGA_DEVICE(0x46AA, info), \
- INTEL_VGA_DEVICE(0x462A, info), \
- INTEL_VGA_DEVICE(0x4626, info), \
- INTEL_VGA_DEVICE(0x4628, info), \
- INTEL_VGA_DEVICE(0x46B0, info), \
- INTEL_VGA_DEVICE(0x46B1, info), \
- INTEL_VGA_DEVICE(0x46B2, info), \
- INTEL_VGA_DEVICE(0x46B3, info), \
- INTEL_VGA_DEVICE(0x46C0, info), \
- INTEL_VGA_DEVICE(0x46C1, info), \
- INTEL_VGA_DEVICE(0x46C2, info), \
- INTEL_VGA_DEVICE(0x46C3, info)
-
-/* ADL-N */
-#define INTEL_ADLN_IDS(info) \
- INTEL_VGA_DEVICE(0x46D0, info), \
- INTEL_VGA_DEVICE(0x46D1, info), \
- INTEL_VGA_DEVICE(0x46D2, info), \
- INTEL_VGA_DEVICE(0x46D3, info), \
- INTEL_VGA_DEVICE(0x46D4, info)
-
-/* RPL-S */
-#define INTEL_RPLS_IDS(info) \
- INTEL_VGA_DEVICE(0xA780, info), \
- INTEL_VGA_DEVICE(0xA781, info), \
- INTEL_VGA_DEVICE(0xA782, info), \
- INTEL_VGA_DEVICE(0xA783, info), \
- INTEL_VGA_DEVICE(0xA788, info), \
- INTEL_VGA_DEVICE(0xA789, info), \
- INTEL_VGA_DEVICE(0xA78A, info), \
- INTEL_VGA_DEVICE(0xA78B, info)
-
-/* RPL-U */
-#define INTEL_RPLU_IDS(info) \
- INTEL_VGA_DEVICE(0xA721, info), \
- INTEL_VGA_DEVICE(0xA7A1, info), \
- INTEL_VGA_DEVICE(0xA7A9, info), \
- INTEL_VGA_DEVICE(0xA7AC, info), \
- INTEL_VGA_DEVICE(0xA7AD, info)
-
-/* RPL-P */
-#define INTEL_RPLP_IDS(info) \
- INTEL_RPLU_IDS(info), \
- INTEL_VGA_DEVICE(0xA720, info), \
- INTEL_VGA_DEVICE(0xA7A0, info), \
- INTEL_VGA_DEVICE(0xA7A8, info), \
- INTEL_VGA_DEVICE(0xA7AA, info), \
- INTEL_VGA_DEVICE(0xA7AB, info)
-
-/* DG2 */
-#define INTEL_DG2_G10_IDS(info) \
- INTEL_VGA_DEVICE(0x5690, info), \
- INTEL_VGA_DEVICE(0x5691, info), \
- INTEL_VGA_DEVICE(0x5692, info), \
- INTEL_VGA_DEVICE(0x56A0, info), \
- INTEL_VGA_DEVICE(0x56A1, info), \
- INTEL_VGA_DEVICE(0x56A2, info), \
- INTEL_VGA_DEVICE(0x56BE, info), \
- INTEL_VGA_DEVICE(0x56BF, info)
-
-#define INTEL_DG2_G11_IDS(info) \
- INTEL_VGA_DEVICE(0x5693, info), \
- INTEL_VGA_DEVICE(0x5694, info), \
- INTEL_VGA_DEVICE(0x5695, info), \
- INTEL_VGA_DEVICE(0x56A5, info), \
- INTEL_VGA_DEVICE(0x56A6, info), \
- INTEL_VGA_DEVICE(0x56B0, info), \
- INTEL_VGA_DEVICE(0x56B1, info), \
- INTEL_VGA_DEVICE(0x56BA, info), \
- INTEL_VGA_DEVICE(0x56BB, info), \
- INTEL_VGA_DEVICE(0x56BC, info), \
- INTEL_VGA_DEVICE(0x56BD, info)
-
-#define INTEL_DG2_G12_IDS(info) \
- INTEL_VGA_DEVICE(0x5696, info), \
- INTEL_VGA_DEVICE(0x5697, info), \
- INTEL_VGA_DEVICE(0x56A3, info), \
- INTEL_VGA_DEVICE(0x56A4, info), \
- INTEL_VGA_DEVICE(0x56B2, info), \
- INTEL_VGA_DEVICE(0x56B3, info)
-
-#define INTEL_DG2_IDS(info) \
- INTEL_DG2_G10_IDS(info), \
- INTEL_DG2_G11_IDS(info), \
- INTEL_DG2_G12_IDS(info)
-
-#define INTEL_ATS_M150_IDS(info) \
- INTEL_VGA_DEVICE(0x56C0, info), \
- INTEL_VGA_DEVICE(0x56C2, info)
-
-#define INTEL_ATS_M75_IDS(info) \
- INTEL_VGA_DEVICE(0x56C1, info)
-
-#define INTEL_ATS_M_IDS(info) \
- INTEL_ATS_M150_IDS(info), \
- INTEL_ATS_M75_IDS(info)
-
-/* MTL */
-#define INTEL_MTL_IDS(info) \
- INTEL_VGA_DEVICE(0x7D40, info), \
- INTEL_VGA_DEVICE(0x7D41, info), \
- INTEL_VGA_DEVICE(0x7D45, info), \
- INTEL_VGA_DEVICE(0x7D51, info), \
- INTEL_VGA_DEVICE(0x7D55, info), \
- INTEL_VGA_DEVICE(0x7D60, info), \
- INTEL_VGA_DEVICE(0x7D67, info), \
- INTEL_VGA_DEVICE(0x7DD1, info), \
- INTEL_VGA_DEVICE(0x7DD5, info)
-
-#endif /* _I915_PCIIDS_H */
diff --git a/include/drm/i915_component.h b/include/drm/intel/i915_component.h
index 4ea3b17aa143..4ea3b17aa143 100644
--- a/include/drm/i915_component.h
+++ b/include/drm/intel/i915_component.h
diff --git a/include/drm/i915_drm.h b/include/drm/intel/i915_drm.h
index adff68538484..adff68538484 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/intel/i915_drm.h
diff --git a/include/drm/i915_gsc_proxy_mei_interface.h b/include/drm/intel/i915_gsc_proxy_mei_interface.h
index 850dfbf40607..850dfbf40607 100644
--- a/include/drm/i915_gsc_proxy_mei_interface.h
+++ b/include/drm/intel/i915_gsc_proxy_mei_interface.h
diff --git a/include/drm/i915_hdcp_interface.h b/include/drm/intel/i915_hdcp_interface.h
index d776ed7dcd00..d776ed7dcd00 100644
--- a/include/drm/i915_hdcp_interface.h
+++ b/include/drm/intel/i915_hdcp_interface.h
diff --git a/include/drm/intel/i915_pciids.h b/include/drm/intel/i915_pciids.h
new file mode 100644
index 000000000000..b21374f76df2
--- /dev/null
+++ b/include/drm/intel/i915_pciids.h
@@ -0,0 +1,800 @@
+/*
+ * Copyright 2013 Intel Corporation
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#ifndef _I915_PCIIDS_H
+#define _I915_PCIIDS_H
+
+/*
+ * A pci_device_id struct {
+ * __u32 vendor, device;
+ * __u32 subvendor, subdevice;
+ * __u32 class, class_mask;
+ * kernel_ulong_t driver_data;
+ * };
+ * Don't use C99 here because "class" is reserved and we want to
+ * give userspace flexibility.
+ */
+#define INTEL_VGA_DEVICE(id, info) { \
+ 0x8086, id, \
+ ~0, ~0, \
+ 0x030000, 0xff0000, \
+ (unsigned long) info }
+
+#define INTEL_QUANTA_VGA_DEVICE(info) { \
+ 0x8086, 0x16a, \
+ 0x152d, 0x8990, \
+ 0x030000, 0xff0000, \
+ (unsigned long) info }
+
+#define INTEL_I810_IDS(MACRO__, ...) \
+ MACRO__(0x7121, ## __VA_ARGS__), /* I810 */ \
+ MACRO__(0x7123, ## __VA_ARGS__), /* I810_DC100 */ \
+ MACRO__(0x7125, ## __VA_ARGS__) /* I810_E */
+
+#define INTEL_I815_IDS(MACRO__, ...) \
+ MACRO__(0x1132, ## __VA_ARGS__) /* I815*/
+
+#define INTEL_I830_IDS(MACRO__, ...) \
+ MACRO__(0x3577, ## __VA_ARGS__)
+
+#define INTEL_I845G_IDS(MACRO__, ...) \
+ MACRO__(0x2562, ## __VA_ARGS__)
+
+#define INTEL_I85X_IDS(MACRO__, ...) \
+ MACRO__(0x3582, ## __VA_ARGS__), /* I855_GM */ \
+ MACRO__(0x358e, ## __VA_ARGS__)
+
+#define INTEL_I865G_IDS(MACRO__, ...) \
+ MACRO__(0x2572, ## __VA_ARGS__) /* I865_G */
+
+#define INTEL_I915G_IDS(MACRO__, ...) \
+ MACRO__(0x2582, ## __VA_ARGS__), /* I915_G */ \
+ MACRO__(0x258a, ## __VA_ARGS__) /* E7221_G */
+
+#define INTEL_I915GM_IDS(MACRO__, ...) \
+ MACRO__(0x2592, ## __VA_ARGS__) /* I915_GM */
+
+#define INTEL_I945G_IDS(MACRO__, ...) \
+ MACRO__(0x2772, ## __VA_ARGS__) /* I945_G */
+
+#define INTEL_I945GM_IDS(MACRO__, ...) \
+ MACRO__(0x27a2, ## __VA_ARGS__), /* I945_GM */ \
+ MACRO__(0x27ae, ## __VA_ARGS__) /* I945_GME */
+
+#define INTEL_I965G_IDS(MACRO__, ...) \
+ MACRO__(0x2972, ## __VA_ARGS__), /* I946_GZ */ \
+ MACRO__(0x2982, ## __VA_ARGS__), /* G35_G */ \
+ MACRO__(0x2992, ## __VA_ARGS__), /* I965_Q */ \
+ MACRO__(0x29a2, ## __VA_ARGS__) /* I965_G */
+
+#define INTEL_G33_IDS(MACRO__, ...) \
+ MACRO__(0x29b2, ## __VA_ARGS__), /* Q35_G */ \
+ MACRO__(0x29c2, ## __VA_ARGS__), /* G33_G */ \
+ MACRO__(0x29d2, ## __VA_ARGS__) /* Q33_G */
+
+#define INTEL_I965GM_IDS(MACRO__, ...) \
+ MACRO__(0x2a02, ## __VA_ARGS__), /* I965_GM */ \
+ MACRO__(0x2a12, ## __VA_ARGS__) /* I965_GME */
+
+#define INTEL_GM45_IDS(MACRO__, ...) \
+ MACRO__(0x2a42, ## __VA_ARGS__) /* GM45_G */
+
+#define INTEL_G45_IDS(MACRO__, ...) \
+ MACRO__(0x2e02, ## __VA_ARGS__), /* IGD_E_G */ \
+ MACRO__(0x2e12, ## __VA_ARGS__), /* Q45_G */ \
+ MACRO__(0x2e22, ## __VA_ARGS__), /* G45_G */ \
+ MACRO__(0x2e32, ## __VA_ARGS__), /* G41_G */ \
+ MACRO__(0x2e42, ## __VA_ARGS__), /* B43_G */ \
+ MACRO__(0x2e92, ## __VA_ARGS__) /* B43_G.1 */
+
+#define INTEL_PNV_G_IDS(MACRO__, ...) \
+ MACRO__(0xa001, ## __VA_ARGS__)
+
+#define INTEL_PNV_M_IDS(MACRO__, ...) \
+ MACRO__(0xa011, ## __VA_ARGS__)
+
+#define INTEL_PNV_IDS(MACRO__, ...) \
+ INTEL_PNV_G_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_PNV_M_IDS(MACRO__, ## __VA_ARGS__)
+
+#define INTEL_ILK_D_IDS(MACRO__, ...) \
+ MACRO__(0x0042, ## __VA_ARGS__)
+
+#define INTEL_ILK_M_IDS(MACRO__, ...) \
+ MACRO__(0x0046, ## __VA_ARGS__)
+
+#define INTEL_ILK_IDS(MACRO__, ...) \
+ INTEL_ILK_D_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_ILK_M_IDS(MACRO__, ## __VA_ARGS__)
+
+#define INTEL_SNB_D_GT1_IDS(MACRO__, ...) \
+ MACRO__(0x0102, ## __VA_ARGS__), \
+ MACRO__(0x010A, ## __VA_ARGS__)
+
+#define INTEL_SNB_D_GT2_IDS(MACRO__, ...) \
+ MACRO__(0x0112, ## __VA_ARGS__), \
+ MACRO__(0x0122, ## __VA_ARGS__)
+
+#define INTEL_SNB_D_IDS(MACRO__, ...) \
+ INTEL_SNB_D_GT1_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_SNB_D_GT2_IDS(MACRO__, ## __VA_ARGS__)
+
+#define INTEL_SNB_M_GT1_IDS(MACRO__, ...) \
+ MACRO__(0x0106, ## __VA_ARGS__)
+
+#define INTEL_SNB_M_GT2_IDS(MACRO__, ...) \
+ MACRO__(0x0116, ## __VA_ARGS__), \
+ MACRO__(0x0126, ## __VA_ARGS__)
+
+#define INTEL_SNB_M_IDS(MACRO__, ...) \
+ INTEL_SNB_M_GT1_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_SNB_M_GT2_IDS(MACRO__, ## __VA_ARGS__)
+
+#define INTEL_SNB_IDS(MACRO__, ...) \
+ INTEL_SNB_D_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_SNB_M_IDS(MACRO__, ## __VA_ARGS__)
+
+#define INTEL_IVB_M_GT1_IDS(MACRO__, ...) \
+ MACRO__(0x0156, ## __VA_ARGS__) /* GT1 mobile */
+
+#define INTEL_IVB_M_GT2_IDS(MACRO__, ...) \
+ MACRO__(0x0166, ## __VA_ARGS__) /* GT2 mobile */
+
+#define INTEL_IVB_M_IDS(MACRO__, ...) \
+ INTEL_IVB_M_GT1_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_IVB_M_GT2_IDS(MACRO__, ## __VA_ARGS__)
+
+#define INTEL_IVB_D_GT1_IDS(MACRO__, ...) \
+ MACRO__(0x0152, ## __VA_ARGS__), /* GT1 desktop */ \
+ MACRO__(0x015a, ## __VA_ARGS__) /* GT1 server */
+
+#define INTEL_IVB_D_GT2_IDS(MACRO__, ...) \
+ MACRO__(0x0162, ## __VA_ARGS__), /* GT2 desktop */ \
+ MACRO__(0x016a, ## __VA_ARGS__) /* GT2 server */
+
+#define INTEL_IVB_D_IDS(MACRO__, ...) \
+ INTEL_IVB_D_GT1_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_IVB_D_GT2_IDS(MACRO__, ## __VA_ARGS__)
+
+#define INTEL_IVB_IDS(MACRO__, ...) \
+ INTEL_IVB_M_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_IVB_D_IDS(MACRO__, ## __VA_ARGS__)
+
+#define INTEL_IVB_Q_IDS(MACRO__, ...) \
+ INTEL_QUANTA_VGA_DEVICE(__VA_ARGS__) /* Quanta transcode */
+
+#define INTEL_HSW_ULT_GT1_IDS(MACRO__, ...) \
+ MACRO__(0x0A02, ## __VA_ARGS__), /* ULT GT1 desktop */ \
+ MACRO__(0x0A06, ## __VA_ARGS__), /* ULT GT1 mobile */ \
+ MACRO__(0x0A0A, ## __VA_ARGS__), /* ULT GT1 server */ \
+ MACRO__(0x0A0B, ## __VA_ARGS__) /* ULT GT1 reserved */
+
+#define INTEL_HSW_ULX_GT1_IDS(MACRO__, ...) \
+ MACRO__(0x0A0E, ## __VA_ARGS__) /* ULX GT1 mobile */
+
+#define INTEL_HSW_GT1_IDS(MACRO__, ...) \
+ INTEL_HSW_ULT_GT1_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_HSW_ULX_GT1_IDS(MACRO__, ## __VA_ARGS__), \
+ MACRO__(0x0402, ## __VA_ARGS__), /* GT1 desktop */ \
+ MACRO__(0x0406, ## __VA_ARGS__), /* GT1 mobile */ \
+ MACRO__(0x040A, ## __VA_ARGS__), /* GT1 server */ \
+ MACRO__(0x040B, ## __VA_ARGS__), /* GT1 reserved */ \
+ MACRO__(0x040E, ## __VA_ARGS__), /* GT1 reserved */ \
+ MACRO__(0x0C02, ## __VA_ARGS__), /* SDV GT1 desktop */ \
+ MACRO__(0x0C06, ## __VA_ARGS__), /* SDV GT1 mobile */ \
+ MACRO__(0x0C0A, ## __VA_ARGS__), /* SDV GT1 server */ \
+ MACRO__(0x0C0B, ## __VA_ARGS__), /* SDV GT1 reserved */ \
+ MACRO__(0x0C0E, ## __VA_ARGS__), /* SDV GT1 reserved */ \
+ MACRO__(0x0D02, ## __VA_ARGS__), /* CRW GT1 desktop */ \
+ MACRO__(0x0D06, ## __VA_ARGS__), /* CRW GT1 mobile */ \
+ MACRO__(0x0D0A, ## __VA_ARGS__), /* CRW GT1 server */ \
+ MACRO__(0x0D0B, ## __VA_ARGS__), /* CRW GT1 reserved */ \
+ MACRO__(0x0D0E, ## __VA_ARGS__) /* CRW GT1 reserved */
+
+#define INTEL_HSW_ULT_GT2_IDS(MACRO__, ...) \
+ MACRO__(0x0A12, ## __VA_ARGS__), /* ULT GT2 desktop */ \
+ MACRO__(0x0A16, ## __VA_ARGS__), /* ULT GT2 mobile */ \
+ MACRO__(0x0A1A, ## __VA_ARGS__), /* ULT GT2 server */ \
+ MACRO__(0x0A1B, ## __VA_ARGS__) /* ULT GT2 reserved */ \
+
+#define INTEL_HSW_ULX_GT2_IDS(MACRO__, ...) \
+ MACRO__(0x0A1E, ## __VA_ARGS__) /* ULX GT2 mobile */ \
+
+#define INTEL_HSW_GT2_IDS(MACRO__, ...) \
+ INTEL_HSW_ULT_GT2_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_HSW_ULX_GT2_IDS(MACRO__, ## __VA_ARGS__), \
+ MACRO__(0x0412, ## __VA_ARGS__), /* GT2 desktop */ \
+ MACRO__(0x0416, ## __VA_ARGS__), /* GT2 mobile */ \
+ MACRO__(0x041A, ## __VA_ARGS__), /* GT2 server */ \
+ MACRO__(0x041B, ## __VA_ARGS__), /* GT2 reserved */ \
+ MACRO__(0x041E, ## __VA_ARGS__), /* GT2 reserved */ \
+ MACRO__(0x0C12, ## __VA_ARGS__), /* SDV GT2 desktop */ \
+ MACRO__(0x0C16, ## __VA_ARGS__), /* SDV GT2 mobile */ \
+ MACRO__(0x0C1A, ## __VA_ARGS__), /* SDV GT2 server */ \
+ MACRO__(0x0C1B, ## __VA_ARGS__), /* SDV GT2 reserved */ \
+ MACRO__(0x0C1E, ## __VA_ARGS__), /* SDV GT2 reserved */ \
+ MACRO__(0x0D12, ## __VA_ARGS__), /* CRW GT2 desktop */ \
+ MACRO__(0x0D16, ## __VA_ARGS__), /* CRW GT2 mobile */ \
+ MACRO__(0x0D1A, ## __VA_ARGS__), /* CRW GT2 server */ \
+ MACRO__(0x0D1B, ## __VA_ARGS__), /* CRW GT2 reserved */ \
+ MACRO__(0x0D1E, ## __VA_ARGS__) /* CRW GT2 reserved */
+
+#define INTEL_HSW_ULT_GT3_IDS(MACRO__, ...) \
+ MACRO__(0x0A22, ## __VA_ARGS__), /* ULT GT3 desktop */ \
+ MACRO__(0x0A26, ## __VA_ARGS__), /* ULT GT3 mobile */ \
+ MACRO__(0x0A2A, ## __VA_ARGS__), /* ULT GT3 server */ \
+ MACRO__(0x0A2B, ## __VA_ARGS__), /* ULT GT3 reserved */ \
+ MACRO__(0x0A2E, ## __VA_ARGS__) /* ULT GT3 reserved */
+
+#define INTEL_HSW_GT3_IDS(MACRO__, ...) \
+ INTEL_HSW_ULT_GT3_IDS(MACRO__, ## __VA_ARGS__), \
+ MACRO__(0x0422, ## __VA_ARGS__), /* GT3 desktop */ \
+ MACRO__(0x0426, ## __VA_ARGS__), /* GT3 mobile */ \
+ MACRO__(0x042A, ## __VA_ARGS__), /* GT3 server */ \
+ MACRO__(0x042B, ## __VA_ARGS__), /* GT3 reserved */ \
+ MACRO__(0x042E, ## __VA_ARGS__), /* GT3 reserved */ \
+ MACRO__(0x0C22, ## __VA_ARGS__), /* SDV GT3 desktop */ \
+ MACRO__(0x0C26, ## __VA_ARGS__), /* SDV GT3 mobile */ \
+ MACRO__(0x0C2A, ## __VA_ARGS__), /* SDV GT3 server */ \
+ MACRO__(0x0C2B, ## __VA_ARGS__), /* SDV GT3 reserved */ \
+ MACRO__(0x0C2E, ## __VA_ARGS__), /* SDV GT3 reserved */ \
+ MACRO__(0x0D22, ## __VA_ARGS__), /* CRW GT3 desktop */ \
+ MACRO__(0x0D26, ## __VA_ARGS__), /* CRW GT3 mobile */ \
+ MACRO__(0x0D2A, ## __VA_ARGS__), /* CRW GT3 server */ \
+ MACRO__(0x0D2B, ## __VA_ARGS__), /* CRW GT3 reserved */ \
+ MACRO__(0x0D2E, ## __VA_ARGS__) /* CRW GT3 reserved */
+
+#define INTEL_HSW_IDS(MACRO__, ...) \
+ INTEL_HSW_GT1_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_HSW_GT2_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_HSW_GT3_IDS(MACRO__, ## __VA_ARGS__)
+
+#define INTEL_VLV_IDS(MACRO__, ...) \
+ MACRO__(0x0f30, ## __VA_ARGS__), \
+ MACRO__(0x0f31, ## __VA_ARGS__), \
+ MACRO__(0x0f32, ## __VA_ARGS__), \
+ MACRO__(0x0f33, ## __VA_ARGS__)
+
+#define INTEL_BDW_ULT_GT1_IDS(MACRO__, ...) \
+ MACRO__(0x1606, ## __VA_ARGS__), /* GT1 ULT */ \
+ MACRO__(0x160B, ## __VA_ARGS__) /* GT1 Iris */
+
+#define INTEL_BDW_ULX_GT1_IDS(MACRO__, ...) \
+ MACRO__(0x160E, ## __VA_ARGS__) /* GT1 ULX */
+
+#define INTEL_BDW_GT1_IDS(MACRO__, ...) \
+ INTEL_BDW_ULT_GT1_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_BDW_ULX_GT1_IDS(MACRO__, ## __VA_ARGS__), \
+ MACRO__(0x1602, ## __VA_ARGS__), /* GT1 ULT */ \
+ MACRO__(0x160A, ## __VA_ARGS__), /* GT1 Server */ \
+ MACRO__(0x160D, ## __VA_ARGS__) /* GT1 Workstation */
+
+#define INTEL_BDW_ULT_GT2_IDS(MACRO__, ...) \
+ MACRO__(0x1616, ## __VA_ARGS__), /* GT2 ULT */ \
+ MACRO__(0x161B, ## __VA_ARGS__) /* GT2 ULT */
+
+#define INTEL_BDW_ULX_GT2_IDS(MACRO__, ...) \
+ MACRO__(0x161E, ## __VA_ARGS__) /* GT2 ULX */
+
+#define INTEL_BDW_GT2_IDS(MACRO__, ...) \
+ INTEL_BDW_ULT_GT2_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_BDW_ULX_GT2_IDS(MACRO__, ## __VA_ARGS__), \
+ MACRO__(0x1612, ## __VA_ARGS__), /* GT2 Halo */ \
+ MACRO__(0x161A, ## __VA_ARGS__), /* GT2 Server */ \
+ MACRO__(0x161D, ## __VA_ARGS__) /* GT2 Workstation */
+
+#define INTEL_BDW_ULT_GT3_IDS(MACRO__, ...) \
+ MACRO__(0x1626, ## __VA_ARGS__), /* ULT */ \
+ MACRO__(0x162B, ## __VA_ARGS__) /* Iris */ \
+
+#define INTEL_BDW_ULX_GT3_IDS(MACRO__, ...) \
+ MACRO__(0x162E, ## __VA_ARGS__) /* ULX */
+
+#define INTEL_BDW_GT3_IDS(MACRO__, ...) \
+ INTEL_BDW_ULT_GT3_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_BDW_ULX_GT3_IDS(MACRO__, ## __VA_ARGS__), \
+ MACRO__(0x1622, ## __VA_ARGS__), /* ULT */ \
+ MACRO__(0x162A, ## __VA_ARGS__), /* Server */ \
+ MACRO__(0x162D, ## __VA_ARGS__) /* Workstation */
+
+#define INTEL_BDW_ULT_RSVD_IDS(MACRO__, ...) \
+ MACRO__(0x1636, ## __VA_ARGS__), /* ULT */ \
+ MACRO__(0x163B, ## __VA_ARGS__) /* Iris */
+
+#define INTEL_BDW_ULX_RSVD_IDS(MACRO__, ...) \
+ MACRO__(0x163E, ## __VA_ARGS__) /* ULX */
+
+#define INTEL_BDW_RSVD_IDS(MACRO__, ...) \
+ INTEL_BDW_ULT_RSVD_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_BDW_ULX_RSVD_IDS(MACRO__, ## __VA_ARGS__), \
+ MACRO__(0x1632, ## __VA_ARGS__), /* ULT */ \
+ MACRO__(0x163A, ## __VA_ARGS__), /* Server */ \
+ MACRO__(0x163D, ## __VA_ARGS__) /* Workstation */
+
+#define INTEL_BDW_IDS(MACRO__, ...) \
+ INTEL_BDW_GT1_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_BDW_GT2_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_BDW_GT3_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_BDW_RSVD_IDS(MACRO__, ## __VA_ARGS__)
+
+#define INTEL_CHV_IDS(MACRO__, ...) \
+ MACRO__(0x22b0, ## __VA_ARGS__), \
+ MACRO__(0x22b1, ## __VA_ARGS__), \
+ MACRO__(0x22b2, ## __VA_ARGS__), \
+ MACRO__(0x22b3, ## __VA_ARGS__)
+
+#define INTEL_SKL_ULT_GT1_IDS(MACRO__, ...) \
+ MACRO__(0x1906, ## __VA_ARGS__), /* ULT GT1 */ \
+ MACRO__(0x1913, ## __VA_ARGS__) /* ULT GT1.5 */
+
+#define INTEL_SKL_ULX_GT1_IDS(MACRO__, ...) \
+ MACRO__(0x190E, ## __VA_ARGS__), /* ULX GT1 */ \
+ MACRO__(0x1915, ## __VA_ARGS__) /* ULX GT1.5 */
+
+#define INTEL_SKL_GT1_IDS(MACRO__, ...) \
+ INTEL_SKL_ULT_GT1_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_SKL_ULX_GT1_IDS(MACRO__, ## __VA_ARGS__), \
+ MACRO__(0x1902, ## __VA_ARGS__), /* DT GT1 */ \
+ MACRO__(0x190A, ## __VA_ARGS__), /* SRV GT1 */ \
+ MACRO__(0x190B, ## __VA_ARGS__), /* Halo GT1 */ \
+ MACRO__(0x1917, ## __VA_ARGS__) /* DT GT1.5 */
+
+#define INTEL_SKL_ULT_GT2_IDS(MACRO__, ...) \
+ MACRO__(0x1916, ## __VA_ARGS__), /* ULT GT2 */ \
+ MACRO__(0x1921, ## __VA_ARGS__) /* ULT GT2F */
+
+#define INTEL_SKL_ULX_GT2_IDS(MACRO__, ...) \
+ MACRO__(0x191E, ## __VA_ARGS__) /* ULX GT2 */
+
+#define INTEL_SKL_GT2_IDS(MACRO__, ...) \
+ INTEL_SKL_ULT_GT2_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_SKL_ULX_GT2_IDS(MACRO__, ## __VA_ARGS__), \
+ MACRO__(0x1912, ## __VA_ARGS__), /* DT GT2 */ \
+ MACRO__(0x191A, ## __VA_ARGS__), /* SRV GT2 */ \
+ MACRO__(0x191B, ## __VA_ARGS__), /* Halo GT2 */ \
+ MACRO__(0x191D, ## __VA_ARGS__) /* WKS GT2 */
+
+#define INTEL_SKL_ULT_GT3_IDS(MACRO__, ...) \
+ MACRO__(0x1923, ## __VA_ARGS__), /* ULT GT3 */ \
+ MACRO__(0x1926, ## __VA_ARGS__), /* ULT GT3e */ \
+ MACRO__(0x1927, ## __VA_ARGS__) /* ULT GT3e */
+
+#define INTEL_SKL_GT3_IDS(MACRO__, ...) \
+ INTEL_SKL_ULT_GT3_IDS(MACRO__, ## __VA_ARGS__), \
+ MACRO__(0x192A, ## __VA_ARGS__), /* SRV GT3 */ \
+ MACRO__(0x192B, ## __VA_ARGS__), /* Halo GT3e */ \
+ MACRO__(0x192D, ## __VA_ARGS__) /* SRV GT3e */
+
+#define INTEL_SKL_GT4_IDS(MACRO__, ...) \
+ MACRO__(0x1932, ## __VA_ARGS__), /* DT GT4 */ \
+ MACRO__(0x193A, ## __VA_ARGS__), /* SRV GT4e */ \
+ MACRO__(0x193B, ## __VA_ARGS__), /* Halo GT4e */ \
+ MACRO__(0x193D, ## __VA_ARGS__) /* WKS GT4e */
+
+#define INTEL_SKL_IDS(MACRO__, ...) \
+ INTEL_SKL_GT1_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_SKL_GT2_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_SKL_GT3_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_SKL_GT4_IDS(MACRO__, ## __VA_ARGS__)
+
+#define INTEL_BXT_IDS(MACRO__, ...) \
+ MACRO__(0x0A84, ## __VA_ARGS__), \
+ MACRO__(0x1A84, ## __VA_ARGS__), \
+ MACRO__(0x1A85, ## __VA_ARGS__), \
+ MACRO__(0x5A84, ## __VA_ARGS__), /* APL HD Graphics 505 */ \
+ MACRO__(0x5A85, ## __VA_ARGS__) /* APL HD Graphics 500 */
+
+#define INTEL_GLK_IDS(MACRO__, ...) \
+ MACRO__(0x3184, ## __VA_ARGS__), \
+ MACRO__(0x3185, ## __VA_ARGS__)
+
+#define INTEL_KBL_ULT_GT1_IDS(MACRO__, ...) \
+ MACRO__(0x5906, ## __VA_ARGS__), /* ULT GT1 */ \
+ MACRO__(0x5913, ## __VA_ARGS__) /* ULT GT1.5 */
+
+#define INTEL_KBL_ULX_GT1_IDS(MACRO__, ...) \
+ MACRO__(0x590E, ## __VA_ARGS__), /* ULX GT1 */ \
+ MACRO__(0x5915, ## __VA_ARGS__) /* ULX GT1.5 */
+
+#define INTEL_KBL_GT1_IDS(MACRO__, ...) \
+ INTEL_KBL_ULT_GT1_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_KBL_ULX_GT1_IDS(MACRO__, ## __VA_ARGS__), \
+ MACRO__(0x5902, ## __VA_ARGS__), /* DT GT1 */ \
+ MACRO__(0x5908, ## __VA_ARGS__), /* Halo GT1 */ \
+ MACRO__(0x590A, ## __VA_ARGS__), /* SRV GT1 */ \
+ MACRO__(0x590B, ## __VA_ARGS__) /* Halo GT1 */
+
+#define INTEL_KBL_ULT_GT2_IDS(MACRO__, ...) \
+ MACRO__(0x5916, ## __VA_ARGS__), /* ULT GT2 */ \
+ MACRO__(0x5921, ## __VA_ARGS__) /* ULT GT2F */
+
+#define INTEL_KBL_ULX_GT2_IDS(MACRO__, ...) \
+ MACRO__(0x591E, ## __VA_ARGS__) /* ULX GT2 */
+
+#define INTEL_KBL_GT2_IDS(MACRO__, ...) \
+ INTEL_KBL_ULT_GT2_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_KBL_ULX_GT2_IDS(MACRO__, ## __VA_ARGS__), \
+ MACRO__(0x5912, ## __VA_ARGS__), /* DT GT2 */ \
+ MACRO__(0x5917, ## __VA_ARGS__), /* Mobile GT2 */ \
+ MACRO__(0x591A, ## __VA_ARGS__), /* SRV GT2 */ \
+ MACRO__(0x591B, ## __VA_ARGS__), /* Halo GT2 */ \
+ MACRO__(0x591D, ## __VA_ARGS__) /* WKS GT2 */
+
+#define INTEL_KBL_ULT_GT3_IDS(MACRO__, ...) \
+ MACRO__(0x5926, ## __VA_ARGS__) /* ULT GT3 */
+
+#define INTEL_KBL_GT3_IDS(MACRO__, ...) \
+ INTEL_KBL_ULT_GT3_IDS(MACRO__, ## __VA_ARGS__), \
+ MACRO__(0x5923, ## __VA_ARGS__), /* ULT GT3 */ \
+ MACRO__(0x5927, ## __VA_ARGS__) /* ULT GT3 */
+
+#define INTEL_KBL_GT4_IDS(MACRO__, ...) \
+ MACRO__(0x593B, ## __VA_ARGS__) /* Halo GT4 */
+
+/* AML/KBL Y GT2 */
+#define INTEL_AML_KBL_GT2_IDS(MACRO__, ...) \
+ MACRO__(0x591C, ## __VA_ARGS__), /* ULX GT2 */ \
+ MACRO__(0x87C0, ## __VA_ARGS__) /* ULX GT2 */
+
+/* AML/CFL Y GT2 */
+#define INTEL_AML_CFL_GT2_IDS(MACRO__, ...) \
+ MACRO__(0x87CA, ## __VA_ARGS__)
+
+/* CML GT1 */
+#define INTEL_CML_GT1_IDS(MACRO__, ...) \
+ MACRO__(0x9BA2, ## __VA_ARGS__), \
+ MACRO__(0x9BA4, ## __VA_ARGS__), \
+ MACRO__(0x9BA5, ## __VA_ARGS__), \
+ MACRO__(0x9BA8, ## __VA_ARGS__)
+
+#define INTEL_CML_U_GT1_IDS(MACRO__, ...) \
+ MACRO__(0x9B21, ## __VA_ARGS__), \
+ MACRO__(0x9BAA, ## __VA_ARGS__), \
+ MACRO__(0x9BAC, ## __VA_ARGS__)
+
+/* CML GT2 */
+#define INTEL_CML_GT2_IDS(MACRO__, ...) \
+ MACRO__(0x9BC2, ## __VA_ARGS__), \
+ MACRO__(0x9BC4, ## __VA_ARGS__), \
+ MACRO__(0x9BC5, ## __VA_ARGS__), \
+ MACRO__(0x9BC6, ## __VA_ARGS__), \
+ MACRO__(0x9BC8, ## __VA_ARGS__), \
+ MACRO__(0x9BE6, ## __VA_ARGS__), \
+ MACRO__(0x9BF6, ## __VA_ARGS__)
+
+#define INTEL_CML_U_GT2_IDS(MACRO__, ...) \
+ MACRO__(0x9B41, ## __VA_ARGS__), \
+ MACRO__(0x9BCA, ## __VA_ARGS__), \
+ MACRO__(0x9BCC, ## __VA_ARGS__)
+
+#define INTEL_CML_IDS(MACRO__, ...) \
+ INTEL_CML_GT1_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_CML_GT2_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_CML_U_GT1_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_CML_U_GT2_IDS(MACRO__, ## __VA_ARGS__)
+
+#define INTEL_KBL_IDS(MACRO__, ...) \
+ INTEL_KBL_GT1_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_KBL_GT2_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_KBL_GT3_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_KBL_GT4_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_AML_KBL_GT2_IDS(MACRO__, ## __VA_ARGS__)
+
+/* CFL S */
+#define INTEL_CFL_S_GT1_IDS(MACRO__, ...) \
+ MACRO__(0x3E90, ## __VA_ARGS__), /* SRV GT1 */ \
+ MACRO__(0x3E93, ## __VA_ARGS__), /* SRV GT1 */ \
+ MACRO__(0x3E99, ## __VA_ARGS__) /* SRV GT1 */
+
+#define INTEL_CFL_S_GT2_IDS(MACRO__, ...) \
+ MACRO__(0x3E91, ## __VA_ARGS__), /* SRV GT2 */ \
+ MACRO__(0x3E92, ## __VA_ARGS__), /* SRV GT2 */ \
+ MACRO__(0x3E96, ## __VA_ARGS__), /* SRV GT2 */ \
+ MACRO__(0x3E98, ## __VA_ARGS__), /* SRV GT2 */ \
+ MACRO__(0x3E9A, ## __VA_ARGS__) /* SRV GT2 */
+
+/* CFL H */
+#define INTEL_CFL_H_GT1_IDS(MACRO__, ...) \
+ MACRO__(0x3E9C, ## __VA_ARGS__)
+
+#define INTEL_CFL_H_GT2_IDS(MACRO__, ...) \
+ MACRO__(0x3E94, ## __VA_ARGS__), /* Halo GT2 */ \
+ MACRO__(0x3E9B, ## __VA_ARGS__) /* Halo GT2 */
+
+/* CFL U GT2 */
+#define INTEL_CFL_U_GT2_IDS(MACRO__, ...) \
+ MACRO__(0x3EA9, ## __VA_ARGS__)
+
+/* CFL U GT3 */
+#define INTEL_CFL_U_GT3_IDS(MACRO__, ...) \
+ MACRO__(0x3EA5, ## __VA_ARGS__), /* ULT GT3 */ \
+ MACRO__(0x3EA6, ## __VA_ARGS__), /* ULT GT3 */ \
+ MACRO__(0x3EA7, ## __VA_ARGS__), /* ULT GT3 */ \
+ MACRO__(0x3EA8, ## __VA_ARGS__) /* ULT GT3 */
+
+#define INTEL_CFL_IDS(MACRO__, ...) \
+ INTEL_CFL_S_GT1_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_CFL_S_GT2_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_CFL_H_GT1_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_CFL_H_GT2_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_CFL_U_GT2_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_CFL_U_GT3_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_AML_CFL_GT2_IDS(MACRO__, ## __VA_ARGS__)
+
+/* WHL/CFL U GT1 */
+#define INTEL_WHL_U_GT1_IDS(MACRO__, ...) \
+ MACRO__(0x3EA1, ## __VA_ARGS__), \
+ MACRO__(0x3EA4, ## __VA_ARGS__)
+
+/* WHL/CFL U GT2 */
+#define INTEL_WHL_U_GT2_IDS(MACRO__, ...) \
+ MACRO__(0x3EA0, ## __VA_ARGS__), \
+ MACRO__(0x3EA3, ## __VA_ARGS__)
+
+/* WHL/CFL U GT3 */
+#define INTEL_WHL_U_GT3_IDS(MACRO__, ...) \
+ MACRO__(0x3EA2, ## __VA_ARGS__)
+
+#define INTEL_WHL_IDS(MACRO__, ...) \
+ INTEL_WHL_U_GT1_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_WHL_U_GT2_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_WHL_U_GT3_IDS(MACRO__, ## __VA_ARGS__)
+
+/* CNL */
+#define INTEL_CNL_PORT_F_IDS(MACRO__, ...) \
+ MACRO__(0x5A44, ## __VA_ARGS__), \
+ MACRO__(0x5A4C, ## __VA_ARGS__), \
+ MACRO__(0x5A54, ## __VA_ARGS__), \
+ MACRO__(0x5A5C, ## __VA_ARGS__)
+
+#define INTEL_CNL_IDS(MACRO__, ...) \
+ INTEL_CNL_PORT_F_IDS(MACRO__, ## __VA_ARGS__), \
+ MACRO__(0x5A40, ## __VA_ARGS__), \
+ MACRO__(0x5A41, ## __VA_ARGS__), \
+ MACRO__(0x5A42, ## __VA_ARGS__), \
+ MACRO__(0x5A49, ## __VA_ARGS__), \
+ MACRO__(0x5A4A, ## __VA_ARGS__), \
+ MACRO__(0x5A50, ## __VA_ARGS__), \
+ MACRO__(0x5A51, ## __VA_ARGS__), \
+ MACRO__(0x5A52, ## __VA_ARGS__), \
+ MACRO__(0x5A59, ## __VA_ARGS__), \
+ MACRO__(0x5A5A, ## __VA_ARGS__)
+
+/* ICL */
+#define INTEL_ICL_PORT_F_IDS(MACRO__, ...) \
+ MACRO__(0x8A50, ## __VA_ARGS__), \
+ MACRO__(0x8A52, ## __VA_ARGS__), \
+ MACRO__(0x8A53, ## __VA_ARGS__), \
+ MACRO__(0x8A54, ## __VA_ARGS__), \
+ MACRO__(0x8A56, ## __VA_ARGS__), \
+ MACRO__(0x8A57, ## __VA_ARGS__), \
+ MACRO__(0x8A58, ## __VA_ARGS__), \
+ MACRO__(0x8A59, ## __VA_ARGS__), \
+ MACRO__(0x8A5A, ## __VA_ARGS__), \
+ MACRO__(0x8A5B, ## __VA_ARGS__), \
+ MACRO__(0x8A5C, ## __VA_ARGS__), \
+ MACRO__(0x8A70, ## __VA_ARGS__), \
+ MACRO__(0x8A71, ## __VA_ARGS__)
+
+#define INTEL_ICL_IDS(MACRO__, ...) \
+ INTEL_ICL_PORT_F_IDS(MACRO__, ## __VA_ARGS__), \
+ MACRO__(0x8A51, ## __VA_ARGS__), \
+ MACRO__(0x8A5D, ## __VA_ARGS__)
+
+/* EHL */
+#define INTEL_EHL_IDS(MACRO__, ...) \
+ MACRO__(0x4541, ## __VA_ARGS__), \
+ MACRO__(0x4551, ## __VA_ARGS__), \
+ MACRO__(0x4555, ## __VA_ARGS__), \
+ MACRO__(0x4557, ## __VA_ARGS__), \
+ MACRO__(0x4570, ## __VA_ARGS__), \
+ MACRO__(0x4571, ## __VA_ARGS__)
+
+/* JSL */
+#define INTEL_JSL_IDS(MACRO__, ...) \
+ MACRO__(0x4E51, ## __VA_ARGS__), \
+ MACRO__(0x4E55, ## __VA_ARGS__), \
+ MACRO__(0x4E57, ## __VA_ARGS__), \
+ MACRO__(0x4E61, ## __VA_ARGS__), \
+ MACRO__(0x4E71, ## __VA_ARGS__)
+
+/* TGL */
+#define INTEL_TGL_GT1_IDS(MACRO__, ...) \
+ MACRO__(0x9A60, ## __VA_ARGS__), \
+ MACRO__(0x9A68, ## __VA_ARGS__), \
+ MACRO__(0x9A70, ## __VA_ARGS__)
+
+#define INTEL_TGL_GT2_IDS(MACRO__, ...) \
+ MACRO__(0x9A40, ## __VA_ARGS__), \
+ MACRO__(0x9A49, ## __VA_ARGS__), \
+ MACRO__(0x9A59, ## __VA_ARGS__), \
+ MACRO__(0x9A78, ## __VA_ARGS__), \
+ MACRO__(0x9AC0, ## __VA_ARGS__), \
+ MACRO__(0x9AC9, ## __VA_ARGS__), \
+ MACRO__(0x9AD9, ## __VA_ARGS__), \
+ MACRO__(0x9AF8, ## __VA_ARGS__)
+
+#define INTEL_TGL_IDS(MACRO__, ...) \
+ INTEL_TGL_GT1_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_TGL_GT2_IDS(MACRO__, ## __VA_ARGS__)
+
+/* RKL */
+#define INTEL_RKL_IDS(MACRO__, ...) \
+ MACRO__(0x4C80, ## __VA_ARGS__), \
+ MACRO__(0x4C8A, ## __VA_ARGS__), \
+ MACRO__(0x4C8B, ## __VA_ARGS__), \
+ MACRO__(0x4C8C, ## __VA_ARGS__), \
+ MACRO__(0x4C90, ## __VA_ARGS__), \
+ MACRO__(0x4C9A, ## __VA_ARGS__)
+
+/* DG1 */
+#define INTEL_DG1_IDS(MACRO__, ...) \
+ MACRO__(0x4905, ## __VA_ARGS__), \
+ MACRO__(0x4906, ## __VA_ARGS__), \
+ MACRO__(0x4907, ## __VA_ARGS__), \
+ MACRO__(0x4908, ## __VA_ARGS__), \
+ MACRO__(0x4909, ## __VA_ARGS__)
+
+/* ADL-S */
+#define INTEL_ADLS_IDS(MACRO__, ...) \
+ MACRO__(0x4680, ## __VA_ARGS__), \
+ MACRO__(0x4682, ## __VA_ARGS__), \
+ MACRO__(0x4688, ## __VA_ARGS__), \
+ MACRO__(0x468A, ## __VA_ARGS__), \
+ MACRO__(0x468B, ## __VA_ARGS__), \
+ MACRO__(0x4690, ## __VA_ARGS__), \
+ MACRO__(0x4692, ## __VA_ARGS__), \
+ MACRO__(0x4693, ## __VA_ARGS__)
+
+/* ADL-P */
+#define INTEL_ADLP_IDS(MACRO__, ...) \
+ MACRO__(0x46A0, ## __VA_ARGS__), \
+ MACRO__(0x46A1, ## __VA_ARGS__), \
+ MACRO__(0x46A2, ## __VA_ARGS__), \
+ MACRO__(0x46A3, ## __VA_ARGS__), \
+ MACRO__(0x46A6, ## __VA_ARGS__), \
+ MACRO__(0x46A8, ## __VA_ARGS__), \
+ MACRO__(0x46AA, ## __VA_ARGS__), \
+ MACRO__(0x462A, ## __VA_ARGS__), \
+ MACRO__(0x4626, ## __VA_ARGS__), \
+ MACRO__(0x4628, ## __VA_ARGS__), \
+ MACRO__(0x46B0, ## __VA_ARGS__), \
+ MACRO__(0x46B1, ## __VA_ARGS__), \
+ MACRO__(0x46B2, ## __VA_ARGS__), \
+ MACRO__(0x46B3, ## __VA_ARGS__), \
+ MACRO__(0x46C0, ## __VA_ARGS__), \
+ MACRO__(0x46C1, ## __VA_ARGS__), \
+ MACRO__(0x46C2, ## __VA_ARGS__), \
+ MACRO__(0x46C3, ## __VA_ARGS__)
+
+/* ADL-N */
+#define INTEL_ADLN_IDS(MACRO__, ...) \
+ MACRO__(0x46D0, ## __VA_ARGS__), \
+ MACRO__(0x46D1, ## __VA_ARGS__), \
+ MACRO__(0x46D2, ## __VA_ARGS__), \
+ MACRO__(0x46D3, ## __VA_ARGS__), \
+ MACRO__(0x46D4, ## __VA_ARGS__)
+
+/* RPL-S */
+#define INTEL_RPLS_IDS(MACRO__, ...) \
+ MACRO__(0xA780, ## __VA_ARGS__), \
+ MACRO__(0xA781, ## __VA_ARGS__), \
+ MACRO__(0xA782, ## __VA_ARGS__), \
+ MACRO__(0xA783, ## __VA_ARGS__), \
+ MACRO__(0xA788, ## __VA_ARGS__), \
+ MACRO__(0xA789, ## __VA_ARGS__), \
+ MACRO__(0xA78A, ## __VA_ARGS__), \
+ MACRO__(0xA78B, ## __VA_ARGS__)
+
+/* RPL-U */
+#define INTEL_RPLU_IDS(MACRO__, ...) \
+ MACRO__(0xA721, ## __VA_ARGS__), \
+ MACRO__(0xA7A1, ## __VA_ARGS__), \
+ MACRO__(0xA7A9, ## __VA_ARGS__), \
+ MACRO__(0xA7AC, ## __VA_ARGS__), \
+ MACRO__(0xA7AD, ## __VA_ARGS__)
+
+/* RPL-P */
+#define INTEL_RPLP_IDS(MACRO__, ...) \
+ MACRO__(0xA720, ## __VA_ARGS__), \
+ MACRO__(0xA7A0, ## __VA_ARGS__), \
+ MACRO__(0xA7A8, ## __VA_ARGS__), \
+ MACRO__(0xA7AA, ## __VA_ARGS__), \
+ MACRO__(0xA7AB, ## __VA_ARGS__)
+
+/* DG2 */
+#define INTEL_DG2_G10_IDS(MACRO__, ...) \
+ MACRO__(0x5690, ## __VA_ARGS__), \
+ MACRO__(0x5691, ## __VA_ARGS__), \
+ MACRO__(0x5692, ## __VA_ARGS__), \
+ MACRO__(0x56A0, ## __VA_ARGS__), \
+ MACRO__(0x56A1, ## __VA_ARGS__), \
+ MACRO__(0x56A2, ## __VA_ARGS__), \
+ MACRO__(0x56BE, ## __VA_ARGS__), \
+ MACRO__(0x56BF, ## __VA_ARGS__)
+
+#define INTEL_DG2_G11_IDS(MACRO__, ...) \
+ MACRO__(0x5693, ## __VA_ARGS__), \
+ MACRO__(0x5694, ## __VA_ARGS__), \
+ MACRO__(0x5695, ## __VA_ARGS__), \
+ MACRO__(0x56A5, ## __VA_ARGS__), \
+ MACRO__(0x56A6, ## __VA_ARGS__), \
+ MACRO__(0x56B0, ## __VA_ARGS__), \
+ MACRO__(0x56B1, ## __VA_ARGS__), \
+ MACRO__(0x56BA, ## __VA_ARGS__), \
+ MACRO__(0x56BB, ## __VA_ARGS__), \
+ MACRO__(0x56BC, ## __VA_ARGS__), \
+ MACRO__(0x56BD, ## __VA_ARGS__)
+
+#define INTEL_DG2_G12_IDS(MACRO__, ...) \
+ MACRO__(0x5696, ## __VA_ARGS__), \
+ MACRO__(0x5697, ## __VA_ARGS__), \
+ MACRO__(0x56A3, ## __VA_ARGS__), \
+ MACRO__(0x56A4, ## __VA_ARGS__), \
+ MACRO__(0x56B2, ## __VA_ARGS__), \
+ MACRO__(0x56B3, ## __VA_ARGS__)
+
+#define INTEL_DG2_IDS(MACRO__, ...) \
+ INTEL_DG2_G10_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_DG2_G11_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_DG2_G12_IDS(MACRO__, ## __VA_ARGS__)
+
+#define INTEL_ATS_M150_IDS(MACRO__, ...) \
+ MACRO__(0x56C0, ## __VA_ARGS__), \
+ MACRO__(0x56C2, ## __VA_ARGS__)
+
+#define INTEL_ATS_M75_IDS(MACRO__, ...) \
+ MACRO__(0x56C1, ## __VA_ARGS__)
+
+#define INTEL_ATS_M_IDS(MACRO__, ...) \
+ INTEL_ATS_M150_IDS(MACRO__, ## __VA_ARGS__), \
+ INTEL_ATS_M75_IDS(MACRO__, ## __VA_ARGS__)
+
+/* MTL */
+#define INTEL_MTL_IDS(MACRO__, ...) \
+ MACRO__(0x7D40, ## __VA_ARGS__), \
+ MACRO__(0x7D41, ## __VA_ARGS__), \
+ MACRO__(0x7D45, ## __VA_ARGS__), \
+ MACRO__(0x7D51, ## __VA_ARGS__), \
+ MACRO__(0x7D55, ## __VA_ARGS__), \
+ MACRO__(0x7D60, ## __VA_ARGS__), \
+ MACRO__(0x7D67, ## __VA_ARGS__), \
+ MACRO__(0x7DD1, ## __VA_ARGS__), \
+ MACRO__(0x7DD5, ## __VA_ARGS__)
+
+/* LNL */
+#define INTEL_LNL_IDS(MACRO__, ...) \
+ MACRO__(0x6420, ## __VA_ARGS__), \
+ MACRO__(0x64A0, ## __VA_ARGS__), \
+ MACRO__(0x64B0, ## __VA_ARGS__)
+
+/* BMG */
+#define INTEL_BMG_IDS(MACRO__, ...) \
+ MACRO__(0xE202, ## __VA_ARGS__), \
+ MACRO__(0xE20B, ## __VA_ARGS__), \
+ MACRO__(0xE20C, ## __VA_ARGS__), \
+ MACRO__(0xE20D, ## __VA_ARGS__), \
+ MACRO__(0xE212, ## __VA_ARGS__)
+
+#endif /* _I915_PCIIDS_H */
diff --git a/include/drm/i915_pxp_tee_interface.h b/include/drm/intel/i915_pxp_tee_interface.h
index a532d32f58f3..a532d32f58f3 100644
--- a/include/drm/i915_pxp_tee_interface.h
+++ b/include/drm/intel/i915_pxp_tee_interface.h
diff --git a/include/drm/intel-gtt.h b/include/drm/intel/intel-gtt.h
index cb0d5b7200c7..cb0d5b7200c7 100644
--- a/include/drm/intel-gtt.h
+++ b/include/drm/intel/intel-gtt.h
diff --git a/include/drm/intel_lpe_audio.h b/include/drm/intel/intel_lpe_audio.h
index b6121c8fe539..b6121c8fe539 100644
--- a/include/drm/intel_lpe_audio.h
+++ b/include/drm/intel/intel_lpe_audio.h
diff --git a/include/drm/xe_pciids.h b/include/drm/intel/xe_pciids.h
index 644872a35c35..644872a35c35 100644
--- a/include/drm/xe_pciids.h
+++ b/include/drm/intel/xe_pciids.h
diff --git a/include/linux/dma-fence-array.h b/include/linux/dma-fence-array.h
index ec7f25def392..29c5650c1038 100644
--- a/include/linux/dma-fence-array.h
+++ b/include/linux/dma-fence-array.h
@@ -33,6 +33,7 @@ struct dma_fence_array_cb {
* @num_pending: fences in the array still pending
* @fences: array of the fences
* @work: internal irq_work function
+ * @callbacks: array of callback helpers
*/
struct dma_fence_array {
struct dma_fence base;
@@ -43,6 +44,8 @@ struct dma_fence_array {
struct dma_fence **fences;
struct irq_work work;
+
+ struct dma_fence_array_cb callbacks[] __counted_by(num_fences);
};
/**
diff --git a/include/linux/dma-heap.h b/include/linux/dma-heap.h
index 0c05561cad6e..064bad725061 100644
--- a/include/linux/dma-heap.h
+++ b/include/linux/dma-heap.h
@@ -23,8 +23,8 @@ struct dma_heap;
struct dma_heap_ops {
struct dma_buf *(*allocate)(struct dma_heap *heap,
unsigned long len,
- unsigned long fd_flags,
- unsigned long heap_flags);
+ u32 fd_flags,
+ u64 heap_flags);
};
/**
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 0f0834939b6a..db7d97b10964 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -225,6 +225,7 @@ struct fb_deferred_io {
struct mutex lock; /* mutex that protects the pageref list */
struct list_head pagereflist; /* list of pagerefs for touched pages */
/* callback */
+ struct page *(*get_page)(struct fb_info *info, unsigned long offset);
void (*deferred_io)(struct fb_info *info, struct list_head *pagelist);
};
#endif
diff --git a/include/linux/mfd/atmel-hlcdc.h b/include/linux/mfd/atmel-hlcdc.h
index a186119a49b5..80d675a03b39 100644
--- a/include/linux/mfd/atmel-hlcdc.h
+++ b/include/linux/mfd/atmel-hlcdc.h
@@ -22,6 +22,8 @@
#define ATMEL_HLCDC_DITHER BIT(6)
#define ATMEL_HLCDC_DISPDLY BIT(7)
#define ATMEL_HLCDC_MODE_MASK GENMASK(9, 8)
+#define ATMEL_XLCDC_MODE_MASK GENMASK(10, 8)
+#define ATMEL_XLCDC_DPI BIT(11)
#define ATMEL_HLCDC_PP BIT(10)
#define ATMEL_HLCDC_VSPSU BIT(12)
#define ATMEL_HLCDC_VSPHO BIT(13)
@@ -34,6 +36,12 @@
#define ATMEL_HLCDC_IDR 0x30
#define ATMEL_HLCDC_IMR 0x34
#define ATMEL_HLCDC_ISR 0x38
+#define ATMEL_XLCDC_ATTRE 0x3c
+
+#define ATMEL_XLCDC_BASE_UPDATE BIT(0)
+#define ATMEL_XLCDC_OVR1_UPDATE BIT(1)
+#define ATMEL_XLCDC_OVR3_UPDATE BIT(2)
+#define ATMEL_XLCDC_HEO_UPDATE BIT(3)
#define ATMEL_HLCDC_CLKPOL BIT(0)
#define ATMEL_HLCDC_CLKSEL BIT(2)
@@ -48,6 +56,8 @@
#define ATMEL_HLCDC_DISP BIT(2)
#define ATMEL_HLCDC_PWM BIT(3)
#define ATMEL_HLCDC_SIP BIT(4)
+#define ATMEL_XLCDC_SD BIT(5)
+#define ATMEL_XLCDC_CM BIT(6)
#define ATMEL_HLCDC_SOF BIT(0)
#define ATMEL_HLCDC_SYNCDIS BIT(1)
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index 1d10939e40af..7e39d486374a 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -18,7 +18,7 @@
#include <sound/pcm.h>
#include <sound/memalloc.h>
#include <sound/hda_verbs.h>
-#include <drm/i915_component.h>
+#include <drm/intel/i915_component.h>
/* codec node id */
typedef u16 hda_nid_t;
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index e44362e74fa1..efe5de6ce208 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -1283,6 +1283,15 @@ struct drm_amdgpu_info_gpuvm_fault {
#define AMDGPU_FAMILY_GC_11_5_0 150 /* GC 11.5.0 */
#define AMDGPU_FAMILY_GC_12_0_0 152 /* GC 12.0.0 */
+/* FIXME wrong namespace! */
+struct drm_color_ctm_3x4 {
+ /*
+ * Conversion matrix with 3x4 dimensions in S31.32 sign-magnitude
+ * (not two's complement!) format.
+ */
+ __u64 matrix[12];
+};
+
#if defined(__cplusplus)
}
#endif
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 1ca5c7e418fd..d390011b89b4 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -846,14 +846,6 @@ struct drm_color_ctm {
__u64 matrix[9];
};
-struct drm_color_ctm_3x4 {
- /*
- * Conversion matrix with 3x4 dimensions in S31.32 sign-magnitude
- * (not two's complement!) format.
- */
- __u64 matrix[12];
-};
-
struct drm_color_lut {
/*
* Values are mapped linearly to 0.0 - 1.0 range, with 0x0 == 0.0 and
diff --git a/include/uapi/drm/ivpu_accel.h b/include/uapi/drm/ivpu_accel.h
index 19a13468eca5..084fb529e1e9 100644
--- a/include/uapi/drm/ivpu_accel.h
+++ b/include/uapi/drm/ivpu_accel.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
/*
- * Copyright (C) 2020-2023 Intel Corporation
+ * Copyright (C) 2020-2024 Intel Corporation
*/
#ifndef __UAPI_IVPU_DRM_H__
@@ -21,6 +21,10 @@ extern "C" {
#define DRM_IVPU_BO_INFO 0x03
#define DRM_IVPU_SUBMIT 0x05
#define DRM_IVPU_BO_WAIT 0x06
+#define DRM_IVPU_METRIC_STREAMER_START 0x07
+#define DRM_IVPU_METRIC_STREAMER_STOP 0x08
+#define DRM_IVPU_METRIC_STREAMER_GET_DATA 0x09
+#define DRM_IVPU_METRIC_STREAMER_GET_INFO 0x0a
#define DRM_IOCTL_IVPU_GET_PARAM \
DRM_IOWR(DRM_COMMAND_BASE + DRM_IVPU_GET_PARAM, struct drm_ivpu_param)
@@ -40,6 +44,22 @@ extern "C" {
#define DRM_IOCTL_IVPU_BO_WAIT \
DRM_IOWR(DRM_COMMAND_BASE + DRM_IVPU_BO_WAIT, struct drm_ivpu_bo_wait)
+#define DRM_IOCTL_IVPU_METRIC_STREAMER_START \
+ DRM_IOWR(DRM_COMMAND_BASE + DRM_IVPU_METRIC_STREAMER_START, \
+ struct drm_ivpu_metric_streamer_start)
+
+#define DRM_IOCTL_IVPU_METRIC_STREAMER_STOP \
+ DRM_IOW(DRM_COMMAND_BASE + DRM_IVPU_METRIC_STREAMER_STOP, \
+ struct drm_ivpu_metric_streamer_stop)
+
+#define DRM_IOCTL_IVPU_METRIC_STREAMER_GET_DATA \
+ DRM_IOWR(DRM_COMMAND_BASE + DRM_IVPU_METRIC_STREAMER_GET_DATA, \
+ struct drm_ivpu_metric_streamer_get_data)
+
+#define DRM_IOCTL_IVPU_METRIC_STREAMER_GET_INFO \
+ DRM_IOWR(DRM_COMMAND_BASE + DRM_IVPU_METRIC_STREAMER_GET_INFO, \
+ struct drm_ivpu_metric_streamer_get_data)
+
/**
* DOC: contexts
*
@@ -336,6 +356,53 @@ struct drm_ivpu_bo_wait {
__u32 pad;
};
+/**
+ * struct drm_ivpu_metric_streamer_start - Start collecting metric data
+ */
+struct drm_ivpu_metric_streamer_start {
+ /** @metric_group_mask: Indicates metric streamer instance */
+ __u64 metric_group_mask;
+ /** @sampling_period_ns: Sampling period in nanoseconds */
+ __u64 sampling_period_ns;
+ /**
+ * @read_period_samples:
+ *
+ * Number of samples after which user space will try to read the data.
+ * Reading the data after significantly longer period may cause data loss.
+ */
+ __u32 read_period_samples;
+ /** @sample_size: Returned size of a single sample in bytes */
+ __u32 sample_size;
+ /** @max_data_size: Returned max @data_size from %DRM_IOCTL_IVPU_METRIC_STREAMER_GET_DATA */
+ __u32 max_data_size;
+};
+
+/**
+ * struct drm_ivpu_metric_streamer_get_data - Copy collected metric data
+ */
+struct drm_ivpu_metric_streamer_get_data {
+ /** @metric_group_mask: Indicates metric streamer instance */
+ __u64 metric_group_mask;
+ /** @buffer_ptr: A pointer to a destination for the copied data */
+ __u64 buffer_ptr;
+ /** @buffer_size: Size of the destination buffer */
+ __u64 buffer_size;
+ /**
+ * @data_size: Returned size of copied metric data
+ *
+ * If the @buffer_size is zero, returns the amount of data ready to be copied.
+ */
+ __u64 data_size;
+};
+
+/**
+ * struct drm_ivpu_metric_streamer_stop - Stop collecting metric data
+ */
+struct drm_ivpu_metric_streamer_stop {
+ /** @metric_group_mask: Indicates metric streamer instance */
+ __u64 metric_group_mask;
+};
+
#if defined(__cplusplus)
}
#endif
diff --git a/include/uapi/drm/v3d_drm.h b/include/uapi/drm/v3d_drm.h
index dce1835eced4..87fc5bb0a61e 100644
--- a/include/uapi/drm/v3d_drm.h
+++ b/include/uapi/drm/v3d_drm.h
@@ -42,6 +42,7 @@ extern "C" {
#define DRM_V3D_PERFMON_DESTROY 0x09
#define DRM_V3D_PERFMON_GET_VALUES 0x0a
#define DRM_V3D_SUBMIT_CPU 0x0b
+#define DRM_V3D_PERFMON_GET_COUNTER 0x0c
#define DRM_IOCTL_V3D_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_CL, struct drm_v3d_submit_cl)
#define DRM_IOCTL_V3D_WAIT_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_WAIT_BO, struct drm_v3d_wait_bo)
@@ -58,6 +59,8 @@ extern "C" {
#define DRM_IOCTL_V3D_PERFMON_GET_VALUES DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_PERFMON_GET_VALUES, \
struct drm_v3d_perfmon_get_values)
#define DRM_IOCTL_V3D_SUBMIT_CPU DRM_IOW(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_CPU, struct drm_v3d_submit_cpu)
+#define DRM_IOCTL_V3D_PERFMON_GET_COUNTER DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_PERFMON_GET_COUNTER, \
+ struct drm_v3d_perfmon_get_counter)
#define DRM_V3D_SUBMIT_CL_FLUSH_CACHE 0x01
#define DRM_V3D_SUBMIT_EXTENSION 0x02
@@ -286,6 +289,7 @@ enum drm_v3d_param {
DRM_V3D_PARAM_SUPPORTS_PERFMON,
DRM_V3D_PARAM_SUPPORTS_MULTISYNC_EXT,
DRM_V3D_PARAM_SUPPORTS_CPU_QUEUE,
+ DRM_V3D_PARAM_MAX_PERF_COUNTERS,
};
struct drm_v3d_get_param {
@@ -599,6 +603,16 @@ struct drm_v3d_submit_cpu {
__u64 extensions;
};
+/* The performance counters index represented by this enum are deprecated and
+ * must no longer be used. These counters are only valid for V3D 4.2.
+ *
+ * In order to check for performance counter information,
+ * use DRM_IOCTL_V3D_PERFMON_GET_COUNTER.
+ *
+ * Don't use V3D_PERFCNT_NUM to retrieve the maximum number of performance
+ * counters. You should use DRM_IOCTL_V3D_GET_PARAM with the following
+ * parameter: DRM_V3D_PARAM_MAX_PERF_COUNTERS.
+ */
enum {
V3D_PERFCNT_FEP_VALID_PRIMTS_NO_PIXELS,
V3D_PERFCNT_FEP_VALID_PRIMS,
@@ -717,6 +731,40 @@ struct drm_v3d_perfmon_get_values {
__u64 values_ptr;
};
+#define DRM_V3D_PERFCNT_MAX_NAME 64
+#define DRM_V3D_PERFCNT_MAX_CATEGORY 32
+#define DRM_V3D_PERFCNT_MAX_DESCRIPTION 256
+
+/**
+ * struct drm_v3d_perfmon_get_counter - ioctl to get the description of a
+ * performance counter
+ *
+ * As userspace needs to retrieve information about the performance counters
+ * available, this IOCTL allows users to get information about a performance
+ * counter (name, category and description).
+ */
+struct drm_v3d_perfmon_get_counter {
+ /*
+ * Counter ID
+ *
+ * Must be smaller than the maximum number of performance counters, which
+ * can be retrieve through DRM_V3D_PARAM_MAX_PERF_COUNTERS.
+ */
+ __u8 counter;
+
+ /* Name of the counter */
+ __u8 name[DRM_V3D_PERFCNT_MAX_NAME];
+
+ /* Category of the counter */
+ __u8 category[DRM_V3D_PERFCNT_MAX_CATEGORY];
+
+ /* Description of the counter */
+ __u8 description[DRM_V3D_PERFCNT_MAX_DESCRIPTION];
+
+ /* mbz */
+ __u8 reserved[7];
+};
+
#if defined(__cplusplus)
}
#endif
diff --git a/include/uapi/linux/dma-heap.h b/include/uapi/linux/dma-heap.h
index 6f84fa08e074..a4cf716a49fa 100644
--- a/include/uapi/linux/dma-heap.h
+++ b/include/uapi/linux/dma-heap.h
@@ -19,7 +19,7 @@
#define DMA_HEAP_VALID_FD_FLAGS (O_CLOEXEC | O_ACCMODE)
/* Currently no heap flags */
-#define DMA_HEAP_VALID_HEAP_FLAGS (0)
+#define DMA_HEAP_VALID_HEAP_FLAGS (0ULL)
/**
* struct dma_heap_allocation_data - metadata passed from userspace for
diff --git a/lib/fonts/Kconfig b/lib/fonts/Kconfig
index 7e945fdcbf11..befcb463f738 100644
--- a/lib/fonts/Kconfig
+++ b/lib/fonts/Kconfig
@@ -10,7 +10,7 @@ if FONT_SUPPORT
config FONTS
bool "Select compiled-in fonts"
- depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
+ depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE || DRM_PANIC
help
Say Y here if you would like to use fonts other than the default
your frame buffer console usually use.
@@ -23,7 +23,7 @@ config FONTS
config FONT_8x8
bool "VGA 8x8 font" if FONTS
- depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
+ depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE || DRM_PANIC
default y if !SPARC && !FONTS
help
This is the "high resolution" font for the VGA frame buffer (the one
@@ -46,7 +46,7 @@ config FONT_8x16
config FONT_6x11
bool "Mac console 6x11 font (not supported by all drivers)" if FONTS
- depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
+ depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE || DRM_PANIC
default y if !SPARC && !FONTS && MAC
help
Small console font with Macintosh-style high-half glyphs. Some Mac
@@ -54,7 +54,7 @@ config FONT_6x11
config FONT_7x14
bool "console 7x14 font (not supported by all drivers)" if FONTS
- depends on FRAMEBUFFER_CONSOLE
+ depends on FRAMEBUFFER_CONSOLE || DRM_PANIC
help
Console font with characters just a bit smaller than the default.
If the standard 8x16 font is a little too big for you, say Y.
@@ -62,7 +62,7 @@ config FONT_7x14
config FONT_PEARL_8x8
bool "Pearl (old m68k) console 8x8 font" if FONTS
- depends on FRAMEBUFFER_CONSOLE
+ depends on FRAMEBUFFER_CONSOLE || DRM_PANIC
default y if !SPARC && !FONTS && AMIGA
help
Small console font with PC-style control-character and high-half
@@ -70,7 +70,7 @@ config FONT_PEARL_8x8
config FONT_ACORN_8x8
bool "Acorn console 8x8 font" if FONTS
- depends on FRAMEBUFFER_CONSOLE
+ depends on FRAMEBUFFER_CONSOLE || DRM_PANIC
default y if !SPARC && !FONTS && ARM && ARCH_ACORN
help
Small console font with PC-style control characters and high-half
@@ -90,7 +90,7 @@ config FONT_6x10
config FONT_10x18
bool "console 10x18 font (not supported by all drivers)" if FONTS
- depends on FRAMEBUFFER_CONSOLE
+ depends on FRAMEBUFFER_CONSOLE || DRM_PANIC
help
This is a high resolution console font for machines with very
big letters. It fits between the sun 12x22 and the normal 8x16 font.
@@ -105,7 +105,7 @@ config FONT_SUN8x16
config FONT_SUN12x22
bool "Sparc console 12x22 font (not supported by all drivers)"
- depends on FRAMEBUFFER_CONSOLE && (!SPARC && FONTS || SPARC)
+ depends on (FRAMEBUFFER_CONSOLE && (!SPARC && FONTS || SPARC)) || DRM_PANIC
help
This is the high resolution console font for Sun machines with very
big letters (like the letters used in the SPARC PROM). If the
@@ -113,7 +113,7 @@ config FONT_SUN12x22
config FONT_TER16x32
bool "Terminus 16x32 font (not supported by all drivers)"
- depends on FRAMEBUFFER_CONSOLE && (!SPARC && FONTS || SPARC)
+ depends on (FRAMEBUFFER_CONSOLE && (!SPARC && FONTS || SPARC)) || DRM_PANIC
help
Terminus Font is a clean, fixed width bitmap font, designed
for long (8 and more hours per day) work with computers.
@@ -122,7 +122,7 @@ config FONT_TER16x32
config FONT_6x8
bool "OLED 6x8 font" if FONTS
- depends on FRAMEBUFFER_CONSOLE
+ depends on FRAMEBUFFER_CONSOLE || DRM_PANIC
help
This font is useful for small displays (OLED).
diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c
index 02f5a7f9b728..d41ea09ffbe5 100644
--- a/sound/x86/intel_hdmi_audio.c
+++ b/sound/x86/intel_hdmi_audio.c
@@ -31,7 +31,7 @@
#include <sound/jack.h>
#include <drm/drm_edid.h>
#include <drm/drm_eld.h>
-#include <drm/intel_lpe_audio.h>
+#include <drm/intel/intel_lpe_audio.h>
#include "intel_hdmi_audio.h"
#define INTEL_HDMI_AUDIO_SUSPEND_DELAY_MS 5000