aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/Makefile3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h12
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c40
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c79
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c5
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c7
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c79
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c32
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c35
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c9
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_job.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c16
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c15
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c145
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h5
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c21
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c36
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h11
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c15
-rw-r--r--drivers/gpu/drm/amd/amdgpu/cik.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/cik_sdma.c5
-rw-r--r--drivers/gpu/drm/amd/amdgpu/df_v4_6_2.c34
-rw-r--r--drivers/gpu/drm/amd/amdgpu/df_v4_6_2.h31
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c28
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c13
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c40
-rw-r--r--drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c5
-rw-r--r--drivers/gpu/drm/amd/amdgpu/nbio_v7_7.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c9
-rw-r--r--drivers/gpu/drm/amd/amdgpu/nv.c10
-rw-r--r--drivers/gpu/drm/amd/amdgpu/psp_v13_0.c78
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c5
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c5
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c16
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c10
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c10
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c10
-rw-r--r--drivers/gpu/drm/amd/amdgpu/si.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/si_dma.c5
-rw-r--r--drivers/gpu/drm/amd/amdgpu/soc15.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/soc21.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/umc_v12_0.c31
-rw-r--r--drivers/gpu/drm/amd/amdgpu/umc_v8_10.c12
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vi.c5
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c18
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_crat.c66
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_migrate.c150
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_migrate.h6
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_svm.c154
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_svm.h9
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_topology.c18
-rw-r--r--drivers/gpu/drm/amd/amdxcp/amdgpu_xcp_drv.c7
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c7
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c48
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c4
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c542
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc.c27
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_resource.c11
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_stream.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c26
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.h5
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn303/dcn303_dccg.h18
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn303/dcn303_init.c18
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn303/dcn303_init.h18
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c19
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.h18
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn31/Makefile2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c23
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c9
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c9
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dpp.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dpp.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dsc.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dsc.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dwb.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubbub.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubbub.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubp.c139
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubp.h16
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn35/dcn35_init.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn35/dcn35_init.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn35/dcn35_mmhubbub.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn35/dcn35_mmhubbub.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn35/dcn35_opp.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn35/dcn35_opp.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn35/dcn35_pg_cntl.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn35/dcn35_pg_cntl.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.c7
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/Makefile8
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/cmntypes.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/display_mode_core_structs.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/display_mode_lib_defines.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/display_mode_util.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/display_mode_util.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c148
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_types.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml2_internal_types.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml2_policy.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h18
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml_assert.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml_depedencies.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2/dml_logging.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/hdcp/Makefile2
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c6
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c21
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn303/dcn303_hwseq.c19
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn303/dcn303_hwseq.h19
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c11
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c39
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.h3
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c10
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/irq/dcn201/irq_service_dcn201.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/irq/dcn303/irq_service_dcn303.c19
-rw-r--r--drivers/gpu/drm/amd/display/dc/irq/dcn303/irq_service_dcn303.h19
-rw-r--r--drivers/gpu/drm/amd/display/dc/irq_types.h6
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c6
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/link_dpms.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c11
-rw-r--r--drivers/gpu/drm/amd/display/dmub/src/dmub_dcn303.c19
-rw-r--r--drivers/gpu/drm/amd/display/dmub/src/dmub_dcn303.h19
-rw-r--r--drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c1
-rw-r--r--drivers/gpu/drm/amd/display/include/signal_types.h1
-rw-r--r--drivers/gpu/drm/amd/include/asic_reg/mp/mp_13_0_2_sh_mask.h28
-rw-r--r--drivers/gpu/drm/amd/include/kgd_pp_interface.h30
-rw-r--r--drivers/gpu/drm/amd/pm/amdgpu_pm.c31
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c3
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h4
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c4
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_pptable.h24
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c40
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h1
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu14_driver_if_v14_0_0.h120
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h2
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c10
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c17
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c10
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c18
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c66
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c3
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c27
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c4
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c260
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c3
-rw-r--r--drivers/gpu/drm/ast/ast_dp.c70
-rw-r--r--drivers/gpu/drm/ast/ast_dp501.c38
-rw-r--r--drivers/gpu/drm/ast/ast_drv.h83
-rw-r--r--drivers/gpu/drm/ast/ast_i2c.c20
-rw-r--r--drivers/gpu/drm/ast/ast_main.c24
-rw-r--r--drivers/gpu/drm/ast/ast_mm.c4
-rw-r--r--drivers/gpu/drm/ast/ast_mode.c200
-rw-r--r--drivers/gpu/drm/ast/ast_post.c26
-rw-r--r--drivers/gpu/drm/ast/ast_reg.h99
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7511.h16
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7511_cec.c14
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7511_drv.c104
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7533.c7
-rw-r--r--drivers/gpu/drm/bridge/imx/Kconfig11
-rw-r--r--drivers/gpu/drm/bridge/imx/Makefile1
-rw-r--r--drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c917
-rw-r--r--drivers/gpu/drm/bridge/lontium-lt9611uxc.c10
-rw-r--r--drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c57
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c97
-rw-r--r--drivers/gpu/drm/ci/arm.config1
-rw-r--r--drivers/gpu/drm/ci/arm64.config2
-rw-r--r--drivers/gpu/drm/ci/build.sh8
-rw-r--r--drivers/gpu/drm/ci/build.yml1
-rw-r--r--drivers/gpu/drm/ci/gitlab-ci.yml38
-rwxr-xr-xdrivers/gpu/drm/ci/igt_runner.sh31
-rw-r--r--drivers/gpu/drm/ci/image-tags.yml6
-rwxr-xr-xdrivers/gpu/drm/ci/lava-submit.sh6
-rw-r--r--drivers/gpu/drm/ci/test.yml34
-rw-r--r--drivers/gpu/drm/ci/xfails/amdgpu-stoney-fails.txt12
-rw-r--r--drivers/gpu/drm/ci/xfails/amdgpu-stoney-flakes.txt20
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-amly-fails.txt9
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-amly-flakes.txt32
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-apl-fails.txt11
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-apl-flakes.txt1
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-cml-fails.txt14
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-cml-flakes.txt38
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-glk-fails.txt17
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-glk-flakes.txt41
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-kbl-fails.txt7
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-kbl-flakes.txt25
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-tgl-fails.txt1
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-tgl-flakes.txt5
-rw-r--r--drivers/gpu/drm/ci/xfails/i915-whl-flakes.txt1
-rw-r--r--drivers/gpu/drm/ci/xfails/mediatek-mt8173-flakes.txt0
-rw-r--r--drivers/gpu/drm/ci/xfails/mediatek-mt8183-fails.txt5
-rw-r--r--drivers/gpu/drm/ci/xfails/mediatek-mt8183-flakes.txt14
-rw-r--r--drivers/gpu/drm/ci/xfails/meson-g12b-fails.txt14
-rw-r--r--drivers/gpu/drm/ci/xfails/meson-g12b-flakes.txt4
-rw-r--r--drivers/gpu/drm/ci/xfails/msm-apq8016-flakes.txt4
-rw-r--r--drivers/gpu/drm/ci/xfails/msm-apq8096-fails.txt2
-rw-r--r--drivers/gpu/drm/ci/xfails/msm-apq8096-flakes.txt4
-rw-r--r--drivers/gpu/drm/ci/xfails/msm-sc7180-fails.txt15
-rw-r--r--drivers/gpu/drm/ci/xfails/msm-sc7180-flakes.txt24
-rw-r--r--drivers/gpu/drm/ci/xfails/msm-sc7180-skips.txt18
-rw-r--r--drivers/gpu/drm/ci/xfails/msm-sdm845-fails.txt9
-rw-r--r--drivers/gpu/drm/ci/xfails/msm-sdm845-flakes.txt19
-rw-r--r--drivers/gpu/drm/ci/xfails/requirements.txt17
-rw-r--r--drivers/gpu/drm/ci/xfails/rockchip-rk3288-fails.txt6
-rw-r--r--drivers/gpu/drm/ci/xfails/rockchip-rk3288-flakes.txt9
-rw-r--r--drivers/gpu/drm/ci/xfails/rockchip-rk3399-fails.txt40
-rw-r--r--drivers/gpu/drm/ci/xfails/rockchip-rk3399-flakes.txt28
-rwxr-xr-xdrivers/gpu/drm/ci/xfails/update-xfails.py204
-rw-r--r--drivers/gpu/drm/ci/xfails/virtio_gpu-none-flakes.txt0
-rw-r--r--drivers/gpu/drm/drm_client.c13
-rw-r--r--drivers/gpu/drm/drm_fourcc.c8
-rw-r--r--drivers/gpu/drm/drm_gpuvm.c2
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_sched.c1
-rw-r--r--drivers/gpu/drm/lima/lima_sched.c4
-rw-r--r--drivers/gpu/drm/msm/msm_ringbuffer.c5
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_sched.c1
-rw-r--r--drivers/gpu/drm/panel/Kconfig9
-rw-r--r--drivers/gpu/drm/panel/Makefile1
-rw-r--r--drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c371
-rw-r--r--drivers/gpu/drm/panel/panel-ilitek-ili9882t.c779
-rw-r--r--drivers/gpu/drm/panel/panel-sitronix-st7703.c125
-rw-r--r--drivers/gpu/drm/panfrost/panfrost_job.c1
-rw-r--r--drivers/gpu/drm/radeon/atombios.h42
-rw-r--r--drivers/gpu/drm/renesas/shmobile/Kconfig3
-rw-r--r--drivers/gpu/drm/renesas/shmobile/Makefile3
-rw-r--r--drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.c82
-rw-r--r--drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.h19
-rw-r--r--drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c650
-rw-r--r--drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h27
-rw-r--r--drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c179
-rw-r--r--drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h18
-rw-r--r--drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c77
-rw-r--r--drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.h9
-rw-r--r--drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c326
-rw-r--r--drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.h5
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_gem.c2
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop.c36
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop.h1
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop2.c77
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop2.h3
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_vop2_reg.c55
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_vop_reg.c66
-rw-r--r--drivers/gpu/drm/scheduler/sched_entity.c18
-rw-r--r--drivers/gpu/drm/scheduler/sched_main.c74
-rw-r--r--drivers/gpu/drm/solomon/Kconfig12
-rw-r--r--drivers/gpu/drm/solomon/ssd130x-i2c.c18
-rw-r--r--drivers/gpu/drm/solomon/ssd130x-spi.c27
-rw-r--r--drivers/gpu/drm/solomon/ssd130x.c523
-rw-r--r--drivers/gpu/drm/solomon/ssd130x.h17
-rw-r--r--drivers/gpu/drm/v3d/v3d_sched.c5
-rw-r--r--drivers/gpu/drm/vc4/vc4_regs.h2
288 files changed, 6549 insertions, 3341 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
index d58e74ae8ade..2afecc55090f 100644
--- a/drivers/gpu/drm/amd/amdgpu/Makefile
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile
@@ -104,7 +104,8 @@ amdgpu-y += \
amdgpu-y += \
df_v1_7.o \
df_v3_6.o \
- df_v4_3.o
+ df_v4_3.o \
+ df_v4_6_2.o
# add GMC block
amdgpu-y += \
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 8df702eaa2ad..8b4ca2576a3d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -363,9 +363,6 @@ struct amdgpu_ip_block_version {
const struct amd_ip_funcs *funcs;
};
-#define HW_REV(_Major, _Minor, _Rev) \
- ((((uint32_t) (_Major)) << 16) | ((uint32_t) (_Minor) << 8) | ((uint32_t) (_Rev)))
-
struct amdgpu_ip_block {
struct amdgpu_ip_block_status status;
const struct amdgpu_ip_block_version *version;
@@ -1119,6 +1116,13 @@ static inline uint32_t amdgpu_ip_version(const struct amdgpu_device *adev,
return adev->ip_versions[ip][inst] & ~0xFFU;
}
+static inline uint32_t amdgpu_ip_version_full(const struct amdgpu_device *adev,
+ uint8_t ip, uint8_t inst)
+{
+ /* This returns full version - major/minor/rev/variant/subrevision */
+ return adev->ip_versions[ip][inst];
+}
+
static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev)
{
return container_of(ddev, struct amdgpu_device, ddev);
@@ -1333,9 +1337,7 @@ void amdgpu_device_pci_config_reset(struct amdgpu_device *adev);
int amdgpu_device_pci_reset(struct amdgpu_device *adev);
bool amdgpu_device_need_post(struct amdgpu_device *adev);
bool amdgpu_device_seamless_boot_supported(struct amdgpu_device *adev);
-bool amdgpu_device_pcie_dynamic_switching_supported(void);
bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev);
-bool amdgpu_device_aspm_support_quirk(void);
void amdgpu_cs_report_moved_bytes(struct amdgpu_device *adev, u64 num_bytes,
u64 num_vis_bytes);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
index 2bca37044ad0..d62e49758635 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
@@ -68,7 +68,7 @@ struct amdgpu_acpi_xcc_info {
struct amdgpu_acpi_dev_info {
struct list_head list;
struct list_head xcc_list;
- uint16_t bdf;
+ uint32_t sbdf;
uint16_t supp_xcp_mode;
uint16_t xcp_mode;
uint16_t mem_mode;
@@ -927,7 +927,7 @@ static acpi_status amdgpu_acpi_get_node_id(acpi_handle handle,
#endif
}
-static struct amdgpu_acpi_dev_info *amdgpu_acpi_get_dev(u16 bdf)
+static struct amdgpu_acpi_dev_info *amdgpu_acpi_get_dev(u32 sbdf)
{
struct amdgpu_acpi_dev_info *acpi_dev;
@@ -935,14 +935,14 @@ static struct amdgpu_acpi_dev_info *amdgpu_acpi_get_dev(u16 bdf)
return NULL;
list_for_each_entry(acpi_dev, &amdgpu_acpi_dev_list, list)
- if (acpi_dev->bdf == bdf)
+ if (acpi_dev->sbdf == sbdf)
return acpi_dev;
return NULL;
}
static int amdgpu_acpi_dev_init(struct amdgpu_acpi_dev_info **dev_info,
- struct amdgpu_acpi_xcc_info *xcc_info, u16 bdf)
+ struct amdgpu_acpi_xcc_info *xcc_info, u32 sbdf)
{
struct amdgpu_acpi_dev_info *tmp;
union acpi_object *obj;
@@ -955,7 +955,7 @@ static int amdgpu_acpi_dev_init(struct amdgpu_acpi_dev_info **dev_info,
INIT_LIST_HEAD(&tmp->xcc_list);
INIT_LIST_HEAD(&tmp->list);
- tmp->bdf = bdf;
+ tmp->sbdf = sbdf;
obj = acpi_evaluate_dsm_typed(xcc_info->handle, &amd_xcc_dsm_guid, 0,
AMD_XCC_DSM_GET_SUPP_MODE, NULL,
@@ -1007,7 +1007,7 @@ static int amdgpu_acpi_dev_init(struct amdgpu_acpi_dev_info **dev_info,
DRM_DEBUG_DRIVER(
"New dev(%x): Supported xcp mode: %x curr xcp_mode : %x mem mode : %x, tmr base: %llx tmr size: %llx ",
- tmp->bdf, tmp->supp_xcp_mode, tmp->xcp_mode, tmp->mem_mode,
+ tmp->sbdf, tmp->supp_xcp_mode, tmp->xcp_mode, tmp->mem_mode,
tmp->tmr_base, tmp->tmr_size);
list_add_tail(&tmp->list, &amdgpu_acpi_dev_list);
*dev_info = tmp;
@@ -1023,7 +1023,7 @@ out:
}
static int amdgpu_acpi_get_xcc_info(struct amdgpu_acpi_xcc_info *xcc_info,
- u16 *bdf)
+ u32 *sbdf)
{
union acpi_object *obj;
acpi_status status;
@@ -1054,8 +1054,10 @@ static int amdgpu_acpi_get_xcc_info(struct amdgpu_acpi_xcc_info *xcc_info,
xcc_info->phy_id = (obj->integer.value >> 32) & 0xFF;
/* xcp node of this xcc [47:40] */
xcc_info->xcp_node = (obj->integer.value >> 40) & 0xFF;
+ /* PF domain of this xcc [31:16] */
+ *sbdf = (obj->integer.value) & 0xFFFF0000;
/* PF bus/dev/fn of this xcc [63:48] */
- *bdf = (obj->integer.value >> 48) & 0xFFFF;
+ *sbdf |= (obj->integer.value >> 48) & 0xFFFF;
ACPI_FREE(obj);
obj = NULL;
@@ -1079,7 +1081,7 @@ static int amdgpu_acpi_enumerate_xcc(void)
struct acpi_device *acpi_dev;
char hid[ACPI_ID_LEN];
int ret, id;
- u16 bdf;
+ u32 sbdf;
INIT_LIST_HEAD(&amdgpu_acpi_dev_list);
xa_init(&numa_info_xa);
@@ -1107,16 +1109,16 @@ static int amdgpu_acpi_enumerate_xcc(void)
xcc_info->handle = acpi_device_handle(acpi_dev);
acpi_dev_put(acpi_dev);
- ret = amdgpu_acpi_get_xcc_info(xcc_info, &bdf);
+ ret = amdgpu_acpi_get_xcc_info(xcc_info, &sbdf);
if (ret) {
kfree(xcc_info);
continue;
}
- dev_info = amdgpu_acpi_get_dev(bdf);
+ dev_info = amdgpu_acpi_get_dev(sbdf);
if (!dev_info)
- ret = amdgpu_acpi_dev_init(&dev_info, xcc_info, bdf);
+ ret = amdgpu_acpi_dev_init(&dev_info, xcc_info, sbdf);
if (ret == -ENOMEM)
return ret;
@@ -1136,13 +1138,14 @@ int amdgpu_acpi_get_tmr_info(struct amdgpu_device *adev, u64 *tmr_offset,
u64 *tmr_size)
{
struct amdgpu_acpi_dev_info *dev_info;
- u16 bdf;
+ u32 sbdf;
if (!tmr_offset || !tmr_size)
return -EINVAL;
- bdf = pci_dev_id(adev->pdev);
- dev_info = amdgpu_acpi_get_dev(bdf);
+ sbdf = (pci_domain_nr(adev->pdev->bus) << 16);
+ sbdf |= pci_dev_id(adev->pdev);
+ dev_info = amdgpu_acpi_get_dev(sbdf);
if (!dev_info)
return -ENOENT;
@@ -1157,13 +1160,14 @@ int amdgpu_acpi_get_mem_info(struct amdgpu_device *adev, int xcc_id,
{
struct amdgpu_acpi_dev_info *dev_info;
struct amdgpu_acpi_xcc_info *xcc_info;
- u16 bdf;
+ u32 sbdf;
if (!numa_info)
return -EINVAL;
- bdf = pci_dev_id(adev->pdev);
- dev_info = amdgpu_acpi_get_dev(bdf);
+ sbdf = (pci_domain_nr(adev->pdev->bus) << 16);
+ sbdf |= pci_dev_id(adev->pdev);
+ dev_info = amdgpu_acpi_get_dev(sbdf);
if (!dev_info)
return -ENOENT;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index bd1d4b2b6b16..23448359838b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -425,6 +425,32 @@ validate_fail:
return ret;
}
+static int amdgpu_amdkfd_bo_validate_and_fence(struct amdgpu_bo *bo,
+ uint32_t domain,
+ struct dma_fence *fence)
+{
+ int ret = amdgpu_bo_reserve(bo, false);
+
+ if (ret)
+ return ret;
+
+ ret = amdgpu_amdkfd_bo_validate(bo, domain, true);
+ if (ret)
+ goto unreserve_out;
+
+ ret = dma_resv_reserve_fences(bo->tbo.base.resv, 1);
+ if (ret)
+ goto unreserve_out;
+
+ dma_resv_add_fence(bo->tbo.base.resv, fence,
+ DMA_RESV_USAGE_BOOKKEEP);
+
+unreserve_out:
+ amdgpu_bo_unreserve(bo);
+
+ return ret;
+}
+
static int amdgpu_amdkfd_validate_vm_bo(void *_unused, struct amdgpu_bo *bo)
{
return amdgpu_amdkfd_bo_validate(bo, bo->allowed_domains, false);
@@ -1784,6 +1810,15 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
}
bo->allowed_domains = AMDGPU_GEM_DOMAIN_GTT;
bo->preferred_domains = AMDGPU_GEM_DOMAIN_GTT;
+ } else {
+ mutex_lock(&avm->process_info->lock);
+ if (avm->process_info->eviction_fence &&
+ !dma_fence_is_signaled(&avm->process_info->eviction_fence->base))
+ ret = amdgpu_amdkfd_bo_validate_and_fence(bo, domain,
+ &avm->process_info->eviction_fence->base);
+ mutex_unlock(&avm->process_info->lock);
+ if (ret)
+ goto err_validate_bo;
}
if (offset)
@@ -1793,6 +1828,7 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
allocate_init_user_pages_failed:
err_pin_bo:
+err_validate_bo:
remove_kgd_mem_from_kfd_bo_list(*mem, avm->process_info);
drm_vma_node_revoke(&gobj->vma_node, drm_priv);
err_node_allow:
@@ -1866,10 +1902,6 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
if (unlikely(ret))
return ret;
- /* The eviction fence should be removed by the last unmap.
- * TODO: Log an error condition if the bo still has the eviction fence
- * attached
- */
amdgpu_amdkfd_remove_eviction_fence(mem->bo,
process_info->eviction_fence);
pr_debug("Release VA 0x%llx - 0x%llx\n", mem->va,
@@ -1998,19 +2030,6 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
if (unlikely(ret))
goto out_unreserve;
- if (mem->mapped_to_gpu_memory == 0 &&
- !amdgpu_ttm_tt_get_usermm(bo->tbo.ttm)) {
- /* Validate BO only once. The eviction fence gets added to BO
- * the first time it is mapped. Validate will wait for all
- * background evictions to complete.
- */
- ret = amdgpu_amdkfd_bo_validate(bo, domain, true);
- if (ret) {
- pr_debug("Validate failed\n");
- goto out_unreserve;
- }
- }
-
list_for_each_entry(entry, &mem->attachments, list) {
if (entry->bo_va->base.vm != avm || entry->is_mapped)
continue;
@@ -2037,10 +2056,6 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
mem->mapped_to_gpu_memory);
}
- if (!amdgpu_ttm_tt_get_usermm(bo->tbo.ttm) && !bo->tbo.pin_count)
- dma_resv_add_fence(bo->tbo.base.resv,
- &avm->process_info->eviction_fence->base,
- DMA_RESV_USAGE_BOOKKEEP);
ret = unreserve_bo_and_vms(&ctx, false, false);
goto out;
@@ -2074,7 +2089,6 @@ int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(
struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv)
{
struct amdgpu_vm *avm = drm_priv_to_vm(drm_priv);
- struct amdkfd_process_info *process_info = avm->process_info;
unsigned long bo_size = mem->bo->tbo.base.size;
struct kfd_mem_attachment *entry;
struct bo_vm_reservation_context ctx;
@@ -2115,15 +2129,6 @@ int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(
mem->mapped_to_gpu_memory);
}
- /* If BO is unmapped from all VMs, unfence it. It can be evicted if
- * required.
- */
- if (mem->mapped_to_gpu_memory == 0 &&
- !amdgpu_ttm_tt_get_usermm(mem->bo->tbo.ttm) &&
- !mem->bo->tbo.pin_count)
- amdgpu_amdkfd_remove_eviction_fence(mem->bo,
- process_info->eviction_fence);
-
unreserve_out:
unreserve_bo_and_vms(&ctx, false, false);
out:
@@ -2351,8 +2356,20 @@ int amdgpu_amdkfd_gpuvm_import_dmabuf(struct amdgpu_device *adev,
amdgpu_sync_create(&(*mem)->sync);
(*mem)->is_imported = true;
+ mutex_lock(&avm->process_info->lock);
+ if (avm->process_info->eviction_fence &&
+ !dma_fence_is_signaled(&avm->process_info->eviction_fence->base))
+ ret = amdgpu_amdkfd_bo_validate_and_fence(bo, (*mem)->domain,
+ &avm->process_info->eviction_fence->base);
+ mutex_unlock(&avm->process_info->lock);
+ if (ret)
+ goto err_remove_mem;
+
return 0;
+err_remove_mem:
+ remove_kgd_mem_from_kfd_bo_list(*mem, avm->process_info);
+ drm_vma_node_revoke(&obj->vma_node, drm_priv);
err_free_mem:
kfree(*mem);
err_put_obj:
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
index 38ccec913f00..f3a09ecb7699 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
@@ -29,6 +29,7 @@
#include "amdgpu.h"
#include "atom.h"
+#include <linux/device.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/acpi.h>
@@ -287,6 +288,10 @@ static bool amdgpu_atrm_get_bios(struct amdgpu_device *adev)
if (adev->flags & AMD_IS_APU)
return false;
+ /* ATRM is for on-platform devices only */
+ if (dev_is_removable(&adev->pdev->dev))
+ return false;
+
while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
dhandle = ACPI_HANDLE(&pdev->dev);
if (!dhandle)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 122472d88756..0245de81cabd 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -1116,6 +1116,11 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
return r;
}
+ /* FIXME: In theory this loop shouldn't be needed any more when
+ * amdgpu_vm_handle_moved handles all moved BOs that are reserved
+ * with p->ticket. But removing it caused test regressions, so I'm
+ * leaving it here for now.
+ */
amdgpu_bo_list_for_each_entry(e, p->bo_list) {
bo_va = e->bo_va;
if (bo_va == NULL)
@@ -1130,7 +1135,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
return r;
}
- r = amdgpu_vm_handle_moved(adev, vm);
+ r = amdgpu_vm_handle_moved(adev, vm, &p->exec.ticket);
if (r)
return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
index 3136a0774dd9..a53f436fa9f1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
@@ -748,6 +748,9 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf,
ssize_t result = 0;
int r;
+ if (!adev->smc_rreg)
+ return -EPERM;
+
if (size & 0x3 || *pos & 0x3)
return -EINVAL;
@@ -804,6 +807,9 @@ static ssize_t amdgpu_debugfs_regs_smc_write(struct file *f, const char __user *
ssize_t result = 0;
int r;
+ if (!adev->smc_wreg)
+ return -EPERM;
+
if (size & 0x3 || *pos & 0x3)
return -EINVAL;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 9340e8dc0413..fd8cd8e2d3f2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -41,6 +41,7 @@
#include <drm/drm_fb_helper.h>
#include <drm/drm_probe_helper.h>
#include <drm/amdgpu_drm.h>
+#include <linux/device.h>
#include <linux/vgaarb.h>
#include <linux/vga_switcheroo.h>
#include <linux/efi.h>
@@ -1073,6 +1074,8 @@ static int amdgpu_device_asic_init(struct amdgpu_device *adev)
amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(11, 0, 0)) {
amdgpu_psp_wait_for_bootloader(adev);
ret = amdgpu_atomfirmware_asic_init(adev, true);
+ /* TODO: check the return val and stop device initialization if boot fails */
+ amdgpu_psp_query_boot_status(adev);
return ret;
} else {
return amdgpu_atom_asic_init(adev->mode_info.atom_context);
@@ -1456,14 +1459,14 @@ bool amdgpu_device_seamless_boot_supported(struct amdgpu_device *adev)
}
/*
- * Intel hosts such as Raptor Lake and Sapphire Rapids don't support dynamic
- * speed switching. Until we have confirmation from Intel that a specific host
- * supports it, it's safer that we keep it disabled for all.
+ * Intel hosts such as Rocket Lake, Alder Lake, Raptor Lake and Sapphire Rapids
+ * don't support dynamic speed switching. Until we have confirmation from Intel
+ * that a specific host supports it, it's safer that we keep it disabled for all.
*
* https://edc.intel.com/content/www/us/en/design/products/platforms/details/raptor-lake-s/13th-generation-core-processors-datasheet-volume-1-of-2/005/pci-express-support/
* https://gitlab.freedesktop.org/drm/amd/-/issues/2663
*/
-bool amdgpu_device_pcie_dynamic_switching_supported(void)
+static bool amdgpu_device_pcie_dynamic_switching_supported(void)
{
#if IS_ENABLED(CONFIG_X86)
struct cpuinfo_x86 *c = &cpu_data(0);
@@ -1496,20 +1499,13 @@ bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev)
default:
return false;
}
+ if (adev->flags & AMD_IS_APU)
+ return false;
+ if (!(adev->pm.pp_feature & PP_PCIE_DPM_MASK))
+ return false;
return pcie_aspm_enabled(adev->pdev);
}
-bool amdgpu_device_aspm_support_quirk(void)
-{
-#if IS_ENABLED(CONFIG_X86)
- struct cpuinfo_x86 *c = &cpu_data(0);
-
- return !(c->x86 == 6 && c->x86_model == INTEL_FAM6_ALDERLAKE);
-#else
- return true;
-#endif
-}
-
/* if we get transitioned to only one device, take VGA back */
/**
* amdgpu_device_vga_set_decode - enable/disable vga decode
@@ -2230,7 +2226,6 @@ out:
*/
static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
{
- struct drm_device *dev = adev_to_drm(adev);
struct pci_dev *parent;
int i, r;
bool total;
@@ -2301,7 +2296,7 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
(amdgpu_is_atpx_hybrid() ||
amdgpu_has_atpx_dgpu_power_cntl()) &&
((adev->flags & AMD_IS_APU) == 0) &&
- !pci_is_thunderbolt_attached(to_pci_dev(dev->dev)))
+ !dev_is_removable(&adev->pdev->dev))
adev->flags |= AMD_IS_PX;
if (!(adev->flags & AMD_IS_APU)) {
@@ -2315,6 +2310,8 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
if (amdgpu_sriov_vf(adev) && adev->asic_type == CHIP_SIENNA_CICHLID)
adev->pm.pp_feature &= ~PP_OVERDRIVE_MASK;
+ if (!amdgpu_device_pcie_dynamic_switching_supported())
+ adev->pm.pp_feature &= ~PP_PCIE_DPM_MASK;
total = true;
for (i = 0; i < adev->num_ip_blocks; i++) {
@@ -2492,6 +2489,7 @@ static int amdgpu_device_init_schedulers(struct amdgpu_device *adev)
}
r = drm_sched_init(&ring->sched, &amdgpu_sched_ops,
+ DRM_SCHED_PRIORITY_COUNT,
ring->num_hw_submission, 0,
timeout, adev->reset_domain->wq,
ring->sched_score, ring->name,
@@ -2661,6 +2659,9 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
if (r)
goto init_failed;
+ if (adev->mman.buffer_funcs_ring->sched.ready)
+ amdgpu_ttm_set_buffer_funcs_status(adev, true);
+
/* Don't init kfd if whole hive need to be reset during init */
if (!adev->gmc.xgmi.pending_reset) {
kgd2kfd_init_zone_device(adev);
@@ -3258,6 +3259,8 @@ int amdgpu_device_ip_suspend(struct amdgpu_device *adev)
amdgpu_virt_request_full_gpu(adev, false);
}
+ amdgpu_ttm_set_buffer_funcs_status(adev, false);
+
r = amdgpu_device_ip_suspend_phase1(adev);
if (r)
return r;
@@ -3447,6 +3450,9 @@ static int amdgpu_device_ip_resume(struct amdgpu_device *adev)
r = amdgpu_device_ip_resume_phase2(adev);
+ if (adev->mman.buffer_funcs_ring->sched.ready)
+ amdgpu_ttm_set_buffer_funcs_status(adev, true);
+
return r;
}
@@ -3958,13 +3964,23 @@ int amdgpu_device_init(struct amdgpu_device *adev,
}
}
} else {
- tmp = amdgpu_reset_method;
- /* It should do a default reset when loading or reloading the driver,
- * regardless of the module parameter reset_method.
- */
- amdgpu_reset_method = AMD_RESET_METHOD_NONE;
- r = amdgpu_asic_reset(adev);
- amdgpu_reset_method = tmp;
+ switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) {
+ case IP_VERSION(13, 0, 0):
+ case IP_VERSION(13, 0, 7):
+ case IP_VERSION(13, 0, 10):
+ r = psp_gpu_reset(adev);
+ break;
+ default:
+ tmp = amdgpu_reset_method;
+ /* It should do a default reset when loading or reloading the driver,
+ * regardless of the module parameter reset_method.
+ */
+ amdgpu_reset_method = AMD_RESET_METHOD_NONE;
+ r = amdgpu_asic_reset(adev);
+ amdgpu_reset_method = tmp;
+ break;
+ }
+
if (r) {
dev_err(adev->dev, "asic reset on init failed\n");
goto failed;
@@ -4128,7 +4144,7 @@ fence_driver_init:
px = amdgpu_device_supports_px(ddev);
- if (px || (!pci_is_thunderbolt_attached(adev->pdev) &&
+ if (px || (!dev_is_removable(&adev->pdev->dev) &&
apple_gmux_detect(NULL, NULL)))
vga_switcheroo_register_client(adev->pdev,
&amdgpu_switcheroo_ops, px);
@@ -4234,6 +4250,8 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
/* disable ras feature must before hw fini */
amdgpu_ras_pre_fini(adev);
+ amdgpu_ttm_set_buffer_funcs_status(adev, false);
+
amdgpu_device_ip_fini_early(adev);
amdgpu_irq_fini_hw(adev);
@@ -4276,7 +4294,7 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev)
px = amdgpu_device_supports_px(adev_to_drm(adev));
- if (px || (!pci_is_thunderbolt_attached(adev->pdev) &&
+ if (px || (!dev_is_removable(&adev->pdev->dev) &&
apple_gmux_detect(NULL, NULL)))
vga_switcheroo_unregister_client(adev->pdev);
@@ -4405,6 +4423,8 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon)
amdgpu_ras_suspend(adev);
+ amdgpu_ttm_set_buffer_funcs_status(adev, false);
+
amdgpu_device_ip_suspend_phase1(adev);
if (!adev->in_s0ix)
@@ -5176,6 +5196,9 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle,
if (r)
goto out;
+ if (tmp_adev->mman.buffer_funcs_ring->sched.ready)
+ amdgpu_ttm_set_buffer_funcs_status(tmp_adev, true);
+
if (vram_lost)
amdgpu_device_fill_reset_magic(tmp_adev);
@@ -5555,10 +5578,6 @@ skip_hw_reset:
drm_sched_start(&ring->sched, true);
}
- if (adev->enable_mes &&
- amdgpu_ip_version(adev, GC_HWIP, 0) != IP_VERSION(11, 0, 3))
- amdgpu_mes_self_test(tmp_adev);
-
if (!drm_drv_uses_atomic_modeset(adev_to_drm(tmp_adev)) && !job_signaled)
drm_helper_resume_force_mode(adev_to_drm(tmp_adev));
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index b6cddcad122f..0431eafa86b5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -35,6 +35,7 @@
#include "df_v1_7.h"
#include "df_v3_6.h"
#include "df_v4_3.h"
+#include "df_v4_6_2.h"
#include "nbio_v6_1.h"
#include "nbio_v7_0.h"
#include "nbio_v7_4.h"
@@ -98,6 +99,7 @@
MODULE_FIRMWARE(FIRMWARE_IP_DISCOVERY);
#define mmRCC_CONFIG_MEMSIZE 0xde3
+#define mmMP0_SMN_C2PMSG_33 0x16061
#define mmMM_INDEX 0x0
#define mmMM_INDEX_HI 0x6
#define mmMM_DATA 0x1
@@ -238,8 +240,26 @@ static int amdgpu_discovery_read_binary_from_sysmem(struct amdgpu_device *adev,
static int amdgpu_discovery_read_binary_from_mem(struct amdgpu_device *adev,
uint8_t *binary)
{
- uint64_t vram_size = (uint64_t)RREG32(mmRCC_CONFIG_MEMSIZE) << 20;
- int ret = 0;
+ uint64_t vram_size;
+ u32 msg;
+ int i, ret = 0;
+
+ /* It can take up to a second for IFWI init to complete on some dGPUs,
+ * but generally it should be in the 60-100ms range. Normally this starts
+ * as soon as the device gets power so by the time the OS loads this has long
+ * completed. However, when a card is hotplugged via e.g., USB4, we need to
+ * wait for this to complete. Once the C2PMSG is updated, we can
+ * continue.
+ */
+ if (dev_is_removable(&adev->pdev->dev)) {
+ for (i = 0; i < 1000; i++) {
+ msg = RREG32(mmMP0_SMN_C2PMSG_33);
+ if (msg & 0x80000000)
+ break;
+ msleep(1);
+ }
+ }
+ vram_size = (uint64_t)RREG32(mmRCC_CONFIG_MEMSIZE) << 20;
if (vram_size) {
uint64_t pos = vram_size - DISCOVERY_TMR_OFFSET;
@@ -1487,7 +1507,7 @@ static int amdgpu_discovery_get_gfx_info(struct amdgpu_device *adev)
adev->gfx.config.num_sc_per_sh = le32_to_cpu(gc_info->v2.gc_num_sc_per_se) /
le32_to_cpu(gc_info->v2.gc_num_sh_per_se);
adev->gfx.config.num_packer_per_sc = le32_to_cpu(gc_info->v2.gc_num_packer_per_sc);
- if (le16_to_cpu(gc_info->v2.header.version_minor == 1)) {
+ if (le16_to_cpu(gc_info->v2.header.version_minor) == 1) {
adev->gfx.config.gc_num_tcp_per_sa = le32_to_cpu(gc_info->v2_1.gc_num_tcp_per_sh);
adev->gfx.config.gc_tcp_size_per_cu = le32_to_cpu(gc_info->v2_1.gc_tcp_size_per_cu);
adev->gfx.config.gc_num_sdp_interface = le32_to_cpu(gc_info->v2_1.gc_num_sdp_interface); /* per XCD */
@@ -2448,6 +2468,9 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
if (amdgpu_ip_version(adev, XGMI_HWIP, 0) == IP_VERSION(4, 8, 0))
adev->gmc.xgmi.supported = true;
+ if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3))
+ adev->ip_versions[XGMI_HWIP][0] = IP_VERSION(6, 4, 0);
+
/* set NBIO version */
switch (amdgpu_ip_version(adev, NBIO_HWIP, 0)) {
case IP_VERSION(6, 1, 0):
@@ -2559,6 +2582,9 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
case IP_VERSION(4, 3, 0):
adev->df.funcs = &df_v4_3_funcs;
break;
+ case IP_VERSION(4, 6, 2):
+ adev->df.funcs = &df_v4_6_2_funcs;
+ break;
default:
break;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
index b5e28fa3f414..e7e87a3b2601 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
@@ -409,7 +409,7 @@ amdgpu_dma_buf_move_notify(struct dma_buf_attachment *attach)
if (!r)
r = amdgpu_vm_clear_freed(adev, vm, NULL);
if (!r)
- r = amdgpu_vm_handle_moved(adev, vm);
+ r = amdgpu_vm_handle_moved(adev, vm, ticket);
if (r && r != -EBUSY)
DRM_ERROR("Failed to invalidate VM page tables (%d))\n",
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 6cc6e3991410..3095a3a864af 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -2041,6 +2041,14 @@ static const struct pci_device_id pciidlist[] = {
MODULE_DEVICE_TABLE(pci, pciidlist);
+static const struct amdgpu_asic_type_quirk asic_type_quirks[] = {
+ /* differentiate between P10 and P11 asics with the same DID */
+ {0x67FF, 0xE3, CHIP_POLARIS10},
+ {0x67FF, 0xE7, CHIP_POLARIS10},
+ {0x67FF, 0xF3, CHIP_POLARIS10},
+ {0x67FF, 0xF7, CHIP_POLARIS10},
+};
+
static const struct drm_driver amdgpu_kms_driver;
static void amdgpu_get_secondary_funcs(struct amdgpu_device *adev)
@@ -2083,6 +2091,22 @@ static void amdgpu_init_debug_options(struct amdgpu_device *adev)
}
}
+static unsigned long amdgpu_fix_asic_type(struct pci_dev *pdev, unsigned long flags)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(asic_type_quirks); i++) {
+ if (pdev->device == asic_type_quirks[i].device &&
+ pdev->revision == asic_type_quirks[i].revision) {
+ flags &= ~AMD_ASIC_MASK;
+ flags |= asic_type_quirks[i].type;
+ break;
+ }
+ }
+
+ return flags;
+}
+
static int amdgpu_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -2110,15 +2134,8 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
"See modparam exp_hw_support\n");
return -ENODEV;
}
- /* differentiate between P10 and P11 asics with the same DID */
- if (pdev->device == 0x67FF &&
- (pdev->revision == 0xE3 ||
- pdev->revision == 0xE7 ||
- pdev->revision == 0xF3 ||
- pdev->revision == 0xF7)) {
- flags &= ~AMD_ASIC_MASK;
- flags |= CHIP_POLARIS10;
- }
+
+ flags = amdgpu_fix_asic_type(pdev, flags);
/* Due to hardware bugs, S/G Display on raven requires a 1:1 IOMMU mapping,
* however, SME requires an indirect IOMMU mapping because the encryption
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c
index cba7e6cdc7cc..5706b282a0c7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c
@@ -56,21 +56,15 @@ static const char *amdgpu_ip_name[AMDGPU_HW_IP_NUM] = {
void amdgpu_show_fdinfo(struct drm_printer *p, struct drm_file *file)
{
- struct amdgpu_device *adev = drm_to_adev(file->minor->dev);
struct amdgpu_fpriv *fpriv = file->driver_priv;
struct amdgpu_vm *vm = &fpriv->vm;
struct amdgpu_mem_stats stats;
ktime_t usage[AMDGPU_HW_IP_NUM];
- uint32_t bus, dev, fn, domain;
unsigned int hw_ip;
int ret;
memset(&stats, 0, sizeof(stats));
- bus = adev->pdev->bus->number;
- domain = pci_domain_nr(adev->pdev->bus);
- dev = PCI_SLOT(adev->pdev->devfn);
- fn = PCI_FUNC(adev->pdev->devfn);
ret = amdgpu_bo_reserve(vm->root.bo, false);
if (ret)
@@ -88,9 +82,6 @@ void amdgpu_show_fdinfo(struct drm_printer *p, struct drm_file *file)
*/
drm_printf(p, "pasid:\t%u\n", fpriv->vm.pasid);
- drm_printf(p, "drm-driver:\t%s\n", file->minor->dev->driver->name);
- drm_printf(p, "drm-pdev:\t%04x:%02x:%02x.%d\n", domain, bus, dev, fn);
- drm_printf(p, "drm-client-id:\t%llu\n", vm->immediate.fence_context);
drm_printf(p, "drm-memory-vram:\t%llu KiB\n", stats.vram/1024UL);
drm_printf(p, "drm-memory-gtt: \t%llu KiB\n", stats.gtt/1024UL);
drm_printf(p, "drm-memory-cpu: \t%llu KiB\n", stats.cpu/1024UL);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
index c92e0aba69e1..a2a29dcb2422 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
@@ -385,9 +385,11 @@ int amdgpu_gfx_mqd_sw_init(struct amdgpu_device *adev,
struct amdgpu_ring *ring = &kiq->ring;
u32 domain = AMDGPU_GEM_DOMAIN_GTT;
+#if !defined(CONFIG_ARM) && !defined(CONFIG_ARM64)
/* Only enable on gfx10 and 11 for now to avoid changing behavior on older chips */
if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(10, 0, 0))
domain |= AMDGPU_GEM_DOMAIN_VRAM;
+#endif
/* create MQD for KIQ */
if (!adev->enable_mes_kiq && !ring->mqd_obj) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
index a02992bff6af..2dce338b0f1e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
@@ -786,6 +786,7 @@ void amdgpu_gmc_tmz_set(struct amdgpu_device *adev)
/* YELLOW_CARP*/
case IP_VERSION(10, 3, 3):
case IP_VERSION(11, 0, 4):
+ case IP_VERSION(11, 5, 0):
/* Don't enable it by default yet.
*/
if (amdgpu_tmz < 1) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
index 78476bc75b4e..1f357198533f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -325,8 +325,8 @@ void amdgpu_job_stop_all_jobs_on_sched(struct drm_gpu_scheduler *sched)
int i;
/* Signal all jobs not yet scheduled */
- for (i = DRM_SCHED_PRIORITY_COUNT - 1; i >= DRM_SCHED_PRIORITY_MIN; i--) {
- struct drm_sched_rq *rq = &sched->sched_rq[i];
+ for (i = sched->num_rqs - 1; i >= DRM_SCHED_PRIORITY_MIN; i--) {
+ struct drm_sched_rq *rq = sched->sched_rq[i];
spin_lock(&rq->lock);
list_for_each_entry(s_entity, &rq->entities, list) {
while ((s_job = to_drm_sched_job(spsc_queue_pop(&s_entity->job_queue)))) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
index 59f10b353b3a..9ddbf1494326 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
@@ -557,8 +557,20 @@ static void amdgpu_mes_queue_init_mqd(struct amdgpu_device *adev,
mqd_prop.hqd_queue_priority = p->hqd_queue_priority;
mqd_prop.hqd_active = false;
+ if (p->queue_type == AMDGPU_RING_TYPE_GFX ||
+ p->queue_type == AMDGPU_RING_TYPE_COMPUTE) {
+ mutex_lock(&adev->srbm_mutex);
+ amdgpu_gfx_select_me_pipe_q(adev, p->ring->me, p->ring->pipe, 0, 0, 0);
+ }
+
mqd_mgr->init_mqd(adev, q->mqd_cpu_ptr, &mqd_prop);
+ if (p->queue_type == AMDGPU_RING_TYPE_GFX ||
+ p->queue_type == AMDGPU_RING_TYPE_COMPUTE) {
+ amdgpu_gfx_select_me_pipe_q(adev, 0, 0, 0, 0, 0);
+ mutex_unlock(&adev->srbm_mutex);
+ }
+
amdgpu_bo_unreserve(q->mqd_obj);
}
@@ -994,9 +1006,13 @@ int amdgpu_mes_add_ring(struct amdgpu_device *adev, int gang_id,
switch (queue_type) {
case AMDGPU_RING_TYPE_GFX:
ring->funcs = adev->gfx.gfx_ring[0].funcs;
+ ring->me = adev->gfx.gfx_ring[0].me;
+ ring->pipe = adev->gfx.gfx_ring[0].pipe;
break;
case AMDGPU_RING_TYPE_COMPUTE:
ring->funcs = adev->gfx.compute_ring[0].funcs;
+ ring->me = adev->gfx.compute_ring[0].me;
+ ring->pipe = adev->gfx.compute_ring[0].pipe;
break;
case AMDGPU_RING_TYPE_SDMA:
ring->funcs = adev->sdma.instance[0].ring.funcs;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
index 648bd5e12830..32b701cc0376 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -2120,6 +2120,21 @@ int amdgpu_psp_wait_for_bootloader(struct amdgpu_device *adev)
return ret;
}
+int amdgpu_psp_query_boot_status(struct amdgpu_device *adev)
+{
+ struct psp_context *psp = &adev->psp;
+ int ret = 0;
+
+ if (amdgpu_sriov_vf(adev) || (adev->flags & AMD_IS_APU))
+ return 0;
+
+ if (psp->funcs &&
+ psp->funcs->query_boot_status)
+ ret = psp->funcs->query_boot_status(psp);
+
+ return ret;
+}
+
static int psp_hw_start(struct psp_context *psp)
{
struct amdgpu_device *adev = psp->adev;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
index 7111dd32e66f..5d36ad3f48c7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
@@ -134,6 +134,7 @@ struct psp_funcs {
int (*update_spirom)(struct psp_context *psp, uint64_t fw_pri_mc_addr);
int (*vbflash_stat)(struct psp_context *psp);
int (*fatal_error_recovery_quirk)(struct psp_context *psp);
+ int (*query_boot_status)(struct psp_context *psp);
};
struct ta_funcs {
@@ -537,4 +538,6 @@ int is_psp_fw_valid(struct psp_bin_desc bin);
int amdgpu_psp_wait_for_bootloader(struct amdgpu_device *adev);
+int amdgpu_psp_query_boot_status(struct amdgpu_device *adev);
+
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
index 3c83a2b8fb2c..b7fe5951b166 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
@@ -635,8 +635,11 @@ static ssize_t amdgpu_ras_sysfs_read(struct device *dev,
static inline void put_obj(struct ras_manager *obj)
{
- if (obj && (--obj->use == 0))
+ if (obj && (--obj->use == 0)) {
list_del(&obj->node);
+ amdgpu_ras_error_data_fini(&obj->err_data);
+ }
+
if (obj && (obj->use < 0))
DRM_ERROR("RAS ERROR: Unbalance obj(%s) use\n", get_ras_block_str(&obj->head));
}
@@ -666,6 +669,9 @@ static struct ras_manager *amdgpu_ras_create_obj(struct amdgpu_device *adev,
if (alive_obj(obj))
return NULL;
+ if (amdgpu_ras_error_data_init(&obj->err_data))
+ return NULL;
+
obj->head = *head;
obj->adev = adev;
list_add(&obj->node, &con->head);
@@ -1023,44 +1029,68 @@ static void amdgpu_ras_get_ecc_info(struct amdgpu_device *adev, struct ras_err_d
}
static void amdgpu_ras_error_print_error_data(struct amdgpu_device *adev,
- struct ras_query_if *query_if,
+ struct ras_manager *ras_mgr,
struct ras_err_data *err_data,
+ const char *blk_name,
bool is_ue)
{
- struct ras_manager *ras_mgr = amdgpu_ras_find_obj(adev, &query_if->head);
- const char *blk_name = get_ras_block_str(&query_if->head);
struct amdgpu_smuio_mcm_config_info *mcm_info;
struct ras_err_node *err_node;
struct ras_err_info *err_info;
- if (is_ue)
- dev_info(adev->dev, "%ld uncorrectable hardware errors detected in %s block\n",
- ras_mgr->err_data.ue_count, blk_name);
- else
- dev_info(adev->dev, "%ld correctable hardware errors detected in %s block\n",
- ras_mgr->err_data.ce_count, blk_name);
+ if (is_ue) {
+ for_each_ras_error(err_node, err_data) {
+ err_info = &err_node->err_info;
+ mcm_info = &err_info->mcm_info;
+ if (err_info->ue_count) {
+ dev_info(adev->dev, "socket: %d, die: %d, "
+ "%lld new uncorrectable hardware errors detected in %s block\n",
+ mcm_info->socket_id,
+ mcm_info->die_id,
+ err_info->ue_count,
+ blk_name);
+ }
+ }
- for_each_ras_error(err_node, err_data) {
- err_info = &err_node->err_info;
- mcm_info = &err_info->mcm_info;
- if (is_ue && err_info->ue_count) {
- dev_info(adev->dev, "socket: %d, die: %d "
- "%lld uncorrectable hardware errors detected in %s block\n",
- mcm_info->socket_id,
- mcm_info->die_id,
- err_info->ue_count,
- blk_name);
- } else if (!is_ue && err_info->ce_count) {
- dev_info(adev->dev, "socket: %d, die: %d "
- "%lld correctable hardware errors detected in %s block\n",
- mcm_info->socket_id,
- mcm_info->die_id,
- err_info->ce_count,
- blk_name);
+ for_each_ras_error(err_node, &ras_mgr->err_data) {
+ err_info = &err_node->err_info;
+ mcm_info = &err_info->mcm_info;
+ dev_info(adev->dev, "socket: %d, die: %d, "
+ "%lld uncorrectable hardware errors detected in total in %s block\n",
+ mcm_info->socket_id, mcm_info->die_id, err_info->ue_count, blk_name);
+ }
+
+ } else {
+ for_each_ras_error(err_node, err_data) {
+ err_info = &err_node->err_info;
+ mcm_info = &err_info->mcm_info;
+ if (err_info->ce_count) {
+ dev_info(adev->dev, "socket: %d, die: %d, "
+ "%lld new correctable hardware errors detected in %s block, "
+ "no user action is needed\n",
+ mcm_info->socket_id,
+ mcm_info->die_id,
+ err_info->ce_count,
+ blk_name);
+ }
+ }
+
+ for_each_ras_error(err_node, &ras_mgr->err_data) {
+ err_info = &err_node->err_info;
+ mcm_info = &err_info->mcm_info;
+ dev_info(adev->dev, "socket: %d, die: %d, "
+ "%lld correctable hardware errors detected in total in %s block, "
+ "no user action is needed\n",
+ mcm_info->socket_id, mcm_info->die_id, err_info->ce_count, blk_name);
}
}
}
+static inline bool err_data_has_source_info(struct ras_err_data *data)
+{
+ return !list_empty(&data->err_node_list);
+}
+
static void amdgpu_ras_error_generate_report(struct amdgpu_device *adev,
struct ras_query_if *query_if,
struct ras_err_data *err_data)
@@ -1069,9 +1099,8 @@ static void amdgpu_ras_error_generate_report(struct amdgpu_device *adev,
const char *blk_name = get_ras_block_str(&query_if->head);
if (err_data->ce_count) {
- if (!list_empty(&err_data->err_node_list)) {
- amdgpu_ras_error_print_error_data(adev, query_if,
- err_data, false);
+ if (err_data_has_source_info(err_data)) {
+ amdgpu_ras_error_print_error_data(adev, ras_mgr, err_data, blk_name, false);
} else if (!adev->aid_mask &&
adev->smuio.funcs &&
adev->smuio.funcs->get_socket_id &&
@@ -1094,9 +1123,8 @@ static void amdgpu_ras_error_generate_report(struct amdgpu_device *adev,
}
if (err_data->ue_count) {
- if (!list_empty(&err_data->err_node_list)) {
- amdgpu_ras_error_print_error_data(adev, query_if,
- err_data, true);
+ if (err_data_has_source_info(err_data)) {
+ amdgpu_ras_error_print_error_data(adev, ras_mgr, err_data, blk_name, true);
} else if (!adev->aid_mask &&
adev->smuio.funcs &&
adev->smuio.funcs->get_socket_id &&
@@ -1118,6 +1146,25 @@ static void amdgpu_ras_error_generate_report(struct amdgpu_device *adev,
}
+static void amdgpu_rasmgr_error_data_statistic_update(struct ras_manager *obj, struct ras_err_data *err_data)
+{
+ struct ras_err_node *err_node;
+ struct ras_err_info *err_info;
+
+ if (err_data_has_source_info(err_data)) {
+ for_each_ras_error(err_node, err_data) {
+ err_info = &err_node->err_info;
+
+ amdgpu_ras_error_statistic_ce_count(&obj->err_data, &err_info->mcm_info, err_info->ce_count);
+ amdgpu_ras_error_statistic_ue_count(&obj->err_data, &err_info->mcm_info, err_info->ue_count);
+ }
+ } else {
+ /* for legacy asic path which doesn't has error source info */
+ obj->err_data.ue_count += err_data->ue_count;
+ obj->err_data.ce_count += err_data->ce_count;
+ }
+}
+
/* query/inject/cure begin */
int amdgpu_ras_query_error_status(struct amdgpu_device *adev,
struct ras_query_if *info)
@@ -1156,8 +1203,7 @@ int amdgpu_ras_query_error_status(struct amdgpu_device *adev,
}
}
- obj->err_data.ue_count += err_data.ue_count;
- obj->err_data.ce_count += err_data.ce_count;
+ amdgpu_rasmgr_error_data_statistic_update(obj, &err_data);
info->ue_count = obj->err_data.ue_count;
info->ce_count = obj->err_data.ce_count;
@@ -1174,6 +1220,10 @@ int amdgpu_ras_reset_error_count(struct amdgpu_device *adev,
enum amdgpu_ras_block block)
{
struct amdgpu_ras_block_object *block_obj = amdgpu_ras_get_ras_block(adev, block, 0);
+ struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
+ const struct amdgpu_mca_smu_funcs *mca_funcs = adev->mca.mca_funcs;
+ struct amdgpu_hive_info *hive;
+ int hive_ras_recovery = 0;
if (!block_obj || !block_obj->hw_ops) {
dev_dbg_once(adev->dev, "%s doesn't config RAS function\n",
@@ -1181,7 +1231,20 @@ int amdgpu_ras_reset_error_count(struct amdgpu_device *adev,
return -EOPNOTSUPP;
}
- if (!amdgpu_ras_is_supported(adev, block))
+ if (!amdgpu_ras_is_supported(adev, block) ||
+ !amdgpu_ras_get_mca_debug_mode(adev))
+ return -EOPNOTSUPP;
+
+ hive = amdgpu_get_xgmi_hive(adev);
+ if (hive) {
+ hive_ras_recovery = atomic_read(&hive->ras_recovery);
+ amdgpu_put_xgmi_hive(hive);
+ }
+
+ /* skip ras error reset in gpu reset */
+ if ((amdgpu_in_reset(adev) || atomic_read(&ras->in_recovery) ||
+ hive_ras_recovery) &&
+ mca_funcs && mca_funcs->mca_set_debug_mode)
return -EOPNOTSUPP;
if (block_obj->hw_ops->reset_ras_error_count)
@@ -2692,7 +2755,8 @@ static void amdgpu_ras_query_poison_mode(struct amdgpu_device *adev)
return;
/* Init poison supported flag, the default value is false */
- if (adev->gmc.xgmi.connected_to_cpu) {
+ if (adev->gmc.xgmi.connected_to_cpu ||
+ adev->gmc.is_app_apu) {
/* enabled by default when GPU is connected to CPU */
con->poison_supported = true;
} else if (adev->df.funcs &&
@@ -3529,11 +3593,10 @@ static struct ras_err_node *amdgpu_ras_error_find_node_by_id(struct ras_err_data
for_each_ras_error(err_node, err_data) {
ref_id = &err_node->err_info.mcm_info;
- if ((mcm_info->socket_id >= 0 && mcm_info->socket_id != ref_id->socket_id) ||
- (mcm_info->die_id >= 0 && mcm_info->die_id != ref_id->die_id))
- continue;
- return err_node;
+ if (mcm_info->socket_id == ref_id->socket_id &&
+ mcm_info->die_id == ref_id->die_id)
+ return err_node;
}
return NULL;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
index 2fdfef62ee27..665414c22ca9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
@@ -515,10 +515,7 @@ struct ras_manager {
/* IH data */
struct ras_ih_data ih_data;
- struct {
- unsigned long ue_count;
- unsigned long ce_count;
- } err_data;
+ struct ras_err_data err_data;
};
struct ras_badpage {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
index e8cbc4142d80..1d9d187de6ee 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
@@ -292,27 +292,6 @@ out:
return err;
}
-void amdgpu_sdma_unset_buffer_funcs_helper(struct amdgpu_device *adev)
-{
- struct amdgpu_ring *sdma;
- int i;
-
- for (i = 0; i < adev->sdma.num_instances; i++) {
- if (adev->sdma.has_page_queue) {
- sdma = &adev->sdma.instance[i].page;
- if (adev->mman.buffer_funcs_ring == sdma) {
- amdgpu_ttm_set_buffer_funcs_status(adev, false);
- break;
- }
- }
- sdma = &adev->sdma.instance[i].ring;
- if (adev->mman.buffer_funcs_ring == sdma) {
- amdgpu_ttm_set_buffer_funcs_status(adev, false);
- break;
- }
- }
-}
-
int amdgpu_sdma_ras_sw_init(struct amdgpu_device *adev)
{
int err = 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
index 513ac22120c1..173a2a308078 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h
@@ -169,7 +169,6 @@ int amdgpu_sdma_init_microcode(struct amdgpu_device *adev, u32 instance,
bool duplicate);
void amdgpu_sdma_destroy_inst_ctx(struct amdgpu_device *adev,
bool duplicate);
-void amdgpu_sdma_unset_buffer_funcs_helper(struct amdgpu_device *adev);
int amdgpu_sdma_ras_sw_init(struct amdgpu_device *adev);
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c
index f74347cc087a..d65e21914d8c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c
@@ -166,8 +166,12 @@ static int amdgpu_umc_do_page_retirement(struct amdgpu_device *adev,
}
}
- if (reset)
+ if (reset) {
+ /* use mode-2 reset for poison consumption */
+ if (!entry)
+ con->gpu_reset_flags |= AMDGPU_RAS_GPU_RESET_MODE2_RESET;
amdgpu_ras_reset_gpu(adev);
+ }
}
kfree(err_data->err_addr);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index f3c9f93d8899..904252456d25 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -844,6 +844,7 @@ static void amdgpu_vm_tlb_seq_cb(struct dma_fence *fence,
* @immediate: immediate submission in a page fault
* @unlocked: unlocked invalidation during MM callback
* @flush_tlb: trigger tlb invalidation after update completed
+ * @allow_override: change MTYPE for local NUMA nodes
* @resv: fences we need to sync to
* @start: start of mapped range
* @last: last mapped entry
@@ -860,7 +861,7 @@ static void amdgpu_vm_tlb_seq_cb(struct dma_fence *fence,
* 0 for success, negative erro code for failure.
*/
int amdgpu_vm_update_range(struct amdgpu_device *adev, struct amdgpu_vm *vm,
- bool immediate, bool unlocked, bool flush_tlb,
+ bool immediate, bool unlocked, bool flush_tlb, bool allow_override,
struct dma_resv *resv, uint64_t start, uint64_t last,
uint64_t flags, uint64_t offset, uint64_t vram_base,
struct ttm_resource *res, dma_addr_t *pages_addr,
@@ -898,6 +899,7 @@ int amdgpu_vm_update_range(struct amdgpu_device *adev, struct amdgpu_vm *vm,
params.immediate = immediate;
params.pages_addr = pages_addr;
params.unlocked = unlocked;
+ params.allow_override = allow_override;
/* Implicitly sync to command submissions in the same VM before
* unmapping. Sync to moving fences before mapping.
@@ -1073,6 +1075,7 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
struct ttm_resource *mem;
struct dma_fence **last_update;
bool flush_tlb = clear;
+ bool uncached;
struct dma_resv *resv;
uint64_t vram_base;
uint64_t flags;
@@ -1110,9 +1113,11 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
bo_adev = amdgpu_ttm_adev(bo->tbo.bdev);
vram_base = bo_adev->vm_manager.vram_base_offset;
+ uncached = (bo->flags & AMDGPU_GEM_CREATE_UNCACHED) != 0;
} else {
flags = 0x0;
vram_base = 0;
+ uncached = false;
}
if (clear || (bo && bo->tbo.base.resv ==
@@ -1146,7 +1151,7 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
trace_amdgpu_vm_bo_update(mapping);
r = amdgpu_vm_update_range(adev, vm, false, false, flush_tlb,
- resv, mapping->start, mapping->last,
+ !uncached, resv, mapping->start, mapping->last,
update_flags, mapping->offset,
vram_base, mem, pages_addr,
last_update);
@@ -1341,8 +1346,8 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
mapping->start < AMDGPU_GMC_HOLE_START)
init_pte_value = AMDGPU_PTE_DEFAULT_ATC;
- r = amdgpu_vm_update_range(adev, vm, false, false, true, resv,
- mapping->start, mapping->last,
+ r = amdgpu_vm_update_range(adev, vm, false, false, true, false,
+ resv, mapping->start, mapping->last,
init_pte_value, 0, 0, NULL, NULL,
&f);
amdgpu_vm_free_mapping(adev, vm, mapping, f);
@@ -1368,6 +1373,7 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
*
* @adev: amdgpu_device pointer
* @vm: requested vm
+ * @ticket: optional reservation ticket used to reserve the VM
*
* Make sure all BOs which are moved are updated in the PTs.
*
@@ -1377,11 +1383,12 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
* PTs have to be reserved!
*/
int amdgpu_vm_handle_moved(struct amdgpu_device *adev,
- struct amdgpu_vm *vm)
+ struct amdgpu_vm *vm,
+ struct ww_acquire_ctx *ticket)
{
struct amdgpu_bo_va *bo_va;
struct dma_resv *resv;
- bool clear;
+ bool clear, unlock;
int r;
spin_lock(&vm->status_lock);
@@ -1404,17 +1411,24 @@ int amdgpu_vm_handle_moved(struct amdgpu_device *adev,
spin_unlock(&vm->status_lock);
/* Try to reserve the BO to avoid clearing its ptes */
- if (!adev->debug_vm && dma_resv_trylock(resv))
+ if (!adev->debug_vm && dma_resv_trylock(resv)) {
+ clear = false;
+ unlock = true;
+ /* The caller is already holding the reservation lock */
+ } else if (ticket && dma_resv_locking_ctx(resv) == ticket) {
clear = false;
+ unlock = false;
/* Somebody else is using the BO right now */
- else
+ } else {
clear = true;
+ unlock = false;
+ }
r = amdgpu_vm_bo_update(adev, bo_va, clear);
if (r)
return r;
- if (!clear)
+ if (unlock)
dma_resv_unlock(resv);
spin_lock(&vm->status_lock);
}
@@ -2618,8 +2632,8 @@ bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, u32 pasid,
goto error_unlock;
}
- r = amdgpu_vm_update_range(adev, vm, true, false, false, NULL, addr,
- addr, flags, value, 0, NULL, NULL, NULL);
+ r = amdgpu_vm_update_range(adev, vm, true, false, false, false,
+ NULL, addr, addr, flags, value, 0, NULL, NULL, NULL);
if (r)
goto error_unlock;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
index 411d42fecfb6..2cd86d2bf73f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
@@ -246,6 +246,12 @@ struct amdgpu_vm_update_params {
* @table_freed: return true if page table is freed when updating
*/
bool table_freed;
+
+ /**
+ * @allow_override: true for memory that is not uncached: allows MTYPE
+ * to be overridden for NUMA local memory.
+ */
+ bool allow_override;
};
struct amdgpu_vm_update_funcs {
@@ -437,11 +443,12 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
struct amdgpu_vm *vm,
struct dma_fence **fence);
int amdgpu_vm_handle_moved(struct amdgpu_device *adev,
- struct amdgpu_vm *vm);
+ struct amdgpu_vm *vm,
+ struct ww_acquire_ctx *ticket);
void amdgpu_vm_bo_base_init(struct amdgpu_vm_bo_base *base,
struct amdgpu_vm *vm, struct amdgpu_bo *bo);
int amdgpu_vm_update_range(struct amdgpu_device *adev, struct amdgpu_vm *vm,
- bool immediate, bool unlocked, bool flush_tlb,
+ bool immediate, bool unlocked, bool flush_tlb, bool allow_override,
struct dma_resv *resv, uint64_t start, uint64_t last,
uint64_t flags, uint64_t offset, uint64_t vram_base,
struct ttm_resource *res, dma_addr_t *pages_addr,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
index 9b025fd17b84..a2287bb25223 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
@@ -843,7 +843,7 @@ static void amdgpu_vm_pte_update_flags(struct amdgpu_vm_update_params *params,
*/
if ((flags & AMDGPU_PTE_SYSTEM) && (adev->flags & AMD_IS_APU) &&
adev->gmc.gmc_funcs->override_vm_pte_flags &&
- num_possible_nodes() > 1 && !params->pages_addr)
+ num_possible_nodes() > 1 && !params->pages_addr && params->allow_override)
amdgpu_gmc_override_vm_pte_flags(adev, params->vm, addr, &flags);
params->vm->update_funcs->update(params, pt, pe, addr, count, incr,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
index 18f58efc9dc7..08916538a615 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
@@ -77,7 +77,16 @@ static inline bool amdgpu_is_vram_mgr_blocks_contiguous(struct list_head *head)
return true;
}
+static inline u64 amdgpu_vram_mgr_blocks_size(struct list_head *head)
+{
+ struct drm_buddy_block *block;
+ u64 size = 0;
+ list_for_each_entry(block, head, link)
+ size += amdgpu_vram_mgr_block_size(block);
+
+ return size;
+}
/**
* DOC: mem_info_vram_total
@@ -516,6 +525,8 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
mutex_unlock(&mgr->lock);
vres->base.start = 0;
+ size = max_t(u64, amdgpu_vram_mgr_blocks_size(&vres->blocks),
+ vres->base.size);
list_for_each_entry(block, &vres->blocks, link) {
unsigned long start;
@@ -523,8 +534,8 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
amdgpu_vram_mgr_block_size(block);
start >>= PAGE_SHIFT;
- if (start > PFN_UP(vres->base.size))
- start -= PFN_UP(vres->base.size);
+ if (start > PFN_UP(size))
+ start -= PFN_UP(size);
else
start = 0;
vres->base.start = max(vres->base.start, start);
diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c
index e63abdf52b6c..4dfaa017cf7f 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik.c
@@ -1709,10 +1709,6 @@ static void cik_program_aspm(struct amdgpu_device *adev)
if (pci_is_root_bus(adev->pdev->bus))
return;
- /* XXX double check APUs */
- if (adev->flags & AMD_IS_APU)
- return;
-
orig = data = RREG32_PCIE(ixPCIE_LC_N_FTS_CNTL);
data &= ~PCIE_LC_N_FTS_CNTL__LC_XMIT_N_FTS_MASK;
data |= (0x24 << PCIE_LC_N_FTS_CNTL__LC_XMIT_N_FTS__SHIFT) |
diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
index ee5dce6f6043..a3fccc4c1f43 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
@@ -308,8 +308,6 @@ static void cik_sdma_gfx_stop(struct amdgpu_device *adev)
u32 rb_cntl;
int i;
- amdgpu_sdma_unset_buffer_funcs_helper(adev);
-
for (i = 0; i < adev->sdma.num_instances; i++) {
rb_cntl = RREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i]);
rb_cntl &= ~SDMA0_GFX_RB_CNTL__RB_ENABLE_MASK;
@@ -498,9 +496,6 @@ static int cik_sdma_gfx_resume(struct amdgpu_device *adev)
r = amdgpu_ring_test_helper(ring);
if (r)
return r;
-
- if (adev->mman.buffer_funcs_ring == ring)
- amdgpu_ttm_set_buffer_funcs_status(adev, true);
}
return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/df_v4_6_2.c b/drivers/gpu/drm/amd/amdgpu/df_v4_6_2.c
new file mode 100644
index 000000000000..a47960a0babd
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/df_v4_6_2.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2023 Advanced Micro Devices, 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, sublicense,
+ * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ */
+#include "amdgpu.h"
+#include "df_v4_6_2.h"
+
+static bool df_v4_6_2_query_ras_poison_mode(struct amdgpu_device *adev)
+{
+ /* return true since related regs are inaccessible */
+ return true;
+}
+
+const struct amdgpu_df_funcs df_v4_6_2_funcs = {
+ .query_ras_poison_mode = df_v4_6_2_query_ras_poison_mode,
+};
diff --git a/drivers/gpu/drm/amd/amdgpu/df_v4_6_2.h b/drivers/gpu/drm/amd/amdgpu/df_v4_6_2.h
new file mode 100644
index 000000000000..3bc3e6d216e2
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/df_v4_6_2.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2023 Advanced Micro Devices, 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, sublicense,
+ * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 __DF_V4_6_2_H__
+#define __DF_V4_6_2_H__
+
+#include "soc15_common.h"
+
+extern const struct amdgpu_df_funcs df_v4_6_2_funcs;
+
+#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
index d9ccacd06fba..c8a3bf01743f 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
@@ -3498,6 +3498,8 @@ static void gfx_v10_0_ring_invalidate_tlbs(struct amdgpu_ring *ring,
static void gfx_v10_0_update_spm_vmid_internal(struct amdgpu_device *adev,
unsigned int vmid);
+static int gfx_v10_0_set_powergating_state(void *handle,
+ enum amd_powergating_state state);
static void gfx10_kiq_set_resources(struct amdgpu_ring *kiq_ring, uint64_t queue_mask)
{
amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_SET_RESOURCES, 6));
@@ -6465,11 +6467,18 @@ static int gfx_v10_0_gfx_init_queue(struct amdgpu_ring *ring)
nv_grbm_select(adev, 0, 0, 0, 0);
mutex_unlock(&adev->srbm_mutex);
if (adev->gfx.me.mqd_backup[mqd_idx])
- memcpy(adev->gfx.me.mqd_backup[mqd_idx], mqd, sizeof(*mqd));
+ memcpy_fromio(adev->gfx.me.mqd_backup[mqd_idx], mqd, sizeof(*mqd));
} else {
+ mutex_lock(&adev->srbm_mutex);
+ nv_grbm_select(adev, ring->me, ring->pipe, ring->queue, 0);
+ if (ring->doorbell_index == adev->doorbell_index.gfx_ring0 << 1)
+ gfx_v10_0_cp_gfx_set_doorbell(adev, ring);
+
+ nv_grbm_select(adev, 0, 0, 0, 0);
+ mutex_unlock(&adev->srbm_mutex);
/* restore mqd with the backup copy */
if (adev->gfx.me.mqd_backup[mqd_idx])
- memcpy(mqd, adev->gfx.me.mqd_backup[mqd_idx], sizeof(*mqd));
+ memcpy_toio(mqd, adev->gfx.me.mqd_backup[mqd_idx], sizeof(*mqd));
/* reset the ring */
ring->wptr = 0;
*ring->wptr_cpu_addr = 0;
@@ -6743,7 +6752,7 @@ static int gfx_v10_0_kiq_init_queue(struct amdgpu_ring *ring)
if (amdgpu_in_reset(adev)) { /* for GPU_RESET case */
/* reset MQD to a clean status */
if (adev->gfx.kiq[0].mqd_backup)
- memcpy(mqd, adev->gfx.kiq[0].mqd_backup, sizeof(*mqd));
+ memcpy_toio(mqd, adev->gfx.kiq[0].mqd_backup, sizeof(*mqd));
/* reset ring buffer */
ring->wptr = 0;
@@ -6766,7 +6775,7 @@ static int gfx_v10_0_kiq_init_queue(struct amdgpu_ring *ring)
mutex_unlock(&adev->srbm_mutex);
if (adev->gfx.kiq[0].mqd_backup)
- memcpy(adev->gfx.kiq[0].mqd_backup, mqd, sizeof(*mqd));
+ memcpy_fromio(adev->gfx.kiq[0].mqd_backup, mqd, sizeof(*mqd));
}
return 0;
@@ -6787,11 +6796,11 @@ static int gfx_v10_0_kcq_init_queue(struct amdgpu_ring *ring)
mutex_unlock(&adev->srbm_mutex);
if (adev->gfx.mec.mqd_backup[mqd_idx])
- memcpy(adev->gfx.mec.mqd_backup[mqd_idx], mqd, sizeof(*mqd));
+ memcpy_fromio(adev->gfx.mec.mqd_backup[mqd_idx], mqd, sizeof(*mqd));
} else {
/* restore MQD to a clean status */
if (adev->gfx.mec.mqd_backup[mqd_idx])
- memcpy(mqd, adev->gfx.mec.mqd_backup[mqd_idx], sizeof(*mqd));
+ memcpy_toio(mqd, adev->gfx.mec.mqd_backup[mqd_idx], sizeof(*mqd));
/* reset ring buffer */
ring->wptr = 0;
atomic64_set((atomic64_t *)ring->wptr_cpu_addr, 0);
@@ -7172,6 +7181,13 @@ static int gfx_v10_0_hw_fini(void *handle)
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
+ /* WA added for Vangogh asic fixing the SMU suspend failure
+ * It needs to set power gating again during gfxoff control
+ * otherwise the gfxoff disallowing will be failed to set.
+ */
+ if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(10, 3, 1))
+ gfx_v10_0_set_powergating_state(handle, AMD_PG_STATE_UNGATE);
+
if (!adev->no_hw_access) {
if (amdgpu_async_gfx_ring) {
if (amdgpu_gfx_disable_kgq(adev, 0))
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
index fd22943685f7..0c6133cc5e57 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
@@ -155,6 +155,7 @@ static void gfx11_kiq_set_resources(struct amdgpu_ring *kiq_ring, uint64_t queue
{
amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_SET_RESOURCES, 6));
amdgpu_ring_write(kiq_ring, PACKET3_SET_RESOURCES_VMID_MASK(0) |
+ PACKET3_SET_RESOURCES_UNMAP_LATENTY(0xa) | /* unmap_latency: 0xa (~ 1s) */
PACKET3_SET_RESOURCES_QUEUE_TYPE(0)); /* vmid_mask:0 queue_type:0 (KIQ) */
amdgpu_ring_write(kiq_ring, lower_32_bits(queue_mask)); /* queue mask lo */
amdgpu_ring_write(kiq_ring, upper_32_bits(queue_mask)); /* queue mask hi */
@@ -3714,11 +3715,11 @@ static int gfx_v11_0_gfx_init_queue(struct amdgpu_ring *ring)
soc21_grbm_select(adev, 0, 0, 0, 0);
mutex_unlock(&adev->srbm_mutex);
if (adev->gfx.me.mqd_backup[mqd_idx])
- memcpy(adev->gfx.me.mqd_backup[mqd_idx], mqd, sizeof(*mqd));
+ memcpy_fromio(adev->gfx.me.mqd_backup[mqd_idx], mqd, sizeof(*mqd));
} else {
/* restore mqd with the backup copy */
if (adev->gfx.me.mqd_backup[mqd_idx])
- memcpy(mqd, adev->gfx.me.mqd_backup[mqd_idx], sizeof(*mqd));
+ memcpy_toio(mqd, adev->gfx.me.mqd_backup[mqd_idx], sizeof(*mqd));
/* reset the ring */
ring->wptr = 0;
*ring->wptr_cpu_addr = 0;
@@ -4007,7 +4008,7 @@ static int gfx_v11_0_kiq_init_queue(struct amdgpu_ring *ring)
if (amdgpu_in_reset(adev)) { /* for GPU_RESET case */
/* reset MQD to a clean status */
if (adev->gfx.kiq[0].mqd_backup)
- memcpy(mqd, adev->gfx.kiq[0].mqd_backup, sizeof(*mqd));
+ memcpy_toio(mqd, adev->gfx.kiq[0].mqd_backup, sizeof(*mqd));
/* reset ring buffer */
ring->wptr = 0;
@@ -4030,7 +4031,7 @@ static int gfx_v11_0_kiq_init_queue(struct amdgpu_ring *ring)
mutex_unlock(&adev->srbm_mutex);
if (adev->gfx.kiq[0].mqd_backup)
- memcpy(adev->gfx.kiq[0].mqd_backup, mqd, sizeof(*mqd));
+ memcpy_fromio(adev->gfx.kiq[0].mqd_backup, mqd, sizeof(*mqd));
}
return 0;
@@ -4051,11 +4052,11 @@ static int gfx_v11_0_kcq_init_queue(struct amdgpu_ring *ring)
mutex_unlock(&adev->srbm_mutex);
if (adev->gfx.mec.mqd_backup[mqd_idx])
- memcpy(adev->gfx.mec.mqd_backup[mqd_idx], mqd, sizeof(*mqd));
+ memcpy_fromio(adev->gfx.mec.mqd_backup[mqd_idx], mqd, sizeof(*mqd));
} else {
/* restore MQD to a clean status */
if (adev->gfx.mec.mqd_backup[mqd_idx])
- memcpy(mqd, adev->gfx.mec.mqd_backup[mqd_idx], sizeof(*mqd));
+ memcpy_toio(mqd, adev->gfx.mec.mqd_backup[mqd_idx], sizeof(*mqd));
/* reset ring buffer */
ring->wptr = 0;
atomic64_set((atomic64_t *)ring->wptr_cpu_addr, 0);
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
index 362bf51ab1d2..41bbabd9ad4d 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
@@ -256,6 +256,7 @@ static int gfx_v9_4_3_ring_test_ring(struct amdgpu_ring *ring)
xcc_offset = SOC15_REG_OFFSET(GC, 0, regSCRATCH_REG0);
scratch_reg0_offset = SOC15_REG_OFFSET(GC, GET_INST(GC, ring->xcc_id), regSCRATCH_REG0);
WREG32(scratch_reg0_offset, 0xCAFEDEAD);
+ tmp = RREG32(scratch_reg0_offset);
r = amdgpu_ring_alloc(ring, 3);
if (r)
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
index 19eaada35ede..4713a62ad586 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
@@ -73,7 +73,8 @@ gmc_v11_0_vm_fault_interrupt_state(struct amdgpu_device *adev,
* fini/suspend, so the overall state doesn't
* change over the course of suspend/resume.
*/
- if (!adev->in_s0ix)
+ if (!adev->in_s0ix && (adev->in_runpm || adev->in_suspend ||
+ amdgpu_in_reset(adev)))
amdgpu_gmc_set_vm_fault_masks(adev, AMDGPU_GFXHUB(0), false);
break;
case AMDGPU_IRQ_STATE_ENABLE:
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
index 5fed01e34928..b66c5f7e1c56 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
@@ -1251,12 +1251,15 @@ static void gmc_v9_0_override_vm_pte_flags(struct amdgpu_device *adev,
return;
}
- /* Only override mappings with MTYPE_NC, which is the safe default for
- * cacheable memory.
+ /* MTYPE_NC is the same default and can be overridden.
+ * MTYPE_UC will be present if the memory is extended-coherent
+ * and can also be overridden.
*/
if ((*flags & AMDGPU_PTE_MTYPE_VG10_MASK) !=
- AMDGPU_PTE_MTYPE_VG10(MTYPE_NC)) {
- dev_dbg_ratelimited(adev->dev, "MTYPE is not NC\n");
+ AMDGPU_PTE_MTYPE_VG10(MTYPE_NC) &&
+ (*flags & AMDGPU_PTE_MTYPE_VG10_MASK) !=
+ AMDGPU_PTE_MTYPE_VG10(MTYPE_UC)) {
+ dev_dbg_ratelimited(adev->dev, "MTYPE is not NC or UC\n");
return;
}
@@ -1283,15 +1286,23 @@ static void gmc_v9_0_override_vm_pte_flags(struct amdgpu_device *adev,
vm->mem_id, local_node, nid);
if (nid == local_node) {
uint64_t old_flags = *flags;
- unsigned int mtype_local = MTYPE_RW;
+ if ((*flags & AMDGPU_PTE_MTYPE_VG10_MASK) ==
+ AMDGPU_PTE_MTYPE_VG10(MTYPE_NC)) {
+ unsigned int mtype_local = MTYPE_RW;
- if (amdgpu_mtype_local == 1)
- mtype_local = MTYPE_NC;
- else if (amdgpu_mtype_local == 2)
- mtype_local = MTYPE_CC;
+ if (amdgpu_mtype_local == 1)
+ mtype_local = MTYPE_NC;
+ else if (amdgpu_mtype_local == 2)
+ mtype_local = MTYPE_CC;
+
+ *flags = (*flags & ~AMDGPU_PTE_MTYPE_VG10_MASK) |
+ AMDGPU_PTE_MTYPE_VG10(mtype_local);
+ } else {
+ /* MTYPE_UC case */
+ *flags = (*flags & ~AMDGPU_PTE_MTYPE_VG10_MASK) |
+ AMDGPU_PTE_MTYPE_VG10(MTYPE_CC);
+ }
- *flags = (*flags & ~AMDGPU_PTE_MTYPE_VG10_MASK) |
- AMDGPU_PTE_MTYPE_VG10(mtype_local);
dev_dbg_ratelimited(adev->dev, "flags updated from %llx to %llx\n",
old_flags, *flags);
}
@@ -2018,11 +2029,8 @@ static int gmc_v9_0_sw_init(void *handle)
* vm size is 256TB (48bit), maximum size of Vega10,
* block size 512 (9bit)
*/
- /* sriov restrict max_pfn below AMDGPU_GMC_HOLE */
- if (amdgpu_sriov_vf(adev))
- amdgpu_vm_adjust_size(adev, 256 * 1024, 9, 3, 47);
- else
- amdgpu_vm_adjust_size(adev, 256 * 1024, 9, 3, 48);
+
+ amdgpu_vm_adjust_size(adev, 256 * 1024, 9, 3, 48);
if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 2))
adev->gmc.translate_further = adev->vm_manager.num_level > 1;
break;
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c
index e523627cfe25..df218d5ca775 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c
+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c
@@ -28,6 +28,7 @@
#include "nbio/nbio_2_3_offset.h"
#include "nbio/nbio_2_3_sh_mask.h"
#include <uapi/linux/kfd_ioctl.h>
+#include <linux/device.h>
#include <linux/pci.h>
#define smnPCIE_CONFIG_CNTL 0x11180044
@@ -361,7 +362,7 @@ static void nbio_v2_3_enable_aspm(struct amdgpu_device *adev,
data |= NAVI10_PCIE__LC_L0S_INACTIVITY_DEFAULT << PCIE_LC_CNTL__LC_L0S_INACTIVITY__SHIFT;
- if (pci_is_thunderbolt_attached(adev->pdev))
+ if (dev_is_removable(&adev->pdev->dev))
data |= NAVI10_PCIE__LC_L1_INACTIVITY_TBT_DEFAULT << PCIE_LC_CNTL__LC_L1_INACTIVITY__SHIFT;
else
data |= NAVI10_PCIE__LC_L1_INACTIVITY_DEFAULT << PCIE_LC_CNTL__LC_L1_INACTIVITY__SHIFT;
@@ -480,7 +481,7 @@ static void nbio_v2_3_program_aspm(struct amdgpu_device *adev)
def = data = RREG32_PCIE(smnPCIE_LC_CNTL);
data |= NAVI10_PCIE__LC_L0S_INACTIVITY_DEFAULT << PCIE_LC_CNTL__LC_L0S_INACTIVITY__SHIFT;
- if (pci_is_thunderbolt_attached(adev->pdev))
+ if (dev_is_removable(&adev->pdev->dev))
data |= NAVI10_PCIE__LC_L1_INACTIVITY_TBT_DEFAULT << PCIE_LC_CNTL__LC_L1_INACTIVITY__SHIFT;
else
data |= NAVI10_PCIE__LC_L1_INACTIVITY_DEFAULT << PCIE_LC_CNTL__LC_L1_INACTIVITY__SHIFT;
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_7.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_7.c
index def89379b51a..4df1055e640a 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_7.c
+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_7.c
@@ -254,7 +254,7 @@ static void nbio_v7_7_update_medium_grain_clock_gating(struct amdgpu_device *ade
{
uint32_t def, data;
- if (enable && !(adev->cg_flags & AMD_CG_SUPPORT_BIF_MGCG))
+ if (!(adev->cg_flags & AMD_CG_SUPPORT_BIF_MGCG))
return;
def = data = RREG32_SOC15(NBIO, 0, regBIF0_CPM_CONTROL);
@@ -283,7 +283,7 @@ static void nbio_v7_7_update_medium_grain_light_sleep(struct amdgpu_device *adev
{
uint32_t def, data;
- if (enable && !(adev->cg_flags & AMD_CG_SUPPORT_BIF_LS))
+ if (!(adev->cg_flags & AMD_CG_SUPPORT_BIF_LS))
return;
def = data = RREG32_SOC15(NBIO, 0, regBIF0_PCIE_CNTL2);
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c
index eccb006e78aa..23f26f8caad4 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c
+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c
@@ -56,8 +56,15 @@ static u32 nbio_v7_9_get_rev_id(struct amdgpu_device *adev)
{
u32 tmp;
+ tmp = IP_VERSION_SUBREV(amdgpu_ip_version_full(adev, NBIO_HWIP, 0));
+ /* If it is VF or subrevision holds a non-zero value, that should be used */
+ if (tmp || amdgpu_sriov_vf(adev))
+ return tmp;
+
+ /* If discovery subrev is not updated, use register version */
tmp = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0);
- tmp = REG_GET_FIELD(tmp, RCC_STRAP0_RCC_DEV0_EPF0_STRAP0, STRAP_ATI_REV_ID_DEV0_F0);
+ tmp = REG_GET_FIELD(tmp, RCC_STRAP0_RCC_DEV0_EPF0_STRAP0,
+ STRAP_ATI_REV_ID_DEV0_F0);
return tmp;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c
index 1995c7459f20..4d7976b77767 100644
--- a/drivers/gpu/drm/amd/amdgpu/nv.c
+++ b/drivers/gpu/drm/amd/amdgpu/nv.c
@@ -513,11 +513,10 @@ static int nv_set_vce_clocks(struct amdgpu_device *adev, u32 evclk, u32 ecclk)
static void nv_program_aspm(struct amdgpu_device *adev)
{
- if (!amdgpu_device_should_use_aspm(adev) || !amdgpu_device_aspm_support_quirk())
+ if (!amdgpu_device_should_use_aspm(adev))
return;
- if (!(adev->flags & AMD_IS_APU) &&
- (adev->nbio.funcs->program_aspm))
+ if (adev->nbio.funcs->program_aspm)
adev->nbio.funcs->program_aspm(adev);
}
@@ -609,9 +608,8 @@ static int nv_update_umd_stable_pstate(struct amdgpu_device *adev,
if (adev->gfx.funcs->update_perfmon_mgcg)
adev->gfx.funcs->update_perfmon_mgcg(adev, !enter);
- if (!(adev->flags & AMD_IS_APU) &&
- (adev->nbio.funcs->enable_aspm) &&
- amdgpu_device_should_use_aspm(adev))
+ if (adev->nbio.funcs->enable_aspm &&
+ amdgpu_device_should_use_aspm(adev))
adev->nbio.funcs->enable_aspm(adev, !enter);
return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c
index 4142e2fcd866..3cf4684d0d3f 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c
@@ -759,6 +759,83 @@ static int psp_v13_0_fatal_error_recovery_quirk(struct psp_context *psp)
return 0;
}
+
+static void psp_v13_0_boot_error_reporting(struct amdgpu_device *adev,
+ uint32_t inst,
+ uint32_t boot_error)
+{
+ uint32_t socket_id;
+ uint32_t aid_id;
+ uint32_t hbm_id;
+ uint32_t reg_data;
+
+ socket_id = REG_GET_FIELD(boot_error, MP0_SMN_C2PMSG_126, SOCKET_ID);
+ aid_id = REG_GET_FIELD(boot_error, MP0_SMN_C2PMSG_126, AID_ID);
+ hbm_id = REG_GET_FIELD(boot_error, MP0_SMN_C2PMSG_126, HBM_ID);
+
+ reg_data = RREG32_SOC15(MP0, inst, regMP0_SMN_C2PMSG_109);
+ dev_info(adev->dev, "socket: %d, aid: %d, firmware boot failed, fw status is 0x%x\n",
+ socket_id, aid_id, reg_data);
+
+ if (REG_GET_FIELD(boot_error, MP0_SMN_C2PMSG_126, GPU_ERR_MEM_TRAINING))
+ dev_info(adev->dev, "socket: %d, aid: %d, hbm: %d, memory training failed\n",
+ socket_id, aid_id, hbm_id);
+
+ if (REG_GET_FIELD(boot_error, MP0_SMN_C2PMSG_126, GPU_ERR_FW_LOAD))
+ dev_info(adev->dev, "socket: %d, aid: %d, firmware load failed at boot time\n",
+ socket_id, aid_id);
+
+ if (REG_GET_FIELD(boot_error, MP0_SMN_C2PMSG_126, GPU_ERR_WAFL_LINK_TRAINING))
+ dev_info(adev->dev, "socket: %d, aid: %d, wafl link training failed\n",
+ socket_id, aid_id);
+
+ if (REG_GET_FIELD(boot_error, MP0_SMN_C2PMSG_126, GPU_ERR_XGMI_LINK_TRAINING))
+ dev_info(adev->dev, "socket: %d, aid: %d, xgmi link training failed\n",
+ socket_id, aid_id);
+
+ if (REG_GET_FIELD(boot_error, MP0_SMN_C2PMSG_126, GPU_ERR_USR_CP_LINK_TRAINING))
+ dev_info(adev->dev, "socket: %d, aid: %d, usr cp link training failed\n",
+ socket_id, aid_id);
+
+ if (REG_GET_FIELD(boot_error, MP0_SMN_C2PMSG_126, GPU_ERR_USR_DP_LINK_TRAINING))
+ dev_info(adev->dev, "socket: %d, aid: %d, usr dp link training failed\n",
+ socket_id, aid_id);
+
+ if (REG_GET_FIELD(boot_error, MP0_SMN_C2PMSG_126, GPU_ERR_HBM_MEM_TEST))
+ dev_info(adev->dev, "socket: %d, aid: %d, hbm: %d, hbm memory test failed\n",
+ socket_id, aid_id, hbm_id);
+
+ if (REG_GET_FIELD(boot_error, MP0_SMN_C2PMSG_126, GPU_ERR_HBM_BIST_TEST))
+ dev_info(adev->dev, "socket: %d, aid: %d, hbm: %d, hbm bist test failed\n",
+ socket_id, aid_id, hbm_id);
+}
+
+static int psp_v13_0_query_boot_status(struct psp_context *psp)
+{
+ struct amdgpu_device *adev = psp->adev;
+ int inst_mask = adev->aid_mask;
+ uint32_t reg_data;
+ uint32_t i;
+ int ret = 0;
+
+ if (amdgpu_ip_version(adev, MP0_HWIP, 0) != IP_VERSION(13, 0, 6))
+ return 0;
+
+ if (RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_59) < 0x00a10007)
+ return 0;
+
+ for_each_inst(i, inst_mask) {
+ reg_data = RREG32_SOC15(MP0, i, regMP0_SMN_C2PMSG_126);
+ if (!REG_GET_FIELD(reg_data, MP0_SMN_C2PMSG_126, BOOT_STATUS)) {
+ psp_v13_0_boot_error_reporting(adev, i, reg_data);
+ ret = -EINVAL;
+ break;
+ }
+ }
+
+ return ret;
+}
+
static const struct psp_funcs psp_v13_0_funcs = {
.init_microcode = psp_v13_0_init_microcode,
.wait_for_bootloader = psp_v13_0_wait_for_bootloader_steady_state,
@@ -781,6 +858,7 @@ static const struct psp_funcs psp_v13_0_funcs = {
.update_spirom = psp_v13_0_update_spirom,
.vbflash_stat = psp_v13_0_vbflash_status,
.fatal_error_recovery_quirk = psp_v13_0_fatal_error_recovery_quirk,
+ .query_boot_status = psp_v13_0_query_boot_status,
};
void psp_v13_0_set_psp_funcs(struct psp_context *psp)
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
index b58a13bd75db..45377a175250 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c
@@ -339,8 +339,6 @@ static void sdma_v2_4_gfx_stop(struct amdgpu_device *adev)
u32 rb_cntl, ib_cntl;
int i;
- amdgpu_sdma_unset_buffer_funcs_helper(adev);
-
for (i = 0; i < adev->sdma.num_instances; i++) {
rb_cntl = RREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i]);
rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 0);
@@ -474,9 +472,6 @@ static int sdma_v2_4_gfx_resume(struct amdgpu_device *adev)
r = amdgpu_ring_test_helper(ring);
if (r)
return r;
-
- if (adev->mman.buffer_funcs_ring == ring)
- amdgpu_ttm_set_buffer_funcs_status(adev, true);
}
return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
index c5ea32687eb5..2ad615be4bb3 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
@@ -513,8 +513,6 @@ static void sdma_v3_0_gfx_stop(struct amdgpu_device *adev)
u32 rb_cntl, ib_cntl;
int i;
- amdgpu_sdma_unset_buffer_funcs_helper(adev);
-
for (i = 0; i < adev->sdma.num_instances; i++) {
rb_cntl = RREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i]);
rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 0);
@@ -746,9 +744,6 @@ static int sdma_v3_0_gfx_resume(struct amdgpu_device *adev)
r = amdgpu_ring_test_helper(ring);
if (r)
return r;
-
- if (adev->mman.buffer_funcs_ring == ring)
- amdgpu_ttm_set_buffer_funcs_status(adev, true);
}
return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
index 683d51ae4bf1..3d68dd5523c6 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
@@ -877,8 +877,6 @@ static void sdma_v4_0_gfx_enable(struct amdgpu_device *adev, bool enable)
u32 rb_cntl, ib_cntl;
int i;
- amdgpu_sdma_unset_buffer_funcs_helper(adev);
-
for (i = 0; i < adev->sdma.num_instances; i++) {
rb_cntl = RREG32_SDMA(i, mmSDMA0_GFX_RB_CNTL);
rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, enable ? 1 : 0);
@@ -913,8 +911,6 @@ static void sdma_v4_0_page_stop(struct amdgpu_device *adev)
u32 rb_cntl, ib_cntl;
int i;
- amdgpu_sdma_unset_buffer_funcs_helper(adev);
-
for (i = 0; i < adev->sdma.num_instances; i++) {
rb_cntl = RREG32_SDMA(i, mmSDMA0_PAGE_RB_CNTL);
rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_PAGE_RB_CNTL,
@@ -1402,13 +1398,7 @@ static int sdma_v4_0_start(struct amdgpu_device *adev)
r = amdgpu_ring_test_helper(page);
if (r)
return r;
-
- if (adev->mman.buffer_funcs_ring == page)
- amdgpu_ttm_set_buffer_funcs_status(adev, true);
}
-
- if (adev->mman.buffer_funcs_ring == ring)
- amdgpu_ttm_set_buffer_funcs_status(adev, true);
}
return r;
@@ -1921,11 +1911,8 @@ static int sdma_v4_0_hw_fini(void *handle)
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
int i;
- if (amdgpu_sriov_vf(adev)) {
- /* disable the scheduler for SDMA */
- amdgpu_sdma_unset_buffer_funcs_helper(adev);
+ if (amdgpu_sriov_vf(adev))
return 0;
- }
if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__SDMA)) {
for (i = 0; i < adev->sdma.num_instances; i++) {
@@ -1964,7 +1951,6 @@ static int sdma_v4_0_resume(void *handle)
if (adev->in_s0ix) {
sdma_v4_0_enable(adev, true);
sdma_v4_0_gfx_enable(adev, true);
- amdgpu_ttm_set_buffer_funcs_status(adev, true);
return 0;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
index c1ff5eda8961..3c485e5a531a 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
@@ -559,8 +559,6 @@ static void sdma_v5_0_gfx_stop(struct amdgpu_device *adev)
u32 rb_cntl, ib_cntl;
int i;
- amdgpu_sdma_unset_buffer_funcs_helper(adev);
-
for (i = 0; i < adev->sdma.num_instances; i++) {
rb_cntl = RREG32_SOC15_IP(GC, sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_CNTL));
rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 0);
@@ -825,9 +823,6 @@ static int sdma_v5_0_gfx_resume(struct amdgpu_device *adev)
r = amdgpu_ring_test_helper(ring);
if (r)
return r;
-
- if (adev->mman.buffer_funcs_ring == ring)
- amdgpu_ttm_set_buffer_funcs_status(adev, true);
}
return 0;
@@ -1426,11 +1421,8 @@ static int sdma_v5_0_hw_fini(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- if (amdgpu_sriov_vf(adev)) {
- /* disable the scheduler for SDMA */
- amdgpu_sdma_unset_buffer_funcs_helper(adev);
+ if (amdgpu_sriov_vf(adev))
return 0;
- }
sdma_v5_0_ctx_switch_enable(adev, false);
sdma_v5_0_enable(adev, false);
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
index 7d1e57189c8c..83c240f741b5 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
@@ -364,8 +364,6 @@ static void sdma_v5_2_gfx_stop(struct amdgpu_device *adev)
u32 rb_cntl, ib_cntl;
int i;
- amdgpu_sdma_unset_buffer_funcs_helper(adev);
-
for (i = 0; i < adev->sdma.num_instances; i++) {
rb_cntl = RREG32_SOC15_IP(GC, sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_GFX_RB_CNTL));
rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 0);
@@ -625,9 +623,6 @@ static int sdma_v5_2_gfx_resume(struct amdgpu_device *adev)
r = amdgpu_ring_test_helper(ring);
if (r)
return r;
-
- if (adev->mman.buffer_funcs_ring == ring)
- amdgpu_ttm_set_buffer_funcs_status(adev, true);
}
return 0;
@@ -1284,11 +1279,8 @@ static int sdma_v5_2_hw_fini(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- if (amdgpu_sriov_vf(adev)) {
- /* disable the scheduler for SDMA */
- amdgpu_sdma_unset_buffer_funcs_helper(adev);
+ if (amdgpu_sriov_vf(adev))
return 0;
- }
sdma_v5_2_ctx_switch_enable(adev, false);
sdma_v5_2_enable(adev, false);
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
index 7e4d5188cbfa..3c7ddd219de8 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
@@ -348,8 +348,6 @@ static void sdma_v6_0_gfx_stop(struct amdgpu_device *adev)
u32 rb_cntl, ib_cntl;
int i;
- amdgpu_sdma_unset_buffer_funcs_helper(adev);
-
for (i = 0; i < adev->sdma.num_instances; i++) {
rb_cntl = RREG32_SOC15_IP(GC, sdma_v6_0_get_reg_offset(adev, i, regSDMA0_QUEUE0_RB_CNTL));
rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_QUEUE0_RB_CNTL, RB_ENABLE, 0);
@@ -561,9 +559,6 @@ static int sdma_v6_0_gfx_resume(struct amdgpu_device *adev)
r = amdgpu_ring_test_helper(ring);
if (r)
return r;
-
- if (adev->mman.buffer_funcs_ring == ring)
- amdgpu_ttm_set_buffer_funcs_status(adev, true);
}
return 0;
@@ -1308,11 +1303,8 @@ static int sdma_v6_0_hw_fini(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- if (amdgpu_sriov_vf(adev)) {
- /* disable the scheduler for SDMA */
- amdgpu_sdma_unset_buffer_funcs_helper(adev);
+ if (amdgpu_sriov_vf(adev))
return 0;
- }
sdma_v6_0_ctxempty_int_enable(adev, false);
sdma_v6_0_enable(adev, false);
diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c
index 4b81f29e5fd5..a757526153e5 100644
--- a/drivers/gpu/drm/amd/amdgpu/si.c
+++ b/drivers/gpu/drm/amd/amdgpu/si.c
@@ -2440,8 +2440,6 @@ static void si_program_aspm(struct amdgpu_device *adev)
if (!amdgpu_device_should_use_aspm(adev))
return;
- if (adev->flags & AMD_IS_APU)
- return;
orig = data = RREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL);
data &= ~LC_XMIT_N_FTS_MASK;
data |= LC_XMIT_N_FTS(0x24) | LC_XMIT_N_FTS_OVERRIDE_EN;
diff --git a/drivers/gpu/drm/amd/amdgpu/si_dma.c b/drivers/gpu/drm/amd/amdgpu/si_dma.c
index 42c4547f32ec..9aa0e11ee673 100644
--- a/drivers/gpu/drm/amd/amdgpu/si_dma.c
+++ b/drivers/gpu/drm/amd/amdgpu/si_dma.c
@@ -115,8 +115,6 @@ static void si_dma_stop(struct amdgpu_device *adev)
u32 rb_cntl;
unsigned i;
- amdgpu_sdma_unset_buffer_funcs_helper(adev);
-
for (i = 0; i < adev->sdma.num_instances; i++) {
/* dma0 */
rb_cntl = RREG32(DMA_RB_CNTL + sdma_offsets[i]);
@@ -177,9 +175,6 @@ static int si_dma_start(struct amdgpu_device *adev)
r = amdgpu_ring_test_helper(ring);
if (r)
return r;
-
- if (adev->mman.buffer_funcs_ring == ring)
- amdgpu_ttm_set_buffer_funcs_status(adev, true);
}
return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c
index 66ed28136bc8..d4b8d62f4294 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15.c
+++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
@@ -646,8 +646,7 @@ static void soc15_program_aspm(struct amdgpu_device *adev)
if (!amdgpu_device_should_use_aspm(adev))
return;
- if (!(adev->flags & AMD_IS_APU) &&
- (adev->nbio.funcs->program_aspm))
+ if (adev->nbio.funcs->program_aspm)
adev->nbio.funcs->program_aspm(adev);
}
diff --git a/drivers/gpu/drm/amd/amdgpu/soc21.c b/drivers/gpu/drm/amd/amdgpu/soc21.c
index 8c6cab641a1c..d5083c549330 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc21.c
+++ b/drivers/gpu/drm/amd/amdgpu/soc21.c
@@ -433,8 +433,7 @@ static void soc21_program_aspm(struct amdgpu_device *adev)
if (!amdgpu_device_should_use_aspm(adev))
return;
- if (!(adev->flags & AMD_IS_APU) &&
- (adev->nbio.funcs->program_aspm))
+ if (adev->nbio.funcs->program_aspm)
adev->nbio.funcs->program_aspm(adev);
}
diff --git a/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c b/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c
index 025e6aeb058d..770b4b4e3138 100644
--- a/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c
@@ -88,6 +88,26 @@ static void umc_v12_0_reset_error_count(struct amdgpu_device *adev)
umc_v12_0_reset_error_count_per_channel, NULL);
}
+static bool umc_v12_0_is_uncorrectable_error(uint64_t mc_umc_status)
+{
+ return ((REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1) &&
+ (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, PCC) == 1 ||
+ REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UC) == 1 ||
+ REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, TCC) == 1));
+}
+
+static bool umc_v12_0_is_correctable_error(uint64_t mc_umc_status)
+{
+ return (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
+ (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1 ||
+ (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1 &&
+ REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UC) == 0) ||
+ /* Identify data parity error in replay mode */
+ ((REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, ErrorCodeExt) == 0x5 ||
+ REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, ErrorCodeExt) == 0xb) &&
+ !(umc_v12_0_is_uncorrectable_error(mc_umc_status)))));
+}
+
static void umc_v12_0_query_correctable_error_count(struct amdgpu_device *adev,
uint64_t umc_reg_offset,
unsigned long *error_count)
@@ -104,10 +124,7 @@ static void umc_v12_0_query_correctable_error_count(struct amdgpu_device *adev,
mc_umc_status =
RREG64_PCIE_EXT((mc_umc_status_addr + umc_reg_offset) * 4);
- if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
- (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1 ||
- (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1 &&
- REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UC) == 0)))
+ if (umc_v12_0_is_correctable_error(mc_umc_status))
*error_count += 1;
}
@@ -125,11 +142,7 @@ static void umc_v12_0_query_uncorrectable_error_count(struct amdgpu_device *adev
mc_umc_status =
RREG64_PCIE_EXT((mc_umc_status_addr + umc_reg_offset) * 4);
- if ((REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1) &&
- (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Deferred) == 1 ||
- REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, PCC) == 1 ||
- REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UC) == 1 ||
- REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, TCC) == 1))
+ if (umc_v12_0_is_uncorrectable_error(mc_umc_status))
*error_count += 1;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/umc_v8_10.c b/drivers/gpu/drm/amd/amdgpu/umc_v8_10.c
index 46bfdee79bfd..c4c77257710c 100644
--- a/drivers/gpu/drm/amd/amdgpu/umc_v8_10.c
+++ b/drivers/gpu/drm/amd/amdgpu/umc_v8_10.c
@@ -336,7 +336,7 @@ static void umc_v8_10_ecc_info_query_correctable_error_count(struct amdgpu_devic
uint32_t node_inst, uint32_t umc_inst, uint32_t ch_inst,
unsigned long *error_count)
{
- uint64_t mc_umc_status;
+ uint16_t ecc_ce_cnt;
uint32_t eccinfo_table_idx;
struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
@@ -345,12 +345,10 @@ static void umc_v8_10_ecc_info_query_correctable_error_count(struct amdgpu_devic
umc_inst * adev->umc.channel_inst_num +
ch_inst;
- /* check the MCUMC_STATUS */
- mc_umc_status = ras->umc_ecc.ecc[eccinfo_table_idx].mca_umc_status;
- if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
- REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1) {
- *error_count += 1;
- }
+ /* Retrieve CE count */
+ ecc_ce_cnt = ras->umc_ecc.ecc[eccinfo_table_idx].ce_count_lo_chip;
+ if (ecc_ce_cnt)
+ *error_count += ecc_ce_cnt;
}
static void umc_v8_10_ecc_info_query_uncorrectable_error_count(struct amdgpu_device *adev,
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
index 6a8494f98d3e..1a98812981f4 100644
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -1124,11 +1124,10 @@ static void vi_program_aspm(struct amdgpu_device *adev)
bool bL1SS = false;
bool bClkReqSupport = true;
- if (!amdgpu_device_should_use_aspm(adev) || !amdgpu_device_aspm_support_quirk())
+ if (!amdgpu_device_should_use_aspm(adev))
return;
- if (adev->flags & AMD_IS_APU ||
- adev->asic_type < CHIP_POLARIS10)
+ if (adev->asic_type < CHIP_POLARIS10)
return;
orig = data = RREG32_PCIE(ixPCIE_LC_CNTL);
diff --git a/drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c b/drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c
index 756f39348dd9..174f13eff575 100644
--- a/drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c
@@ -205,19 +205,21 @@ static int vpe_v6_1_ring_start(struct amdgpu_vpe *vpe)
static int vpe_v_6_1_ring_stop(struct amdgpu_vpe *vpe)
{
struct amdgpu_device *adev = vpe->ring.adev;
- uint32_t rb_cntl, ib_cntl;
+ uint32_t queue_reset;
+ int ret;
- rb_cntl = RREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE0_RB_CNTL));
- rb_cntl = REG_SET_FIELD(rb_cntl, VPEC_QUEUE0_RB_CNTL, RB_ENABLE, 0);
- WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE0_RB_CNTL), rb_cntl);
+ queue_reset = RREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE_RESET_REQ));
+ queue_reset = REG_SET_FIELD(queue_reset, VPEC_QUEUE_RESET_REQ, QUEUE0_RESET, 1);
+ WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE_RESET_REQ), queue_reset);
- ib_cntl = RREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE0_IB_CNTL));
- ib_cntl = REG_SET_FIELD(ib_cntl, VPEC_QUEUE0_IB_CNTL, IB_ENABLE, 0);
- WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_QUEUE0_IB_CNTL), ib_cntl);
+ ret = SOC15_WAIT_ON_RREG(VPE, 0, regVPEC_QUEUE_RESET_REQ, 0,
+ VPEC_QUEUE_RESET_REQ__QUEUE0_RESET_MASK);
+ if (ret)
+ dev_err(adev->dev, "VPE queue reset failed\n");
vpe->ring.sched.ready = false;
- return 0;
+ return ret;
}
static int vpe_v6_1_set_trap_irq_state(struct amdgpu_device *adev,
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
index 0e792a8496d6..cd8e459201f1 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
@@ -1404,6 +1404,66 @@ static int kfd_fill_gpu_cache_info_from_gfx_config(struct kfd_dev *kdev,
return i;
}
+static int kfd_fill_gpu_cache_info_from_gfx_config_v2(struct kfd_dev *kdev,
+ struct kfd_gpu_cache_info *pcache_info)
+{
+ struct amdgpu_device *adev = kdev->adev;
+ int i = 0;
+
+ /* TCP L1 Cache per CU */
+ if (adev->gfx.config.gc_tcp_size_per_cu) {
+ pcache_info[i].cache_size = adev->gfx.config.gc_tcp_size_per_cu;
+ pcache_info[i].cache_level = 1;
+ pcache_info[i].flags = (CRAT_CACHE_FLAGS_ENABLED |
+ CRAT_CACHE_FLAGS_DATA_CACHE |
+ CRAT_CACHE_FLAGS_SIMD_CACHE);
+ pcache_info[i].num_cu_shared = 1;
+ i++;
+ }
+ /* Scalar L1 Instruction Cache per SQC */
+ if (adev->gfx.config.gc_l1_instruction_cache_size_per_sqc) {
+ pcache_info[i].cache_size =
+ adev->gfx.config.gc_l1_instruction_cache_size_per_sqc;
+ pcache_info[i].cache_level = 1;
+ pcache_info[i].flags = (CRAT_CACHE_FLAGS_ENABLED |
+ CRAT_CACHE_FLAGS_INST_CACHE |
+ CRAT_CACHE_FLAGS_SIMD_CACHE);
+ pcache_info[i].num_cu_shared = adev->gfx.config.gc_num_cu_per_sqc;
+ i++;
+ }
+ /* Scalar L1 Data Cache per SQC */
+ if (adev->gfx.config.gc_l1_data_cache_size_per_sqc) {
+ pcache_info[i].cache_size = adev->gfx.config.gc_l1_data_cache_size_per_sqc;
+ pcache_info[i].cache_level = 1;
+ pcache_info[i].flags = (CRAT_CACHE_FLAGS_ENABLED |
+ CRAT_CACHE_FLAGS_DATA_CACHE |
+ CRAT_CACHE_FLAGS_SIMD_CACHE);
+ pcache_info[i].num_cu_shared = adev->gfx.config.gc_num_cu_per_sqc;
+ i++;
+ }
+ /* L2 Data Cache per GPU (Total Tex Cache) */
+ if (adev->gfx.config.gc_tcc_size) {
+ pcache_info[i].cache_size = adev->gfx.config.gc_tcc_size;
+ pcache_info[i].cache_level = 2;
+ pcache_info[i].flags = (CRAT_CACHE_FLAGS_ENABLED |
+ CRAT_CACHE_FLAGS_DATA_CACHE |
+ CRAT_CACHE_FLAGS_SIMD_CACHE);
+ pcache_info[i].num_cu_shared = adev->gfx.config.max_cu_per_sh;
+ i++;
+ }
+ /* L3 Data Cache per GPU */
+ if (adev->gmc.mall_size) {
+ pcache_info[i].cache_size = adev->gmc.mall_size / 1024;
+ pcache_info[i].cache_level = 3;
+ pcache_info[i].flags = (CRAT_CACHE_FLAGS_ENABLED |
+ CRAT_CACHE_FLAGS_DATA_CACHE |
+ CRAT_CACHE_FLAGS_SIMD_CACHE);
+ pcache_info[i].num_cu_shared = adev->gfx.config.max_cu_per_sh;
+ i++;
+ }
+ return i;
+}
+
int kfd_get_gpu_cache_info(struct kfd_node *kdev, struct kfd_gpu_cache_info **pcache_info)
{
int num_of_cache_types = 0;
@@ -1461,10 +1521,14 @@ int kfd_get_gpu_cache_info(struct kfd_node *kdev, struct kfd_gpu_cache_info **pc
num_of_cache_types = ARRAY_SIZE(vega20_cache_info);
break;
case IP_VERSION(9, 4, 2):
- case IP_VERSION(9, 4, 3):
*pcache_info = aldebaran_cache_info;
num_of_cache_types = ARRAY_SIZE(aldebaran_cache_info);
break;
+ case IP_VERSION(9, 4, 3):
+ num_of_cache_types =
+ kfd_fill_gpu_cache_info_from_gfx_config_v2(kdev->kfd,
+ *pcache_info);
+ break;
case IP_VERSION(9, 1, 0):
case IP_VERSION(9, 2, 2):
*pcache_info = raven_cache_info;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
index 81d25a679427..6c25dab051d5 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
@@ -442,10 +442,10 @@ svm_migrate_vma_to_vram(struct kfd_node *node, struct svm_range *prange,
goto out_free;
}
if (cpages != npages)
- pr_debug("partial migration, 0x%lx/0x%llx pages collected\n",
+ pr_debug("partial migration, 0x%lx/0x%llx pages migrated\n",
cpages, npages);
else
- pr_debug("0x%lx pages collected\n", cpages);
+ pr_debug("0x%lx pages migrated\n", cpages);
r = svm_migrate_copy_to_vram(node, prange, &migrate, &mfence, scratch, ttm_res_offset);
migrate_vma_pages(&migrate);
@@ -479,8 +479,6 @@ out:
* svm_migrate_ram_to_vram - migrate svm range from system to device
* @prange: range structure
* @best_loc: the device to migrate to
- * @start_mgr: start page to migrate
- * @last_mgr: last page to migrate
* @mm: the process mm structure
* @trigger: reason of migration
*
@@ -491,7 +489,6 @@ out:
*/
static int
svm_migrate_ram_to_vram(struct svm_range *prange, uint32_t best_loc,
- unsigned long start_mgr, unsigned long last_mgr,
struct mm_struct *mm, uint32_t trigger)
{
unsigned long addr, start, end;
@@ -501,30 +498,23 @@ svm_migrate_ram_to_vram(struct svm_range *prange, uint32_t best_loc,
unsigned long cpages = 0;
long r = 0;
- if (!best_loc) {
- pr_debug("svms 0x%p [0x%lx 0x%lx] migrate to sys ram\n",
- prange->svms, start_mgr, last_mgr);
+ if (prange->actual_loc == best_loc) {
+ pr_debug("svms 0x%p [0x%lx 0x%lx] already on best_loc 0x%x\n",
+ prange->svms, prange->start, prange->last, best_loc);
return 0;
}
- if (start_mgr < prange->start || last_mgr > prange->last) {
- pr_debug("range [0x%lx 0x%lx] out prange [0x%lx 0x%lx]\n",
- start_mgr, last_mgr, prange->start, prange->last);
- return -EFAULT;
- }
-
node = svm_range_get_node_by_id(prange, best_loc);
if (!node) {
pr_debug("failed to get kfd node by id 0x%x\n", best_loc);
return -ENODEV;
}
- pr_debug("svms 0x%p [0x%lx 0x%lx] in [0x%lx 0x%lx] to gpu 0x%x\n",
- prange->svms, start_mgr, last_mgr, prange->start, prange->last,
- best_loc);
+ pr_debug("svms 0x%p [0x%lx 0x%lx] to gpu 0x%x\n", prange->svms,
+ prange->start, prange->last, best_loc);
- start = start_mgr << PAGE_SHIFT;
- end = (last_mgr + 1) << PAGE_SHIFT;
+ start = prange->start << PAGE_SHIFT;
+ end = (prange->last + 1) << PAGE_SHIFT;
r = svm_range_vram_node_new(node, prange, true);
if (r) {
@@ -554,11 +544,8 @@ svm_migrate_ram_to_vram(struct svm_range *prange, uint32_t best_loc,
if (cpages) {
prange->actual_loc = best_loc;
- prange->vram_pages = prange->vram_pages + cpages;
- } else if (!prange->actual_loc) {
- /* if no page migrated and all pages from prange are at
- * sys ram drop svm_bo got from svm_range_vram_node_new
- */
+ svm_range_dma_unmap(prange);
+ } else {
svm_range_vram_node_free(prange);
}
@@ -676,8 +663,9 @@ out_oom:
* Context: Process context, caller hold mmap read lock, prange->migrate_mutex
*
* Return:
+ * 0 - success with all pages migrated
* negative values - indicate error
- * positive values or zero - number of pages got migrated
+ * positive values - partial migration, number of pages not migrated
*/
static long
svm_migrate_vma_to_ram(struct kfd_node *node, struct svm_range *prange,
@@ -688,7 +676,6 @@ svm_migrate_vma_to_ram(struct kfd_node *node, struct svm_range *prange,
uint64_t npages = (end - start) >> PAGE_SHIFT;
unsigned long upages = npages;
unsigned long cpages = 0;
- unsigned long mpages = 0;
struct amdgpu_device *adev = node->adev;
struct kfd_process_device *pdd;
struct dma_fence *mfence = NULL;
@@ -738,10 +725,10 @@ svm_migrate_vma_to_ram(struct kfd_node *node, struct svm_range *prange,
goto out_free;
}
if (cpages != npages)
- pr_debug("partial migration, 0x%lx/0x%llx pages collected\n",
+ pr_debug("partial migration, 0x%lx/0x%llx pages migrated\n",
cpages, npages);
else
- pr_debug("0x%lx pages collected\n", cpages);
+ pr_debug("0x%lx pages migrated\n", cpages);
r = svm_migrate_copy_to_ram(adev, prange, &migrate, &mfence,
scratch, npages);
@@ -764,21 +751,17 @@ out_free:
kvfree(buf);
out:
if (!r && cpages) {
- mpages = cpages - upages;
pdd = svm_range_get_pdd_by_node(prange, node);
if (pdd)
- WRITE_ONCE(pdd->page_out, pdd->page_out + mpages);
+ WRITE_ONCE(pdd->page_out, pdd->page_out + cpages);
}
-
- return r ? r : mpages;
+ return r ? r : upages;
}
/**
* svm_migrate_vram_to_ram - migrate svm range from device to system
* @prange: range structure
* @mm: process mm, use current->mm if NULL
- * @start_mgr: start page need be migrated to sys ram
- * @last_mgr: last page need be migrated to sys ram
* @trigger: reason of migration
* @fault_page: is from vmf->page, svm_migrate_to_ram(), this is CPU page fault callback
*
@@ -788,7 +771,6 @@ out:
* 0 - OK, otherwise error code
*/
int svm_migrate_vram_to_ram(struct svm_range *prange, struct mm_struct *mm,
- unsigned long start_mgr, unsigned long last_mgr,
uint32_t trigger, struct page *fault_page)
{
struct kfd_node *node;
@@ -796,33 +778,26 @@ int svm_migrate_vram_to_ram(struct svm_range *prange, struct mm_struct *mm,
unsigned long addr;
unsigned long start;
unsigned long end;
- unsigned long mpages = 0;
+ unsigned long upages = 0;
long r = 0;
- /* this pragne has no any vram page to migrate to sys ram */
if (!prange->actual_loc) {
pr_debug("[0x%lx 0x%lx] already migrated to ram\n",
prange->start, prange->last);
return 0;
}
- if (start_mgr < prange->start || last_mgr > prange->last) {
- pr_debug("range [0x%lx 0x%lx] out prange [0x%lx 0x%lx]\n",
- start_mgr, last_mgr, prange->start, prange->last);
- return -EFAULT;
- }
-
node = svm_range_get_node_by_id(prange, prange->actual_loc);
if (!node) {
pr_debug("failed to get kfd node by id 0x%x\n", prange->actual_loc);
return -ENODEV;
}
pr_debug("svms 0x%p prange 0x%p [0x%lx 0x%lx] from gpu 0x%x to ram\n",
- prange->svms, prange, start_mgr, last_mgr,
+ prange->svms, prange, prange->start, prange->last,
prange->actual_loc);
- start = start_mgr << PAGE_SHIFT;
- end = (last_mgr + 1) << PAGE_SHIFT;
+ start = prange->start << PAGE_SHIFT;
+ end = (prange->last + 1) << PAGE_SHIFT;
for (addr = start; addr < end;) {
unsigned long next;
@@ -841,21 +816,14 @@ int svm_migrate_vram_to_ram(struct svm_range *prange, struct mm_struct *mm,
pr_debug("failed %ld to migrate prange %p\n", r, prange);
break;
} else {
- mpages += r;
+ upages += r;
}
addr = next;
}
- if (r >= 0) {
- prange->vram_pages -= mpages;
-
- /* prange does not have vram page set its actual_loc to system
- * and drop its svm_bo ref
- */
- if (prange->vram_pages == 0 && prange->ttm_res) {
- prange->actual_loc = 0;
- svm_range_vram_node_free(prange);
- }
+ if (r >= 0 && !upages) {
+ svm_range_vram_node_free(prange);
+ prange->actual_loc = 0;
}
return r < 0 ? r : 0;
@@ -865,23 +833,17 @@ int svm_migrate_vram_to_ram(struct svm_range *prange, struct mm_struct *mm,
* svm_migrate_vram_to_vram - migrate svm range from device to device
* @prange: range structure
* @best_loc: the device to migrate to
- * @start: start page need be migrated to sys ram
- * @last: last page need be migrated to sys ram
* @mm: process mm, use current->mm if NULL
* @trigger: reason of migration
*
* Context: Process context, caller hold mmap read lock, svms lock, prange lock
*
- * migrate all vram pages in prange to sys ram, then migrate
- * [start, last] pages from sys ram to gpu node best_loc.
- *
* Return:
* 0 - OK, otherwise error code
*/
static int
svm_migrate_vram_to_vram(struct svm_range *prange, uint32_t best_loc,
- unsigned long start, unsigned long last,
- struct mm_struct *mm, uint32_t trigger)
+ struct mm_struct *mm, uint32_t trigger)
{
int r, retries = 3;
@@ -893,8 +855,7 @@ svm_migrate_vram_to_vram(struct svm_range *prange, uint32_t best_loc,
pr_debug("from gpu 0x%x to gpu 0x%x\n", prange->actual_loc, best_loc);
do {
- r = svm_migrate_vram_to_ram(prange, mm, prange->start, prange->last,
- trigger, NULL);
+ r = svm_migrate_vram_to_ram(prange, mm, trigger, NULL);
if (r)
return r;
} while (prange->actual_loc && --retries);
@@ -902,21 +863,17 @@ svm_migrate_vram_to_vram(struct svm_range *prange, uint32_t best_loc,
if (prange->actual_loc)
return -EDEADLK;
- return svm_migrate_ram_to_vram(prange, best_loc, start, last, mm, trigger);
+ return svm_migrate_ram_to_vram(prange, best_loc, mm, trigger);
}
int
svm_migrate_to_vram(struct svm_range *prange, uint32_t best_loc,
- unsigned long start, unsigned long last,
- struct mm_struct *mm, uint32_t trigger)
+ struct mm_struct *mm, uint32_t trigger)
{
- if (!prange->actual_loc || prange->actual_loc == best_loc)
- return svm_migrate_ram_to_vram(prange, best_loc, start, last,
- mm, trigger);
-
+ if (!prange->actual_loc)
+ return svm_migrate_ram_to_vram(prange, best_loc, mm, trigger);
else
- return svm_migrate_vram_to_vram(prange, best_loc, start, last,
- mm, trigger);
+ return svm_migrate_vram_to_vram(prange, best_loc, mm, trigger);
}
@@ -932,9 +889,10 @@ svm_migrate_to_vram(struct svm_range *prange, uint32_t best_loc,
*/
static vm_fault_t svm_migrate_to_ram(struct vm_fault *vmf)
{
- unsigned long start, last, size;
unsigned long addr = vmf->address;
struct svm_range_bo *svm_bo;
+ enum svm_work_list_ops op;
+ struct svm_range *parent;
struct svm_range *prange;
struct kfd_process *p;
struct mm_struct *mm;
@@ -971,31 +929,51 @@ static vm_fault_t svm_migrate_to_ram(struct vm_fault *vmf)
mutex_lock(&p->svms.lock);
- prange = svm_range_from_addr(&p->svms, addr, NULL);
+ prange = svm_range_from_addr(&p->svms, addr, &parent);
if (!prange) {
pr_debug("failed get range svms 0x%p addr 0x%lx\n", &p->svms, addr);
r = -EFAULT;
goto out_unlock_svms;
}
- mutex_lock(&prange->migrate_mutex);
+ mutex_lock(&parent->migrate_mutex);
+ if (prange != parent)
+ mutex_lock_nested(&prange->migrate_mutex, 1);
if (!prange->actual_loc)
goto out_unlock_prange;
- /* Align migration range start and size to granularity size */
- size = 1UL << prange->granularity;
- start = max(ALIGN_DOWN(addr, size), prange->start);
- last = min(ALIGN(addr + 1, size) - 1, prange->last);
+ svm_range_lock(parent);
+ if (prange != parent)
+ mutex_lock_nested(&prange->lock, 1);
+ r = svm_range_split_by_granularity(p, mm, addr, parent, prange);
+ if (prange != parent)
+ mutex_unlock(&prange->lock);
+ svm_range_unlock(parent);
+ if (r) {
+ pr_debug("failed %d to split range by granularity\n", r);
+ goto out_unlock_prange;
+ }
- r = svm_migrate_vram_to_ram(prange, vmf->vma->vm_mm, start, last,
- KFD_MIGRATE_TRIGGER_PAGEFAULT_CPU, vmf->page);
+ r = svm_migrate_vram_to_ram(prange, vmf->vma->vm_mm,
+ KFD_MIGRATE_TRIGGER_PAGEFAULT_CPU,
+ vmf->page);
if (r)
pr_debug("failed %d migrate svms 0x%p range 0x%p [0x%lx 0x%lx]\n",
- r, prange->svms, prange, start, last);
+ r, prange->svms, prange, prange->start, prange->last);
+
+ /* xnack on, update mapping on GPUs with ACCESS_IN_PLACE */
+ if (p->xnack_enabled && parent == prange)
+ op = SVM_OP_UPDATE_RANGE_NOTIFIER_AND_MAP;
+ else
+ op = SVM_OP_UPDATE_RANGE_NOTIFIER;
+ svm_range_add_list_work(&p->svms, parent, mm, op);
+ schedule_deferred_list_work(&p->svms);
out_unlock_prange:
- mutex_unlock(&prange->migrate_mutex);
+ if (prange != parent)
+ mutex_unlock(&prange->migrate_mutex);
+ mutex_unlock(&parent->migrate_mutex);
out_unlock_svms:
mutex_unlock(&p->svms.lock);
out_unref_process:
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.h b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.h
index 9e48d10e848e..487f26368164 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.h
@@ -41,13 +41,9 @@ enum MIGRATION_COPY_DIR {
};
int svm_migrate_to_vram(struct svm_range *prange, uint32_t best_loc,
- unsigned long start, unsigned long last,
struct mm_struct *mm, uint32_t trigger);
-
int svm_migrate_vram_to_ram(struct svm_range *prange, struct mm_struct *mm,
- unsigned long start, unsigned long last,
- uint32_t trigger, struct page *fault_page);
-
+ uint32_t trigger, struct page *fault_page);
unsigned long
svm_migrate_addr_to_pfn(struct amdgpu_device *adev, unsigned long addr);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
index bda88dc6e2fa..e67d06a42809 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
@@ -158,13 +158,12 @@ svm_is_valid_dma_mapping_addr(struct device *dev, dma_addr_t dma_addr)
static int
svm_range_dma_map_dev(struct amdgpu_device *adev, struct svm_range *prange,
unsigned long offset, unsigned long npages,
- unsigned long *hmm_pfns, uint32_t gpuidx, uint64_t *vram_pages)
+ unsigned long *hmm_pfns, uint32_t gpuidx)
{
enum dma_data_direction dir = DMA_BIDIRECTIONAL;
dma_addr_t *addr = prange->dma_addr[gpuidx];
struct device *dev = adev->dev;
struct page *page;
- uint64_t vram_pages_dev;
int i, r;
if (!addr) {
@@ -174,7 +173,6 @@ svm_range_dma_map_dev(struct amdgpu_device *adev, struct svm_range *prange,
prange->dma_addr[gpuidx] = addr;
}
- vram_pages_dev = 0;
addr += offset;
for (i = 0; i < npages; i++) {
if (svm_is_valid_dma_mapping_addr(dev, addr[i]))
@@ -184,7 +182,6 @@ svm_range_dma_map_dev(struct amdgpu_device *adev, struct svm_range *prange,
if (is_zone_device_page(page)) {
struct amdgpu_device *bo_adev = prange->svm_bo->node->adev;
- vram_pages_dev++;
addr[i] = (hmm_pfns[i] << PAGE_SHIFT) +
bo_adev->vm_manager.vram_base_offset -
bo_adev->kfd.pgmap.range.start;
@@ -201,14 +198,13 @@ svm_range_dma_map_dev(struct amdgpu_device *adev, struct svm_range *prange,
pr_debug_ratelimited("dma mapping 0x%llx for page addr 0x%lx\n",
addr[i] >> PAGE_SHIFT, page_to_pfn(page));
}
- *vram_pages = vram_pages_dev;
return 0;
}
static int
svm_range_dma_map(struct svm_range *prange, unsigned long *bitmap,
unsigned long offset, unsigned long npages,
- unsigned long *hmm_pfns, uint64_t *vram_pages)
+ unsigned long *hmm_pfns)
{
struct kfd_process *p;
uint32_t gpuidx;
@@ -227,7 +223,7 @@ svm_range_dma_map(struct svm_range *prange, unsigned long *bitmap,
}
r = svm_range_dma_map_dev(pdd->dev->adev, prange, offset, npages,
- hmm_pfns, gpuidx, vram_pages);
+ hmm_pfns, gpuidx);
if (r)
break;
}
@@ -353,7 +349,6 @@ svm_range *svm_range_new(struct svm_range_list *svms, uint64_t start,
INIT_LIST_HEAD(&prange->child_list);
atomic_set(&prange->invalid, 0);
prange->validate_timestamp = 0;
- prange->vram_pages = 0;
mutex_init(&prange->migrate_mutex);
mutex_init(&prange->lock);
@@ -400,8 +395,6 @@ static void svm_range_bo_release(struct kref *kref)
prange->start, prange->last);
mutex_lock(&prange->lock);
prange->svm_bo = NULL;
- /* prange should not hold vram page now */
- WARN_ON(prange->actual_loc);
mutex_unlock(&prange->lock);
spin_lock(&svm_bo->list_lock);
@@ -783,7 +776,7 @@ svm_range_apply_attrs(struct kfd_process *p, struct svm_range *prange,
prange->flags &= ~attrs[i].value;
break;
case KFD_IOCTL_SVM_ATTR_GRANULARITY:
- prange->granularity = attrs[i].value;
+ prange->granularity = min_t(uint32_t, attrs[i].value, 0x3F);
break;
default:
WARN_ONCE(1, "svm_range_check_attrs wasn't called?");
@@ -982,11 +975,6 @@ svm_range_split_nodes(struct svm_range *new, struct svm_range *old,
new->svm_bo = svm_range_bo_ref(old->svm_bo);
new->ttm_res = old->ttm_res;
- /* set new's vram_pages as old range's now, the acurate vram_pages
- * will be updated during mapping
- */
- new->vram_pages = min(old->vram_pages, new->npages);
-
spin_lock(&new->svm_bo->list_lock);
list_add(&new->svm_bo_list, &new->svm_bo->range_list);
spin_unlock(&new->svm_bo->list_lock);
@@ -1147,6 +1135,66 @@ svm_range_add_child(struct svm_range *prange, struct mm_struct *mm,
list_add_tail(&pchild->child_list, &prange->child_list);
}
+/**
+ * svm_range_split_by_granularity - collect ranges within granularity boundary
+ *
+ * @p: the process with svms list
+ * @mm: mm structure
+ * @addr: the vm fault address in pages, to split the prange
+ * @parent: parent range if prange is from child list
+ * @prange: prange to split
+ *
+ * Trims @prange to be a single aligned block of prange->granularity if
+ * possible. The head and tail are added to the child_list in @parent.
+ *
+ * Context: caller must hold mmap_read_lock and prange->lock
+ *
+ * Return:
+ * 0 - OK, otherwise error code
+ */
+int
+svm_range_split_by_granularity(struct kfd_process *p, struct mm_struct *mm,
+ unsigned long addr, struct svm_range *parent,
+ struct svm_range *prange)
+{
+ struct svm_range *head, *tail;
+ unsigned long start, last, size;
+ int r;
+
+ /* Align splited range start and size to granularity size, then a single
+ * PTE will be used for whole range, this reduces the number of PTE
+ * updated and the L1 TLB space used for translation.
+ */
+ size = 1UL << prange->granularity;
+ start = ALIGN_DOWN(addr, size);
+ last = ALIGN(addr + 1, size) - 1;
+
+ pr_debug("svms 0x%p split [0x%lx 0x%lx] to [0x%lx 0x%lx] size 0x%lx\n",
+ prange->svms, prange->start, prange->last, start, last, size);
+
+ if (start > prange->start) {
+ r = svm_range_split(prange, start, prange->last, &head);
+ if (r)
+ return r;
+ svm_range_add_child(parent, mm, head, SVM_OP_ADD_RANGE);
+ }
+
+ if (last < prange->last) {
+ r = svm_range_split(prange, prange->start, last, &tail);
+ if (r)
+ return r;
+ svm_range_add_child(parent, mm, tail, SVM_OP_ADD_RANGE);
+ }
+
+ /* xnack on, update mapping on GPUs with ACCESS_IN_PLACE */
+ if (p->xnack_enabled && prange->work_item.op == SVM_OP_ADD_RANGE) {
+ prange->work_item.op = SVM_OP_ADD_RANGE_AND_MAP;
+ pr_debug("change prange 0x%p [0x%lx 0x%lx] op %d\n",
+ prange, prange->start, prange->last,
+ SVM_OP_ADD_RANGE_AND_MAP);
+ }
+ return 0;
+}
static bool
svm_nodes_in_same_hive(struct kfd_node *node_a, struct kfd_node *node_b)
{
@@ -1234,7 +1282,7 @@ svm_range_get_pte_flags(struct kfd_node *node,
if (num_possible_nodes() <= 1)
mapping_flags |= mtype_local;
else
- mapping_flags |= AMDGPU_VM_MTYPE_NC;
+ mapping_flags |= ext_coherent ? AMDGPU_VM_MTYPE_UC : AMDGPU_VM_MTYPE_NC;
/* system memory accessed by the dGPU */
} else {
mapping_flags |= AMDGPU_VM_MTYPE_UC;
@@ -1269,7 +1317,7 @@ svm_range_unmap_from_gpu(struct amdgpu_device *adev, struct amdgpu_vm *vm,
pr_debug("[0x%llx 0x%llx]\n", start, last);
- return amdgpu_vm_update_range(adev, vm, false, true, true, NULL, start,
+ return amdgpu_vm_update_range(adev, vm, false, true, true, false, NULL, start,
last, init_pte_value, 0, 0, NULL, NULL,
fence);
}
@@ -1376,8 +1424,8 @@ svm_range_map_to_gpu(struct kfd_process_device *pdd, struct svm_range *prange,
* different memory partition based on fpfn/lpfn, we should use
* same vm_manager.vram_base_offset regardless memory partition.
*/
- r = amdgpu_vm_update_range(adev, vm, false, false, flush_tlb, NULL,
- last_start, prange->start + i,
+ r = amdgpu_vm_update_range(adev, vm, false, false, flush_tlb, true,
+ NULL, last_start, prange->start + i,
pte_flags,
(last_start - prange->start) << PAGE_SHIFT,
bo_adev ? bo_adev->vm_manager.vram_base_offset : 0,
@@ -1570,7 +1618,6 @@ static int svm_range_validate_and_map(struct mm_struct *mm,
struct svm_validate_context *ctx;
unsigned long start, end, addr;
struct kfd_process *p;
- uint64_t vram_pages;
void *owner;
int32_t idx;
int r = 0;
@@ -1639,13 +1686,11 @@ static int svm_range_validate_and_map(struct mm_struct *mm,
}
}
- vram_pages = 0;
start = prange->start << PAGE_SHIFT;
end = (prange->last + 1) << PAGE_SHIFT;
for (addr = start; !r && addr < end; ) {
struct hmm_range *hmm_range;
struct vm_area_struct *vma;
- uint64_t vram_pages_vma;
unsigned long next = 0;
unsigned long offset;
unsigned long npages;
@@ -1674,11 +1719,9 @@ static int svm_range_validate_and_map(struct mm_struct *mm,
if (!r) {
offset = (addr - start) >> PAGE_SHIFT;
r = svm_range_dma_map(prange, ctx->bitmap, offset, npages,
- hmm_range->hmm_pfns, &vram_pages_vma);
+ hmm_range->hmm_pfns);
if (r)
pr_debug("failed %d to dma map range\n", r);
- else
- vram_pages += vram_pages_vma;
}
svm_range_lock(prange);
@@ -1704,19 +1747,6 @@ static int svm_range_validate_and_map(struct mm_struct *mm,
addr = next;
}
- if (addr == end) {
- prange->vram_pages = vram_pages;
-
- /* if prange does not include any vram page and it
- * has not released svm_bo drop its svm_bo reference
- * and set its actaul_loc to sys ram
- */
- if (!vram_pages && prange->ttm_res) {
- prange->actual_loc = 0;
- svm_range_vram_node_free(prange);
- }
- }
-
svm_range_unreserve_bos(ctx);
if (!r)
prange->validate_timestamp = ktime_get_boottime();
@@ -1969,7 +1999,6 @@ static struct svm_range *svm_range_clone(struct svm_range *old)
new->actual_loc = old->actual_loc;
new->granularity = old->granularity;
new->mapped_to_gpu = old->mapped_to_gpu;
- new->vram_pages = old->vram_pages;
bitmap_copy(new->bitmap_access, old->bitmap_access, MAX_GPU_INSTANCE);
bitmap_copy(new->bitmap_aip, old->bitmap_aip, MAX_GPU_INSTANCE);
@@ -2035,6 +2064,7 @@ svm_range_split_new(struct svm_range_list *svms, uint64_t start, uint64_t last,
* @update_list: output, the ranges need validate and update GPU mapping
* @insert_list: output, the ranges need insert to svms
* @remove_list: output, the ranges are replaced and need remove from svms
+ * @remap_list: output, remap unaligned svm ranges
*
* Check if the virtual address range has overlap with any existing ranges,
* split partly overlapping ranges and add new ranges in the gaps. All changes
@@ -2876,7 +2906,6 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid,
uint32_t vmid, uint32_t node_id,
uint64_t addr, bool write_fault)
{
- unsigned long start, last, size;
struct mm_struct *mm = NULL;
struct svm_range_list *svms;
struct svm_range *prange;
@@ -3012,35 +3041,32 @@ retry_write_locked:
kfd_smi_event_page_fault_start(node, p->lead_thread->pid, addr,
write_fault, timestamp);
- if (prange->actual_loc != 0 || best_loc != 0) {
+ if (prange->actual_loc != best_loc) {
migration = true;
- /* Align migration range start and size to granularity size */
- size = 1UL << prange->granularity;
- start = max_t(unsigned long, ALIGN_DOWN(addr, size), prange->start);
- last = min_t(unsigned long, ALIGN(addr + 1, size) - 1, prange->last);
-
if (best_loc) {
- r = svm_migrate_to_vram(prange, best_loc, start, last,
- mm, KFD_MIGRATE_TRIGGER_PAGEFAULT_GPU);
+ r = svm_migrate_to_vram(prange, best_loc, mm,
+ KFD_MIGRATE_TRIGGER_PAGEFAULT_GPU);
if (r) {
pr_debug("svm_migrate_to_vram failed (%d) at %llx, falling back to system memory\n",
r, addr);
/* Fallback to system memory if migration to
* VRAM failed
*/
- if (prange->actual_loc && prange->actual_loc != best_loc)
- r = svm_migrate_vram_to_ram(prange, mm, start, last,
- KFD_MIGRATE_TRIGGER_PAGEFAULT_GPU, NULL);
+ if (prange->actual_loc)
+ r = svm_migrate_vram_to_ram(prange, mm,
+ KFD_MIGRATE_TRIGGER_PAGEFAULT_GPU,
+ NULL);
else
r = 0;
}
} else {
- r = svm_migrate_vram_to_ram(prange, mm, start, last,
- KFD_MIGRATE_TRIGGER_PAGEFAULT_GPU, NULL);
+ r = svm_migrate_vram_to_ram(prange, mm,
+ KFD_MIGRATE_TRIGGER_PAGEFAULT_GPU,
+ NULL);
}
if (r) {
pr_debug("failed %d to migrate svms %p [0x%lx 0x%lx]\n",
- r, svms, start, last);
+ r, svms, prange->start, prange->last);
goto out_unlock_range;
}
}
@@ -3394,24 +3420,18 @@ svm_range_trigger_migration(struct mm_struct *mm, struct svm_range *prange,
*migrated = false;
best_loc = svm_range_best_prefetch_location(prange);
- /* when best_loc is a gpu node and same as prange->actual_loc
- * we still need do migration as prange->actual_loc !=0 does
- * not mean all pages in prange are vram. hmm migrate will pick
- * up right pages during migration.
- */
- if ((best_loc == KFD_IOCTL_SVM_LOCATION_UNDEFINED) ||
- (best_loc == 0 && prange->actual_loc == 0))
+ if (best_loc == KFD_IOCTL_SVM_LOCATION_UNDEFINED ||
+ best_loc == prange->actual_loc)
return 0;
if (!best_loc) {
- r = svm_migrate_vram_to_ram(prange, mm, prange->start, prange->last,
+ r = svm_migrate_vram_to_ram(prange, mm,
KFD_MIGRATE_TRIGGER_PREFETCH, NULL);
*migrated = !r;
return r;
}
- r = svm_migrate_to_vram(prange, best_loc, prange->start, prange->last,
- mm, KFD_MIGRATE_TRIGGER_PREFETCH);
+ r = svm_migrate_to_vram(prange, best_loc, mm, KFD_MIGRATE_TRIGGER_PREFETCH);
*migrated = !r;
return r;
@@ -3466,11 +3486,7 @@ static void svm_range_evict_svm_bo_worker(struct work_struct *work)
mutex_lock(&prange->migrate_mutex);
do {
- /* migrate all vram pages in this prange to sys ram
- * after that prange->actual_loc should be zero
- */
r = svm_migrate_vram_to_ram(prange, mm,
- prange->start, prange->last,
KFD_MIGRATE_TRIGGER_TTM_EVICTION, NULL);
} while (!r && prange->actual_loc && --retries);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
index 026863a0abcd..c528df1d0ba2 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
@@ -78,7 +78,6 @@ struct svm_work_list_item {
* @update_list:link list node used to add to update_list
* @mapping: bo_va mapping structure to create and update GPU page table
* @npages: number of pages
- * @vram_pages: vram pages number in this svm_range
* @dma_addr: dma mapping address on each GPU for system memory physical page
* @ttm_res: vram ttm resource map
* @offset: range start offset within mm_nodes
@@ -89,9 +88,7 @@ struct svm_work_list_item {
* @flags: flags defined as KFD_IOCTL_SVM_FLAG_*
* @perferred_loc: perferred location, 0 for CPU, or GPU id
* @perfetch_loc: last prefetch location, 0 for CPU, or GPU id
- * @actual_loc: this svm_range location. 0: all pages are from sys ram;
- * GPU id: this svm_range may include vram pages from GPU with
- * id actual_loc.
+ * @actual_loc: the actual location, 0 for CPU, or GPU id
* @granularity:migration granularity, log2 num pages
* @invalid: not 0 means cpu page table is invalidated
* @validate_timestamp: system timestamp when range is validated
@@ -115,7 +112,6 @@ struct svm_range {
struct list_head list;
struct list_head update_list;
uint64_t npages;
- uint64_t vram_pages;
dma_addr_t *dma_addr[MAX_GPU_INSTANCE];
struct ttm_resource *ttm_res;
uint64_t offset;
@@ -172,6 +168,9 @@ struct kfd_node *svm_range_get_node_by_id(struct svm_range *prange,
int svm_range_vram_node_new(struct kfd_node *node, struct svm_range *prange,
bool clear);
void svm_range_vram_node_free(struct svm_range *prange);
+int svm_range_split_by_granularity(struct kfd_process *p, struct mm_struct *mm,
+ unsigned long addr, struct svm_range *parent,
+ struct svm_range *prange);
int svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid,
uint32_t vmid, uint32_t node_id, uint64_t addr,
bool write_fault);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
index 4e530791507e..dc7c8312e8c7 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
@@ -1602,10 +1602,13 @@ static int fill_in_l2_l3_pcache(struct kfd_cache_properties **props_ext,
unsigned int cu_sibling_map_mask;
int first_active_cu;
int i, j, k, xcc, start, end;
+ int num_xcc = NUM_XCC(knode->xcc_mask);
struct kfd_cache_properties *pcache = NULL;
+ enum amdgpu_memory_partition mode;
+ struct amdgpu_device *adev = knode->adev;
start = ffs(knode->xcc_mask) - 1;
- end = start + NUM_XCC(knode->xcc_mask);
+ end = start + num_xcc;
cu_sibling_map_mask = cu_info->bitmap[start][0][0];
cu_sibling_map_mask &=
((1 << pcache_info[cache_type].num_cu_shared) - 1);
@@ -1624,7 +1627,18 @@ static int fill_in_l2_l3_pcache(struct kfd_cache_properties **props_ext,
pcache->processor_id_low = cu_processor_id
+ (first_active_cu - 1);
pcache->cache_level = pcache_info[cache_type].cache_level;
- pcache->cache_size = pcache_info[cache_type].cache_size;
+
+ if (KFD_GC_VERSION(knode) == IP_VERSION(9, 4, 3))
+ mode = adev->gmc.gmc_funcs->query_mem_partition_mode(adev);
+ else
+ mode = UNKNOWN_MEMORY_PARTITION_MODE;
+
+ if (pcache->cache_level == 2)
+ pcache->cache_size = pcache_info[cache_type].cache_size * num_xcc;
+ else if (mode)
+ pcache->cache_size = pcache_info[cache_type].cache_size / mode;
+ else
+ pcache->cache_size = pcache_info[cache_type].cache_size;
if (pcache_info[cache_type].flags & CRAT_CACHE_FLAGS_DATA_CACHE)
pcache->cache_type |= HSA_CACHE_TYPE_DATA;
diff --git a/drivers/gpu/drm/amd/amdxcp/amdgpu_xcp_drv.c b/drivers/gpu/drm/amd/amdxcp/amdgpu_xcp_drv.c
index 353597fc908d..90ddd8371176 100644
--- a/drivers/gpu/drm/amd/amdxcp/amdgpu_xcp_drv.c
+++ b/drivers/gpu/drm/amd/amdxcp/amdgpu_xcp_drv.c
@@ -89,9 +89,10 @@ EXPORT_SYMBOL(amdgpu_xcp_drm_dev_alloc);
void amdgpu_xcp_drv_release(void)
{
for (--pdev_num; pdev_num >= 0; --pdev_num) {
- devres_release_group(&xcp_dev[pdev_num]->pdev->dev, NULL);
- platform_device_unregister(xcp_dev[pdev_num]->pdev);
- xcp_dev[pdev_num]->pdev = NULL;
+ struct platform_device *pdev = xcp_dev[pdev_num]->pdev;
+
+ devres_release_group(&pdev->dev, NULL);
+ platform_device_unregister(pdev);
xcp_dev[pdev_num] = NULL;
}
pdev_num = 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 9a712791f309..6f99f6754c11 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1642,7 +1642,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
init_data.flags.gpu_vm_support = (amdgpu_sg_display != 0) && (adev->flags & AMD_IS_APU);
}
- init_data.flags.gpu_vm_support = adev->mode_info.gpu_vm_support;
+ adev->mode_info.gpu_vm_support = init_data.flags.gpu_vm_support;
if (amdgpu_dc_feature_mask & DC_FBC_MASK)
init_data.flags.fbc_support = true;
@@ -6513,6 +6513,9 @@ static void create_eml_sink(struct amdgpu_dm_connector *aconnector)
return;
}
+ if (drm_detect_hdmi_monitor(edid))
+ init_params.sink_signal = SIGNAL_TYPE_HDMI_TYPE_A;
+
aconnector->edid = edid;
aconnector->dc_em_sink = dc_link_add_remote_sink(
@@ -9877,7 +9880,7 @@ static int dm_update_plane_state(struct dc *dc,
/* Block top most plane from being a video plane */
if (plane->type == DRM_PLANE_TYPE_OVERLAY) {
- if (is_video_format(new_plane_state->fb->format->format) && *is_top_most_overlay)
+ if (amdgpu_dm_plane_is_video_format(new_plane_state->fb->format->format) && *is_top_most_overlay)
return -EINVAL;
*is_top_most_overlay = false;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
index 97b7a0b8a1c2..cb0b48bb2a7d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
@@ -96,7 +96,7 @@ bool amdgpu_dm_crtc_vrr_active(struct dm_crtc_state *dm_state)
dm_state->freesync_config.state == VRR_STATE_ACTIVE_FIXED;
}
-static void vblank_control_worker(struct work_struct *work)
+static void amdgpu_dm_crtc_vblank_control_worker(struct work_struct *work)
{
struct vblank_control_work *vblank_work =
container_of(work, struct vblank_control_work, work);
@@ -151,7 +151,7 @@ static void vblank_control_worker(struct work_struct *work)
kfree(vblank_work);
}
-static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable)
+static inline int amdgpu_dm_crtc_set_vblank(struct drm_crtc *crtc, bool enable)
{
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
struct amdgpu_device *adev = drm_to_adev(crtc->dev);
@@ -191,7 +191,7 @@ skip:
if (!work)
return -ENOMEM;
- INIT_WORK(&work->work, vblank_control_worker);
+ INIT_WORK(&work->work, amdgpu_dm_crtc_vblank_control_worker);
work->dm = dm;
work->acrtc = acrtc;
work->enable = enable;
@@ -209,15 +209,15 @@ skip:
int amdgpu_dm_crtc_enable_vblank(struct drm_crtc *crtc)
{
- return dm_set_vblank(crtc, true);
+ return amdgpu_dm_crtc_set_vblank(crtc, true);
}
void amdgpu_dm_crtc_disable_vblank(struct drm_crtc *crtc)
{
- dm_set_vblank(crtc, false);
+ amdgpu_dm_crtc_set_vblank(crtc, false);
}
-static void dm_crtc_destroy_state(struct drm_crtc *crtc,
+static void amdgpu_dm_crtc_destroy_state(struct drm_crtc *crtc,
struct drm_crtc_state *state)
{
struct dm_crtc_state *cur = to_dm_crtc_state(state);
@@ -233,7 +233,7 @@ static void dm_crtc_destroy_state(struct drm_crtc *crtc,
kfree(state);
}
-static struct drm_crtc_state *dm_crtc_duplicate_state(struct drm_crtc *crtc)
+static struct drm_crtc_state *amdgpu_dm_crtc_duplicate_state(struct drm_crtc *crtc)
{
struct dm_crtc_state *state, *cur;
@@ -273,12 +273,12 @@ static void amdgpu_dm_crtc_destroy(struct drm_crtc *crtc)
kfree(crtc);
}
-static void dm_crtc_reset_state(struct drm_crtc *crtc)
+static void amdgpu_dm_crtc_reset_state(struct drm_crtc *crtc)
{
struct dm_crtc_state *state;
if (crtc->state)
- dm_crtc_destroy_state(crtc, crtc->state);
+ amdgpu_dm_crtc_destroy_state(crtc, crtc->state);
state = kzalloc(sizeof(*state), GFP_KERNEL);
if (WARN_ON(!state))
@@ -298,12 +298,12 @@ static int amdgpu_dm_crtc_late_register(struct drm_crtc *crtc)
/* Implemented only the options currently available for the driver */
static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
- .reset = dm_crtc_reset_state,
+ .reset = amdgpu_dm_crtc_reset_state,
.destroy = amdgpu_dm_crtc_destroy,
.set_config = drm_atomic_helper_set_config,
.page_flip = drm_atomic_helper_page_flip,
- .atomic_duplicate_state = dm_crtc_duplicate_state,
- .atomic_destroy_state = dm_crtc_destroy_state,
+ .atomic_duplicate_state = amdgpu_dm_crtc_duplicate_state,
+ .atomic_destroy_state = amdgpu_dm_crtc_destroy_state,
.set_crc_source = amdgpu_dm_crtc_set_crc_source,
.verify_crc_source = amdgpu_dm_crtc_verify_crc_source,
.get_crc_sources = amdgpu_dm_crtc_get_crc_sources,
@@ -316,11 +316,11 @@ static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
#endif
};
-static void dm_crtc_helper_disable(struct drm_crtc *crtc)
+static void amdgpu_dm_crtc_helper_disable(struct drm_crtc *crtc)
{
}
-static int count_crtc_active_planes(struct drm_crtc_state *new_crtc_state)
+static int amdgpu_dm_crtc_count_crtc_active_planes(struct drm_crtc_state *new_crtc_state)
{
struct drm_atomic_state *state = new_crtc_state->state;
struct drm_plane *plane;
@@ -352,8 +352,8 @@ static int count_crtc_active_planes(struct drm_crtc_state *new_crtc_state)
return num_active;
}
-static void dm_update_crtc_active_planes(struct drm_crtc *crtc,
- struct drm_crtc_state *new_crtc_state)
+static void amdgpu_dm_crtc_update_crtc_active_planes(struct drm_crtc *crtc,
+ struct drm_crtc_state *new_crtc_state)
{
struct dm_crtc_state *dm_new_crtc_state =
to_dm_crtc_state(new_crtc_state);
@@ -364,18 +364,18 @@ static void dm_update_crtc_active_planes(struct drm_crtc *crtc,
return;
dm_new_crtc_state->active_planes =
- count_crtc_active_planes(new_crtc_state);
+ amdgpu_dm_crtc_count_crtc_active_planes(new_crtc_state);
}
-static bool dm_crtc_helper_mode_fixup(struct drm_crtc *crtc,
+static bool amdgpu_dm_crtc_helper_mode_fixup(struct drm_crtc *crtc,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
return true;
}
-static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc,
- struct drm_atomic_state *state)
+static int amdgpu_dm_crtc_helper_atomic_check(struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
{
struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
crtc);
@@ -386,7 +386,7 @@ static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc,
trace_amdgpu_dm_crtc_atomic_check(crtc_state);
- dm_update_crtc_active_planes(crtc, crtc_state);
+ amdgpu_dm_crtc_update_crtc_active_planes(crtc, crtc_state);
if (WARN_ON(unlikely(!dm_crtc_state->stream &&
amdgpu_dm_crtc_modeset_required(crtc_state, NULL, dm_crtc_state->stream)))) {
@@ -429,9 +429,9 @@ static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc,
}
static const struct drm_crtc_helper_funcs amdgpu_dm_crtc_helper_funcs = {
- .disable = dm_crtc_helper_disable,
- .atomic_check = dm_crtc_helper_atomic_check,
- .mode_fixup = dm_crtc_helper_mode_fixup,
+ .disable = amdgpu_dm_crtc_helper_disable,
+ .atomic_check = amdgpu_dm_crtc_helper_atomic_check,
+ .mode_fixup = amdgpu_dm_crtc_helper_mode_fixup,
.get_scanout_position = amdgpu_crtc_get_scanout_position,
};
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
index 1259d6351c50..13a177d34376 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -3645,7 +3645,9 @@ static int capabilities_show(struct seq_file *m, void *unused)
struct amdgpu_device *adev = (struct amdgpu_device *)m->private;
struct dc *dc = adev->dm.dc;
bool mall_supported = dc->caps.mall_size_total;
+ bool subvp_supported = dc->caps.subvp_fw_processing_delay_us;
unsigned int mall_in_use = false;
+ unsigned int subvp_in_use = dc->cap_funcs.get_subvp_en(dc, dc->current_state);
struct hubbub *hubbub = dc->res_pool->hubbub;
if (hubbub->funcs->get_mall_en)
@@ -3653,6 +3655,8 @@ static int capabilities_show(struct seq_file *m, void *unused)
seq_printf(m, "mall supported: %s, enabled: %s\n",
mall_supported ? "yes" : "no", mall_in_use ? "yes" : "no");
+ seq_printf(m, "sub-viewport supported: %s, enabled: %s\n",
+ subvp_supported ? "yes" : "no", subvp_in_use ? "yes" : "no");
return 0;
}
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 03df26bd8e83..116121e647ca 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -139,7 +139,7 @@ void amdgpu_dm_plane_fill_blending_from_plane_state(const struct drm_plane_state
}
}
-static void add_modifier(uint64_t **mods, uint64_t *size, uint64_t *cap, uint64_t mod)
+static void amdgpu_dm_plane_add_modifier(uint64_t **mods, uint64_t *size, uint64_t *cap, uint64_t mod)
{
if (!*mods)
return;
@@ -164,12 +164,12 @@ static void add_modifier(uint64_t **mods, uint64_t *size, uint64_t *cap, uint64_
*size += 1;
}
-static bool modifier_has_dcc(uint64_t modifier)
+static bool amdgpu_dm_plane_modifier_has_dcc(uint64_t modifier)
{
return IS_AMD_FMT_MOD(modifier) && AMD_FMT_MOD_GET(DCC, modifier);
}
-static unsigned int modifier_gfx9_swizzle_mode(uint64_t modifier)
+static unsigned int amdgpu_dm_plane_modifier_gfx9_swizzle_mode(uint64_t modifier)
{
if (modifier == DRM_FORMAT_MOD_LINEAR)
return 0;
@@ -177,8 +177,8 @@ static unsigned int modifier_gfx9_swizzle_mode(uint64_t modifier)
return AMD_FMT_MOD_GET(TILE, modifier);
}
-static void fill_gfx8_tiling_info_from_flags(union dc_tiling_info *tiling_info,
- uint64_t tiling_flags)
+static void amdgpu_dm_plane_fill_gfx8_tiling_info_from_flags(union dc_tiling_info *tiling_info,
+ uint64_t tiling_flags)
{
/* Fill GFX8 params */
if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == DC_ARRAY_2D_TILED_THIN1) {
@@ -209,8 +209,8 @@ static void fill_gfx8_tiling_info_from_flags(union dc_tiling_info *tiling_info,
AMDGPU_TILING_GET(tiling_flags, PIPE_CONFIG);
}
-static void fill_gfx9_tiling_info_from_device(const struct amdgpu_device *adev,
- union dc_tiling_info *tiling_info)
+static void amdgpu_dm_plane_fill_gfx9_tiling_info_from_device(const struct amdgpu_device *adev,
+ union dc_tiling_info *tiling_info)
{
/* Fill GFX9 params */
tiling_info->gfx9.num_pipes =
@@ -230,9 +230,9 @@ static void fill_gfx9_tiling_info_from_device(const struct amdgpu_device *adev,
tiling_info->gfx9.num_pkrs = adev->gfx.config.gb_addr_config_fields.num_pkrs;
}
-static void fill_gfx9_tiling_info_from_modifier(const struct amdgpu_device *adev,
- union dc_tiling_info *tiling_info,
- uint64_t modifier)
+static void amdgpu_dm_plane_fill_gfx9_tiling_info_from_modifier(const struct amdgpu_device *adev,
+ union dc_tiling_info *tiling_info,
+ uint64_t modifier)
{
unsigned int mod_bank_xor_bits = AMD_FMT_MOD_GET(BANK_XOR_BITS, modifier);
unsigned int mod_pipe_xor_bits = AMD_FMT_MOD_GET(PIPE_XOR_BITS, modifier);
@@ -241,7 +241,7 @@ static void fill_gfx9_tiling_info_from_modifier(const struct amdgpu_device *adev
pipes_log2 = min(5u, mod_pipe_xor_bits);
- fill_gfx9_tiling_info_from_device(adev, tiling_info);
+ amdgpu_dm_plane_fill_gfx9_tiling_info_from_device(adev, tiling_info);
if (!IS_AMD_FMT_MOD(modifier))
return;
@@ -258,13 +258,13 @@ static void fill_gfx9_tiling_info_from_modifier(const struct amdgpu_device *adev
}
}
-static int validate_dcc(struct amdgpu_device *adev,
- const enum surface_pixel_format format,
- const enum dc_rotation_angle rotation,
- const union dc_tiling_info *tiling_info,
- const struct dc_plane_dcc_param *dcc,
- const struct dc_plane_address *address,
- const struct plane_size *plane_size)
+static int amdgpu_dm_plane_validate_dcc(struct amdgpu_device *adev,
+ const enum surface_pixel_format format,
+ const enum dc_rotation_angle rotation,
+ const union dc_tiling_info *tiling_info,
+ const struct dc_plane_dcc_param *dcc,
+ const struct dc_plane_address *address,
+ const struct plane_size *plane_size)
{
struct dc *dc = adev->dm.dc;
struct dc_dcc_surface_param input;
@@ -303,23 +303,23 @@ static int validate_dcc(struct amdgpu_device *adev,
return 0;
}
-static int fill_gfx9_plane_attributes_from_modifiers(struct amdgpu_device *adev,
- const struct amdgpu_framebuffer *afb,
- const enum surface_pixel_format format,
- const enum dc_rotation_angle rotation,
- const struct plane_size *plane_size,
- union dc_tiling_info *tiling_info,
- struct dc_plane_dcc_param *dcc,
- struct dc_plane_address *address,
- const bool force_disable_dcc)
+static int amdgpu_dm_plane_fill_gfx9_plane_attributes_from_modifiers(struct amdgpu_device *adev,
+ const struct amdgpu_framebuffer *afb,
+ const enum surface_pixel_format format,
+ const enum dc_rotation_angle rotation,
+ const struct plane_size *plane_size,
+ union dc_tiling_info *tiling_info,
+ struct dc_plane_dcc_param *dcc,
+ struct dc_plane_address *address,
+ const bool force_disable_dcc)
{
const uint64_t modifier = afb->base.modifier;
int ret = 0;
- fill_gfx9_tiling_info_from_modifier(adev, tiling_info, modifier);
- tiling_info->gfx9.swizzle = modifier_gfx9_swizzle_mode(modifier);
+ amdgpu_dm_plane_fill_gfx9_tiling_info_from_modifier(adev, tiling_info, modifier);
+ tiling_info->gfx9.swizzle = amdgpu_dm_plane_modifier_gfx9_swizzle_mode(modifier);
- if (modifier_has_dcc(modifier) && !force_disable_dcc) {
+ if (amdgpu_dm_plane_modifier_has_dcc(modifier) && !force_disable_dcc) {
uint64_t dcc_address = afb->address + afb->base.offsets[1];
bool independent_64b_blks = AMD_FMT_MOD_GET(DCC_INDEPENDENT_64B, modifier);
bool independent_128b_blks = AMD_FMT_MOD_GET(DCC_INDEPENDENT_128B, modifier);
@@ -347,60 +347,64 @@ static int fill_gfx9_plane_attributes_from_modifiers(struct amdgpu_device *adev,
address->grph.meta_addr.high_part = upper_32_bits(dcc_address);
}
- ret = validate_dcc(adev, format, rotation, tiling_info, dcc, address, plane_size);
+ ret = amdgpu_dm_plane_validate_dcc(adev, format, rotation, tiling_info, dcc, address, plane_size);
if (ret)
- drm_dbg_kms(adev_to_drm(adev), "validate_dcc: returned error: %d\n", ret);
+ drm_dbg_kms(adev_to_drm(adev), "amdgpu_dm_plane_validate_dcc: returned error: %d\n", ret);
return ret;
}
-static void add_gfx10_1_modifiers(const struct amdgpu_device *adev,
- uint64_t **mods, uint64_t *size, uint64_t *capacity)
+static void amdgpu_dm_plane_add_gfx10_1_modifiers(const struct amdgpu_device *adev,
+ uint64_t **mods,
+ uint64_t *size,
+ uint64_t *capacity)
{
int pipe_xor_bits = ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes);
- add_modifier(mods, size, capacity, AMD_FMT_MOD |
- AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
- AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10) |
- AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
- AMD_FMT_MOD_SET(DCC, 1) |
- AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
- AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
- AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B));
-
- add_modifier(mods, size, capacity, AMD_FMT_MOD |
- AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
- AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10) |
- AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
- AMD_FMT_MOD_SET(DCC, 1) |
- AMD_FMT_MOD_SET(DCC_RETILE, 1) |
- AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
- AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
- AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B));
-
- add_modifier(mods, size, capacity, AMD_FMT_MOD |
- AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
- AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10) |
- AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits));
-
- add_modifier(mods, size, capacity, AMD_FMT_MOD |
- AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
- AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10) |
- AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits));
-
-
- /* Only supported for 64bpp, will be filtered in dm_plane_format_mod_supported */
- add_modifier(mods, size, capacity, AMD_FMT_MOD |
- AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D) |
- AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9));
-
- add_modifier(mods, size, capacity, AMD_FMT_MOD |
- AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S) |
- AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9));
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
+ AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10) |
+ AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
+ AMD_FMT_MOD_SET(DCC, 1) |
+ AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
+ AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
+ AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B));
+
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
+ AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10) |
+ AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
+ AMD_FMT_MOD_SET(DCC, 1) |
+ AMD_FMT_MOD_SET(DCC_RETILE, 1) |
+ AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
+ AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
+ AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B));
+
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
+ AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10) |
+ AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits));
+
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
+ AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10) |
+ AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits));
+
+
+ /* Only supported for 64bpp, will be filtered in amdgpu_dm_plane_format_mod_supported */
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D) |
+ AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9));
+
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S) |
+ AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9));
}
-static void add_gfx9_modifiers(const struct amdgpu_device *adev,
- uint64_t **mods, uint64_t *size, uint64_t *capacity)
+static void amdgpu_dm_plane_add_gfx9_modifiers(const struct amdgpu_device *adev,
+ uint64_t **mods,
+ uint64_t *size,
+ uint64_t *capacity)
{
int pipes = ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes);
int pipe_xor_bits = min(8, pipes +
@@ -421,163 +425,164 @@ static void add_gfx9_modifiers(const struct amdgpu_device *adev,
*/
if (has_constant_encode) {
- add_modifier(mods, size, capacity, AMD_FMT_MOD |
- AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
- AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
- AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
- AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) |
- AMD_FMT_MOD_SET(DCC, 1) |
- AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
- AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B) |
- AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1));
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
+ AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
+ AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
+ AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) |
+ AMD_FMT_MOD_SET(DCC, 1) |
+ AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
+ AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B) |
+ AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1));
}
- add_modifier(mods, size, capacity, AMD_FMT_MOD |
- AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
- AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
- AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
- AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) |
- AMD_FMT_MOD_SET(DCC, 1) |
- AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
- AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B) |
- AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 0));
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
+ AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
+ AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
+ AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) |
+ AMD_FMT_MOD_SET(DCC, 1) |
+ AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
+ AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B) |
+ AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 0));
if (has_constant_encode) {
- add_modifier(mods, size, capacity, AMD_FMT_MOD |
- AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
- AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
- AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
- AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) |
- AMD_FMT_MOD_SET(DCC, 1) |
- AMD_FMT_MOD_SET(DCC_RETILE, 1) |
- AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
- AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B) |
-
- AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
- AMD_FMT_MOD_SET(RB, rb) |
- AMD_FMT_MOD_SET(PIPE, pipes));
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
+ AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
+ AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
+ AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) |
+ AMD_FMT_MOD_SET(DCC, 1) |
+ AMD_FMT_MOD_SET(DCC_RETILE, 1) |
+ AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
+ AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B) |
+ AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
+ AMD_FMT_MOD_SET(RB, rb) |
+ AMD_FMT_MOD_SET(PIPE, pipes));
}
- add_modifier(mods, size, capacity, AMD_FMT_MOD |
- AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
- AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
- AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
- AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) |
- AMD_FMT_MOD_SET(DCC, 1) |
- AMD_FMT_MOD_SET(DCC_RETILE, 1) |
- AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
- AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B) |
- AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 0) |
- AMD_FMT_MOD_SET(RB, rb) |
- AMD_FMT_MOD_SET(PIPE, pipes));
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
+ AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
+ AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
+ AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) |
+ AMD_FMT_MOD_SET(DCC, 1) |
+ AMD_FMT_MOD_SET(DCC_RETILE, 1) |
+ AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
+ AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B) |
+ AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 0) |
+ AMD_FMT_MOD_SET(RB, rb) |
+ AMD_FMT_MOD_SET(PIPE, pipes));
}
/*
* Only supported for 64bpp on Raven, will be filtered on format in
- * dm_plane_format_mod_supported.
+ * amdgpu_dm_plane_format_mod_supported.
*/
- add_modifier(mods, size, capacity, AMD_FMT_MOD |
- AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D_X) |
- AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
- AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
- AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits));
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D_X) |
+ AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
+ AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
+ AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits));
if (adev->family == AMDGPU_FAMILY_RV) {
- add_modifier(mods, size, capacity, AMD_FMT_MOD |
- AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
- AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
- AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
- AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits));
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
+ AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
+ AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
+ AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits));
}
/*
* Only supported for 64bpp on Raven, will be filtered on format in
- * dm_plane_format_mod_supported.
+ * amdgpu_dm_plane_format_mod_supported.
*/
- add_modifier(mods, size, capacity, AMD_FMT_MOD |
- AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D) |
- AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9));
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D) |
+ AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9));
if (adev->family == AMDGPU_FAMILY_RV) {
- add_modifier(mods, size, capacity, AMD_FMT_MOD |
- AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S) |
- AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9));
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S) |
+ AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9));
}
}
-static void add_gfx10_3_modifiers(const struct amdgpu_device *adev,
- uint64_t **mods, uint64_t *size, uint64_t *capacity)
+static void amdgpu_dm_plane_add_gfx10_3_modifiers(const struct amdgpu_device *adev,
+ uint64_t **mods,
+ uint64_t *size,
+ uint64_t *capacity)
{
int pipe_xor_bits = ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes);
int pkrs = ilog2(adev->gfx.config.gb_addr_config_fields.num_pkrs);
- add_modifier(mods, size, capacity, AMD_FMT_MOD |
- AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
- AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
- AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
- AMD_FMT_MOD_SET(PACKERS, pkrs) |
- AMD_FMT_MOD_SET(DCC, 1) |
- AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
- AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
- AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
- AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B));
-
- add_modifier(mods, size, capacity, AMD_FMT_MOD |
- AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
- AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
- AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
- AMD_FMT_MOD_SET(PACKERS, pkrs) |
- AMD_FMT_MOD_SET(DCC, 1) |
- AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
- AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
- AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_128B));
-
- add_modifier(mods, size, capacity, AMD_FMT_MOD |
- AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
- AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
- AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
- AMD_FMT_MOD_SET(PACKERS, pkrs) |
- AMD_FMT_MOD_SET(DCC, 1) |
- AMD_FMT_MOD_SET(DCC_RETILE, 1) |
- AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
- AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
- AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
- AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B));
-
- add_modifier(mods, size, capacity, AMD_FMT_MOD |
- AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
- AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
- AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
- AMD_FMT_MOD_SET(PACKERS, pkrs) |
- AMD_FMT_MOD_SET(DCC, 1) |
- AMD_FMT_MOD_SET(DCC_RETILE, 1) |
- AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
- AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
- AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_128B));
-
- add_modifier(mods, size, capacity, AMD_FMT_MOD |
- AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
- AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
- AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
- AMD_FMT_MOD_SET(PACKERS, pkrs));
-
- add_modifier(mods, size, capacity, AMD_FMT_MOD |
- AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
- AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
- AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
- AMD_FMT_MOD_SET(PACKERS, pkrs));
-
- /* Only supported for 64bpp, will be filtered in dm_plane_format_mod_supported */
- add_modifier(mods, size, capacity, AMD_FMT_MOD |
- AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D) |
- AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9));
-
- add_modifier(mods, size, capacity, AMD_FMT_MOD |
- AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S) |
- AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9));
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
+ AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
+ AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
+ AMD_FMT_MOD_SET(PACKERS, pkrs) |
+ AMD_FMT_MOD_SET(DCC, 1) |
+ AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
+ AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
+ AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
+ AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B));
+
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
+ AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
+ AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
+ AMD_FMT_MOD_SET(PACKERS, pkrs) |
+ AMD_FMT_MOD_SET(DCC, 1) |
+ AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
+ AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
+ AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_128B));
+
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
+ AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
+ AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
+ AMD_FMT_MOD_SET(PACKERS, pkrs) |
+ AMD_FMT_MOD_SET(DCC, 1) |
+ AMD_FMT_MOD_SET(DCC_RETILE, 1) |
+ AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
+ AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
+ AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
+ AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B));
+
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
+ AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
+ AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
+ AMD_FMT_MOD_SET(PACKERS, pkrs) |
+ AMD_FMT_MOD_SET(DCC, 1) |
+ AMD_FMT_MOD_SET(DCC_RETILE, 1) |
+ AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
+ AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
+ AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_128B));
+
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
+ AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
+ AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
+ AMD_FMT_MOD_SET(PACKERS, pkrs));
+
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
+ AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
+ AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
+ AMD_FMT_MOD_SET(PACKERS, pkrs));
+
+ /* Only supported for 64bpp, will be filtered in amdgpu_dm_plane_format_mod_supported */
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D) |
+ AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9));
+
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S) |
+ AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9));
}
-static void add_gfx11_modifiers(struct amdgpu_device *adev,
+static void amdgpu_dm_plane_add_gfx11_modifiers(struct amdgpu_device *adev,
uint64_t **mods, uint64_t *size, uint64_t *capacity)
{
int num_pipes = 0;
@@ -628,21 +633,21 @@ static void add_gfx11_modifiers(struct amdgpu_device *adev,
AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B);
- add_modifier(mods, size, capacity, modifier_dcc_best);
- add_modifier(mods, size, capacity, modifier_dcc_4k);
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, modifier_dcc_best);
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, modifier_dcc_4k);
- add_modifier(mods, size, capacity, modifier_dcc_best | AMD_FMT_MOD_SET(DCC_RETILE, 1));
- add_modifier(mods, size, capacity, modifier_dcc_4k | AMD_FMT_MOD_SET(DCC_RETILE, 1));
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, modifier_dcc_best | AMD_FMT_MOD_SET(DCC_RETILE, 1));
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, modifier_dcc_4k | AMD_FMT_MOD_SET(DCC_RETILE, 1));
- add_modifier(mods, size, capacity, modifier_r_x);
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, modifier_r_x);
}
- add_modifier(mods, size, capacity, AMD_FMT_MOD |
- AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX11) |
- AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D));
+ amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD |
+ AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX11) |
+ AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D));
}
-static int get_plane_modifiers(struct amdgpu_device *adev, unsigned int plane_type, uint64_t **mods)
+static int amdgpu_dm_plane_get_plane_modifiers(struct amdgpu_device *adev, unsigned int plane_type, uint64_t **mods)
{
uint64_t size = 0, capacity = 128;
*mods = NULL;
@@ -654,15 +659,15 @@ static int get_plane_modifiers(struct amdgpu_device *adev, unsigned int plane_ty
*mods = kmalloc(capacity * sizeof(uint64_t), GFP_KERNEL);
if (plane_type == DRM_PLANE_TYPE_CURSOR) {
- add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_LINEAR);
- add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_INVALID);
+ amdgpu_dm_plane_add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_LINEAR);
+ amdgpu_dm_plane_add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_INVALID);
return *mods ? 0 : -ENOMEM;
}
switch (adev->family) {
case AMDGPU_FAMILY_AI:
case AMDGPU_FAMILY_RV:
- add_gfx9_modifiers(adev, mods, &size, &capacity);
+ amdgpu_dm_plane_add_gfx9_modifiers(adev, mods, &size, &capacity);
break;
case AMDGPU_FAMILY_NV:
case AMDGPU_FAMILY_VGH:
@@ -670,21 +675,21 @@ static int get_plane_modifiers(struct amdgpu_device *adev, unsigned int plane_ty
case AMDGPU_FAMILY_GC_10_3_6:
case AMDGPU_FAMILY_GC_10_3_7:
if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(10, 3, 0))
- add_gfx10_3_modifiers(adev, mods, &size, &capacity);
+ amdgpu_dm_plane_add_gfx10_3_modifiers(adev, mods, &size, &capacity);
else
- add_gfx10_1_modifiers(adev, mods, &size, &capacity);
+ amdgpu_dm_plane_add_gfx10_1_modifiers(adev, mods, &size, &capacity);
break;
case AMDGPU_FAMILY_GC_11_0_0:
case AMDGPU_FAMILY_GC_11_0_1:
case AMDGPU_FAMILY_GC_11_5_0:
- add_gfx11_modifiers(adev, mods, &size, &capacity);
+ amdgpu_dm_plane_add_gfx11_modifiers(adev, mods, &size, &capacity);
break;
}
- add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_LINEAR);
+ amdgpu_dm_plane_add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_LINEAR);
/* INVALID marks the end of the list. */
- add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_INVALID);
+ amdgpu_dm_plane_add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_INVALID);
if (!*mods)
return -ENOMEM;
@@ -692,9 +697,9 @@ static int get_plane_modifiers(struct amdgpu_device *adev, unsigned int plane_ty
return 0;
}
-static int get_plane_formats(const struct drm_plane *plane,
- const struct dc_plane_cap *plane_cap,
- uint32_t *formats, int max_formats)
+static int amdgpu_dm_plane_get_plane_formats(const struct drm_plane *plane,
+ const struct dc_plane_cap *plane_cap,
+ uint32_t *formats, int max_formats)
{
int i, num_formats = 0;
@@ -818,22 +823,22 @@ int amdgpu_dm_plane_fill_plane_buffer_attributes(struct amdgpu_device *adev,
}
if (adev->family >= AMDGPU_FAMILY_AI) {
- ret = fill_gfx9_plane_attributes_from_modifiers(adev, afb, format,
- rotation, plane_size,
- tiling_info, dcc,
- address,
- force_disable_dcc);
+ ret = amdgpu_dm_plane_fill_gfx9_plane_attributes_from_modifiers(adev, afb, format,
+ rotation, plane_size,
+ tiling_info, dcc,
+ address,
+ force_disable_dcc);
if (ret)
return ret;
} else {
- fill_gfx8_tiling_info_from_flags(tiling_info, tiling_flags);
+ amdgpu_dm_plane_fill_gfx8_tiling_info_from_flags(tiling_info, tiling_flags);
}
return 0;
}
-static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
- struct drm_plane_state *new_state)
+static int amdgpu_dm_plane_helper_prepare_fb(struct drm_plane *plane,
+ struct drm_plane_state *new_state)
{
struct amdgpu_framebuffer *afb;
struct drm_gem_object *obj;
@@ -928,8 +933,8 @@ error_unlock:
return r;
}
-static void dm_plane_helper_cleanup_fb(struct drm_plane *plane,
- struct drm_plane_state *old_state)
+static void amdgpu_dm_plane_helper_cleanup_fb(struct drm_plane *plane,
+ struct drm_plane_state *old_state)
{
struct amdgpu_bo *rbo;
int r;
@@ -949,7 +954,7 @@ static void dm_plane_helper_cleanup_fb(struct drm_plane *plane,
amdgpu_bo_unref(&rbo);
}
-static void get_min_max_dc_plane_scaling(struct drm_device *dev,
+static void amdgpu_dm_plane_get_min_max_dc_plane_scaling(struct drm_device *dev,
struct drm_framebuffer *fb,
int *min_downscale, int *max_upscale)
{
@@ -1030,8 +1035,8 @@ int amdgpu_dm_plane_helper_check_state(struct drm_plane_state *state,
}
/* Get min/max allowed scaling factors from plane caps. */
- get_min_max_dc_plane_scaling(state->crtc->dev, fb,
- &min_downscale, &max_upscale);
+ amdgpu_dm_plane_get_min_max_dc_plane_scaling(state->crtc->dev, fb,
+ &min_downscale, &max_upscale);
/*
* Convert to drm convention: 16.16 fixed point, instead of dc's
* 1.0 == 1000. Also drm scaling is src/dst instead of dc's
@@ -1101,8 +1106,8 @@ int amdgpu_dm_plane_fill_dc_scaling_info(struct amdgpu_device *adev,
/* Validate scaling per-format with DC plane caps */
if (state->plane && state->plane->dev && state->fb) {
- get_min_max_dc_plane_scaling(state->plane->dev, state->fb,
- &min_downscale, &max_upscale);
+ amdgpu_dm_plane_get_min_max_dc_plane_scaling(state->plane->dev, state->fb,
+ &min_downscale, &max_upscale);
} else {
min_downscale = 250;
max_upscale = 16000;
@@ -1128,8 +1133,8 @@ int amdgpu_dm_plane_fill_dc_scaling_info(struct amdgpu_device *adev,
return 0;
}
-static int dm_plane_atomic_check(struct drm_plane *plane,
- struct drm_atomic_state *state)
+static int amdgpu_dm_plane_atomic_check(struct drm_plane *plane,
+ struct drm_atomic_state *state)
{
struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
plane);
@@ -1167,8 +1172,8 @@ static int dm_plane_atomic_check(struct drm_plane *plane,
return -EINVAL;
}
-static int dm_plane_atomic_async_check(struct drm_plane *plane,
- struct drm_atomic_state *state)
+static int amdgpu_dm_plane_atomic_async_check(struct drm_plane *plane,
+ struct drm_atomic_state *state)
{
/* Only support async updates on cursor planes. */
if (plane->type != DRM_PLANE_TYPE_CURSOR)
@@ -1177,8 +1182,8 @@ static int dm_plane_atomic_async_check(struct drm_plane *plane,
return 0;
}
-static int get_cursor_position(struct drm_plane *plane, struct drm_crtc *crtc,
- struct dc_cursor_position *position)
+static int amdgpu_dm_plane_get_cursor_position(struct drm_plane *plane, struct drm_crtc *crtc,
+ struct dc_cursor_position *position)
{
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
int x, y;
@@ -1241,7 +1246,7 @@ void amdgpu_dm_plane_handle_cursor_update(struct drm_plane *plane,
amdgpu_crtc->crtc_id, plane->state->crtc_w,
plane->state->crtc_h);
- ret = get_cursor_position(plane, crtc, &position);
+ ret = amdgpu_dm_plane_get_cursor_position(plane, crtc, &position);
if (ret)
return;
@@ -1290,8 +1295,8 @@ void amdgpu_dm_plane_handle_cursor_update(struct drm_plane *plane,
}
}
-static void dm_plane_atomic_async_update(struct drm_plane *plane,
- struct drm_atomic_state *state)
+static void amdgpu_dm_plane_atomic_async_update(struct drm_plane *plane,
+ struct drm_atomic_state *state)
{
struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
plane);
@@ -1315,14 +1320,14 @@ static void dm_plane_atomic_async_update(struct drm_plane *plane,
}
static const struct drm_plane_helper_funcs dm_plane_helper_funcs = {
- .prepare_fb = dm_plane_helper_prepare_fb,
- .cleanup_fb = dm_plane_helper_cleanup_fb,
- .atomic_check = dm_plane_atomic_check,
- .atomic_async_check = dm_plane_atomic_async_check,
- .atomic_async_update = dm_plane_atomic_async_update
+ .prepare_fb = amdgpu_dm_plane_helper_prepare_fb,
+ .cleanup_fb = amdgpu_dm_plane_helper_cleanup_fb,
+ .atomic_check = amdgpu_dm_plane_atomic_check,
+ .atomic_async_check = amdgpu_dm_plane_atomic_async_check,
+ .atomic_async_update = amdgpu_dm_plane_atomic_async_update
};
-static void dm_drm_plane_reset(struct drm_plane *plane)
+static void amdgpu_dm_plane_drm_plane_reset(struct drm_plane *plane)
{
struct dm_plane_state *amdgpu_state = NULL;
@@ -1336,8 +1341,7 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
__drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
}
-static struct drm_plane_state *
-dm_drm_plane_duplicate_state(struct drm_plane *plane)
+static struct drm_plane_state *amdgpu_dm_plane_drm_plane_duplicate_state(struct drm_plane *plane)
{
struct dm_plane_state *dm_plane_state, *old_dm_plane_state;
@@ -1356,15 +1360,15 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane)
return &dm_plane_state->base;
}
-static bool dm_plane_format_mod_supported(struct drm_plane *plane,
- uint32_t format,
- uint64_t modifier)
+static bool amdgpu_dm_plane_format_mod_supported(struct drm_plane *plane,
+ uint32_t format,
+ uint64_t modifier)
{
struct amdgpu_device *adev = drm_to_adev(plane->dev);
const struct drm_format_info *info = drm_format_info(format);
int i;
- enum dm_micro_swizzle microtile = modifier_gfx9_swizzle_mode(modifier) & 3;
+ enum dm_micro_swizzle microtile = amdgpu_dm_plane_modifier_gfx9_swizzle_mode(modifier) & 3;
if (!info)
return false;
@@ -1401,7 +1405,7 @@ static bool dm_plane_format_mod_supported(struct drm_plane *plane,
info->cpp[0] < 8)
return false;
- if (modifier_has_dcc(modifier)) {
+ if (amdgpu_dm_plane_modifier_has_dcc(modifier)) {
/* Per radeonsi comments 16/64 bpp are more complicated. */
if (info->cpp[0] != 4)
return false;
@@ -1415,8 +1419,8 @@ static bool dm_plane_format_mod_supported(struct drm_plane *plane,
return true;
}
-static void dm_drm_plane_destroy_state(struct drm_plane *plane,
- struct drm_plane_state *state)
+static void amdgpu_dm_plane_drm_plane_destroy_state(struct drm_plane *plane,
+ struct drm_plane_state *state)
{
struct dm_plane_state *dm_plane_state = to_dm_plane_state(state);
@@ -1430,10 +1434,10 @@ static const struct drm_plane_funcs dm_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = drm_plane_helper_destroy,
- .reset = dm_drm_plane_reset,
- .atomic_duplicate_state = dm_drm_plane_duplicate_state,
- .atomic_destroy_state = dm_drm_plane_destroy_state,
- .format_mod_supported = dm_plane_format_mod_supported,
+ .reset = amdgpu_dm_plane_drm_plane_reset,
+ .atomic_duplicate_state = amdgpu_dm_plane_drm_plane_duplicate_state,
+ .atomic_destroy_state = amdgpu_dm_plane_drm_plane_destroy_state,
+ .format_mod_supported = amdgpu_dm_plane_format_mod_supported,
};
int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
@@ -1447,10 +1451,10 @@ int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
unsigned int supported_rotations;
uint64_t *modifiers = NULL;
- num_formats = get_plane_formats(plane, plane_cap, formats,
- ARRAY_SIZE(formats));
+ num_formats = amdgpu_dm_plane_get_plane_formats(plane, plane_cap, formats,
+ ARRAY_SIZE(formats));
- res = get_plane_modifiers(dm->adev, plane->type, &modifiers);
+ res = amdgpu_dm_plane_get_plane_modifiers(dm->adev, plane->type, &modifiers);
if (res)
return res;
@@ -1520,7 +1524,7 @@ int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
return 0;
}
-bool is_video_format(uint32_t format)
+bool amdgpu_dm_plane_is_video_format(uint32_t format)
{
int i;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
index 930f1572f898..b51a6b57bd9b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
@@ -62,5 +62,5 @@ void amdgpu_dm_plane_fill_blending_from_plane_state(const struct drm_plane_state
bool *per_pixel_alpha, bool *pre_multiplied_alpha,
bool *global_alpha, int *global_alpha_value);
-bool is_video_format(uint32_t format);
+bool amdgpu_dm_plane_is_video_format(uint32_t format);
#endif
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index e13d8bab0b33..4360a696f10a 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -3575,7 +3575,8 @@ static void wait_for_outstanding_hw_updates(struct dc *dc, const struct dc_state
mpcc_inst = hubp->inst;
// MPCC inst is equal to pipe index in practice
for (opp_inst = 0; opp_inst < opp_count; opp_inst++) {
- if (dc->res_pool->opps[opp_inst]->mpcc_disconnect_pending[mpcc_inst]) {
+ if ((dc->res_pool->opps[opp_inst] != NULL) &&
+ (dc->res_pool->opps[opp_inst]->mpcc_disconnect_pending[mpcc_inst])) {
dc->res_pool->mpc->funcs->wait_for_idle(dc->res_pool->mpc, mpcc_inst);
dc->res_pool->opps[opp_inst]->mpcc_disconnect_pending[mpcc_inst] = false;
break;
@@ -4347,7 +4348,6 @@ static bool full_update_required(struct dc *dc,
srf_updates[i].in_transfer_func ||
srf_updates[i].func_shaper ||
srf_updates[i].lut3d_func ||
- srf_updates[i].blend_tf ||
srf_updates[i].surface->force_full_update ||
(srf_updates[i].flip_addr &&
srf_updates[i].flip_addr->address.tmz_surface != srf_updates[i].surface->address.tmz_surface) ||
@@ -4884,6 +4884,9 @@ void dc_allow_idle_optimizations(struct dc *dc, bool allow)
if (dc->debug.disable_idle_power_optimizations)
return;
+ if (dc->caps.ips_support && dc->config.disable_ips)
+ return;
+
if (dc->clk_mgr != NULL && dc->clk_mgr->funcs->is_smu_present)
if (!dc->clk_mgr->funcs->is_smu_present(dc->clk_mgr))
return;
@@ -4895,6 +4898,26 @@ void dc_allow_idle_optimizations(struct dc *dc, bool allow)
dc->idle_optimizations_allowed = allow;
}
+bool dc_dmub_is_ips_idle_state(struct dc *dc)
+{
+ uint32_t idle_state = 0;
+
+ if (dc->debug.disable_idle_power_optimizations)
+ return false;
+
+ if (!dc->caps.ips_support || dc->config.disable_ips)
+ return false;
+
+ if (dc->hwss.get_idle_state)
+ idle_state = dc->hwss.get_idle_state(dc);
+
+ if ((idle_state & DMUB_IPS1_ALLOW_MASK) ||
+ (idle_state & DMUB_IPS2_ALLOW_MASK))
+ return true;
+
+ return false;
+}
+
/* set min and max memory clock to lowest and highest DPM level, respectively */
void dc_unlock_memory_clock_frequency(struct dc *dc)
{
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index 97f402123fbb..1d48278cba96 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -321,10 +321,11 @@ struct resource_pool *dc_create_resource_pool(struct dc *dc,
res_pool->ref_clocks.xtalin_clock_inKhz;
res_pool->ref_clocks.dchub_ref_clock_inKhz =
res_pool->ref_clocks.xtalin_clock_inKhz;
- if (res_pool->hubbub && res_pool->hubbub->funcs->get_dchub_ref_freq)
- res_pool->hubbub->funcs->get_dchub_ref_freq(res_pool->hubbub,
- res_pool->ref_clocks.dccg_ref_clock_inKhz,
- &res_pool->ref_clocks.dchub_ref_clock_inKhz);
+ if (dc->debug.using_dml2)
+ if (res_pool->hubbub && res_pool->hubbub->funcs->get_dchub_ref_freq)
+ res_pool->hubbub->funcs->get_dchub_ref_freq(res_pool->hubbub,
+ res_pool->ref_clocks.dccg_ref_clock_inKhz,
+ &res_pool->ref_clocks.dchub_ref_clock_inKhz);
} else
ASSERT_CRITICAL(false);
}
@@ -4228,7 +4229,7 @@ static void set_avi_info_frame(
switch (stream->content_type) {
case DISPLAY_CONTENT_TYPE_NO_DATA:
hdmi_info.bits.CN0_CN1 = 0;
- hdmi_info.bits.ITC = 0;
+ hdmi_info.bits.ITC = 1;
break;
case DISPLAY_CONTENT_TYPE_GRAPHICS:
hdmi_info.bits.CN0_CN1 = 0;
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
index 6ed40b6c6178..4bdf105d1d71 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -533,7 +533,7 @@ uint32_t dc_stream_get_vblank_counter(const struct dc_stream_state *stream)
for (i = 0; i < MAX_PIPES; i++) {
struct timing_generator *tg = res_ctx->pipe_ctx[i].stream_res.tg;
- if (res_ctx->pipe_ctx[i].stream != stream)
+ if (res_ctx->pipe_ctx[i].stream != stream || !tg)
continue;
return tg->funcs->get_frame_count(tg);
@@ -592,7 +592,7 @@ bool dc_stream_get_scanoutpos(const struct dc_stream_state *stream,
for (i = 0; i < MAX_PIPES; i++) {
struct timing_generator *tg = res_ctx->pipe_ctx[i].stream_res.tg;
- if (res_ctx->pipe_ctx[i].stream != stream)
+ if (res_ctx->pipe_ctx[i].stream != stream || !tg)
continue;
tg->funcs->get_scanoutpos(tg,
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 582d94c759f6..6e54ca055fcb 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -49,7 +49,7 @@ struct aux_payload;
struct set_config_cmd_payload;
struct dmub_notification;
-#define DC_VER "3.2.255"
+#define DC_VER "3.2.256"
#define MAX_SURFACES 3
#define MAX_PLANES 6
@@ -382,6 +382,7 @@ struct dc_cap_funcs {
bool (*get_dcc_compression_cap)(const struct dc *dc,
const struct dc_dcc_surface_param *input,
struct dc_surface_dcc_cap *output);
+ bool (*get_subvp_en)(struct dc *dc, struct dc_state *context);
};
struct link_training_settings;
@@ -2317,6 +2318,7 @@ bool dc_is_plane_eligible_for_idle_optimizations(struct dc *dc, struct dc_plane_
struct dc_cursor_attributes *cursor_attr);
void dc_allow_idle_optimizations(struct dc *dc, bool allow);
+bool dc_dmub_is_ips_idle_state(struct dc *dc);
/* set min and max memory clock to lowest and highest DPM level, respectively */
void dc_unlock_memory_clock_frequency(struct dc *dc);
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
index 4fd3f09432be..ba142bef626b 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -1110,8 +1110,10 @@ void dc_dmub_srv_notify_idle(const struct dc *dc, bool allow_idle)
void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
{
+ const uint32_t max_num_polls = 10000;
uint32_t allow_state = 0;
uint32_t commit_state = 0;
+ uint32_t i;
if (dc->debug.dmcub_emulation)
return;
@@ -1138,22 +1140,36 @@ void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
udelay(dc->debug.ips2_entry_delay_us);
dc->clk_mgr->funcs->exit_low_power_state(dc->clk_mgr);
- do {
+ for (i = 0; i < max_num_polls; ++i) {
commit_state = dc->hwss.get_idle_state(dc);
- } while (commit_state & DMUB_IPS2_COMMIT_MASK);
+ if (!(commit_state & DMUB_IPS2_COMMIT_MASK))
+ break;
+
+ udelay(1);
+ }
+ ASSERT(i < max_num_polls);
if (!dc_dmub_srv_is_hw_pwr_up(dc->ctx->dmub_srv, true))
ASSERT(0);
- return;
+ /* TODO: See if we can return early here - IPS2 should go
+ * back directly to IPS0 and clear the flags, but it will
+ * be safer to directly notify DMCUB of this.
+ */
+ allow_state = dc->hwss.get_idle_state(dc);
}
}
dc_dmub_srv_notify_idle(dc, false);
if (allow_state & DMUB_IPS1_ALLOW_MASK) {
- do {
+ for (i = 0; i < max_num_polls; ++i) {
commit_state = dc->hwss.get_idle_state(dc);
- } while (commit_state & DMUB_IPS1_COMMIT_MASK);
+ if (!(commit_state & DMUB_IPS1_COMMIT_MASK))
+ break;
+
+ udelay(1);
+ }
+ ASSERT(i < max_num_polls);
}
}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
index d1d8e904346e..b94c5c97eee7 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
@@ -554,6 +554,7 @@ static const struct dc_debug_options debug_defaults_drv = {
.max_downscale_src_width = 3840,
.underflow_assert_delay_us = 0xFFFFFFFF,
.enable_legacy_fast_update = true,
+ .using_dml2 = false,
};
static const struct dc_debug_options debug_defaults_diags = {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
index 7eda4bbcd8ac..0a422fbb14bc 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -723,6 +723,7 @@ static const struct dc_debug_options debug_defaults_drv = {
.sanity_checks = false,
.underflow_assert_delay_us = 0xFFFFFFFF,
.enable_legacy_fast_update = true,
+ .using_dml2 = false,
};
void dcn20_dpp_destroy(struct dpp **dpp)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c
index a11b2f6afe4a..bca22d867696 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c
@@ -614,6 +614,7 @@ static const struct dc_debug_options debug_defaults_drv = {
.underflow_assert_delay_us = 0xFFFFFFFF,
.enable_tri_buf = false,
.enable_legacy_fast_update = true,
+ .using_dml2 = false,
};
static void dcn201_dpp_destroy(struct dpp **dpp)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
index 58a0d37e9523..42277b280586 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
@@ -654,6 +654,7 @@ static const struct dc_debug_options debug_defaults_drv = {
.dmub_command_table = true,
.use_max_lb = true,
.enable_legacy_fast_update = true,
+ .using_dml2 = false,
};
static const struct dc_panel_config panel_config_defaults = {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c
index 50dc83404644..11f7746f3a65 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c
@@ -613,16 +613,19 @@ static void dpp3_program_blnd_pwl(
REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].red_reg);
REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, last_base_value_red);
} else {
+ REG_SET(CM_BLNDGAM_LUT_INDEX, 0, CM_BLNDGAM_LUT_INDEX, 0);
REG_UPDATE(CM_BLNDGAM_LUT_CONTROL, CM_BLNDGAM_LUT_WRITE_COLOR_MASK, 4);
for (i = 0 ; i < num; i++)
REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].red_reg);
REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, last_base_value_red);
+ REG_SET(CM_BLNDGAM_LUT_INDEX, 0, CM_BLNDGAM_LUT_INDEX, 0);
REG_UPDATE(CM_BLNDGAM_LUT_CONTROL, CM_BLNDGAM_LUT_WRITE_COLOR_MASK, 2);
for (i = 0 ; i < num; i++)
REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].green_reg);
REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, last_base_value_green);
+ REG_SET(CM_BLNDGAM_LUT_INDEX, 0, CM_BLNDGAM_LUT_INDEX, 0);
REG_UPDATE(CM_BLNDGAM_LUT_CONTROL, CM_BLNDGAM_LUT_WRITE_COLOR_MASK, 1);
for (i = 0 ; i < num; i++)
REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].blue_reg);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c
index 2861d974fcf6..75547ce86c09 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c
@@ -316,7 +316,7 @@ bool hubp3_program_surface_flip_and_addr(
return true;
}
-static void hubp3_program_tiling(
+void hubp3_program_tiling(
struct dcn20_hubp *hubp2,
const union dc_tiling_info *info,
const enum surface_pixel_format pixel_format)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.h
index 8a32772d4e91..b010531a7fe8 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.h
@@ -278,6 +278,11 @@ void hubp3_setup(
struct _vcs_dpi_display_rq_regs_st *rq_regs,
struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest);
+void hubp3_program_tiling(
+ struct dcn20_hubp *hubp2,
+ const union dc_tiling_info *info,
+ const enum surface_pixel_format pixel_format);
+
void hubp3_dcc_control(struct hubp *hubp, bool enable,
enum hubp_ind_block_size blk_size);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
index 473581cff06b..7b259cb5f418 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
@@ -729,6 +729,7 @@ static const struct dc_debug_options debug_defaults_drv = {
.use_max_lb = true,
.exit_idle_opt_for_cursor_updates = true,
.enable_legacy_fast_update = false,
+ .using_dml2 = false,
};
static const struct dc_panel_config panel_config_defaults = {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
index b4b3b52990b9..f3b75f283aa2 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
@@ -701,7 +701,8 @@ static const struct dc_debug_options debug_defaults_drv = {
.dwb_fi_phase = -1, // -1 = disable
.dmub_command_table = true,
.use_max_lb = false,
- .exit_idle_opt_for_cursor_updates = true
+ .exit_idle_opt_for_cursor_updates = true,
+ .using_dml2 = false,
};
static void dcn301_dpp_destroy(struct dpp **dpp)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c
index 06332bd4e625..63ac984a04f7 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c
@@ -99,6 +99,7 @@ static const struct dc_debug_options debug_defaults_drv = {
.use_max_lb = true,
.exit_idle_opt_for_cursor_updates = true,
.enable_legacy_fast_update = false,
+ .using_dml2 = false,
};
static const struct dc_panel_config panel_config_defaults = {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_dccg.h b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_dccg.h
index 294bd757bcb5..2e12fb643005 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_dccg.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_dccg.h
@@ -2,6 +2,24 @@
/*
* Copyright (C) 2021 Advanced Micro Devices, 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, sublicense,
+ * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
* Authors: AMD
*/
diff --git a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_init.c b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_init.c
index 39cf7a50bd26..edb4d68b8187 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_init.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_init.c
@@ -2,6 +2,24 @@
/*
* Copyright (C) 2021 Advanced Micro Devices, 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, sublicense,
+ * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
* Authors: AMD
*/
diff --git a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_init.h b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_init.h
index 66b1e3604f07..4949981126d7 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_init.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_init.h
@@ -2,6 +2,24 @@
/*
* Copyright (C) 2021 Advanced Micro Devices, 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, sublicense,
+ * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
* Authors: AMD
*/
diff --git a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c
index 0d91291a54a9..49cb7fde416a 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c
@@ -2,6 +2,24 @@
/*
* Copyright (C) 2021 Advanced Micro Devices, 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, sublicense,
+ * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
* Authors: AMD
*/
@@ -81,6 +99,7 @@ static const struct dc_debug_options debug_defaults_drv = {
.dmub_command_table = true,
.exit_idle_opt_for_cursor_updates = true,
.disable_idle_power_optimizations = false,
+ .using_dml2 = false,
};
static const struct dc_panel_config panel_config_defaults = {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.h b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.h
index 9c7d79540900..37cf1525820b 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.h
@@ -2,6 +2,24 @@
/*
* Copyright (C) 2021 Advanced Micro Devices, 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, sublicense,
+ * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
* Authors: AMD
*/
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/Makefile b/drivers/gpu/drm/amd/display/dc/dcn31/Makefile
index 996d8c1e9d2a..96e45c9efb46 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/Makefile
@@ -1,5 +1,5 @@
#
-# (c) Copyright 2020 Advanced Micro Devices, Inc. All the rights reserved
+# Copyright 2020 Advanced Micro Devices, Inc. All the rights reserved
#
# All rights reserved. This notice is intended as a precaution against
# inadvertent publication and does not imply publication or any waiver
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c
index f6b59c29cee2..5b5b5e0775fa 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c
@@ -109,6 +109,28 @@ static void dcn31_program_det_size(struct hubbub *hubbub, int hubp_inst, unsigne
+ hubbub2->det3_size + hubbub2->compbuf_size_segments <= hubbub2->crb_size_segs);
}
+static void dcn31_wait_for_det_apply(struct hubbub *hubbub, int hubp_inst)
+{
+ struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
+
+ switch (hubp_inst) {
+ case 0:
+ REG_WAIT(DCHUBBUB_DET0_CTRL, DET0_SIZE_CURRENT, hubbub2->det0_size, 1000, 30);
+ break;
+ case 1:
+ REG_WAIT(DCHUBBUB_DET1_CTRL, DET1_SIZE_CURRENT, hubbub2->det1_size, 1000, 30);
+ break;
+ case 2:
+ REG_WAIT(DCHUBBUB_DET2_CTRL, DET2_SIZE_CURRENT, hubbub2->det2_size, 1000, 30);
+ break;
+ case 3:
+ REG_WAIT(DCHUBBUB_DET3_CTRL, DET3_SIZE_CURRENT, hubbub2->det3_size, 1000, 30);
+ break;
+ default:
+ break;
+ }
+}
+
static void dcn31_program_compbuf_size(struct hubbub *hubbub, unsigned int compbuf_size_kb, bool safe_to_increase)
{
struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
@@ -1041,6 +1063,7 @@ static const struct hubbub_funcs hubbub31_funcs = {
.is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled,
.verify_allow_pstate_change_high = hubbub31_verify_allow_pstate_change_high,
.program_det_size = dcn31_program_det_size,
+ .wait_for_det_apply = dcn31_wait_for_det_apply,
.program_compbuf_size = dcn31_program_compbuf_size,
.init_crb = dcn31_init_crb,
.hubbub_read_state = hubbub2_read_state,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
index cdf005f91869..79416cfb22f0 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
@@ -893,6 +893,7 @@ static const struct dc_debug_options debug_defaults_drv = {
.enable_legacy_fast_update = true,
.enable_z9_disable_interface = true, /* Allow support for the PMFW interface for disable Z9*/
.dml_hostvm_override = DML_HOSTVM_OVERRIDE_FALSE,
+ .using_dml2 = false,
};
static const struct dc_panel_config panel_config_defaults = {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
index 2d7436f2ea82..677361d74a4e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
@@ -916,7 +916,7 @@ static const struct dc_debug_options debug_defaults_drv = {
.hdmistream = true,
.hdmichar = true,
.dpstream = true,
- .symclk32_se = true,
+ .symclk32_se = false,
.symclk32_le = true,
.symclk_fe = true,
.physymclk = true,
@@ -924,7 +924,8 @@ static const struct dc_debug_options debug_defaults_drv = {
}
},
- .seamless_boot_odm_combine = true
+ .seamless_boot_odm_combine = true,
+ .using_dml2 = false,
};
static const struct dc_debug_options debug_defaults_diags = {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c
index c11dbb1f4033..cb8024eee8e4 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c
@@ -889,6 +889,7 @@ static const struct dc_debug_options debug_defaults_drv = {
},
.enable_legacy_fast_update = true,
.psr_power_use_phy_fsm = 0,
+ .using_dml2 = false,
};
static const struct dc_panel_config panel_config_defaults = {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c b/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c
index 4220fe4cae4a..b9753d4606f8 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c
@@ -885,6 +885,7 @@ static const struct dc_debug_options debug_defaults_drv = {
}
},
.enable_legacy_fast_update = true,
+ .using_dml2 = false,
};
static const struct dc_panel_config panel_config_defaults = {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c
index 90f061edb64c..427cfc8c24a4 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c
@@ -60,7 +60,7 @@ static const struct hw_sequencer_funcs dcn32_funcs = {
.pipe_control_lock = dcn20_pipe_control_lock,
.interdependent_update_lock = dcn10_lock_all_pipes,
.cursor_lock = dcn10_cursor_lock,
- .prepare_bandwidth = dcn30_prepare_bandwidth,
+ .prepare_bandwidth = dcn32_prepare_bandwidth,
.optimize_bandwidth = dcn20_optimize_bandwidth,
.update_bandwidth = dcn20_update_bandwidth,
.set_drr = dcn10_set_drr,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c
index 1d052f08aff5..994b21ed272f 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c
@@ -237,16 +237,19 @@ void mpc32_program_post1dlut_pwl(
REG_SET(MPCC_MCM_1DLUT_LUT_DATA[mpcc_id], 0, MPCC_MCM_1DLUT_LUT_DATA, rgb[i].red_reg);
REG_SET(MPCC_MCM_1DLUT_LUT_DATA[mpcc_id], 0, MPCC_MCM_1DLUT_LUT_DATA, last_base_value_red);
} else {
+ REG_SET(MPCC_MCM_1DLUT_LUT_INDEX[mpcc_id], 0, MPCC_MCM_1DLUT_LUT_INDEX, 0);
REG_UPDATE(MPCC_MCM_1DLUT_LUT_CONTROL[mpcc_id], MPCC_MCM_1DLUT_LUT_WRITE_COLOR_MASK, 4);
for (i = 0 ; i < num; i++)
REG_SET(MPCC_MCM_1DLUT_LUT_DATA[mpcc_id], 0, MPCC_MCM_1DLUT_LUT_DATA, rgb[i].red_reg);
REG_SET(MPCC_MCM_1DLUT_LUT_DATA[mpcc_id], 0, MPCC_MCM_1DLUT_LUT_DATA, last_base_value_red);
+ REG_SET(MPCC_MCM_1DLUT_LUT_INDEX[mpcc_id], 0, MPCC_MCM_1DLUT_LUT_INDEX, 0);
REG_UPDATE(MPCC_MCM_1DLUT_LUT_CONTROL[mpcc_id], MPCC_MCM_1DLUT_LUT_WRITE_COLOR_MASK, 2);
for (i = 0 ; i < num; i++)
REG_SET(MPCC_MCM_1DLUT_LUT_DATA[mpcc_id], 0, MPCC_MCM_1DLUT_LUT_DATA, rgb[i].green_reg);
REG_SET(MPCC_MCM_1DLUT_LUT_DATA[mpcc_id], 0, MPCC_MCM_1DLUT_LUT_DATA, last_base_value_green);
+ REG_SET(MPCC_MCM_1DLUT_LUT_INDEX[mpcc_id], 0, MPCC_MCM_1DLUT_LUT_INDEX, 0);
REG_UPDATE(MPCC_MCM_1DLUT_LUT_CONTROL[mpcc_id], MPCC_MCM_1DLUT_LUT_WRITE_COLOR_MASK, 1);
for (i = 0 ; i < num; i++)
REG_SET(MPCC_MCM_1DLUT_LUT_DATA[mpcc_id], 0, MPCC_MCM_1DLUT_LUT_DATA, rgb[i].blue_reg);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
index 81b0588fa80b..89b072447dba 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
@@ -1993,7 +1993,8 @@ int dcn32_populate_dml_pipes_from_context(
}
static struct dc_cap_funcs cap_funcs = {
- .get_dcc_compression_cap = dcn20_get_dcc_compression_cap
+ .get_dcc_compression_cap = dcn20_get_dcc_compression_cap,
+ .get_subvp_en = dcn32_subvp_in_use,
};
void dcn32_calculate_wm_and_dlg(struct dc *dc, struct dc_state *context,
@@ -2445,6 +2446,11 @@ static bool dcn32_resource_construct(
dc->dml2_options.callbacks.build_scaling_params = &resource_build_scaling_params;
dc->dml2_options.callbacks.can_support_mclk_switch_using_fw_based_vblank_stretch = &dcn30_can_support_mclk_switch_using_fw_based_vblank_stretch;
dc->dml2_options.callbacks.acquire_secondary_pipe_for_mpc_odm = &dc_resource_acquire_secondary_pipe_for_mpc_odm_legacy;
+ dc->dml2_options.callbacks.update_pipes_for_stream_with_slice_count = &resource_update_pipes_for_stream_with_slice_count;
+ dc->dml2_options.callbacks.update_pipes_for_plane_with_slice_count = &resource_update_pipes_for_plane_with_slice_count;
+ dc->dml2_options.callbacks.get_mpc_slice_index = &resource_get_mpc_slice_index;
+ dc->dml2_options.callbacks.get_odm_slice_index = &resource_get_odm_slice_index;
+ dc->dml2_options.callbacks.get_opp_head = &resource_get_opp_head;
dc->dml2_options.svp_pstate.callbacks.dc = dc;
dc->dml2_options.svp_pstate.callbacks.add_plane_to_context = &dc_add_plane_to_context;
@@ -2476,6 +2482,7 @@ static bool dcn32_resource_construct(
dc->dml2_options.max_segments_per_hubp = 18;
dc->dml2_options.det_segment_size = DCN3_2_DET_SEG_SIZE;
+ dc->dml2_options.map_dc_pipes_with_callbacks = true;
if (ASICREV_IS_GC_11_0_3(dc->ctx->asic_id.hw_internal_rev) && (dc->config.sdpif_request_limit_words_per_umc == 0))
dc->config.sdpif_request_limit_words_per_umc = 16;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c
index 44caf6711589..f7de3eca1225 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c
@@ -732,6 +732,7 @@ static const struct dc_debug_options debug_defaults_drv = {
.fpo_vactive_max_blank_us = 1000,
.enable_legacy_fast_update = false,
.disable_dc_mode_overwrite = true,
+ .using_dml2 = false,
};
static struct dce_aux *dcn321_aux_engine_create(
@@ -1570,7 +1571,8 @@ static void dcn321_destroy_resource_pool(struct resource_pool **pool)
}
static struct dc_cap_funcs cap_funcs = {
- .get_dcc_compression_cap = dcn20_get_dcc_compression_cap
+ .get_dcc_compression_cap = dcn20_get_dcc_compression_cap,
+ .get_subvp_en = dcn32_subvp_in_use,
};
static void dcn321_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params)
@@ -1998,6 +2000,11 @@ static bool dcn321_resource_construct(
dc->dml2_options.callbacks.build_scaling_params = &resource_build_scaling_params;
dc->dml2_options.callbacks.can_support_mclk_switch_using_fw_based_vblank_stretch = &dcn30_can_support_mclk_switch_using_fw_based_vblank_stretch;
dc->dml2_options.callbacks.acquire_secondary_pipe_for_mpc_odm = &dc_resource_acquire_secondary_pipe_for_mpc_odm_legacy;
+ dc->dml2_options.callbacks.update_pipes_for_stream_with_slice_count = &resource_update_pipes_for_stream_with_slice_count;
+ dc->dml2_options.callbacks.update_pipes_for_plane_with_slice_count = &resource_update_pipes_for_plane_with_slice_count;
+ dc->dml2_options.callbacks.get_mpc_slice_index = &resource_get_mpc_slice_index;
+ dc->dml2_options.callbacks.get_odm_slice_index = &resource_get_odm_slice_index;
+ dc->dml2_options.callbacks.get_opp_head = &resource_get_opp_head;
dc->dml2_options.svp_pstate.callbacks.dc = dc;
dc->dml2_options.svp_pstate.callbacks.add_plane_to_context = &dc_add_plane_to_context;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dpp.c
index 84a9afb7098a..3341ef71009b 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dpp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dpp.c
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#include "core_types.h"
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dpp.h b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dpp.h
index 17f5344994f0..09b84307cd9e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dpp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dpp.h
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#ifndef __DCN35_DPP_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dsc.c b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dsc.c
index d7915c96bcd1..71d2dff9986d 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dsc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dsc.c
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#include "dcn35_dsc.h"
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dsc.h b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dsc.h
index c19c2e022f12..133ad38842cc 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dsc.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dsc.h
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#ifndef __DCN35_DSC_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dwb.h b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dwb.h
index 877f93c8168e..886e727ed080 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dwb.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dwb.h
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#ifndef __DCN35_DWB_H
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubbub.c
index f8e63bd541bc..339bf0c722dd 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubbub.c
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubbub.h b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubbub.h
index d57ed580305e..54cf00ffceb8 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubbub.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubbub.h
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#ifndef __DC_HUBBUB_DCN35_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubp.c
index 2ae7b151b56c..771fcd0d3b99 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubp.c
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#include "dcn35_hubp.h"
@@ -51,11 +53,146 @@ static void hubp35_init(struct hubp *hubp)
/*do nothing for now for dcn3.5 or later*/
}
+
+void hubp35_program_pixel_format(
+ struct hubp *hubp,
+ enum surface_pixel_format format)
+{
+ struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+ uint32_t green_bar = 1;
+ uint32_t red_bar = 3;
+ uint32_t blue_bar = 2;
+
+ /* swap for ABGR format */
+ if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888
+ || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010
+ || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS
+ || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616
+ || format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F) {
+ red_bar = 2;
+ blue_bar = 3;
+ }
+
+ REG_UPDATE_3(HUBPRET_CONTROL,
+ CROSSBAR_SRC_Y_G, green_bar,
+ CROSSBAR_SRC_CB_B, blue_bar,
+ CROSSBAR_SRC_CR_R, red_bar);
+
+ /* Mapping is same as ipp programming (cnvc) */
+
+ switch (format) {
+ case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
+ REG_UPDATE(DCSURF_SURFACE_CONFIG,
+ SURFACE_PIXEL_FORMAT, 1);
+ break;
+ case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
+ REG_UPDATE(DCSURF_SURFACE_CONFIG,
+ SURFACE_PIXEL_FORMAT, 3);
+ break;
+ case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
+ case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
+ REG_UPDATE(DCSURF_SURFACE_CONFIG,
+ SURFACE_PIXEL_FORMAT, 8);
+ break;
+ case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
+ case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
+ case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
+ REG_UPDATE(DCSURF_SURFACE_CONFIG,
+ SURFACE_PIXEL_FORMAT, 10);
+ break;
+ case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
+ case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616: /* we use crossbar already */
+ REG_UPDATE(DCSURF_SURFACE_CONFIG,
+ SURFACE_PIXEL_FORMAT, 26); /* ARGB16161616_UNORM */
+ break;
+ case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
+ case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:/*we use crossbar already*/
+ REG_UPDATE(DCSURF_SURFACE_CONFIG,
+ SURFACE_PIXEL_FORMAT, 24);
+ break;
+
+ case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
+ REG_UPDATE(DCSURF_SURFACE_CONFIG,
+ SURFACE_PIXEL_FORMAT, 65);
+ break;
+ case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
+ REG_UPDATE(DCSURF_SURFACE_CONFIG,
+ SURFACE_PIXEL_FORMAT, 64);
+ break;
+ case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
+ REG_UPDATE(DCSURF_SURFACE_CONFIG,
+ SURFACE_PIXEL_FORMAT, 67);
+ break;
+ case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
+ REG_UPDATE(DCSURF_SURFACE_CONFIG,
+ SURFACE_PIXEL_FORMAT, 66);
+ break;
+ case SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
+ REG_UPDATE(DCSURF_SURFACE_CONFIG,
+ SURFACE_PIXEL_FORMAT, 12);
+ break;
+ case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FIX:
+ REG_UPDATE(DCSURF_SURFACE_CONFIG,
+ SURFACE_PIXEL_FORMAT, 112);
+ break;
+ case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX:
+ REG_UPDATE(DCSURF_SURFACE_CONFIG,
+ SURFACE_PIXEL_FORMAT, 113);
+ break;
+ case SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
+ REG_UPDATE(DCSURF_SURFACE_CONFIG,
+ SURFACE_PIXEL_FORMAT, 114);
+ break;
+ case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT:
+ REG_UPDATE(DCSURF_SURFACE_CONFIG,
+ SURFACE_PIXEL_FORMAT, 118);
+ break;
+ case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT:
+ REG_UPDATE(DCSURF_SURFACE_CONFIG,
+ SURFACE_PIXEL_FORMAT, 119);
+ break;
+ case SURFACE_PIXEL_FORMAT_GRPH_RGBE:
+ REG_UPDATE_2(DCSURF_SURFACE_CONFIG,
+ SURFACE_PIXEL_FORMAT, 116,
+ ALPHA_PLANE_EN, 0);
+ break;
+ case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA:
+ REG_UPDATE_2(DCSURF_SURFACE_CONFIG,
+ SURFACE_PIXEL_FORMAT, 116,
+ ALPHA_PLANE_EN, 1);
+ break;
+ default:
+ BREAK_TO_DEBUGGER();
+ break;
+ }
+
+ /* don't see the need of program the xbar in DCN 1.0 */
+}
+
+void hubp35_program_surface_config(
+ struct hubp *hubp,
+ enum surface_pixel_format format,
+ union dc_tiling_info *tiling_info,
+ struct plane_size *plane_size,
+ enum dc_rotation_angle rotation,
+ struct dc_plane_dcc_param *dcc,
+ bool horizontal_mirror,
+ unsigned int compat_level)
+{
+ struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
+
+ hubp3_dcc_control_sienna_cichlid(hubp, dcc);
+ hubp3_program_tiling(hubp2, tiling_info, format);
+ hubp2_program_size(hubp, format, plane_size, dcc);
+ hubp2_program_rotation(hubp, rotation, horizontal_mirror);
+ hubp35_program_pixel_format(hubp, format);
+}
+
struct hubp_funcs dcn35_hubp_funcs = {
.hubp_enable_tripleBuffer = hubp2_enable_triplebuffer,
.hubp_is_triplebuffer_enabled = hubp2_is_triplebuffer_enabled,
.hubp_program_surface_flip_and_addr = hubp3_program_surface_flip_and_addr,
- .hubp_program_surface_config = hubp3_program_surface_config,
+ .hubp_program_surface_config = hubp35_program_surface_config,
.hubp_is_flip_pending = hubp2_is_flip_pending,
.hubp_setup = hubp3_setup,
.hubp_setup_interdependent = hubp2_setup_interdependent,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubp.h
index a8879c3db447..586b43aa5834 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubp.h
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#ifndef __DC_HUBP_DCN35_H__
@@ -56,4 +58,18 @@ bool hubp35_construct(
void hubp35_set_fgcg(struct hubp *hubp, bool enable);
+void hubp35_program_pixel_format(
+ struct hubp *hubp,
+ enum surface_pixel_format format);
+
+void hubp35_program_surface_config(
+ struct hubp *hubp,
+ enum surface_pixel_format format,
+ union dc_tiling_info *tiling_info,
+ struct plane_size *plane_size,
+ enum dc_rotation_angle rotation,
+ struct dc_plane_dcc_param *dcc,
+ bool horizontal_mirror,
+ unsigned int compat_level);
+
#endif /* __DC_HUBP_DCN35_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_init.c b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_init.c
index 534223dbe595..296bf3a38cb9 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_init.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_init.c
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#include "dce110/dce110_hwseq.h"
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_init.h b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_init.h
index ccfc28225cff..b67015032c35 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_init.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_init.h
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#ifndef __DC_DCN35_INIT_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_mmhubbub.c b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_mmhubbub.c
index ea1042cdc88d..4317100564a4 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_mmhubbub.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_mmhubbub.c
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#include "dcn35_mmhubbub.h"
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_mmhubbub.h b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_mmhubbub.h
index e7b5b6703e73..098e13e07272 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_mmhubbub.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_mmhubbub.h
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#ifndef __DCN35_MMHUBBUB_H
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_opp.c b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_opp.c
index d79e8c6365c1..3542b51c9aac 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_opp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_opp.c
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#include "dcn35_opp.h"
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_opp.h b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_opp.h
index 9dd21b104287..a9a413527801 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_opp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_opp.h
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#ifndef __DCN35_OPP_H
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c
index b0c068240a94..a4a39f1638cf 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#include "dcn35_optc.h"
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.h b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.h
index 7e7a5f4b85b0..1f422e4c468f 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.h
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#ifndef __DC_OPTC_DCN35_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_pg_cntl.c b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_pg_cntl.c
index e62a192c595e..0f60c40e1fc5 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_pg_cntl.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_pg_cntl.c
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#include "reg_helper.h"
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_pg_cntl.h b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_pg_cntl.h
index d073ce5cc6f3..3de240884d22 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_pg_cntl.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_pg_cntl.h
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#ifndef _DCN35_PG_CNTL_H_
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.c b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.c
index 99d55b958977..3c7c810bab1f 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.c
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#include "dm_services.h"
@@ -2084,6 +2086,11 @@ static bool dcn35_resource_construct(
dc->dml2_options.callbacks.build_scaling_params = &resource_build_scaling_params;
dc->dml2_options.callbacks.can_support_mclk_switch_using_fw_based_vblank_stretch = &dcn30_can_support_mclk_switch_using_fw_based_vblank_stretch;
dc->dml2_options.callbacks.acquire_secondary_pipe_for_mpc_odm = &dc_resource_acquire_secondary_pipe_for_mpc_odm_legacy;
+ dc->dml2_options.callbacks.update_pipes_for_stream_with_slice_count = &resource_update_pipes_for_stream_with_slice_count;
+ dc->dml2_options.callbacks.update_pipes_for_plane_with_slice_count = &resource_update_pipes_for_plane_with_slice_count;
+ dc->dml2_options.callbacks.get_mpc_slice_index = &resource_get_mpc_slice_index;
+ dc->dml2_options.callbacks.get_odm_slice_index = &resource_get_odm_slice_index;
+ dc->dml2_options.callbacks.get_opp_head = &resource_get_opp_head;
dc->dml2_options.max_segments_per_hubp = 24;
dc->dml2_options.det_segment_size = DCN3_2_DET_SEG_SIZE;/*todo*/
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.h b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.h
index 5ec70d46a38f..99aea102e3f7 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.h
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#ifndef _DCN35_RESOURCE_H_
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/Makefile b/drivers/gpu/drm/amd/display/dc/dml2/Makefile
index 66431525f2a0..acff3449b8d7 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dml2/Makefile
@@ -20,7 +20,9 @@
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
-# makefile for dml2
+# Authors: AMD
+#
+# Makefile for dml2.
ifdef CONFIG_X86
dml2_ccflags-$(CONFIG_CC_IS_GCC) := -mhard-float
@@ -58,8 +60,12 @@ endif
endif
ifneq ($(CONFIG_FRAME_WARN),0)
+ifeq ($(filter y,$(CONFIG_KASAN)$(CONFIG_KCSAN)),y)
+frame_warn_flag := -Wframe-larger-than=3072
+else
frame_warn_flag := -Wframe-larger-than=2048
endif
+endif
CFLAGS_$(AMDDALPATH)/dc/dml2/display_mode_core.o := $(dml2_ccflags) $(frame_warn_flag)
CFLAGS_$(AMDDALPATH)/dc/dml2/display_mode_util.o := $(dml2_ccflags)
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/cmntypes.h b/drivers/gpu/drm/amd/display/dc/dml2/cmntypes.h
index 5450aa5295f7..e450445bc05d 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/cmntypes.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/cmntypes.h
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#ifndef __CMNTYPES_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c b/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c
index 5f54251a559c..510be909cd75 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#include "display_mode_core.h"
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core_structs.h b/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core_structs.h
index c2fa28ff57ab..b274bfb4225f 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core_structs.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core_structs.h
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#ifndef __DISPLAY_MODE_CORE_STRUCT_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/display_mode_lib_defines.h b/drivers/gpu/drm/amd/display/dc/dml2/display_mode_lib_defines.h
index 99bdb2ddd8ab..de63364be01d 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/display_mode_lib_defines.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/display_mode_lib_defines.h
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#ifndef __DISPLAY_MODE_LIB_DEFINES_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/display_mode_util.c b/drivers/gpu/drm/amd/display/dc/dml2/display_mode_util.c
index 7dd1f8a12582..c247aee89caf 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/display_mode_util.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/display_mode_util.c
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#include "display_mode_util.h"
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/display_mode_util.h b/drivers/gpu/drm/amd/display/dc/dml2/display_mode_util.h
index fb74385e1060..113b0265e1d1 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/display_mode_util.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/display_mode_util.h
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#ifndef __DISPLAY_MODE_UTIL_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c
index f45fbe820445..d2046e770c50 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#include "dml2_mall_phantom.h"
@@ -756,6 +758,148 @@ static void map_pipes_for_plane(struct dml2_context *ctx, struct dc_state *state
free_unused_pipes_for_plane(ctx, state, plane, &scratch->pipe_pool, stream->stream_id);
}
+static unsigned int get_mpc_factor(struct dml2_context *ctx,
+ const struct dc_state *state,
+ const struct dml_display_cfg_st *disp_cfg,
+ struct dml2_dml_to_dc_pipe_mapping *mapping,
+ const struct dc_stream_status *status, unsigned int stream_id,
+ int plane_idx)
+{
+ unsigned int plane_id;
+ unsigned int cfg_idx;
+
+ get_plane_id(state, status->plane_states[plane_idx], stream_id, &plane_id);
+ cfg_idx = find_disp_cfg_idx_by_plane_id(mapping, plane_id);
+ if (ctx->architecture == dml2_architecture_20)
+ return (unsigned int)disp_cfg->hw.DPPPerSurface[cfg_idx];
+ ASSERT(false);
+ return 1;
+}
+
+static unsigned int get_odm_factor(
+ const struct dml2_context *ctx,
+ const struct dml_display_cfg_st *disp_cfg,
+ struct dml2_dml_to_dc_pipe_mapping *mapping,
+ const struct dc_stream_state *stream)
+{
+ unsigned int cfg_idx = find_disp_cfg_idx_by_stream_id(
+ mapping, stream->stream_id);
+
+ if (ctx->architecture == dml2_architecture_20)
+ switch (disp_cfg->hw.ODMMode[cfg_idx]) {
+ case dml_odm_mode_bypass:
+ return 1;
+ case dml_odm_mode_combine_2to1:
+ return 2;
+ case dml_odm_mode_combine_4to1:
+ return 4;
+ default:
+ break;
+ }
+ ASSERT(false);
+ return 1;
+}
+
+static void populate_mpc_factors_for_stream(
+ struct dml2_context *ctx,
+ const struct dml_display_cfg_st *disp_cfg,
+ struct dml2_dml_to_dc_pipe_mapping *mapping,
+ const struct dc_state *state,
+ unsigned int stream_idx,
+ unsigned int odm_factor,
+ unsigned int mpc_factors[MAX_PIPES])
+{
+ const struct dc_stream_status *status = &state->stream_status[stream_idx];
+ unsigned int stream_id = state->streams[stream_idx]->stream_id;
+ int i;
+
+ for (i = 0; i < status->plane_count; i++)
+ if (odm_factor == 1)
+ mpc_factors[i] = get_mpc_factor(
+ ctx, state, disp_cfg, mapping, status,
+ stream_id, i);
+ else
+ mpc_factors[i] = 1;
+}
+
+static void populate_odm_factors(const struct dml2_context *ctx,
+ const struct dml_display_cfg_st *disp_cfg,
+ struct dml2_dml_to_dc_pipe_mapping *mapping,
+ const struct dc_state *state,
+ unsigned int odm_factors[MAX_PIPES])
+{
+ int i;
+
+ for (i = 0; i < state->stream_count; i++)
+ odm_factors[i] = get_odm_factor(
+ ctx, disp_cfg, mapping, state->streams[i]);
+}
+
+static bool map_dc_pipes_for_stream(struct dml2_context *ctx,
+ struct dc_state *state,
+ const struct dc_state *existing_state,
+ const struct dc_stream_state *stream,
+ const struct dc_stream_status *status,
+ unsigned int odm_factor,
+ unsigned int mpc_factors[MAX_PIPES])
+{
+ int plane_idx;
+ bool result = true;
+
+ if (odm_factor == 1)
+ /*
+ * ODM and MPC combines are by DML design mutually exclusive.
+ * ODM factor of 1 means MPC factors may be greater than 1.
+ * In this case, we want to set ODM factor to 1 first to free up
+ * pipe resources from previous ODM configuration before setting
+ * up MPC combine to acquire more pipe resources.
+ */
+ result &= ctx->config.callbacks.update_pipes_for_stream_with_slice_count(
+ state,
+ existing_state,
+ ctx->config.callbacks.dc->res_pool,
+ stream,
+ odm_factor);
+ for (plane_idx = 0; plane_idx < status->plane_count; plane_idx++)
+ result &= ctx->config.callbacks.update_pipes_for_plane_with_slice_count(
+ state,
+ existing_state,
+ ctx->config.callbacks.dc->res_pool,
+ status->plane_states[plane_idx],
+ mpc_factors[plane_idx]);
+ if (odm_factor > 1)
+ result &= ctx->config.callbacks.update_pipes_for_stream_with_slice_count(
+ state,
+ existing_state,
+ ctx->config.callbacks.dc->res_pool,
+ stream,
+ odm_factor);
+ return result;
+}
+
+static bool map_dc_pipes_with_callbacks(struct dml2_context *ctx,
+ struct dc_state *state,
+ const struct dml_display_cfg_st *disp_cfg,
+ struct dml2_dml_to_dc_pipe_mapping *mapping,
+ const struct dc_state *existing_state)
+{
+ unsigned int odm_factors[MAX_PIPES];
+ unsigned int mpc_factors_for_stream[MAX_PIPES];
+ int i;
+ bool result = true;
+
+ populate_odm_factors(ctx, disp_cfg, mapping, state, odm_factors);
+ for (i = 0; i < state->stream_count; i++) {
+ populate_mpc_factors_for_stream(ctx, disp_cfg, mapping, state,
+ i, odm_factors[i], mpc_factors_for_stream);
+ result &= map_dc_pipes_for_stream(ctx, state, existing_state,
+ state->streams[i],
+ &state->stream_status[i],
+ odm_factors[i], mpc_factors_for_stream);
+ }
+ return result;
+}
+
bool dml2_map_dc_pipes(struct dml2_context *ctx, struct dc_state *state, const struct dml_display_cfg_st *disp_cfg, struct dml2_dml_to_dc_pipe_mapping *mapping, const struct dc_state *existing_state)
{
int stream_index, plane_index, i;
@@ -770,6 +914,10 @@ bool dml2_map_dc_pipes(struct dml2_context *ctx, struct dc_state *state, const s
unsigned int odm_mode_array[__DML2_WRAPPER_MAX_STREAMS_PLANES__] = {0}, dpp_per_surface_array[__DML2_WRAPPER_MAX_STREAMS_PLANES__] = {0};
struct dc_pipe_mapping_scratch scratch;
+ if (ctx->config.map_dc_pipes_with_callbacks)
+ return map_dc_pipes_with_callbacks(
+ ctx, state, disp_cfg, mapping, existing_state);
+
if (ctx->architecture == dml2_architecture_21) {
/*
* Extract ODM and DPP outputs from DML2.1 and map them in an array as required for pipe mapping in dml2_map_dc_pipes.
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.h b/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.h
index a78de194793d..2f91244a7b01 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.h
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#ifndef __DML2_DC_RESOURCE_MGMT_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_types.h b/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_types.h
index 191b2e63ce6e..e85866db80ff 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_types.h
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_internal_types.h b/drivers/gpu/drm/amd/display/dc/dml2/dml2_internal_types.h
index bcb59bcd9179..ed5b767d46e0 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_internal_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_internal_types.h
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#ifndef __DML2_INTERNAL_TYPES_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.c
index 02797cb2667e..32f8a43af3d6 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.c
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#include "dml2_dc_types.h"
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.h b/drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.h
index c14b4de29d73..9d64851f54e7 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.h
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#ifndef __DML2_MALL_PHANTOM_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_policy.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_policy.c
index f8e9aa32ceab..c4c52173ef22 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_policy.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_policy.c
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#include "dml2_policy.h"
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c
index e5ccd2887c94..89836f175a13 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#include "display_mode_core.h"
@@ -569,6 +571,8 @@ static void populate_dml_timing_cfg_from_stream_state(struct dml_timing_cfg_st *
out->RefreshRate[location] = ((in->timing.pix_clk_100hz * 100) / in->timing.h_total) / in->timing.v_total;
out->VFrontPorch[location] = in->timing.v_front_porch;
out->PixelClock[location] = in->timing.pix_clk_100hz / 10000.00;
+ if (in->timing.timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING)
+ out->PixelClock[location] *= 2;
out->HTotal[location] = in->timing.h_total;
out->VTotal[location] = in->timing.v_total;
out->Interlace[location] = in->timing.flags.INTERLACE;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.h b/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.h
index 1bcfca51e665..dac6d27b14cd 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.h
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#ifndef __DML2_TRANSLATION_HELPER_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c
index ac6bf776bad0..69fd96f4f3b0 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
//#include "dml2_utils.h"
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c
index 9a5e145168bc..0a06bf3b135a 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#include "display_mode_core.h"
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h
index f3b85b0891d3..317f90776d97 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#ifndef _DML2_WRAPPER_H_
@@ -71,6 +73,21 @@ struct dml2_dc_callbacks {
bool (*build_scaling_params)(struct pipe_ctx *pipe_ctx);
bool (*can_support_mclk_switch_using_fw_based_vblank_stretch)(struct dc *dc, struct dc_state *context);
bool (*acquire_secondary_pipe_for_mpc_odm)(const struct dc *dc, struct dc_state *state, struct pipe_ctx *pri_pipe, struct pipe_ctx *sec_pipe, bool odm);
+ bool (*update_pipes_for_stream_with_slice_count)(
+ struct dc_state *new_ctx,
+ const struct dc_state *cur_ctx,
+ const struct resource_pool *pool,
+ const struct dc_stream_state *stream,
+ int new_slice_count);
+ bool (*update_pipes_for_plane_with_slice_count)(
+ struct dc_state *new_ctx,
+ const struct dc_state *cur_ctx,
+ const struct resource_pool *pool,
+ const struct dc_plane_state *plane,
+ int slice_count);
+ int (*get_odm_slice_index)(const struct pipe_ctx *opp_head);
+ int (*get_mpc_slice_index)(const struct pipe_ctx *dpp_pipe);
+ struct pipe_ctx *(*get_opp_head)(const struct pipe_ctx *pipe_ctx);
};
struct dml2_dc_svp_callbacks {
@@ -152,6 +169,7 @@ struct dml2_configuration_options {
struct dml2_soc_bbox_overrides bbox_overrides;
unsigned int max_segments_per_hubp;
unsigned int det_segment_size;
+ bool map_dc_pipes_with_callbacks;
};
/*
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml_assert.h b/drivers/gpu/drm/amd/display/dc/dml2/dml_assert.h
index b5e463aa61af..17f0972b1af7 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml_assert.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml_assert.h
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#ifndef __DML_ASSERT_H__
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml_depedencies.h b/drivers/gpu/drm/amd/display/dc/dml2/dml_depedencies.h
index d8c7f7497e9c..f7d30b47beff 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml_depedencies.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml_depedencies.h
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
/* This header intentinally does not include an #ifdef guard as it only contains includes for other headers*/
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml_logging.h b/drivers/gpu/drm/amd/display/dc/dml2/dml_logging.h
index 890c0a072012..2a2f84e07ca8 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml_logging.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml_logging.h
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#ifndef __DML_LOGGING_H__
#define __DML_LOGGING_H__
diff --git a/drivers/gpu/drm/amd/display/dc/hdcp/Makefile b/drivers/gpu/drm/amd/display/dc/hdcp/Makefile
index 4170b6eb9ec0..c1c47a6cefe1 100644
--- a/drivers/gpu/drm/amd/display/dc/hdcp/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/hdcp/Makefile
@@ -1,4 +1,4 @@
-# Copyright 2019 Advanced Micro Devices, Inc.
+# Copyright 2022 Advanced Micro Devices, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
index 4d6493e0ccfc..608221b0dd5d 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
@@ -2746,6 +2746,8 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
struct dce_hwseq *hws = dc->hwseq;
unsigned int k1_div = PIXEL_RATE_DIV_NA;
unsigned int k2_div = PIXEL_RATE_DIV_NA;
+ struct link_encoder *link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link);
+ struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc;
if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
if (dc->hwseq->funcs.setup_hpo_hw_control)
@@ -2765,6 +2767,10 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
dto_params.timing = &pipe_ctx->stream->timing;
dto_params.ref_dtbclk_khz = dc->clk_mgr->funcs->get_dtb_ref_clk_frequency(dc->clk_mgr);
dccg->funcs->set_dtbclk_dto(dccg, &dto_params);
+ } else {
+ if (dccg->funcs->enable_symclk_se)
+ dccg->funcs->enable_symclk_se(dccg, stream_enc->stream_enc_inst,
+ link_enc->transmitter - TRANSMITTER_UNIPHY_A);
}
if (hws->funcs.calculate_dccg_k1_k2_values && dc->res_pool->dccg->funcs->set_pixel_rate_div) {
hws->funcs.calculate_dccg_k1_k2_values(pipe_ctx, &k1_div, &k2_div);
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
index 1c839e52bae5..d71faf2ecd41 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
@@ -993,11 +993,7 @@ void dcn30_set_disp_pattern_generator(const struct dc *dc,
void dcn30_prepare_bandwidth(struct dc *dc,
struct dc_state *context)
{
- bool p_state_change_support = context->bw_ctx.bw.dcn.clk.p_state_change_support;
- /* Any transition into an FPO config should disable MCLK switching first to avoid
- * driver and FW P-State synchronization issues.
- */
- if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || dc->clk_mgr->clks.fw_based_mclk_switching) {
+ if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching && !dc->clk_mgr->clks.fw_based_mclk_switching) {
dc->optimized_required = true;
context->bw_ctx.bw.dcn.clk.p_state_change_support = false;
}
@@ -1008,20 +1004,9 @@ void dcn30_prepare_bandwidth(struct dc *dc,
dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz);
dcn20_prepare_bandwidth(dc, context);
- /*
- * enabled -> enabled: do not disable
- * enabled -> disabled: disable
- * disabled -> enabled: don't care
- * disabled -> disabled: don't care
- */
- if (!context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching)
- dc_dmub_srv_p_state_delegate(dc, false, context);
- if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || dc->clk_mgr->clks.fw_based_mclk_switching) {
- /* After disabling P-State, restore the original value to ensure we get the correct P-State
- * on the next optimize. */
- context->bw_ctx.bw.dcn.clk.p_state_change_support = p_state_change_support;
- }
+ if (!dc->clk_mgr->clks.fw_based_mclk_switching)
+ dc_dmub_srv_p_state_delegate(dc, false, context);
}
void dcn30_set_static_screen_control(struct pipe_ctx **pipe_ctx,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn303/dcn303_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn303/dcn303_hwseq.c
index b48b732aa647..3bc56ac346f3 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn303/dcn303_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn303/dcn303_hwseq.c
@@ -2,7 +2,26 @@
/*
* Copyright (C) 2021 Advanced Micro Devices, 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, sublicense,
+ * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
* Authors: AMD
+ *
*/
#include "dcn303_hwseq.h"
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn303/dcn303_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn303/dcn303_hwseq.h
index 8b69a3b76c11..7fdfc4175f80 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn303/dcn303_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn303/dcn303_hwseq.h
@@ -2,7 +2,26 @@
/*
* Copyright (C) 2021 Advanced Micro Devices, 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, sublicense,
+ * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
* Authors: AMD
+ *
*/
#ifndef __DC_HWSS_DCN303_H__
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
index f369f7af6b3a..97798cee876e 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
@@ -584,6 +584,17 @@ void dcn31_reset_hw_ctx_wrap(
pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {
struct clock_source *old_clk = pipe_ctx_old->clock_source;
+ /* Reset pipe which is seamless boot stream. */
+ if (!pipe_ctx_old->plane_state &&
+ dc->res_pool->hubbub->funcs->program_det_size &&
+ dc->res_pool->hubbub->funcs->wait_for_det_apply) {
+ dc->res_pool->hubbub->funcs->program_det_size(
+ dc->res_pool->hubbub, pipe_ctx_old->plane_res.hubp->inst, 0);
+ /* Wait det size changed. */
+ dc->res_pool->hubbub->funcs->wait_for_det_apply(
+ dc->res_pool->hubbub, pipe_ctx_old->plane_res.hubp->inst);
+ }
+
dcn31_reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_state);
if (hws->funcs.enable_stream_gating)
hws->funcs.enable_stream_gating(dc, pipe_ctx_old);
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
index 68dc99034eba..1b9f21fd4f17 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
@@ -50,6 +50,7 @@
#include "dce/dmub_hw_lock_mgr.h"
#include "dcn32/dcn32_resource.h"
#include "link.h"
+#include "../dcn20/dcn20_hwseq.h"
#define DC_LOGGER_INIT(logger)
@@ -217,7 +218,7 @@ static bool dcn32_check_no_memory_request_for_cab(struct dc *dc)
static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *ctx)
{
int i;
- uint8_t num_ways = 0;
+ uint32_t num_ways = 0;
uint32_t mall_ss_size_bytes = 0;
mall_ss_size_bytes = ctx->bw_ctx.bw.dcn.mall_ss_size_bytes;
@@ -247,7 +248,8 @@ static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *c
bool dcn32_apply_idle_power_optimizations(struct dc *dc, bool enable)
{
union dmub_rb_cmd cmd;
- uint8_t ways, i;
+ uint8_t i;
+ uint32_t ways;
int j;
bool mall_ss_unsupported = false;
struct dc_plane_state *plane = NULL;
@@ -307,7 +309,7 @@ bool dcn32_apply_idle_power_optimizations(struct dc *dc, bool enable)
cmd.cab.header.type = DMUB_CMD__CAB_FOR_SS;
cmd.cab.header.sub_type = DMUB_CMD__CAB_DCN_SS_FIT_IN_CAB;
cmd.cab.header.payload_bytes = sizeof(cmd.cab) - sizeof(cmd.cab.header);
- cmd.cab.cab_alloc_ways = ways;
+ cmd.cab.cab_alloc_ways = (uint8_t)ways;
dm_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT);
@@ -492,6 +494,7 @@ bool dcn32_set_mcm_luts(
}
}
result = mpc->funcs->program_1dlut(mpc, lut_params, mpcc_id);
+ lut_params = NULL;
// Shaper
if (plane_state->in_shaper_func) {
@@ -1676,3 +1679,33 @@ bool dcn32_is_pipe_topology_transition_seamless(struct dc *dc,
return is_seamless;
}
+
+void dcn32_prepare_bandwidth(struct dc *dc,
+ struct dc_state *context)
+{
+ bool p_state_change_support = context->bw_ctx.bw.dcn.clk.p_state_change_support;
+ /* Any transition into an FPO config should disable MCLK switching first to avoid
+ * driver and FW P-State synchronization issues.
+ */
+ if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || dc->clk_mgr->clks.fw_based_mclk_switching) {
+ dc->optimized_required = true;
+ context->bw_ctx.bw.dcn.clk.p_state_change_support = false;
+ }
+
+ if (dc->clk_mgr->dc_mode_softmax_enabled)
+ if (dc->clk_mgr->clks.dramclk_khz <= dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000 &&
+ context->bw_ctx.bw.dcn.clk.dramclk_khz > dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000)
+ dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz);
+
+ dcn20_prepare_bandwidth(dc, context);
+
+ if (!context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching)
+ dc_dmub_srv_p_state_delegate(dc, false, context);
+
+ if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || dc->clk_mgr->clks.fw_based_mclk_switching) {
+ /* After disabling P-State, restore the original value to ensure we get the correct P-State
+ * on the next optimize.
+ */
+ context->bw_ctx.bw.dcn.clk.p_state_change_support = p_state_change_support;
+ }
+}
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.h
index 9992e40acd21..cecf7f0f5671 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.h
@@ -124,4 +124,7 @@ bool dcn32_is_pipe_topology_transition_seamless(struct dc *dc,
const struct dc_state *cur_ctx,
const struct dc_state *new_ctx);
+void dcn32_prepare_bandwidth(struct dc *dc,
+ struct dc_state *context);
+
#endif /* __DC_HWSS_DCN32_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
index 0e218f9e2a86..34737d60b965 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#include "dm_services.h"
@@ -627,12 +629,8 @@ void dcn35_power_down_on_boot(struct dc *dc)
if (dc->clk_mgr->funcs->set_low_power_state)
dc->clk_mgr->funcs->set_low_power_state(dc->clk_mgr);
- if (dc->clk_mgr->clks.pwr_state == DCN_PWR_STATE_LOW_POWER) {
- if (!dc->idle_optimizations_allowed) {
- dc_dmub_srv_notify_idle(dc, true);
- dc->idle_optimizations_allowed = true;
- }
- }
+ if (dc->clk_mgr->clks.pwr_state == DCN_PWR_STATE_LOW_POWER)
+ dc_allow_idle_optimizations(dc, true);
}
bool dcn35_apply_idle_power_optimizations(struct dc *dc, bool enable)
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h
index 14bbdb0fa634..0dff10d179b8 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h
@@ -20,6 +20,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
+ * Authors: AMD
+ *
*/
#ifndef __DC_HWSS_DCN35_H__
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
index cea05843990c..901891316dfb 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
@@ -188,6 +188,7 @@ struct hubbub_funcs {
* compressed or detiled buffers.
*/
void (*program_det_size)(struct hubbub *hubbub, int hubp_inst, unsigned det_buffer_size_in_kbyte);
+ void (*wait_for_det_apply)(struct hubbub *hubbub, int hubp_inst);
void (*program_compbuf_size)(struct hubbub *hubbub, unsigned compbuf_size_kb, bool safe_to_increase);
void (*init_crb)(struct hubbub *hubbub);
void (*force_usr_retraining_allow)(struct hubbub *hubbub, bool allow);
diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn201/irq_service_dcn201.c b/drivers/gpu/drm/amd/display/dc/irq/dcn201/irq_service_dcn201.c
index 5171d04519ee..4fb9cd6708d5 100644
--- a/drivers/gpu/drm/amd/display/dc/irq/dcn201/irq_service_dcn201.c
+++ b/drivers/gpu/drm/amd/display/dc/irq/dcn201/irq_service_dcn201.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 Advanced Micro Devices, Inc.
+ * Copyright 2022 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn303/irq_service_dcn303.c b/drivers/gpu/drm/amd/display/dc/irq/dcn303/irq_service_dcn303.c
index e09ca4594ec3..262bb8b74b15 100644
--- a/drivers/gpu/drm/amd/display/dc/irq/dcn303/irq_service_dcn303.c
+++ b/drivers/gpu/drm/amd/display/dc/irq/dcn303/irq_service_dcn303.c
@@ -2,7 +2,26 @@
/*
* Copyright (C) 2021 Advanced Micro Devices, 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, sublicense,
+ * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
* Authors: AMD
+ *
*/
#include "dm_services.h"
diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn303/irq_service_dcn303.h b/drivers/gpu/drm/amd/display/dc/irq/dcn303/irq_service_dcn303.h
index fd64e3848ff3..be8fe836b3f1 100644
--- a/drivers/gpu/drm/amd/display/dc/irq/dcn303/irq_service_dcn303.h
+++ b/drivers/gpu/drm/amd/display/dc/irq/dcn303/irq_service_dcn303.h
@@ -2,7 +2,26 @@
/*
* Copyright (C) 2021 Advanced Micro Devices, 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, sublicense,
+ * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
* Authors: AMD
+ *
*/
#ifndef __DAL_IRQ_SERVICE_DCN303_H__
diff --git a/drivers/gpu/drm/amd/display/dc/irq_types.h b/drivers/gpu/drm/amd/display/dc/irq_types.h
index 530c2578db40..93354bff456a 100644
--- a/drivers/gpu/drm/amd/display/dc/irq_types.h
+++ b/drivers/gpu/drm/amd/display/dc/irq_types.h
@@ -178,7 +178,7 @@ enum dc_interrupt_context {
INTERRUPT_CONTEXT_NUMBER
};
-enum dc_interrupt_porlarity {
+enum dc_interrupt_polarity {
INTERRUPT_POLARITY_DEFAULT = 0,
INTERRUPT_POLARITY_LOW = INTERRUPT_POLARITY_DEFAULT,
INTERRUPT_POLARITY_HIGH,
@@ -199,12 +199,12 @@ struct dc_interrupt_params {
/* The polarity *change* which will trigger an interrupt.
* If 'requested_polarity == INTERRUPT_POLARITY_BOTH', then
* 'current_polarity' must be initialised. */
- enum dc_interrupt_porlarity requested_polarity;
+ enum dc_interrupt_polarity requested_polarity;
/* If 'requested_polarity == INTERRUPT_POLARITY_BOTH',
* 'current_polarity' should contain the current state, which means
* the interrupt will be triggered when state changes from what is,
* in 'current_polarity'. */
- enum dc_interrupt_porlarity current_polarity;
+ enum dc_interrupt_polarity current_polarity;
enum dc_irq_source irq_source;
enum dc_interrupt_context int_context;
};
diff --git a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c
index 0894e6aef3dd..21a39afd274b 100644
--- a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c
+++ b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c
@@ -839,6 +839,12 @@ bool dp_set_test_pattern(
pipe_ctx->stream->vsc_infopacket.sb[17] |= (1 << 7); // sb17 bit 7 Dynamic Range: 0 = VESA range, 1 = CTA range
else
pipe_ctx->stream->vsc_infopacket.sb[17] &= ~(1 << 7);
+
+ if (color_space == COLOR_SPACE_YCBCR601_LIMITED)
+ pipe_ctx->stream->vsc_infopacket.sb[16] &= 0xf0;
+ else if (color_space == COLOR_SPACE_YCBCR709_LIMITED)
+ pipe_ctx->stream->vsc_infopacket.sb[16] |= 1;
+
resource_build_info_frame(pipe_ctx);
link->dc->hwss.update_info_frame(pipe_ctx);
}
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
index 4538451945b4..34a4a8c0e18c 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
@@ -1932,8 +1932,7 @@ static void disable_link_dp(struct dc_link *link,
dp_disable_link_phy(link, link_res, signal);
if (link->connector_signal == SIGNAL_TYPE_EDP) {
- if (!link->dc->config.edp_no_power_sequencing &&
- !link->skip_implict_edp_power_control)
+ if (!link->skip_implict_edp_power_control)
link->dc->hwss.edp_power_control(link, false);
}
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c
index 938df1f0f7da..e32a7974a4bc 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c
@@ -182,7 +182,7 @@ bool edp_set_backlight_level_nits(struct dc_link *link,
&backlight_control, 1) != DC_OK)
return false;
} else {
- const uint8_t backlight_enable = DP_EDP_PANEL_LUMINANCE_CONTROL_ENABLE;
+ uint8_t backlight_enable = 0;
struct target_luminance_value *target_luminance = NULL;
//if target luminance value is greater than 24 bits, clip the value to 24 bits
@@ -191,6 +191,11 @@ bool edp_set_backlight_level_nits(struct dc_link *link,
target_luminance = (struct target_luminance_value *)&backlight_millinits;
+ core_link_read_dpcd(link, DP_EDP_BACKLIGHT_MODE_SET_REGISTER,
+ &backlight_enable, sizeof(uint8_t));
+
+ backlight_enable |= DP_EDP_PANEL_LUMINANCE_CONTROL_ENABLE;
+
if (core_link_write_dpcd(link, DP_EDP_BACKLIGHT_MODE_SET_REGISTER,
&backlight_enable,
sizeof(backlight_enable)) != DC_OK)
@@ -283,8 +288,8 @@ bool set_default_brightness_aux(struct dc_link *link)
if (link && link->dpcd_sink_ext_caps.bits.oled == 1) {
if (!read_default_bl_aux(link, &default_backlight))
default_backlight = 150000;
- // if < 5 nits or > 5000, it might be wrong readback
- if (default_backlight < 5000 || default_backlight > 5000000)
+ // if < 1 nits or > 5000, it might be wrong readback
+ if (default_backlight < 1000 || default_backlight > 5000000)
default_backlight = 150000; //
return edp_set_backlight_level_nits(link, true,
diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn303.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn303.c
index b42369984473..878700160fa9 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn303.c
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn303.c
@@ -2,7 +2,26 @@
/*
* Copyright (C) 2021 Advanced Micro Devices, 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, sublicense,
+ * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
* Authors: AMD
+ *
*/
#include "../dmub_srv.h"
diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn303.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn303.h
index 84141d450256..abe087251cc1 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn303.h
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn303.h
@@ -2,7 +2,26 @@
/*
* Copyright (C) 2021 Advanced Micro Devices, 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, sublicense,
+ * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
* Authors: AMD
+ *
*/
#ifndef _DMUB_DCN303_H_
diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
index b99db771e071..e43e8d4bfe37 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
@@ -352,6 +352,7 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic)
funcs->init_reg_offsets = dmub_srv_dcn35_regs_init;
funcs->is_hw_powered_up = dmub_dcn35_is_hw_powered_up;
+ funcs->should_detect = dmub_dcn35_should_detect;
break;
default:
diff --git a/drivers/gpu/drm/amd/display/include/signal_types.h b/drivers/gpu/drm/amd/display/include/signal_types.h
index 325c5ba4c82a..1b14b17a79c7 100644
--- a/drivers/gpu/drm/amd/display/include/signal_types.h
+++ b/drivers/gpu/drm/amd/display/include/signal_types.h
@@ -132,7 +132,6 @@ static inline bool dc_is_audio_capable_signal(enum signal_type signal)
{
return (signal == SIGNAL_TYPE_DISPLAY_PORT ||
signal == SIGNAL_TYPE_DISPLAY_PORT_MST ||
- signal == SIGNAL_TYPE_VIRTUAL ||
dc_is_hdmi_signal(signal));
}
diff --git a/drivers/gpu/drm/amd/include/asic_reg/mp/mp_13_0_2_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/mp/mp_13_0_2_sh_mask.h
index 6e29a185de51..765d9ca2316f 100644
--- a/drivers/gpu/drm/amd/include/asic_reg/mp/mp_13_0_2_sh_mask.h
+++ b/drivers/gpu/drm/amd/include/asic_reg/mp/mp_13_0_2_sh_mask.h
@@ -242,6 +242,34 @@
//MP0_SMN_C2PMSG_103
#define MP0_SMN_C2PMSG_103__CONTENT__SHIFT 0x0
#define MP0_SMN_C2PMSG_103__CONTENT_MASK 0xFFFFFFFFL
+//MP0_SMN_C2PMSG_109
+#define MP0_SMN_C2PMSG_109__CONTENT__SHIFT 0x0
+#define MP0_SMN_C2PMSG_109__CONTENT_MASK 0xFFFFFFFFL
+//MP0_SMN_C2PMSG_126
+#define MP0_SMN_C2PMSG_126__GPU_ERR_MEM_TRAINING__SHIFT 0x0
+#define MP0_SMN_C2PMSG_126__GPU_ERR_FW_LOAD__SHIFT 0x1
+#define MP0_SMN_C2PMSG_126__GPU_ERR_WAFL_LINK_TRAINING__SHIFT 0x2
+#define MP0_SMN_C2PMSG_126__GPU_ERR_XGMI_LINK_TRAINING__SHIFT 0x3
+#define MP0_SMN_C2PMSG_126__GPU_ERR_USR_CP_LINK_TRAINING__SHIFT 0x4
+#define MP0_SMN_C2PMSG_126__GPU_ERR_USR_DP_LINK_TRAINING__SHIFT 0x5
+#define MP0_SMN_C2PMSG_126__GPU_ERR_HBM_MEM_TEST__SHIFT 0x6
+#define MP0_SMN_C2PMSG_126__GPU_ERR_HBM_BIST_TEST__SHIFT 0x7
+#define MP0_SMN_C2PMSG_126__SOCKET_ID__SHIFT 0x8
+#define MP0_SMN_C2PMSG_126__AID_ID__SHIFT 0xb
+#define MP0_SMN_C2PMSG_126__HBM_ID__SHIFT 0xd
+#define MP0_SMN_C2PMSG_126__BOOT_STATUS__SHIFT 0x1f
+#define MP0_SMN_C2PMSG_126__GPU_ERR_MEM_TRAINING_MASK 0x00000001L
+#define MP0_SMN_C2PMSG_126__GPU_ERR_FW_LOAD_MASK 0x00000002L
+#define MP0_SMN_C2PMSG_126__GPU_ERR_WAFL_LINK_TRAINING_MASK 0x00000004L
+#define MP0_SMN_C2PMSG_126__GPU_ERR_XGMI_LINK_TRAINING_MASK 0x00000008L
+#define MP0_SMN_C2PMSG_126__GPU_ERR_USR_CP_LINK_TRAINING_MASK 0x00000010L
+#define MP0_SMN_C2PMSG_126__GPU_ERR_USR_DP_LINK_TRAINING_MASK 0x00000020L
+#define MP0_SMN_C2PMSG_126__GPU_ERR_HBM_MEM_TEST_MASK 0x00000040L
+#define MP0_SMN_C2PMSG_126__GPU_ERR_HBM_BIST_TEST_MASK 0x00000080L
+#define MP0_SMN_C2PMSG_126__SOCKET_ID_MASK 0x00000700L
+#define MP0_SMN_C2PMSG_126__AID_ID_MASK 0x00001800L
+#define MP0_SMN_C2PMSG_126__HBM_ID_MASK 0x00002000L
+#define MP0_SMN_C2PMSG_126__BOOT_STATUS_MASK 0x80000000L
//MP0_SMN_IH_CREDIT
#define MP0_SMN_IH_CREDIT__CREDIT_VALUE__SHIFT 0x0
#define MP0_SMN_IH_CREDIT__CLIENT_ID__SHIFT 0x10
diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
index 3201808c2dd8..cd3c40a86029 100644
--- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
+++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
@@ -1080,33 +1080,35 @@ struct gpu_metrics_v3_0 {
uint16_t average_ipu_activity[8];
/* time filtered per-core C0 residency % [0-100]*/
uint16_t average_core_c0_activity[16];
- /* time filtered DRAM read bandwidth [GB/sec] */
+ /* time filtered DRAM read bandwidth [MB/sec] */
uint16_t average_dram_reads;
- /* time filtered DRAM write bandwidth [GB/sec] */
+ /* time filtered DRAM write bandwidth [MB/sec] */
uint16_t average_dram_writes;
/* Driver attached timestamp (in ns) */
uint64_t system_clock_counter;
/* Power/Energy */
- /* average dGPU + APU power on A + A platform */
+ /* time filtered power used for PPT/STAPM [APU+dGPU] [mW] */
uint32_t average_socket_power;
- /* average IPU power [W] */
+ /* time filtered IPU power [mW] */
uint16_t average_ipu_power;
- /* average APU power [W] */
+ /* time filtered APU power [mW] */
uint32_t average_apu_power;
- /* average dGPU power [W] */
+ /* time filtered GFX power [mW] */
+ uint32_t average_gfx_power;
+ /* time filtered dGPU power [mW] */
uint32_t average_dgpu_power;
- /* sum of core power across all cores in the socket [W] */
- uint32_t average_core_power;
- /* calculated core power [W] */
- uint16_t core_power[16];
- /* maximum IRM defined STAPM power limit [W] */
+ /* time filtered sum of core power across all cores in the socket [mW] */
+ uint32_t average_all_core_power;
+ /* calculated core power [mW] */
+ uint16_t average_core_power[16];
+ /* maximum IRM defined STAPM power limit [mW] */
uint16_t stapm_power_limit;
- /* time filtered STAPM power limit [W] */
+ /* time filtered STAPM power limit [mW] */
uint16_t current_stapm_power_limit;
- /* Average clocks */
+ /* time filtered clocks [MHz] */
uint16_t average_gfxclk_frequency;
uint16_t average_socclk_frequency;
uint16_t average_vpeclk_frequency;
@@ -1115,7 +1117,7 @@ struct gpu_metrics_v3_0 {
uint16_t average_vclk_frequency;
/* Current clocks */
- /* target core frequency */
+ /* target core frequency [MHz] */
uint16_t current_coreclk[16];
/* CCLK frequency limit enforced on classic cores [MHz] */
uint16_t current_core_maxfreq;
diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
index 358bb5e485f2..4ba9195c83c5 100644
--- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
@@ -3288,10 +3288,6 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj,
uint32_t gc_ver = amdgpu_ip_version(adev, GC_HWIP, 0);
uint32_t tmp;
- /* under multi-vf mode, the hwmon attributes are all not supported */
- if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev))
- return 0;
-
/* under pp one vf mode manage of hwmon attributes is not supported */
if (amdgpu_sriov_is_pp_one_vf(adev))
effective_mode &= ~S_IWUSR;
@@ -4162,6 +4158,7 @@ err_out:
int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
{
+ enum amdgpu_sriov_vf_mode mode;
uint32_t mask = 0;
int ret;
@@ -4173,17 +4170,21 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
if (adev->pm.dpm_enabled == 0)
return 0;
- adev->pm.int_hwmon_dev = hwmon_device_register_with_groups(adev->dev,
- DRIVER_NAME, adev,
- hwmon_groups);
- if (IS_ERR(adev->pm.int_hwmon_dev)) {
- ret = PTR_ERR(adev->pm.int_hwmon_dev);
- dev_err(adev->dev,
- "Unable to register hwmon device: %d\n", ret);
- return ret;
+ mode = amdgpu_virt_get_sriov_vf_mode(adev);
+
+ /* under multi-vf mode, the hwmon attributes are all not supported */
+ if (mode != SRIOV_VF_MODE_MULTI_VF) {
+ adev->pm.int_hwmon_dev = hwmon_device_register_with_groups(adev->dev,
+ DRIVER_NAME, adev,
+ hwmon_groups);
+ if (IS_ERR(adev->pm.int_hwmon_dev)) {
+ ret = PTR_ERR(adev->pm.int_hwmon_dev);
+ dev_err(adev->dev, "Unable to register hwmon device: %d\n", ret);
+ return ret;
+ }
}
- switch (amdgpu_virt_get_sriov_vf_mode(adev)) {
+ switch (mode) {
case SRIOV_VF_MODE_ONE_VF:
mask = ATTR_FLAG_ONEVF;
break;
@@ -4290,10 +4291,10 @@ static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *a
seq_printf(m, "\t%u mV (VDDNB)\n", value);
size = sizeof(uint32_t);
if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_AVG_POWER, (void *)&query, &size))
- seq_printf(m, "\t%u.%u W (average GPU)\n", query >> 8, query & 0xff);
+ seq_printf(m, "\t%u.%02u W (average GPU)\n", query >> 8, query & 0xff);
size = sizeof(uint32_t);
if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_INPUT_POWER, (void *)&query, &size))
- seq_printf(m, "\t%u.%u W (current GPU)\n", query >> 8, query & 0xff);
+ seq_printf(m, "\t%u.%02u W (current GPU)\n", query >> 8, query & 0xff);
size = sizeof(value);
seq_printf(m, "\n");
diff --git a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
index 9e4f8a4104a3..914c15387157 100644
--- a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
+++ b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
@@ -1022,6 +1022,9 @@ static int pp_get_power_limit(void *handle, uint32_t *limit,
*limit /= 100;
}
break;
+ case PP_PWR_LIMIT_MIN:
+ *limit = 0;
+ break;
default:
ret = -EOPNOTSUPP;
break;
diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h
index 9fcad69a9f34..2cf2a7b12623 100644
--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h
+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h
@@ -367,7 +367,7 @@ typedef struct _ATOM_Tonga_VCE_State_Record {
typedef struct _ATOM_Tonga_VCE_State_Table {
UCHAR ucRevId;
UCHAR ucNumEntries;
- ATOM_Tonga_VCE_State_Record entries[1];
+ ATOM_Tonga_VCE_State_Record entries[];
} ATOM_Tonga_VCE_State_Table;
typedef struct _ATOM_Tonga_PowerTune_Table {
@@ -481,7 +481,7 @@ typedef struct _ATOM_Tonga_Hard_Limit_Record {
typedef struct _ATOM_Tonga_Hard_Limit_Table {
UCHAR ucRevId;
UCHAR ucNumEntries;
- ATOM_Tonga_Hard_Limit_Record entries[1];
+ ATOM_Tonga_Hard_Limit_Record entries[];
} ATOM_Tonga_Hard_Limit_Table;
typedef struct _ATOM_Tonga_GPIO_Table {
diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c
index 5a2371484a58..11372fcc59c8 100644
--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c
+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c
@@ -1823,9 +1823,7 @@ static void smu7_init_dpm_defaults(struct pp_hwmgr *hwmgr)
data->mclk_dpm_key_disabled = hwmgr->feature_mask & PP_MCLK_DPM_MASK ? false : true;
data->sclk_dpm_key_disabled = hwmgr->feature_mask & PP_SCLK_DPM_MASK ? false : true;
- data->pcie_dpm_key_disabled =
- !amdgpu_device_pcie_dynamic_switching_supported() ||
- !(hwmgr->feature_mask & PP_PCIE_DPM_MASK);
+ data->pcie_dpm_key_disabled = !(hwmgr->feature_mask & PP_PCIE_DPM_MASK);
/* need to set voltage control types before EVV patching */
data->voltage_control = SMU7_VOLTAGE_CONTROL_NONE;
data->vddci_control = SMU7_VOLTAGE_CONTROL_NONE;
diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_pptable.h b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_pptable.h
index 8b0590b834cc..de2926df5ed7 100644
--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_pptable.h
+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_pptable.h
@@ -129,7 +129,7 @@ typedef struct _ATOM_Vega10_State {
typedef struct _ATOM_Vega10_State_Array {
UCHAR ucRevId;
UCHAR ucNumEntries; /* Number of entries. */
- ATOM_Vega10_State states[1]; /* Dynamically allocate entries. */
+ ATOM_Vega10_State states[]; /* Dynamically allocate entries. */
} ATOM_Vega10_State_Array;
typedef struct _ATOM_Vega10_CLK_Dependency_Record {
@@ -169,37 +169,37 @@ typedef struct _ATOM_Vega10_GFXCLK_Dependency_Table {
typedef struct _ATOM_Vega10_MCLK_Dependency_Table {
UCHAR ucRevId;
UCHAR ucNumEntries; /* Number of entries. */
- ATOM_Vega10_MCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */
+ ATOM_Vega10_MCLK_Dependency_Record entries[]; /* Dynamically allocate entries. */
} ATOM_Vega10_MCLK_Dependency_Table;
typedef struct _ATOM_Vega10_SOCCLK_Dependency_Table {
UCHAR ucRevId;
UCHAR ucNumEntries; /* Number of entries. */
- ATOM_Vega10_CLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */
+ ATOM_Vega10_CLK_Dependency_Record entries[]; /* Dynamically allocate entries. */
} ATOM_Vega10_SOCCLK_Dependency_Table;
typedef struct _ATOM_Vega10_DCEFCLK_Dependency_Table {
UCHAR ucRevId;
UCHAR ucNumEntries; /* Number of entries. */
- ATOM_Vega10_CLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */
+ ATOM_Vega10_CLK_Dependency_Record entries[]; /* Dynamically allocate entries. */
} ATOM_Vega10_DCEFCLK_Dependency_Table;
typedef struct _ATOM_Vega10_PIXCLK_Dependency_Table {
UCHAR ucRevId;
UCHAR ucNumEntries; /* Number of entries. */
- ATOM_Vega10_CLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */
+ ATOM_Vega10_CLK_Dependency_Record entries[]; /* Dynamically allocate entries. */
} ATOM_Vega10_PIXCLK_Dependency_Table;
typedef struct _ATOM_Vega10_DISPCLK_Dependency_Table {
UCHAR ucRevId;
UCHAR ucNumEntries; /* Number of entries.*/
- ATOM_Vega10_CLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */
+ ATOM_Vega10_CLK_Dependency_Record entries[]; /* Dynamically allocate entries. */
} ATOM_Vega10_DISPCLK_Dependency_Table;
typedef struct _ATOM_Vega10_PHYCLK_Dependency_Table {
UCHAR ucRevId;
UCHAR ucNumEntries; /* Number of entries. */
- ATOM_Vega10_CLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */
+ ATOM_Vega10_CLK_Dependency_Record entries[]; /* Dynamically allocate entries. */
} ATOM_Vega10_PHYCLK_Dependency_Table;
typedef struct _ATOM_Vega10_MM_Dependency_Record {
@@ -213,7 +213,7 @@ typedef struct _ATOM_Vega10_MM_Dependency_Record {
typedef struct _ATOM_Vega10_MM_Dependency_Table {
UCHAR ucRevId;
UCHAR ucNumEntries; /* Number of entries */
- ATOM_Vega10_MM_Dependency_Record entries[1]; /* Dynamically allocate entries */
+ ATOM_Vega10_MM_Dependency_Record entries[]; /* Dynamically allocate entries */
} ATOM_Vega10_MM_Dependency_Table;
typedef struct _ATOM_Vega10_PCIE_Record {
@@ -225,7 +225,7 @@ typedef struct _ATOM_Vega10_PCIE_Record {
typedef struct _ATOM_Vega10_PCIE_Table {
UCHAR ucRevId;
UCHAR ucNumEntries; /* Number of entries */
- ATOM_Vega10_PCIE_Record entries[1]; /* Dynamically allocate entries. */
+ ATOM_Vega10_PCIE_Record entries[]; /* Dynamically allocate entries. */
} ATOM_Vega10_PCIE_Table;
typedef struct _ATOM_Vega10_Voltage_Lookup_Record {
@@ -235,7 +235,7 @@ typedef struct _ATOM_Vega10_Voltage_Lookup_Record {
typedef struct _ATOM_Vega10_Voltage_Lookup_Table {
UCHAR ucRevId;
UCHAR ucNumEntries; /* Number of entries */
- ATOM_Vega10_Voltage_Lookup_Record entries[1]; /* Dynamically allocate entries */
+ ATOM_Vega10_Voltage_Lookup_Record entries[]; /* Dynamically allocate entries */
} ATOM_Vega10_Voltage_Lookup_Table;
typedef struct _ATOM_Vega10_Fan_Table {
@@ -327,7 +327,7 @@ typedef struct _ATOM_Vega10_VCE_State_Record {
typedef struct _ATOM_Vega10_VCE_State_Table {
UCHAR ucRevId;
UCHAR ucNumEntries;
- ATOM_Vega10_VCE_State_Record entries[1];
+ ATOM_Vega10_VCE_State_Record entries[];
} ATOM_Vega10_VCE_State_Table;
typedef struct _ATOM_Vega10_PowerTune_Table {
@@ -427,7 +427,7 @@ typedef struct _ATOM_Vega10_Hard_Limit_Record {
typedef struct _ATOM_Vega10_Hard_Limit_Table {
UCHAR ucRevId;
UCHAR ucNumEntries;
- ATOM_Vega10_Hard_Limit_Record entries[1];
+ ATOM_Vega10_Hard_Limit_Record entries[];
} ATOM_Vega10_Hard_Limit_Table;
typedef struct _Vega10_PPTable_Generic_SubTable_Header {
diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
index 7087f9840ab7..23b00eddc1af 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
@@ -733,7 +733,7 @@ static int smu_early_init(void *handle)
smu->adev = adev;
smu->pm_enabled = !!amdgpu_dpm;
smu->is_apu = false;
- smu->smu_baco.state = SMU_BACO_STATE_EXIT;
+ smu->smu_baco.state = SMU_BACO_STATE_NONE;
smu->smu_baco.platform_support = false;
smu->user_dpm_profile.fan_mode = -1;
@@ -1678,13 +1678,14 @@ static int smu_disable_dpms(struct smu_context *smu)
}
/*
- * For SMU 13.0.4/11, PMFW will handle the features disablement properly
+ * For SMU 13.0.4/11 and 14.0.0, PMFW will handle the features disablement properly
* for gpu reset and S0i3 cases. Driver involvement is unnecessary.
*/
if (amdgpu_in_reset(adev) || adev->in_s0ix) {
switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) {
case IP_VERSION(13, 0, 4):
case IP_VERSION(13, 0, 11):
+ case IP_VERSION(14, 0, 0):
return 0;
default:
break;
@@ -1741,10 +1742,31 @@ static int smu_smc_hw_cleanup(struct smu_context *smu)
return 0;
}
+static int smu_reset_mp1_state(struct smu_context *smu)
+{
+ struct amdgpu_device *adev = smu->adev;
+ int ret = 0;
+
+ if ((!adev->in_runpm) && (!adev->in_suspend) &&
+ (!amdgpu_in_reset(adev)))
+ switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) {
+ case IP_VERSION(13, 0, 0):
+ case IP_VERSION(13, 0, 7):
+ case IP_VERSION(13, 0, 10):
+ ret = smu_set_mp1_state(smu, PP_MP1_STATE_UNLOAD);
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
static int smu_hw_fini(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
struct smu_context *smu = adev->powerplay.pp_handle;
+ int ret;
if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev))
return 0;
@@ -1762,7 +1784,15 @@ static int smu_hw_fini(void *handle)
adev->pm.dpm_enabled = false;
- return smu_smc_hw_cleanup(smu);
+ ret = smu_smc_hw_cleanup(smu);
+ if (ret)
+ return ret;
+
+ ret = smu_reset_mp1_state(smu);
+ if (ret)
+ return ret;
+
+ return 0;
}
static void smu_late_fini(void *handle)
@@ -2434,7 +2464,6 @@ int smu_get_power_limit(void *handle,
break;
default:
return -EOPNOTSUPP;
- break;
}
switch (pp_limit_level) {
@@ -2452,7 +2481,6 @@ int smu_get_power_limit(void *handle,
break;
default:
return -EOPNOTSUPP;
- break;
}
if (limit_type != SMU_DEFAULT_PPT_LIMIT) {
@@ -2486,7 +2514,7 @@ int smu_get_power_limit(void *handle,
*limit = smu->min_power_limit;
break;
default:
- break;
+ return -EINVAL;
}
}
diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
index 839553a86aa2..8def291b18bc 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
@@ -419,6 +419,7 @@ enum smu_reset_mode {
enum smu_baco_state {
SMU_BACO_STATE_ENTER = 0,
SMU_BACO_STATE_EXIT,
+ SMU_BACO_STATE_NONE,
};
struct smu_baco_context {
diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu14_driver_if_v14_0_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu14_driver_if_v14_0_0.h
index b483c8e096e7..22f88842a7fd 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu14_driver_if_v14_0_0.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu14_driver_if_v14_0_0.h
@@ -150,97 +150,39 @@ typedef struct {
} DpmClocks_t;
typedef struct {
- uint16_t CoreFrequency[16]; //Target core frequency [MHz]
- uint16_t CorePower[16]; //CAC calculated core power [W] [Q8.8]
- uint16_t CoreTemperature[16]; //TSEN measured core temperature [C] [Q8.8]
- uint16_t GfxTemperature; //TSEN measured GFX temperature [C] [Q8.8]
- uint16_t SocTemperature; //TSEN measured SOC temperature [C] [Q8.8]
- uint16_t StapmOpnLimit; //Maximum IRM defined STAPM power limit [W] [Q8.8]
- uint16_t StapmCurrentLimit; //Time filtered STAPM power limit [W] [Q8.8]
- uint16_t InfrastructureCpuMaxFreq; //CCLK frequency limit enforced on classic cores [MHz]
- uint16_t InfrastructureGfxMaxFreq; //GFXCLK frequency limit enforced on GFX [MHz]
- uint16_t SkinTemp; //Maximum skin temperature reported by APU and HS2 chassis sensors [C] [Q8.8]
- uint16_t AverageGfxclkFrequency; //Time filtered target GFXCLK frequency [MHz]
- uint16_t AverageFclkFrequency; //Time filtered target FCLK frequency [MHz]
- uint16_t AverageGfxActivity; //Time filtered GFX busy % [0-100] [Q8.8]
- uint16_t AverageSocclkFrequency; //Time filtered target SOCCLK frequency [MHz]
- uint16_t AverageVclkFrequency; //Time filtered target VCLK frequency [MHz]
- uint16_t AverageVcnActivity; //Time filtered VCN busy % [0-100] [Q8.8]
- uint16_t AverageVpeclkFrequency; //Time filtered target VPECLK frequency [MHz]
- uint16_t AverageIpuclkFrequency; //Time filtered target IPUCLK frequency [MHz]
- uint16_t AverageIpuBusy[8]; //Time filtered IPU per-column busy % [0-100] [Q8.8]
- uint16_t AverageDRAMReads; //Time filtered DRAM read bandwidth [GB/sec] [Q8.8]
- uint16_t AverageDRAMWrites; //Time filtered DRAM write bandwidth [GB/sec] [Q8.8]
- uint16_t AverageCoreC0Residency[16]; //Time filtered per-core C0 residency % [0-100] [Q8.8]
- uint16_t IpuPower; //Time filtered IPU power [W] [Q8.8]
- uint32_t ApuPower; //Time filtered APU power [W] [Q24.8]
- uint32_t dGpuPower; //Time filtered dGPU power [W] [Q24.8]
- uint32_t AverageSocketPower; //Time filtered power used for PPT/STAPM [APU+dGPU] [W] [Q24.8]
- uint32_t AverageCorePower; //Time filtered sum of core power across all cores in the socket [W] [Q24.8]
- uint32_t FilterAlphaValue; //Metrics table alpha filter time constant [us]
- uint32_t MetricsCounter; //Counter that is incremented on every metrics table update [PM_TIMER cycles]
+ uint16_t CoreFrequency[16]; //Target core frequency [MHz]
+ uint16_t CorePower[16]; //CAC calculated core power [mW]
+ uint16_t CoreTemperature[16]; //TSEN measured core temperature [centi-C]
+ uint16_t GfxTemperature; //TSEN measured GFX temperature [centi-C]
+ uint16_t SocTemperature; //TSEN measured SOC temperature [centi-C]
+ uint16_t StapmOpnLimit; //Maximum IRM defined STAPM power limit [mW]
+ uint16_t StapmCurrentLimit; //Time filtered STAPM power limit [mW]
+ uint16_t InfrastructureCpuMaxFreq; //CCLK frequency limit enforced on classic cores [MHz]
+ uint16_t InfrastructureGfxMaxFreq; //GFXCLK frequency limit enforced on GFX [MHz]
+ uint16_t SkinTemp; //Maximum skin temperature reported by APU and HS2 chassis sensors [centi-C]
+ uint16_t GfxclkFrequency; //Time filtered target GFXCLK frequency [MHz]
+ uint16_t FclkFrequency; //Time filtered target FCLK frequency [MHz]
+ uint16_t GfxActivity; //Time filtered GFX busy % [0-100]
+ uint16_t SocclkFrequency; //Time filtered target SOCCLK frequency [MHz]
+ uint16_t VclkFrequency; //Time filtered target VCLK frequency [MHz]
+ uint16_t VcnActivity; //Time filtered VCN busy % [0-100]
+ uint16_t VpeclkFrequency; //Time filtered target VPECLK frequency [MHz]
+ uint16_t IpuclkFrequency; //Time filtered target IPUCLK frequency [MHz]
+ uint16_t IpuBusy[8]; //Time filtered IPU per-column busy % [0-100]
+ uint16_t DRAMReads; //Time filtered DRAM read bandwidth [MB/sec]
+ uint16_t DRAMWrites; //Time filtered DRAM write bandwidth [MB/sec]
+ uint16_t CoreC0Residency[16]; //Time filtered per-core C0 residency % [0-100]
+ uint16_t IpuPower; //Time filtered IPU power [mW]
+ uint32_t ApuPower; //Time filtered APU power [mW]
+ uint32_t GfxPower; //Time filtered GFX power [mW]
+ uint32_t dGpuPower; //Time filtered dGPU power [mW]
+ uint32_t SocketPower; //Time filtered power used for PPT/STAPM [APU+dGPU] [mW]
+ uint32_t AllCorePower; //Time filtered sum of core power across all cores in the socket [mW]
+ uint32_t FilterAlphaValue; //Metrics table alpha filter time constant [us]
+ uint32_t MetricsCounter; //Counter that is incremented on every metrics table update [PM_TIMER cycles]
+ uint32_t spare[16];
} SmuMetrics_t;
-typedef struct {
- uint16_t GfxclkFrequency; //[MHz]
- uint16_t SocclkFrequency; //[MHz]
- uint16_t VclkFrequency; //[MHz]
- uint16_t DclkFrequency; //[MHz]
- uint16_t MemclkFrequency; //[MHz]
- uint16_t spare;
- uint16_t UvdActivity; //[centi]
- uint16_t GfxActivity; //[centi]
-
- uint16_t Voltage[2]; //[mV] indices: VDDCR_VDD, VDDCR_SOC
- uint16_t Current[2]; //[mA] indices: VDDCR_VDD, VDDCR_SOC
- uint16_t Power[2]; //[mW] indices: VDDCR_VDD, VDDCR_SOC
-
- uint16_t CoreFrequency[8]; //[MHz]
- uint16_t CorePower[8]; //[mW]
- uint16_t CoreTemperature[8]; //[centi-Celsius]
- uint16_t L3Frequency[2]; //[MHz]
- uint16_t L3Temperature[2]; //[centi-Celsius]
-
- uint16_t spare2[24];
-
- uint16_t GfxTemperature; //[centi-Celsius]
- uint16_t SocTemperature; //[centi-Celsius]
- uint16_t ThrottlerStatus;
-
- uint16_t CurrentSocketPower; //[mW]
- uint16_t StapmOpnLimit; //[W]
- uint16_t StapmCurrentLimit; //[W]
- uint32_t ApuPower; //[mW]
- uint32_t dGpuPower; //[mW]
-
- uint16_t VddTdcValue; //[mA]
- uint16_t SocTdcValue; //[mA]
- uint16_t VddEdcValue; //[mA]
- uint16_t SocEdcValue; //[mA]
-
- uint16_t InfrastructureCpuMaxFreq; //[MHz]
- uint16_t InfrastructureGfxMaxFreq; //[MHz]
-
- uint16_t SkinTemp;
- uint16_t DeviceState;
- uint16_t CurTemp; //[centi-Celsius]
- uint16_t FilterAlphaValue; //[m]
-
- uint16_t AverageGfxclkFrequency;
- uint16_t AverageFclkFrequency;
- uint16_t AverageGfxActivity;
- uint16_t AverageSocclkFrequency;
- uint16_t AverageVclkFrequency;
- uint16_t AverageVcnActivity;
- uint16_t AverageDRAMReads; //Filtered DF Bandwidth::DRAM Reads
- uint16_t AverageDRAMWrites; //Filtered DF Bandwidth::DRAM Writes
- uint16_t AverageSocketPower; //Filtered value of CurrentSocketPower
- uint16_t AverageCorePower[2]; //Filtered of [sum of CorePower[8] per ccx])
- uint16_t AverageCoreC0Residency[16]; //Filtered of [average C0 residency % per core]
- uint16_t spare1;
- uint32_t MetricsCounter; //Counts the # of metrics table parameter reads per update to the metrics table, i.e. if the metrics table update happens every 1 second, this value could be up to 1000 if the smu collected metrics data every cycle, or as low as 0 if the smu was asleep the whole time. Reset to 0 after writing.
-} SmuMetrics_legacy_t;
-
//ISP tile definitions
typedef enum {
TILE_XTILE = 0, //ONO0
diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
index cc02f979e9e9..95cb919718ae 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
@@ -299,5 +299,7 @@ int smu_v13_0_update_pcie_parameters(struct smu_context *smu,
uint8_t pcie_gen_cap,
uint8_t pcie_width_cap);
+int smu_v13_0_disable_pmfw_state(struct smu_context *smu);
+
#endif
#endif
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
index 090249b6422a..1de9f8b5cc5f 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
@@ -2115,7 +2115,7 @@ static int sienna_cichlid_update_pcie_parameters(struct smu_context *smu,
min_lane_width = min_lane_width > max_lane_width ?
max_lane_width : min_lane_width;
- if (!amdgpu_device_pcie_dynamic_switching_supported()) {
+ if (!(smu->adev->pm.pp_feature & PP_PCIE_DPM_MASK)) {
pcie_table->pcie_gen[0] = max_gen_speed;
pcie_table->pcie_lane[0] = max_lane_width;
} else {
@@ -2461,12 +2461,18 @@ static bool sienna_cichlid_is_mode1_reset_supported(struct smu_context *smu)
{
struct amdgpu_device *adev = smu->adev;
uint32_t val;
+ uint32_t smu_version;
+ int ret;
/**
* SRIOV env will not support SMU mode1 reset
* PM FW support mode1 reset from 58.26
*/
- if (amdgpu_sriov_vf(adev) || (smu->smc_fw_version < 0x003a1a00))
+ ret = smu_cmn_get_smc_version(smu, NULL, &smu_version);
+ if (ret)
+ return false;
+
+ if (amdgpu_sriov_vf(adev) || (smu_version < 0x003a1a00))
return false;
/**
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
index 3efc6aed28f1..762b31455a0b 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
@@ -234,24 +234,15 @@ static int vangogh_tables_init(struct smu_context *smu)
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
SMU_TABLE_INIT(tables, SMU_TABLE_ACTIVITY_MONITOR_COEFF, sizeof(DpmActivityMonitorCoeffExt_t),
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
+ SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, max(sizeof(SmuMetrics_t), sizeof(SmuMetrics_legacy_t)),
+ PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
- if (smu->smc_fw_if_version < 0x3) {
- SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_legacy_t),
- PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
- smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_legacy_t), GFP_KERNEL);
- } else {
- SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t),
- PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
- smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL);
- }
+ smu_table->metrics_table = kzalloc(max(sizeof(SmuMetrics_t), sizeof(SmuMetrics_legacy_t)), GFP_KERNEL);
if (!smu_table->metrics_table)
goto err0_out;
smu_table->metrics_time = 0;
- if (smu->smc_fw_version >= 0x043F3E00)
- smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v2_3);
- else
- smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v2_2);
+ smu_table->gpu_metrics_table_size = max(sizeof(struct gpu_metrics_v2_3), sizeof(struct gpu_metrics_v2_2));
smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL);
if (!smu_table->gpu_metrics_table)
goto err1_out;
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
index f082cd4b40c1..1a6675d70a4b 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
@@ -1931,11 +1931,19 @@ static bool aldebaran_is_mode1_reset_supported(struct smu_context *smu)
#if 0
struct amdgpu_device *adev = smu->adev;
uint32_t val;
+ uint32_t smu_version;
+ int ret;
+
/**
* PM FW version support mode1 reset from 68.07
*/
- if ((smu->smc_fw_version < 0x00440700))
+ ret = smu_cmn_get_smc_version(smu, NULL, &smu_version);
+ if (ret)
return false;
+
+ if ((smu_version < 0x00440700))
+ return false;
+
/**
* mode1 reset relies on PSP, so we should check if
* PSP is alive.
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
index ba3ef3c2918a..cf1b84060bc3 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
@@ -2438,7 +2438,10 @@ int smu_v13_0_update_pcie_parameters(struct smu_context *smu,
uint32_t smu_pcie_arg;
int ret, i;
- if (!amdgpu_device_pcie_dynamic_switching_supported()) {
+ if (!num_of_levels)
+ return 0;
+
+ if (!(smu->adev->pm.pp_feature & PP_PCIE_DPM_MASK)) {
if (pcie_table->pcie_gen[num_of_levels - 1] < pcie_gen_cap)
pcie_gen_cap = pcie_table->pcie_gen[num_of_levels - 1];
@@ -2474,3 +2477,16 @@ int smu_v13_0_update_pcie_parameters(struct smu_context *smu,
return 0;
}
+
+int smu_v13_0_disable_pmfw_state(struct smu_context *smu)
+{
+ int ret;
+ struct amdgpu_device *adev = smu->adev;
+
+ WREG32_PCIE(MP1_Public | (smnMP1_FIRMWARE_FLAGS & 0xffffffff), 0);
+
+ ret = RREG32_PCIE(MP1_Public |
+ (smnMP1_FIRMWARE_FLAGS & 0xffffffff));
+
+ return ret == 0 ? 0 : -EINVAL;
+}
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
index bcd7b39a3a1b..82c4e1f1c6f0 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
@@ -354,12 +354,12 @@ static int smu_v13_0_0_check_powerplay_table(struct smu_context *smu)
if (powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_HARDWAREDC)
smu->dc_controlled_by_gpio = true;
- if (powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_BACO ||
- powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_MACO)
+ if (powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_BACO) {
smu_baco->platform_support = true;
- if (powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_MACO)
- smu_baco->maco_support = true;
+ if (powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_MACO)
+ smu_baco->maco_support = true;
+ }
if (!overdrive_lowerlimits->FeatureCtrlMask ||
!overdrive_upperlimits->FeatureCtrlMask)
@@ -2530,38 +2530,10 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu,
}
}
- if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_COMPUTE &&
- (((smu->adev->pdev->device == 0x744C) && (smu->adev->pdev->revision == 0xC8)) ||
- ((smu->adev->pdev->device == 0x744C) && (smu->adev->pdev->revision == 0xCC)))) {
- ret = smu_cmn_update_table(smu,
- SMU_TABLE_ACTIVITY_MONITOR_COEFF,
- WORKLOAD_PPLIB_COMPUTE_BIT,
- (void *)(&activity_monitor_external),
- false);
- if (ret) {
- dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
- return ret;
- }
-
- ret = smu_cmn_update_table(smu,
- SMU_TABLE_ACTIVITY_MONITOR_COEFF,
- WORKLOAD_PPLIB_CUSTOM_BIT,
- (void *)(&activity_monitor_external),
- true);
- if (ret) {
- dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__);
- return ret;
- }
-
- workload_type = smu_cmn_to_asic_specific_index(smu,
- CMN2ASIC_MAPPING_WORKLOAD,
- PP_SMC_POWER_PROFILE_CUSTOM);
- } else {
- /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
- workload_type = smu_cmn_to_asic_specific_index(smu,
+ /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
+ workload_type = smu_cmn_to_asic_specific_index(smu,
CMN2ASIC_MAPPING_WORKLOAD,
smu->power_profile_mode);
- }
if (workload_type < 0)
return -EINVAL;
@@ -2602,26 +2574,38 @@ static int smu_v13_0_0_baco_enter(struct smu_context *smu)
static int smu_v13_0_0_baco_exit(struct smu_context *smu)
{
struct amdgpu_device *adev = smu->adev;
+ int ret;
if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) {
/* Wait for PMFW handling for the Dstate change */
usleep_range(10000, 11000);
- return smu_v13_0_baco_set_armd3_sequence(smu, BACO_SEQ_ULPS);
+ ret = smu_v13_0_baco_set_armd3_sequence(smu, BACO_SEQ_ULPS);
} else {
- return smu_v13_0_baco_exit(smu);
+ ret = smu_v13_0_baco_exit(smu);
}
+
+ if (!ret)
+ adev->gfx.is_poweron = false;
+
+ return ret;
}
static bool smu_v13_0_0_is_mode1_reset_supported(struct smu_context *smu)
{
struct amdgpu_device *adev = smu->adev;
+ u32 smu_version;
+ int ret;
/* SRIOV does not support SMU mode1 reset */
if (amdgpu_sriov_vf(adev))
return false;
/* PMFW support is available since 78.41 */
- if (smu->smc_fw_version < 0x004e2900)
+ ret = smu_cmn_get_smc_version(smu, NULL, &smu_version);
+ if (ret)
+ return false;
+
+ if (smu_version < 0x004e2900)
return false;
return true;
@@ -2788,7 +2772,13 @@ static int smu_v13_0_0_set_mp1_state(struct smu_context *smu,
switch (mp1_state) {
case PP_MP1_STATE_UNLOAD:
- ret = smu_cmn_set_mp1_state(smu, mp1_state);
+ ret = smu_cmn_send_smc_msg_with_param(smu,
+ SMU_MSG_PrepareMp1ForUnload,
+ 0x55, NULL);
+
+ if (!ret && smu->smu_baco.state == SMU_BACO_STATE_EXIT)
+ ret = smu_v13_0_disable_pmfw_state(smu);
+
break;
default:
/* Ignore others */
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
index 60eb6f8af187..20f66e696f87 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
@@ -270,7 +270,7 @@ static int smu_v13_0_6_init_microcode(struct smu_context *smu)
struct amdgpu_device *adev = smu->adev;
uint32_t p2s_table_id = P2S_TABLE_ID_A;
int ret = 0, i, p2stable_count;
- char ucode_prefix[30];
+ char ucode_prefix[15];
char fw_name[30];
/* No need to load P2S tables in IOV mode */
@@ -1478,6 +1478,7 @@ static int smu_v13_0_6_mca_set_debug_mode(struct smu_context *smu, bool enable)
if (smu->smc_fw_version < 0x554800)
return 0;
+ amdgpu_ras_set_mca_debug_mode(smu->adev, enable);
return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ClearMcaOnRead,
enable ? 0 : ClearMcaOnRead_UE_FLAG_MASK | ClearMcaOnRead_CE_POLL_MASK,
NULL);
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
index ac0e1cc812bd..81eafed76045 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
@@ -346,12 +346,13 @@ static int smu_v13_0_7_check_powerplay_table(struct smu_context *smu)
if (powerplay_table->platform_caps & SMU_13_0_7_PP_PLATFORM_CAP_HARDWAREDC)
smu->dc_controlled_by_gpio = true;
- if (powerplay_table->platform_caps & SMU_13_0_7_PP_PLATFORM_CAP_BACO ||
- powerplay_table->platform_caps & SMU_13_0_7_PP_PLATFORM_CAP_MACO)
+ if (powerplay_table->platform_caps & SMU_13_0_7_PP_PLATFORM_CAP_BACO) {
smu_baco->platform_support = true;
- if (smu_baco->platform_support && (BoardTable->HsrEnabled || BoardTable->VddqOffEnabled))
- smu_baco->maco_support = true;
+ if ((powerplay_table->platform_caps & SMU_13_0_7_PP_PLATFORM_CAP_MACO)
+ && (BoardTable->HsrEnabled || BoardTable->VddqOffEnabled))
+ smu_baco->maco_support = true;
+ }
if (!overdrive_lowerlimits->FeatureCtrlMask ||
!overdrive_upperlimits->FeatureCtrlMask)
@@ -2498,7 +2499,13 @@ static int smu_v13_0_7_set_mp1_state(struct smu_context *smu,
switch (mp1_state) {
case PP_MP1_STATE_UNLOAD:
- ret = smu_cmn_set_mp1_state(smu, mp1_state);
+ ret = smu_cmn_send_smc_msg_with_param(smu,
+ SMU_MSG_PrepareMp1ForUnload,
+ 0x55, NULL);
+
+ if (!ret && smu->smu_baco.state == SMU_BACO_STATE_EXIT)
+ ret = smu_v13_0_disable_pmfw_state(smu);
+
break;
default:
/* Ignore others */
@@ -2524,14 +2531,20 @@ static int smu_v13_0_7_baco_enter(struct smu_context *smu)
static int smu_v13_0_7_baco_exit(struct smu_context *smu)
{
struct amdgpu_device *adev = smu->adev;
+ int ret;
if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) {
/* Wait for PMFW handling for the Dstate change */
usleep_range(10000, 11000);
- return smu_v13_0_baco_set_armd3_sequence(smu, BACO_SEQ_ULPS);
+ ret = smu_v13_0_baco_set_armd3_sequence(smu, BACO_SEQ_ULPS);
} else {
- return smu_v13_0_baco_exit(smu);
+ ret = smu_v13_0_baco_exit(smu);
}
+
+ if (!ret)
+ adev->gfx.is_poweron = false;
+
+ return ret;
}
static bool smu_v13_0_7_is_mode1_reset_supported(struct smu_context *smu)
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c
index 4ac22f44d160..d8f8ad0e7137 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c
@@ -57,7 +57,7 @@ int smu_v14_0_init_microcode(struct smu_context *smu)
{
struct amdgpu_device *adev = smu->adev;
char fw_name[30];
- char ucode_prefix[30];
+ char ucode_prefix[15];
int err = 0;
const struct smc_firmware_header_v1_0 *hdr;
const struct common_firmware_header *header;
@@ -229,6 +229,8 @@ int smu_v14_0_check_fw_version(struct smu_context *smu)
smu->smc_driver_if_version = SMU14_DRIVER_IF_VERSION_SMU_V14_0_2;
break;
case IP_VERSION(14, 0, 0):
+ if ((smu->smc_fw_version < 0x5d3a00))
+ dev_warn(smu->adev->dev, "The PMFW version(%x) is behind in this BIOS!\n", smu->smc_fw_version);
smu->smc_driver_if_version = SMU14_DRIVER_IF_VERSION_SMU_V14_0_0;
break;
default:
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c
index c36fc10b63c8..03b38c3a9968 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c
@@ -156,15 +156,10 @@ static int smu_v14_0_0_init_smc_tables(struct smu_context *smu)
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
SMU_TABLE_INIT(tables, SMU_TABLE_DPMCLOCKS, sizeof(DpmClocks_t),
PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
- if (smu->smc_fw_version > 0x5d3500) {
- SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t),
- PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
- smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL);
- } else {
- SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_legacy_t),
- PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
- smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_legacy_t), GFP_KERNEL);
- }
+ SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t),
+ PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
+
+ smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL);
if (!smu_table->metrics_table)
goto err0_out;
smu_table->metrics_time = 0;
@@ -177,10 +172,7 @@ static int smu_v14_0_0_init_smc_tables(struct smu_context *smu)
if (!smu_table->watermarks_table)
goto err2_out;
- if (smu->smc_fw_version > 0x5d3500)
- smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v3_0);
- else
- smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v2_1);
+ smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v3_0);
smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL);
if (!smu_table->gpu_metrics_table)
goto err3_out;
@@ -242,13 +234,13 @@ static int smu_v14_0_0_get_smu_metrics_data(struct smu_context *smu,
switch (member) {
case METRICS_AVERAGE_GFXCLK:
- *value = metrics->AverageGfxclkFrequency;
+ *value = metrics->GfxclkFrequency;
break;
case METRICS_AVERAGE_SOCCLK:
- *value = metrics->AverageSocclkFrequency;
+ *value = metrics->SocclkFrequency;
break;
case METRICS_AVERAGE_VCLK:
- *value = metrics->AverageVclkFrequency;
+ *value = metrics->VclkFrequency;
break;
case METRICS_AVERAGE_DCLK:
*value = 0;
@@ -257,25 +249,25 @@ static int smu_v14_0_0_get_smu_metrics_data(struct smu_context *smu,
*value = 0;
break;
case METRICS_AVERAGE_FCLK:
- *value = metrics->AverageFclkFrequency;
+ *value = metrics->FclkFrequency;
break;
case METRICS_AVERAGE_GFXACTIVITY:
- *value = metrics->AverageGfxActivity >> 8;
+ *value = metrics->GfxActivity / 100;
break;
case METRICS_AVERAGE_VCNACTIVITY:
- *value = metrics->AverageVcnActivity >> 8;
+ *value = metrics->VcnActivity / 100;
break;
case METRICS_AVERAGE_SOCKETPOWER:
case METRICS_CURR_SOCKETPOWER:
- *value = (metrics->AverageSocketPower & 0xff00) +
- ((metrics->AverageSocketPower & 0xff) * 100 >> 8);
+ *value = (metrics->SocketPower / 1000 << 8) +
+ (metrics->SocketPower % 1000 / 10);
break;
case METRICS_TEMPERATURE_EDGE:
- *value = (metrics->GfxTemperature >> 8) *
+ *value = metrics->GfxTemperature / 100 *
SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
break;
case METRICS_TEMPERATURE_HOTSPOT:
- *value = (metrics->SocTemperature >> 8) *
+ *value = metrics->SocTemperature / 100 *
SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
break;
case METRICS_THROTTLER_STATUS:
@@ -317,107 +309,6 @@ static int smu_v14_0_0_get_smu_metrics_data(struct smu_context *smu,
return ret;
}
-static int smu_v14_0_0_legacy_get_smu_metrics_data(struct smu_context *smu,
- MetricsMember_t member,
- uint32_t *value)
-{
- struct smu_table_context *smu_table = &smu->smu_table;
-
- SmuMetrics_legacy_t *metrics = (SmuMetrics_legacy_t *)smu_table->metrics_table;
- int ret = 0;
-
- ret = smu_cmn_get_metrics_table(smu, NULL, false);
- if (ret)
- return ret;
-
- switch (member) {
- case METRICS_AVERAGE_GFXCLK:
- *value = metrics->GfxclkFrequency;
- break;
- case METRICS_AVERAGE_SOCCLK:
- *value = metrics->SocclkFrequency;
- break;
- case METRICS_AVERAGE_VCLK:
- *value = metrics->VclkFrequency;
- break;
- case METRICS_AVERAGE_DCLK:
- *value = metrics->DclkFrequency;
- break;
- case METRICS_AVERAGE_UCLK:
- *value = metrics->MemclkFrequency;
- break;
- case METRICS_AVERAGE_GFXACTIVITY:
- *value = metrics->GfxActivity / 100;
- break;
- case METRICS_AVERAGE_FCLK:
- *value = metrics->AverageFclkFrequency;
- break;
- case METRICS_AVERAGE_VCNACTIVITY:
- *value = metrics->UvdActivity;
- break;
- case METRICS_AVERAGE_SOCKETPOWER:
- *value = (metrics->AverageSocketPower << 8) / 1000;
- break;
- case METRICS_CURR_SOCKETPOWER:
- *value = (metrics->CurrentSocketPower << 8) / 1000;
- break;
- case METRICS_TEMPERATURE_EDGE:
- *value = metrics->GfxTemperature / 100 *
- SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
- break;
- case METRICS_TEMPERATURE_HOTSPOT:
- *value = metrics->SocTemperature / 100 *
- SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
- break;
- case METRICS_THROTTLER_STATUS:
- *value = metrics->ThrottlerStatus;
- break;
- case METRICS_VOLTAGE_VDDGFX:
- *value = metrics->Voltage[0];
- break;
- case METRICS_VOLTAGE_VDDSOC:
- *value = metrics->Voltage[1];
- break;
- case METRICS_SS_APU_SHARE:
- /* return the percentage of APU power with respect to APU's power limit.
- * percentage is reported, this isn't boost value. Smartshift power
- * boost/shift is only when the percentage is more than 100.
- */
- if (metrics->StapmOpnLimit > 0)
- *value = (metrics->ApuPower * 100) / metrics->StapmOpnLimit;
- else
- *value = 0;
- break;
- case METRICS_SS_DGPU_SHARE:
- /* return the percentage of dGPU power with respect to dGPU's power limit.
- * percentage is reported, this isn't boost value. Smartshift power
- * boost/shift is only when the percentage is more than 100.
- */
- if ((metrics->dGpuPower > 0) &&
- (metrics->StapmCurrentLimit > metrics->StapmOpnLimit))
- *value = (metrics->dGpuPower * 100) /
- (metrics->StapmCurrentLimit - metrics->StapmOpnLimit);
- else
- *value = 0;
- break;
- default:
- *value = UINT_MAX;
- break;
- }
-
- return ret;
-}
-
-static int smu_v14_0_0_common_get_smu_metrics_data(struct smu_context *smu,
- MetricsMember_t member,
- uint32_t *value)
-{
- if (smu->smc_fw_version > 0x5d3500)
- return smu_v14_0_0_get_smu_metrics_data(smu, member, value);
- else
- return smu_v14_0_0_legacy_get_smu_metrics_data(smu, member, value);
-}
-
static int smu_v14_0_0_read_sensor(struct smu_context *smu,
enum amd_pp_sensors sensor,
void *data, uint32_t *size)
@@ -429,69 +320,69 @@ static int smu_v14_0_0_read_sensor(struct smu_context *smu,
switch (sensor) {
case AMDGPU_PP_SENSOR_GPU_LOAD:
- ret = smu_v14_0_0_common_get_smu_metrics_data(smu,
+ ret = smu_v14_0_0_get_smu_metrics_data(smu,
METRICS_AVERAGE_GFXACTIVITY,
(uint32_t *)data);
*size = 4;
break;
case AMDGPU_PP_SENSOR_GPU_AVG_POWER:
- ret = smu_v14_0_0_common_get_smu_metrics_data(smu,
+ ret = smu_v14_0_0_get_smu_metrics_data(smu,
METRICS_AVERAGE_SOCKETPOWER,
(uint32_t *)data);
*size = 4;
break;
case AMDGPU_PP_SENSOR_GPU_INPUT_POWER:
- ret = smu_v14_0_0_common_get_smu_metrics_data(smu,
+ ret = smu_v14_0_0_get_smu_metrics_data(smu,
METRICS_CURR_SOCKETPOWER,
(uint32_t *)data);
*size = 4;
break;
case AMDGPU_PP_SENSOR_EDGE_TEMP:
- ret = smu_v14_0_0_common_get_smu_metrics_data(smu,
+ ret = smu_v14_0_0_get_smu_metrics_data(smu,
METRICS_TEMPERATURE_EDGE,
(uint32_t *)data);
*size = 4;
break;
case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
- ret = smu_v14_0_0_common_get_smu_metrics_data(smu,
+ ret = smu_v14_0_0_get_smu_metrics_data(smu,
METRICS_TEMPERATURE_HOTSPOT,
(uint32_t *)data);
*size = 4;
break;
case AMDGPU_PP_SENSOR_GFX_MCLK:
- ret = smu_v14_0_0_common_get_smu_metrics_data(smu,
+ ret = smu_v14_0_0_get_smu_metrics_data(smu,
METRICS_AVERAGE_UCLK,
(uint32_t *)data);
*(uint32_t *)data *= 100;
*size = 4;
break;
case AMDGPU_PP_SENSOR_GFX_SCLK:
- ret = smu_v14_0_0_common_get_smu_metrics_data(smu,
+ ret = smu_v14_0_0_get_smu_metrics_data(smu,
METRICS_AVERAGE_GFXCLK,
(uint32_t *)data);
*(uint32_t *)data *= 100;
*size = 4;
break;
case AMDGPU_PP_SENSOR_VDDGFX:
- ret = smu_v14_0_0_common_get_smu_metrics_data(smu,
+ ret = smu_v14_0_0_get_smu_metrics_data(smu,
METRICS_VOLTAGE_VDDGFX,
(uint32_t *)data);
*size = 4;
break;
case AMDGPU_PP_SENSOR_VDDNB:
- ret = smu_v14_0_0_common_get_smu_metrics_data(smu,
+ ret = smu_v14_0_0_get_smu_metrics_data(smu,
METRICS_VOLTAGE_VDDSOC,
(uint32_t *)data);
*size = 4;
break;
case AMDGPU_PP_SENSOR_SS_APU_SHARE:
- ret = smu_v14_0_0_common_get_smu_metrics_data(smu,
+ ret = smu_v14_0_0_get_smu_metrics_data(smu,
METRICS_SS_APU_SHARE,
(uint32_t *)data);
*size = 4;
break;
case AMDGPU_PP_SENSOR_SS_DGPU_SHARE:
- ret = smu_v14_0_0_common_get_smu_metrics_data(smu,
+ ret = smu_v14_0_0_get_smu_metrics_data(smu,
METRICS_SS_DGPU_SHARE,
(uint32_t *)data);
*size = 4;
@@ -588,7 +479,7 @@ static ssize_t smu_v14_0_0_get_gpu_metrics(struct smu_context *smu,
if (ret)
return ret;
- smu_cmn_init_soft_gpu_metrics(gpu_metrics, 2, 1);
+ smu_cmn_init_soft_gpu_metrics(gpu_metrics, 3, 0);
gpu_metrics->temperature_gfx = metrics.GfxTemperature;
gpu_metrics->temperature_soc = metrics.SocTemperature;
@@ -597,32 +488,33 @@ static ssize_t smu_v14_0_0_get_gpu_metrics(struct smu_context *smu,
sizeof(uint16_t) * 16);
gpu_metrics->temperature_skin = metrics.SkinTemp;
- gpu_metrics->average_gfx_activity = metrics.AverageGfxActivity;
- gpu_metrics->average_vcn_activity = metrics.AverageVcnActivity;
+ gpu_metrics->average_gfx_activity = metrics.GfxActivity;
+ gpu_metrics->average_vcn_activity = metrics.VcnActivity;
memcpy(&gpu_metrics->average_ipu_activity[0],
- &metrics.AverageIpuBusy[0],
+ &metrics.IpuBusy[0],
sizeof(uint16_t) * 8);
memcpy(&gpu_metrics->average_core_c0_activity[0],
- &metrics.AverageCoreC0Residency[0],
+ &metrics.CoreC0Residency[0],
sizeof(uint16_t) * 16);
- gpu_metrics->average_dram_reads = metrics.AverageDRAMReads;
- gpu_metrics->average_dram_writes = metrics.AverageDRAMWrites;
+ gpu_metrics->average_dram_reads = metrics.DRAMReads;
+ gpu_metrics->average_dram_writes = metrics.DRAMWrites;
- gpu_metrics->average_socket_power = metrics.AverageSocketPower;
+ gpu_metrics->average_socket_power = metrics.SocketPower;
gpu_metrics->average_ipu_power = metrics.IpuPower;
gpu_metrics->average_apu_power = metrics.ApuPower;
+ gpu_metrics->average_gfx_power = metrics.GfxPower;
gpu_metrics->average_dgpu_power = metrics.dGpuPower;
- gpu_metrics->average_core_power = metrics.AverageCorePower;
- memcpy(&gpu_metrics->core_power[0],
+ gpu_metrics->average_all_core_power = metrics.AllCorePower;
+ memcpy(&gpu_metrics->average_core_power[0],
&metrics.CorePower[0],
sizeof(uint16_t) * 16);
- gpu_metrics->average_gfxclk_frequency = metrics.AverageGfxclkFrequency;
- gpu_metrics->average_socclk_frequency = metrics.AverageSocclkFrequency;
- gpu_metrics->average_vpeclk_frequency = metrics.AverageVpeclkFrequency;
- gpu_metrics->average_fclk_frequency = metrics.AverageFclkFrequency;
- gpu_metrics->average_vclk_frequency = metrics.AverageVclkFrequency;
- gpu_metrics->average_ipuclk_frequency = metrics.AverageIpuclkFrequency;
+ gpu_metrics->average_gfxclk_frequency = metrics.GfxclkFrequency;
+ gpu_metrics->average_socclk_frequency = metrics.SocclkFrequency;
+ gpu_metrics->average_vpeclk_frequency = metrics.VpeclkFrequency;
+ gpu_metrics->average_fclk_frequency = metrics.FclkFrequency;
+ gpu_metrics->average_vclk_frequency = metrics.VclkFrequency;
+ gpu_metrics->average_ipuclk_frequency = metrics.IpuclkFrequency;
memcpy(&gpu_metrics->current_coreclk[0],
&metrics.CoreFrequency[0],
@@ -638,68 +530,6 @@ static ssize_t smu_v14_0_0_get_gpu_metrics(struct smu_context *smu,
return sizeof(struct gpu_metrics_v3_0);
}
-static ssize_t smu_v14_0_0_get_legacy_gpu_metrics(struct smu_context *smu,
- void **table)
-{
- struct smu_table_context *smu_table = &smu->smu_table;
- struct gpu_metrics_v2_1 *gpu_metrics =
- (struct gpu_metrics_v2_1 *)smu_table->gpu_metrics_table;
- SmuMetrics_legacy_t metrics;
- int ret = 0;
-
- ret = smu_cmn_get_metrics_table(smu, &metrics, true);
- if (ret)
- return ret;
-
- smu_cmn_init_soft_gpu_metrics(gpu_metrics, 2, 1);
-
- gpu_metrics->temperature_gfx = metrics.GfxTemperature;
- gpu_metrics->temperature_soc = metrics.SocTemperature;
- memcpy(&gpu_metrics->temperature_core[0],
- &metrics.CoreTemperature[0],
- sizeof(uint16_t) * 8);
- gpu_metrics->temperature_l3[0] = metrics.L3Temperature[0];
- gpu_metrics->temperature_l3[1] = metrics.L3Temperature[1];
-
- gpu_metrics->average_gfx_activity = metrics.GfxActivity;
- gpu_metrics->average_mm_activity = metrics.UvdActivity;
-
- gpu_metrics->average_socket_power = metrics.CurrentSocketPower;
- gpu_metrics->average_gfx_power = metrics.Power[0];
- gpu_metrics->average_soc_power = metrics.Power[1];
- memcpy(&gpu_metrics->average_core_power[0],
- &metrics.CorePower[0],
- sizeof(uint16_t) * 8);
-
- gpu_metrics->average_gfxclk_frequency = metrics.GfxclkFrequency;
- gpu_metrics->average_socclk_frequency = metrics.SocclkFrequency;
- gpu_metrics->average_uclk_frequency = metrics.MemclkFrequency;
- gpu_metrics->average_fclk_frequency = metrics.MemclkFrequency;
- gpu_metrics->average_vclk_frequency = metrics.VclkFrequency;
- gpu_metrics->average_dclk_frequency = metrics.DclkFrequency;
-
- memcpy(&gpu_metrics->current_coreclk[0],
- &metrics.CoreFrequency[0],
- sizeof(uint16_t) * 8);
-
- gpu_metrics->throttle_status = metrics.ThrottlerStatus;
- gpu_metrics->system_clock_counter = ktime_get_boottime_ns();
-
- *table = (void *)gpu_metrics;
-
- return sizeof(struct gpu_metrics_v2_1);
-}
-
-static ssize_t smu_v14_0_0_common_get_gpu_metrics(struct smu_context *smu,
- void **table)
-{
-
- if (smu->smc_fw_version > 0x5d3500)
- return smu_v14_0_0_get_gpu_metrics(smu, table);
- else
- return smu_v14_0_0_get_legacy_gpu_metrics(smu, table);
-}
-
static int smu_v14_0_0_mode2_reset(struct smu_context *smu)
{
int ret;
@@ -928,7 +758,7 @@ static int smu_v14_0_0_get_current_clk_freq(struct smu_context *smu,
return -EINVAL;
}
- return smu_v14_0_0_common_get_smu_metrics_data(smu, member_type, value);
+ return smu_v14_0_0_get_smu_metrics_data(smu, member_type, value);
}
static int smu_v14_0_0_get_dpm_level_count(struct smu_context *smu,
@@ -1230,7 +1060,7 @@ static const struct pptable_funcs smu_v14_0_0_ppt_funcs = {
.read_sensor = smu_v14_0_0_read_sensor,
.is_dpm_running = smu_v14_0_0_is_dpm_running,
.set_watermarks_table = smu_v14_0_0_set_watermarks_table,
- .get_gpu_metrics = smu_v14_0_0_common_get_gpu_metrics,
+ .get_gpu_metrics = smu_v14_0_0_get_gpu_metrics,
.get_enabled_mask = smu_cmn_get_enabled_mask,
.get_pp_feature_mask = smu_cmn_get_pp_feature_mask,
.set_driver_table_location = smu_v14_0_set_driver_table_location,
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
index 6e57c94379a9..001a5cf09657 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
@@ -1004,6 +1004,9 @@ void smu_cmn_init_soft_gpu_metrics(void *table, uint8_t frev, uint8_t crev)
case METRICS_VERSION(2, 4):
structure_size = sizeof(struct gpu_metrics_v2_4);
break;
+ case METRICS_VERSION(3, 0):
+ structure_size = sizeof(struct gpu_metrics_v3_0);
+ break;
default:
return;
}
diff --git a/drivers/gpu/drm/ast/ast_dp.c b/drivers/gpu/drm/ast/ast_dp.c
index fdd9a493aa9c..ebb6d8ebd44e 100644
--- a/drivers/gpu/drm/ast/ast_dp.c
+++ b/drivers/gpu/drm/ast/ast_dp.c
@@ -9,11 +9,11 @@
bool ast_astdp_is_connected(struct ast_device *ast)
{
- if (!ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, ASTDP_MCU_FW_EXECUTING))
+ if (!ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1, ASTDP_MCU_FW_EXECUTING))
return false;
- if (!ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD))
+ if (!ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, ASTDP_HPD))
return false;
- if (!ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC, ASTDP_LINK_SUCCESS))
+ if (!ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDC, ASTDP_LINK_SUCCESS))
return false;
return true;
}
@@ -29,22 +29,22 @@ int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata)
* CRDF[b0]: DP HPD
* CRE5[b0]: Host reading EDID process is done
*/
- if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, ASTDP_MCU_FW_EXECUTING) &&
- ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC, ASTDP_LINK_SUCCESS) &&
- ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD) &&
- ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5,
+ if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1, ASTDP_MCU_FW_EXECUTING) &&
+ ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDC, ASTDP_LINK_SUCCESS) &&
+ ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, ASTDP_HPD) &&
+ ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xE5,
ASTDP_HOST_EDID_READ_DONE_MASK))) {
goto err_astdp_edid_not_ready;
}
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK,
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK,
0x00);
for (i = 0; i < 32; i++) {
/*
* CRE4[7:0]: Read-Pointer for EDID (Unit: 4bytes); valid range: 0~64
*/
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE4,
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE4,
ASTDP_AND_CLEAR_MASK, (u8)i);
j = 0;
@@ -52,9 +52,9 @@ int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata)
* CRD7[b0]: valid flag for EDID
* CRD6[b0]: mirror read pointer for EDID
*/
- while ((ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD7,
+ while ((ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD7,
ASTDP_EDID_VALID_FLAG_MASK) != 0x01) ||
- (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD6,
+ (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD6,
ASTDP_EDID_READ_POINTER_MASK) != i)) {
/*
* Delay are getting longer with each retry.
@@ -64,11 +64,11 @@ int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata)
*/
mdelay(j+1);
- if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1,
+ if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1,
ASTDP_MCU_FW_EXECUTING) &&
- ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC,
+ ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDC,
ASTDP_LINK_SUCCESS) &&
- ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD))) {
+ ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, ASTDP_HPD))) {
goto err_astdp_jump_out_loop_of_edid;
}
@@ -77,13 +77,13 @@ int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata)
goto err_astdp_jump_out_loop_of_edid;
}
- *(ediddata) = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT,
+ *(ediddata) = ast_get_index_reg_mask(ast, AST_IO_VGACRI,
0xD8, ASTDP_EDID_READ_DATA_MASK);
- *(ediddata + 1) = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD9,
+ *(ediddata + 1) = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD9,
ASTDP_EDID_READ_DATA_MASK);
- *(ediddata + 2) = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDA,
+ *(ediddata + 2) = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDA,
ASTDP_EDID_READ_DATA_MASK);
- *(ediddata + 3) = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDB,
+ *(ediddata + 3) = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDB,
ASTDP_EDID_READ_DATA_MASK);
if (i == 31) {
@@ -103,25 +103,25 @@ int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata)
ediddata += 4;
}
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK,
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK,
ASTDP_HOST_EDID_READ_DONE);
return 0;
err_astdp_jump_out_loop_of_edid:
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5,
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE5,
(u8) ~ASTDP_HOST_EDID_READ_DONE_MASK,
ASTDP_HOST_EDID_READ_DONE);
return (~(j+256) + 1);
err_astdp_edid_not_ready:
- if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, ASTDP_MCU_FW_EXECUTING)))
+ if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1, ASTDP_MCU_FW_EXECUTING)))
return (~0xD1 + 1);
- if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC, ASTDP_LINK_SUCCESS)))
+ if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDC, ASTDP_LINK_SUCCESS)))
return (~0xDC + 1);
- if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD)))
+ if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, ASTDP_HPD)))
return (~0xDF + 1);
- if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, ASTDP_HOST_EDID_READ_DONE_MASK)))
+ if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xE5, ASTDP_HOST_EDID_READ_DONE_MASK)))
return (~0xE5 + 1);
return 0;
@@ -137,7 +137,7 @@ void ast_dp_launch(struct drm_device *dev)
struct ast_device *ast = to_ast_device(dev);
// Wait one second then timeout.
- while (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, ASTDP_MCU_FW_EXECUTING) !=
+ while (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1, ASTDP_MCU_FW_EXECUTING) !=
ASTDP_MCU_FW_EXECUTING) {
i++;
// wait 100 ms
@@ -153,7 +153,7 @@ void ast_dp_launch(struct drm_device *dev)
if (!bDPExecute)
drm_err(dev, "Wait DPMCU executing timeout\n");
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5,
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE5,
(u8) ~ASTDP_HOST_EDID_READ_DONE_MASK,
ASTDP_HOST_EDID_READ_DONE);
}
@@ -164,14 +164,14 @@ void ast_dp_power_on_off(struct drm_device *dev, bool on)
{
struct ast_device *ast = to_ast_device(dev);
// Read and Turn off DP PHY sleep
- u8 bE3 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE3, AST_DP_VIDEO_ENABLE);
+ u8 bE3 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xE3, AST_DP_VIDEO_ENABLE);
// Turn on DP PHY sleep
if (!on)
bE3 |= AST_DP_PHY_SLEEP;
// DP Power on/off
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE3, (u8) ~AST_DP_PHY_SLEEP, bE3);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE3, (u8) ~AST_DP_PHY_SLEEP, bE3);
}
@@ -182,13 +182,13 @@ void ast_dp_set_on_off(struct drm_device *dev, bool on)
u8 video_on_off = on;
// Video On/Off
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE3, (u8) ~AST_DP_VIDEO_ENABLE, on);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE3, (u8) ~AST_DP_VIDEO_ENABLE, on);
// If DP plug in and link successful then check video on / off status
- if (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC, ASTDP_LINK_SUCCESS) &&
- ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD)) {
+ if (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDC, ASTDP_LINK_SUCCESS) &&
+ ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, ASTDP_HPD)) {
video_on_off <<= 4;
- while (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF,
+ while (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF,
ASTDP_MIRROR_VIDEO_ENABLE) != video_on_off) {
// wait 1 ms
mdelay(1);
@@ -264,8 +264,8 @@ void ast_dp_set_mode(struct drm_crtc *crtc, struct ast_vbios_mode_info *vbios_mo
* CRE1[7:0]: MISC1 (default: 0x00)
* CRE2[7:0]: video format index (0x00 ~ 0x20 or 0x40 ~ 0x50)
*/
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE0, ASTDP_AND_CLEAR_MASK,
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE0, ASTDP_AND_CLEAR_MASK,
ASTDP_MISC0_24bpp);
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE1, ASTDP_AND_CLEAR_MASK, ASTDP_MISC1);
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE2, ASTDP_AND_CLEAR_MASK, ModeIdx);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE1, ASTDP_AND_CLEAR_MASK, ASTDP_MISC1);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE2, ASTDP_AND_CLEAR_MASK, ModeIdx);
}
diff --git a/drivers/gpu/drm/ast/ast_dp501.c b/drivers/gpu/drm/ast/ast_dp501.c
index f10d53b0c94f..9a4c3a0963f9 100644
--- a/drivers/gpu/drm/ast/ast_dp501.c
+++ b/drivers/gpu/drm/ast/ast_dp501.c
@@ -31,17 +31,17 @@ static int ast_load_dp501_microcode(struct drm_device *dev)
static void send_ack(struct ast_device *ast)
{
u8 sendack;
- sendack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0xff);
+ sendack = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0x9b, 0xff);
sendack |= 0x80;
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0x00, sendack);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9b, 0x00, sendack);
}
static void send_nack(struct ast_device *ast)
{
u8 sendack;
- sendack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0xff);
+ sendack = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0x9b, 0xff);
sendack &= ~0x80;
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0x00, sendack);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9b, 0x00, sendack);
}
static bool wait_ack(struct ast_device *ast)
@@ -49,7 +49,7 @@ static bool wait_ack(struct ast_device *ast)
u8 waitack;
u32 retry = 0;
do {
- waitack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff);
+ waitack = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd2, 0xff);
waitack &= 0x80;
udelay(100);
} while ((!waitack) && (retry++ < 1000));
@@ -65,7 +65,7 @@ static bool wait_nack(struct ast_device *ast)
u8 waitack;
u32 retry = 0;
do {
- waitack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff);
+ waitack = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd2, 0xff);
waitack &= 0x80;
udelay(100);
} while ((waitack) && (retry++ < 1000));
@@ -78,12 +78,12 @@ static bool wait_nack(struct ast_device *ast)
static void set_cmd_trigger(struct ast_device *ast)
{
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, ~0x40, 0x40);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9b, ~0x40, 0x40);
}
static void clear_cmd_trigger(struct ast_device *ast)
{
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, ~0x40, 0x00);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9b, ~0x40, 0x00);
}
#if 0
@@ -92,7 +92,7 @@ static bool wait_fw_ready(struct ast_device *ast)
u8 waitready;
u32 retry = 0;
do {
- waitready = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff);
+ waitready = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd2, 0xff);
waitready &= 0x40;
udelay(100);
} while ((!waitready) && (retry++ < 1000));
@@ -110,7 +110,7 @@ static bool ast_write_cmd(struct drm_device *dev, u8 data)
int retry = 0;
if (wait_nack(ast)) {
send_nack(ast);
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, data);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9a, 0x00, data);
send_ack(ast);
set_cmd_trigger(ast);
do {
@@ -132,7 +132,7 @@ static bool ast_write_data(struct drm_device *dev, u8 data)
if (wait_nack(ast)) {
send_nack(ast);
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, data);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9a, 0x00, data);
send_ack(ast);
if (wait_ack(ast)) {
send_nack(ast);
@@ -153,7 +153,7 @@ static bool ast_read_data(struct drm_device *dev, u8 *data)
if (wait_ack(ast) == false)
return false;
- tmp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd3, 0xff);
+ tmp = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd3, 0xff);
*data = tmp;
if (wait_nack(ast) == false) {
send_nack(ast);
@@ -166,7 +166,7 @@ static bool ast_read_data(struct drm_device *dev, u8 *data)
static void clear_cmd(struct ast_device *ast)
{
send_nack(ast);
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, 0x00);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9a, 0x00, 0x00);
}
#endif
@@ -265,9 +265,9 @@ static bool ast_launch_m68k(struct drm_device *dev)
data |= 0x800;
ast_moutdwm(ast, 0x1e6e2040, data);
- jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x99, 0xfc); /* D[1:0]: Reserved Video Buffer */
+ jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0x99, 0xfc); /* D[1:0]: Reserved Video Buffer */
jreg |= 0x02;
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x99, jreg);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0x99, jreg);
}
return true;
}
@@ -354,7 +354,7 @@ static bool ast_init_dvo(struct drm_device *dev)
ast_write32(ast, 0xf000, 0x1);
ast_write32(ast, 0x12000, 0x1688a8a8);
- jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
+ jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
if (!(jreg & 0x80)) {
/* Init SCU DVO Settings */
data = ast_read32(ast, 0x12008);
@@ -413,7 +413,7 @@ static bool ast_init_dvo(struct drm_device *dev)
ast_write32(ast, 0x1202c, data);
/* Init VGA DVO Settings */
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x80);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x80);
return true;
}
@@ -442,7 +442,7 @@ static void ast_init_analog(struct drm_device *dev)
ast_write32(ast, 0, data);
/* Disable DVO */
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x00);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x00);
}
void ast_init_3rdtx(struct drm_device *dev)
@@ -451,7 +451,7 @@ void ast_init_3rdtx(struct drm_device *dev)
u8 jreg;
if (IS_AST_GEN4(ast) || IS_AST_GEN5(ast)) {
- jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
+ jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, 0xff);
switch (jreg & 0x0e) {
case 0x04:
ast_init_dvo(dev);
diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index 848a9f1403e8..2aee32344f4a 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -39,6 +39,8 @@
#include <drm/drm_mode.h>
#include <drm/drm_framebuffer.h>
+#include "ast_reg.h"
+
#define DRIVER_AUTHOR "Dave Airlie"
#define DRIVER_NAME "ast"
@@ -259,25 +261,6 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen)
#define IS_AST_GEN6(__ast) __ast_gen_is_eq(__ast, 6)
#define IS_AST_GEN7(__ast) __ast_gen_is_eq(__ast, 7)
-#define AST_IO_AR_PORT_WRITE (0x40)
-#define AST_IO_MISC_PORT_WRITE (0x42)
-#define AST_IO_VGA_ENABLE_PORT (0x43)
-#define AST_IO_SEQ_PORT (0x44)
-#define AST_IO_DAC_INDEX_READ (0x47)
-#define AST_IO_DAC_INDEX_WRITE (0x48)
-#define AST_IO_DAC_DATA (0x49)
-#define AST_IO_GR_PORT (0x4E)
-#define AST_IO_CRTC_PORT (0x54)
-#define AST_IO_INPUT_STATUS1_READ (0x5A)
-#define AST_IO_MISC_PORT_READ (0x4C)
-
-#define AST_IO_MM_OFFSET (0x380)
-
-#define AST_IO_VGAIR1_VREFRESH BIT(3)
-
-#define AST_IO_VGACRCB_HWC_ENABLED BIT(1)
-#define AST_IO_VGACRCB_HWC_16BPP BIT(0) /* set: ARGB4444, cleared: 2bpp palette */
-
static inline u32 ast_read32(struct ast_device *ast, u32 reg)
{
return ioread32(ast->regs + reg);
@@ -399,72 +382,10 @@ int ast_mode_config_init(struct ast_device *ast);
#define AST_DP501_LINKRATE 0xf014
#define AST_DP501_EDID_DATA 0xf020
-/*
- * Display Transmitter Type:
- */
-#define TX_TYPE_MASK GENMASK(3, 1)
-#define NO_TX (0 << 1)
-#define ITE66121_VBIOS_TX (1 << 1)
-#define SI164_VBIOS_TX (2 << 1)
-#define CH7003_VBIOS_TX (3 << 1)
-#define DP501_VBIOS_TX (4 << 1)
-#define ANX9807_VBIOS_TX (5 << 1)
-#define TX_FW_EMBEDDED_FW_TX (6 << 1)
-#define ASTDP_DPMCU_TX (7 << 1)
-
-#define AST_VRAM_INIT_STATUS_MASK GENMASK(7, 6)
-//#define AST_VRAM_INIT_BY_BMC BIT(7)
-//#define AST_VRAM_INIT_READY BIT(6)
-
-/* Define for Soc scratched reg used on ASTDP */
-#define AST_DP_PHY_SLEEP BIT(4)
-#define AST_DP_VIDEO_ENABLE BIT(0)
-
#define AST_DP_POWER_ON true
#define AST_DP_POWER_OFF false
/*
- * CRD1[b5]: DP MCU FW is executing
- * CRDC[b0]: DP link success
- * CRDF[b0]: DP HPD
- * CRE5[b0]: Host reading EDID process is done
- */
-#define ASTDP_MCU_FW_EXECUTING BIT(5)
-#define ASTDP_LINK_SUCCESS BIT(0)
-#define ASTDP_HPD BIT(0)
-#define ASTDP_HOST_EDID_READ_DONE BIT(0)
-#define ASTDP_HOST_EDID_READ_DONE_MASK GENMASK(0, 0)
-
-/*
- * CRB8[b1]: Enable VSYNC off
- * CRB8[b0]: Enable HSYNC off
- */
-#define AST_DPMS_VSYNC_OFF BIT(1)
-#define AST_DPMS_HSYNC_OFF BIT(0)
-
-/*
- * CRDF[b4]: Mirror of AST_DP_VIDEO_ENABLE
- * Precondition: A. ~AST_DP_PHY_SLEEP &&
- * B. DP_HPD &&
- * C. DP_LINK_SUCCESS
- */
-#define ASTDP_MIRROR_VIDEO_ENABLE BIT(4)
-
-#define ASTDP_EDID_READ_POINTER_MASK GENMASK(7, 0)
-#define ASTDP_EDID_VALID_FLAG_MASK GENMASK(0, 0)
-#define ASTDP_EDID_READ_DATA_MASK GENMASK(7, 0)
-
-/*
- * ASTDP setmode registers:
- * CRE0[7:0]: MISC0 ((0x00: 18-bpp) or (0x20: 24-bpp)
- * CRE1[7:0]: MISC1 (default: 0x00)
- * CRE2[7:0]: video format index (0x00 ~ 0x20 or 0x40 ~ 0x50)
- */
-#define ASTDP_MISC0_24bpp BIT(5)
-#define ASTDP_MISC1 0
-#define ASTDP_AND_CLEAR_MASK 0x00
-
-/*
* ASTDP resoultion table:
* EX: ASTDP_A_B_C:
* A: Resolution
diff --git a/drivers/gpu/drm/ast/ast_i2c.c b/drivers/gpu/drm/ast/ast_i2c.c
index d64045c0b849..0e845e7acd9b 100644
--- a/drivers/gpu/drm/ast/ast_i2c.c
+++ b/drivers/gpu/drm/ast/ast_i2c.c
@@ -35,8 +35,8 @@ static void ast_i2c_setsda(void *i2c_priv, int data)
for (i = 0; i < 0x10000; i++) {
ujcrb7 = ((data & 0x01) ? 0 : 1) << 2;
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf1, ujcrb7);
- jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x04);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0xf1, ujcrb7);
+ jtemp = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x04);
if (ujcrb7 == jtemp)
break;
}
@@ -51,8 +51,8 @@ static void ast_i2c_setscl(void *i2c_priv, int clock)
for (i = 0; i < 0x10000; i++) {
ujcrb7 = ((clock & 0x01) ? 0 : 1);
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf4, ujcrb7);
- jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x01);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0xf4, ujcrb7);
+ jtemp = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x01);
if (ujcrb7 == jtemp)
break;
}
@@ -66,14 +66,14 @@ static int ast_i2c_getsda(void *i2c_priv)
count = 0;
pass = 0;
- val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
+ val = (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x20) >> 5) & 0x01;
do {
- val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
+ val2 = (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x20) >> 5) & 0x01;
if (val == val2) {
pass++;
} else {
pass = 0;
- val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
+ val = (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x20) >> 5) & 0x01;
}
} while ((pass < 5) && (count++ < 0x10000));
@@ -88,14 +88,14 @@ static int ast_i2c_getscl(void *i2c_priv)
count = 0;
pass = 0;
- val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
+ val = (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x10) >> 4) & 0x01;
do {
- val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
+ val2 = (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x10) >> 4) & 0x01;
if (val == val2) {
pass++;
} else {
pass = 0;
- val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
+ val = (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x10) >> 4) & 0x01;
}
} while ((pass < 5) && (count++ < 0x10000));
diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
index dae365ed3969..f4ab40e22cea 100644
--- a/drivers/gpu/drm/ast/ast_main.c
+++ b/drivers/gpu/drm/ast/ast_main.c
@@ -40,7 +40,7 @@ static bool ast_is_vga_enabled(struct drm_device *dev)
struct ast_device *ast = to_ast_device(dev);
u8 ch;
- ch = ast_io_read8(ast, AST_IO_VGA_ENABLE_PORT);
+ ch = ast_io_read8(ast, AST_IO_VGAER);
return !!(ch & 0x01);
}
@@ -49,8 +49,8 @@ static void ast_enable_vga(struct drm_device *dev)
{
struct ast_device *ast = to_ast_device(dev);
- ast_io_write8(ast, AST_IO_VGA_ENABLE_PORT, 0x01);
- ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, 0x01);
+ ast_io_write8(ast, AST_IO_VGAER, 0x01);
+ ast_io_write8(ast, AST_IO_VGAMR_W, 0x01);
}
/*
@@ -62,21 +62,21 @@ static void ast_enable_mmio_release(void *data)
struct ast_device *ast = data;
/* enable standard VGA decode */
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x04);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0xa1, 0x04);
}
static int ast_enable_mmio(struct ast_device *ast)
{
struct drm_device *dev = &ast->base;
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0xa1, 0x06);
return devm_add_action_or_reset(dev->dev, ast_enable_mmio_release, ast);
}
static void ast_open_key(struct ast_device *ast)
{
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x80, 0xA8);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0x80, 0xA8);
}
static int ast_device_config_init(struct ast_device *ast)
@@ -105,8 +105,8 @@ static int ast_device_config_init(struct ast_device *ast)
* is disabled. We force using P2A if VGA only mode bit
* is set D[7]
*/
- jregd0 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
- jregd1 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
+ jregd0 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
+ jregd1 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, 0xff);
if (!(jregd0 & 0x80) || !(jregd1 & 0x10)) {
/*
@@ -219,7 +219,7 @@ static void ast_detect_widescreen(struct ast_device *ast)
ast->support_wide_screen = false;
break;
default:
- jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
+ jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
if (!(jreg & 0x80))
ast->support_wide_screen = true;
else if (jreg & 0x01)
@@ -256,7 +256,7 @@ static void ast_detect_tx_chip(struct ast_device *ast, bool need_post)
* SIL164 when there is none.
*/
if (!need_post) {
- jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xff);
+ jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xff);
if (jreg & 0x80)
ast->tx_chip_types = AST_TX_SIL164_BIT;
}
@@ -267,7 +267,7 @@ static void ast_detect_tx_chip(struct ast_device *ast, bool need_post)
* the SOC scratch register #1 bits 11:8 (interestingly marked
* as "reserved" in the spec)
*/
- jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
+ jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, 0xff);
switch (jreg) {
case 0x04:
ast->tx_chip_types = AST_TX_SIL164_BIT;
@@ -286,7 +286,7 @@ static void ast_detect_tx_chip(struct ast_device *ast, bool need_post)
ast->tx_chip_types = AST_TX_DP501_BIT;
}
} else if (IS_AST_GEN7(ast)) {
- if (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, TX_TYPE_MASK) ==
+ if (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1, TX_TYPE_MASK) ==
ASTDP_DPMCU_TX) {
ast->tx_chip_types = AST_TX_ASTDP_BIT;
ast_dp_launch(&ast->base);
diff --git a/drivers/gpu/drm/ast/ast_mm.c b/drivers/gpu/drm/ast/ast_mm.c
index bc174bd933b9..6dfe6d9777d4 100644
--- a/drivers/gpu/drm/ast/ast_mm.c
+++ b/drivers/gpu/drm/ast/ast_mm.c
@@ -39,7 +39,7 @@ static u32 ast_get_vram_size(struct ast_device *ast)
u32 vram_size;
vram_size = AST_VIDMEM_DEFAULT_SIZE;
- jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xaa, 0xff);
+ jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xaa, 0xff);
switch (jreg & 3) {
case 0:
vram_size = AST_VIDMEM_SIZE_8M;
@@ -55,7 +55,7 @@ static u32 ast_get_vram_size(struct ast_device *ast)
break;
}
- jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x99, 0xff);
+ jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0x99, 0xff);
switch (jreg & 0x03) {
case 1:
vram_size -= 0x100000;
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index 32f04ec6c386..cb9614984285 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -55,14 +55,14 @@ static inline void ast_load_palette_index(struct ast_device *ast,
u8 index, u8 red, u8 green,
u8 blue)
{
- ast_io_write8(ast, AST_IO_DAC_INDEX_WRITE, index);
- ast_io_read8(ast, AST_IO_SEQ_PORT);
- ast_io_write8(ast, AST_IO_DAC_DATA, red);
- ast_io_read8(ast, AST_IO_SEQ_PORT);
- ast_io_write8(ast, AST_IO_DAC_DATA, green);
- ast_io_read8(ast, AST_IO_SEQ_PORT);
- ast_io_write8(ast, AST_IO_DAC_DATA, blue);
- ast_io_read8(ast, AST_IO_SEQ_PORT);
+ ast_io_write8(ast, AST_IO_VGADWR, index);
+ ast_io_read8(ast, AST_IO_VGASRI);
+ ast_io_write8(ast, AST_IO_VGAPDR, red);
+ ast_io_read8(ast, AST_IO_VGASRI);
+ ast_io_write8(ast, AST_IO_VGAPDR, green);
+ ast_io_read8(ast, AST_IO_VGASRI);
+ ast_io_write8(ast, AST_IO_VGAPDR, blue);
+ ast_io_read8(ast, AST_IO_VGASRI);
}
static void ast_crtc_set_gamma_linear(struct ast_device *ast,
@@ -253,13 +253,13 @@ static void ast_set_vbios_color_reg(struct ast_device *ast,
return;
}
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8c, (u8)((color_index & 0x0f) << 4));
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0x8c, (u8)((color_index & 0x0f) << 4));
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0x91, 0x00);
if (vbios_mode->enh_table->flags & NewModeInfo) {
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8);
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92, format->cpp[0] * 8);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0x91, 0xa8);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0x92, format->cpp[0] * 8);
}
}
@@ -272,18 +272,18 @@ static void ast_set_vbios_mode_reg(struct ast_device *ast,
refresh_rate_index = vbios_mode->enh_table->refresh_rate_index;
mode_id = vbios_mode->enh_table->mode_id;
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8d, refresh_rate_index & 0xff);
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8e, mode_id & 0xff);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0x8d, refresh_rate_index & 0xff);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0x8e, mode_id & 0xff);
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0x91, 0x00);
if (vbios_mode->enh_table->flags & NewModeInfo) {
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8);
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x93, adjusted_mode->clock / 1000);
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x94, adjusted_mode->crtc_hdisplay);
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x95, adjusted_mode->crtc_hdisplay >> 8);
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x96, adjusted_mode->crtc_vdisplay);
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x97, adjusted_mode->crtc_vdisplay >> 8);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0x91, 0xa8);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0x93, adjusted_mode->clock / 1000);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0x94, adjusted_mode->crtc_hdisplay);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0x95, adjusted_mode->crtc_hdisplay >> 8);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0x96, adjusted_mode->crtc_vdisplay);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0x97, adjusted_mode->crtc_vdisplay >> 8);
}
}
@@ -298,41 +298,41 @@ static void ast_set_std_reg(struct ast_device *ast,
stdtable = vbios_mode->std_table;
jreg = stdtable->misc;
- ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg);
+ ast_io_write8(ast, AST_IO_VGAMR_W, jreg);
/* Set SEQ; except Screen Disable field */
- ast_set_index_reg(ast, AST_IO_SEQ_PORT, 0x00, 0x03);
- ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, stdtable->seq[0]);
+ ast_set_index_reg(ast, AST_IO_VGASRI, 0x00, 0x03);
+ ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, stdtable->seq[0]);
for (i = 1; i < 4; i++) {
jreg = stdtable->seq[i];
- ast_set_index_reg(ast, AST_IO_SEQ_PORT, (i + 1), jreg);
+ ast_set_index_reg(ast, AST_IO_VGASRI, (i + 1), jreg);
}
/* Set CRTC; except base address and offset */
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x11, 0x7f, 0x00);
for (i = 0; i < 12; i++)
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]);
+ ast_set_index_reg(ast, AST_IO_VGACRI, i, stdtable->crtc[i]);
for (i = 14; i < 19; i++)
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]);
+ ast_set_index_reg(ast, AST_IO_VGACRI, i, stdtable->crtc[i]);
for (i = 20; i < 25; i++)
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]);
+ ast_set_index_reg(ast, AST_IO_VGACRI, i, stdtable->crtc[i]);
/* set AR */
- jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ);
+ jreg = ast_io_read8(ast, AST_IO_VGAIR1_R);
for (i = 0; i < 20; i++) {
jreg = stdtable->ar[i];
- ast_io_write8(ast, AST_IO_AR_PORT_WRITE, (u8)i);
- ast_io_write8(ast, AST_IO_AR_PORT_WRITE, jreg);
+ ast_io_write8(ast, AST_IO_VGAARI_W, (u8)i);
+ ast_io_write8(ast, AST_IO_VGAARI_W, jreg);
}
- ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x14);
- ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x00);
+ ast_io_write8(ast, AST_IO_VGAARI_W, 0x14);
+ ast_io_write8(ast, AST_IO_VGAARI_W, 0x00);
- jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ);
- ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x20);
+ jreg = ast_io_read8(ast, AST_IO_VGAIR1_R);
+ ast_io_write8(ast, AST_IO_VGAARI_W, 0x20);
/* Set GR */
for (i = 0; i < 9; i++)
- ast_set_index_reg(ast, AST_IO_GR_PORT, i, stdtable->gr[i]);
+ ast_set_index_reg(ast, AST_IO_VGAGRI, i, stdtable->gr[i]);
}
static void ast_set_crtc_reg(struct ast_device *ast,
@@ -346,48 +346,48 @@ static void ast_set_crtc_reg(struct ast_device *ast,
(vbios_mode->enh_table->flags & AST2500PreCatchCRT))
precache = 40;
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x11, 0x7f, 0x00);
temp = (mode->crtc_htotal >> 3) - 5;
if (temp & 0x100)
jregAC |= 0x01; /* HT D[8] */
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x00, 0x00, temp);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x00, 0x00, temp);
temp = (mode->crtc_hdisplay >> 3) - 1;
if (temp & 0x100)
jregAC |= 0x04; /* HDE D[8] */
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x01, 0x00, temp);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x01, 0x00, temp);
temp = (mode->crtc_hblank_start >> 3) - 1;
if (temp & 0x100)
jregAC |= 0x10; /* HBS D[8] */
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x02, 0x00, temp);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x02, 0x00, temp);
temp = ((mode->crtc_hblank_end >> 3) - 1) & 0x7f;
if (temp & 0x20)
jreg05 |= 0x80; /* HBE D[5] */
if (temp & 0x40)
jregAD |= 0x01; /* HBE D[5] */
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x03, 0xE0, (temp & 0x1f));
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x03, 0xE0, (temp & 0x1f));
temp = ((mode->crtc_hsync_start-precache) >> 3) - 1;
if (temp & 0x100)
jregAC |= 0x40; /* HRS D[5] */
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x04, 0x00, temp);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x04, 0x00, temp);
temp = (((mode->crtc_hsync_end-precache) >> 3) - 1) & 0x3f;
if (temp & 0x20)
jregAD |= 0x04; /* HRE D[5] */
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x05, 0x60, (u8)((temp & 0x1f) | jreg05));
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x05, 0x60, (u8)((temp & 0x1f) | jreg05));
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAC, 0x00, jregAC);
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAD, 0x00, jregAD);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xAC, 0x00, jregAC);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xAD, 0x00, jregAD);
// Workaround for HSync Time non octave pixels (1920x1080@60Hz HSync 44 pixels);
if (IS_AST_GEN7(ast) && (mode->crtc_vdisplay == 1080))
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xFC, 0xFD, 0x02);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xFC, 0xFD, 0x02);
else
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xFC, 0xFD, 0x00);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xFC, 0xFD, 0x00);
/* vert timings */
temp = (mode->crtc_vtotal) - 2;
@@ -397,7 +397,7 @@ static void ast_set_crtc_reg(struct ast_device *ast,
jreg07 |= 0x20;
if (temp & 0x400)
jregAE |= 0x01;
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x06, 0x00, temp);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x06, 0x00, temp);
temp = (mode->crtc_vsync_start) - 1;
if (temp & 0x100)
@@ -406,14 +406,14 @@ static void ast_set_crtc_reg(struct ast_device *ast,
jreg07 |= 0x80;
if (temp & 0x400)
jregAE |= 0x08;
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x10, 0x00, temp);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x10, 0x00, temp);
temp = (mode->crtc_vsync_end - 1) & 0x3f;
if (temp & 0x10)
jregAE |= 0x20;
if (temp & 0x20)
jregAE |= 0x40;
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x70, temp & 0xf);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x11, 0x70, temp & 0xf);
temp = mode->crtc_vdisplay - 1;
if (temp & 0x100)
@@ -422,7 +422,7 @@ static void ast_set_crtc_reg(struct ast_device *ast,
jreg07 |= 0x40;
if (temp & 0x400)
jregAE |= 0x02;
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x12, 0x00, temp);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x12, 0x00, temp);
temp = mode->crtc_vblank_start - 1;
if (temp & 0x100)
@@ -431,23 +431,23 @@ static void ast_set_crtc_reg(struct ast_device *ast,
jreg09 |= 0x20;
if (temp & 0x400)
jregAE |= 0x04;
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x15, 0x00, temp);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x15, 0x00, temp);
temp = mode->crtc_vblank_end - 1;
if (temp & 0x100)
jregAE |= 0x10;
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x16, 0x00, temp);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x16, 0x00, temp);
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x07, 0x00, jreg07);
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x09, 0xdf, jreg09);
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAE, 0x00, (jregAE | 0x80));
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x07, 0x00, jreg07);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x09, 0xdf, jreg09);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xAE, 0x00, (jregAE | 0x80));
if (precache)
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x80);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0x3f, 0x80);
else
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x00);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0x3f, 0x00);
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x80);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x11, 0x7f, 0x80);
}
static void ast_set_offset_reg(struct ast_device *ast,
@@ -456,8 +456,8 @@ static void ast_set_offset_reg(struct ast_device *ast,
u16 offset;
offset = fb->pitches[0] >> 3;
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x13, (offset & 0xff));
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xb0, (offset >> 8) & 0x3f);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0x13, (offset & 0xff));
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0xb0, (offset >> 8) & 0x3f);
}
static void ast_set_dclk_reg(struct ast_device *ast,
@@ -471,9 +471,9 @@ static void ast_set_dclk_reg(struct ast_device *ast,
else
clk_info = &dclk_table[vbios_mode->enh_table->dclk_index];
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc0, 0x00, clk_info->param1);
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc1, 0x00, clk_info->param2);
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xbb, 0x0f,
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xc0, 0x00, clk_info->param1);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xc1, 0x00, clk_info->param2);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xbb, 0x0f,
(clk_info->param3 & 0xc0) |
((clk_info->param3 & 0x3) << 4));
}
@@ -502,26 +502,26 @@ static void ast_set_color_reg(struct ast_device *ast,
break;
}
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa0, 0x8f, jregA0);
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xf0, jregA3);
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa8, 0xfd, jregA8);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa0, 0x8f, jregA0);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xf0, jregA3);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa8, 0xfd, jregA8);
}
static void ast_set_crtthd_reg(struct ast_device *ast)
{
/* Set Threshold */
if (IS_AST_GEN7(ast)) {
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0xe0);
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0xa0);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0xa7, 0xe0);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0xa6, 0xa0);
} else if (IS_AST_GEN6(ast) || IS_AST_GEN5(ast) || IS_AST_GEN4(ast)) {
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x78);
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x60);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0xa7, 0x78);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0xa6, 0x60);
} else if (IS_AST_GEN3(ast) || IS_AST_GEN2(ast)) {
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x3f);
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x2f);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0xa7, 0x3f);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0xa6, 0x2f);
} else {
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x2f);
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x1f);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0xa7, 0x2f);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0xa6, 0x1f);
}
}
@@ -531,13 +531,13 @@ static void ast_set_sync_reg(struct ast_device *ast,
{
u8 jreg;
- jreg = ast_io_read8(ast, AST_IO_MISC_PORT_READ);
+ jreg = ast_io_read8(ast, AST_IO_VGAMR_R);
jreg &= ~0xC0;
if (vbios_mode->enh_table->flags & NVSync)
jreg |= 0x80;
if (vbios_mode->enh_table->flags & NHSync)
jreg |= 0x40;
- ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg);
+ ast_io_write8(ast, AST_IO_VGAMR_W, jreg);
}
static void ast_set_start_address_crt1(struct ast_device *ast,
@@ -546,9 +546,9 @@ static void ast_set_start_address_crt1(struct ast_device *ast,
u32 addr;
addr = offset >> 2;
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x0d, (u8)(addr & 0xff));
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x0c, (u8)((addr >> 8) & 0xff));
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xaf, (u8)((addr >> 16) & 0xff));
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0x0d, (u8)(addr & 0xff));
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0x0c, (u8)((addr >> 8) & 0xff));
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0xaf, (u8)((addr >> 16) & 0xff));
}
@@ -558,7 +558,7 @@ static void ast_wait_for_vretrace(struct ast_device *ast)
u8 vgair1;
do {
- vgair1 = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ);
+ vgair1 = ast_io_read8(ast, AST_IO_VGAIR1_R);
} while (!(vgair1 & AST_IO_VGAIR1_VREFRESH) && time_before(jiffies, timeout));
}
@@ -689,7 +689,7 @@ static void ast_primary_plane_helper_atomic_enable(struct drm_plane *plane,
* Therefore only reprogram the address after enabling the plane.
*/
ast_set_start_address_crt1(ast, (u32)ast_plane->offset);
- ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x00);
+ ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x1, 0xdf, 0x00);
}
static void ast_primary_plane_helper_atomic_disable(struct drm_plane *plane,
@@ -697,7 +697,7 @@ static void ast_primary_plane_helper_atomic_disable(struct drm_plane *plane,
{
struct ast_device *ast = to_ast_device(plane->dev);
- ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x20);
+ ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x1, 0xdf, 0x20);
}
static const struct drm_plane_helper_funcs ast_primary_plane_helper_funcs = {
@@ -814,9 +814,9 @@ static void ast_set_cursor_base(struct ast_device *ast, u64 address)
u8 addr1 = (address >> 11) & 0xff;
u8 addr2 = (address >> 19) & 0xff;
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc8, addr0);
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc9, addr1);
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xca, addr2);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0xc8, addr0);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0xc9, addr1);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0xca, addr2);
}
static void ast_set_cursor_location(struct ast_device *ast, u16 x, u16 y,
@@ -827,12 +827,12 @@ static void ast_set_cursor_location(struct ast_device *ast, u16 x, u16 y,
u8 y0 = (y & 0x00ff);
u8 y1 = (y & 0x0700) >> 8;
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc2, x_offset);
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc3, y_offset);
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc4, x0);
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc5, x1);
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc6, y0);
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc7, y1);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0xc2, x_offset);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0xc3, y_offset);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0xc4, x0);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0xc5, x1);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0xc6, y0);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0xc7, y1);
}
static void ast_set_cursor_enabled(struct ast_device *ast, bool enabled)
@@ -845,7 +845,7 @@ static void ast_set_cursor_enabled(struct ast_device *ast, bool enabled)
if (enabled)
vgacrcb |= AST_IO_VGACRCB_HWC_ENABLED;
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, mask, vgacrcb);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xcb, mask, vgacrcb);
}
static const uint32_t ast_cursor_plane_formats[] = {
@@ -1014,8 +1014,8 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode)
*/
switch (mode) {
case DRM_MODE_DPMS_ON:
- ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, 0);
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xfc, 0);
+ ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, 0);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xfc, 0);
if (ast->tx_chip_types & AST_TX_DP501_BIT)
ast_set_dp501_video_output(crtc->dev, 1);
@@ -1051,8 +1051,8 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode)
ast_dp_power_on_off(crtc->dev, AST_DP_POWER_OFF);
}
- ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, 0x20);
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xfc, ch);
+ ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, 0x20);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xfc, ch);
break;
}
}
@@ -1086,7 +1086,7 @@ ast_crtc_helper_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode
return MODE_OK;
if ((mode->hdisplay == 1920) && (mode->vdisplay == 1200)) {
- jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
+ jtemp = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, 0xff);
if (jtemp & 0x01)
return MODE_NOMODE;
else
@@ -1219,7 +1219,7 @@ static void ast_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atom
struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
ast_set_vbios_mode_reg(ast, adjusted_mode, vbios_mode_info);
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06);
+ ast_set_index_reg(ast, AST_IO_VGACRI, 0xa1, 0x06);
ast_set_std_reg(ast, adjusted_mode, vbios_mode_info);
ast_set_crtc_reg(ast, adjusted_mode, vbios_mode_info);
ast_set_dclk_reg(ast, adjusted_mode, vbios_mode_info);
diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c
index 13e15173f2c5..7a993a384314 100644
--- a/drivers/gpu/drm/ast/ast_post.c
+++ b/drivers/gpu/drm/ast/ast_post.c
@@ -49,7 +49,7 @@ ast_set_def_ext_reg(struct drm_device *dev)
/* reset scratch */
for (i = 0x81; i <= 0x9f; i++)
- ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, 0x00);
+ ast_set_index_reg(ast, AST_IO_VGACRI, i, 0x00);
if (IS_AST_GEN4(ast) || IS_AST_GEN5(ast) || IS_AST_GEN6(ast))
ext_reg_info = extreginfo_ast2300;
@@ -58,23 +58,23 @@ ast_set_def_ext_reg(struct drm_device *dev)
index = 0xa0;
while (*ext_reg_info != 0xff) {
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, index, 0x00, *ext_reg_info);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, index, 0x00, *ext_reg_info);
index++;
ext_reg_info++;
}
/* disable standard IO/MEM decode if secondary */
- /* ast_set_index_reg-mask(ast, AST_IO_CRTC_PORT, 0xa1, 0xff, 0x3); */
+ /* ast_set_index_reg-mask(ast, AST_IO_VGACRI, 0xa1, 0xff, 0x3); */
/* Set Ext. Default */
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x8c, 0x00, 0x01);
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x00, 0x00);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x8c, 0x00, 0x01);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x00, 0x00);
/* Enable RAMDAC for A1 */
reg = 0x04;
if (IS_AST_GEN4(ast) || IS_AST_GEN5(ast) || IS_AST_GEN6(ast))
reg |= 0x20;
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xff, reg);
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xff, reg);
}
u32 ast_mindwm(struct ast_device *ast, u32 r)
@@ -245,7 +245,7 @@ static void ast_init_dram_reg(struct drm_device *dev)
u32 data, temp, i;
const struct ast_dramstruct *dram_reg_info;
- j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
+ j = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
if ((j & 0x80) == 0) { /* VGA only */
if (IS_AST_GEN1(ast)) {
@@ -325,7 +325,7 @@ static void ast_init_dram_reg(struct drm_device *dev)
/* wait ready */
do {
- j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
+ j = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
} while ((j & 0x40) == 0);
}
@@ -349,7 +349,7 @@ void ast_post_gpu(struct drm_device *dev)
ast_init_3rdtx(dev);
} else {
if (ast->tx_chip_types & AST_TX_SIL164_BIT)
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x80); /* Enable DVO */
+ ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x80); /* Enable DVO */
}
}
@@ -1562,7 +1562,7 @@ static void ast_post_chip_2300(struct drm_device *dev)
u32 temp;
u8 reg;
- reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
+ reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
if ((reg & 0x80) == 0) {/* vga only */
ast_write32(ast, 0xf004, 0x1e6e0000);
ast_write32(ast, 0xf000, 0x1);
@@ -1634,7 +1634,7 @@ static void ast_post_chip_2300(struct drm_device *dev)
/* wait ready */
do {
- reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
+ reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
} while ((reg & 0x40) == 0);
}
@@ -2027,7 +2027,7 @@ void ast_post_chip_2500(struct drm_device *dev)
u32 temp;
u8 reg;
- reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
+ reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
if ((reg & AST_VRAM_INIT_STATUS_MASK) == 0) {/* vga only */
/* Clear bus lock condition */
ast_patch_ahb_2500(ast);
@@ -2075,6 +2075,6 @@ void ast_post_chip_2500(struct drm_device *dev)
/* wait ready */
do {
- reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
+ reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff);
} while ((reg & 0x40) == 0);
}
diff --git a/drivers/gpu/drm/ast/ast_reg.h b/drivers/gpu/drm/ast/ast_reg.h
new file mode 100644
index 000000000000..555286ecf520
--- /dev/null
+++ b/drivers/gpu/drm/ast/ast_reg.h
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: MIT */
+
+#ifndef __AST_REG_H__
+#define __AST_REG_H__
+
+#include <linux/bits.h>
+
+/*
+ * Modesetting
+ */
+
+#define AST_IO_MM_OFFSET (0x380)
+
+#define AST_IO_VGAARI_W (0x40)
+#define AST_IO_VGAMR_W (0x42)
+#define AST_IO_VGAER (0x43)
+#define AST_IO_VGASRI (0x44)
+#define AST_IO_VGADRR (0x47)
+#define AST_IO_VGADWR (0x48)
+#define AST_IO_VGAPDR (0x49)
+#define AST_IO_VGAGRI (0x4E)
+
+#define AST_IO_VGACRI (0x54)
+#define AST_IO_VGACRCB_HWC_16BPP BIT(0) /* set: ARGB4444, cleared: 2bpp palette */
+#define AST_IO_VGACRCB_HWC_ENABLED BIT(1)
+
+#define AST_IO_VGAIR1_R (0x5A)
+#define AST_IO_VGAIR1_VREFRESH BIT(3)
+
+#define AST_IO_VGAMR_R (0x4C)
+
+/*
+ * Display Transmitter Type
+ */
+
+#define TX_TYPE_MASK GENMASK(3, 1)
+#define NO_TX (0 << 1)
+#define ITE66121_VBIOS_TX (1 << 1)
+#define SI164_VBIOS_TX (2 << 1)
+#define CH7003_VBIOS_TX (3 << 1)
+#define DP501_VBIOS_TX (4 << 1)
+#define ANX9807_VBIOS_TX (5 << 1)
+#define TX_FW_EMBEDDED_FW_TX (6 << 1)
+#define ASTDP_DPMCU_TX (7 << 1)
+
+#define AST_VRAM_INIT_STATUS_MASK GENMASK(7, 6)
+//#define AST_VRAM_INIT_BY_BMC BIT(7)
+//#define AST_VRAM_INIT_READY BIT(6)
+
+/*
+ * AST DisplayPort
+ */
+
+/* Define for Soc scratched reg used on ASTDP */
+#define AST_DP_PHY_SLEEP BIT(4)
+#define AST_DP_VIDEO_ENABLE BIT(0)
+
+/*
+ * CRD1[b5]: DP MCU FW is executing
+ * CRDC[b0]: DP link success
+ * CRDF[b0]: DP HPD
+ * CRE5[b0]: Host reading EDID process is done
+ */
+#define ASTDP_MCU_FW_EXECUTING BIT(5)
+#define ASTDP_LINK_SUCCESS BIT(0)
+#define ASTDP_HPD BIT(0)
+#define ASTDP_HOST_EDID_READ_DONE BIT(0)
+#define ASTDP_HOST_EDID_READ_DONE_MASK GENMASK(0, 0)
+
+/*
+ * CRB8[b1]: Enable VSYNC off
+ * CRB8[b0]: Enable HSYNC off
+ */
+#define AST_DPMS_VSYNC_OFF BIT(1)
+#define AST_DPMS_HSYNC_OFF BIT(0)
+
+/*
+ * CRDF[b4]: Mirror of AST_DP_VIDEO_ENABLE
+ * Precondition: A. ~AST_DP_PHY_SLEEP &&
+ * B. DP_HPD &&
+ * C. DP_LINK_SUCCESS
+ */
+#define ASTDP_MIRROR_VIDEO_ENABLE BIT(4)
+
+#define ASTDP_EDID_READ_POINTER_MASK GENMASK(7, 0)
+#define ASTDP_EDID_VALID_FLAG_MASK GENMASK(0, 0)
+#define ASTDP_EDID_READ_DATA_MASK GENMASK(7, 0)
+
+/*
+ * ASTDP setmode registers:
+ * CRE0[7:0]: MISC0 ((0x00: 18-bpp) or (0x20: 24-bpp)
+ * CRE1[7:0]: MISC1 (default: 0x00)
+ * CRE2[7:0]: video format index (0x00 ~ 0x20 or 0x40 ~ 0x50)
+ */
+#define ASTDP_MISC0_24bpp BIT(5)
+#define ASTDP_MISC1 0
+#define ASTDP_AND_CLEAR_MASK 0x00
+
+#endif
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index 17445800248d..39c9ece373b0 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -333,6 +333,18 @@ enum adv7511_type {
#define ADV7511_MAX_ADDRS 3
+struct adv7511_chip_info {
+ enum adv7511_type type;
+ unsigned int max_mode_clock_khz;
+ unsigned int max_lane_freq_khz;
+ const char * const *supply_names;
+ unsigned int num_supplies;
+ unsigned int reg_cec_offset;
+ bool has_dsi;
+ bool link_config;
+ bool hpd_override_enable;
+};
+
struct adv7511 {
struct i2c_client *i2c_main;
struct i2c_client *i2c_edid;
@@ -341,7 +353,6 @@ struct adv7511 {
struct regmap *regmap;
struct regmap *regmap_cec;
- unsigned int reg_cec_offset;
enum drm_connector_status status;
bool powered;
@@ -369,7 +380,6 @@ struct adv7511 {
struct gpio_desc *gpio_pd;
struct regulator_bulk_data *supplies;
- unsigned int num_supplies;
/* ADV7533 DSI RX related params */
struct device_node *host_node;
@@ -377,7 +387,7 @@ struct adv7511 {
u8 num_dsi_lanes;
bool use_timing_gen;
- enum adv7511_type type;
+ const struct adv7511_chip_info *info;
struct platform_device *audio_pdev;
struct cec_adapter *cec_adap;
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
index 2a6b91f752cb..44451a9658a3 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
@@ -33,7 +33,7 @@ static const u8 ADV7511_REG_CEC_RX_FRAME_LEN[] = {
static void adv_cec_tx_raw_status(struct adv7511 *adv7511, u8 tx_raw_status)
{
- unsigned int offset = adv7511->reg_cec_offset;
+ unsigned int offset = adv7511->info->reg_cec_offset;
unsigned int val;
if (regmap_read(adv7511->regmap_cec,
@@ -84,7 +84,7 @@ static void adv_cec_tx_raw_status(struct adv7511 *adv7511, u8 tx_raw_status)
static void adv7511_cec_rx(struct adv7511 *adv7511, int rx_buf)
{
- unsigned int offset = adv7511->reg_cec_offset;
+ unsigned int offset = adv7511->info->reg_cec_offset;
struct cec_msg msg = {};
unsigned int len;
unsigned int val;
@@ -121,7 +121,7 @@ static void adv7511_cec_rx(struct adv7511 *adv7511, int rx_buf)
void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1)
{
- unsigned int offset = adv7511->reg_cec_offset;
+ unsigned int offset = adv7511->info->reg_cec_offset;
const u32 irq_tx_mask = ADV7511_INT1_CEC_TX_READY |
ADV7511_INT1_CEC_TX_ARBIT_LOST |
ADV7511_INT1_CEC_TX_RETRY_TIMEOUT;
@@ -177,7 +177,7 @@ void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1)
static int adv7511_cec_adap_enable(struct cec_adapter *adap, bool enable)
{
struct adv7511 *adv7511 = cec_get_drvdata(adap);
- unsigned int offset = adv7511->reg_cec_offset;
+ unsigned int offset = adv7511->info->reg_cec_offset;
if (adv7511->i2c_cec == NULL)
return -EIO;
@@ -223,7 +223,7 @@ static int adv7511_cec_adap_enable(struct cec_adapter *adap, bool enable)
static int adv7511_cec_adap_log_addr(struct cec_adapter *adap, u8 addr)
{
struct adv7511 *adv7511 = cec_get_drvdata(adap);
- unsigned int offset = adv7511->reg_cec_offset;
+ unsigned int offset = adv7511->info->reg_cec_offset;
unsigned int i, free_idx = ADV7511_MAX_ADDRS;
if (!adv7511->cec_enabled_adap)
@@ -292,7 +292,7 @@ static int adv7511_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
u32 signal_free_time, struct cec_msg *msg)
{
struct adv7511 *adv7511 = cec_get_drvdata(adap);
- unsigned int offset = adv7511->reg_cec_offset;
+ unsigned int offset = adv7511->info->reg_cec_offset;
u8 len = msg->len;
unsigned int i;
@@ -345,7 +345,7 @@ static int adv7511_cec_parse_dt(struct device *dev, struct adv7511 *adv7511)
int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511)
{
- unsigned int offset = adv7511->reg_cec_offset;
+ unsigned int offset = adv7511->info->reg_cec_offset;
int ret = adv7511_cec_parse_dt(dev, adv7511);
if (ret)
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index d518de88b5c3..8be235144f6d 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -354,7 +354,7 @@ static void __adv7511_power_on(struct adv7511 *adv7511)
* first few seconds after enabling the output. On the other hand
* adv7535 require to enable HPD Override bit for proper HPD.
*/
- if (adv7511->type == ADV7535)
+ if (adv7511->info->hpd_override_enable)
regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
ADV7535_REG_POWER2_HPD_OVERRIDE,
ADV7535_REG_POWER2_HPD_OVERRIDE);
@@ -373,7 +373,7 @@ static void adv7511_power_on(struct adv7511 *adv7511)
*/
regcache_sync(adv7511->regmap);
- if (adv7511->type == ADV7533 || adv7511->type == ADV7535)
+ if (adv7511->info->has_dsi)
adv7533_dsi_power_on(adv7511);
adv7511->powered = true;
}
@@ -381,7 +381,7 @@ static void adv7511_power_on(struct adv7511 *adv7511)
static void __adv7511_power_off(struct adv7511 *adv7511)
{
/* TODO: setup additional power down modes */
- if (adv7511->type == ADV7535)
+ if (adv7511->info->hpd_override_enable)
regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
ADV7535_REG_POWER2_HPD_OVERRIDE, 0);
@@ -397,7 +397,7 @@ static void __adv7511_power_off(struct adv7511 *adv7511)
static void adv7511_power_off(struct adv7511 *adv7511)
{
__adv7511_power_off(adv7511);
- if (adv7511->type == ADV7533 || adv7511->type == ADV7535)
+ if (adv7511->info->has_dsi)
adv7533_dsi_power_off(adv7511);
adv7511->powered = false;
}
@@ -682,7 +682,7 @@ adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector)
status = connector_status_disconnected;
} else {
/* Renable HPD sensing */
- if (adv7511->type == ADV7535)
+ if (adv7511->info->hpd_override_enable)
regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
ADV7535_REG_POWER2_HPD_OVERRIDE,
ADV7535_REG_POWER2_HPD_OVERRIDE);
@@ -786,7 +786,7 @@ static void adv7511_mode_set(struct adv7511 *adv7511,
else
low_refresh_rate = ADV7511_LOW_REFRESH_RATE_NONE;
- if (adv7511->type == ADV7511)
+ if (adv7511->info->type == ADV7511)
regmap_update_bits(adv7511->regmap, 0xfb,
0x6, low_refresh_rate << 1);
else
@@ -921,7 +921,7 @@ static enum drm_mode_status adv7511_bridge_mode_valid(struct drm_bridge *bridge,
{
struct adv7511 *adv = bridge_to_adv7511(bridge);
- if (adv->type == ADV7533 || adv->type == ADV7535)
+ if (adv->info->has_dsi)
return adv7533_mode_valid(adv, mode);
else
return adv7511_mode_valid(adv, mode);
@@ -1004,37 +1004,30 @@ static const char * const adv7533_supply_names[] = {
static int adv7511_init_regulators(struct adv7511 *adv)
{
+ const char * const *supply_names = adv->info->supply_names;
+ unsigned int num_supplies = adv->info->num_supplies;
struct device *dev = &adv->i2c_main->dev;
- const char * const *supply_names;
unsigned int i;
int ret;
- if (adv->type == ADV7511) {
- supply_names = adv7511_supply_names;
- adv->num_supplies = ARRAY_SIZE(adv7511_supply_names);
- } else {
- supply_names = adv7533_supply_names;
- adv->num_supplies = ARRAY_SIZE(adv7533_supply_names);
- }
-
- adv->supplies = devm_kcalloc(dev, adv->num_supplies,
+ adv->supplies = devm_kcalloc(dev, num_supplies,
sizeof(*adv->supplies), GFP_KERNEL);
if (!adv->supplies)
return -ENOMEM;
- for (i = 0; i < adv->num_supplies; i++)
+ for (i = 0; i < num_supplies; i++)
adv->supplies[i].supply = supply_names[i];
- ret = devm_regulator_bulk_get(dev, adv->num_supplies, adv->supplies);
+ ret = devm_regulator_bulk_get(dev, num_supplies, adv->supplies);
if (ret)
return ret;
- return regulator_bulk_enable(adv->num_supplies, adv->supplies);
+ return regulator_bulk_enable(num_supplies, adv->supplies);
}
static void adv7511_uninit_regulators(struct adv7511 *adv)
{
- regulator_bulk_disable(adv->num_supplies, adv->supplies);
+ regulator_bulk_disable(adv->info->num_supplies, adv->supplies);
}
static bool adv7511_cec_register_volatile(struct device *dev, unsigned int reg)
@@ -1042,7 +1035,7 @@ static bool adv7511_cec_register_volatile(struct device *dev, unsigned int reg)
struct i2c_client *i2c = to_i2c_client(dev);
struct adv7511 *adv7511 = i2c_get_clientdata(i2c);
- reg -= adv7511->reg_cec_offset;
+ reg -= adv7511->info->reg_cec_offset;
switch (reg) {
case ADV7511_REG_CEC_RX1_FRAME_HDR:
@@ -1093,12 +1086,10 @@ static int adv7511_init_cec_regmap(struct adv7511 *adv)
goto err;
}
- if (adv->type == ADV7533 || adv->type == ADV7535) {
+ if (adv->info->reg_cec_offset == ADV7533_REG_CEC_OFFSET) {
ret = adv7533_patch_cec_registers(adv);
if (ret)
goto err;
-
- adv->reg_cec_offset = ADV7533_REG_CEC_OFFSET;
}
return 0;
@@ -1192,7 +1183,6 @@ static int adv7511_parse_dt(struct device_node *np,
static int adv7511_probe(struct i2c_client *i2c)
{
- const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
struct adv7511_link_config link_config;
struct adv7511 *adv7511;
struct device *dev = &i2c->dev;
@@ -1209,15 +1199,11 @@ static int adv7511_probe(struct i2c_client *i2c)
adv7511->i2c_main = i2c;
adv7511->powered = false;
adv7511->status = connector_status_disconnected;
-
- if (dev->of_node)
- adv7511->type = (enum adv7511_type)of_device_get_match_data(dev);
- else
- adv7511->type = id->driver_data;
+ adv7511->info = i2c_get_match_data(i2c);
memset(&link_config, 0, sizeof(link_config));
- if (adv7511->type == ADV7511)
+ if (adv7511->info->link_config)
ret = adv7511_parse_dt(dev->of_node, &link_config);
else
ret = adv7533_parse_dt(dev->of_node, adv7511);
@@ -1254,7 +1240,7 @@ static int adv7511_probe(struct i2c_client *i2c)
goto uninit_regulators;
dev_dbg(dev, "Rev. %d\n", val);
- if (adv7511->type == ADV7511)
+ if (adv7511->info->type == ADV7511)
ret = regmap_register_patch(adv7511->regmap,
adv7511_fixed_registers,
ARRAY_SIZE(adv7511_fixed_registers));
@@ -1306,7 +1292,7 @@ static int adv7511_probe(struct i2c_client *i2c)
i2c_set_clientdata(i2c, adv7511);
- if (adv7511->type == ADV7511)
+ if (adv7511->info->link_config)
adv7511_set_link_config(adv7511, &link_config);
ret = adv7511_cec_init(dev, adv7511);
@@ -1325,7 +1311,7 @@ static int adv7511_probe(struct i2c_client *i2c)
adv7511_audio_init(dev, adv7511);
- if (adv7511->type == ADV7533 || adv7511->type == ADV7535) {
+ if (adv7511->info->has_dsi) {
ret = adv7533_attach_dsi(adv7511);
if (ret)
goto err_unregister_audio;
@@ -1368,22 +1354,50 @@ static void adv7511_remove(struct i2c_client *i2c)
i2c_unregister_device(adv7511->i2c_edid);
}
+static const struct adv7511_chip_info adv7511_chip_info = {
+ .type = ADV7511,
+ .supply_names = adv7511_supply_names,
+ .num_supplies = ARRAY_SIZE(adv7511_supply_names),
+ .link_config = true,
+};
+
+static const struct adv7511_chip_info adv7533_chip_info = {
+ .type = ADV7533,
+ .max_mode_clock_khz = 80000,
+ .max_lane_freq_khz = 800000,
+ .supply_names = adv7533_supply_names,
+ .num_supplies = ARRAY_SIZE(adv7533_supply_names),
+ .reg_cec_offset = ADV7533_REG_CEC_OFFSET,
+ .has_dsi = true,
+};
+
+static const struct adv7511_chip_info adv7535_chip_info = {
+ .type = ADV7535,
+ .max_mode_clock_khz = 148500,
+ .max_lane_freq_khz = 891000,
+ .supply_names = adv7533_supply_names,
+ .num_supplies = ARRAY_SIZE(adv7533_supply_names),
+ .reg_cec_offset = ADV7533_REG_CEC_OFFSET,
+ .has_dsi = true,
+ .hpd_override_enable = true,
+};
+
static const struct i2c_device_id adv7511_i2c_ids[] = {
- { "adv7511", ADV7511 },
- { "adv7511w", ADV7511 },
- { "adv7513", ADV7511 },
- { "adv7533", ADV7533 },
- { "adv7535", ADV7535 },
+ { "adv7511", (kernel_ulong_t)&adv7511_chip_info },
+ { "adv7511w", (kernel_ulong_t)&adv7511_chip_info },
+ { "adv7513", (kernel_ulong_t)&adv7511_chip_info },
+ { "adv7533", (kernel_ulong_t)&adv7533_chip_info },
+ { "adv7535", (kernel_ulong_t)&adv7535_chip_info },
{ }
};
MODULE_DEVICE_TABLE(i2c, adv7511_i2c_ids);
static const struct of_device_id adv7511_of_ids[] = {
- { .compatible = "adi,adv7511", .data = (void *)ADV7511 },
- { .compatible = "adi,adv7511w", .data = (void *)ADV7511 },
- { .compatible = "adi,adv7513", .data = (void *)ADV7511 },
- { .compatible = "adi,adv7533", .data = (void *)ADV7533 },
- { .compatible = "adi,adv7535", .data = (void *)ADV7535 },
+ { .compatible = "adi,adv7511", .data = &adv7511_chip_info },
+ { .compatible = "adi,adv7511w", .data = &adv7511_chip_info },
+ { .compatible = "adi,adv7513", .data = &adv7511_chip_info },
+ { .compatible = "adi,adv7533", .data = &adv7533_chip_info },
+ { .compatible = "adi,adv7535", .data = &adv7535_chip_info },
{ }
};
MODULE_DEVICE_TABLE(of, adv7511_of_ids);
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c b/drivers/gpu/drm/bridge/adv7511/adv7533.c
index 7e3e56441aed..4481489aaf5e 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7533.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c
@@ -103,18 +103,15 @@ void adv7533_dsi_power_off(struct adv7511 *adv)
enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv,
const struct drm_display_mode *mode)
{
- unsigned long max_lane_freq;
struct mipi_dsi_device *dsi = adv->dsi;
u8 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
/* Check max clock for either 7533 or 7535 */
- if (mode->clock > (adv->type == ADV7533 ? 80000 : 148500))
+ if (mode->clock > adv->info->max_mode_clock_khz)
return MODE_CLOCK_HIGH;
/* Check max clock for each lane */
- max_lane_freq = (adv->type == ADV7533 ? 800000 : 891000);
-
- if (mode->clock * bpp > max_lane_freq * adv->num_dsi_lanes)
+ if (mode->clock * bpp > adv->info->max_lane_freq_khz * adv->num_dsi_lanes)
return MODE_CLOCK_HIGH;
return MODE_OK;
diff --git a/drivers/gpu/drm/bridge/imx/Kconfig b/drivers/gpu/drm/bridge/imx/Kconfig
index 9fae28db6aa7..5a4f3d58501e 100644
--- a/drivers/gpu/drm/bridge/imx/Kconfig
+++ b/drivers/gpu/drm/bridge/imx/Kconfig
@@ -49,4 +49,15 @@ config DRM_IMX8QXP_PIXEL_LINK_TO_DPI
Choose this to enable pixel link to display pixel interface(PXL2DPI)
found in Freescale i.MX8qxp processor.
+config DRM_IMX93_MIPI_DSI
+ tristate "Freescale i.MX93 specific extensions for Synopsys DW MIPI DSI"
+ depends on OF
+ depends on COMMON_CLK
+ select DRM_DW_MIPI_DSI
+ select GENERIC_PHY
+ select GENERIC_PHY_MIPI_DPHY
+ help
+ Choose this to enable MIPI DSI controller found in Freescale i.MX93
+ processor.
+
endif # ARCH_MXC || COMPILE_TEST
diff --git a/drivers/gpu/drm/bridge/imx/Makefile b/drivers/gpu/drm/bridge/imx/Makefile
index 8e2ebf3399a1..2b0c2e44aa1b 100644
--- a/drivers/gpu/drm/bridge/imx/Makefile
+++ b/drivers/gpu/drm/bridge/imx/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_DRM_IMX8QXP_LDB) += imx8qxp-ldb.o
obj-$(CONFIG_DRM_IMX8QXP_PIXEL_COMBINER) += imx8qxp-pixel-combiner.o
obj-$(CONFIG_DRM_IMX8QXP_PIXEL_LINK) += imx8qxp-pixel-link.o
obj-$(CONFIG_DRM_IMX8QXP_PIXEL_LINK_TO_DPI) += imx8qxp-pxl2dpi.o
+obj-$(CONFIG_DRM_IMX93_MIPI_DSI) += imx93-mipi-dsi.o
diff --git a/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c
new file mode 100644
index 000000000000..3ff30ce80c5b
--- /dev/null
+++ b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c
@@ -0,0 +1,917 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/*
+ * Copyright 2022,2023 NXP
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/math.h>
+#include <linux/media-bus-format.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/phy/phy-mipi-dphy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <drm/bridge/dw_mipi_dsi.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_modes.h>
+
+/* DPHY PLL configuration registers */
+#define DSI_REG 0x4c
+#define CFGCLKFREQRANGE_MASK GENMASK(5, 0)
+#define CFGCLKFREQRANGE(x) FIELD_PREP(CFGCLKFREQRANGE_MASK, (x))
+#define CLKSEL_MASK GENMASK(7, 6)
+#define CLKSEL_STOP FIELD_PREP(CLKSEL_MASK, 0)
+#define CLKSEL_GEN FIELD_PREP(CLKSEL_MASK, 1)
+#define CLKSEL_EXT FIELD_PREP(CLKSEL_MASK, 2)
+#define HSFREQRANGE_MASK GENMASK(14, 8)
+#define HSFREQRANGE(x) FIELD_PREP(HSFREQRANGE_MASK, (x))
+#define UPDATE_PLL BIT(17)
+#define SHADOW_CLR BIT(18)
+#define CLK_EXT BIT(19)
+
+#define DSI_WRITE_REG0 0x50
+#define M_MASK GENMASK(9, 0)
+#define M(x) FIELD_PREP(M_MASK, ((x) - 2))
+#define N_MASK GENMASK(13, 10)
+#define N(x) FIELD_PREP(N_MASK, ((x) - 1))
+#define VCO_CTRL_MASK GENMASK(19, 14)
+#define VCO_CTRL(x) FIELD_PREP(VCO_CTRL_MASK, (x))
+#define PROP_CTRL_MASK GENMASK(25, 20)
+#define PROP_CTRL(x) FIELD_PREP(PROP_CTRL_MASK, (x))
+#define INT_CTRL_MASK GENMASK(31, 26)
+#define INT_CTRL(x) FIELD_PREP(INT_CTRL_MASK, (x))
+
+#define DSI_WRITE_REG1 0x54
+#define GMP_CTRL_MASK GENMASK(1, 0)
+#define GMP_CTRL(x) FIELD_PREP(GMP_CTRL_MASK, (x))
+#define CPBIAS_CTRL_MASK GENMASK(8, 2)
+#define CPBIAS_CTRL(x) FIELD_PREP(CPBIAS_CTRL_MASK, (x))
+#define PLL_SHADOW_CTRL BIT(9)
+
+/* display mux control register */
+#define DISPLAY_MUX 0x60
+#define MIPI_DSI_RGB666_MAP_CFG GENMASK(7, 6)
+#define RGB666_CONFIG1 FIELD_PREP(MIPI_DSI_RGB666_MAP_CFG, 0)
+#define RGB666_CONFIG2 FIELD_PREP(MIPI_DSI_RGB666_MAP_CFG, 1)
+#define MIPI_DSI_RGB565_MAP_CFG GENMASK(5, 4)
+#define RGB565_CONFIG1 FIELD_PREP(MIPI_DSI_RGB565_MAP_CFG, 0)
+#define RGB565_CONFIG2 FIELD_PREP(MIPI_DSI_RGB565_MAP_CFG, 1)
+#define RGB565_CONFIG3 FIELD_PREP(MIPI_DSI_RGB565_MAP_CFG, 2)
+#define LCDIF_CROSS_LINE_PATTERN GENMASK(3, 0)
+#define RGB888_TO_RGB888 FIELD_PREP(LCDIF_CROSS_LINE_PATTERN, 0)
+#define RGB888_TO_RGB666 FIELD_PREP(LCDIF_CROSS_LINE_PATTERN, 6)
+#define RGB565_TO_RGB565 FIELD_PREP(LCDIF_CROSS_LINE_PATTERN, 7)
+
+#define MHZ(x) ((x) * 1000000UL)
+
+#define REF_CLK_RATE_MAX MHZ(64)
+#define REF_CLK_RATE_MIN MHZ(2)
+#define FOUT_MAX MHZ(1250)
+#define FOUT_MIN MHZ(40)
+#define FVCO_DIV_FACTOR MHZ(80)
+
+#define MBPS(x) ((x) * 1000000UL)
+
+#define DATA_RATE_MAX_SPEED MBPS(2500)
+#define DATA_RATE_MIN_SPEED MBPS(80)
+
+#define M_MAX 625UL
+#define M_MIN 64UL
+
+#define N_MAX 16U
+#define N_MIN 1U
+
+struct imx93_dsi {
+ struct device *dev;
+ struct regmap *regmap;
+ struct clk *clk_pixel;
+ struct clk *clk_ref;
+ struct clk *clk_cfg;
+ struct dw_mipi_dsi *dmd;
+ struct dw_mipi_dsi_plat_data pdata;
+ union phy_configure_opts phy_cfg;
+ unsigned long ref_clk_rate;
+ u32 format;
+};
+
+struct dphy_pll_cfg {
+ u32 m; /* PLL Feedback Multiplication Ratio */
+ u32 n; /* PLL Input Frequency Division Ratio */
+};
+
+struct dphy_pll_vco_prop {
+ unsigned long max_fout;
+ u8 vco_cntl;
+ u8 prop_cntl;
+};
+
+struct dphy_pll_hsfreqrange {
+ unsigned long max_mbps;
+ u8 hsfreqrange;
+};
+
+/* DPHY Databook Table 3-13 Charge-pump Programmability */
+static const struct dphy_pll_vco_prop vco_prop_map[] = {
+ { 55, 0x3f, 0x0d },
+ { 82, 0x37, 0x0d },
+ { 110, 0x2f, 0x0d },
+ { 165, 0x27, 0x0d },
+ { 220, 0x1f, 0x0d },
+ { 330, 0x17, 0x0d },
+ { 440, 0x0f, 0x0d },
+ { 660, 0x07, 0x0d },
+ { 1149, 0x03, 0x0d },
+ { 1152, 0x01, 0x0d },
+ { 1250, 0x01, 0x0e },
+};
+
+/* DPHY Databook Table 5-7 Frequency Ranges and Defaults */
+static const struct dphy_pll_hsfreqrange hsfreqrange_map[] = {
+ { 89, 0x00 },
+ { 99, 0x10 },
+ { 109, 0x20 },
+ { 119, 0x30 },
+ { 129, 0x01 },
+ { 139, 0x11 },
+ { 149, 0x21 },
+ { 159, 0x31 },
+ { 169, 0x02 },
+ { 179, 0x12 },
+ { 189, 0x22 },
+ { 204, 0x32 },
+ { 219, 0x03 },
+ { 234, 0x13 },
+ { 249, 0x23 },
+ { 274, 0x33 },
+ { 299, 0x04 },
+ { 324, 0x14 },
+ { 349, 0x25 },
+ { 399, 0x35 },
+ { 449, 0x05 },
+ { 499, 0x16 },
+ { 549, 0x26 },
+ { 599, 0x37 },
+ { 649, 0x07 },
+ { 699, 0x18 },
+ { 749, 0x28 },
+ { 799, 0x39 },
+ { 849, 0x09 },
+ { 899, 0x19 },
+ { 949, 0x29 },
+ { 999, 0x3a },
+ { 1049, 0x0a },
+ { 1099, 0x1a },
+ { 1149, 0x2a },
+ { 1199, 0x3b },
+ { 1249, 0x0b },
+ { 1299, 0x1b },
+ { 1349, 0x2b },
+ { 1399, 0x3c },
+ { 1449, 0x0c },
+ { 1499, 0x1c },
+ { 1549, 0x2c },
+ { 1599, 0x3d },
+ { 1649, 0x0d },
+ { 1699, 0x1d },
+ { 1749, 0x2e },
+ { 1799, 0x3e },
+ { 1849, 0x0e },
+ { 1899, 0x1e },
+ { 1949, 0x2f },
+ { 1999, 0x3f },
+ { 2049, 0x0f },
+ { 2099, 0x40 },
+ { 2149, 0x41 },
+ { 2199, 0x42 },
+ { 2249, 0x43 },
+ { 2299, 0x44 },
+ { 2349, 0x45 },
+ { 2399, 0x46 },
+ { 2449, 0x47 },
+ { 2499, 0x48 },
+ { 2500, 0x49 },
+};
+
+static void dphy_pll_write(struct imx93_dsi *dsi, unsigned int reg, u32 value)
+{
+ int ret;
+
+ ret = regmap_write(dsi->regmap, reg, value);
+ if (ret < 0)
+ dev_err(dsi->dev, "failed to write 0x%08x to pll reg 0x%x: %d\n",
+ value, reg, ret);
+}
+
+static inline unsigned long data_rate_to_fout(unsigned long data_rate)
+{
+ /* Fout is half of data rate */
+ return data_rate / 2;
+}
+
+static int
+dphy_pll_get_configure_from_opts(struct imx93_dsi *dsi,
+ struct phy_configure_opts_mipi_dphy *dphy_opts,
+ struct dphy_pll_cfg *cfg)
+{
+ struct device *dev = dsi->dev;
+ unsigned long fin = dsi->ref_clk_rate;
+ unsigned long fout;
+ unsigned long best_fout = 0;
+ unsigned int fvco_div;
+ unsigned int min_n, max_n, n, best_n;
+ unsigned long m, best_m;
+ unsigned long min_delta = ULONG_MAX;
+ unsigned long delta;
+ u64 tmp;
+
+ if (dphy_opts->hs_clk_rate < DATA_RATE_MIN_SPEED ||
+ dphy_opts->hs_clk_rate > DATA_RATE_MAX_SPEED) {
+ dev_dbg(dev, "invalid data rate per lane: %lu\n",
+ dphy_opts->hs_clk_rate);
+ return -EINVAL;
+ }
+
+ fout = data_rate_to_fout(dphy_opts->hs_clk_rate);
+
+ /* DPHY Databook 3.3.6.1 Output Frequency */
+ /* Fout = Fvco / Fvco_div = (Fin * M) / (Fvco_div * N) */
+ /* Fvco_div could be 1/2/4/8 according to Fout range. */
+ fvco_div = 8UL / min(DIV_ROUND_UP(fout, FVCO_DIV_FACTOR), 8UL);
+
+ /* limitation: 2MHz <= Fin / N <= 8MHz */
+ min_n = DIV_ROUND_UP_ULL((u64)fin, MHZ(8));
+ max_n = DIV_ROUND_DOWN_ULL((u64)fin, MHZ(2));
+
+ /* clamp possible N(s) */
+ min_n = clamp(min_n, N_MIN, N_MAX);
+ max_n = clamp(max_n, N_MIN, N_MAX);
+
+ dev_dbg(dev, "Fout = %lu, Fvco_div = %u, n_range = [%u, %u]\n",
+ fout, fvco_div, min_n, max_n);
+
+ for (n = min_n; n <= max_n; n++) {
+ /* M = (Fout * N * Fvco_div) / Fin */
+ m = DIV_ROUND_CLOSEST(fout * n * fvco_div, fin);
+
+ /* check M range */
+ if (m < M_MIN || m > M_MAX)
+ continue;
+
+ /* calculate temporary Fout */
+ tmp = m * fin;
+ do_div(tmp, n * fvco_div);
+ if (tmp < FOUT_MIN || tmp > FOUT_MAX)
+ continue;
+
+ delta = abs(fout - tmp);
+ if (delta < min_delta) {
+ best_n = n;
+ best_m = m;
+ min_delta = delta;
+ best_fout = tmp;
+ }
+ }
+
+ if (best_fout) {
+ cfg->m = best_m;
+ cfg->n = best_n;
+ dev_dbg(dev, "best Fout = %lu, m = %u, n = %u\n",
+ best_fout, cfg->m, cfg->n);
+ } else {
+ dev_dbg(dev, "failed to find best Fout\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void dphy_pll_clear_shadow(struct imx93_dsi *dsi)
+{
+ /* Reference DPHY Databook Figure 3-3 Initialization Timing Diagram. */
+ /* Select clock generation first. */
+ dphy_pll_write(dsi, DSI_REG, CLKSEL_GEN);
+
+ /* Clear shadow after clock selection is done a while. */
+ fsleep(1);
+ dphy_pll_write(dsi, DSI_REG, CLKSEL_GEN | SHADOW_CLR);
+
+ /* A minimum pulse of 5ns on shadow_clear signal. */
+ fsleep(1);
+ dphy_pll_write(dsi, DSI_REG, CLKSEL_GEN);
+}
+
+static unsigned long dphy_pll_get_cfgclkrange(struct imx93_dsi *dsi)
+{
+ /*
+ * DPHY Databook Table 4-4 System Control Signals mentions an equation
+ * for cfgclkfreqrange[5:0].
+ */
+ return (clk_get_rate(dsi->clk_cfg) / MHZ(1) - 17) * 4;
+}
+
+static u8
+dphy_pll_get_hsfreqrange(struct phy_configure_opts_mipi_dphy *dphy_opts)
+{
+ unsigned long mbps = dphy_opts->hs_clk_rate / MHZ(1);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(hsfreqrange_map); i++)
+ if (mbps <= hsfreqrange_map[i].max_mbps)
+ return hsfreqrange_map[i].hsfreqrange;
+
+ return 0;
+}
+
+static u8 dphy_pll_get_vco(struct phy_configure_opts_mipi_dphy *dphy_opts)
+{
+ unsigned long fout = data_rate_to_fout(dphy_opts->hs_clk_rate) / MHZ(1);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(vco_prop_map); i++)
+ if (fout <= vco_prop_map[i].max_fout)
+ return vco_prop_map[i].vco_cntl;
+
+ return 0;
+}
+
+static u8 dphy_pll_get_prop(struct phy_configure_opts_mipi_dphy *dphy_opts)
+{
+ unsigned long fout = data_rate_to_fout(dphy_opts->hs_clk_rate) / MHZ(1);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(vco_prop_map); i++)
+ if (fout <= vco_prop_map[i].max_fout)
+ return vco_prop_map[i].prop_cntl;
+
+ return 0;
+}
+
+static int dphy_pll_update(struct imx93_dsi *dsi)
+{
+ int ret;
+
+ ret = regmap_update_bits(dsi->regmap, DSI_REG, UPDATE_PLL, UPDATE_PLL);
+ if (ret < 0) {
+ dev_err(dsi->dev, "failed to set UPDATE_PLL: %d\n", ret);
+ return ret;
+ }
+
+ /*
+ * The updatepll signal should be asserted for a minimum of four clkin
+ * cycles, according to DPHY Databook Figure 3-3 Initialization Timing
+ * Diagram.
+ */
+ fsleep(10);
+
+ ret = regmap_update_bits(dsi->regmap, DSI_REG, UPDATE_PLL, 0);
+ if (ret < 0) {
+ dev_err(dsi->dev, "failed to clear UPDATE_PLL: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int dphy_pll_configure(struct imx93_dsi *dsi, union phy_configure_opts *opts)
+{
+ struct dphy_pll_cfg cfg = { 0 };
+ u32 val;
+ int ret;
+
+ ret = dphy_pll_get_configure_from_opts(dsi, &opts->mipi_dphy, &cfg);
+ if (ret) {
+ dev_err(dsi->dev, "failed to get phy pll cfg %d\n", ret);
+ return ret;
+ }
+
+ dphy_pll_clear_shadow(dsi);
+
+ /* DSI_REG */
+ val = CLKSEL_GEN |
+ CFGCLKFREQRANGE(dphy_pll_get_cfgclkrange(dsi)) |
+ HSFREQRANGE(dphy_pll_get_hsfreqrange(&opts->mipi_dphy));
+ dphy_pll_write(dsi, DSI_REG, val);
+
+ /* DSI_WRITE_REG0 */
+ val = M(cfg.m) | N(cfg.n) | INT_CTRL(0) |
+ VCO_CTRL(dphy_pll_get_vco(&opts->mipi_dphy)) |
+ PROP_CTRL(dphy_pll_get_prop(&opts->mipi_dphy));
+ dphy_pll_write(dsi, DSI_WRITE_REG0, val);
+
+ /* DSI_WRITE_REG1 */
+ dphy_pll_write(dsi, DSI_WRITE_REG1, GMP_CTRL(1) | CPBIAS_CTRL(0x10));
+
+ ret = clk_prepare_enable(dsi->clk_ref);
+ if (ret < 0) {
+ dev_err(dsi->dev, "failed to enable ref clock: %d\n", ret);
+ return ret;
+ }
+
+ /*
+ * At least 10 refclk cycles are required before updatePLL assertion,
+ * according to DPHY Databook Figure 3-3 Initialization Timing Diagram.
+ */
+ fsleep(10);
+
+ ret = dphy_pll_update(dsi);
+ if (ret < 0) {
+ clk_disable_unprepare(dsi->clk_ref);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void dphy_pll_clear_reg(struct imx93_dsi *dsi)
+{
+ dphy_pll_write(dsi, DSI_REG, 0);
+ dphy_pll_write(dsi, DSI_WRITE_REG0, 0);
+ dphy_pll_write(dsi, DSI_WRITE_REG1, 0);
+}
+
+static int dphy_pll_init(struct imx93_dsi *dsi)
+{
+ int ret;
+
+ ret = clk_prepare_enable(dsi->clk_cfg);
+ if (ret < 0) {
+ dev_err(dsi->dev, "failed to enable config clock: %d\n", ret);
+ return ret;
+ }
+
+ dphy_pll_clear_reg(dsi);
+
+ return 0;
+}
+
+static void dphy_pll_uninit(struct imx93_dsi *dsi)
+{
+ dphy_pll_clear_reg(dsi);
+ clk_disable_unprepare(dsi->clk_cfg);
+}
+
+static void dphy_pll_power_off(struct imx93_dsi *dsi)
+{
+ dphy_pll_clear_reg(dsi);
+ clk_disable_unprepare(dsi->clk_ref);
+}
+
+static int imx93_dsi_get_phy_configure_opts(struct imx93_dsi *dsi,
+ const struct drm_display_mode *mode,
+ union phy_configure_opts *phy_cfg,
+ u32 lanes, u32 format)
+{
+ struct device *dev = dsi->dev;
+ int bpp;
+ int ret;
+
+ bpp = mipi_dsi_pixel_format_to_bpp(format);
+ if (bpp < 0) {
+ dev_dbg(dev, "failed to get bpp for pixel format %d\n", format);
+ return -EINVAL;
+ }
+
+ ret = phy_mipi_dphy_get_default_config(mode->clock * MSEC_PER_SEC, bpp,
+ lanes, &phy_cfg->mipi_dphy);
+ if (ret < 0) {
+ dev_dbg(dev, "failed to get default phy cfg %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static enum drm_mode_status
+imx93_dsi_validate_mode(struct imx93_dsi *dsi, const struct drm_display_mode *mode)
+{
+ struct drm_bridge *bridge = dw_mipi_dsi_get_bridge(dsi->dmd);
+
+ /* Get the last bridge */
+ while (drm_bridge_get_next_bridge(bridge))
+ bridge = drm_bridge_get_next_bridge(bridge);
+
+ if ((bridge->ops & DRM_BRIDGE_OP_DETECT) &&
+ (bridge->ops & DRM_BRIDGE_OP_EDID)) {
+ unsigned long pixel_clock_rate = mode->clock * 1000;
+ unsigned long rounded_rate;
+
+ /* Allow +/-0.5% pixel clock rate deviation */
+ rounded_rate = clk_round_rate(dsi->clk_pixel, pixel_clock_rate);
+ if (rounded_rate < pixel_clock_rate * 995 / 1000 ||
+ rounded_rate > pixel_clock_rate * 1005 / 1000) {
+ dev_dbg(dsi->dev, "failed to round clock for mode " DRM_MODE_FMT "\n",
+ DRM_MODE_ARG(mode));
+ return MODE_NOCLOCK;
+ }
+ }
+
+ return MODE_OK;
+}
+
+static enum drm_mode_status
+imx93_dsi_validate_phy(struct imx93_dsi *dsi, const struct drm_display_mode *mode,
+ unsigned long mode_flags, u32 lanes, u32 format)
+{
+ union phy_configure_opts phy_cfg;
+ struct dphy_pll_cfg cfg = { 0 };
+ struct device *dev = dsi->dev;
+ int ret;
+
+ ret = imx93_dsi_get_phy_configure_opts(dsi, mode, &phy_cfg, lanes,
+ format);
+ if (ret < 0) {
+ dev_dbg(dev, "failed to get phy cfg opts %d\n", ret);
+ return MODE_ERROR;
+ }
+
+ ret = dphy_pll_get_configure_from_opts(dsi, &phy_cfg.mipi_dphy, &cfg);
+ if (ret < 0) {
+ dev_dbg(dev, "failed to get phy pll cfg %d\n", ret);
+ return MODE_NOCLOCK;
+ }
+
+ return MODE_OK;
+}
+
+static enum drm_mode_status
+imx93_dsi_mode_valid(void *priv_data, const struct drm_display_mode *mode,
+ unsigned long mode_flags, u32 lanes, u32 format)
+{
+ struct imx93_dsi *dsi = priv_data;
+ struct device *dev = dsi->dev;
+ enum drm_mode_status ret;
+
+ ret = imx93_dsi_validate_mode(dsi, mode);
+ if (ret != MODE_OK) {
+ dev_dbg(dev, "failed to validate mode " DRM_MODE_FMT "\n",
+ DRM_MODE_ARG(mode));
+ return ret;
+ }
+
+ ret = imx93_dsi_validate_phy(dsi, mode, mode_flags, lanes, format);
+ if (ret != MODE_OK) {
+ dev_dbg(dev, "failed to validate phy for mode " DRM_MODE_FMT "\n",
+ DRM_MODE_ARG(mode));
+ return ret;
+ }
+
+ return MODE_OK;
+}
+
+static bool imx93_dsi_mode_fixup(void *priv_data,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct imx93_dsi *dsi = priv_data;
+ unsigned long pixel_clock_rate;
+ unsigned long rounded_rate;
+
+ pixel_clock_rate = mode->clock * 1000;
+ rounded_rate = clk_round_rate(dsi->clk_pixel, pixel_clock_rate);
+
+ memcpy(adjusted_mode, mode, sizeof(*mode));
+ adjusted_mode->clock = rounded_rate / 1000;
+
+ dev_dbg(dsi->dev, "adj clock %d for mode " DRM_MODE_FMT "\n",
+ adjusted_mode->clock, DRM_MODE_ARG(mode));
+
+ return true;
+}
+
+static u32 *imx93_dsi_get_input_bus_fmts(void *priv_data,
+ struct drm_bridge *bridge,
+ struct drm_bridge_state *bridge_state,
+ struct drm_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state,
+ u32 output_fmt,
+ unsigned int *num_input_fmts)
+{
+ u32 *input_fmts, input_fmt;
+
+ *num_input_fmts = 0;
+
+ switch (output_fmt) {
+ case MEDIA_BUS_FMT_RGB888_1X24:
+ case MEDIA_BUS_FMT_RGB666_1X18:
+ case MEDIA_BUS_FMT_FIXED:
+ input_fmt = MEDIA_BUS_FMT_RGB888_1X24;
+ break;
+ case MEDIA_BUS_FMT_RGB565_1X16:
+ input_fmt = output_fmt;
+ break;
+ default:
+ return NULL;
+ }
+
+ input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL);
+ if (!input_fmts)
+ return NULL;
+ input_fmts[0] = input_fmt;
+ *num_input_fmts = 1;
+
+ return input_fmts;
+}
+
+static int imx93_dsi_phy_init(void *priv_data)
+{
+ struct imx93_dsi *dsi = priv_data;
+ unsigned int fmt = 0;
+ int ret;
+
+ switch (dsi->format) {
+ case MIPI_DSI_FMT_RGB888:
+ fmt = RGB888_TO_RGB888;
+ break;
+ case MIPI_DSI_FMT_RGB666:
+ fmt = RGB888_TO_RGB666;
+ regmap_update_bits(dsi->regmap, DISPLAY_MUX,
+ MIPI_DSI_RGB666_MAP_CFG, RGB666_CONFIG2);
+ break;
+ case MIPI_DSI_FMT_RGB666_PACKED:
+ fmt = RGB888_TO_RGB666;
+ regmap_update_bits(dsi->regmap, DISPLAY_MUX,
+ MIPI_DSI_RGB666_MAP_CFG, RGB666_CONFIG1);
+ break;
+ case MIPI_DSI_FMT_RGB565:
+ fmt = RGB565_TO_RGB565;
+ regmap_update_bits(dsi->regmap, DISPLAY_MUX,
+ MIPI_DSI_RGB565_MAP_CFG, RGB565_CONFIG1);
+ break;
+ }
+
+ regmap_update_bits(dsi->regmap, DISPLAY_MUX, LCDIF_CROSS_LINE_PATTERN, fmt);
+
+ ret = dphy_pll_init(dsi);
+ if (ret < 0) {
+ dev_err(dsi->dev, "failed to init phy pll: %d\n", ret);
+ return ret;
+ }
+
+ ret = dphy_pll_configure(dsi, &dsi->phy_cfg);
+ if (ret < 0) {
+ dev_err(dsi->dev, "failed to configure phy pll: %d\n", ret);
+ dphy_pll_uninit(dsi);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void imx93_dsi_phy_power_off(void *priv_data)
+{
+ struct imx93_dsi *dsi = priv_data;
+
+ dphy_pll_power_off(dsi);
+ dphy_pll_uninit(dsi);
+}
+
+static int
+imx93_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
+ unsigned long mode_flags, u32 lanes, u32 format,
+ unsigned int *lane_mbps)
+{
+ struct imx93_dsi *dsi = priv_data;
+ union phy_configure_opts phy_cfg;
+ struct device *dev = dsi->dev;
+ int ret;
+
+ ret = imx93_dsi_get_phy_configure_opts(dsi, mode, &phy_cfg, lanes,
+ format);
+ if (ret < 0) {
+ dev_dbg(dev, "failed to get phy cfg opts %d\n", ret);
+ return ret;
+ }
+
+ *lane_mbps = DIV_ROUND_UP(phy_cfg.mipi_dphy.hs_clk_rate, USEC_PER_SEC);
+
+ memcpy(&dsi->phy_cfg, &phy_cfg, sizeof(phy_cfg));
+
+ dev_dbg(dev, "get lane_mbps %u for mode " DRM_MODE_FMT "\n",
+ *lane_mbps, DRM_MODE_ARG(mode));
+
+ return 0;
+}
+
+/* High-Speed Transition Times */
+struct hstt {
+ unsigned int maxfreq;
+ struct dw_mipi_dsi_dphy_timing timing;
+};
+
+#define HSTT(_maxfreq, _c_lp2hs, _c_hs2lp, _d_lp2hs, _d_hs2lp) \
+{ \
+ .maxfreq = (_maxfreq), \
+ .timing = { \
+ .clk_lp2hs = (_c_lp2hs), \
+ .clk_hs2lp = (_c_hs2lp), \
+ .data_lp2hs = (_d_lp2hs), \
+ .data_hs2lp = (_d_hs2lp), \
+ } \
+}
+
+/* DPHY Databook Table A-4 High-Speed Transition Times */
+static const struct hstt hstt_table[] = {
+ HSTT(80, 21, 17, 15, 10),
+ HSTT(90, 23, 17, 16, 10),
+ HSTT(100, 22, 17, 16, 10),
+ HSTT(110, 25, 18, 17, 11),
+ HSTT(120, 26, 20, 18, 11),
+ HSTT(130, 27, 19, 19, 11),
+ HSTT(140, 27, 19, 19, 11),
+ HSTT(150, 28, 20, 20, 12),
+ HSTT(160, 30, 21, 22, 13),
+ HSTT(170, 30, 21, 23, 13),
+ HSTT(180, 31, 21, 23, 13),
+ HSTT(190, 32, 22, 24, 13),
+ HSTT(205, 35, 22, 25, 13),
+ HSTT(220, 37, 26, 27, 15),
+ HSTT(235, 38, 28, 27, 16),
+ HSTT(250, 41, 29, 30, 17),
+ HSTT(275, 43, 29, 32, 18),
+ HSTT(300, 45, 32, 35, 19),
+ HSTT(325, 48, 33, 36, 18),
+ HSTT(350, 51, 35, 40, 20),
+ HSTT(400, 59, 37, 44, 21),
+ HSTT(450, 65, 40, 49, 23),
+ HSTT(500, 71, 41, 54, 24),
+ HSTT(550, 77, 44, 57, 26),
+ HSTT(600, 82, 46, 64, 27),
+ HSTT(650, 87, 48, 67, 28),
+ HSTT(700, 94, 52, 71, 29),
+ HSTT(750, 99, 52, 75, 31),
+ HSTT(800, 105, 55, 82, 32),
+ HSTT(850, 110, 58, 85, 32),
+ HSTT(900, 115, 58, 88, 35),
+ HSTT(950, 120, 62, 93, 36),
+ HSTT(1000, 128, 63, 99, 38),
+ HSTT(1050, 132, 65, 102, 38),
+ HSTT(1100, 138, 67, 106, 39),
+ HSTT(1150, 146, 69, 112, 42),
+ HSTT(1200, 151, 71, 117, 43),
+ HSTT(1250, 153, 74, 120, 45),
+ HSTT(1300, 160, 73, 124, 46),
+ HSTT(1350, 165, 76, 130, 47),
+ HSTT(1400, 172, 78, 134, 49),
+ HSTT(1450, 177, 80, 138, 49),
+ HSTT(1500, 183, 81, 143, 52),
+ HSTT(1550, 191, 84, 147, 52),
+ HSTT(1600, 194, 85, 152, 52),
+ HSTT(1650, 201, 86, 155, 53),
+ HSTT(1700, 208, 88, 161, 53),
+ HSTT(1750, 212, 89, 165, 53),
+ HSTT(1800, 220, 90, 171, 54),
+ HSTT(1850, 223, 92, 175, 54),
+ HSTT(1900, 231, 91, 180, 55),
+ HSTT(1950, 236, 95, 185, 56),
+ HSTT(2000, 243, 97, 190, 56),
+ HSTT(2050, 248, 99, 194, 58),
+ HSTT(2100, 252, 100, 199, 59),
+ HSTT(2150, 259, 102, 204, 61),
+ HSTT(2200, 266, 105, 210, 62),
+ HSTT(2250, 269, 109, 213, 63),
+ HSTT(2300, 272, 109, 217, 65),
+ HSTT(2350, 281, 112, 225, 66),
+ HSTT(2400, 283, 115, 226, 66),
+ HSTT(2450, 282, 115, 226, 67),
+ HSTT(2500, 281, 118, 227, 67),
+};
+
+static int imx93_dsi_phy_get_timing(void *priv_data, unsigned int lane_mbps,
+ struct dw_mipi_dsi_dphy_timing *timing)
+{
+ struct imx93_dsi *dsi = priv_data;
+ struct device *dev = dsi->dev;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(hstt_table); i++)
+ if (lane_mbps <= hstt_table[i].maxfreq)
+ break;
+
+ if (i == ARRAY_SIZE(hstt_table)) {
+ dev_err(dev, "failed to get phy timing for lane_mbps %u\n",
+ lane_mbps);
+ return -EINVAL;
+ }
+
+ *timing = hstt_table[i].timing;
+
+ dev_dbg(dev, "get phy timing for %u <= %u (lane_mbps)\n",
+ lane_mbps, hstt_table[i].maxfreq);
+
+ return 0;
+}
+
+static const struct dw_mipi_dsi_phy_ops imx93_dsi_phy_ops = {
+ .init = imx93_dsi_phy_init,
+ .power_off = imx93_dsi_phy_power_off,
+ .get_lane_mbps = imx93_dsi_get_lane_mbps,
+ .get_timing = imx93_dsi_phy_get_timing,
+};
+
+static int imx93_dsi_host_attach(void *priv_data, struct mipi_dsi_device *device)
+{
+ struct imx93_dsi *dsi = priv_data;
+
+ dsi->format = device->format;
+
+ return 0;
+}
+
+static const struct dw_mipi_dsi_host_ops imx93_dsi_host_ops = {
+ .attach = imx93_dsi_host_attach,
+};
+
+static int imx93_dsi_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct imx93_dsi *dsi;
+ int ret;
+
+ dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
+ if (!dsi)
+ return -ENOMEM;
+
+ dsi->regmap = syscon_regmap_lookup_by_phandle(np, "fsl,media-blk-ctrl");
+ if (IS_ERR(dsi->regmap)) {
+ ret = PTR_ERR(dsi->regmap);
+ dev_err(dev, "failed to get block ctrl regmap: %d\n", ret);
+ return ret;
+ }
+
+ dsi->clk_pixel = devm_clk_get(dev, "pix");
+ if (IS_ERR(dsi->clk_pixel))
+ return dev_err_probe(dev, PTR_ERR(dsi->clk_pixel),
+ "failed to get pixel clock\n");
+
+ dsi->clk_cfg = devm_clk_get(dev, "phy_cfg");
+ if (IS_ERR(dsi->clk_cfg))
+ return dev_err_probe(dev, PTR_ERR(dsi->clk_cfg),
+ "failed to get phy cfg clock\n");
+
+ dsi->clk_ref = devm_clk_get(dev, "phy_ref");
+ if (IS_ERR(dsi->clk_ref))
+ return dev_err_probe(dev, PTR_ERR(dsi->clk_ref),
+ "failed to get phy ref clock\n");
+
+ dsi->ref_clk_rate = clk_get_rate(dsi->clk_ref);
+ if (dsi->ref_clk_rate < REF_CLK_RATE_MIN ||
+ dsi->ref_clk_rate > REF_CLK_RATE_MAX) {
+ dev_err(dev, "invalid phy ref clock rate %lu\n",
+ dsi->ref_clk_rate);
+ return -EINVAL;
+ }
+ dev_dbg(dev, "phy ref clock rate: %lu\n", dsi->ref_clk_rate);
+
+ dsi->dev = dev;
+ dsi->pdata.max_data_lanes = 4;
+ dsi->pdata.mode_valid = imx93_dsi_mode_valid;
+ dsi->pdata.mode_fixup = imx93_dsi_mode_fixup;
+ dsi->pdata.get_input_bus_fmts = imx93_dsi_get_input_bus_fmts;
+ dsi->pdata.phy_ops = &imx93_dsi_phy_ops;
+ dsi->pdata.host_ops = &imx93_dsi_host_ops;
+ dsi->pdata.priv_data = dsi;
+ platform_set_drvdata(pdev, dsi);
+
+ dsi->dmd = dw_mipi_dsi_probe(pdev, &dsi->pdata);
+ if (IS_ERR(dsi->dmd))
+ return dev_err_probe(dev, PTR_ERR(dsi->dmd),
+ "failed to probe dw_mipi_dsi\n");
+
+ return 0;
+}
+
+static void imx93_dsi_remove(struct platform_device *pdev)
+{
+ struct imx93_dsi *dsi = platform_get_drvdata(pdev);
+
+ dw_mipi_dsi_remove(dsi->dmd);
+}
+
+static const struct of_device_id imx93_dsi_dt_ids[] = {
+ { .compatible = "fsl,imx93-mipi-dsi", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx93_dsi_dt_ids);
+
+static struct platform_driver imx93_dsi_driver = {
+ .probe = imx93_dsi_probe,
+ .remove_new = imx93_dsi_remove,
+ .driver = {
+ .of_match_table = imx93_dsi_dt_ids,
+ .name = "imx93_mipi_dsi",
+ },
+};
+module_platform_driver(imx93_dsi_driver);
+
+MODULE_DESCRIPTION("Freescale i.MX93 MIPI DSI driver");
+MODULE_AUTHOR("Liu Ying <victor.liu@nxp.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
index 7835738a532e..e971b75e90ad 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
@@ -929,9 +929,9 @@ retry:
init_waitqueue_head(&lt9611uxc->wq);
INIT_WORK(&lt9611uxc->work, lt9611uxc_hpd_work);
- ret = devm_request_threaded_irq(dev, client->irq, NULL,
- lt9611uxc_irq_thread_handler,
- IRQF_ONESHOT, "lt9611uxc", lt9611uxc);
+ ret = request_threaded_irq(client->irq, NULL,
+ lt9611uxc_irq_thread_handler,
+ IRQF_ONESHOT, "lt9611uxc", lt9611uxc);
if (ret) {
dev_err(dev, "failed to request irq\n");
goto err_disable_regulators;
@@ -967,6 +967,8 @@ retry:
return lt9611uxc_audio_init(dev, lt9611uxc);
err_remove_bridge:
+ free_irq(client->irq, lt9611uxc);
+ cancel_work_sync(&lt9611uxc->work);
drm_bridge_remove(&lt9611uxc->bridge);
err_disable_regulators:
@@ -983,7 +985,7 @@ static void lt9611uxc_remove(struct i2c_client *client)
{
struct lt9611uxc *lt9611uxc = i2c_get_clientdata(client);
- disable_irq(client->irq);
+ free_irq(client->irq, lt9611uxc);
cancel_work_sync(&lt9611uxc->work);
lt9611uxc_audio_exit(lt9611uxc);
drm_bridge_remove(&lt9611uxc->bridge);
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 460db3c8a08c..e93083bbec9d 100644
--- a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
+++ b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
@@ -65,12 +65,11 @@ struct ge_b850v3_lvds {
static struct ge_b850v3_lvds *ge_b850v3_lvds_ptr;
-static u8 *stdp2690_get_edid(struct i2c_client *client)
+static int stdp2690_read_block(void *context, u8 *buf, unsigned int block, size_t len)
{
+ struct i2c_client *client = context;
struct i2c_adapter *adapter = client->adapter;
- unsigned char start = 0x00;
- unsigned int total_size;
- u8 *block = kmalloc(EDID_LENGTH, GFP_KERNEL);
+ unsigned char start = block * EDID_LENGTH;
struct i2c_msg msgs[] = {
{
@@ -81,53 +80,15 @@ static u8 *stdp2690_get_edid(struct i2c_client *client)
}, {
.addr = client->addr,
.flags = I2C_M_RD,
- .len = EDID_LENGTH,
- .buf = block,
+ .len = len,
+ .buf = buf,
}
};
- if (!block)
- return NULL;
+ if (i2c_transfer(adapter, msgs, 2) != 2)
+ return -1;
- if (i2c_transfer(adapter, msgs, 2) != 2) {
- DRM_ERROR("Unable to read EDID.\n");
- goto err;
- }
-
- if (!drm_edid_block_valid(block, 0, false, NULL)) {
- DRM_ERROR("Invalid EDID data\n");
- goto err;
- }
-
- total_size = (block[EDID_EXT_BLOCK_CNT] + 1) * EDID_LENGTH;
- if (total_size > EDID_LENGTH) {
- kfree(block);
- block = kmalloc(total_size, GFP_KERNEL);
- if (!block)
- return NULL;
-
- /* Yes, read the entire buffer, and do not skip the first
- * EDID_LENGTH bytes.
- */
- start = 0x00;
- msgs[1].len = total_size;
- msgs[1].buf = block;
-
- if (i2c_transfer(adapter, msgs, 2) != 2) {
- DRM_ERROR("Unable to read EDID extension blocks.\n");
- goto err;
- }
- if (!drm_edid_block_valid(block, 1, false, NULL)) {
- DRM_ERROR("Invalid EDID data\n");
- goto err;
- }
- }
-
- return block;
-
-err:
- kfree(block);
- return NULL;
+ return 0;
}
static struct edid *ge_b850v3_lvds_get_edid(struct drm_bridge *bridge,
@@ -137,7 +98,7 @@ static struct edid *ge_b850v3_lvds_get_edid(struct drm_bridge *bridge,
client = ge_b850v3_lvds_ptr->stdp2690_i2c;
- return (struct edid *)stdp2690_get_edid(client);
+ return drm_do_get_edid(connector, stdp2690_read_block, client);
}
static int ge_b850v3_lvds_get_modes(struct drm_connector *connector)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index a8dd2a2e7c7b..824fb3c65742 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -12,6 +12,8 @@
#include <linux/component.h>
#include <linux/debugfs.h>
#include <linux/iopoll.h>
+#include <linux/math64.h>
+#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
@@ -22,6 +24,7 @@
#include <drm/bridge/dw_mipi_dsi.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h>
+#include <drm/drm_connector.h>
#include <drm/drm_crtc.h>
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_modes.h>
@@ -538,6 +541,59 @@ static const struct mipi_dsi_host_ops dw_mipi_dsi_host_ops = {
.transfer = dw_mipi_dsi_host_transfer,
};
+static u32 *
+dw_mipi_dsi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
+ struct drm_bridge_state *bridge_state,
+ struct drm_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state,
+ u32 output_fmt,
+ unsigned int *num_input_fmts)
+{
+ struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
+ const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data;
+ u32 *input_fmts;
+
+ if (pdata->get_input_bus_fmts)
+ return pdata->get_input_bus_fmts(pdata->priv_data,
+ bridge, bridge_state,
+ crtc_state, conn_state,
+ output_fmt, num_input_fmts);
+
+ /* Fall back to MEDIA_BUS_FMT_FIXED as the only input format. */
+ input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL);
+ if (!input_fmts)
+ return NULL;
+ input_fmts[0] = MEDIA_BUS_FMT_FIXED;
+ *num_input_fmts = 1;
+
+ return input_fmts;
+}
+
+static int dw_mipi_dsi_bridge_atomic_check(struct drm_bridge *bridge,
+ struct drm_bridge_state *bridge_state,
+ struct drm_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state)
+{
+ struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
+ const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data;
+ bool ret;
+
+ bridge_state->input_bus_cfg.flags =
+ DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE;
+
+ if (pdata->mode_fixup) {
+ ret = pdata->mode_fixup(pdata->priv_data, &crtc_state->mode,
+ &crtc_state->adjusted_mode);
+ if (!ret) {
+ DRM_DEBUG_DRIVER("failed to fixup mode " DRM_MODE_FMT "\n",
+ DRM_MODE_ARG(&crtc_state->mode));
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi)
{
u32 val;
@@ -630,7 +686,7 @@ static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi)
* timeout clock division should be computed with the
* high speed transmission counter timeout and byte lane...
*/
- dsi_write(dsi, DSI_CLKMGR_CFG, TO_CLK_DIVISION(10) |
+ dsi_write(dsi, DSI_CLKMGR_CFG, TO_CLK_DIVISION(0) |
TX_ESC_CLK_DIVISION(esc_clk_division));
}
@@ -693,7 +749,7 @@ static void dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi *dsi)
* compute high speed transmission counter timeout according
* to the timeout clock division (TO_CLK_DIVISION) and byte lane...
*/
- dsi_write(dsi, DSI_TO_CNT_CFG, HSTX_TO_CNT(1000) | LPRX_TO_CNT(1000));
+ dsi_write(dsi, DSI_TO_CNT_CFG, HSTX_TO_CNT(0) | LPRX_TO_CNT(0));
/*
* TODO dw drv improvements
* the Bus-Turn-Around Timeout Counter should be computed
@@ -703,20 +759,45 @@ static void dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi *dsi)
dsi_write(dsi, DSI_MODE_CFG, ENABLE_CMD_MODE);
}
+static const u32 minimum_lbccs[] = {10, 5, 4, 3};
+
+static inline u32 dw_mipi_dsi_get_minimum_lbcc(struct dw_mipi_dsi *dsi)
+{
+ return minimum_lbccs[dsi->lanes - 1];
+}
+
/* Get lane byte clock cycles. */
static u32 dw_mipi_dsi_get_hcomponent_lbcc(struct dw_mipi_dsi *dsi,
const struct drm_display_mode *mode,
u32 hcomponent)
{
- u32 frac, lbcc;
+ u32 frac, lbcc, minimum_lbcc;
+ int bpp;
- lbcc = hcomponent * dsi->lane_mbps * MSEC_PER_SEC / 8;
+ if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) {
+ /* lbcc based on lane_mbps */
+ lbcc = hcomponent * dsi->lane_mbps * MSEC_PER_SEC / 8;
+ } else {
+ /* lbcc based on pixel clock rate */
+ bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
+ if (bpp < 0) {
+ dev_err(dsi->dev, "failed to get bpp\n");
+ return 0;
+ }
+
+ lbcc = div_u64((u64)hcomponent * mode->clock * bpp, dsi->lanes * 8);
+ }
frac = lbcc % mode->clock;
lbcc = lbcc / mode->clock;
if (frac)
lbcc++;
+ minimum_lbcc = dw_mipi_dsi_get_minimum_lbcc(dsi);
+
+ if (lbcc < minimum_lbcc)
+ lbcc = minimum_lbcc;
+
return lbcc;
}
@@ -1006,6 +1087,8 @@ static int dw_mipi_dsi_bridge_attach(struct drm_bridge *bridge,
static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = {
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+ .atomic_get_input_bus_fmts = dw_mipi_dsi_bridge_atomic_get_input_bus_fmts,
+ .atomic_check = dw_mipi_dsi_bridge_atomic_check,
.atomic_reset = drm_atomic_helper_bridge_reset,
.atomic_pre_enable = dw_mipi_dsi_bridge_atomic_pre_enable,
.atomic_enable = dw_mipi_dsi_bridge_atomic_enable,
@@ -1209,6 +1292,12 @@ void dw_mipi_dsi_set_slave(struct dw_mipi_dsi *dsi, struct dw_mipi_dsi *slave)
}
EXPORT_SYMBOL_GPL(dw_mipi_dsi_set_slave);
+struct drm_bridge *dw_mipi_dsi_get_bridge(struct dw_mipi_dsi *dsi)
+{
+ return &dsi->bridge;
+}
+EXPORT_SYMBOL_GPL(dw_mipi_dsi_get_bridge);
+
/*
* Probe/remove API, used from platforms based on the DRM bridge API.
*/
diff --git a/drivers/gpu/drm/ci/arm.config b/drivers/gpu/drm/ci/arm.config
index 871f4de063ad..411e814819a8 100644
--- a/drivers/gpu/drm/ci/arm.config
+++ b/drivers/gpu/drm/ci/arm.config
@@ -24,6 +24,7 @@ CONFIG_DRM_LIMA=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_PWM_CROS_EC=y
CONFIG_BACKLIGHT_PWM=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_ROCKCHIP_CDN_DP=n
diff --git a/drivers/gpu/drm/ci/arm64.config b/drivers/gpu/drm/ci/arm64.config
index 817e18ddfd4f..b4f653417883 100644
--- a/drivers/gpu/drm/ci/arm64.config
+++ b/drivers/gpu/drm/ci/arm64.config
@@ -26,6 +26,7 @@ CONFIG_DRM_ETNAVIV=y
CONFIG_DRM_I2C_ADV7511=y
CONFIG_PWM_CROS_EC=y
CONFIG_BACKLIGHT_PWM=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_ROCKCHIP_CDN_DP=n
@@ -61,6 +62,7 @@ CONFIG_PHY_QCOM_QUSB2=y
CONFIG_PHY_QCOM_QMP=y
CONFIG_MSM_GCC_8996=y
CONFIG_QCOM_CLK_APCC_MSM8996=y
+CONFIG_MSM_MMCC_8996=y
CONFIG_QCOM_LLCC=y
CONFIG_QCOM_LMH=y
CONFIG_QCOM_SPMI_TEMP_ALARM=y
diff --git a/drivers/gpu/drm/ci/build.sh b/drivers/gpu/drm/ci/build.sh
index 7b014287a041..e5c5dcedd108 100644
--- a/drivers/gpu/drm/ci/build.sh
+++ b/drivers/gpu/drm/ci/build.sh
@@ -35,7 +35,7 @@ elif [[ "$KERNEL_ARCH" = "arm" ]]; then
apt-get install -y libssl-dev:armhf
else
GCC_ARCH="x86_64-linux-gnu"
- DEBIAN_ARCH="x86_64"
+ DEBIAN_ARCH="amd64"
DEVICE_TREES=""
fi
@@ -64,10 +64,15 @@ if [ "$(git ls-remote --exit-code --heads ${UPSTREAM_REPO} ${TARGET_BRANCH}-exte
fi
# Try to merge fixes from local repo if this isn't a merge request
+# otherwise try merging the fixes from the merge target
if [ -z "$CI_MERGE_REQUEST_PROJECT_PATH" ]; then
if [ "$(git ls-remote --exit-code --heads origin ${TARGET_BRANCH}-external-fixes)" ]; then
git pull origin ${TARGET_BRANCH}-external-fixes
fi
+else
+ if [ "$(git ls-remote --exit-code --heads ${CI_MERGE_REQUEST_PROJECT_URL} ${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}-external-fixes)" ]; then
+ git pull ${CI_MERGE_REQUEST_PROJECT_URL} ${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}-external-fixes
+ fi
fi
for opt in $ENABLE_KCONFIGS; do
@@ -148,6 +153,7 @@ 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
for image in ${KERNEL_IMAGE_NAME}; do
cp /lava-files/$image artifacts/install/.
diff --git a/drivers/gpu/drm/ci/build.yml b/drivers/gpu/drm/ci/build.yml
index e6503f1c5927..17ab38304885 100644
--- a/drivers/gpu/drm/ci/build.yml
+++ b/drivers/gpu/drm/ci/build.yml
@@ -1,6 +1,7 @@
.build:
extends:
- .build-rules
+ - .container+build-rules
stage: build
artifacts:
paths:
diff --git a/drivers/gpu/drm/ci/gitlab-ci.yml b/drivers/gpu/drm/ci/gitlab-ci.yml
index 2c4df53f5dfe..aeb9bab1b069 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 0dc961645c4f0241f8512cb0ec3ad59635842072
+ DRM_CI_COMMIT_SHA: &drm-ci-commit-sha edfbf74df1d4d6ce54ffe24566108be0e1a98c3d
UPSTREAM_REPO: git://anongit.freedesktop.org/drm/drm
TARGET_BRANCH: drm-next
- IGT_VERSION: 471bfababd070e1dac0ebb87470ac4f2ae85e663
+ IGT_VERSION: d1db7333d9c5fbbb05e50b0804123950d9dc1c46
DEQP_RUNNER_GIT_URL: https://gitlab.freedesktop.org/anholt/deqp-runner.git
DEQP_RUNNER_GIT_TAG: v0.15.0
@@ -24,7 +24,9 @@ variables:
PIPELINE_ARTIFACTS_BASE: ${S3_HOST}/artifacts/${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_IMAGE_BASE: https://${S3_HOST}/mesa-lava/gfx-ci/linux/v6.4.12-for-mesa-ci-f6b4ad45f48d
+ LAVA_TAGS: subset-1-gfx
LAVA_JOB_PRIORITY: 30
default:
@@ -53,20 +55,6 @@ default:
export CI_JOB_JWT="$(<${CI_JOB_JWT_FILE})" &&
rm "${CI_JOB_JWT_FILE}"
- # Retry when job fails.
- retry:
- max: 1
- # Ignore runner_unsupported, stale_schedule, archived_failure, or
- # unmet_prerequisites
- when:
- - api_failure
- - runner_system_failure
- - script_failure
- - job_execution_timeout
- - scheduler_failure
- - data_integrity_failure
- - unknown_failure
-
include:
- project: 'freedesktop/ci-templates'
ref: 16bc29078de5e0a067ff84a1a199a3760d3b3811
@@ -86,6 +74,17 @@ include:
- '/.gitlab-ci/container/gitlab-ci.yml'
- '/.gitlab-ci/test/gitlab-ci.yml'
- '/.gitlab-ci/lava/lava-gitlab-ci.yml'
+ - '/src/microsoft/ci/gitlab-ci-inc.yml'
+ - '/src/gallium/drivers/zink/ci/gitlab-ci-inc.yml'
+ - '/src/gallium/drivers/crocus/ci/gitlab-ci-inc.yml'
+ - '/src/gallium/drivers/softpipe/ci/gitlab-ci-inc.yml'
+ - '/src/gallium/drivers/llvmpipe/ci/gitlab-ci-inc.yml'
+ - '/src/gallium/drivers/virgl/ci/gitlab-ci-inc.yml'
+ - '/src/gallium/drivers/nouveau/ci/gitlab-ci-inc.yml'
+ - '/src/gallium/frontends/lavapipe/ci/gitlab-ci-inc.yml'
+ - '/src/intel/ci/gitlab-ci-inc.yml'
+ - '/src/freedreno/ci/gitlab-ci-inc.yml'
+ - '/src/amd/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
@@ -154,6 +153,11 @@ stages:
# Run automatically once all dependency jobs have passed
- when: on_success
+# When to automatically run the CI for container jobs
+.container+build-rules:
+ rules:
+ - !reference [.no_scheduled_pipelines-rules, rules]
+ - when: manual
.ci-deqp-artifacts:
artifacts:
diff --git a/drivers/gpu/drm/ci/igt_runner.sh b/drivers/gpu/drm/ci/igt_runner.sh
index 2bb759165063..2f815ee3a8a3 100755
--- a/drivers/gpu/drm/ci/igt_runner.sh
+++ b/drivers/gpu/drm/ci/igt_runner.sh
@@ -20,11 +20,16 @@ set +e
cat /sys/kernel/debug/dri/*/state
set -e
-# Cannot use HWCI_KERNEL_MODULES as at that point we don't have the module in /lib
-if [ "$IGT_FORCE_DRIVER" = "amdgpu" ]; then
- mv /install/modules/lib/modules/* /lib/modules/.
- modprobe amdgpu
-fi
+case "$DRIVER_NAME" in
+ rockchip|mediatek|meson)
+ export IGT_FORCE_DRIVER="panfrost"
+ ;;
+ amdgpu)
+ # 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
+ ;;
+esac
if [ -e "/install/xfails/$DRIVER_NAME-$GPU_VERSION-skips.txt" ]; then
IGT_SKIPS="--skips /install/xfails/$DRIVER_NAME-$GPU_VERSION-skips.txt"
@@ -48,6 +53,20 @@ 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 /
+
+# 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
+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
+ # Add the line to the file
+ echo "core_getversion" >> /install/testlist.txt
+fi
+
set +e
igt-runner \
run \
@@ -57,8 +76,6 @@ igt-runner \
$IGT_SKIPS \
$IGT_FLAKES \
$IGT_FAILS \
- --fraction-start $CI_NODE_INDEX \
- --fraction $CI_NODE_TOTAL \
--jobs 1
ret=$?
set -e
diff --git a/drivers/gpu/drm/ci/image-tags.yml b/drivers/gpu/drm/ci/image-tags.yml
index f051b6c547c5..7ab4f2514da8 100644
--- a/drivers/gpu/drm/ci/image-tags.yml
+++ b/drivers/gpu/drm/ci/image-tags.yml
@@ -1,12 +1,12 @@
variables:
- CONTAINER_TAG: "2023-08-10-mesa-uprev"
+ CONTAINER_TAG: "2023-10-11-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: "${CONTAINER_TAG}"
+ DEBIAN_BUILD_TAG: "2023-10-08-config"
- KERNEL_ROOTFS_TAG: "${CONTAINER_TAG}"
+ KERNEL_ROOTFS_TAG: "2023-10-06-amd"
DEBIAN_X86_64_TEST_BASE_IMAGE: "debian/x86_64_test-base"
DEBIAN_X86_64_TEST_IMAGE_GL_PATH: "debian/x86_64_test-gl"
diff --git a/drivers/gpu/drm/ci/lava-submit.sh b/drivers/gpu/drm/ci/lava-submit.sh
index 0c4456b21b0f..3d39b0c916a8 100755
--- a/drivers/gpu/drm/ci/lava-submit.sh
+++ b/drivers/gpu/drm/ci/lava-submit.sh
@@ -22,7 +22,7 @@ cp "$SCRIPTS_DIR"/setup-test-env.sh results/job-rootfs-overlay/
# Prepare env vars for upload.
section_start variables "Variables passed through:"
-KERNEL_IMAGE_BASE_URL="https://${BASE_SYSTEM_HOST_PATH}" \
+KERNEL_IMAGE_BASE="https://${BASE_SYSTEM_HOST_PATH}" \
artifacts/ci-common/generate-env.sh | tee results/job-rootfs-overlay/set-job-env-vars.sh
section_end variables
@@ -37,8 +37,8 @@ PYTHONPATH=artifacts/ artifacts/lava/lava_job_submitter.py \
--dump-yaml \
--pipeline-info "$CI_JOB_NAME: $CI_PIPELINE_URL on $CI_COMMIT_REF_NAME ${CI_NODE_INDEX}/${CI_NODE_TOTAL}" \
--rootfs-url-prefix "https://${BASE_SYSTEM_HOST_PATH}" \
- --kernel-url-prefix "https://${PIPELINE_ARTIFACTS_BASE}/${ARCH}" \
- --build-url "${FDO_HTTP_CACHE_URI:-}https://${PIPELINE_ARTIFACTS_BASE}/${ARCH}/kernel-files.tar.zst" \
+ --kernel-url-prefix "https://${PIPELINE_ARTIFACTS_BASE}/${DEBIAN_ARCH}" \
+ --build-url "${FDO_HTTP_CACHE_URI:-}https://${PIPELINE_ARTIFACTS_BASE}/${DEBIAN_ARCH}/kernel-files.tar.zst" \
--job-rootfs-overlay-url "${FDO_HTTP_CACHE_URI:-}https://${JOB_ROOTFS_OVERLAY_PATH}" \
--job-timeout-min ${JOB_TIMEOUT:-80} \
--first-stage-init artifacts/ci-common/init-stage1.sh \
diff --git a/drivers/gpu/drm/ci/test.yml b/drivers/gpu/drm/ci/test.yml
index 6473cddaa7a9..f285ed67eb3d 100644
--- a/drivers/gpu/drm/ci/test.yml
+++ b/drivers/gpu/drm/ci/test.yml
@@ -23,7 +23,7 @@
- .lava-test:arm32
variables:
HWCI_TEST_SCRIPT: "/install/igt_runner.sh"
- ARCH: "armhf"
+ DEBIAN_ARCH: "armhf"
dependencies:
- testing:arm32
needs:
@@ -38,7 +38,7 @@
- .lava-test:arm64
variables:
HWCI_TEST_SCRIPT: "/install/igt_runner.sh"
- ARCH: "arm64"
+ DEBIAN_ARCH: "arm64"
dependencies:
- testing:arm64
needs:
@@ -53,7 +53,7 @@
- .lava-test:x86_64
variables:
HWCI_TEST_SCRIPT: "/install/igt_runner.sh"
- ARCH: "x86_64"
+ DEBIAN_ARCH: "amd64"
dependencies:
- testing:x86_64
needs:
@@ -86,7 +86,7 @@ msm:sc7180:
extends:
- .lava-igt:arm64
stage: msm
- parallel: 2
+ parallel: 4
variables:
DRIVER_NAME: msm
DEVICE_TYPE: sc7180-trogdor-lazor-limozeen
@@ -155,7 +155,7 @@ rockchip:rk3399:
extends:
- .lava-igt:arm64
stage: rockchip
- parallel: 3
+ parallel: 2
variables:
DRIVER_NAME: rockchip
DEVICE_TYPE: rk3399-gru-kevin
@@ -178,7 +178,8 @@ rockchip:rk3399:
i915:apl:
extends:
- .i915
- parallel: 12
+ parallel: 3
+ timeout: "1h30m"
variables:
DEVICE_TYPE: asus-C523NA-A20057-coral
GPU_VERSION: apl
@@ -187,7 +188,8 @@ i915:apl:
i915:glk:
extends:
- .i915
- parallel: 5
+ parallel: 2
+ timeout: "1h30m"
variables:
DEVICE_TYPE: hp-x360-12b-ca0010nr-n4020-octopus
GPU_VERSION: glk
@@ -196,7 +198,8 @@ i915:glk:
i915:amly:
extends:
- .i915
- parallel: 8
+ parallel: 2
+ timeout: "1h30m"
variables:
DEVICE_TYPE: asus-C433TA-AJ0005-rammus
GPU_VERSION: amly
@@ -205,7 +208,7 @@ i915:amly:
i915:kbl:
extends:
- .i915
- parallel: 5
+ parallel: 3
variables:
DEVICE_TYPE: hp-x360-14-G1-sona
GPU_VERSION: kbl
@@ -214,7 +217,8 @@ i915:kbl:
i915:whl:
extends:
- .i915
- parallel: 8
+ parallel: 2
+ timeout: "1h30m"
variables:
DEVICE_TYPE: dell-latitude-5400-8665U-sarien
GPU_VERSION: whl
@@ -223,7 +227,8 @@ i915:whl:
i915:cml:
extends:
- .i915
- parallel: 6
+ parallel: 2
+ timeout: "1h30m"
variables:
DEVICE_TYPE: asus-C436FA-Flip-hatch
GPU_VERSION: cml
@@ -232,7 +237,7 @@ i915:cml:
i915:tgl:
extends:
- .i915
- parallel: 6
+ parallel: 8
variables:
DEVICE_TYPE: asus-cx9400-volteer
GPU_VERSION: tgl
@@ -251,6 +256,7 @@ i915:tgl:
amdgpu:stoney:
extends:
- .amdgpu
+ parallel: 2
variables:
DEVICE_TYPE: hp-11A-G6-EE-grunt
GPU_VERSION: stoney
@@ -269,6 +275,7 @@ amdgpu:stoney:
mediatek:mt8173:
extends:
- .mediatek
+ parallel: 4
variables:
DEVICE_TYPE: mt8173-elm-hana
GPU_VERSION: mt8173
@@ -280,6 +287,7 @@ mediatek:mt8173:
mediatek:mt8183:
extends:
- .mediatek
+ parallel: 3
variables:
DEVICE_TYPE: mt8183-kukui-jacuzzi-juniper-sku16
GPU_VERSION: mt8183
@@ -289,6 +297,7 @@ mediatek:mt8183:
.mediatek:mt8192:
extends:
- .mediatek
+ parallel: 3
variables:
DEVICE_TYPE: mt8192-asurada-spherion-r0
GPU_VERSION: mt8192
@@ -307,6 +316,7 @@ mediatek:mt8183:
meson:g12b:
extends:
- .meson
+ parallel: 3
variables:
DEVICE_TYPE: meson-g12b-a311d-khadas-vim3
GPU_VERSION: g12b
diff --git a/drivers/gpu/drm/ci/xfails/amdgpu-stoney-fails.txt b/drivers/gpu/drm/ci/xfails/amdgpu-stoney-fails.txt
index bd9392536e7c..ea87dc46bc2b 100644
--- a/drivers/gpu/drm/ci/xfails/amdgpu-stoney-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/amdgpu-stoney-fails.txt
@@ -1,8 +1,14 @@
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@plane-immutable-zpos,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
@@ -11,9 +17,11 @@ kms_color@degamma,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_legacy@forked-move,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_plane@pixel-format,Fail
kms_plane_multiple@atomic-pipe-A-tiling-none,Fail
kms_rmfb@close-fd,Fail
kms_rotation_crc@primary-rotation-180,Fail
diff --git a/drivers/gpu/drm/ci/xfails/amdgpu-stoney-flakes.txt b/drivers/gpu/drm/ci/xfails/amdgpu-stoney-flakes.txt
index f8defa0f9e67..6faf75e667d3 100644
--- a/drivers/gpu/drm/ci/xfails/amdgpu-stoney-flakes.txt
+++ b/drivers/gpu/drm/ci/xfails/amdgpu-stoney-flakes.txt
@@ -1,21 +1 @@
-kms_addfb_basic@too-high
-kms_async_flips@alternate-sync-async-flip
kms_async_flips@async-flip-with-page-flip-events
-kms_async_flips@crc
-kms_async_flips@test-cursor
-kms_async_flips@test-time-stamp
-kms_atomic_transition@plane-all-modeset-transition-internal-panels
-kms_atomic_transition@plane-all-transition
-kms_atomic_transition@plane-use-after-nonblocking-unbind
-kms_bw@linear-tiling-1-displays-1920x1080p
-kms_bw@linear-tiling-2-displays-1920x1080p
-kms_bw@linear-tiling-2-displays-2560x1440p
-kms_bw@linear-tiling-3-displays-2560x1440p
-kms_bw@linear-tiling-3-displays-3840x2160p
-kms_cursor_crc@pipe-A-cursor-alpha-opaque
-kms_cursor_crc@pipe-B-cursor-alpha-opaque
-kms_plane@pixel-format
-kms_plane_multiple@atomic-pipe-B-tiling-none
-kms_plane_scaling@downscale-with-rotation-factor-0-5
-kms_universal_plane@disable-primary-vs-flip-pipe-A
-kms_universal_plane@disable-primary-vs-flip-pipe-B
diff --git a/drivers/gpu/drm/ci/xfails/i915-amly-fails.txt b/drivers/gpu/drm/ci/xfails/i915-amly-fails.txt
index 5f513c638beb..59438e4df86e 100644
--- a/drivers/gpu/drm/ci/xfails/i915-amly-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/i915-amly-fails.txt
@@ -2,6 +2,10 @@ 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-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
@@ -10,7 +14,12 @@ 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_plane_alpha_blend@alpha-basic,Fail
kms_plane_alpha_blend@alpha-opaque-fb,Fail
kms_plane_alpha_blend@alpha-transparent-fb,Fail
diff --git a/drivers/gpu/drm/ci/xfails/i915-amly-flakes.txt b/drivers/gpu/drm/ci/xfails/i915-amly-flakes.txt
deleted file mode 100644
index d5000515a315..000000000000
--- a/drivers/gpu/drm/ci/xfails/i915-amly-flakes.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-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_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-downscaling
-kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-upscaling
-kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-downscaling
-kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-upscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-downscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-upscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-downscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-upscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-downscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-upscaling
-kms_plane_alpha_blend@pipe-A-alpha-basic
-kms_plane_alpha_blend@pipe-A-alpha-opaque-fb
-kms_plane_alpha_blend@pipe-A-alpha-transparent-fb
-kms_plane_alpha_blend@pipe-A-constant-alpha-max
-kms_plane_alpha_blend@pipe-B-alpha-basic
-kms_plane_alpha_blend@pipe-B-alpha-opaque-fb
-kms_plane_alpha_blend@pipe-B-alpha-transparent-fb
-kms_plane_alpha_blend@pipe-B-constant-alpha-max
-kms_plane_alpha_blend@pipe-C-alpha-basic
-kms_plane_alpha_blend@pipe-C-alpha-opaque-fb
-kms_plane_alpha_blend@pipe-C-alpha-transparent-fb
-kms_plane_alpha_blend@pipe-C-constant-alpha-max
-kms_sysfs_edid_timing
diff --git a/drivers/gpu/drm/ci/xfails/i915-apl-fails.txt b/drivers/gpu/drm/ci/xfails/i915-apl-fails.txt
index 46397ce38d5a..2e3b7c5dac3c 100644
--- a/drivers/gpu/drm/ci/xfails/i915-apl-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/i915-apl-fails.txt
@@ -8,13 +8,6 @@ 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_color@ctm-0-25,Fail
-kms_color@ctm-0-50,Fail
-kms_color@ctm-0-75,Fail
-kms_color@ctm-max,Fail
-kms_color@ctm-negative,Fail
-kms_color@ctm-red-to-blue,Fail
-kms_color@ctm-signed,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
@@ -38,8 +31,6 @@ 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_hdmi_inject@inject-4k,Timeout
-kms_plane@plane-position-hole,Timeout
kms_plane_alpha_blend@alpha-basic,Fail
kms_plane_alpha_blend@alpha-opaque-fb,Fail
kms_plane_alpha_blend@alpha-transparent-fb,Fail
@@ -53,6 +44,4 @@ 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_multiple@tiling-y,Timeout
-kms_pwrite_crc,Timeout
kms_sysfs_edid_timing,Fail
diff --git a/drivers/gpu/drm/ci/xfails/i915-apl-flakes.txt b/drivers/gpu/drm/ci/xfails/i915-apl-flakes.txt
deleted file mode 100644
index 331c5841bb41..000000000000
--- a/drivers/gpu/drm/ci/xfails/i915-apl-flakes.txt
+++ /dev/null
@@ -1 +0,0 @@
-kms_frontbuffer_tracking@fbc-tiling-linear
diff --git a/drivers/gpu/drm/ci/xfails/i915-cml-fails.txt b/drivers/gpu/drm/ci/xfails/i915-cml-fails.txt
index 6139b410e767..240ef8467c26 100644
--- a/drivers/gpu/drm/ci/xfails/i915-cml-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/i915-cml-fails.txt
@@ -1,8 +1,11 @@
-kms_color@ctm-0-25,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
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
@@ -11,8 +14,17 @@ 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_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_psr2_su@page_flip-NV12,Fail
+kms_psr2_su@page_flip-P010,Fail
+kms_setmode@basic,Fail
diff --git a/drivers/gpu/drm/ci/xfails/i915-cml-flakes.txt b/drivers/gpu/drm/ci/xfails/i915-cml-flakes.txt
deleted file mode 100644
index 0514a7b3fdb0..000000000000
--- a/drivers/gpu/drm/ci/xfails/i915-cml-flakes.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-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_draw_crc@draw-method-xrgb8888-render-xtiled
-kms_flip@flip-vs-suspend
-kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-downscaling
-kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-upscaling
-kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-downscaling
-kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-upscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-downscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-upscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-downscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-upscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-downscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-upscaling
-kms_hdr@bpc-switch-suspend
-kms_plane_alpha_blend@constant-alpha-min
-kms_plane_alpha_blend@pipe-A-alpha-basic
-kms_plane_alpha_blend@pipe-A-alpha-opaque-fb
-kms_plane_alpha_blend@pipe-A-alpha-transparent-fb
-kms_plane_alpha_blend@pipe-A-constant-alpha-max
-kms_plane_alpha_blend@pipe-B-alpha-basic
-kms_plane_alpha_blend@pipe-B-alpha-opaque-fb
-kms_plane_alpha_blend@pipe-B-alpha-transparent-fb
-kms_plane_alpha_blend@pipe-B-constant-alpha-max
-kms_plane_alpha_blend@pipe-C-alpha-basic
-kms_plane_alpha_blend@pipe-C-alpha-opaque-fb
-kms_plane_alpha_blend@pipe-C-alpha-transparent-fb
-kms_plane_alpha_blend@pipe-C-constant-alpha-max
-kms_psr2_su@page_flip-NV12
-kms_psr2_su@page_flip-P010
-kms_setmode@basic
diff --git a/drivers/gpu/drm/ci/xfails/i915-glk-fails.txt b/drivers/gpu/drm/ci/xfails/i915-glk-fails.txt
index 5bd432e78129..4596055d7e5e 100644
--- a/drivers/gpu/drm/ci/xfails/i915-glk-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/i915-glk-fails.txt
@@ -1,8 +1,15 @@
kms_fbcon_fbt@fbc,Fail
+kms_flip@blocking-wf_vblank,Fail
+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
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-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
@@ -11,9 +18,19 @@ 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_frontbuffer_tracking@fbc-tiling-linear,Fail
kms_frontbuffer_tracking@fbcdrrs-tiling-linear,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_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
diff --git a/drivers/gpu/drm/ci/xfails/i915-glk-flakes.txt b/drivers/gpu/drm/ci/xfails/i915-glk-flakes.txt
deleted file mode 100644
index fc41d13a2d56..000000000000
--- a/drivers/gpu/drm/ci/xfails/i915-glk-flakes.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-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_flip@blocking-wf_vblank
-kms_flip@wf_vblank-ts-check
-kms_flip@wf_vblank-ts-check-interruptible
-kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-downscaling
-kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-upscaling
-kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-downscaling
-kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-upscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-downscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-upscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-downscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-upscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-downscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-upscaling
-kms_frontbuffer_tracking@fbc-tiling-linear
-kms_plane_alpha_blend@pipe-A-alpha-basic
-kms_plane_alpha_blend@pipe-A-alpha-opaque-fb
-kms_plane_alpha_blend@pipe-A-alpha-transparent-fb
-kms_plane_alpha_blend@pipe-A-constant-alpha-max
-kms_plane_alpha_blend@pipe-B-alpha-basic
-kms_plane_alpha_blend@pipe-B-alpha-opaque-fb
-kms_plane_alpha_blend@pipe-B-alpha-transparent-fb
-kms_plane_alpha_blend@pipe-B-constant-alpha-max
-kms_plane_alpha_blend@pipe-C-alpha-basic
-kms_plane_alpha_blend@pipe-C-alpha-opaque-fb
-kms_plane_alpha_blend@pipe-C-alpha-transparent-fb
-kms_plane_alpha_blend@pipe-C-constant-alpha-max
-kms_prop_blob@invalid-set-prop-any
-kms_rotation_crc@multiplane-rotation
-kms_rotation_crc@multiplane-rotation-cropping-bottom
-kms_rotation_crc@multiplane-rotation-cropping-top
-kms_setmode@basic
diff --git a/drivers/gpu/drm/ci/xfails/i915-kbl-fails.txt b/drivers/gpu/drm/ci/xfails/i915-kbl-fails.txt
index 56ec021a7679..dab202716909 100644
--- a/drivers/gpu/drm/ci/xfails/i915-kbl-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/i915-kbl-fails.txt
@@ -4,7 +4,10 @@ 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-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
@@ -13,8 +16,12 @@ 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
diff --git a/drivers/gpu/drm/ci/xfails/i915-kbl-flakes.txt b/drivers/gpu/drm/ci/xfails/i915-kbl-flakes.txt
index f3ba1c4c5d46..a12f888530dd 100644
--- a/drivers/gpu/drm/ci/xfails/i915-kbl-flakes.txt
+++ b/drivers/gpu/drm/ci/xfails/i915-kbl-flakes.txt
@@ -1,26 +1 @@
kms_async_flips@crc
-kms_bw@linear-tiling-2-displays-1920x1080p
-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-3840x2160p
-kms_color@ctm-0-25
-kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-downscaling
-kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-downscaling
-kms_flip_scaled_crc@flip-32bpp-ytileccs-to-64bpp-ytile-upscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-downscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-16bpp-ytile-upscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytile-upscaling
-kms_flip_scaled_crc@flip-64bpp-ytile-to-32bpp-ytilercccs-downscaling
-kms_plane_alpha_blend@pipe-A-alpha-basic
-kms_plane_alpha_blend@pipe-A-alpha-opaque-fb
-kms_plane_alpha_blend@pipe-A-alpha-transparent-fb
-kms_plane_alpha_blend@pipe-B-alpha-basic
-kms_plane_alpha_blend@pipe-B-alpha-transparent-fb
-kms_plane_alpha_blend@pipe-B-constant-alpha-max
-kms_plane_alpha_blend@pipe-C-alpha-basic
-kms_plane_alpha_blend@pipe-C-alpha-opaque-fb
-kms_plane_alpha_blend@pipe-C-alpha-transparent-fb
-kms_sysfs_edid_timing
diff --git a/drivers/gpu/drm/ci/xfails/i915-tgl-fails.txt b/drivers/gpu/drm/ci/xfails/i915-tgl-fails.txt
index a6da5544e198..27bfca1c6f2c 100644
--- a/drivers/gpu/drm/ci/xfails/i915-tgl-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/i915-tgl-fails.txt
@@ -8,7 +8,6 @@ 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_color@ctm-0-25,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
diff --git a/drivers/gpu/drm/ci/xfails/i915-tgl-flakes.txt b/drivers/gpu/drm/ci/xfails/i915-tgl-flakes.txt
deleted file mode 100644
index 1cd910ee06df..000000000000
--- a/drivers/gpu/drm/ci/xfails/i915-tgl-flakes.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-kms_draw_crc@.*
-kms_flip@blocking-absolute-wf_vblank
-kms_flip@bo-too-big-interruptible
-kms_flip@busy-flip
-kms_flip@flip-vs-rmfb-interruptible
diff --git a/drivers/gpu/drm/ci/xfails/i915-whl-flakes.txt b/drivers/gpu/drm/ci/xfails/i915-whl-flakes.txt
deleted file mode 100644
index c33202e7e2a1..000000000000
--- a/drivers/gpu/drm/ci/xfails/i915-whl-flakes.txt
+++ /dev/null
@@ -1 +0,0 @@
-kms_flip@flip-vs-suspend
diff --git a/drivers/gpu/drm/ci/xfails/mediatek-mt8173-flakes.txt b/drivers/gpu/drm/ci/xfails/mediatek-mt8173-flakes.txt
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/drivers/gpu/drm/ci/xfails/mediatek-mt8173-flakes.txt
+++ /dev/null
diff --git a/drivers/gpu/drm/ci/xfails/mediatek-mt8183-fails.txt b/drivers/gpu/drm/ci/xfails/mediatek-mt8183-fails.txt
index 6ff81d00e84e..67d690fc4037 100644
--- a/drivers/gpu/drm/ci/xfails/mediatek-mt8183-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/mediatek-mt8183-fails.txt
@@ -6,5 +6,8 @@ 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 \ No newline at end of file
+kms_rmfb@close-fd,Fail
diff --git a/drivers/gpu/drm/ci/xfails/mediatek-mt8183-flakes.txt b/drivers/gpu/drm/ci/xfails/mediatek-mt8183-flakes.txt
deleted file mode 100644
index 208890b79eb0..000000000000
--- a/drivers/gpu/drm/ci/xfails/mediatek-mt8183-flakes.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-core_setmaster_vs_auth
-kms_bw@linear-tiling-1-displays-1920x1080p
-kms_bw@linear-tiling-1-displays-3840x2160p
-kms_bw@linear-tiling-3-displays-1920x1080p
-kms_cursor_legacy@cursor-vs-flip-atomic
-kms_plane_scaling@invalid-num-scalers
-kms_plane_scaling@planes-upscale-20x20
-kms_plane_scaling@planes-upscale-20x20-downscale-factor-0-5
-kms_plane_scaling@upscale-with-modifier-20x20
-kms_plane_scaling@upscale-with-pixel-format-20x20
-kms_prop_blob@invalid-set-prop-any
-kms_properties@get_properties-sanity-atomic
-kms_properties@plane-properties-atomic
-kms_properties@plane-properties-legacy \ No newline at end of file
diff --git a/drivers/gpu/drm/ci/xfails/meson-g12b-fails.txt b/drivers/gpu/drm/ci/xfails/meson-g12b-fails.txt
index 860e702091e2..56a2ae7047b4 100644
--- a/drivers/gpu/drm/ci/xfails/meson-g12b-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/meson-g12b-fails.txt
@@ -1,12 +1,16 @@
kms_3d,Fail
-kms_properties@connector-properties-atomic,Fail
-kms_properties@get_properties-sanity-atomic,Fail
-kms_properties@get_properties-sanity-non-atomic,Fail
-kms_properties@connector-properties-legacy,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_hdmi_inject@inject-4k,Fail \ No newline at end of file
+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
diff --git a/drivers/gpu/drm/ci/xfails/meson-g12b-flakes.txt b/drivers/gpu/drm/ci/xfails/meson-g12b-flakes.txt
deleted file mode 100644
index b63329d06767..000000000000
--- a/drivers/gpu/drm/ci/xfails/meson-g12b-flakes.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-kms_force_connector_basic@force-connector-state
-kms_force_connector_basic@force-edid
-kms_force_connector_basic@force-load-detect
-kms_force_connector_basic@prune-stale-modes \ No newline at end of file
diff --git a/drivers/gpu/drm/ci/xfails/msm-apq8016-flakes.txt b/drivers/gpu/drm/ci/xfails/msm-apq8016-flakes.txt
deleted file mode 100644
index 0e3b60d3fade..000000000000
--- a/drivers/gpu/drm/ci/xfails/msm-apq8016-flakes.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-kms_force_connector_basic@force-connector-state
-kms_force_connector_basic@force-edid
-kms_force_connector_basic@force-load-detect
-kms_force_connector_basic@prune-stale-modes
diff --git a/drivers/gpu/drm/ci/xfails/msm-apq8096-fails.txt b/drivers/gpu/drm/ci/xfails/msm-apq8096-fails.txt
index 88a1fc0a3b0d..2cd49e8ee47f 100644
--- a/drivers/gpu/drm/ci/xfails/msm-apq8096-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/msm-apq8096-fails.txt
@@ -1,2 +1,4 @@
kms_3d,Fail
kms_addfb_basic@addfb25-bad-modifier,Fail
+kms_force_connector_basic@force-edid,Fail
+kms_hdmi_inject@inject-4k,Fail
diff --git a/drivers/gpu/drm/ci/xfails/msm-apq8096-flakes.txt b/drivers/gpu/drm/ci/xfails/msm-apq8096-flakes.txt
deleted file mode 100644
index 0e3b60d3fade..000000000000
--- a/drivers/gpu/drm/ci/xfails/msm-apq8096-flakes.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-kms_force_connector_basic@force-connector-state
-kms_force_connector_basic@force-edid
-kms_force_connector_basic@force-load-detect
-kms_force_connector_basic@prune-stale-modes
diff --git a/drivers/gpu/drm/ci/xfails/msm-sc7180-fails.txt b/drivers/gpu/drm/ci/xfails/msm-sc7180-fails.txt
index 14adeba3b62d..f71166a57731 100644
--- a/drivers/gpu/drm/ci/xfails/msm-sc7180-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/msm-sc7180-fails.txt
@@ -1,12 +1,17 @@
+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-negative,Fail
+kms_color@ctm-red-to-blue,Fail
+kms_color@ctm-signed,Fail
kms_cursor_legacy@cursor-vs-flip-toggle,Fail
kms_cursor_legacy@cursor-vs-flip-varying-size,Fail
kms_cursor_legacy@cursorA-vs-flipA-atomic-transitions,Crash
+kms_flip@flip-vs-modeset-vs-hang,Fail
+kms_flip@flip-vs-panning-vs-hang,Fail
kms_pipe_crc_basic@compare-crc-sanitycheck-nv12,Fail
-kms_plane@pixel-format,Fail
-kms_plane@pixel-format-source-clamping,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@coverage-7efc,Fail
kms_plane_alpha_blend@coverage-vs-premult-vs-constant,Fail
diff --git a/drivers/gpu/drm/ci/xfails/msm-sc7180-flakes.txt b/drivers/gpu/drm/ci/xfails/msm-sc7180-flakes.txt
index 636563d3e59a..04730044ed12 100644
--- a/drivers/gpu/drm/ci/xfails/msm-sc7180-flakes.txt
+++ b/drivers/gpu/drm/ci/xfails/msm-sc7180-flakes.txt
@@ -1,7 +1,17 @@
-
-# Test ends up reading CRC from frame before cursor update
-# bug
-# sometimes.. tbd if this is a kernel CRC bug or a test
-kms_cursor_crc@.*
-kms_plane_multiple@atomic-pipe-A-tiling-none
-kms_atomic_transition@modeset-transition-nonblocking-fencing,Fail \ No newline at end of file
+kms_color@ctm-0-25
+kms_color@ctm-0-50
+kms_color@ctm-0-75
+kms_color@ctm-blue-to-red
+kms_color@ctm-green-to-red
+kms_color@ctm-negative
+kms_color@ctm-red-to-blue
+kms_color@ctm-signed
+kms_flip@flip-vs-modeset-vs-hang
+kms_flip@flip-vs-panning-vs-hang
+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_writeback@writeback-fb-id
+kms_writeback@writeback-invalid-parameters
diff --git a/drivers/gpu/drm/ci/xfails/msm-sc7180-skips.txt b/drivers/gpu/drm/ci/xfails/msm-sc7180-skips.txt
index 410e0eeb3161..e59a2fddfde0 100644
--- a/drivers/gpu/drm/ci/xfails/msm-sc7180-skips.txt
+++ b/drivers/gpu/drm/ci/xfails/msm-sc7180-skips.txt
@@ -4,20 +4,4 @@
# Test incorrectly assumes that CTM support implies gamma/degamma
# LUT support. None of the subtests handle the case of only having
# CTM support
-kms_color.*
-
-# 4k@60 is not supported on this hw, but driver doesn't handle it
-# too gracefully.. https://gitlab.freedesktop.org/drm/msm/-/issues/15
-kms_bw@linear-tiling-.*-displays-3840x2160p
-
-# Until igt fix lands: https://patchwork.freedesktop.org/patch/493175/
-kms_bw@linear-tiling-2.*
-kms_bw@linear-tiling-3.*
-kms_bw@linear-tiling-4.*
-kms_bw@linear-tiling-5.*
-kms_bw@linear-tiling-6.*
-
-# igt fix posted: https://patchwork.freedesktop.org/patch/499926/
-# failure mode is flakey due to randomization but fails frequently
-# enough to be detected as a Crash or occasionally UnexpectedPass.
-kms_plane_multiple@atomic-pipe-A-tiling-none
+#kms_color.*
diff --git a/drivers/gpu/drm/ci/xfails/msm-sdm845-fails.txt b/drivers/gpu/drm/ci/xfails/msm-sdm845-fails.txt
index 09c0c623cd75..c55baa2d18c1 100644
--- a/drivers/gpu/drm/ci/xfails/msm-sdm845-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/msm-sdm845-fails.txt
@@ -15,19 +15,16 @@ 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-legacy,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@basic-flip-before-cursor-varying-size,Fail
kms_cursor_legacy@cursor-vs-flip-atomic,Fail
kms_cursor_legacy@cursor-vs-flip-atomic-transitions,Fail
kms_cursor_legacy@cursor-vs-flip-atomic-transitions-varying-size,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@cursorA-vs-flipA-toggle,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
@@ -35,11 +32,9 @@ kms_cursor_legacy@flip-vs-cursor-legacy,Fail
kms_cursor_legacy@short-flip-after-cursor-atomic-transitions,Fail
kms_cursor_legacy@short-flip-after-cursor-atomic-transitions-varying-size,Fail
kms_cursor_legacy@short-flip-after-cursor-toggle,Fail
-kms_cursor_legacy@short-flip-before-cursor-atomic-transitions,Fail
-kms_cursor_legacy@short-flip-before-cursor-atomic-transitions-varying-size,Fail
+kms_flip@flip-vs-modeset-vs-hang,Fail
+kms_flip@flip-vs-panning-vs-hang,Fail
kms_pipe_crc_basic@compare-crc-sanitycheck-nv12,Fail
-kms_plane@pixel-format,Fail
-kms_plane@pixel-format-source-clamping,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
diff --git a/drivers/gpu/drm/ci/xfails/msm-sdm845-flakes.txt b/drivers/gpu/drm/ci/xfails/msm-sdm845-flakes.txt
index 5b3aaab7ac3f..16d205c04cbb 100644
--- a/drivers/gpu/drm/ci/xfails/msm-sdm845-flakes.txt
+++ b/drivers/gpu/drm/ci/xfails/msm-sdm845-flakes.txt
@@ -1,11 +1,12 @@
-
-
-# Test ends up reading CRC from frame before cursor update
-# bug
-# sometimes.. tbd if this is a kernel CRC bug or a test
-kms_cursor_crc@.*
+kms_cursor_legacy@basic-flip-after-cursor-atomic
+kms_cursor_legacy@basic-flip-before-cursor-varying-size
+kms_cursor_legacy@cursorA-vs-flipA-toggle
+kms_cursor_legacy@flip-vs-cursor-atomic-transitions
kms_cursor_legacy@flip-vs-cursor-toggle
-kms_cursor_legacy@pipe-A-forked-bo
-kms_cursor_legacy@pipe-A-forked-move
+kms_cursor_legacy@flip-vs-cursor-varying-size
+kms_cursor_legacy@short-flip-before-cursor-atomic-transitions
kms_cursor_legacy@short-flip-before-cursor-toggle
-kms_flip@dpms-vs-vblank-race-interruptible
+kms_flip@flip-vs-modeset-vs-hang
+kms_flip@flip-vs-panning-vs-hang
+kms_plane@pixel-format
+kms_plane@pixel-format-source-clamping
diff --git a/drivers/gpu/drm/ci/xfails/requirements.txt b/drivers/gpu/drm/ci/xfails/requirements.txt
new file mode 100644
index 000000000000..d8856d1581fd
--- /dev/null
+++ b/drivers/gpu/drm/ci/xfails/requirements.txt
@@ -0,0 +1,17 @@
+git+https://gitlab.freedesktop.org/gfx-ci/ci-collate@09e7142715c16f54344ddf97013331ba063b162b
+termcolor==2.3.0
+
+# ci-collate dependencies
+certifi==2023.7.22
+charset-normalizer==3.2.0
+idna==3.4
+pip==23.2.1
+python-gitlab==3.15.0
+requests==2.31.0
+requests-toolbelt==1.0.0
+ruamel.yaml==0.17.32
+ruamel.yaml.clib==0.2.7
+setuptools==68.0.0
+tenacity==8.2.3
+urllib3==2.0.4
+wheel==0.41.1 \ No newline at end of file
diff --git a/drivers/gpu/drm/ci/xfails/rockchip-rk3288-fails.txt b/drivers/gpu/drm/ci/xfails/rockchip-rk3288-fails.txt
index 2a1baa948e12..90c63f519e9e 100644
--- a/drivers/gpu/drm/ci/xfails/rockchip-rk3288-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/rockchip-rk3288-fails.txt
@@ -5,8 +5,13 @@ 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
@@ -45,4 +50,5 @@ 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
diff --git a/drivers/gpu/drm/ci/xfails/rockchip-rk3288-flakes.txt b/drivers/gpu/drm/ci/xfails/rockchip-rk3288-flakes.txt
deleted file mode 100644
index 45c54c75c899..000000000000
--- a/drivers/gpu/drm/ci/xfails/rockchip-rk3288-flakes.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-kms_addfb_basic@addfb25-bad-modifier
-kms_cursor_crc@.*
-kms_flip@basic-flip-vs-wf_vblank
-kms_invalid_mode@int-max-clock,Crash
-kms_pipe_crc_basic@.*
-kms_properties@connector-properties-atomic,Crash
-kms_properties@get_properties-sanity-atomic,Crash
-kms_properties@get_properties-sanity-non-atomic,Crash
-kms_rmfb@close-fd
diff --git a/drivers/gpu/drm/ci/xfails/rockchip-rk3399-fails.txt b/drivers/gpu/drm/ci/xfails/rockchip-rk3399-fails.txt
index 6db08ba6b008..d516d9c1d546 100644
--- a/drivers/gpu/drm/ci/xfails/rockchip-rk3399-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/rockchip-rk3399-fails.txt
@@ -1,15 +1,40 @@
+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-wf_vblank-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
@@ -17,11 +42,21 @@ 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
@@ -31,7 +66,10 @@ 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
diff --git a/drivers/gpu/drm/ci/xfails/rockchip-rk3399-flakes.txt b/drivers/gpu/drm/ci/xfails/rockchip-rk3399-flakes.txt
index 4c0539b4beaf..c9fdc623ab91 100644
--- a/drivers/gpu/drm/ci/xfails/rockchip-rk3399-flakes.txt
+++ b/drivers/gpu/drm/ci/xfails/rockchip-rk3399-flakes.txt
@@ -1,23 +1,7 @@
-
-kms_cursor_crc@.*
+kms_bw@linear-tiling-2-displays-1920x1080p
+kms_cursor_crc@cursor-offscreen-64x21
kms_flip@dpms-vs-vblank-race-interruptible
-kms_flip@flip-vs-expired-vblank
-kms_flip@modeset-vs-vblank-race-interruptible
-kms_pipe_crc_basic@.*
-kms_pipe_crc_basic@compare-crc-sanitycheck-pipe-A
-kms_pipe_crc_basic@compare-crc-sanitycheck-pipe-B
-kms_plane@plane-position-hole
-kms_plane_multiple@atomic-pipe-A-tiling-none
-kms_plane_multiple@atomic-pipe-B-tiling-none
-kms_sequence@get-forked
-kms_sequence@get-forked-busy
-kms_setmode@basic
-kms_universal_plane@universal-plane-pipe-B-functional,UnexpectedPass
-kms_vblank@pipe-A-accuracy-idle
-kms_vblank@pipe-A-query-busy
-kms_vblank@pipe-A-query-forked-busy
-kms_vblank@pipe-A-wait-idle
-kms_vblank@pipe-B-accuracy-idle
-kms_vblank@pipe-B-query-busy
-kms_vblank@pipe-B-query-forked-busy
-kms_vblank@pipe-B-wait-idle
+kms_flip@flip-vs-wf_vblank-interruptible
+kms_plane_cursor@overlay
+kms_plane_cursor@primary
+kms_plane_cursor@viewport
diff --git a/drivers/gpu/drm/ci/xfails/update-xfails.py b/drivers/gpu/drm/ci/xfails/update-xfails.py
new file mode 100755
index 000000000000..e9f0ec7fed8d
--- /dev/null
+++ b/drivers/gpu/drm/ci/xfails/update-xfails.py
@@ -0,0 +1,204 @@
+#!/usr/bin/env python3
+
+import argparse
+from collections import defaultdict
+import difflib
+import os
+import re
+from glcollate import Collate
+from termcolor import colored
+from urllib.parse import urlparse
+
+
+def get_canonical_name(job_name):
+ return re.split(r" \d+/\d+", job_name)[0]
+
+
+def get_xfails_file_path(job_name, suffix):
+ canonical_name = get_canonical_name(job_name)
+ name = canonical_name.replace(":", "-")
+ script_dir = os.path.dirname(os.path.abspath(__file__))
+ return os.path.join(script_dir, f"{name}-{suffix}.txt")
+
+
+def get_unit_test_name_and_results(unit_test):
+ if "Artifact results/failures.csv not found" in unit_test or '' == unit_test:
+ return None, None
+ unit_test_name, unit_test_result = unit_test.strip().split(",")
+ return unit_test_name, unit_test_result
+
+
+def read_file(file_path):
+ try:
+ with open(file_path, "r") as file:
+ f = file.readlines()
+ if len(f):
+ f[-1] = f[-1].strip() + "\n"
+ return f
+ except FileNotFoundError:
+ return []
+
+
+def save_file(content, file_path):
+ # delete file is content is empty
+ if not content or not any(content):
+ if os.path.exists(file_path):
+ os.remove(file_path)
+ return
+
+ with open(file_path, "w") as file:
+ file.writelines(content)
+
+
+def is_test_present_on_file(file_content, unit_test_name):
+ return any(unit_test_name in line for line in file_content)
+
+
+def is_unit_test_present_in_other_jobs(unit_test, job_ids):
+ return all(unit_test in job_ids[job_id] for job_id in job_ids)
+
+
+def remove_unit_test_if_present(lines, unit_test_name):
+ if not is_test_present_on_file(lines, unit_test_name):
+ return
+ lines[:] = [line for line in lines if unit_test_name not in line]
+
+
+def add_unit_test_if_not_present(lines, unit_test_name, file_name):
+ # core_getversion is mandatory
+ if "core_getversion" in unit_test_name:
+ print("WARNING: core_getversion should pass, not adding it to", os.path.basename(file_name))
+ elif all(unit_test_name not in line for line in lines):
+ lines.append(unit_test_name + "\n")
+
+
+def update_unit_test_result_in_fails_txt(fails_txt, unit_test):
+ unit_test_name, unit_test_result = get_unit_test_name_and_results(unit_test)
+ for i, line in enumerate(fails_txt):
+ if unit_test_name in line:
+ _, current_result = get_unit_test_name_and_results(line)
+ fails_txt[i] = unit_test + "\n"
+ return
+
+
+def add_unit_test_or_update_result_to_fails_if_present(fails_txt, unit_test, fails_txt_path):
+ unit_test_name, _ = get_unit_test_name_and_results(unit_test)
+ if not is_test_present_on_file(fails_txt, unit_test_name):
+ add_unit_test_if_not_present(fails_txt, unit_test, fails_txt_path)
+ # if it is present but not with the same result
+ elif not is_test_present_on_file(fails_txt, unit_test):
+ update_unit_test_result_in_fails_txt(fails_txt, unit_test)
+
+
+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]:
+ del xfails[job_name][job_id]
+ continue
+ xfails[job_name][job_id] = xfails[job_name][job_id].strip().split("\n")
+
+
+def get_xfails_from_pipeline_url(pipeline_url):
+ parsed_url = urlparse(pipeline_url)
+ path_components = parsed_url.path.strip("/").split("/")
+
+ namespace = path_components[0]
+ project = path_components[1]
+ pipeline_id = path_components[-1]
+
+ print("Collating from:", namespace, project, pipeline_id)
+ xfails = (
+ Collate(namespace=namespace, project=project)
+ .from_pipeline(pipeline_id)
+ .get_artifact("results/failures.csv")
+ )
+
+ split_unit_test_from_collate(xfails)
+ return xfails
+
+
+def get_xfails_from_pipeline_urls(pipelines_urls):
+ xfails = defaultdict(dict)
+
+ for url in pipelines_urls:
+ new_xfails = get_xfails_from_pipeline_url(url)
+ for key in new_xfails:
+ xfails[key].update(new_xfails[key])
+
+ return xfails
+
+
+def print_diff(old_content, new_content, file_name):
+ diff = difflib.unified_diff(old_content, new_content, lineterm="", fromfile=file_name, tofile=file_name)
+ diff = [colored(line, "green") if line.startswith("+") else
+ colored(line, "red") if line.startswith("-") else line for line in diff]
+ print("\n".join(diff[:3]))
+ print("".join(diff[3:]))
+
+
+def main(pipelines_urls, only_flakes):
+ xfails = get_xfails_from_pipeline_urls(pipelines_urls)
+
+ for job_name in xfails.keys():
+ fails_txt_path = get_xfails_file_path(job_name, "fails")
+ flakes_txt_path = get_xfails_file_path(job_name, "flakes")
+
+ fails_txt = read_file(fails_txt_path)
+ flakes_txt = read_file(flakes_txt_path)
+
+ fails_txt_original = fails_txt.copy()
+ flakes_txt_original = flakes_txt.copy()
+
+ for job_id in xfails[job_name].keys():
+ for unit_test in xfails[job_name][job_id]:
+ unit_test_name, unit_test_result = get_unit_test_name_and_results(unit_test)
+
+ if not unit_test_name:
+ continue
+
+ if only_flakes:
+ remove_unit_test_if_present(fails_txt, unit_test_name)
+ add_unit_test_if_not_present(flakes_txt, unit_test_name, flakes_txt_path)
+ continue
+
+ # drop it from flakes if it is present to analyze it again
+ remove_unit_test_if_present(flakes_txt, unit_test_name)
+
+ if unit_test_result == "UnexpectedPass":
+ remove_unit_test_if_present(fails_txt, unit_test_name)
+ # flake result
+ if not is_unit_test_present_in_other_jobs(unit_test, xfails[job_name]):
+ add_unit_test_if_not_present(flakes_txt, unit_test_name, flakes_txt_path)
+ continue
+
+ # flake result
+ if not is_unit_test_present_in_other_jobs(unit_test, xfails[job_name]):
+ remove_unit_test_if_present(fails_txt, unit_test_name)
+ add_unit_test_if_not_present(flakes_txt, unit_test_name, flakes_txt_path)
+ continue
+
+ # consistent result
+ add_unit_test_or_update_result_to_fails_if_present(fails_txt, unit_test,
+ fails_txt_path)
+
+ fails_txt.sort()
+ flakes_txt.sort()
+
+ if fails_txt != fails_txt_original:
+ save_file(fails_txt, fails_txt_path)
+ print_diff(fails_txt_original, fails_txt, os.path.basename(fails_txt_path))
+ if flakes_txt != flakes_txt_original:
+ save_file(flakes_txt, flakes_txt_path)
+ print_diff(flakes_txt_original, flakes_txt, os.path.basename(flakes_txt_path))
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(description="Update xfails from a given pipeline.")
+ parser.add_argument("pipeline_urls", nargs="+", type=str, help="URLs to the pipelines to analyze the failures.")
+ parser.add_argument("--only-flakes", action="store_true", help="Treat every detected failure as a flake, edit *-flakes.txt only.")
+
+ args = parser.parse_args()
+
+ main(args.pipeline_urls, args.only_flakes)
+ print("Done.")
diff --git a/drivers/gpu/drm/ci/xfails/virtio_gpu-none-flakes.txt b/drivers/gpu/drm/ci/xfails/virtio_gpu-none-flakes.txt
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/drivers/gpu/drm/ci/xfails/virtio_gpu-none-flakes.txt
+++ /dev/null
diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c
index 2762572f286e..c3027115d055 100644
--- a/drivers/gpu/drm/drm_client.c
+++ b/drivers/gpu/drm/drm_client.c
@@ -395,19 +395,16 @@ static int drm_client_buffer_addfb(struct drm_client_buffer *buffer,
u32 handle)
{
struct drm_client_dev *client = buffer->client;
- struct drm_mode_fb_cmd fb_req = { };
- const struct drm_format_info *info;
+ struct drm_mode_fb_cmd2 fb_req = { };
int ret;
- info = drm_format_info(format);
- fb_req.bpp = drm_format_info_bpp(info, 0);
- fb_req.depth = info->depth;
fb_req.width = width;
fb_req.height = height;
- fb_req.handle = handle;
- fb_req.pitch = buffer->pitch;
+ fb_req.pixel_format = format;
+ fb_req.handles[0] = handle;
+ fb_req.pitches[0] = buffer->pitch;
- ret = drm_mode_addfb(client->dev, &fb_req, client->file);
+ ret = drm_mode_addfb2(client->dev, &fb_req, client->file);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index 0f17dfa8702b..193cf8ed7912 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -299,6 +299,14 @@ const struct drm_format_info *__drm_format_info(u32 format)
.num_planes = 2, .char_per_block = { 5, 5, 0 },
.block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2,
.vsub = 2, .is_yuv = true },
+ { .format = DRM_FORMAT_NV20, .depth = 0,
+ .num_planes = 2, .char_per_block = { 5, 5, 0 },
+ .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2,
+ .vsub = 1, .is_yuv = true },
+ { .format = DRM_FORMAT_NV30, .depth = 0,
+ .num_planes = 2, .char_per_block = { 5, 5, 0 },
+ .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, .hsub = 1,
+ .vsub = 1, .is_yuv = true },
{ .format = DRM_FORMAT_Q410, .depth = 0,
.num_planes = 3, .char_per_block = { 2, 2, 2 },
.block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 1,
diff --git a/drivers/gpu/drm/drm_gpuvm.c b/drivers/gpu/drm/drm_gpuvm.c
index 02ce6baacdad..08c088319652 100644
--- a/drivers/gpu/drm/drm_gpuvm.c
+++ b/drivers/gpu/drm/drm_gpuvm.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0-only
+// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
* Copyright (c) 2022 Red Hat.
*
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.c b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
index 345fec6cb1a4..9b79f218e21a 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
@@ -135,6 +135,7 @@ int etnaviv_sched_init(struct etnaviv_gpu *gpu)
int ret;
ret = drm_sched_init(&gpu->sched, &etnaviv_sched_ops,
+ DRM_SCHED_PRIORITY_COUNT,
etnaviv_hw_jobs_limit, etnaviv_job_hang_limit,
msecs_to_jiffies(500), NULL, NULL,
dev_name(gpu->dev), gpu->dev);
diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c
index ffd91a5ee299..295f0353a02e 100644
--- a/drivers/gpu/drm/lima/lima_sched.c
+++ b/drivers/gpu/drm/lima/lima_sched.c
@@ -488,7 +488,9 @@ int lima_sched_pipe_init(struct lima_sched_pipe *pipe, const char *name)
INIT_WORK(&pipe->recover_work, lima_sched_recover_work);
- return drm_sched_init(&pipe->base, &lima_sched_ops, 1,
+ return drm_sched_init(&pipe->base, &lima_sched_ops,
+ DRM_SCHED_PRIORITY_COUNT,
+ 1,
lima_job_hang_limit,
msecs_to_jiffies(timeout), NULL,
NULL, name, pipe->ldev->dev);
diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c
index 40c0bc35a44c..95257ab0185d 100644
--- a/drivers/gpu/drm/msm/msm_ringbuffer.c
+++ b/drivers/gpu/drm/msm/msm_ringbuffer.c
@@ -95,8 +95,9 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id,
sched_timeout = MAX_SCHEDULE_TIMEOUT;
ret = drm_sched_init(&ring->sched, &msm_sched_ops,
- num_hw_submissions, 0, sched_timeout,
- NULL, NULL, to_msm_bo(ring->bo)->name, gpu->dev->dev);
+ DRM_SCHED_PRIORITY_COUNT,
+ num_hw_submissions, 0, sched_timeout,
+ NULL, NULL, to_msm_bo(ring->bo)->name, gpu->dev->dev);
if (ret) {
goto fail;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_sched.c b/drivers/gpu/drm/nouveau/nouveau_sched.c
index 3b7ea5221226..7c376c4ccdcf 100644
--- a/drivers/gpu/drm/nouveau/nouveau_sched.c
+++ b/drivers/gpu/drm/nouveau/nouveau_sched.c
@@ -436,6 +436,7 @@ int nouveau_sched_init(struct nouveau_drm *drm)
return -ENOMEM;
return drm_sched_init(sched, &nouveau_sched_ops,
+ DRM_SCHED_PRIORITY_COUNT,
NOUVEAU_SCHED_HW_SUBMISSIONS, 0, job_hang_limit,
NULL, NULL, "nouveau_sched", drm->dev->dev);
}
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index ecb22ea326cb..99e14dc212ec 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -203,6 +203,15 @@ config DRM_PANEL_ILITEK_ILI9881C
Say Y if you want to enable support for panels based on the
Ilitek ILI9881c controller.
+config DRM_PANEL_ILITEK_ILI9882T
+ tristate "Ilitek ILI9882t-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
+ Ilitek ILI9882t controller.
+
config DRM_PANEL_INNOLUX_EJ030NA
tristate "Innolux EJ030NA 320x480 LCD panel"
depends on OF && SPI
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index e14ce55a0875..d10c3de51c6d 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_DRM_PANEL_HIMAX_HX8394) += panel-himax-hx8394.o
obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o
obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9341) += panel-ilitek-ili9341.o
obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o
+obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9882T) += panel-ilitek-ili9882t.o
obj-$(CONFIG_DRM_PANEL_INNOLUX_EJ030NA) += panel-innolux-ej030na.o
obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o
obj-$(CONFIG_DRM_PANEL_JADARD_JD9365DA_H3) += panel-jadard-jd9365da-h3.o
diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
index c9087f474cbc..9323e7b9e384 100644
--- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
+++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
@@ -1368,346 +1368,6 @@ static const struct panel_init_cmd starry_himax83102_j02_init_cmd[] = {
{},
};
-static const struct panel_init_cmd starry_ili9882t_init_cmd[] = {
- _INIT_DELAY_CMD(5),
- _INIT_DCS_CMD(0xFF, 0x98, 0x82, 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_DCS_CMD(0xFF, 0x98, 0x82, 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_DCS_CMD(0xFF, 0x98, 0x82, 0x03),
- _INIT_DCS_CMD(0x20, 0x01),
- _INIT_DCS_CMD(0x21, 0x3C),
- _INIT_DCS_CMD(0x22, 0xFA),
-
- _INIT_DCS_CMD(0xFF, 0x98, 0x82, 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_DCS_CMD(0xFF, 0x98, 0x82, 0x12),
- _INIT_DCS_CMD(0x87, 0x2C),
-
- _INIT_DCS_CMD(0xFF, 0x98, 0x82, 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_DCS_CMD(0xFF, 0x98, 0x82, 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_DCS_CMD(0xFF, 0x98, 0x82, 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_DCS_CMD(0xFF, 0x98, 0x82, 0x04),
- _INIT_DCS_CMD(0xBA, 0x81),
-
- _INIT_DCS_CMD(0xFF, 0x98, 0x82, 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_DCS_CMD(0xFF, 0x98, 0x82, 0x04),
- _INIT_DCS_CMD(0xBA, 0x01),
-
- _INIT_DCS_CMD(0xFF, 0x98, 0x82, 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_DCS_CMD(0xFF, 0x98, 0x82, 0x1E),
- _INIT_DCS_CMD(0x60, 0x00),
- _INIT_DCS_CMD(0x64, 0x00),
- _INIT_DCS_CMD(0x6D, 0x00),
-
- _INIT_DCS_CMD(0xFF, 0x98, 0x82, 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_DCS_CMD(0xFF, 0x98, 0x82, 0x05),
- _INIT_DCS_CMD(0x86, 0x87),
-
- _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x06),
- _INIT_DCS_CMD(0x92, 0x22),
-
- _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x00),
- _INIT_DCS_CMD(0x11),
- _INIT_DELAY_CMD(120),
- _INIT_DCS_CMD(0x29),
- _INIT_DELAY_CMD(20),
- {},
-};
-
static inline struct boe_panel *to_boe_panel(struct drm_panel *panel)
{
return container_of(panel, struct boe_panel, base);
@@ -2133,34 +1793,6 @@ static const struct panel_desc starry_himax83102_j02_desc = {
.lp11_before_reset = true,
};
-static const struct drm_display_mode starry_ili9882t_default_mode = {
- .clock = 165280,
- .hdisplay = 1200,
- .hsync_start = 1200 + 72,
- .hsync_end = 1200 + 72 + 30,
- .htotal = 1200 + 72 + 30 + 72,
- .vdisplay = 1920,
- .vsync_start = 1920 + 68,
- .vsync_end = 1920 + 68 + 2,
- .vtotal = 1920 + 68 + 2 + 10,
- .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
-};
-
-static const struct panel_desc starry_ili9882t_desc = {
- .modes = &starry_ili9882t_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_ili9882t_init_cmd,
- .lp11_before_reset = true,
-};
-
static int boe_panel_get_modes(struct drm_panel *panel,
struct drm_connector *connector)
{
@@ -2337,9 +1969,6 @@ static const struct of_device_id boe_of_match[] = {
{ .compatible = "starry,himax83102-j02",
.data = &starry_himax83102_j02_desc
},
- { .compatible = "starry,ili9882t",
- .data = &starry_ili9882t_desc
- },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, boe_of_match);
diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
new file mode 100644
index 000000000000..267a5307041c
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
@@ -0,0 +1,779 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Panels based on the Ilitek ILI9882T display controller.
+ */
+#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>
+
+/*
+ * Use this descriptor struct to describe different panels using the
+ * Ilitek ILI9882T display controller.
+ */
+struct panel_desc {
+ const struct drm_display_mode *modes;
+ unsigned int bpc;
+
+ /**
+ * @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;
+
+ unsigned long mode_flags;
+ enum mipi_dsi_pixel_format format;
+ const struct panel_init_cmd *init_cmds;
+ unsigned int lanes;
+};
+
+struct ili9882t {
+ struct drm_panel base;
+ struct mipi_dsi_device *dsi;
+
+ const struct panel_desc *desc;
+
+ enum drm_panel_orientation orientation;
+ struct regulator *pp3300;
+ struct regulator *pp1800;
+ struct regulator *avee;
+ struct regulator *avdd;
+ 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),
+ {},
+};
+
+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;
+
+ 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;
+ }
+
+ msleep(150);
+
+ return 0;
+}
+
+static int ili9882t_unprepare(struct drm_panel *panel)
+{
+ struct ili9882t *ili = to_ili9882t(panel);
+
+ gpiod_set_value(ili->enable_gpio, 0);
+ usleep_range(1000, 2000);
+ regulator_disable(ili->avee);
+ regulator_disable(ili->avdd);
+ usleep_range(5000, 7000);
+ regulator_disable(ili->pp1800);
+ regulator_disable(ili->pp3300);
+
+ return 0;
+}
+
+static int ili9882t_prepare(struct drm_panel *panel)
+{
+ struct ili9882t *ili = to_ili9882t(panel);
+ int ret;
+
+ gpiod_set_value(ili->enable_gpio, 0);
+ usleep_range(1000, 1500);
+
+ ret = regulator_enable(ili->pp3300);
+ if (ret < 0)
+ return ret;
+
+ ret = regulator_enable(ili->pp1800);
+ if (ret < 0)
+ return ret;
+
+ usleep_range(3000, 5000);
+
+ ret = regulator_enable(ili->avdd);
+ if (ret < 0)
+ goto poweroff1v8;
+ ret = regulator_enable(ili->avee);
+ if (ret < 0)
+ goto poweroffavdd;
+
+ 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);
+ usleep_range(1000, 2000);
+
+ gpiod_set_value(ili->enable_gpio, 1);
+ usleep_range(1000, 2000);
+ gpiod_set_value(ili->enable_gpio, 0);
+ msleep(50);
+ 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);
+ goto poweroff;
+ }
+
+ return 0;
+
+poweroff:
+ 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;
+}
+
+static int ili9882t_enable(struct drm_panel *panel)
+{
+ msleep(130);
+ return 0;
+}
+
+static const struct drm_display_mode starry_ili9882t_default_mode = {
+ .clock = 165280,
+ .hdisplay = 1200,
+ .hsync_start = 1200 + 72,
+ .hsync_end = 1200 + 72 + 30,
+ .htotal = 1200 + 72 + 30 + 72,
+ .vdisplay = 1920,
+ .vsync_start = 1920 + 68,
+ .vsync_end = 1920 + 68 + 2,
+ .vtotal = 1920 + 68 + 2 + 10,
+ .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
+};
+
+static const struct panel_desc starry_ili9882t_desc = {
+ .modes = &starry_ili9882t_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_ili9882t_init_cmd,
+};
+
+static int ili9882t_get_modes(struct drm_panel *panel,
+ struct drm_connector *connector)
+{
+ struct ili9882t *ili = to_ili9882t(panel);
+ const struct drm_display_mode *m = ili->desc->modes;
+ struct drm_display_mode *mode;
+
+ mode = drm_mode_duplicate(connector->dev, m);
+ if (!mode) {
+ dev_err(panel->dev, "failed to add mode %ux%u@%u\n",
+ m->hdisplay, m->vdisplay, drm_mode_vrefresh(m));
+ return -ENOMEM;
+ }
+
+ 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 = ili->desc->size.width_mm;
+ connector->display_info.height_mm = ili->desc->size.height_mm;
+ connector->display_info.bpc = ili->desc->bpc;
+
+ return 1;
+}
+
+static enum drm_panel_orientation ili9882t_get_orientation(struct drm_panel *panel)
+{
+ struct ili9882t *ili = to_ili9882t(panel);
+
+ return ili->orientation;
+}
+
+static const struct drm_panel_funcs ili9882t_funcs = {
+ .disable = ili9882t_disable,
+ .unprepare = ili9882t_unprepare,
+ .prepare = ili9882t_prepare,
+ .enable = ili9882t_enable,
+ .get_modes = ili9882t_get_modes,
+ .get_orientation = ili9882t_get_orientation,
+};
+
+static int ili9882t_add(struct ili9882t *ili)
+{
+ struct device *dev = &ili->dsi->dev;
+ int err;
+
+ ili->avdd = devm_regulator_get(dev, "avdd");
+ if (IS_ERR(ili->avdd))
+ return PTR_ERR(ili->avdd);
+
+ ili->avee = devm_regulator_get(dev, "avee");
+ if (IS_ERR(ili->avee))
+ return PTR_ERR(ili->avee);
+
+ ili->pp3300 = devm_regulator_get(dev, "pp3300");
+ if (IS_ERR(ili->pp3300))
+ return PTR_ERR(ili->pp3300);
+
+ ili->pp1800 = devm_regulator_get(dev, "pp1800");
+ if (IS_ERR(ili->pp1800))
+ return PTR_ERR(ili->pp1800);
+
+ ili->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
+ if (IS_ERR(ili->enable_gpio)) {
+ dev_err(dev, "cannot get reset-gpios %ld\n",
+ PTR_ERR(ili->enable_gpio));
+ return PTR_ERR(ili->enable_gpio);
+ }
+
+ gpiod_set_value(ili->enable_gpio, 0);
+
+ drm_panel_init(&ili->base, dev, &ili9882t_funcs,
+ DRM_MODE_CONNECTOR_DSI);
+ err = of_drm_get_panel_orientation(dev->of_node, &ili->orientation);
+ if (err < 0) {
+ dev_err(dev, "%pOF: failed to get orientation %d\n", dev->of_node, err);
+ return err;
+ }
+
+ err = drm_panel_of_backlight(&ili->base);
+ if (err)
+ return err;
+
+ ili->base.funcs = &ili9882t_funcs;
+ ili->base.dev = &ili->dsi->dev;
+
+ drm_panel_add(&ili->base);
+
+ return 0;
+}
+
+static int ili9882t_probe(struct mipi_dsi_device *dsi)
+{
+ struct ili9882t *ili;
+ int ret;
+ const struct panel_desc *desc;
+
+ ili = devm_kzalloc(&dsi->dev, sizeof(*ili), GFP_KERNEL);
+ if (!ili)
+ return -ENOMEM;
+
+ desc = of_device_get_match_data(&dsi->dev);
+ dsi->lanes = desc->lanes;
+ dsi->format = desc->format;
+ dsi->mode_flags = desc->mode_flags;
+ ili->desc = desc;
+ ili->dsi = dsi;
+ ret = ili9882t_add(ili);
+ if (ret < 0)
+ return ret;
+
+ mipi_dsi_set_drvdata(dsi, ili);
+
+ ret = mipi_dsi_attach(dsi);
+ if (ret)
+ drm_panel_remove(&ili->base);
+
+ return ret;
+}
+
+static void ili9882t_remove(struct mipi_dsi_device *dsi)
+{
+ struct ili9882t *ili = 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 (ili->base.dev)
+ drm_panel_remove(&ili->base);
+}
+
+static const struct of_device_id ili9882t_of_match[] = {
+ { .compatible = "starry,ili9882t",
+ .data = &starry_ili9882t_desc
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, ili9882t_of_match);
+
+static struct mipi_dsi_driver ili9882t_driver = {
+ .driver = {
+ .name = "panel-ili9882t",
+ .of_match_table = ili9882t_of_match,
+ },
+ .probe = ili9882t_probe,
+ .remove = ili9882t_remove,
+};
+module_mipi_dsi_driver(ili9882t_driver);
+
+MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
+MODULE_DESCRIPTION("Ilitek ILI9882T-based panels driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c b/drivers/gpu/drm/panel/panel-sitronix-st7703.c
index 6a3945639535..b55bafd1a8be 100644
--- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c
+++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c
@@ -130,6 +130,7 @@ static int jh057n_init_sequence(struct st7703 *ctx)
0x18, 0x00, 0x09, 0x0E, 0x29, 0x2D, 0x3C, 0x41,
0x37, 0x07, 0x0B, 0x0D, 0x10, 0x11, 0x0F, 0x10,
0x11, 0x18);
+ msleep(20);
return 0;
}
@@ -276,7 +277,6 @@ static int xbd599_init_sequence(struct st7703 *ctx)
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETBGP,
0x07, /* VREF_SEL = 4.2V */
0x07 /* NVREF_SEL = 4.2V */);
- msleep(20);
mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETVCOM,
0x2C, /* VCOMDC_F = -0.67V */
@@ -433,6 +433,94 @@ static const struct st7703_panel_desc rg353v2_desc = {
.init_sequence = rg353v2_init_sequence,
};
+static int rgb30panel_init_sequence(struct st7703 *ctx)
+{
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+
+ /* Init sequence extracted from Powkiddy RGB30 BSP kernel. */
+
+ /*
+ * For some reason this specific panel must be taken out of sleep
+ * before the full init sequence, or else it will not display.
+ */
+ mipi_dsi_dcs_exit_sleep_mode(dsi);
+ msleep(250);
+
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETEXTC, 0xf1, 0x12, 0x83);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETMIPI, 0x33, 0x81, 0x05, 0xf9,
+ 0x0e, 0x0e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x44, 0x25, 0x00, 0x90, 0x0a, 0x00,
+ 0x00, 0x01, 0x4f, 0x01, 0x00, 0x00, 0x37);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER_EXT, 0x25, 0x22, 0xf0,
+ 0x63);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_UNKNOWN_BF, 0x02, 0x11, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETRGBIF, 0x10, 0x10, 0x28,
+ 0x28, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETSCR, 0x73, 0x73, 0x50, 0x50,
+ 0x00, 0x00, 0x12, 0x70, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETVDC, 0x46);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPANEL, 0x0b);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETCYC, 0x80);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETDISP, 0x3c, 0x12, 0x30);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETEQ, 0x07, 0x07, 0x0b, 0x0b,
+ 0x03, 0x0b, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
+ 0xc0, 0x10);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER, 0x36, 0x00, 0x32,
+ 0x32, 0x77, 0xf1, 0xcc, 0xcc, 0x77, 0x77, 0x33,
+ 0x33);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETBGP, 0x0a, 0x0a);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETVCOM, 0x88, 0x88);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGIP1, 0xc8, 0x10, 0x0a, 0x10,
+ 0x0f, 0xa1, 0x80, 0x12, 0x31, 0x23, 0x47, 0x86,
+ 0xa1, 0x80, 0x47, 0x08, 0x00, 0x00, 0x0d, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
+ 0x48, 0x02, 0x8b, 0xaf, 0x46, 0x02, 0x88, 0x88,
+ 0x88, 0x88, 0x88, 0x48, 0x13, 0x8b, 0xaf, 0x57,
+ 0x13, 0x88, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGIP2, 0x96, 0x12, 0x01, 0x01,
+ 0x01, 0x78, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x31, 0x8b, 0xa8, 0x31, 0x75, 0x88, 0x88,
+ 0x88, 0x88, 0x88, 0x4f, 0x20, 0x8b, 0xa8, 0x20,
+ 0x64, 0x88, 0x88, 0x88, 0x88, 0x88, 0x23, 0x00,
+ 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x40, 0xa1, 0x80, 0x00, 0x00, 0x00,
+ 0x00);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGAMMA, 0x00, 0x0a, 0x0f,
+ 0x29, 0x3b, 0x3f, 0x42, 0x39, 0x06, 0x0d, 0x10,
+ 0x13, 0x15, 0x14, 0x15, 0x10, 0x17, 0x00, 0x0a,
+ 0x0f, 0x29, 0x3b, 0x3f, 0x42, 0x39, 0x06, 0x0d,
+ 0x10, 0x13, 0x15, 0x14, 0x15, 0x10, 0x17);
+
+ return 0;
+}
+
+static const struct drm_display_mode rgb30panel_mode = {
+ .hdisplay = 720,
+ .hsync_start = 720 + 45,
+ .hsync_end = 720 + 45 + 4,
+ .htotal = 720 + 45 + 4 + 45,
+ .vdisplay = 720,
+ .vsync_start = 720 + 15,
+ .vsync_end = 720 + 15 + 3,
+ .vtotal = 720 + 15 + 3 + 11,
+ .clock = 36570,
+ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
+ .width_mm = 76,
+ .height_mm = 76,
+};
+
+static const struct st7703_panel_desc rgb30panel_desc = {
+ .mode = &rgb30panel_mode,
+ .lanes = 4,
+ .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
+ MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_MODE_LPM,
+ .format = MIPI_DSI_FMT_RGB888,
+ .init_sequence = rgb30panel_init_sequence,
+};
+
static int st7703_enable(struct drm_panel *panel)
{
struct st7703 *ctx = panel_to_st7703(panel);
@@ -445,16 +533,14 @@ static int st7703_enable(struct drm_panel *panel)
return ret;
}
- msleep(20);
-
ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
if (ret < 0) {
dev_err(ctx->dev, "Failed to exit sleep mode: %d\n", ret);
return ret;
}
- /* Panel is operational 120 msec after reset */
- msleep(60);
+ /* It takes the controller 120 msec to wake up after sleep. */
+ msleep(120);
ret = mipi_dsi_dcs_set_display_on(dsi);
if (ret)
@@ -479,6 +565,9 @@ static int st7703_disable(struct drm_panel *panel)
if (ret < 0)
dev_err(ctx->dev, "Failed to enter sleep mode: %d\n", ret);
+ /* It takes the controller 120 msec to enter sleep mode. */
+ msleep(120);
+
return 0;
}
@@ -506,29 +595,30 @@ static int st7703_prepare(struct drm_panel *panel)
return 0;
dev_dbg(ctx->dev, "Resetting the panel\n");
- ret = regulator_enable(ctx->vcc);
+ gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+
+ ret = regulator_enable(ctx->iovcc);
if (ret < 0) {
- dev_err(ctx->dev, "Failed to enable vcc supply: %d\n", ret);
+ dev_err(ctx->dev, "Failed to enable iovcc supply: %d\n", ret);
return ret;
}
- ret = regulator_enable(ctx->iovcc);
+
+ ret = regulator_enable(ctx->vcc);
if (ret < 0) {
- dev_err(ctx->dev, "Failed to enable iovcc supply: %d\n", ret);
- goto disable_vcc;
+ dev_err(ctx->dev, "Failed to enable vcc supply: %d\n", ret);
+ regulator_disable(ctx->iovcc);
+ return ret;
}
- gpiod_set_value_cansleep(ctx->reset_gpio, 1);
- usleep_range(20, 40);
+ /* Give power supplies time to stabilize before deasserting reset. */
+ usleep_range(10000, 20000);
+
gpiod_set_value_cansleep(ctx->reset_gpio, 0);
- msleep(20);
+ usleep_range(15000, 20000);
ctx->prepared = true;
return 0;
-
-disable_vcc:
- regulator_disable(ctx->vcc);
- return ret;
}
static const u32 mantix_bus_formats[] = {
@@ -694,6 +784,7 @@ static void st7703_remove(struct mipi_dsi_device *dsi)
static const struct of_device_id st7703_of_match[] = {
{ .compatible = "anbernic,rg353v-panel-v2", .data = &rg353v2_desc },
+ { .compatible = "powkiddy,rgb30-panel", .data = &rgb30panel_desc },
{ .compatible = "rocktech,jh057n00900", .data = &jh057n00900_panel_desc },
{ .compatible = "xingbangda,xbd599", .data = &xbd599_desc },
{ /* sentinel */ }
diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c
index fb16de2d0420..ecd2e035147f 100644
--- a/drivers/gpu/drm/panfrost/panfrost_job.c
+++ b/drivers/gpu/drm/panfrost/panfrost_job.c
@@ -853,6 +853,7 @@ int panfrost_job_init(struct panfrost_device *pfdev)
ret = drm_sched_init(&js->queue[j].sched,
&panfrost_sched_ops,
+ DRM_SCHED_PRIORITY_COUNT,
nentries, 0,
msecs_to_jiffies(JOB_TIMEOUT_MS),
pfdev->reset.wq,
diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h
index 8a6621f1e82c..2db40789235c 100644
--- a/drivers/gpu/drm/radeon/atombios.h
+++ b/drivers/gpu/drm/radeon/atombios.h
@@ -3893,7 +3893,7 @@ typedef struct _ATOM_GPIO_PIN_ASSIGNMENT
typedef struct _ATOM_GPIO_PIN_LUT
{
ATOM_COMMON_TABLE_HEADER sHeader;
- ATOM_GPIO_PIN_ASSIGNMENT asGPIO_Pin[1];
+ ATOM_GPIO_PIN_ASSIGNMENT asGPIO_Pin[];
}ATOM_GPIO_PIN_LUT;
/****************************************************************************/
@@ -4061,7 +4061,7 @@ typedef struct _ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT //usSrcDstTableOffset
UCHAR ucNumberOfSrc;
USHORT usSrcObjectID[1];
UCHAR ucNumberOfDst;
- USHORT usDstObjectID[1];
+ USHORT usDstObjectID[];
}ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT;
@@ -4233,7 +4233,7 @@ typedef struct _ATOM_CONNECTOR_DEVICE_TAG_RECORD
ATOM_COMMON_RECORD_HEADER sheader;
UCHAR ucNumberOfDevice;
UCHAR ucReserved;
- ATOM_CONNECTOR_DEVICE_TAG asDeviceTag[1]; //This Id is same as "ATOM_DEVICE_XXX_SUPPORT", 1 is only for allocation
+ ATOM_CONNECTOR_DEVICE_TAG asDeviceTag[]; //This Id is same as "ATOM_DEVICE_XXX_SUPPORT", 1 is only for allocation
}ATOM_CONNECTOR_DEVICE_TAG_RECORD;
@@ -4293,7 +4293,7 @@ typedef struct _ATOM_OBJECT_GPIO_CNTL_RECORD
ATOM_COMMON_RECORD_HEADER sheader;
UCHAR ucFlags; // Future expnadibility
UCHAR ucNumberOfPins; // Number of GPIO pins used to control the object
- ATOM_GPIO_PIN_CONTROL_PAIR asGpio[1]; // the real gpio pin pair determined by number of pins ucNumberOfPins
+ ATOM_GPIO_PIN_CONTROL_PAIR asGpio[]; // the real gpio pin pair determined by number of pins ucNumberOfPins
}ATOM_OBJECT_GPIO_CNTL_RECORD;
//Definitions for GPIO pin state
@@ -4444,7 +4444,7 @@ typedef struct _ATOM_BRACKET_LAYOUT_RECORD
UCHAR ucWidth;
UCHAR ucConnNum;
UCHAR ucReserved;
- ATOM_CONNECTOR_LAYOUT_INFO asConnInfo[1];
+ ATOM_CONNECTOR_LAYOUT_INFO asConnInfo[];
}ATOM_BRACKET_LAYOUT_RECORD;
/****************************************************************************/
@@ -4600,7 +4600,7 @@ typedef struct _ATOM_I2C_VOLTAGE_OBJECT_V3
UCHAR ucVoltageControlAddress;
UCHAR ucVoltageControlOffset;
ULONG ulReserved;
- VOLTAGE_LUT_ENTRY asVolI2cLut[1]; // end with 0xff
+ VOLTAGE_LUT_ENTRY asVolI2cLut[]; // end with 0xff
}ATOM_I2C_VOLTAGE_OBJECT_V3;
// ATOM_I2C_VOLTAGE_OBJECT_V3.ucVoltageControlFlag
@@ -4625,7 +4625,7 @@ typedef struct _ATOM_LEAKAGE_VOLTAGE_OBJECT_V3
UCHAR ucLeakageEntryNum; // indicate the entry number of LeakageId/Voltage Lut table
UCHAR ucReserved[2];
ULONG ulMaxVoltageLevel;
- LEAKAGE_VOLTAGE_LUT_ENTRY_V2 asLeakageIdLut[1];
+ LEAKAGE_VOLTAGE_LUT_ENTRY_V2 asLeakageIdLut[];
}ATOM_LEAKAGE_VOLTAGE_OBJECT_V3;
@@ -4753,7 +4753,7 @@ typedef struct _ATOM_POWER_SOURCE_INFO
{
ATOM_COMMON_TABLE_HEADER asHeader;
UCHAR asPwrbehave[16];
- ATOM_POWER_SOURCE_OBJECT asPwrObj[1];
+ ATOM_POWER_SOURCE_OBJECT asPwrObj[];
}ATOM_POWER_SOURCE_INFO;
@@ -5440,7 +5440,7 @@ typedef struct _ATOM_FUSION_SYSTEM_INFO_V2
typedef struct _ATOM_I2C_DATA_RECORD
{
UCHAR ucNunberOfBytes; //Indicates how many bytes SW needs to write to the external ASIC for one block, besides to "Start" and "Stop"
- UCHAR ucI2CData[1]; //I2C data in bytes, should be less than 16 bytes usually
+ UCHAR ucI2CData[]; //I2C data in bytes, should be less than 16 bytes usually
}ATOM_I2C_DATA_RECORD;
@@ -5451,14 +5451,14 @@ typedef struct _ATOM_I2C_DEVICE_SETUP_INFO
UCHAR ucSSChipID; //SS chip being used
UCHAR ucSSChipSlaveAddr; //Slave Address to set up this SS chip
UCHAR ucNumOfI2CDataRecords; //number of data block
- ATOM_I2C_DATA_RECORD asI2CData[1];
+ ATOM_I2C_DATA_RECORD asI2CData[];
}ATOM_I2C_DEVICE_SETUP_INFO;
//==========================================================================================
typedef struct _ATOM_ASIC_MVDD_INFO
{
ATOM_COMMON_TABLE_HEADER sHeader;
- ATOM_I2C_DEVICE_SETUP_INFO asI2CSetup[1];
+ ATOM_I2C_DEVICE_SETUP_INFO asI2CSetup[];
}ATOM_ASIC_MVDD_INFO;
//==========================================================================================
@@ -5520,7 +5520,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO
typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V2
{
ATOM_COMMON_TABLE_HEADER sHeader;
- ATOM_ASIC_SS_ASSIGNMENT_V2 asSpreadSpectrum[1]; //this is point only.
+ ATOM_ASIC_SS_ASSIGNMENT_V2 asSpreadSpectrum[]; //this is point only.
}ATOM_ASIC_INTERNAL_SS_INFO_V2;
typedef struct _ATOM_ASIC_SS_ASSIGNMENT_V3
@@ -5542,7 +5542,7 @@ typedef struct _ATOM_ASIC_SS_ASSIGNMENT_V3
typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V3
{
ATOM_COMMON_TABLE_HEADER sHeader;
- ATOM_ASIC_SS_ASSIGNMENT_V3 asSpreadSpectrum[1]; //this is pointer only.
+ ATOM_ASIC_SS_ASSIGNMENT_V3 asSpreadSpectrum[]; //this is pointer only.
}ATOM_ASIC_INTERNAL_SS_INFO_V3;
@@ -6282,7 +6282,7 @@ typedef union _ATOM_MEMORY_SETTING_ID_CONFIG_ACCESS
typedef struct _ATOM_MEMORY_SETTING_DATA_BLOCK{
ATOM_MEMORY_SETTING_ID_CONFIG_ACCESS ulMemoryID;
- ULONG aulMemData[1];
+ ULONG aulMemData[];
}ATOM_MEMORY_SETTING_DATA_BLOCK;
@@ -7092,7 +7092,7 @@ typedef struct _ATOM_DISP_OUT_INFO_V3
UCHAR ucCoreRefClkSource; // value of CORE_REF_CLK_SOURCE
UCHAR ucDispCaps;
UCHAR ucReserved[2];
- ASIC_TRANSMITTER_INFO_V2 asTransmitterInfo[1]; // for alligment only
+ ASIC_TRANSMITTER_INFO_V2 asTransmitterInfo[]; // for alligment only
}ATOM_DISP_OUT_INFO_V3;
//ucDispCaps
@@ -7324,12 +7324,12 @@ typedef struct _CLOCK_CONDITION_SETTING_ENTRY{
USHORT usMaxClockFreq;
UCHAR ucEncodeMode;
UCHAR ucPhySel;
- ULONG ulAnalogSetting[1];
+ ULONG ulAnalogSetting[];
}CLOCK_CONDITION_SETTING_ENTRY;
typedef struct _CLOCK_CONDITION_SETTING_INFO{
USHORT usEntrySize;
- CLOCK_CONDITION_SETTING_ENTRY asClkCondSettingEntry[1];
+ CLOCK_CONDITION_SETTING_ENTRY asClkCondSettingEntry[];
}CLOCK_CONDITION_SETTING_INFO;
typedef struct _PHY_CONDITION_REG_VAL{
@@ -7346,27 +7346,27 @@ typedef struct _PHY_CONDITION_REG_VAL_V2{
typedef struct _PHY_CONDITION_REG_INFO{
USHORT usRegIndex;
USHORT usSize;
- PHY_CONDITION_REG_VAL asRegVal[1];
+ PHY_CONDITION_REG_VAL asRegVal[];
}PHY_CONDITION_REG_INFO;
typedef struct _PHY_CONDITION_REG_INFO_V2{
USHORT usRegIndex;
USHORT usSize;
- PHY_CONDITION_REG_VAL_V2 asRegVal[1];
+ PHY_CONDITION_REG_VAL_V2 asRegVal[];
}PHY_CONDITION_REG_INFO_V2;
typedef struct _PHY_ANALOG_SETTING_INFO{
UCHAR ucEncodeMode;
UCHAR ucPhySel;
USHORT usSize;
- PHY_CONDITION_REG_INFO asAnalogSetting[1];
+ PHY_CONDITION_REG_INFO asAnalogSetting[];
}PHY_ANALOG_SETTING_INFO;
typedef struct _PHY_ANALOG_SETTING_INFO_V2{
UCHAR ucEncodeMode;
UCHAR ucPhySel;
USHORT usSize;
- PHY_CONDITION_REG_INFO_V2 asAnalogSetting[1];
+ PHY_CONDITION_REG_INFO_V2 asAnalogSetting[];
}PHY_ANALOG_SETTING_INFO_V2;
typedef struct _GFX_HAVESTING_PARAMETERS {
diff --git a/drivers/gpu/drm/renesas/shmobile/Kconfig b/drivers/gpu/drm/renesas/shmobile/Kconfig
index ad14112999ad..027220b8fe1c 100644
--- a/drivers/gpu/drm/renesas/shmobile/Kconfig
+++ b/drivers/gpu/drm/renesas/shmobile/Kconfig
@@ -1,11 +1,12 @@
# SPDX-License-Identifier: GPL-2.0
config DRM_SHMOBILE
tristate "DRM Support for SH Mobile"
- depends on DRM
+ depends on DRM && PM
depends on ARCH_RENESAS || ARCH_SHMOBILE || COMPILE_TEST
select BACKLIGHT_CLASS_DEVICE
select DRM_KMS_HELPER
select DRM_GEM_DMA_HELPER
+ select VIDEOMODE_HELPERS
help
Choose this option if you have an SH Mobile chipset.
If M is selected the module will be called shmob-drm.
diff --git a/drivers/gpu/drm/renesas/shmobile/Makefile b/drivers/gpu/drm/renesas/shmobile/Makefile
index 861edafed856..2679555d61a7 100644
--- a/drivers/gpu/drm/renesas/shmobile/Makefile
+++ b/drivers/gpu/drm/renesas/shmobile/Makefile
@@ -1,6 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
-shmob-drm-y := shmob_drm_backlight.o \
- shmob_drm_crtc.o \
+shmob-drm-y := shmob_drm_crtc.o \
shmob_drm_drv.o \
shmob_drm_kms.o \
shmob_drm_plane.o
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.c
deleted file mode 100644
index 794573badfe8..000000000000
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.c
+++ /dev/null
@@ -1,82 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * shmob_drm_backlight.c -- SH Mobile DRM Backlight
- *
- * Copyright (C) 2012 Renesas Electronics Corporation
- *
- * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- */
-
-#include <linux/backlight.h>
-
-#include "shmob_drm_backlight.h"
-#include "shmob_drm_crtc.h"
-#include "shmob_drm_drv.h"
-
-static int shmob_drm_backlight_update(struct backlight_device *bdev)
-{
- struct shmob_drm_connector *scon = bl_get_data(bdev);
- struct shmob_drm_device *sdev = scon->connector.dev->dev_private;
- const struct shmob_drm_backlight_data *bdata = &sdev->pdata->backlight;
- int brightness = backlight_get_brightness(bdev);
-
- return bdata->set_brightness(brightness);
-}
-
-static int shmob_drm_backlight_get_brightness(struct backlight_device *bdev)
-{
- struct shmob_drm_connector *scon = bl_get_data(bdev);
- struct shmob_drm_device *sdev = scon->connector.dev->dev_private;
- const struct shmob_drm_backlight_data *bdata = &sdev->pdata->backlight;
-
- return bdata->get_brightness();
-}
-
-static const struct backlight_ops shmob_drm_backlight_ops = {
- .options = BL_CORE_SUSPENDRESUME,
- .update_status = shmob_drm_backlight_update,
- .get_brightness = shmob_drm_backlight_get_brightness,
-};
-
-void shmob_drm_backlight_dpms(struct shmob_drm_connector *scon, int mode)
-{
- if (scon->backlight == NULL)
- return;
-
- scon->backlight->props.power = mode == DRM_MODE_DPMS_ON
- ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
- backlight_update_status(scon->backlight);
-}
-
-int shmob_drm_backlight_init(struct shmob_drm_connector *scon)
-{
- struct shmob_drm_device *sdev = scon->connector.dev->dev_private;
- const struct shmob_drm_backlight_data *bdata = &sdev->pdata->backlight;
- struct drm_connector *connector = &scon->connector;
- struct drm_device *dev = connector->dev;
- struct backlight_device *backlight;
-
- if (!bdata->max_brightness)
- return 0;
-
- backlight = backlight_device_register(bdata->name, dev->dev, scon,
- &shmob_drm_backlight_ops, NULL);
- if (IS_ERR(backlight)) {
- dev_err(dev->dev, "unable to register backlight device: %ld\n",
- PTR_ERR(backlight));
- return PTR_ERR(backlight);
- }
-
- backlight->props.max_brightness = bdata->max_brightness;
- backlight->props.brightness = bdata->max_brightness;
- backlight->props.power = FB_BLANK_POWERDOWN;
- backlight_update_status(backlight);
-
- scon->backlight = backlight;
- return 0;
-}
-
-void shmob_drm_backlight_exit(struct shmob_drm_connector *scon)
-{
- backlight_device_unregister(scon->backlight);
-}
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.h
deleted file mode 100644
index d9abb7a60be5..000000000000
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * shmob_drm_backlight.h -- SH Mobile DRM Backlight
- *
- * Copyright (C) 2012 Renesas Electronics Corporation
- *
- * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
- */
-
-#ifndef __SHMOB_DRM_BACKLIGHT_H__
-#define __SHMOB_DRM_BACKLIGHT_H__
-
-struct shmob_drm_connector;
-
-void shmob_drm_backlight_dpms(struct shmob_drm_connector *scon, int mode);
-int shmob_drm_backlight_init(struct shmob_drm_connector *scon);
-void shmob_drm_backlight_exit(struct shmob_drm_connector *scon);
-
-#endif /* __SHMOB_DRM_BACKLIGHT_H__ */
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index 11dd2bc803e7..2e2f37b9d0a4 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -7,9 +7,18 @@
* Laurent Pinchart (laurent.pinchart@ideasonboard.com)
*/
-#include <linux/backlight.h>
#include <linux/clk.h>
-
+#include <linux/media-bus-format.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/pm_runtime.h>
+
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_atomic_state_helper.h>
+#include <drm/drm_atomic_uapi.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_bridge_connector.h>
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_dma_helper.h>
@@ -18,85 +27,123 @@
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_modeset_helper.h>
#include <drm/drm_modeset_helper_vtables.h>
-#include <drm/drm_plane_helper.h>
+#include <drm/drm_panel.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_simple_kms_helper.h>
#include <drm/drm_vblank.h>
-#include "shmob_drm_backlight.h"
+#include <video/videomode.h>
+
#include "shmob_drm_crtc.h"
#include "shmob_drm_drv.h"
#include "shmob_drm_kms.h"
#include "shmob_drm_plane.h"
#include "shmob_drm_regs.h"
-/*
- * TODO: panel support
- */
-
/* -----------------------------------------------------------------------------
- * Clock management
+ * Page Flip
*/
-static int shmob_drm_clk_on(struct shmob_drm_device *sdev)
+void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc)
{
- int ret;
+ struct drm_pending_vblank_event *event;
+ struct drm_device *dev = scrtc->base.dev;
+ unsigned long flags;
- if (sdev->clock) {
- ret = clk_prepare_enable(sdev->clock);
- if (ret < 0)
- return ret;
+ spin_lock_irqsave(&dev->event_lock, flags);
+ event = scrtc->event;
+ scrtc->event = NULL;
+ if (event) {
+ drm_crtc_send_vblank_event(&scrtc->base, event);
+ wake_up(&scrtc->flip_wait);
+ drm_crtc_vblank_put(&scrtc->base);
}
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+}
- return 0;
+static bool shmob_drm_crtc_page_flip_pending(struct shmob_drm_crtc *scrtc)
+{
+ struct drm_device *dev = scrtc->base.dev;
+ unsigned long flags;
+ bool pending;
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ pending = scrtc->event != NULL;
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+
+ return pending;
}
-static void shmob_drm_clk_off(struct shmob_drm_device *sdev)
+static void shmob_drm_crtc_wait_page_flip(struct shmob_drm_crtc *scrtc)
{
- if (sdev->clock)
- clk_disable_unprepare(sdev->clock);
+ struct drm_crtc *crtc = &scrtc->base;
+ struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
+
+ if (wait_event_timeout(scrtc->flip_wait,
+ !shmob_drm_crtc_page_flip_pending(scrtc),
+ msecs_to_jiffies(50)))
+ return;
+
+ dev_warn(sdev->dev, "page flip timeout\n");
+
+ shmob_drm_crtc_finish_page_flip(scrtc);
}
/* -----------------------------------------------------------------------------
* CRTC
*/
+static const struct {
+ u32 fmt;
+ u32 ldmt1r;
+} shmob_drm_bus_fmts[] = {
+ { MEDIA_BUS_FMT_RGB888_3X8, LDMT1R_MIFTYP_RGB8 },
+ { MEDIA_BUS_FMT_RGB666_2X9_BE, LDMT1R_MIFTYP_RGB9 },
+ { MEDIA_BUS_FMT_RGB888_2X12_BE, LDMT1R_MIFTYP_RGB12A },
+ { MEDIA_BUS_FMT_RGB444_1X12, LDMT1R_MIFTYP_RGB12B },
+ { MEDIA_BUS_FMT_RGB565_1X16, LDMT1R_MIFTYP_RGB16 },
+ { MEDIA_BUS_FMT_RGB666_1X18, LDMT1R_MIFTYP_RGB18 },
+ { MEDIA_BUS_FMT_RGB888_1X24, LDMT1R_MIFTYP_RGB24 },
+ { MEDIA_BUS_FMT_UYVY8_1X16, LDMT1R_MIFTYP_YCBCR },
+};
+
static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc)
{
- struct drm_crtc *crtc = &scrtc->crtc;
- struct shmob_drm_device *sdev = crtc->dev->dev_private;
- const struct shmob_drm_interface_data *idata = &sdev->pdata->iface;
+ struct drm_crtc *crtc = &scrtc->base;
+ struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
+ const struct drm_display_info *info = &sdev->connector->display_info;
const struct drm_display_mode *mode = &crtc->mode;
+ unsigned int i;
u32 value;
- value = sdev->ldmt1r
- | ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? 0 : LDMT1R_VPOL)
- | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? 0 : LDMT1R_HPOL)
- | ((idata->flags & SHMOB_DRM_IFACE_FL_DWPOL) ? LDMT1R_DWPOL : 0)
- | ((idata->flags & SHMOB_DRM_IFACE_FL_DIPOL) ? LDMT1R_DIPOL : 0)
- | ((idata->flags & SHMOB_DRM_IFACE_FL_DAPOL) ? LDMT1R_DAPOL : 0)
- | ((idata->flags & SHMOB_DRM_IFACE_FL_HSCNT) ? LDMT1R_HSCNT : 0)
- | ((idata->flags & SHMOB_DRM_IFACE_FL_DWCNT) ? LDMT1R_DWCNT : 0);
- lcdc_write(sdev, LDMT1R, value);
-
- if (idata->interface >= SHMOB_DRM_IFACE_SYS8A &&
- idata->interface <= SHMOB_DRM_IFACE_SYS24) {
- /* Setup SYS bus. */
- value = (idata->sys.cs_setup << LDMT2R_CSUP_SHIFT)
- | (idata->sys.vsync_active_high ? LDMT2R_RSV : 0)
- | (idata->sys.vsync_dir_input ? LDMT2R_VSEL : 0)
- | (idata->sys.write_setup << LDMT2R_WCSC_SHIFT)
- | (idata->sys.write_cycle << LDMT2R_WCEC_SHIFT)
- | (idata->sys.write_strobe << LDMT2R_WCLW_SHIFT);
- lcdc_write(sdev, LDMT2R, value);
-
- value = (idata->sys.read_latch << LDMT3R_RDLC_SHIFT)
- | (idata->sys.read_setup << LDMT3R_RCSC_SHIFT)
- | (idata->sys.read_cycle << LDMT3R_RCEC_SHIFT)
- | (idata->sys.read_strobe << LDMT3R_RCLW_SHIFT);
- lcdc_write(sdev, LDMT3R, value);
+ if (!info->num_bus_formats || !info->bus_formats) {
+ dev_warn(sdev->dev, "No bus format reported, using RGB888\n");
+ value = LDMT1R_MIFTYP_RGB24;
+ } else {
+ for (i = 0; i < ARRAY_SIZE(shmob_drm_bus_fmts); i++) {
+ if (shmob_drm_bus_fmts[i].fmt == info->bus_formats[0])
+ break;
+ }
+ if (i < ARRAY_SIZE(shmob_drm_bus_fmts)) {
+ value = shmob_drm_bus_fmts[i].ldmt1r;
+ } else {
+ dev_warn(sdev->dev,
+ "unsupported bus format 0x%x, using RGB888\n",
+ info->bus_formats[0]);
+ value = LDMT1R_MIFTYP_RGB24;
+ }
}
+ if (info->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE)
+ value |= LDMT1R_DWPOL;
+ if (info->bus_flags & DRM_BUS_FLAG_DE_LOW)
+ value |= LDMT1R_DIPOL;
+ if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+ value |= LDMT1R_VPOL;
+ if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+ value |= LDMT1R_HPOL;
+ lcdc_write(sdev, LDMT1R, value);
+
value = ((mode->hdisplay / 8) << 16) /* HDCN */
| (mode->htotal / 8); /* HTCN */
lcdc_write(sdev, LDHCNR, value);
@@ -121,7 +168,7 @@ static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc)
static void shmob_drm_crtc_start_stop(struct shmob_drm_crtc *scrtc, bool start)
{
- struct shmob_drm_device *sdev = scrtc->crtc.dev->dev_private;
+ struct shmob_drm_device *sdev = to_shmob_device(scrtc->base.dev);
u32 value;
value = lcdc_read(sdev, LDCNT2R);
@@ -145,34 +192,23 @@ static void shmob_drm_crtc_start_stop(struct shmob_drm_crtc *scrtc, bool start)
}
}
-/*
- * shmob_drm_crtc_start - Configure and start the LCDC
- * @scrtc: the SH Mobile CRTC
- *
- * Configure and start the LCDC device. External devices (clocks, MERAM, panels,
- * ...) are not touched by this function.
- */
-static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
+static inline struct shmob_drm_crtc *to_shmob_crtc(struct drm_crtc *crtc)
+{
+ return container_of(crtc, struct shmob_drm_crtc, base);
+}
+
+static void shmob_drm_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
{
- struct drm_crtc *crtc = &scrtc->crtc;
- struct shmob_drm_device *sdev = crtc->dev->dev_private;
- const struct shmob_drm_interface_data *idata = &sdev->pdata->iface;
- const struct shmob_drm_format_info *format;
- struct drm_device *dev = sdev->ddev;
- struct drm_plane *plane;
+ struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc);
+ struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
+ unsigned int clk_div = sdev->config.clk_div;
+ struct device *dev = sdev->dev;
u32 value;
int ret;
- if (scrtc->started)
- return;
-
- format = shmob_drm_format_info(crtc->primary->fb->format->format);
- if (WARN_ON(format == NULL))
- return;
-
- /* Enable clocks before accessing the hardware. */
- ret = shmob_drm_clk_on(sdev);
- if (ret < 0)
+ ret = pm_runtime_resume_and_get(dev);
+ if (ret)
return;
/* Reset and enable the LCDC. */
@@ -188,79 +224,50 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
lcdc_write(sdev, LDPMR, 0);
value = sdev->lddckr;
- if (idata->clk_div) {
+ if (clk_div) {
/* FIXME: sh7724 can only use 42, 48, 54 and 60 for the divider
* denominator.
*/
lcdc_write(sdev, LDDCKPAT1R, 0);
- lcdc_write(sdev, LDDCKPAT2R, (1 << (idata->clk_div / 2)) - 1);
+ lcdc_write(sdev, LDDCKPAT2R, (1 << (clk_div / 2)) - 1);
- if (idata->clk_div == 1)
+ if (clk_div == 1)
value |= LDDCKR_MOSEL;
else
- value |= idata->clk_div;
+ value |= clk_div;
}
lcdc_write(sdev, LDDCKR, value);
lcdc_write(sdev, LDDCKSTPR, 0);
lcdc_wait_bit(sdev, LDDCKSTPR, ~0, 0);
- /* TODO: Setup SYS panel */
-
/* Setup geometry, format, frame buffer memory and operation mode. */
shmob_drm_crtc_setup_geometry(scrtc);
- /* TODO: Handle YUV colorspaces. Hardcode REC709 for now. */
- lcdc_write(sdev, LDDFR, format->lddfr | LDDFR_CF1);
- lcdc_write(sdev, LDMLSR, scrtc->line_size);
- lcdc_write(sdev, LDSA1R, scrtc->dma[0]);
- if (format->yuv)
- lcdc_write(sdev, LDSA2R, scrtc->dma[1]);
lcdc_write(sdev, LDSM1R, 0);
- /* Word and long word swap. */
- switch (format->fourcc) {
- case DRM_FORMAT_RGB565:
- case DRM_FORMAT_NV21:
- case DRM_FORMAT_NV61:
- case DRM_FORMAT_NV42:
- value = LDDDSR_LS | LDDDSR_WS;
- break;
- case DRM_FORMAT_RGB888:
- case DRM_FORMAT_NV12:
- case DRM_FORMAT_NV16:
- case DRM_FORMAT_NV24:
- value = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS;
- break;
- case DRM_FORMAT_ARGB8888:
- case DRM_FORMAT_XRGB8888:
- default:
- value = LDDDSR_LS;
- break;
- }
- lcdc_write(sdev, LDDDSR, value);
-
- /* Setup planes. */
- drm_for_each_legacy_plane(plane, dev) {
- if (plane->crtc == crtc)
- shmob_drm_plane_setup(plane);
- }
-
/* Enable the display output. */
lcdc_write(sdev, LDCNT1R, LDCNT1R_DE);
shmob_drm_crtc_start_stop(scrtc, true);
- scrtc->started = true;
+ /* Turn vertical blank interrupt reporting back on. */
+ drm_crtc_vblank_on(crtc);
}
-static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc)
+static void shmob_drm_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
{
- struct drm_crtc *crtc = &scrtc->crtc;
- struct shmob_drm_device *sdev = crtc->dev->dev_private;
+ struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc);
+ struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
- if (!scrtc->started)
- return;
+ /*
+ * Disable vertical blank interrupt reporting. We first need to wait
+ * for page flip completion before stopping the CRTC as userspace
+ * expects page flips to eventually complete.
+ */
+ shmob_drm_crtc_wait_page_flip(scrtc);
+ drm_crtc_vblank_off(crtc);
/* Stop the LCDC. */
shmob_drm_crtc_start_stop(scrtc, false);
@@ -268,145 +275,31 @@ static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc)
/* Disable the display output. */
lcdc_write(sdev, LDCNT1R, 0);
- /* Stop clocks. */
- shmob_drm_clk_off(sdev);
-
- scrtc->started = false;
-}
-
-void shmob_drm_crtc_suspend(struct shmob_drm_crtc *scrtc)
-{
- shmob_drm_crtc_stop(scrtc);
-}
-
-void shmob_drm_crtc_resume(struct shmob_drm_crtc *scrtc)
-{
- if (scrtc->dpms != DRM_MODE_DPMS_ON)
- return;
-
- shmob_drm_crtc_start(scrtc);
+ pm_runtime_put(sdev->dev);
}
-static void shmob_drm_crtc_compute_base(struct shmob_drm_crtc *scrtc,
- int x, int y)
+static void shmob_drm_crtc_atomic_flush(struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
{
- struct drm_crtc *crtc = &scrtc->crtc;
- struct drm_framebuffer *fb = crtc->primary->fb;
- struct drm_gem_dma_object *gem;
- unsigned int bpp;
-
- bpp = scrtc->format->yuv ? 8 : scrtc->format->bpp;
- gem = drm_fb_dma_get_gem_obj(fb, 0);
- scrtc->dma[0] = gem->dma_addr + fb->offsets[0]
- + y * fb->pitches[0] + x * bpp / 8;
-
- if (scrtc->format->yuv) {
- bpp = scrtc->format->bpp - 8;
- gem = drm_fb_dma_get_gem_obj(fb, 1);
- scrtc->dma[1] = gem->dma_addr + fb->offsets[1]
- + y / (bpp == 4 ? 2 : 1) * fb->pitches[1]
- + x * (bpp == 16 ? 2 : 1);
- }
-}
-
-static void shmob_drm_crtc_update_base(struct shmob_drm_crtc *scrtc)
-{
- struct drm_crtc *crtc = &scrtc->crtc;
- struct shmob_drm_device *sdev = crtc->dev->dev_private;
-
- shmob_drm_crtc_compute_base(scrtc, crtc->x, crtc->y);
-
- lcdc_write_mirror(sdev, LDSA1R, scrtc->dma[0]);
- if (scrtc->format->yuv)
- lcdc_write_mirror(sdev, LDSA2R, scrtc->dma[1]);
-
- lcdc_write(sdev, LDRCNTR, lcdc_read(sdev, LDRCNTR) ^ LDRCNTR_MRS);
-}
-
-#define to_shmob_crtc(c) container_of(c, struct shmob_drm_crtc, crtc)
-
-static void shmob_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
- struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc);
-
- if (scrtc->dpms == mode)
- return;
-
- if (mode == DRM_MODE_DPMS_ON)
- shmob_drm_crtc_start(scrtc);
- else
- shmob_drm_crtc_stop(scrtc);
-
- scrtc->dpms = mode;
-}
-
-static void shmob_drm_crtc_mode_prepare(struct drm_crtc *crtc)
-{
- shmob_drm_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
-}
+ struct drm_pending_vblank_event *event;
+ struct drm_device *dev = crtc->dev;
+ unsigned long flags;
-static int shmob_drm_crtc_mode_set(struct drm_crtc *crtc,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode,
- int x, int y,
- struct drm_framebuffer *old_fb)
-{
- struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc);
- struct shmob_drm_device *sdev = crtc->dev->dev_private;
- const struct shmob_drm_format_info *format;
-
- format = shmob_drm_format_info(crtc->primary->fb->format->format);
- if (format == NULL) {
- dev_dbg(sdev->dev, "mode_set: unsupported format %p4cc\n",
- &crtc->primary->fb->format->format);
- return -EINVAL;
+ if (crtc->state->event) {
+ spin_lock_irqsave(&dev->event_lock, flags);
+ event = crtc->state->event;
+ crtc->state->event = NULL;
+ drm_crtc_send_vblank_event(crtc, event);
+ spin_unlock_irqrestore(&dev->event_lock, flags);
}
-
- scrtc->format = format;
- scrtc->line_size = crtc->primary->fb->pitches[0];
-
- shmob_drm_crtc_compute_base(scrtc, x, y);
-
- return 0;
-}
-
-static void shmob_drm_crtc_mode_commit(struct drm_crtc *crtc)
-{
- shmob_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
-}
-
-static int shmob_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
- struct drm_framebuffer *old_fb)
-{
- shmob_drm_crtc_update_base(to_shmob_crtc(crtc));
-
- return 0;
}
static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
- .dpms = shmob_drm_crtc_dpms,
- .prepare = shmob_drm_crtc_mode_prepare,
- .commit = shmob_drm_crtc_mode_commit,
- .mode_set = shmob_drm_crtc_mode_set,
- .mode_set_base = shmob_drm_crtc_mode_set_base,
+ .atomic_flush = shmob_drm_crtc_atomic_flush,
+ .atomic_enable = shmob_drm_crtc_atomic_enable,
+ .atomic_disable = shmob_drm_crtc_atomic_disable,
};
-void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc)
-{
- struct drm_pending_vblank_event *event;
- struct drm_device *dev = scrtc->crtc.dev;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->event_lock, flags);
- event = scrtc->event;
- scrtc->event = NULL;
- if (event) {
- drm_crtc_send_vblank_event(&scrtc->crtc, event);
- drm_crtc_vblank_put(&scrtc->crtc);
- }
- spin_unlock_irqrestore(&dev->event_lock, flags);
-}
-
static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event,
@@ -414,7 +307,7 @@ static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc,
struct drm_modeset_acquire_ctx *ctx)
{
struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc);
- struct drm_device *dev = scrtc->crtc.dev;
+ struct drm_device *dev = scrtc->base.dev;
unsigned long flags;
spin_lock_irqsave(&dev->event_lock, flags);
@@ -424,12 +317,11 @@ static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc,
}
spin_unlock_irqrestore(&dev->event_lock, flags);
- crtc->primary->fb = fb;
- shmob_drm_crtc_update_base(scrtc);
+ drm_atomic_set_fb_for_plane(crtc->primary->state, fb);
if (event) {
event->pipe = 0;
- drm_crtc_vblank_get(&scrtc->crtc);
+ drm_crtc_vblank_get(&scrtc->base);
spin_lock_irqsave(&dev->event_lock, flags);
scrtc->event = event;
spin_unlock_irqrestore(&dev->event_lock, flags);
@@ -457,7 +349,7 @@ static void shmob_drm_crtc_enable_vblank(struct shmob_drm_device *sdev,
static int shmob_drm_enable_vblank(struct drm_crtc *crtc)
{
- struct shmob_drm_device *sdev = crtc->dev->dev_private;
+ struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
shmob_drm_crtc_enable_vblank(sdev, true);
@@ -466,88 +358,65 @@ static int shmob_drm_enable_vblank(struct drm_crtc *crtc)
static void shmob_drm_disable_vblank(struct drm_crtc *crtc)
{
- struct shmob_drm_device *sdev = crtc->dev->dev_private;
+ struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
shmob_drm_crtc_enable_vblank(sdev, false);
}
static const struct drm_crtc_funcs crtc_funcs = {
+ .reset = drm_atomic_helper_crtc_reset,
.destroy = drm_crtc_cleanup,
- .set_config = drm_crtc_helper_set_config,
+ .set_config = drm_atomic_helper_set_config,
.page_flip = shmob_drm_crtc_page_flip,
+ .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
.enable_vblank = shmob_drm_enable_vblank,
.disable_vblank = shmob_drm_disable_vblank,
};
-static const uint32_t modeset_formats[] = {
- DRM_FORMAT_RGB565,
- DRM_FORMAT_RGB888,
- DRM_FORMAT_ARGB8888,
- DRM_FORMAT_XRGB8888,
-};
-
-static const struct drm_plane_funcs primary_plane_funcs = {
- DRM_PLANE_NON_ATOMIC_FUNCS,
-};
-
int shmob_drm_crtc_create(struct shmob_drm_device *sdev)
{
- struct drm_crtc *crtc = &sdev->crtc.crtc;
- struct drm_plane *primary;
+ struct drm_crtc *crtc = &sdev->crtc.base;
+ struct drm_plane *primary, *plane;
+ unsigned int i;
int ret;
- sdev->crtc.dpms = DRM_MODE_DPMS_OFF;
+ init_waitqueue_head(&sdev->crtc.flip_wait);
- primary = __drm_universal_plane_alloc(sdev->ddev, sizeof(*primary), 0,
- 0, &primary_plane_funcs,
- modeset_formats,
- ARRAY_SIZE(modeset_formats),
- NULL, DRM_PLANE_TYPE_PRIMARY,
- NULL);
+ primary = shmob_drm_plane_create(sdev, DRM_PLANE_TYPE_PRIMARY, 0);
if (IS_ERR(primary))
return PTR_ERR(primary);
- ret = drm_crtc_init_with_planes(sdev->ddev, crtc, primary, NULL,
+ for (i = 1; i < 5; ++i) {
+ plane = shmob_drm_plane_create(sdev, DRM_PLANE_TYPE_OVERLAY, i);
+ if (IS_ERR(plane))
+ return PTR_ERR(plane);
+ }
+
+ ret = drm_crtc_init_with_planes(&sdev->ddev, crtc, primary, NULL,
&crtc_funcs, NULL);
- if (ret < 0) {
- drm_plane_cleanup(primary);
- kfree(primary);
+ if (ret < 0)
return ret;
- }
drm_crtc_helper_add(crtc, &crtc_helper_funcs);
+ /* Start with vertical blank interrupt reporting disabled. */
+ drm_crtc_vblank_off(crtc);
+
return 0;
}
/* -----------------------------------------------------------------------------
- * Encoder
+ * Legacy Encoder
*/
-#define to_shmob_encoder(e) \
- container_of(e, struct shmob_drm_encoder, encoder)
-
-static void shmob_drm_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
- struct shmob_drm_encoder *senc = to_shmob_encoder(encoder);
- struct shmob_drm_device *sdev = encoder->dev->dev_private;
- struct shmob_drm_connector *scon = &sdev->connector;
-
- if (senc->dpms == mode)
- return;
-
- shmob_drm_backlight_dpms(scon, mode);
-
- senc->dpms = mode;
-}
-
static bool shmob_drm_encoder_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
struct drm_device *dev = encoder->dev;
- struct shmob_drm_device *sdev = dev->dev_private;
- struct drm_connector *connector = &sdev->connector.connector;
+ struct shmob_drm_device *sdev = to_shmob_device(dev);
+ struct drm_connector *connector = sdev->connector;
const struct drm_display_mode *panel_mode;
if (list_empty(&connector->modes)) {
@@ -563,60 +432,61 @@ static bool shmob_drm_encoder_mode_fixup(struct drm_encoder *encoder,
return true;
}
-static void shmob_drm_encoder_mode_prepare(struct drm_encoder *encoder)
-{
- /* No-op, everything is handled in the CRTC code. */
-}
-
-static void shmob_drm_encoder_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- /* No-op, everything is handled in the CRTC code. */
-}
-
-static void shmob_drm_encoder_mode_commit(struct drm_encoder *encoder)
-{
- /* No-op, everything is handled in the CRTC code. */
-}
-
static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
- .dpms = shmob_drm_encoder_dpms,
.mode_fixup = shmob_drm_encoder_mode_fixup,
- .prepare = shmob_drm_encoder_mode_prepare,
- .commit = shmob_drm_encoder_mode_commit,
- .mode_set = shmob_drm_encoder_mode_set,
};
+/* -----------------------------------------------------------------------------
+ * Encoder
+ */
+
int shmob_drm_encoder_create(struct shmob_drm_device *sdev)
{
- struct drm_encoder *encoder = &sdev->encoder.encoder;
+ struct drm_encoder *encoder = &sdev->encoder;
+ struct drm_bridge *bridge;
int ret;
- sdev->encoder.dpms = DRM_MODE_DPMS_OFF;
-
encoder->possible_crtcs = 1;
- ret = drm_simple_encoder_init(sdev->ddev, encoder,
- DRM_MODE_ENCODER_LVDS);
+ ret = drm_simple_encoder_init(&sdev->ddev, encoder,
+ DRM_MODE_ENCODER_DPI);
if (ret < 0)
return ret;
- drm_encoder_helper_add(encoder, &encoder_helper_funcs);
+ if (sdev->pdata) {
+ drm_encoder_helper_add(encoder, &encoder_helper_funcs);
+ return 0;
+ }
+
+ /* Create a panel bridge */
+ bridge = devm_drm_of_get_bridge(sdev->dev, sdev->dev->of_node, 0, 0);
+ if (IS_ERR(bridge))
+ return PTR_ERR(bridge);
+
+ /* Attach the bridge to the encoder */
+ ret = drm_bridge_attach(encoder, bridge, NULL,
+ DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+ if (ret) {
+ dev_err(sdev->dev, "failed to attach bridge: %pe\n",
+ ERR_PTR(ret));
+ return ret;
+ }
return 0;
}
/* -----------------------------------------------------------------------------
- * Connector
+ * Legacy Connector
*/
-#define to_shmob_connector(c) \
- container_of(c, struct shmob_drm_connector, connector)
+static inline struct shmob_drm_connector *to_shmob_connector(struct drm_connector *connector)
+{
+ return container_of(connector, struct shmob_drm_connector, base);
+}
static int shmob_drm_connector_get_modes(struct drm_connector *connector)
{
- struct shmob_drm_device *sdev = connector->dev->dev_private;
+ struct shmob_drm_connector *scon = to_shmob_connector(connector);
struct drm_display_mode *mode;
mode = drm_mode_create(connector->dev);
@@ -624,22 +494,10 @@ static int shmob_drm_connector_get_modes(struct drm_connector *connector)
return 0;
mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
- mode->clock = sdev->pdata->panel.mode.clock;
- mode->hdisplay = sdev->pdata->panel.mode.hdisplay;
- mode->hsync_start = sdev->pdata->panel.mode.hsync_start;
- mode->hsync_end = sdev->pdata->panel.mode.hsync_end;
- mode->htotal = sdev->pdata->panel.mode.htotal;
- mode->vdisplay = sdev->pdata->panel.mode.vdisplay;
- mode->vsync_start = sdev->pdata->panel.mode.vsync_start;
- mode->vsync_end = sdev->pdata->panel.mode.vsync_end;
- mode->vtotal = sdev->pdata->panel.mode.vtotal;
- mode->flags = sdev->pdata->panel.mode.flags;
-
- drm_mode_set_name(mode);
- drm_mode_probed_add(connector, mode);
- connector->display_info.width_mm = sdev->pdata->panel.width_mm;
- connector->display_info.height_mm = sdev->pdata->panel.height_mm;
+ drm_display_mode_from_videomode(scon->mode, mode);
+
+ drm_mode_probed_add(connector, mode);
return 1;
}
@@ -659,54 +517,106 @@ static const struct drm_connector_helper_funcs connector_helper_funcs = {
static void shmob_drm_connector_destroy(struct drm_connector *connector)
{
- struct shmob_drm_connector *scon = to_shmob_connector(connector);
-
- shmob_drm_backlight_exit(scon);
drm_connector_unregister(connector);
drm_connector_cleanup(connector);
+
+ kfree(connector);
}
static const struct drm_connector_funcs connector_funcs = {
- .dpms = drm_helper_connector_dpms,
+ .reset = drm_atomic_helper_connector_reset,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = shmob_drm_connector_destroy,
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
-int shmob_drm_connector_create(struct shmob_drm_device *sdev,
- struct drm_encoder *encoder)
+static struct drm_connector *
+shmob_drm_connector_init(struct shmob_drm_device *sdev,
+ struct drm_encoder *encoder)
{
- struct drm_connector *connector = &sdev->connector.connector;
+ u32 bus_fmt = sdev->pdata->iface.bus_fmt;
+ struct shmob_drm_connector *scon;
+ struct drm_connector *connector;
+ struct drm_display_info *info;
+ unsigned int i;
int ret;
- sdev->connector.encoder = encoder;
+ for (i = 0; i < ARRAY_SIZE(shmob_drm_bus_fmts); i++) {
+ if (shmob_drm_bus_fmts[i].fmt == bus_fmt)
+ break;
+ }
+ if (i == ARRAY_SIZE(shmob_drm_bus_fmts)) {
+ dev_err(sdev->dev, "unsupported bus format 0x%x\n", bus_fmt);
+ return ERR_PTR(-EINVAL);
+ }
- connector->display_info.width_mm = sdev->pdata->panel.width_mm;
- connector->display_info.height_mm = sdev->pdata->panel.height_mm;
+ scon = kzalloc(sizeof(*scon), GFP_KERNEL);
+ if (!scon)
+ return ERR_PTR(-ENOMEM);
- ret = drm_connector_init(sdev->ddev, connector, &connector_funcs,
- DRM_MODE_CONNECTOR_LVDS);
- if (ret < 0)
- return ret;
+ connector = &scon->base;
+ scon->encoder = encoder;
+ scon->mode = &sdev->pdata->panel.mode;
+
+ info = &connector->display_info;
+ info->width_mm = sdev->pdata->panel.width_mm;
+ info->height_mm = sdev->pdata->panel.height_mm;
+
+ if (scon->mode->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
+ info->bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE;
+ if (scon->mode->flags & DISPLAY_FLAGS_DE_LOW)
+ info->bus_flags |= DRM_BUS_FLAG_DE_LOW;
+
+ ret = drm_display_info_set_bus_formats(info, &bus_fmt, 1);
+ if (ret < 0) {
+ kfree(scon);
+ return ERR_PTR(ret);
+ }
+
+ ret = drm_connector_init(&sdev->ddev, connector, &connector_funcs,
+ DRM_MODE_CONNECTOR_DPI);
+ if (ret < 0) {
+ kfree(scon);
+ return ERR_PTR(ret);
+ }
drm_connector_helper_add(connector, &connector_helper_funcs);
- ret = shmob_drm_backlight_init(&sdev->connector);
- if (ret < 0)
- goto err_cleanup;
+ return connector;
+}
+
+/* -----------------------------------------------------------------------------
+ * Connector
+ */
+
+int shmob_drm_connector_create(struct shmob_drm_device *sdev,
+ struct drm_encoder *encoder)
+{
+ struct drm_connector *connector;
+ int ret;
+
+ if (sdev->pdata)
+ connector = shmob_drm_connector_init(sdev, encoder);
+ else
+ connector = drm_bridge_connector_init(&sdev->ddev, encoder);
+ if (IS_ERR(connector)) {
+ dev_err(sdev->dev, "failed to created connector: %pe\n",
+ connector);
+ return PTR_ERR(connector);
+ }
ret = drm_connector_attach_encoder(connector, encoder);
if (ret < 0)
- goto err_backlight;
+ goto error;
+
+ connector->dpms = DRM_MODE_DPMS_OFF;
- drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
- drm_object_property_set_value(&connector->base,
- sdev->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF);
+ sdev->connector = connector;
return 0;
-err_backlight:
- shmob_drm_backlight_exit(&sdev->connector);
-err_cleanup:
+error:
drm_connector_cleanup(connector);
return ret;
}
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
index 21718843f46d..16e1712dd04e 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h
@@ -14,39 +14,30 @@
#include <drm/drm_connector.h>
#include <drm/drm_encoder.h>
-struct backlight_device;
+#include <linux/wait.h>
+
+#include <video/videomode.h>
+
struct drm_pending_vblank_event;
struct shmob_drm_device;
struct shmob_drm_format_info;
struct shmob_drm_crtc {
- struct drm_crtc crtc;
+ struct drm_crtc base;
struct drm_pending_vblank_event *event;
- int dpms;
-
- const struct shmob_drm_format_info *format;
- unsigned long dma[2];
- unsigned int line_size;
- bool started;
-};
-
-struct shmob_drm_encoder {
- struct drm_encoder encoder;
- int dpms;
+ wait_queue_head_t flip_wait;
};
+/* Legacy connector */
struct shmob_drm_connector {
- struct drm_connector connector;
+ struct drm_connector base;
struct drm_encoder *encoder;
-
- struct backlight_device *backlight;
+ const struct videomode *mode;
};
int shmob_drm_crtc_create(struct shmob_drm_device *sdev);
void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc);
-void shmob_drm_crtc_suspend(struct shmob_drm_crtc *scrtc);
-void shmob_drm_crtc_resume(struct shmob_drm_crtc *scrtc);
int shmob_drm_encoder_create(struct shmob_drm_device *sdev);
int shmob_drm_connector_create(struct shmob_drm_device *sdev,
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
index e5db4e0095ba..e83c3e52251d 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
@@ -11,13 +11,17 @@
#include <linux/io.h>
#include <linux/mm.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
+#include <linux/pm_runtime.h>
#include <linux/slab.h>
+#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
#include <drm/drm_fbdev_generic.h>
#include <drm/drm_gem_dma_helper.h>
+#include <drm/drm_modeset_helper.h>
#include <drm/drm_module.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h>
@@ -31,57 +35,23 @@
* Hardware initialization
*/
-static int shmob_drm_init_interface(struct shmob_drm_device *sdev)
-{
- static const u32 ldmt1r[] = {
- [SHMOB_DRM_IFACE_RGB8] = LDMT1R_MIFTYP_RGB8,
- [SHMOB_DRM_IFACE_RGB9] = LDMT1R_MIFTYP_RGB9,
- [SHMOB_DRM_IFACE_RGB12A] = LDMT1R_MIFTYP_RGB12A,
- [SHMOB_DRM_IFACE_RGB12B] = LDMT1R_MIFTYP_RGB12B,
- [SHMOB_DRM_IFACE_RGB16] = LDMT1R_MIFTYP_RGB16,
- [SHMOB_DRM_IFACE_RGB18] = LDMT1R_MIFTYP_RGB18,
- [SHMOB_DRM_IFACE_RGB24] = LDMT1R_MIFTYP_RGB24,
- [SHMOB_DRM_IFACE_YUV422] = LDMT1R_MIFTYP_YCBCR,
- [SHMOB_DRM_IFACE_SYS8A] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS8A,
- [SHMOB_DRM_IFACE_SYS8B] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS8B,
- [SHMOB_DRM_IFACE_SYS8C] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS8C,
- [SHMOB_DRM_IFACE_SYS8D] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS8D,
- [SHMOB_DRM_IFACE_SYS9] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS9,
- [SHMOB_DRM_IFACE_SYS12] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS12,
- [SHMOB_DRM_IFACE_SYS16A] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS16A,
- [SHMOB_DRM_IFACE_SYS16B] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS16B,
- [SHMOB_DRM_IFACE_SYS16C] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS16C,
- [SHMOB_DRM_IFACE_SYS18] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS18,
- [SHMOB_DRM_IFACE_SYS24] = LDMT1R_IFM | LDMT1R_MIFTYP_SYS24,
- };
-
- if (sdev->pdata->iface.interface >= ARRAY_SIZE(ldmt1r)) {
- dev_err(sdev->dev, "invalid interface type %u\n",
- sdev->pdata->iface.interface);
- return -EINVAL;
- }
-
- sdev->ldmt1r = ldmt1r[sdev->pdata->iface.interface];
- return 0;
-}
-
static int shmob_drm_setup_clocks(struct shmob_drm_device *sdev,
- enum shmob_drm_clk_source clksrc)
+ enum shmob_drm_clk_source clksrc)
{
struct clk *clk;
char *clkname;
switch (clksrc) {
case SHMOB_DRM_CLK_BUS:
- clkname = "bus_clk";
+ clkname = "fck";
sdev->lddckr = LDDCKR_ICKSEL_BUS;
break;
case SHMOB_DRM_CLK_PERIPHERAL:
- clkname = "peripheral_clk";
+ clkname = "media";
sdev->lddckr = LDDCKR_ICKSEL_MIPI;
break;
case SHMOB_DRM_CLK_EXTERNAL:
- clkname = NULL;
+ clkname = "lclk";
sdev->lddckr = LDDCKR_ICKSEL_HDMI;
break;
default:
@@ -105,7 +75,7 @@ static int shmob_drm_setup_clocks(struct shmob_drm_device *sdev,
static irqreturn_t shmob_drm_irq(int irq, void *arg)
{
struct drm_device *dev = arg;
- struct shmob_drm_device *sdev = dev->dev_private;
+ struct shmob_drm_device *sdev = to_shmob_device(dev);
unsigned long flags;
u32 status;
@@ -119,7 +89,7 @@ static irqreturn_t shmob_drm_irq(int irq, void *arg)
spin_unlock_irqrestore(&sdev->irq_lock, flags);
if (status & LDINTR_VES) {
- drm_handle_vblank(dev, 0);
+ drm_crtc_handle_vblank(&sdev->crtc.base);
shmob_drm_crtc_finish_page_flip(&sdev->crtc);
}
@@ -129,7 +99,7 @@ static irqreturn_t shmob_drm_irq(int irq, void *arg)
DEFINE_DRM_GEM_DMA_FOPS(shmob_drm_fops);
static const struct drm_driver shmob_drm_driver = {
- .driver_features = DRIVER_GEM | DRIVER_MODESET,
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
DRM_GEM_DMA_DRIVER_OPS,
.fops = &shmob_drm_fops,
.name = "shmob-drm",
@@ -147,26 +117,45 @@ static int shmob_drm_pm_suspend(struct device *dev)
{
struct shmob_drm_device *sdev = dev_get_drvdata(dev);
- drm_kms_helper_poll_disable(sdev->ddev);
- shmob_drm_crtc_suspend(&sdev->crtc);
+ return drm_mode_config_helper_suspend(&sdev->ddev);
+}
+
+static int shmob_drm_pm_resume(struct device *dev)
+{
+ struct shmob_drm_device *sdev = dev_get_drvdata(dev);
+
+ return drm_mode_config_helper_resume(&sdev->ddev);
+}
+
+static int shmob_drm_pm_runtime_suspend(struct device *dev)
+{
+ struct shmob_drm_device *sdev = dev_get_drvdata(dev);
+
+ if (sdev->clock)
+ clk_disable_unprepare(sdev->clock);
return 0;
}
-static int shmob_drm_pm_resume(struct device *dev)
+static int shmob_drm_pm_runtime_resume(struct device *dev)
{
struct shmob_drm_device *sdev = dev_get_drvdata(dev);
+ int ret;
- drm_modeset_lock_all(sdev->ddev);
- shmob_drm_crtc_resume(&sdev->crtc);
- drm_modeset_unlock_all(sdev->ddev);
+ if (sdev->clock) {
+ ret = clk_prepare_enable(sdev->clock);
+ if (ret < 0)
+ return ret;
+ }
- drm_kms_helper_poll_enable(sdev->ddev);
return 0;
}
-static DEFINE_SIMPLE_DEV_PM_OPS(shmob_drm_pm_ops,
- shmob_drm_pm_suspend, shmob_drm_pm_resume);
+static const struct dev_pm_ops shmob_drm_pm_ops = {
+ SYSTEM_SLEEP_PM_OPS(shmob_drm_pm_suspend, shmob_drm_pm_resume)
+ RUNTIME_PM_OPS(shmob_drm_pm_runtime_suspend,
+ shmob_drm_pm_runtime_resume, NULL)
+};
/* -----------------------------------------------------------------------------
* Platform driver
@@ -175,37 +164,45 @@ static DEFINE_SIMPLE_DEV_PM_OPS(shmob_drm_pm_ops,
static void shmob_drm_remove(struct platform_device *pdev)
{
struct shmob_drm_device *sdev = platform_get_drvdata(pdev);
- struct drm_device *ddev = sdev->ddev;
+ struct drm_device *ddev = &sdev->ddev;
drm_dev_unregister(ddev);
+ drm_atomic_helper_shutdown(ddev);
drm_kms_helper_poll_fini(ddev);
- free_irq(sdev->irq, ddev);
- drm_dev_put(ddev);
}
static int shmob_drm_probe(struct platform_device *pdev)
{
struct shmob_drm_platform_data *pdata = pdev->dev.platform_data;
+ const struct shmob_drm_config *config;
struct shmob_drm_device *sdev;
struct drm_device *ddev;
- unsigned int i;
int ret;
- if (pdata == NULL) {
+ config = of_device_get_match_data(&pdev->dev);
+ if (!config && !pdata) {
dev_err(&pdev->dev, "no platform data\n");
return -EINVAL;
}
/*
- * Allocate and initialize the driver private data, I/O resources and
- * clocks.
+ * Allocate and initialize the DRM device, driver private data, I/O
+ * resources and clocks.
*/
- sdev = devm_kzalloc(&pdev->dev, sizeof(*sdev), GFP_KERNEL);
- if (sdev == NULL)
- return -ENOMEM;
+ sdev = devm_drm_dev_alloc(&pdev->dev, &shmob_drm_driver,
+ struct shmob_drm_device, ddev);
+ if (IS_ERR(sdev))
+ return PTR_ERR(sdev);
+ ddev = &sdev->ddev;
sdev->dev = &pdev->dev;
- sdev->pdata = pdata;
+ if (config) {
+ sdev->config = *config;
+ } else {
+ sdev->pdata = pdata;
+ sdev->config.clk_source = pdata->clk_source;
+ sdev->config.clk_div = pdata->iface.clk_div;
+ }
spin_lock_init(&sdev->irq_lock);
platform_set_drvdata(pdev, sdev);
@@ -214,49 +211,32 @@ static int shmob_drm_probe(struct platform_device *pdev)
if (IS_ERR(sdev->mmio))
return PTR_ERR(sdev->mmio);
- ret = shmob_drm_setup_clocks(sdev, pdata->clk_source);
+ ret = shmob_drm_setup_clocks(sdev, sdev->config.clk_source);
if (ret < 0)
return ret;
- ret = shmob_drm_init_interface(sdev);
- if (ret < 0)
+ ret = devm_pm_runtime_enable(&pdev->dev);
+ if (ret)
return ret;
- /* Allocate and initialize the DRM device. */
- ddev = drm_dev_alloc(&shmob_drm_driver, &pdev->dev);
- if (IS_ERR(ddev))
- return PTR_ERR(ddev);
-
- sdev->ddev = ddev;
- ddev->dev_private = sdev;
-
- ret = shmob_drm_modeset_init(sdev);
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to initialize mode setting\n");
- goto err_free_drm_dev;
- }
-
- for (i = 0; i < 4; ++i) {
- ret = shmob_drm_plane_create(sdev, i);
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to create plane %u\n", i);
- goto err_modeset_cleanup;
- }
- }
-
ret = drm_vblank_init(ddev, 1);
if (ret < 0) {
dev_err(&pdev->dev, "failed to initialize vblank\n");
- goto err_modeset_cleanup;
+ return ret;
}
+ ret = shmob_drm_modeset_init(sdev);
+ if (ret < 0)
+ return dev_err_probe(&pdev->dev, ret,
+ "failed to initialize mode setting\n");
+
ret = platform_get_irq(pdev, 0);
if (ret < 0)
goto err_modeset_cleanup;
sdev->irq = ret;
- ret = request_irq(sdev->irq, shmob_drm_irq, 0, ddev->driver->name,
- ddev);
+ ret = devm_request_irq(&pdev->dev, sdev->irq, shmob_drm_irq, 0,
+ ddev->driver->name, ddev);
if (ret < 0) {
dev_err(&pdev->dev, "failed to install IRQ handler\n");
goto err_modeset_cleanup;
@@ -268,28 +248,35 @@ static int shmob_drm_probe(struct platform_device *pdev)
*/
ret = drm_dev_register(ddev, 0);
if (ret < 0)
- goto err_irq_uninstall;
+ goto err_modeset_cleanup;
drm_fbdev_generic_setup(ddev, 16);
return 0;
-err_irq_uninstall:
- free_irq(sdev->irq, ddev);
err_modeset_cleanup:
drm_kms_helper_poll_fini(ddev);
-err_free_drm_dev:
- drm_dev_put(ddev);
-
return ret;
}
+static const struct shmob_drm_config shmob_arm_config = {
+ .clk_source = SHMOB_DRM_CLK_BUS,
+ .clk_div = 5,
+};
+
+static const struct of_device_id shmob_drm_of_table[] __maybe_unused = {
+ { .compatible = "renesas,r8a7740-lcdc", .data = &shmob_arm_config, },
+ { .compatible = "renesas,sh73a0-lcdc", .data = &shmob_arm_config, },
+ { /* sentinel */ }
+};
+
static struct platform_driver shmob_drm_platform_driver = {
.probe = shmob_drm_probe,
.remove_new = shmob_drm_remove,
.driver = {
.name = "shmob-drm",
- .pm = pm_sleep_ptr(&shmob_drm_pm_ops),
+ .of_match_table = of_match_ptr(shmob_drm_of_table),
+ .pm = &shmob_drm_pm_ops,
},
};
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
index 4964ddd5ab74..088ac5381e91 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h
@@ -20,23 +20,33 @@ struct clk;
struct device;
struct drm_device;
+struct shmob_drm_config {
+ enum shmob_drm_clk_source clk_source;
+ unsigned int clk_div;
+};
+
struct shmob_drm_device {
struct device *dev;
const struct shmob_drm_platform_data *pdata;
+ struct shmob_drm_config config;
void __iomem *mmio;
struct clk *clock;
u32 lddckr;
- u32 ldmt1r;
unsigned int irq;
spinlock_t irq_lock; /* Protects hardware LDINTR register */
- struct drm_device *ddev;
+ struct drm_device ddev;
struct shmob_drm_crtc crtc;
- struct shmob_drm_encoder encoder;
- struct shmob_drm_connector connector;
+ struct drm_encoder encoder;
+ struct drm_connector *connector;
};
+static inline struct shmob_drm_device *to_shmob_device(struct drm_device *dev)
+{
+ return container_of(dev, struct shmob_drm_device, ddev);
+}
+
#endif /* __SHMOB_DRM_DRV_H__ */
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
index 99381cc0abf3..4202ab00fb0c 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c
@@ -7,6 +7,7 @@
* Laurent Pinchart (laurent.pinchart@ideasonboard.com)
*/
+#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_fourcc.h>
@@ -17,6 +18,7 @@
#include "shmob_drm_crtc.h"
#include "shmob_drm_drv.h"
#include "shmob_drm_kms.h"
+#include "shmob_drm_plane.h"
#include "shmob_drm_regs.h"
/* -----------------------------------------------------------------------------
@@ -27,53 +29,73 @@ static const struct shmob_drm_format_info shmob_drm_format_infos[] = {
{
.fourcc = DRM_FORMAT_RGB565,
.bpp = 16,
- .yuv = false,
.lddfr = LDDFR_PKF_RGB16,
+ .ldddsr = LDDDSR_LS | LDDDSR_WS,
+ .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
+ LDBBSIFR_RY | LDBBSIFR_RPKF_RGB16,
}, {
.fourcc = DRM_FORMAT_RGB888,
.bpp = 24,
- .yuv = false,
.lddfr = LDDFR_PKF_RGB24,
+ .ldddsr = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS,
+ .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
+ LDBBSIFR_SWPB | LDBBSIFR_RY | LDBBSIFR_RPKF_RGB24,
}, {
.fourcc = DRM_FORMAT_ARGB8888,
.bpp = 32,
- .yuv = false,
.lddfr = LDDFR_PKF_ARGB32,
+ .ldddsr = LDDDSR_LS,
+ .ldbbsifr = LDBBSIFR_AL_PK | LDBBSIFR_SWPL | LDBBSIFR_RY |
+ LDBBSIFR_RPKF_ARGB32,
}, {
.fourcc = DRM_FORMAT_XRGB8888,
.bpp = 32,
- .yuv = false,
.lddfr = LDDFR_PKF_ARGB32,
+ .ldddsr = LDDDSR_LS,
+ .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_RY |
+ LDBBSIFR_RPKF_ARGB32,
}, {
.fourcc = DRM_FORMAT_NV12,
.bpp = 12,
- .yuv = true,
.lddfr = LDDFR_CC | LDDFR_YF_420,
+ .ldddsr = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS,
+ .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
+ LDBBSIFR_SWPB | LDBBSIFR_CHRR_420,
}, {
.fourcc = DRM_FORMAT_NV21,
.bpp = 12,
- .yuv = true,
.lddfr = LDDFR_CC | LDDFR_YF_420,
+ .ldddsr = LDDDSR_LS | LDDDSR_WS,
+ .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
+ LDBBSIFR_CHRR_420,
}, {
.fourcc = DRM_FORMAT_NV16,
.bpp = 16,
- .yuv = true,
.lddfr = LDDFR_CC | LDDFR_YF_422,
+ .ldddsr = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS,
+ .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
+ LDBBSIFR_SWPB | LDBBSIFR_CHRR_422,
}, {
.fourcc = DRM_FORMAT_NV61,
.bpp = 16,
- .yuv = true,
.lddfr = LDDFR_CC | LDDFR_YF_422,
+ .ldddsr = LDDDSR_LS | LDDDSR_WS,
+ .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
+ LDBBSIFR_CHRR_422,
}, {
.fourcc = DRM_FORMAT_NV24,
.bpp = 24,
- .yuv = true,
.lddfr = LDDFR_CC | LDDFR_YF_444,
+ .ldddsr = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS,
+ .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
+ LDBBSIFR_SWPB | LDBBSIFR_CHRR_444,
}, {
.fourcc = DRM_FORMAT_NV42,
.bpp = 24,
- .yuv = true,
.lddfr = LDDFR_CC | LDDFR_YF_444,
+ .ldddsr = LDDDSR_LS | LDDDSR_WS,
+ .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW |
+ LDBBSIFR_CHRR_444,
},
};
@@ -112,7 +134,7 @@ shmob_drm_fb_create(struct drm_device *dev, struct drm_file *file_priv,
return ERR_PTR(-EINVAL);
}
- if (format->yuv) {
+ if (shmob_drm_format_is_yuv(format)) {
unsigned int chroma_cpp = format->bpp == 24 ? 2 : 1;
if (mode_cmd->pitches[1] != mode_cmd->pitches[0] * chroma_cpp) {
@@ -127,29 +149,40 @@ shmob_drm_fb_create(struct drm_device *dev, struct drm_file *file_priv,
static const struct drm_mode_config_funcs shmob_drm_mode_config_funcs = {
.fb_create = shmob_drm_fb_create,
+ .atomic_check = drm_atomic_helper_check,
+ .atomic_commit = drm_atomic_helper_commit,
};
int shmob_drm_modeset_init(struct shmob_drm_device *sdev)
{
+ struct drm_device *dev = &sdev->ddev;
int ret;
- ret = drmm_mode_config_init(sdev->ddev);
+ ret = drmm_mode_config_init(dev);
if (ret)
return ret;
- shmob_drm_crtc_create(sdev);
- shmob_drm_encoder_create(sdev);
- shmob_drm_connector_create(sdev, &sdev->encoder.encoder);
+ ret = shmob_drm_crtc_create(sdev);
+ if (ret < 0)
+ return ret;
+
+ ret = shmob_drm_encoder_create(sdev);
+ if (ret < 0)
+ return ret;
+
+ ret = shmob_drm_connector_create(sdev, &sdev->encoder);
+ if (ret < 0)
+ return ret;
- drm_kms_helper_poll_init(sdev->ddev);
+ drm_mode_config_reset(dev);
- sdev->ddev->mode_config.min_width = 0;
- sdev->ddev->mode_config.min_height = 0;
- sdev->ddev->mode_config.max_width = 4095;
- sdev->ddev->mode_config.max_height = 4095;
- sdev->ddev->mode_config.funcs = &shmob_drm_mode_config_funcs;
+ drm_kms_helper_poll_init(dev);
- drm_helper_disable_unused_functions(sdev->ddev);
+ sdev->ddev.mode_config.min_width = 0;
+ sdev->ddev.mode_config.min_height = 0;
+ sdev->ddev.mode_config.max_width = 4095;
+ sdev->ddev.mode_config.max_height = 4095;
+ sdev->ddev.mode_config.funcs = &shmob_drm_mode_config_funcs;
return 0;
}
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.h
index 0347b1fd2338..590162c3db20 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.h
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.h
@@ -17,11 +17,14 @@ struct shmob_drm_device;
struct shmob_drm_format_info {
u32 fourcc;
- unsigned int bpp;
- bool yuv;
- u32 lddfr;
+ u32 lddfr; /* LCD Data Format Register */
+ u16 ldbbsifr; /* CHn Source Image Format Register low bits */
+ u8 ldddsr; /* LCDC Input Image Data Swap Register low bits */
+ u8 bpp;
};
+#define shmob_drm_format_is_yuv(format) ((format)->lddfr & LDDFR_CC)
+
const struct shmob_drm_format_info *shmob_drm_format_info(u32 fourcc);
int shmob_drm_modeset_init(struct shmob_drm_device *sdev);
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
index 850986cee848..8f9a728affde 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
@@ -7,11 +7,14 @@
* Laurent Pinchart (laurent.pinchart@ideasonboard.com)
*/
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.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_dma_helper.h>
+#include <drm/drm_plane_helper.h>
#include "shmob_drm_drv.h"
#include "shmob_drm_kms.h"
@@ -19,102 +22,84 @@
#include "shmob_drm_regs.h"
struct shmob_drm_plane {
- struct drm_plane plane;
+ struct drm_plane base;
unsigned int index;
- unsigned int alpha;
+};
+
+struct shmob_drm_plane_state {
+ struct drm_plane_state base;
const struct shmob_drm_format_info *format;
- unsigned long dma[2];
-
- unsigned int src_x;
- unsigned int src_y;
- unsigned int crtc_x;
- unsigned int crtc_y;
- unsigned int crtc_w;
- unsigned int crtc_h;
+ u32 dma[2];
};
-#define to_shmob_plane(p) container_of(p, struct shmob_drm_plane, plane)
+static inline struct shmob_drm_plane *to_shmob_plane(struct drm_plane *plane)
+{
+ return container_of(plane, struct shmob_drm_plane, base);
+}
+
+static inline struct shmob_drm_plane_state *to_shmob_plane_state(struct drm_plane_state *state)
+{
+ return container_of(state, struct shmob_drm_plane_state, base);
+}
-static void shmob_drm_plane_compute_base(struct shmob_drm_plane *splane,
- struct drm_framebuffer *fb,
- int x, int y)
+static void shmob_drm_plane_compute_base(struct shmob_drm_plane_state *sstate)
{
+ struct drm_framebuffer *fb = sstate->base.fb;
+ unsigned int x = sstate->base.src_x >> 16;
+ unsigned int y = sstate->base.src_y >> 16;
struct drm_gem_dma_object *gem;
unsigned int bpp;
- bpp = splane->format->yuv ? 8 : splane->format->bpp;
+ bpp = shmob_drm_format_is_yuv(sstate->format) ? 8 : sstate->format->bpp;
gem = drm_fb_dma_get_gem_obj(fb, 0);
- splane->dma[0] = gem->dma_addr + fb->offsets[0]
+ sstate->dma[0] = gem->dma_addr + fb->offsets[0]
+ y * fb->pitches[0] + x * bpp / 8;
- if (splane->format->yuv) {
- bpp = splane->format->bpp - 8;
+ if (shmob_drm_format_is_yuv(sstate->format)) {
+ bpp = sstate->format->bpp - 8;
gem = drm_fb_dma_get_gem_obj(fb, 1);
- splane->dma[1] = gem->dma_addr + fb->offsets[1]
+ sstate->dma[1] = gem->dma_addr + fb->offsets[1]
+ y / (bpp == 4 ? 2 : 1) * fb->pitches[1]
+ x * (bpp == 16 ? 2 : 1);
}
}
-static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
- struct drm_framebuffer *fb)
+static void shmob_drm_primary_plane_setup(struct shmob_drm_plane *splane,
+ struct drm_plane_state *state)
{
- struct shmob_drm_device *sdev = splane->plane.dev->dev_private;
+ struct shmob_drm_plane_state *sstate = to_shmob_plane_state(state);
+ struct shmob_drm_device *sdev = to_shmob_device(splane->base.dev);
+ struct drm_framebuffer *fb = state->fb;
+
+ /* TODO: Handle YUV colorspaces. Hardcode REC709 for now. */
+ lcdc_write(sdev, LDDFR, sstate->format->lddfr | LDDFR_CF1);
+ lcdc_write(sdev, LDMLSR, fb->pitches[0]);
+
+ /* Word and long word swap. */
+ lcdc_write(sdev, LDDDSR, sstate->format->ldddsr);
+
+ lcdc_write_mirror(sdev, LDSA1R, sstate->dma[0]);
+ if (shmob_drm_format_is_yuv(sstate->format))
+ lcdc_write_mirror(sdev, LDSA2R, sstate->dma[1]);
+
+ lcdc_write(sdev, LDRCNTR, lcdc_read(sdev, LDRCNTR) ^ LDRCNTR_MRS);
+}
+
+static void shmob_drm_overlay_plane_setup(struct shmob_drm_plane *splane,
+ struct drm_plane_state *state)
+{
+ struct shmob_drm_plane_state *sstate = to_shmob_plane_state(state);
+ struct shmob_drm_device *sdev = to_shmob_device(splane->base.dev);
+ struct drm_framebuffer *fb = state->fb;
u32 format;
/* TODO: Support ROP3 mode */
- format = LDBBSIFR_EN | (splane->alpha << LDBBSIFR_LAY_SHIFT);
-
- switch (splane->format->fourcc) {
- case DRM_FORMAT_RGB565:
- case DRM_FORMAT_NV21:
- case DRM_FORMAT_NV61:
- case DRM_FORMAT_NV42:
- format |= LDBBSIFR_SWPL | LDBBSIFR_SWPW;
- break;
- case DRM_FORMAT_RGB888:
- case DRM_FORMAT_NV12:
- case DRM_FORMAT_NV16:
- case DRM_FORMAT_NV24:
- format |= LDBBSIFR_SWPL | LDBBSIFR_SWPW | LDBBSIFR_SWPB;
- break;
- case DRM_FORMAT_ARGB8888:
- case DRM_FORMAT_XRGB8888:
- default:
- format |= LDBBSIFR_SWPL;
- break;
- }
-
- switch (splane->format->fourcc) {
- case DRM_FORMAT_RGB565:
- format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDBBSIFR_RPKF_RGB16;
- break;
- case DRM_FORMAT_RGB888:
- format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDBBSIFR_RPKF_RGB24;
- break;
- case DRM_FORMAT_ARGB8888:
- format |= LDBBSIFR_AL_PK | LDBBSIFR_RY | LDDFR_PKF_ARGB32;
- break;
- case DRM_FORMAT_XRGB8888:
- format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDDFR_PKF_ARGB32;
- break;
- case DRM_FORMAT_NV12:
- case DRM_FORMAT_NV21:
- format |= LDBBSIFR_AL_1 | LDBBSIFR_CHRR_420;
- break;
- case DRM_FORMAT_NV16:
- case DRM_FORMAT_NV61:
- format |= LDBBSIFR_AL_1 | LDBBSIFR_CHRR_422;
- break;
- case DRM_FORMAT_NV24:
- case DRM_FORMAT_NV42:
- format |= LDBBSIFR_AL_1 | LDBBSIFR_CHRR_444;
- break;
- }
+ format = LDBBSIFR_EN | ((state->alpha >> 8) << LDBBSIFR_LAY_SHIFT) |
+ sstate->format->ldbbsifr;
#define plane_reg_dump(sdev, splane, reg) \
- dev_dbg(sdev->ddev->dev, "%s(%u): %s 0x%08x 0x%08x\n", __func__, \
+ dev_dbg(sdev->ddev.dev, "%s(%u): %s 0x%08x 0x%08x\n", __func__, \
splane->index, #reg, \
lcdc_read(sdev, reg(splane->index)), \
lcdc_read(sdev, reg(splane->index) + LCDC_SIDE_B_OFFSET))
@@ -127,29 +112,27 @@ static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
plane_reg_dump(sdev, splane, LDBnBSACR);
lcdc_write(sdev, LDBCR, LDBCR_UPC(splane->index));
- dev_dbg(sdev->ddev->dev, "%s(%u): %s 0x%08x\n", __func__, splane->index,
+ dev_dbg(sdev->ddev.dev, "%s(%u): %s 0x%08x\n", __func__, splane->index,
"LDBCR", lcdc_read(sdev, LDBCR));
lcdc_write(sdev, LDBnBSIFR(splane->index), format);
lcdc_write(sdev, LDBnBSSZR(splane->index),
- (splane->crtc_h << LDBBSSZR_BVSS_SHIFT) |
- (splane->crtc_w << LDBBSSZR_BHSS_SHIFT));
+ (state->crtc_h << LDBBSSZR_BVSS_SHIFT) |
+ (state->crtc_w << LDBBSSZR_BHSS_SHIFT));
lcdc_write(sdev, LDBnBLOCR(splane->index),
- (splane->crtc_y << LDBBLOCR_CVLC_SHIFT) |
- (splane->crtc_x << LDBBLOCR_CHLC_SHIFT));
+ (state->crtc_y << LDBBLOCR_CVLC_SHIFT) |
+ (state->crtc_x << LDBBLOCR_CHLC_SHIFT));
lcdc_write(sdev, LDBnBSMWR(splane->index),
fb->pitches[0] << LDBBSMWR_BSMW_SHIFT);
- shmob_drm_plane_compute_base(splane, fb, splane->src_x, splane->src_y);
-
- lcdc_write(sdev, LDBnBSAYR(splane->index), splane->dma[0]);
- if (splane->format->yuv)
- lcdc_write(sdev, LDBnBSACR(splane->index), splane->dma[1]);
+ lcdc_write(sdev, LDBnBSAYR(splane->index), sstate->dma[0]);
+ if (shmob_drm_format_is_yuv(sstate->format))
+ lcdc_write(sdev, LDBnBSACR(splane->index), sstate->dma[1]);
lcdc_write(sdev, LDBCR,
LDBCR_UPF(splane->index) | LDBCR_UPD(splane->index));
- dev_dbg(sdev->ddev->dev, "%s(%u): %s 0x%08x\n", __func__, splane->index,
+ dev_dbg(sdev->ddev.dev, "%s(%u): %s 0x%08x\n", __func__, splane->index,
"LDBCR", lcdc_read(sdev, LDBCR));
plane_reg_dump(sdev, splane, LDBnBSIFR);
@@ -160,75 +143,143 @@ static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane,
plane_reg_dump(sdev, splane, LDBnBSACR);
}
-void shmob_drm_plane_setup(struct drm_plane *plane)
+static int shmob_drm_plane_atomic_check(struct drm_plane *plane,
+ struct drm_atomic_state *state)
{
- struct shmob_drm_plane *splane = to_shmob_plane(plane);
+ struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane);
+ struct shmob_drm_plane_state *sstate = to_shmob_plane_state(new_plane_state);
+ struct drm_crtc_state *crtc_state;
+ bool is_primary = plane->type == DRM_PLANE_TYPE_PRIMARY;
+ int ret;
- if (plane->fb == NULL)
- return;
+ if (!new_plane_state->crtc) {
+ /*
+ * The visible field is not reset by the DRM core but only
+ * updated by drm_atomic_helper_check_plane_state(), set it
+ * manually.
+ */
+ new_plane_state->visible = false;
+ sstate->format = NULL;
+ return 0;
+ }
- __shmob_drm_plane_setup(splane, plane->fb);
-}
+ crtc_state = drm_atomic_get_crtc_state(state, new_plane_state->crtc);
+ if (IS_ERR(crtc_state))
+ return PTR_ERR(crtc_state);
-static int
-shmob_drm_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
- struct drm_framebuffer *fb, int crtc_x, int crtc_y,
- unsigned int crtc_w, unsigned int crtc_h,
- uint32_t src_x, uint32_t src_y,
- uint32_t src_w, uint32_t src_h,
- struct drm_modeset_acquire_ctx *ctx)
-{
- struct shmob_drm_plane *splane = to_shmob_plane(plane);
- struct shmob_drm_device *sdev = plane->dev->dev_private;
- const struct shmob_drm_format_info *format;
+ ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
+ DRM_PLANE_NO_SCALING,
+ DRM_PLANE_NO_SCALING,
+ !is_primary, true);
+ if (ret < 0)
+ return ret;
- format = shmob_drm_format_info(fb->format->format);
- if (format == NULL) {
- dev_dbg(sdev->dev, "update_plane: unsupported format %08x\n",
- fb->format->format);
- return -EINVAL;
+ if (!new_plane_state->visible) {
+ sstate->format = NULL;
+ return 0;
}
- if (src_w >> 16 != crtc_w || src_h >> 16 != crtc_h) {
- dev_dbg(sdev->dev, "%s: scaling not supported\n", __func__);
+ sstate->format = shmob_drm_format_info(new_plane_state->fb->format->format);
+ if (!sstate->format) {
+ dev_dbg(plane->dev->dev,
+ "plane_atomic_check: unsupported format %p4cc\n",
+ &new_plane_state->fb->format->format);
return -EINVAL;
}
- splane->format = format;
+ shmob_drm_plane_compute_base(sstate);
- splane->src_x = src_x >> 16;
- splane->src_y = src_y >> 16;
- splane->crtc_x = crtc_x;
- splane->crtc_y = crtc_y;
- splane->crtc_w = crtc_w;
- splane->crtc_h = crtc_h;
-
- __shmob_drm_plane_setup(splane, fb);
return 0;
}
-static int shmob_drm_plane_disable(struct drm_plane *plane,
- struct drm_modeset_acquire_ctx *ctx)
+static void shmob_drm_plane_atomic_update(struct drm_plane *plane,
+ struct drm_atomic_state *state)
{
+ struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane);
struct shmob_drm_plane *splane = to_shmob_plane(plane);
- struct shmob_drm_device *sdev = plane->dev->dev_private;
- splane->format = NULL;
+ if (!new_plane_state->visible)
+ return;
+ if (plane->type == DRM_PLANE_TYPE_PRIMARY)
+ shmob_drm_primary_plane_setup(splane, new_plane_state);
+ else
+ shmob_drm_overlay_plane_setup(splane, new_plane_state);
+}
+
+static void shmob_drm_plane_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 shmob_drm_device *sdev = to_shmob_device(plane->dev);
+ struct shmob_drm_plane *splane = to_shmob_plane(plane);
+
+ if (!old_state->crtc)
+ return;
+
+ if (plane->type != DRM_PLANE_TYPE_OVERLAY)
+ return;
+
+ lcdc_write(sdev, LDBCR, LDBCR_UPC(splane->index));
lcdc_write(sdev, LDBnBSIFR(splane->index), 0);
- return 0;
+ lcdc_write(sdev, LDBCR,
+ LDBCR_UPF(splane->index) | LDBCR_UPD(splane->index));
}
-static void shmob_drm_plane_destroy(struct drm_plane *plane)
+static struct drm_plane_state *
+shmob_drm_plane_atomic_duplicate_state(struct drm_plane *plane)
{
- drm_plane_force_disable(plane);
- drm_plane_cleanup(plane);
+ struct shmob_drm_plane_state *state;
+ struct shmob_drm_plane_state *copy;
+
+ if (WARN_ON(!plane->state))
+ return NULL;
+
+ state = to_shmob_plane_state(plane->state);
+ copy = kmemdup(state, sizeof(*state), GFP_KERNEL);
+ if (copy == NULL)
+ return NULL;
+
+ __drm_atomic_helper_plane_duplicate_state(plane, &copy->base);
+
+ return &copy->base;
}
+static void shmob_drm_plane_atomic_destroy_state(struct drm_plane *plane,
+ struct drm_plane_state *state)
+{
+ __drm_atomic_helper_plane_destroy_state(state);
+ kfree(to_shmob_plane_state(state));
+}
+
+static void shmob_drm_plane_reset(struct drm_plane *plane)
+{
+ struct shmob_drm_plane_state *state;
+
+ if (plane->state) {
+ shmob_drm_plane_atomic_destroy_state(plane, plane->state);
+ plane->state = NULL;
+ }
+
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
+ if (state == NULL)
+ return;
+
+ __drm_atomic_helper_plane_reset(plane, &state->base);
+}
+
+static const struct drm_plane_helper_funcs shmob_drm_plane_helper_funcs = {
+ .atomic_check = shmob_drm_plane_atomic_check,
+ .atomic_update = shmob_drm_plane_atomic_update,
+ .atomic_disable = shmob_drm_plane_atomic_disable,
+};
+
static const struct drm_plane_funcs shmob_drm_plane_funcs = {
- .update_plane = shmob_drm_plane_update,
- .disable_plane = shmob_drm_plane_disable,
- .destroy = shmob_drm_plane_destroy,
+ .update_plane = drm_atomic_helper_update_plane,
+ .disable_plane = drm_atomic_helper_disable_plane,
+ .reset = shmob_drm_plane_reset,
+ .atomic_duplicate_state = shmob_drm_plane_atomic_duplicate_state,
+ .atomic_destroy_state = shmob_drm_plane_atomic_destroy_state,
};
static const uint32_t formats[] = {
@@ -244,22 +295,23 @@ static const uint32_t formats[] = {
DRM_FORMAT_NV42,
};
-int shmob_drm_plane_create(struct shmob_drm_device *sdev, unsigned int index)
+struct drm_plane *shmob_drm_plane_create(struct shmob_drm_device *sdev,
+ enum drm_plane_type type,
+ unsigned int index)
{
struct shmob_drm_plane *splane;
- int ret;
- splane = devm_kzalloc(sdev->dev, sizeof(*splane), GFP_KERNEL);
- if (splane == NULL)
- return -ENOMEM;
+ splane = drmm_universal_plane_alloc(&sdev->ddev,
+ struct shmob_drm_plane, base, 1,
+ &shmob_drm_plane_funcs, formats,
+ ARRAY_SIZE(formats), NULL, type,
+ NULL);
+ if (IS_ERR(splane))
+ return ERR_CAST(splane);
splane->index = index;
- splane->alpha = 255;
- ret = drm_universal_plane_init(sdev->ddev, &splane->plane, 1,
- &shmob_drm_plane_funcs,
- formats, ARRAY_SIZE(formats), NULL,
- DRM_PLANE_TYPE_OVERLAY, NULL);
+ drm_plane_helper_add(&splane->base, &shmob_drm_plane_helper_funcs);
- return ret;
+ return &splane->base;
}
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.h b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.h
index e72b21a4288f..dcfddd605899 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.h
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.h
@@ -13,7 +13,8 @@
struct drm_plane;
struct shmob_drm_device;
-int shmob_drm_plane_create(struct shmob_drm_device *sdev, unsigned int index);
-void shmob_drm_plane_setup(struct drm_plane *plane);
+struct drm_plane *shmob_drm_plane_create(struct shmob_drm_device *sdev,
+ enum drm_plane_type type,
+ unsigned int index);
#endif /* __SHMOB_DRM_PLANE_H__ */
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index b8f8b45ebf59..93ed841f5dce 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -40,7 +40,7 @@ static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj)
ret = iommu_map_sgtable(private->domain, rk_obj->dma_addr, rk_obj->sgt,
prot);
- if (ret < rk_obj->base.size) {
+ if (ret < (ssize_t)rk_obj->base.size) {
DRM_ERROR("failed to map buffer: size=%zd request_size=%zd\n",
ret, rk_obj->base.size);
ret = -ENOMEM;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index e1ea50c8fd39..066299894d04 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -272,6 +272,18 @@ static bool has_uv_swapped(uint32_t format)
}
}
+static bool is_fmt_10(uint32_t format)
+{
+ switch (format) {
+ case DRM_FORMAT_NV15:
+ case DRM_FORMAT_NV20:
+ case DRM_FORMAT_NV30:
+ return true;
+ default:
+ return false;
+ }
+}
+
static enum vop_data_format vop_convert_format(uint32_t format)
{
switch (format) {
@@ -287,12 +299,15 @@ static enum vop_data_format vop_convert_format(uint32_t format)
case DRM_FORMAT_BGR565:
return VOP_FMT_RGB565;
case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV15:
case DRM_FORMAT_NV21:
return VOP_FMT_YUV420SP;
case DRM_FORMAT_NV16:
+ case DRM_FORMAT_NV20:
case DRM_FORMAT_NV61:
return VOP_FMT_YUV422SP;
case DRM_FORMAT_NV24:
+ case DRM_FORMAT_NV30:
case DRM_FORMAT_NV42:
return VOP_FMT_YUV444SP;
default:
@@ -939,7 +954,12 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
dsp_sty = dest->y1 + crtc->mode.vtotal - crtc->mode.vsync_start;
dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);
- offset = (src->x1 >> 16) * fb->format->cpp[0];
+ if (fb->format->char_per_block[0])
+ offset = drm_format_info_min_pitch(fb->format, 0,
+ src->x1 >> 16);
+ else
+ offset = (src->x1 >> 16) * fb->format->cpp[0];
+
offset += (src->y1 >> 16) * fb->pitches[0];
dma_addr = rk_obj->dma_addr + offset + fb->offsets[0];
@@ -965,6 +985,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
}
VOP_WIN_SET(vop, win, format, format);
+ VOP_WIN_SET(vop, win, fmt_10, is_fmt_10(fb->format->format));
VOP_WIN_SET(vop, win, yrgb_vir, DIV_ROUND_UP(fb->pitches[0], 4));
VOP_WIN_SET(vop, win, yrgb_mst, dma_addr);
VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, y2r_en, is_yuv);
@@ -974,15 +995,16 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
(new_state->rotation & DRM_MODE_REFLECT_X) ? 1 : 0);
if (is_yuv) {
- int hsub = fb->format->hsub;
- int vsub = fb->format->vsub;
- int bpp = fb->format->cpp[1];
-
uv_obj = fb->obj[1];
rk_uv_obj = to_rockchip_obj(uv_obj);
- offset = (src->x1 >> 16) * bpp / hsub;
- offset += (src->y1 >> 16) * fb->pitches[1] / vsub;
+ if (fb->format->char_per_block[1])
+ offset = drm_format_info_min_pitch(fb->format, 1,
+ src->x1 >> 16);
+ else
+ offset = (src->x1 >> 16) * fb->format->cpp[1];
+ offset /= fb->format->hsub;
+ offset += (src->y1 >> 16) * fb->pitches[1] / fb->format->vsub;
dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1];
VOP_WIN_SET(vop, win, uv_vir, DIV_ROUND_UP(fb->pitches[1], 4));
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index 5f56e0597df8..4b2daefeb8c1 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -186,6 +186,7 @@ struct vop_win_phy {
struct vop_reg enable;
struct vop_reg gate;
struct vop_reg format;
+ struct vop_reg fmt_10;
struct vop_reg rb_swap;
struct vop_reg uv_swap;
struct vop_reg act_info;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index ec7e0e6149af..6862fb146ace 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -160,7 +160,6 @@ struct vop2_video_port {
struct vop2 *vop2;
struct clk *dclk;
unsigned int id;
- const struct vop2_video_port_regs *regs;
const struct vop2_video_port_data *data;
struct completion dsp_hold_completion;
@@ -283,9 +282,28 @@ static void vop2_win_disable(struct vop2_win *win)
vop2_win_write(win, VOP2_WIN_CLUSTER_ENABLE, 0);
}
+static u32 vop2_get_bpp(const struct drm_format_info *format)
+{
+ switch (format->format) {
+ case DRM_FORMAT_YUV420_8BIT:
+ return 12;
+ case DRM_FORMAT_YUV420_10BIT:
+ return 15;
+ case DRM_FORMAT_VUY101010:
+ return 30;
+ default:
+ return drm_format_info_bpp(format, 0);
+ }
+}
+
static enum vop2_data_format vop2_convert_format(u32 format)
{
switch (format) {
+ case DRM_FORMAT_XRGB2101010:
+ case DRM_FORMAT_ARGB2101010:
+ case DRM_FORMAT_XBGR2101010:
+ case DRM_FORMAT_ABGR2101010:
+ return VOP2_FMT_XRGB101010;
case DRM_FORMAT_XRGB8888:
case DRM_FORMAT_ARGB8888:
case DRM_FORMAT_XBGR8888:
@@ -298,10 +316,19 @@ static enum vop2_data_format vop2_convert_format(u32 format)
case DRM_FORMAT_BGR565:
return VOP2_FMT_RGB565;
case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV21:
+ case DRM_FORMAT_YUV420_8BIT:
return VOP2_FMT_YUV420SP;
+ case DRM_FORMAT_NV15:
+ case DRM_FORMAT_YUV420_10BIT:
+ return VOP2_FMT_YUV420SP_10;
case DRM_FORMAT_NV16:
+ case DRM_FORMAT_NV61:
return VOP2_FMT_YUV422SP;
+ case DRM_FORMAT_Y210:
+ return VOP2_FMT_YUV422SP_10;
case DRM_FORMAT_NV24:
+ case DRM_FORMAT_NV42:
return VOP2_FMT_YUV444SP;
case DRM_FORMAT_YUYV:
case DRM_FORMAT_YVYU:
@@ -318,6 +345,11 @@ static enum vop2_data_format vop2_convert_format(u32 format)
static enum vop2_afbc_format vop2_convert_afbc_format(u32 format)
{
switch (format) {
+ case DRM_FORMAT_XRGB2101010:
+ case DRM_FORMAT_ARGB2101010:
+ case DRM_FORMAT_XBGR2101010:
+ case DRM_FORMAT_ABGR2101010:
+ return VOP2_AFBC_FMT_ARGB2101010;
case DRM_FORMAT_XRGB8888:
case DRM_FORMAT_ARGB8888:
case DRM_FORMAT_XBGR8888:
@@ -329,10 +361,17 @@ static enum vop2_afbc_format vop2_convert_afbc_format(u32 format)
case DRM_FORMAT_RGB565:
case DRM_FORMAT_BGR565:
return VOP2_AFBC_FMT_RGB565;
- case DRM_FORMAT_NV12:
+ case DRM_FORMAT_YUV420_8BIT:
return VOP2_AFBC_FMT_YUV420;
- case DRM_FORMAT_NV16:
+ case DRM_FORMAT_YUV420_10BIT:
+ return VOP2_AFBC_FMT_YUV420_10BIT;
+ case DRM_FORMAT_YVYU:
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_VYUY:
+ case DRM_FORMAT_UYVY:
return VOP2_AFBC_FMT_YUV422;
+ case DRM_FORMAT_Y210:
+ return VOP2_AFBC_FMT_YUV422_10BIT;
default:
return VOP2_AFBC_FMT_INVALID;
}
@@ -343,6 +382,8 @@ static enum vop2_afbc_format vop2_convert_afbc_format(u32 format)
static bool vop2_win_rb_swap(u32 format)
{
switch (format) {
+ case DRM_FORMAT_XBGR2101010:
+ case DRM_FORMAT_ABGR2101010:
case DRM_FORMAT_XBGR8888:
case DRM_FORMAT_ABGR8888:
case DRM_FORMAT_BGR888:
@@ -353,21 +394,13 @@ static bool vop2_win_rb_swap(u32 format)
}
}
-static bool vop2_afbc_rb_swap(u32 format)
-{
- switch (format) {
- case DRM_FORMAT_NV24:
- return true;
- default:
- return false;
- }
-}
-
static bool vop2_afbc_uv_swap(u32 format)
{
switch (format) {
- case DRM_FORMAT_NV12:
- case DRM_FORMAT_NV16:
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_Y210:
+ case DRM_FORMAT_YUV420_8BIT:
+ case DRM_FORMAT_YUV420_10BIT:
return true;
default:
return false;
@@ -380,6 +413,9 @@ static bool vop2_win_uv_swap(u32 format)
case DRM_FORMAT_NV12:
case DRM_FORMAT_NV16:
case DRM_FORMAT_NV24:
+ case DRM_FORMAT_NV15:
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_UYVY:
return true;
default:
return false;
@@ -483,7 +519,7 @@ static u32 vop2_afbc_transform_offset(struct drm_plane_state *pstate,
{
struct drm_rect *src = &pstate->src;
struct drm_framebuffer *fb = pstate->fb;
- u32 bpp = fb->format->cpp[0] * 8;
+ u32 bpp = vop2_get_bpp(fb->format);
u32 vir_width = (fb->pitches[0] << 3) / bpp;
u32 width = drm_rect_width(src) >> 16;
u32 height = drm_rect_height(src) >> 16;
@@ -1081,7 +1117,7 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
struct vop2 *vop2 = win->vop2;
struct drm_framebuffer *fb = pstate->fb;
- u32 bpp = fb->format->cpp[0] * 8;
+ u32 bpp = vop2_get_bpp(fb->format);
u32 actual_w, actual_h, dsp_w, dsp_h;
u32 act_info, dsp_info;
u32 format;
@@ -1219,7 +1255,6 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
drm_err(vop2->drm, "vp%d %s stride[%d] not 64 pixel aligned\n",
vp->id, win->data->name, stride);
- rb_swap = vop2_afbc_rb_swap(fb->format->format);
uv_swap = vop2_afbc_uv_swap(fb->format->format);
/*
* This is a workaround for crazy IC design, Cluster
@@ -1236,7 +1271,6 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
if (vop2_cluster_window(win))
vop2_win_write(win, VOP2_WIN_AFBC_ENABLE, 1);
vop2_win_write(win, VOP2_WIN_AFBC_FORMAT, afbc_format);
- vop2_win_write(win, VOP2_WIN_AFBC_RB_SWAP, rb_swap);
vop2_win_write(win, VOP2_WIN_AFBC_UV_SWAP, uv_swap);
vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 0);
vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 0);
@@ -2251,8 +2285,6 @@ static struct vop2_video_port *find_vp_without_primary(struct vop2 *vop2)
return NULL;
}
-#define NR_LAYERS 6
-
static int vop2_create_crtcs(struct vop2 *vop2)
{
const struct vop2_data *vop2_data = vop2->data;
@@ -2273,7 +2305,6 @@ static int vop2_create_crtcs(struct vop2 *vop2)
vp = &vop2->vps[i];
vp->vop2 = vop2;
vp->id = vp_data->id;
- vp->regs = vp_data->regs;
vp->data = vp_data;
snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", vp->id);
@@ -2372,7 +2403,7 @@ static int vop2_create_crtcs(struct vop2 *vop2)
struct vop2_video_port *vp = &vop2->vps[i];
if (vp->crtc.port)
- vp->nlayers = NR_LAYERS / nvps;
+ vp->nlayers = vop2_data->win_size / nvps;
}
return 0;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index f1234a151130..56fd31e05238 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -134,16 +134,13 @@ struct vop2_video_port_data {
u16 cubic_lut_len;
struct vop_rect max_output;
const u8 pre_scan_max_dly[4];
- const struct vop2_video_port_regs *regs;
unsigned int offset;
};
struct vop2_data {
u8 nr_vps;
- const struct vop2_ctrl *ctrl;
const struct vop2_win_data *win;
const struct vop2_video_port_data *vp;
- const struct vop_csc_table *csc_table;
struct vop_rect max_input;
struct vop_rect max_output;
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index fcd4cf3072cd..22288ad7f326 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -15,7 +15,11 @@
#include "rockchip_drm_vop2.h"
-static const uint32_t formats_win_full_10bit[] = {
+static const uint32_t formats_cluster[] = {
+ DRM_FORMAT_XRGB2101010,
+ DRM_FORMAT_ARGB2101010,
+ DRM_FORMAT_XBGR2101010,
+ DRM_FORMAT_ABGR2101010,
DRM_FORMAT_XRGB8888,
DRM_FORMAT_ARGB8888,
DRM_FORMAT_XBGR8888,
@@ -24,12 +28,13 @@ static const uint32_t formats_win_full_10bit[] = {
DRM_FORMAT_BGR888,
DRM_FORMAT_RGB565,
DRM_FORMAT_BGR565,
- DRM_FORMAT_NV12,
- DRM_FORMAT_NV16,
- DRM_FORMAT_NV24,
+ DRM_FORMAT_YUV420_8BIT, /* yuv420_8bit non-Linear mode only */
+ DRM_FORMAT_YUV420_10BIT, /* yuv420_10bit non-Linear mode only */
+ DRM_FORMAT_YUYV, /* yuv422_8bit non-Linear mode only*/
+ DRM_FORMAT_Y210, /* yuv422_10bit non-Linear mode only */
};
-static const uint32_t formats_win_full_10bit_yuyv[] = {
+static const uint32_t formats_rk356x_esmart[] = {
DRM_FORMAT_XRGB8888,
DRM_FORMAT_ARGB8888,
DRM_FORMAT_XBGR8888,
@@ -38,14 +43,18 @@ static const uint32_t formats_win_full_10bit_yuyv[] = {
DRM_FORMAT_BGR888,
DRM_FORMAT_RGB565,
DRM_FORMAT_BGR565,
- DRM_FORMAT_NV12,
- DRM_FORMAT_NV16,
- DRM_FORMAT_NV24,
- DRM_FORMAT_YVYU,
- DRM_FORMAT_VYUY,
+ DRM_FORMAT_NV12, /* yuv420_8bit linear mode, 2 plane */
+ DRM_FORMAT_NV21, /* yuv420_8bit linear mode, 2 plane */
+ DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */
+ DRM_FORMAT_NV16, /* yuv422_8bit linear mode, 2 plane */
+ DRM_FORMAT_NV61, /* yuv422_8bit linear mode, 2 plane */
+ DRM_FORMAT_NV24, /* yuv444_8bit linear mode, 2 plane */
+ DRM_FORMAT_NV42, /* yuv444_8bit linear mode, 2 plane */
+ DRM_FORMAT_YVYU, /* yuv422_8bit[YVYU] linear mode */
+ DRM_FORMAT_VYUY, /* yuv422_8bit[VYUY] linear mode */
};
-static const uint32_t formats_win_lite[] = {
+static const uint32_t formats_smart[] = {
DRM_FORMAT_XRGB8888,
DRM_FORMAT_ARGB8888,
DRM_FORMAT_XBGR8888,
@@ -144,8 +153,8 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
.name = "Smart0-win0",
.phys_id = ROCKCHIP_VOP2_SMART0,
.base = 0x1c00,
- .formats = formats_win_lite,
- .nformats = ARRAY_SIZE(formats_win_lite),
+ .formats = formats_smart,
+ .nformats = ARRAY_SIZE(formats_smart),
.format_modifiers = format_modifiers,
.layer_sel_id = 3,
.supported_rotations = DRM_MODE_REFLECT_Y,
@@ -156,8 +165,8 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
}, {
.name = "Smart1-win0",
.phys_id = ROCKCHIP_VOP2_SMART1,
- .formats = formats_win_lite,
- .nformats = ARRAY_SIZE(formats_win_lite),
+ .formats = formats_smart,
+ .nformats = ARRAY_SIZE(formats_smart),
.format_modifiers = format_modifiers,
.base = 0x1e00,
.layer_sel_id = 7,
@@ -169,8 +178,8 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
}, {
.name = "Esmart1-win0",
.phys_id = ROCKCHIP_VOP2_ESMART1,
- .formats = formats_win_full_10bit_yuyv,
- .nformats = ARRAY_SIZE(formats_win_full_10bit_yuyv),
+ .formats = formats_rk356x_esmart,
+ .nformats = ARRAY_SIZE(formats_rk356x_esmart),
.format_modifiers = format_modifiers,
.base = 0x1a00,
.layer_sel_id = 6,
@@ -182,8 +191,8 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
}, {
.name = "Esmart0-win0",
.phys_id = ROCKCHIP_VOP2_ESMART0,
- .formats = formats_win_full_10bit_yuyv,
- .nformats = ARRAY_SIZE(formats_win_full_10bit_yuyv),
+ .formats = formats_rk356x_esmart,
+ .nformats = ARRAY_SIZE(formats_rk356x_esmart),
.format_modifiers = format_modifiers,
.base = 0x1800,
.layer_sel_id = 2,
@@ -196,8 +205,8 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
.name = "Cluster0-win0",
.phys_id = ROCKCHIP_VOP2_CLUSTER0,
.base = 0x1000,
- .formats = formats_win_full_10bit,
- .nformats = ARRAY_SIZE(formats_win_full_10bit),
+ .formats = formats_cluster,
+ .nformats = ARRAY_SIZE(formats_cluster),
.format_modifiers = format_modifiers_afbc,
.layer_sel_id = 0,
.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
@@ -211,8 +220,8 @@ static const struct vop2_win_data rk3568_vop_win_data[] = {
.name = "Cluster1-win0",
.phys_id = ROCKCHIP_VOP2_CLUSTER1,
.base = 0x1200,
- .formats = formats_win_full_10bit,
- .nformats = ARRAY_SIZE(formats_win_full_10bit),
+ .formats = formats_cluster,
+ .nformats = ARRAY_SIZE(formats_cluster),
.format_modifiers = format_modifiers_afbc,
.layer_sel_id = 1,
.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index d053ef027552..c51ca82320cb 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -53,6 +53,26 @@ static const uint32_t formats_win_full[] = {
DRM_FORMAT_NV42,
};
+static const uint32_t formats_win_full_10[] = {
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_XBGR8888,
+ DRM_FORMAT_ABGR8888,
+ DRM_FORMAT_RGB888,
+ DRM_FORMAT_BGR888,
+ DRM_FORMAT_RGB565,
+ DRM_FORMAT_BGR565,
+ DRM_FORMAT_NV12,
+ DRM_FORMAT_NV21,
+ DRM_FORMAT_NV16,
+ DRM_FORMAT_NV61,
+ DRM_FORMAT_NV24,
+ DRM_FORMAT_NV42,
+ DRM_FORMAT_NV15,
+ DRM_FORMAT_NV20,
+ DRM_FORMAT_NV30,
+};
+
static const uint64_t format_modifiers_win_full[] = {
DRM_FORMAT_MOD_LINEAR,
DRM_FORMAT_MOD_INVALID,
@@ -627,11 +647,12 @@ static const struct vop_scl_regs rk3288_win_full_scl = {
static const struct vop_win_phy rk3288_win01_data = {
.scl = &rk3288_win_full_scl,
- .data_formats = formats_win_full,
- .nformats = ARRAY_SIZE(formats_win_full),
+ .data_formats = formats_win_full_10,
+ .nformats = ARRAY_SIZE(formats_win_full_10),
.format_modifiers = format_modifiers_win_full,
.enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
.format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
+ .fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 4),
.rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
.uv_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 15),
.act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
@@ -936,13 +957,38 @@ static const struct vop_win_yuv2yuv_data rk3399_vop_big_win_yuv2yuv_data[] = {
};
-static const struct vop_win_phy rk3399_win01_data = {
+static const struct vop_win_phy rk3399_win0_data = {
.scl = &rk3288_win_full_scl,
- .data_formats = formats_win_full,
- .nformats = ARRAY_SIZE(formats_win_full),
+ .data_formats = formats_win_full_10,
+ .nformats = ARRAY_SIZE(formats_win_full_10),
.format_modifiers = format_modifiers_win_full_afbc,
.enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
.format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
+ .fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 4),
+ .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
+ .uv_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 15),
+ .x_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 21),
+ .y_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 22),
+ .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
+ .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
+ .dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0),
+ .yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0),
+ .uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0),
+ .yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0),
+ .uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16),
+ .src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
+ .dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0),
+ .channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0),
+};
+
+static const struct vop_win_phy rk3399_win1_data = {
+ .scl = &rk3288_win_full_scl,
+ .data_formats = formats_win_full_10,
+ .nformats = ARRAY_SIZE(formats_win_full_10),
+ .format_modifiers = format_modifiers_win_full,
+ .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
+ .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
+ .fmt_10 = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 4),
.rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
.uv_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 15),
.x_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 21),
@@ -965,9 +1011,9 @@ static const struct vop_win_phy rk3399_win01_data = {
* AFBC on the primary plane.
*/
static const struct vop_win_data rk3399_vop_win_data[] = {
- { .base = 0x00, .phy = &rk3399_win01_data,
+ { .base = 0x00, .phy = &rk3399_win0_data,
.type = DRM_PLANE_TYPE_PRIMARY },
- { .base = 0x40, .phy = &rk3368_win01_data,
+ { .base = 0x40, .phy = &rk3399_win1_data,
.type = DRM_PLANE_TYPE_OVERLAY },
{ .base = 0x00, .phy = &rk3368_win23_data,
.type = DRM_PLANE_TYPE_OVERLAY },
@@ -1099,11 +1145,11 @@ static const struct vop_intr rk3328_vop_intr = {
};
static const struct vop_win_data rk3328_vop_win_data[] = {
- { .base = 0xd0, .phy = &rk3368_win01_data,
+ { .base = 0xd0, .phy = &rk3399_win1_data,
.type = DRM_PLANE_TYPE_PRIMARY },
- { .base = 0x1d0, .phy = &rk3368_win01_data,
+ { .base = 0x1d0, .phy = &rk3399_win1_data,
.type = DRM_PLANE_TYPE_OVERLAY },
- { .base = 0x2d0, .phy = &rk3368_win01_data,
+ { .base = 0x2d0, .phy = &rk3399_win1_data,
.type = DRM_PLANE_TYPE_CURSOR },
};
diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c
index a42763e1429d..409e4256f6e7 100644
--- a/drivers/gpu/drm/scheduler/sched_entity.c
+++ b/drivers/gpu/drm/scheduler/sched_entity.c
@@ -75,8 +75,20 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
RCU_INIT_POINTER(entity->last_scheduled, NULL);
RB_CLEAR_NODE(&entity->rb_tree_node);
- if(num_sched_list)
- entity->rq = &sched_list[0]->sched_rq[entity->priority];
+ if (!sched_list[0]->sched_rq) {
+ /* Warn drivers not to do this and to fix their DRM
+ * calling order.
+ */
+ pr_warn("%s: called with uninitialized scheduler\n", __func__);
+ } else if (num_sched_list) {
+ /* The "priority" of an entity cannot exceed the number
+ * of run-queues of a scheduler.
+ */
+ if (entity->priority >= sched_list[0]->num_rqs)
+ entity->priority = max_t(u32, sched_list[0]->num_rqs,
+ DRM_SCHED_PRIORITY_MIN);
+ entity->rq = sched_list[0]->sched_rq[entity->priority];
+ }
init_completion(&entity->entity_idle);
@@ -533,7 +545,7 @@ void drm_sched_entity_select_rq(struct drm_sched_entity *entity)
spin_lock(&entity->rq_lock);
sched = drm_sched_pick_best(entity->sched_list, entity->num_sched_list);
- rq = sched ? &sched->sched_rq[entity->priority] : NULL;
+ rq = sched ? sched->sched_rq[entity->priority] : NULL;
if (rq != entity->rq) {
drm_sched_rq_remove_entity(entity->rq, entity);
entity->rq = rq;
diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c
index 5a3a622fc672..99797a8c836a 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -632,8 +632,14 @@ int drm_sched_job_init(struct drm_sched_job *job,
struct drm_sched_entity *entity,
void *owner)
{
- if (!entity->rq)
+ if (!entity->rq) {
+ /* This will most likely be followed by missing frames
+ * or worse--a blank screen--leave a trail in the
+ * logs, so this can be debugged easier.
+ */
+ drm_err(job->sched, "%s: entity has no rq!\n", __func__);
return -ENOENT;
+ }
job->entity = entity;
job->s_fence = drm_sched_fence_alloc(entity, owner);
@@ -671,7 +677,7 @@ void drm_sched_job_arm(struct drm_sched_job *job)
sched = entity->rq->sched;
job->sched = sched;
- job->s_priority = entity->rq - sched->sched_rq;
+ job->s_priority = entity->priority;
job->id = atomic64_inc_return(&sched->job_id_count);
drm_sched_fence_init(job->s_fence, job->entity);
@@ -888,10 +894,10 @@ drm_sched_select_entity(struct drm_gpu_scheduler *sched)
return NULL;
/* Kernel run queue has higher priority than normal run queue*/
- for (i = DRM_SCHED_PRIORITY_COUNT - 1; i >= DRM_SCHED_PRIORITY_MIN; i--) {
+ for (i = sched->num_rqs - 1; i >= DRM_SCHED_PRIORITY_MIN; i--) {
entity = drm_sched_policy == DRM_SCHED_POLICY_FIFO ?
- drm_sched_rq_select_entity_fifo(&sched->sched_rq[i]) :
- drm_sched_rq_select_entity_rr(&sched->sched_rq[i]);
+ drm_sched_rq_select_entity_fifo(sched->sched_rq[i]) :
+ drm_sched_rq_select_entity_rr(sched->sched_rq[i]);
if (entity)
break;
}
@@ -1071,6 +1077,7 @@ static int drm_sched_main(void *param)
*
* @sched: scheduler instance
* @ops: backend operations for this scheduler
+ * @num_rqs: number of runqueues, one for each priority, up to DRM_SCHED_PRIORITY_COUNT
* @hw_submission: number of hw submissions that can be in flight
* @hang_limit: number of times to allow a job to hang before dropping it
* @timeout: timeout value in jiffies for the scheduler
@@ -1084,11 +1091,12 @@ static int drm_sched_main(void *param)
*/
int drm_sched_init(struct drm_gpu_scheduler *sched,
const struct drm_sched_backend_ops *ops,
- unsigned hw_submission, unsigned hang_limit,
+ u32 num_rqs, uint32_t hw_submission, unsigned int hang_limit,
long timeout, struct workqueue_struct *timeout_wq,
atomic_t *score, const char *name, struct device *dev)
{
int i, ret;
+
sched->ops = ops;
sched->hw_submission_limit = hw_submission;
sched->name = name;
@@ -1097,8 +1105,36 @@ int drm_sched_init(struct drm_gpu_scheduler *sched,
sched->hang_limit = hang_limit;
sched->score = score ? score : &sched->_score;
sched->dev = dev;
- for (i = DRM_SCHED_PRIORITY_MIN; i < DRM_SCHED_PRIORITY_COUNT; i++)
- drm_sched_rq_init(sched, &sched->sched_rq[i]);
+
+ if (num_rqs > DRM_SCHED_PRIORITY_COUNT) {
+ /* This is a gross violation--tell drivers what the problem is.
+ */
+ drm_err(sched, "%s: num_rqs cannot be greater than DRM_SCHED_PRIORITY_COUNT\n",
+ __func__);
+ return -EINVAL;
+ } else if (sched->sched_rq) {
+ /* Not an error, but warn anyway so drivers can
+ * fine-tune their DRM calling order, and return all
+ * is good.
+ */
+ drm_warn(sched, "%s: scheduler already initialized!\n", __func__);
+ return 0;
+ }
+
+ sched->sched_rq = kmalloc_array(num_rqs, sizeof(*sched->sched_rq),
+ GFP_KERNEL | __GFP_ZERO);
+ if (!sched->sched_rq) {
+ drm_err(sched, "%s: out of memory for sched_rq\n", __func__);
+ return -ENOMEM;
+ }
+ sched->num_rqs = num_rqs;
+ ret = -ENOMEM;
+ for (i = DRM_SCHED_PRIORITY_MIN; i < sched->num_rqs; i++) {
+ sched->sched_rq[i] = kzalloc(sizeof(*sched->sched_rq[i]), GFP_KERNEL);
+ if (!sched->sched_rq[i])
+ goto Out_unroll;
+ drm_sched_rq_init(sched, sched->sched_rq[i]);
+ }
init_waitqueue_head(&sched->wake_up_worker);
init_waitqueue_head(&sched->job_scheduled);
@@ -1115,11 +1151,18 @@ int drm_sched_init(struct drm_gpu_scheduler *sched,
ret = PTR_ERR(sched->thread);
sched->thread = NULL;
DRM_DEV_ERROR(sched->dev, "Failed to create scheduler for %s.\n", name);
- return ret;
+ goto Out_unroll;
}
sched->ready = true;
return 0;
+Out_unroll:
+ for (--i ; i >= DRM_SCHED_PRIORITY_MIN; i--)
+ kfree(sched->sched_rq[i]);
+ kfree(sched->sched_rq);
+ sched->sched_rq = NULL;
+ drm_err(sched, "%s: Failed to setup GPU scheduler--out of memory\n", __func__);
+ return ret;
}
EXPORT_SYMBOL(drm_sched_init);
@@ -1138,8 +1181,8 @@ void drm_sched_fini(struct drm_gpu_scheduler *sched)
if (sched->thread)
kthread_stop(sched->thread);
- for (i = DRM_SCHED_PRIORITY_COUNT - 1; i >= DRM_SCHED_PRIORITY_MIN; i--) {
- struct drm_sched_rq *rq = &sched->sched_rq[i];
+ for (i = sched->num_rqs - 1; i >= DRM_SCHED_PRIORITY_MIN; i--) {
+ struct drm_sched_rq *rq = sched->sched_rq[i];
spin_lock(&rq->lock);
list_for_each_entry(s_entity, &rq->entities, list)
@@ -1150,7 +1193,7 @@ void drm_sched_fini(struct drm_gpu_scheduler *sched)
*/
s_entity->stopped = true;
spin_unlock(&rq->lock);
-
+ kfree(sched->sched_rq[i]);
}
/* Wakeup everyone stuck in drm_sched_entity_flush for this scheduler */
@@ -1160,6 +1203,8 @@ void drm_sched_fini(struct drm_gpu_scheduler *sched)
cancel_delayed_work_sync(&sched->work_tdr);
sched->ready = false;
+ kfree(sched->sched_rq);
+ sched->sched_rq = NULL;
}
EXPORT_SYMBOL(drm_sched_fini);
@@ -1186,9 +1231,10 @@ void drm_sched_increase_karma(struct drm_sched_job *bad)
if (bad->s_priority != DRM_SCHED_PRIORITY_KERNEL) {
atomic_inc(&bad->karma);
- for (i = DRM_SCHED_PRIORITY_MIN; i < DRM_SCHED_PRIORITY_KERNEL;
+ for (i = DRM_SCHED_PRIORITY_MIN;
+ i < min_t(typeof(sched->num_rqs), sched->num_rqs, DRM_SCHED_PRIORITY_KERNEL);
i++) {
- struct drm_sched_rq *rq = &sched->sched_rq[i];
+ struct drm_sched_rq *rq = sched->sched_rq[i];
spin_lock(&rq->lock);
list_for_each_entry_safe(entity, tmp, &rq->entities, list) {
diff --git a/drivers/gpu/drm/solomon/Kconfig b/drivers/gpu/drm/solomon/Kconfig
index e170716d976b..c3ee956c2bb9 100644
--- a/drivers/gpu/drm/solomon/Kconfig
+++ b/drivers/gpu/drm/solomon/Kconfig
@@ -1,31 +1,31 @@
config DRM_SSD130X
- tristate "DRM support for Solomon SSD130x OLED displays"
+ tristate "DRM support for Solomon SSD13xx OLED displays"
depends on DRM && MMU
select BACKLIGHT_CLASS_DEVICE
select DRM_GEM_SHMEM_HELPER
select DRM_KMS_HELPER
help
- DRM driver for the SSD130x Solomon and SINO WEALTH SH110x OLED
+ DRM driver for the SSD13xx Solomon and SINO WEALTH SH110x OLED
controllers. This is only for the core driver, a driver for the
appropriate bus transport in your chip also must be selected.
If M is selected the module will be called ssd130x.
config DRM_SSD130X_I2C
- tristate "DRM support for Solomon SSD130x OLED displays (I2C bus)"
+ tristate "DRM support for Solomon SSD13xx OLED displays (I2C bus)"
depends on DRM_SSD130X && I2C
select REGMAP_I2C
help
- Say Y here if the SSD130x or SH110x OLED display is connected via
+ Say Y here if the SSD13xx or SH110x OLED display is connected via
I2C bus.
If M is selected the module will be called ssd130x-i2c.
config DRM_SSD130X_SPI
- tristate "DRM support for Solomon SSD130X OLED displays (SPI bus)"
+ tristate "DRM support for Solomon SSD13xx OLED displays (SPI bus)"
depends on DRM_SSD130X && SPI
select REGMAP
help
- Say Y here if the SSD130x OLED display is connected via SPI bus.
+ Say Y here if the SSD13xx OLED display is connected via SPI bus.
If M is selected the module will be called ssd130x-spi.
diff --git a/drivers/gpu/drm/solomon/ssd130x-i2c.c b/drivers/gpu/drm/solomon/ssd130x-i2c.c
index b4eb2d64bf6e..f2ccab9c06d9 100644
--- a/drivers/gpu/drm/solomon/ssd130x-i2c.c
+++ b/drivers/gpu/drm/solomon/ssd130x-i2c.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * DRM driver for Solomon SSD130x OLED displays (I2C bus)
+ * DRM driver for Solomon SSD13xx OLED displays (I2C bus)
*
* Copyright 2022 Red Hat Inc.
* Author: Javier Martinez Canillas <javierm@redhat.com>
@@ -14,7 +14,7 @@
#include "ssd130x.h"
#define DRIVER_NAME "ssd130x-i2c"
-#define DRIVER_DESC "DRM driver for Solomon SSD130x OLED displays (I2C)"
+#define DRIVER_DESC "DRM driver for Solomon SSD13xx OLED displays (I2C)"
static const struct regmap_config ssd130x_i2c_regmap_config = {
.reg_bits = 8,
@@ -54,6 +54,7 @@ static void ssd130x_i2c_shutdown(struct i2c_client *client)
}
static const struct of_device_id ssd130x_of_match[] = {
+ /* ssd130x family */
{
.compatible = "sinowealth,sh1106",
.data = &ssd130x_variants[SH1106_ID],
@@ -91,6 +92,19 @@ static const struct of_device_id ssd130x_of_match[] = {
.compatible = "solomon,ssd1309fb-i2c",
.data = &ssd130x_variants[SSD1309_ID],
},
+ /* ssd132x family */
+ {
+ .compatible = "solomon,ssd1322",
+ .data = &ssd130x_variants[SSD1322_ID],
+ },
+ {
+ .compatible = "solomon,ssd1325",
+ .data = &ssd130x_variants[SSD1325_ID],
+ },
+ {
+ .compatible = "solomon,ssd1327",
+ .data = &ssd130x_variants[SSD1327_ID],
+ },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ssd130x_of_match);
diff --git a/drivers/gpu/drm/solomon/ssd130x-spi.c b/drivers/gpu/drm/solomon/ssd130x-spi.c
index 19ab4942cb33..84e035a7ab3f 100644
--- a/drivers/gpu/drm/solomon/ssd130x-spi.c
+++ b/drivers/gpu/drm/solomon/ssd130x-spi.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * DRM driver for Solomon SSD130X OLED displays (SPI bus)
+ * DRM driver for Solomon SSD13xx OLED displays (SPI bus)
*
* Copyright 2022 Red Hat Inc.
* Authors: Javier Martinez Canillas <javierm@redhat.com>
@@ -11,7 +11,7 @@
#include "ssd130x.h"
#define DRIVER_NAME "ssd130x-spi"
-#define DRIVER_DESC "DRM driver for Solomon SSD130X OLED displays (SPI)"
+#define DRIVER_DESC "DRM driver for Solomon SSD13xx OLED displays (SPI)"
struct ssd130x_spi_transport {
struct spi_device *spi;
@@ -34,10 +34,10 @@ static int ssd130x_spi_write(void *context, const void *data, size_t count)
struct spi_device *spi = t->spi;
const u8 *reg = data;
- if (*reg == SSD130X_COMMAND)
+ if (*reg == SSD13XX_COMMAND)
gpiod_set_value_cansleep(t->dc, 0);
- if (*reg == SSD130X_DATA)
+ if (*reg == SSD13XX_DATA)
gpiod_set_value_cansleep(t->dc, 1);
/* Remove control byte since is not used in a 4-wire SPI interface */
@@ -108,6 +108,7 @@ static void ssd130x_spi_shutdown(struct spi_device *spi)
}
static const struct of_device_id ssd130x_of_match[] = {
+ /* ssd130x family */
{
.compatible = "sinowealth,sh1106",
.data = &ssd130x_variants[SH1106_ID],
@@ -128,6 +129,19 @@ static const struct of_device_id ssd130x_of_match[] = {
.compatible = "solomon,ssd1309",
.data = &ssd130x_variants[SSD1309_ID],
},
+ /* ssd132x family */
+ {
+ .compatible = "solomon,ssd1322",
+ .data = &ssd130x_variants[SSD1322_ID],
+ },
+ {
+ .compatible = "solomon,ssd1325",
+ .data = &ssd130x_variants[SSD1325_ID],
+ },
+ {
+ .compatible = "solomon,ssd1327",
+ .data = &ssd130x_variants[SSD1327_ID],
+ },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ssd130x_of_match);
@@ -142,11 +156,16 @@ MODULE_DEVICE_TABLE(of, ssd130x_of_match);
* not be needed for this driver to match the registered SPI devices.
*/
static const struct spi_device_id ssd130x_spi_table[] = {
+ /* ssd130x family */
{ "sh1106", SH1106_ID },
{ "ssd1305", SSD1305_ID },
{ "ssd1306", SSD1306_ID },
{ "ssd1307", SSD1307_ID },
{ "ssd1309", SSD1309_ID },
+ /* ssd132x family */
+ { "ssd1322", SSD1322_ID },
+ { "ssd1325", SSD1325_ID },
+ { "ssd1327", SSD1327_ID },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(spi, ssd130x_spi_table);
diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c
index 6dcf3e041113..e0174f82e353 100644
--- a/drivers/gpu/drm/solomon/ssd130x.c
+++ b/drivers/gpu/drm/solomon/ssd130x.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * DRM driver for Solomon SSD130x OLED displays
+ * DRM driver for Solomon SSD13xx OLED displays
*
* Copyright 2022 Red Hat Inc.
* Author: Javier Martinez Canillas <javierm@redhat.com>
@@ -37,23 +37,33 @@
#include "ssd130x.h"
#define DRIVER_NAME "ssd130x"
-#define DRIVER_DESC "DRM driver for Solomon SSD130x OLED displays"
+#define DRIVER_DESC "DRM driver for Solomon SSD13xx OLED displays"
#define DRIVER_DATE "20220131"
#define DRIVER_MAJOR 1
#define DRIVER_MINOR 0
+#define SSD130X_PAGE_HEIGHT 8
+
+#define SSD132X_SEGMENT_WIDTH 2
+
+/* ssd13xx commands */
+#define SSD13XX_CONTRAST 0x81
+#define SSD13XX_SET_SEG_REMAP 0xa0
+#define SSD13XX_SET_MULTIPLEX_RATIO 0xa8
+#define SSD13XX_DISPLAY_OFF 0xae
+#define SSD13XX_DISPLAY_ON 0xaf
+
+#define SSD13XX_SET_SEG_REMAP_MASK GENMASK(0, 0)
+#define SSD13XX_SET_SEG_REMAP_SET(val) FIELD_PREP(SSD13XX_SET_SEG_REMAP_MASK, (val))
+
+/* ssd130x commands */
#define SSD130X_PAGE_COL_START_LOW 0x00
#define SSD130X_PAGE_COL_START_HIGH 0x10
#define SSD130X_SET_ADDRESS_MODE 0x20
#define SSD130X_SET_COL_RANGE 0x21
#define SSD130X_SET_PAGE_RANGE 0x22
-#define SSD130X_CONTRAST 0x81
#define SSD130X_SET_LOOKUP_TABLE 0x91
#define SSD130X_CHARGE_PUMP 0x8d
-#define SSD130X_SET_SEG_REMAP 0xa0
-#define SSD130X_DISPLAY_OFF 0xae
-#define SSD130X_SET_MULTIPLEX_RATIO 0xa8
-#define SSD130X_DISPLAY_ON 0xaf
#define SSD130X_START_PAGE_ADDRESS 0xb0
#define SSD130X_SET_COM_SCAN_DIR 0xc0
#define SSD130X_SET_DISPLAY_OFFSET 0xd3
@@ -63,13 +73,12 @@
#define SSD130X_SET_COM_PINS_CONFIG 0xda
#define SSD130X_SET_VCOMH 0xdb
+/* ssd130x commands accessors */
#define SSD130X_PAGE_COL_START_MASK GENMASK(3, 0)
#define SSD130X_PAGE_COL_START_HIGH_SET(val) FIELD_PREP(SSD130X_PAGE_COL_START_MASK, (val) >> 4)
#define SSD130X_PAGE_COL_START_LOW_SET(val) FIELD_PREP(SSD130X_PAGE_COL_START_MASK, (val))
#define SSD130X_START_PAGE_ADDRESS_MASK GENMASK(2, 0)
#define SSD130X_START_PAGE_ADDRESS_SET(val) FIELD_PREP(SSD130X_START_PAGE_ADDRESS_MASK, (val))
-#define SSD130X_SET_SEG_REMAP_MASK GENMASK(0, 0)
-#define SSD130X_SET_SEG_REMAP_SET(val) FIELD_PREP(SSD130X_SET_SEG_REMAP_MASK, (val))
#define SSD130X_SET_COM_SCAN_DIR_MASK GENMASK(3, 3)
#define SSD130X_SET_COM_SCAN_DIR_SET(val) FIELD_PREP(SSD130X_SET_COM_SCAN_DIR_MASK, (val))
#define SSD130X_SET_CLOCK_DIV_MASK GENMASK(3, 0)
@@ -92,6 +101,24 @@
#define SSD130X_SET_AREA_COLOR_MODE_ENABLE 0x1e
#define SSD130X_SET_AREA_COLOR_MODE_LOW_POWER 0x05
+/* ssd132x commands */
+#define SSD132X_SET_COL_RANGE 0x15
+#define SSD132X_SET_DEACTIVATE_SCROLL 0x2e
+#define SSD132X_SET_ROW_RANGE 0x75
+#define SSD132X_SET_DISPLAY_START 0xa1
+#define SSD132X_SET_DISPLAY_OFFSET 0xa2
+#define SSD132X_SET_DISPLAY_NORMAL 0xa4
+#define SSD132X_SET_FUNCTION_SELECT_A 0xab
+#define SSD132X_SET_PHASE_LENGTH 0xb1
+#define SSD132X_SET_CLOCK_FREQ 0xb3
+#define SSD132X_SET_GPIO 0xb5
+#define SSD132X_SET_PRECHARGE_PERIOD 0xb6
+#define SSD132X_SET_GRAY_SCALE_TABLE 0xb8
+#define SSD132X_SELECT_DEFAULT_TABLE 0xb9
+#define SSD132X_SET_PRECHARGE_VOLTAGE 0xbc
+#define SSD130X_SET_VCOMH_VOLTAGE 0xbe
+#define SSD132X_SET_FUNCTION_SELECT_B 0xd5
+
#define MAX_CONTRAST 255
const struct ssd130x_deviceinfo ssd130x_variants[] = {
@@ -102,7 +129,7 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = {
.default_width = 132,
.default_height = 64,
.page_mode_only = 1,
- .page_height = 8,
+ .family_id = SSD130X_FAMILY,
},
[SSD1305_ID] = {
.default_vcomh = 0x34,
@@ -110,7 +137,7 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = {
.default_dclk_frq = 7,
.default_width = 132,
.default_height = 64,
- .page_height = 8,
+ .family_id = SSD130X_FAMILY,
},
[SSD1306_ID] = {
.default_vcomh = 0x20,
@@ -119,7 +146,7 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = {
.need_chargepump = 1,
.default_width = 128,
.default_height = 64,
- .page_height = 8,
+ .family_id = SSD130X_FAMILY,
},
[SSD1307_ID] = {
.default_vcomh = 0x20,
@@ -128,7 +155,7 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = {
.need_pwm = 1,
.default_width = 128,
.default_height = 39,
- .page_height = 8,
+ .family_id = SSD130X_FAMILY,
},
[SSD1309_ID] = {
.default_vcomh = 0x34,
@@ -136,7 +163,23 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = {
.default_dclk_frq = 10,
.default_width = 128,
.default_height = 64,
- .page_height = 8,
+ .family_id = SSD130X_FAMILY,
+ },
+ /* ssd132x family */
+ [SSD1322_ID] = {
+ .default_width = 480,
+ .default_height = 128,
+ .family_id = SSD132X_FAMILY,
+ },
+ [SSD1325_ID] = {
+ .default_width = 128,
+ .default_height = 80,
+ .family_id = SSD132X_FAMILY,
+ },
+ [SSD1327_ID] = {
+ .default_width = 128,
+ .default_height = 128,
+ .family_id = SSD132X_FAMILY,
}
};
EXPORT_SYMBOL_NS_GPL(ssd130x_variants, DRM_SSD130X);
@@ -169,20 +212,20 @@ static inline struct ssd130x_device *drm_to_ssd130x(struct drm_device *drm)
}
/*
- * Helper to write data (SSD130X_DATA) to the device.
+ * Helper to write data (SSD13XX_DATA) to the device.
*/
static int ssd130x_write_data(struct ssd130x_device *ssd130x, u8 *values, int count)
{
- return regmap_bulk_write(ssd130x->regmap, SSD130X_DATA, values, count);
+ return regmap_bulk_write(ssd130x->regmap, SSD13XX_DATA, values, count);
}
/*
- * Helper to write command (SSD130X_COMMAND). The fist variadic argument
+ * Helper to write command (SSD13XX_COMMAND). The fist variadic argument
* is the command to write and the following are the command options.
*
- * Note that the ssd130x protocol requires each command and option to be
- * written as a SSD130X_COMMAND device register value. That is why a call
- * to regmap_write(..., SSD130X_COMMAND, ...) is done for each argument.
+ * Note that the ssd13xx protocol requires each command and option to be
+ * written as a SSD13XX_COMMAND device register value. That is why a call
+ * to regmap_write(..., SSD13XX_COMMAND, ...) is done for each argument.
*/
static int ssd130x_write_cmd(struct ssd130x_device *ssd130x, int count,
/* u8 cmd, u8 option, ... */...)
@@ -195,7 +238,7 @@ static int ssd130x_write_cmd(struct ssd130x_device *ssd130x, int count,
do {
value = va_arg(ap, int);
- ret = regmap_write(ssd130x->regmap, SSD130X_COMMAND, value);
+ ret = regmap_write(ssd130x->regmap, SSD13XX_COMMAND, value);
if (ret)
goto out_end;
} while (--count);
@@ -339,13 +382,13 @@ static int ssd130x_init(struct ssd130x_device *ssd130x)
int ret;
/* Set initial contrast */
- ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_CONTRAST, ssd130x->contrast);
+ ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_CONTRAST, ssd130x->contrast);
if (ret < 0)
return ret;
/* Set segment re-map */
- seg_remap = (SSD130X_SET_SEG_REMAP |
- SSD130X_SET_SEG_REMAP_SET(ssd130x->seg_remap));
+ seg_remap = (SSD13XX_SET_SEG_REMAP |
+ SSD13XX_SET_SEG_REMAP_SET(ssd130x->seg_remap));
ret = ssd130x_write_cmd(ssd130x, 1, seg_remap);
if (ret < 0)
return ret;
@@ -358,7 +401,7 @@ static int ssd130x_init(struct ssd130x_device *ssd130x)
return ret;
/* Set multiplex ratio value */
- ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_MULTIPLEX_RATIO, ssd130x->height - 1);
+ ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_SET_MULTIPLEX_RATIO, ssd130x->height - 1);
if (ret < 0)
return ret;
@@ -456,6 +499,96 @@ static int ssd130x_init(struct ssd130x_device *ssd130x)
SSD130X_SET_ADDRESS_MODE_HORIZONTAL);
}
+static int ssd132x_init(struct ssd130x_device *ssd130x)
+{
+ int ret;
+
+ /* Set initial contrast */
+ ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_CONTRAST, 0x80);
+ if (ret < 0)
+ return ret;
+
+ /* Set column start and end */
+ ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_COL_RANGE, 0x00,
+ ssd130x->width / SSD132X_SEGMENT_WIDTH - 1);
+ if (ret < 0)
+ return ret;
+
+ /* Set row start and end */
+ ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_ROW_RANGE, 0x00, ssd130x->height - 1);
+ if (ret < 0)
+ return ret;
+ /*
+ * Horizontal Address Increment
+ * Re-map for Column Address, Nibble and COM
+ * COM Split Odd Even
+ */
+ ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_SET_SEG_REMAP, 0x53);
+ if (ret < 0)
+ return ret;
+
+ /* Set display start and offset */
+ ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_DISPLAY_START, 0x00);
+ if (ret < 0)
+ return ret;
+
+ ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_DISPLAY_OFFSET, 0x00);
+ if (ret < 0)
+ return ret;
+
+ /* Set display mode normal */
+ ret = ssd130x_write_cmd(ssd130x, 1, SSD132X_SET_DISPLAY_NORMAL);
+ if (ret < 0)
+ return ret;
+
+ /* Set multiplex ratio value */
+ ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_SET_MULTIPLEX_RATIO, ssd130x->height - 1);
+ if (ret < 0)
+ return ret;
+
+ /* Set phase length */
+ ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_PHASE_LENGTH, 0x55);
+ if (ret < 0)
+ return ret;
+
+ /* Select default linear gray scale table */
+ ret = ssd130x_write_cmd(ssd130x, 1, SSD132X_SELECT_DEFAULT_TABLE);
+ if (ret < 0)
+ return ret;
+
+ /* Set clock frequency */
+ ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_CLOCK_FREQ, 0x01);
+ if (ret < 0)
+ return ret;
+
+ /* Enable internal VDD regulator */
+ ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_FUNCTION_SELECT_A, 0x1);
+ if (ret < 0)
+ return ret;
+
+ /* Set pre-charge period */
+ ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_PRECHARGE_PERIOD, 0x01);
+ if (ret < 0)
+ return ret;
+
+ /* Set pre-charge voltage */
+ ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_PRECHARGE_VOLTAGE, 0x08);
+ if (ret < 0)
+ return ret;
+
+ /* Set VCOMH voltage */
+ ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_VCOMH_VOLTAGE, 0x07);
+ if (ret < 0)
+ return ret;
+
+ /* Enable second pre-charge and internal VSL */
+ ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_FUNCTION_SELECT_B, 0x62);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
static int ssd130x_update_rect(struct ssd130x_device *ssd130x,
struct drm_rect *rect, u8 *buf,
u8 *data_array)
@@ -465,13 +598,13 @@ static int ssd130x_update_rect(struct ssd130x_device *ssd130x,
unsigned int width = drm_rect_width(rect);
unsigned int height = drm_rect_height(rect);
unsigned int line_length = DIV_ROUND_UP(width, 8);
- unsigned int page_height = ssd130x->device_info->page_height;
+ unsigned int page_height = SSD130X_PAGE_HEIGHT;
unsigned int pages = DIV_ROUND_UP(height, page_height);
struct drm_device *drm = &ssd130x->drm;
u32 array_idx = 0;
int ret, i, j, k;
- drm_WARN_ONCE(drm, y % 8 != 0, "y must be aligned to screen page\n");
+ drm_WARN_ONCE(drm, y % page_height != 0, "y must be aligned to screen page\n");
/*
* The screen is divided in pages, each having a height of 8
@@ -503,27 +636,32 @@ static int ssd130x_update_rect(struct ssd130x_device *ssd130x,
*/
if (!ssd130x->page_address_mode) {
+ u8 page_start;
+
/* Set address range for horizontal addressing mode */
ret = ssd130x_set_col_range(ssd130x, ssd130x->col_offset + x, width);
if (ret < 0)
return ret;
- ret = ssd130x_set_page_range(ssd130x, ssd130x->page_offset + y / 8, pages);
+ page_start = ssd130x->page_offset + y / page_height;
+ ret = ssd130x_set_page_range(ssd130x, page_start, pages);
if (ret < 0)
return ret;
}
for (i = 0; i < pages; i++) {
- int m = 8;
+ int m = page_height;
/* Last page may be partial */
- if (8 * (y / 8 + i + 1) > ssd130x->height)
- m = ssd130x->height % 8;
+ if (page_height * (y / page_height + i + 1) > ssd130x->height)
+ m = ssd130x->height % page_height;
+
for (j = 0; j < width; j++) {
u8 data = 0;
for (k = 0; k < m; k++) {
- u8 byte = buf[(8 * i + k) * line_length + j / 8];
+ u32 idx = (page_height * i + k) * line_length + j / 8;
+ u8 byte = buf[idx];
u8 bit = (byte >> (j % 8)) & 1;
data |= bit << k;
@@ -557,10 +695,67 @@ static int ssd130x_update_rect(struct ssd130x_device *ssd130x,
return ret;
}
+static int ssd132x_update_rect(struct ssd130x_device *ssd130x,
+ struct drm_rect *rect, u8 *buf,
+ u8 *data_array)
+{
+ unsigned int x = rect->x1;
+ unsigned int y = rect->y1;
+ unsigned int segment_width = SSD132X_SEGMENT_WIDTH;
+ unsigned int width = drm_rect_width(rect);
+ unsigned int height = drm_rect_height(rect);
+ unsigned int columns = DIV_ROUND_UP(width, segment_width);
+ unsigned int rows = height;
+ struct drm_device *drm = &ssd130x->drm;
+ u32 array_idx = 0;
+ unsigned int i, j;
+ int ret;
+
+ drm_WARN_ONCE(drm, x % segment_width != 0, "x must be aligned to screen segment\n");
+
+ /*
+ * The screen is divided in Segment and Common outputs, where
+ * COM0 to COM[N - 1] are the rows and SEG0 to SEG[M - 1] are
+ * the columns.
+ *
+ * Each Segment has a 4-bit pixel and each Common output has a
+ * row of pixels. When using the (default) horizontal address
+ * increment mode, each byte of data sent to the controller has
+ * two Segments (e.g: SEG0 and SEG1) that are stored in the lower
+ * and higher nibbles of a single byte representing one column.
+ * That is, the first byte are SEG0 (D0[3:0]) and SEG1 (D0[7:4]),
+ * the second byte are SEG2 (D1[3:0]) and SEG3 (D1[7:4]) and so on.
+ */
+
+ /* Set column start and end */
+ ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_COL_RANGE, x / segment_width, columns - 1);
+ if (ret < 0)
+ return ret;
+
+ /* Set row start and end */
+ ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_ROW_RANGE, y, rows - 1);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < height; i++) {
+ /* Process pair of pixels and combine them into a single byte */
+ for (j = 0; j < width; j += segment_width) {
+ u8 n1 = buf[i * width + j];
+ u8 n2 = buf[i * width + j + 1];
+
+ data_array[array_idx++] = (n2 << 4) | n1;
+ }
+ }
+
+ /* Write out update in one go since horizontal addressing mode is used */
+ ret = ssd130x_write_data(ssd130x, data_array, columns * rows);
+
+ return ret;
+}
+
static void ssd130x_clear_screen(struct ssd130x_device *ssd130x, u8 *data_array)
{
- unsigned int page_height = ssd130x->device_info->page_height;
- unsigned int pages = DIV_ROUND_UP(ssd130x->height, page_height);
+ unsigned int pages = DIV_ROUND_UP(ssd130x->height, SSD130X_PAGE_HEIGHT);
unsigned int width = ssd130x->width;
int ret, i;
@@ -599,20 +794,30 @@ static void ssd130x_clear_screen(struct ssd130x_device *ssd130x, u8 *data_array)
}
}
+static void ssd132x_clear_screen(struct ssd130x_device *ssd130x, u8 *data_array)
+{
+ unsigned int columns = DIV_ROUND_UP(ssd130x->height, SSD132X_SEGMENT_WIDTH);
+ unsigned int height = ssd130x->height;
+
+ memset(data_array, 0, columns * height);
+
+ /* Write out update in one go since horizontal addressing mode is used */
+ ssd130x_write_data(ssd130x, data_array, columns * height);
+}
+
static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb,
const struct iosys_map *vmap,
struct drm_rect *rect,
u8 *buf, u8 *data_array)
{
struct ssd130x_device *ssd130x = drm_to_ssd130x(fb->dev);
- unsigned int page_height = ssd130x->device_info->page_height;
struct iosys_map dst;
unsigned int dst_pitch;
int ret = 0;
/* Align y to display page boundaries */
- rect->y1 = round_down(rect->y1, page_height);
- rect->y2 = min_t(unsigned int, round_up(rect->y2, page_height), ssd130x->height);
+ rect->y1 = round_down(rect->y1, SSD130X_PAGE_HEIGHT);
+ rect->y2 = min_t(unsigned int, round_up(rect->y2, SSD130X_PAGE_HEIGHT), ssd130x->height);
dst_pitch = DIV_ROUND_UP(drm_rect_width(rect), 8);
@@ -630,6 +835,35 @@ static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb,
return ret;
}
+static int ssd132x_fb_blit_rect(struct drm_framebuffer *fb,
+ const struct iosys_map *vmap,
+ struct drm_rect *rect, u8 *buf,
+ u8 *data_array)
+{
+ struct ssd130x_device *ssd130x = drm_to_ssd130x(fb->dev);
+ unsigned int dst_pitch = drm_rect_width(rect);
+ struct iosys_map dst;
+ int ret = 0;
+
+ /* Align x to display segment boundaries */
+ rect->x1 = round_down(rect->x1, SSD132X_SEGMENT_WIDTH);
+ rect->x2 = min_t(unsigned int, round_up(rect->x2, SSD132X_SEGMENT_WIDTH),
+ ssd130x->width);
+
+ ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
+ if (ret)
+ return ret;
+
+ iosys_map_set_vaddr(&dst, buf);
+ drm_fb_xrgb8888_to_gray8(&dst, &dst_pitch, vmap, fb, rect);
+
+ drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
+
+ ssd132x_update_rect(ssd130x, rect, buf, data_array);
+
+ return ret;
+}
+
static int ssd130x_primary_plane_atomic_check(struct drm_plane *plane,
struct drm_atomic_state *state)
{
@@ -638,23 +872,62 @@ static int ssd130x_primary_plane_atomic_check(struct drm_plane *plane,
struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
struct ssd130x_plane_state *ssd130x_state = to_ssd130x_plane_state(plane_state);
struct drm_crtc *crtc = plane_state->crtc;
- struct drm_crtc_state *crtc_state;
+ struct drm_crtc_state *crtc_state = NULL;
const struct drm_format_info *fi;
unsigned int pitch;
int ret;
- if (!crtc)
+ if (crtc)
+ crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+
+ ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state,
+ DRM_PLANE_NO_SCALING,
+ DRM_PLANE_NO_SCALING,
+ false, false);
+ if (ret)
+ return ret;
+ else if (!plane_state->visible)
+ return 0;
+
+ fi = drm_format_info(DRM_FORMAT_R1);
+ if (!fi)
return -EINVAL;
- crtc_state = drm_atomic_get_crtc_state(state, crtc);
- if (IS_ERR(crtc_state))
- return PTR_ERR(crtc_state);
+ pitch = drm_format_info_min_pitch(fi, 0, ssd130x->width);
+
+ ssd130x_state->buffer = kcalloc(pitch, ssd130x->height, GFP_KERNEL);
+ if (!ssd130x_state->buffer)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static int ssd132x_primary_plane_atomic_check(struct drm_plane *plane,
+ struct drm_atomic_state *state)
+{
+ struct drm_device *drm = plane->dev;
+ struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
+ struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
+ struct ssd130x_plane_state *ssd130x_state = to_ssd130x_plane_state(plane_state);
+ struct drm_crtc *crtc = plane_state->crtc;
+ struct drm_crtc_state *crtc_state = NULL;
+ const struct drm_format_info *fi;
+ unsigned int pitch;
+ int ret;
+
+ if (crtc)
+ crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
- ret = drm_plane_helper_atomic_check(plane, state);
+ ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state,
+ DRM_PLANE_NO_SCALING,
+ DRM_PLANE_NO_SCALING,
+ false, false);
if (ret)
return ret;
+ else if (!plane_state->visible)
+ return 0;
- fi = drm_format_info(DRM_FORMAT_R1);
+ fi = drm_format_info(DRM_FORMAT_R8);
if (!fi)
return -EINVAL;
@@ -701,6 +974,40 @@ static void ssd130x_primary_plane_atomic_update(struct drm_plane *plane,
drm_dev_exit(idx);
}
+static void ssd132x_primary_plane_atomic_update(struct drm_plane *plane,
+ struct drm_atomic_state *state)
+{
+ struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
+ struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
+ struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
+ struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc);
+ struct ssd130x_crtc_state *ssd130x_crtc_state = to_ssd130x_crtc_state(crtc_state);
+ struct ssd130x_plane_state *ssd130x_plane_state = to_ssd130x_plane_state(plane_state);
+ struct drm_framebuffer *fb = plane_state->fb;
+ struct drm_atomic_helper_damage_iter iter;
+ struct drm_device *drm = plane->dev;
+ struct drm_rect dst_clip;
+ struct drm_rect damage;
+ int idx;
+
+ if (!drm_dev_enter(drm, &idx))
+ return;
+
+ drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state);
+ drm_atomic_for_each_plane_damage(&iter, &damage) {
+ dst_clip = plane_state->dst;
+
+ if (!drm_rect_intersect(&dst_clip, &damage))
+ continue;
+
+ ssd132x_fb_blit_rect(fb, &shadow_plane_state->data[0], &dst_clip,
+ ssd130x_plane_state->buffer,
+ ssd130x_crtc_state->data_array);
+ }
+
+ drm_dev_exit(idx);
+}
+
static void ssd130x_primary_plane_atomic_disable(struct drm_plane *plane,
struct drm_atomic_state *state)
{
@@ -725,6 +1032,30 @@ static void ssd130x_primary_plane_atomic_disable(struct drm_plane *plane,
drm_dev_exit(idx);
}
+static void ssd132x_primary_plane_atomic_disable(struct drm_plane *plane,
+ struct drm_atomic_state *state)
+{
+ struct drm_device *drm = plane->dev;
+ struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
+ struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
+ struct drm_crtc_state *crtc_state;
+ struct ssd130x_crtc_state *ssd130x_crtc_state;
+ int idx;
+
+ if (!plane_state->crtc)
+ return;
+
+ crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc);
+ ssd130x_crtc_state = to_ssd130x_crtc_state(crtc_state);
+
+ if (!drm_dev_enter(drm, &idx))
+ return;
+
+ ssd132x_clear_screen(ssd130x, ssd130x_crtc_state->data_array);
+
+ drm_dev_exit(idx);
+}
+
/* Called during init to allocate the plane's atomic state. */
static void ssd130x_primary_plane_reset(struct drm_plane *plane)
{
@@ -775,11 +1106,19 @@ static void ssd130x_primary_plane_destroy_state(struct drm_plane *plane,
kfree(ssd130x_state);
}
-static const struct drm_plane_helper_funcs ssd130x_primary_plane_helper_funcs = {
- DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
- .atomic_check = ssd130x_primary_plane_atomic_check,
- .atomic_update = ssd130x_primary_plane_atomic_update,
- .atomic_disable = ssd130x_primary_plane_atomic_disable,
+static const struct drm_plane_helper_funcs ssd130x_primary_plane_helper_funcs[] = {
+ [SSD130X_FAMILY] = {
+ DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
+ .atomic_check = ssd130x_primary_plane_atomic_check,
+ .atomic_update = ssd130x_primary_plane_atomic_update,
+ .atomic_disable = ssd130x_primary_plane_atomic_disable,
+ },
+ [SSD132X_FAMILY] = {
+ DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
+ .atomic_check = ssd132x_primary_plane_atomic_check,
+ .atomic_update = ssd132x_primary_plane_atomic_update,
+ .atomic_disable = ssd132x_primary_plane_atomic_disable,
+ }
};
static const struct drm_plane_funcs ssd130x_primary_plane_funcs = {
@@ -814,8 +1153,7 @@ static int ssd130x_crtc_atomic_check(struct drm_crtc *crtc,
struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
struct ssd130x_crtc_state *ssd130x_state = to_ssd130x_crtc_state(crtc_state);
- unsigned int page_height = ssd130x->device_info->page_height;
- unsigned int pages = DIV_ROUND_UP(ssd130x->height, page_height);
+ unsigned int pages = DIV_ROUND_UP(ssd130x->height, SSD130X_PAGE_HEIGHT);
int ret;
ret = drm_crtc_helper_atomic_check(crtc, state);
@@ -829,6 +1167,27 @@ static int ssd130x_crtc_atomic_check(struct drm_crtc *crtc,
return 0;
}
+static int ssd132x_crtc_atomic_check(struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
+{
+ struct drm_device *drm = crtc->dev;
+ struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
+ struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+ struct ssd130x_crtc_state *ssd130x_state = to_ssd130x_crtc_state(crtc_state);
+ unsigned int columns = DIV_ROUND_UP(ssd130x->width, SSD132X_SEGMENT_WIDTH);
+ int ret;
+
+ ret = drm_crtc_helper_atomic_check(crtc, state);
+ if (ret)
+ return ret;
+
+ ssd130x_state->data_array = kmalloc(columns * ssd130x->height, GFP_KERNEL);
+ if (!ssd130x_state->data_array)
+ return -ENOMEM;
+
+ return 0;
+}
+
/* Called during init to allocate the CRTC's atomic state. */
static void ssd130x_crtc_reset(struct drm_crtc *crtc)
{
@@ -881,9 +1240,15 @@ static void ssd130x_crtc_destroy_state(struct drm_crtc *crtc,
* the primary plane's atomic_update function. Disabling clears
* the screen in the primary plane's atomic_disable function.
*/
-static const struct drm_crtc_helper_funcs ssd130x_crtc_helper_funcs = {
- .mode_valid = ssd130x_crtc_mode_valid,
- .atomic_check = ssd130x_crtc_atomic_check,
+static const struct drm_crtc_helper_funcs ssd130x_crtc_helper_funcs[] = {
+ [SSD130X_FAMILY] = {
+ .mode_valid = ssd130x_crtc_mode_valid,
+ .atomic_check = ssd130x_crtc_atomic_check,
+ },
+ [SSD132X_FAMILY] = {
+ .mode_valid = ssd130x_crtc_mode_valid,
+ .atomic_check = ssd132x_crtc_atomic_check,
+ },
};
static const struct drm_crtc_funcs ssd130x_crtc_funcs = {
@@ -910,7 +1275,7 @@ static void ssd130x_encoder_atomic_enable(struct drm_encoder *encoder,
if (ret)
goto power_off;
- ssd130x_write_cmd(ssd130x, 1, SSD130X_DISPLAY_ON);
+ ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_ON);
backlight_enable(ssd130x->bl_dev);
@@ -921,6 +1286,31 @@ power_off:
return;
}
+static void ssd132x_encoder_atomic_enable(struct drm_encoder *encoder,
+ struct drm_atomic_state *state)
+{
+ struct drm_device *drm = encoder->dev;
+ struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
+ int ret;
+
+ ret = ssd130x_power_on(ssd130x);
+ if (ret)
+ return;
+
+ ret = ssd132x_init(ssd130x);
+ if (ret)
+ goto power_off;
+
+ ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_ON);
+
+ backlight_enable(ssd130x->bl_dev);
+
+ return;
+
+power_off:
+ ssd130x_power_off(ssd130x);
+}
+
static void ssd130x_encoder_atomic_disable(struct drm_encoder *encoder,
struct drm_atomic_state *state)
{
@@ -929,14 +1319,20 @@ static void ssd130x_encoder_atomic_disable(struct drm_encoder *encoder,
backlight_disable(ssd130x->bl_dev);
- ssd130x_write_cmd(ssd130x, 1, SSD130X_DISPLAY_OFF);
+ ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_OFF);
ssd130x_power_off(ssd130x);
}
-static const struct drm_encoder_helper_funcs ssd130x_encoder_helper_funcs = {
- .atomic_enable = ssd130x_encoder_atomic_enable,
- .atomic_disable = ssd130x_encoder_atomic_disable,
+static const struct drm_encoder_helper_funcs ssd130x_encoder_helper_funcs[] = {
+ [SSD130X_FAMILY] = {
+ .atomic_enable = ssd130x_encoder_atomic_enable,
+ .atomic_disable = ssd130x_encoder_atomic_disable,
+ },
+ [SSD132X_FAMILY] = {
+ .atomic_enable = ssd132x_encoder_atomic_enable,
+ .atomic_disable = ssd130x_encoder_atomic_disable,
+ }
};
static const struct drm_encoder_funcs ssd130x_encoder_funcs = {
@@ -1005,7 +1401,7 @@ static int ssd130x_update_bl(struct backlight_device *bdev)
ssd130x->contrast = brightness;
- ret = ssd130x_write_cmd(ssd130x, 1, SSD130X_CONTRAST);
+ ret = ssd130x_write_cmd(ssd130x, 1, SSD13XX_CONTRAST);
if (ret < 0)
return ret;
@@ -1070,6 +1466,7 @@ static void ssd130x_parse_properties(struct ssd130x_device *ssd130x)
static int ssd130x_init_modeset(struct ssd130x_device *ssd130x)
{
+ enum ssd130x_family_ids family_id = ssd130x->device_info->family_id;
struct drm_display_mode *mode = &ssd130x->mode;
struct device *dev = ssd130x->dev;
struct drm_device *drm = &ssd130x->drm;
@@ -1120,7 +1517,7 @@ static int ssd130x_init_modeset(struct ssd130x_device *ssd130x)
return ret;
}
- drm_plane_helper_add(primary_plane, &ssd130x_primary_plane_helper_funcs);
+ drm_plane_helper_add(primary_plane, &ssd130x_primary_plane_helper_funcs[family_id]);
drm_plane_enable_fb_damage_clips(primary_plane);
@@ -1134,7 +1531,7 @@ static int ssd130x_init_modeset(struct ssd130x_device *ssd130x)
return ret;
}
- drm_crtc_helper_add(crtc, &ssd130x_crtc_helper_funcs);
+ drm_crtc_helper_add(crtc, &ssd130x_crtc_helper_funcs[family_id]);
/* Encoder */
@@ -1146,7 +1543,7 @@ static int ssd130x_init_modeset(struct ssd130x_device *ssd130x)
return ret;
}
- drm_encoder_helper_add(encoder, &ssd130x_encoder_helper_funcs);
+ drm_encoder_helper_add(encoder, &ssd130x_encoder_helper_funcs[family_id]);
encoder->possible_crtcs = drm_crtc_mask(crtc);
diff --git a/drivers/gpu/drm/solomon/ssd130x.h b/drivers/gpu/drm/solomon/ssd130x.h
index aa39b13615eb..acf7cedf0c1a 100644
--- a/drivers/gpu/drm/solomon/ssd130x.h
+++ b/drivers/gpu/drm/solomon/ssd130x.h
@@ -21,15 +21,25 @@
#include <linux/regmap.h>
-#define SSD130X_DATA 0x40
-#define SSD130X_COMMAND 0x80
+#define SSD13XX_DATA 0x40
+#define SSD13XX_COMMAND 0x80
+
+enum ssd130x_family_ids {
+ SSD130X_FAMILY,
+ SSD132X_FAMILY
+};
enum ssd130x_variants {
+ /* ssd130x family */
SH1106_ID,
SSD1305_ID,
SSD1306_ID,
SSD1307_ID,
SSD1309_ID,
+ /* ssd132x family */
+ SSD1322_ID,
+ SSD1325_ID,
+ SSD1327_ID,
NR_SSD130X_VARIANTS
};
@@ -39,10 +49,11 @@ struct ssd130x_deviceinfo {
u32 default_dclk_frq;
u32 default_width;
u32 default_height;
- u32 page_height;
bool need_pwm;
bool need_chargepump;
bool page_mode_only;
+
+ enum ssd130x_family_ids family_id;
};
struct ssd130x_device {
diff --git a/drivers/gpu/drm/v3d/v3d_sched.c b/drivers/gpu/drm/v3d/v3d_sched.c
index 06238e6d7f5c..038e1ae589c7 100644
--- a/drivers/gpu/drm/v3d/v3d_sched.c
+++ b/drivers/gpu/drm/v3d/v3d_sched.c
@@ -389,6 +389,7 @@ v3d_sched_init(struct v3d_dev *v3d)
ret = drm_sched_init(&v3d->queue[V3D_BIN].sched,
&v3d_bin_sched_ops,
+ DRM_SCHED_PRIORITY_COUNT,
hw_jobs_limit, job_hang_limit,
msecs_to_jiffies(hang_limit_ms), NULL,
NULL, "v3d_bin", v3d->drm.dev);
@@ -397,6 +398,7 @@ v3d_sched_init(struct v3d_dev *v3d)
ret = drm_sched_init(&v3d->queue[V3D_RENDER].sched,
&v3d_render_sched_ops,
+ DRM_SCHED_PRIORITY_COUNT,
hw_jobs_limit, job_hang_limit,
msecs_to_jiffies(hang_limit_ms), NULL,
NULL, "v3d_render", v3d->drm.dev);
@@ -405,6 +407,7 @@ v3d_sched_init(struct v3d_dev *v3d)
ret = drm_sched_init(&v3d->queue[V3D_TFU].sched,
&v3d_tfu_sched_ops,
+ DRM_SCHED_PRIORITY_COUNT,
hw_jobs_limit, job_hang_limit,
msecs_to_jiffies(hang_limit_ms), NULL,
NULL, "v3d_tfu", v3d->drm.dev);
@@ -414,6 +417,7 @@ v3d_sched_init(struct v3d_dev *v3d)
if (v3d_has_csd(v3d)) {
ret = drm_sched_init(&v3d->queue[V3D_CSD].sched,
&v3d_csd_sched_ops,
+ DRM_SCHED_PRIORITY_COUNT,
hw_jobs_limit, job_hang_limit,
msecs_to_jiffies(hang_limit_ms), NULL,
NULL, "v3d_csd", v3d->drm.dev);
@@ -422,6 +426,7 @@ v3d_sched_init(struct v3d_dev *v3d)
ret = drm_sched_init(&v3d->queue[V3D_CACHE_CLEAN].sched,
&v3d_cache_clean_sched_ops,
+ DRM_SCHED_PRIORITY_COUNT,
hw_jobs_limit, job_hang_limit,
msecs_to_jiffies(hang_limit_ms), NULL,
NULL, "v3d_cache_clean", v3d->drm.dev);
diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
index f3763bd600f6..8ac9515554f8 100644
--- a/drivers/gpu/drm/vc4/vc4_regs.h
+++ b/drivers/gpu/drm/vc4/vc4_regs.h
@@ -588,7 +588,7 @@ enum {
# define VC4_HDMI_HORZA_HAP_MASK VC4_MASK(12, 0)
# define VC4_HDMI_HORZA_HAP_SHIFT 0
-/* Horizontal pack porch (htotal - hsync_end). */
+/* Horizontal back porch (htotal - hsync_end). */
# define VC4_HDMI_HORZB_HBP_MASK VC4_MASK(29, 20)
# define VC4_HDMI_HORZB_HBP_SHIFT 20
/* Horizontal sync pulse (hsync_end - hsync_start). */