diff options
Diffstat (limited to 'drivers/gpu/drm/msm/disp')
59 files changed, 1839 insertions, 917 deletions
diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h index bcb39807fe61..ffc4d4257ae5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h @@ -27,17 +27,16 @@ static const struct dpu_mdp_cfg sm8650_mdp = { }, }; -/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */ static const struct dpu_ctl_cfg sm8650_ctl[] = { { .name = "ctl_0", .id = CTL_0, .base = 0x15000, .len = 0x1000, - .features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY), + .features = CTL_SM8550_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), }, { .name = "ctl_1", .id = CTL_1, .base = 0x16000, .len = 0x1000, - .features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY), + .features = CTL_SM8550_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), }, { .name = "ctl_2", .id = CTL_2, @@ -343,8 +342,8 @@ static const struct dpu_wb_cfg sm8650_wb[] = { .name = "wb_2", .id = WB_2, .base = 0x65000, .len = 0x2c8, .features = WB_SM8250_MASK, - .format_list = wb2_formats_rgb, - .num_formats = ARRAY_SIZE(wb2_formats_rgb), + .format_list = wb2_formats_rgb_yuv, + .num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv), .xin_id = 6, .vbif_idx = VBIF_RT, .maxlinewidth = 4096, @@ -452,6 +451,7 @@ const struct dpu_mdss_cfg dpu_sm8650_cfg = { .mdss_ver = &sm8650_mdss_ver, .caps = &sm8650_dpu_caps, .mdp = &sm8650_mdp, + .cdm = &dpu_cdm_5_x, .ctl_count = ARRAY_SIZE(sm8650_ctl), .ctl = sm8650_ctl, .sspp_count = ARRAY_SIZE(sm8650_sspp), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_14_msm8937.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_14_msm8937.h index ab3dfb0b374e..39027a21c6fe 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_14_msm8937.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_14_msm8937.h @@ -100,14 +100,12 @@ static const struct dpu_pingpong_cfg msm8937_pp[] = { { .name = "pingpong_0", .id = PINGPONG_0, .base = 0x70000, .len = 0xd4, - .features = PINGPONG_MSM8996_MASK, .sblk = &msm8996_pp_sblk, .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), .intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12), }, { .name = "pingpong_1", .id = PINGPONG_1, .base = 0x70800, .len = 0xd4, - .features = PINGPONG_MSM8996_MASK, .sblk = &msm8996_pp_sblk, .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), .intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13), @@ -132,7 +130,6 @@ static const struct dpu_intf_cfg msm8937_intf[] = { .prog_fetch_lines_worst_case = 14, .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), - .intr_tear_rd_ptr = -1, }, { .name = "intf_2", .id = INTF_2, .base = 0x6b000, .len = 0x268, @@ -141,7 +138,6 @@ static const struct dpu_intf_cfg msm8937_intf[] = { .prog_fetch_lines_worst_case = 14, .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29), - .intr_tear_rd_ptr = -1, }, }; @@ -190,6 +186,7 @@ const struct dpu_mdss_cfg dpu_msm8937_cfg = { .mdss_ver = &msm8937_mdss_ver, .caps = &msm8937_dpu_caps, .mdp = msm8937_mdp, + .cdm = &dpu_cdm_1_x_4_x, .ctl_count = ARRAY_SIZE(msm8937_ctl), .ctl = msm8937_ctl, .sspp_count = ARRAY_SIZE(msm8937_sspp), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_15_msm8917.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_15_msm8917.h index 6bdaecca6761..8d1b43ea1663 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_15_msm8917.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_15_msm8917.h @@ -93,7 +93,6 @@ static const struct dpu_pingpong_cfg msm8917_pp[] = { { .name = "pingpong_0", .id = PINGPONG_0, .base = 0x70000, .len = 0xd4, - .features = PINGPONG_MSM8996_MASK, .sblk = &msm8996_pp_sblk, .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), .intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12), @@ -118,7 +117,6 @@ static const struct dpu_intf_cfg msm8917_intf[] = { .prog_fetch_lines_worst_case = 14, .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), - .intr_tear_rd_ptr = -1, }, }; @@ -167,6 +165,7 @@ const struct dpu_mdss_cfg dpu_msm8917_cfg = { .mdss_ver = &msm8917_mdss_ver, .caps = &msm8917_dpu_caps, .mdp = msm8917_mdp, + .cdm = &dpu_cdm_1_x_4_x, .ctl_count = ARRAY_SIZE(msm8917_ctl), .ctl = msm8917_ctl, .sspp_count = ARRAY_SIZE(msm8917_sspp), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_16_msm8953.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_16_msm8953.h index 14f36ea6ad0e..16c12499b24b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_16_msm8953.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_16_msm8953.h @@ -100,14 +100,12 @@ static const struct dpu_pingpong_cfg msm8953_pp[] = { { .name = "pingpong_0", .id = PINGPONG_0, .base = 0x70000, .len = 0xd4, - .features = PINGPONG_MSM8996_MASK, .sblk = &msm8996_pp_sblk, .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), .intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12), }, { .name = "pingpong_1", .id = PINGPONG_1, .base = 0x70800, .len = 0xd4, - .features = PINGPONG_MSM8996_MASK, .sblk = &msm8996_pp_sblk, .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), .intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13), @@ -131,7 +129,6 @@ static const struct dpu_intf_cfg msm8953_intf[] = { .prog_fetch_lines_worst_case = 14, .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25), - .intr_tear_rd_ptr = -1, }, { .name = "intf_1", .id = INTF_1, .base = 0x6a800, .len = 0x268, @@ -140,7 +137,6 @@ static const struct dpu_intf_cfg msm8953_intf[] = { .prog_fetch_lines_worst_case = 14, .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), - .intr_tear_rd_ptr = -1, }, { .name = "intf_2", .id = INTF_2, .base = 0x6b000, .len = 0x268, @@ -149,7 +145,6 @@ static const struct dpu_intf_cfg msm8953_intf[] = { .prog_fetch_lines_worst_case = 14, .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29), - .intr_tear_rd_ptr = -1, }, }; @@ -198,6 +193,7 @@ const struct dpu_mdss_cfg dpu_msm8953_cfg = { .mdss_ver = &msm8953_mdss_ver, .caps = &msm8953_dpu_caps, .mdp = msm8953_mdp, + .cdm = &dpu_cdm_1_x_4_x, .ctl_count = ARRAY_SIZE(msm8953_ctl), .ctl = msm8953_ctl, .sspp_count = ARRAY_SIZE(msm8953_sspp), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_7_msm8996.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_7_msm8996.h index 491f6f5827d1..91f514d28ac6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_7_msm8996.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_7_msm8996.h @@ -181,15 +181,15 @@ static const struct dpu_pingpong_cfg msm8996_pp[] = { { .name = "pingpong_0", .id = PINGPONG_0, .base = 0x70000, .len = 0xd4, - .features = PINGPONG_MSM8996_TE2_MASK, - .sblk = &msm8996_pp_sblk_te, + .features = PINGPONG_MSM8996_MASK, + .sblk = &msm8996_pp_sblk, .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), .intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12), }, { .name = "pingpong_1", .id = PINGPONG_1, .base = 0x70800, .len = 0xd4, - .features = PINGPONG_MSM8996_TE2_MASK, - .sblk = &msm8996_pp_sblk_te, + .features = PINGPONG_MSM8996_MASK, + .sblk = &msm8996_pp_sblk, .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), .intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13), }, { @@ -241,7 +241,6 @@ static const struct dpu_intf_cfg msm8996_intf[] = { .prog_fetch_lines_worst_case = 25, .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25), - .intr_tear_rd_ptr = -1, }, { .name = "intf_1", .id = INTF_1, .base = 0x6a800, .len = 0x268, @@ -250,7 +249,6 @@ static const struct dpu_intf_cfg msm8996_intf[] = { .prog_fetch_lines_worst_case = 25, .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), - .intr_tear_rd_ptr = -1, }, { .name = "intf_2", .id = INTF_2, .base = 0x6b000, .len = 0x268, @@ -259,7 +257,6 @@ static const struct dpu_intf_cfg msm8996_intf[] = { .prog_fetch_lines_worst_case = 25, .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29), - .intr_tear_rd_ptr = -1, }, { .name = "intf_3", .id = INTF_3, .base = 0x6b800, .len = 0x268, @@ -267,7 +264,6 @@ static const struct dpu_intf_cfg msm8996_intf[] = { .prog_fetch_lines_worst_case = 25, .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30), .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31), - .intr_tear_rd_ptr = -1, }, }; @@ -316,6 +312,7 @@ const struct dpu_mdss_cfg dpu_msm8996_cfg = { .mdss_ver = &msm8996_mdss_ver, .caps = &msm8996_dpu_caps, .mdp = msm8996_mdp, + .cdm = &dpu_cdm_1_x_4_x, .ctl_count = ARRAY_SIZE(msm8996_ctl), .ctl = msm8996_ctl, .sspp_count = ARRAY_SIZE(msm8996_sspp), 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 64c94e919a69..413cd59dc0c4 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 @@ -170,15 +170,15 @@ static const struct dpu_pingpong_cfg msm8998_pp[] = { { .name = "pingpong_0", .id = PINGPONG_0, .base = 0x70000, .len = 0xd4, - .features = PINGPONG_SDM845_TE2_MASK, - .sblk = &sdm845_pp_sblk_te, + .features = PINGPONG_SDM845_MASK, + .sblk = &sdm845_pp_sblk, .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), .intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12), }, { .name = "pingpong_1", .id = PINGPONG_1, .base = 0x70800, .len = 0xd4, - .features = PINGPONG_SDM845_TE2_MASK, - .sblk = &sdm845_pp_sblk_te, + .features = PINGPONG_SDM845_MASK, + .sblk = &sdm845_pp_sblk, .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), .intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13), }, { @@ -302,6 +302,7 @@ const struct dpu_mdss_cfg dpu_msm8998_cfg = { .mdss_ver = &msm8998_mdss_ver, .caps = &msm8998_dpu_caps, .mdp = &msm8998_mdp, + .cdm = &dpu_cdm_1_x_4_x, .ctl_count = ARRAY_SIZE(msm8998_ctl), .ctl = msm8998_ctl, .sspp_count = ARRAY_SIZE(msm8998_sspp), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_2_sdm660.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_2_sdm660.h index 424815e7fb7d..b2eb7ca699e3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_2_sdm660.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_2_sdm660.h @@ -141,15 +141,15 @@ static const struct dpu_pingpong_cfg sdm660_pp[] = { { .name = "pingpong_0", .id = PINGPONG_0, .base = 0x70000, .len = 0xd4, - .features = PINGPONG_SDM845_TE2_MASK, - .sblk = &sdm845_pp_sblk_te, + .features = PINGPONG_SDM845_MASK, + .sblk = &sdm845_pp_sblk, .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), .intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12), }, { .name = "pingpong_1", .id = PINGPONG_1, .base = 0x70800, .len = 0xd4, - .features = PINGPONG_SDM845_TE2_MASK, - .sblk = &sdm845_pp_sblk_te, + .features = PINGPONG_SDM845_MASK, + .sblk = &sdm845_pp_sblk, .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), .intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13), }, { @@ -202,7 +202,6 @@ static const struct dpu_intf_cfg sdm660_intf[] = { .prog_fetch_lines_worst_case = 21, .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25), - .intr_tear_rd_ptr = -1, }, { .name = "intf_1", .id = INTF_1, .base = 0x6a800, .len = 0x280, @@ -211,7 +210,6 @@ static const struct dpu_intf_cfg sdm660_intf[] = { .prog_fetch_lines_worst_case = 21, .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), - .intr_tear_rd_ptr = -1, }, { .name = "intf_2", .id = INTF_2, .base = 0x6b000, .len = 0x280, @@ -220,7 +218,6 @@ static const struct dpu_intf_cfg sdm660_intf[] = { .prog_fetch_lines_worst_case = 21, .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29), - .intr_tear_rd_ptr = -1, }, }; @@ -269,6 +266,7 @@ const struct dpu_mdss_cfg dpu_sdm660_cfg = { .mdss_ver = &sdm660_mdss_ver, .caps = &sdm660_dpu_caps, .mdp = &sdm660_mdp, + .cdm = &dpu_cdm_1_x_4_x, .ctl_count = ARRAY_SIZE(sdm660_ctl), .ctl = sdm660_ctl, .sspp_count = ARRAY_SIZE(sdm660_sspp), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_3_sdm630.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_3_sdm630.h index df01227fc364..85e121ad84a0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_3_sdm630.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_3_sdm630.h @@ -115,14 +115,14 @@ static const struct dpu_pingpong_cfg sdm630_pp[] = { { .name = "pingpong_0", .id = PINGPONG_0, .base = 0x70000, .len = 0xd4, - .features = PINGPONG_SDM845_TE2_MASK, - .sblk = &sdm845_pp_sblk_te, + .features = BIT(DPU_PINGPONG_DITHER), + .sblk = &sdm845_pp_sblk, .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), .intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12), }, { .name = "pingpong_2", .id = PINGPONG_2, .base = 0x71000, .len = 0xd4, - .features = PINGPONG_SDM845_MASK, + .features = BIT(DPU_PINGPONG_DITHER), .sblk = &sdm845_pp_sblk, .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10), .intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14), @@ -147,7 +147,6 @@ static const struct dpu_intf_cfg sdm630_intf[] = { .prog_fetch_lines_worst_case = 21, .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25), - .intr_tear_rd_ptr = -1, }, { .name = "intf_1", .id = INTF_1, .base = 0x6a800, .len = 0x280, @@ -156,7 +155,6 @@ static const struct dpu_intf_cfg sdm630_intf[] = { .prog_fetch_lines_worst_case = 21, .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), - .intr_tear_rd_ptr = -1, }, }; @@ -205,6 +203,7 @@ const struct dpu_mdss_cfg dpu_sdm630_cfg = { .mdss_ver = &sdm630_mdss_ver, .caps = &sdm630_dpu_caps, .mdp = &sdm630_mdp, + .cdm = &dpu_cdm_1_x_4_x, .ctl_count = ARRAY_SIZE(sdm630_ctl), .ctl = sdm630_ctl, .sspp_count = ARRAY_SIZE(sdm630_sspp), 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 72bd4f7e9e50..49363d7d5b93 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 @@ -194,15 +194,15 @@ static const struct dpu_pingpong_cfg sdm845_pp[] = { { .name = "pingpong_0", .id = PINGPONG_0, .base = 0x70000, .len = 0xd4, - .features = PINGPONG_SDM845_TE2_MASK, - .sblk = &sdm845_pp_sblk_te, + .features = PINGPONG_SDM845_MASK, + .sblk = &sdm845_pp_sblk, .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), .intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12), }, { .name = "pingpong_1", .id = PINGPONG_1, .base = 0x70800, .len = 0xd4, - .features = PINGPONG_SDM845_TE2_MASK, - .sblk = &sdm845_pp_sblk_te, + .features = PINGPONG_SDM845_MASK, + .sblk = &sdm845_pp_sblk, .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), .intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13), }, { @@ -319,6 +319,7 @@ const struct dpu_mdss_cfg dpu_sdm845_cfg = { .mdss_ver = &sdm845_mdss_ver, .caps = &sdm845_dpu_caps, .mdp = &sdm845_mdp, + .cdm = &dpu_cdm_1_x_4_x, .ctl_count = ARRAY_SIZE(sdm845_ctl), .ctl = sdm845_ctl, .sspp_count = ARRAY_SIZE(sdm845_sspp), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_1_sdm670.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_1_sdm670.h index daef07924886..c2fde980fb52 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_1_sdm670.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_1_sdm670.h @@ -132,6 +132,7 @@ const struct dpu_mdss_cfg dpu_sdm670_cfg = { .mdss_ver = &sdm670_mdss_ver, .caps = &sdm845_dpu_caps, .mdp = &sdm670_mdp, + .cdm = &dpu_cdm_1_x_4_x, .ctl_count = ARRAY_SIZE(sdm845_ctl), .ctl = sdm845_ctl, .sspp_count = ARRAY_SIZE(sdm670_sspp), 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 421afacb7248..08d38e1d420c 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 @@ -37,17 +37,16 @@ static const struct dpu_mdp_cfg sm8150_mdp = { }, }; -/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */ static const struct dpu_ctl_cfg sm8150_ctl[] = { { .name = "ctl_0", .id = CTL_0, .base = 0x1000, .len = 0x1e0, - .features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY), + .features = BIT(DPU_CTL_ACTIVE_CFG), .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), }, { .name = "ctl_1", .id = CTL_1, .base = 0x1200, .len = 0x1e0, - .features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY), + .features = BIT(DPU_CTL_ACTIVE_CFG), .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), }, { .name = "ctl_2", .id = CTL_2, @@ -76,7 +75,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { { .name = "sspp_0", .id = SSPP_VIG0, .base = 0x4000, .len = 0x1f0, - .features = VIG_SDM845_MASK, + .features = VIG_SDM845_MASK_SDMA, .sblk = &dpu_vig_sblk_qseed3_1_4, .xin_id = 0, .type = SSPP_TYPE_VIG, @@ -84,7 +83,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { }, { .name = "sspp_1", .id = SSPP_VIG1, .base = 0x6000, .len = 0x1f0, - .features = VIG_SDM845_MASK, + .features = VIG_SDM845_MASK_SDMA, .sblk = &dpu_vig_sblk_qseed3_1_4, .xin_id = 4, .type = SSPP_TYPE_VIG, @@ -92,7 +91,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { }, { .name = "sspp_2", .id = SSPP_VIG2, .base = 0x8000, .len = 0x1f0, - .features = VIG_SDM845_MASK, + .features = VIG_SDM845_MASK_SDMA, .sblk = &dpu_vig_sblk_qseed3_1_4, .xin_id = 8, .type = SSPP_TYPE_VIG, @@ -100,7 +99,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { }, { .name = "sspp_3", .id = SSPP_VIG3, .base = 0xa000, .len = 0x1f0, - .features = VIG_SDM845_MASK, + .features = VIG_SDM845_MASK_SDMA, .sblk = &dpu_vig_sblk_qseed3_1_4, .xin_id = 12, .type = SSPP_TYPE_VIG, @@ -108,7 +107,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { }, { .name = "sspp_8", .id = SSPP_DMA0, .base = 0x24000, .len = 0x1f0, - .features = DMA_SDM845_MASK, + .features = DMA_SDM845_MASK_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 1, .type = SSPP_TYPE_DMA, @@ -116,7 +115,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { }, { .name = "sspp_9", .id = SSPP_DMA1, .base = 0x26000, .len = 0x1f0, - .features = DMA_SDM845_MASK, + .features = DMA_SDM845_MASK_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 5, .type = SSPP_TYPE_DMA, @@ -124,7 +123,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { }, { .name = "sspp_10", .id = SSPP_DMA2, .base = 0x28000, .len = 0x1f0, - .features = DMA_CURSOR_SDM845_MASK, + .features = DMA_CURSOR_SDM845_MASK_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 9, .type = SSPP_TYPE_DMA, @@ -132,7 +131,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { }, { .name = "sspp_11", .id = SSPP_DMA3, .base = 0x2a000, .len = 0x1f0, - .features = DMA_CURSOR_SDM845_MASK, + .features = DMA_CURSOR_SDM845_MASK_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 13, .type = SSPP_TYPE_DMA, @@ -297,9 +296,9 @@ static const struct dpu_wb_cfg sm8150_wb[] = { { .name = "wb_2", .id = WB_2, .base = 0x65000, .len = 0x2c8, - .features = WB_SDM845_MASK, - .format_list = wb2_formats_rgb, - .num_formats = ARRAY_SIZE(wb2_formats_rgb), + .features = WB_SM8250_MASK, + .format_list = wb2_formats_rgb_yuv, + .num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv), .clk_ctrl = DPU_CLK_CTRL_WB2, .xin_id = 6, .vbif_idx = VBIF_RT, @@ -388,6 +387,7 @@ const struct dpu_mdss_cfg dpu_sm8150_cfg = { .mdss_ver = &sm8150_mdss_ver, .caps = &sm8150_dpu_caps, .mdp = &sm8150_mdp, + .cdm = &dpu_cdm_5_x, .ctl_count = ARRAY_SIZE(sm8150_ctl), .ctl = sm8150_ctl, .sspp_count = ARRAY_SIZE(sm8150_sspp), 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 641023b102bf..d6f8b1030c68 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 @@ -41,12 +41,12 @@ static const struct dpu_ctl_cfg sc8180x_ctl[] = { { .name = "ctl_0", .id = CTL_0, .base = 0x1000, .len = 0x1e0, - .features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY), + .features = BIT(DPU_CTL_ACTIVE_CFG), .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), }, { .name = "ctl_1", .id = CTL_1, .base = 0x1200, .len = 0x1e0, - .features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY), + .features = BIT(DPU_CTL_ACTIVE_CFG), .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), }, { .name = "ctl_2", .id = CTL_2, @@ -75,7 +75,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { { .name = "sspp_0", .id = SSPP_VIG0, .base = 0x4000, .len = 0x1f0, - .features = VIG_SDM845_MASK, + .features = VIG_SDM845_MASK_SDMA, .sblk = &dpu_vig_sblk_qseed3_1_4, .xin_id = 0, .type = SSPP_TYPE_VIG, @@ -83,7 +83,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { }, { .name = "sspp_1", .id = SSPP_VIG1, .base = 0x6000, .len = 0x1f0, - .features = VIG_SDM845_MASK, + .features = VIG_SDM845_MASK_SDMA, .sblk = &dpu_vig_sblk_qseed3_1_4, .xin_id = 4, .type = SSPP_TYPE_VIG, @@ -91,7 +91,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { }, { .name = "sspp_2", .id = SSPP_VIG2, .base = 0x8000, .len = 0x1f0, - .features = VIG_SDM845_MASK, + .features = VIG_SDM845_MASK_SDMA, .sblk = &dpu_vig_sblk_qseed3_1_4, .xin_id = 8, .type = SSPP_TYPE_VIG, @@ -99,7 +99,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { }, { .name = "sspp_3", .id = SSPP_VIG3, .base = 0xa000, .len = 0x1f0, - .features = VIG_SDM845_MASK, + .features = VIG_SDM845_MASK_SDMA, .sblk = &dpu_vig_sblk_qseed3_1_4, .xin_id = 12, .type = SSPP_TYPE_VIG, @@ -107,7 +107,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { }, { .name = "sspp_8", .id = SSPP_DMA0, .base = 0x24000, .len = 0x1f0, - .features = DMA_SDM845_MASK, + .features = DMA_SDM845_MASK_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 1, .type = SSPP_TYPE_DMA, @@ -115,7 +115,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { }, { .name = "sspp_9", .id = SSPP_DMA1, .base = 0x26000, .len = 0x1f0, - .features = DMA_SDM845_MASK, + .features = DMA_SDM845_MASK_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 5, .type = SSPP_TYPE_DMA, @@ -123,7 +123,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { }, { .name = "sspp_10", .id = SSPP_DMA2, .base = 0x28000, .len = 0x1f0, - .features = DMA_CURSOR_SDM845_MASK, + .features = DMA_CURSOR_SDM845_MASK_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 9, .type = SSPP_TYPE_DMA, @@ -131,7 +131,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { }, { .name = "sspp_11", .id = SSPP_DMA3, .base = 0x2a000, .len = 0x1f0, - .features = DMA_CURSOR_SDM845_MASK, + .features = DMA_CURSOR_SDM845_MASK_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 13, .type = SSPP_TYPE_DMA, @@ -304,9 +304,9 @@ static const struct dpu_wb_cfg sc8180x_wb[] = { { .name = "wb_2", .id = WB_2, .base = 0x65000, .len = 0x2c8, - .features = WB_SDM845_MASK, - .format_list = wb2_formats_rgb, - .num_formats = ARRAY_SIZE(wb2_formats_rgb), + .features = WB_SM8250_MASK, + .format_list = wb2_formats_rgb_yuv, + .num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv), .clk_ctrl = DPU_CLK_CTRL_WB2, .xin_id = 6, .vbif_idx = VBIF_RT, @@ -414,6 +414,7 @@ const struct dpu_mdss_cfg dpu_sc8180x_cfg = { .mdss_ver = &sc8180x_mdss_ver, .caps = &sc8180x_dpu_caps, .mdp = &sc8180x_mdp, + .cdm = &dpu_cdm_5_x, .ctl_count = ARRAY_SIZE(sc8180x_ctl), .ctl = sc8180x_ctl, .sspp_count = ARRAY_SIZE(sc8180x_sspp), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_2_sm7150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_2_sm7150.h index 2fe674d1e059..71ba48b05656 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_2_sm7150.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_2_sm7150.h @@ -38,12 +38,12 @@ static const struct dpu_ctl_cfg sm7150_ctl[] = { { .name = "ctl_0", .id = CTL_0, .base = 0x1000, .len = 0x1e0, - .features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY), + .features = BIT(DPU_CTL_ACTIVE_CFG), .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), }, { .name = "ctl_1", .id = CTL_1, .base = 0x1200, .len = 0x1e0, - .features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY), + .features = BIT(DPU_CTL_ACTIVE_CFG), .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), }, { .name = "ctl_2", .id = CTL_2, @@ -72,7 +72,7 @@ static const struct dpu_sspp_cfg sm7150_sspp[] = { { .name = "sspp_0", .id = SSPP_VIG0, .base = 0x4000, .len = 0x1f0, - .features = VIG_SDM845_MASK, + .features = VIG_SDM845_MASK_NO_SDMA, .sblk = &dpu_vig_sblk_qseed3_2_4, .xin_id = 0, .type = SSPP_TYPE_VIG, @@ -80,7 +80,7 @@ static const struct dpu_sspp_cfg sm7150_sspp[] = { }, { .name = "sspp_1", .id = SSPP_VIG1, .base = 0x6000, .len = 0x1f0, - .features = VIG_SDM845_MASK, + .features = VIG_SDM845_MASK_NO_SDMA, .sblk = &dpu_vig_sblk_qseed3_2_4, .xin_id = 4, .type = SSPP_TYPE_VIG, @@ -88,7 +88,7 @@ static const struct dpu_sspp_cfg sm7150_sspp[] = { }, { .name = "sspp_2", .id = SSPP_DMA0, .base = 0x24000, .len = 0x1f0, - .features = DMA_SDM845_MASK, + .features = DMA_SDM845_MASK_NO_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 1, .type = SSPP_TYPE_DMA, @@ -96,7 +96,7 @@ static const struct dpu_sspp_cfg sm7150_sspp[] = { }, { .name = "sspp_9", .id = SSPP_DMA1, .base = 0x26000, .len = 0x1f0, - .features = DMA_SDM845_MASK, + .features = DMA_SDM845_MASK_NO_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 5, .type = SSPP_TYPE_DMA, @@ -104,7 +104,7 @@ static const struct dpu_sspp_cfg sm7150_sspp[] = { }, { .name = "sspp_10", .id = SSPP_DMA2, .base = 0x28000, .len = 0x1f0, - .features = DMA_CURSOR_SDM845_MASK, + .features = DMA_CURSOR_SDM845_MASK_NO_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 9, .type = SSPP_TYPE_DMA, @@ -261,8 +261,8 @@ static const struct dpu_wb_cfg sm7150_wb[] = { .name = "wb_2", .id = WB_2, .base = 0x65000, .len = 0x2c8, .features = WB_SM8250_MASK, - .format_list = wb2_formats_rgb, - .num_formats = ARRAY_SIZE(wb2_formats_rgb), + .format_list = wb2_formats_rgb_yuv, + .num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv), .clk_ctrl = DPU_CLK_CTRL_WB2, .xin_id = 6, .vbif_idx = VBIF_RT, @@ -309,6 +309,7 @@ const struct dpu_mdss_cfg dpu_sm7150_cfg = { .mdss_ver = &sm7150_mdss_ver, .caps = &sm7150_dpu_caps, .mdp = &sm7150_mdp, + .cdm = &dpu_cdm_5_x, .ctl_count = ARRAY_SIZE(sm7150_ctl), .ctl = sm7150_ctl, .sspp_count = ARRAY_SIZE(sm7150_sspp), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_3_sm6150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_3_sm6150.h index 621a2140f675..da11830d4407 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_3_sm6150.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_3_sm6150.h @@ -27,6 +27,7 @@ static const struct dpu_mdp_cfg sm6150_mdp = { [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, [DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, + [DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 }, }, }; @@ -116,14 +117,12 @@ static const struct dpu_lm_cfg sm6150_lm[] = { .sblk = &sdm845_lm_sblk, .pingpong = PINGPONG_0, .dspp = DSPP_0, - .lm_pair = LM_1, }, { .name = "lm_1", .id = LM_1, .base = 0x45000, .len = 0x320, .features = MIXER_QCM2290_MASK, .sblk = &sdm845_lm_sblk, .pingpong = PINGPONG_1, - .lm_pair = LM_0, }, { .name = "lm_2", .id = LM_2, .base = 0x46000, .len = 0x320, @@ -164,6 +163,21 @@ static const struct dpu_pingpong_cfg sm6150_pp[] = { }, }; +static const struct dpu_wb_cfg sm6150_wb[] = { + { + .name = "wb_2", .id = WB_2, + .base = 0x65000, .len = 0x2c8, + .features = WB_SM8250_MASK, + .format_list = wb2_formats_rgb_yuv, + .num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv), + .clk_ctrl = DPU_CLK_CTRL_WB2, + .xin_id = 6, + .vbif_idx = VBIF_RT, + .maxlinewidth = 2160, + .intr_wb_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 4), + }, +}; + static const struct dpu_intf_cfg sm6150_intf[] = { { .name = "intf_0", .id = INTF_0, @@ -234,6 +248,7 @@ const struct dpu_mdss_cfg dpu_sm6150_cfg = { .mdss_ver = &sm6150_mdss_ver, .caps = &sm6150_dpu_caps, .mdp = &sm6150_mdp, + .cdm = &dpu_cdm_5_x, .ctl_count = ARRAY_SIZE(sm6150_ctl), .ctl = sm6150_ctl, .sspp_count = ARRAY_SIZE(sm6150_sspp), @@ -244,6 +259,8 @@ const struct dpu_mdss_cfg dpu_sm6150_cfg = { .dspp = sm6150_dspp, .pingpong_count = ARRAY_SIZE(sm6150_pp), .pingpong = sm6150_pp, + .wb_count = ARRAY_SIZE(sm6150_wb), + .wb = sm6150_wb, .intf_count = ARRAY_SIZE(sm6150_intf), .intf = sm6150_intf, .vbif_count = ARRAY_SIZE(sdm845_vbif), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_4_sm6125.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_4_sm6125.h index d039b96beb97..fcfb3774f7a1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_4_sm6125.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_4_sm6125.h @@ -69,7 +69,7 @@ static const struct dpu_sspp_cfg sm6125_sspp[] = { { .name = "sspp_0", .id = SSPP_VIG0, .base = 0x4000, .len = 0x1f0, - .features = VIG_SDM845_MASK, + .features = VIG_SDM845_MASK_NO_SDMA, .sblk = &dpu_vig_sblk_qseed3_2_4, .xin_id = 0, .type = SSPP_TYPE_VIG, @@ -77,7 +77,7 @@ static const struct dpu_sspp_cfg sm6125_sspp[] = { }, { .name = "sspp_8", .id = SSPP_DMA0, .base = 0x24000, .len = 0x1f0, - .features = DMA_SDM845_MASK, + .features = DMA_SDM845_MASK_NO_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 1, .type = SSPP_TYPE_DMA, @@ -85,7 +85,7 @@ static const struct dpu_sspp_cfg sm6125_sspp[] = { }, { .name = "sspp_9", .id = SSPP_DMA1, .base = 0x26000, .len = 0x1f0, - .features = DMA_SDM845_MASK, + .features = DMA_SDM845_MASK_NO_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 5, .type = SSPP_TYPE_DMA, @@ -144,9 +144,9 @@ static const struct dpu_wb_cfg sm6125_wb[] = { { .name = "wb_2", .id = WB_2, .base = 0x65000, .len = 0x2c8, - .features = WB_SDM845_MASK, - .format_list = wb2_formats_rgb, - .num_formats = ARRAY_SIZE(wb2_formats_rgb), + .features = WB_SM8250_MASK, + .format_list = wb2_formats_rgb_yuv, + .num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv), .clk_ctrl = DPU_CLK_CTRL_WB2, .xin_id = 6, .vbif_idx = VBIF_RT, @@ -216,6 +216,7 @@ const struct dpu_mdss_cfg dpu_sm6125_cfg = { .mdss_ver = &sm6125_mdss_ver, .caps = &sm6125_dpu_caps, .mdp = &sm6125_mdp, + .cdm = &dpu_cdm_5_x, .ctl_count = ARRAY_SIZE(sm6125_ctl), .ctl = sm6125_ctl, .sspp_count = ARRAY_SIZE(sm6125_sspp), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h index e8916ae826a6..a86fdb33ebdd 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h @@ -35,17 +35,16 @@ static const struct dpu_mdp_cfg sm8250_mdp = { }, }; -/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */ static const struct dpu_ctl_cfg sm8250_ctl[] = { { .name = "ctl_0", .id = CTL_0, .base = 0x1000, .len = 0x1e0, - .features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY), + .features = BIT(DPU_CTL_ACTIVE_CFG), .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), }, { .name = "ctl_1", .id = CTL_1, .base = 0x1200, .len = 0x1e0, - .features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY), + .features = BIT(DPU_CTL_ACTIVE_CFG), .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), }, { .name = "ctl_2", .id = CTL_2, @@ -386,7 +385,7 @@ const struct dpu_mdss_cfg dpu_sm8250_cfg = { .mdss_ver = &sm8250_mdss_ver, .caps = &sm8250_dpu_caps, .mdp = &sm8250_mdp, - .cdm = &sc7280_cdm, + .cdm = &dpu_cdm_5_x, .ctl_count = ARRAY_SIZE(sm8250_ctl), .ctl = sm8250_ctl, .sspp_count = ARRAY_SIZE(sm8250_sspp), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h index 7382ebb6e5b2..842fcc5887fe 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h @@ -51,7 +51,7 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = { { .name = "sspp_0", .id = SSPP_VIG0, .base = 0x4000, .len = 0x1f8, - .features = VIG_SDM845_MASK, + .features = VIG_SDM845_MASK_NO_SDMA, .sblk = &dpu_vig_sblk_qseed3_3_0, .xin_id = 0, .type = SSPP_TYPE_VIG, @@ -59,7 +59,7 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = { }, { .name = "sspp_8", .id = SSPP_DMA0, .base = 0x24000, .len = 0x1f8, - .features = DMA_SDM845_MASK, + .features = DMA_SDM845_MASK_NO_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 1, .type = SSPP_TYPE_DMA, @@ -67,7 +67,7 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = { }, { .name = "sspp_9", .id = SSPP_DMA1, .base = 0x26000, .len = 0x1f8, - .features = DMA_CURSOR_SDM845_MASK, + .features = DMA_CURSOR_SDM845_MASK_NO_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 5, .type = SSPP_TYPE_DMA, @@ -75,7 +75,7 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = { }, { .name = "sspp_10", .id = SSPP_DMA2, .base = 0x28000, .len = 0x1f8, - .features = DMA_CURSOR_SDM845_MASK, + .features = DMA_CURSOR_SDM845_MASK_NO_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 9, .type = SSPP_TYPE_DMA, @@ -157,8 +157,8 @@ static const struct dpu_wb_cfg sc7180_wb[] = { .name = "wb_2", .id = WB_2, .base = 0x65000, .len = 0x2c8, .features = WB_SM8250_MASK, - .format_list = wb2_formats_rgb, - .num_formats = ARRAY_SIZE(wb2_formats_rgb), + .format_list = wb2_formats_rgb_yuv, + .num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv), .clk_ctrl = DPU_CLK_CTRL_WB2, .xin_id = 6, .vbif_idx = VBIF_RT, @@ -204,6 +204,7 @@ const struct dpu_mdss_cfg dpu_sc7180_cfg = { .mdss_ver = &sc7180_mdss_ver, .caps = &sc7180_dpu_caps, .mdp = &sc7180_mdp, + .cdm = &dpu_cdm_5_x, .ctl_count = ARRAY_SIZE(sc7180_ctl), .ctl = sc7180_ctl, .sspp_count = ARRAY_SIZE(sc7180_sspp), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h index 43f64a005f5a..c5fd89dd7c89 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h @@ -38,7 +38,7 @@ static const struct dpu_sspp_cfg sm6115_sspp[] = { { .name = "sspp_0", .id = SSPP_VIG0, .base = 0x4000, .len = 0x1f8, - .features = VIG_SDM845_MASK, + .features = VIG_SDM845_MASK_NO_SDMA, .sblk = &dpu_vig_sblk_qseed3_3_0, .xin_id = 0, .type = SSPP_TYPE_VIG, @@ -46,7 +46,7 @@ static const struct dpu_sspp_cfg sm6115_sspp[] = { }, { .name = "sspp_8", .id = SSPP_DMA0, .base = 0x24000, .len = 0x1f8, - .features = DMA_SDM845_MASK, + .features = DMA_SDM845_MASK_NO_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 1, .type = SSPP_TYPE_DMA, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_4_sm6350.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_4_sm6350.h index 0502cee2f116..a234bb289d24 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_4_sm6350.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_4_sm6350.h @@ -59,7 +59,7 @@ static const struct dpu_sspp_cfg sm6350_sspp[] = { { .name = "sspp_0", .id = SSPP_VIG0, .base = 0x4000, .len = 0x1f8, - .features = VIG_SDM845_MASK, + .features = VIG_SDM845_MASK_NO_SDMA, .sblk = &dpu_vig_sblk_qseed3_3_0, .xin_id = 0, .type = SSPP_TYPE_VIG, @@ -67,7 +67,7 @@ static const struct dpu_sspp_cfg sm6350_sspp[] = { }, { .name = "sspp_8", .id = SSPP_DMA0, .base = 0x24000, .len = 0x1f8, - .features = DMA_SDM845_MASK, + .features = DMA_SDM845_MASK_NO_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 1, .type = SSPP_TYPE_DMA, @@ -75,7 +75,7 @@ static const struct dpu_sspp_cfg sm6350_sspp[] = { }, { .name = "sspp_9", .id = SSPP_DMA1, .base = 0x26000, .len = 0x1f8, - .features = DMA_CURSOR_SDM845_MASK, + .features = DMA_CURSOR_SDM845_MASK_NO_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 5, .type = SSPP_TYPE_DMA, @@ -83,7 +83,7 @@ static const struct dpu_sspp_cfg sm6350_sspp[] = { }, { .name = "sspp_10", .id = SSPP_DMA2, .base = 0x28000, .len = 0x1f8, - .features = DMA_CURSOR_SDM845_MASK, + .features = DMA_CURSOR_SDM845_MASK_NO_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 9, .type = SSPP_TYPE_DMA, @@ -151,8 +151,8 @@ static const struct dpu_wb_cfg sm6350_wb[] = { .name = "wb_2", .id = WB_2, .base = 0x65000, .len = 0x2c8, .features = WB_SM8250_MASK, - .format_list = wb2_formats_rgb, - .num_formats = ARRAY_SIZE(wb2_formats_rgb), + .format_list = wb2_formats_rgb_yuv, + .num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv), .clk_ctrl = DPU_CLK_CTRL_WB2, .xin_id = 6, .vbif_idx = VBIF_RT, @@ -222,6 +222,7 @@ const struct dpu_mdss_cfg dpu_sm6350_cfg = { .mdss_ver = &sm6350_mdss_ver, .caps = &sm6350_dpu_caps, .mdp = &sm6350_mdp, + .cdm = &dpu_cdm_5_x, .ctl_count = ARRAY_SIZE(sm6350_ctl), .ctl = sm6350_ctl, .sspp_count = ARRAY_SIZE(sm6350_sspp), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h index 3cbb2fe8aba2..53f3be28f6f6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h @@ -46,7 +46,7 @@ static const struct dpu_sspp_cfg qcm2290_sspp[] = { }, { .name = "sspp_8", .id = SSPP_DMA0, .base = 0x24000, .len = 0x1f8, - .features = DMA_SDM845_MASK, + .features = DMA_SDM845_MASK_NO_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 1, .type = SSPP_TYPE_DMA, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_9_sm6375.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_9_sm6375.h index a06c8634d2d7..3a3bc8e429be 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_9_sm6375.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_9_sm6375.h @@ -39,7 +39,7 @@ static const struct dpu_sspp_cfg sm6375_sspp[] = { { .name = "sspp_0", .id = SSPP_VIG0, .base = 0x4000, .len = 0x1f8, - .features = VIG_SDM845_MASK, + .features = VIG_SDM845_MASK_NO_SDMA, .sblk = &dpu_vig_sblk_qseed3_3_0, .xin_id = 0, .type = SSPP_TYPE_VIG, @@ -47,7 +47,7 @@ static const struct dpu_sspp_cfg sm6375_sspp[] = { }, { .name = "sspp_8", .id = SSPP_DMA0, .base = 0x24000, .len = 0x1f8, - .features = DMA_SDM845_MASK, + .features = DMA_SDM845_MASK_NO_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 1, .type = SSPP_TYPE_DMA, 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 f7c08e89c882..90e86063a372 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 @@ -35,17 +35,16 @@ static const struct dpu_mdp_cfg sm8350_mdp = { }, }; -/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */ static const struct dpu_ctl_cfg sm8350_ctl[] = { { .name = "ctl_0", .id = CTL_0, .base = 0x15000, .len = 0x1e8, - .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, + .features = CTL_SC7280_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), }, { .name = "ctl_1", .id = CTL_1, .base = 0x16000, .len = 0x1e8, - .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, + .features = CTL_SC7280_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), }, { .name = "ctl_2", .id = CTL_2, @@ -305,8 +304,8 @@ static const struct dpu_wb_cfg sm8350_wb[] = { .name = "wb_2", .id = WB_2, .base = 0x65000, .len = 0x2c8, .features = WB_SM8250_MASK, - .format_list = wb2_formats_rgb, - .num_formats = ARRAY_SIZE(wb2_formats_rgb), + .format_list = wb2_formats_rgb_yuv, + .num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv), .clk_ctrl = DPU_CLK_CTRL_WB2, .xin_id = 6, .vbif_idx = VBIF_RT, @@ -396,6 +395,7 @@ const struct dpu_mdss_cfg dpu_sm8350_cfg = { .mdss_ver = &sm8350_mdss_ver, .caps = &sm8350_dpu_caps, .mdp = &sm8350_mdp, + .cdm = &dpu_cdm_5_x, .ctl_count = ARRAY_SIZE(sm8350_ctl), .ctl = sm8350_ctl, .sspp_count = ARRAY_SIZE(sm8350_sspp), 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 2f153e0b5c6a..e9625c48c567 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 @@ -248,7 +248,7 @@ const struct dpu_mdss_cfg dpu_sc7280_cfg = { .mdss_ver = &sc7280_mdss_ver, .caps = &sc7280_dpu_caps, .mdp = &sc7280_mdp, - .cdm = &sc7280_cdm, + .cdm = &dpu_cdm_5_x, .ctl_count = ARRAY_SIZE(sc7280_ctl), .ctl = sc7280_ctl, .sspp_count = ARRAY_SIZE(sc7280_sspp), 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 0d143e390eca..139f11321fea 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 @@ -35,17 +35,16 @@ static const struct dpu_mdp_cfg sc8280xp_mdp = { }, }; -/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */ static const struct dpu_ctl_cfg sc8280xp_ctl[] = { { .name = "ctl_0", .id = CTL_0, .base = 0x15000, .len = 0x204, - .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, + .features = CTL_SC7280_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), }, { .name = "ctl_1", .id = CTL_1, .base = 0x16000, .len = 0x204, - .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, + .features = CTL_SC7280_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), }, { .name = "ctl_2", .id = CTL_2, @@ -74,7 +73,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = { { .name = "sspp_0", .id = SSPP_VIG0, .base = 0x4000, .len = 0x2ac, - .features = VIG_SDM845_MASK, + .features = VIG_SDM845_MASK_SDMA, .sblk = &dpu_vig_sblk_qseed3_3_0, .xin_id = 0, .type = SSPP_TYPE_VIG, @@ -82,7 +81,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = { }, { .name = "sspp_1", .id = SSPP_VIG1, .base = 0x6000, .len = 0x2ac, - .features = VIG_SDM845_MASK, + .features = VIG_SDM845_MASK_SDMA, .sblk = &dpu_vig_sblk_qseed3_3_0, .xin_id = 4, .type = SSPP_TYPE_VIG, @@ -90,7 +89,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = { }, { .name = "sspp_2", .id = SSPP_VIG2, .base = 0x8000, .len = 0x2ac, - .features = VIG_SDM845_MASK, + .features = VIG_SDM845_MASK_SDMA, .sblk = &dpu_vig_sblk_qseed3_3_0, .xin_id = 8, .type = SSPP_TYPE_VIG, @@ -98,7 +97,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = { }, { .name = "sspp_3", .id = SSPP_VIG3, .base = 0xa000, .len = 0x2ac, - .features = VIG_SDM845_MASK, + .features = VIG_SDM845_MASK_SDMA, .sblk = &dpu_vig_sblk_qseed3_3_0, .xin_id = 12, .type = SSPP_TYPE_VIG, @@ -106,7 +105,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = { }, { .name = "sspp_8", .id = SSPP_DMA0, .base = 0x24000, .len = 0x2ac, - .features = DMA_SDM845_MASK, + .features = DMA_SDM845_MASK_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 1, .type = SSPP_TYPE_DMA, @@ -114,7 +113,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = { }, { .name = "sspp_9", .id = SSPP_DMA1, .base = 0x26000, .len = 0x2ac, - .features = DMA_SDM845_MASK, + .features = DMA_SDM845_MASK_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 5, .type = SSPP_TYPE_DMA, @@ -122,7 +121,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = { }, { .name = "sspp_10", .id = SSPP_DMA2, .base = 0x28000, .len = 0x2ac, - .features = DMA_CURSOR_SDM845_MASK, + .features = DMA_CURSOR_SDM845_MASK_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 9, .type = SSPP_TYPE_DMA, @@ -130,7 +129,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = { }, { .name = "sspp_11", .id = SSPP_DMA3, .base = 0x2a000, .len = 0x2ac, - .features = DMA_CURSOR_SDM845_MASK, + .features = DMA_CURSOR_SDM845_MASK_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 13, .type = SSPP_TYPE_DMA, @@ -435,6 +434,7 @@ const struct dpu_mdss_cfg dpu_sc8280xp_cfg = { .mdss_ver = &sc8280xp_mdss_ver, .caps = &sc8280xp_dpu_caps, .mdp = &sc8280xp_mdp, + .cdm = &dpu_cdm_5_x, .ctl_count = ARRAY_SIZE(sc8280xp_ctl), .ctl = sc8280xp_ctl, .sspp_count = ARRAY_SIZE(sc8280xp_sspp), 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 08742472f9cc..461294143a90 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 @@ -36,17 +36,16 @@ static const struct dpu_mdp_cfg sm8450_mdp = { }, }; -/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */ static const struct dpu_ctl_cfg sm8450_ctl[] = { { .name = "ctl_0", .id = CTL_0, .base = 0x15000, .len = 0x204, - .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, + .features = CTL_SC7280_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), }, { .name = "ctl_1", .id = CTL_1, .base = 0x16000, .len = 0x204, - .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, + .features = CTL_SC7280_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), }, { .name = "ctl_2", .id = CTL_2, @@ -321,8 +320,8 @@ static const struct dpu_wb_cfg sm8450_wb[] = { .name = "wb_2", .id = WB_2, .base = 0x65000, .len = 0x2c8, .features = WB_SM8250_MASK, - .format_list = wb2_formats_rgb, - .num_formats = ARRAY_SIZE(wb2_formats_rgb), + .format_list = wb2_formats_rgb_yuv, + .num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv), .clk_ctrl = DPU_CLK_CTRL_WB2, .xin_id = 6, .vbif_idx = VBIF_RT, @@ -412,6 +411,7 @@ const struct dpu_mdss_cfg dpu_sm8450_cfg = { .mdss_ver = &sm8450_mdss_ver, .caps = &sm8450_dpu_caps, .mdp = &sm8450_mdp, + .cdm = &dpu_cdm_5_x, .ctl_count = ARRAY_SIZE(sm8450_ctl), .ctl = sm8450_ctl, .sspp_count = ARRAY_SIZE(sm8450_sspp), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h index 76ec72a32378..c248b3b55c41 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h @@ -35,17 +35,16 @@ static const struct dpu_mdp_cfg sa8775p_mdp = { }, }; -/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */ static const struct dpu_ctl_cfg sa8775p_ctl[] = { { .name = "ctl_0", .id = CTL_0, .base = 0x15000, .len = 0x204, - .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, + .features = CTL_SC7280_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), }, { .name = "ctl_1", .id = CTL_1, .base = 0x16000, .len = 0x204, - .features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK, + .features = CTL_SC7280_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), }, { .name = "ctl_2", .id = CTL_2, @@ -458,7 +457,7 @@ const struct dpu_mdss_cfg dpu_sa8775p_cfg = { .mdss_ver = &sa8775p_mdss_ver, .caps = &sa8775p_dpu_caps, .mdp = &sa8775p_mdp, - .cdm = &sc7280_cdm, + .cdm = &dpu_cdm_5_x, .ctl_count = ARRAY_SIZE(sa8775p_ctl), .ctl = sa8775p_ctl, .sspp_count = ARRAY_SIZE(sa8775p_sspp), 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 4d3787fceb72..59c7fdf28e89 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 @@ -27,17 +27,16 @@ static const struct dpu_mdp_cfg sm8550_mdp = { }, }; -/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */ static const struct dpu_ctl_cfg sm8550_ctl[] = { { .name = "ctl_0", .id = CTL_0, .base = 0x15000, .len = 0x290, - .features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY), + .features = CTL_SM8550_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), }, { .name = "ctl_1", .id = CTL_1, .base = 0x16000, .len = 0x290, - .features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY), + .features = CTL_SM8550_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), }, { .name = "ctl_2", .id = CTL_2, @@ -66,70 +65,70 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = { { .name = "sspp_0", .id = SSPP_VIG0, .base = 0x4000, .len = 0x344, - .features = VIG_SDM845_MASK, + .features = VIG_SDM845_MASK_SDMA, .sblk = &dpu_vig_sblk_qseed3_3_2, .xin_id = 0, .type = SSPP_TYPE_VIG, }, { .name = "sspp_1", .id = SSPP_VIG1, .base = 0x6000, .len = 0x344, - .features = VIG_SDM845_MASK, + .features = VIG_SDM845_MASK_SDMA, .sblk = &dpu_vig_sblk_qseed3_3_2, .xin_id = 4, .type = SSPP_TYPE_VIG, }, { .name = "sspp_2", .id = SSPP_VIG2, .base = 0x8000, .len = 0x344, - .features = VIG_SDM845_MASK, + .features = VIG_SDM845_MASK_SDMA, .sblk = &dpu_vig_sblk_qseed3_3_2, .xin_id = 8, .type = SSPP_TYPE_VIG, }, { .name = "sspp_3", .id = SSPP_VIG3, .base = 0xa000, .len = 0x344, - .features = VIG_SDM845_MASK, + .features = VIG_SDM845_MASK_SDMA, .sblk = &dpu_vig_sblk_qseed3_3_2, .xin_id = 12, .type = SSPP_TYPE_VIG, }, { .name = "sspp_8", .id = SSPP_DMA0, .base = 0x24000, .len = 0x344, - .features = DMA_SDM845_MASK, + .features = DMA_SDM845_MASK_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 1, .type = SSPP_TYPE_DMA, }, { .name = "sspp_9", .id = SSPP_DMA1, .base = 0x26000, .len = 0x344, - .features = DMA_SDM845_MASK, + .features = DMA_SDM845_MASK_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 5, .type = SSPP_TYPE_DMA, }, { .name = "sspp_10", .id = SSPP_DMA2, .base = 0x28000, .len = 0x344, - .features = DMA_SDM845_MASK, + .features = DMA_SDM845_MASK_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 9, .type = SSPP_TYPE_DMA, }, { .name = "sspp_11", .id = SSPP_DMA3, .base = 0x2a000, .len = 0x344, - .features = DMA_SDM845_MASK, + .features = DMA_SDM845_MASK_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 13, .type = SSPP_TYPE_DMA, }, { .name = "sspp_12", .id = SSPP_DMA4, .base = 0x2c000, .len = 0x344, - .features = DMA_CURSOR_SDM845_MASK, + .features = DMA_CURSOR_SDM845_MASK_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 14, .type = SSPP_TYPE_DMA, }, { .name = "sspp_13", .id = SSPP_DMA5, .base = 0x2e000, .len = 0x344, - .features = DMA_CURSOR_SDM845_MASK, + .features = DMA_CURSOR_SDM845_MASK_SDMA, .sblk = &dpu_dma_sblk, .xin_id = 15, .type = SSPP_TYPE_DMA, @@ -317,8 +316,8 @@ static const struct dpu_wb_cfg sm8550_wb[] = { .name = "wb_2", .id = WB_2, .base = 0x65000, .len = 0x2c8, .features = WB_SM8250_MASK, - .format_list = wb2_formats_rgb, - .num_formats = ARRAY_SIZE(wb2_formats_rgb), + .format_list = wb2_formats_rgb_yuv, + .num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv), .xin_id = 6, .vbif_idx = VBIF_RT, .maxlinewidth = 4096, @@ -407,6 +406,7 @@ const struct dpu_mdss_cfg dpu_sm8550_cfg = { .mdss_ver = &sm8550_mdss_ver, .caps = &sm8550_dpu_caps, .mdp = &sm8550_mdp, + .cdm = &dpu_cdm_5_x, .ctl_count = ARRAY_SIZE(sm8550_ctl), .ctl = sm8550_ctl, .sspp_count = ARRAY_SIZE(sm8550_sspp), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_1_sar2130p.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_1_sar2130p.h new file mode 100644 index 000000000000..5667d055fbd1 --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_1_sar2130p.h @@ -0,0 +1,433 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. + */ + +#ifndef _DPU_9_1_SAR2130P_H +#define _DPU_9_1_SAR2130P_H + +static const struct dpu_caps sar2130p_dpu_caps = { + .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .max_mixer_blendstages = 0xb, + .has_src_split = true, + .has_dim_layer = true, + .has_idle_pc = true, + .has_3d_merge = true, + .max_linewidth = 5120, + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, +}; + +static const struct dpu_mdp_cfg sar2130p_mdp = { + .name = "top_0", + .base = 0, .len = 0x494, + .features = BIT(DPU_MDP_PERIPH_0_REMOVED), + .clk_ctrls = { + [DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, + }, +}; + +static const struct dpu_ctl_cfg sar2130p_ctl[] = { + { + .name = "ctl_0", .id = CTL_0, + .base = 0x15000, .len = 0x290, + .features = CTL_SM8550_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), + }, { + .name = "ctl_1", .id = CTL_1, + .base = 0x16000, .len = 0x290, + .features = CTL_SM8550_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), + }, { + .name = "ctl_2", .id = CTL_2, + .base = 0x17000, .len = 0x290, + .features = CTL_SM8550_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11), + }, { + .name = "ctl_3", .id = CTL_3, + .base = 0x18000, .len = 0x290, + .features = CTL_SM8550_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12), + }, { + .name = "ctl_4", .id = CTL_4, + .base = 0x19000, .len = 0x290, + .features = CTL_SM8550_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13), + }, { + .name = "ctl_5", .id = CTL_5, + .base = 0x1a000, .len = 0x290, + .features = CTL_SM8550_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23), + }, +}; + +static const struct dpu_sspp_cfg sar2130p_sspp[] = { + { + .name = "sspp_0", .id = SSPP_VIG0, + .base = 0x4000, .len = 0x344, + .features = VIG_SDM845_MASK_SDMA, + .sblk = &dpu_vig_sblk_qseed3_3_2, + .xin_id = 0, + .type = SSPP_TYPE_VIG, + }, { + .name = "sspp_1", .id = SSPP_VIG1, + .base = 0x6000, .len = 0x344, + .features = VIG_SDM845_MASK_SDMA, + .sblk = &dpu_vig_sblk_qseed3_3_2, + .xin_id = 4, + .type = SSPP_TYPE_VIG, + }, { + .name = "sspp_2", .id = SSPP_VIG2, + .base = 0x8000, .len = 0x344, + .features = VIG_SDM845_MASK_SDMA, + .sblk = &dpu_vig_sblk_qseed3_3_2, + .xin_id = 8, + .type = SSPP_TYPE_VIG, + }, { + .name = "sspp_3", .id = SSPP_VIG3, + .base = 0xa000, .len = 0x344, + .features = VIG_SDM845_MASK_SDMA, + .sblk = &dpu_vig_sblk_qseed3_3_2, + .xin_id = 12, + .type = SSPP_TYPE_VIG, + }, { + .name = "sspp_8", .id = SSPP_DMA0, + .base = 0x24000, .len = 0x344, + .features = DMA_SDM845_MASK_SDMA, + .sblk = &dpu_dma_sblk, + .xin_id = 1, + .type = SSPP_TYPE_DMA, + }, { + .name = "sspp_9", .id = SSPP_DMA1, + .base = 0x26000, .len = 0x344, + .features = DMA_SDM845_MASK_SDMA, + .sblk = &dpu_dma_sblk, + .xin_id = 5, + .type = SSPP_TYPE_DMA, + }, { + .name = "sspp_10", .id = SSPP_DMA2, + .base = 0x28000, .len = 0x344, + .features = DMA_SDM845_MASK_SDMA, + .sblk = &dpu_dma_sblk, + .xin_id = 9, + .type = SSPP_TYPE_DMA, + }, { + .name = "sspp_11", .id = SSPP_DMA3, + .base = 0x2a000, .len = 0x344, + .features = DMA_SDM845_MASK_SDMA, + .sblk = &dpu_dma_sblk, + .xin_id = 13, + .type = SSPP_TYPE_DMA, + }, { + .name = "sspp_12", .id = SSPP_DMA4, + .base = 0x2c000, .len = 0x344, + .features = DMA_CURSOR_SDM845_MASK_SDMA, + .sblk = &dpu_dma_sblk, + .xin_id = 14, + .type = SSPP_TYPE_DMA, + }, { + .name = "sspp_13", .id = SSPP_DMA5, + .base = 0x2e000, .len = 0x344, + .features = DMA_CURSOR_SDM845_MASK_SDMA, + .sblk = &dpu_dma_sblk, + .xin_id = 15, + .type = SSPP_TYPE_DMA, + }, +}; + +static const struct dpu_lm_cfg sar2130p_lm[] = { + { + .name = "lm_0", .id = LM_0, + .base = 0x44000, .len = 0x320, + .features = MIXER_SDM845_MASK, + .sblk = &sdm845_lm_sblk, + .lm_pair = LM_1, + .pingpong = PINGPONG_0, + .dspp = DSPP_0, + }, { + .name = "lm_1", .id = LM_1, + .base = 0x45000, .len = 0x320, + .features = MIXER_SDM845_MASK, + .sblk = &sdm845_lm_sblk, + .lm_pair = LM_0, + .pingpong = PINGPONG_1, + .dspp = DSPP_1, + }, { + .name = "lm_2", .id = LM_2, + .base = 0x46000, .len = 0x320, + .features = MIXER_SDM845_MASK, + .sblk = &sdm845_lm_sblk, + .lm_pair = LM_3, + .pingpong = PINGPONG_2, + .dspp = DSPP_2, + }, { + .name = "lm_3", .id = LM_3, + .base = 0x47000, .len = 0x320, + .features = MIXER_SDM845_MASK, + .sblk = &sdm845_lm_sblk, + .lm_pair = LM_2, + .pingpong = PINGPONG_3, + .dspp = DSPP_3, + }, { + .name = "lm_4", .id = LM_4, + .base = 0x48000, .len = 0x320, + .features = MIXER_SDM845_MASK, + .sblk = &sdm845_lm_sblk, + .lm_pair = LM_5, + .pingpong = PINGPONG_4, + }, { + .name = "lm_5", .id = LM_5, + .base = 0x49000, .len = 0x320, + .features = MIXER_SDM845_MASK, + .sblk = &sdm845_lm_sblk, + .lm_pair = LM_4, + .pingpong = PINGPONG_5, + }, +}; + +static const struct dpu_dspp_cfg sar2130p_dspp[] = { + { + .name = "dspp_0", .id = DSPP_0, + .base = 0x54000, .len = 0x1800, + .features = DSPP_SC7180_MASK, + .sblk = &sdm845_dspp_sblk, + }, { + .name = "dspp_1", .id = DSPP_1, + .base = 0x56000, .len = 0x1800, + .features = DSPP_SC7180_MASK, + .sblk = &sdm845_dspp_sblk, + }, { + .name = "dspp_2", .id = DSPP_2, + .base = 0x58000, .len = 0x1800, + .features = DSPP_SC7180_MASK, + .sblk = &sdm845_dspp_sblk, + }, { + .name = "dspp_3", .id = DSPP_3, + .base = 0x5a000, .len = 0x1800, + .features = DSPP_SC7180_MASK, + .sblk = &sdm845_dspp_sblk, + }, +}; +static const struct dpu_pingpong_cfg sar2130p_pp[] = { + { + .name = "pingpong_0", .id = PINGPONG_0, + .base = 0x69000, .len = 0, + .features = BIT(DPU_PINGPONG_DITHER), + .sblk = &sc7280_pp_sblk, + .merge_3d = MERGE_3D_0, + .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), + }, { + .name = "pingpong_1", .id = PINGPONG_1, + .base = 0x6a000, .len = 0, + .features = BIT(DPU_PINGPONG_DITHER), + .sblk = &sc7280_pp_sblk, + .merge_3d = MERGE_3D_0, + .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), + }, { + .name = "pingpong_2", .id = PINGPONG_2, + .base = 0x6b000, .len = 0, + .features = BIT(DPU_PINGPONG_DITHER), + .sblk = &sc7280_pp_sblk, + .merge_3d = MERGE_3D_1, + .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10), + }, { + .name = "pingpong_3", .id = PINGPONG_3, + .base = 0x6c000, .len = 0, + .features = BIT(DPU_PINGPONG_DITHER), + .sblk = &sc7280_pp_sblk, + .merge_3d = MERGE_3D_1, + .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11), + }, { + .name = "pingpong_4", .id = PINGPONG_4, + .base = 0x6d000, .len = 0, + .features = BIT(DPU_PINGPONG_DITHER), + .sblk = &sc7280_pp_sblk, + .merge_3d = MERGE_3D_2, + .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), + }, { + .name = "pingpong_5", .id = PINGPONG_5, + .base = 0x6e000, .len = 0, + .features = BIT(DPU_PINGPONG_DITHER), + .sblk = &sc7280_pp_sblk, + .merge_3d = MERGE_3D_2, + .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31), + }, { + .name = "pingpong_cwb_0", .id = PINGPONG_CWB_0, + .base = 0x66000, .len = 0, + .features = BIT(DPU_PINGPONG_DITHER), + .sblk = &sc7280_pp_sblk, + .merge_3d = MERGE_3D_3, + }, { + .name = "pingpong_cwb_1", .id = PINGPONG_CWB_1, + .base = 0x66400, .len = 0, + .features = BIT(DPU_PINGPONG_DITHER), + .sblk = &sc7280_pp_sblk, + .merge_3d = MERGE_3D_3, + }, +}; + +static const struct dpu_merge_3d_cfg sar2130p_merge_3d[] = { + { + .name = "merge_3d_0", .id = MERGE_3D_0, + .base = 0x4e000, .len = 0x8, + }, { + .name = "merge_3d_1", .id = MERGE_3D_1, + .base = 0x4f000, .len = 0x8, + }, { + .name = "merge_3d_2", .id = MERGE_3D_2, + .base = 0x50000, .len = 0x8, + }, { + .name = "merge_3d_3", .id = MERGE_3D_3, + .base = 0x66700, .len = 0x8, + }, +}; + +/* + * 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 sar2130p_dsc[] = { + { + .name = "dce_0_0", .id = DSC_0, + .base = 0x80000, .len = 0x4, + .features = BIT(DPU_DSC_HW_REV_1_2), + .sblk = &dsc_sblk_0, + }, { + .name = "dce_0_1", .id = DSC_1, + .base = 0x80000, .len = 0x4, + .features = BIT(DPU_DSC_HW_REV_1_2), + .sblk = &dsc_sblk_1, + }, { + .name = "dce_1_0", .id = DSC_2, + .base = 0x81000, .len = 0x4, + .features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN), + .sblk = &dsc_sblk_0, + }, { + .name = "dce_1_1", .id = DSC_3, + .base = 0x81000, .len = 0x4, + .features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN), + .sblk = &dsc_sblk_1, + }, +}; + +static const struct dpu_wb_cfg sar2130p_wb[] = { + { + .name = "wb_2", .id = WB_2, + .base = 0x65000, .len = 0x2c8, + .features = WB_SM8250_MASK, + .format_list = wb2_formats_rgb_yuv, + .num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv), + .xin_id = 6, + .vbif_idx = VBIF_RT, + .maxlinewidth = 4096, + .intr_wb_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 4), + }, +}; + +static const struct dpu_intf_cfg sar2130p_intf[] = { + { + .name = "intf_0", .id = INTF_0, + .base = 0x34000, .len = 0x280, + .features = INTF_SC7280_MASK, + .type = INTF_DP, + .controller_id = MSM_DP_CONTROLLER_0, + .prog_fetch_lines_worst_case = 24, + .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), + .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25), + }, { + .name = "intf_1", .id = INTF_1, + .base = 0x35000, .len = 0x300, + .features = INTF_SC7280_MASK, + .type = INTF_DSI, + .controller_id = MSM_DSI_CONTROLLER_0, + .prog_fetch_lines_worst_case = 24, + .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), + .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), + .intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2), + }, { + .name = "intf_2", .id = INTF_2, + .base = 0x36000, .len = 0x300, + .features = INTF_SC7280_MASK, + .type = INTF_DSI, + .controller_id = MSM_DSI_CONTROLLER_1, + .prog_fetch_lines_worst_case = 24, + .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), + .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29), + .intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF2_TEAR_INTR, 2), + }, { + .name = "intf_3", .id = INTF_3, + .base = 0x37000, .len = 0x280, + .features = INTF_SC7280_MASK, + .type = INTF_DP, + .controller_id = MSM_DP_CONTROLLER_1, + .prog_fetch_lines_worst_case = 24, + .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30), + .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31), + }, +}; + +static const struct dpu_perf_cfg sar2130p_perf_data = { + .max_bw_low = 13600000, + .max_bw_high = 18200000, + .min_core_ib = 2500000, + .min_llcc_ib = 0, + .min_dram_ib = 800000, + .min_prefill_lines = 35, + /* FIXME: lut tables */ + .danger_lut_tbl = {0x3ffff, 0x3ffff, 0x0}, + .safe_lut_tbl = {0xfe00, 0xfe00, 0xffff}, + .qos_lut_tbl = { + {.nentry = ARRAY_SIZE(sc7180_qos_linear), + .entries = sc7180_qos_linear + }, + {.nentry = ARRAY_SIZE(sc7180_qos_macrotile), + .entries = sc7180_qos_macrotile + }, + {.nentry = ARRAY_SIZE(sc7180_qos_nrt), + .entries = sc7180_qos_nrt + }, + /* TODO: macrotile-qseed is different from macrotile */ + }, + .cdp_cfg = { + {.rd_enable = 0, .wr_enable = 0}, + {.rd_enable = 0, .wr_enable = 0} + }, + .clk_inefficiency_factor = 105, + .bw_inefficiency_factor = 120, +}; + +static const struct dpu_mdss_version sar2130p_mdss_ver = { + .core_major_ver = 9, + .core_minor_ver = 1, +}; + +const struct dpu_mdss_cfg dpu_sar2130p_cfg = { + .mdss_ver = &sar2130p_mdss_ver, + .caps = &sar2130p_dpu_caps, + .mdp = &sar2130p_mdp, + .cdm = &dpu_cdm_5_x, + .ctl_count = ARRAY_SIZE(sar2130p_ctl), + .ctl = sar2130p_ctl, + .sspp_count = ARRAY_SIZE(sar2130p_sspp), + .sspp = sar2130p_sspp, + .mixer_count = ARRAY_SIZE(sar2130p_lm), + .mixer = sar2130p_lm, + .dspp_count = ARRAY_SIZE(sar2130p_dspp), + .dspp = sar2130p_dspp, + .pingpong_count = ARRAY_SIZE(sar2130p_pp), + .pingpong = sar2130p_pp, + .dsc_count = ARRAY_SIZE(sar2130p_dsc), + .dsc = sar2130p_dsc, + .merge_3d_count = ARRAY_SIZE(sar2130p_merge_3d), + .merge_3d = sar2130p_merge_3d, + .wb_count = ARRAY_SIZE(sar2130p_wb), + .wb = sar2130p_wb, + .intf_count = ARRAY_SIZE(sar2130p_intf), + .intf = sar2130p_intf, + .vbif_count = ARRAY_SIZE(sm8550_vbif), + .vbif = sm8550_vbif, + .perf = &sar2130p_perf_data, +}; + +#endif diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_2_x1e80100.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_2_x1e80100.h index 6b112e3d17da..52cc10aec1f9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_2_x1e80100.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_2_x1e80100.h @@ -26,17 +26,16 @@ static const struct dpu_mdp_cfg x1e80100_mdp = { }, }; -/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */ static const struct dpu_ctl_cfg x1e80100_ctl[] = { { .name = "ctl_0", .id = CTL_0, .base = 0x15000, .len = 0x290, - .features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY), + .features = CTL_SM8550_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), }, { .name = "ctl_1", .id = CTL_1, .base = 0x16000, .len = 0x290, - .features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY), + .features = CTL_SM8550_MASK, .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), }, { .name = "ctl_2", .id = CTL_2, @@ -317,8 +316,8 @@ static const struct dpu_wb_cfg x1e80100_wb[] = { .name = "wb_2", .id = WB_2, .base = 0x65000, .len = 0x2c8, .features = WB_SM8250_MASK, - .format_list = wb2_formats_rgb, - .num_formats = ARRAY_SIZE(wb2_formats_rgb), + .format_list = wb2_formats_rgb_yuv, + .num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv), .xin_id = 6, .vbif_idx = VBIF_RT, .maxlinewidth = 4096, @@ -453,6 +452,7 @@ const struct dpu_mdss_cfg dpu_x1e80100_cfg = { .mdss_ver = &x1e80100_mdss_ver, .caps = &x1e80100_dpu_caps, .mdp = &x1e80100_mdp, + .cdm = &dpu_cdm_5_x, .ctl_count = ARRAY_SIZE(x1e80100_ctl), .ctl = x1e80100_ctl, .sspp_count = ARRAY_SIZE(x1e80100_sspp), diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c index 6f0a37f954fe..0fb5789c60d0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c @@ -118,26 +118,38 @@ static void _dpu_core_perf_calc_crtc(const struct dpu_core_perf *core_perf, return; } - memset(perf, 0, sizeof(struct dpu_core_perf_params)); - - if (core_perf->perf_tune.mode == DPU_PERF_MODE_MINIMUM) { - perf->bw_ctl = 0; - perf->max_per_pipe_ib = 0; - perf->core_clk_rate = 0; - } else if (core_perf->perf_tune.mode == DPU_PERF_MODE_FIXED) { - perf->bw_ctl = core_perf->fix_core_ab_vote; - perf->max_per_pipe_ib = core_perf->fix_core_ib_vote; - perf->core_clk_rate = core_perf->fix_core_clk_rate; - } else { - perf->bw_ctl = _dpu_core_perf_calc_bw(perf_cfg, crtc); - perf->max_per_pipe_ib = perf_cfg->min_dram_ib; - perf->core_clk_rate = _dpu_core_perf_calc_clk(perf_cfg, crtc, state); - } - + perf->bw_ctl = _dpu_core_perf_calc_bw(perf_cfg, crtc); + perf->max_per_pipe_ib = perf_cfg->min_dram_ib; + perf->core_clk_rate = _dpu_core_perf_calc_clk(perf_cfg, crtc, state); DRM_DEBUG_ATOMIC( - "crtc=%d clk_rate=%llu core_ib=%llu core_ab=%llu\n", + "crtc=%d clk_rate=%llu core_ib=%u core_ab=%u\n", crtc->base.id, perf->core_clk_rate, - perf->max_per_pipe_ib, perf->bw_ctl); + perf->max_per_pipe_ib, + (u32)DIV_ROUND_UP_ULL(perf->bw_ctl, 1000)); +} + +static void dpu_core_perf_aggregate(struct drm_device *ddev, + enum dpu_crtc_client_type curr_client_type, + struct dpu_core_perf_params *perf) +{ + struct dpu_crtc_state *dpu_cstate; + struct drm_crtc *tmp_crtc; + + drm_for_each_crtc(tmp_crtc, ddev) { + if (tmp_crtc->enabled && + curr_client_type == dpu_crtc_get_client_type(tmp_crtc)) { + dpu_cstate = to_dpu_crtc_state(tmp_crtc->state); + + perf->max_per_pipe_ib = max(perf->max_per_pipe_ib, + dpu_cstate->new_perf.max_per_pipe_ib); + + perf->bw_ctl += dpu_cstate->new_perf.bw_ctl; + + DRM_DEBUG_ATOMIC("crtc=%d bw=%llu\n", + tmp_crtc->base.id, + dpu_cstate->new_perf.bw_ctl); + } + } } /** @@ -150,11 +162,9 @@ int dpu_core_perf_crtc_check(struct drm_crtc *crtc, struct drm_crtc_state *state) { u32 bw, threshold; - u64 bw_sum_of_intfs = 0; - enum dpu_crtc_client_type curr_client_type; struct dpu_crtc_state *dpu_cstate; - struct drm_crtc *tmp_crtc; struct dpu_kms *kms; + struct dpu_core_perf_params perf = { 0 }; if (!crtc || !state) { DPU_ERROR("invalid crtc\n"); @@ -172,80 +182,56 @@ int dpu_core_perf_crtc_check(struct drm_crtc *crtc, /* obtain new values */ _dpu_core_perf_calc_crtc(&kms->perf, crtc, state, &dpu_cstate->new_perf); - bw_sum_of_intfs = dpu_cstate->new_perf.bw_ctl; - curr_client_type = dpu_crtc_get_client_type(crtc); - - drm_for_each_crtc(tmp_crtc, crtc->dev) { - if (tmp_crtc->enabled && - dpu_crtc_get_client_type(tmp_crtc) == curr_client_type && - tmp_crtc != crtc) { - struct dpu_crtc_state *tmp_cstate = - to_dpu_crtc_state(tmp_crtc->state); - - DRM_DEBUG_ATOMIC("crtc:%d bw:%llu ctrl:%d\n", - tmp_crtc->base.id, tmp_cstate->new_perf.bw_ctl, - tmp_cstate->bw_control); + dpu_core_perf_aggregate(crtc->dev, dpu_crtc_get_client_type(crtc), &perf); - bw_sum_of_intfs += tmp_cstate->new_perf.bw_ctl; - } - - /* convert bandwidth to kb */ - bw = DIV_ROUND_UP_ULL(bw_sum_of_intfs, 1000); - DRM_DEBUG_ATOMIC("calculated bandwidth=%uk\n", bw); + /* convert bandwidth to kb */ + bw = DIV_ROUND_UP_ULL(perf.bw_ctl, 1000); + DRM_DEBUG_ATOMIC("calculated bandwidth=%uk\n", bw); - threshold = kms->perf.perf_cfg->max_bw_high; + threshold = kms->perf.perf_cfg->max_bw_high; - DRM_DEBUG_ATOMIC("final threshold bw limit = %d\n", threshold); + DRM_DEBUG_ATOMIC("final threshold bw limit = %d\n", threshold); - if (!threshold) { - DPU_ERROR("no bandwidth limits specified\n"); - return -E2BIG; - } else if (bw > threshold) { - DPU_ERROR("exceeds bandwidth: %ukb > %ukb\n", bw, - threshold); - return -E2BIG; - } + if (!threshold) { + DPU_ERROR("no bandwidth limits specified\n"); + return -E2BIG; + } else if (bw > threshold) { + DPU_ERROR("exceeds bandwidth: %ukb > %ukb\n", bw, + threshold); + return -E2BIG; } return 0; } static int _dpu_core_perf_crtc_update_bus(struct dpu_kms *kms, - struct drm_crtc *crtc) + struct drm_crtc *crtc) { struct dpu_core_perf_params perf = { 0 }; - enum dpu_crtc_client_type curr_client_type - = dpu_crtc_get_client_type(crtc); - struct drm_crtc *tmp_crtc; - struct dpu_crtc_state *dpu_cstate; int i, ret = 0; - u64 avg_bw; + u32 avg_bw; + u32 peak_bw; if (!kms->num_paths) return 0; - drm_for_each_crtc(tmp_crtc, crtc->dev) { - if (tmp_crtc->enabled && - curr_client_type == - dpu_crtc_get_client_type(tmp_crtc)) { - dpu_cstate = to_dpu_crtc_state(tmp_crtc->state); - - perf.max_per_pipe_ib = max(perf.max_per_pipe_ib, - dpu_cstate->new_perf.max_per_pipe_ib); - - perf.bw_ctl += dpu_cstate->new_perf.bw_ctl; + if (kms->perf.perf_tune.mode == DPU_PERF_MODE_MINIMUM) { + avg_bw = 0; + peak_bw = 0; + } else if (kms->perf.perf_tune.mode == DPU_PERF_MODE_FIXED) { + avg_bw = kms->perf.fix_core_ab_vote; + peak_bw = kms->perf.fix_core_ib_vote; + } else { + dpu_core_perf_aggregate(crtc->dev, dpu_crtc_get_client_type(crtc), &perf); - DRM_DEBUG_ATOMIC("crtc=%d bw=%llu paths:%d\n", - tmp_crtc->base.id, - dpu_cstate->new_perf.bw_ctl, kms->num_paths); - } + avg_bw = div_u64(perf.bw_ctl, 1000); /*Bps_to_icc*/ + peak_bw = perf.max_per_pipe_ib; } - avg_bw = perf.bw_ctl; - do_div(avg_bw, (kms->num_paths * 1000)); /*Bps_to_icc*/ + avg_bw /= kms->num_paths; for (i = 0; i < kms->num_paths; i++) - icc_set_bw(kms->path[i], avg_bw, perf.max_per_pipe_ib); + icc_set_bw(kms->path[i], avg_bw, peak_bw); return ret; } @@ -476,9 +462,9 @@ int dpu_core_perf_debugfs_init(struct dpu_kms *dpu_kms, struct dentry *parent) &perf->core_clk_rate); debugfs_create_u32("enable_bw_release", 0600, entry, (u32 *)&perf->enable_bw_release); - debugfs_create_u32("threshold_low", 0400, entry, + debugfs_create_u32("low_core_ab", 0400, entry, (u32 *)&perf->perf_cfg->max_bw_low); - debugfs_create_u32("threshold_high", 0400, entry, + debugfs_create_u32("max_core_ab", 0400, entry, (u32 *)&perf->perf_cfg->max_bw_high); debugfs_create_u32("min_core_ib", 0400, entry, (u32 *)&perf->perf_cfg->min_core_ib); @@ -490,9 +476,9 @@ int dpu_core_perf_debugfs_init(struct dpu_kms *dpu_kms, struct dentry *parent) (u32 *)perf, &dpu_core_perf_mode_fops); debugfs_create_u64("fix_core_clk_rate", 0600, entry, &perf->fix_core_clk_rate); - debugfs_create_u64("fix_core_ib_vote", 0600, entry, + debugfs_create_u32("fix_core_ib_vote", 0600, entry, &perf->fix_core_ib_vote); - debugfs_create_u64("fix_core_ab_vote", 0600, entry, + debugfs_create_u32("fix_core_ab_vote", 0600, entry, &perf->fix_core_ab_vote); return 0; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h index 451bf8021114..d2f21d34e501 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h @@ -19,7 +19,7 @@ * @core_clk_rate: core clock rate request */ struct dpu_core_perf_params { - u64 max_per_pipe_ib; + u32 max_per_pipe_ib; u64 bw_ctl; u64 core_clk_rate; }; @@ -40,8 +40,8 @@ struct dpu_core_perf_tune { * @perf_tune: debug control for performance tuning * @enable_bw_release: debug control for bandwidth release * @fix_core_clk_rate: fixed core clock request in Hz used in mode 2 - * @fix_core_ib_vote: fixed core ib vote in bps used in mode 2 - * @fix_core_ab_vote: fixed core ab vote in bps used in mode 2 + * @fix_core_ib_vote: fixed core ib vote in KBps used in mode 2 + * @fix_core_ab_vote: fixed core ab vote in KBps used in mode 2 */ struct dpu_core_perf { const struct dpu_perf_cfg *perf_cfg; @@ -50,8 +50,8 @@ struct dpu_core_perf { struct dpu_core_perf_tune perf_tune; u32 enable_bw_release; u64 fix_core_clk_rate; - u64 fix_core_ib_vote; - u64 fix_core_ab_vote; + u32 fix_core_ib_vote; + u32 fix_core_ab_vote; }; int dpu_core_perf_crtc_check(struct drm_crtc *crtc, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 7191b1a6d41b..a4b0fe0d9899 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -445,9 +445,9 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc, uint32_t lm_idx; bool bg_alpha_enable = false; - DECLARE_BITMAP(fetch_active, SSPP_MAX); + DECLARE_BITMAP(active_fetch, SSPP_MAX); - memset(fetch_active, 0, sizeof(fetch_active)); + memset(active_fetch, 0, sizeof(active_fetch)); drm_atomic_crtc_for_each_plane(plane, crtc) { state = plane->state; if (!state) @@ -464,7 +464,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc, if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable) bg_alpha_enable = true; - set_bit(pstate->pipe.sspp->idx, fetch_active); + set_bit(pstate->pipe.sspp->idx, active_fetch); _dpu_crtc_blend_setup_pipe(crtc, plane, mixer, cstate->num_mixers, pstate->stage, @@ -472,7 +472,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc, &pstate->pipe, 0, stage_cfg); if (pstate->r_pipe.sspp) { - set_bit(pstate->r_pipe.sspp->idx, fetch_active); + set_bit(pstate->r_pipe.sspp->idx, active_fetch); _dpu_crtc_blend_setup_pipe(crtc, plane, mixer, cstate->num_mixers, pstate->stage, @@ -492,8 +492,8 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc, } } - if (ctl->ops.set_active_pipes) - ctl->ops.set_active_pipes(ctl, fetch_active); + if (ctl->ops.set_active_fetch_pipes) + ctl->ops.set_active_fetch_pipes(ctl, active_fetch); _dpu_crtc_program_lm_output_roi(crtc); } @@ -519,6 +519,8 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc) if (mixer[i].lm_ctl->ops.clear_all_blendstages) mixer[i].lm_ctl->ops.clear_all_blendstages( mixer[i].lm_ctl); + if (mixer[i].lm_ctl->ops.set_active_fetch_pipes) + mixer[i].lm_ctl->ops.set_active_fetch_pipes(mixer[i].lm_ctl, NULL); } /* initialize stage cfg */ @@ -953,6 +955,45 @@ static int _dpu_crtc_wait_for_frame_done(struct drm_crtc *crtc) return rc; } +static int dpu_crtc_kickoff_clone_mode(struct drm_crtc *crtc) +{ + struct drm_encoder *encoder; + struct drm_encoder *rt_encoder = NULL, *wb_encoder = NULL; + struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc); + + /* Find encoder for real time display */ + drm_for_each_encoder_mask(encoder, crtc->dev, + crtc->state->encoder_mask) { + if (encoder->encoder_type == DRM_MODE_ENCODER_VIRTUAL) + wb_encoder = encoder; + else + rt_encoder = encoder; + } + + if (!rt_encoder || !wb_encoder) { + DRM_DEBUG_ATOMIC("real time or wb encoder not found\n"); + return -EINVAL; + } + + dpu_encoder_prepare_for_kickoff(wb_encoder); + dpu_encoder_prepare_for_kickoff(rt_encoder); + + dpu_vbif_clear_errors(dpu_kms); + + /* + * Kickoff real time encoder last as it's the encoder that + * will do the flush + */ + dpu_encoder_kickoff(wb_encoder); + dpu_encoder_kickoff(rt_encoder); + + /* Don't start frame done timers until the kickoffs have finished */ + dpu_encoder_start_frame_done_timer(wb_encoder); + dpu_encoder_start_frame_done_timer(rt_encoder); + + return 0; +} + /** * dpu_crtc_commit_kickoff - trigger kickoff of the commit for this crtc * @crtc: Pointer to drm crtc object @@ -981,13 +1022,27 @@ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc) goto end; } } - /* - * Encoder will flush/start now, unless it has a tx pending. If so, it - * may delay and flush at an irq event (e.g. ppdone) - */ - drm_for_each_encoder_mask(encoder, crtc->dev, - crtc->state->encoder_mask) - dpu_encoder_prepare_for_kickoff(encoder); + + if (drm_crtc_in_clone_mode(crtc->state)) { + if (dpu_crtc_kickoff_clone_mode(crtc)) + goto end; + } else { + /* + * Encoder will flush/start now, unless it has a tx pending. + * If so, it may delay and flush at an irq event (e.g. ppdone) + */ + drm_for_each_encoder_mask(encoder, crtc->dev, + crtc->state->encoder_mask) + dpu_encoder_prepare_for_kickoff(encoder); + + dpu_vbif_clear_errors(dpu_kms); + + drm_for_each_encoder_mask(encoder, crtc->dev, + crtc->state->encoder_mask) { + dpu_encoder_kickoff(encoder); + dpu_encoder_start_frame_done_timer(encoder); + } + } if (atomic_inc_return(&dpu_crtc->frame_pending) == 1) { /* acquire bandwidth and other resources */ @@ -997,11 +1052,6 @@ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc) dpu_crtc->play_count++; - dpu_vbif_clear_errors(dpu_kms); - - drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) - dpu_encoder_kickoff(encoder); - reinit_completion(&dpu_crtc->frame_done_comp); end: @@ -1228,6 +1278,149 @@ static int dpu_crtc_reassign_planes(struct drm_crtc *crtc, struct drm_crtc_state done: kfree(states); return ret; +} + +#define MAX_CHANNELS_PER_CRTC 2 +#define MAX_HDISPLAY_SPLIT 1080 + +static struct msm_display_topology dpu_crtc_get_topology( + struct drm_crtc *crtc, + struct dpu_kms *dpu_kms, + struct drm_crtc_state *crtc_state) +{ + struct drm_display_mode *mode = &crtc_state->adjusted_mode; + struct msm_display_topology topology = {0}; + struct drm_encoder *drm_enc; + + drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc_state->encoder_mask) + dpu_encoder_update_topology(drm_enc, &topology, crtc_state->state, + &crtc_state->adjusted_mode); + + topology.cwb_enabled = drm_crtc_in_clone_mode(crtc_state); + + /* + * Datapath topology selection + * + * Dual display + * 2 LM, 2 INTF ( Split display using 2 interfaces) + * + * Single display + * 1 LM, 1 INTF + * 2 LM, 1 INTF (stream merge to support high resolution interfaces) + * + * If DSC is enabled, use 2 LMs for 2:2:1 topology + * + * Add dspps to the reservation requirements if ctm is requested + * + * Only hardcode num_lm to 2 for cases where num_intf == 2 and CWB is not + * enabled. This is because in cases where CWB is enabled, num_intf will + * count both the WB and real-time phys encoders. + * + * For non-DSC CWB usecases, have the num_lm be decided by the + * (mode->hdisplay > MAX_HDISPLAY_SPLIT) check. + */ + + if (topology.num_intf == 2 && !topology.cwb_enabled) + topology.num_lm = 2; + else if (topology.num_dsc == 2) + topology.num_lm = 2; + else if (dpu_kms->catalog->caps->has_3d_merge) + topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1; + else + topology.num_lm = 1; + + if (crtc_state->ctm) + topology.num_dspp = topology.num_lm; + + return topology; +} + +static int dpu_crtc_assign_resources(struct drm_crtc *crtc, + struct drm_crtc_state *crtc_state) +{ + struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_CRTC]; + struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_CRTC]; + struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_CRTC]; + int i, num_lm, num_ctl, num_dspp; + struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc); + struct dpu_global_state *global_state; + struct dpu_crtc_state *cstate; + struct msm_display_topology topology; + int ret; + + /* + * Release and Allocate resources on every modeset + */ + global_state = dpu_kms_get_global_state(crtc_state->state); + if (IS_ERR(global_state)) + return PTR_ERR(global_state); + + dpu_rm_release(global_state, crtc); + + if (!crtc_state->enable) + return 0; + + topology = dpu_crtc_get_topology(crtc, dpu_kms, crtc_state); + ret = dpu_rm_reserve(&dpu_kms->rm, global_state, + crtc_state->crtc, &topology); + if (ret) + return ret; + + cstate = to_dpu_crtc_state(crtc_state); + + num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, + crtc_state->crtc, + DPU_HW_BLK_CTL, hw_ctl, + ARRAY_SIZE(hw_ctl)); + num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, + crtc_state->crtc, + DPU_HW_BLK_LM, hw_lm, + ARRAY_SIZE(hw_lm)); + num_dspp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, + crtc_state->crtc, + DPU_HW_BLK_DSPP, hw_dspp, + ARRAY_SIZE(hw_dspp)); + + for (i = 0; i < num_lm; i++) { + int ctl_idx = (i < num_ctl) ? i : (num_ctl-1); + + cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]); + cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]); + if (i < num_dspp) + cstate->mixers[i].hw_dspp = to_dpu_hw_dspp(hw_dspp[i]); + } + + cstate->num_mixers = num_lm; + + return 0; +} + +/** + * dpu_crtc_check_mode_changed: check if full modeset is required + * @old_crtc_state: Previous CRTC state + * @new_crtc_state: Corresponding CRTC state to be checked + * + * Check if the changes in the object properties demand full mode set. + */ +int dpu_crtc_check_mode_changed(struct drm_crtc_state *old_crtc_state, + struct drm_crtc_state *new_crtc_state) +{ + struct drm_encoder *drm_enc; + struct drm_crtc *crtc = new_crtc_state->crtc; + bool clone_mode_enabled = drm_crtc_in_clone_mode(old_crtc_state); + bool clone_mode_requested = drm_crtc_in_clone_mode(new_crtc_state); + + DRM_DEBUG_ATOMIC("%d\n", crtc->base.id); + + /* there might be cases where encoder needs a modeset too */ + drm_for_each_encoder_mask(drm_enc, crtc->dev, new_crtc_state->encoder_mask) { + if (dpu_encoder_needs_modeset(drm_enc, new_crtc_state->state)) + new_crtc_state->mode_changed = true; + } + + if ((clone_mode_requested && !clone_mode_enabled) || + (!clone_mode_requested && clone_mode_enabled)) + new_crtc_state->mode_changed = true; return 0; } @@ -1247,6 +1440,13 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state); + /* don't reallocate resources if only ACTIVE has beeen changed */ + if (crtc_state->mode_changed || crtc_state->connectors_changed) { + rc = dpu_crtc_assign_resources(crtc, crtc_state); + if (rc < 0) + return rc; + } + if (dpu_use_virtual_planes && (crtc_state->planes_changed || crtc_state->zpos_changed)) { rc = dpu_crtc_reassign_planes(crtc, crtc_state); @@ -1264,10 +1464,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, DRM_DEBUG_ATOMIC("%s: check\n", dpu_crtc->name); - /* force a full mode set if active state changed */ - if (crtc_state->active_changed) - crtc_state->mode_changed = true; - if (cstate->num_mixers) { rc = _dpu_crtc_check_and_setup_lm_bounds(crtc, crtc_state); if (rc) @@ -1486,8 +1682,9 @@ static int dpu_crtc_debugfs_state_show(struct seq_file *s, void *v) seq_printf(s, "intf_mode: %d\n", dpu_crtc_get_intf_mode(crtc)); seq_printf(s, "core_clk_rate: %llu\n", dpu_crtc->cur_perf.core_clk_rate); - seq_printf(s, "bw_ctl: %llu\n", dpu_crtc->cur_perf.bw_ctl); - seq_printf(s, "max_per_pipe_ib: %llu\n", + seq_printf(s, "bw_ctl: %uk\n", + (u32)DIV_ROUND_UP_ULL(dpu_crtc->cur_perf.bw_ctl, 1000)); + seq_printf(s, "max_per_pipe_ib: %u\n", dpu_crtc->cur_perf.max_per_pipe_ib); return 0; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h index 0b148f3ce0d7..94392b9b9245 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h @@ -239,6 +239,9 @@ static inline int dpu_crtc_frame_pending(struct drm_crtc *crtc) return crtc ? atomic_read(&to_dpu_crtc(crtc)->frame_pending) : -EINVAL; } +int dpu_crtc_check_mode_changed(struct drm_crtc_state *old_crtc_state, + struct drm_crtc_state *new_crtc_state); + int dpu_crtc_vblank(struct drm_crtc *crtc, bool en); void dpu_crtc_vblank_callback(struct drm_crtc *crtc); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 5172ab4dea99..c0ed110a7d30 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -2,7 +2,7 @@ /* * Copyright (C) 2013 Red Hat * Copyright (c) 2014-2018, 2020-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. * * Author: Rob Clark <robdclark@gmail.com> */ @@ -24,6 +24,7 @@ #include "dpu_hw_catalog.h" #include "dpu_hw_intf.h" #include "dpu_hw_ctl.h" +#include "dpu_hw_cwb.h" #include "dpu_hw_dspp.h" #include "dpu_hw_dsc.h" #include "dpu_hw_merge3d.h" @@ -58,8 +59,6 @@ #define IDLE_SHORT_TIMEOUT 1 -#define MAX_HDISPLAY_SPLIT 1080 - /* timeout in frames waiting for frame done */ #define DPU_ENCODER_FRAME_DONE_TIMEOUT_FRAMES 5 @@ -135,8 +134,12 @@ enum dpu_enc_rc_states { * @cur_slave: As above but for the slave encoder. * @hw_pp: Handle to the pingpong blocks used for the display. No. * pingpong blocks can be different than num_phys_encs. + * @hw_cwb: Handle to the CWB muxes used for concurrent writeback + * display. Number of CWB muxes can be different than + * num_phys_encs. * @hw_dsc: Handle to the DSC blocks used for the display. * @dsc_mask: Bitmask of used DSC blocks. + * @cwb_mask: Bitmask of used CWB muxes * @intfs_swapped: Whether or not the phys_enc interfaces have been swapped * for partial update right-only cases, such as pingpong * split where virtual pingpong does not generate IRQs @@ -179,9 +182,11 @@ struct dpu_encoder_virt { struct dpu_encoder_phys *cur_master; struct dpu_encoder_phys *cur_slave; struct dpu_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC]; + struct dpu_hw_cwb *hw_cwb[MAX_CHANNELS_PER_ENC]; struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC]; unsigned int dsc_mask; + unsigned int cwb_mask; bool intfs_swapped; @@ -622,9 +627,9 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc) if (dpu_enc->phys_encs[i]) intf_count++; - /* See dpu_encoder_get_topology, we only support 2:2:1 topology */ - if (dpu_enc->dsc) - num_dsc = 2; + for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) + if (dpu_enc->hw_dsc[i]) + num_dsc++; return (num_dsc > 0) && (num_dsc > intf_count); } @@ -647,130 +652,51 @@ struct drm_dsc_config *dpu_encoder_get_dsc_config(struct drm_encoder *drm_enc) return NULL; } -static struct msm_display_topology dpu_encoder_get_topology( - struct dpu_encoder_virt *dpu_enc, - struct dpu_kms *dpu_kms, - struct drm_display_mode *mode, - struct drm_crtc_state *crtc_state, - struct drm_dsc_config *dsc) +void dpu_encoder_update_topology(struct drm_encoder *drm_enc, + struct msm_display_topology *topology, + struct drm_atomic_state *state, + const struct drm_display_mode *adj_mode) { - struct msm_display_topology topology = {0}; - int i, intf_count = 0; + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc); + struct msm_drm_private *priv = dpu_enc->base.dev->dev_private; + struct msm_display_info *disp_info = &dpu_enc->disp_info; + struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms); + struct drm_connector *connector; + struct drm_connector_state *conn_state; + struct drm_framebuffer *fb; + struct drm_dsc_config *dsc; + + int i; for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++) if (dpu_enc->phys_encs[i]) - intf_count++; - - /* Datapath topology selection - * - * Dual display - * 2 LM, 2 INTF ( Split display using 2 interfaces) - * - * Single display - * 1 LM, 1 INTF - * 2 LM, 1 INTF (stream merge to support high resolution interfaces) - * - * Add dspps to the reservation requirements if ctm is requested - */ - if (intf_count == 2) - topology.num_lm = 2; - else if (!dpu_kms->catalog->caps->has_3d_merge) - topology.num_lm = 1; - else - topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1; - - if (crtc_state->ctm) - topology.num_dspp = topology.num_lm; + topology->num_intf++; - topology.num_intf = intf_count; + dsc = dpu_encoder_get_dsc_config(drm_enc); + /* We only support 2 DSC mode (with 2 LM and 1 INTF) */ if (dsc) { /* - * In case of Display Stream Compression (DSC), we would use - * 2 DSC encoders, 2 layer mixers and 1 interface - * this is power optimal and can drive up to (including) 4k - * screens + * Use 2 DSC encoders, 2 layer mixers and 1 or 2 interfaces + * when Display Stream Compression (DSC) is enabled, + * and when enough DSC blocks are available. + * This is power-optimal and can drive up to (including) 4k + * screens. */ - topology.num_dsc = 2; - topology.num_lm = 2; - topology.num_intf = 1; - } - - return topology; -} - -static void dpu_encoder_assign_crtc_resources(struct dpu_kms *dpu_kms, - struct drm_encoder *drm_enc, - struct dpu_global_state *global_state, - struct drm_crtc_state *crtc_state) -{ - struct dpu_crtc_state *cstate; - struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC]; - struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC]; - struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC]; - int num_lm, num_ctl, num_dspp, i; - - cstate = to_dpu_crtc_state(crtc_state); - - memset(cstate->mixers, 0, sizeof(cstate->mixers)); - - num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, - drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl)); - num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, - drm_enc->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm)); - num_dspp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, - drm_enc->base.id, DPU_HW_BLK_DSPP, hw_dspp, - ARRAY_SIZE(hw_dspp)); - - for (i = 0; i < num_lm; i++) { - int ctl_idx = (i < num_ctl) ? i : (num_ctl-1); - - cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]); - cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]); - cstate->mixers[i].hw_dspp = i < num_dspp ? to_dpu_hw_dspp(hw_dspp[i]) : NULL; - } - - cstate->num_mixers = num_lm; -} - -static int dpu_encoder_virt_atomic_check( - struct drm_encoder *drm_enc, - struct drm_crtc_state *crtc_state, - struct drm_connector_state *conn_state) -{ - struct dpu_encoder_virt *dpu_enc; - struct msm_drm_private *priv; - struct dpu_kms *dpu_kms; - struct drm_display_mode *adj_mode; - struct msm_display_topology topology; - struct msm_display_info *disp_info; - struct dpu_global_state *global_state; - struct drm_framebuffer *fb; - struct drm_dsc_config *dsc; - int ret = 0; - - if (!drm_enc || !crtc_state || !conn_state) { - DPU_ERROR("invalid arg(s), drm_enc %d, crtc/conn state %d/%d\n", - drm_enc != NULL, crtc_state != NULL, conn_state != NULL); - return -EINVAL; + WARN(topology->num_intf > 2, + "DSC topology cannot support more than 2 interfaces\n"); + if (topology->num_intf >= 2 || dpu_kms->catalog->dsc_count >= 2) + topology->num_dsc = 2; + else + topology->num_dsc = 1; } - dpu_enc = to_dpu_encoder_virt(drm_enc); - DPU_DEBUG_ENC(dpu_enc, "\n"); - - priv = drm_enc->dev->dev_private; - disp_info = &dpu_enc->disp_info; - dpu_kms = to_dpu_kms(priv->kms); - adj_mode = &crtc_state->adjusted_mode; - global_state = dpu_kms_get_global_state(crtc_state->state); - if (IS_ERR(global_state)) - return PTR_ERR(global_state); - - trace_dpu_enc_atomic_check(DRMID(drm_enc)); - - dsc = dpu_encoder_get_dsc_config(drm_enc); - - topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, crtc_state, dsc); + connector = drm_atomic_get_new_connector_for_encoder(state, drm_enc); + if (!connector) + return; + conn_state = drm_atomic_get_new_connector_state(state, connector); + if (!conn_state) + return; /* * Use CDM only for writeback or DP at the moment as other interfaces cannot handle it. @@ -781,34 +707,45 @@ static int dpu_encoder_virt_atomic_check( fb = conn_state->writeback_job->fb; if (fb && MSM_FORMAT_IS_YUV(msm_framebuffer_format(fb))) - topology.needs_cdm = true; + topology->num_cdm++; } else if (disp_info->intf_type == INTF_DP) { if (msm_dp_is_yuv_420_enabled(priv->dp[disp_info->h_tile_instance[0]], adj_mode)) - topology.needs_cdm = true; + topology->num_cdm++; } +} - if (topology.needs_cdm && !dpu_enc->cur_master->hw_cdm) - crtc_state->mode_changed = true; - else if (!topology.needs_cdm && dpu_enc->cur_master->hw_cdm) - crtc_state->mode_changed = true; - /* - * Release and Allocate resources on every modeset - * Dont allocate when active is false. - */ - if (drm_atomic_crtc_needs_modeset(crtc_state)) { - dpu_rm_release(global_state, drm_enc); +bool dpu_encoder_needs_modeset(struct drm_encoder *drm_enc, struct drm_atomic_state *state) +{ + struct drm_connector *connector; + struct drm_connector_state *conn_state; + struct drm_framebuffer *fb; + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc); - if (!crtc_state->active_changed || crtc_state->enable) - ret = dpu_rm_reserve(&dpu_kms->rm, global_state, - drm_enc, crtc_state, &topology); - if (!ret) - dpu_encoder_assign_crtc_resources(dpu_kms, drm_enc, - global_state, crtc_state); - } + if (!drm_enc || !state) + return false; - trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags); + connector = drm_atomic_get_new_connector_for_encoder(state, drm_enc); + if (!connector) + return false; - return ret; + conn_state = drm_atomic_get_new_connector_state(state, connector); + + /** + * These checks are duplicated from dpu_encoder_update_topology() since + * CRTC and encoder don't hold topology information + */ + if (dpu_enc->disp_info.intf_type == INTF_WB && conn_state->writeback_job) { + fb = conn_state->writeback_job->fb; + if (fb && MSM_FORMAT_IS_YUV(msm_framebuffer_format(fb))) { + if (!dpu_enc->cur_master->hw_cdm) + return true; + } else { + if (dpu_enc->cur_master->hw_cdm) + return true; + } + } + + return false; } static void _dpu_encoder_update_vsync_source(struct dpu_encoder_virt *dpu_enc, @@ -1219,8 +1156,12 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC]; struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC]; struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC]; + struct dpu_hw_blk *hw_cwb[MAX_CHANNELS_PER_ENC]; int num_ctl, num_pp, num_dsc; + int num_cwb = 0; + bool is_cwb_encoder; unsigned int dsc_mask = 0; + unsigned int cwb_mask = 0; int i; if (!drm_enc) { @@ -1233,6 +1174,8 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, priv = drm_enc->dev->dev_private; dpu_kms = to_dpu_kms(priv->kms); + is_cwb_encoder = drm_crtc_in_clone_mode(crtc_state) && + dpu_enc->disp_info.intf_type == INTF_WB; global_state = dpu_kms_get_existing_global_state(dpu_kms); if (IS_ERR_OR_NULL(global_state)) { @@ -1243,18 +1186,38 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, trace_dpu_enc_mode_set(DRMID(drm_enc)); /* Query resource that have been reserved in atomic check step. */ - num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, - drm_enc->base.id, DPU_HW_BLK_PINGPONG, hw_pp, - ARRAY_SIZE(hw_pp)); + if (is_cwb_encoder) { + num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, + drm_enc->crtc, + DPU_HW_BLK_DCWB_PINGPONG, + hw_pp, ARRAY_SIZE(hw_pp)); + num_cwb = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, + drm_enc->crtc, + DPU_HW_BLK_CWB, + hw_cwb, ARRAY_SIZE(hw_cwb)); + } else { + num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, + drm_enc->crtc, + DPU_HW_BLK_PINGPONG, hw_pp, + ARRAY_SIZE(hw_pp)); + } + + for (i = 0; i < num_cwb; i++) { + dpu_enc->hw_cwb[i] = to_dpu_hw_cwb(hw_cwb[i]); + cwb_mask |= BIT(dpu_enc->hw_cwb[i]->idx - CWB_0); + } + + dpu_enc->cwb_mask = cwb_mask; + num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, - drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl)); + drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl)); for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i]) : NULL; num_dsc = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, - drm_enc->base.id, DPU_HW_BLK_DSC, + drm_enc->crtc, DPU_HW_BLK_DSC, hw_dsc, ARRAY_SIZE(hw_dsc)); for (i = 0; i < num_dsc; i++) { dpu_enc->hw_dsc[i] = to_dpu_hw_dsc(hw_dsc[i]); @@ -1268,7 +1231,7 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, struct dpu_hw_blk *hw_cdm = NULL; dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, - drm_enc->base.id, DPU_HW_BLK_CDM, + drm_enc->crtc, DPU_HW_BLK_CDM, &hw_cdm, 1); dpu_enc->cur_master->hw_cdm = hw_cdm ? to_dpu_hw_cdm(hw_cdm) : NULL; } @@ -1283,7 +1246,11 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, return; } - phys->hw_ctl = i < num_ctl ? to_dpu_hw_ctl(hw_ctl[i]) : NULL; + /* Use first (and only) CTL if active CTLs are supported */ + if (num_ctl == 1) + phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[0]); + else + phys->hw_ctl = i < num_ctl ? to_dpu_hw_ctl(hw_ctl[i]) : NULL; if (!phys->hw_ctl) { DPU_ERROR_ENC(dpu_enc, "no ctl block assigned at idx: %d\n", i); @@ -1447,7 +1414,7 @@ static void dpu_encoder_virt_atomic_disable(struct drm_encoder *drm_enc, /* after phys waits for frame-done, should be no more frames pending */ if (atomic_xchg(&dpu_enc->frame_done_timeout_ms, 0)) { DPU_ERROR("enc%d timeout pending\n", drm_enc->base.id); - del_timer_sync(&dpu_enc->frame_done_timer); + timer_delete_sync(&dpu_enc->frame_done_timer); } dpu_encoder_resource_control(drm_enc, DPU_ENC_RC_EVENT_STOP); @@ -1619,7 +1586,7 @@ void dpu_encoder_frame_done_callback( if (!dpu_enc->frame_busy_mask[0]) { atomic_set(&dpu_enc->frame_done_timeout_ms, 0); - del_timer(&dpu_enc->frame_done_timer); + timer_delete(&dpu_enc->frame_done_timer); dpu_encoder_resource_control(drm_enc, DPU_ENC_RC_EVENT_FRAME_DONE); @@ -1654,6 +1621,7 @@ static void dpu_encoder_off_work(struct work_struct *work) static void _dpu_encoder_trigger_flush(struct drm_encoder *drm_enc, struct dpu_encoder_phys *phys, uint32_t extra_flush_bits) { + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc); struct dpu_hw_ctl *ctl; int pending_kickoff_cnt; u32 ret = UINT_MAX; @@ -1671,6 +1639,15 @@ static void _dpu_encoder_trigger_flush(struct drm_encoder *drm_enc, pending_kickoff_cnt = dpu_encoder_phys_inc_pending(phys); + /* Return early if encoder is writeback and in clone mode */ + if (drm_enc->encoder_type == DRM_MODE_ENCODER_VIRTUAL && + dpu_enc->cwb_mask) { + DPU_DEBUG("encoder %d skip flush for concurrent writeback encoder\n", + DRMID(drm_enc)); + return; + } + + if (extra_flush_bits && ctl->ops.update_pending_flush) ctl->ops.update_pending_flush(ctl, extra_flush_bits); @@ -1693,6 +1670,8 @@ static void _dpu_encoder_trigger_flush(struct drm_encoder *drm_enc, */ static void _dpu_encoder_trigger_start(struct dpu_encoder_phys *phys) { + struct dpu_encoder_virt *dpu_enc; + if (!phys) { DPU_ERROR("invalid argument(s)\n"); return; @@ -1703,6 +1682,14 @@ static void _dpu_encoder_trigger_start(struct dpu_encoder_phys *phys) return; } + dpu_enc = to_dpu_encoder_virt(phys->parent); + + if (phys->parent->encoder_type == DRM_MODE_ENCODER_VIRTUAL && + dpu_enc->cwb_mask) { + DPU_DEBUG("encoder %d CWB enabled, skipping\n", DRMID(phys->parent)); + return; + } + if (phys->ops.trigger_start && phys->enable_state != DPU_ENC_DISABLED) phys->ops.trigger_start(phys); } @@ -2020,7 +2007,6 @@ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_ctl *ctl, static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc, struct drm_dsc_config *dsc) { - /* 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]; @@ -2030,22 +2016,24 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc, int dsc_common_mode; int pic_width; u32 initial_lines; + int num_dsc = 0; 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_ERROR_ENC(dpu_enc, "invalid params for DSC\n"); - return; - } + if (!hw_pp[i] || !hw_dsc[i]) + break; + + num_dsc++; } - dsc_common_mode = 0; pic_width = dsc->pic_width; - dsc_common_mode = DSC_MODE_SPLIT_PANEL; + dsc_common_mode = 0; + if (num_dsc > 1) + dsc_common_mode |= DSC_MODE_SPLIT_PANEL; if (dpu_encoder_use_dsc_merge(enc_master->parent)) dsc_common_mode |= DSC_MODE_MULTIPLEX; if (enc_master->intf_mode == INTF_MODE_VIDEO) @@ -2054,14 +2042,10 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc, this_frame_slices = pic_width / dsc->slice_width; intf_ip_w = this_frame_slices * dsc->slice_width; - /* - * dsc merge case: when using 2 encoders for the same stream, - * no. of slices need to be same on both the encoders. - */ - enc_ip_w = intf_ip_w / 2; + enc_ip_w = intf_ip_w / num_dsc; initial_lines = dpu_encoder_dsc_initial_line_calc(dsc, enc_ip_w); - for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) + for (i = 0; i < num_dsc; i++) dpu_encoder_dsc_pipe_cfg(ctl, hw_dsc[i], hw_pp[i], dsc, dsc_common_mode, initial_lines); } @@ -2135,6 +2119,25 @@ bool dpu_encoder_is_valid_for_commit(struct drm_encoder *drm_enc) } /** + * dpu_encoder_start_frame_done_timer - Start the encoder frame done timer + * @drm_enc: Pointer to drm encoder structure + */ +void dpu_encoder_start_frame_done_timer(struct drm_encoder *drm_enc) +{ + struct dpu_encoder_virt *dpu_enc; + unsigned long timeout_ms; + + dpu_enc = to_dpu_encoder_virt(drm_enc); + timeout_ms = DPU_ENCODER_FRAME_DONE_TIMEOUT_FRAMES * 1000 / + drm_mode_vrefresh(&drm_enc->crtc->state->adjusted_mode); + + atomic_set(&dpu_enc->frame_done_timeout_ms, timeout_ms); + mod_timer(&dpu_enc->frame_done_timer, + jiffies + msecs_to_jiffies(timeout_ms)); + +} + +/** * dpu_encoder_kickoff - trigger a double buffer flip of the ctl path * (i.e. ctl flush and start) immediately. * @drm_enc: encoder pointer @@ -2143,7 +2146,6 @@ void dpu_encoder_kickoff(struct drm_encoder *drm_enc) { struct dpu_encoder_virt *dpu_enc; struct dpu_encoder_phys *phys; - unsigned long timeout_ms; unsigned int i; DPU_ATRACE_BEGIN("encoder_kickoff"); @@ -2151,13 +2153,6 @@ void dpu_encoder_kickoff(struct drm_encoder *drm_enc) trace_dpu_enc_kickoff(DRMID(drm_enc)); - timeout_ms = DPU_ENCODER_FRAME_DONE_TIMEOUT_FRAMES * 1000 / - drm_mode_vrefresh(&drm_enc->crtc->state->adjusted_mode); - - atomic_set(&dpu_enc->frame_done_timeout_ms, timeout_ms); - mod_timer(&dpu_enc->frame_done_timer, - jiffies + msecs_to_jiffies(timeout_ms)); - /* All phys encs are ready to go, trigger the kickoff */ _dpu_encoder_kickoff_phys(dpu_enc); @@ -2183,22 +2178,25 @@ static void dpu_encoder_helper_reset_mixers(struct dpu_encoder_phys *phys_enc) memset(&mixer, 0, sizeof(mixer)); /* reset all mixers for this encoder */ - if (phys_enc->hw_ctl->ops.clear_all_blendstages) - phys_enc->hw_ctl->ops.clear_all_blendstages(phys_enc->hw_ctl); + if (ctl->ops.clear_all_blendstages) + ctl->ops.clear_all_blendstages(ctl); global_state = dpu_kms_get_existing_global_state(phys_enc->dpu_kms); num_lm = dpu_rm_get_assigned_resources(&phys_enc->dpu_kms->rm, global_state, - phys_enc->parent->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm)); + phys_enc->parent->crtc, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm)); for (i = 0; i < num_lm; i++) { hw_mixer[i] = to_dpu_hw_mixer(hw_lm[i]); - if (phys_enc->hw_ctl->ops.update_pending_flush_mixer) - phys_enc->hw_ctl->ops.update_pending_flush_mixer(ctl, hw_mixer[i]->idx); + if (ctl->ops.update_pending_flush_mixer) + ctl->ops.update_pending_flush_mixer(ctl, hw_mixer[i]->idx); /* clear all blendstages */ - if (phys_enc->hw_ctl->ops.setup_blendstage) - phys_enc->hw_ctl->ops.setup_blendstage(ctl, hw_mixer[i]->idx, NULL); + if (ctl->ops.setup_blendstage) + ctl->ops.setup_blendstage(ctl, hw_mixer[i]->idx, NULL); + + if (ctl->ops.set_active_fetch_pipes) + ctl->ops.set_active_fetch_pipes(ctl, NULL); } } @@ -2250,7 +2248,7 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) dpu_enc = to_dpu_encoder_virt(phys_enc->parent); - phys_enc->hw_ctl->ops.reset(ctl); + ctl->ops.reset(ctl); dpu_encoder_helper_reset_mixers(phys_enc); @@ -2265,8 +2263,8 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) phys_enc->hw_wb->ops.bind_pingpong_blk(phys_enc->hw_wb, PINGPONG_NONE); /* mark WB flush as pending */ - if (phys_enc->hw_ctl->ops.update_pending_flush_wb) - phys_enc->hw_ctl->ops.update_pending_flush_wb(ctl, phys_enc->hw_wb->idx); + if (ctl->ops.update_pending_flush_wb) + ctl->ops.update_pending_flush_wb(ctl, phys_enc->hw_wb->idx); } else { for (i = 0; i < dpu_enc->num_phys_encs; i++) { if (dpu_enc->phys_encs[i] && phys_enc->hw_intf->ops.bind_pingpong_blk) @@ -2275,18 +2273,24 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) PINGPONG_NONE); /* mark INTF flush as pending */ - if (phys_enc->hw_ctl->ops.update_pending_flush_intf) - phys_enc->hw_ctl->ops.update_pending_flush_intf(phys_enc->hw_ctl, + if (ctl->ops.update_pending_flush_intf) + ctl->ops.update_pending_flush_intf(ctl, dpu_enc->phys_encs[i]->hw_intf->idx); } } + if (phys_enc->hw_pp && phys_enc->hw_pp->ops.setup_dither) + phys_enc->hw_pp->ops.setup_dither(phys_enc->hw_pp, NULL); + + if (dpu_enc->cwb_mask) + dpu_encoder_helper_phys_setup_cwb(phys_enc, false); + /* reset the merge 3D HW block */ if (phys_enc->hw_pp && phys_enc->hw_pp->merge_3d) { phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d, BLEND_3D_NONE); - if (phys_enc->hw_ctl->ops.update_pending_flush_merge_3d) - phys_enc->hw_ctl->ops.update_pending_flush_merge_3d(ctl, + if (ctl->ops.update_pending_flush_merge_3d) + ctl->ops.update_pending_flush_merge_3d(ctl, phys_enc->hw_pp->merge_3d->idx); } @@ -2294,9 +2298,9 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) if (phys_enc->hw_cdm->ops.bind_pingpong_blk && phys_enc->hw_pp) phys_enc->hw_cdm->ops.bind_pingpong_blk(phys_enc->hw_cdm, PINGPONG_NONE); - if (phys_enc->hw_ctl->ops.update_pending_flush_cdm) - phys_enc->hw_ctl->ops.update_pending_flush_cdm(phys_enc->hw_ctl, - phys_enc->hw_cdm->idx); + if (ctl->ops.update_pending_flush_cdm) + ctl->ops.update_pending_flush_cdm(ctl, + phys_enc->hw_cdm->idx); } if (dpu_enc->dsc) { @@ -2307,6 +2311,7 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_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); + intf_cfg.cwb = dpu_enc->cwb_mask; if (phys_enc->hw_intf) intf_cfg.intf = phys_enc->hw_intf->idx; @@ -2324,6 +2329,68 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) ctl->ops.clear_pending_flush(ctl); } +void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys *phys_enc, + bool enable) +{ + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(phys_enc->parent); + struct dpu_hw_cwb *hw_cwb; + struct dpu_hw_ctl *hw_ctl; + struct dpu_hw_cwb_setup_cfg cwb_cfg; + + struct dpu_kms *dpu_kms; + struct dpu_global_state *global_state; + struct dpu_hw_blk *rt_pp_list[MAX_CHANNELS_PER_ENC]; + int num_pp; + + if (!phys_enc->hw_wb) + return; + + hw_ctl = phys_enc->hw_ctl; + + if (!phys_enc->hw_ctl) { + DPU_DEBUG("[wb:%d] no ctl assigned\n", + phys_enc->hw_wb->idx - WB_0); + return; + } + + dpu_kms = phys_enc->dpu_kms; + global_state = dpu_kms_get_existing_global_state(dpu_kms); + num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, + phys_enc->parent->crtc, + DPU_HW_BLK_PINGPONG, rt_pp_list, + ARRAY_SIZE(rt_pp_list)); + + if (num_pp == 0 || num_pp > MAX_CHANNELS_PER_ENC) { + DPU_DEBUG_ENC(dpu_enc, "invalid num_pp %d\n", num_pp); + return; + } + + /* + * The CWB mux supports using LM or DSPP as tap points. For now, + * always use LM tap point + */ + cwb_cfg.input = INPUT_MODE_LM_OUT; + + for (int i = 0; i < MAX_CHANNELS_PER_ENC; i++) { + hw_cwb = dpu_enc->hw_cwb[i]; + if (!hw_cwb) + continue; + + if (enable) { + struct dpu_hw_pingpong *hw_pp = + to_dpu_hw_pingpong(rt_pp_list[i]); + cwb_cfg.pp_idx = hw_pp->idx; + } else { + cwb_cfg.pp_idx = PINGPONG_NONE; + } + + hw_cwb->ops.config_cwb(hw_cwb, &cwb_cfg); + + if (hw_ctl->ops.update_pending_flush_cwb) + hw_ctl->ops.update_pending_flush_cwb(hw_ctl, hw_cwb->idx); + } +} + /** * dpu_encoder_helper_phys_setup_cdm - setup chroma down sampling block * @phys_enc: Pointer to physical encoder @@ -2510,6 +2577,38 @@ static int dpu_encoder_virt_add_phys_encs( return 0; } +/** + * dpu_encoder_get_clones - Calculate the possible_clones for DPU encoder + * @drm_enc: DRM encoder pointer + * Returns: possible_clones mask + */ +uint32_t dpu_encoder_get_clones(struct drm_encoder *drm_enc) +{ + struct drm_encoder *curr; + int type = drm_enc->encoder_type; + uint32_t clone_mask = drm_encoder_mask(drm_enc); + + /* + * Set writeback as possible clones of real-time DSI encoders and vice + * versa + * + * Writeback encoders can't be clones of each other and DSI + * encoders can't be clones of each other. + * + * TODO: Add DP encoders as valid possible clones for writeback encoders + * (and vice versa) once concurrent writeback has been validated for DP + */ + drm_for_each_encoder(curr, drm_enc->dev) { + if ((type == DRM_MODE_ENCODER_VIRTUAL && + curr->encoder_type == DRM_MODE_ENCODER_DSI) || + (type == DRM_MODE_ENCODER_DSI && + curr->encoder_type == DRM_MODE_ENCODER_VIRTUAL)) + clone_mask |= drm_encoder_mask(curr); + } + + return clone_mask; +} + static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, struct dpu_kms *dpu_kms, struct msm_display_info *disp_info) @@ -2594,8 +2693,8 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, static void dpu_encoder_frame_done_timeout(struct timer_list *t) { - struct dpu_encoder_virt *dpu_enc = from_timer(dpu_enc, t, - frame_done_timer); + struct dpu_encoder_virt *dpu_enc = timer_container_of(dpu_enc, t, + frame_done_timer); struct drm_encoder *drm_enc = &dpu_enc->base; u32 event; @@ -2627,7 +2726,6 @@ static const struct drm_encoder_helper_funcs dpu_encoder_helper_funcs = { .atomic_mode_set = dpu_encoder_virt_atomic_mode_set, .atomic_disable = dpu_encoder_virt_atomic_disable, .atomic_enable = dpu_encoder_virt_atomic_enable, - .atomic_check = dpu_encoder_virt_atomic_check, }; static const struct drm_encoder_funcs dpu_encoder_funcs = { @@ -2786,6 +2884,18 @@ enum dpu_intf_mode dpu_encoder_get_intf_mode(struct drm_encoder *encoder) } /** + * dpu_encoder_helper_get_cwb_mask - get CWB blocks mask for the DPU encoder + * @phys_enc: Pointer to physical encoder structure + */ +unsigned int dpu_encoder_helper_get_cwb_mask(struct dpu_encoder_phys *phys_enc) +{ + struct drm_encoder *encoder = phys_enc->parent; + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(encoder); + + return dpu_enc->cwb_mask; +} + +/** * dpu_encoder_helper_get_dsc - get DSC blocks mask for the DPU encoder * This helper function is used by physical encoder to get DSC blocks mask * used for this encoder. diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h index 92b5ee390788..ca1ca2e51d7e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.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-2024 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark <robdclark@gmail.com> @@ -60,6 +60,8 @@ enum dpu_intf_mode dpu_encoder_get_intf_mode(struct drm_encoder *encoder); void dpu_encoder_virt_runtime_resume(struct drm_encoder *encoder); +uint32_t dpu_encoder_get_clones(struct drm_encoder *drm_enc); + struct drm_encoder *dpu_encoder_init(struct drm_device *dev, int drm_enc_mode, struct msm_display_info *disp_info); @@ -80,6 +82,13 @@ int dpu_encoder_get_crc(const struct drm_encoder *drm_enc, u32 *crcs, int pos); bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc); +void dpu_encoder_update_topology(struct drm_encoder *drm_enc, + struct msm_display_topology *topology, + struct drm_atomic_state *state, + const struct drm_display_mode *adj_mode); + +bool dpu_encoder_needs_modeset(struct drm_encoder *drm_enc, struct drm_atomic_state *state); + void dpu_encoder_prepare_wb_job(struct drm_encoder *drm_enc, struct drm_writeback_job *job); @@ -88,4 +97,5 @@ void dpu_encoder_cleanup_wb_job(struct drm_encoder *drm_enc, bool dpu_encoder_is_valid_for_commit(struct drm_encoder *drm_enc); +void dpu_encoder_start_frame_done_timer(struct drm_encoder *drm_enc); #endif /* __DPU_ENCODER_H__ */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h index 63f09857025c..61b22d949454 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.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-2024 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved. */ @@ -309,6 +309,8 @@ static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode( return BLEND_3D_NONE; } +unsigned int dpu_encoder_helper_get_cwb_mask(struct dpu_encoder_phys *phys_enc); + unsigned int dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc); struct drm_dsc_config *dpu_encoder_get_dsc_config(struct drm_encoder *drm_enc); @@ -331,6 +333,9 @@ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc, void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc); +void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys *phys_enc, + bool enable); + void dpu_encoder_helper_phys_setup_cdm(struct dpu_encoder_phys *phys_enc, const struct msm_format *dpu_fmt, u32 output_type); 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 e9bbccc44dad..a0ba55ab3c89 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 @@ -5,6 +5,7 @@ #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ #include <linux/delay.h> +#include <linux/string_choices.h> #include "dpu_encoder_phys.h" #include "dpu_hw_interrupts.h" #include "dpu_hw_pingpong.h" @@ -59,6 +60,8 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg( return; intf_cfg.intf = phys_enc->hw_intf->idx; + if (phys_enc->split_role == ENC_ROLE_MASTER) + intf_cfg.intf_master = phys_enc->hw_intf->idx; intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_CMD; intf_cfg.stream_sel = cmd_enc->stream_sel; intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); @@ -261,7 +264,7 @@ static int dpu_encoder_phys_cmd_control_vblank_irq( DRM_DEBUG_KMS("id:%u pp:%d enable=%s/%d\n", DRMID(phys_enc->parent), phys_enc->hw_pp->idx - PINGPONG_0, - enable ? "true" : "false", refcount); + str_true_false(enable), refcount); if (enable) { if (phys_enc->vblank_refcount == 0) @@ -285,7 +288,7 @@ end: DRM_ERROR("vblank irq err id:%u pp:%d ret:%d, enable %s/%d\n", DRMID(phys_enc->parent), phys_enc->hw_pp->idx - PINGPONG_0, ret, - enable ? "true" : "false", refcount); + str_true_false(enable), refcount); } return ret; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c index abd6600046cb..1c468ca5d692 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c @@ -94,17 +94,21 @@ static void drm_mode_to_intf_timing_params( timing->vsync_polarity = 0; } - /* for DP/EDP, Shift timings to align it to bottom right */ - if (phys_enc->hw_intf->cap->type == INTF_DP) { + timing->wide_bus_en = dpu_encoder_is_widebus_enabled(phys_enc->parent); + timing->compression_en = dpu_encoder_is_dsc_enabled(phys_enc->parent); + + /* + * For DP/EDP, Shift timings to align it to bottom right. + * wide_bus_en is set for everything excluding SDM845 & + * porch changes cause DisplayPort failure and HDMI tearing. + */ + if (phys_enc->hw_intf->cap->type == INTF_DP && timing->wide_bus_en) { timing->h_back_porch += timing->h_front_porch; timing->h_front_porch = 0; timing->v_back_porch += timing->v_front_porch; timing->v_front_porch = 0; } - timing->wide_bus_en = dpu_encoder_is_widebus_enabled(phys_enc->parent); - timing->compression_en = dpu_encoder_is_dsc_enabled(phys_enc->parent); - /* * for DP, divide the horizonal parameters by 2 when * widebus is enabled @@ -298,6 +302,8 @@ static void dpu_encoder_phys_vid_setup_timing_engine( if (phys_enc->hw_cdm) intf_cfg.cdm = phys_enc->hw_cdm->idx; intf_cfg.intf = phys_enc->hw_intf->idx; + if (phys_enc->split_role == ENC_ROLE_MASTER) + intf_cfg.intf_master = phys_enc->hw_intf->idx; intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_VID; 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); @@ -372,7 +378,8 @@ static void dpu_encoder_phys_vid_underrun_irq(void *arg) static bool dpu_encoder_phys_vid_needs_single_flush( struct dpu_encoder_phys *phys_enc) { - return phys_enc->split_role != ENC_ROLE_SOLO; + return !(phys_enc->hw_ctl->caps->features & BIT(DPU_CTL_ACTIVE_CFG)) && + phys_enc->split_role != ENC_ROLE_SOLO; } static void dpu_encoder_phys_vid_atomic_mode_set( diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c index 4c006ec74575..849fea580a4c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ @@ -68,7 +68,7 @@ static void dpu_encoder_phys_wb_set_ot_limit( ot_params.num = hw_wb->idx - WB_0; ot_params.width = phys_enc->cached_mode.hdisplay; ot_params.height = phys_enc->cached_mode.vdisplay; - ot_params.is_wfd = true; + ot_params.is_wfd = !dpu_encoder_helper_get_cwb_mask(phys_enc); ot_params.frame_rate = drm_mode_vrefresh(&phys_enc->cached_mode); ot_params.vbif_idx = hw_wb->caps->vbif_idx; ot_params.rd = false; @@ -111,7 +111,7 @@ static void dpu_encoder_phys_wb_set_qos_remap( qos_params.vbif_idx = hw_wb->caps->vbif_idx; qos_params.xin_id = hw_wb->caps->xin_id; qos_params.num = hw_wb->idx - WB_0; - qos_params.is_rt = false; + qos_params.is_rt = dpu_encoder_helper_get_cwb_mask(phys_enc); DPU_DEBUG("[qos_remap] wb:%d vbif:%d xin:%d is_rt:%d\n", qos_params.num, @@ -174,6 +174,7 @@ static void dpu_encoder_phys_wb_setup_fb(struct dpu_encoder_phys *phys_enc, struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc); struct dpu_hw_wb *hw_wb; struct dpu_hw_wb_cfg *wb_cfg; + u32 cdp_usage; if (!phys_enc || !phys_enc->dpu_kms || !phys_enc->dpu_kms->catalog) { DPU_ERROR("invalid encoder\n"); @@ -182,6 +183,10 @@ static void dpu_encoder_phys_wb_setup_fb(struct dpu_encoder_phys *phys_enc, hw_wb = phys_enc->hw_wb; wb_cfg = &wb_enc->wb_cfg; + if (dpu_encoder_helper_get_cwb_mask(phys_enc)) + cdp_usage = DPU_PERF_CDP_USAGE_RT; + else + cdp_usage = DPU_PERF_CDP_USAGE_NRT; wb_cfg->intf_mode = phys_enc->intf_mode; wb_cfg->roi.x1 = 0; @@ -199,7 +204,7 @@ static void dpu_encoder_phys_wb_setup_fb(struct dpu_encoder_phys *phys_enc, const struct dpu_perf_cfg *perf = phys_enc->dpu_kms->catalog->perf; hw_wb->ops.setup_cdp(hw_wb, format, - perf->cdp_cfg[DPU_PERF_CDP_USAGE_NRT].wr_enable); + perf->cdp_cfg[cdp_usage].wr_enable); } if (hw_wb->ops.setup_outaddress) @@ -236,6 +241,7 @@ static void dpu_encoder_phys_wb_setup_ctl(struct dpu_encoder_phys *phys_enc) intf_cfg.intf = DPU_NONE; intf_cfg.wb = hw_wb->idx; + intf_cfg.cwb = dpu_encoder_helper_get_cwb_mask(phys_enc); if (mode_3d && hw_pp && hw_pp->merge_3d) intf_cfg.merge_3d = hw_pp->merge_3d->idx; @@ -340,6 +346,8 @@ static void dpu_encoder_phys_wb_setup( dpu_encoder_helper_phys_setup_cdm(phys_enc, format, CDM_CDWN_OUTPUT_WB); + dpu_encoder_helper_phys_setup_cwb(phys_enc, true); + dpu_encoder_phys_wb_setup_ctl(phys_enc); } 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 0b342c043875..c878fe196aeb 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -34,11 +34,11 @@ #define VIG_MSM8998_MASK \ (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3_COMPATIBLE)) -#define VIG_SDM845_MASK \ +#define VIG_SDM845_MASK_NO_SDMA \ (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3_COMPATIBLE)) #define VIG_SDM845_MASK_SDMA \ - (VIG_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2)) + (VIG_SDM845_MASK_NO_SDMA | BIT(DPU_SSPP_SMART_DMA_V2)) #define VIG_QCM2290_MASK (VIG_BASE_MASK | BIT(DPU_SSPP_QOS_8LVL)) @@ -54,24 +54,24 @@ BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT)) #define VIG_SC7280_MASK \ - (VIG_SDM845_MASK | BIT(DPU_SSPP_INLINE_ROTATION)) + (VIG_SDM845_MASK_NO_SDMA | BIT(DPU_SSPP_INLINE_ROTATION)) #define VIG_SC7280_MASK_SDMA \ (VIG_SC7280_MASK | BIT(DPU_SSPP_SMART_DMA_V2)) -#define DMA_SDM845_MASK \ +#define DMA_SDM845_MASK_NO_SDMA \ (BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_QOS_8LVL) |\ BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\ BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT)) -#define DMA_CURSOR_SDM845_MASK \ - (DMA_SDM845_MASK | BIT(DPU_SSPP_CURSOR)) +#define DMA_CURSOR_SDM845_MASK_NO_SDMA \ + (DMA_SDM845_MASK_NO_SDMA | BIT(DPU_SSPP_CURSOR)) #define DMA_SDM845_MASK_SDMA \ - (DMA_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2)) + (DMA_SDM845_MASK_NO_SDMA | BIT(DPU_SSPP_SMART_DMA_V2)) #define DMA_CURSOR_SDM845_MASK_SDMA \ - (DMA_CURSOR_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2)) + (DMA_CURSOR_SDM845_MASK_NO_SDMA | BIT(DPU_SSPP_SMART_DMA_V2)) #define DMA_CURSOR_MSM8996_MASK \ (DMA_MSM8996_MASK | BIT(DPU_SSPP_CURSOR)) @@ -98,15 +98,9 @@ #define PINGPONG_MSM8996_MASK \ (BIT(DPU_PINGPONG_DSC)) -#define PINGPONG_MSM8996_TE2_MASK \ - (PINGPONG_MSM8996_MASK | BIT(DPU_PINGPONG_TE2)) - #define PINGPONG_SDM845_MASK \ (BIT(DPU_PINGPONG_DITHER) | 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_DSC)) @@ -232,37 +226,6 @@ static const u32 rotation_v2_formats[] = { /* TODO add formats after validation */ }; -static const u32 wb2_formats_rgb[] = { - DRM_FORMAT_RGB565, - DRM_FORMAT_BGR565, - DRM_FORMAT_RGB888, - DRM_FORMAT_ARGB8888, - DRM_FORMAT_RGBA8888, - DRM_FORMAT_ABGR8888, - DRM_FORMAT_XRGB8888, - DRM_FORMAT_RGBX8888, - DRM_FORMAT_XBGR8888, - DRM_FORMAT_ARGB1555, - DRM_FORMAT_RGBA5551, - DRM_FORMAT_XRGB1555, - DRM_FORMAT_RGBX5551, - DRM_FORMAT_ARGB4444, - DRM_FORMAT_RGBA4444, - DRM_FORMAT_RGBX4444, - DRM_FORMAT_XRGB4444, - DRM_FORMAT_BGR888, - DRM_FORMAT_BGRA8888, - DRM_FORMAT_BGRX8888, - DRM_FORMAT_ABGR1555, - DRM_FORMAT_BGRA5551, - DRM_FORMAT_XBGR1555, - DRM_FORMAT_BGRX5551, - DRM_FORMAT_ABGR4444, - DRM_FORMAT_BGRA4444, - DRM_FORMAT_BGRX4444, - DRM_FORMAT_XBGR4444, -}; - static const u32 wb2_formats_rgb_yuv[] = { DRM_FORMAT_RGB565, DRM_FORMAT_BGR565, @@ -407,8 +370,6 @@ static const struct dpu_sspp_sub_blks dpu_dma_sblk = _DMA_SBLK(); * MIXER sub blocks config *************************************************************/ -/* MSM8998 */ - static const struct dpu_lm_sub_blks msm8998_lm_sblk = { .maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH, .maxblendstages = 7, /* excluding base layer */ @@ -418,8 +379,6 @@ static const struct dpu_lm_sub_blks msm8998_lm_sblk = { }, }; -/* SDM845 */ - static const struct dpu_lm_sub_blks sdm845_lm_sblk = { .maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH, .maxblendstages = 11, /* excluding base layer */ @@ -429,8 +388,6 @@ static const struct dpu_lm_sub_blks sdm845_lm_sblk = { }, }; -/* SC7180 */ - static const struct dpu_lm_sub_blks sc7180_lm_sblk = { .maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH, .maxblendstages = 7, /* excluding base layer */ @@ -439,8 +396,6 @@ static const struct dpu_lm_sub_blks sc7180_lm_sblk = { }, }; -/* QCM2290 */ - static const struct dpu_lm_sub_blks qcm2290_lm_sblk = { .maxwidth = DEFAULT_DPU_LINE_WIDTH, .maxblendstages = 4, /* excluding base layer */ @@ -465,22 +420,11 @@ static const struct dpu_dspp_sub_blks sdm845_dspp_sblk = { /************************************************************* * PINGPONG sub blocks config *************************************************************/ -static const struct dpu_pingpong_sub_blks msm8996_pp_sblk_te = { - .te2 = {.name = "te2", .base = 0x2000, .len = 0x0, - .version = 0x1}, -}; static const struct dpu_pingpong_sub_blks msm8996_pp_sblk = { /* No dither block */ }; -static const struct dpu_pingpong_sub_blks sdm845_pp_sblk_te = { - .te2 = {.name = "te2", .base = 0x2000, .len = 0x0, - .version = 0x1}, - .dither = {.name = "dither", .base = 0x30e0, - .len = 0x20, .version = 0x10000}, -}; - static const struct dpu_pingpong_sub_blks sdm845_pp_sblk = { .dither = {.name = "dither", .base = 0x30e0, .len = 0x20, .version = 0x10000}, @@ -507,7 +451,14 @@ static const struct dpu_dsc_sub_blks dsc_sblk_1 = { /************************************************************* * CDM block config *************************************************************/ -static const struct dpu_cdm_cfg sc7280_cdm = { +static const struct dpu_cdm_cfg dpu_cdm_1_x_4_x = { + .name = "cdm_0", + .id = CDM_0, + .len = 0x224, + .base = 0x79200, +}; + +static const struct dpu_cdm_cfg dpu_cdm_5_x = { .name = "cdm_0", .id = CDM_0, .len = 0x228, @@ -783,7 +734,7 @@ static const struct dpu_qos_lut_entry sc7180_qos_nrt[] = { #include "catalog/dpu_8_4_sa8775p.h" #include "catalog/dpu_9_0_sm8550.h" - +#include "catalog/dpu_9_1_sar2130p.h" #include "catalog/dpu_9_2_x1e80100.h" #include "catalog/dpu_10_0_sm8650.h" 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 4cea19e1a203..01dd6e65f777 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -115,7 +115,6 @@ enum { /** * PINGPONG sub-blocks - * @DPU_PINGPONG_TE2 Additional 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 @@ -123,8 +122,7 @@ enum { * @DPU_PINGPONG_MAX */ enum { - DPU_PINGPONG_TE2 = 0x1, - DPU_PINGPONG_SPLIT, + DPU_PINGPONG_SPLIT = 0x1, DPU_PINGPONG_SLAVE, DPU_PINGPONG_DITHER, DPU_PINGPONG_DSC, @@ -404,8 +402,6 @@ struct dpu_dspp_sub_blks { }; struct dpu_pingpong_sub_blks { - struct dpu_pp_blk te; - struct dpu_pp_blk te2; struct dpu_pp_blk dither; }; @@ -841,6 +837,7 @@ extern const struct dpu_mdss_cfg dpu_msm8937_cfg; extern const struct dpu_mdss_cfg dpu_msm8953_cfg; extern const struct dpu_mdss_cfg dpu_msm8996_cfg; extern const struct dpu_mdss_cfg dpu_msm8998_cfg; +extern const struct dpu_mdss_cfg dpu_sar2130p_cfg; extern const struct dpu_mdss_cfg dpu_sdm630_cfg; extern const struct dpu_mdss_cfg dpu_sdm660_cfg; extern const struct dpu_mdss_cfg dpu_sdm845_cfg; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c index ae1534c49ae0..3f88c3641d4a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c @@ -214,7 +214,9 @@ static void dpu_hw_cdm_bind_pingpong_blk(struct dpu_hw_cdm *ctx, const enum dpu_ mux_cfg = DPU_REG_READ(c, CDM_MUX); mux_cfg &= ~0xf; - if (pp) + if (pp >= PINGPONG_CWB_0) + mux_cfg |= 0xd; + else if (pp) mux_cfg |= (pp - PINGPONG_0) & 0x7; else mux_cfg |= 0xf; 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 4893f10d6a58..573e42b06ad0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include <linux/delay.h> @@ -31,12 +31,14 @@ #define CTL_MERGE_3D_ACTIVE 0x0E4 #define CTL_DSC_ACTIVE 0x0E8 #define CTL_WB_ACTIVE 0x0EC +#define CTL_CWB_ACTIVE 0x0F0 #define CTL_INTF_ACTIVE 0x0F4 #define CTL_CDM_ACTIVE 0x0F8 #define CTL_FETCH_PIPE_ACTIVE 0x0FC #define CTL_MERGE_3D_FLUSH 0x100 #define CTL_DSC_FLUSH 0x104 #define CTL_WB_FLUSH 0x108 +#define CTL_CWB_FLUSH 0x10C #define CTL_INTF_FLUSH 0x110 #define CTL_CDM_FLUSH 0x114 #define CTL_PERIPH_FLUSH 0x128 @@ -53,6 +55,7 @@ #define PERIPH_IDX 30 #define INTF_IDX 31 #define WB_IDX 16 +#define CWB_IDX 28 #define DSPP_IDX 29 /* From DPU hw rev 7.x.x */ #define CTL_INVALID_BIT 0xffff #define CTL_DEFAULT_GROUP_ID 0xf @@ -110,6 +113,7 @@ static inline void dpu_hw_ctl_clear_pending_flush(struct dpu_hw_ctl *ctx) ctx->pending_flush_mask = 0x0; ctx->pending_intf_flush_mask = 0; ctx->pending_wb_flush_mask = 0; + ctx->pending_cwb_flush_mask = 0; ctx->pending_merge_3d_flush_mask = 0; ctx->pending_dsc_flush_mask = 0; ctx->pending_cdm_flush_mask = 0; @@ -144,6 +148,9 @@ static inline void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx) if (ctx->pending_flush_mask & BIT(WB_IDX)) DPU_REG_WRITE(&ctx->hw, CTL_WB_FLUSH, ctx->pending_wb_flush_mask); + if (ctx->pending_flush_mask & BIT(CWB_IDX)) + DPU_REG_WRITE(&ctx->hw, CTL_CWB_FLUSH, + ctx->pending_cwb_flush_mask); if (ctx->pending_flush_mask & BIT(DSPP_IDX)) for (dspp = DSPP_0; dspp < DSPP_MAX; dspp++) { @@ -254,6 +261,12 @@ static void dpu_hw_ctl_update_pending_flush_mixer(struct dpu_hw_ctl *ctx, case LM_5: ctx->pending_flush_mask |= BIT(20); break; + case LM_6: + ctx->pending_flush_mask |= BIT(21); + break; + case LM_7: + ctx->pending_flush_mask |= BIT(27); + break; default: break; } @@ -310,6 +323,13 @@ static void dpu_hw_ctl_update_pending_flush_wb_v1(struct dpu_hw_ctl *ctx, ctx->pending_flush_mask |= BIT(WB_IDX); } +static void dpu_hw_ctl_update_pending_flush_cwb_v1(struct dpu_hw_ctl *ctx, + enum dpu_cwb cwb) +{ + ctx->pending_cwb_flush_mask |= BIT(cwb - CWB_0); + ctx->pending_flush_mask |= BIT(CWB_IDX); +} + static void dpu_hw_ctl_update_pending_flush_intf_v1(struct dpu_hw_ctl *ctx, enum dpu_intf intf) { @@ -547,7 +567,9 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, u32 intf_active = 0; u32 dsc_active = 0; u32 wb_active = 0; + u32 cwb_active = 0; u32 mode_sel = 0; + u32 merge_3d_active = 0; /* CTL_TOP[31:28] carries group_id to collate CTL paths * per VM. Explicitly disable it until VM support is @@ -561,7 +583,9 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, intf_active = DPU_REG_READ(c, CTL_INTF_ACTIVE); wb_active = DPU_REG_READ(c, CTL_WB_ACTIVE); + cwb_active = DPU_REG_READ(c, CTL_CWB_ACTIVE); dsc_active = DPU_REG_READ(c, CTL_DSC_ACTIVE); + merge_3d_active = DPU_REG_READ(c, CTL_MERGE_3D_ACTIVE); if (cfg->intf) intf_active |= BIT(cfg->intf - INTF_0); @@ -569,17 +593,24 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, if (cfg->wb) wb_active |= BIT(cfg->wb - WB_0); + if (cfg->cwb) + cwb_active |= cfg->cwb; + if (cfg->dsc) dsc_active |= cfg->dsc; + if (cfg->merge_3d) + merge_3d_active |= BIT(cfg->merge_3d - MERGE_3D_0); + DPU_REG_WRITE(c, CTL_TOP, mode_sel); DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active); DPU_REG_WRITE(c, CTL_WB_ACTIVE, wb_active); + DPU_REG_WRITE(c, CTL_CWB_ACTIVE, cwb_active); DPU_REG_WRITE(c, CTL_DSC_ACTIVE, dsc_active); + DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, merge_3d_active); - if (cfg->merge_3d) - DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, - BIT(cfg->merge_3d - MERGE_3D_0)); + if (cfg->intf_master) + DPU_REG_WRITE(c, CTL_INTF_MASTER, BIT(cfg->intf_master - INTF_0)); if (cfg->cdm) DPU_REG_WRITE(c, CTL_CDM_ACTIVE, cfg->cdm); @@ -623,7 +654,9 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx, { struct dpu_hw_blk_reg_map *c = &ctx->hw; u32 intf_active = 0; + u32 intf_master = 0; u32 wb_active = 0; + u32 cwb_active = 0; u32 merge3d_active = 0; u32 dsc_active; u32 cdm_active; @@ -645,10 +678,27 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx, dpu_hw_ctl_clear_all_blendstages(ctx); + if (ctx->ops.set_active_fetch_pipes) + ctx->ops.set_active_fetch_pipes(ctx, NULL); + if (cfg->intf) { intf_active = DPU_REG_READ(c, CTL_INTF_ACTIVE); intf_active &= ~BIT(cfg->intf - INTF_0); DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active); + + intf_master = DPU_REG_READ(c, CTL_INTF_MASTER); + + /* Unset this intf as master, if it is the current master */ + if (intf_master == BIT(cfg->intf - INTF_0)) { + DPU_DEBUG_DRIVER("Unsetting INTF_%d master\n", cfg->intf - INTF_0); + DPU_REG_WRITE(c, CTL_INTF_MASTER, 0); + } + } + + if (cfg->cwb) { + cwb_active = DPU_REG_READ(c, CTL_CWB_ACTIVE); + cwb_active &= ~cfg->cwb; + DPU_REG_WRITE(c, CTL_CWB_ACTIVE, cwb_active); } if (cfg->wb) { @@ -670,8 +720,8 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx, } } -static void dpu_hw_ctl_set_fetch_pipe_active(struct dpu_hw_ctl *ctx, - unsigned long *fetch_active) +static void dpu_hw_ctl_set_active_fetch_pipes(struct dpu_hw_ctl *ctx, + unsigned long *fetch_active) { int i; u32 val = 0; @@ -703,6 +753,7 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops, ops->update_pending_flush_merge_3d = dpu_hw_ctl_update_pending_flush_merge_3d_v1; ops->update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb_v1; + ops->update_pending_flush_cwb = dpu_hw_ctl_update_pending_flush_cwb_v1; ops->update_pending_flush_dsc = dpu_hw_ctl_update_pending_flush_dsc_v1; ops->update_pending_flush_cdm = dpu_hw_ctl_update_pending_flush_cdm_v1; @@ -733,7 +784,7 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops, ops->update_pending_flush_dspp = dpu_hw_ctl_update_pending_flush_dspp; if (cap & BIT(DPU_CTL_FETCH_ACTIVE)) - ops->set_active_pipes = dpu_hw_ctl_set_fetch_pipe_active; + ops->set_active_fetch_pipes = dpu_hw_ctl_set_active_fetch_pipes; }; /** diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h index 85c6c835cc87..feb09590bc8f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _DPU_HW_CTL_H @@ -36,21 +36,25 @@ struct dpu_hw_stage_cfg { /** * struct dpu_hw_intf_cfg :Describes how the DPU writes data to output interface * @intf : Interface id + * @intf_master: Master interface id in the dual pipe topology * @mode_3d: 3d mux configuration * @merge_3d: 3d merge block used * @intf_mode_sel: Interface mode, cmd / vid * @cdm: CDM block used * @stream_sel: Stream selection for multi-stream interfaces * @dsc: DSC BIT masks used + * @cwb: CWB BIT masks used */ struct dpu_hw_intf_cfg { enum dpu_intf intf; + enum dpu_intf intf_master; enum dpu_wb wb; enum dpu_3d_blend_mode mode_3d; enum dpu_merge_3d merge_3d; enum dpu_ctl_mode_sel intf_mode_sel; enum dpu_cdm cdm; int stream_sel; + unsigned int cwb; unsigned int dsc; }; @@ -115,6 +119,15 @@ struct dpu_hw_ctl_ops { enum dpu_wb blk); /** + * OR in the given flushbits to the cached pending_(cwb_)flush_mask + * No effect on hardware + * @ctx : ctl path ctx pointer + * @blk : concurrent writeback block index + */ + void (*update_pending_flush_cwb)(struct dpu_hw_ctl *ctx, + enum dpu_cwb blk); + + /** * OR in the given flushbits to the cached pending_(intf_)flush_mask * No effect on hardware * @ctx : ctl path ctx pointer @@ -243,7 +256,7 @@ struct dpu_hw_ctl_ops { void (*setup_blendstage)(struct dpu_hw_ctl *ctx, enum dpu_lm lm, struct dpu_hw_stage_cfg *cfg); - void (*set_active_pipes)(struct dpu_hw_ctl *ctx, + void (*set_active_fetch_pipes)(struct dpu_hw_ctl *ctx, unsigned long *fetch_active); }; @@ -258,6 +271,7 @@ struct dpu_hw_ctl_ops { * @pending_flush_mask: storage for pending ctl_flush managed via ops * @pending_intf_flush_mask: pending INTF flush * @pending_wb_flush_mask: pending WB flush + * @pending_cwb_flush_mask: pending CWB flush * @pending_dsc_flush_mask: pending DSC flush * @pending_cdm_flush_mask: pending CDM flush * @ops: operation list @@ -274,6 +288,7 @@ struct dpu_hw_ctl { u32 pending_flush_mask; u32 pending_intf_flush_mask; u32 pending_wb_flush_mask; + u32 pending_cwb_flush_mask; u32 pending_periph_flush_mask; u32 pending_merge_3d_flush_mask; u32 pending_dspp_flush_mask[DSPP_MAX - DSPP_0]; 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 657200401f57..cec6d4e8baec 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c @@ -52,6 +52,7 @@ static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc, u32 slice_last_group_size; u32 det_thresh_flatness; bool is_cmd_mode = !(mode & DSC_MODE_VIDEO); + bool input_10_bits = dsc->bits_per_component == 10; DPU_REG_WRITE(c, DSC_COMMON_MODE, mode); @@ -68,7 +69,7 @@ static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc, data |= (dsc->line_buf_depth << 3); data |= (dsc->simple_422 << 2); data |= (dsc->convert_rgb << 1); - data |= dsc->bits_per_component; + data |= input_10_bits; DPU_REG_WRITE(c, DSC_ENC, data); 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 ba7bb05efe9b..175639c8bfbb 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h @@ -77,12 +77,14 @@ enum dpu_hw_blk_type { DPU_HW_BLK_LM, DPU_HW_BLK_CTL, DPU_HW_BLK_PINGPONG, + DPU_HW_BLK_DCWB_PINGPONG, DPU_HW_BLK_INTF, DPU_HW_BLK_WB, DPU_HW_BLK_DSPP, DPU_HW_BLK_MERGE_3D, DPU_HW_BLK_DSC, DPU_HW_BLK_CDM, + DPU_HW_BLK_CWB, DPU_HW_BLK_MAX, }; @@ -123,6 +125,7 @@ enum dpu_lm { LM_4, LM_5, LM_6, + LM_7, LM_MAX }; @@ -167,6 +170,8 @@ enum dpu_dsc { DSC_3, DSC_4, DSC_5, + DSC_6, + DSC_7, DSC_MAX }; @@ -183,6 +188,8 @@ enum dpu_pingpong { PINGPONG_3, PINGPONG_4, PINGPONG_5, + PINGPONG_6, + PINGPONG_7, PINGPONG_CWB_0, PINGPONG_CWB_1, PINGPONG_CWB_2, @@ -197,6 +204,7 @@ enum dpu_merge_3d { MERGE_3D_2, MERGE_3D_3, MERGE_3D_4, + MERGE_3D_5, MERGE_3D_MAX }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c index ad19330de61a..562a3f4c5238 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c @@ -272,7 +272,7 @@ static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops, if (cap & BIT(DPU_MDP_VSYNC_SEL)) ops->setup_vsync_source = dpu_hw_setup_vsync_sel; - else + else if (!(cap & BIT(DPU_MDP_PERIPH_0_REMOVED))) ops->setup_vsync_source = dpu_hw_setup_wd_timer; ops->get_safe_status = dpu_hw_get_safe_status; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 97e9cb8c2b09..1fd82b6747e9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -2,7 +2,7 @@ /* * Copyright (C) 2013 Red Hat * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. * * Author: Rob Clark <robdclark@gmail.com> */ @@ -446,6 +446,19 @@ static void dpu_kms_disable_commit(struct msm_kms *kms) pm_runtime_put_sync(&dpu_kms->pdev->dev); } +static int dpu_kms_check_mode_changed(struct msm_kms *kms, struct drm_atomic_state *state) +{ + struct drm_crtc_state *new_crtc_state; + struct drm_crtc_state *old_crtc_state; + struct drm_crtc *crtc; + int i; + + for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) + dpu_crtc_check_mode_changed(old_crtc_state, new_crtc_state); + + return 0; +} + static void dpu_kms_flush_commit(struct msm_kms *kms, unsigned crtc_mask) { struct dpu_kms *dpu_kms = to_dpu_kms(kms); @@ -811,8 +824,11 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms) return ret; num_encoders = 0; - drm_for_each_encoder(encoder, dev) + drm_for_each_encoder(encoder, dev) { num_encoders++; + if (catalog->cwb_count > 0) + encoder->possible_clones = dpu_encoder_get_clones(encoder); + } max_crtc_count = min(catalog->mixer_count, num_encoders); @@ -1062,6 +1078,7 @@ static const struct msm_kms_funcs kms_funcs = { .irq = dpu_core_irq, .enable_commit = dpu_kms_enable_commit, .disable_commit = dpu_kms_disable_commit, + .check_mode_changed = dpu_kms_check_mode_changed, .flush_commit = dpu_kms_flush_commit, .wait_flush = dpu_kms_wait_flush, .complete_commit = dpu_kms_complete_commit, @@ -1495,6 +1512,7 @@ static const struct of_device_id dpu_dt_match[] = { { .compatible = "qcom,msm8998-dpu", .data = &dpu_msm8998_cfg, }, { .compatible = "qcom,qcm2290-dpu", .data = &dpu_qcm2290_cfg, }, { .compatible = "qcom,sa8775p-dpu", .data = &dpu_sa8775p_cfg, }, + { .compatible = "qcom,sar2130p-dpu", .data = &dpu_sar2130p_cfg, }, { .compatible = "qcom,sdm630-mdp5", .data = &dpu_sdm630_cfg, }, { .compatible = "qcom,sdm660-mdp5", .data = &dpu_sdm660_cfg, }, { .compatible = "qcom,sdm670-dpu", .data = &dpu_sdm670_cfg, }, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index 547cdb2c0c78..a57ec2ec1060 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -124,14 +124,15 @@ struct dpu_global_state { struct dpu_rm *rm; - uint32_t pingpong_to_enc_id[PINGPONG_MAX - PINGPONG_0]; - uint32_t mixer_to_enc_id[LM_MAX - LM_0]; - uint32_t ctl_to_enc_id[CTL_MAX - CTL_0]; - uint32_t dspp_to_enc_id[DSPP_MAX - DSPP_0]; - uint32_t dsc_to_enc_id[DSC_MAX - DSC_0]; - uint32_t cdm_to_enc_id; + uint32_t pingpong_to_crtc_id[PINGPONG_MAX - PINGPONG_0]; + uint32_t mixer_to_crtc_id[LM_MAX - LM_0]; + uint32_t ctl_to_crtc_id[CTL_MAX - CTL_0]; + uint32_t dspp_to_crtc_id[DSPP_MAX - DSPP_0]; + uint32_t dsc_to_crtc_id[DSC_MAX - DSC_0]; + uint32_t cdm_to_crtc_id; uint32_t sspp_to_crtc_id[SSPP_MAX - SSPP_NONE]; + uint32_t cwb_to_crtc_id[CWB_MAX - CWB_0]; }; struct dpu_global_state diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 098abc2c0003..421138bc3cb7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -729,12 +729,40 @@ static int dpu_plane_check_inline_rotation(struct dpu_plane *pdpu, static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu, struct dpu_sw_pipe *pipe, struct dpu_sw_pipe_cfg *pipe_cfg, - const struct msm_format *fmt, - const struct drm_display_mode *mode) + const struct drm_display_mode *mode, + struct drm_plane_state *new_plane_state) { uint32_t min_src_size; struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base); int ret; + const struct msm_format *fmt; + uint32_t supported_rotations; + const struct dpu_sspp_cfg *pipe_hw_caps; + const struct dpu_sspp_sub_blks *sblk; + + pipe_hw_caps = pipe->sspp->cap; + sblk = pipe->sspp->cap->sblk; + + /* + * We already have verified scaling against platform limitations. + * Now check if the SSPP supports scaling at all. + */ + if (!sblk->scaler_blk.len && + ((drm_rect_width(&new_plane_state->src) >> 16 != + drm_rect_width(&new_plane_state->dst)) || + (drm_rect_height(&new_plane_state->src) >> 16 != + drm_rect_height(&new_plane_state->dst)))) + return -ERANGE; + + fmt = msm_framebuffer_format(new_plane_state->fb); + + supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0; + + if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION)) + supported_rotations |= DRM_MODE_ROTATE_90; + + pipe_cfg->rotation = drm_rotation_simplify(new_plane_state->rotation, + supported_rotations); min_src_size = MSM_FORMAT_IS_YUV(fmt) ? 2 : 1; @@ -887,10 +915,9 @@ static int dpu_plane_atomic_check_nosspp(struct drm_plane *plane, return 0; } -static int dpu_plane_is_multirect_parallel_capable(struct dpu_hw_sspp *sspp, - struct dpu_sw_pipe_cfg *pipe_cfg, - const struct msm_format *fmt, - uint32_t max_linewidth) +static int dpu_plane_is_multirect_capable(struct dpu_hw_sspp *sspp, + struct dpu_sw_pipe_cfg *pipe_cfg, + const struct msm_format *fmt) { if (drm_rect_width(&pipe_cfg->src_rect) != drm_rect_width(&pipe_cfg->dst_rect) || drm_rect_height(&pipe_cfg->src_rect) != drm_rect_height(&pipe_cfg->dst_rect)) @@ -902,10 +929,6 @@ static int dpu_plane_is_multirect_parallel_capable(struct dpu_hw_sspp *sspp, if (MSM_FORMAT_IS_YUV(fmt)) return false; - if (MSM_FORMAT_IS_UBWC(fmt) && - drm_rect_width(&pipe_cfg->src_rect) > max_linewidth / 2) - return false; - if (!test_bit(DPU_SSPP_SMART_DMA_V1, &sspp->cap->features) && !test_bit(DPU_SSPP_SMART_DMA_V2, &sspp->cap->features)) return false; @@ -913,6 +936,27 @@ static int dpu_plane_is_multirect_parallel_capable(struct dpu_hw_sspp *sspp, return true; } +static int dpu_plane_is_parallel_capable(struct dpu_sw_pipe_cfg *pipe_cfg, + const struct msm_format *fmt, + uint32_t max_linewidth) +{ + if (MSM_FORMAT_IS_UBWC(fmt) && + drm_rect_width(&pipe_cfg->src_rect) > max_linewidth / 2) + return false; + + return true; +} + +static int dpu_plane_is_multirect_parallel_capable(struct dpu_hw_sspp *sspp, + struct dpu_sw_pipe_cfg *pipe_cfg, + const struct msm_format *fmt, + uint32_t max_linewidth) +{ + return dpu_plane_is_multirect_capable(sspp, pipe_cfg, fmt) && + dpu_plane_is_parallel_capable(pipe_cfg, fmt, max_linewidth); +} + + static int dpu_plane_atomic_check_sspp(struct drm_plane *plane, struct drm_atomic_state *state, const struct drm_crtc_state *crtc_state) @@ -923,47 +967,20 @@ static int dpu_plane_atomic_check_sspp(struct drm_plane *plane, struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state); struct dpu_sw_pipe *pipe = &pstate->pipe; struct dpu_sw_pipe *r_pipe = &pstate->r_pipe; - const struct msm_format *fmt; struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg; struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg; - uint32_t supported_rotations; - const struct dpu_sspp_cfg *pipe_hw_caps; - const struct dpu_sspp_sub_blks *sblk; int ret = 0; - pipe_hw_caps = pipe->sspp->cap; - sblk = pipe->sspp->cap->sblk; - - /* - * We already have verified scaling against platform limitations. - * Now check if the SSPP supports scaling at all. - */ - if (!sblk->scaler_blk.len && - ((drm_rect_width(&new_plane_state->src) >> 16 != - drm_rect_width(&new_plane_state->dst)) || - (drm_rect_height(&new_plane_state->src) >> 16 != - drm_rect_height(&new_plane_state->dst)))) - return -ERANGE; - - fmt = msm_framebuffer_format(new_plane_state->fb); - - supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0; - - if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION)) - supported_rotations |= DRM_MODE_ROTATE_90; - - pipe_cfg->rotation = drm_rotation_simplify(new_plane_state->rotation, - supported_rotations); - r_pipe_cfg->rotation = pipe_cfg->rotation; - - ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt, - &crtc_state->adjusted_mode); + ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, + &crtc_state->adjusted_mode, + new_plane_state); if (ret) return ret; if (drm_rect_width(&r_pipe_cfg->src_rect) != 0) { - ret = dpu_plane_atomic_check_pipe(pdpu, r_pipe, r_pipe_cfg, fmt, - &crtc_state->adjusted_mode); + ret = dpu_plane_atomic_check_pipe(pdpu, r_pipe, r_pipe_cfg, + &crtc_state->adjusted_mode, + new_plane_state); if (ret) return ret; } @@ -1001,6 +1018,69 @@ static bool dpu_plane_try_multirect_parallel(struct dpu_sw_pipe *pipe, struct dp return true; } +static int dpu_plane_try_multirect_shared(struct dpu_plane_state *pstate, + struct dpu_plane_state *prev_adjacent_pstate, + const struct msm_format *fmt, + uint32_t max_linewidth) +{ + struct dpu_sw_pipe *pipe = &pstate->pipe; + struct dpu_sw_pipe *r_pipe = &pstate->r_pipe; + struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg; + struct dpu_sw_pipe *prev_pipe = &prev_adjacent_pstate->pipe; + struct dpu_sw_pipe_cfg *prev_pipe_cfg = &prev_adjacent_pstate->pipe_cfg; + const struct msm_format *prev_fmt = msm_framebuffer_format(prev_adjacent_pstate->base.fb); + u16 max_tile_height = 1; + + if (prev_adjacent_pstate->r_pipe.sspp != NULL || + prev_pipe->multirect_mode != DPU_SSPP_MULTIRECT_NONE) + return false; + + if (!dpu_plane_is_multirect_capable(pipe->sspp, pipe_cfg, fmt) || + !dpu_plane_is_multirect_capable(prev_pipe->sspp, prev_pipe_cfg, prev_fmt)) + return false; + + if (MSM_FORMAT_IS_UBWC(fmt)) + max_tile_height = max(max_tile_height, fmt->tile_height); + + if (MSM_FORMAT_IS_UBWC(prev_fmt)) + max_tile_height = max(max_tile_height, prev_fmt->tile_height); + + r_pipe->multirect_index = DPU_SSPP_RECT_SOLO; + r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE; + + r_pipe->sspp = NULL; + + if (dpu_plane_is_parallel_capable(pipe_cfg, fmt, max_linewidth) && + dpu_plane_is_parallel_capable(prev_pipe_cfg, prev_fmt, max_linewidth) && + (pipe_cfg->dst_rect.x1 >= prev_pipe_cfg->dst_rect.x2 || + prev_pipe_cfg->dst_rect.x1 >= pipe_cfg->dst_rect.x2)) { + pipe->sspp = prev_pipe->sspp; + + pipe->multirect_index = DPU_SSPP_RECT_1; + pipe->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL; + + prev_pipe->multirect_index = DPU_SSPP_RECT_0; + prev_pipe->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL; + + return true; + } + + if (pipe_cfg->dst_rect.y1 >= prev_pipe_cfg->dst_rect.y2 + 2 * max_tile_height || + prev_pipe_cfg->dst_rect.y1 >= pipe_cfg->dst_rect.y2 + 2 * max_tile_height) { + pipe->sspp = prev_pipe->sspp; + + pipe->multirect_index = DPU_SSPP_RECT_1; + pipe->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX; + + prev_pipe->multirect_index = DPU_SSPP_RECT_0; + prev_pipe->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX; + + return true; + } + + return false; +} + static int dpu_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_state *state) { @@ -1059,6 +1139,9 @@ static int dpu_plane_virtual_atomic_check(struct drm_plane *plane, struct drm_crtc_state *crtc_state; int ret; + if (IS_ERR(plane_state)) + return PTR_ERR(plane_state); + if (plane_state->crtc) crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc); @@ -1098,13 +1181,14 @@ static int dpu_plane_virtual_atomic_check(struct drm_plane *plane, static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc, struct dpu_global_state *global_state, struct drm_atomic_state *state, - struct drm_plane_state *plane_state) + struct drm_plane_state *plane_state, + struct drm_plane_state *prev_adjacent_plane_state) { const struct drm_crtc_state *crtc_state = NULL; struct drm_plane *plane = plane_state->plane; struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane); struct dpu_rm_sspp_requirements reqs; - struct dpu_plane_state *pstate; + struct dpu_plane_state *pstate, *prev_adjacent_pstate; struct dpu_sw_pipe *pipe; struct dpu_sw_pipe *r_pipe; struct dpu_sw_pipe_cfg *pipe_cfg; @@ -1116,6 +1200,8 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc, plane_state->crtc); pstate = to_dpu_plane_state(plane_state); + prev_adjacent_pstate = prev_adjacent_plane_state ? + to_dpu_plane_state(prev_adjacent_plane_state) : NULL; pipe = &pstate->pipe; r_pipe = &pstate->r_pipe; pipe_cfg = &pstate->pipe_cfg; @@ -1134,24 +1220,42 @@ static int dpu_plane_virtual_assign_resources(struct drm_crtc *crtc, reqs.rot90 = drm_rotation_90_or_270(plane_state->rotation); - pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &reqs); - if (!pipe->sspp) - return -ENODEV; + if (drm_rect_width(&r_pipe_cfg->src_rect) == 0) { + if (!prev_adjacent_pstate || + !dpu_plane_try_multirect_shared(pstate, prev_adjacent_pstate, fmt, + dpu_kms->catalog->caps->max_linewidth)) { + pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &reqs); + if (!pipe->sspp) + return -ENODEV; - if (!dpu_plane_try_multirect_parallel(pipe, pipe_cfg, r_pipe, r_pipe_cfg, - pipe->sspp, - msm_framebuffer_format(plane_state->fb), - dpu_kms->catalog->caps->max_linewidth)) { - /* multirect is not possible, use two SSPP blocks */ - r_pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &reqs); - if (!r_pipe->sspp) + r_pipe->sspp = NULL; + + pipe->multirect_index = DPU_SSPP_RECT_SOLO; + pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE; + + r_pipe->multirect_index = DPU_SSPP_RECT_SOLO; + r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE; + } + } else { + pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &reqs); + if (!pipe->sspp) return -ENODEV; - pipe->multirect_index = DPU_SSPP_RECT_SOLO; - pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE; + if (!dpu_plane_try_multirect_parallel(pipe, pipe_cfg, r_pipe, r_pipe_cfg, + pipe->sspp, + msm_framebuffer_format(plane_state->fb), + dpu_kms->catalog->caps->max_linewidth)) { + /* multirect is not possible, use two SSPP blocks */ + r_pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, &reqs); + if (!r_pipe->sspp) + return -ENODEV; - r_pipe->multirect_index = DPU_SSPP_RECT_SOLO; - r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE; + pipe->multirect_index = DPU_SSPP_RECT_SOLO; + pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE; + + r_pipe->multirect_index = DPU_SSPP_RECT_SOLO; + r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE; + } } return dpu_plane_atomic_check_sspp(plane, state, crtc_state); @@ -1164,7 +1268,7 @@ int dpu_assign_plane_resources(struct dpu_global_state *global_state, unsigned int num_planes) { unsigned int i; - int ret; + struct drm_plane_state *prev_adjacent_plane_state = NULL; for (i = 0; i < num_planes; i++) { struct drm_plane_state *plane_state = states[i]; @@ -1173,13 +1277,16 @@ int dpu_assign_plane_resources(struct dpu_global_state *global_state, !plane_state->visible) continue; - ret = dpu_plane_virtual_assign_resources(crtc, global_state, - state, plane_state); + int ret = dpu_plane_virtual_assign_resources(crtc, global_state, + state, plane_state, + prev_adjacent_plane_state); if (ret) break; + + prev_adjacent_plane_state = plane_state; } - return ret; + return 0; } static void dpu_plane_flush_csc(struct dpu_plane *pdpu, struct dpu_sw_pipe *pipe) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index 5baf9df702b8..2e296f79cba1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -22,9 +22,9 @@ static inline bool reserved_by_other(uint32_t *res_map, int idx, - uint32_t enc_id) + uint32_t crtc_id) { - return res_map[idx] && res_map[idx] != enc_id; + return res_map[idx] && res_map[idx] != crtc_id; } /** @@ -53,6 +53,8 @@ int dpu_rm_init(struct drm_device *dev, /* Clear, setup lists */ memset(rm, 0, sizeof(*rm)); + rm->has_legacy_ctls = (cat->mdss_ver->core_major_ver < 5); + /* Interrogate HW catalog and create tracking items for hw blocks */ for (i = 0; i < cat->mixer_count; i++) { struct dpu_hw_mixer *hw; @@ -233,13 +235,66 @@ static int _dpu_rm_get_lm_peer(struct dpu_rm *rm, int primary_idx) return -EINVAL; } +static int _dpu_rm_reserve_cwb_mux_and_pingpongs(struct dpu_rm *rm, + struct dpu_global_state *global_state, + uint32_t crtc_id, + struct msm_display_topology *topology) +{ + int num_cwb_mux = topology->num_lm, cwb_mux_count = 0; + int cwb_pp_start_idx = PINGPONG_CWB_0 - PINGPONG_0; + int cwb_pp_idx[MAX_BLOCKS]; + int cwb_mux_idx[MAX_BLOCKS]; + + /* + * Reserve additional dedicated CWB PINGPONG blocks and muxes for each + * mixer + * + * TODO: add support reserving resources for platforms with no + * PINGPONG_CWB + */ + for (int i = 0; i < ARRAY_SIZE(rm->mixer_blks) && + cwb_mux_count < num_cwb_mux; i++) { + for (int j = 0; j < ARRAY_SIZE(rm->cwb_blks); j++) { + /* + * Odd LMs must be assigned to odd CWB muxes and even + * LMs with even CWB muxes. + * + * Since the RM HW block array index is based on the HW + * block ids, we can also use the array index to enforce + * the odd/even rule. See dpu_rm_init() for more + * information + */ + if (reserved_by_other(global_state->cwb_to_crtc_id, j, crtc_id) || + i % 2 != j % 2) + continue; + + cwb_mux_idx[cwb_mux_count] = j; + cwb_pp_idx[cwb_mux_count] = j + cwb_pp_start_idx; + cwb_mux_count++; + break; + } + } + + if (cwb_mux_count != num_cwb_mux) { + DPU_ERROR("Unable to reserve all CWB PINGPONGs\n"); + return -ENAVAIL; + } + + for (int i = 0; i < cwb_mux_count; i++) { + global_state->pingpong_to_crtc_id[cwb_pp_idx[i]] = crtc_id; + global_state->cwb_to_crtc_id[cwb_mux_idx[i]] = crtc_id; + } + + return 0; +} + /** * _dpu_rm_check_lm_and_get_connected_blks - check if proposed layer mixer meets * proposed use case requirements, incl. hardwired dependent blocks like * pingpong * @rm: dpu resource manager handle * @global_state: resources shared across multiple kms objects - * @enc_id: encoder id requesting for allocation + * @crtc_id: crtc id requesting for allocation * @lm_idx: index of proposed layer mixer in rm->mixer_blks[], function checks * if lm, and all other hardwired blocks connected to the lm (pp) is * available and appropriate @@ -252,14 +307,14 @@ static int _dpu_rm_get_lm_peer(struct dpu_rm *rm, int primary_idx) */ static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm, struct dpu_global_state *global_state, - uint32_t enc_id, int lm_idx, int *pp_idx, int *dspp_idx, + uint32_t crtc_id, int lm_idx, int *pp_idx, int *dspp_idx, struct msm_display_topology *topology) { const struct dpu_lm_cfg *lm_cfg; int idx; /* Already reserved? */ - if (reserved_by_other(global_state->mixer_to_enc_id, lm_idx, enc_id)) { + if (reserved_by_other(global_state->mixer_to_crtc_id, lm_idx, crtc_id)) { DPU_DEBUG("lm %d already reserved\n", lm_idx + LM_0); return false; } @@ -271,7 +326,7 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm, return false; } - if (reserved_by_other(global_state->pingpong_to_enc_id, idx, enc_id)) { + if (reserved_by_other(global_state->pingpong_to_crtc_id, idx, crtc_id)) { DPU_DEBUG("lm %d pp %d already reserved\n", lm_cfg->id, lm_cfg->pingpong); return false; @@ -287,7 +342,7 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm, return false; } - if (reserved_by_other(global_state->dspp_to_enc_id, idx, enc_id)) { + if (reserved_by_other(global_state->dspp_to_crtc_id, idx, crtc_id)) { DPU_DEBUG("lm %d dspp %d already reserved\n", lm_cfg->id, lm_cfg->dspp); return false; @@ -299,7 +354,7 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm, static int _dpu_rm_reserve_lms(struct dpu_rm *rm, struct dpu_global_state *global_state, - uint32_t enc_id, + uint32_t crtc_id, struct msm_display_topology *topology) { @@ -323,7 +378,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, lm_idx[lm_count] = i; if (!_dpu_rm_check_lm_and_get_connected_blks(rm, global_state, - enc_id, i, &pp_idx[lm_count], + crtc_id, i, &pp_idx[lm_count], &dspp_idx[lm_count], topology)) { continue; } @@ -342,7 +397,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, continue; if (!_dpu_rm_check_lm_and_get_connected_blks(rm, - global_state, enc_id, j, + global_state, crtc_id, j, &pp_idx[lm_count], &dspp_idx[lm_count], topology)) { continue; @@ -359,12 +414,12 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, } for (i = 0; i < lm_count; i++) { - global_state->mixer_to_enc_id[lm_idx[i]] = enc_id; - global_state->pingpong_to_enc_id[pp_idx[i]] = enc_id; - global_state->dspp_to_enc_id[dspp_idx[i]] = - topology->num_dspp ? enc_id : 0; + global_state->mixer_to_crtc_id[lm_idx[i]] = crtc_id; + global_state->pingpong_to_crtc_id[pp_idx[i]] = crtc_id; + global_state->dspp_to_crtc_id[dspp_idx[i]] = + topology->num_dspp ? crtc_id : 0; - trace_dpu_rm_reserve_lms(lm_idx[i] + LM_0, enc_id, + trace_dpu_rm_reserve_lms(lm_idx[i] + LM_0, crtc_id, pp_idx[i] + PINGPONG_0); } @@ -374,17 +429,26 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, static int _dpu_rm_reserve_ctls( struct dpu_rm *rm, struct dpu_global_state *global_state, - uint32_t enc_id, + uint32_t crtc_id, const struct msm_display_topology *top) { int ctl_idx[MAX_BLOCKS]; int i = 0, j, num_ctls; bool needs_split_display; - /* each hw_intf needs its own hw_ctrl to program its control path */ - num_ctls = top->num_intf; - - needs_split_display = _dpu_rm_needs_split_display(top); + if (rm->has_legacy_ctls) { + /* + * TODO: check if there is a need for special handling if + * DPU < 5.0 get CWB support. + */ + num_ctls = top->num_intf; + + needs_split_display = _dpu_rm_needs_split_display(top); + } else { + /* use single CTL */ + num_ctls = 1; + needs_split_display = false; + } for (j = 0; j < ARRAY_SIZE(rm->ctl_blks); j++) { const struct dpu_hw_ctl *ctl; @@ -393,7 +457,7 @@ static int _dpu_rm_reserve_ctls( if (!rm->ctl_blks[j]) continue; - if (reserved_by_other(global_state->ctl_to_enc_id, j, enc_id)) + if (reserved_by_other(global_state->ctl_to_crtc_id, j, crtc_id)) continue; ctl = to_dpu_hw_ctl(rm->ctl_blks[j]); @@ -417,8 +481,8 @@ static int _dpu_rm_reserve_ctls( return -ENAVAIL; for (i = 0; i < ARRAY_SIZE(ctl_idx) && i < num_ctls; i++) { - global_state->ctl_to_enc_id[ctl_idx[i]] = enc_id; - trace_dpu_rm_reserve_ctls(i + CTL_0, enc_id); + global_state->ctl_to_crtc_id[ctl_idx[i]] = crtc_id; + trace_dpu_rm_reserve_ctls(i + CTL_0, crtc_id); } return 0; @@ -426,12 +490,12 @@ static int _dpu_rm_reserve_ctls( static int _dpu_rm_pingpong_next_index(struct dpu_global_state *global_state, int start, - uint32_t enc_id) + uint32_t crtc_id) { int i; for (i = start; i < (PINGPONG_MAX - PINGPONG_0); i++) { - if (global_state->pingpong_to_enc_id[i] == enc_id) + if (global_state->pingpong_to_crtc_id[i] == crtc_id) return i; } @@ -452,7 +516,7 @@ static int _dpu_rm_pingpong_dsc_check(int dsc_idx, int pp_idx) static int _dpu_rm_dsc_alloc(struct dpu_rm *rm, struct dpu_global_state *global_state, - uint32_t enc_id, + uint32_t crtc_id, const struct msm_display_topology *top) { int num_dsc = 0; @@ -465,10 +529,10 @@ static int _dpu_rm_dsc_alloc(struct dpu_rm *rm, if (!rm->dsc_blks[dsc_idx]) continue; - if (reserved_by_other(global_state->dsc_to_enc_id, dsc_idx, enc_id)) + if (reserved_by_other(global_state->dsc_to_crtc_id, dsc_idx, crtc_id)) continue; - pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx, enc_id); + pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx, crtc_id); if (pp_idx < 0) return -ENAVAIL; @@ -476,7 +540,7 @@ static int _dpu_rm_dsc_alloc(struct dpu_rm *rm, if (ret) return -ENAVAIL; - global_state->dsc_to_enc_id[dsc_idx] = enc_id; + global_state->dsc_to_crtc_id[dsc_idx] = crtc_id; num_dsc++; pp_idx++; } @@ -492,7 +556,7 @@ static int _dpu_rm_dsc_alloc(struct dpu_rm *rm, static int _dpu_rm_dsc_alloc_pair(struct dpu_rm *rm, struct dpu_global_state *global_state, - uint32_t enc_id, + uint32_t crtc_id, const struct msm_display_topology *top) { int num_dsc = 0; @@ -507,11 +571,11 @@ static int _dpu_rm_dsc_alloc_pair(struct dpu_rm *rm, continue; /* consective dsc index to be paired */ - if (reserved_by_other(global_state->dsc_to_enc_id, dsc_idx, enc_id) || - reserved_by_other(global_state->dsc_to_enc_id, dsc_idx + 1, enc_id)) + if (reserved_by_other(global_state->dsc_to_crtc_id, dsc_idx, crtc_id) || + reserved_by_other(global_state->dsc_to_crtc_id, dsc_idx + 1, crtc_id)) continue; - pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx, enc_id); + pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx, crtc_id); if (pp_idx < 0) return -ENAVAIL; @@ -521,7 +585,7 @@ static int _dpu_rm_dsc_alloc_pair(struct dpu_rm *rm, continue; } - pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx + 1, enc_id); + pp_idx = _dpu_rm_pingpong_next_index(global_state, pp_idx + 1, crtc_id); if (pp_idx < 0) return -ENAVAIL; @@ -531,8 +595,8 @@ static int _dpu_rm_dsc_alloc_pair(struct dpu_rm *rm, continue; } - global_state->dsc_to_enc_id[dsc_idx] = enc_id; - global_state->dsc_to_enc_id[dsc_idx + 1] = enc_id; + global_state->dsc_to_crtc_id[dsc_idx] = crtc_id; + global_state->dsc_to_crtc_id[dsc_idx + 1] = crtc_id; num_dsc += 2; pp_idx++; /* start for next pair */ } @@ -548,11 +612,9 @@ static int _dpu_rm_dsc_alloc_pair(struct dpu_rm *rm, static int _dpu_rm_reserve_dsc(struct dpu_rm *rm, struct dpu_global_state *global_state, - struct drm_encoder *enc, + uint32_t crtc_id, const struct msm_display_topology *top) { - uint32_t enc_id = enc->base.id; - if (!top->num_dsc || !top->num_intf) return 0; @@ -568,16 +630,17 @@ static int _dpu_rm_reserve_dsc(struct dpu_rm *rm, /* num_dsc should be either 1, 2 or 4 */ if (top->num_dsc > top->num_intf) /* merge mode */ - return _dpu_rm_dsc_alloc_pair(rm, global_state, enc_id, top); + return _dpu_rm_dsc_alloc_pair(rm, global_state, crtc_id, top); else - return _dpu_rm_dsc_alloc(rm, global_state, enc_id, top); + return _dpu_rm_dsc_alloc(rm, global_state, crtc_id, top); return 0; } static int _dpu_rm_reserve_cdm(struct dpu_rm *rm, struct dpu_global_state *global_state, - struct drm_encoder *enc) + uint32_t crtc_id, + int num_cdm) { /* try allocating only one CDM block */ if (!rm->cdm_blk) { @@ -585,12 +648,17 @@ static int _dpu_rm_reserve_cdm(struct dpu_rm *rm, return -EIO; } - if (global_state->cdm_to_enc_id) { + if (num_cdm > 1) { + DPU_ERROR("More than 1 INTF requesting CDM\n"); + return -EINVAL; + } + + if (global_state->cdm_to_crtc_id) { DPU_ERROR("CDM_0 is already allocated\n"); return -EIO; } - global_state->cdm_to_enc_id = enc->base.id; + global_state->cdm_to_crtc_id = crtc_id; return 0; } @@ -598,30 +666,37 @@ static int _dpu_rm_reserve_cdm(struct dpu_rm *rm, static int _dpu_rm_make_reservation( struct dpu_rm *rm, struct dpu_global_state *global_state, - struct drm_encoder *enc, + uint32_t crtc_id, struct msm_display_topology *topology) { int ret; - ret = _dpu_rm_reserve_lms(rm, global_state, enc->base.id, topology); + ret = _dpu_rm_reserve_lms(rm, global_state, crtc_id, topology); if (ret) { DPU_ERROR("unable to find appropriate mixers\n"); return ret; } - ret = _dpu_rm_reserve_ctls(rm, global_state, enc->base.id, + if (topology->cwb_enabled) { + ret = _dpu_rm_reserve_cwb_mux_and_pingpongs(rm, global_state, + crtc_id, topology); + if (ret) + return ret; + } + + ret = _dpu_rm_reserve_ctls(rm, global_state, crtc_id, topology); if (ret) { DPU_ERROR("unable to find appropriate CTL\n"); return ret; } - ret = _dpu_rm_reserve_dsc(rm, global_state, enc, topology); + ret = _dpu_rm_reserve_dsc(rm, global_state, crtc_id, topology); if (ret) return ret; - if (topology->needs_cdm) { - ret = _dpu_rm_reserve_cdm(rm, global_state, enc); + if (topology->num_cdm > 0) { + ret = _dpu_rm_reserve_cdm(rm, global_state, crtc_id, topology->num_cdm); if (ret) { DPU_ERROR("unable to find CDM blk\n"); return ret; @@ -632,12 +707,12 @@ static int _dpu_rm_make_reservation( } static void _dpu_rm_clear_mapping(uint32_t *res_mapping, int cnt, - uint32_t enc_id) + uint32_t crtc_id) { int i; for (i = 0; i < cnt; i++) { - if (res_mapping[i] == enc_id) + if (res_mapping[i] == crtc_id) res_mapping[i] = 0; } } @@ -646,23 +721,27 @@ static void _dpu_rm_clear_mapping(uint32_t *res_mapping, int cnt, * dpu_rm_release - Given the encoder for the display chain, release any * HW blocks previously reserved for that use case. * @global_state: resources shared across multiple kms objects - * @enc: DRM Encoder handle + * @crtc: DRM CRTC handle * @return: 0 on Success otherwise -ERROR */ void dpu_rm_release(struct dpu_global_state *global_state, - struct drm_encoder *enc) + struct drm_crtc *crtc) { - _dpu_rm_clear_mapping(global_state->pingpong_to_enc_id, - ARRAY_SIZE(global_state->pingpong_to_enc_id), enc->base.id); - _dpu_rm_clear_mapping(global_state->mixer_to_enc_id, - ARRAY_SIZE(global_state->mixer_to_enc_id), enc->base.id); - _dpu_rm_clear_mapping(global_state->ctl_to_enc_id, - ARRAY_SIZE(global_state->ctl_to_enc_id), enc->base.id); - _dpu_rm_clear_mapping(global_state->dsc_to_enc_id, - ARRAY_SIZE(global_state->dsc_to_enc_id), enc->base.id); - _dpu_rm_clear_mapping(global_state->dspp_to_enc_id, - ARRAY_SIZE(global_state->dspp_to_enc_id), enc->base.id); - _dpu_rm_clear_mapping(&global_state->cdm_to_enc_id, 1, enc->base.id); + uint32_t crtc_id = crtc->base.id; + + _dpu_rm_clear_mapping(global_state->pingpong_to_crtc_id, + ARRAY_SIZE(global_state->pingpong_to_crtc_id), crtc_id); + _dpu_rm_clear_mapping(global_state->mixer_to_crtc_id, + ARRAY_SIZE(global_state->mixer_to_crtc_id), crtc_id); + _dpu_rm_clear_mapping(global_state->ctl_to_crtc_id, + ARRAY_SIZE(global_state->ctl_to_crtc_id), crtc_id); + _dpu_rm_clear_mapping(global_state->dsc_to_crtc_id, + ARRAY_SIZE(global_state->dsc_to_crtc_id), crtc_id); + _dpu_rm_clear_mapping(global_state->dspp_to_crtc_id, + ARRAY_SIZE(global_state->dspp_to_crtc_id), crtc_id); + _dpu_rm_clear_mapping(&global_state->cdm_to_crtc_id, 1, crtc_id); + _dpu_rm_clear_mapping(global_state->cwb_to_crtc_id, + ARRAY_SIZE(global_state->cwb_to_crtc_id), crtc_id); } /** @@ -674,42 +753,33 @@ void dpu_rm_release(struct dpu_global_state *global_state, * HW Reservations should be released via dpu_rm_release_hw. * @rm: DPU Resource Manager handle * @global_state: resources shared across multiple kms objects - * @enc: DRM Encoder handle - * @crtc_state: Proposed Atomic DRM CRTC State handle + * @crtc: DRM CRTC handle * @topology: Pointer to topology info for the display * @return: 0 on Success otherwise -ERROR */ int dpu_rm_reserve( struct dpu_rm *rm, struct dpu_global_state *global_state, - struct drm_encoder *enc, - struct drm_crtc_state *crtc_state, + struct drm_crtc *crtc, struct msm_display_topology *topology) { int ret; - /* Check if this is just a page-flip */ - if (!drm_atomic_crtc_needs_modeset(crtc_state)) - return 0; - if (IS_ERR(global_state)) { DPU_ERROR("failed to global state\n"); return PTR_ERR(global_state); } - DRM_DEBUG_KMS("reserving hw for enc %d crtc %d\n", - enc->base.id, crtc_state->crtc->base.id); + DRM_DEBUG_KMS("reserving hw for crtc %d\n", crtc->base.id); DRM_DEBUG_KMS("num_lm: %d num_dsc: %d num_intf: %d\n", topology->num_lm, topology->num_dsc, topology->num_intf); - ret = _dpu_rm_make_reservation(rm, global_state, enc, topology); + ret = _dpu_rm_make_reservation(rm, global_state, crtc->base.id, topology); if (ret) DPU_ERROR("failed to reserve hw resources: %d\n", ret); - - return ret; } @@ -800,50 +870,57 @@ void dpu_rm_release_all_sspp(struct dpu_global_state *global_state, * assigned to this encoder * @rm: DPU Resource Manager handle * @global_state: resources shared across multiple kms objects - * @enc_id: encoder id requesting for allocation + * @crtc: DRM CRTC handle * @type: resource type to return data for * @blks: pointer to the array to be filled by HW resources * @blks_size: size of the @blks array */ int dpu_rm_get_assigned_resources(struct dpu_rm *rm, - struct dpu_global_state *global_state, uint32_t enc_id, + struct dpu_global_state *global_state, struct drm_crtc *crtc, enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size) { + uint32_t crtc_id = crtc->base.id; struct dpu_hw_blk **hw_blks; - uint32_t *hw_to_enc_id; + uint32_t *hw_to_crtc_id; int i, num_blks, max_blks; switch (type) { case DPU_HW_BLK_PINGPONG: + case DPU_HW_BLK_DCWB_PINGPONG: hw_blks = rm->pingpong_blks; - hw_to_enc_id = global_state->pingpong_to_enc_id; + hw_to_crtc_id = global_state->pingpong_to_crtc_id; max_blks = ARRAY_SIZE(rm->pingpong_blks); break; case DPU_HW_BLK_LM: hw_blks = rm->mixer_blks; - hw_to_enc_id = global_state->mixer_to_enc_id; + hw_to_crtc_id = global_state->mixer_to_crtc_id; max_blks = ARRAY_SIZE(rm->mixer_blks); break; case DPU_HW_BLK_CTL: hw_blks = rm->ctl_blks; - hw_to_enc_id = global_state->ctl_to_enc_id; + hw_to_crtc_id = global_state->ctl_to_crtc_id; max_blks = ARRAY_SIZE(rm->ctl_blks); break; case DPU_HW_BLK_DSPP: hw_blks = rm->dspp_blks; - hw_to_enc_id = global_state->dspp_to_enc_id; + hw_to_crtc_id = global_state->dspp_to_crtc_id; max_blks = ARRAY_SIZE(rm->dspp_blks); break; case DPU_HW_BLK_DSC: hw_blks = rm->dsc_blks; - hw_to_enc_id = global_state->dsc_to_enc_id; + hw_to_crtc_id = global_state->dsc_to_crtc_id; max_blks = ARRAY_SIZE(rm->dsc_blks); break; case DPU_HW_BLK_CDM: hw_blks = &rm->cdm_blk; - hw_to_enc_id = &global_state->cdm_to_enc_id; + hw_to_crtc_id = &global_state->cdm_to_crtc_id; max_blks = 1; break; + case DPU_HW_BLK_CWB: + hw_blks = rm->cwb_blks; + hw_to_crtc_id = global_state->cwb_to_crtc_id; + max_blks = ARRAY_SIZE(rm->cwb_blks); + break; default: DPU_ERROR("blk type %d not managed by rm\n", type); return 0; @@ -851,17 +928,31 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm, num_blks = 0; for (i = 0; i < max_blks; i++) { - if (hw_to_enc_id[i] != enc_id) + if (hw_to_crtc_id[i] != crtc_id) continue; + if (type == DPU_HW_BLK_PINGPONG) { + struct dpu_hw_pingpong *pp = to_dpu_hw_pingpong(hw_blks[i]); + + if (pp->idx >= PINGPONG_CWB_0) + continue; + } + + if (type == DPU_HW_BLK_DCWB_PINGPONG) { + struct dpu_hw_pingpong *pp = to_dpu_hw_pingpong(hw_blks[i]); + + if (pp->idx < PINGPONG_CWB_0) + continue; + } + if (num_blks == blks_size) { - DPU_ERROR("More than %d resources assigned to enc %d\n", - blks_size, enc_id); + DPU_ERROR("More than %d resources assigned to crtc %d\n", + blks_size, crtc_id); break; } if (!hw_blks[i]) { - DPU_ERROR("Allocated resource %d unavailable to assign to enc %d\n", - type, enc_id); + DPU_ERROR("Allocated resource %d unavailable to assign to crtc %d\n", + type, crtc_id); break; } blks[num_blks++] = hw_blks[i]; @@ -896,38 +987,38 @@ void dpu_rm_print_state(struct drm_printer *p, drm_puts(p, "resource mapping:\n"); drm_puts(p, "\tpingpong="); - for (i = 0; i < ARRAY_SIZE(global_state->pingpong_to_enc_id); i++) + for (i = 0; i < ARRAY_SIZE(global_state->pingpong_to_crtc_id); i++) dpu_rm_print_state_helper(p, rm->pingpong_blks[i], - global_state->pingpong_to_enc_id[i]); + global_state->pingpong_to_crtc_id[i]); drm_puts(p, "\n"); drm_puts(p, "\tmixer="); - for (i = 0; i < ARRAY_SIZE(global_state->mixer_to_enc_id); i++) + for (i = 0; i < ARRAY_SIZE(global_state->mixer_to_crtc_id); i++) dpu_rm_print_state_helper(p, rm->mixer_blks[i], - global_state->mixer_to_enc_id[i]); + global_state->mixer_to_crtc_id[i]); drm_puts(p, "\n"); drm_puts(p, "\tctl="); - for (i = 0; i < ARRAY_SIZE(global_state->ctl_to_enc_id); i++) + for (i = 0; i < ARRAY_SIZE(global_state->ctl_to_crtc_id); i++) dpu_rm_print_state_helper(p, rm->ctl_blks[i], - global_state->ctl_to_enc_id[i]); + global_state->ctl_to_crtc_id[i]); drm_puts(p, "\n"); drm_puts(p, "\tdspp="); - for (i = 0; i < ARRAY_SIZE(global_state->dspp_to_enc_id); i++) + for (i = 0; i < ARRAY_SIZE(global_state->dspp_to_crtc_id); i++) dpu_rm_print_state_helper(p, rm->dspp_blks[i], - global_state->dspp_to_enc_id[i]); + global_state->dspp_to_crtc_id[i]); drm_puts(p, "\n"); drm_puts(p, "\tdsc="); - for (i = 0; i < ARRAY_SIZE(global_state->dsc_to_enc_id); i++) + for (i = 0; i < ARRAY_SIZE(global_state->dsc_to_crtc_id); i++) dpu_rm_print_state_helper(p, rm->dsc_blks[i], - global_state->dsc_to_enc_id[i]); + global_state->dsc_to_crtc_id[i]); drm_puts(p, "\n"); drm_puts(p, "\tcdm="); dpu_rm_print_state_helper(p, rm->cdm_blk, - global_state->cdm_to_enc_id); + global_state->cdm_to_crtc_id); drm_puts(p, "\n"); drm_puts(p, "\tsspp="); @@ -936,4 +1027,10 @@ void dpu_rm_print_state(struct drm_printer *p, dpu_rm_print_state_helper(p, rm->hw_sspp[i] ? &rm->hw_sspp[i]->base : NULL, global_state->sspp_to_crtc_id[i]); drm_puts(p, "\n"); + + drm_puts(p, "\tcwb="); + for (i = 0; i < ARRAY_SIZE(global_state->cwb_to_crtc_id); i++) + dpu_rm_print_state_helper(p, rm->cwb_blks[i], + global_state->cwb_to_crtc_id[i]); + drm_puts(p, "\n"); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h index 99bd594ee0d1..aa62966056d4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h @@ -24,6 +24,7 @@ struct dpu_global_state; * @dspp_blks: array of dspp hardware resources * @hw_sspp: array of sspp hardware resources * @cdm_blk: cdm hardware resource + * @has_legacy_ctls: DPU uses pre-ACTIVE CTL blocks. */ struct dpu_rm { struct dpu_hw_blk *pingpong_blks[PINGPONG_MAX - PINGPONG_0]; @@ -37,6 +38,7 @@ struct dpu_rm { struct dpu_hw_blk *dsc_blks[DSC_MAX - DSC_0]; struct dpu_hw_sspp *hw_sspp[SSPP_MAX - SSPP_NONE]; struct dpu_hw_blk *cdm_blk; + bool has_legacy_ctls; }; struct dpu_rm_sspp_requirements { @@ -51,14 +53,17 @@ struct dpu_rm_sspp_requirements { * @num_intf: number of interfaces the panel is mounted on * @num_dspp: number of dspp blocks used * @num_dsc: number of Display Stream Compression (DSC) blocks used - * @needs_cdm: indicates whether cdm block is needed for this display topology + * @num_cdm: indicates how many outputs are requesting cdm block for + * this display topology + * @cwb_enabled: indicates whether CWB is enabled for this display topology */ struct msm_display_topology { u32 num_lm; u32 num_intf; u32 num_dspp; u32 num_dsc; - bool needs_cdm; + int num_cdm; + bool cwb_enabled; }; int dpu_rm_init(struct drm_device *dev, @@ -69,12 +74,11 @@ int dpu_rm_init(struct drm_device *dev, int dpu_rm_reserve(struct dpu_rm *rm, struct dpu_global_state *global_state, - struct drm_encoder *drm_enc, - struct drm_crtc_state *crtc_state, + struct drm_crtc *crtc, struct msm_display_topology *topology); void dpu_rm_release(struct dpu_global_state *global_state, - struct drm_encoder *enc); + struct drm_crtc *crtc); struct dpu_hw_sspp *dpu_rm_reserve_sspp(struct dpu_rm *rm, struct dpu_global_state *global_state, @@ -85,7 +89,7 @@ void dpu_rm_release_all_sspp(struct dpu_global_state *global_state, struct drm_crtc *crtc); int dpu_rm_get_assigned_resources(struct dpu_rm *rm, - struct dpu_global_state *global_state, uint32_t enc_id, + struct dpu_global_state *global_state, struct drm_crtc *crtc, enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size); void dpu_rm_print_state(struct drm_printer *p, diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c index c469e66cfc11..7e942c1337b3 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c @@ -6,6 +6,8 @@ #include <linux/delay.h> +#include <drm/drm_bridge.h> +#include <drm/drm_bridge_connector.h> #include <drm/drm_vblank.h> #include "msm_drv.h" @@ -189,7 +191,7 @@ static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4_kms, struct msm_drm_private *priv = dev->dev_private; struct drm_encoder *encoder; struct drm_connector *connector; - struct device_node *panel_node; + struct drm_bridge *next_bridge; int dsi_id; int ret; @@ -199,27 +201,43 @@ static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4_kms, * bail out early if there is no panel node (no need to * initialize LCDC encoder and LVDS connector) */ - panel_node = of_graph_get_remote_node(dev->dev->of_node, 0, 0); - if (!panel_node) - return 0; + next_bridge = devm_drm_of_get_bridge(dev->dev, dev->dev->of_node, 0, 0); + if (IS_ERR(next_bridge)) { + ret = PTR_ERR(next_bridge); + if (ret == -ENODEV) + return 0; + return ret; + } - encoder = mdp4_lcdc_encoder_init(dev, panel_node); + encoder = mdp4_lcdc_encoder_init(dev); if (IS_ERR(encoder)) { DRM_DEV_ERROR(dev->dev, "failed to construct LCDC encoder\n"); - of_node_put(panel_node); return PTR_ERR(encoder); } /* LCDC can be hooked to DMA_P (TODO: Add DMA_S later?) */ encoder->possible_crtcs = 1 << DMA_P; - connector = mdp4_lvds_connector_init(dev, panel_node, encoder); + ret = drm_bridge_attach(encoder, next_bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR); + if (ret) { + DRM_DEV_ERROR(dev->dev, "failed to attach LVDS panel/bridge: %d\n", ret); + + return ret; + } + + connector = drm_bridge_connector_init(dev, encoder); if (IS_ERR(connector)) { DRM_DEV_ERROR(dev->dev, "failed to initialize LVDS connector\n"); - of_node_put(panel_node); return PTR_ERR(connector); } + ret = drm_connector_attach_encoder(connector, encoder); + if (ret) { + DRM_DEV_ERROR(dev->dev, "failed to attach LVDS connector: %d\n", ret); + + return ret; + } + break; case DRM_MODE_ENCODER_TMDS: encoder = mdp4_dtv_encoder_init(dev); diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h index 94b1ba92785f..f9d988076337 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h @@ -191,12 +191,7 @@ struct drm_crtc *mdp4_crtc_init(struct drm_device *dev, long mdp4_dtv_round_pixclk(struct drm_encoder *encoder, unsigned long rate); struct drm_encoder *mdp4_dtv_encoder_init(struct drm_device *dev); -long mdp4_lcdc_round_pixclk(struct drm_encoder *encoder, unsigned long rate); -struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev, - struct device_node *panel_node); - -struct drm_connector *mdp4_lvds_connector_init(struct drm_device *dev, - struct device_node *panel_node, struct drm_encoder *encoder); +struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev); #ifdef CONFIG_DRM_MSM_DSI struct drm_encoder *mdp4_dsi_encoder_init(struct drm_device *dev); @@ -207,13 +202,6 @@ static inline struct drm_encoder *mdp4_dsi_encoder_init(struct drm_device *dev) } #endif -#ifdef CONFIG_COMMON_CLK -struct clk *mpd4_lvds_pll_init(struct drm_device *dev); -#else -static inline struct clk *mpd4_lvds_pll_init(struct drm_device *dev) -{ - return ERR_PTR(-ENODEV); -} -#endif +struct clk *mpd4_get_lcdc_clock(struct drm_device *dev); #endif /* __MDP4_KMS_H__ */ diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c index 8bbc7fb881d5..06a307c1272d 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c @@ -14,7 +14,6 @@ struct mdp4_lcdc_encoder { struct drm_encoder base; - struct device_node *panel_node; struct drm_panel *panel; struct clk *lcdc_clk; unsigned long int pixclock; @@ -262,19 +261,12 @@ static void mdp4_lcdc_encoder_disable(struct drm_encoder *encoder) struct mdp4_lcdc_encoder *mdp4_lcdc_encoder = to_mdp4_lcdc_encoder(encoder); struct mdp4_kms *mdp4_kms = get_kms(encoder); - struct drm_panel *panel; if (WARN_ON(!mdp4_lcdc_encoder->enabled)) return; mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 0); - panel = of_drm_find_panel(mdp4_lcdc_encoder->panel_node); - if (!IS_ERR(panel)) { - drm_panel_disable(panel); - drm_panel_unprepare(panel); - } - /* * Wait for a vsync so we know the ENABLE=0 latched before * the (connector) source of the vsync's gets disabled, @@ -300,7 +292,6 @@ static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder) to_mdp4_lcdc_encoder(encoder); unsigned long pc = mdp4_lcdc_encoder->pixclock; struct mdp4_kms *mdp4_kms = get_kms(encoder); - struct drm_panel *panel; uint32_t config; int ret; @@ -335,12 +326,6 @@ static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder) if (ret) DRM_DEV_ERROR(dev->dev, "failed to enable lcdc_clk: %d\n", ret); - panel = of_drm_find_panel(mdp4_lcdc_encoder->panel_node); - if (!IS_ERR(panel)) { - drm_panel_prepare(panel); - drm_panel_enable(panel); - } - setup_phy(encoder); mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 1); @@ -348,22 +333,34 @@ static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder) mdp4_lcdc_encoder->enabled = true; } +static enum drm_mode_status +mdp4_lcdc_encoder_mode_valid(struct drm_encoder *encoder, + const struct drm_display_mode *mode) +{ + struct mdp4_lcdc_encoder *mdp4_lcdc_encoder = + to_mdp4_lcdc_encoder(encoder); + long actual, requested; + + requested = 1000 * mode->clock; + actual = clk_round_rate(mdp4_lcdc_encoder->lcdc_clk, requested); + + DBG("requested=%ld, actual=%ld", requested, actual); + + if (actual != requested) + return MODE_CLOCK_RANGE; + + return MODE_OK; +} + static const struct drm_encoder_helper_funcs mdp4_lcdc_encoder_helper_funcs = { .mode_set = mdp4_lcdc_encoder_mode_set, .disable = mdp4_lcdc_encoder_disable, .enable = mdp4_lcdc_encoder_enable, + .mode_valid = mdp4_lcdc_encoder_mode_valid, }; -long mdp4_lcdc_round_pixclk(struct drm_encoder *encoder, unsigned long rate) -{ - struct mdp4_lcdc_encoder *mdp4_lcdc_encoder = - to_mdp4_lcdc_encoder(encoder); - return clk_round_rate(mdp4_lcdc_encoder->lcdc_clk, rate); -} - /* initialize encoder */ -struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev, - struct device_node *panel_node) +struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev) { struct drm_encoder *encoder; struct mdp4_lcdc_encoder *mdp4_lcdc_encoder; @@ -374,14 +371,11 @@ struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev, if (IS_ERR(mdp4_lcdc_encoder)) return ERR_CAST(mdp4_lcdc_encoder); - mdp4_lcdc_encoder->panel_node = panel_node; - encoder = &mdp4_lcdc_encoder->base; drm_encoder_helper_add(encoder, &mdp4_lcdc_encoder_helper_funcs); - /* TODO: do we need different pll in other cases? */ - mdp4_lcdc_encoder->lcdc_clk = mpd4_lvds_pll_init(dev); + mdp4_lcdc_encoder->lcdc_clk = mpd4_get_lcdc_clock(dev); if (IS_ERR(mdp4_lcdc_encoder->lcdc_clk)) { DRM_DEV_ERROR(dev->dev, "failed to get lvds_clk\n"); return ERR_CAST(mdp4_lcdc_encoder->lcdc_clk); diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c deleted file mode 100644 index 7444b75c4215..000000000000 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c +++ /dev/null @@ -1,121 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2014 Red Hat - * Author: Rob Clark <robdclark@gmail.com> - * Author: Vinay Simha <vinaysimha@inforcecomputing.com> - */ - -#include "mdp4_kms.h" - -struct mdp4_lvds_connector { - struct drm_connector base; - struct drm_encoder *encoder; - struct device_node *panel_node; - struct drm_panel *panel; -}; -#define to_mdp4_lvds_connector(x) container_of(x, struct mdp4_lvds_connector, base) - -static enum drm_connector_status mdp4_lvds_connector_detect( - struct drm_connector *connector, bool force) -{ - struct mdp4_lvds_connector *mdp4_lvds_connector = - to_mdp4_lvds_connector(connector); - - if (!mdp4_lvds_connector->panel) { - mdp4_lvds_connector->panel = - of_drm_find_panel(mdp4_lvds_connector->panel_node); - if (IS_ERR(mdp4_lvds_connector->panel)) - mdp4_lvds_connector->panel = NULL; - } - - return mdp4_lvds_connector->panel ? - connector_status_connected : - connector_status_disconnected; -} - -static void mdp4_lvds_connector_destroy(struct drm_connector *connector) -{ - struct mdp4_lvds_connector *mdp4_lvds_connector = - to_mdp4_lvds_connector(connector); - - drm_connector_cleanup(connector); - - kfree(mdp4_lvds_connector); -} - -static int mdp4_lvds_connector_get_modes(struct drm_connector *connector) -{ - struct mdp4_lvds_connector *mdp4_lvds_connector = - to_mdp4_lvds_connector(connector); - struct drm_panel *panel = mdp4_lvds_connector->panel; - int ret = 0; - - if (panel) - ret = drm_panel_get_modes(panel, connector); - - return ret; -} - -static enum drm_mode_status -mdp4_lvds_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct mdp4_lvds_connector *mdp4_lvds_connector = - to_mdp4_lvds_connector(connector); - struct drm_encoder *encoder = mdp4_lvds_connector->encoder; - long actual, requested; - - requested = 1000 * mode->clock; - actual = mdp4_lcdc_round_pixclk(encoder, requested); - - DBG("requested=%ld, actual=%ld", requested, actual); - - if (actual != requested) - return MODE_CLOCK_RANGE; - - return MODE_OK; -} - -static const struct drm_connector_funcs mdp4_lvds_connector_funcs = { - .detect = mdp4_lvds_connector_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .destroy = mdp4_lvds_connector_destroy, - .reset = drm_atomic_helper_connector_reset, - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -}; - -static const struct drm_connector_helper_funcs mdp4_lvds_connector_helper_funcs = { - .get_modes = mdp4_lvds_connector_get_modes, - .mode_valid = mdp4_lvds_connector_mode_valid, -}; - -/* initialize connector */ -struct drm_connector *mdp4_lvds_connector_init(struct drm_device *dev, - struct device_node *panel_node, struct drm_encoder *encoder) -{ - struct drm_connector *connector = NULL; - struct mdp4_lvds_connector *mdp4_lvds_connector; - - mdp4_lvds_connector = kzalloc(sizeof(*mdp4_lvds_connector), GFP_KERNEL); - if (!mdp4_lvds_connector) - return ERR_PTR(-ENOMEM); - - mdp4_lvds_connector->encoder = encoder; - mdp4_lvds_connector->panel_node = panel_node; - - connector = &mdp4_lvds_connector->base; - - drm_connector_init(dev, connector, &mdp4_lvds_connector_funcs, - DRM_MODE_CONNECTOR_LVDS); - drm_connector_helper_add(connector, &mdp4_lvds_connector_helper_funcs); - - connector->polled = 0; - - connector->interlace_allowed = 0; - connector->doublescan_allowed = 0; - - drm_connector_attach_encoder(connector, encoder); - - return connector; -} diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_pll.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_pll.c index ab8c0c187fb2..fa2c29470510 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_pll.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_pll.c @@ -122,40 +122,59 @@ static const struct clk_ops mpd4_lvds_pll_ops = { .set_rate = mpd4_lvds_pll_set_rate, }; -static const char *mpd4_lvds_pll_parents[] = { - "pxo", +static const struct clk_parent_data mpd4_lvds_pll_parents[] = { + { .fw_name = "pxo", .name = "pxo", }, }; static struct clk_init_data pll_init = { .name = "mpd4_lvds_pll", .ops = &mpd4_lvds_pll_ops, - .parent_names = mpd4_lvds_pll_parents, + .parent_data = mpd4_lvds_pll_parents, .num_parents = ARRAY_SIZE(mpd4_lvds_pll_parents), }; -struct clk *mpd4_lvds_pll_init(struct drm_device *dev) +static struct clk_hw *mpd4_lvds_pll_init(struct drm_device *dev) { struct mdp4_lvds_pll *lvds_pll; - struct clk *clk; int ret; lvds_pll = devm_kzalloc(dev->dev, sizeof(*lvds_pll), GFP_KERNEL); - if (!lvds_pll) { - ret = -ENOMEM; - goto fail; - } + if (!lvds_pll) + return ERR_PTR(-ENOMEM); lvds_pll->dev = dev; lvds_pll->pll_hw.init = &pll_init; - clk = devm_clk_register(dev->dev, &lvds_pll->pll_hw); - if (IS_ERR(clk)) { - ret = PTR_ERR(clk); - goto fail; + ret = devm_clk_hw_register(dev->dev, &lvds_pll->pll_hw); + if (ret) + return ERR_PTR(ret); + + ret = devm_of_clk_add_hw_provider(dev->dev, of_clk_hw_simple_get, &lvds_pll->pll_hw); + if (ret) + return ERR_PTR(ret); + + return &lvds_pll->pll_hw; +} + +struct clk *mpd4_get_lcdc_clock(struct drm_device *dev) +{ + struct clk_hw *hw; + struct clk *clk; + + + /* TODO: do we need different pll in other cases? */ + hw = mpd4_lvds_pll_init(dev); + if (IS_ERR(hw)) { + DRM_DEV_ERROR(dev->dev, "failed to register LVDS PLL\n"); + return ERR_CAST(hw); } - return clk; + clk = devm_clk_get(dev->dev, "lcdc_clk"); + if (clk == ERR_PTR(-ENOENT)) { + drm_warn(dev, "can't get LCDC clock, using PLL directly\n"); -fail: - return ERR_PTR(ret); + return devm_clk_hw_get_clk(dev->dev, hw, "lcdc_clk"); + } + + return clk; } diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c index 666de99a46a5..fc183fe37f56 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c @@ -3,6 +3,7 @@ * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. */ +#include <linux/string_choices.h> #include "mdp5_kms.h" #include "mdp5_ctl.h" @@ -233,7 +234,7 @@ int mdp5_ctl_set_encoder_state(struct mdp5_ctl *ctl, return -EINVAL; ctl->encoder_enabled = enabled; - DBG("intf_%d: %s", intf->num, enabled ? "on" : "off"); + DBG("intf_%d: %s", intf->num, str_on_off(enabled)); if (start_signal_needed(ctl, pipeline)) { send_start_signal(ctl); diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c index 62de248ed1b0..bb1601921938 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c @@ -368,7 +368,7 @@ static void mdp5_plane_atomic_update(struct drm_plane *plane, } static int mdp5_plane_atomic_async_check(struct drm_plane *plane, - struct drm_atomic_state *state) + struct drm_atomic_state *state, bool flip) { struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane); |