Re: [Freedreno] [PATCH v2 0/3] drm/msm/adreno: GPU support on SC8280XP
On Mon, May 22, 2023 at 8:15 PM Bjorn Andersson wrote: > > This series introduces support for A690 in the DRM/MSM driver and > enables it for the two SC8280XP laptops. > > Bjorn Andersson (3): > drm/msm/adreno: Add Adreno A690 support > arm64: dts: qcom: sc8280xp: Add GPU related nodes > arm64: dts: qcom: sc8280xp: Enable GPU related nodes > > arch/arm64/boot/dts/qcom/sc8280xp-crd.dts | 26 +++ > .../qcom/sc8280xp-lenovo-thinkpad-x13s.dts| 26 +++ > arch/arm64/boot/dts/qcom/sc8280xp.dtsi| 169 ++ > drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 113 +++- > drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 33 > drivers/gpu/drm/msm/adreno/adreno_device.c| 14 ++ > drivers/gpu/drm/msm/adreno/adreno_gpu.h | 11 +- > 7 files changed, 387 insertions(+), 5 deletions(-) > > -- > 2.39.2 > Tested here on my X13s with GNOME 44.1 and using Wayland. Tested-by: Steev Klimaszewski
Re: [Freedreno] [PATCH] Revert "drm/msm/dp: Remove INIT_SETUP delay"
Abhinav Kumar writes: There is no need to add the 100ms delay back yet. thanks for posting this but NAK on this patch till we post the fix this week. Appreciate a bit of patience till then. >>> >>> This regression is already part of the 6.3 stable release series. Will >>> the new patch qualify for inclusion in 6.3.y? Or will it be part of 6.4 >>> and this revert should go into 6.3.y? >> >> This is a tough situation, as landing a revert will break x13s, as noted >> by Bjorn. Given that the workaround is known at this moment, I would >> like to wait for the patch from Abhinav to appear, then we can decide >> which of the fixes should go to the stable kernel. I wasn't able to find new patches, though may have missed them. Is there a decision yet how to proceed with this regression? 6.2 now being EOL may make this a good moment to decide on the next steps. >>> [ 275.025497] [drm:dpu_encoder_phys_vid_wait_for_commit_done:488] >>> [dpu error]vblank timeout >>> [ 275.025514] [drm:dpu_kms_wait_for_commit_done:510] [dpu error]wait >>> for commit done returned -110 >>> [ 275.064141] [drm:dpu_encoder_frame_done_timeout:2382] [dpu >>> error]enc33 frame done timeout > > This is a different crash but the root-cause of both the issues is the > bridge hpd_enable/disable series. > > https://patchwork.freedesktop.org/patch/514414/ > > This is breaking the sequence and logic of internal hpd as per my > discussion with kuogee. > > We are analyzing the issue and the fix internally first and once we > figure out all the details will post it. Thank you!
Re: [Freedreno] [PATCH v2 0/7] drm/msm/dpu: simplify DPU encoder init
On 5/18/2023 7:38 PM, Dmitry Baryshkov wrote: Rework dpu_encoder initialization code, simplifying calling sequences and separating common init parts. Changes since v1: - Withdrawn two pathes for a later consideration - Changed dpu_encoder_phys_init() to return void (Abhinav) - Added small simplifications of dpu_encoder_phys_cmd_init() and dpu_encoder_phys_wb_init() I had previously given these comments on the cover letter of v1, so giving it again. Please mention that your series was made on top of https://patchwork.freedesktop.org/series/116530/. Figured it out when I tried to apply it to my branch to test. I had tested v1, and between v1 and v2 i only see very trivial change, so i think its okay to retain: Tested-by: Abhinav Kumar # sc7280 Dmitry Baryshkov (7): drm/msm/dpu: merge dpu_encoder_init() and dpu_encoder_setup() drm/msm/dpu: separate common function to init physical encoder drm/msm/dpu: drop duplicated intf/wb indices from encoder structs drm/msm/dpu: inline dpu_encoder_get_wb() drm/msm/dpu: call dpu_rm_get_intf() from dpu_encoder_get_intf() drm/msm/dpu: drop temp variable from dpu_encoder_phys_cmd_init() drm/msm/dpu: simplify dpu_encoder_phys_wb_init() drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 178 -- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 14 +- .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 15 +- .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 35 ++-- .../drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 19 +- .../drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 35 +--- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 87 - 7 files changed, 140 insertions(+), 243 deletions(-)
Re: [Freedreno] [PATCH v2 7/7] drm/msm/dpu: simplify dpu_encoder_phys_wb_init()
On 5/18/2023 7:38 PM, Dmitry Baryshkov wrote: There is no need to assign a result to temp varable just to return it after a goto. Drop the temporary variable and goto and return the result directly. Signed-off-by: Dmitry Baryshkov --- Reviewed-by: Abhinav Kumar
[Freedreno] [PATCH v2 2/3] arm64: dts: qcom: sc8280xp: Add GPU related nodes
From: Bjorn Andersson Add Adreno SMMU, GPU clock controller, GMU and GPU nodes for the SC8280XP. Signed-off-by: Bjorn Andersson Signed-off-by: Bjorn Andersson --- Changes since v1: - Dropped gmu_pdc_seq region from , as it shouldn't have been used. - Added missing compatible to _smmu. - Dropped aoss_qmp clock in and _smmu. arch/arm64/boot/dts/qcom/sc8280xp.dtsi | 169 + 1 file changed, 169 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi index d2a2224d138a..329ec2119ecf 100644 --- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi +++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -2331,6 +2332,174 @@ tcsr: syscon@1fc { reg = <0x0 0x01fc 0x0 0x3>; }; + gpu: gpu@3d0 { + compatible = "qcom,adreno-690.0", "qcom,adreno"; + + reg = <0 0x03d0 0 0x4>, + <0 0x03d9e000 0 0x1000>, + <0 0x03d61000 0 0x800>; + reg-names = "kgsl_3d0_reg_memory", + "cx_mem", + "cx_dbgc"; + interrupts = ; + iommus = <_smmu 0 0xc00>, <_smmu 1 0xc00>; + operating-points-v2 = <_opp_table>; + + qcom,gmu = <>; + interconnects = <_noc MASTER_GFX3D 0 _virt SLAVE_EBI1 0>; + interconnect-names = "gfx-mem"; + #cooling-cells = <2>; + + status = "disabled"; + + gpu_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-27000 { + opp-hz = /bits/ 64 <27000>; + opp-level = ; + opp-peak-kBps = <451000>; + }; + + opp-41000 { + opp-hz = /bits/ 64 <41000>; + opp-level = ; + opp-peak-kBps = <1555000>; + }; + + opp-5 { + opp-hz = /bits/ 64 <5>; + opp-level = ; + opp-peak-kBps = <1555000>; + }; + + opp-54700 { + opp-hz = /bits/ 64 <54700>; + opp-level = ; + opp-peak-kBps = <1555000>; + }; + + opp-60600 { + opp-hz = /bits/ 64 <60600>; + opp-level = ; + opp-peak-kBps = <2736000>; + }; + + opp-64000 { + opp-hz = /bits/ 64 <64000>; + opp-level = ; + opp-peak-kBps = <2736000>; + }; + + opp-69000 { + opp-hz = /bits/ 64 <69000>; + opp-level = ; + opp-peak-kBps = <2736000>; + }; + }; + }; + + gmu: gmu@3d6a000 { + compatible = "qcom,adreno-gmu-690.0", "qcom,adreno-gmu"; + reg = <0 0x03d6a000 0 0x34000>, + <0 0x03de 0 0x1>, + <0 0x0b29 0 0x1>; + reg-names = "gmu", "rscc", "gmu_pdc"; + interrupts = , +; + interrupt-names = "hfi", "gmu"; + clocks = < GPU_CC_CX_GMU_CLK>, +< GPU_CC_CXO_CLK>, +< GCC_DDRSS_GPU_AXI_CLK>, +< GCC_GPU_MEMNOC_GFX_CLK>, +< GPU_CC_AHB_CLK>, +< GPU_CC_HUB_CX_INT_CLK>, +< GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>; + clock-names = "gmu", + "cxo", + "axi", + "memnoc", + "ahb", +
[Freedreno] [PATCH v2 1/3] drm/msm/adreno: Add Adreno A690 support
From: Bjorn Andersson Introduce support for the Adreno A690, found in Qualcomm SC8280XP. Signed-off-by: Bjorn Andersson Signed-off-by: Bjorn Andersson --- Changes since v1: - Moved a690 to adreno_is_a660_family(), which simplifies hw_init() and ensured that pdc_in_aop got set. - Dropped dynamic lookup in cmd-db. Will look into posting this separately. drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 113 - drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 33 ++ drivers/gpu/drm/msm/adreno/adreno_device.c | 14 +++ drivers/gpu/drm/msm/adreno/adreno_gpu.h| 11 +- 4 files changed, 166 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 9fb214f150dd..cabc8f9a12d7 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -588,6 +588,63 @@ const struct adreno_reglist a660_hwcg[] = { {}, }; +const struct adreno_reglist a690_hwcg[] = { + {REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x0222}, + {REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x0220}, + {REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x0080}, + {REG_A6XX_RBBM_CLOCK_HYST_SP0, 0xF3CF}, + {REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x}, + {REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x}, + {REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x}, + {REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x0002}, + {REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x}, + {REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x}, + {REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x}, + {REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x0001}, + {REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x}, + {REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x}, + {REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x}, + {REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x0007}, + {REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x}, + {REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x0100}, + {REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x2220}, + {REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040F00}, + {REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x25222022}, + {REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x}, + {REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x0011}, + {REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044}, + {REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x0422}, + {REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x}, + {REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x0022}, + {REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x0002}, + {REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x}, + {REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x4000}, + {REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x}, + {REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x0200}, + {REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x}, + {REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x}, + {REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x}, + {REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004}, + {REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x}, + {REG_A6XX_RBBM_CLOCK_CNTL_TEX_FCHE, 0x0222}, + {REG_A6XX_RBBM_CLOCK_DELAY_TEX_FCHE, 0x0111}, + {REG_A6XX_RBBM_CLOCK_HYST_TEX_FCHE, 0x}, + {REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x}, + {REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x0004}, + {REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x0002}, + {REG_A6XX_RBBM_CLOCK_CNTL, 0x8AA8AA82}, + {REG_A6XX_RBBM_ISDB_CNT, 0x0182}, + {REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x}, + {REG_A6XX_RBBM_SP_HYST_CNT, 0x}, + {REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x0222}, + {REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x0111}, + {REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x0555}, + {REG_A6XX_GPU_GMU_AO_GMU_CGC_MODE_CNTL, 0x20200}, + {REG_A6XX_GPU_GMU_AO_GMU_CGC_DELAY_CNTL, 0x10111}, + {REG_A6XX_GPU_GMU_AO_GMU_CGC_HYST_CNTL, 0x}, + {} +}; + static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); @@ -747,6 +804,45 @@ static const u32 a660_protect[] = { A6XX_PROTECT_NORDWR(0x1f8c0, 0x), /* note: infinite range */ }; +/* These are for a690 */ +static const u32 a690_protect[] = { + A6XX_PROTECT_RDONLY(0x0, 0x004ff), + A6XX_PROTECT_RDONLY(0x00501, 0x1), + A6XX_PROTECT_RDONLY(0x0050b, 0x002f4), + A6XX_PROTECT_NORDWR(0x0050e, 0x0), + A6XX_PROTECT_NORDWR(0x00510, 0x0), + A6XX_PROTECT_NORDWR(0x00534, 0x0), + A6XX_PROTECT_NORDWR(0x00800, 0x00082), + A6XX_PROTECT_NORDWR(0x008a0, 0x8), + A6XX_PROTECT_NORDWR(0x008ab, 0x00024), + A6XX_PROTECT_RDONLY(0x008d0, 0x000bc), + A6XX_PROTECT_NORDWR(0x00900, 0x0004d), + A6XX_PROTECT_NORDWR(0x0098d, 0x00272), + A6XX_PROTECT_NORDWR(0x00e00, 0x1), + A6XX_PROTECT_NORDWR(0x00e03, 0xc), + A6XX_PROTECT_NORDWR(0x03c00, 0x000c3), + A6XX_PROTECT_RDONLY(0x03cc4, 0x01fff), + A6XX_PROTECT_NORDWR(0x08630, 0x001cf), +
[Freedreno] [PATCH v2 3/3] arm64: dts: qcom: sc8280xp: Enable GPU related nodes
From: Bjorn Andersson Add memory reservation for the zap-shader and enable the Adreno SMMU, GPU clock controller, GMU and the GPU nodes for the SC8280XP CRD and the Lenovo ThinkPad X13s. Signed-off-by: Bjorn Andersson Signed-off-by: Bjorn Andersson --- Changes since v1: - None arch/arm64/boot/dts/qcom/sc8280xp-crd.dts | 26 +++ .../qcom/sc8280xp-lenovo-thinkpad-x13s.dts| 26 +++ 2 files changed, 52 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts b/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts index 5b25d54b9591..547277924ea3 100644 --- a/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts +++ b/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts @@ -210,6 +210,11 @@ vreg_wwan: regulator-wwan { }; reserved-memory { + gpu_mem: gpu-mem@8bf0 { + reg = <0 0x8bf0 0 0x2000>; + no-map; + }; + linux,cma { compatible = "shared-dma-pool"; size = <0x0 0x800>; @@ -259,6 +264,10 @@ usb1_sbu_mux: endpoint { }; }; +_smmu { + status = "okay"; +}; + _rsc { regulators-0 { compatible = "qcom,pm8350-rpmh-regulators"; @@ -376,6 +385,23 @@ { status = "okay"; }; + { + status = "okay"; +}; + + { + status = "okay"; + + zap-shader { + memory-region = <_mem>; + firmware-name = "qcom/sc8280xp/qcdxkmsuc8280.mbn"; + }; +}; + + { + status = "okay"; +}; + { status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts index bdcba719fc38..5ef3f4c07d75 100644 --- a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts +++ b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts @@ -264,6 +264,11 @@ vreg_wwan: regulator-wwan { }; reserved-memory { + gpu_mem: gpu-mem@8bf0 { + reg = <0 0x8bf0 0 0x2000>; + no-map; + }; + linux,cma { compatible = "shared-dma-pool"; size = <0x0 0x800>; @@ -359,6 +364,10 @@ usb1_sbu_mux: endpoint { }; }; +_smmu { + status = "okay"; +}; + _rsc { regulators-0 { compatible = "qcom,pm8350-rpmh-regulators"; @@ -518,6 +527,23 @@ { status = "okay"; }; + { + status = "okay"; +}; + + { + status = "okay"; + + zap-shader { + memory-region = <_mem>; + firmware-name = "qcom/sc8280xp/LENOVO/21BX/qcdxkmsuc8280.mbn"; + }; +}; + + { + status = "okay"; +}; + { status = "okay"; }; -- 2.39.2
[Freedreno] [PATCH v2 0/3] drm/msm/adreno: GPU support on SC8280XP
This series introduces support for A690 in the DRM/MSM driver and enables it for the two SC8280XP laptops. Bjorn Andersson (3): drm/msm/adreno: Add Adreno A690 support arm64: dts: qcom: sc8280xp: Add GPU related nodes arm64: dts: qcom: sc8280xp: Enable GPU related nodes arch/arm64/boot/dts/qcom/sc8280xp-crd.dts | 26 +++ .../qcom/sc8280xp-lenovo-thinkpad-x13s.dts| 26 +++ arch/arm64/boot/dts/qcom/sc8280xp.dtsi| 169 ++ drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 113 +++- drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 33 drivers/gpu/drm/msm/adreno/adreno_device.c| 14 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.h | 11 +- 7 files changed, 387 insertions(+), 5 deletions(-) -- 2.39.2
[Freedreno] [PATCH v5 1/5] msm/drm/dsi: Round up DSC hdisplay calculation
Currently, when compression is enabled, hdisplay is reduced via integer division. This causes issues for modes where the original hdisplay is not a multiple of 3. To fix this, use DIV_ROUND_UP to divide hdisplay. Suggested-by: Marijn Suijten Fixes: 08802f515c3cf ("drm/msm/dsi: Add support for DSC configuration") Reviewed-by: Marijn Suijten Signed-off-by: Jessica Zhang --- drivers/gpu/drm/msm/dsi/dsi_host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 1a99d75025dc..a448931af804 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -949,7 +949,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) * pulse width same */ h_total -= hdisplay; - hdisplay = msm_dsc_get_bytes_per_line(msm_host->dsc) / 3; + hdisplay = DIV_ROUND_UP(msm_dsc_get_bytes_per_line(msm_host->dsc), 3); h_total += hdisplay; ha_end = ha_start + hdisplay; } -- 2.40.1
[Freedreno] [PATCH v5 0/5] Add DSC v1.2 Support for DSI
This is a series of changes for DSI to enable command mode support for DSC v1.2. This includes: 1) Rounding up `hdisplay / 3` in dsc_timing_setup() 2) Adjusting pclk_rate to account for compression 3) Fixing incorrect uses of slice_count in DSI DSC calculations 4) Setting the DATA_COMPRESS bit when DSC is enabled With these changes (and the dependency below), DSC v1.2 should work over DSI in command mode. Note: Changes that add DSC v1.2 support for video mode will be posted with the DP support changes. Depends-on: - "add DSC 1.2 dpu supports" [1] - "Introduce MSM-specific DSC helpers" [2] - "drm/msm/dsi: use mult_frac for pclk_bpp calculation" [3] [1] https://patchwork.freedesktop.org/series/116789/ [2] https://patchwork.freedesktop.org/series/115833/ [3] https://patchwork.freedesktop.org/patch/538273/?series=118072=1 Signed-off-by: Jessica Zhang --- Changes in v5: - Added newline before enable_compression() function pointer definition - Rebased on top of "drm/msm/dsi: use mult_frac for pclk_bpp calculation" - Reworded commit messages for clarity - Dropped mentions of "soft slice" in commit messages - "slice_per_packet" -> "slice_per_pkt" - Picked up reviewed-by tags - Link to v4: https://lore.kernel.org/r/20230405-add-dsc-support-v4-0-15daf84f8...@quicinc.com Changes in v4: - Clarified slice_per_pkt comment regarding pkt_per_line calculations - Reworded commit message for "drm/msm/dsi: Remove incorrect references to slice_count" - Wrapped INTF_SC7280_MASK macro definition in parentheses - Fixed incorrect commit hash in "msm/drm/dsi: Round up DSC hdisplay calculation" - Picked up Reviewed-by tag - Link to v3: https://lore.kernel.org/r/20230405-add-dsc-support-v3-0-6e1d35a20...@quicinc.com Changes in v3: - Added fix to round up hdisplay DSC adjustment - Fixed inconsistent whitespace in dpu_hw_intf_ops comment doc - Moved placement of dpu_hw_intf_enable_compression - Picked up "drm/msm/dsi: Fix calculation for pkt_per_line" patch and squashed all slice_count fixes into a single patch - Use drm_mode_vrefresh() to calculate adjusted pclk rate - Moved compressed pclk adjustment to dsi_adjust_compressed_pclk() helper - Rebased changes on top of updated dependencies - Reworded commit message for "drm/msm/dpu: Set DATA_COMPRESS for command mode" for clarity - Removed revision changelog in commit messages - Link to v2: https://lore.kernel.org/r/20230405-add-dsc-support-v2-0-1072c70e9...@quicinc.com Changes in v2: - Changed has_data_compress dpu_cap to a DATA_COMPRESS INTF feature flag - Changed pclk math to only divide hdisplay by compression ratio - Reworded word count TODO comment - Make DATA_COMPRESS an INTF flag - Read INTF_CONFIG2 before writing to DATA_COMPRESS bit - Fixed whitespace issue in macro definition - Removed `inline` from dpu_hw_intf_enable_compression declaration - Only set dpu_hw_intf_ops.data_compress if DATA_COMPRESS feature is set - Reworded commit messages and cover letter for clarity - Link to v1: https://lore.kernel.org/r/20230405-add-dsc-support-v1-0-6bc6f03ae...@quicinc.com --- Jessica Zhang (5): msm/drm/dsi: Round up DSC hdisplay calculation drm/msm/dsi: Adjust pclk rate for compression drm/msm/dpu: Add DPU_INTF_DATA_COMPRESS feature flag for DPU >= 7.0 drm/msm/dpu: Set DATA_COMPRESS on command mode for DCE/DSC 1.2 drm/msm/dsi: Remove incorrect references to slice_count .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 3 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 3 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c| 13 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h| 3 ++ drivers/gpu/drm/msm/dsi/dsi_host.c | 49 +++--- 6 files changed, 58 insertions(+), 15 deletions(-) --- base-commit: 12a0bf73039bd760c5e78d08109882aa628cce8c change-id: 20230405-add-dsc-support-fe130ba49841 Best regards, -- Jessica Zhang
[Freedreno] [PATCH v5 3/5] drm/msm/dpu: Add DPU_INTF_DATA_COMPRESS feature flag for DPU >= 7.0
In DPU 7.x and later, DSC/DCE enablement registers have been moved from PINGPONG to INTF. Thus, add a DPU_INTF_DATA_COMPRESS feature flag that will be set if the DATA_COMPRESS register is in the INTF block. Reviewed-by: Marijn Suijten Signed-off-by: Jessica Zhang --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 3 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 243399d09ffe..09c8c1672910 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -104,7 +104,8 @@ #define INTF_SC7180_MASK \ (BIT(DPU_INTF_INPUT_CTRL) | BIT(DPU_INTF_TE) | BIT(DPU_INTF_STATUS_SUPPORTED)) -#define INTF_SC7280_MASK INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN) +#define INTF_SC7280_MASK \ + (INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN) | BIT(DPU_INTF_DATA_COMPRESS)) #define WB_SM8250_MASK (BIT(DPU_WB_LINE_MODE) | \ BIT(DPU_WB_UBWC) | \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 11610f7d3150..334e4ab7281a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -185,6 +185,7 @@ enum { * @DPU_DATA_HCTL_ENAllows data to be transferred at different rate * than video timing * @DPU_INTF_STATUS_SUPPORTED INTF block has INTF_STATUS register + * @DPU_INTF_DATA_COMPRESS INTF block has DATA_COMPRESS register * @DPU_INTF_MAX */ enum { @@ -192,6 +193,7 @@ enum { DPU_INTF_TE, DPU_DATA_HCTL_EN, DPU_INTF_STATUS_SUPPORTED, + DPU_INTF_DATA_COMPRESS, DPU_INTF_MAX }; -- 2.40.1
[Freedreno] [PATCH v5 2/5] drm/msm/dsi: Adjust pclk rate for compression
Adjust the pclk rate to divide hdisplay by the compression ratio when DSC is enabled. Signed-off-by: Jessica Zhang --- drivers/gpu/drm/msm/dsi/dsi_host.c | 21 ++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index a448931af804..88f370dd2ea1 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -561,7 +561,18 @@ void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host) clk_disable_unprepare(msm_host->byte_clk); } -static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode, bool is_bonded_dsi) +static unsigned long dsi_adjust_compressed_pclk(const struct drm_display_mode *mode, + const struct drm_dsc_config *dsc) +{ + int new_hdisplay = DIV_ROUND_UP(mode->hdisplay * drm_dsc_get_bpp_int(dsc), + dsc->bits_per_component * 3); + + return (new_hdisplay + (mode->htotal - mode->hdisplay)) + * mode->vtotal * drm_mode_vrefresh(mode); +} + +static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode, + const struct drm_dsc_config *dsc, bool is_bonded_dsi) { unsigned long pclk_rate; @@ -576,6 +587,10 @@ static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode, bool if (is_bonded_dsi) pclk_rate /= 2; + /* If DSC is enabled, divide hdisplay by compression ratio */ + if (dsc) + pclk_rate = dsi_adjust_compressed_pclk(mode, dsc); + return pclk_rate; } @@ -585,7 +600,7 @@ unsigned long dsi_byte_clk_get_rate(struct mipi_dsi_host *host, bool is_bonded_d struct msm_dsi_host *msm_host = to_msm_dsi_host(host); u8 lanes = msm_host->lanes; u32 bpp = dsi_get_bpp(msm_host->format); - unsigned long pclk_rate = dsi_get_pclk_rate(mode, is_bonded_dsi); + unsigned long pclk_rate = dsi_get_pclk_rate(mode, msm_host->dsc, is_bonded_dsi); unsigned long pclk_bpp; if (lanes == 0) { @@ -604,7 +619,7 @@ unsigned long dsi_byte_clk_get_rate(struct mipi_dsi_host *host, bool is_bonded_d static void dsi_calc_pclk(struct msm_dsi_host *msm_host, bool is_bonded_dsi) { - msm_host->pixel_clk_rate = dsi_get_pclk_rate(msm_host->mode, is_bonded_dsi); + msm_host->pixel_clk_rate = dsi_get_pclk_rate(msm_host->mode, msm_host->dsc, is_bonded_dsi); msm_host->byte_clk_rate = dsi_byte_clk_get_rate(_host->base, is_bonded_dsi, msm_host->mode); -- 2.40.1
[Freedreno] [PATCH v5 5/5] drm/msm/dsi: Remove incorrect references to slice_count
Currently, slice_count is being used to calculate word count and pkt_per_line. Instead, these values should be calculated using slice per packet, which is not the same as slice_count. Slice count represents the number of slices per interface, and its value will not always match that of slice per packet. For example, it is possible to have cases where there are multiple slices per interface but the panel specifies only one slice per packet. Thus, use the default value of one slice per packet and remove slice_count from the aforementioned calculations. Fixes: 08802f515c3c ("drm/msm/dsi: Add support for DSC configuration") Fixes: bc6b6ff8135c ("drm/msm/dsi: Use DSC slice(s) packet size to compute word count") Reviewed-by: Marijn Suijten Signed-off-by: Jessica Zhang --- drivers/gpu/drm/msm/dsi/dsi_host.c | 26 -- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 88f370dd2ea1..919760740bba 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -863,18 +863,17 @@ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mod */ slice_per_intf = msm_dsc_get_slices_per_intf(dsc, hdisplay); - /* -* If slice_count is greater than slice_per_intf -* then default to 1. This can happen during partial -* update. -*/ - if (dsc->slice_count > slice_per_intf) - dsc->slice_count = 1; - total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf; eol_byte_num = total_bytes_per_intf % 3; - pkt_per_line = slice_per_intf / dsc->slice_count; + + /* +* Typically, pkt_per_line = slice_per_intf * slice_per_pkt. +* +* Since the current driver only supports slice_per_pkt = 1, +* pkt_per_line will be equal to slice per intf for now. +*/ + pkt_per_line = slice_per_intf; if (is_cmd_mode) /* packet data type */ reg = DSI_COMMAND_COMPRESSION_MODE_CTRL_STREAM0_DATATYPE(MIPI_DSI_DCS_LONG_WRITE); @@ -998,7 +997,14 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) if (!msm_host->dsc) wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1; else - wc = msm_host->dsc->slice_chunk_size * msm_host->dsc->slice_count + 1; + /* +* When DSC is enabled, WC = slice_chunk_size * slice_per_pkt + 1. +* Currently, the driver only supports default value of slice_per_pkt = 1 +* +* TODO: Expand mipi_dsi_device struct to hold slice_per_pkt info +* and adjust DSC math to account for slice_per_pkt. +*/ + wc = msm_host->dsc->slice_chunk_size + 1; dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM0_CTRL, DSI_CMD_MDP_STREAM0_CTRL_WORD_COUNT(wc) | -- 2.40.1
[Freedreno] [PATCH v5 4/5] drm/msm/dpu: Set DATA_COMPRESS on command mode for DCE/DSC 1.2
Add a DPU INTF op to set the DCE_DATA_COMPRESS bit to enable the DCE/DSC 1.2 datapath Note: For now, this op is called for command mode encoders only. Changes to set DATA_COMPRESS for video mode encoders will be posted along with DSC v1.2 support for DP. Reviewed-by: Marijn Suijten Signed-off-by: Jessica Zhang --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 3 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 13 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h | 3 +++ 3 files changed, 19 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index d8ed85a238af..1a4c20f02312 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -68,6 +68,9 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg( phys_enc->hw_intf, true, phys_enc->hw_pp->idx); + + if (phys_enc->hw_intf->ops.enable_compression) + phys_enc->hw_intf->ops.enable_compression(phys_enc->hw_intf); } static void dpu_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c index 6485500eedb8..a462c6780e6e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -91,6 +91,7 @@ #define INTF_CFG2_DATABUS_WIDENBIT(0) #define INTF_CFG2_DATA_HCTL_EN BIT(4) +#define INTF_CFG2_DCE_DATA_COMPRESS BIT(12) static void dpu_hw_intf_setup_timing_engine(struct dpu_hw_intf *ctx, const struct intf_timing_params *p, @@ -522,6 +523,15 @@ static void dpu_hw_intf_disable_autorefresh(struct dpu_hw_intf *intf, } +static void dpu_hw_intf_enable_compression(struct dpu_hw_intf *ctx) +{ + u32 intf_cfg2 = DPU_REG_READ(>hw, INTF_CONFIG2); + + intf_cfg2 |= INTF_CFG2_DCE_DATA_COMPRESS; + + DPU_REG_WRITE(>hw, INTF_CONFIG2, intf_cfg2); +} + static void _setup_intf_ops(struct dpu_hw_intf_ops *ops, unsigned long cap) { @@ -542,6 +552,9 @@ static void _setup_intf_ops(struct dpu_hw_intf_ops *ops, ops->vsync_sel = dpu_hw_intf_vsync_sel; ops->disable_autorefresh = dpu_hw_intf_disable_autorefresh; } + + if (cap & BIT(DPU_INTF_DATA_COMPRESS)) + ops->enable_compression = dpu_hw_intf_enable_compression; } struct dpu_hw_intf *dpu_hw_intf_init(const struct dpu_intf_cfg *cfg, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h index 73b0885918f8..5e8e103e29ce 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h @@ -70,6 +70,7 @@ struct intf_status { * @get_autorefresh:Retrieve autorefresh config from hardware * Return: 0 on success, -ETIMEDOUT on timeout * @vsync_sel: Select vsync signal for tear-effect configuration + * @enable_compression: Enable data compression */ struct dpu_hw_intf_ops { void (*setup_timing_gen)(struct dpu_hw_intf *intf, @@ -107,6 +108,8 @@ struct dpu_hw_intf_ops { * Disable autorefresh if enabled */ void (*disable_autorefresh)(struct dpu_hw_intf *intf, uint32_t encoder_id, u16 vdisplay); + + void (*enable_compression)(struct dpu_hw_intf *intf); }; struct dpu_hw_intf { -- 2.40.1
Re: [Freedreno] [PATCH v4 0/9] drm: fdinfo memory stats
On Sun, 21 May 2023 at 10:03, Dmitry Baryshkov wrote: > > On 15/05/2023 17:30, Rob Clark wrote: > > From: Rob Clark > > > > Similar motivation to other similar recent attempt[1]. But with an > > attempt to have some shared code for this. As well as documentation. > > > > It is probably a bit UMA-centric, I guess devices with VRAM might want > > some placement stats as well. But this seems like a reasonable start. > > > > Basic gputop support: https://patchwork.freedesktop.org/series/116236/ > > And already nvtop support: https://github.com/Syllo/nvtop/pull/204 > > > > I've combined the separate series to add comm/cmdline override onto > > the end of this, simply out of convenience (they would otherwise > > conflict in a bunch of places). > > > > v2: Extend things to allow for multiple regions other than just system > > "memory", make drm_show_memory_stats() a helper so that, drivers > > can use it or not based on their needs (but in either case, re- > > use drm_print_memory_stats() > > v3: Docs fixes > > v4: use u64 for drm_memory_stats, small docs update and collected > > Tvrtko's a-b > > > > [1] https://patchwork.freedesktop.org/series/112397/ > > > > Rob Clark (9): > >drm/docs: Fix usage stats typos > >drm: Add common fdinfo helper > >drm/msm: Switch to fdinfo helper > >drm/amdgpu: Switch to fdinfo helper > >drm: Add fdinfo memory stats > >drm/msm: Add memory stats to fdinfo > >drm/doc: Relax fdinfo string constraints > >drm/fdinfo: Add comm/cmdline override fields > >drm/msm: Wire up comm/cmdline override for fdinfo > > > > Documentation/gpu/drm-usage-stats.rst | 101 ++ > > drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c| 3 +- > > drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c | 16 +-- > > drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.h | 2 +- > > drivers/gpu/drm/drm_file.c | 147 + > > drivers/gpu/drm/msm/adreno/adreno_gpu.c| 24 +++- > > drivers/gpu/drm/msm/msm_drv.c | 15 ++- > > drivers/gpu/drm/msm/msm_gem.c | 15 +++ > > drivers/gpu/drm/msm/msm_gpu.c | 2 - > > drivers/gpu/drm/msm/msm_gpu.h | 10 ++ > > include/drm/drm_drv.h | 7 + > > include/drm/drm_file.h | 51 +++ > > include/drm/drm_gem.h | 32 + > > 13 files changed, 378 insertions(+), 47 deletions(-) > > What is the expected merge plan for this series? msm-next? drm-misc? I'm fine with this going via drm-misc, Acked-by: Dave Airlie if that is the plan. Dave.
[Freedreno] [PATCH v13 08/10] drm/msm/dpu: separate DSC flush update out of interface
Currently DSC flushing happens during interface configuration at dpu_hw_ctl_intf_cfg_v1(). Separate DSC flush away from dpu_hw_ctl_intf_cfg_v1() by adding dpu_hw_ctl_update_pending_flush_dsc_v1() to handle both per-DSC engine and DSC flush bits at same time to make it consistent with the location of flush programming of other DPU sub-blocks. Changes in v10: -- rewording commit text -- pass ctl directly instead of dpu_enc to dsc_pipe_cfg() -- ctx->pending_dsc_flush_mask = 0; Changes in v11: -- add Fixes tag -- capitalize MERGE_3D, DSPP and DSC at struct dpu_hw_ctl_ops{} Changes in v12: -- move dsc parameter to next line at dpu_encoder_dsc_pipe_cfg() Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 10 -- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 23 +-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 11 +++ 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index ffa6f04..7fca09e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1834,7 +1834,8 @@ dpu_encoder_dsc_initial_line_calc(struct drm_dsc_config *dsc, return DIV_ROUND_UP(total_pixels, dsc->slice_width); } -static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc, +static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_ctl *ctl, +struct dpu_hw_dsc *hw_dsc, struct dpu_hw_pingpong *hw_pp, struct drm_dsc_config *dsc, u32 common_mode, @@ -1854,6 +1855,9 @@ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc, if (hw_pp->ops.enable_dsc) hw_pp->ops.enable_dsc(hw_pp); + + if (ctl->ops.update_pending_flush_dsc) + ctl->ops.update_pending_flush_dsc(ctl, hw_dsc->idx); } static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc, @@ -1861,6 +1865,7 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc, { /* coding only for 2LM, 2enc, 1 dsc config */ struct dpu_encoder_phys *enc_master = dpu_enc->cur_master; + struct dpu_hw_ctl *ctl = enc_master->hw_ctl; struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC]; struct dpu_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC]; int this_frame_slices; @@ -1898,7 +1903,8 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc, initial_lines = dpu_encoder_dsc_initial_line_calc(dsc, enc_ip_w); for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) - dpu_encoder_dsc_pipe_cfg(hw_dsc[i], hw_pp[i], dsc, dsc_common_mode, initial_lines); + dpu_encoder_dsc_pipe_cfg(ctl, hw_dsc[i], hw_pp[i], +dsc, dsc_common_mode, initial_lines); } void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 64c21e0..ad6983e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -103,6 +103,7 @@ static inline void dpu_hw_ctl_clear_pending_flush(struct dpu_hw_ctl *ctx) ctx->pending_intf_flush_mask = 0; ctx->pending_wb_flush_mask = 0; ctx->pending_merge_3d_flush_mask = 0; + ctx->pending_dsc_flush_mask = 0; memset(ctx->pending_dspp_flush_mask, 0, sizeof(ctx->pending_dspp_flush_mask)); @@ -142,6 +143,11 @@ static inline void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx) CTL_DSPP_n_FLUSH(dspp - DSPP_0), ctx->pending_dspp_flush_mask[dspp - DSPP_0]); } + + if (ctx->pending_flush_mask & BIT(DSC_IDX)) + DPU_REG_WRITE(>hw, CTL_DSC_FLUSH, + ctx->pending_dsc_flush_mask); + DPU_REG_WRITE(>hw, CTL_FLUSH, ctx->pending_flush_mask); } @@ -288,6 +294,13 @@ static void dpu_hw_ctl_update_pending_flush_merge_3d_v1(struct dpu_hw_ctl *ctx, ctx->pending_flush_mask |= BIT(MERGE_3D_IDX); } +static void dpu_hw_ctl_update_pending_flush_dsc_v1(struct dpu_hw_ctl *ctx, + enum dpu_dsc dsc_num) +{ + ctx->pending_dsc_flush_mask |= BIT(dsc_num - DSC_0); + ctx->pending_flush_mask |= BIT(DSC_IDX); +} + static void dpu_hw_ctl_update_pending_flush_dspp(struct dpu_hw_ctl *ctx, enum dpu_dspp dspp, u32 dspp_sub_blk) { @@ -505,9 +518,6 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, if ((test_bit(DPU_CTL_VM_CFG, >caps->features))) mode_sel = CTL_DEFAULT_GROUP_ID << 28; - if (cfg->dsc) - DPU_REG_WRITE(>hw, CTL_DSC_FLUSH, cfg->dsc); - if (cfg->intf_mode_sel
[Freedreno] [PATCH v13 06/10] drm/msm/dpu: add support for DSC encoder v1.2 engine
Add support for DSC 1.2 by providing the necessary hooks to program the DPU DSC 1.2 encoder. Changes in v3: -- fixed kernel test rebot report that "__iomem *off" is declared but not used at dpu_hw_dsc_config_1_2() -- unrolling thresh loops Changes in v4: -- delete DPU_DSC_HW_REV_1_1 -- delete off and used real register name directly Changes in v7: -- replace offset with sblk->enc.base -- replace ss with slice Changes in v8: -- fixed checkpatch warning Changes in v9: -- replaced __dsc_calc_ob_max_addr() with __dsc_calc_output_buf_max_addr() -- replaced variable num_ss with num_softslice -- remove inline from function declaration changes in v10: -- rewording text of changes in v9 -- replace DPU_DSC_NATIVE_422_EN with DPU_DSC_NATIVE_42x_EN -- replace drm_dsc_calculate_flatness_det_thresh() with drm_dsc_flatness_det_thresh() Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 31 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 14 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 387 + drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 7 +- 5 files changed, 436 insertions(+), 4 deletions(-) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 7274c412..4c7195af2 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -65,6 +65,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \ disp/dpu1/dpu_hw_catalog.o \ disp/dpu1/dpu_hw_ctl.o \ disp/dpu1/dpu_hw_dsc.o \ + disp/dpu1/dpu_hw_dsc_1_2.o \ disp/dpu1/dpu_hw_interrupts.o \ disp/dpu1/dpu_hw_intf.o \ disp/dpu1/dpu_hw_lm.o \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 83854e8..11610f7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. */ @@ -244,12 +244,18 @@ enum { }; /** - * DSC features + * DSC sub-blocks/features * @DPU_DSC_OUTPUT_CTRL Configure which PINGPONG block gets *the pixel output from this DSC. + * @DPU_DSC_HW_REV_1_2DSC block supports DSC 1.1 and 1.2 + * @DPU_DSC_NATIVE_42x_EN Supports NATIVE_422_EN and NATIVE_420_EN encoding + * @DPU_DSC_MAX */ enum { DPU_DSC_OUTPUT_CTRL = 0x1, + DPU_DSC_HW_REV_1_2, + DPU_DSC_NATIVE_42x_EN, + DPU_DSC_MAX }; /** @@ -306,6 +312,14 @@ struct dpu_pp_blk { }; /** + * struct dpu_dsc_blk - DSC Encoder sub-blk information + * @info: HW register and features supported by this sub-blk + */ +struct dpu_dsc_blk { + DPU_HW_SUBBLK_INFO; +}; + +/** * enum dpu_qos_lut_usage - define QoS LUT use cases */ enum dpu_qos_lut_usage { @@ -452,6 +466,16 @@ struct dpu_pingpong_sub_blks { }; /** + * struct dpu_dsc_sub_blks - DSC sub-blks + * @enc: DSC encoder sub-block + * @ctl: DSC controller sub-block + */ +struct dpu_dsc_sub_blks { + struct dpu_dsc_blk enc; + struct dpu_dsc_blk ctl; +}; + +/** * dpu_clk_ctrl_type - Defines top level clock control signals */ enum dpu_clk_ctrl_type { @@ -605,10 +629,13 @@ struct dpu_merge_3d_cfg { * struct dpu_dsc_cfg - information of DSC blocks * @id enum identifying this block * @base register offset of this block + * @len: length of hardware block * @features bit mask identifying sub-blocks/features + * @sblk: sub-blocks information */ struct dpu_dsc_cfg { DPU_HW_BLK_INFO; + const struct dpu_dsc_sub_blks *sblk; }; /** diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h index 138080a..d5b597a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h @@ -1,5 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2020-2022, Linaro Limited */ +/* + * Copyright (c) 2020-2022, Linaro Limited + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved + */ #ifndef _DPU_HW_DSC_H #define _DPU_HW_DSC_H @@ -69,6 +72,15 @@ struct dpu_hw_dsc *dpu_hw_dsc_init(const struct dpu_dsc_cfg *cfg, void __iomem *addr); /** + * dpu_hw_dsc_init_1_2() - initializes the v1.2 DSC hw driver object + * @cfg: DSC catalog entry for which driver object is required + * @addr: Mapped register io address of MDP + * Returns: Error code or allocated dpu_hw_dsc context + */ +struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(const struct
[Freedreno] [PATCH v13 10/10] drm/msm/dpu: tear down DSC data path when DSC disabled
Unset DSC_ACTIVE bit at dpu_hw_ctl_reset_intf_cfg_v1(), dpu_encoder_unprep_dsc() and dpu_encoder_dsc_pipe_clr() functions to tear down DSC data path if DSC data path was setup previous. Changes in V10: -- pass ctl directly instead of dpu_enc to dsc_pipe_cfg() -- move both dpu_encoder_unprep_dsc() and dpu_encoder_dsc_pipe_clr() to above phys_cleanup() Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 39 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 7 ++ 2 files changed, 46 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 7fca09e..3b416e1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -2036,6 +2036,41 @@ static void dpu_encoder_helper_reset_mixers(struct dpu_encoder_phys *phys_enc) } } +static void dpu_encoder_dsc_pipe_clr(struct dpu_hw_ctl *ctl, +struct dpu_hw_dsc *hw_dsc, +struct dpu_hw_pingpong *hw_pp) +{ + if (hw_dsc->ops.dsc_disable) + hw_dsc->ops.dsc_disable(hw_dsc); + + if (hw_pp->ops.disable_dsc) + hw_pp->ops.disable_dsc(hw_pp); + + if (hw_dsc->ops.dsc_bind_pingpong_blk) + hw_dsc->ops.dsc_bind_pingpong_blk(hw_dsc, PINGPONG_NONE); + + if (ctl->ops.update_pending_flush_dsc) + ctl->ops.update_pending_flush_dsc(ctl, hw_dsc->idx); +} + +static void dpu_encoder_unprep_dsc(struct dpu_encoder_virt *dpu_enc) +{ + /* coding only for 2LM, 2enc, 1 dsc config */ + struct dpu_encoder_phys *enc_master = dpu_enc->cur_master; + struct dpu_hw_ctl *ctl = enc_master->hw_ctl; + struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC]; + struct dpu_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC]; + int i; + + for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { + hw_pp[i] = dpu_enc->hw_pp[i]; + hw_dsc[i] = dpu_enc->hw_dsc[i]; + + if (hw_pp[i] && hw_dsc[i]) + dpu_encoder_dsc_pipe_clr(ctl, hw_dsc[i], hw_pp[i]); + } +} + void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) { struct dpu_hw_ctl *ctl = phys_enc->hw_ctl; @@ -2086,8 +2121,12 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) phys_enc->hw_pp->merge_3d->idx); } + if (dpu_enc->dsc) + dpu_encoder_unprep_dsc(dpu_enc); + intf_cfg.stream_sel = 0; /* Don't care value for video mode */ intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); + intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc); if (phys_enc->hw_intf) intf_cfg.intf = phys_enc->hw_intf->idx; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index ad6983e..e28e8f8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -582,6 +582,7 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx, u32 intf_active = 0; u32 wb_active = 0; u32 merge3d_active = 0; + u32 dsc_active; /* * This API resets each portion of the CTL path namely, @@ -611,6 +612,12 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx, wb_active &= ~BIT(cfg->wb - WB_0); DPU_REG_WRITE(c, CTL_WB_ACTIVE, wb_active); } + + if (cfg->dsc) { + dsc_active = DPU_REG_READ(c, CTL_DSC_ACTIVE); + dsc_active &= ~cfg->dsc; + DPU_REG_WRITE(c, CTL_DSC_ACTIVE, dsc_active); + } } static void dpu_hw_ctl_set_fetch_pipe_active(struct dpu_hw_ctl *ctx, -- 2.7.4
[Freedreno] [PATCH v13 09/10] drm/msm/dpu: add DSC 1.2 hw blocks for relevant chipsets
From: Abhinav Kumar Add DSC 1.2 hardware blocks to the catalog with necessary sub-block and feature flag information. Each display compression engine (DCE) contains dual DSC encoders so both share same base address but with its own different sub block address. changes in v4: -- delete DPU_DSC_HW_REV_1_1 -- re arrange sc8280xp_dsc[] changes in v4: -- fix checkpatch warning changes in v10: -- remove hard slice from commit text -- replace DPU_DSC_NATIVE_422_EN with DPU_DSC_NATIVE_42x_EN -- change DSC_BLK_1_2 .len from 0x100 to 0x29c changes in v11: -- remove comment at DSC_BLK_1_2 marco Signed-off-by: Abhinav Kumar Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten --- .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 14 ++ .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 7 +++ .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 16 .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 14 ++ .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 14 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 20 +++- 6 files changed, 84 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h index 500cfd0..d90486f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h @@ -153,6 +153,18 @@ static const struct dpu_merge_3d_cfg sm8350_merge_3d[] = { MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x5), }; +/* + * NOTE: Each display compression engine (DCE) contains dual hard + * slice DSC encoders so both share same base address but with + * its own different sub block address. + */ +static const struct dpu_dsc_cfg sm8350_dsc[] = { + DSC_BLK_1_2("dce_0_0", DSC_0, 0x8, 0x29c, 0, dsc_sblk_0), + DSC_BLK_1_2("dce_0_1", DSC_1, 0x8, 0x29c, 0, dsc_sblk_1), + DSC_BLK_1_2("dce_1_0", DSC_2, 0x81000, 0x29c, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_0), + DSC_BLK_1_2("dce_1_1", DSC_3, 0x81000, 0x29c, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_1), +}; + static const struct dpu_intf_cfg sm8350_intf[] = { INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), @@ -215,6 +227,8 @@ const struct dpu_mdss_cfg dpu_sm8350_cfg = { .dspp = sm8350_dspp, .pingpong_count = ARRAY_SIZE(sm8350_pp), .pingpong = sm8350_pp, + .dsc_count = ARRAY_SIZE(sm8350_dsc), + .dsc = sm8350_dsc, .merge_3d_count = ARRAY_SIZE(sm8350_merge_3d), .merge_3d = sm8350_merge_3d, .intf_count = ARRAY_SIZE(sm8350_intf), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h index 5646713..52609b8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h @@ -93,6 +93,11 @@ static const struct dpu_pingpong_cfg sc7280_pp[] = { PP_BLK_DITHER("pingpong_3", PINGPONG_3, 0x6c000, 0, sc7280_pp_sblk, -1, -1), }; +/* NOTE: sc7280 only has one DSC hard slice encoder */ +static const struct dpu_dsc_cfg sc7280_dsc[] = { + DSC_BLK_1_2("dce_0_0", DSC_0, 0x8, 0x29c, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_0), +}; + static const struct dpu_intf_cfg sc7280_intf[] = { INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), @@ -149,6 +154,8 @@ const struct dpu_mdss_cfg dpu_sc7280_cfg = { .mixer = sc7280_lm, .pingpong_count = ARRAY_SIZE(sc7280_pp), .pingpong = sc7280_pp, + .dsc_count = ARRAY_SIZE(sc7280_dsc), + .dsc = sc7280_dsc, .intf_count = ARRAY_SIZE(sc7280_intf), .intf = sc7280_intf, .vbif_count = ARRAY_SIZE(sdm845_vbif), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h index 808aacd..a84cf36 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h @@ -141,6 +141,20 @@ static const struct dpu_merge_3d_cfg sc8280xp_merge_3d[] = { MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x5), }; +/* + * NOTE: Each display compression engine (DCE) contains dual hard + * slice DSC encoders so both share same base address but with + * its own different sub block address. + */ +static const struct dpu_dsc_cfg sc8280xp_dsc[] = { + DSC_BLK_1_2("dce_0_0", DSC_0, 0x8, 0x29c, 0, dsc_sblk_0), + DSC_BLK_1_2("dce_0_1", DSC_1, 0x8, 0x29c, 0, dsc_sblk_1), + DSC_BLK_1_2("dce_1_0", DSC_2, 0x81000, 0x29c, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_0), + DSC_BLK_1_2("dce_1_1", DSC_3, 0x81000,
[Freedreno] [PATCH v13 07/10] drm/msm/dpu: always clear every individual pending flush mask
There are two tiers of pending flush control, top levle and individual hardware block. Currently only the top level of flush mask is reset to 0 but the individual pending flush masks of particular hardware blocks are left at their previous values, eventually accumulating all possible bit values and typically flushing more than necessary. Reset all individual hardware blocks flush masks to 0 to avoid individual hardware block be triggered accidentally. Changes in V13: -- rewording commi ttext -- add an empty space line as suggested Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 69d0ea2..64c21e0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -100,6 +100,9 @@ static inline void dpu_hw_ctl_clear_pending_flush(struct dpu_hw_ctl *ctx) trace_dpu_hw_ctl_clear_pending_flush(ctx->pending_flush_mask, dpu_hw_ctl_get_flush_register(ctx)); ctx->pending_flush_mask = 0x0; + ctx->pending_intf_flush_mask = 0; + ctx->pending_wb_flush_mask = 0; + ctx->pending_merge_3d_flush_mask = 0; memset(ctx->pending_dspp_flush_mask, 0, sizeof(ctx->pending_dspp_flush_mask)); -- 2.7.4
[Freedreno] [PATCH v13 03/10] drm/msm/dpu: add DPU_PINGPONG_DSC feature bit for DPU < 7.0.0
DPU < 7.0.0 requires the PINGPONG block to be involved during DSC setting up. Since DPU >= 7.0.0, enabling and starting the DSC encoder engine was moved to INTF with the help of the flush mechanism. Add a DPU_PINGPONG_DSC feature bit to restrict the availability of dpu_hw_pp_setup_dsc() and dpu_hw_pp_dsc_{enable,disable}() on the PINGPONG block to DPU < 7.0.0 hardware, as the registers are not available on DPU 7.0.0 and higher anymore. Add DPU_PINGPONG_DSC to PINGPONG_SDM845_MASK, PINGPONG_SDM845_TE2_MASK and PINGPONG_SM8150_MASK which is used for all DPU < 7.0 chipsets. changes in v6: -- split patches and rearrange to keep catalog related files at this patch changes in v7: -- rewording commit text as suggested at review comments changes in v9: -- delete BIT(DPU_PINGPONG_DSC) from PINGPONG_SDM845_TE2_MASK changes in v10: -- correct order of commit text Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 4 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 82b58c6..f2a1535 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -76,13 +76,13 @@ (BIT(DPU_DIM_LAYER) | BIT(DPU_MIXER_COMBINED_ALPHA)) #define PINGPONG_SDM845_MASK \ - (BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_TE)) + (BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_TE) | BIT(DPU_PINGPONG_DSC)) #define PINGPONG_SDM845_TE2_MASK \ (PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2)) #define PINGPONG_SM8150_MASK \ - (BIT(DPU_PINGPONG_DITHER)) + (BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_DSC)) #define CTL_SC7280_MASK \ (BIT(DPU_CTL_ACTIVE_CFG) | \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 6ee48f0..83854e8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -144,7 +144,8 @@ enum { * @DPU_PINGPONG_TE2Additional tear check block for split pipes * @DPU_PINGPONG_SPLIT PP block supports split fifo * @DPU_PINGPONG_SLAVE PP block is a suitable slave for split fifo - * @DPU_PINGPONG_DITHER,Dither blocks + * @DPU_PINGPONG_DITHER Dither blocks + * @DPU_PINGPONG_DSCPP block supports DSC * @DPU_PINGPONG_MAX */ enum { @@ -153,6 +154,7 @@ enum { DPU_PINGPONG_SPLIT, DPU_PINGPONG_SLAVE, DPU_PINGPONG_DITHER, + DPU_PINGPONG_DSC, DPU_PINGPONG_MAX }; -- 2.7.4
[Freedreno] [PATCH v13 05/10] drm/msm/dpu: Introduce PINGPONG_NONE to disconnect DSC from PINGPONG
Disabling the crossbar mux between DSC and PINGPONG currently requires a bogus enum dpu_pingpong value to be passed when calling dsc_bind_pingpong_blk() with enable=false, even though the register value written is independent of the current PINGPONG block. Replace that `bool enable` parameter with a new PINGPONG_NONE dpu_pingpong flag that triggers the write of the "special" 0xF "crossbar disabled" value to the register instead. Changes in v4: -- more details to commit text Changes in v5: -- rewording commit text suggested by Marijn -- add DRM_DEBUG_KMS for DSC unbinding case Changes in v8: -- fix checkpatch warning Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c | 14 +++--- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 3 ++- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index cf1de5d..ffa6f04 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1850,7 +1850,7 @@ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc, hw_pp->ops.setup_dsc(hw_pp); if (hw_dsc->ops.dsc_bind_pingpong_blk) - hw_dsc->ops.dsc_bind_pingpong_blk(hw_dsc, true, hw_pp->idx); + hw_dsc->ops.dsc_bind_pingpong_blk(hw_dsc, hw_pp->idx); if (hw_pp->ops.enable_dsc) hw_pp->ops.enable_dsc(hw_pp); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c index 8deedeae..509dbaa 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c @@ -157,7 +157,6 @@ static void dpu_hw_dsc_config_thresh(struct dpu_hw_dsc *hw_dsc, static void dpu_hw_dsc_bind_pingpong_blk( struct dpu_hw_dsc *hw_dsc, - bool enable, const enum dpu_pingpong pp) { struct dpu_hw_blk_reg_map *c = _dsc->hw; @@ -166,14 +165,15 @@ static void dpu_hw_dsc_bind_pingpong_blk( dsc_ctl_offset = DSC_CTL(hw_dsc->idx); - if (enable) + if (pp) mux_cfg = (pp - PINGPONG_0) & 0x7; - DRM_DEBUG_KMS("%s dsc:%d %s pp:%d\n", - enable ? "Binding" : "Unbinding", - hw_dsc->idx - DSC_0, - enable ? "to" : "from", - pp - PINGPONG_0); + if (pp) + DRM_DEBUG_KMS("Binding dsc:%d to pp:%d\n", + hw_dsc->idx - DSC_0, pp - PINGPONG_0); + else + DRM_DEBUG_KMS("Unbinding dsc:%d from any pp\n", + hw_dsc->idx - DSC_0); DPU_REG_WRITE(c, dsc_ctl_offset, mux_cfg); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h index 287ec5f..138080a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h @@ -44,7 +44,6 @@ struct dpu_hw_dsc_ops { struct drm_dsc_config *dsc); void (*dsc_bind_pingpong_blk)(struct dpu_hw_dsc *hw_dsc, - bool enable, enum dpu_pingpong pp); }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h index 1913a19..02a0f48 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h @@ -191,7 +191,8 @@ enum dpu_dsc { }; enum dpu_pingpong { - PINGPONG_0 = 1, + PINGPONG_NONE, + PINGPONG_0, PINGPONG_1, PINGPONG_2, PINGPONG_3, -- 2.7.4
[Freedreno] [PATCH v13 04/10] drm/msm/dpu: Guard PINGPONG DSC ops behind DPU_PINGPONG_DSC bit
DPU < 7.0.0 has DPU_PINGPONG_DSC feature bit set to indicate it requires both dpu_hw_pp_setup_dsc() and dpu_hw_pp_dsc_{enable,disable}() to be executed to complete DSC configuration if DSC hardware block is present. Hence test DPU_PINGPONG_DSC feature bit and assign DSC related functions to the ops of PINGPONG block accordingly if DPU_PINGPONG_DSC bit is set. Changes in v6: -- split patches, this patch has function handles DPU_PINGPONG_DSC bit Changes in v9: -- the original code of assigning dsc related functions to the ops of pingpong block without testing the DPU_PINGPONG_DSC feature bit was restored back due to rebase error which defeat the purpose of this patch. Remove those error code. Changes in v10: -- change commit title -- correct texts at changes in v9 Changes in v12: -- fixed length too long at Changes in v9 Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c index 79e4576..437d9e6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c @@ -291,9 +291,12 @@ static void _setup_pingpong_ops(struct dpu_hw_pingpong *c, c->ops.get_line_count = dpu_hw_pp_get_line_count; c->ops.disable_autorefresh = dpu_hw_pp_disable_autorefresh; } - c->ops.setup_dsc = dpu_hw_pp_setup_dsc; - c->ops.enable_dsc = dpu_hw_pp_dsc_enable; - c->ops.disable_dsc = dpu_hw_pp_dsc_disable; + + if (test_bit(DPU_PINGPONG_DSC, )) { + c->ops.setup_dsc = dpu_hw_pp_setup_dsc; + c->ops.enable_dsc = dpu_hw_pp_dsc_enable; + c->ops.disable_dsc = dpu_hw_pp_dsc_disable; + } if (test_bit(DPU_PINGPONG_DITHER, )) c->ops.setup_dither = dpu_hw_pp_setup_dither; -- 2.7.4
[Freedreno] [PATCH v13 02/10] drm/msm/dpu: add dsc blocks to the catalog of MSM8998 and SC8180X
From: Abhinav Kumar Some platforms have DSC blocks which have not been declared in the catalog. Complete DSC 1.1 support for all platforms by adding the missing blocks to MSM8998 and SC8180X. Changes in v9: -- add MSM8998 and SC8180x to commit title Changes in v10: -- fix grammar at commit text Changes in v12: -- fix "titil" with "title" at changes in v9 Signed-off-by: Abhinav Kumar Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 7 +++ drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 11 +++ 2 files changed, 18 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h index c0dd477..521cfd5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h @@ -126,6 +126,11 @@ static const struct dpu_pingpong_cfg msm8998_pp[] = { DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)), }; +static const struct dpu_dsc_cfg msm8998_dsc[] = { + DSC_BLK("dsc_0", DSC_0, 0x8, 0), + DSC_BLK("dsc_1", DSC_1, 0x80400, 0), +}; + static const struct dpu_dspp_cfg msm8998_dspp[] = { DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_MSM8998_MASK, _dspp_sblk), @@ -199,6 +204,8 @@ const struct dpu_mdss_cfg dpu_msm8998_cfg = { .dspp = msm8998_dspp, .pingpong_count = ARRAY_SIZE(msm8998_pp), .pingpong = msm8998_pp, + .dsc_count = ARRAY_SIZE(msm8998_dsc), + .dsc = msm8998_dsc, .intf_count = ARRAY_SIZE(msm8998_intf), .intf = msm8998_intf, .vbif_count = ARRAY_SIZE(msm8998_vbif), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h index e8057a1..fec1665 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h @@ -142,6 +142,15 @@ static const struct dpu_merge_3d_cfg sc8180x_merge_3d[] = { MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x83200), }; +static const struct dpu_dsc_cfg sc8180x_dsc[] = { + DSC_BLK("dsc_0", DSC_0, 0x8, BIT(DPU_DSC_OUTPUT_CTRL)), + DSC_BLK("dsc_1", DSC_1, 0x80400, BIT(DPU_DSC_OUTPUT_CTRL)), + DSC_BLK("dsc_2", DSC_2, 0x80800, BIT(DPU_DSC_OUTPUT_CTRL)), + DSC_BLK("dsc_3", DSC_3, 0x80c00, BIT(DPU_DSC_OUTPUT_CTRL)), + DSC_BLK("dsc_4", DSC_4, 0x81000, BIT(DPU_DSC_OUTPUT_CTRL)), + DSC_BLK("dsc_5", DSC_5, 0x81400, BIT(DPU_DSC_OUTPUT_CTRL)), +}; + static const struct dpu_intf_cfg sc8180x_intf[] = { INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), @@ -206,6 +215,8 @@ const struct dpu_mdss_cfg dpu_sc8180x_cfg = { .mixer = sc8180x_lm, .pingpong_count = ARRAY_SIZE(sc8180x_pp), .pingpong = sc8180x_pp, + .dsc_count = ARRAY_SIZE(sc8180x_dsc), + .dsc = sc8180x_dsc, .merge_3d_count = ARRAY_SIZE(sc8180x_merge_3d), .merge_3d = sc8180x_merge_3d, .intf_count = ARRAY_SIZE(sc8180x_intf), -- 2.7.4
[Freedreno] [PATCH v13 01/10] drm/msm/dpu: set DSC flush bit correctly at MDP CTL flush register
The DSC CTL_FLUSH register should be programmed with the 22th bit (DSC_IDX) to flush the DSC hardware blocks, not the literal value of 22 (which corresponds to flushing VIG1, VIG2 and RGB1 instead). Changes in V12: -- split this patch out of "separate DSC flush update out of interface" Changes in V13: -- rewording the commit text Fixes: 77f6da90487c ("drm/msm/disp/dpu1: Add DSC support in hw_ctl") Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 4f7cfa9..69d0ea2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -525,7 +525,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, BIT(cfg->merge_3d - MERGE_3D_0)); if (cfg->dsc) { - DPU_REG_WRITE(>hw, CTL_FLUSH, DSC_IDX); + DPU_REG_WRITE(>hw, CTL_FLUSH, BIT(DSC_IDX)); DPU_REG_WRITE(c, CTL_DSC_ACTIVE, cfg->dsc); } } -- 2.7.4
[Freedreno] [PATCH v13 00/10] add DSC 1.2 dpu supports
This series adds the DPU side changes to support DSC 1.2 encoder. This was validated with both DSI DSC 1.2 panel and DP DSC 1.2 monitor. The DSI and DP parts will be pushed later on top of this change. This seriel is rebase on [1], [2] and catalog fixes from rev-4 of [3]. [1]: https://patchwork.freedesktop.org/series/116851/ [2]: https://patchwork.freedesktop.org/series/116615/ [3]: https://patchwork.freedesktop.org/series/112332/ Abhinav Kumar (2): drm/msm/dpu: add dsc blocks to the catalog of MSM8998 and SC8180X drm/msm/dpu: add DSC 1.2 hw blocks for relevant chipsets Kuogee Hsieh (8): drm/msm/dpu: set DSC flush bit correctly at MDP CTL flush register drm/msm/dpu: add DPU_PINGPONG_DSC feature bit for DPU < 7.0.0 drm/msm/dpu: Guard PINGPONG DSC ops behind DPU_PINGPONG_DSC bit drm/msm/dpu: Introduce PINGPONG_NONE to disconnect DSC from PINGPONG drm/msm/dpu: add support for DSC encoder v1.2 engine drm/msm/dpu: always clear every individual pending flush mask drm/msm/dpu: separate DSC flush update out of interface drm/msm/dpu: tear down DSC data path when DSC disabled drivers/gpu/drm/msm/Makefile | 1 + .../drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h| 7 + .../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h| 11 + .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 14 + .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 7 + .../drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 16 + .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 14 + .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 14 + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c| 51 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 24 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 35 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 33 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 11 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c | 14 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 15 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 387 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h| 3 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c| 9 +- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 7 +- 19 files changed, 644 insertions(+), 29 deletions(-) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c -- 2.7.4
Re: [Freedreno] [PATCH v2 1/6] drm/msm/dpu: don't set DPU_INTF_TE globally
On 2023-05-23 00:45:22, Dmitry Baryshkov wrote: > Using BIT(DPU_INTF_TE) in INTF_SC7180_MASK (and by extension in > INTF_SC7280_MASK) results in this bit (and corrsponding operations) > being enabled for all interfaces, even the ones which do not have TE > block. Move this bit setting to INTF_DSI_TE(), so that it is only > enabled for those INTF blocks which have TE support. > > Fixes: 152c1d430992 ("drm/msm/dpu: Add TEAR-READ-pointer interrupt to INTF > block") > Reviewed-by: Neil Armstrong > Signed-off-by: Dmitry Baryshkov > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > index 1dee5ba2b312..162141cb5c83 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > @@ -101,7 +101,6 @@ > > #define INTF_SC7180_MASK \ > (BIT(DPU_INTF_INPUT_CTRL) | \ > - BIT(DPU_INTF_TE) | \ >BIT(DPU_INTF_STATUS_SUPPORTED) | \ >BIT(DPU_DATA_HCTL_EN)) > > @@ -544,7 +543,7 @@ static const struct dpu_pingpong_sub_blks sc7280_pp_sblk > = { > {\ > .name = _name, .id = _id, \ > .base = _base, .len = _len, \ > - .features = _features, \ > + .features = _features | BIT(DPU_INTF_TE), \ We'll have to be very careful when applying this. I already had a hard time reviewing because of missing the #define context but assumed it would apply to INTF_BLK_DSI_TE()... but when actually applying it locally this ended up in INTF_BLK() and breaking everything. - Marijn > .type = _type, \ > .controller_id = _ctrl_id, \ > .prog_fetch_lines_worst_case = _progfetch, \ > -- > 2.39.2 >
[Freedreno] [PATCH v4] drm/msm/dp: enable HDP plugin/unplugged interrupts at hpd_enable/disable
The internal_hpd flag is set to true by dp_bridge_hpd_enable() and set to false by dp_bridge_hpd_disable() to handle GPIO pinmuxed into DP controller case. HDP related interrupts can not be enabled until internal_hpd is set to true. At current implementation dp_display_config_hpd() will initialize DP host controller first followed by enabling HDP related interrupts if internal_hpd was true at that time. Enable HDP related interrupts depends on internal_hpd status may leave system with DP driver host is in running state but without HDP related interrupts being enabled. This will prevent external display from being detected. Eliminated this dependency by moving HDP related interrupts enable/disable be done at dp_bridge_hpd_enable/disable() directly regardless of internal_hpd status. Changes in V3: -- dp_catalog_ctrl_hpd_enable() and dp_catalog_ctrl_hpd_disable() -- rewording ocmmit text Changes in V4: -- replace dp_display_config_hpd() with dp_display_host_start() -- move enable_irq() at dp_display_host_start(); Fixes: cd198caddea7 ("drm/msm/dp: Rely on hpd_enable/disable callbacks") Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/dp/dp_catalog.c | 15 +- drivers/gpu/drm/msm/dp/dp_catalog.h | 3 +- drivers/gpu/drm/msm/dp/dp_display.c | 58 + 3 files changed, 36 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c index 7a8cf1c..5142aeb 100644 --- a/drivers/gpu/drm/msm/dp/dp_catalog.c +++ b/drivers/gpu/drm/msm/dp/dp_catalog.c @@ -620,7 +620,7 @@ void dp_catalog_hpd_config_intr(struct dp_catalog *dp_catalog, config & DP_DP_HPD_INT_MASK); } -void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog) +void dp_catalog_ctrl_hpd_enable(struct dp_catalog *dp_catalog) { struct dp_catalog_private *catalog = container_of(dp_catalog, struct dp_catalog_private, dp_catalog); @@ -635,6 +635,19 @@ void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog) dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, DP_DP_HPD_CTRL_HPD_EN); } +void dp_catalog_ctrl_hpd_disable(struct dp_catalog *dp_catalog) +{ + struct dp_catalog_private *catalog = container_of(dp_catalog, + struct dp_catalog_private, dp_catalog); + + u32 reftimer = dp_read_aux(catalog, REG_DP_DP_HPD_REFTIMER); + + reftimer &= ~DP_DP_HPD_REFTIMER_ENABLE; + dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer); + + dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, 0); +} + static void dp_catalog_enable_sdp(struct dp_catalog_private *catalog) { /* trigger sdp */ diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h b/drivers/gpu/drm/msm/dp/dp_catalog.h index 82376a2..38786e8 100644 --- a/drivers/gpu/drm/msm/dp/dp_catalog.h +++ b/drivers/gpu/drm/msm/dp/dp_catalog.h @@ -104,7 +104,8 @@ bool dp_catalog_ctrl_mainlink_ready(struct dp_catalog *dp_catalog); void dp_catalog_ctrl_enable_irq(struct dp_catalog *dp_catalog, bool enable); void dp_catalog_hpd_config_intr(struct dp_catalog *dp_catalog, u32 intr_mask, bool en); -void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog); +void dp_catalog_ctrl_hpd_enable(struct dp_catalog *dp_catalog); +void dp_catalog_ctrl_hpd_disable(struct dp_catalog *dp_catalog); void dp_catalog_ctrl_config_psr(struct dp_catalog *dp_catalog); void dp_catalog_ctrl_set_psr(struct dp_catalog *dp_catalog, bool enter); u32 dp_catalog_link_is_connected(struct dp_catalog *dp_catalog); diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 3e13acdf..370632b 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -615,12 +615,6 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data) dp->hpd_state = ST_MAINLINK_READY; } - /* enable HDP irq_hpd/replug interrupt */ - if (dp->dp_display.internal_hpd) - dp_catalog_hpd_config_intr(dp->catalog, - DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, - true); - drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n", dp->dp_display.connector_type, state); mutex_unlock(>event_mutex); @@ -658,12 +652,6 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data) drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n", dp->dp_display.connector_type, state); - /* disable irq_hpd/replug interrupts */ - if (dp->dp_display.internal_hpd) - dp_catalog_hpd_config_intr(dp->catalog, - DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, - false); - /* unplugged, no more irq_hpd handle */
Re: [Freedreno] [PATCH v3] drm/msm/dp: enable HDP plugin/unplugged interrupts at hpd_enable/disable
On Mon, May 22, 2023 at 03:35:13PM -0700, Kuogee Hsieh wrote: > > > > > > -static void dp_display_config_hpd(struct dp_display_private *dp) > > > > -{ > > > > - > > > > - dp_display_host_init(dp); > > > > - dp_catalog_ctrl_hpd_config(dp->catalog); > > > > - > > > > - /* Enable plug and unplug interrupts only if requested */ > > > > - if (dp->dp_display.internal_hpd) > > > > - dp_catalog_hpd_config_intr(dp->catalog, > > > > - DP_DP_HPD_PLUG_INT_MASK | > > > > - DP_DP_HPD_UNPLUG_INT_MASK, > > > > - true); > > > > - > > > > - /* Enable interrupt first time > > > > - * we are leaving dp clocks on during disconnect > > > > - * and never disable interrupt > > > > - */ > > > > - enable_irq(dp->irq); > > > > > > ...we need dp->irq enabled for handling the other interrupts, otherwise > > > e.g. AUX transfers will time out. > > > > > > I added enable_irq(dp_priv->irq) to the EV_HPD_INIT_SETUP case below, > > > just for testing, and with that the patch seems to be working fine. > > > > > > > > > Is there any reason why we need to delay its enablement to after we > > > unmask the HPD interrupts? > > my though is aux transaction should happen after plugin interrupt detected. > I have a next_bridge which implements DRM_BRIDGE_OP_HPD, in which case dp_bridge_hpd_enable() will never be called (the next_bridge's hpd_enable will be called instead). > can you please let me know what did you do to trigger aux timeout? > In this setup I just connect the cable, wait a few seconds and the transfers fails - as there's no interrupts signalling them being completed. > It does not happen on me at my test. > Given that you have the HPD signal on a GPIO, you should be able to rewrite your DTS in line with: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/qcom/sa8295p-adp.dts#n28 And pinmux the HPD signal as GPIO instead. I believe this would allow you to test both code paths - without the actual TCPM known to Linux. > > > > As I wrote, I'd probably prefer to see enable_irq() and disable_irq() > > calls gone. > > ok, i will move enable_irq() out of here. > Thanks, Bjorn > > > > > > > Regards, > > > Bjorn > > > > >
Re: [Freedreno] [PATCH v2 6/7] drm/msm/dpu: drop temp variable from dpu_encoder_phys_cmd_init()
On 5/18/2023 7:38 PM, Dmitry Baryshkov wrote: There is no need to assign a result to temp varable just to return it two lines below. Drop the temporary variable. Signed-off-by: Dmitry Baryshkov --- Reviewed-by: Abhinav Kumar
Re: [Freedreno] [PATCH v3] drm/msm/dp: enable HDP plugin/unplugged interrupts at hpd_enable/disable
-static void dp_display_config_hpd(struct dp_display_private *dp) -{ - - dp_display_host_init(dp); - dp_catalog_ctrl_hpd_config(dp->catalog); - - /* Enable plug and unplug interrupts only if requested */ - if (dp->dp_display.internal_hpd) - dp_catalog_hpd_config_intr(dp->catalog, - DP_DP_HPD_PLUG_INT_MASK | - DP_DP_HPD_UNPLUG_INT_MASK, - true); - - /* Enable interrupt first time - * we are leaving dp clocks on during disconnect - * and never disable interrupt - */ - enable_irq(dp->irq); ...we need dp->irq enabled for handling the other interrupts, otherwise e.g. AUX transfers will time out. I added enable_irq(dp_priv->irq) to the EV_HPD_INIT_SETUP case below, just for testing, and with that the patch seems to be working fine. Is there any reason why we need to delay its enablement to after we unmask the HPD interrupts? my though is aux transaction should happen after plugin interrupt detected. can you please let me know what did you do to trigger aux timeout? It does not happen on me at my test. As I wrote, I'd probably prefer to see enable_irq() and disable_irq() calls gone. ok, i will move enable_irq() out of here. Regards, Bjorn
Re: [Freedreno] [PATCH v2 2/7] drm/msm/dpu: separate common function to init physical encoder
On 5/18/2023 7:38 PM, Dmitry Baryshkov wrote: Move common DPU physical encoder initialization code to the new function dpu_encoder_phys_init(). Signed-off-by: Dmitry Baryshkov --- Reviewed-by: Abhinav Kumar
Re: [Freedreno] [PATCH v2 1/2] drm/msm/dsi: remove extra call to dsi_get_pclk_rate()
On 5/20/2023 1:01 PM, Dmitry Baryshkov wrote: In dsi_calc_clk_rate_v2() there is no need to call dsi_get_pclk_rate(). This function has just been called (from dsi_calc_pclk()) and its result is stored at msm_host->pixel_clk_rate. Use this variable directly. Hi Dmitry, LGTM. Reviewed-by: Jessica Zhang Thanks, Jessica Zhang Reviewed-by: Marijn Suijten Signed-off-by: Dmitry Baryshkov --- Changes since v1: - Fix typos in commit message (Marijn) --- drivers/gpu/drm/msm/dsi/dsi_host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 961689a255c4..2b257b459974 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -633,7 +633,7 @@ int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_bonded_dsi) dsi_calc_pclk(msm_host, is_bonded_dsi); - pclk_bpp = (u64)dsi_get_pclk_rate(msm_host->mode, is_bonded_dsi) * bpp; + pclk_bpp = (u64)msm_host->pixel_clk_rate * bpp; do_div(pclk_bpp, 8); msm_host->src_clk_rate = pclk_bpp; -- 2.39.2
Re: [Freedreno] [PATCH v4 2/5] drm/msm/dsi: Adjust pclk rate for compression
On 5/22/2023 2:31 PM, Marijn Suijten wrote: On 2023-05-22 13:30:21, Jessica Zhang wrote: Adjust the pclk rate to divide hdisplay by the compression ratio when DSC is enabled. Signed-off-by: Jessica Zhang As discussed previously, this patch would apply a lot more cleanly on top of: https://lore.kernel.org/linux-arm-msm/20230520200103.4019607-1-dmitry.barysh...@linaro.org/T/#u (This is the v2 that doesn't change the callback, but does change the code flow so that you have to *touch less lines* in this patch). Hi Marijn, Sounds good. I'll rebase on top of that. Thanks, Jessica Zhang - Marijn --- drivers/gpu/drm/msm/dsi/dsi_host.c | 23 +++ 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 18d38b90eb28..d04f8bbd707d 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -561,7 +561,18 @@ void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host) clk_disable_unprepare(msm_host->byte_clk); } -static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode, bool is_bonded_dsi) +static unsigned long dsi_adjust_compressed_pclk(const struct drm_display_mode *mode, + const struct drm_dsc_config *dsc) +{ + int new_hdisplay = DIV_ROUND_UP(mode->hdisplay * drm_dsc_get_bpp_int(dsc), + dsc->bits_per_component * 3); + + return (new_hdisplay + (mode->htotal - mode->hdisplay)) + * mode->vtotal * drm_mode_vrefresh(mode); +} + +static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode, + const struct drm_dsc_config *dsc, bool is_bonded_dsi) { unsigned long pclk_rate; @@ -576,6 +587,10 @@ static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode, bool if (is_bonded_dsi) pclk_rate /= 2; + /* If DSC is enabled, divide hdisplay by compression ratio */ + if (dsc) + pclk_rate = dsi_adjust_compressed_pclk(mode, dsc); + return pclk_rate; } @@ -585,7 +600,7 @@ unsigned long dsi_byte_clk_get_rate(struct mipi_dsi_host *host, bool is_bonded_d struct msm_dsi_host *msm_host = to_msm_dsi_host(host); u8 lanes = msm_host->lanes; u32 bpp = dsi_get_bpp(msm_host->format); - unsigned long pclk_rate = dsi_get_pclk_rate(mode, is_bonded_dsi); + unsigned long pclk_rate = dsi_get_pclk_rate(mode, msm_host->dsc, is_bonded_dsi); u64 pclk_bpp = (u64)pclk_rate * bpp; if (lanes == 0) { @@ -604,7 +619,7 @@ unsigned long dsi_byte_clk_get_rate(struct mipi_dsi_host *host, bool is_bonded_d static void dsi_calc_pclk(struct msm_dsi_host *msm_host, bool is_bonded_dsi) { - msm_host->pixel_clk_rate = dsi_get_pclk_rate(msm_host->mode, is_bonded_dsi); + msm_host->pixel_clk_rate = dsi_get_pclk_rate(msm_host->mode, msm_host->dsc, is_bonded_dsi); msm_host->byte_clk_rate = dsi_byte_clk_get_rate(_host->base, is_bonded_dsi, msm_host->mode); @@ -634,7 +649,7 @@ int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_bonded_dsi) dsi_calc_pclk(msm_host, is_bonded_dsi); - pclk_bpp = (u64)dsi_get_pclk_rate(msm_host->mode, is_bonded_dsi) * bpp; + pclk_bpp = (u64)dsi_get_pclk_rate(msm_host->mode, msm_host->dsc, is_bonded_dsi) * bpp; do_div(pclk_bpp, 8); msm_host->src_clk_rate = pclk_bpp; -- 2.40.1
Re: [Freedreno] [PATCH v2 1/6] drm/msm/dpu: don't set DPU_INTF_TE globally
On 2023-05-23 01:01:50, Dmitry Baryshkov wrote: > On 23/05/2023 00:56, Marijn Suijten wrote: > > Title suggestion: s/globally/on non-TE/DSI (INTF) blocks > > > > On 2023-05-23 00:45:22, Dmitry Baryshkov wrote: > >> Using BIT(DPU_INTF_TE) in INTF_SC7180_MASK (and by extension in > >> INTF_SC7280_MASK) results in this bit (and corrsponding operations) > >> being enabled for all interfaces, even the ones which do not have TE > >> block. Move this bit setting to INTF_DSI_TE(), so that it is only > >> enabled for those INTF blocks which have TE support. > >> > >> Fixes: 152c1d430992 ("drm/msm/dpu: Add TEAR-READ-pointer interrupt to INTF > >> block") > >> Reviewed-by: Neil Armstrong > >> Signed-off-by: Dmitry Baryshkov > > > > We've always been setting flags globally but I guess it makes sense to > > not only restrict this flag to DPU >= 5.0.0 but also just the few > > hardware blocks that actually have these in their *enlarged* register > > space (and have the interrupt). > > > > Reviewed-by: Marijn Suijten > > > >> --- > >> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 3 +-- > >> 1 file changed, 1 insertion(+), 2 deletions(-) > >> > >> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > >> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > >> index 1dee5ba2b312..162141cb5c83 100644 > >> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > >> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > >> @@ -101,7 +101,6 @@ > >> > >> #define INTF_SC7180_MASK \ > >>(BIT(DPU_INTF_INPUT_CTRL) | \ > >> - BIT(DPU_INTF_TE) | \ > >> BIT(DPU_INTF_STATUS_SUPPORTED) | \ > >> BIT(DPU_DATA_HCTL_EN)) > >> > >> @@ -544,7 +543,7 @@ static const struct dpu_pingpong_sub_blks > >> sc7280_pp_sblk = { > >>{\ > >>.name = _name, .id = _id, \ > >>.base = _base, .len = _len, \ > >> - .features = _features, \ > >> + .features = _features | BIT(DPU_INTF_TE), \ > > > > Now that we're more broadly switching to this pattern, should we do the > > same for PP_BLK() with and without TE block? That way we can also > > forcefully initialize intr_rdptr=-1 similar to what I did for > > intr_tear_rd_ptr in INTF_BLK() (vs INTF_BLK_DSI_TE) here, instead of > > having the -1's floating around the catalog when I added them in commit > > 7952f5180eb3e ("drm/msm/dpu: Remove intr_rdptr from DPU >= 5.0.0 > > pingpong config"). > > If we are going to expand the macros, then hiding -1 probably doesn't > make sense as it will reappear soon. > > Probably it makes sense to do another thing (which would play better > with the expanded macros): increase IRQ indices by 1, making 'NO IRQ' > equal to 0 instead of -1. This way all non-existing interrupts can be > omitted during macros expansion. WDYT? I'm fine explicitly setting it to -1 to clarify it is missing. On the other hand, default struct initialization might accidentally initialize it to the first interrupt on MDP_SSPP_TOP0_INTR (when users forget to write the member), where it makes sense to start at 1 instead. Need to think about this for a bit. (The forced number of arguments is an advantage of the macro, even if we now have too many numeric constants to know which field it sets) - Marijn > > - Marijn > > > >>.type = _type, \ > >>.controller_id = _ctrl_id, \ > >>.prog_fetch_lines_worst_case = _progfetch, \ > >> -- > >> 2.39.2 > >> > > -- > With best wishes > Dmitry >
Re: [Freedreno] [PATCH v4 1/5] msm/drm/dsi: Round up DSC hdisplay calculation
On 23/05/2023 01:18, Marijn Suijten wrote: On 2023-05-23 01:14:40, Dmitry Baryshkov wrote: On Tue, 23 May 2023 at 00:45, Jessica Zhang wrote: On 5/22/2023 1:44 PM, Marijn Suijten wrote: On 2023-05-22 13:30:20, Jessica Zhang wrote: Currently, when compression is enabled, hdisplay is reduced via integer division. This causes issues for modes where the original hdisplay is not a multiple of 3. To fix this, use DIV_ROUND_UP to divide hdisplay. Reviewed-by: Marijn Suijten Suggested-by: Marijn Suijten Nit: probably these should go in the opposite order. And if they're all supposed to be chronological, I think it is: Suggested-by: Fixes: Signed-off-by: Reviewed-by: But unsure if that's a hard requirement, or even correct at all. Hi Marijn, I don't see any explicit documentation on the order of R-b tags. FWIW, I see in the git log that S-o-b always goes at the bottom of the commit message. I would prefer the S-o-b to always be at the bottom (as it helps me avoid duplicate S-o-b's when doing `git commit -s`), though I can flip the order of the R-b and suggested-by tags. I'd second Jessica here. Consider these tags as a history or a transcript: I would not vote on the particular order of the Suggested-by/Fixes tags, I don't think that is important. These come first. Then the patch goes through different cycles. of reviews, which gain Reviewed-by tags. In the same way Link/Patchwork/whatever other tags are added in the historical order. By having the submitter's S-o-b at the bottom, the submitter adds the final signature under everything else being stated/recorded. Correct, so the s-o-b can always be kept / moved back to the bottom on a resend, stating that they sign off on "all that was written previously" including picking up reviews. However, for the rest of your reply about "history / transcript", you seem to agree exactly with my point of keeping (or rather, simply appending) these in chronological order? Yes. - Marijn Of course, in a more complicated story, there might be other developers taking part (Co-Developed-By + Signed-off-by), etc. Note: all described is just my perception and might differ from the BCP regarding the tags. -- With best wishes Dmitry
Re: [Freedreno] [RFC PATCH v2 06/13] drm/msm/dpu: switch RM to use crtc_id rather than enc_id for allocation
Sorry for the delay, other topics delayed my response on this one. On 5/18/2023 6:50 PM, Dmitry Baryshkov wrote: On 19/05/2023 02:46, Abhinav Kumar wrote: On 3/20/2023 6:18 PM, Dmitry Baryshkov wrote: Up to now the driver has been using encoder to allocate hardware resources. Switch it to use CRTC id in preparation for the next step. This decision to use encoder id instead of CRTC has been there downstream for quite sometime. So most of the delay in reviewing this series was trying to understand why we had this in the first place and who knew that story. You are right that from the perspective of clone mode mapping resources to CRTC is correct but using encoder id is what has been working so far without too much difficulty with a little more management But another use-case can get simplified with this. Thank you for the historical perspective and for the feedback. I think that keeping resource allocation in dpu_encoder was required when INTF/WB themselves were allocated through the RM. However as INTF/WB blocks are now allocated in a static way, it doesn't make so much sense anymore. No, whether intf/wb block themselves are allocated through RM or not did not really go into this. It was just about considering where all hardware blocks make sense to be mapped : crtc or encoder. At the end, considering the dsc, cwb and some more blocks encoder id was used. There is another angle to this. There are hardware blocks which can do writeback and the physical display concurrently. We call it concurrent writeback or CWB. This is present even on some of the chipsets already supported upstream. Now, lets say we start a concurrent writeback session , in todays code we will allocate the resources with the encoder id of the writeback's encoder and the other physical display's encoder. When the session stops, we can just deallocate the resources of the writeback encoder without touching the other encoder. So it will become easier to just free up the resources mapped to the encoder. I have not looked into CWB programming. However from your description it would be as easy to do a full reallocation of the pipeline as just dropping the CWB/extra encoder. In fact this is what the driver was doing: in case of a modeset, drop all old resources and allocate full set of resources. Correct and the reason it was able to seamlessly drop all the old resources was because of the encoder_id mapping, for the cwb use-case using crtc id will not be so seamless to release the resources. With clone mode implemented with CRTC id to map resources, we will have to probably do some extra book-keeping to handle concurrent writeback. Probably not much. We'd have to describe the topology/requirements and then pass that to RM. I have been waiting for this patchset (and up to some point the DSC/ctl) to be reviewed before finalizing/submitting the patches that rework the CTL interface to use this kind of data structure. There is some effort there from what I can see in the cwb case. I am unable to visualize how your rework will help that case. If you want to move this mapping to crtc id to that series to convince us how, then it is a better fit for that series. Thats the use-case which gets impacted with this but for others, there shouldnt be a major impact from what we see. That being said, what benefit are you seeing from making that change now for this series? Why is it specifically needed for virtual planes? I see in the commit text that you have mentioned this is in preparation for next step and next step talks about clone mode. But clone mode is not there yet. So why this change now? There were several items that triggered this review. First thing first. Current design allocates resources from dpu_encoder_virt_atomic_check(), then in dpu_encoder_virt_atomic_mode_set() the driver has to poke manually in the cstate and fill CTL and LM. This kept on bugging me for some time. The encoder should not be poking into the CRTC state. Interesting point, but the DRM documentation seems to allow that and I think now thats one of the positives to have things in encoder's atomic check. 803 * This callback is used to validate encoder state for atomic drivers. 804 * Since the encoder is the object connecting the CRTC and connector it 805 * gets passed both states, to be able to validate interactions and 806 * update the CRTC to match what the encoder needs for the requested 807 * connector. 808 * Encoder is the place where we have both the crtc and the connector state being passed down to. the crtc's atomic check doesnt have the states of encoder. So it just seems the encoder's atomic check is more centralized for the entire pipeline. Then came the virtual planes. I think you'd agree that for the virtual planes we assign SSPPs to the CRTCs. My initial design kept enc_id for all the resources except the SSPP blocks (which
Re: [Freedreno] [PATCH v2 6/6] drm/msm/dpu: drop compatibility INTR defines
On 2023-05-23 00:45:27, Dmitry Baryshkov wrote: > While reworking interrupts masks, it was easier to keep old > MDP_INTFn_7xxx_INTR and MDP_INTFn_7xxx_TEAR_INTR symbols. Now it is time > to drop them and use unified symbol names. > > Reviewed-by: Neil Armstrong > Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten > --- > .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 4 ++-- > .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 2 +- > .../drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h| 4 ++-- > .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 4 ++-- > .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 4 ++-- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 13 - > 6 files changed, 9 insertions(+), 22 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h > index 649784aa6567..df88e3f2a548 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h > @@ -161,11 +161,11 @@ static const struct dpu_intf_cfg sm8350_intf[] = { > INTF_BLK_DSI_TE("intf_1", INTF_1, 0x35000, 0x2c4, INTF_DSI, 0, 24, > INTF_SC7280_MASK, > DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), > DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), > - DPU_IRQ_IDX(MDP_INTF1_7xxx_TEAR_INTR, 2)), > + DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2)), > INTF_BLK_DSI_TE("intf_2", INTF_2, 0x36000, 0x2c4, INTF_DSI, 1, 24, > INTF_SC7280_MASK, > DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), > DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29), > - DPU_IRQ_IDX(MDP_INTF2_7xxx_TEAR_INTR, 2)), > + DPU_IRQ_IDX(MDP_INTF2_TEAR_INTR, 2)), > INTF_BLK("intf_3", INTF_3, 0x37000, 0x280, INTF_DP, > MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, > DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30), > DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31)), > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h > index 1e87c7f4775d..4d9936d41464 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h > @@ -107,7 +107,7 @@ static const struct dpu_intf_cfg sc7280_intf[] = { > INTF_BLK_DSI_TE("intf_1", INTF_1, 0x35000, 0x2c4, INTF_DSI, 0, 24, > INTF_SC7280_MASK, > DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), > DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), > - DPU_IRQ_IDX(MDP_INTF1_7xxx_TEAR_INTR, 2)), > + DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2)), > INTF_BLK("intf_5", INTF_5, 0x39000, 0x280, INTF_DP, > MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, > DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 22), > DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 23)), > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h > index 3082657f06f2..65fa65b954db 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h > @@ -151,11 +151,11 @@ static const struct dpu_intf_cfg sc8280xp_intf[] = { > INTF_BLK_DSI_TE("intf_1", INTF_1, 0x35000, 0x300, INTF_DSI, 0, 24, > INTF_SC7280_MASK, > DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), > DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), > - DPU_IRQ_IDX(MDP_INTF1_7xxx_TEAR_INTR, 2)), > + DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2)), > INTF_BLK_DSI_TE("intf_2", INTF_2, 0x36000, 0x300, INTF_DSI, 1, 24, > INTF_SC7280_MASK, > DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), > DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29), > - DPU_IRQ_IDX(MDP_INTF2_7xxx_TEAR_INTR, 2)), > + DPU_IRQ_IDX(MDP_INTF2_TEAR_INTR, 2)), > INTF_BLK("intf_3", INTF_3, 0x37000, 0x280, INTF_NONE, > MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, > DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30), > DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31)), > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h > index ca5b82bc8322..b8158ed94845 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h > @@ -169,11 +169,11 @@ static const struct dpu_intf_cfg sm8450_intf[] = { > INTF_BLK_DSI_TE("intf_1", INTF_1, 0x35000, 0x300, INTF_DSI, 0, 24, > INTF_SC7280_MASK, > DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), > DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), > - DPU_IRQ_IDX(MDP_INTF1_7xxx_TEAR_INTR, 2)),
Re: [Freedreno] [PATCH v2 4/6] drm/msm/dpu: autodetect supported interrupts
On 2023-05-23 01:17:50, Dmitry Baryshkov wrote: > On Tue, 23 May 2023 at 01:12, Marijn Suijten > wrote: > > > > On 2023-05-23 00:45:25, Dmitry Baryshkov wrote: > > > Declaring the mask of supported interrupts proved to be error-prone. It > > > is very easy to add a bit with no corresponding backing block or to miss > > > the INTF TE bit. Replace this with looping over the enabled INTF blocks > > > to setup the irq mask. > > > > > > Signed-off-by: Dmitry Baryshkov > > > > Reviewed-by: Marijn Suijten > > > > > --- > > > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 20 ++- > > > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 6 ++ > > > 2 files changed, 25 insertions(+), 1 deletion(-) > > > > > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > > > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > > > index a03d826bb9ad..01f2660a2354 100644 > > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > > > @@ -463,6 +463,7 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem > > > *addr, > > > { > > > struct dpu_hw_intr *intr; > > > int nirq = MDP_INTR_MAX * 32; > > > + unsigned int i; > > > > > > if (!addr || !m) > > > return ERR_PTR(-EINVAL); > > > @@ -480,7 +481,24 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem > > > *addr, > > > > > > intr->total_irqs = nirq; > > > > > > - intr->irq_mask = m->mdss_irqs; > > > + intr->irq_mask = BIT(MDP_SSPP_TOP0_INTR) | > > > + BIT(MDP_SSPP_TOP0_INTR2) | > > > + BIT(MDP_SSPP_TOP0_HIST_INTR); > > > + for (i = 0; i < m->intf_count; i++) { > > > + const struct dpu_intf_cfg *intf = >intf[i]; > > > + > > > + if (intf->type == INTF_NONE) > > > + continue; > > > + > > > + intr->irq_mask |= BIT(MDP_INTFn_INTR(intf->id)); > > > + > > > + if (test_bit(DPU_INTF_TE, >features)) { > > > + unsigned idx = MDP_INTFn_TEAR_INTR(intf->id); > > > + > > > + if (!WARN_ON(idx == -1)) > > > > We don't need to validate the catalog? But warning users about this > > (and accidentally turning on all interrupt bits hiding the issue anyway) > > is a nice side effect though, as you showed it was already going wrong > > in patch 1/6. > > > > OTOH you might have inlined the macro and provided a more useful warning > > message (DPU_INTF_TE can only be present on INTF1/2)... and then one > > could assert on INTF_DSI etc etc etc... > > I'd prefer to keep it, as a safeguard for submission being in > progress, newer generations gaining TE blocks on other interfaces, > etc. > I was selecting between having explicit intf->id == INTF_1 || == > INTF_2 condition and this kind of macro. Being explicit in-line here has my preference. Maybe the same for the above bit, not sure about that one yet (e.g. have an upper bound on INTF_8). - Marijn > > > > > - Marijn > > > > > + intr->irq_mask |= BIT(idx); > > > + } > > > + } > > > > > > spin_lock_init(>irq_lock); > > > > > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h > > > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h > > > index f329d6d7f646..f0b92c9e3b09 100644 > > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h > > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h > > > @@ -17,6 +17,7 @@ enum dpu_hw_intr_reg { > > > MDP_SSPP_TOP0_INTR, > > > MDP_SSPP_TOP0_INTR2, > > > MDP_SSPP_TOP0_HIST_INTR, > > > + /* All MDP_INTFn_INTR should come sequentially */ > > > MDP_INTF0_INTR, > > > MDP_INTF1_INTR, > > > MDP_INTF2_INTR, > > > @@ -33,6 +34,11 @@ enum dpu_hw_intr_reg { > > > MDP_INTR_MAX, > > > }; > > > > > > +#define MDP_INTFn_INTR(intf) (MDP_INTF0_INTR + (intf - INTF_0)) > > > +#define MDP_INTFn_TEAR_INTR(intf) (intf == INTF_1 ? MDP_INTF1_TEAR_INTR > > > : \ > > > +intf == INTF_2 ? MDP_INTF2_TEAR_INTR : \ > > > +-1) > > > + > > > /* compatibility */ > > > #define MDP_INTF0_7xxx_INTR MDP_INTF0_INTR > > > #define MDP_INTF1_7xxx_INTR MDP_INTF1_INTR > > > -- > > > 2.39.2 > > > > > > > -- > With best wishes > Dmitry
Re: [Freedreno] [PATCH v2 5/6] drm/msm/dpu: drop now-unused mdss_irqs field from hw catalog
On Tue, 23 May 2023 at 01:15, Marijn Suijten wrote: > > On 2023-05-23 00:45:26, Dmitry Baryshkov wrote: > > Now as the list of the interrupts is constructed from the catalog > > data, drop the mdss_irqs field from catalog. > > > > Reviewed-by: Neil Armstrong > > Signed-off-by: Dmitry Baryshkov > > --- > > .../drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h| 8 > > .../gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h | 9 - > > .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 11 --- > > .../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h| 13 - > > .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 10 -- > > .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 6 -- > > .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h | 5 - > > .../drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h| 5 - > > .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 9 - > > .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 7 --- > > .../drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 14 -- > > .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 9 - > > .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 9 - > > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 3 --- > > 14 files changed, 118 deletions(-) > > > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h > > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h > > index 3c732a0360c7..ff7c3d522046 100644 > > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h > > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h > > @@ -204,14 +204,6 @@ const struct dpu_mdss_cfg dpu_msm8998_cfg = { > > .vbif_count = ARRAY_SIZE(msm8998_vbif), > > .vbif = msm8998_vbif, > > .perf = _perf_data, > > - .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ > > - BIT(MDP_SSPP_TOP0_INTR2) | \ > > - BIT(MDP_SSPP_TOP0_HIST_INTR) | \ > > - BIT(MDP_INTF0_INTR) | \ > > - BIT(MDP_INTF1_INTR) | \ > > - BIT(MDP_INTF2_INTR) | \ > > - BIT(MDP_INTF3_INTR) | \ > > - BIT(MDP_INTF4_INTR), > > }; > > > > #endif > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h > > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h > > index 36ea1af10894..c4ccd742690a 100644 > > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h > > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h > > @@ -202,15 +202,6 @@ const struct dpu_mdss_cfg dpu_sdm845_cfg = { > > .vbif_count = ARRAY_SIZE(sdm845_vbif), > > .vbif = sdm845_vbif, > > .perf = _perf_data, > > - .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ > > - BIT(MDP_SSPP_TOP0_INTR2) | \ > > - BIT(MDP_SSPP_TOP0_HIST_INTR) | \ > > - BIT(MDP_INTF0_INTR) | \ > > - BIT(MDP_INTF1_INTR) | \ > > - BIT(MDP_INTF2_INTR) | \ > > - BIT(MDP_INTF3_INTR) | \ > > - BIT(MDP_AD4_0_INTR) | \ > > - BIT(MDP_AD4_1_INTR), > > I don't think you're adding AD4 back anywhere? Not that there is > any code handling AD4 (e.g. registering those interrupts) anywhere, but > that should be done and documented in a separate patch then. > > After dropping that from this patch and describing it in a preliminary > one: > > Reviewed-by: Marijn Suijten Good point. > > > }; > > > > #endif > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h > > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h > > index b5f751354267..fb7069d470ff 100644 > > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h > > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h > > @@ -231,17 +231,6 @@ const struct dpu_mdss_cfg dpu_sm8150_cfg = { > > .vbif_count = ARRAY_SIZE(sdm845_vbif), > > .vbif = sdm845_vbif, > > .perf = _perf_data, > > - .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ > > - BIT(MDP_SSPP_TOP0_INTR2) | \ > > - BIT(MDP_SSPP_TOP0_HIST_INTR) | \ > > - BIT(MDP_INTF0_INTR) | \ > > - BIT(MDP_INTF1_INTR) | \ > > - BIT(MDP_INTF1_TEAR_INTR) | \ > > - BIT(MDP_INTF2_INTR) | \ > > - BIT(MDP_INTF2_TEAR_INTR) | \ > > - BIT(MDP_INTF3_INTR) | \ > > - BIT(MDP_AD4_0_INTR) | \ > > - BIT(MDP_AD4_1_INTR), > > }; > > > > #endif > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h > > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h > > index 8ed2b263c5ea..bd7422e597aa 100644 > > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h > > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h > > @@ -237,19 +237,6 @@ const struct dpu_mdss_cfg dpu_sc8180x_cfg = { > > .vbif_count =
Re: [Freedreno] [PATCH v4 1/5] msm/drm/dsi: Round up DSC hdisplay calculation
On 2023-05-23 01:14:40, Dmitry Baryshkov wrote: > On Tue, 23 May 2023 at 00:45, Jessica Zhang wrote: > > > > > > > > On 5/22/2023 1:44 PM, Marijn Suijten wrote: > > > On 2023-05-22 13:30:20, Jessica Zhang wrote: > > >> Currently, when compression is enabled, hdisplay is reduced via integer > > >> division. This causes issues for modes where the original hdisplay is > > >> not a multiple of 3. > > >> > > >> To fix this, use DIV_ROUND_UP to divide hdisplay. > > >> > > >> Reviewed-by: Marijn Suijten > > >> Suggested-by: Marijn Suijten > > > > > > Nit: probably these should go in the opposite order. And if they're > > > all supposed to be chronological, I think it is: > > > > > > Suggested-by: > > > Fixes: > > > Signed-off-by: > > > Reviewed-by: > > > > > > But unsure if that's a hard requirement, or even correct at all. > > > > Hi Marijn, > > > > I don't see any explicit documentation on the order of R-b tags. FWIW, I > > see in the git log that S-o-b always goes at the bottom of the commit > > message. > > > > I would prefer the S-o-b to always be at the bottom (as it helps me > > avoid duplicate S-o-b's when doing `git commit -s`), though I can flip > > the order of the R-b and suggested-by tags. > > I'd second Jessica here. Consider these tags as a history or a transcript: > > I would not vote on the particular order of the Suggested-by/Fixes > tags, I don't think that is important. These come first. Then the > patch goes through different cycles. of reviews, which gain > Reviewed-by tags. > > In the same way Link/Patchwork/whatever other tags are added in the > historical order. > > By having the submitter's S-o-b at the bottom, the submitter adds the > final signature under everything else being stated/recorded. Correct, so the s-o-b can always be kept / moved back to the bottom on a resend, stating that they sign off on "all that was written previously" including picking up reviews. However, for the rest of your reply about "history / transcript", you seem to agree exactly with my point of keeping (or rather, simply appending) these in chronological order? - Marijn > > Of course, in a more complicated story, there might be other > developers taking part (Co-Developed-By + Signed-off-by), etc. > > Note: all described is just my perception and might differ from the > BCP regarding the tags.
Re: [Freedreno] [PATCH v2 4/6] drm/msm/dpu: autodetect supported interrupts
On Tue, 23 May 2023 at 01:12, Marijn Suijten wrote: > > On 2023-05-23 00:45:25, Dmitry Baryshkov wrote: > > Declaring the mask of supported interrupts proved to be error-prone. It > > is very easy to add a bit with no corresponding backing block or to miss > > the INTF TE bit. Replace this with looping over the enabled INTF blocks > > to setup the irq mask. > > > > Signed-off-by: Dmitry Baryshkov > > Reviewed-by: Marijn Suijten > > > --- > > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 20 ++- > > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 6 ++ > > 2 files changed, 25 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > > index a03d826bb9ad..01f2660a2354 100644 > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > > @@ -463,6 +463,7 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, > > { > > struct dpu_hw_intr *intr; > > int nirq = MDP_INTR_MAX * 32; > > + unsigned int i; > > > > if (!addr || !m) > > return ERR_PTR(-EINVAL); > > @@ -480,7 +481,24 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem > > *addr, > > > > intr->total_irqs = nirq; > > > > - intr->irq_mask = m->mdss_irqs; > > + intr->irq_mask = BIT(MDP_SSPP_TOP0_INTR) | > > + BIT(MDP_SSPP_TOP0_INTR2) | > > + BIT(MDP_SSPP_TOP0_HIST_INTR); > > + for (i = 0; i < m->intf_count; i++) { > > + const struct dpu_intf_cfg *intf = >intf[i]; > > + > > + if (intf->type == INTF_NONE) > > + continue; > > + > > + intr->irq_mask |= BIT(MDP_INTFn_INTR(intf->id)); > > + > > + if (test_bit(DPU_INTF_TE, >features)) { > > + unsigned idx = MDP_INTFn_TEAR_INTR(intf->id); > > + > > + if (!WARN_ON(idx == -1)) > > We don't need to validate the catalog? But warning users about this > (and accidentally turning on all interrupt bits hiding the issue anyway) > is a nice side effect though, as you showed it was already going wrong > in patch 1/6. > > OTOH you might have inlined the macro and provided a more useful warning > message (DPU_INTF_TE can only be present on INTF1/2)... and then one > could assert on INTF_DSI etc etc etc... I'd prefer to keep it, as a safeguard for submission being in progress, newer generations gaining TE blocks on other interfaces, etc. I was selecting between having explicit intf->id == INTF_1 || == INTF_2 condition and this kind of macro. > > - Marijn > > > + intr->irq_mask |= BIT(idx); > > + } > > + } > > > > spin_lock_init(>irq_lock); > > > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h > > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h > > index f329d6d7f646..f0b92c9e3b09 100644 > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h > > @@ -17,6 +17,7 @@ enum dpu_hw_intr_reg { > > MDP_SSPP_TOP0_INTR, > > MDP_SSPP_TOP0_INTR2, > > MDP_SSPP_TOP0_HIST_INTR, > > + /* All MDP_INTFn_INTR should come sequentially */ > > MDP_INTF0_INTR, > > MDP_INTF1_INTR, > > MDP_INTF2_INTR, > > @@ -33,6 +34,11 @@ enum dpu_hw_intr_reg { > > MDP_INTR_MAX, > > }; > > > > +#define MDP_INTFn_INTR(intf) (MDP_INTF0_INTR + (intf - INTF_0)) > > +#define MDP_INTFn_TEAR_INTR(intf) (intf == INTF_1 ? MDP_INTF1_TEAR_INTR : \ > > +intf == INTF_2 ? MDP_INTF2_TEAR_INTR : \ > > +-1) > > + > > /* compatibility */ > > #define MDP_INTF0_7xxx_INTR MDP_INTF0_INTR > > #define MDP_INTF1_7xxx_INTR MDP_INTF1_INTR > > -- > > 2.39.2 > > -- With best wishes Dmitry
Re: [Freedreno] [PATCH v2 5/6] drm/msm/dpu: drop now-unused mdss_irqs field from hw catalog
On 2023-05-23 00:45:26, Dmitry Baryshkov wrote: > Now as the list of the interrupts is constructed from the catalog > data, drop the mdss_irqs field from catalog. > > Reviewed-by: Neil Armstrong > Signed-off-by: Dmitry Baryshkov > --- > .../drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h| 8 > .../gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h | 9 - > .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 11 --- > .../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h| 13 - > .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 10 -- > .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 6 -- > .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h | 5 - > .../drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h| 5 - > .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 9 - > .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 7 --- > .../drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 14 -- > .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 9 - > .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 9 - > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 3 --- > 14 files changed, 118 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h > index 3c732a0360c7..ff7c3d522046 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h > @@ -204,14 +204,6 @@ const struct dpu_mdss_cfg dpu_msm8998_cfg = { > .vbif_count = ARRAY_SIZE(msm8998_vbif), > .vbif = msm8998_vbif, > .perf = _perf_data, > - .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ > - BIT(MDP_SSPP_TOP0_INTR2) | \ > - BIT(MDP_SSPP_TOP0_HIST_INTR) | \ > - BIT(MDP_INTF0_INTR) | \ > - BIT(MDP_INTF1_INTR) | \ > - BIT(MDP_INTF2_INTR) | \ > - BIT(MDP_INTF3_INTR) | \ > - BIT(MDP_INTF4_INTR), > }; > > #endif > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h > index 36ea1af10894..c4ccd742690a 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h > @@ -202,15 +202,6 @@ const struct dpu_mdss_cfg dpu_sdm845_cfg = { > .vbif_count = ARRAY_SIZE(sdm845_vbif), > .vbif = sdm845_vbif, > .perf = _perf_data, > - .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ > - BIT(MDP_SSPP_TOP0_INTR2) | \ > - BIT(MDP_SSPP_TOP0_HIST_INTR) | \ > - BIT(MDP_INTF0_INTR) | \ > - BIT(MDP_INTF1_INTR) | \ > - BIT(MDP_INTF2_INTR) | \ > - BIT(MDP_INTF3_INTR) | \ > - BIT(MDP_AD4_0_INTR) | \ > - BIT(MDP_AD4_1_INTR), I don't think you're adding AD4 back anywhere? Not that there is any code handling AD4 (e.g. registering those interrupts) anywhere, but that should be done and documented in a separate patch then. After dropping that from this patch and describing it in a preliminary one: Reviewed-by: Marijn Suijten > }; > > #endif > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h > index b5f751354267..fb7069d470ff 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h > @@ -231,17 +231,6 @@ const struct dpu_mdss_cfg dpu_sm8150_cfg = { > .vbif_count = ARRAY_SIZE(sdm845_vbif), > .vbif = sdm845_vbif, > .perf = _perf_data, > - .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ > - BIT(MDP_SSPP_TOP0_INTR2) | \ > - BIT(MDP_SSPP_TOP0_HIST_INTR) | \ > - BIT(MDP_INTF0_INTR) | \ > - BIT(MDP_INTF1_INTR) | \ > - BIT(MDP_INTF1_TEAR_INTR) | \ > - BIT(MDP_INTF2_INTR) | \ > - BIT(MDP_INTF2_TEAR_INTR) | \ > - BIT(MDP_INTF3_INTR) | \ > - BIT(MDP_AD4_0_INTR) | \ > - BIT(MDP_AD4_1_INTR), > }; > > #endif > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h > index 8ed2b263c5ea..bd7422e597aa 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h > @@ -237,19 +237,6 @@ const struct dpu_mdss_cfg dpu_sc8180x_cfg = { > .vbif_count = ARRAY_SIZE(sdm845_vbif), > .vbif = sdm845_vbif, > .perf = _perf_data, > - .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ > - BIT(MDP_SSPP_TOP0_INTR2) | \ > - BIT(MDP_SSPP_TOP0_HIST_INTR) | \ > -
Re: [Freedreno] [PATCH v4 1/5] msm/drm/dsi: Round up DSC hdisplay calculation
On Tue, 23 May 2023 at 00:45, Jessica Zhang wrote: > > > > On 5/22/2023 1:44 PM, Marijn Suijten wrote: > > On 2023-05-22 13:30:20, Jessica Zhang wrote: > >> Currently, when compression is enabled, hdisplay is reduced via integer > >> division. This causes issues for modes where the original hdisplay is > >> not a multiple of 3. > >> > >> To fix this, use DIV_ROUND_UP to divide hdisplay. > >> > >> Reviewed-by: Marijn Suijten > >> Suggested-by: Marijn Suijten > > > > Nit: probably these should go in the opposite order. And if they're > > all supposed to be chronological, I think it is: > > > > Suggested-by: > > Fixes: > > Signed-off-by: > > Reviewed-by: > > > > But unsure if that's a hard requirement, or even correct at all. > > Hi Marijn, > > I don't see any explicit documentation on the order of R-b tags. FWIW, I > see in the git log that S-o-b always goes at the bottom of the commit > message. > > I would prefer the S-o-b to always be at the bottom (as it helps me > avoid duplicate S-o-b's when doing `git commit -s`), though I can flip > the order of the R-b and suggested-by tags. I'd second Jessica here. Consider these tags as a history or a transcript: I would not vote on the particular order of the Suggested-by/Fixes tags, I don't think that is important. These come first. Then the patch goes through different cycles. of reviews, which gain Reviewed-by tags. In the same way Link/Patchwork/whatever other tags are added in the historical order. By having the submitter's S-o-b at the bottom, the submitter adds the final signature under everything else being stated/recorded. Of course, in a more complicated story, there might be other developers taking part (Co-Developed-By + Signed-off-by), etc. Note: all described is just my perception and might differ from the BCP regarding the tags. > > Thanks, > > Jessica Zhang > > > > > - Marijn > > > >> Fixes: 08802f515c3cf ("drm/msm/dsi: Add support for DSC configuration") > >> Signed-off-by: Jessica Zhang > >> --- > >> drivers/gpu/drm/msm/dsi/dsi_host.c | 2 +- > >> 1 file changed, 1 insertion(+), 1 deletion(-) > >> > >> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c > >> b/drivers/gpu/drm/msm/dsi/dsi_host.c > >> index 9223d7ec5a73..18d38b90eb28 100644 > >> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c > >> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c > >> @@ -952,7 +952,7 @@ static void dsi_timing_setup(struct msm_dsi_host > >> *msm_host, bool is_bonded_dsi) > >> * pulse width same > >> */ > >> h_total -= hdisplay; > >> -hdisplay = msm_dsc_get_bytes_per_line(msm_host->dsc) / 3; > >> +hdisplay = > >> DIV_ROUND_UP(msm_dsc_get_bytes_per_line(msm_host->dsc), 3); > >> h_total += hdisplay; > >> ha_end = ha_start + hdisplay; > >> } > >> > >> -- > >> 2.40.1 > >> -- With best wishes Dmitry
Re: [Freedreno] [PATCH v2 4/6] drm/msm/dpu: autodetect supported interrupts
On 2023-05-23 00:45:25, Dmitry Baryshkov wrote: > Declaring the mask of supported interrupts proved to be error-prone. It > is very easy to add a bit with no corresponding backing block or to miss > the INTF TE bit. Replace this with looping over the enabled INTF blocks > to setup the irq mask. > > Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten > --- > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 20 ++- > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 6 ++ > 2 files changed, 25 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > index a03d826bb9ad..01f2660a2354 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > @@ -463,6 +463,7 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, > { > struct dpu_hw_intr *intr; > int nirq = MDP_INTR_MAX * 32; > + unsigned int i; > > if (!addr || !m) > return ERR_PTR(-EINVAL); > @@ -480,7 +481,24 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, > > intr->total_irqs = nirq; > > - intr->irq_mask = m->mdss_irqs; > + intr->irq_mask = BIT(MDP_SSPP_TOP0_INTR) | > + BIT(MDP_SSPP_TOP0_INTR2) | > + BIT(MDP_SSPP_TOP0_HIST_INTR); > + for (i = 0; i < m->intf_count; i++) { > + const struct dpu_intf_cfg *intf = >intf[i]; > + > + if (intf->type == INTF_NONE) > + continue; > + > + intr->irq_mask |= BIT(MDP_INTFn_INTR(intf->id)); > + > + if (test_bit(DPU_INTF_TE, >features)) { > + unsigned idx = MDP_INTFn_TEAR_INTR(intf->id); > + > + if (!WARN_ON(idx == -1)) We don't need to validate the catalog? But warning users about this (and accidentally turning on all interrupt bits hiding the issue anyway) is a nice side effect though, as you showed it was already going wrong in patch 1/6. OTOH you might have inlined the macro and provided a more useful warning message (DPU_INTF_TE can only be present on INTF1/2)... and then one could assert on INTF_DSI etc etc etc... - Marijn > + intr->irq_mask |= BIT(idx); > + } > + } > > spin_lock_init(>irq_lock); > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h > index f329d6d7f646..f0b92c9e3b09 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h > @@ -17,6 +17,7 @@ enum dpu_hw_intr_reg { > MDP_SSPP_TOP0_INTR, > MDP_SSPP_TOP0_INTR2, > MDP_SSPP_TOP0_HIST_INTR, > + /* All MDP_INTFn_INTR should come sequentially */ > MDP_INTF0_INTR, > MDP_INTF1_INTR, > MDP_INTF2_INTR, > @@ -33,6 +34,11 @@ enum dpu_hw_intr_reg { > MDP_INTR_MAX, > }; > > +#define MDP_INTFn_INTR(intf) (MDP_INTF0_INTR + (intf - INTF_0)) > +#define MDP_INTFn_TEAR_INTR(intf) (intf == INTF_1 ? MDP_INTF1_TEAR_INTR : \ > +intf == INTF_2 ? MDP_INTF2_TEAR_INTR : \ > +-1) > + > /* compatibility */ > #define MDP_INTF0_7xxx_INTR MDP_INTF0_INTR > #define MDP_INTF1_7xxx_INTR MDP_INTF1_INTR > -- > 2.39.2 >
Re: [Freedreno] [PATCH v4 1/5] msm/drm/dsi: Round up DSC hdisplay calculation
On 5/22/2023 2:45 PM, Jessica Zhang wrote: On 5/22/2023 1:44 PM, Marijn Suijten wrote: On 2023-05-22 13:30:20, Jessica Zhang wrote: Currently, when compression is enabled, hdisplay is reduced via integer division. This causes issues for modes where the original hdisplay is not a multiple of 3. To fix this, use DIV_ROUND_UP to divide hdisplay. Reviewed-by: Marijn Suijten Suggested-by: Marijn Suijten Nit: probably these should go in the opposite order. And if they're all supposed to be chronological, I think it is: Suggested-by: Fixes: Signed-off-by: Reviewed-by: But unsure if that's a hard requirement, or even correct at all. Hi Marijn, I don't see any explicit documentation on the order of R-b tags. FWIW, I see in the git log that S-o-b always goes at the bottom of the commit message. I would prefer the S-o-b to always be at the bottom (as it helps me avoid duplicate S-o-b's when doing `git commit -s`), though I can flip the order of the R-b and suggested-by tags. Correction -- I can reorder the tags so that it's: Suggested-by: Fixes: Reviewed-by: Signed-off-by: Thanks, Jessica Zhang Thanks, Jessica Zhang - Marijn Fixes: 08802f515c3cf ("drm/msm/dsi: Add support for DSC configuration") Signed-off-by: Jessica Zhang --- drivers/gpu/drm/msm/dsi/dsi_host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 9223d7ec5a73..18d38b90eb28 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -952,7 +952,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) * pulse width same */ h_total -= hdisplay; - hdisplay = msm_dsc_get_bytes_per_line(msm_host->dsc) / 3; + hdisplay = DIV_ROUND_UP(msm_dsc_get_bytes_per_line(msm_host->dsc), 3); h_total += hdisplay; ha_end = ha_start + hdisplay; } -- 2.40.1
Re: [Freedreno] [PATCH v2 3/6] drm/msm/dpu: split interrupt address arrays
... for 7xxx? On 2023-05-23 00:45:24, Dmitry Baryshkov wrote: > There is no point in having a single enum (and a single array) for both > DPU < 7.0 and DPU >= 7.0 interrupt registers. Instead define a single > enum and two IRQ address arrays. > > Signed-off-by: Dmitry Baryshkov Really like this idea to simplify some: Reviewed-by: Marijn Suijten > --- > .../msm/disp/dpu1/catalog/dpu_7_0_sm8350.h| 1 + > .../msm/disp/dpu1/catalog/dpu_7_2_sc7280.h| 1 + > .../msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 1 + > .../msm/disp/dpu1/catalog/dpu_8_1_sm8450.h| 1 + > .../msm/disp/dpu1/catalog/dpu_9_0_sm8550.h| 1 + > .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h| 2 + > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 82 +-- > .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 28 --- > 8 files changed, 79 insertions(+), 38 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h > index 3c1b2c13398d..320cfa4be633 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h > @@ -15,6 +15,7 @@ static const struct dpu_caps sm8350_dpu_caps = { > .has_dim_layer = true, > .has_idle_pc = true, > .has_3d_merge = true, > + .has_7xxx_intr = true, > .max_linewidth = 4096, > .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, > }; > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h > index 5d894cbb0a62..9306c7a115e9 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h > @@ -13,6 +13,7 @@ static const struct dpu_caps sc7280_dpu_caps = { > .qseed_type = DPU_SSPP_SCALER_QSEED4, > .has_dim_layer = true, > .has_idle_pc = true, > + .has_7xxx_intr = true, > .max_linewidth = 2400, > .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, > }; > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h > index c3f1ae000a21..fc1e17c495f0 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h > @@ -15,6 +15,7 @@ static const struct dpu_caps sc8280xp_dpu_caps = { > .has_dim_layer = true, > .has_idle_pc = true, > .has_3d_merge = true, > + .has_7xxx_intr = true, > .max_linewidth = 5120, > .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, > }; > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h > index 86c2e68ebd2c..eb72411c16db 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h > @@ -14,6 +14,7 @@ static const struct dpu_caps sm8450_dpu_caps = { > .has_src_split = true, > .has_dim_layer = true, > .has_idle_pc = true, > + .has_7xxx_intr = true, > .has_3d_merge = true, > .max_linewidth = 5120, > .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h > index 85dc34458b88..8209ca317bdc 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h > @@ -15,6 +15,7 @@ static const struct dpu_caps sm8550_dpu_caps = { > .has_dim_layer = true, > .has_idle_pc = true, > .has_3d_merge = true, > + .has_7xxx_intr = true, > .max_linewidth = 5120, > .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, > }; > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > index 677048cc3b7d..72530ebb0ae6 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > @@ -351,6 +351,7 @@ struct dpu_rotation_cfg { > * @has_dim_layer dim layer feature status > * @has_idle_pcindicate if idle power collapse feature is supported > * @has_3d_merge indicate if 3D merge is supported > + * @has_7xxx_intr indicate that INTF/IRQs use addressing for DPU 7.0 > and greater > * @max_linewidth max linewidth for sspp > * @pixel_ram_size size of latency hiding and de-tiling buffer in bytes > * @max_hdeci_exp max horizontal decimation supported (max is 2^value) > @@ -364,6 +365,7 @@ struct dpu_caps { > bool has_dim_layer; > bool has_idle_pc; > bool has_3d_merge; > + bool has_7xxx_intr; > /* SSPP limits */ > u32 max_linewidth; > u32 pixel_ram_size; > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > index
Re: [Freedreno] [PATCH v3] drm/msm/dp: enable HDP plugin/unplugged interrupts at hpd_enable/disable
On 23/05/2023 01:05, Bjorn Andersson wrote: On Mon, May 22, 2023 at 02:31:32PM -0700, Kuogee Hsieh wrote: The internal_hpd flag is set to true by dp_bridge_hpd_enable() and set to false by dp_bridge_hpd_disable() to handle GPIO pinmuxed into DP controller case. HDP related interrupts can not be enabled until internal_hpd is set to true. At current implementation dp_display_config_hpd() will initialize DP host controller first followed by enabling HDP related interrupts if internal_hpd was true at that time. Enable HDP related interrupts depends on internal_hpd status may leave system with DP driver host is in running state but without HDP related interrupts being enabled. This will prevent external display from being detected. Eliminated this dependency by moving HDP related interrupts enable/disable be done at dp_bridge_hpd_enable/disable() directly regardless of internal_hpd status. Thanks Kuogee, this looks quite good to me. But... Changes in V3: -- dp_catalog_ctrl_hpd_enable() and dp_catalog_ctrl_hpd_disable() -- rewording ocmmit text Fixes: cd198caddea7 ("drm/msm/dp: Rely on hpd_enable/disable callbacks") Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/dp/dp_catalog.c | 15 +++- drivers/gpu/drm/msm/dp/dp_catalog.h | 3 +- drivers/gpu/drm/msm/dp/dp_display.c | 70 +++-- 3 files changed, 37 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c index 7a8cf1c..5142aeb 100644 --- a/drivers/gpu/drm/msm/dp/dp_catalog.c +++ b/drivers/gpu/drm/msm/dp/dp_catalog.c @@ -620,7 +620,7 @@ void dp_catalog_hpd_config_intr(struct dp_catalog *dp_catalog, config & DP_DP_HPD_INT_MASK); } -void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog) +void dp_catalog_ctrl_hpd_enable(struct dp_catalog *dp_catalog) { struct dp_catalog_private *catalog = container_of(dp_catalog, struct dp_catalog_private, dp_catalog); @@ -635,6 +635,19 @@ void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog) dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, DP_DP_HPD_CTRL_HPD_EN); } +void dp_catalog_ctrl_hpd_disable(struct dp_catalog *dp_catalog) +{ + struct dp_catalog_private *catalog = container_of(dp_catalog, + struct dp_catalog_private, dp_catalog); + + u32 reftimer = dp_read_aux(catalog, REG_DP_DP_HPD_REFTIMER); + + reftimer &= ~DP_DP_HPD_REFTIMER_ENABLE; + dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer); + + dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, 0); +} + static void dp_catalog_enable_sdp(struct dp_catalog_private *catalog) { /* trigger sdp */ diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h b/drivers/gpu/drm/msm/dp/dp_catalog.h index 82376a2..38786e8 100644 --- a/drivers/gpu/drm/msm/dp/dp_catalog.h +++ b/drivers/gpu/drm/msm/dp/dp_catalog.h @@ -104,7 +104,8 @@ bool dp_catalog_ctrl_mainlink_ready(struct dp_catalog *dp_catalog); void dp_catalog_ctrl_enable_irq(struct dp_catalog *dp_catalog, bool enable); void dp_catalog_hpd_config_intr(struct dp_catalog *dp_catalog, u32 intr_mask, bool en); -void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog); +void dp_catalog_ctrl_hpd_enable(struct dp_catalog *dp_catalog); +void dp_catalog_ctrl_hpd_disable(struct dp_catalog *dp_catalog); void dp_catalog_ctrl_config_psr(struct dp_catalog *dp_catalog); void dp_catalog_ctrl_set_psr(struct dp_catalog *dp_catalog, bool enter); u32 dp_catalog_link_is_connected(struct dp_catalog *dp_catalog); diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 3e13acdf..69bbc5f 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -615,12 +615,6 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data) dp->hpd_state = ST_MAINLINK_READY; } - /* enable HDP irq_hpd/replug interrupt */ - if (dp->dp_display.internal_hpd) - dp_catalog_hpd_config_intr(dp->catalog, - DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, - true); - drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n", dp->dp_display.connector_type, state); mutex_unlock(>event_mutex); @@ -658,12 +652,6 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data) drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n", dp->dp_display.connector_type, state); - /* disable irq_hpd/replug interrupts */ - if (dp->dp_display.internal_hpd) - dp_catalog_hpd_config_intr(dp->catalog, - DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, - false); - /* unplugged,
Re: [Freedreno] [PATCH v4 3/5] drm/msm/dpu: Add DPU_INTF_DATA_COMPRESS feature flag
On 5/22/2023 1:47 PM, Marijn Suijten wrote: Can you fit DPU >= 7.0 in the title? Hi Marijn, Sure. On 2023-05-22 13:30:22, Jessica Zhang wrote: Add DATA_COMPRESS feature flag to DPU INTF block. Nit: repeating the title, perhaps you can reflow this with the second paragraph? Acked. Thanks, Jessica Zhang - Marijn In DPU 7.x and later, DSC/DCE enablement registers have been moved from PINGPONG to INTF. Reviewed-by: Marijn Suijten Signed-off-by: Jessica Zhang --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 3 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 7944481d0a33..8e12e07728df 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -104,7 +104,8 @@ #define INTF_SC7180_MASK \ (BIT(DPU_INTF_INPUT_CTRL) | BIT(DPU_INTF_TE) | BIT(DPU_INTF_STATUS_SUPPORTED)) -#define INTF_SC7280_MASK INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN) +#define INTF_SC7280_MASK \ + (INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN) | BIT(DPU_INTF_DATA_COMPRESS)) #define WB_SM8250_MASK (BIT(DPU_WB_LINE_MODE) | \ BIT(DPU_WB_UBWC) | \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 4eda2cc847ef..01c65f940f2a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -185,6 +185,7 @@ enum { * @DPU_DATA_HCTL_ENAllows data to be transferred at different rate * than video timing * @DPU_INTF_STATUS_SUPPORTED INTF block has INTF_STATUS register + * @DPU_INTF_DATA_COMPRESS INTF block has DATA_COMPRESS register * @DPU_INTF_MAX */ enum { @@ -192,6 +193,7 @@ enum { DPU_INTF_TE, DPU_DATA_HCTL_EN, DPU_INTF_STATUS_SUPPORTED, + DPU_INTF_DATA_COMPRESS, DPU_INTF_MAX }; -- 2.40.1
Re: [Freedreno] [PATCH v3] drm/msm/dp: enable HDP plugin/unplugged interrupts at hpd_enable/disable
On Mon, May 22, 2023 at 02:31:32PM -0700, Kuogee Hsieh wrote: > The internal_hpd flag is set to true by dp_bridge_hpd_enable() and set to > false by dp_bridge_hpd_disable() to handle GPIO pinmuxed into DP controller > case. HDP related interrupts can not be enabled until internal_hpd is set > to true. At current implementation dp_display_config_hpd() will initialize > DP host controller first followed by enabling HDP related interrupts if > internal_hpd was true at that time. Enable HDP related interrupts depends on > internal_hpd status may leave system with DP driver host is in running state > but without HDP related interrupts being enabled. This will prevent external > display from being detected. Eliminated this dependency by moving HDP related > interrupts enable/disable be done at dp_bridge_hpd_enable/disable() directly > regardless of internal_hpd status. > Thanks Kuogee, this looks quite good to me. But... > Changes in V3: > -- dp_catalog_ctrl_hpd_enable() and dp_catalog_ctrl_hpd_disable() > -- rewording ocmmit text > > Fixes: cd198caddea7 ("drm/msm/dp: Rely on hpd_enable/disable callbacks") > Signed-off-by: Kuogee Hsieh > --- > drivers/gpu/drm/msm/dp/dp_catalog.c | 15 +++- > drivers/gpu/drm/msm/dp/dp_catalog.h | 3 +- > drivers/gpu/drm/msm/dp/dp_display.c | 70 > +++-- > 3 files changed, 37 insertions(+), 51 deletions(-) > > diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c > b/drivers/gpu/drm/msm/dp/dp_catalog.c > index 7a8cf1c..5142aeb 100644 > --- a/drivers/gpu/drm/msm/dp/dp_catalog.c > +++ b/drivers/gpu/drm/msm/dp/dp_catalog.c > @@ -620,7 +620,7 @@ void dp_catalog_hpd_config_intr(struct dp_catalog > *dp_catalog, > config & DP_DP_HPD_INT_MASK); > } > > -void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog) > +void dp_catalog_ctrl_hpd_enable(struct dp_catalog *dp_catalog) > { > struct dp_catalog_private *catalog = container_of(dp_catalog, > struct dp_catalog_private, dp_catalog); > @@ -635,6 +635,19 @@ void dp_catalog_ctrl_hpd_config(struct dp_catalog > *dp_catalog) > dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, DP_DP_HPD_CTRL_HPD_EN); > } > > +void dp_catalog_ctrl_hpd_disable(struct dp_catalog *dp_catalog) > +{ > + struct dp_catalog_private *catalog = container_of(dp_catalog, > + struct dp_catalog_private, dp_catalog); > + > + u32 reftimer = dp_read_aux(catalog, REG_DP_DP_HPD_REFTIMER); > + > + reftimer &= ~DP_DP_HPD_REFTIMER_ENABLE; > + dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer); > + > + dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, 0); > +} > + > static void dp_catalog_enable_sdp(struct dp_catalog_private *catalog) > { > /* trigger sdp */ > diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h > b/drivers/gpu/drm/msm/dp/dp_catalog.h > index 82376a2..38786e8 100644 > --- a/drivers/gpu/drm/msm/dp/dp_catalog.h > +++ b/drivers/gpu/drm/msm/dp/dp_catalog.h > @@ -104,7 +104,8 @@ bool dp_catalog_ctrl_mainlink_ready(struct dp_catalog > *dp_catalog); > void dp_catalog_ctrl_enable_irq(struct dp_catalog *dp_catalog, bool enable); > void dp_catalog_hpd_config_intr(struct dp_catalog *dp_catalog, > u32 intr_mask, bool en); > -void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog); > +void dp_catalog_ctrl_hpd_enable(struct dp_catalog *dp_catalog); > +void dp_catalog_ctrl_hpd_disable(struct dp_catalog *dp_catalog); > void dp_catalog_ctrl_config_psr(struct dp_catalog *dp_catalog); > void dp_catalog_ctrl_set_psr(struct dp_catalog *dp_catalog, bool enter); > u32 dp_catalog_link_is_connected(struct dp_catalog *dp_catalog); > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c > b/drivers/gpu/drm/msm/dp/dp_display.c > index 3e13acdf..69bbc5f 100644 > --- a/drivers/gpu/drm/msm/dp/dp_display.c > +++ b/drivers/gpu/drm/msm/dp/dp_display.c > @@ -615,12 +615,6 @@ static int dp_hpd_plug_handle(struct dp_display_private > *dp, u32 data) > dp->hpd_state = ST_MAINLINK_READY; > } > > - /* enable HDP irq_hpd/replug interrupt */ > - if (dp->dp_display.internal_hpd) > - dp_catalog_hpd_config_intr(dp->catalog, > -DP_DP_IRQ_HPD_INT_MASK | > DP_DP_HPD_REPLUG_INT_MASK, > -true); > - > drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n", > dp->dp_display.connector_type, state); > mutex_unlock(>event_mutex); > @@ -658,12 +652,6 @@ static int dp_hpd_unplug_handle(struct > dp_display_private *dp, u32 data) > drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n", > dp->dp_display.connector_type, state); > > - /* disable irq_hpd/replug interrupts */ > - if (dp->dp_display.internal_hpd) > - dp_catalog_hpd_config_intr(dp->catalog, > -DP_DP_IRQ_HPD_INT_MASK | >
Re: [Freedreno] [PATCH v2 1/6] drm/msm/dpu: don't set DPU_INTF_TE globally
On 23/05/2023 00:56, Marijn Suijten wrote: Title suggestion: s/globally/on non-TE/DSI (INTF) blocks On 2023-05-23 00:45:22, Dmitry Baryshkov wrote: Using BIT(DPU_INTF_TE) in INTF_SC7180_MASK (and by extension in INTF_SC7280_MASK) results in this bit (and corrsponding operations) being enabled for all interfaces, even the ones which do not have TE block. Move this bit setting to INTF_DSI_TE(), so that it is only enabled for those INTF blocks which have TE support. Fixes: 152c1d430992 ("drm/msm/dpu: Add TEAR-READ-pointer interrupt to INTF block") Reviewed-by: Neil Armstrong Signed-off-by: Dmitry Baryshkov We've always been setting flags globally but I guess it makes sense to not only restrict this flag to DPU >= 5.0.0 but also just the few hardware blocks that actually have these in their *enlarged* register space (and have the interrupt). Reviewed-by: Marijn Suijten --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 1dee5ba2b312..162141cb5c83 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -101,7 +101,6 @@ #define INTF_SC7180_MASK \ (BIT(DPU_INTF_INPUT_CTRL) | \ -BIT(DPU_INTF_TE) | \ BIT(DPU_INTF_STATUS_SUPPORTED) | \ BIT(DPU_DATA_HCTL_EN)) @@ -544,7 +543,7 @@ static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = { {\ .name = _name, .id = _id, \ .base = _base, .len = _len, \ - .features = _features, \ + .features = _features | BIT(DPU_INTF_TE), \ Now that we're more broadly switching to this pattern, should we do the same for PP_BLK() with and without TE block? That way we can also forcefully initialize intr_rdptr=-1 similar to what I did for intr_tear_rd_ptr in INTF_BLK() (vs INTF_BLK_DSI_TE) here, instead of having the -1's floating around the catalog when I added them in commit 7952f5180eb3e ("drm/msm/dpu: Remove intr_rdptr from DPU >= 5.0.0 pingpong config"). If we are going to expand the macros, then hiding -1 probably doesn't make sense as it will reappear soon. Probably it makes sense to do another thing (which would play better with the expanded macros): increase IRQ indices by 1, making 'NO IRQ' equal to 0 instead of -1. This way all non-existing interrupts can be omitted during macros expansion. WDYT? - Marijn .type = _type, \ .controller_id = _ctrl_id, \ .prog_fetch_lines_worst_case = _progfetch, \ -- 2.39.2 -- With best wishes Dmitry
Re: [Freedreno] [PATCH v2 2/6] drm/msm/dpu: inline __intr_offset
On 2023-05-23 00:45:23, Dmitry Baryshkov wrote: > Inline __intr_offset(), there is no point in having a separate oneline > function for setting base block address. > > Reviewed-by: Neil Armstrong > Signed-off-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 8 +--- > 1 file changed, 1 insertion(+), 7 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > index 5e2d68ebb113..0776b0f6df4f 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c > @@ -435,12 +435,6 @@ u32 dpu_core_irq_read(struct dpu_kms *dpu_kms, int > irq_idx) > return intr_status; > } > > -static void __intr_offset(const struct dpu_mdss_cfg *m, > - void __iomem *addr, struct dpu_hw_blk_reg_map *hw) > -{ > - hw->blk_addr = addr + m->mdp[0].base; > -} > - > struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, > const struct dpu_mdss_cfg *m) > { > @@ -454,7 +448,7 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, > if (!intr) > return ERR_PTR(-ENOMEM); > > - __intr_offset(m, addr, >hw); > + intr->hw.blk_addr = addr + m->mdp[0].base; > > intr->total_irqs = nirq; > We could also drop the two newlines here and make these member assignments sit clearly/tightly together. - Marijn > -- > 2.39.2 >
Re: [Freedreno] [PATCH v2 1/6] drm/msm/dpu: don't set DPU_INTF_TE globally
Title suggestion: s/globally/on non-TE/DSI (INTF) blocks On 2023-05-23 00:45:22, Dmitry Baryshkov wrote: > Using BIT(DPU_INTF_TE) in INTF_SC7180_MASK (and by extension in > INTF_SC7280_MASK) results in this bit (and corrsponding operations) > being enabled for all interfaces, even the ones which do not have TE > block. Move this bit setting to INTF_DSI_TE(), so that it is only > enabled for those INTF blocks which have TE support. > > Fixes: 152c1d430992 ("drm/msm/dpu: Add TEAR-READ-pointer interrupt to INTF > block") > Reviewed-by: Neil Armstrong > Signed-off-by: Dmitry Baryshkov We've always been setting flags globally but I guess it makes sense to not only restrict this flag to DPU >= 5.0.0 but also just the few hardware blocks that actually have these in their *enlarged* register space (and have the interrupt). Reviewed-by: Marijn Suijten > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > index 1dee5ba2b312..162141cb5c83 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > @@ -101,7 +101,6 @@ > > #define INTF_SC7180_MASK \ > (BIT(DPU_INTF_INPUT_CTRL) | \ > - BIT(DPU_INTF_TE) | \ >BIT(DPU_INTF_STATUS_SUPPORTED) | \ >BIT(DPU_DATA_HCTL_EN)) > > @@ -544,7 +543,7 @@ static const struct dpu_pingpong_sub_blks sc7280_pp_sblk > = { > {\ > .name = _name, .id = _id, \ > .base = _base, .len = _len, \ > - .features = _features, \ > + .features = _features | BIT(DPU_INTF_TE), \ Now that we're more broadly switching to this pattern, should we do the same for PP_BLK() with and without TE block? That way we can also forcefully initialize intr_rdptr=-1 similar to what I did for intr_tear_rd_ptr in INTF_BLK() (vs INTF_BLK_DSI_TE) here, instead of having the -1's floating around the catalog when I added them in commit 7952f5180eb3e ("drm/msm/dpu: Remove intr_rdptr from DPU >= 5.0.0 pingpong config"). - Marijn > .type = _type, \ > .controller_id = _ctrl_id, \ > .prog_fetch_lines_worst_case = _progfetch, \ > -- > 2.39.2 >
Re: [Freedreno] [RFC] drm/msm/dp: Allow attaching a drm_panel
On Mon, May 22, 2023 at 03:51:01PM -0500, Bjorn Andersson wrote: > On Fri, Oct 08, 2021 at 03:38:21PM +0300, Heikki Krogerus wrote: > > Hi, > > > > On Thu, Oct 07, 2021 at 09:15:12AM -0700, Bjorn Andersson wrote: > > > The one thing that I still don't understand though is, if the typec_mux > > > is used by the typec controller to inform _the_ mux about the function > > > to be used, what's up with the complexity in typec_mux_match()? This is > > > what lead me to believe that typec_mux was enabling/disabling individual > > > altmodes, rather just flipping the physical switch at the bottom. > > > > Ah, typec_mux_match() is a mess. I'm sorry about that. I think most of > > the code in that function is not used by anybody. If I remember > > correctly, all that complexity is attempting to solve some > > hypothetical corner case(s). Probable a case where we have multiple > > muxes per port to deal with. > > > > I think it would probable be best to clean the function to the bare > > minimum by keeping only the parts that are actually used today > > (attached). > > > > Sorry for not replying to this in a timely manner Heikki. I've been > ignoring this issue for a long time now, just adding "svid" to our dts > files. But, this obviously shows up in DT validation - and I'd prefer > not defining these properties as valid. > > The attached patch works as expected. > Sorry, I must have failed at applying the patch - it doesn't work... > Could you please spin this as a proper patch, so we can get it merged? > > Regards, > Bjorn > > > thanks, > > > > -- > > heikki > > > diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c > > index c8340de0ed495..44f168c9bd9bf 100644 > > --- a/drivers/usb/typec/mux.c > > +++ b/drivers/usb/typec/mux.c > > @@ -193,56 +193,15 @@ static int mux_fwnode_match(struct device *dev, const > > void *fwnode) > > static void *typec_mux_match(struct fwnode_handle *fwnode, const char *id, > > void *data) > > { > > - const struct typec_altmode_desc *desc = data; > > struct device *dev; > > - bool match; > > - int nval; > > - u16 *val; > > - int ret; > > - int i; > > > > /* > > -* Check has the identifier already been "consumed". If it > > -* has, no need to do any extra connection identification. > > +* The connection identifier will be needed with device graph (OF > > graph). > > +* Device graph is not supported by this code yet, so bailing out. > > */ > > - match = !id; > > - if (match) > > - goto find_mux; > > - > > - /* Accessory Mode muxes */ > > - if (!desc) { > > - match = fwnode_property_present(fwnode, "accessory"); > > - if (match) > > - goto find_mux; > > - return NULL; > > - } > > - > > - /* Alternate Mode muxes */ > > - nval = fwnode_property_count_u16(fwnode, "svid"); > > - if (nval <= 0) > > - return NULL; > > - > > - val = kcalloc(nval, sizeof(*val), GFP_KERNEL); > > - if (!val) > > - return ERR_PTR(-ENOMEM); > > - > > - ret = fwnode_property_read_u16_array(fwnode, "svid", val, nval); > > - if (ret < 0) { > > - kfree(val); > > - return ERR_PTR(ret); > > - } > > - > > - for (i = 0; i < nval; i++) { > > - match = val[i] == desc->svid; > > - if (match) { > > - kfree(val); > > - goto find_mux; > > - } > > - } > > - kfree(val); > > - return NULL; > > + if (id) We pass id as "mode-switch", so this will never be NULL. But we also only want to consider endpoints with "mode-switch", otherwise we'll fail if any of the referred endpoints is not implementing a typec_mux... So this needs the same snippet we find in typec_switch_match(): /* * Device graph (OF graph) does not give any means to identify the * device type or the device class of the remote port parent that @fwnode * represents, so in order to identify the type or the class of @fwnode * an additional device property is needed. With typec switches the * property is named "orientation-switch" (@id). The value of the device * property is ignored. */ if (id && !fwnode_property_present(fwnode, id)) return NULL; With that, this works as expected! Regards, Bjorn > > + return ERR_PTR(-ENOTSUPP); > > > > -find_mux: > > dev = class_find_device(_mux_class, NULL, fwnode, > > mux_fwnode_match); > > >
[Freedreno] [PATCH v2 3/6] drm/msm/dpu: split interrupt address arrays
There is no point in having a single enum (and a single array) for both DPU < 7.0 and DPU >= 7.0 interrupt registers. Instead define a single enum and two IRQ address arrays. Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_7_0_sm8350.h| 1 + .../msm/disp/dpu1/catalog/dpu_7_2_sc7280.h| 1 + .../msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 1 + .../msm/disp/dpu1/catalog/dpu_8_1_sm8450.h| 1 + .../msm/disp/dpu1/catalog/dpu_9_0_sm8550.h| 1 + .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h| 2 + .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 82 +-- .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 28 --- 8 files changed, 79 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h index 3c1b2c13398d..320cfa4be633 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h @@ -15,6 +15,7 @@ static const struct dpu_caps sm8350_dpu_caps = { .has_dim_layer = true, .has_idle_pc = true, .has_3d_merge = true, + .has_7xxx_intr = true, .max_linewidth = 4096, .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h index 5d894cbb0a62..9306c7a115e9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h @@ -13,6 +13,7 @@ static const struct dpu_caps sc7280_dpu_caps = { .qseed_type = DPU_SSPP_SCALER_QSEED4, .has_dim_layer = true, .has_idle_pc = true, + .has_7xxx_intr = true, .max_linewidth = 2400, .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h index c3f1ae000a21..fc1e17c495f0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h @@ -15,6 +15,7 @@ static const struct dpu_caps sc8280xp_dpu_caps = { .has_dim_layer = true, .has_idle_pc = true, .has_3d_merge = true, + .has_7xxx_intr = true, .max_linewidth = 5120, .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h index 86c2e68ebd2c..eb72411c16db 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h @@ -14,6 +14,7 @@ static const struct dpu_caps sm8450_dpu_caps = { .has_src_split = true, .has_dim_layer = true, .has_idle_pc = true, + .has_7xxx_intr = true, .has_3d_merge = true, .max_linewidth = 5120, .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h index 85dc34458b88..8209ca317bdc 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h @@ -15,6 +15,7 @@ static const struct dpu_caps sm8550_dpu_caps = { .has_dim_layer = true, .has_idle_pc = true, .has_3d_merge = true, + .has_7xxx_intr = true, .max_linewidth = 5120, .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 677048cc3b7d..72530ebb0ae6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -351,6 +351,7 @@ struct dpu_rotation_cfg { * @has_dim_layer dim layer feature status * @has_idle_pcindicate if idle power collapse feature is supported * @has_3d_merge indicate if 3D merge is supported + * @has_7xxx_intr indicate that INTF/IRQs use addressing for DPU 7.0 and greater * @max_linewidth max linewidth for sspp * @pixel_ram_size size of latency hiding and de-tiling buffer in bytes * @max_hdeci_exp max horizontal decimation supported (max is 2^value) @@ -364,6 +365,7 @@ struct dpu_caps { bool has_dim_layer; bool has_idle_pc; bool has_3d_merge; + bool has_7xxx_intr; /* SSPP limits */ u32 max_linewidth; u32 pixel_ram_size; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c index 0776b0f6df4f..a03d826bb9ad 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c @@ -51,11 +51,9 @@ struct dpu_intr_reg { }; /* - * struct dpu_intr_reg - List of DPU interrupt registers - * - * When making changes be sure
[Freedreno] [PATCH v2 5/6] drm/msm/dpu: drop now-unused mdss_irqs field from hw catalog
Now as the list of the interrupts is constructed from the catalog data, drop the mdss_irqs field from catalog. Reviewed-by: Neil Armstrong Signed-off-by: Dmitry Baryshkov --- .../drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h| 8 .../gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h | 9 - .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 11 --- .../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h| 13 - .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 10 -- .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 6 -- .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h | 5 - .../drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h| 5 - .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 9 - .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 7 --- .../drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 14 -- .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 9 - .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 9 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 3 --- 14 files changed, 118 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h index 3c732a0360c7..ff7c3d522046 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h @@ -204,14 +204,6 @@ const struct dpu_mdss_cfg dpu_msm8998_cfg = { .vbif_count = ARRAY_SIZE(msm8998_vbif), .vbif = msm8998_vbif, .perf = _perf_data, - .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ -BIT(MDP_SSPP_TOP0_INTR2) | \ -BIT(MDP_SSPP_TOP0_HIST_INTR) | \ -BIT(MDP_INTF0_INTR) | \ -BIT(MDP_INTF1_INTR) | \ -BIT(MDP_INTF2_INTR) | \ -BIT(MDP_INTF3_INTR) | \ -BIT(MDP_INTF4_INTR), }; #endif diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h index 36ea1af10894..c4ccd742690a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h @@ -202,15 +202,6 @@ const struct dpu_mdss_cfg dpu_sdm845_cfg = { .vbif_count = ARRAY_SIZE(sdm845_vbif), .vbif = sdm845_vbif, .perf = _perf_data, - .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ -BIT(MDP_SSPP_TOP0_INTR2) | \ -BIT(MDP_SSPP_TOP0_HIST_INTR) | \ -BIT(MDP_INTF0_INTR) | \ -BIT(MDP_INTF1_INTR) | \ -BIT(MDP_INTF2_INTR) | \ -BIT(MDP_INTF3_INTR) | \ -BIT(MDP_AD4_0_INTR) | \ -BIT(MDP_AD4_1_INTR), }; #endif diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h index b5f751354267..fb7069d470ff 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h @@ -231,17 +231,6 @@ const struct dpu_mdss_cfg dpu_sm8150_cfg = { .vbif_count = ARRAY_SIZE(sdm845_vbif), .vbif = sdm845_vbif, .perf = _perf_data, - .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ -BIT(MDP_SSPP_TOP0_INTR2) | \ -BIT(MDP_SSPP_TOP0_HIST_INTR) | \ -BIT(MDP_INTF0_INTR) | \ -BIT(MDP_INTF1_INTR) | \ -BIT(MDP_INTF1_TEAR_INTR) | \ -BIT(MDP_INTF2_INTR) | \ -BIT(MDP_INTF2_TEAR_INTR) | \ -BIT(MDP_INTF3_INTR) | \ -BIT(MDP_AD4_0_INTR) | \ -BIT(MDP_AD4_1_INTR), }; #endif diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h index 8ed2b263c5ea..bd7422e597aa 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h @@ -237,19 +237,6 @@ const struct dpu_mdss_cfg dpu_sc8180x_cfg = { .vbif_count = ARRAY_SIZE(sdm845_vbif), .vbif = sdm845_vbif, .perf = _perf_data, - .mdss_irqs = BIT(MDP_SSPP_TOP0_INTR) | \ -BIT(MDP_SSPP_TOP0_INTR2) | \ -BIT(MDP_SSPP_TOP0_HIST_INTR) | \ -BIT(MDP_INTF0_INTR) | \ -BIT(MDP_INTF1_INTR) | \ -BIT(MDP_INTF1_TEAR_INTR) | \ -BIT(MDP_INTF2_INTR) | \ -BIT(MDP_INTF2_TEAR_INTR) | \ -BIT(MDP_INTF3_INTR) | \ -BIT(MDP_INTF4_INTR) | \ -BIT(MDP_INTF5_INTR) | \ -BIT(MDP_AD4_0_INTR) | \ -BIT(MDP_AD4_1_INTR), }; #endif diff --git
[Freedreno] [PATCH v2 6/6] drm/msm/dpu: drop compatibility INTR defines
While reworking interrupts masks, it was easier to keep old MDP_INTFn_7xxx_INTR and MDP_INTFn_7xxx_TEAR_INTR symbols. Now it is time to drop them and use unified symbol names. Reviewed-by: Neil Armstrong Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 4 ++-- .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 2 +- .../drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h| 4 ++-- .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 4 ++-- .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 4 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 13 - 6 files changed, 9 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h index 649784aa6567..df88e3f2a548 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h @@ -161,11 +161,11 @@ static const struct dpu_intf_cfg sm8350_intf[] = { INTF_BLK_DSI_TE("intf_1", INTF_1, 0x35000, 0x2c4, INTF_DSI, 0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), - DPU_IRQ_IDX(MDP_INTF1_7xxx_TEAR_INTR, 2)), + DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2)), INTF_BLK_DSI_TE("intf_2", INTF_2, 0x36000, 0x2c4, INTF_DSI, 1, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29), - DPU_IRQ_IDX(MDP_INTF2_7xxx_TEAR_INTR, 2)), + DPU_IRQ_IDX(MDP_INTF2_TEAR_INTR, 2)), INTF_BLK("intf_3", INTF_3, 0x37000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31)), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h index 1e87c7f4775d..4d9936d41464 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h @@ -107,7 +107,7 @@ static const struct dpu_intf_cfg sc7280_intf[] = { INTF_BLK_DSI_TE("intf_1", INTF_1, 0x35000, 0x2c4, INTF_DSI, 0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), - DPU_IRQ_IDX(MDP_INTF1_7xxx_TEAR_INTR, 2)), + DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2)), INTF_BLK("intf_5", INTF_5, 0x39000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 22), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 23)), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h index 3082657f06f2..65fa65b954db 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h @@ -151,11 +151,11 @@ static const struct dpu_intf_cfg sc8280xp_intf[] = { INTF_BLK_DSI_TE("intf_1", INTF_1, 0x35000, 0x300, INTF_DSI, 0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), - DPU_IRQ_IDX(MDP_INTF1_7xxx_TEAR_INTR, 2)), + DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2)), INTF_BLK_DSI_TE("intf_2", INTF_2, 0x36000, 0x300, INTF_DSI, 1, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29), - DPU_IRQ_IDX(MDP_INTF2_7xxx_TEAR_INTR, 2)), + DPU_IRQ_IDX(MDP_INTF2_TEAR_INTR, 2)), INTF_BLK("intf_3", INTF_3, 0x37000, 0x280, INTF_NONE, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31)), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h index ca5b82bc8322..b8158ed94845 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h @@ -169,11 +169,11 @@ static const struct dpu_intf_cfg sm8450_intf[] = { INTF_BLK_DSI_TE("intf_1", INTF_1, 0x35000, 0x300, INTF_DSI, 0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), - DPU_IRQ_IDX(MDP_INTF1_7xxx_TEAR_INTR, 2)), + DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2)), INTF_BLK_DSI_TE("intf_2", INTF_2, 0x36000, 0x300, INTF_DSI, 1, 24, INTF_SC7280_MASK,
[Freedreno] [PATCH v2 1/6] drm/msm/dpu: don't set DPU_INTF_TE globally
Using BIT(DPU_INTF_TE) in INTF_SC7180_MASK (and by extension in INTF_SC7280_MASK) results in this bit (and corrsponding operations) being enabled for all interfaces, even the ones which do not have TE block. Move this bit setting to INTF_DSI_TE(), so that it is only enabled for those INTF blocks which have TE support. Fixes: 152c1d430992 ("drm/msm/dpu: Add TEAR-READ-pointer interrupt to INTF block") Reviewed-by: Neil Armstrong Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 1dee5ba2b312..162141cb5c83 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -101,7 +101,6 @@ #define INTF_SC7180_MASK \ (BIT(DPU_INTF_INPUT_CTRL) | \ -BIT(DPU_INTF_TE) | \ BIT(DPU_INTF_STATUS_SUPPORTED) | \ BIT(DPU_DATA_HCTL_EN)) @@ -544,7 +543,7 @@ static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = { {\ .name = _name, .id = _id, \ .base = _base, .len = _len, \ - .features = _features, \ + .features = _features | BIT(DPU_INTF_TE), \ .type = _type, \ .controller_id = _ctrl_id, \ .prog_fetch_lines_worst_case = _progfetch, \ -- 2.39.2
[Freedreno] [PATCH v2 2/6] drm/msm/dpu: inline __intr_offset
Inline __intr_offset(), there is no point in having a separate oneline function for setting base block address. Reviewed-by: Neil Armstrong Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 8 +--- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c index 5e2d68ebb113..0776b0f6df4f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c @@ -435,12 +435,6 @@ u32 dpu_core_irq_read(struct dpu_kms *dpu_kms, int irq_idx) return intr_status; } -static void __intr_offset(const struct dpu_mdss_cfg *m, - void __iomem *addr, struct dpu_hw_blk_reg_map *hw) -{ - hw->blk_addr = addr + m->mdp[0].base; -} - struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, const struct dpu_mdss_cfg *m) { @@ -454,7 +448,7 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, if (!intr) return ERR_PTR(-ENOMEM); - __intr_offset(m, addr, >hw); + intr->hw.blk_addr = addr + m->mdp[0].base; intr->total_irqs = nirq; -- 2.39.2
[Freedreno] [PATCH v2 4/6] drm/msm/dpu: autodetect supported interrupts
Declaring the mask of supported interrupts proved to be error-prone. It is very easy to add a bit with no corresponding backing block or to miss the INTF TE bit. Replace this with looping over the enabled INTF blocks to setup the irq mask. Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 20 ++- .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 6 ++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c index a03d826bb9ad..01f2660a2354 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c @@ -463,6 +463,7 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, { struct dpu_hw_intr *intr; int nirq = MDP_INTR_MAX * 32; + unsigned int i; if (!addr || !m) return ERR_PTR(-EINVAL); @@ -480,7 +481,24 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, intr->total_irqs = nirq; - intr->irq_mask = m->mdss_irqs; + intr->irq_mask = BIT(MDP_SSPP_TOP0_INTR) | +BIT(MDP_SSPP_TOP0_INTR2) | +BIT(MDP_SSPP_TOP0_HIST_INTR); + for (i = 0; i < m->intf_count; i++) { + const struct dpu_intf_cfg *intf = >intf[i]; + + if (intf->type == INTF_NONE) + continue; + + intr->irq_mask |= BIT(MDP_INTFn_INTR(intf->id)); + + if (test_bit(DPU_INTF_TE, >features)) { + unsigned idx = MDP_INTFn_TEAR_INTR(intf->id); + + if (!WARN_ON(idx == -1)) + intr->irq_mask |= BIT(idx); + } + } spin_lock_init(>irq_lock); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h index f329d6d7f646..f0b92c9e3b09 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h @@ -17,6 +17,7 @@ enum dpu_hw_intr_reg { MDP_SSPP_TOP0_INTR, MDP_SSPP_TOP0_INTR2, MDP_SSPP_TOP0_HIST_INTR, + /* All MDP_INTFn_INTR should come sequentially */ MDP_INTF0_INTR, MDP_INTF1_INTR, MDP_INTF2_INTR, @@ -33,6 +34,11 @@ enum dpu_hw_intr_reg { MDP_INTR_MAX, }; +#define MDP_INTFn_INTR(intf) (MDP_INTF0_INTR + (intf - INTF_0)) +#define MDP_INTFn_TEAR_INTR(intf) (intf == INTF_1 ? MDP_INTF1_TEAR_INTR : \ + intf == INTF_2 ? MDP_INTF2_TEAR_INTR : \ + -1) + /* compatibility */ #define MDP_INTF0_7xxx_INTR MDP_INTF0_INTR #define MDP_INTF1_7xxx_INTR MDP_INTF1_INTR -- 2.39.2
[Freedreno] [PATCH v2 0/6] drm/msm/dpu: rework interrupt handling
Declaring the mask of supported interrupts proved to be error-prone. It is very easy to add a bit with no corresponding backing block or to miss the INTF TE bit. Replace this static configuration with the irq mask calculated from the HW catalog data. Changes since v1: - Enable dpu_caps::has_7xxx_intr for DPU >= 7.0 (Neil) Dmitry Baryshkov (6): drm/msm/dpu: don't set DPU_INTF_TE globally drm/msm/dpu: inline __intr_offset drm/msm/dpu: split interrupt address arrays drm/msm/dpu: autodetect supported interrupts drm/msm/dpu: drop now-unused mdss_irqs field from hw catalog drm/msm/dpu: drop compatibility INTR defines .../msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 8 -- .../msm/disp/dpu1/catalog/dpu_4_0_sdm845.h| 9 -- .../msm/disp/dpu1/catalog/dpu_5_0_sm8150.h| 11 -- .../msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 13 --- .../msm/disp/dpu1/catalog/dpu_6_0_sm8250.h| 10 -- .../msm/disp/dpu1/catalog/dpu_6_2_sc7180.h| 6 - .../msm/disp/dpu1/catalog/dpu_6_3_sm6115.h| 5 - .../msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 5 - .../msm/disp/dpu1/catalog/dpu_7_0_sm8350.h| 14 +-- .../msm/disp/dpu1/catalog/dpu_7_2_sc7280.h| 10 +- .../msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 19 +-- .../msm/disp/dpu1/catalog/dpu_8_1_sm8450.h| 14 +-- .../msm/disp/dpu1/catalog/dpu_9_0_sm8550.h| 14 +-- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 3 +- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h| 5 +- .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 110 -- .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 21 ++-- 17 files changed, 102 insertions(+), 175 deletions(-) -- 2.39.2
Re: [Freedreno] [PATCH v4 1/5] msm/drm/dsi: Round up DSC hdisplay calculation
On 5/22/2023 1:44 PM, Marijn Suijten wrote: On 2023-05-22 13:30:20, Jessica Zhang wrote: Currently, when compression is enabled, hdisplay is reduced via integer division. This causes issues for modes where the original hdisplay is not a multiple of 3. To fix this, use DIV_ROUND_UP to divide hdisplay. Reviewed-by: Marijn Suijten Suggested-by: Marijn Suijten Nit: probably these should go in the opposite order. And if they're all supposed to be chronological, I think it is: Suggested-by: Fixes: Signed-off-by: Reviewed-by: But unsure if that's a hard requirement, or even correct at all. Hi Marijn, I don't see any explicit documentation on the order of R-b tags. FWIW, I see in the git log that S-o-b always goes at the bottom of the commit message. I would prefer the S-o-b to always be at the bottom (as it helps me avoid duplicate S-o-b's when doing `git commit -s`), though I can flip the order of the R-b and suggested-by tags. Thanks, Jessica Zhang - Marijn Fixes: 08802f515c3cf ("drm/msm/dsi: Add support for DSC configuration") Signed-off-by: Jessica Zhang --- drivers/gpu/drm/msm/dsi/dsi_host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 9223d7ec5a73..18d38b90eb28 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -952,7 +952,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) * pulse width same */ h_total -= hdisplay; - hdisplay = msm_dsc_get_bytes_per_line(msm_host->dsc) / 3; + hdisplay = DIV_ROUND_UP(msm_dsc_get_bytes_per_line(msm_host->dsc), 3); h_total += hdisplay; ha_end = ha_start + hdisplay; } -- 2.40.1
Re: [Freedreno] [PATCH v3] drm/msm/dp: enable HDP plugin/unplugged interrupts at hpd_enable/disable
On Tue, 23 May 2023 at 00:31, Kuogee Hsieh wrote: > > The internal_hpd flag is set to true by dp_bridge_hpd_enable() and set to > false by dp_bridge_hpd_disable() to handle GPIO pinmuxed into DP controller > case. HDP related interrupts can not be enabled until internal_hpd is set > to true. At current implementation dp_display_config_hpd() will initialize > DP host controller first followed by enabling HDP related interrupts if > internal_hpd was true at that time. Enable HDP related interrupts depends on > internal_hpd status may leave system with DP driver host is in running state > but without HDP related interrupts being enabled. This will prevent external > display from being detected. Eliminated this dependency by moving HDP related > interrupts enable/disable be done at dp_bridge_hpd_enable/disable() directly > regardless of internal_hpd status. > > Changes in V3: > -- dp_catalog_ctrl_hpd_enable() and dp_catalog_ctrl_hpd_disable() > -- rewording ocmmit text > > Fixes: cd198caddea7 ("drm/msm/dp: Rely on hpd_enable/disable callbacks") > Signed-off-by: Kuogee Hsieh > --- > drivers/gpu/drm/msm/dp/dp_catalog.c | 15 +++- > drivers/gpu/drm/msm/dp/dp_catalog.h | 3 +- > drivers/gpu/drm/msm/dp/dp_display.c | 70 > +++-- > 3 files changed, 37 insertions(+), 51 deletions(-) > > diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c > b/drivers/gpu/drm/msm/dp/dp_catalog.c > index 7a8cf1c..5142aeb 100644 > --- a/drivers/gpu/drm/msm/dp/dp_catalog.c > +++ b/drivers/gpu/drm/msm/dp/dp_catalog.c > @@ -620,7 +620,7 @@ void dp_catalog_hpd_config_intr(struct dp_catalog > *dp_catalog, > config & DP_DP_HPD_INT_MASK); > } > > -void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog) > +void dp_catalog_ctrl_hpd_enable(struct dp_catalog *dp_catalog) > { > struct dp_catalog_private *catalog = container_of(dp_catalog, > struct dp_catalog_private, dp_catalog); > @@ -635,6 +635,19 @@ void dp_catalog_ctrl_hpd_config(struct dp_catalog > *dp_catalog) > dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, DP_DP_HPD_CTRL_HPD_EN); > } > > +void dp_catalog_ctrl_hpd_disable(struct dp_catalog *dp_catalog) > +{ > + struct dp_catalog_private *catalog = container_of(dp_catalog, > + struct dp_catalog_private, dp_catalog); > + > + u32 reftimer = dp_read_aux(catalog, REG_DP_DP_HPD_REFTIMER); > + > + reftimer &= ~DP_DP_HPD_REFTIMER_ENABLE; > + dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer); > + > + dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, 0); > +} > + > static void dp_catalog_enable_sdp(struct dp_catalog_private *catalog) > { > /* trigger sdp */ > diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h > b/drivers/gpu/drm/msm/dp/dp_catalog.h > index 82376a2..38786e8 100644 > --- a/drivers/gpu/drm/msm/dp/dp_catalog.h > +++ b/drivers/gpu/drm/msm/dp/dp_catalog.h > @@ -104,7 +104,8 @@ bool dp_catalog_ctrl_mainlink_ready(struct dp_catalog > *dp_catalog); > void dp_catalog_ctrl_enable_irq(struct dp_catalog *dp_catalog, bool enable); > void dp_catalog_hpd_config_intr(struct dp_catalog *dp_catalog, > u32 intr_mask, bool en); > -void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog); > +void dp_catalog_ctrl_hpd_enable(struct dp_catalog *dp_catalog); > +void dp_catalog_ctrl_hpd_disable(struct dp_catalog *dp_catalog); > void dp_catalog_ctrl_config_psr(struct dp_catalog *dp_catalog); > void dp_catalog_ctrl_set_psr(struct dp_catalog *dp_catalog, bool enter); > u32 dp_catalog_link_is_connected(struct dp_catalog *dp_catalog); > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c > b/drivers/gpu/drm/msm/dp/dp_display.c > index 3e13acdf..69bbc5f 100644 > --- a/drivers/gpu/drm/msm/dp/dp_display.c > +++ b/drivers/gpu/drm/msm/dp/dp_display.c > @@ -615,12 +615,6 @@ static int dp_hpd_plug_handle(struct dp_display_private > *dp, u32 data) > dp->hpd_state = ST_MAINLINK_READY; > } > > - /* enable HDP irq_hpd/replug interrupt */ > - if (dp->dp_display.internal_hpd) > - dp_catalog_hpd_config_intr(dp->catalog, > - DP_DP_IRQ_HPD_INT_MASK | > DP_DP_HPD_REPLUG_INT_MASK, > - true); > - > drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n", > dp->dp_display.connector_type, state); > mutex_unlock(>event_mutex); > @@ -658,12 +652,6 @@ static int dp_hpd_unplug_handle(struct > dp_display_private *dp, u32 data) > drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n", > dp->dp_display.connector_type, state); > > - /* disable irq_hpd/replug interrupts */ > - if (dp->dp_display.internal_hpd) > - dp_catalog_hpd_config_intr(dp->catalog, > - DP_DP_IRQ_HPD_INT_MASK | >
[Freedreno] [PATCH v3] drm/msm/dp: enable HDP plugin/unplugged interrupts at hpd_enable/disable
The internal_hpd flag is set to true by dp_bridge_hpd_enable() and set to false by dp_bridge_hpd_disable() to handle GPIO pinmuxed into DP controller case. HDP related interrupts can not be enabled until internal_hpd is set to true. At current implementation dp_display_config_hpd() will initialize DP host controller first followed by enabling HDP related interrupts if internal_hpd was true at that time. Enable HDP related interrupts depends on internal_hpd status may leave system with DP driver host is in running state but without HDP related interrupts being enabled. This will prevent external display from being detected. Eliminated this dependency by moving HDP related interrupts enable/disable be done at dp_bridge_hpd_enable/disable() directly regardless of internal_hpd status. Changes in V3: -- dp_catalog_ctrl_hpd_enable() and dp_catalog_ctrl_hpd_disable() -- rewording ocmmit text Fixes: cd198caddea7 ("drm/msm/dp: Rely on hpd_enable/disable callbacks") Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/dp/dp_catalog.c | 15 +++- drivers/gpu/drm/msm/dp/dp_catalog.h | 3 +- drivers/gpu/drm/msm/dp/dp_display.c | 70 +++-- 3 files changed, 37 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c index 7a8cf1c..5142aeb 100644 --- a/drivers/gpu/drm/msm/dp/dp_catalog.c +++ b/drivers/gpu/drm/msm/dp/dp_catalog.c @@ -620,7 +620,7 @@ void dp_catalog_hpd_config_intr(struct dp_catalog *dp_catalog, config & DP_DP_HPD_INT_MASK); } -void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog) +void dp_catalog_ctrl_hpd_enable(struct dp_catalog *dp_catalog) { struct dp_catalog_private *catalog = container_of(dp_catalog, struct dp_catalog_private, dp_catalog); @@ -635,6 +635,19 @@ void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog) dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, DP_DP_HPD_CTRL_HPD_EN); } +void dp_catalog_ctrl_hpd_disable(struct dp_catalog *dp_catalog) +{ + struct dp_catalog_private *catalog = container_of(dp_catalog, + struct dp_catalog_private, dp_catalog); + + u32 reftimer = dp_read_aux(catalog, REG_DP_DP_HPD_REFTIMER); + + reftimer &= ~DP_DP_HPD_REFTIMER_ENABLE; + dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer); + + dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, 0); +} + static void dp_catalog_enable_sdp(struct dp_catalog_private *catalog) { /* trigger sdp */ diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h b/drivers/gpu/drm/msm/dp/dp_catalog.h index 82376a2..38786e8 100644 --- a/drivers/gpu/drm/msm/dp/dp_catalog.h +++ b/drivers/gpu/drm/msm/dp/dp_catalog.h @@ -104,7 +104,8 @@ bool dp_catalog_ctrl_mainlink_ready(struct dp_catalog *dp_catalog); void dp_catalog_ctrl_enable_irq(struct dp_catalog *dp_catalog, bool enable); void dp_catalog_hpd_config_intr(struct dp_catalog *dp_catalog, u32 intr_mask, bool en); -void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog); +void dp_catalog_ctrl_hpd_enable(struct dp_catalog *dp_catalog); +void dp_catalog_ctrl_hpd_disable(struct dp_catalog *dp_catalog); void dp_catalog_ctrl_config_psr(struct dp_catalog *dp_catalog); void dp_catalog_ctrl_set_psr(struct dp_catalog *dp_catalog, bool enter); u32 dp_catalog_link_is_connected(struct dp_catalog *dp_catalog); diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 3e13acdf..69bbc5f 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -615,12 +615,6 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data) dp->hpd_state = ST_MAINLINK_READY; } - /* enable HDP irq_hpd/replug interrupt */ - if (dp->dp_display.internal_hpd) - dp_catalog_hpd_config_intr(dp->catalog, - DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, - true); - drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n", dp->dp_display.connector_type, state); mutex_unlock(>event_mutex); @@ -658,12 +652,6 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data) drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n", dp->dp_display.connector_type, state); - /* disable irq_hpd/replug interrupts */ - if (dp->dp_display.internal_hpd) - dp_catalog_hpd_config_intr(dp->catalog, - DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, - false); - /* unplugged, no more irq_hpd handle */ dp_del_event(dp, EV_IRQ_HPD_INT); @@ -687,10 +675,6 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
Re: [Freedreno] [PATCH v4 2/5] drm/msm/dsi: Adjust pclk rate for compression
On 2023-05-22 13:30:21, Jessica Zhang wrote: > Adjust the pclk rate to divide hdisplay by the compression ratio when DSC > is enabled. > > Signed-off-by: Jessica Zhang As discussed previously, this patch would apply a lot more cleanly on top of: https://lore.kernel.org/linux-arm-msm/20230520200103.4019607-1-dmitry.barysh...@linaro.org/T/#u (This is the v2 that doesn't change the callback, but does change the code flow so that you have to *touch less lines* in this patch). - Marijn > --- > drivers/gpu/drm/msm/dsi/dsi_host.c | 23 +++ > 1 file changed, 19 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c > b/drivers/gpu/drm/msm/dsi/dsi_host.c > index 18d38b90eb28..d04f8bbd707d 100644 > --- a/drivers/gpu/drm/msm/dsi/dsi_host.c > +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c > @@ -561,7 +561,18 @@ void dsi_link_clk_disable_v2(struct msm_dsi_host > *msm_host) > clk_disable_unprepare(msm_host->byte_clk); > } > > -static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode, > bool is_bonded_dsi) > +static unsigned long dsi_adjust_compressed_pclk(const struct > drm_display_mode *mode, > + const struct drm_dsc_config *dsc) > +{ > + int new_hdisplay = DIV_ROUND_UP(mode->hdisplay * > drm_dsc_get_bpp_int(dsc), > + dsc->bits_per_component * 3); > + > + return (new_hdisplay + (mode->htotal - mode->hdisplay)) > + * mode->vtotal * drm_mode_vrefresh(mode); > +} > + > +static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode, > + const struct drm_dsc_config *dsc, bool is_bonded_dsi) > { > unsigned long pclk_rate; > > @@ -576,6 +587,10 @@ static unsigned long dsi_get_pclk_rate(const struct > drm_display_mode *mode, bool > if (is_bonded_dsi) > pclk_rate /= 2; > > + /* If DSC is enabled, divide hdisplay by compression ratio */ > + if (dsc) > + pclk_rate = dsi_adjust_compressed_pclk(mode, dsc); > + > return pclk_rate; > } > > @@ -585,7 +600,7 @@ unsigned long dsi_byte_clk_get_rate(struct mipi_dsi_host > *host, bool is_bonded_d > struct msm_dsi_host *msm_host = to_msm_dsi_host(host); > u8 lanes = msm_host->lanes; > u32 bpp = dsi_get_bpp(msm_host->format); > - unsigned long pclk_rate = dsi_get_pclk_rate(mode, is_bonded_dsi); > + unsigned long pclk_rate = dsi_get_pclk_rate(mode, msm_host->dsc, > is_bonded_dsi); > u64 pclk_bpp = (u64)pclk_rate * bpp; > > if (lanes == 0) { > @@ -604,7 +619,7 @@ unsigned long dsi_byte_clk_get_rate(struct mipi_dsi_host > *host, bool is_bonded_d > > static void dsi_calc_pclk(struct msm_dsi_host *msm_host, bool is_bonded_dsi) > { > - msm_host->pixel_clk_rate = dsi_get_pclk_rate(msm_host->mode, > is_bonded_dsi); > + msm_host->pixel_clk_rate = dsi_get_pclk_rate(msm_host->mode, > msm_host->dsc, is_bonded_dsi); > msm_host->byte_clk_rate = dsi_byte_clk_get_rate(_host->base, > is_bonded_dsi, > msm_host->mode); > > @@ -634,7 +649,7 @@ int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, > bool is_bonded_dsi) > > dsi_calc_pclk(msm_host, is_bonded_dsi); > > - pclk_bpp = (u64)dsi_get_pclk_rate(msm_host->mode, is_bonded_dsi) * bpp; > + pclk_bpp = (u64)dsi_get_pclk_rate(msm_host->mode, msm_host->dsc, > is_bonded_dsi) * bpp; > do_div(pclk_bpp, 8); > msm_host->src_clk_rate = pclk_bpp; > > > -- > 2.40.1 >
Re: [Freedreno] [PATCH v4 5/5] drm/msm/dsi: Remove incorrect references to slice_count
On 5/22/2023 2:01 PM, Marijn Suijten wrote: On 2023-05-22 13:30:24, Jessica Zhang wrote: Currently, slice_count is being used to calculate word count and pkt_per_line. Instead, these values should be calculated using slice per packet, which is not the same as slice_count. Slice count represents the number of soft slices per interface, and its value will not always match that of slice per packet. For example, it is possible to have cases where there are multiple soft slices per interface but the panel specifies only one slice per packet. As discussed in many patches before, there is no definition of "soft slices" anyhwere. Unless we can have that, and reference it, this should more clearly explain what it means or leave out the word "soft" altogether. Hi Marijn, Acked. Thus, use the default value of one slice per packet and remove slice_count from the aforementioned calculations. Fixes: 08802f515c3c ("drm/msm/dsi: Add support for DSC configuration") Fixes: bc6b6ff8135c ("drm/msm/dsi: Use DSC slice(s) packet size to compute word count") Signed-off-by: Jessica Zhang --- drivers/gpu/drm/msm/dsi/dsi_host.c | 26 -- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index d04f8bbd707d..2eed99afdba9 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -866,18 +866,17 @@ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mod */ slice_per_intf = msm_dsc_get_slices_per_intf(dsc, hdisplay); - /* -* If slice_count is greater than slice_per_intf -* then default to 1. This can happen during partial -* update. -*/ - if (dsc->slice_count > slice_per_intf) - dsc->slice_count = 1; - total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf; eol_byte_num = total_bytes_per_intf % 3; - pkt_per_line = slice_per_intf / dsc->slice_count; + + /* +* Typically, pkt_per_line = slice_per_intf * slice_per_pkt. +* +* Since the current driver only supports slice_per_pkt = 1, +* pkt_per_line will be equal to slice per intf for now. +*/ + pkt_per_line = slice_per_intf; if (is_cmd_mode) /* packet data type */ reg = DSI_COMMAND_COMPRESSION_MODE_CTRL_STREAM0_DATATYPE(MIPI_DSI_DCS_LONG_WRITE); @@ -1001,7 +1000,14 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) if (!msm_host->dsc) wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1; else - wc = msm_host->dsc->slice_chunk_size * msm_host->dsc->slice_count + 1; + /* +* When DSC is enabled, WC = slice_chunk_size * slice_per_packet + 1. +* Currently, the driver only supports default value of slice_per_packet = 1 +* +* TODO: Expand mipi_dsi_device struct to hold slice_per_packet info +* and adjust DSC math to account for slice_per_packet. +*/ Either rename this all to slice_per_pkt, or rename the above comment to slice_per_packet. Acked. Thanks, Jessica Zhang After improving on that: Reviewed-by: Marijn Suijten We all learned the wrong thing initially, thanks for clearing up that slice_count != slice_per_pkt. - Marijn + wc = msm_host->dsc->slice_chunk_size + 1; dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM0_CTRL, DSI_CMD_MDP_STREAM0_CTRL_WORD_COUNT(wc) | -- 2.40.1
Re: [Freedreno] [PATCH v4 4/5] drm/msm/dpu: Set DATA_COMPRESS for command mode
On 5/22/2023 1:54 PM, Marijn Suijten wrote: How about: Enable INTF DATA_COMPRESS bit (on cmdmode) for DCE/DSC 1.2? Hi Marijn, Acked. Drop parenthesis at your convenience. On 2023-05-22 13:30:23, Jessica Zhang wrote: Add a DPU INTF op to set DATA_COMPRESS register if the DPU_INTF_DATA_COMPRESS feature is enabled. This bit needs to be set in order for DSC v1.2 to work. "in order for .. to work" sounds like bugfixing... How about just: "set the DCE_DATA_COMPRESS bit to enable the DCE/DSC 1.2 datapath", which I think is what it is doing? Everyone seems to favour the "datapath" word anyway :) Sounds good. Thanks, Jessica Zhang Note: For now, this op is called for command mode encoders only. Changes to set DATA_COMPRESS for video mode encoders will be posted along with DSC v1.2 support for DP. Signed-off-by: Jessica Zhang --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 3 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 13 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h | 2 ++ 3 files changed, 18 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index d8ed85a238af..1a4c20f02312 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -68,6 +68,9 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg( phys_enc->hw_intf, true, phys_enc->hw_pp->idx); + + if (phys_enc->hw_intf->ops.enable_compression) + phys_enc->hw_intf->ops.enable_compression(phys_enc->hw_intf); } static void dpu_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c index 6485500eedb8..a462c6780e6e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -91,6 +91,7 @@ #define INTF_CFG2_DATABUS_WIDEN BIT(0) #define INTF_CFG2_DATA_HCTL_ENBIT(4) +#define INTF_CFG2_DCE_DATA_COMPRESS BIT(12) static void dpu_hw_intf_setup_timing_engine(struct dpu_hw_intf *ctx, const struct intf_timing_params *p, @@ -522,6 +523,15 @@ static void dpu_hw_intf_disable_autorefresh(struct dpu_hw_intf *intf, } +static void dpu_hw_intf_enable_compression(struct dpu_hw_intf *ctx) +{ + u32 intf_cfg2 = DPU_REG_READ(>hw, INTF_CONFIG2); + + intf_cfg2 |= INTF_CFG2_DCE_DATA_COMPRESS; + + DPU_REG_WRITE(>hw, INTF_CONFIG2, intf_cfg2); +} + static void _setup_intf_ops(struct dpu_hw_intf_ops *ops, unsigned long cap) { @@ -542,6 +552,9 @@ static void _setup_intf_ops(struct dpu_hw_intf_ops *ops, ops->vsync_sel = dpu_hw_intf_vsync_sel; ops->disable_autorefresh = dpu_hw_intf_disable_autorefresh; } + + if (cap & BIT(DPU_INTF_DATA_COMPRESS)) + ops->enable_compression = dpu_hw_intf_enable_compression; } struct dpu_hw_intf *dpu_hw_intf_init(const struct dpu_intf_cfg *cfg, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h index 73b0885918f8..72fe907729f1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h @@ -70,6 +70,7 @@ struct intf_status { * @get_autorefresh:Retrieve autorefresh config from hardware * Return: 0 on success, -ETIMEDOUT on timeout * @vsync_sel: Select vsync signal for tear-effect configuration + * @enable_compression: Enable data compression */ struct dpu_hw_intf_ops { void (*setup_timing_gen)(struct dpu_hw_intf *intf, @@ -107,6 +108,7 @@ struct dpu_hw_intf_ops { * Disable autorefresh if enabled */ void (*disable_autorefresh)(struct dpu_hw_intf *intf, uint32_t encoder_id, u16 vdisplay); Newline here. For the contents of the patch though: Reviewed-by: Marijn Suijten + void (*enable_compression)(struct dpu_hw_intf *intf); }; struct dpu_hw_intf { -- 2.40.1
Re: [Freedreno] [PATCH v12 07/10] drm/msm/dpu: always clear every individual pending flush mask
On 2023-05-22 12:30:50, Kuogee Hsieh wrote: > There are two tiers of pending flush control, main controller and > individual hardware block. Currently only the main controller of I would call "main controller" "top level" instead, but not sure how the hardware manual calls this? > flush mask is reset to 0 but leave out some individual pending flush > mask of particular hardware block keep previous value at > clear_pending_flush(). ... but the individual pending flush masks of particular hardware blocks are left at their previous values, eventually accumulating all possible bit values and typically flushing more than necessary. > Reset all individual hardware blocks flush > mask to 0 to avoid individual hardware block be triggered accidentally. maskS* > > Signed-off-by: Kuogee Hsieh > Reviewed-by: Dmitry Baryshkov Thanks! Does this need any fixes tag? Reviewed-by: Marijn Suijten > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c > index 69d0ea2..069c6e5 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c > @@ -100,7 +100,9 @@ static inline void dpu_hw_ctl_clear_pending_flush(struct > dpu_hw_ctl *ctx) > trace_dpu_hw_ctl_clear_pending_flush(ctx->pending_flush_mask, >dpu_hw_ctl_get_flush_register(ctx)); > ctx->pending_flush_mask = 0x0; > - > + ctx->pending_intf_flush_mask = 0; > + ctx->pending_wb_flush_mask = 0; > + ctx->pending_merge_3d_flush_mask = 0; I wouldn't mind keeping an empty line here. > memset(ctx->pending_dspp_flush_mask, 0, > sizeof(ctx->pending_dspp_flush_mask)); > } > -- > 2.7.4 >
Re: [Freedreno] [PATCH v12 3/9] drm/display/dsc: Add drm_dsc_get_bpp_int helper
On 5/22/2023 2:35 AM, Jani Nikula wrote: On Wed, 17 May 2023, Jessica Zhang wrote: Add helper to get the integer value of drm_dsc_config.bits_per_pixel Reviewed-by: Marijn Suijten Signed-off-by: Jessica Zhang --- include/drm/display/drm_dsc_helper.h | 7 +++ 1 file changed, 7 insertions(+) diff --git a/include/drm/display/drm_dsc_helper.h b/include/drm/display/drm_dsc_helper.h index e0cbc38ada26..7bf7e8ff8eb4 100644 --- a/include/drm/display/drm_dsc_helper.h +++ b/include/drm/display/drm_dsc_helper.h @@ -9,6 +9,7 @@ #define DRM_DSC_HELPER_H_ #include +#include Seems like a small thing, adding static inlines in headers usually leads to more header dependencies like this, and gradually slows down build. Does it need to be a static inline? Hi Jani, Good point about the dependencies. Will make this a non-inline function. Thanks, Jessica Zhang BR, Jani. enum drm_dsc_params_type { DRM_DSC_1_2_444, @@ -26,6 +27,12 @@ void drm_dsc_set_rc_buf_thresh(struct drm_dsc_config *vdsc_cfg); int drm_dsc_setup_rc_params(struct drm_dsc_config *vdsc_cfg, enum drm_dsc_params_type type); int drm_dsc_compute_rc_parameters(struct drm_dsc_config *vdsc_cfg); +static inline u32 drm_dsc_get_bpp_int(const struct drm_dsc_config *dsc) +{ + WARN_ON_ONCE(dsc->bits_per_pixel & 0xf); + return dsc->bits_per_pixel >> 4; +} + static inline u8 drm_dsc_initial_scale_value(const struct drm_dsc_config *dsc) { return 8 * dsc->rc_model_size / (dsc->rc_model_size - dsc->initial_offset); -- Jani Nikula, Intel Open Source Graphics Center
Re: [Freedreno] [PATCH v12 1/9] drm/display/dsc: Add flatness and initial scale value calculations
On 5/22/2023 2:37 AM, Jani Nikula wrote: On Wed, 17 May 2023, Jessica Zhang wrote: Add helpers to calculate det_thresh_flatness and initial_scale_value as these calculations are defined within the DSC spec. Reviewed-by: Marijn Suijten Signed-off-by: Jessica Zhang --- include/drm/display/drm_dsc_helper.h | 10 ++ 1 file changed, 10 insertions(+) diff --git a/include/drm/display/drm_dsc_helper.h b/include/drm/display/drm_dsc_helper.h index fc2104415dcb..753b0034eda7 100644 --- a/include/drm/display/drm_dsc_helper.h +++ b/include/drm/display/drm_dsc_helper.h @@ -25,5 +25,15 @@ void drm_dsc_set_rc_buf_thresh(struct drm_dsc_config *vdsc_cfg); int drm_dsc_setup_rc_params(struct drm_dsc_config *vdsc_cfg, enum drm_dsc_params_type type); int drm_dsc_compute_rc_parameters(struct drm_dsc_config *vdsc_cfg); +static inline u8 drm_dsc_initial_scale_value(const struct drm_dsc_config *dsc) +{ + return 8 * dsc->rc_model_size / (dsc->rc_model_size - dsc->initial_offset); +} + +static inline u32 drm_dsc_flatness_det_thresh(const struct drm_dsc_config *dsc) +{ + return 2 << (dsc->bits_per_component - 8); +} kernel-doc? Hi Jani, Sure, I'll add kernel docs for these. Maybe make them regular functions instead of static inline? I was under the impression that smaller/single-line functions were good candidates for inlining. However, if you have a strong preference for having these as regular functions, I'm ok with that too. Thanks, Jessica Zhang BR, Jani. + #endif /* _DRM_DSC_HELPER_H_ */ -- Jani Nikula, Intel Open Source Graphics Center
Re: [Freedreno] [PATCH v12 01/10] drm/msm/dpu: set DSC flush bit correctly at MDP CTL flush register
On 2023-05-22 23:18:02, Dmitry Baryshkov wrote: > On 22/05/2023 22:30, Kuogee Hsieh wrote: > > DSC flush bit is the bit 22 of CTL flush register. BIT(22) is expected > > to be written to CTL flush register to indicates that DSC is ready for > > flush. However 0x22 (BIT(1) and BIT(5)) was written mistakenly at current > > DSC_IDX is 22, not 0x22. > > > implementation. Fix this problem by writing BIT(22) to CTL flush register > > for DSC to work properly. Perhaps this whole comment needs a rewrite anyway, instead of pointing out grammar errors and confusion: The DSC CTL_FLUSH register should be programmed with the 22th bit (DSC_IDX) to flush the DSC hardware blocks, not the literal value of 22 (which corresponds to flushing VIG1, VIG2 and RGB1 instead). Patch contents are good though, thanks! - Marijn > > Changes in V12: > > -- split this patch out of "separate DSC flush update out of interface" > > > > Fixes: 77f6da90487c ("drm/msm/disp/dpu1: Add DSC support in hw_ctl") > > Signed-off-by: Kuogee Hsieh > > --- > > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c > > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c > > index 4f7cfa9..69d0ea2 100644 > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c > > @@ -525,7 +525,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl > > *ctx, > > DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, > > BIT(cfg->merge_3d - MERGE_3D_0)); > > if (cfg->dsc) { > > - DPU_REG_WRITE(>hw, CTL_FLUSH, DSC_IDX); > > + DPU_REG_WRITE(>hw, CTL_FLUSH, BIT(DSC_IDX)); > > DPU_REG_WRITE(c, CTL_DSC_ACTIVE, cfg->dsc); > > } > > } > > -- > With best wishes > Dmitry >
Re: [Freedreno] [PATCH v4 5/5] drm/msm/dsi: Remove incorrect references to slice_count
One more suggestion: DSC slice_count* On 2023-05-22 13:30:24, Jessica Zhan - Marijn
Re: [Freedreno] [PATCH v4 5/5] drm/msm/dsi: Remove incorrect references to slice_count
On 2023-05-22 13:30:24, Jessica Zhang wrote: > Currently, slice_count is being used to calculate word count and > pkt_per_line. Instead, these values should be calculated using slice per > packet, which is not the same as slice_count. > > Slice count represents the number of soft slices per interface, and its > value will not always match that of slice per packet. For example, it is > possible to have cases where there are multiple soft slices per interface > but the panel specifies only one slice per packet. As discussed in many patches before, there is no definition of "soft slices" anyhwere. Unless we can have that, and reference it, this should more clearly explain what it means or leave out the word "soft" altogether. > Thus, use the default value of one slice per packet and remove slice_count > from the aforementioned calculations. > > Fixes: 08802f515c3c ("drm/msm/dsi: Add support for DSC configuration") > Fixes: bc6b6ff8135c ("drm/msm/dsi: Use DSC slice(s) packet size to compute > word count") > Signed-off-by: Jessica Zhang > --- > drivers/gpu/drm/msm/dsi/dsi_host.c | 26 -- > 1 file changed, 16 insertions(+), 10 deletions(-) > > diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c > b/drivers/gpu/drm/msm/dsi/dsi_host.c > index d04f8bbd707d..2eed99afdba9 100644 > --- a/drivers/gpu/drm/msm/dsi/dsi_host.c > +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c > @@ -866,18 +866,17 @@ static void dsi_update_dsc_timing(struct msm_dsi_host > *msm_host, bool is_cmd_mod >*/ > slice_per_intf = msm_dsc_get_slices_per_intf(dsc, hdisplay); > > - /* > - * If slice_count is greater than slice_per_intf > - * then default to 1. This can happen during partial > - * update. > - */ > - if (dsc->slice_count > slice_per_intf) > - dsc->slice_count = 1; > - > total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf; > > eol_byte_num = total_bytes_per_intf % 3; > - pkt_per_line = slice_per_intf / dsc->slice_count; > + > + /* > + * Typically, pkt_per_line = slice_per_intf * slice_per_pkt. > + * > + * Since the current driver only supports slice_per_pkt = 1, > + * pkt_per_line will be equal to slice per intf for now. > + */ > + pkt_per_line = slice_per_intf; > > if (is_cmd_mode) /* packet data type */ > reg = > DSI_COMMAND_COMPRESSION_MODE_CTRL_STREAM0_DATATYPE(MIPI_DSI_DCS_LONG_WRITE); > @@ -1001,7 +1000,14 @@ static void dsi_timing_setup(struct msm_dsi_host > *msm_host, bool is_bonded_dsi) > if (!msm_host->dsc) > wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1; > else > - wc = msm_host->dsc->slice_chunk_size * > msm_host->dsc->slice_count + 1; > + /* > + * When DSC is enabled, WC = slice_chunk_size * > slice_per_packet + 1. > + * Currently, the driver only supports default value of > slice_per_packet = 1 > + * > + * TODO: Expand mipi_dsi_device struct to hold > slice_per_packet info > + * and adjust DSC math to account for > slice_per_packet. > + */ Either rename this all to slice_per_pkt, or rename the above comment to slice_per_packet. After improving on that: Reviewed-by: Marijn Suijten We all learned the wrong thing initially, thanks for clearing up that slice_count != slice_per_pkt. - Marijn > + wc = msm_host->dsc->slice_chunk_size + 1; > > dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM0_CTRL, > DSI_CMD_MDP_STREAM0_CTRL_WORD_COUNT(wc) | > > -- > 2.40.1 >
Re: [Freedreno] [PATCH v4 1/5] msm/drm/dsi: Round up DSC hdisplay calculation
On 2023-05-22 22:52:40, Konrad Dybcio wrote: > > > On 22.05.2023 22:44, Marijn Suijten wrote: > > On 2023-05-22 13:30:20, Jessica Zhang wrote: > >> Currently, when compression is enabled, hdisplay is reduced via integer > >> division. This causes issues for modes where the original hdisplay is > >> not a multiple of 3. > >> > >> To fix this, use DIV_ROUND_UP to divide hdisplay. > >> > >> Reviewed-by: Marijn Suijten > >> Suggested-by: Marijn Suijten > > > > Nit: probably these should go in the opposite order. And if they're > > all supposed to be chronological, I think it is: > > > > Suggested-by: > > Fixes: > > Signed-off-by: > > Reviewed-by: > > > > But unsure if that's a hard requirement, or even correct at all. > > > > - Marijn > Or you can rely on b4 to pick that up if it comes from others The problem is that somewhat stupidly, b4 (trailers -u) puts them in the wrong (not chronological) order, so it's pretty much useless for this. Unless there's a required ordering specified somewhere in the docs, that is *not* chronological, and that b4 is abiding by? (that is my question above) - Marijn > > Konrad
Re: [Freedreno] [PATCH v4 4/5] drm/msm/dpu: Set DATA_COMPRESS for command mode
How about: Enable INTF DATA_COMPRESS bit (on cmdmode) for DCE/DSC 1.2? Drop parenthesis at your convenience. On 2023-05-22 13:30:23, Jessica Zhang wrote: > Add a DPU INTF op to set DATA_COMPRESS register if the > DPU_INTF_DATA_COMPRESS feature is enabled. This bit needs to be set in > order for DSC v1.2 to work. "in order for .. to work" sounds like bugfixing... How about just: "set the DCE_DATA_COMPRESS bit to enable the DCE/DSC 1.2 datapath", which I think is what it is doing? Everyone seems to favour the "datapath" word anyway :) > Note: For now, this op is called for command mode encoders only. Changes to > set DATA_COMPRESS for video mode encoders will be posted along with DSC > v1.2 support for DP. > > Signed-off-by: Jessica Zhang > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 3 +++ > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 13 + > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h | 2 ++ > 3 files changed, 18 insertions(+) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > index d8ed85a238af..1a4c20f02312 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > @@ -68,6 +68,9 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg( > phys_enc->hw_intf, > true, > phys_enc->hw_pp->idx); > + > + if (phys_enc->hw_intf->ops.enable_compression) > + phys_enc->hw_intf->ops.enable_compression(phys_enc->hw_intf); > } > > static void dpu_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx) > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c > index 6485500eedb8..a462c6780e6e 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c > @@ -91,6 +91,7 @@ > > #define INTF_CFG2_DATABUS_WIDEN BIT(0) > #define INTF_CFG2_DATA_HCTL_EN BIT(4) > +#define INTF_CFG2_DCE_DATA_COMPRESS BIT(12) > > static void dpu_hw_intf_setup_timing_engine(struct dpu_hw_intf *ctx, > const struct intf_timing_params *p, > @@ -522,6 +523,15 @@ static void dpu_hw_intf_disable_autorefresh(struct > dpu_hw_intf *intf, > > } > > +static void dpu_hw_intf_enable_compression(struct dpu_hw_intf *ctx) > +{ > + u32 intf_cfg2 = DPU_REG_READ(>hw, INTF_CONFIG2); > + > + intf_cfg2 |= INTF_CFG2_DCE_DATA_COMPRESS; > + > + DPU_REG_WRITE(>hw, INTF_CONFIG2, intf_cfg2); > +} > + > static void _setup_intf_ops(struct dpu_hw_intf_ops *ops, > unsigned long cap) > { > @@ -542,6 +552,9 @@ static void _setup_intf_ops(struct dpu_hw_intf_ops *ops, > ops->vsync_sel = dpu_hw_intf_vsync_sel; > ops->disable_autorefresh = dpu_hw_intf_disable_autorefresh; > } > + > + if (cap & BIT(DPU_INTF_DATA_COMPRESS)) > + ops->enable_compression = dpu_hw_intf_enable_compression; > } > > struct dpu_hw_intf *dpu_hw_intf_init(const struct dpu_intf_cfg *cfg, > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h > index 73b0885918f8..72fe907729f1 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h > @@ -70,6 +70,7 @@ struct intf_status { > * @get_autorefresh:Retrieve autorefresh config from hardware > * Return: 0 on success, -ETIMEDOUT on timeout > * @vsync_sel: Select vsync signal for tear-effect > configuration > + * @enable_compression: Enable data compression > */ > struct dpu_hw_intf_ops { > void (*setup_timing_gen)(struct dpu_hw_intf *intf, > @@ -107,6 +108,7 @@ struct dpu_hw_intf_ops { >* Disable autorefresh if enabled >*/ > void (*disable_autorefresh)(struct dpu_hw_intf *intf, uint32_t > encoder_id, u16 vdisplay); Newline here. For the contents of the patch though: Reviewed-by: Marijn Suijten > + void (*enable_compression)(struct dpu_hw_intf *intf); > }; > > struct dpu_hw_intf { > > -- > 2.40.1 >
Re: [Freedreno] [PATCH v4 1/5] msm/drm/dsi: Round up DSC hdisplay calculation
On 22.05.2023 22:44, Marijn Suijten wrote: > On 2023-05-22 13:30:20, Jessica Zhang wrote: >> Currently, when compression is enabled, hdisplay is reduced via integer >> division. This causes issues for modes where the original hdisplay is >> not a multiple of 3. >> >> To fix this, use DIV_ROUND_UP to divide hdisplay. >> >> Reviewed-by: Marijn Suijten >> Suggested-by: Marijn Suijten > > Nit: probably these should go in the opposite order. And if they're > all supposed to be chronological, I think it is: > > Suggested-by: > Fixes: > Signed-off-by: > Reviewed-by: > > But unsure if that's a hard requirement, or even correct at all. > > - Marijn Or you can rely on b4 to pick that up if it comes from others Konrad > >> Fixes: 08802f515c3cf ("drm/msm/dsi: Add support for DSC configuration") >> Signed-off-by: Jessica Zhang >> --- >> drivers/gpu/drm/msm/dsi/dsi_host.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c >> b/drivers/gpu/drm/msm/dsi/dsi_host.c >> index 9223d7ec5a73..18d38b90eb28 100644 >> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c >> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c >> @@ -952,7 +952,7 @@ static void dsi_timing_setup(struct msm_dsi_host >> *msm_host, bool is_bonded_dsi) >> * pulse width same >> */ >> h_total -= hdisplay; >> -hdisplay = msm_dsc_get_bytes_per_line(msm_host->dsc) / 3; >> +hdisplay = >> DIV_ROUND_UP(msm_dsc_get_bytes_per_line(msm_host->dsc), 3); >> h_total += hdisplay; >> ha_end = ha_start + hdisplay; >> } >> >> -- >> 2.40.1 >>
Re: [Freedreno] [RFC] drm/msm/dp: Allow attaching a drm_panel
On Fri, Oct 08, 2021 at 03:38:21PM +0300, Heikki Krogerus wrote: > Hi, > > On Thu, Oct 07, 2021 at 09:15:12AM -0700, Bjorn Andersson wrote: > > The one thing that I still don't understand though is, if the typec_mux > > is used by the typec controller to inform _the_ mux about the function > > to be used, what's up with the complexity in typec_mux_match()? This is > > what lead me to believe that typec_mux was enabling/disabling individual > > altmodes, rather just flipping the physical switch at the bottom. > > Ah, typec_mux_match() is a mess. I'm sorry about that. I think most of > the code in that function is not used by anybody. If I remember > correctly, all that complexity is attempting to solve some > hypothetical corner case(s). Probable a case where we have multiple > muxes per port to deal with. > > I think it would probable be best to clean the function to the bare > minimum by keeping only the parts that are actually used today > (attached). > Sorry for not replying to this in a timely manner Heikki. I've been ignoring this issue for a long time now, just adding "svid" to our dts files. But, this obviously shows up in DT validation - and I'd prefer not defining these properties as valid. The attached patch works as expected. Could you please spin this as a proper patch, so we can get it merged? Regards, Bjorn > thanks, > > -- > heikki > diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c > index c8340de0ed495..44f168c9bd9bf 100644 > --- a/drivers/usb/typec/mux.c > +++ b/drivers/usb/typec/mux.c > @@ -193,56 +193,15 @@ static int mux_fwnode_match(struct device *dev, const > void *fwnode) > static void *typec_mux_match(struct fwnode_handle *fwnode, const char *id, >void *data) > { > - const struct typec_altmode_desc *desc = data; > struct device *dev; > - bool match; > - int nval; > - u16 *val; > - int ret; > - int i; > > /* > - * Check has the identifier already been "consumed". If it > - * has, no need to do any extra connection identification. > + * The connection identifier will be needed with device graph (OF > graph). > + * Device graph is not supported by this code yet, so bailing out. >*/ > - match = !id; > - if (match) > - goto find_mux; > - > - /* Accessory Mode muxes */ > - if (!desc) { > - match = fwnode_property_present(fwnode, "accessory"); > - if (match) > - goto find_mux; > - return NULL; > - } > - > - /* Alternate Mode muxes */ > - nval = fwnode_property_count_u16(fwnode, "svid"); > - if (nval <= 0) > - return NULL; > - > - val = kcalloc(nval, sizeof(*val), GFP_KERNEL); > - if (!val) > - return ERR_PTR(-ENOMEM); > - > - ret = fwnode_property_read_u16_array(fwnode, "svid", val, nval); > - if (ret < 0) { > - kfree(val); > - return ERR_PTR(ret); > - } > - > - for (i = 0; i < nval; i++) { > - match = val[i] == desc->svid; > - if (match) { > - kfree(val); > - goto find_mux; > - } > - } > - kfree(val); > - return NULL; > + if (id) > + return ERR_PTR(-ENOTSUPP); > > -find_mux: > dev = class_find_device(_mux_class, NULL, fwnode, > mux_fwnode_match); >
Re: [Freedreno] [PATCH v4 3/5] drm/msm/dpu: Add DPU_INTF_DATA_COMPRESS feature flag
Can you fit DPU >= 7.0 in the title? On 2023-05-22 13:30:22, Jessica Zhang wrote: > Add DATA_COMPRESS feature flag to DPU INTF block. Nit: repeating the title, perhaps you can reflow this with the second paragraph? - Marijn > In DPU 7.x and later, DSC/DCE enablement registers have been moved from > PINGPONG to INTF. > > Reviewed-by: Marijn Suijten > Signed-off-by: Jessica Zhang > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 3 ++- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 ++ > 2 files changed, 4 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > index 7944481d0a33..8e12e07728df 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > @@ -104,7 +104,8 @@ > #define INTF_SC7180_MASK \ > (BIT(DPU_INTF_INPUT_CTRL) | BIT(DPU_INTF_TE) | > BIT(DPU_INTF_STATUS_SUPPORTED)) > > -#define INTF_SC7280_MASK INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN) > +#define INTF_SC7280_MASK \ > + (INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN) | BIT(DPU_INTF_DATA_COMPRESS)) > > #define WB_SM8250_MASK (BIT(DPU_WB_LINE_MODE) | \ >BIT(DPU_WB_UBWC) | \ > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > index 4eda2cc847ef..01c65f940f2a 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > @@ -185,6 +185,7 @@ enum { > * @DPU_DATA_HCTL_ENAllows data to be transferred at > different rate > * than video timing > * @DPU_INTF_STATUS_SUPPORTED INTF block has INTF_STATUS register > + * @DPU_INTF_DATA_COMPRESS INTF block has DATA_COMPRESS register > * @DPU_INTF_MAX > */ > enum { > @@ -192,6 +193,7 @@ enum { > DPU_INTF_TE, > DPU_DATA_HCTL_EN, > DPU_INTF_STATUS_SUPPORTED, > + DPU_INTF_DATA_COMPRESS, > DPU_INTF_MAX > }; > > > -- > 2.40.1 >
Re: [Freedreno] [PATCH v4 1/5] msm/drm/dsi: Round up DSC hdisplay calculation
On 2023-05-22 13:30:20, Jessica Zhang wrote: > Currently, when compression is enabled, hdisplay is reduced via integer > division. This causes issues for modes where the original hdisplay is > not a multiple of 3. > > To fix this, use DIV_ROUND_UP to divide hdisplay. > > Reviewed-by: Marijn Suijten > Suggested-by: Marijn Suijten Nit: probably these should go in the opposite order. And if they're all supposed to be chronological, I think it is: Suggested-by: Fixes: Signed-off-by: Reviewed-by: But unsure if that's a hard requirement, or even correct at all. - Marijn > Fixes: 08802f515c3cf ("drm/msm/dsi: Add support for DSC configuration") > Signed-off-by: Jessica Zhang > --- > drivers/gpu/drm/msm/dsi/dsi_host.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c > b/drivers/gpu/drm/msm/dsi/dsi_host.c > index 9223d7ec5a73..18d38b90eb28 100644 > --- a/drivers/gpu/drm/msm/dsi/dsi_host.c > +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c > @@ -952,7 +952,7 @@ static void dsi_timing_setup(struct msm_dsi_host > *msm_host, bool is_bonded_dsi) >* pulse width same >*/ > h_total -= hdisplay; > - hdisplay = msm_dsc_get_bytes_per_line(msm_host->dsc) / 3; > + hdisplay = > DIV_ROUND_UP(msm_dsc_get_bytes_per_line(msm_host->dsc), 3); > h_total += hdisplay; > ha_end = ha_start + hdisplay; > } > > -- > 2.40.1 >
[Freedreno] [PATCH v4 3/5] drm/msm/dpu: Add DPU_INTF_DATA_COMPRESS feature flag
Add DATA_COMPRESS feature flag to DPU INTF block. In DPU 7.x and later, DSC/DCE enablement registers have been moved from PINGPONG to INTF. Reviewed-by: Marijn Suijten Signed-off-by: Jessica Zhang --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 3 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 7944481d0a33..8e12e07728df 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -104,7 +104,8 @@ #define INTF_SC7180_MASK \ (BIT(DPU_INTF_INPUT_CTRL) | BIT(DPU_INTF_TE) | BIT(DPU_INTF_STATUS_SUPPORTED)) -#define INTF_SC7280_MASK INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN) +#define INTF_SC7280_MASK \ + (INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN) | BIT(DPU_INTF_DATA_COMPRESS)) #define WB_SM8250_MASK (BIT(DPU_WB_LINE_MODE) | \ BIT(DPU_WB_UBWC) | \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 4eda2cc847ef..01c65f940f2a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -185,6 +185,7 @@ enum { * @DPU_DATA_HCTL_ENAllows data to be transferred at different rate * than video timing * @DPU_INTF_STATUS_SUPPORTED INTF block has INTF_STATUS register + * @DPU_INTF_DATA_COMPRESS INTF block has DATA_COMPRESS register * @DPU_INTF_MAX */ enum { @@ -192,6 +193,7 @@ enum { DPU_INTF_TE, DPU_DATA_HCTL_EN, DPU_INTF_STATUS_SUPPORTED, + DPU_INTF_DATA_COMPRESS, DPU_INTF_MAX }; -- 2.40.1
[Freedreno] [PATCH v4 2/5] drm/msm/dsi: Adjust pclk rate for compression
Adjust the pclk rate to divide hdisplay by the compression ratio when DSC is enabled. Signed-off-by: Jessica Zhang --- drivers/gpu/drm/msm/dsi/dsi_host.c | 23 +++ 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 18d38b90eb28..d04f8bbd707d 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -561,7 +561,18 @@ void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host) clk_disable_unprepare(msm_host->byte_clk); } -static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode, bool is_bonded_dsi) +static unsigned long dsi_adjust_compressed_pclk(const struct drm_display_mode *mode, + const struct drm_dsc_config *dsc) +{ + int new_hdisplay = DIV_ROUND_UP(mode->hdisplay * drm_dsc_get_bpp_int(dsc), + dsc->bits_per_component * 3); + + return (new_hdisplay + (mode->htotal - mode->hdisplay)) + * mode->vtotal * drm_mode_vrefresh(mode); +} + +static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode, + const struct drm_dsc_config *dsc, bool is_bonded_dsi) { unsigned long pclk_rate; @@ -576,6 +587,10 @@ static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode, bool if (is_bonded_dsi) pclk_rate /= 2; + /* If DSC is enabled, divide hdisplay by compression ratio */ + if (dsc) + pclk_rate = dsi_adjust_compressed_pclk(mode, dsc); + return pclk_rate; } @@ -585,7 +600,7 @@ unsigned long dsi_byte_clk_get_rate(struct mipi_dsi_host *host, bool is_bonded_d struct msm_dsi_host *msm_host = to_msm_dsi_host(host); u8 lanes = msm_host->lanes; u32 bpp = dsi_get_bpp(msm_host->format); - unsigned long pclk_rate = dsi_get_pclk_rate(mode, is_bonded_dsi); + unsigned long pclk_rate = dsi_get_pclk_rate(mode, msm_host->dsc, is_bonded_dsi); u64 pclk_bpp = (u64)pclk_rate * bpp; if (lanes == 0) { @@ -604,7 +619,7 @@ unsigned long dsi_byte_clk_get_rate(struct mipi_dsi_host *host, bool is_bonded_d static void dsi_calc_pclk(struct msm_dsi_host *msm_host, bool is_bonded_dsi) { - msm_host->pixel_clk_rate = dsi_get_pclk_rate(msm_host->mode, is_bonded_dsi); + msm_host->pixel_clk_rate = dsi_get_pclk_rate(msm_host->mode, msm_host->dsc, is_bonded_dsi); msm_host->byte_clk_rate = dsi_byte_clk_get_rate(_host->base, is_bonded_dsi, msm_host->mode); @@ -634,7 +649,7 @@ int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_bonded_dsi) dsi_calc_pclk(msm_host, is_bonded_dsi); - pclk_bpp = (u64)dsi_get_pclk_rate(msm_host->mode, is_bonded_dsi) * bpp; + pclk_bpp = (u64)dsi_get_pclk_rate(msm_host->mode, msm_host->dsc, is_bonded_dsi) * bpp; do_div(pclk_bpp, 8); msm_host->src_clk_rate = pclk_bpp; -- 2.40.1
[Freedreno] [PATCH v4 4/5] drm/msm/dpu: Set DATA_COMPRESS for command mode
Add a DPU INTF op to set DATA_COMPRESS register if the DPU_INTF_DATA_COMPRESS feature is enabled. This bit needs to be set in order for DSC v1.2 to work. Note: For now, this op is called for command mode encoders only. Changes to set DATA_COMPRESS for video mode encoders will be posted along with DSC v1.2 support for DP. Signed-off-by: Jessica Zhang --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 3 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 13 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h | 2 ++ 3 files changed, 18 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index d8ed85a238af..1a4c20f02312 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -68,6 +68,9 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg( phys_enc->hw_intf, true, phys_enc->hw_pp->idx); + + if (phys_enc->hw_intf->ops.enable_compression) + phys_enc->hw_intf->ops.enable_compression(phys_enc->hw_intf); } static void dpu_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c index 6485500eedb8..a462c6780e6e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -91,6 +91,7 @@ #define INTF_CFG2_DATABUS_WIDENBIT(0) #define INTF_CFG2_DATA_HCTL_EN BIT(4) +#define INTF_CFG2_DCE_DATA_COMPRESS BIT(12) static void dpu_hw_intf_setup_timing_engine(struct dpu_hw_intf *ctx, const struct intf_timing_params *p, @@ -522,6 +523,15 @@ static void dpu_hw_intf_disable_autorefresh(struct dpu_hw_intf *intf, } +static void dpu_hw_intf_enable_compression(struct dpu_hw_intf *ctx) +{ + u32 intf_cfg2 = DPU_REG_READ(>hw, INTF_CONFIG2); + + intf_cfg2 |= INTF_CFG2_DCE_DATA_COMPRESS; + + DPU_REG_WRITE(>hw, INTF_CONFIG2, intf_cfg2); +} + static void _setup_intf_ops(struct dpu_hw_intf_ops *ops, unsigned long cap) { @@ -542,6 +552,9 @@ static void _setup_intf_ops(struct dpu_hw_intf_ops *ops, ops->vsync_sel = dpu_hw_intf_vsync_sel; ops->disable_autorefresh = dpu_hw_intf_disable_autorefresh; } + + if (cap & BIT(DPU_INTF_DATA_COMPRESS)) + ops->enable_compression = dpu_hw_intf_enable_compression; } struct dpu_hw_intf *dpu_hw_intf_init(const struct dpu_intf_cfg *cfg, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h index 73b0885918f8..72fe907729f1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h @@ -70,6 +70,7 @@ struct intf_status { * @get_autorefresh:Retrieve autorefresh config from hardware * Return: 0 on success, -ETIMEDOUT on timeout * @vsync_sel: Select vsync signal for tear-effect configuration + * @enable_compression: Enable data compression */ struct dpu_hw_intf_ops { void (*setup_timing_gen)(struct dpu_hw_intf *intf, @@ -107,6 +108,7 @@ struct dpu_hw_intf_ops { * Disable autorefresh if enabled */ void (*disable_autorefresh)(struct dpu_hw_intf *intf, uint32_t encoder_id, u16 vdisplay); + void (*enable_compression)(struct dpu_hw_intf *intf); }; struct dpu_hw_intf { -- 2.40.1
[Freedreno] [PATCH v4 5/5] drm/msm/dsi: Remove incorrect references to slice_count
Currently, slice_count is being used to calculate word count and pkt_per_line. Instead, these values should be calculated using slice per packet, which is not the same as slice_count. Slice count represents the number of soft slices per interface, and its value will not always match that of slice per packet. For example, it is possible to have cases where there are multiple soft slices per interface but the panel specifies only one slice per packet. Thus, use the default value of one slice per packet and remove slice_count from the aforementioned calculations. Fixes: 08802f515c3c ("drm/msm/dsi: Add support for DSC configuration") Fixes: bc6b6ff8135c ("drm/msm/dsi: Use DSC slice(s) packet size to compute word count") Signed-off-by: Jessica Zhang --- drivers/gpu/drm/msm/dsi/dsi_host.c | 26 -- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index d04f8bbd707d..2eed99afdba9 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -866,18 +866,17 @@ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mod */ slice_per_intf = msm_dsc_get_slices_per_intf(dsc, hdisplay); - /* -* If slice_count is greater than slice_per_intf -* then default to 1. This can happen during partial -* update. -*/ - if (dsc->slice_count > slice_per_intf) - dsc->slice_count = 1; - total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf; eol_byte_num = total_bytes_per_intf % 3; - pkt_per_line = slice_per_intf / dsc->slice_count; + + /* +* Typically, pkt_per_line = slice_per_intf * slice_per_pkt. +* +* Since the current driver only supports slice_per_pkt = 1, +* pkt_per_line will be equal to slice per intf for now. +*/ + pkt_per_line = slice_per_intf; if (is_cmd_mode) /* packet data type */ reg = DSI_COMMAND_COMPRESSION_MODE_CTRL_STREAM0_DATATYPE(MIPI_DSI_DCS_LONG_WRITE); @@ -1001,7 +1000,14 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) if (!msm_host->dsc) wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1; else - wc = msm_host->dsc->slice_chunk_size * msm_host->dsc->slice_count + 1; + /* +* When DSC is enabled, WC = slice_chunk_size * slice_per_packet + 1. +* Currently, the driver only supports default value of slice_per_packet = 1 +* +* TODO: Expand mipi_dsi_device struct to hold slice_per_packet info +* and adjust DSC math to account for slice_per_packet. +*/ + wc = msm_host->dsc->slice_chunk_size + 1; dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM0_CTRL, DSI_CMD_MDP_STREAM0_CTRL_WORD_COUNT(wc) | -- 2.40.1
[Freedreno] [PATCH v4 1/5] msm/drm/dsi: Round up DSC hdisplay calculation
Currently, when compression is enabled, hdisplay is reduced via integer division. This causes issues for modes where the original hdisplay is not a multiple of 3. To fix this, use DIV_ROUND_UP to divide hdisplay. Reviewed-by: Marijn Suijten Suggested-by: Marijn Suijten Fixes: 08802f515c3cf ("drm/msm/dsi: Add support for DSC configuration") Signed-off-by: Jessica Zhang --- drivers/gpu/drm/msm/dsi/dsi_host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 9223d7ec5a73..18d38b90eb28 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -952,7 +952,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) * pulse width same */ h_total -= hdisplay; - hdisplay = msm_dsc_get_bytes_per_line(msm_host->dsc) / 3; + hdisplay = DIV_ROUND_UP(msm_dsc_get_bytes_per_line(msm_host->dsc), 3); h_total += hdisplay; ha_end = ha_start + hdisplay; } -- 2.40.1
[Freedreno] [PATCH v4 0/5] Add DSC v1.2 Support for DSI
This is a series of changes for DSI to enable command mode support for DSC v1.2. This includes: 1) Rounding up `hdisplay / 3` in dsc_timing_setup() 2) Adjusting pclk_rate to account for compression 3) Fixing incorrect uses of slice_count in DSI DSC calculations 4) Setting the DATA_COMPRESS bit when DSC is enabled With these changes (and the dependency below), DSC v1.2 should work over DSI in command mode. Note: Changes that add DSC v1.2 support for video mode will be posted with the DP support changes. Depends-on: "add DSC 1.2 dpu supports" [1] and "Introduce MSM-specific DSC helpers" [2] [1] https://patchwork.freedesktop.org/series/116789/ [2] https://patchwork.freedesktop.org/series/115833/ Signed-off-by: Jessica Zhang --- Changes in v4: - Clarified slice_per_pkt comment regarding pkt_per_line calculations - Reworded commit message for "drm/msm/dsi: Remove incorrect references to slice_count" - Wrapped INTF_SC7280_MASK macro definition in parentheses - Fixed incorrect commit hash in "msm/drm/dsi: Round up DSC hdisplay calculation" - Picked up Reviewed-by tag - Link to v3: https://lore.kernel.org/r/20230405-add-dsc-support-v3-0-6e1d35a20...@quicinc.com Changes in v3: - Added fix to round up hdisplay DSC adjustment - Fixed inconsistent whitespace in dpu_hw_intf_ops comment doc - Moved placement of dpu_hw_intf_enable_compression - Picked up "drm/msm/dsi: Fix calculation for pkt_per_line" patch and squashed all slice_count fixes into a single patch - Use drm_mode_vrefresh() to calculate adjusted pclk rate - Moved compressed pclk adjustment to dsi_adjust_compressed_pclk() helper - Rebased changes on top of updated dependencies - Reworded commit message for "drm/msm/dpu: Set DATA_COMPRESS for command mode" for clarity - Removed revision changelog in commit messages - Link to v2: https://lore.kernel.org/r/20230405-add-dsc-support-v2-0-1072c70e9...@quicinc.com Changes in v2: - Changed has_data_compress dpu_cap to a DATA_COMPRESS INTF feature flag - Changed pclk math to only divide hdisplay by compression ratio - Reworded word count TODO comment - Make DATA_COMPRESS an INTF flag - Read INTF_CONFIG2 before writing to DATA_COMPRESS bit - Fixed whitespace issue in macro definition - Removed `inline` from dpu_hw_intf_enable_compression declaration - Only set dpu_hw_intf_ops.data_compress if DATA_COMPRESS feature is set - Reworded commit messages and cover letter for clarity - Link to v1: https://lore.kernel.org/r/20230405-add-dsc-support-v1-0-6bc6f03ae...@quicinc.com --- Jessica Zhang (5): msm/drm/dsi: Round up DSC hdisplay calculation drm/msm/dsi: Adjust pclk rate for compression drm/msm/dpu: Add DPU_INTF_DATA_COMPRESS feature flag drm/msm/dpu: Set DATA_COMPRESS for command mode drm/msm/dsi: Remove incorrect references to slice_count .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 3 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 3 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c| 13 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h| 2 + drivers/gpu/drm/msm/dsi/dsi_host.c | 51 +++--- 6 files changed, 58 insertions(+), 16 deletions(-) --- base-commit: 2f0218fa4805d7c7eed8dc072e1bdf9f100492c7 change-id: 20230405-add-dsc-support-fe130ba49841 Best regards, -- Jessica Zhang
Re: [Freedreno] [PATCH v12 01/10] drm/msm/dpu: set DSC flush bit correctly at MDP CTL flush register
On 22/05/2023 22:30, Kuogee Hsieh wrote: DSC flush bit is the bit 22 of CTL flush register. BIT(22) is expected to be written to CTL flush register to indicates that DSC is ready for flush. However 0x22 (BIT(1) and BIT(5)) was written mistakenly at current DSC_IDX is 22, not 0x22. implementation. Fix this problem by writing BIT(22) to CTL flush register for DSC to work properly. Changes in V12: -- split this patch out of "separate DSC flush update out of interface" Fixes: 77f6da90487c ("drm/msm/disp/dpu1: Add DSC support in hw_ctl") Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 4f7cfa9..69d0ea2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -525,7 +525,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, BIT(cfg->merge_3d - MERGE_3D_0)); if (cfg->dsc) { - DPU_REG_WRITE(>hw, CTL_FLUSH, DSC_IDX); + DPU_REG_WRITE(>hw, CTL_FLUSH, BIT(DSC_IDX)); DPU_REG_WRITE(c, CTL_DSC_ACTIVE, cfg->dsc); } } -- With best wishes Dmitry
Re: [Freedreno] [PATCH v2] drm/msm/dp: enable HDP plugin/unplugged interrupts at hpd_enable/disable
On 22/05/2023 23:08, Kuogee Hsieh wrote: The internal_hpd flag was introduced to handle external DP HPD derived from GPIO pinmuxed into DP controller. HPD plug/unplug interrupts cannot be enabled until internal_hpd flag is set to true. At both bootup and resume time, the DP driver will enable external DP plugin interrupts and handle plugin interrupt accordingly. However dp_bridge_hpd_enable() bridge ops function was called to set internal_hpd to true later than where DP driver expected during both bootup and resume time. Excuse me, can't parse this. This prevent DP driver from detecting external plugin interrupt due to HPD related interrupts are not enabled on time. Hence external display prevents not being enabled can not be lit up properly. Move HPD related interrupts control of both enable/disable HDP hardware block and setup individual interrupt mask bits to dp_bridge_hpd_enable() and dp_bridge_hpd_disable(). Fixes: cd198caddea7 ("drm/msm/dp: Rely on hpd_enable/disable callbacks") Signed-off-by: Kuogee Hsieh This looks pretty good to me, minor nit below. --- drivers/gpu/drm/msm/dp/dp_catalog.c | 19 ++ drivers/gpu/drm/msm/dp/dp_catalog.h | 2 +- drivers/gpu/drm/msm/dp/dp_display.c | 70 +++-- 3 files changed, 35 insertions(+), 56 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c index 7a8cf1c..1da711e 100644 --- a/drivers/gpu/drm/msm/dp/dp_catalog.c +++ b/drivers/gpu/drm/msm/dp/dp_catalog.c @@ -620,19 +620,26 @@ void dp_catalog_hpd_config_intr(struct dp_catalog *dp_catalog, config & DP_DP_HPD_INT_MASK); } -void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog) +void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog, bool enable) Could you please split it into _enable and _disable functions? Having dp_catalog_ctrl_hpd_config(.., false) doesn't sound logical. { struct dp_catalog_private *catalog = container_of(dp_catalog, struct dp_catalog_private, dp_catalog); u32 reftimer = dp_read_aux(catalog, REG_DP_DP_HPD_REFTIMER); - /* Configure REFTIMER and enable it */ - reftimer |= DP_DP_HPD_REFTIMER_ENABLE; - dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer); + if (enable) { + /* Configure REFTIMER and enable it */ + reftimer |= DP_DP_HPD_REFTIMER_ENABLE; + dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer); + + /* Enable HPD */ + dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, DP_DP_HPD_CTRL_HPD_EN); + } else { + reftimer &= ~DP_DP_HPD_REFTIMER_ENABLE; + dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer); - /* Enable HPD */ - dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, DP_DP_HPD_CTRL_HPD_EN); + dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, 0); + } } static void dp_catalog_enable_sdp(struct dp_catalog_private *catalog) diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h b/drivers/gpu/drm/msm/dp/dp_catalog.h index 82376a2..818c036 100644 --- a/drivers/gpu/drm/msm/dp/dp_catalog.h +++ b/drivers/gpu/drm/msm/dp/dp_catalog.h @@ -104,7 +104,7 @@ bool dp_catalog_ctrl_mainlink_ready(struct dp_catalog *dp_catalog); void dp_catalog_ctrl_enable_irq(struct dp_catalog *dp_catalog, bool enable); void dp_catalog_hpd_config_intr(struct dp_catalog *dp_catalog, u32 intr_mask, bool en); -void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog); +void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog, bool enable); void dp_catalog_ctrl_config_psr(struct dp_catalog *dp_catalog); void dp_catalog_ctrl_set_psr(struct dp_catalog *dp_catalog, bool enter); u32 dp_catalog_link_is_connected(struct dp_catalog *dp_catalog); diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 3e13acdf..fee23e5 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -615,12 +615,6 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data) dp->hpd_state = ST_MAINLINK_READY; } - /* enable HDP irq_hpd/replug interrupt */ - if (dp->dp_display.internal_hpd) - dp_catalog_hpd_config_intr(dp->catalog, - DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, - true); - drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n", dp->dp_display.connector_type, state); mutex_unlock(>event_mutex); @@ -658,12 +652,6 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data) drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n", dp->dp_display.connector_type, state); - /* disable irq_hpd/replug interrupts */ - if
[Freedreno] [PATCH v2] drm/msm/dp: enable HDP plugin/unplugged interrupts at hpd_enable/disable
The internal_hpd flag was introduced to handle external DP HPD derived from GPIO pinmuxed into DP controller. HPD plug/unplug interrupts cannot be enabled until internal_hpd flag is set to true. At both bootup and resume time, the DP driver will enable external DP plugin interrupts and handle plugin interrupt accordingly. However dp_bridge_hpd_enable() bridge ops function was called to set internal_hpd to true later than where DP driver expected during both bootup and resume time. This prevent DP driver from detecting external plugin interrupt due to HPD related interrupts are not enabled on time. Hence external display can not be lit up properly. Move HPD related interrupts control of both enable/disable HDP hardware block and setup individual interrupt mask bits to dp_bridge_hpd_enable() and dp_bridge_hpd_disable(). Fixes: cd198caddea7 ("drm/msm/dp: Rely on hpd_enable/disable callbacks") Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/dp/dp_catalog.c | 19 ++ drivers/gpu/drm/msm/dp/dp_catalog.h | 2 +- drivers/gpu/drm/msm/dp/dp_display.c | 70 +++-- 3 files changed, 35 insertions(+), 56 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c index 7a8cf1c..1da711e 100644 --- a/drivers/gpu/drm/msm/dp/dp_catalog.c +++ b/drivers/gpu/drm/msm/dp/dp_catalog.c @@ -620,19 +620,26 @@ void dp_catalog_hpd_config_intr(struct dp_catalog *dp_catalog, config & DP_DP_HPD_INT_MASK); } -void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog) +void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog, bool enable) { struct dp_catalog_private *catalog = container_of(dp_catalog, struct dp_catalog_private, dp_catalog); u32 reftimer = dp_read_aux(catalog, REG_DP_DP_HPD_REFTIMER); - /* Configure REFTIMER and enable it */ - reftimer |= DP_DP_HPD_REFTIMER_ENABLE; - dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer); + if (enable) { + /* Configure REFTIMER and enable it */ + reftimer |= DP_DP_HPD_REFTIMER_ENABLE; + dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer); + + /* Enable HPD */ + dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, DP_DP_HPD_CTRL_HPD_EN); + } else { + reftimer &= ~DP_DP_HPD_REFTIMER_ENABLE; + dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer); - /* Enable HPD */ - dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, DP_DP_HPD_CTRL_HPD_EN); + dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, 0); + } } static void dp_catalog_enable_sdp(struct dp_catalog_private *catalog) diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h b/drivers/gpu/drm/msm/dp/dp_catalog.h index 82376a2..818c036 100644 --- a/drivers/gpu/drm/msm/dp/dp_catalog.h +++ b/drivers/gpu/drm/msm/dp/dp_catalog.h @@ -104,7 +104,7 @@ bool dp_catalog_ctrl_mainlink_ready(struct dp_catalog *dp_catalog); void dp_catalog_ctrl_enable_irq(struct dp_catalog *dp_catalog, bool enable); void dp_catalog_hpd_config_intr(struct dp_catalog *dp_catalog, u32 intr_mask, bool en); -void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog); +void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog, bool enable); void dp_catalog_ctrl_config_psr(struct dp_catalog *dp_catalog); void dp_catalog_ctrl_set_psr(struct dp_catalog *dp_catalog, bool enter); u32 dp_catalog_link_is_connected(struct dp_catalog *dp_catalog); diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 3e13acdf..fee23e5 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -615,12 +615,6 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data) dp->hpd_state = ST_MAINLINK_READY; } - /* enable HDP irq_hpd/replug interrupt */ - if (dp->dp_display.internal_hpd) - dp_catalog_hpd_config_intr(dp->catalog, - DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, - true); - drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n", dp->dp_display.connector_type, state); mutex_unlock(>event_mutex); @@ -658,12 +652,6 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data) drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n", dp->dp_display.connector_type, state); - /* disable irq_hpd/replug interrupts */ - if (dp->dp_display.internal_hpd) - dp_catalog_hpd_config_intr(dp->catalog, - DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK, - false); - /* unplugged, no more irq_hpd handle */
[Freedreno] [PATCH v12 09/10] drm/msm/dpu: add DSC 1.2 hw blocks for relevant chipsets
From: Abhinav Kumar Add DSC 1.2 hardware blocks to the catalog with necessary sub-block and feature flag information. Each display compression engine (DCE) contains dual DSC encoders so both share same base address but with its own different sub block address. changes in v4: -- delete DPU_DSC_HW_REV_1_1 -- re arrange sc8280xp_dsc[] changes in v4: -- fix checkpatch warning changes in v10: -- remove hard slice from commit text -- replace DPU_DSC_NATIVE_422_EN with DPU_DSC_NATIVE_42x_EN -- change DSC_BLK_1_2 .len from 0x100 to 0x29c changes in v11: -- remove comment at DSC_BLK_1_2 marco Signed-off-by: Abhinav Kumar Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten --- .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 14 ++ .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 7 +++ .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 16 .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 14 ++ .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 14 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 20 +++- 6 files changed, 84 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h index 500cfd0..d90486f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h @@ -153,6 +153,18 @@ static const struct dpu_merge_3d_cfg sm8350_merge_3d[] = { MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x5), }; +/* + * NOTE: Each display compression engine (DCE) contains dual hard + * slice DSC encoders so both share same base address but with + * its own different sub block address. + */ +static const struct dpu_dsc_cfg sm8350_dsc[] = { + DSC_BLK_1_2("dce_0_0", DSC_0, 0x8, 0x29c, 0, dsc_sblk_0), + DSC_BLK_1_2("dce_0_1", DSC_1, 0x8, 0x29c, 0, dsc_sblk_1), + DSC_BLK_1_2("dce_1_0", DSC_2, 0x81000, 0x29c, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_0), + DSC_BLK_1_2("dce_1_1", DSC_3, 0x81000, 0x29c, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_1), +}; + static const struct dpu_intf_cfg sm8350_intf[] = { INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), @@ -215,6 +227,8 @@ const struct dpu_mdss_cfg dpu_sm8350_cfg = { .dspp = sm8350_dspp, .pingpong_count = ARRAY_SIZE(sm8350_pp), .pingpong = sm8350_pp, + .dsc_count = ARRAY_SIZE(sm8350_dsc), + .dsc = sm8350_dsc, .merge_3d_count = ARRAY_SIZE(sm8350_merge_3d), .merge_3d = sm8350_merge_3d, .intf_count = ARRAY_SIZE(sm8350_intf), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h index 5646713..52609b8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h @@ -93,6 +93,11 @@ static const struct dpu_pingpong_cfg sc7280_pp[] = { PP_BLK_DITHER("pingpong_3", PINGPONG_3, 0x6c000, 0, sc7280_pp_sblk, -1, -1), }; +/* NOTE: sc7280 only has one DSC hard slice encoder */ +static const struct dpu_dsc_cfg sc7280_dsc[] = { + DSC_BLK_1_2("dce_0_0", DSC_0, 0x8, 0x29c, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_0), +}; + static const struct dpu_intf_cfg sc7280_intf[] = { INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), @@ -149,6 +154,8 @@ const struct dpu_mdss_cfg dpu_sc7280_cfg = { .mixer = sc7280_lm, .pingpong_count = ARRAY_SIZE(sc7280_pp), .pingpong = sc7280_pp, + .dsc_count = ARRAY_SIZE(sc7280_dsc), + .dsc = sc7280_dsc, .intf_count = ARRAY_SIZE(sc7280_intf), .intf = sc7280_intf, .vbif_count = ARRAY_SIZE(sdm845_vbif), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h index 808aacd..a84cf36 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h @@ -141,6 +141,20 @@ static const struct dpu_merge_3d_cfg sc8280xp_merge_3d[] = { MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x5), }; +/* + * NOTE: Each display compression engine (DCE) contains dual hard + * slice DSC encoders so both share same base address but with + * its own different sub block address. + */ +static const struct dpu_dsc_cfg sc8280xp_dsc[] = { + DSC_BLK_1_2("dce_0_0", DSC_0, 0x8, 0x29c, 0, dsc_sblk_0), + DSC_BLK_1_2("dce_0_1", DSC_1, 0x8, 0x29c, 0, dsc_sblk_1), + DSC_BLK_1_2("dce_1_0", DSC_2, 0x81000, 0x29c, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_0), + DSC_BLK_1_2("dce_1_1", DSC_3, 0x81000,
[Freedreno] [PATCH v12 06/10] drm/msm/dpu: add support for DSC encoder v1.2 engine
Add support for DSC 1.2 by providing the necessary hooks to program the DPU DSC 1.2 encoder. Changes in v3: -- fixed kernel test rebot report that "__iomem *off" is declared but not used at dpu_hw_dsc_config_1_2() -- unrolling thresh loops Changes in v4: -- delete DPU_DSC_HW_REV_1_1 -- delete off and used real register name directly Changes in v7: -- replace offset with sblk->enc.base -- replace ss with slice Changes in v8: -- fixed checkpatch warning Changes in v9: -- replaced __dsc_calc_ob_max_addr() with __dsc_calc_output_buf_max_addr() -- replaced variable num_ss with num_softslice -- remove inline from function declaration changes in v10: -- rewording text of changes in v9 -- replace DPU_DSC_NATIVE_422_EN with DPU_DSC_NATIVE_42x_EN -- replace drm_dsc_calculate_flatness_det_thresh() with drm_dsc_flatness_det_thresh() Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 31 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 14 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 387 + drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 7 +- 5 files changed, 436 insertions(+), 4 deletions(-) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 7274c412..4c7195af2 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -65,6 +65,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \ disp/dpu1/dpu_hw_catalog.o \ disp/dpu1/dpu_hw_ctl.o \ disp/dpu1/dpu_hw_dsc.o \ + disp/dpu1/dpu_hw_dsc_1_2.o \ disp/dpu1/dpu_hw_interrupts.o \ disp/dpu1/dpu_hw_intf.o \ disp/dpu1/dpu_hw_lm.o \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 83854e8..11610f7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. */ @@ -244,12 +244,18 @@ enum { }; /** - * DSC features + * DSC sub-blocks/features * @DPU_DSC_OUTPUT_CTRL Configure which PINGPONG block gets *the pixel output from this DSC. + * @DPU_DSC_HW_REV_1_2DSC block supports DSC 1.1 and 1.2 + * @DPU_DSC_NATIVE_42x_EN Supports NATIVE_422_EN and NATIVE_420_EN encoding + * @DPU_DSC_MAX */ enum { DPU_DSC_OUTPUT_CTRL = 0x1, + DPU_DSC_HW_REV_1_2, + DPU_DSC_NATIVE_42x_EN, + DPU_DSC_MAX }; /** @@ -306,6 +312,14 @@ struct dpu_pp_blk { }; /** + * struct dpu_dsc_blk - DSC Encoder sub-blk information + * @info: HW register and features supported by this sub-blk + */ +struct dpu_dsc_blk { + DPU_HW_SUBBLK_INFO; +}; + +/** * enum dpu_qos_lut_usage - define QoS LUT use cases */ enum dpu_qos_lut_usage { @@ -452,6 +466,16 @@ struct dpu_pingpong_sub_blks { }; /** + * struct dpu_dsc_sub_blks - DSC sub-blks + * @enc: DSC encoder sub-block + * @ctl: DSC controller sub-block + */ +struct dpu_dsc_sub_blks { + struct dpu_dsc_blk enc; + struct dpu_dsc_blk ctl; +}; + +/** * dpu_clk_ctrl_type - Defines top level clock control signals */ enum dpu_clk_ctrl_type { @@ -605,10 +629,13 @@ struct dpu_merge_3d_cfg { * struct dpu_dsc_cfg - information of DSC blocks * @id enum identifying this block * @base register offset of this block + * @len: length of hardware block * @features bit mask identifying sub-blocks/features + * @sblk: sub-blocks information */ struct dpu_dsc_cfg { DPU_HW_BLK_INFO; + const struct dpu_dsc_sub_blks *sblk; }; /** diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h index 138080a..d5b597a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h @@ -1,5 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2020-2022, Linaro Limited */ +/* + * Copyright (c) 2020-2022, Linaro Limited + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved + */ #ifndef _DPU_HW_DSC_H #define _DPU_HW_DSC_H @@ -69,6 +72,15 @@ struct dpu_hw_dsc *dpu_hw_dsc_init(const struct dpu_dsc_cfg *cfg, void __iomem *addr); /** + * dpu_hw_dsc_init_1_2() - initializes the v1.2 DSC hw driver object + * @cfg: DSC catalog entry for which driver object is required + * @addr: Mapped register io address of MDP + * Returns: Error code or allocated dpu_hw_dsc context + */ +struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(const struct
[Freedreno] [PATCH v12 08/10] drm/msm/dpu: separate DSC flush update out of interface
Currently DSC flushing happens during interface configuration at dpu_hw_ctl_intf_cfg_v1(). Separate DSC flush away from dpu_hw_ctl_intf_cfg_v1() by adding dpu_hw_ctl_update_pending_flush_dsc_v1() to handle both per-DSC engine and DSC flush bits at same time to make it consistent with the location of flush programming of other DPU sub-blocks. Changes in v10: -- rewording commit text -- pass ctl directly instead of dpu_enc to dsc_pipe_cfg() -- ctx->pending_dsc_flush_mask = 0; Changes in v11: -- add Fixes tag -- capitalize MERGE_3D, DSPP and DSC at struct dpu_hw_ctl_ops{} Changes in v12: -- move dsc parameter to next line at dpu_encoder_dsc_pipe_cfg() Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 10 -- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 23 +-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 11 +++ 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index ffa6f04..7fca09e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1834,7 +1834,8 @@ dpu_encoder_dsc_initial_line_calc(struct drm_dsc_config *dsc, return DIV_ROUND_UP(total_pixels, dsc->slice_width); } -static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc, +static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_ctl *ctl, +struct dpu_hw_dsc *hw_dsc, struct dpu_hw_pingpong *hw_pp, struct drm_dsc_config *dsc, u32 common_mode, @@ -1854,6 +1855,9 @@ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc, if (hw_pp->ops.enable_dsc) hw_pp->ops.enable_dsc(hw_pp); + + if (ctl->ops.update_pending_flush_dsc) + ctl->ops.update_pending_flush_dsc(ctl, hw_dsc->idx); } static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc, @@ -1861,6 +1865,7 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc, { /* coding only for 2LM, 2enc, 1 dsc config */ struct dpu_encoder_phys *enc_master = dpu_enc->cur_master; + struct dpu_hw_ctl *ctl = enc_master->hw_ctl; struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC]; struct dpu_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC]; int this_frame_slices; @@ -1898,7 +1903,8 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc, initial_lines = dpu_encoder_dsc_initial_line_calc(dsc, enc_ip_w); for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) - dpu_encoder_dsc_pipe_cfg(hw_dsc[i], hw_pp[i], dsc, dsc_common_mode, initial_lines); + dpu_encoder_dsc_pipe_cfg(ctl, hw_dsc[i], hw_pp[i], +dsc, dsc_common_mode, initial_lines); } void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 069c6e5..20e08c6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -103,6 +103,7 @@ static inline void dpu_hw_ctl_clear_pending_flush(struct dpu_hw_ctl *ctx) ctx->pending_intf_flush_mask = 0; ctx->pending_wb_flush_mask = 0; ctx->pending_merge_3d_flush_mask = 0; + ctx->pending_dsc_flush_mask = 0; memset(ctx->pending_dspp_flush_mask, 0, sizeof(ctx->pending_dspp_flush_mask)); } @@ -141,6 +142,11 @@ static inline void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx) CTL_DSPP_n_FLUSH(dspp - DSPP_0), ctx->pending_dspp_flush_mask[dspp - DSPP_0]); } + + if (ctx->pending_flush_mask & BIT(DSC_IDX)) + DPU_REG_WRITE(>hw, CTL_DSC_FLUSH, + ctx->pending_dsc_flush_mask); + DPU_REG_WRITE(>hw, CTL_FLUSH, ctx->pending_flush_mask); } @@ -287,6 +293,13 @@ static void dpu_hw_ctl_update_pending_flush_merge_3d_v1(struct dpu_hw_ctl *ctx, ctx->pending_flush_mask |= BIT(MERGE_3D_IDX); } +static void dpu_hw_ctl_update_pending_flush_dsc_v1(struct dpu_hw_ctl *ctx, + enum dpu_dsc dsc_num) +{ + ctx->pending_dsc_flush_mask |= BIT(dsc_num - DSC_0); + ctx->pending_flush_mask |= BIT(DSC_IDX); +} + static void dpu_hw_ctl_update_pending_flush_dspp(struct dpu_hw_ctl *ctx, enum dpu_dspp dspp, u32 dspp_sub_blk) { @@ -504,9 +517,6 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, if ((test_bit(DPU_CTL_VM_CFG, >caps->features))) mode_sel = CTL_DEFAULT_GROUP_ID << 28; - if (cfg->dsc) - DPU_REG_WRITE(>hw, CTL_DSC_FLUSH, cfg->dsc); - if
[Freedreno] [PATCH v12 00/10] add DSC 1.2 dpu supports
This series adds the DPU side changes to support DSC 1.2 encoder. This was validated with both DSI DSC 1.2 panel and DP DSC 1.2 monitor. The DSI and DP parts will be pushed later on top of this change. This seriel is rebase on [1], [2] and catalog fixes from rev-4 of [3]. [1]: https://patchwork.freedesktop.org/series/116851/ [2]: https://patchwork.freedesktop.org/series/116615/ [3]: https://patchwork.freedesktop.org/series/112332/ Abhinav Kumar (2): drm/msm/dpu: add dsc blocks to the catalog of MSM8998 and SC8180X drm/msm/dpu: add DSC 1.2 hw blocks for relevant chipsets Kuogee Hsieh (8): drm/msm/dpu: set DSC flush bit correctly at MDP CTL flush register drm/msm/dpu: add DPU_PINGPONG_DSC feature bit for DPU < 7.0.0 drm/msm/dpu: Guard PINGPONG DSC ops behind DPU_PINGPONG_DSC bit drm/msm/dpu: Introduce PINGPONG_NONE to disconnect DSC from PINGPONG drm/msm/dpu: add support for DSC encoder v1.2 engine drm/msm/dpu: always clear every individual pending flush mask drm/msm/dpu: separate DSC flush update out of interface drm/msm/dpu: tear down DSC data path when DSC disabled drivers/gpu/drm/msm/Makefile | 1 + .../drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h| 7 + .../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h| 11 + .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 14 + .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 7 + .../drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 16 + .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 14 + .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 14 + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c| 51 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 24 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 35 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 34 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 11 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c | 14 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 15 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 387 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h| 3 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c| 9 +- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 7 +- 19 files changed, 644 insertions(+), 30 deletions(-) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c -- 2.7.4
[Freedreno] [PATCH v12 01/10] drm/msm/dpu: set DSC flush bit correctly at MDP CTL flush register
DSC flush bit is the bit 22 of CTL flush register. BIT(22) is expected to be written to CTL flush register to indicates that DSC is ready for flush. However 0x22 (BIT(1) and BIT(5)) was written mistakenly at current implementation. Fix this problem by writing BIT(22) to CTL flush register for DSC to work properly. Changes in V12: -- split this patch out of "separate DSC flush update out of interface" Fixes: 77f6da90487c ("drm/msm/disp/dpu1: Add DSC support in hw_ctl") Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 4f7cfa9..69d0ea2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -525,7 +525,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, BIT(cfg->merge_3d - MERGE_3D_0)); if (cfg->dsc) { - DPU_REG_WRITE(>hw, CTL_FLUSH, DSC_IDX); + DPU_REG_WRITE(>hw, CTL_FLUSH, BIT(DSC_IDX)); DPU_REG_WRITE(c, CTL_DSC_ACTIVE, cfg->dsc); } } -- 2.7.4
[Freedreno] [PATCH v12 10/10] drm/msm/dpu: tear down DSC data path when DSC disabled
Unset DSC_ACTIVE bit at dpu_hw_ctl_reset_intf_cfg_v1(), dpu_encoder_unprep_dsc() and dpu_encoder_dsc_pipe_clr() functions to tear down DSC data path if DSC data path was setup previous. Changes in V10: -- pass ctl directly instead of dpu_enc to dsc_pipe_cfg() -- move both dpu_encoder_unprep_dsc() and dpu_encoder_dsc_pipe_clr() to above phys_cleanup() Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 39 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 7 ++ 2 files changed, 46 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 7fca09e..3b416e1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -2036,6 +2036,41 @@ static void dpu_encoder_helper_reset_mixers(struct dpu_encoder_phys *phys_enc) } } +static void dpu_encoder_dsc_pipe_clr(struct dpu_hw_ctl *ctl, +struct dpu_hw_dsc *hw_dsc, +struct dpu_hw_pingpong *hw_pp) +{ + if (hw_dsc->ops.dsc_disable) + hw_dsc->ops.dsc_disable(hw_dsc); + + if (hw_pp->ops.disable_dsc) + hw_pp->ops.disable_dsc(hw_pp); + + if (hw_dsc->ops.dsc_bind_pingpong_blk) + hw_dsc->ops.dsc_bind_pingpong_blk(hw_dsc, PINGPONG_NONE); + + if (ctl->ops.update_pending_flush_dsc) + ctl->ops.update_pending_flush_dsc(ctl, hw_dsc->idx); +} + +static void dpu_encoder_unprep_dsc(struct dpu_encoder_virt *dpu_enc) +{ + /* coding only for 2LM, 2enc, 1 dsc config */ + struct dpu_encoder_phys *enc_master = dpu_enc->cur_master; + struct dpu_hw_ctl *ctl = enc_master->hw_ctl; + struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC]; + struct dpu_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC]; + int i; + + for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { + hw_pp[i] = dpu_enc->hw_pp[i]; + hw_dsc[i] = dpu_enc->hw_dsc[i]; + + if (hw_pp[i] && hw_dsc[i]) + dpu_encoder_dsc_pipe_clr(ctl, hw_dsc[i], hw_pp[i]); + } +} + void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) { struct dpu_hw_ctl *ctl = phys_enc->hw_ctl; @@ -2086,8 +2121,12 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) phys_enc->hw_pp->merge_3d->idx); } + if (dpu_enc->dsc) + dpu_encoder_unprep_dsc(dpu_enc); + intf_cfg.stream_sel = 0; /* Don't care value for video mode */ intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); + intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc); if (phys_enc->hw_intf) intf_cfg.intf = phys_enc->hw_intf->idx; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 20e08c6..c2cb426 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -581,6 +581,7 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx, u32 intf_active = 0; u32 wb_active = 0; u32 merge3d_active = 0; + u32 dsc_active; /* * This API resets each portion of the CTL path namely, @@ -610,6 +611,12 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx, wb_active &= ~BIT(cfg->wb - WB_0); DPU_REG_WRITE(c, CTL_WB_ACTIVE, wb_active); } + + if (cfg->dsc) { + dsc_active = DPU_REG_READ(c, CTL_DSC_ACTIVE); + dsc_active &= ~cfg->dsc; + DPU_REG_WRITE(c, CTL_DSC_ACTIVE, dsc_active); + } } static void dpu_hw_ctl_set_fetch_pipe_active(struct dpu_hw_ctl *ctx, -- 2.7.4
[Freedreno] [PATCH v12 04/10] drm/msm/dpu: Guard PINGPONG DSC ops behind DPU_PINGPONG_DSC bit
DPU < 7.0.0 has DPU_PINGPONG_DSC feature bit set to indicate it requires both dpu_hw_pp_setup_dsc() and dpu_hw_pp_dsc_{enable,disable}() to be executed to complete DSC configuration if DSC hardware block is present. Hence test DPU_PINGPONG_DSC feature bit and assign DSC related functions to the ops of PINGPONG block accordingly if DPU_PINGPONG_DSC bit is set. Changes in v6: -- split patches, this patch has function handles DPU_PINGPONG_DSC bit Changes in v9: -- the original code of assigning dsc related functions to the ops of pingpong block without testing the DPU_PINGPONG_DSC feature bit was restored back due to rebase error which defeat the purpose of this patch. Remove those error code. Changes in v10: -- change commit title -- correct texts at changes in v9 Changes in v12: -- fixed length too long at Changes in v9 Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c index 79e4576..437d9e6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c @@ -291,9 +291,12 @@ static void _setup_pingpong_ops(struct dpu_hw_pingpong *c, c->ops.get_line_count = dpu_hw_pp_get_line_count; c->ops.disable_autorefresh = dpu_hw_pp_disable_autorefresh; } - c->ops.setup_dsc = dpu_hw_pp_setup_dsc; - c->ops.enable_dsc = dpu_hw_pp_dsc_enable; - c->ops.disable_dsc = dpu_hw_pp_dsc_disable; + + if (test_bit(DPU_PINGPONG_DSC, )) { + c->ops.setup_dsc = dpu_hw_pp_setup_dsc; + c->ops.enable_dsc = dpu_hw_pp_dsc_enable; + c->ops.disable_dsc = dpu_hw_pp_dsc_disable; + } if (test_bit(DPU_PINGPONG_DITHER, )) c->ops.setup_dither = dpu_hw_pp_setup_dither; -- 2.7.4
[Freedreno] [PATCH v12 07/10] drm/msm/dpu: always clear every individual pending flush mask
There are two tiers of pending flush control, main controller and individual hardware block. Currently only the main controller of flush mask is reset to 0 but leave out some individual pending flush mask of particular hardware block keep previous value at clear_pending_flush(). Reset all individual hardware blocks flush mask to 0 to avoid individual hardware block be triggered accidentally. Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 69d0ea2..069c6e5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -100,7 +100,9 @@ static inline void dpu_hw_ctl_clear_pending_flush(struct dpu_hw_ctl *ctx) trace_dpu_hw_ctl_clear_pending_flush(ctx->pending_flush_mask, dpu_hw_ctl_get_flush_register(ctx)); ctx->pending_flush_mask = 0x0; - + ctx->pending_intf_flush_mask = 0; + ctx->pending_wb_flush_mask = 0; + ctx->pending_merge_3d_flush_mask = 0; memset(ctx->pending_dspp_flush_mask, 0, sizeof(ctx->pending_dspp_flush_mask)); } -- 2.7.4
[Freedreno] [PATCH v12 05/10] drm/msm/dpu: Introduce PINGPONG_NONE to disconnect DSC from PINGPONG
Disabling the crossbar mux between DSC and PINGPONG currently requires a bogus enum dpu_pingpong value to be passed when calling dsc_bind_pingpong_blk() with enable=false, even though the register value written is independent of the current PINGPONG block. Replace that `bool enable` parameter with a new PINGPONG_NONE dpu_pingpong flag that triggers the write of the "special" 0xF "crossbar disabled" value to the register instead. Changes in v4: -- more details to commit text Changes in v5: -- rewording commit text suggested by Marijn -- add DRM_DEBUG_KMS for DSC unbinding case Changes in v8: -- fix checkpatch warning Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c | 14 +++--- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 3 ++- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index cf1de5d..ffa6f04 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1850,7 +1850,7 @@ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc, hw_pp->ops.setup_dsc(hw_pp); if (hw_dsc->ops.dsc_bind_pingpong_blk) - hw_dsc->ops.dsc_bind_pingpong_blk(hw_dsc, true, hw_pp->idx); + hw_dsc->ops.dsc_bind_pingpong_blk(hw_dsc, hw_pp->idx); if (hw_pp->ops.enable_dsc) hw_pp->ops.enable_dsc(hw_pp); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c index 8deedeae..509dbaa 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c @@ -157,7 +157,6 @@ static void dpu_hw_dsc_config_thresh(struct dpu_hw_dsc *hw_dsc, static void dpu_hw_dsc_bind_pingpong_blk( struct dpu_hw_dsc *hw_dsc, - bool enable, const enum dpu_pingpong pp) { struct dpu_hw_blk_reg_map *c = _dsc->hw; @@ -166,14 +165,15 @@ static void dpu_hw_dsc_bind_pingpong_blk( dsc_ctl_offset = DSC_CTL(hw_dsc->idx); - if (enable) + if (pp) mux_cfg = (pp - PINGPONG_0) & 0x7; - DRM_DEBUG_KMS("%s dsc:%d %s pp:%d\n", - enable ? "Binding" : "Unbinding", - hw_dsc->idx - DSC_0, - enable ? "to" : "from", - pp - PINGPONG_0); + if (pp) + DRM_DEBUG_KMS("Binding dsc:%d to pp:%d\n", + hw_dsc->idx - DSC_0, pp - PINGPONG_0); + else + DRM_DEBUG_KMS("Unbinding dsc:%d from any pp\n", + hw_dsc->idx - DSC_0); DPU_REG_WRITE(c, dsc_ctl_offset, mux_cfg); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h index 287ec5f..138080a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h @@ -44,7 +44,6 @@ struct dpu_hw_dsc_ops { struct drm_dsc_config *dsc); void (*dsc_bind_pingpong_blk)(struct dpu_hw_dsc *hw_dsc, - bool enable, enum dpu_pingpong pp); }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h index 1913a19..02a0f48 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h @@ -191,7 +191,8 @@ enum dpu_dsc { }; enum dpu_pingpong { - PINGPONG_0 = 1, + PINGPONG_NONE, + PINGPONG_0, PINGPONG_1, PINGPONG_2, PINGPONG_3, -- 2.7.4
[Freedreno] [PATCH v12 02/10] drm/msm/dpu: add dsc blocks to the catalog of MSM8998 and SC8180X
From: Abhinav Kumar Some platforms have DSC blocks which have not been declared in the catalog. Complete DSC 1.1 support for all platforms by adding the missing blocks to MSM8998 and SC8180X. Changes in v9: -- add MSM8998 and SC8180x to commit title Changes in v10: -- fix grammar at commit text Changes in v12: -- fix "titil" with "title" at changes in v9 Signed-off-by: Abhinav Kumar Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 7 +++ drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 11 +++ 2 files changed, 18 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h index c0dd477..521cfd5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h @@ -126,6 +126,11 @@ static const struct dpu_pingpong_cfg msm8998_pp[] = { DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)), }; +static const struct dpu_dsc_cfg msm8998_dsc[] = { + DSC_BLK("dsc_0", DSC_0, 0x8, 0), + DSC_BLK("dsc_1", DSC_1, 0x80400, 0), +}; + static const struct dpu_dspp_cfg msm8998_dspp[] = { DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_MSM8998_MASK, _dspp_sblk), @@ -199,6 +204,8 @@ const struct dpu_mdss_cfg dpu_msm8998_cfg = { .dspp = msm8998_dspp, .pingpong_count = ARRAY_SIZE(msm8998_pp), .pingpong = msm8998_pp, + .dsc_count = ARRAY_SIZE(msm8998_dsc), + .dsc = msm8998_dsc, .intf_count = ARRAY_SIZE(msm8998_intf), .intf = msm8998_intf, .vbif_count = ARRAY_SIZE(msm8998_vbif), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h index e8057a1..fec1665 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h @@ -142,6 +142,15 @@ static const struct dpu_merge_3d_cfg sc8180x_merge_3d[] = { MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x83200), }; +static const struct dpu_dsc_cfg sc8180x_dsc[] = { + DSC_BLK("dsc_0", DSC_0, 0x8, BIT(DPU_DSC_OUTPUT_CTRL)), + DSC_BLK("dsc_1", DSC_1, 0x80400, BIT(DPU_DSC_OUTPUT_CTRL)), + DSC_BLK("dsc_2", DSC_2, 0x80800, BIT(DPU_DSC_OUTPUT_CTRL)), + DSC_BLK("dsc_3", DSC_3, 0x80c00, BIT(DPU_DSC_OUTPUT_CTRL)), + DSC_BLK("dsc_4", DSC_4, 0x81000, BIT(DPU_DSC_OUTPUT_CTRL)), + DSC_BLK("dsc_5", DSC_5, 0x81400, BIT(DPU_DSC_OUTPUT_CTRL)), +}; + static const struct dpu_intf_cfg sc8180x_intf[] = { INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), @@ -206,6 +215,8 @@ const struct dpu_mdss_cfg dpu_sc8180x_cfg = { .mixer = sc8180x_lm, .pingpong_count = ARRAY_SIZE(sc8180x_pp), .pingpong = sc8180x_pp, + .dsc_count = ARRAY_SIZE(sc8180x_dsc), + .dsc = sc8180x_dsc, .merge_3d_count = ARRAY_SIZE(sc8180x_merge_3d), .merge_3d = sc8180x_merge_3d, .intf_count = ARRAY_SIZE(sc8180x_intf), -- 2.7.4
[Freedreno] [PATCH v12 03/10] drm/msm/dpu: add DPU_PINGPONG_DSC feature bit for DPU < 7.0.0
DPU < 7.0.0 requires the PINGPONG block to be involved during DSC setting up. Since DPU >= 7.0.0, enabling and starting the DSC encoder engine was moved to INTF with the help of the flush mechanism. Add a DPU_PINGPONG_DSC feature bit to restrict the availability of dpu_hw_pp_setup_dsc() and dpu_hw_pp_dsc_{enable,disable}() on the PINGPONG block to DPU < 7.0.0 hardware, as the registers are not available on DPU 7.0.0 and higher anymore. Add DPU_PINGPONG_DSC to PINGPONG_SDM845_MASK, PINGPONG_SDM845_TE2_MASK and PINGPONG_SM8150_MASK which is used for all DPU < 7.0 chipsets. changes in v6: -- split patches and rearrange to keep catalog related files at this patch changes in v7: -- rewording commit text as suggested at review comments changes in v9: -- delete BIT(DPU_PINGPONG_DSC) from PINGPONG_SDM845_TE2_MASK changes in v10: -- correct order of commit text Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 4 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 82b58c6..f2a1535 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -76,13 +76,13 @@ (BIT(DPU_DIM_LAYER) | BIT(DPU_MIXER_COMBINED_ALPHA)) #define PINGPONG_SDM845_MASK \ - (BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_TE)) + (BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_TE) | BIT(DPU_PINGPONG_DSC)) #define PINGPONG_SDM845_TE2_MASK \ (PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2)) #define PINGPONG_SM8150_MASK \ - (BIT(DPU_PINGPONG_DITHER)) + (BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_DSC)) #define CTL_SC7280_MASK \ (BIT(DPU_CTL_ACTIVE_CFG) | \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 6ee48f0..83854e8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -144,7 +144,8 @@ enum { * @DPU_PINGPONG_TE2Additional tear check block for split pipes * @DPU_PINGPONG_SPLIT PP block supports split fifo * @DPU_PINGPONG_SLAVE PP block is a suitable slave for split fifo - * @DPU_PINGPONG_DITHER,Dither blocks + * @DPU_PINGPONG_DITHER Dither blocks + * @DPU_PINGPONG_DSCPP block supports DSC * @DPU_PINGPONG_MAX */ enum { @@ -153,6 +154,7 @@ enum { DPU_PINGPONG_SPLIT, DPU_PINGPONG_SLAVE, DPU_PINGPONG_DITHER, + DPU_PINGPONG_DSC, DPU_PINGPONG_MAX }; -- 2.7.4
[Freedreno] [PATCH] drm/msm: Use struct fb_info.screen_buffer
The fbdev framebuffer is in system memory. Store the address in the field 'screen_buffer'. Fixes the following sparse warning. ../drivers/gpu/drm/msm/msm_fbdev.c:124:26: warning: incorrect type in assignment (different address spaces) ../drivers/gpu/drm/msm/msm_fbdev.c:124:26:expected char [noderef] __iomem *screen_base ../drivers/gpu/drm/msm/msm_fbdev.c:124:26:got void * Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/msm/msm_fbdev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index 2ebc86381e1c..ce0ba6d1979a 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c @@ -121,9 +121,9 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, drm_fb_helper_fill_info(fbi, helper, sizes); - fbi->screen_base = msm_gem_get_vaddr(bo); - if (IS_ERR(fbi->screen_base)) { - ret = PTR_ERR(fbi->screen_base); + fbi->screen_buffer = msm_gem_get_vaddr(bo); + if (IS_ERR(fbi->screen_buffer)) { + ret = PTR_ERR(fbi->screen_buffer); goto fail; } fbi->screen_size = bo->size; -- 2.40.1