diff options
Diffstat (limited to 'drivers/gpu/drm/msm/disp')
59 files changed, 2361 insertions, 949 deletions
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 new file mode 100644 index 000000000000..ab3dfb0b374e --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_14_msm8937.h @@ -0,0 +1,210 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2023, Linaro Limited + */ + +#ifndef _DPU_1_14_MSM8937_H +#define _DPU_1_14_MSM8937_H + +static const struct dpu_caps msm8937_dpu_caps = { + .max_mixer_width = DEFAULT_DPU_LINE_WIDTH, + .max_mixer_blendstages = 0x4, + .max_linewidth = DEFAULT_DPU_LINE_WIDTH, + .pixel_ram_size = 40 * 1024, + .max_hdeci_exp = MAX_HORZ_DECIMATION, + .max_vdeci_exp = MAX_VERT_DECIMATION, +}; + +static const struct dpu_mdp_cfg msm8937_mdp[] = { + { + .name = "top_0", + .base = 0x0, .len = 0x454, + .features = BIT(DPU_MDP_VSYNC_SEL), + .clk_ctrls = { + [DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, + [DPU_CLK_CTRL_RGB0] = { .reg_off = 0x2ac, .bit_off = 4 }, + [DPU_CLK_CTRL_RGB1] = { .reg_off = 0x2b4, .bit_off = 4 }, + [DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, + [DPU_CLK_CTRL_CURSOR0] = { .reg_off = 0x3a8, .bit_off = 16 }, + }, + }, +}; + +static const struct dpu_ctl_cfg msm8937_ctl[] = { + { + .name = "ctl_0", .id = CTL_0, + .base = 0x1000, .len = 0x64, + }, { + .name = "ctl_1", .id = CTL_1, + .base = 0x1200, .len = 0x64, + }, { + .name = "ctl_2", .id = CTL_2, + .base = 0x1400, .len = 0x64, + }, +}; + +static const struct dpu_sspp_cfg msm8937_sspp[] = { + { + .name = "sspp_0", .id = SSPP_VIG0, + .base = 0x4000, .len = 0x150, + .features = VIG_MSM8953_MASK, + .sblk = &dpu_vig_sblk_qseed2, + .xin_id = 0, + .type = SSPP_TYPE_VIG, + .clk_ctrl = DPU_CLK_CTRL_VIG0, + }, { + .name = "sspp_4", .id = SSPP_RGB0, + .base = 0x14000, .len = 0x150, + .features = RGB_MSM8953_MASK, + .sblk = &dpu_rgb_sblk, + .xin_id = 1, + .type = SSPP_TYPE_RGB, + .clk_ctrl = DPU_CLK_CTRL_RGB0, + }, { + .name = "sspp_5", .id = SSPP_RGB1, + .base = 0x16000, .len = 0x150, + .features = RGB_MSM8953_MASK, + .sblk = &dpu_rgb_sblk, + .xin_id = 5, + .type = SSPP_TYPE_RGB, + .clk_ctrl = DPU_CLK_CTRL_RGB1, + }, { + .name = "sspp_8", .id = SSPP_DMA0, + .base = 0x24000, .len = 0x150, + .features = DMA_MSM8953_MASK | BIT(DPU_SSPP_CURSOR), + .sblk = &dpu_dma_sblk, + .xin_id = 2, + .type = SSPP_TYPE_DMA, + .clk_ctrl = DPU_CLK_CTRL_DMA0, + }, +}; + +static const struct dpu_lm_cfg msm8937_lm[] = { + { + .name = "lm_0", .id = LM_0, + .base = 0x44000, .len = 0x320, + .sblk = &msm8998_lm_sblk, + .lm_pair = LM_1, + .pingpong = PINGPONG_0, + .dspp = DSPP_0, + }, { + .name = "lm_1", .id = LM_1, + .base = 0x45000, .len = 0x320, + .sblk = &msm8998_lm_sblk, + .lm_pair = LM_0, + .pingpong = PINGPONG_1, + }, +}; + +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), + }, +}; + +static const struct dpu_dspp_cfg msm8937_dspp[] = { + { + .name = "dspp_0", .id = DSPP_0, + .base = 0x54000, .len = 0x1800, + .features = DSPP_SC7180_MASK, + .sblk = &msm8998_dspp_sblk, + }, +}; + +static const struct dpu_intf_cfg msm8937_intf[] = { + { + .name = "intf_1", .id = INTF_1, + .base = 0x6a800, .len = 0x268, + .type = INTF_DSI, + .controller_id = MSM_DSI_CONTROLLER_0, + .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, + .type = INTF_DSI, + .controller_id = MSM_DSI_CONTROLLER_1, + .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, + }, +}; + +static const struct dpu_perf_cfg msm8937_perf_data = { + .max_bw_low = 3100000, + .max_bw_high = 3100000, + .min_core_ib = 2400000, + .min_llcc_ib = 0, /* No LLCC on this SoC */ + .min_dram_ib = 800000, + .undersized_prefill_lines = 2, + .xtra_prefill_lines = 2, + .dest_scale_prefill_lines = 3, + .macrotile_prefill_lines = 4, + .yuv_nv12_prefill_lines = 8, + .linear_prefill_lines = 1, + .downscaling_prefill_lines = 1, + .amortizable_threshold = 25, + .min_prefill_lines = 14, + .danger_lut_tbl = {0xf, 0xffff, 0x0}, + .safe_lut_tbl = {0xfffc, 0xff00, 0xffff}, + .qos_lut_tbl = { + {.nentry = ARRAY_SIZE(msm8998_qos_linear), + .entries = msm8998_qos_linear + }, + {.nentry = ARRAY_SIZE(msm8998_qos_macrotile), + .entries = msm8998_qos_macrotile + }, + {.nentry = ARRAY_SIZE(msm8998_qos_nrt), + .entries = msm8998_qos_nrt + }, + }, + .cdp_cfg = { + {.rd_enable = 1, .wr_enable = 1}, + {.rd_enable = 1, .wr_enable = 0} + }, + .clk_inefficiency_factor = 105, + .bw_inefficiency_factor = 120, +}; + +static const struct dpu_mdss_version msm8937_mdss_ver = { + .core_major_ver = 1, + .core_minor_ver = 14, +}; + +const struct dpu_mdss_cfg dpu_msm8937_cfg = { + .mdss_ver = &msm8937_mdss_ver, + .caps = &msm8937_dpu_caps, + .mdp = msm8937_mdp, + .ctl_count = ARRAY_SIZE(msm8937_ctl), + .ctl = msm8937_ctl, + .sspp_count = ARRAY_SIZE(msm8937_sspp), + .sspp = msm8937_sspp, + .mixer_count = ARRAY_SIZE(msm8937_lm), + .mixer = msm8937_lm, + .dspp_count = ARRAY_SIZE(msm8937_dspp), + .dspp = msm8937_dspp, + .pingpong_count = ARRAY_SIZE(msm8937_pp), + .pingpong = msm8937_pp, + .intf_count = ARRAY_SIZE(msm8937_intf), + .intf = msm8937_intf, + .vbif_count = ARRAY_SIZE(msm8996_vbif), + .vbif = msm8996_vbif, + .perf = &msm8937_perf_data, +}; + +#endif 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 new file mode 100644 index 000000000000..6bdaecca6761 --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_15_msm8917.h @@ -0,0 +1,187 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2023, Linaro Limited + */ + +#ifndef _DPU_1_14_MSM8917_H +#define _DPU_1_14_MSM8917_H + +static const struct dpu_caps msm8917_dpu_caps = { + .max_mixer_width = DEFAULT_DPU_LINE_WIDTH, + .max_mixer_blendstages = 0x4, + .max_linewidth = DEFAULT_DPU_LINE_WIDTH, + .pixel_ram_size = 16 * 1024, + .max_hdeci_exp = MAX_HORZ_DECIMATION, + .max_vdeci_exp = MAX_VERT_DECIMATION, +}; + +static const struct dpu_mdp_cfg msm8917_mdp[] = { + { + .name = "top_0", + .base = 0x0, .len = 0x454, + .features = BIT(DPU_MDP_VSYNC_SEL), + .clk_ctrls = { + [DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, + [DPU_CLK_CTRL_RGB0] = { .reg_off = 0x2ac, .bit_off = 4 }, + [DPU_CLK_CTRL_RGB1] = { .reg_off = 0x2b4, .bit_off = 4 }, + [DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, + [DPU_CLK_CTRL_CURSOR0] = { .reg_off = 0x3a8, .bit_off = 16 }, + }, + }, +}; + +static const struct dpu_ctl_cfg msm8917_ctl[] = { + { + .name = "ctl_0", .id = CTL_0, + .base = 0x1000, .len = 0x64, + }, { + .name = "ctl_1", .id = CTL_1, + .base = 0x1200, .len = 0x64, + }, { + .name = "ctl_2", .id = CTL_2, + .base = 0x1400, .len = 0x64, + }, +}; + +static const struct dpu_sspp_cfg msm8917_sspp[] = { + { + .name = "sspp_0", .id = SSPP_VIG0, + .base = 0x4000, .len = 0x150, + .features = VIG_MSM8953_MASK, + .sblk = &dpu_vig_sblk_qseed2, + .xin_id = 0, + .type = SSPP_TYPE_VIG, + .clk_ctrl = DPU_CLK_CTRL_VIG0, + }, { + .name = "sspp_4", .id = SSPP_RGB0, + .base = 0x14000, .len = 0x150, + .features = RGB_MSM8953_MASK, + .sblk = &dpu_rgb_sblk, + .xin_id = 1, + .type = SSPP_TYPE_RGB, + .clk_ctrl = DPU_CLK_CTRL_RGB0, + }, { + .name = "sspp_5", .id = SSPP_RGB1, + .base = 0x16000, .len = 0x150, + .features = RGB_MSM8953_MASK, + .sblk = &dpu_rgb_sblk, + .xin_id = 5, + .type = SSPP_TYPE_RGB, + .clk_ctrl = DPU_CLK_CTRL_RGB1, + }, { + .name = "sspp_8", .id = SSPP_DMA0, + .base = 0x24000, .len = 0x150, + .features = DMA_MSM8953_MASK | BIT(DPU_SSPP_CURSOR), + .sblk = &dpu_dma_sblk, + .xin_id = 2, + .type = SSPP_TYPE_DMA, + .clk_ctrl = DPU_CLK_CTRL_DMA0, + }, +}; + +static const struct dpu_lm_cfg msm8917_lm[] = { + { + .name = "lm_0", .id = LM_0, + .base = 0x44000, .len = 0x320, + .sblk = &msm8998_lm_sblk, + .pingpong = PINGPONG_0, + .dspp = DSPP_0, + }, +}; + +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), + }, +}; + +static const struct dpu_dspp_cfg msm8917_dspp[] = { + { + .name = "dspp_0", .id = DSPP_0, + .base = 0x54000, .len = 0x1800, + .features = DSPP_SC7180_MASK, + .sblk = &msm8998_dspp_sblk, + }, +}; + +static const struct dpu_intf_cfg msm8917_intf[] = { + { + .name = "intf_1", .id = INTF_1, + .base = 0x6a800, .len = 0x268, + .type = INTF_DSI, + .controller_id = MSM_DSI_CONTROLLER_0, + .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, + }, +}; + +static const struct dpu_perf_cfg msm8917_perf_data = { + .max_bw_low = 1800000, + .max_bw_high = 1800000, + .min_core_ib = 2400000, + .min_llcc_ib = 0, /* No LLCC on this SoC */ + .min_dram_ib = 800000, + .undersized_prefill_lines = 2, + .xtra_prefill_lines = 2, + .dest_scale_prefill_lines = 3, + .macrotile_prefill_lines = 4, + .yuv_nv12_prefill_lines = 8, + .linear_prefill_lines = 1, + .downscaling_prefill_lines = 1, + .amortizable_threshold = 25, + .min_prefill_lines = 21, + .danger_lut_tbl = {0xf, 0xffff, 0x0}, + .safe_lut_tbl = {0xfffc, 0xff00, 0xffff}, + .qos_lut_tbl = { + {.nentry = ARRAY_SIZE(msm8998_qos_linear), + .entries = msm8998_qos_linear + }, + {.nentry = ARRAY_SIZE(msm8998_qos_macrotile), + .entries = msm8998_qos_macrotile + }, + {.nentry = ARRAY_SIZE(msm8998_qos_nrt), + .entries = msm8998_qos_nrt + }, + }, + .cdp_cfg = { + {.rd_enable = 1, .wr_enable = 1}, + {.rd_enable = 1, .wr_enable = 0} + }, + .clk_inefficiency_factor = 105, + .bw_inefficiency_factor = 120, +}; + +static const struct dpu_mdss_version msm8917_mdss_ver = { + .core_major_ver = 1, + .core_minor_ver = 15, +}; + +const struct dpu_mdss_cfg dpu_msm8917_cfg = { + .mdss_ver = &msm8917_mdss_ver, + .caps = &msm8917_dpu_caps, + .mdp = msm8917_mdp, + .ctl_count = ARRAY_SIZE(msm8917_ctl), + .ctl = msm8917_ctl, + .sspp_count = ARRAY_SIZE(msm8917_sspp), + .sspp = msm8917_sspp, + .mixer_count = ARRAY_SIZE(msm8917_lm), + .mixer = msm8917_lm, + .dspp_count = ARRAY_SIZE(msm8917_dspp), + .dspp = msm8917_dspp, + .pingpong_count = ARRAY_SIZE(msm8917_pp), + .pingpong = msm8917_pp, + .intf_count = ARRAY_SIZE(msm8917_intf), + .intf = msm8917_intf, + .vbif_count = ARRAY_SIZE(msm8996_vbif), + .vbif = msm8996_vbif, + .perf = &msm8917_perf_data, +}; + +#endif 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 new file mode 100644 index 000000000000..14f36ea6ad0e --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_16_msm8953.h @@ -0,0 +1,218 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2023, Linaro Limited + */ + +#ifndef _DPU_1_16_MSM8953_H +#define _DPU_1_16_MSM8953_H + +static const struct dpu_caps msm8953_dpu_caps = { + .max_mixer_width = DEFAULT_DPU_LINE_WIDTH, + .max_mixer_blendstages = 0x4, + .max_linewidth = DEFAULT_DPU_LINE_WIDTH, + .pixel_ram_size = 40 * 1024, + .max_hdeci_exp = MAX_HORZ_DECIMATION, + .max_vdeci_exp = MAX_VERT_DECIMATION, +}; + +static const struct dpu_mdp_cfg msm8953_mdp[] = { + { + .name = "top_0", + .base = 0x0, .len = 0x454, + .features = BIT(DPU_MDP_VSYNC_SEL), + .clk_ctrls = { + [DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, + [DPU_CLK_CTRL_RGB0] = { .reg_off = 0x2ac, .bit_off = 4 }, + [DPU_CLK_CTRL_RGB1] = { .reg_off = 0x2b4, .bit_off = 4 }, + [DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, + [DPU_CLK_CTRL_CURSOR0] = { .reg_off = 0x3a8, .bit_off = 16 }, + }, + }, +}; + +static const struct dpu_ctl_cfg msm8953_ctl[] = { + { + .name = "ctl_0", .id = CTL_0, + .base = 0x1000, .len = 0x64, + }, { + .name = "ctl_1", .id = CTL_1, + .base = 0x1200, .len = 0x64, + }, { + .name = "ctl_2", .id = CTL_2, + .base = 0x1400, .len = 0x64, + }, +}; + +static const struct dpu_sspp_cfg msm8953_sspp[] = { + { + .name = "sspp_0", .id = SSPP_VIG0, + .base = 0x4000, .len = 0x150, + .features = VIG_MSM8953_MASK, + .sblk = &dpu_vig_sblk_qseed2, + .xin_id = 0, + .type = SSPP_TYPE_VIG, + .clk_ctrl = DPU_CLK_CTRL_VIG0, + }, { + .name = "sspp_4", .id = SSPP_RGB0, + .base = 0x14000, .len = 0x150, + .features = RGB_MSM8953_MASK, + .sblk = &dpu_rgb_sblk, + .xin_id = 1, + .type = SSPP_TYPE_RGB, + .clk_ctrl = DPU_CLK_CTRL_RGB0, + }, { + .name = "sspp_5", .id = SSPP_RGB1, + .base = 0x16000, .len = 0x150, + .features = RGB_MSM8953_MASK, + .sblk = &dpu_rgb_sblk, + .xin_id = 5, + .type = SSPP_TYPE_RGB, + .clk_ctrl = DPU_CLK_CTRL_RGB1, + }, { + .name = "sspp_8", .id = SSPP_DMA0, + .base = 0x24000, .len = 0x150, + .features = DMA_MSM8953_MASK | BIT(DPU_SSPP_CURSOR), + .sblk = &dpu_dma_sblk, + .xin_id = 2, + .type = SSPP_TYPE_DMA, + .clk_ctrl = DPU_CLK_CTRL_DMA0, + }, +}; + +static const struct dpu_lm_cfg msm8953_lm[] = { + { + .name = "lm_0", .id = LM_0, + .base = 0x44000, .len = 0x320, + .sblk = &msm8998_lm_sblk, + .lm_pair = LM_1, + .pingpong = PINGPONG_0, + .dspp = DSPP_0, + }, { + .name = "lm_1", .id = LM_1, + .base = 0x45000, .len = 0x320, + .sblk = &msm8998_lm_sblk, + .lm_pair = LM_0, + .pingpong = PINGPONG_1, + }, +}; + +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), + }, +}; + +static const struct dpu_dspp_cfg msm8953_dspp[] = { + { + .name = "dspp_0", .id = DSPP_0, + .base = 0x54000, .len = 0x1800, + .features = DSPP_SC7180_MASK, + .sblk = &msm8998_dspp_sblk, + }, +}; + +static const struct dpu_intf_cfg msm8953_intf[] = { + { + .name = "intf_0", .id = INTF_0, + .base = 0x6a000, .len = 0x268, + .type = INTF_NONE, + .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, + .type = INTF_DSI, + .controller_id = MSM_DSI_CONTROLLER_0, + .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, + .type = INTF_DSI, + .controller_id = MSM_DSI_CONTROLLER_1, + .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, + }, +}; + +static const struct dpu_perf_cfg msm8953_perf_data = { + .max_bw_low = 3400000, + .max_bw_high = 3400000, + .min_core_ib = 2400000, + .min_llcc_ib = 0, /* No LLCC on this SoC */ + .min_dram_ib = 800000, + .undersized_prefill_lines = 2, + .xtra_prefill_lines = 2, + .dest_scale_prefill_lines = 3, + .macrotile_prefill_lines = 4, + .yuv_nv12_prefill_lines = 8, + .linear_prefill_lines = 1, + .downscaling_prefill_lines = 1, + .amortizable_threshold = 25, + .min_prefill_lines = 14, + .danger_lut_tbl = {0xf, 0xffff, 0x0}, + .safe_lut_tbl = {0xfffc, 0xff00, 0xffff}, + .qos_lut_tbl = { + {.nentry = ARRAY_SIZE(msm8998_qos_linear), + .entries = msm8998_qos_linear + }, + {.nentry = ARRAY_SIZE(msm8998_qos_macrotile), + .entries = msm8998_qos_macrotile + }, + {.nentry = ARRAY_SIZE(msm8998_qos_nrt), + .entries = msm8998_qos_nrt + }, + }, + .cdp_cfg = { + {.rd_enable = 1, .wr_enable = 1}, + {.rd_enable = 1, .wr_enable = 0} + }, + .clk_inefficiency_factor = 105, + .bw_inefficiency_factor = 120, +}; + +static const struct dpu_mdss_version msm8953_mdss_ver = { + .core_major_ver = 1, + .core_minor_ver = 16, +}; + +const struct dpu_mdss_cfg dpu_msm8953_cfg = { + .mdss_ver = &msm8953_mdss_ver, + .caps = &msm8953_dpu_caps, + .mdp = msm8953_mdp, + .ctl_count = ARRAY_SIZE(msm8953_ctl), + .ctl = msm8953_ctl, + .sspp_count = ARRAY_SIZE(msm8953_sspp), + .sspp = msm8953_sspp, + .mixer_count = ARRAY_SIZE(msm8953_lm), + .mixer = msm8953_lm, + .dspp_count = ARRAY_SIZE(msm8953_dspp), + .dspp = msm8953_dspp, + .pingpong_count = ARRAY_SIZE(msm8953_pp), + .pingpong = msm8953_pp, + .intf_count = ARRAY_SIZE(msm8953_intf), + .intf = msm8953_intf, + .vbif_count = ARRAY_SIZE(msm8996_vbif), + .vbif = msm8996_vbif, + .perf = &msm8953_perf_data, +}; + +#endif 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 new file mode 100644 index 000000000000..491f6f5827d1 --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_7_msm8996.h @@ -0,0 +1,338 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2023, Linaro Limited + * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. + */ + +#ifndef _DPU_1_7_MSM8996_H +#define _DPU_1_7_MSM8996_H + +static const struct dpu_caps msm8996_dpu_caps = { + .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .max_mixer_blendstages = 0x7, + .has_src_split = true, + .max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH, + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, + .max_hdeci_exp = MAX_HORZ_DECIMATION, + .max_vdeci_exp = MAX_VERT_DECIMATION, +}; + +static const struct dpu_mdp_cfg msm8996_mdp[] = { + { + .name = "top_0", + .base = 0x0, .len = 0x454, + .features = BIT(DPU_MDP_VSYNC_SEL), + .clk_ctrls = { + [DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, + [DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 }, + [DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 }, + [DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0 }, + [DPU_CLK_CTRL_RGB0] = { .reg_off = 0x2ac, .bit_off = 4 }, + [DPU_CLK_CTRL_RGB1] = { .reg_off = 0x2b4, .bit_off = 4 }, + [DPU_CLK_CTRL_RGB2] = { .reg_off = 0x2bc, .bit_off = 4 }, + [DPU_CLK_CTRL_RGB3] = { .reg_off = 0x2c4, .bit_off = 4 }, + [DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, + [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, + [DPU_CLK_CTRL_CURSOR0] = { .reg_off = 0x3a8, .bit_off = 16 }, + [DPU_CLK_CTRL_CURSOR1] = { .reg_off = 0x3b0, .bit_off = 16 }, + }, + }, +}; + +static const struct dpu_ctl_cfg msm8996_ctl[] = { + { + .name = "ctl_0", .id = CTL_0, + .base = 0x1000, .len = 0x64, + }, { + .name = "ctl_1", .id = CTL_1, + .base = 0x1200, .len = 0x64, + }, { + .name = "ctl_2", .id = CTL_2, + .base = 0x1400, .len = 0x64, + }, { + .name = "ctl_3", .id = CTL_3, + .base = 0x1600, .len = 0x64, + }, { + .name = "ctl_4", .id = CTL_4, + .base = 0x1800, .len = 0x64, + }, +}; + +static const struct dpu_sspp_cfg msm8996_sspp[] = { + { + .name = "sspp_0", .id = SSPP_VIG0, + .base = 0x4000, .len = 0x150, + .features = VIG_MSM8996_MASK, + .sblk = &dpu_vig_sblk_qseed2, + .xin_id = 0, + .type = SSPP_TYPE_VIG, + .clk_ctrl = DPU_CLK_CTRL_VIG0, + }, { + .name = "sspp_1", .id = SSPP_VIG1, + .base = 0x6000, .len = 0x150, + .features = VIG_MSM8996_MASK, + .sblk = &dpu_vig_sblk_qseed2, + .xin_id = 4, + .type = SSPP_TYPE_VIG, + .clk_ctrl = DPU_CLK_CTRL_VIG1, + }, { + .name = "sspp_2", .id = SSPP_VIG2, + .base = 0x8000, .len = 0x150, + .features = VIG_MSM8996_MASK, + .sblk = &dpu_vig_sblk_qseed2, + .xin_id = 8, + .type = SSPP_TYPE_VIG, + .clk_ctrl = DPU_CLK_CTRL_VIG2, + }, { + .name = "sspp_3", .id = SSPP_VIG3, + .base = 0xa000, .len = 0x150, + .features = VIG_MSM8996_MASK, + .sblk = &dpu_vig_sblk_qseed2, + .xin_id = 12, + .type = SSPP_TYPE_VIG, + .clk_ctrl = DPU_CLK_CTRL_VIG3, + }, { + .name = "sspp_4", .id = SSPP_RGB0, + .base = 0x14000, .len = 0x150, + .features = RGB_MSM8996_MASK, + .sblk = &dpu_rgb_sblk, + .xin_id = 1, + .type = SSPP_TYPE_RGB, + .clk_ctrl = DPU_CLK_CTRL_RGB0, + }, { + .name = "sspp_5", .id = SSPP_RGB1, + .base = 0x16000, .len = 0x150, + .features = RGB_MSM8996_MASK, + .sblk = &dpu_rgb_sblk, + .xin_id = 5, + .type = SSPP_TYPE_RGB, + .clk_ctrl = DPU_CLK_CTRL_RGB1, + }, { + .name = "sspp_6", .id = SSPP_RGB2, + .base = 0x18000, .len = 0x150, + .features = RGB_MSM8996_MASK, + .sblk = &dpu_rgb_sblk, + .xin_id = 9, + .type = SSPP_TYPE_RGB, + .clk_ctrl = DPU_CLK_CTRL_RGB2, + }, { + .name = "sspp_7", .id = SSPP_RGB3, + .base = 0x1a000, .len = 0x150, + .features = RGB_MSM8996_MASK, + .sblk = &dpu_rgb_sblk, + .xin_id = 13, + .type = SSPP_TYPE_RGB, + .clk_ctrl = DPU_CLK_CTRL_RGB3, + }, { + .name = "sspp_8", .id = SSPP_DMA0, + .base = 0x24000, .len = 0x150, + .features = DMA_MSM8996_MASK, + .sblk = &dpu_dma_sblk, + .xin_id = 2, + .type = SSPP_TYPE_DMA, + .clk_ctrl = DPU_CLK_CTRL_DMA0, + }, { + .name = "sspp_9", .id = SSPP_DMA1, + .base = 0x26000, .len = 0x150, + .features = DMA_MSM8996_MASK, + .sblk = &dpu_dma_sblk, + .xin_id = 10, + .type = SSPP_TYPE_DMA, + .clk_ctrl = DPU_CLK_CTRL_DMA1, + }, +}; + +static const struct dpu_lm_cfg msm8996_lm[] = { + { + .name = "lm_0", .id = LM_0, + .base = 0x44000, .len = 0x320, + .features = MIXER_MSM8998_MASK, + .sblk = &msm8998_lm_sblk, + .lm_pair = LM_1, + .pingpong = PINGPONG_0, + .dspp = DSPP_0, + }, { + .name = "lm_1", .id = LM_1, + .base = 0x45000, .len = 0x320, + .features = MIXER_MSM8998_MASK, + .sblk = &msm8998_lm_sblk, + .lm_pair = LM_0, + .pingpong = PINGPONG_1, + .dspp = DSPP_1, + }, { + .name = "lm_2", .id = LM_2, + .base = 0x46000, .len = 0x320, + .features = MIXER_MSM8998_MASK, + .sblk = &msm8998_lm_sblk, + .lm_pair = LM_5, + .pingpong = PINGPONG_2, + }, { + .name = "lm_5", .id = LM_5, + .base = 0x49000, .len = 0x320, + .features = MIXER_MSM8998_MASK, + .sblk = &msm8998_lm_sblk, + .lm_pair = LM_2, + .pingpong = PINGPONG_3, + }, +}; + +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, + .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, + .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), + .intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13), + }, { + .name = "pingpong_2", .id = PINGPONG_2, + .base = 0x71000, .len = 0xd4, + .features = PINGPONG_MSM8996_MASK, + .sblk = &msm8996_pp_sblk, + .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10), + .intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14), + }, { + .name = "pingpong_3", .id = PINGPONG_3, + .base = 0x71800, .len = 0xd4, + .features = PINGPONG_MSM8996_MASK, + .sblk = &msm8996_pp_sblk, + .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11), + .intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15), + }, +}; + +static const struct dpu_dsc_cfg msm8996_dsc[] = { + { + .name = "dsc_0", .id = DSC_0, + .base = 0x80000, .len = 0x140, + }, { + .name = "dsc_1", .id = DSC_1, + .base = 0x80400, .len = 0x140, + }, +}; + +static const struct dpu_dspp_cfg msm8996_dspp[] = { + { + .name = "dspp_0", .id = DSPP_0, + .base = 0x54000, .len = 0x1800, + .features = DSPP_SC7180_MASK, + .sblk = &msm8998_dspp_sblk, + }, { + .name = "dspp_1", .id = DSPP_1, + .base = 0x56000, .len = 0x1800, + .features = DSPP_SC7180_MASK, + .sblk = &msm8998_dspp_sblk, + }, +}; + +static const struct dpu_intf_cfg msm8996_intf[] = { + { + .name = "intf_0", .id = INTF_0, + .base = 0x6a000, .len = 0x268, + .type = INTF_NONE, + .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, + .type = INTF_DSI, + .controller_id = MSM_DSI_CONTROLLER_0, + .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, + .type = INTF_DSI, + .controller_id = MSM_DSI_CONTROLLER_1, + .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, + .type = INTF_HDMI, + .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, + }, +}; + +static const struct dpu_perf_cfg msm8996_perf_data = { + .max_bw_low = 9600000, + .max_bw_high = 9600000, + .min_core_ib = 2400000, + .min_llcc_ib = 0, /* No LLCC on this SoC */ + .min_dram_ib = 800000, + .undersized_prefill_lines = 2, + .xtra_prefill_lines = 2, + .dest_scale_prefill_lines = 3, + .macrotile_prefill_lines = 4, + .yuv_nv12_prefill_lines = 8, + .linear_prefill_lines = 1, + .downscaling_prefill_lines = 1, + .amortizable_threshold = 25, + .min_prefill_lines = 21, + .danger_lut_tbl = {0xf, 0xffff, 0x0}, + .safe_lut_tbl = {0xfffc, 0xff00, 0xffff}, + .qos_lut_tbl = { + {.nentry = ARRAY_SIZE(msm8998_qos_linear), + .entries = msm8998_qos_linear + }, + {.nentry = ARRAY_SIZE(msm8998_qos_macrotile), + .entries = msm8998_qos_macrotile + }, + {.nentry = ARRAY_SIZE(msm8998_qos_nrt), + .entries = msm8998_qos_nrt + }, + }, + .cdp_cfg = { + {.rd_enable = 1, .wr_enable = 1}, + {.rd_enable = 1, .wr_enable = 0} + }, + .clk_inefficiency_factor = 105, + .bw_inefficiency_factor = 120, +}; + +static const struct dpu_mdss_version msm8996_mdss_ver = { + .core_major_ver = 1, + .core_minor_ver = 7, +}; + +const struct dpu_mdss_cfg dpu_msm8996_cfg = { + .mdss_ver = &msm8996_mdss_ver, + .caps = &msm8996_dpu_caps, + .mdp = msm8996_mdp, + .ctl_count = ARRAY_SIZE(msm8996_ctl), + .ctl = msm8996_ctl, + .sspp_count = ARRAY_SIZE(msm8996_sspp), + .sspp = msm8996_sspp, + .mixer_count = ARRAY_SIZE(msm8996_lm), + .mixer = msm8996_lm, + .dspp_count = ARRAY_SIZE(msm8996_dspp), + .dspp = msm8996_dspp, + .pingpong_count = ARRAY_SIZE(msm8996_pp), + .pingpong = msm8996_pp, + .dsc_count = ARRAY_SIZE(msm8996_dsc), + .dsc = msm8996_dsc, + .intf_count = ARRAY_SIZE(msm8996_intf), + .intf = msm8996_intf, + .vbif_count = ARRAY_SIZE(msm8996_vbif), + .vbif = msm8996_vbif, + .perf = &msm8996_perf_data, +}; + +#endif 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 1d3e9666c741..64c94e919a69 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 @@ -157,18 +157,6 @@ static const struct dpu_lm_cfg msm8998_lm[] = { .lm_pair = LM_5, .pingpong = PINGPONG_2, }, { - .name = "lm_3", .id = LM_3, - .base = 0x47000, .len = 0x320, - .features = MIXER_MSM8998_MASK, - .sblk = &msm8998_lm_sblk, - .pingpong = PINGPONG_NONE, - }, { - .name = "lm_4", .id = LM_4, - .base = 0x48000, .len = 0x320, - .features = MIXER_MSM8998_MASK, - .sblk = &msm8998_lm_sblk, - .pingpong = PINGPONG_NONE, - }, { .name = "lm_5", .id = LM_5, .base = 0x49000, .len = 0x320, .features = MIXER_MSM8998_MASK, 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 7a23389a5732..72bd4f7e9e50 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 @@ -156,25 +156,13 @@ static const struct dpu_lm_cfg sdm845_lm[] = { .pingpong = PINGPONG_2, .dspp = DSPP_2, }, { - .name = "lm_3", .id = LM_3, - .base = 0x0, .len = 0x320, - .features = MIXER_SDM845_MASK, - .sblk = &sdm845_lm_sblk, - .pingpong = PINGPONG_NONE, - .dspp = DSPP_3, - }, { - .name = "lm_4", .id = LM_4, - .base = 0x0, .len = 0x320, - .features = MIXER_SDM845_MASK, - .sblk = &sdm845_lm_sblk, - .pingpong = PINGPONG_NONE, - }, { .name = "lm_5", .id = LM_5, .base = 0x49000, .len = 0x320, .features = MIXER_SDM845_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_2, .pingpong = PINGPONG_3, + .dspp = DSPP_3, }, }; 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 new file mode 100644 index 000000000000..907b4d7ceb47 --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h @@ -0,0 +1,485 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _DPU_8_4_SA8775P_H +#define _DPU_8_4_SA8775P_H + +static const struct dpu_caps sa8775p_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 sa8775p_mdp = { + .name = "top_0", + .base = 0x0, .len = 0x494, + .features = BIT(DPU_MDP_PERIPH_0_REMOVED), + .clk_ctrls = { + [DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, + [DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 }, + [DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 }, + [DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0 }, + [DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, + [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 }, + [DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, + }, +}; + +/* 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, + .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, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), + }, { + .name = "ctl_2", .id = CTL_2, + .base = 0x17000, .len = 0x204, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11), + }, { + .name = "ctl_3", .id = CTL_3, + .base = 0x18000, .len = 0x204, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12), + }, { + .name = "ctl_4", .id = CTL_4, + .base = 0x19000, .len = 0x204, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13), + }, { + .name = "ctl_5", .id = CTL_5, + .base = 0x1a000, .len = 0x204, + .features = CTL_SC7280_MASK, + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23), + }, +}; + +static const struct dpu_sspp_cfg sa8775p_sspp[] = { + { + .name = "sspp_0", .id = SSPP_VIG0, + .base = 0x4000, .len = 0x32c, + .features = VIG_SDM845_MASK_SDMA, + .sblk = &dpu_vig_sblk_qseed3_3_1, + .xin_id = 0, + .type = SSPP_TYPE_VIG, + .clk_ctrl = DPU_CLK_CTRL_VIG0, + }, { + .name = "sspp_1", .id = SSPP_VIG1, + .base = 0x6000, .len = 0x32c, + .features = VIG_SDM845_MASK_SDMA, + .sblk = &dpu_vig_sblk_qseed3_3_1, + .xin_id = 4, + .type = SSPP_TYPE_VIG, + .clk_ctrl = DPU_CLK_CTRL_VIG1, + }, { + .name = "sspp_2", .id = SSPP_VIG2, + .base = 0x8000, .len = 0x32c, + .features = VIG_SDM845_MASK_SDMA, + .sblk = &dpu_vig_sblk_qseed3_3_1, + .xin_id = 8, + .type = SSPP_TYPE_VIG, + .clk_ctrl = DPU_CLK_CTRL_VIG2, + }, { + .name = "sspp_3", .id = SSPP_VIG3, + .base = 0xa000, .len = 0x32c, + .features = VIG_SDM845_MASK_SDMA, + .sblk = &dpu_vig_sblk_qseed3_3_1, + .xin_id = 12, + .type = SSPP_TYPE_VIG, + .clk_ctrl = DPU_CLK_CTRL_VIG3, + }, { + .name = "sspp_8", .id = SSPP_DMA0, + .base = 0x24000, .len = 0x32c, + .features = DMA_SDM845_MASK_SDMA, + .sblk = &dpu_dma_sblk, + .xin_id = 1, + .type = SSPP_TYPE_DMA, + .clk_ctrl = DPU_CLK_CTRL_DMA0, + }, { + .name = "sspp_9", .id = SSPP_DMA1, + .base = 0x26000, .len = 0x32c, + .features = DMA_SDM845_MASK_SDMA, + .sblk = &dpu_dma_sblk, + .xin_id = 5, + .type = SSPP_TYPE_DMA, + .clk_ctrl = DPU_CLK_CTRL_DMA1, + }, { + .name = "sspp_10", .id = SSPP_DMA2, + .base = 0x28000, .len = 0x32c, + .features = DMA_CURSOR_SDM845_MASK_SDMA, + .sblk = &dpu_dma_sblk, + .xin_id = 9, + .type = SSPP_TYPE_DMA, + .clk_ctrl = DPU_CLK_CTRL_DMA2, + }, { + .name = "sspp_11", .id = SSPP_DMA3, + .base = 0x2a000, .len = 0x32c, + .features = DMA_CURSOR_SDM845_MASK_SDMA, + .sblk = &dpu_dma_sblk, + .xin_id = 13, + .type = SSPP_TYPE_DMA, + .clk_ctrl = DPU_CLK_CTRL_DMA3, + }, +}; + +static const struct dpu_lm_cfg sa8775p_lm[] = { + { + .name = "lm_0", .id = LM_0, + .base = 0x44000, .len = 0x400, + .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 = 0x400, + .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 = 0x400, + .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 = 0x400, + .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 = 0x400, + .features = MIXER_SDM845_MASK, + .sblk = &sdm845_lm_sblk, + .lm_pair = LM_5, + .pingpong = PINGPONG_4, + }, { + .name = "lm_5", .id = LM_5, + .base = 0x49000, .len = 0x400, + .features = MIXER_SDM845_MASK, + .sblk = &sdm845_lm_sblk, + .lm_pair = LM_4, + .pingpong = PINGPONG_5, + }, +}; + +static const struct dpu_dspp_cfg sa8775p_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 sa8775p_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_6", .id = PINGPONG_6, + .base = 0x65800, .len = 0, + .features = BIT(DPU_PINGPONG_DITHER), + .sblk = &sc7280_pp_sblk, + .merge_3d = MERGE_3D_3, + }, { + .name = "pingpong_7", .id = PINGPONG_7, + .base = 0x65c00, .len = 0, + .features = BIT(DPU_PINGPONG_DITHER), + .sblk = &sc7280_pp_sblk, + .merge_3d = MERGE_3D_3, + }, +}; + +static const struct dpu_merge_3d_cfg sa8775p_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 = 0x65f00, .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 sa8775p_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, + }, { + .name = "dce_2_0", .id = DSC_4, + .base = 0x82000, .len = 0x4, + .features = BIT(DPU_DSC_HW_REV_1_2), + .sblk = &dsc_sblk_0, + }, { + .name = "dce_2_1", .id = DSC_5, + .base = 0x82000, .len = 0x4, + .features = BIT(DPU_DSC_HW_REV_1_2), + .sblk = &dsc_sblk_1, + }, +}; + +static const struct dpu_wb_cfg sa8775p_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 = 4096, + .intr_wb_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 4), + }, +}; + +/* TODO: INTF 3, 6, 7 and 8 are used for MST, marked as INTF_NONE for now */ +static const struct dpu_intf_cfg sa8775p_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_NONE, + .controller_id = MSM_DP_CONTROLLER_0, /* pair with intf_0 for DP MST */ + .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), + }, { + .name = "intf_4", .id = INTF_4, + .base = 0x38000, .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, 20), + .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 21), + }, { + .name = "intf_6", .id = INTF_6, + .base = 0x3A000, .len = 0x280, + .features = INTF_SC7280_MASK, + .type = INTF_NONE, + .controller_id = MSM_DP_CONTROLLER_0, /* pair with intf_0 for DP MST */ + .prog_fetch_lines_worst_case = 24, + .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 17), + .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 16), + }, { + .name = "intf_7", .id = INTF_7, + .base = 0x3b000, .len = 0x280, + .features = INTF_SC7280_MASK, + .type = INTF_NONE, + .controller_id = MSM_DP_CONTROLLER_0, /* pair with intf_0 for DP MST */ + .prog_fetch_lines_worst_case = 24, + .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 18), + .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 19), + }, { + .name = "intf_8", .id = INTF_8, + .base = 0x3c000, .len = 0x280, + .features = INTF_SC7280_MASK, + .type = INTF_NONE, + .controller_id = MSM_DP_CONTROLLER_1, /* pair with intf_4 for DP MST */ + .prog_fetch_lines_worst_case = 24, + .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12), + .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13), + }, +}; + +static const struct dpu_perf_cfg sa8775p_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 = {0xfff0, 0xfff0, 0x1}, + .qos_lut_tbl = { + {.nentry = ARRAY_SIZE(sm6350_qos_linear_macrotile), + .entries = sm6350_qos_linear_macrotile + }, + {.nentry = ARRAY_SIZE(sm6350_qos_linear_macrotile), + .entries = sm6350_qos_linear_macrotile + }, + {.nentry = ARRAY_SIZE(sc7180_qos_nrt), + .entries = sc7180_qos_nrt + }, + /* TODO: macrotile-qseed is different from macrotile */ + }, + .cdp_cfg = { + {.rd_enable = 1, .wr_enable = 1}, + {.rd_enable = 1, .wr_enable = 0} + }, + .clk_inefficiency_factor = 105, + .bw_inefficiency_factor = 120, +}; + +static const struct dpu_mdss_version sa8775p_mdss_ver = { + .core_major_ver = 8, + .core_minor_ver = 4, +}; + +const struct dpu_mdss_cfg dpu_sa8775p_cfg = { + .mdss_ver = &sa8775p_mdss_ver, + .caps = &sa8775p_dpu_caps, + .mdp = &sa8775p_mdp, + .cdm = &sc7280_cdm, + .ctl_count = ARRAY_SIZE(sa8775p_ctl), + .ctl = sa8775p_ctl, + .sspp_count = ARRAY_SIZE(sa8775p_sspp), + .sspp = sa8775p_sspp, + .mixer_count = ARRAY_SIZE(sa8775p_lm), + .mixer = sa8775p_lm, + .dspp_count = ARRAY_SIZE(sa8775p_dspp), + .dspp = sa8775p_dspp, + .pingpong_count = ARRAY_SIZE(sa8775p_pp), + .pingpong = sa8775p_pp, + .dsc_count = ARRAY_SIZE(sa8775p_dsc), + .dsc = sa8775p_dsc, + .merge_3d_count = ARRAY_SIZE(sa8775p_merge_3d), + .merge_3d = sa8775p_merge_3d, + .wb_count = ARRAY_SIZE(sa8775p_wb), + .wb = sa8775p_wb, + .intf_count = ARRAY_SIZE(sa8775p_intf), + .intf = sa8775p_intf, + .vbif_count = ARRAY_SIZE(sdm845_vbif), + .vbif = sdm845_vbif, + .perf = &sa8775p_perf_data, +}; + +#endif diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h index 7c286bafb948..e7183cf05776 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h @@ -8,72 +8,26 @@ #include "dpu_kms.h" #include "dpu_hw_interrupts.h" -/** - * dpu_core_irq_preinstall - perform pre-installation of core IRQ handler - * @kms: MSM KMS handle - * @return: none - */ void dpu_core_irq_preinstall(struct msm_kms *kms); -/** - * dpu_core_irq_uninstall - uninstall core IRQ handler - * @kms: MSM KMS handle - * @return: none - */ void dpu_core_irq_uninstall(struct msm_kms *kms); -/** - * dpu_core_irq - core IRQ handler - * @kms: MSM KMS handle - * @return: interrupt handling status - */ irqreturn_t dpu_core_irq(struct msm_kms *kms); -/** - * dpu_core_irq_read - IRQ helper function for reading IRQ status - * @dpu_kms: DPU handle - * @irq_idx: irq index - * @return: non-zero if irq detected; otherwise no irq detected - */ u32 dpu_core_irq_read( struct dpu_kms *dpu_kms, unsigned int irq_idx); -/** - * dpu_core_irq_register_callback - For registering callback function on IRQ - * interrupt - * @dpu_kms: DPU handle - * @irq_idx: irq index - * @irq_cb: IRQ callback funcion. - * @irq_arg: IRQ callback argument. - * @return: 0 for success registering callback, otherwise failure - * - * This function supports registration of multiple callbacks for each interrupt. - */ int dpu_core_irq_register_callback( struct dpu_kms *dpu_kms, unsigned int irq_idx, void (*irq_cb)(void *arg), void *irq_arg); -/** - * dpu_core_irq_unregister_callback - For unregistering callback function on IRQ - * interrupt - * @dpu_kms: DPU handle - * @irq_idx: irq index - * @return: 0 for success registering callback, otherwise failure - * - * This function supports registration of multiple callbacks for each interrupt. - */ int dpu_core_irq_unregister_callback( struct dpu_kms *dpu_kms, unsigned int irq_idx); -/** - * dpu_debugfs_core_irq_init - register core irq debugfs - * @dpu_kms: pointer to kms - * @parent: debugfs directory root - */ void dpu_debugfs_core_irq_init(struct dpu_kms *dpu_kms, struct dentry *parent); 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 68fae048a9a8..6f0a37f954fe 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c @@ -80,7 +80,7 @@ static u64 _dpu_core_perf_calc_clk(const struct dpu_perf_cfg *perf_cfg, mode = &state->adjusted_mode; - crtc_clk = mode->vtotal * mode->hdisplay * drm_mode_vrefresh(mode); + crtc_clk = (u64)mode->vtotal * mode->hdisplay * drm_mode_vrefresh(mode); drm_atomic_crtc_for_each_plane(plane, crtc) { pstate = to_dpu_plane_state(plane->state); @@ -140,6 +140,12 @@ static void _dpu_core_perf_calc_crtc(const struct dpu_core_perf *core_perf, perf->max_per_pipe_ib, perf->bw_ctl); } +/** + * dpu_core_perf_crtc_check - validate performance of the given crtc state + * @crtc: Pointer to crtc + * @state: Pointer to new crtc state + * return: zero if success, or error code otherwise + */ int dpu_core_perf_crtc_check(struct drm_crtc *crtc, struct drm_crtc_state *state) { @@ -301,6 +307,12 @@ static u64 _dpu_core_perf_get_core_clk_rate(struct dpu_kms *kms) return clk_rate; } +/** + * dpu_core_perf_crtc_update - update performance of the given crtc + * @crtc: Pointer to crtc + * @params_changed: true if crtc parameters are modified + * return: zero if success, or error code otherwise + */ int dpu_core_perf_crtc_update(struct drm_crtc *crtc, int params_changed) { @@ -446,6 +458,11 @@ static const struct file_operations dpu_core_perf_mode_fops = { .write = _dpu_core_perf_mode_write, }; +/** + * dpu_core_perf_debugfs_init - initialize debugfs for core performance context + * @dpu_kms: Pointer to the dpu_kms struct + * @parent: Pointer to parent debugfs + */ int dpu_core_perf_debugfs_init(struct dpu_kms *dpu_kms, struct dentry *parent) { struct dpu_core_perf *perf = &dpu_kms->perf; @@ -482,6 +499,12 @@ int dpu_core_perf_debugfs_init(struct dpu_kms *dpu_kms, struct dentry *parent) } #endif +/** + * dpu_core_perf_init - initialize the given core performance context + * @perf: Pointer to core performance context + * @perf_cfg: Pointer to platform performance configuration + * @max_core_clk_rate: Maximum core clock rate + */ int dpu_core_perf_init(struct dpu_core_perf *perf, const struct dpu_perf_cfg *perf_cfg, unsigned long max_core_clk_rate) 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 4186977390bd..451bf8021114 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h @@ -54,47 +54,20 @@ struct dpu_core_perf { u64 fix_core_ab_vote; }; -/** - * dpu_core_perf_crtc_check - validate performance of the given crtc state - * @crtc: Pointer to crtc - * @state: Pointer to new crtc state - * return: zero if success, or error code otherwise - */ int dpu_core_perf_crtc_check(struct drm_crtc *crtc, struct drm_crtc_state *state); -/** - * dpu_core_perf_crtc_update - update performance of the given crtc - * @crtc: Pointer to crtc - * @params_changed: true if crtc parameters are modified - * return: zero if success, or error code otherwise - */ int dpu_core_perf_crtc_update(struct drm_crtc *crtc, int params_changed); -/** - * dpu_core_perf_crtc_release_bw - release bandwidth of the given crtc - * @crtc: Pointer to crtc - */ void dpu_core_perf_crtc_release_bw(struct drm_crtc *crtc); -/** - * dpu_core_perf_init - initialize the given core performance context - * @perf: Pointer to core performance context - * @perf_cfg: Pointer to platform performance configuration - * @max_core_clk_rate: Maximum core clock rate - */ int dpu_core_perf_init(struct dpu_core_perf *perf, const struct dpu_perf_cfg *perf_cfg, unsigned long max_core_clk_rate); struct dpu_kms; -/** - * dpu_core_perf_debugfs_init - initialize debugfs for core performance context - * @dpu_kms: Pointer to the dpu_kms struct - * @debugfs_parent: Pointer to parent debugfs - */ int dpu_core_perf_debugfs_init(struct dpu_kms *dpu_kms, struct dentry *parent); #endif /* _DPU_CORE_PERF_H_ */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index db6c57900781..9f6ffd344693 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -572,6 +572,10 @@ static void _dpu_crtc_complete_flip(struct drm_crtc *crtc) spin_unlock_irqrestore(&dev->event_lock, flags); } +/** + * dpu_crtc_get_intf_mode - get interface mode of the given crtc + * @crtc: Pointert to crtc + */ enum dpu_intf_mode dpu_crtc_get_intf_mode(struct drm_crtc *crtc) { struct drm_encoder *encoder; @@ -594,6 +598,10 @@ enum dpu_intf_mode dpu_crtc_get_intf_mode(struct drm_crtc *crtc) return INTF_MODE_NONE; } +/** + * dpu_crtc_vblank_callback - called on vblank irq, issues completion events + * @crtc: Pointer to drm crtc object + */ void dpu_crtc_vblank_callback(struct drm_crtc *crtc) { struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); @@ -704,6 +712,10 @@ void dpu_crtc_frame_event_cb(struct drm_crtc *crtc, u32 event) kthread_queue_work(priv->event_thread[crtc_id].worker, &fevent->work); } +/** + * dpu_crtc_complete_commit - callback signalling completion of current commit + * @crtc: Pointer to drm crtc object + */ void dpu_crtc_complete_commit(struct drm_crtc *crtc) { trace_dpu_crtc_complete_commit(DRMID(crtc)); @@ -934,6 +946,10 @@ static int _dpu_crtc_wait_for_frame_done(struct drm_crtc *crtc) return rc; } +/** + * dpu_crtc_commit_kickoff - trigger kickoff of the commit for this crtc + * @crtc: Pointer to drm crtc object + */ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc) { struct drm_encoder *encoder; @@ -1230,6 +1246,24 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, return 0; } +static enum drm_mode_status dpu_crtc_mode_valid(struct drm_crtc *crtc, + const struct drm_display_mode *mode) +{ + struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc); + + /* + * max crtc width is equal to the max mixer width * 2 and max height is 4K + */ + return drm_mode_validate_size(mode, + 2 * dpu_kms->catalog->caps->max_mixer_width, + 4096); +} + +/** + * dpu_crtc_vblank - enable or disable vblanks for this crtc + * @crtc: Pointer to drm crtc object + * @en: true to enable vblanks, false to disable + */ int dpu_crtc_vblank(struct drm_crtc *crtc, bool en) { struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); @@ -1445,10 +1479,19 @@ static const struct drm_crtc_helper_funcs dpu_crtc_helper_funcs = { .atomic_check = dpu_crtc_atomic_check, .atomic_begin = dpu_crtc_atomic_begin, .atomic_flush = dpu_crtc_atomic_flush, + .mode_valid = dpu_crtc_mode_valid, .get_scanout_position = dpu_crtc_get_scanout_position, }; -/* initialize crtc */ +/** + * dpu_crtc_init - create a new crtc object + * @dev: dpu device + * @plane: base plane + * @cursor: cursor plane + * @return: new crtc object or error + * + * initialize CRTC + */ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane, struct drm_plane *cursor) { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h index febc3e764a63..0b148f3ce0d7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h @@ -239,55 +239,17 @@ static inline int dpu_crtc_frame_pending(struct drm_crtc *crtc) return crtc ? atomic_read(&to_dpu_crtc(crtc)->frame_pending) : -EINVAL; } -/** - * dpu_crtc_vblank - enable or disable vblanks for this crtc - * @crtc: Pointer to drm crtc object - * @en: true to enable vblanks, false to disable - */ int dpu_crtc_vblank(struct drm_crtc *crtc, bool en); -/** - * dpu_crtc_vblank_callback - called on vblank irq, issues completion events - * @crtc: Pointer to drm crtc object - */ void dpu_crtc_vblank_callback(struct drm_crtc *crtc); -/** - * dpu_crtc_commit_kickoff - trigger kickoff of the commit for this crtc - * @crtc: Pointer to drm crtc object - */ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc); -/** - * dpu_crtc_complete_commit - callback signalling completion of current commit - * @crtc: Pointer to drm crtc object - */ void dpu_crtc_complete_commit(struct drm_crtc *crtc); -/** - * dpu_crtc_init - create a new crtc object - * @dev: dpu device - * @plane: base plane - * @cursor: cursor plane - * @Return: new crtc object or error - */ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane, struct drm_plane *cursor); -/** - * dpu_crtc_register_custom_event - api for enabling/disabling crtc event - * @kms: Pointer to dpu_kms - * @crtc_drm: Pointer to crtc object - * @event: Event that client is interested - * @en: Flag to enable/disable the event - */ -int dpu_crtc_register_custom_event(struct dpu_kms *kms, - struct drm_crtc *crtc_drm, u32 event, bool en); - -/** - * dpu_crtc_get_intf_mode - get interface mode of the given crtc - * @crtc: Pointert to crtc - */ enum dpu_intf_mode dpu_crtc_get_intf_mode(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 bd3698bf0cf7..83de7564e2c1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -217,6 +217,10 @@ static u32 dither_matrix[DITHER_MATRIX_SZ] = { 15, 7, 13, 5, 3, 11, 1, 9, 12, 4, 14, 6, 0, 8, 2, 10 }; +/** + * dpu_encoder_get_drm_fmt - return DRM fourcc format + * @phys_enc: Pointer to physical encoder structure + */ u32 dpu_encoder_get_drm_fmt(struct dpu_encoder_phys *phys_enc) { struct drm_encoder *drm_enc; @@ -235,6 +239,11 @@ u32 dpu_encoder_get_drm_fmt(struct dpu_encoder_phys *phys_enc) return DRM_FORMAT_RGB888; } +/** + * dpu_encoder_needs_periph_flush - return true if physical encoder requires + * peripheral flush + * @phys_enc: Pointer to physical encoder structure + */ bool dpu_encoder_needs_periph_flush(struct dpu_encoder_phys *phys_enc) { struct drm_encoder *drm_enc; @@ -253,6 +262,10 @@ bool dpu_encoder_needs_periph_flush(struct dpu_encoder_phys *phys_enc) msm_dp_needs_periph_flush(priv->dp[disp_info->h_tile_instance[0]], mode); } +/** + * dpu_encoder_is_widebus_enabled - return bool value if widebus is enabled + * @drm_enc: Pointer to previously created drm encoder structure + */ bool dpu_encoder_is_widebus_enabled(const struct drm_encoder *drm_enc) { const struct dpu_encoder_virt *dpu_enc; @@ -272,6 +285,11 @@ bool dpu_encoder_is_widebus_enabled(const struct drm_encoder *drm_enc) return false; } +/** + * dpu_encoder_is_dsc_enabled - indicate whether dsc is enabled + * for the encoder. + * @drm_enc: Pointer to previously created drm encoder structure + */ bool dpu_encoder_is_dsc_enabled(const struct drm_encoder *drm_enc) { const struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc); @@ -279,6 +297,12 @@ bool dpu_encoder_is_dsc_enabled(const struct drm_encoder *drm_enc) return dpu_enc->dsc ? true : false; } +/** + * dpu_encoder_get_crc_values_cnt - get number of physical encoders contained + * in virtual encoder that can collect CRC values + * @drm_enc: Pointer to previously created drm encoder structure + * Returns: Number of physical encoders for given drm encoder + */ int dpu_encoder_get_crc_values_cnt(const struct drm_encoder *drm_enc) { struct dpu_encoder_virt *dpu_enc; @@ -297,6 +321,10 @@ int dpu_encoder_get_crc_values_cnt(const struct drm_encoder *drm_enc) return num_intf; } +/** + * dpu_encoder_setup_misr - enable misr calculations + * @drm_enc: Pointer to previously created drm encoder structure + */ void dpu_encoder_setup_misr(const struct drm_encoder *drm_enc) { struct dpu_encoder_virt *dpu_enc; @@ -315,6 +343,13 @@ void dpu_encoder_setup_misr(const struct drm_encoder *drm_enc) } } +/** + * dpu_encoder_get_crc - get the crc value from interface blocks + * @drm_enc: Pointer to previously created drm encoder structure + * @crcs: array to fill with CRC data + * @pos: offset into the @crcs array + * Returns: 0 on success, error otherwise + */ int dpu_encoder_get_crc(const struct drm_encoder *drm_enc, u32 *crcs, int pos) { struct dpu_encoder_virt *dpu_enc; @@ -385,6 +420,12 @@ static char *dpu_encoder_helper_get_intf_type(enum dpu_intf_mode intf_mode) } } +/** + * dpu_encoder_helper_report_irq_timeout - utility to report error that irq has + * timed out, including reporting frame error event to crtc and debug dump + * @phys_enc: Pointer to physical encoder structure + * @intr_idx: Failing interrupt index + */ void dpu_encoder_helper_report_irq_timeout(struct dpu_encoder_phys *phys_enc, enum dpu_intr_idx intr_idx) { @@ -402,6 +443,15 @@ void dpu_encoder_helper_report_irq_timeout(struct dpu_encoder_phys *phys_enc, static int dpu_encoder_helper_wait_event_timeout(int32_t drm_id, u32 irq_idx, struct dpu_encoder_wait_info *info); +/** + * dpu_encoder_helper_wait_for_irq - utility to wait on an irq. + * note: will call dpu_encoder_helper_wait_for_irq on timeout + * @phys_enc: Pointer to physical encoder structure + * @irq_idx: IRQ index + * @func: IRQ callback to be called in case of timeout + * @wait_info: wait info struct + * @return: 0 or -ERROR + */ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc, unsigned int irq_idx, void (*func)(void *arg), @@ -473,6 +523,10 @@ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc, return ret; } +/** + * dpu_encoder_get_vsync_count - get vsync count for the encoder. + * @drm_enc: Pointer to previously created drm encoder structure + */ int dpu_encoder_get_vsync_count(struct drm_encoder *drm_enc) { struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc); @@ -480,6 +534,10 @@ int dpu_encoder_get_vsync_count(struct drm_encoder *drm_enc) return phys ? atomic_read(&phys->vsync_cnt) : 0; } +/** + * dpu_encoder_get_linecount - get interface line count for the encoder. + * @drm_enc: Pointer to previously created drm encoder structure + */ int dpu_encoder_get_linecount(struct drm_encoder *drm_enc) { struct dpu_encoder_virt *dpu_enc; @@ -495,6 +553,13 @@ int dpu_encoder_get_linecount(struct drm_encoder *drm_enc) return linecount; } +/** + * dpu_encoder_helper_split_config - split display configuration helper function + * This helper function may be used by physical encoders to configure + * the split display related registers. + * @phys_enc: Pointer to physical encoder structure + * @interface: enum dpu_intf setting + */ void dpu_encoder_helper_split_config( struct dpu_encoder_phys *phys_enc, enum dpu_intf interface) @@ -544,6 +609,10 @@ void dpu_encoder_helper_split_config( } } +/** + * dpu_encoder_use_dsc_merge - returns true if the encoder uses DSC merge topology. + * @drm_enc: Pointer to previously created drm encoder structure + */ bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc) { struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc); @@ -560,6 +629,12 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc) return (num_dsc > 0) && (num_dsc > intf_count); } +/** + * dpu_encoder_get_dsc_config - get DSC config for the DPU encoder + * This helper function is used by physical encoder to get DSC config + * used for this encoder. + * @drm_enc: Pointer to encoder structure + */ struct drm_dsc_config *dpu_encoder_get_dsc_config(struct drm_encoder *drm_enc) { struct msm_drm_private *priv = drm_enc->dev->dev_private; @@ -1089,6 +1164,11 @@ static int dpu_encoder_resource_control(struct drm_encoder *drm_enc, return 0; } +/** + * dpu_encoder_prepare_wb_job - prepare writeback job for the encoder. + * @drm_enc: Pointer to previously created drm encoder structure + * @job: Pointer to the current drm writeback job + */ void dpu_encoder_prepare_wb_job(struct drm_encoder *drm_enc, struct drm_writeback_job *job) { @@ -1106,6 +1186,11 @@ void dpu_encoder_prepare_wb_job(struct drm_encoder *drm_enc, } } +/** + * dpu_encoder_cleanup_wb_job - cleanup writeback job for the encoder. + * @drm_enc: Pointer to previously created drm encoder structure + * @job: Pointer to the current drm writeback job + */ void dpu_encoder_cleanup_wb_job(struct drm_encoder *drm_enc, struct drm_writeback_job *job) { @@ -1248,6 +1333,10 @@ static void _dpu_encoder_virt_enable_helper(struct drm_encoder *drm_enc) } } +/** + * dpu_encoder_virt_runtime_resume - pm runtime resume the encoder configs + * @drm_enc: encoder pointer + */ void dpu_encoder_virt_runtime_resume(struct drm_encoder *drm_enc) { struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc); @@ -1389,6 +1478,12 @@ static struct dpu_hw_intf *dpu_encoder_get_intf(const struct dpu_mdss_cfg *catal return NULL; } +/** + * dpu_encoder_vblank_callback - Notify virtual encoder of vblank IRQ reception + * @drm_enc: Pointer to drm encoder structure + * @phy_enc: Pointer to physical encoder + * Note: This is called from IRQ handler context. + */ void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc, struct dpu_encoder_phys *phy_enc) { @@ -1411,6 +1506,12 @@ void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc, DPU_ATRACE_END("encoder_vblank_callback"); } +/** + * dpu_encoder_underrun_callback - Notify virtual encoder of underrun IRQ reception + * @drm_enc: Pointer to drm encoder structure + * @phy_enc: Pointer to physical encoder + * Note: This is called from IRQ handler context. + */ void dpu_encoder_underrun_callback(struct drm_encoder *drm_enc, struct dpu_encoder_phys *phy_enc) { @@ -1429,6 +1530,11 @@ void dpu_encoder_underrun_callback(struct drm_encoder *drm_enc, DPU_ATRACE_END("encoder_underrun_callback"); } +/** + * dpu_encoder_assign_crtc - Link the encoder to the crtc it's assigned to + * @drm_enc: encoder pointer + * @crtc: crtc pointer + */ void dpu_encoder_assign_crtc(struct drm_encoder *drm_enc, struct drm_crtc *crtc) { struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc); @@ -1441,6 +1547,13 @@ void dpu_encoder_assign_crtc(struct drm_encoder *drm_enc, struct drm_crtc *crtc) spin_unlock_irqrestore(&dpu_enc->enc_spinlock, lock_flags); } +/** + * dpu_encoder_toggle_vblank_for_crtc - Toggles vblank interrupts on or off if + * the encoder is assigned to the given crtc + * @drm_enc: encoder pointer + * @crtc: crtc pointer + * @enable: true if vblank should be enabled + */ void dpu_encoder_toggle_vblank_for_crtc(struct drm_encoder *drm_enc, struct drm_crtc *crtc, bool enable) { @@ -1465,6 +1578,13 @@ void dpu_encoder_toggle_vblank_for_crtc(struct drm_encoder *drm_enc, } } +/** + * dpu_encoder_frame_done_callback - Notify virtual encoder that this phys + * encoder completes last request frame + * @drm_enc: Pointer to drm encoder structure + * @ready_phys: Pointer to physical encoder + * @event: Event to process + */ void dpu_encoder_frame_done_callback( struct drm_encoder *drm_enc, struct dpu_encoder_phys *ready_phys, u32 event) @@ -1587,6 +1707,12 @@ static void _dpu_encoder_trigger_start(struct dpu_encoder_phys *phys) phys->ops.trigger_start(phys); } +/** + * dpu_encoder_helper_trigger_start - control start helper function + * This helper function may be optionally specified by physical + * encoders if they require ctl_start triggering. + * @phys_enc: Pointer to physical encoder structure + */ void dpu_encoder_helper_trigger_start(struct dpu_encoder_phys *phys_enc) { struct dpu_hw_ctl *ctl; @@ -1708,6 +1834,11 @@ static void _dpu_encoder_kickoff_phys(struct dpu_encoder_virt *dpu_enc) spin_unlock_irqrestore(&dpu_enc->enc_spinlock, lock_flags); } +/** + * dpu_encoder_trigger_kickoff_pending - Clear the flush bits from previous + * kickoff and trigger the ctl prepare progress for command mode display. + * @drm_enc: encoder pointer + */ void dpu_encoder_trigger_kickoff_pending(struct drm_encoder *drm_enc) { struct dpu_encoder_virt *dpu_enc; @@ -1784,6 +1915,11 @@ static u32 _dpu_encoder_calculate_linetime(struct dpu_encoder_virt *dpu_enc, return line_time; } +/** + * dpu_encoder_vsync_time - get the time of the next vsync + * @drm_enc: encoder pointer + * @wakeup_time: pointer to ktime_t to write the vsync time to + */ int dpu_encoder_vsync_time(struct drm_encoder *drm_enc, ktime_t *wakeup_time) { struct drm_display_mode *mode; @@ -1930,6 +2066,13 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc, dsc, dsc_common_mode, initial_lines); } +/** + * dpu_encoder_prepare_for_kickoff - schedule double buffer flip of the ctl + * path (i.e. ctl flush and start) at next appropriate time. + * Immediately: if no previous commit is outstanding. + * Delayed: Block until next trigger can be issued. + * @drm_enc: encoder pointer + */ void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc) { struct dpu_encoder_virt *dpu_enc; @@ -1966,6 +2109,10 @@ void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc) dpu_encoder_prep_dsc(dpu_enc, dpu_enc->dsc); } +/** + * dpu_encoder_is_valid_for_commit - check if encode has valid parameters for commit. + * @drm_enc: Pointer to drm encoder structure + */ bool dpu_encoder_is_valid_for_commit(struct drm_encoder *drm_enc) { struct dpu_encoder_virt *dpu_enc; @@ -1987,6 +2134,11 @@ bool dpu_encoder_is_valid_for_commit(struct drm_encoder *drm_enc) return true; } +/** + * dpu_encoder_kickoff - trigger a double buffer flip of the ctl path + * (i.e. ctl flush and start) immediately. + * @drm_enc: encoder pointer + */ void dpu_encoder_kickoff(struct drm_encoder *drm_enc) { struct dpu_encoder_virt *dpu_enc; @@ -2085,6 +2237,10 @@ static void dpu_encoder_unprep_dsc(struct dpu_encoder_virt *dpu_enc) } } +/** + * dpu_encoder_helper_phys_cleanup - helper to cleanup dpu pipeline + * @phys_enc: Pointer to physical encoder structure + */ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) { struct dpu_hw_ctl *ctl = phys_enc->hw_ctl; @@ -2168,6 +2324,12 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) ctl->ops.clear_pending_flush(ctl); } +/** + * dpu_encoder_helper_phys_setup_cdm - setup chroma down sampling block + * @phys_enc: Pointer to physical encoder + * @dpu_fmt: Pinter to the format description + * @output_type: HDMI/WB + */ void dpu_encoder_helper_phys_setup_cdm(struct dpu_encoder_phys *phys_enc, const struct msm_format *dpu_fmt, u32 output_type) @@ -2472,6 +2634,13 @@ static const struct drm_encoder_funcs dpu_encoder_funcs = { .debugfs_init = dpu_encoder_debugfs_init, }; +/** + * dpu_encoder_init - initialize virtual encoder object + * @dev: Pointer to drm device structure + * @drm_enc_mode: corresponding DRM_MODE_ENCODER_* constant + * @disp_info: Pointer to display information structure + * Returns: Pointer to newly created drm encoder + */ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, int drm_enc_mode, struct msm_display_info *disp_info) @@ -2593,6 +2762,10 @@ int dpu_encoder_wait_for_tx_complete(struct drm_encoder *drm_enc) return ret; } +/** + * dpu_encoder_get_intf_mode - get interface mode of the given encoder + * @encoder: Pointer to drm encoder object + */ enum dpu_intf_mode dpu_encoder_get_intf_mode(struct drm_encoder *encoder) { struct dpu_encoder_virt *dpu_enc = NULL; @@ -2612,6 +2785,12 @@ enum dpu_intf_mode dpu_encoder_get_intf_mode(struct drm_encoder *encoder) return INTF_MODE_NONE; } +/** + * 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. + * @phys_enc: Pointer to physical encoder structure + */ unsigned int dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc) { struct drm_encoder *encoder = phys_enc->parent; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h index f7465a1774aa..92b5ee390788 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h @@ -19,6 +19,8 @@ #define IDLE_TIMEOUT (66 - 16/2) +#define MAX_H_TILES_PER_DISPLAY 2 + /** * struct msm_display_info - defines display properties * @intf_type: INTF_ type @@ -36,159 +38,54 @@ struct msm_display_info { enum dpu_vsync_source vsync_source; }; -/** - * dpu_encoder_assign_crtc - Link the encoder to the crtc it's assigned to - * @encoder: encoder pointer - * @crtc: crtc pointer - */ void dpu_encoder_assign_crtc(struct drm_encoder *encoder, struct drm_crtc *crtc); -/** - * dpu_encoder_toggle_vblank_for_crtc - Toggles vblank interrupts on or off if - * the encoder is assigned to the given crtc - * @encoder: encoder pointer - * @crtc: crtc pointer - * @enable: true if vblank should be enabled - */ void dpu_encoder_toggle_vblank_for_crtc(struct drm_encoder *encoder, struct drm_crtc *crtc, bool enable); -/** - * dpu_encoder_prepare_for_kickoff - schedule double buffer flip of the ctl - * path (i.e. ctl flush and start) at next appropriate time. - * Immediately: if no previous commit is outstanding. - * Delayed: Block until next trigger can be issued. - * @encoder: encoder pointer - */ void dpu_encoder_prepare_for_kickoff(struct drm_encoder *encoder); -/** - * dpu_encoder_trigger_kickoff_pending - Clear the flush bits from previous - * kickoff and trigger the ctl prepare progress for command mode display. - * @encoder: encoder pointer - */ void dpu_encoder_trigger_kickoff_pending(struct drm_encoder *encoder); -/** - * dpu_encoder_kickoff - trigger a double buffer flip of the ctl path - * (i.e. ctl flush and start) immediately. - * @encoder: encoder pointer - */ void dpu_encoder_kickoff(struct drm_encoder *encoder); -/** - * dpu_encoder_wakeup_time - get the time of the next vsync - */ int dpu_encoder_vsync_time(struct drm_encoder *drm_enc, ktime_t *wakeup_time); int dpu_encoder_wait_for_commit_done(struct drm_encoder *drm_encoder); int dpu_encoder_wait_for_tx_complete(struct drm_encoder *drm_encoder); -/* - * dpu_encoder_get_intf_mode - get interface mode of the given encoder - * @encoder: Pointer to drm encoder object - */ enum dpu_intf_mode dpu_encoder_get_intf_mode(struct drm_encoder *encoder); -/** - * dpu_encoder_virt_runtime_resume - pm runtime resume the encoder configs - * @encoder: encoder pointer - */ void dpu_encoder_virt_runtime_resume(struct drm_encoder *encoder); -/** - * dpu_encoder_init - initialize virtual encoder object - * @dev: Pointer to drm device structure - * @drm_enc_mode: corresponding DRM_MODE_ENCODER_* constant - * @disp_info: Pointer to display information structure - * Returns: Pointer to newly created drm encoder - */ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, int drm_enc_mode, struct msm_display_info *disp_info); -/** - * dpu_encoder_set_idle_timeout - set the idle timeout for video - * and command mode encoders. - * @drm_enc: Pointer to previously created drm encoder structure - * @idle_timeout: idle timeout duration in milliseconds - */ -void dpu_encoder_set_idle_timeout(struct drm_encoder *drm_enc, - u32 idle_timeout); -/** - * dpu_encoder_get_linecount - get interface line count for the encoder. - * @drm_enc: Pointer to previously created drm encoder structure - */ int dpu_encoder_get_linecount(struct drm_encoder *drm_enc); -/** - * dpu_encoder_get_vsync_count - get vsync count for the encoder. - * @drm_enc: Pointer to previously created drm encoder structure - */ int dpu_encoder_get_vsync_count(struct drm_encoder *drm_enc); -/** - * dpu_encoder_is_widebus_enabled - return bool value if widebus is enabled - * @drm_enc: Pointer to previously created drm encoder structure - */ bool dpu_encoder_is_widebus_enabled(const struct drm_encoder *drm_enc); -/** - * dpu_encoder_is_dsc_enabled - indicate whether dsc is enabled - * for the encoder. - * @drm_enc: Pointer to previously created drm encoder structure - */ bool dpu_encoder_is_dsc_enabled(const struct drm_encoder *drm_enc); -/** - * dpu_encoder_get_crc_values_cnt - get number of physical encoders contained - * in virtual encoder that can collect CRC values - * @drm_enc: Pointer to previously created drm encoder structure - * Returns: Number of physical encoders for given drm encoder - */ int dpu_encoder_get_crc_values_cnt(const struct drm_encoder *drm_enc); -/** - * dpu_encoder_setup_misr - enable misr calculations - * @drm_enc: Pointer to previously created drm encoder structure - */ void dpu_encoder_setup_misr(const struct drm_encoder *drm_encoder); -/** - * dpu_encoder_get_crc - get the crc value from interface blocks - * @drm_enc: Pointer to previously created drm encoder structure - * Returns: 0 on success, error otherwise - */ int dpu_encoder_get_crc(const struct drm_encoder *drm_enc, u32 *crcs, int pos); -/** - * dpu_encoder_use_dsc_merge - returns true if the encoder uses DSC merge topology. - * @drm_enc: Pointer to previously created drm encoder structure - */ bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc); -/** - * dpu_encoder_prepare_wb_job - prepare writeback job for the encoder. - * @drm_enc: Pointer to previously created drm encoder structure - * @job: Pointer to the current drm writeback job - */ void dpu_encoder_prepare_wb_job(struct drm_encoder *drm_enc, struct drm_writeback_job *job); -/** - * dpu_encoder_cleanup_wb_job - cleanup writeback job for the encoder. - * @drm_enc: Pointer to previously created drm encoder structure - * @job: Pointer to the current drm writeback job - */ void dpu_encoder_cleanup_wb_job(struct drm_encoder *drm_enc, struct drm_writeback_job *job); -/** - * dpu_encoder_is_valid_for_commit - check if encode has valid parameters for commit. - * @drm_enc: Pointer to drm encoder structure - */ bool dpu_encoder_is_valid_for_commit(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 e77ebe3a68da..63f09857025c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -279,37 +279,15 @@ struct dpu_encoder_wait_info { s64 timeout_ms; }; -/** - * dpu_encoder_phys_vid_init - Construct a new video mode physical encoder - * @p: Pointer to init params structure - * Return: Error code or newly allocated encoder - */ struct dpu_encoder_phys *dpu_encoder_phys_vid_init(struct drm_device *dev, struct dpu_enc_phys_init_params *p); -/** - * dpu_encoder_phys_cmd_init - Construct a new command mode physical encoder - * @dev: Corresponding device for devres management - * @p: Pointer to init params structure - * Return: Error code or newly allocated encoder - */ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(struct drm_device *dev, struct dpu_enc_phys_init_params *p); -/** - * dpu_encoder_phys_wb_init - initialize writeback encoder - * @dev: Corresponding device for devres management - * @init: Pointer to init info structure with initialization params - */ struct dpu_encoder_phys *dpu_encoder_phys_wb_init(struct drm_device *dev, struct dpu_enc_phys_init_params *p); -/** - * dpu_encoder_helper_trigger_start - control start helper function - * This helper function may be optionally specified by physical - * encoders if they require ctl_start triggering. - * @phys_enc: Pointer to physical encoder structure - */ void dpu_encoder_helper_trigger_start(struct dpu_encoder_phys *phys_enc); static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode( @@ -331,106 +309,38 @@ static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode( return BLEND_3D_NONE; } -/** - * 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. - * @phys_enc: Pointer to physical encoder structure - */ unsigned int dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc); -/** - * dpu_encoder_get_dsc_config - get DSC config for the DPU encoder - * This helper function is used by physical encoder to get DSC config - * used for this encoder. - * @drm_enc: Pointer to encoder structure - */ struct drm_dsc_config *dpu_encoder_get_dsc_config(struct drm_encoder *drm_enc); -/** - * dpu_encoder_get_drm_fmt - return DRM fourcc format - * @phys_enc: Pointer to physical encoder structure - */ u32 dpu_encoder_get_drm_fmt(struct dpu_encoder_phys *phys_enc); -/** - * dpu_encoder_needs_periph_flush - return true if physical encoder requires - * peripheral flush - * @phys_enc: Pointer to physical encoder structure - */ bool dpu_encoder_needs_periph_flush(struct dpu_encoder_phys *phys_enc); -/** - * dpu_encoder_helper_split_config - split display configuration helper function - * This helper function may be used by physical encoders to configure - * the split display related registers. - * @phys_enc: Pointer to physical encoder structure - * @interface: enum dpu_intf setting - */ void dpu_encoder_helper_split_config( struct dpu_encoder_phys *phys_enc, enum dpu_intf interface); -/** - * dpu_encoder_helper_report_irq_timeout - utility to report error that irq has - * timed out, including reporting frame error event to crtc and debug dump - * @phys_enc: Pointer to physical encoder structure - * @intr_idx: Failing interrupt index - */ void dpu_encoder_helper_report_irq_timeout(struct dpu_encoder_phys *phys_enc, enum dpu_intr_idx intr_idx); -/** - * dpu_encoder_helper_wait_for_irq - utility to wait on an irq. - * note: will call dpu_encoder_helper_wait_for_irq on timeout - * @phys_enc: Pointer to physical encoder structure - * @irq: IRQ index - * @func: IRQ callback to be called in case of timeout - * @wait_info: wait info struct - * @Return: 0 or -ERROR - */ int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc, unsigned int irq, void (*func)(void *arg), struct dpu_encoder_wait_info *wait_info); -/** - * dpu_encoder_helper_phys_cleanup - helper to cleanup dpu pipeline - * @phys_enc: Pointer to physical encoder structure - */ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc); -/** - * dpu_encoder_helper_phys_setup_cdm - setup chroma down sampling block - * @phys_enc: Pointer to physical encoder - * @output_type: HDMI/WB - */ void dpu_encoder_helper_phys_setup_cdm(struct dpu_encoder_phys *phys_enc, const struct msm_format *dpu_fmt, u32 output_type); -/** - * dpu_encoder_vblank_callback - Notify virtual encoder of vblank IRQ reception - * @drm_enc: Pointer to drm encoder structure - * @phys_enc: Pointer to physical encoder - * Note: This is called from IRQ handler context. - */ void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc, struct dpu_encoder_phys *phy_enc); -/** dpu_encoder_underrun_callback - Notify virtual encoder of underrun IRQ reception - * @drm_enc: Pointer to drm encoder structure - * @phys_enc: Pointer to physical encoder - * Note: This is called from IRQ handler context. - */ void dpu_encoder_underrun_callback(struct drm_encoder *drm_enc, struct dpu_encoder_phys *phy_enc); -/** dpu_encoder_frame_done_callback -- Notify virtual encoder that this phys encoder completes last request frame - * @drm_enc: Pointer to drm encoder structure - * @phys_enc: Pointer to physical encoder - * @event: Event to process - */ void dpu_encoder_frame_done_callback( struct drm_encoder *drm_enc, struct dpu_encoder_phys *ready_phys, u32 event); 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 6fc31d47cd1d..e9bbccc44dad 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 @@ -720,6 +720,12 @@ static void dpu_encoder_phys_cmd_init_ops( ops->get_line_count = dpu_encoder_phys_cmd_get_line_count; } +/** + * dpu_encoder_phys_cmd_init - Construct a new command mode physical encoder + * @dev: Corresponding device for devres management + * @p: Pointer to init params structure + * Return: Error code or newly allocated encoder + */ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(struct drm_device *dev, struct dpu_enc_phys_init_params *p) { 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 d8a2edebfe8c..abd6600046cb 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 @@ -746,6 +746,12 @@ static void dpu_encoder_phys_vid_init_ops(struct dpu_encoder_phys_ops *ops) ops->get_frame_count = dpu_encoder_phys_vid_get_frame_count; } +/** + * dpu_encoder_phys_vid_init - Construct a new video mode physical encoder + * @dev: Corresponding device for devres management + * @p: Pointer to init params structure + * Return: Error code or newly allocated encoder + */ struct dpu_encoder_phys *dpu_encoder_phys_vid_init(struct drm_device *dev, struct dpu_enc_phys_init_params *p) { 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 07035ab77b79..4c006ec74575 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 @@ -166,10 +166,10 @@ static void dpu_encoder_phys_wb_set_qos(struct dpu_encoder_phys *phys_enc) /** * dpu_encoder_phys_wb_setup_fb - setup output framebuffer * @phys_enc: Pointer to physical encoder - * @fb: Pointer to output framebuffer + * @format: Format of the framebuffer */ static void dpu_encoder_phys_wb_setup_fb(struct dpu_encoder_phys *phys_enc, - struct drm_framebuffer *fb) + const struct msm_format *format) { struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc); struct dpu_hw_wb *hw_wb; @@ -193,12 +193,12 @@ static void dpu_encoder_phys_wb_setup_fb(struct dpu_encoder_phys *phys_enc, hw_wb->ops.setup_roi(hw_wb, wb_cfg); if (hw_wb->ops.setup_outformat) - hw_wb->ops.setup_outformat(hw_wb, wb_cfg); + hw_wb->ops.setup_outformat(hw_wb, wb_cfg, format); if (hw_wb->ops.setup_cdp) { const struct dpu_perf_cfg *perf = phys_enc->dpu_kms->catalog->perf; - hw_wb->ops.setup_cdp(hw_wb, wb_cfg->dest.format, + hw_wb->ops.setup_cdp(hw_wb, format, perf->cdp_cfg[DPU_PERF_CDP_USAGE_NRT].wr_enable); } @@ -321,15 +321,10 @@ static void dpu_encoder_phys_wb_setup( { struct dpu_hw_wb *hw_wb = phys_enc->hw_wb; struct drm_display_mode mode = phys_enc->cached_mode; - struct drm_framebuffer *fb = NULL; struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc); - struct drm_writeback_job *wb_job; const struct msm_format *format; - const struct msm_format *dpu_fmt; - wb_job = wb_enc->wb_job; format = msm_framebuffer_format(wb_enc->wb_job->fb); - dpu_fmt = mdp_get_format(&phys_enc->dpu_kms->base, format->pixel_format, wb_job->fb->modifier); DPU_DEBUG("[mode_set:%d, \"%s\",%d,%d]\n", hw_wb->idx - WB_0, mode.name, @@ -341,9 +336,9 @@ static void dpu_encoder_phys_wb_setup( dpu_encoder_phys_wb_set_qos(phys_enc); - dpu_encoder_phys_wb_setup_fb(phys_enc, fb); + dpu_encoder_phys_wb_setup_fb(phys_enc, format); - dpu_encoder_helper_phys_setup_cdm(phys_enc, dpu_fmt, CDM_CDWN_OUTPUT_WB); + dpu_encoder_helper_phys_setup_cdm(phys_enc, format, CDM_CDWN_OUTPUT_WB); dpu_encoder_phys_wb_setup_ctl(phys_enc); } @@ -587,26 +582,20 @@ static void dpu_encoder_phys_wb_prepare_wb_job(struct dpu_encoder_phys *phys_enc format = msm_framebuffer_format(job->fb); - wb_cfg->dest.format = mdp_get_format(&phys_enc->dpu_kms->base, - format->pixel_format, job->fb->modifier); - if (!wb_cfg->dest.format) { - /* this error should be detected during atomic_check */ - DPU_ERROR("failed to get format %p4cc\n", &format->pixel_format); - return; - } - - ret = dpu_format_populate_layout(aspace, job->fb, &wb_cfg->dest); + ret = dpu_format_populate_plane_sizes(job->fb, &wb_cfg->dest); if (ret) { - DPU_DEBUG("failed to populate layout %d\n", ret); + DPU_DEBUG("failed to populate plane sizes%d\n", ret); return; } + dpu_format_populate_addrs(aspace, job->fb, &wb_cfg->dest); + wb_cfg->dest.width = job->fb->width; wb_cfg->dest.height = job->fb->height; - wb_cfg->dest.num_planes = wb_cfg->dest.format->num_planes; + wb_cfg->dest.num_planes = format->num_planes; - if ((wb_cfg->dest.format->fetch_type == MDP_PLANE_PLANAR) && - (wb_cfg->dest.format->element[0] == C1_B_Cb)) + if ((format->fetch_type == MDP_PLANE_PLANAR) && + (format->element[0] == C1_B_Cb)) swap(wb_cfg->dest.plane_addr[1], wb_cfg->dest.plane_addr[2]); DPU_DEBUG("[fb_offset:%8.8x,%8.8x,%8.8x,%8.8x]\n", diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c index 6b1e9a617da3..59c9427da7dd 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c @@ -13,9 +13,6 @@ #define DPU_UBWC_PLANE_SIZE_ALIGNMENT 4096 -#define DPU_MAX_IMG_WIDTH 0x3FFF -#define DPU_MAX_IMG_HEIGHT 0x3FFF - /* * struct dpu_media_color_map - maps drm format to media format * @format: DRM base pixel format @@ -93,10 +90,9 @@ static int _dpu_format_get_media_color_ubwc(const struct msm_format *fmt) return color_fmt; } -static int _dpu_format_get_plane_sizes_ubwc( +static int _dpu_format_populate_plane_sizes_ubwc( const struct msm_format *fmt, - const uint32_t width, - const uint32_t height, + struct drm_framebuffer *fb, struct dpu_hw_fmt_layout *layout) { int i; @@ -104,9 +100,8 @@ static int _dpu_format_get_plane_sizes_ubwc( bool meta = MSM_FORMAT_IS_UBWC(fmt); memset(layout, 0, sizeof(struct dpu_hw_fmt_layout)); - layout->format = fmt; - layout->width = width; - layout->height = height; + layout->width = fb->width; + layout->height = fb->height; layout->num_planes = fmt->num_planes; color = _dpu_format_get_media_color_ubwc(fmt); @@ -116,19 +111,19 @@ static int _dpu_format_get_plane_sizes_ubwc( return -EINVAL; } - if (MSM_FORMAT_IS_YUV(layout->format)) { + if (MSM_FORMAT_IS_YUV(fmt)) { uint32_t y_sclines, uv_sclines; uint32_t y_meta_scanlines = 0; uint32_t uv_meta_scanlines = 0; layout->num_planes = 2; - layout->plane_pitch[0] = VENUS_Y_STRIDE(color, width); - y_sclines = VENUS_Y_SCANLINES(color, height); + layout->plane_pitch[0] = VENUS_Y_STRIDE(color, fb->width); + y_sclines = VENUS_Y_SCANLINES(color, fb->height); layout->plane_size[0] = MSM_MEDIA_ALIGN(layout->plane_pitch[0] * y_sclines, DPU_UBWC_PLANE_SIZE_ALIGNMENT); - layout->plane_pitch[1] = VENUS_UV_STRIDE(color, width); - uv_sclines = VENUS_UV_SCANLINES(color, height); + layout->plane_pitch[1] = VENUS_UV_STRIDE(color, fb->width); + uv_sclines = VENUS_UV_SCANLINES(color, fb->height); layout->plane_size[1] = MSM_MEDIA_ALIGN(layout->plane_pitch[1] * uv_sclines, DPU_UBWC_PLANE_SIZE_ALIGNMENT); @@ -136,13 +131,13 @@ static int _dpu_format_get_plane_sizes_ubwc( goto done; layout->num_planes += 2; - layout->plane_pitch[2] = VENUS_Y_META_STRIDE(color, width); - y_meta_scanlines = VENUS_Y_META_SCANLINES(color, height); + layout->plane_pitch[2] = VENUS_Y_META_STRIDE(color, fb->width); + y_meta_scanlines = VENUS_Y_META_SCANLINES(color, fb->height); layout->plane_size[2] = MSM_MEDIA_ALIGN(layout->plane_pitch[2] * y_meta_scanlines, DPU_UBWC_PLANE_SIZE_ALIGNMENT); - layout->plane_pitch[3] = VENUS_UV_META_STRIDE(color, width); - uv_meta_scanlines = VENUS_UV_META_SCANLINES(color, height); + layout->plane_pitch[3] = VENUS_UV_META_STRIDE(color, fb->width); + uv_meta_scanlines = VENUS_UV_META_SCANLINES(color, fb->height); layout->plane_size[3] = MSM_MEDIA_ALIGN(layout->plane_pitch[3] * uv_meta_scanlines, DPU_UBWC_PLANE_SIZE_ALIGNMENT); @@ -151,16 +146,16 @@ static int _dpu_format_get_plane_sizes_ubwc( layout->num_planes = 1; - layout->plane_pitch[0] = VENUS_RGB_STRIDE(color, width); - rgb_scanlines = VENUS_RGB_SCANLINES(color, height); + layout->plane_pitch[0] = VENUS_RGB_STRIDE(color, fb->width); + rgb_scanlines = VENUS_RGB_SCANLINES(color, fb->height); layout->plane_size[0] = MSM_MEDIA_ALIGN(layout->plane_pitch[0] * rgb_scanlines, DPU_UBWC_PLANE_SIZE_ALIGNMENT); if (!meta) goto done; layout->num_planes += 2; - layout->plane_pitch[2] = VENUS_RGB_META_STRIDE(color, width); - rgb_meta_scanlines = VENUS_RGB_META_SCANLINES(color, height); + layout->plane_pitch[2] = VENUS_RGB_META_STRIDE(color, fb->width); + rgb_meta_scanlines = VENUS_RGB_META_SCANLINES(color, fb->height); layout->plane_size[2] = MSM_MEDIA_ALIGN(layout->plane_pitch[2] * rgb_meta_scanlines, DPU_UBWC_PLANE_SIZE_ALIGNMENT); } @@ -172,26 +167,23 @@ done: return 0; } -static int _dpu_format_get_plane_sizes_linear( +static int _dpu_format_populate_plane_sizes_linear( const struct msm_format *fmt, - const uint32_t width, - const uint32_t height, - struct dpu_hw_fmt_layout *layout, - const uint32_t *pitches) + struct drm_framebuffer *fb, + struct dpu_hw_fmt_layout *layout) { int i; memset(layout, 0, sizeof(struct dpu_hw_fmt_layout)); - layout->format = fmt; - layout->width = width; - layout->height = height; + layout->width = fb->width; + layout->height = fb->height; layout->num_planes = fmt->num_planes; /* Due to memset above, only need to set planes of interest */ if (fmt->fetch_type == MDP_PLANE_INTERLEAVED) { layout->num_planes = 1; - layout->plane_size[0] = width * height * layout->format->bpp; - layout->plane_pitch[0] = width * layout->format->bpp; + layout->plane_size[0] = fb->width * fb->height * fmt->bpp; + layout->plane_pitch[0] = fb->width * fmt->bpp; } else { uint32_t v_subsample, h_subsample; uint32_t chroma_samp; @@ -201,7 +193,7 @@ static int _dpu_format_get_plane_sizes_linear( _dpu_get_v_h_subsample_rate(chroma_samp, &v_subsample, &h_subsample); - if (width % h_subsample || height % v_subsample) { + if (fb->width % h_subsample || fb->height % v_subsample) { DRM_ERROR("mismatch in subsample vs dimensions\n"); return -EINVAL; } @@ -209,11 +201,11 @@ static int _dpu_format_get_plane_sizes_linear( if ((fmt->pixel_format == DRM_FORMAT_NV12) && (MSM_FORMAT_IS_DX(fmt))) bpp = 2; - layout->plane_pitch[0] = width * bpp; + layout->plane_pitch[0] = fb->width * bpp; layout->plane_pitch[1] = layout->plane_pitch[0] / h_subsample; - layout->plane_size[0] = layout->plane_pitch[0] * height; + layout->plane_size[0] = layout->plane_pitch[0] * fb->height; layout->plane_size[1] = layout->plane_pitch[1] * - (height / v_subsample); + (fb->height / v_subsample); if (fmt->fetch_type == MDP_PLANE_PSEUDO_PLANAR) { layout->num_planes = 2; @@ -234,8 +226,13 @@ static int _dpu_format_get_plane_sizes_linear( * all the components based on ubwc specifications. */ for (i = 0; i < layout->num_planes && i < DPU_MAX_PLANES; ++i) { - if (pitches && layout->plane_pitch[i] < pitches[i]) - layout->plane_pitch[i] = pitches[i]; + if (layout->plane_pitch[i] <= fb->pitches[i]) { + layout->plane_pitch[i] = fb->pitches[i]; + } else { + DRM_DEBUG("plane %u expected pitch %u, fb %u\n", + i, layout->plane_pitch[i], fb->pitches[i]); + return -EINVAL; + } } for (i = 0; i < DPU_MAX_PLANES; i++) @@ -244,53 +241,54 @@ static int _dpu_format_get_plane_sizes_linear( return 0; } -static int dpu_format_get_plane_sizes( - const struct msm_format *fmt, - const uint32_t w, - const uint32_t h, - struct dpu_hw_fmt_layout *layout, - const uint32_t *pitches) +/** + * dpu_format_populate_plane_sizes - populate non-address part of the layout based on + * fb, and format found in the fb + * @fb: framebuffer pointer + * @layout: format layout structure to populate + * + * Return: error code on failure or 0 if new addresses were populated + */ +int dpu_format_populate_plane_sizes( + struct drm_framebuffer *fb, + struct dpu_hw_fmt_layout *layout) { - if (!layout || !fmt) { + const struct msm_format *fmt; + + if (!layout || !fb) { DRM_ERROR("invalid pointer\n"); return -EINVAL; } - if ((w > DPU_MAX_IMG_WIDTH) || (h > DPU_MAX_IMG_HEIGHT)) { + if (fb->width > DPU_MAX_IMG_WIDTH || + fb->height > DPU_MAX_IMG_HEIGHT) { DRM_ERROR("image dimensions outside max range\n"); return -ERANGE; } + fmt = msm_framebuffer_format(fb); + if (MSM_FORMAT_IS_UBWC(fmt) || MSM_FORMAT_IS_TILE(fmt)) - return _dpu_format_get_plane_sizes_ubwc(fmt, w, h, layout); + return _dpu_format_populate_plane_sizes_ubwc(fmt, fb, layout); - return _dpu_format_get_plane_sizes_linear(fmt, w, h, layout, pitches); + return _dpu_format_populate_plane_sizes_linear(fmt, fb, layout); } -static int _dpu_format_populate_addrs_ubwc( - struct msm_gem_address_space *aspace, - struct drm_framebuffer *fb, - struct dpu_hw_fmt_layout *layout) +static void _dpu_format_populate_addrs_ubwc(struct msm_gem_address_space *aspace, + struct drm_framebuffer *fb, + struct dpu_hw_fmt_layout *layout) { + const struct msm_format *fmt; uint32_t base_addr = 0; bool meta; - if (!fb || !layout) { - DRM_ERROR("invalid pointers\n"); - return -EINVAL; - } - - if (aspace) - base_addr = msm_framebuffer_iova(fb, aspace, 0); - if (!base_addr) { - DRM_ERROR("failed to retrieve base addr\n"); - return -EFAULT; - } + base_addr = msm_framebuffer_iova(fb, aspace, 0); - meta = MSM_FORMAT_IS_UBWC(layout->format); + fmt = msm_framebuffer_format(fb); + meta = MSM_FORMAT_IS_UBWC(fmt); /* Per-format logic for verifying active planes */ - if (MSM_FORMAT_IS_YUV(layout->format)) { + if (MSM_FORMAT_IS_YUV(fmt)) { /************************************************/ /* UBWC ** */ /* buffer ** DPU PLANE */ @@ -319,7 +317,7 @@ static int _dpu_format_populate_addrs_ubwc( + layout->plane_size[2] + layout->plane_size[3]; if (!meta) - return 0; + return; /* configure Y metadata plane */ layout->plane_addr[2] = base_addr; @@ -350,119 +348,43 @@ static int _dpu_format_populate_addrs_ubwc( layout->plane_addr[1] = 0; if (!meta) - return 0; + return; layout->plane_addr[2] = base_addr; layout->plane_addr[3] = 0; } - return 0; } -static int _dpu_format_populate_addrs_linear( - struct msm_gem_address_space *aspace, - struct drm_framebuffer *fb, - struct dpu_hw_fmt_layout *layout) +static void _dpu_format_populate_addrs_linear(struct msm_gem_address_space *aspace, + struct drm_framebuffer *fb, + struct dpu_hw_fmt_layout *layout) { unsigned int i; - /* Can now check the pitches given vs pitches expected */ - for (i = 0; i < layout->num_planes; ++i) { - if (layout->plane_pitch[i] > fb->pitches[i]) { - DRM_ERROR("plane %u expected pitch %u, fb %u\n", - i, layout->plane_pitch[i], fb->pitches[i]); - return -EINVAL; - } - } - /* Populate addresses for simple formats here */ - for (i = 0; i < layout->num_planes; ++i) { - if (aspace) - layout->plane_addr[i] = - msm_framebuffer_iova(fb, aspace, i); - if (!layout->plane_addr[i]) { - DRM_ERROR("failed to retrieve base addr\n"); - return -EFAULT; - } - } - - return 0; + for (i = 0; i < layout->num_planes; ++i) + layout->plane_addr[i] = msm_framebuffer_iova(fb, aspace, i); } -int dpu_format_populate_layout( - struct msm_gem_address_space *aspace, - struct drm_framebuffer *fb, - struct dpu_hw_fmt_layout *layout) +/** + * dpu_format_populate_addrs - populate buffer addresses based on + * mmu, fb, and format found in the fb + * @aspace: address space pointer + * @fb: framebuffer pointer + * @layout: format layout structure to populate + */ +void dpu_format_populate_addrs(struct msm_gem_address_space *aspace, + struct drm_framebuffer *fb, + struct dpu_hw_fmt_layout *layout) { - int ret; - - if (!fb || !layout) { - DRM_ERROR("invalid arguments\n"); - return -EINVAL; - } + const struct msm_format *fmt; - if ((fb->width > DPU_MAX_IMG_WIDTH) || - (fb->height > DPU_MAX_IMG_HEIGHT)) { - DRM_ERROR("image dimensions outside max range\n"); - return -ERANGE; - } - - layout->format = msm_framebuffer_format(fb); - - /* Populate the plane sizes etc via get_format */ - ret = dpu_format_get_plane_sizes(layout->format, fb->width, fb->height, - layout, fb->pitches); - if (ret) - return ret; + fmt = msm_framebuffer_format(fb); /* Populate the addresses given the fb */ - if (MSM_FORMAT_IS_UBWC(layout->format) || - MSM_FORMAT_IS_TILE(layout->format)) - ret = _dpu_format_populate_addrs_ubwc(aspace, fb, layout); + if (MSM_FORMAT_IS_UBWC(fmt) || + MSM_FORMAT_IS_TILE(fmt)) + _dpu_format_populate_addrs_ubwc(aspace, fb, layout); else - ret = _dpu_format_populate_addrs_linear(aspace, fb, layout); - - return ret; -} - -int dpu_format_check_modified_format( - const struct msm_kms *kms, - const struct msm_format *fmt, - const struct drm_mode_fb_cmd2 *cmd, - struct drm_gem_object **bos) -{ - const struct drm_format_info *info; - struct dpu_hw_fmt_layout layout; - uint32_t bos_total_size = 0; - int ret, i; - - if (!fmt || !cmd || !bos) { - DRM_ERROR("invalid arguments\n"); - return -EINVAL; - } - - info = drm_format_info(fmt->pixel_format); - if (!info) - return -EINVAL; - - ret = dpu_format_get_plane_sizes(fmt, cmd->width, cmd->height, - &layout, cmd->pitches); - if (ret) - return ret; - - for (i = 0; i < info->num_planes; i++) { - if (!bos[i]) { - DRM_ERROR("invalid handle for plane %d\n", i); - return -EINVAL; - } - if ((i == 0) || (bos[i] != bos[0])) - bos_total_size += bos[i]->size; - } - - if (bos_total_size < layout.total_size) { - DRM_ERROR("buffers total size too small %u expected %u\n", - bos_total_size, layout.total_size); - return -EINVAL; - } - - return 0; + _dpu_format_populate_addrs_linear(aspace, fb, layout); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.h index 210d0ed5f0af..c6145d43aa3f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.h @@ -31,35 +31,12 @@ static inline bool dpu_find_format(u32 format, const u32 *supported_formats, return false; } -/** - * dpu_format_check_modified_format - validate format and buffers for - * dpu non-standard, i.e. modified format - * @kms: kms driver - * @msm_fmt: pointer to the msm_fmt base pointer of an msm_format - * @cmd: fb_cmd2 structure user request - * @bos: gem buffer object list - * - * Return: error code on failure, 0 on success - */ -int dpu_format_check_modified_format( - const struct msm_kms *kms, - const struct msm_format *msm_fmt, - const struct drm_mode_fb_cmd2 *cmd, - struct drm_gem_object **bos); +void dpu_format_populate_addrs(struct msm_gem_address_space *aspace, + struct drm_framebuffer *fb, + struct dpu_hw_fmt_layout *layout); -/** - * dpu_format_populate_layout - populate the given format layout based on - * mmu, fb, and format found in the fb - * @aspace: address space pointer - * @fb: framebuffer pointer - * @fmtl: format layout structure to populate - * - * Return: error code on failure, -EAGAIN if success but the addresses - * are the same as before or 0 if new addresses were populated - */ -int dpu_format_populate_layout( - struct msm_gem_address_space *aspace, +int dpu_format_populate_plane_sizes( struct drm_framebuffer *fb, - struct dpu_hw_fmt_layout *fmtl); + struct dpu_hw_fmt_layout *layout); #endif /*_DPU_FORMATS_H */ 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 dcb4fd85e73b..2cbf41f33cc0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -21,6 +21,16 @@ (VIG_BASE_MASK | \ BIT(DPU_SSPP_CSC_10BIT)) +#define VIG_MSM8953_MASK \ + (BIT(DPU_SSPP_QOS) |\ + BIT(DPU_SSPP_SCALER_QSEED2) |\ + BIT(DPU_SSPP_CSC)) + +#define VIG_MSM8996_MASK \ + (BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_CDP) |\ + BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_SCALER_QSEED2) |\ + BIT(DPU_SSPP_CSC)) + #define VIG_MSM8998_MASK \ (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3_COMPATIBLE)) @@ -32,6 +42,12 @@ #define VIG_QCM2290_MASK (VIG_BASE_MASK | BIT(DPU_SSPP_QOS_8LVL)) +#define DMA_MSM8953_MASK \ + (BIT(DPU_SSPP_QOS)) + +#define DMA_MSM8996_MASK \ + (BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_CDP)) + #define DMA_MSM8998_MASK \ (BIT(DPU_SSPP_QOS) |\ BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\ @@ -57,9 +73,19 @@ #define DMA_CURSOR_SDM845_MASK_SDMA \ (DMA_CURSOR_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2)) +#define DMA_CURSOR_MSM8996_MASK \ + (DMA_MSM8996_MASK | BIT(DPU_SSPP_CURSOR)) + #define DMA_CURSOR_MSM8998_MASK \ (DMA_MSM8998_MASK | BIT(DPU_SSPP_CURSOR)) +#define RGB_MSM8953_MASK \ + (BIT(DPU_SSPP_QOS)) + +#define RGB_MSM8996_MASK \ + (BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_CDP) |\ + BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_SCALER_RGB)) + #define MIXER_MSM8998_MASK \ (BIT(DPU_MIXER_SOURCESPLIT)) @@ -69,6 +95,12 @@ #define MIXER_QCM2290_MASK \ (BIT(DPU_DIM_LAYER) | BIT(DPU_MIXER_COMBINED_ALPHA)) +#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)) @@ -115,10 +147,6 @@ #define MAX_HORZ_DECIMATION 4 #define MAX_VERT_DECIMATION 4 -#define MAX_UPSCALE_RATIO 20 -#define MAX_DOWNSCALE_RATIO 4 -#define SSPP_UNITY_SCALE 1 - #define STRCAT(X, Y) (X Y) static const uint32_t plane_formats[] = { @@ -276,8 +304,6 @@ static const u32 wb2_formats_rgb_yuv[] = { /* SSPP common configuration */ #define _VIG_SBLK(scaler_ver) \ { \ - .maxdwnscale = MAX_DOWNSCALE_RATIO, \ - .maxupscale = MAX_UPSCALE_RATIO, \ .scaler_blk = {.name = "scaler", \ .version = scaler_ver, \ .base = 0xa00, .len = 0xa0,}, \ @@ -285,15 +311,11 @@ static const u32 wb2_formats_rgb_yuv[] = { .base = 0x1a00, .len = 0x100,}, \ .format_list = plane_formats_yuv, \ .num_formats = ARRAY_SIZE(plane_formats_yuv), \ - .virt_format_list = plane_formats, \ - .virt_num_formats = ARRAY_SIZE(plane_formats), \ .rotation_cfg = NULL, \ } #define _VIG_SBLK_ROT(scaler_ver, rot_cfg) \ { \ - .maxdwnscale = MAX_DOWNSCALE_RATIO, \ - .maxupscale = MAX_UPSCALE_RATIO, \ .scaler_blk = {.name = "scaler", \ .version = scaler_ver, \ .base = 0xa00, .len = 0xa0,}, \ @@ -301,29 +323,40 @@ static const u32 wb2_formats_rgb_yuv[] = { .base = 0x1a00, .len = 0x100,}, \ .format_list = plane_formats_yuv, \ .num_formats = ARRAY_SIZE(plane_formats_yuv), \ - .virt_format_list = plane_formats, \ - .virt_num_formats = ARRAY_SIZE(plane_formats), \ .rotation_cfg = rot_cfg, \ } #define _VIG_SBLK_NOSCALE() \ { \ - .maxdwnscale = SSPP_UNITY_SCALE, \ - .maxupscale = SSPP_UNITY_SCALE, \ .format_list = plane_formats, \ .num_formats = ARRAY_SIZE(plane_formats), \ - .virt_format_list = plane_formats, \ - .virt_num_formats = ARRAY_SIZE(plane_formats), \ + } + +/* qseed2 is not supported, so disabled scaling */ +#define _VIG_SBLK_QSEED2() \ + { \ + .scaler_blk = {.name = "scaler", \ + /* no version for qseed2 */ \ + .base = 0x200, .len = 0xa0,}, \ + .csc_blk = {.name = "csc", \ + .base = 0x320, .len = 0x100,}, \ + .format_list = plane_formats_yuv, \ + .num_formats = ARRAY_SIZE(plane_formats_yuv), \ + .rotation_cfg = NULL, \ + } + +#define _RGB_SBLK() \ + { \ + .scaler_blk = {.name = "scaler", \ + .base = 0x200, .len = 0x28,}, \ + .format_list = plane_formats, \ + .num_formats = ARRAY_SIZE(plane_formats), \ } #define _DMA_SBLK() \ { \ - .maxdwnscale = SSPP_UNITY_SCALE, \ - .maxupscale = SSPP_UNITY_SCALE, \ .format_list = plane_formats, \ .num_formats = ARRAY_SIZE(plane_formats), \ - .virt_format_list = plane_formats, \ - .virt_num_formats = ARRAY_SIZE(plane_formats), \ } static const struct dpu_rotation_cfg dpu_rot_sc7280_cfg_v2 = { @@ -332,6 +365,9 @@ static const struct dpu_rotation_cfg dpu_rot_sc7280_cfg_v2 = { .rot_format_list = rotation_v2_formats, }; +static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed2 = + _VIG_SBLK_QSEED2(); + static const struct dpu_sspp_sub_blks dpu_vig_sblk_noscale = _VIG_SBLK_NOSCALE(); @@ -363,6 +399,8 @@ static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_2 = static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_3 = _VIG_SBLK(SSPP_SCALER_VER(3, 3)); +static const struct dpu_sspp_sub_blks dpu_rgb_sblk = _RGB_SBLK(); + static const struct dpu_sspp_sub_blks dpu_dma_sblk = _DMA_SBLK(); /************************************************************* @@ -427,6 +465,15 @@ 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}, @@ -492,6 +539,34 @@ static const struct dpu_vbif_dynamic_ot_cfg msm8998_ot_rdwr_cfg[] = { }, }; +static const struct dpu_vbif_cfg msm8996_vbif[] = { + { + .name = "vbif_rt", .id = VBIF_RT, + .base = 0, .len = 0x1040, + .default_ot_rd_limit = 32, + .default_ot_wr_limit = 16, + .features = BIT(DPU_VBIF_QOS_REMAP) | BIT(DPU_VBIF_QOS_OTLIM), + .xin_halt_timeout = 0x4000, + .qos_rp_remap_size = 0x20, + .dynamic_ot_rd_tbl = { + .count = ARRAY_SIZE(msm8998_ot_rdwr_cfg), + .cfg = msm8998_ot_rdwr_cfg, + }, + .dynamic_ot_wr_tbl = { + .count = ARRAY_SIZE(msm8998_ot_rdwr_cfg), + .cfg = msm8998_ot_rdwr_cfg, + }, + .qos_rt_tbl = { + .npriority_lvl = ARRAY_SIZE(msm8998_rt_pri_lvl), + .priority_lvl = msm8998_rt_pri_lvl, + }, + .qos_nrt_tbl = { + .npriority_lvl = ARRAY_SIZE(msm8998_nrt_pri_lvl), + .priority_lvl = msm8998_nrt_pri_lvl, + }, + }, +}; + static const struct dpu_vbif_cfg msm8998_vbif[] = { { .name = "vbif_rt", .id = VBIF_RT, @@ -675,6 +750,11 @@ static const struct dpu_qos_lut_entry sc7180_qos_nrt[] = { * Hardware catalog *************************************************************/ +#include "catalog/dpu_1_7_msm8996.h" +#include "catalog/dpu_1_14_msm8937.h" +#include "catalog/dpu_1_15_msm8917.h" +#include "catalog/dpu_1_16_msm8953.h" + #include "catalog/dpu_3_0_msm8998.h" #include "catalog/dpu_3_2_sdm660.h" #include "catalog/dpu_3_3_sdm630.h" @@ -699,6 +779,7 @@ static const struct dpu_qos_lut_entry sc7180_qos_nrt[] = { #include "catalog/dpu_8_0_sc8280xp.h" #include "catalog/dpu_8_1_sm8450.h" +#include "catalog/dpu_8_4_sa8775p.h" #include "catalog/dpu_9_0_sm8550.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 37e18e820a20..c701d18c3522 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -21,8 +21,8 @@ #define DPU_HW_BLK_NAME_LEN 16 -#define MAX_IMG_WIDTH 0x3fff -#define MAX_IMG_HEIGHT 0x3fff +#define DPU_MAX_IMG_WIDTH 0x3fff +#define DPU_MAX_IMG_HEIGHT 0x3fff #define CRTC_DUAL_MIXERS 2 @@ -364,21 +364,15 @@ struct dpu_caps { /** * struct dpu_sspp_sub_blks : SSPP sub-blocks * common: Pointer to common configurations shared by sub blocks - * @maxdwnscale: max downscale ratio supported(without DECIMATION) - * @maxupscale: maxupscale ratio supported * @max_per_pipe_bw: maximum allowable bandwidth of this pipe in kBps * @qseed_ver: qseed version * @scaler_blk: * @csc_blk: * @format_list: Pointer to list of supported formats * @num_formats: Number of supported formats - * @virt_format_list: Pointer to list of supported formats for virtual planes - * @virt_num_formats: Number of supported formats for virtual planes * @dpu_rotation_cfg: inline rotation configuration */ struct dpu_sspp_sub_blks { - u32 maxdwnscale; - u32 maxupscale; u32 max_per_pipe_bw; u32 qseed_ver; struct dpu_scaler_blk scaler_blk; @@ -386,8 +380,6 @@ struct dpu_sspp_sub_blks { const u32 *format_list; u32 num_formats; - const u32 *virt_format_list; - u32 virt_num_formats; const struct dpu_rotation_cfg *rotation_cfg; }; @@ -831,6 +823,10 @@ struct dpu_mdss_cfg { const struct dpu_format_extended *vig_formats; }; +extern const struct dpu_mdss_cfg dpu_msm8917_cfg; +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_sdm630_cfg; extern const struct dpu_mdss_cfg dpu_sdm660_cfg; @@ -850,6 +846,7 @@ extern const struct dpu_mdss_cfg dpu_sm8350_cfg; extern const struct dpu_mdss_cfg dpu_sc7280_cfg; extern const struct dpu_mdss_cfg dpu_sc8280xp_cfg; extern const struct dpu_mdss_cfg dpu_sm8450_cfg; +extern const struct dpu_mdss_cfg dpu_sa8775p_cfg; extern const struct dpu_mdss_cfg dpu_sm8550_cfg; extern const struct dpu_mdss_cfg dpu_sm8650_cfg; extern const struct dpu_mdss_cfg dpu_x1e80100_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 55d2768a6d4d..ae1534c49ae0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c @@ -222,6 +222,14 @@ static void dpu_hw_cdm_bind_pingpong_blk(struct dpu_hw_cdm *ctx, const enum dpu_ DPU_REG_WRITE(c, CDM_MUX, mux_cfg); } +/** + * dpu_hw_cdm_init - initializes the cdm hw driver object. + * should be called once before accessing every cdm. + * @dev: DRM device handle + * @cfg: CDM catalog entry for which driver object is required + * @addr : mapped register io address of MDSS + * @mdss_rev: mdss hw core revision + */ struct dpu_hw_cdm *dpu_hw_cdm_init(struct drm_device *dev, const struct dpu_cdm_cfg *cfg, void __iomem *addr, const struct dpu_mdss_version *mdss_rev) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.h index ec71c9886d75..6bb3476a05f8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.h @@ -122,14 +122,6 @@ struct dpu_hw_cdm { struct dpu_hw_cdm_ops ops; }; -/** - * dpu_hw_cdm_init - initializes the cdm hw driver object. - * should be called once before accessing every cdm. - * @dev: DRM device handle - * @cdm: CDM catalog entry for which driver object is required - * @addr : mapped register io address of MDSS - * @mdss_rev: mdss hw core revision - */ struct dpu_hw_cdm *dpu_hw_cdm_init(struct drm_device *dev, const struct dpu_cdm_cfg *cdm, void __iomem *addr, const struct dpu_mdss_version *mdss_rev); 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 2e50049f2f85..4893f10d6a58 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -736,6 +736,15 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops, ops->set_active_pipes = dpu_hw_ctl_set_fetch_pipe_active; }; +/** + * dpu_hw_ctl_init() - Initializes the ctl_path hw driver object. + * Should be called before accessing any ctl_path register. + * @dev: Corresponding device for devres management + * @cfg: ctl_path catalog entry for which driver object is required + * @addr: mapped register io address of MDP + * @mixer_count: Number of mixers in @mixer + * @mixer: Pointer to an array of Layer Mixers defined in the catalog + */ struct dpu_hw_ctl *dpu_hw_ctl_init(struct drm_device *dev, const struct dpu_ctl_cfg *cfg, void __iomem *addr, 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 4401fdc0f3e4..85c6c835cc87 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h @@ -294,15 +294,6 @@ static inline struct dpu_hw_ctl *to_dpu_hw_ctl(struct dpu_hw_blk *hw) return container_of(hw, struct dpu_hw_ctl, base); } -/** - * dpu_hw_ctl_init() - Initializes the ctl_path hw driver object. - * Should be called before accessing any ctl_path register. - * @dev: Corresponding device for devres management - * @cfg: ctl_path catalog entry for which driver object is required - * @addr: mapped register io address of MDP - * @mixer_count: Number of mixers in @mixer - * @mixer: Pointer to an array of Layer Mixers defined in the catalog - */ struct dpu_hw_ctl *dpu_hw_ctl_init(struct drm_device *dev, const struct dpu_ctl_cfg *cfg, void __iomem *addr, 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 5e9aad1b2aa2..657200401f57 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c @@ -190,6 +190,13 @@ static void _setup_dsc_ops(struct dpu_hw_dsc_ops *ops, ops->dsc_bind_pingpong_blk = dpu_hw_dsc_bind_pingpong_blk; }; +/** + * dpu_hw_dsc_init() - Initializes the DSC hw driver object. + * @dev: Corresponding device for devres management + * @cfg: DSC catalog entry for which driver object is required + * @addr: Mapped register io address of MDP + * Return: Error code or allocated dpu_hw_dsc context + */ struct dpu_hw_dsc *dpu_hw_dsc_init(struct drm_device *dev, const struct dpu_dsc_cfg *cfg, void __iomem *addr) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h index 989c88d2449b..fc171bdeca48 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h @@ -62,24 +62,10 @@ struct dpu_hw_dsc { struct dpu_hw_dsc_ops ops; }; -/** - * dpu_hw_dsc_init() - Initializes the DSC hw driver object. - * @dev: Corresponding device for devres management - * @cfg: DSC catalog entry for which driver object is required - * @addr: Mapped register io address of MDP - * Return: Error code or allocated dpu_hw_dsc context - */ struct dpu_hw_dsc *dpu_hw_dsc_init(struct drm_device *dev, const struct dpu_dsc_cfg *cfg, void __iomem *addr); -/** - * dpu_hw_dsc_init_1_2() - initializes the v1.2 DSC hw driver object - * @dev: Corresponding device for devres management - * @cfg: DSC catalog entry for which driver object is required - * @addr: Mapped register io address of MDP - * Returns: Error code or allocated dpu_hw_dsc context - */ struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(struct drm_device *dev, const struct dpu_dsc_cfg *cfg, void __iomem *addr); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c index ba193b0376fe..b9c433567262 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c @@ -369,6 +369,13 @@ static void _setup_dcs_ops_1_2(struct dpu_hw_dsc_ops *ops, ops->dsc_bind_pingpong_blk = dpu_hw_dsc_bind_pingpong_blk_1_2; } +/** + * dpu_hw_dsc_init_1_2() - initializes the v1.2 DSC hw driver object + * @dev: Corresponding device for devres management + * @cfg: DSC catalog entry for which driver object is required + * @addr: Mapped register io address of MDP + * Returns: Error code or allocated dpu_hw_dsc context + */ struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(struct drm_device *dev, const struct dpu_dsc_cfg *cfg, void __iomem *addr) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c index b1da88e2935f..829ca272873e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c @@ -70,6 +70,14 @@ static void _setup_dspp_ops(struct dpu_hw_dspp *c, c->ops.setup_pcc = dpu_setup_dspp_pcc; } +/** + * dpu_hw_dspp_init() - Initializes the DSPP hw driver object. + * should be called once before accessing every DSPP. + * @dev: Corresponding device for devres management + * @cfg: DSPP catalog entry for which driver object is required + * @addr: Mapped register io address of MDP + * Return: pointer to structure or ERR_PTR + */ struct dpu_hw_dspp *dpu_hw_dspp_init(struct drm_device *dev, const struct dpu_dspp_cfg *cfg, void __iomem *addr) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.h index 3b435690b6cc..45c26cd49fa3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.h @@ -78,14 +78,6 @@ static inline struct dpu_hw_dspp *to_dpu_hw_dspp(struct dpu_hw_blk *hw) return container_of(hw, struct dpu_hw_dspp, base); } -/** - * dpu_hw_dspp_init() - Initializes the DSPP hw driver object. - * should be called once before accessing every DSPP. - * @dev: Corresponding device for devres management - * @cfg: DSPP catalog entry for which driver object is required - * @addr: Mapped register io address of MDP - * Return: pointer to structure or ERR_PTR - */ struct dpu_hw_dspp *dpu_hw_dspp_init(struct drm_device *dev, const struct dpu_dspp_cfg *cfg, void __iomem *addr); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c index b85881aab047..49bd77a755aa 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c @@ -237,6 +237,11 @@ static void dpu_core_irq_callback_handler(struct dpu_kms *dpu_kms, unsigned int irq_entry->cb(irq_entry->arg); } +/** + * dpu_core_irq - core IRQ handler + * @kms: MSM KMS handle + * @return: interrupt handling status + */ irqreturn_t dpu_core_irq(struct msm_kms *kms) { struct dpu_kms *dpu_kms = to_dpu_kms(kms); @@ -442,6 +447,12 @@ static void dpu_disable_all_irqs(struct dpu_kms *dpu_kms) wmb(); } +/** + * dpu_core_irq_read - IRQ helper function for reading IRQ status + * @dpu_kms: DPU handle + * @irq_idx: irq index + * @return: non-zero if irq detected; otherwise no irq detected + */ u32 dpu_core_irq_read(struct dpu_kms *dpu_kms, unsigned int irq_idx) { @@ -476,6 +487,12 @@ u32 dpu_core_irq_read(struct dpu_kms *dpu_kms, return intr_status; } +/** + * dpu_hw_intr_init(): Initializes the interrupts hw object + * @dev: Corresponding device for devres management + * @addr: mapped register io address of MDP + * @m: pointer to MDSS catalog data + */ struct dpu_hw_intr *dpu_hw_intr_init(struct drm_device *dev, void __iomem *addr, const struct dpu_mdss_cfg *m) @@ -517,6 +534,17 @@ struct dpu_hw_intr *dpu_hw_intr_init(struct drm_device *dev, return intr; } +/** + * dpu_core_irq_register_callback - For registering callback function on IRQ + * interrupt + * @dpu_kms: DPU handle + * @irq_idx: irq index + * @irq_cb: IRQ callback function. + * @irq_arg: IRQ callback argument. + * @return: 0 for success registering callback, otherwise failure + * + * This function supports registration of multiple callbacks for each interrupt. + */ int dpu_core_irq_register_callback(struct dpu_kms *dpu_kms, unsigned int irq_idx, void (*irq_cb)(void *arg), @@ -567,6 +595,15 @@ int dpu_core_irq_register_callback(struct dpu_kms *dpu_kms, return 0; } +/** + * dpu_core_irq_unregister_callback - For unregistering callback function on IRQ + * interrupt + * @dpu_kms: DPU handle + * @irq_idx: irq index + * @return: 0 for success registering callback, otherwise failure + * + * This function supports registration of multiple callbacks for each interrupt. + */ int dpu_core_irq_unregister_callback(struct dpu_kms *dpu_kms, unsigned int irq_idx) { @@ -628,6 +665,11 @@ static int dpu_debugfs_core_irq_show(struct seq_file *s, void *v) DEFINE_SHOW_ATTRIBUTE(dpu_debugfs_core_irq); +/** + * dpu_debugfs_core_irq_init - register core irq debugfs + * @dpu_kms: pointer to kms + * @parent: debugfs directory root + */ void dpu_debugfs_core_irq_init(struct dpu_kms *dpu_kms, struct dentry *parent) { @@ -636,6 +678,11 @@ void dpu_debugfs_core_irq_init(struct dpu_kms *dpu_kms, } #endif +/** + * dpu_core_irq_preinstall - perform pre-installation of core IRQ handler + * @kms: MSM KMS handle + * @return: none + */ void dpu_core_irq_preinstall(struct msm_kms *kms) { struct dpu_kms *dpu_kms = to_dpu_kms(kms); @@ -653,6 +700,11 @@ void dpu_core_irq_preinstall(struct msm_kms *kms) } } +/** + * dpu_core_irq_uninstall - uninstall core IRQ handler + * @kms: MSM KMS handle + * @return: none + */ void dpu_core_irq_uninstall(struct msm_kms *kms) { struct dpu_kms *dpu_kms = to_dpu_kms(kms); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h index 564b750a28fe..142358a105c5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h @@ -68,12 +68,6 @@ struct dpu_hw_intr { struct dpu_hw_intr_entry irq_tbl[DPU_NUM_IRQS]; }; -/** - * dpu_hw_intr_init(): Initializes the interrupts hw object - * @dev: Corresponding device for devres management - * @addr: mapped register io address of MDP - * @m: pointer to MDSS catalog data - */ struct dpu_hw_intr *dpu_hw_intr_init(struct drm_device *dev, void __iomem *addr, const struct dpu_mdss_cfg *m); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c index 29cb854f831a..fb1d25baa518 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -547,6 +547,14 @@ static void dpu_hw_intf_program_intf_cmd_cfg(struct dpu_hw_intf *intf, DPU_REG_WRITE(&intf->hw, INTF_CONFIG2, intf_cfg2); } +/** + * dpu_hw_intf_init() - Initializes the INTF driver for the passed + * interface catalog entry. + * @dev: Corresponding device for devres management + * @cfg: interface catalog entry for which driver object is required + * @addr: mapped register io address of MDP + * @mdss_rev: dpu core's major and minor versions + */ struct dpu_hw_intf *dpu_hw_intf_init(struct drm_device *dev, const struct dpu_intf_cfg *cfg, void __iomem *addr, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h index fc23650dfbf0..114be272ac0a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h @@ -130,14 +130,6 @@ struct dpu_hw_intf { struct dpu_hw_intf_ops ops; }; -/** - * dpu_hw_intf_init() - Initializes the INTF driver for the passed - * interface catalog entry. - * @dev: Corresponding device for devres management - * @cfg: interface catalog entry for which driver object is required - * @addr: mapped register io address of MDP - * @mdss_rev: dpu core's major and minor versions - */ struct dpu_hw_intf *dpu_hw_intf_init(struct drm_device *dev, const struct dpu_intf_cfg *cfg, void __iomem *addr, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c index 1d3ccf3228c6..81b56f066519 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c @@ -158,6 +158,13 @@ static void _setup_mixer_ops(struct dpu_hw_lm_ops *ops, ops->collect_misr = dpu_hw_lm_collect_misr; } +/** + * dpu_hw_lm_init() - Initializes the mixer hw driver object. + * should be called once before accessing every mixer. + * @dev: Corresponding device for devres management + * @cfg: mixer catalog entry for which driver object is required + * @addr: mapped register io address of MDP + */ struct dpu_hw_mixer *dpu_hw_lm_init(struct drm_device *dev, const struct dpu_lm_cfg *cfg, void __iomem *addr) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h index 0a3381755249..6f60fa9b3cd7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h @@ -93,13 +93,6 @@ static inline struct dpu_hw_mixer *to_dpu_hw_mixer(struct dpu_hw_blk *hw) return container_of(hw, struct dpu_hw_mixer, base); } -/** - * dpu_hw_lm_init() - Initializes the mixer hw driver object. - * should be called once before accessing every mixer. - * @dev: Corresponding device for devres management - * @cfg: mixer catalog entry for which driver object is required - * @addr: mapped register io address of MDP - */ struct dpu_hw_mixer *dpu_hw_lm_init(struct drm_device *dev, const struct dpu_lm_cfg *cfg, void __iomem *addr); 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 a2eff36a2224..f8806a4d317b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h @@ -293,7 +293,6 @@ enum dpu_3d_blend_mode { /** * struct dpu_hw_fmt_layout - format information of the source pixel data - * @format: pixel format parameters * @num_planes: number of planes (including meta data planes) * @width: image width * @height: image height @@ -303,7 +302,6 @@ enum dpu_3d_blend_mode { * @plane_pitch: pitch of each plane */ struct dpu_hw_fmt_layout { - const struct msm_format *format; uint32_t num_planes; uint32_t width; uint32_t height; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.c index ddfa40a959cb..0b3325f9c870 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.c @@ -39,6 +39,14 @@ static void _setup_merge_3d_ops(struct dpu_hw_merge_3d *c, c->ops.setup_3d_mode = dpu_hw_merge_3d_setup_3d_mode; }; +/** + * dpu_hw_merge_3d_init() - Initializes the merge_3d driver for the passed + * merge3d catalog entry. + * @dev: Corresponding device for devres management + * @cfg: Pingpong catalog entry for which driver object is required + * @addr: Mapped register io address of MDP + * Return: Error code or allocated dpu_hw_merge_3d context + */ struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(struct drm_device *dev, const struct dpu_merge_3d_cfg *cfg, void __iomem *addr) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.h index c192f02ec1ab..6833c0207523 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.h @@ -45,14 +45,6 @@ static inline struct dpu_hw_merge_3d *to_dpu_hw_merge_3d(struct dpu_hw_blk *hw) return container_of(hw, struct dpu_hw_merge_3d, base); } -/** - * dpu_hw_merge_3d_init() - Initializes the merge_3d driver for the passed - * merge3d catalog entry. - * @dev: Corresponding device for devres management - * @cfg: Pingpong catalog entry for which driver object is required - * @addr: Mapped register io address of MDP - * Return: Error code or allocated dpu_hw_merge_3d context - */ struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(struct drm_device *dev, const struct dpu_merge_3d_cfg *cfg, void __iomem *addr); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c index 2db4c6fba37a..36c0ec775b92 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c @@ -283,6 +283,15 @@ static int dpu_hw_pp_setup_dsc(struct dpu_hw_pingpong *pp) return 0; } +/** + * dpu_hw_pingpong_init() - initializes the pingpong driver for the passed + * pingpong catalog entry. + * @dev: Corresponding device for devres management + * @cfg: Pingpong catalog entry for which driver object is required + * @addr: Mapped register io address of MDP + * @mdss_rev: dpu core's major and minor versions + * Return: Error code or allocated dpu_hw_pingpong context + */ struct dpu_hw_pingpong *dpu_hw_pingpong_init(struct drm_device *dev, const struct dpu_pingpong_cfg *cfg, void __iomem *addr, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h index a48b69fd79a3..dd99e1c21a1e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h @@ -118,15 +118,6 @@ static inline struct dpu_hw_pingpong *to_dpu_hw_pingpong(struct dpu_hw_blk *hw) return container_of(hw, struct dpu_hw_pingpong, base); } -/** - * dpu_hw_pingpong_init() - initializes the pingpong driver for the passed - * pingpong catalog entry. - * @dev: Corresponding device for devres management - * @cfg: Pingpong catalog entry for which driver object is required - * @addr: Mapped register io address of MDP - * @mdss_rev: dpu core's major and minor versions - * Return: Error code or allocated dpu_hw_pingpong context - */ struct dpu_hw_pingpong *dpu_hw_pingpong_init(struct drm_device *dev, const struct dpu_pingpong_cfg *cfg, void __iomem *addr, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c index 2c720f1fc1b2..32c7c8084553 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c @@ -672,6 +672,15 @@ int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms, } #endif +/** + * dpu_hw_sspp_init() - Initializes the sspp hw driver object. + * Should be called once before accessing every pipe. + * @dev: Corresponding device for devres management + * @cfg: Pipe catalog entry for which driver object is required + * @addr: Mapped register io address of MDP + * @mdss_data: UBWC / MDSS configuration data + * @mdss_rev: dpu core's major and minor versions + */ struct dpu_hw_sspp *dpu_hw_sspp_init(struct drm_device *dev, const struct dpu_sspp_cfg *cfg, void __iomem *addr, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h index 4a910b808687..56a0edf2a57c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h @@ -12,6 +12,8 @@ struct dpu_hw_sspp; +#define DPU_SSPP_MAX_PITCH_SIZE 0xffff + /** * Flags */ @@ -142,10 +144,12 @@ struct dpu_hw_pixel_ext { * @src_rect: src ROI, caller takes into account the different operations * such as decimation, flip etc to program this field * @dest_rect: destination ROI. + * @rotation: simplified drm rotation hint */ struct dpu_sw_pipe_cfg { struct drm_rect src_rect; struct drm_rect dst_rect; + unsigned int rotation; }; /** @@ -315,15 +319,7 @@ struct dpu_hw_sspp { }; struct dpu_kms; -/** - * dpu_hw_sspp_init() - Initializes the sspp hw driver object. - * Should be called once before accessing every pipe. - * @dev: Corresponding device for devres management - * @cfg: Pipe catalog entry for which driver object is required - * @addr: Mapped register io address of MDP - * @mdss_data: UBWC / MDSS configuration data - * @mdss_rev: dpu core's major and minor versions - */ + struct dpu_hw_sspp *dpu_hw_sspp_init(struct drm_device *dev, const struct dpu_sspp_cfg *cfg, void __iomem *addr, 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 0f40eea7f5e2..ad19330de61a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c @@ -284,6 +284,13 @@ static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops, ops->intf_audio_select = dpu_hw_intf_audio_select; } +/** + * dpu_hw_mdptop_init - initializes the top driver for the passed config + * @dev: Corresponding device for devres management + * @cfg: MDP TOP configuration from catalog + * @addr: Mapped register io address of MDP + * @mdss_rev: dpu core's major and minor versions + */ struct dpu_hw_mdp *dpu_hw_mdptop_init(struct drm_device *dev, const struct dpu_mdp_cfg *cfg, void __iomem *addr, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h index f1ab9fd106e5..04efdcd21ceb 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h @@ -157,18 +157,9 @@ struct dpu_hw_mdp { struct dpu_hw_mdp_ops ops; }; -/** - * dpu_hw_mdptop_init - initializes the top driver for the passed config - * @dev: Corresponding device for devres management - * @cfg: MDP TOP configuration from catalog - * @addr: Mapped register io address of MDP - * @mdss_rev: dpu core's major and minor versions - */ struct dpu_hw_mdp *dpu_hw_mdptop_init(struct drm_device *dev, const struct dpu_mdp_cfg *cfg, void __iomem *addr, const struct dpu_mdss_version *mdss_rev); -void dpu_hw_mdp_destroy(struct dpu_hw_mdp *mdp); - #endif /*_DPU_HW_TOP_H */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c index 98e34afde2d2..af76ad8a8103 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c @@ -213,6 +213,13 @@ static void _setup_vbif_ops(struct dpu_hw_vbif_ops *ops, ops->set_write_gather_en = dpu_hw_set_write_gather_en; } +/** + * dpu_hw_vbif_init() - Initializes the VBIF driver for the passed + * VBIF catalog entry. + * @dev: Corresponding device for devres management + * @cfg: VBIF catalog entry for which driver object is required + * @addr: Mapped register io address of MDSS + */ struct dpu_hw_vbif *dpu_hw_vbif_init(struct drm_device *dev, const struct dpu_vbif_cfg *cfg, void __iomem *addr) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h index e2b4307500e4..285121ec804c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h @@ -105,13 +105,6 @@ struct dpu_hw_vbif { struct dpu_hw_vbif_ops ops; }; -/** - * dpu_hw_vbif_init() - Initializes the VBIF driver for the passed - * VBIF catalog entry. - * @dev: Corresponding device for devres management - * @cfg: VBIF catalog entry for which driver object is required - * @addr: Mapped register io address of MDSS - */ struct dpu_hw_vbif *dpu_hw_vbif_init(struct drm_device *dev, const struct dpu_vbif_cfg *cfg, void __iomem *addr); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c index 93ff01c889b5..fb9f90957762 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c @@ -64,10 +64,10 @@ static void dpu_hw_wb_setup_outaddress(struct dpu_hw_wb *ctx, } static void dpu_hw_wb_setup_format(struct dpu_hw_wb *ctx, - struct dpu_hw_wb_cfg *data) + struct dpu_hw_wb_cfg *data, + const struct msm_format *fmt) { struct dpu_hw_blk_reg_map *c = &ctx->hw; - const struct msm_format *fmt = data->dest.format; u32 dst_format, pattern, ystride0, ystride1, outsize, chroma_samp; u32 write_config = 0; u32 opmode = 0; @@ -213,6 +213,14 @@ static void _setup_wb_ops(struct dpu_hw_wb_ops *ops, ops->setup_clk_force_ctrl = dpu_hw_wb_setup_clk_force_ctrl; } +/** + * dpu_hw_wb_init() - Initializes the writeback hw driver object. + * @dev: Corresponding device for devres management + * @cfg: wb_path catalog entry for which driver object is required + * @addr: mapped register io address of MDP + * @mdss_rev: dpu core's major and minor versions + * Return: Error code or allocated dpu_hw_wb context + */ struct dpu_hw_wb *dpu_hw_wb_init(struct drm_device *dev, const struct dpu_wb_cfg *cfg, void __iomem *addr, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h index 37497473e16c..ee5e5ab786e1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h @@ -37,7 +37,8 @@ struct dpu_hw_wb_ops { struct dpu_hw_wb_cfg *wb); void (*setup_outformat)(struct dpu_hw_wb *ctx, - struct dpu_hw_wb_cfg *wb); + struct dpu_hw_wb_cfg *wb, + const struct msm_format *fmt); void (*setup_roi)(struct dpu_hw_wb *ctx, struct dpu_hw_wb_cfg *wb); @@ -74,14 +75,6 @@ struct dpu_hw_wb { struct dpu_hw_wb_ops ops; }; -/** - * dpu_hw_wb_init() - Initializes the writeback hw driver object. - * @dev: Corresponding device for devres management - * @cfg: wb_path catalog entry for which driver object is required - * @addr: mapped register io address of MDP - * @mdss_rev: dpu core's major and minor versions - * Return: Error code or allocated dpu_hw_wb context - */ struct dpu_hw_wb *dpu_hw_wb_init(struct drm_device *dev, const struct dpu_wb_cfg *cfg, void __iomem *addr, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 9bcae53c4f45..ca4847b2b738 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -230,6 +230,21 @@ static int dpu_regset32_show(struct seq_file *s, void *data) } DEFINE_SHOW_ATTRIBUTE(dpu_regset32); +/** + * dpu_debugfs_create_regset32 - Create register read back file for debugfs + * + * This function is almost identical to the standard debugfs_create_regset32() + * function, with the main difference being that a list of register + * names/offsets do not need to be provided. The 'read' function simply outputs + * sequential register values over a specified range. + * + * @name: File name within debugfs + * @mode: File mode within debugfs + * @parent: Parent directory entry within debugfs, can be NULL + * @offset: sub-block offset + * @length: sub-block length, in bytes + * @dpu_kms: pointer to dpu kms structure + */ void dpu_debugfs_create_regset32(const char *name, umode_t mode, void *parent, uint32_t offset, uint32_t length, struct dpu_kms *dpu_kms) @@ -1025,7 +1040,6 @@ static const struct msm_kms_funcs kms_funcs = { .complete_commit = dpu_kms_complete_commit, .enable_vblank = dpu_kms_enable_vblank, .disable_vblank = dpu_kms_disable_vblank, - .check_modified_format = dpu_format_check_modified_format, .destroy = dpu_kms_destroy, .snapshot = dpu_kms_mdp_snapshot, #ifdef CONFIG_DEBUG_FS @@ -1061,6 +1075,13 @@ static int _dpu_kms_mmu_init(struct dpu_kms *dpu_kms) return 0; } +/** + * dpu_kms_get_clk_rate() - get the clock rate + * @dpu_kms: pointer to dpu_kms structure + * @clock_name: clock name to get the rate + * + * Return: current clock rate + */ unsigned long dpu_kms_get_clk_rate(struct dpu_kms *dpu_kms, char *clock_name) { struct clk *clk; @@ -1202,13 +1223,8 @@ static int dpu_kms_hw_init(struct msm_kms *kms) dev->mode_config.min_width = 0; dev->mode_config.min_height = 0; - /* - * max crtc width is equal to the max mixer width * 2 and max height is - * is 4K - */ - dev->mode_config.max_width = - dpu_kms->catalog->caps->max_mixer_width * 2; - dev->mode_config.max_height = 4096; + dev->mode_config.max_width = DPU_MAX_IMG_WIDTH; + dev->mode_config.max_height = DPU_MAX_IMG_HEIGHT; dev->max_vblank_count = 0xffffffff; /* Disable vblank irqs aggressively for power-saving */ @@ -1445,8 +1461,13 @@ static const struct dev_pm_ops dpu_pm_ops = { }; static const struct of_device_id dpu_dt_match[] = { + { .compatible = "qcom,msm8917-mdp5", .data = &dpu_msm8917_cfg, }, + { .compatible = "qcom,msm8937-mdp5", .data = &dpu_msm8937_cfg, }, + { .compatible = "qcom,msm8953-mdp5", .data = &dpu_msm8953_cfg, }, + { .compatible = "qcom,msm8996-mdp5", .data = &dpu_msm8996_cfg, }, { .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,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 935ff6fd172c..88d64d43ea1a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -145,38 +145,11 @@ struct dpu_global_state * @dpu_debugfs_create_regset32: Create 32-bit register dump file */ -/** - * dpu_debugfs_create_regset32 - Create register read back file for debugfs - * - * This function is almost identical to the standard debugfs_create_regset32() - * function, with the main difference being that a list of register - * names/offsets do not need to be provided. The 'read' function simply outputs - * sequential register values over a specified range. - * - * @name: File name within debugfs - * @mode: File mode within debugfs - * @parent: Parent directory entry within debugfs, can be NULL - * @offset: sub-block offset - * @length: sub-block length, in bytes - * @dpu_kms: pointer to dpu kms structure - */ void dpu_debugfs_create_regset32(const char *name, umode_t mode, void *parent, uint32_t offset, uint32_t length, struct dpu_kms *dpu_kms); /** - * dpu_debugfs_get_root - Return root directory entry for KMS's debugfs - * - * The return value should be passed as the 'parent' argument to subsequent - * debugfs create calls. - * - * @dpu_kms: Pointer to DPU's KMS structure - * - * Return: dentry pointer for DPU's debugfs location - */ -void *dpu_debugfs_get_root(struct dpu_kms *dpu_kms); - -/** * DPU info management functions * These functions/definitions allow for building up a 'dpu_info' structure * containing one or more "key=value\n" entries. @@ -189,13 +162,6 @@ void *dpu_debugfs_get_root(struct dpu_kms *dpu_kms); int dpu_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); void dpu_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); -/** - * dpu_kms_get_clk_rate() - get the clock rate - * @dpu_kms: pointer to dpu_kms structure - * @clock_name: clock name to get the rate - * - * Return: current clock rate - */ unsigned long dpu_kms_get_clk_rate(struct dpu_kms *dpu_kms, char *clock_name); #endif /* __dpu_kms_H__ */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 29298e066163..3ffac24333a2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -528,8 +528,7 @@ static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_sw_pipe *pipe, static void _dpu_plane_setup_scaler(struct dpu_sw_pipe *pipe, const struct msm_format *fmt, bool color_fill, - struct dpu_sw_pipe_cfg *pipe_cfg, - unsigned int rotation) + struct dpu_sw_pipe_cfg *pipe_cfg) { struct dpu_hw_sspp *pipe_hw = pipe->sspp; const struct drm_format_info *info = drm_format_info(fmt->pixel_format); @@ -552,7 +551,7 @@ static void _dpu_plane_setup_scaler(struct dpu_sw_pipe *pipe, dst_height, &scaler3_cfg, fmt, info->hsub, info->vsub, - rotation); + pipe_cfg->rotation); /* configure pixel extension based on scalar config */ _dpu_plane_setup_pixel_ext(&scaler3_cfg, &pixel_ext, @@ -604,7 +603,7 @@ static void _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate, if (pipe->sspp->ops.setup_rects) pipe->sspp->ops.setup_rects(pipe, &pipe_cfg); - _dpu_plane_setup_scaler(pipe, fmt, true, &pipe_cfg, pstate->rotation); + _dpu_plane_setup_scaler(pipe, fmt, true, &pipe_cfg); } /** @@ -648,7 +647,6 @@ static int dpu_plane_prepare_fb(struct drm_plane *plane, struct drm_framebuffer *fb = new_state->fb; struct dpu_plane *pdpu = to_dpu_plane(plane); struct dpu_plane_state *pstate = to_dpu_plane_state(new_state); - struct dpu_hw_fmt_layout layout; struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base); int ret; @@ -676,17 +674,6 @@ static int dpu_plane_prepare_fb(struct drm_plane *plane, } } - /* validate framebuffer layout before commit */ - ret = dpu_format_populate_layout(pstate->aspace, - new_state->fb, &layout); - if (ret) { - DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret); - if (pstate->aspace) - msm_framebuffer_cleanup(new_state->fb, pstate->aspace, - pstate->needs_dirtyfb); - return ret; - } - return 0; } @@ -708,12 +695,17 @@ static void dpu_plane_cleanup_fb(struct drm_plane *plane, } static int dpu_plane_check_inline_rotation(struct dpu_plane *pdpu, - const struct dpu_sspp_sub_blks *sblk, - struct drm_rect src, const struct msm_format *fmt) + struct dpu_sw_pipe *pipe, + struct drm_rect src, + const struct msm_format *fmt) { + const struct dpu_sspp_sub_blks *sblk = pipe->sspp->cap->sblk; size_t num_formats; const u32 *supported_formats; + if (!test_bit(DPU_SSPP_INLINE_ROTATION, &pipe->sspp->cap->features)) + return -EINVAL; + if (!sblk->rotation_cfg) { DPU_ERROR("invalid rotation cfg\n"); return -EINVAL; @@ -743,6 +735,7 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu, { uint32_t min_src_size; struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base); + int ret; min_src_size = MSM_FORMAT_IS_YUV(fmt) ? 2 : 1; @@ -780,6 +773,12 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu, return -EINVAL; } + if (pipe_cfg->rotation & DRM_MODE_ROTATE_90) { + ret = dpu_plane_check_inline_rotation(pdpu, pipe, pipe_cfg->src_rect, fmt); + if (ret) + return ret; + } + /* max clk check */ if (_dpu_plane_calc_clk(mode, pipe_cfg) > kms->perf.max_core_clk_rate) { DPU_DEBUG_PLANE(pdpu, "plane exceeds max mdp core clk limits\n"); @@ -789,37 +788,29 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu, return 0; } -static int dpu_plane_atomic_check(struct drm_plane *plane, - struct drm_atomic_state *state) +#define MAX_UPSCALE_RATIO 20 +#define MAX_DOWNSCALE_RATIO 4 + +static int dpu_plane_atomic_check_nosspp(struct drm_plane *plane, + struct drm_plane_state *new_plane_state, + const struct drm_crtc_state *crtc_state) { - struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, - plane); - int ret = 0, min_scale; + int i, ret = 0, min_scale, max_scale; struct dpu_plane *pdpu = to_dpu_plane(plane); struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base); u64 max_mdp_clk_rate = kms->perf.max_core_clk_rate; 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 drm_crtc_state *crtc_state = NULL; - 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; struct drm_rect fb_rect = { 0 }; uint32_t max_linewidth; - unsigned int rotation; - uint32_t supported_rotations; - const struct dpu_sspp_cfg *pipe_hw_caps = pstate->pipe.sspp->cap; - const struct dpu_sspp_sub_blks *sblk = pstate->pipe.sspp->cap->sblk; - if (new_plane_state->crtc) - crtc_state = drm_atomic_get_new_crtc_state(state, - new_plane_state->crtc); + min_scale = FRAC_16_16(1, MAX_UPSCALE_RATIO); + max_scale = MAX_DOWNSCALE_RATIO << 16; - min_scale = FRAC_16_16(1, sblk->maxupscale); ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state, min_scale, - sblk->maxdwnscale << 16, + max_scale, true, true); if (ret) { DPU_DEBUG_PLANE(pdpu, "Check plane state failed (%d)\n", ret); @@ -828,12 +819,6 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, if (!new_plane_state->visible) return 0; - 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; - r_pipe->sspp = NULL; - pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos; if (pstate->stage >= pdpu->catalog->caps->max_mixer_blendstages) { DPU_ERROR("> %d plane stages assigned\n", @@ -841,13 +826,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, return -EINVAL; } - pipe_cfg->src_rect = new_plane_state->src; - /* state->src is 16.16, src_rect is not */ - pipe_cfg->src_rect.x1 >>= 16; - pipe_cfg->src_rect.x2 >>= 16; - pipe_cfg->src_rect.y1 >>= 16; - pipe_cfg->src_rect.y2 >>= 16; + drm_rect_fp_to_int(&pipe_cfg->src_rect, &new_plane_state->src); pipe_cfg->dst_rect = new_plane_state->dst; @@ -855,14 +835,22 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, fb_rect.y2 = new_plane_state->fb->height; /* Ensure fb size is supported */ - if (drm_rect_width(&fb_rect) > MAX_IMG_WIDTH || - drm_rect_height(&fb_rect) > MAX_IMG_HEIGHT) { + if (drm_rect_width(&fb_rect) > DPU_MAX_IMG_WIDTH || + drm_rect_height(&fb_rect) > DPU_MAX_IMG_HEIGHT) { DPU_DEBUG_PLANE(pdpu, "invalid framebuffer " DRM_RECT_FMT "\n", DRM_RECT_ARG(&fb_rect)); return -E2BIG; } - fmt = msm_framebuffer_format(new_plane_state->fb); + ret = dpu_format_populate_plane_sizes(new_plane_state->fb, &pstate->layout); + if (ret) { + DPU_ERROR_PLANE(pdpu, "failed to get format plane sizes, %d\n", ret); + return ret; + } + + for (i = 0; i < pstate->layout.num_planes; i++) + if (pstate->layout.plane_pitch[i] > DPU_SSPP_MAX_PITCH_SIZE) + return -E2BIG; max_linewidth = pdpu->catalog->caps->max_linewidth; @@ -872,6 +860,86 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, if ((drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) || _dpu_plane_calc_clk(&crtc_state->adjusted_mode, pipe_cfg) > max_mdp_clk_rate) { + if (drm_rect_width(&pipe_cfg->src_rect) > 2 * max_linewidth) { + DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u\n", + DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth); + return -E2BIG; + } + + *r_pipe_cfg = *pipe_cfg; + pipe_cfg->src_rect.x2 = (pipe_cfg->src_rect.x1 + pipe_cfg->src_rect.x2) >> 1; + pipe_cfg->dst_rect.x2 = (pipe_cfg->dst_rect.x1 + pipe_cfg->dst_rect.x2) >> 1; + r_pipe_cfg->src_rect.x1 = pipe_cfg->src_rect.x2; + r_pipe_cfg->dst_rect.x1 = pipe_cfg->dst_rect.x2; + } else { + memset(r_pipe_cfg, 0, sizeof(*r_pipe_cfg)); + } + + drm_rect_rotate_inv(&pipe_cfg->src_rect, + new_plane_state->fb->width, new_plane_state->fb->height, + new_plane_state->rotation); + if (r_pipe_cfg->src_rect.x1 != 0) + drm_rect_rotate_inv(&r_pipe_cfg->src_rect, + new_plane_state->fb->width, new_plane_state->fb->height, + new_plane_state->rotation); + + pstate->needs_qos_remap = drm_atomic_crtc_needs_modeset(crtc_state); + + return 0; +} + +static int dpu_plane_atomic_check_sspp(struct drm_plane *plane, + struct drm_atomic_state *state, + const struct drm_crtc_state *crtc_state) +{ + struct drm_plane_state *new_plane_state = + drm_atomic_get_new_plane_state(state, plane); + struct dpu_plane *pdpu = to_dpu_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 max_linewidth; + 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); + + max_linewidth = pdpu->catalog->caps->max_linewidth; + + 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); + if (ret) + return ret; + + if (drm_rect_width(&r_pipe_cfg->src_rect) != 0) { /* * In parallel multirect case only the half of the usual width * is supported for tiled formats. If we are here, we know that @@ -885,16 +953,11 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, return -E2BIG; } - if (drm_rect_width(&pipe_cfg->src_rect) > 2 * max_linewidth) { - DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u\n", - DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth); - return -E2BIG; - } - 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) || (!test_bit(DPU_SSPP_SMART_DMA_V1, &pipe->sspp->cap->features) && !test_bit(DPU_SSPP_SMART_DMA_V2, &pipe->sspp->cap->features)) || + pipe_cfg->rotation & DRM_MODE_ROTATE_90 || MSM_FORMAT_IS_YUV(fmt)) { DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u, can't use split source\n", DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth); @@ -912,51 +975,48 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, r_pipe->multirect_index = DPU_SSPP_RECT_1; r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL; - *r_pipe_cfg = *pipe_cfg; - pipe_cfg->src_rect.x2 = (pipe_cfg->src_rect.x1 + pipe_cfg->src_rect.x2) >> 1; - pipe_cfg->dst_rect.x2 = (pipe_cfg->dst_rect.x1 + pipe_cfg->dst_rect.x2) >> 1; - r_pipe_cfg->src_rect.x1 = pipe_cfg->src_rect.x2; - r_pipe_cfg->dst_rect.x1 = pipe_cfg->dst_rect.x2; - } - - drm_rect_rotate_inv(&pipe_cfg->src_rect, - new_plane_state->fb->width, new_plane_state->fb->height, - new_plane_state->rotation); - if (r_pipe->sspp) - drm_rect_rotate_inv(&r_pipe_cfg->src_rect, - new_plane_state->fb->width, new_plane_state->fb->height, - new_plane_state->rotation); - - ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt, &crtc_state->adjusted_mode); - if (ret) - return ret; - - if (r_pipe->sspp) { ret = dpu_plane_atomic_check_pipe(pdpu, r_pipe, r_pipe_cfg, fmt, &crtc_state->adjusted_mode); if (ret) return ret; } - supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0; + return 0; +} - if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION)) - supported_rotations |= DRM_MODE_ROTATE_90; +static int dpu_plane_atomic_check(struct drm_plane *plane, + struct drm_atomic_state *state) +{ + struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, + plane); + int ret = 0; + struct dpu_plane *pdpu = to_dpu_plane(plane); + struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state); + struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane); + struct dpu_sw_pipe *pipe = &pstate->pipe; + struct dpu_sw_pipe *r_pipe = &pstate->r_pipe; + const struct drm_crtc_state *crtc_state = NULL; - rotation = drm_rotation_simplify(new_plane_state->rotation, - supported_rotations); + if (new_plane_state->crtc) + crtc_state = drm_atomic_get_new_crtc_state(state, + new_plane_state->crtc); - if ((pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION)) && - (rotation & DRM_MODE_ROTATE_90)) { - ret = dpu_plane_check_inline_rotation(pdpu, sblk, pipe_cfg->src_rect, fmt); - if (ret) - return ret; - } + pipe->sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe); + r_pipe->sspp = NULL; - pstate->rotation = rotation; - pstate->needs_qos_remap = drm_atomic_crtc_needs_modeset(crtc_state); + ret = dpu_plane_atomic_check_nosspp(plane, new_plane_state, crtc_state); + if (ret) + return ret; - return 0; + if (!new_plane_state->visible) + return 0; + + 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); } static void dpu_plane_flush_csc(struct dpu_plane *pdpu, struct dpu_sw_pipe *pipe) @@ -981,6 +1041,10 @@ static void dpu_plane_flush_csc(struct dpu_plane *pdpu, struct dpu_sw_pipe *pipe } +/** + * dpu_plane_flush - final plane operations before commit flush + * @plane: Pointer to drm plane structure + */ void dpu_plane_flush(struct drm_plane *plane) { struct dpu_plane *pdpu; @@ -1060,14 +1124,14 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane, pipe_cfg); } - _dpu_plane_setup_scaler(pipe, fmt, false, pipe_cfg, pstate->rotation); + _dpu_plane_setup_scaler(pipe, fmt, false, pipe_cfg); if (pipe->sspp->ops.setup_multirect) pipe->sspp->ops.setup_multirect( pipe); if (pipe->sspp->ops.setup_format) { - unsigned int rotation = pstate->rotation; + unsigned int rotation = pipe_cfg->rotation; src_flags = 0x0; @@ -1101,7 +1165,8 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane, _dpu_plane_set_qos_remap(plane, pipe); } -static void dpu_plane_sspp_atomic_update(struct drm_plane *plane) +static void dpu_plane_sspp_atomic_update(struct drm_plane *plane, + struct drm_plane_state *new_state) { struct dpu_plane *pdpu = to_dpu_plane(plane); struct drm_plane_state *state = plane->state; @@ -1115,17 +1180,6 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane) msm_framebuffer_format(fb); struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg; struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg; - struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base); - struct msm_gem_address_space *aspace = kms->base.aspace; - struct dpu_hw_fmt_layout layout; - bool layout_valid = false; - int ret; - - ret = dpu_format_populate_layout(aspace, fb, &layout); - if (ret) - DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret); - else - layout_valid = true; pstate->pending = true; @@ -1133,6 +1187,8 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane) pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe); pdpu->is_rt_pipe = is_rt_pipe; + dpu_format_populate_addrs(pstate->aspace, new_state->fb, &pstate->layout); + DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT ", %p4cc ubwc %d\n", fb->base.id, DRM_RECT_FP_ARG(&state->src), crtc->base.id, DRM_RECT_ARG(&state->dst), @@ -1140,12 +1196,12 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane) dpu_plane_sspp_update_pipe(plane, pipe, pipe_cfg, fmt, drm_mode_vrefresh(&crtc->mode), - layout_valid ? &layout : NULL); + &pstate->layout); if (r_pipe->sspp) { dpu_plane_sspp_update_pipe(plane, r_pipe, r_pipe_cfg, fmt, drm_mode_vrefresh(&crtc->mode), - layout_valid ? &layout : NULL); + &pstate->layout); } if (pstate->needs_qos_remap) @@ -1197,7 +1253,7 @@ static void dpu_plane_atomic_update(struct drm_plane *plane, if (!new_state->visible) { _dpu_plane_atomic_disable(plane); } else { - dpu_plane_sspp_atomic_update(plane); + dpu_plane_sspp_atomic_update(plane, new_state); } } @@ -1301,7 +1357,6 @@ static void dpu_plane_reset(struct drm_plane *plane) { struct dpu_plane *pdpu; struct dpu_plane_state *pstate; - struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane); if (!plane) { DPU_ERROR("invalid plane\n"); @@ -1323,16 +1378,6 @@ static void dpu_plane_reset(struct drm_plane *plane) return; } - /* - * Set the SSPP here until we have proper virtualized DPU planes. - * This is the place where the state is allocated, so fill it fully. - */ - pstate->pipe.sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe); - pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO; - pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE; - - pstate->r_pipe.sspp = NULL; - __drm_atomic_helper_plane_reset(plane, &pstate->base); } @@ -1388,7 +1433,15 @@ static const struct drm_plane_helper_funcs dpu_plane_helper_funcs = { .atomic_update = dpu_plane_atomic_update, }; -/* initialize plane */ +/** + * dpu_plane_init - create new dpu plane for the given pipe + * @dev: Pointer to DRM device + * @pipe: dpu hardware pipe identifier + * @type: Plane type - PRIMARY/OVERLAY/CURSOR + * @possible_crtcs: bitmask of crtc that can be attached to the given pipe + * + * Initialize the plane. + */ struct drm_plane *dpu_plane_init(struct drm_device *dev, uint32_t pipe, enum drm_plane_type type, unsigned long possible_crtcs) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h index abd6b21a049b..97090ca7842b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h @@ -30,7 +30,7 @@ * @plane_fetch_bw: calculated BW per plane * @plane_clk: calculated clk per plane * @needs_dirtyfb: whether attached CRTC needs pixel data explicitly flushed - * @rotation: simplified drm rotation hint + * @layout: framebuffer memory layout */ struct dpu_plane_state { struct drm_plane_state base; @@ -47,46 +47,21 @@ struct dpu_plane_state { u64 plane_clk; bool needs_dirtyfb; - unsigned int rotation; + + struct dpu_hw_fmt_layout layout; }; #define to_dpu_plane_state(x) \ container_of(x, struct dpu_plane_state, base) -/** - * dpu_plane_flush - final plane operations before commit flush - * @plane: Pointer to drm plane structure - */ void dpu_plane_flush(struct drm_plane *plane); -/** - * dpu_plane_set_error: enable/disable error condition - * @plane: pointer to drm_plane structure - */ void dpu_plane_set_error(struct drm_plane *plane, bool error); -/** - * dpu_plane_init - create new dpu plane for the given pipe - * @dev: Pointer to DRM device - * @pipe: dpu hardware pipe identifier - * @type: Plane type - PRIMARY/OVERLAY/CURSOR - * @possible_crtcs: bitmask of crtc that can be attached to the given pipe - * - */ struct drm_plane *dpu_plane_init(struct drm_device *dev, uint32_t pipe, enum drm_plane_type type, unsigned long possible_crtcs); -/** - * dpu_plane_color_fill - enables color fill on plane - * @plane: Pointer to DRM plane object - * @color: RGB fill color value, [23..16] Blue, [15..8] Green, [7..0] Red - * @alpha: 8-bit fill alpha value, 255 selects 100% alpha - * Returns: 0 on success - */ -int dpu_plane_color_fill(struct drm_plane *plane, - uint32_t color, uint32_t alpha); - #ifdef CONFIG_DEBUG_FS void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable); #else diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index 44938ba7a2b7..c247af03dc8e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -34,6 +34,16 @@ struct dpu_rm_requirements { struct msm_display_topology topology; }; +/** + * dpu_rm_init - Read hardware catalog and create reservation tracking objects + * for all HW blocks. + * @dev: Corresponding device for devres management + * @rm: DPU Resource Manager handle + * @cat: Pointer to hardware catalog + * @mdss_data: Pointer to MDSS / UBWC configuration + * @mmio: mapped register io address of MDP + * @return: 0 on Success otherwise -ERROR + */ int dpu_rm_init(struct drm_device *dev, struct dpu_rm *rm, const struct dpu_mdss_cfg *cat, @@ -641,6 +651,13 @@ 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 + * @return: 0 on Success otherwise -ERROR + */ void dpu_rm_release(struct dpu_global_state *global_state, struct drm_encoder *enc) { @@ -657,6 +674,20 @@ void dpu_rm_release(struct dpu_global_state *global_state, _dpu_rm_clear_mapping(&global_state->cdm_to_enc_id, 1, enc->base.id); } +/** + * dpu_rm_reserve - Given a CRTC->Encoder->Connector display chain, analyze + * the use connections and user requirements, specified through related + * topology control properties, and reserve hardware blocks to that + * display chain. + * HW blocks can then be accessed through dpu_rm_get_* functions. + * 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 + * @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, @@ -694,6 +725,16 @@ int dpu_rm_reserve( return ret; } +/** + * dpu_rm_get_assigned_resources - Get hw resources of the given type that are + * assigned to this encoder + * @rm: DPU Resource Manager handle + * @global_state: resources shared across multiple kms objects + * @enc_id: encoder id requesting for allocation + * @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, enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size) @@ -772,6 +813,11 @@ static void dpu_rm_print_state_helper(struct drm_printer *p, } +/** + * dpu_rm_print_state - output the RM private state + * @p: DRM printer + * @global_state: global state + */ void dpu_rm_print_state(struct drm_printer *p, const struct dpu_global_state *global_state) { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h index e63db8ace6b9..ea0e49cb7b0d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h @@ -38,62 +38,40 @@ struct dpu_rm { }; /** - * dpu_rm_init - Read hardware catalog and create reservation tracking objects - * for all HW blocks. - * @dev: Corresponding device for devres management - * @rm: DPU Resource Manager handle - * @cat: Pointer to hardware catalog - * @mdss_data: Pointer to MDSS / UBWC configuration - * @mmio: mapped register io address of MDP - * @Return: 0 on Success otherwise -ERROR + * struct msm_display_topology - defines a display topology pipeline + * @num_lm: number of layer mixers used + * @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 */ +struct msm_display_topology { + u32 num_lm; + u32 num_intf; + u32 num_dspp; + u32 num_dsc; + bool needs_cdm; +}; + int dpu_rm_init(struct drm_device *dev, struct dpu_rm *rm, const struct dpu_mdss_cfg *cat, const struct msm_mdss_data *mdss_data, void __iomem *mmio); -/** - * dpu_rm_reserve - Given a CRTC->Encoder->Connector display chain, analyze - * the use connections and user requirements, specified through related - * topology control properties, and reserve hardware blocks to that - * display chain. - * HW blocks can then be accessed through dpu_rm_get_* functions. - * HW Reservations should be released via dpu_rm_release_hw. - * @rm: DPU Resource Manager handle - * @drm_enc: DRM Encoder handle - * @crtc_state: Proposed Atomic DRM CRTC State 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 *drm_enc, struct drm_crtc_state *crtc_state, struct msm_display_topology topology); -/** - * dpu_rm_reserve - Given the encoder for the display chain, release any - * HW blocks previously reserved for that use case. - * @rm: DPU Resource Manager handle - * @enc: DRM Encoder handle - * @Return: 0 on Success otherwise -ERROR - */ void dpu_rm_release(struct dpu_global_state *global_state, struct drm_encoder *enc); -/** - * Get hw resources of the given type that are assigned to this encoder. - */ int dpu_rm_get_assigned_resources(struct dpu_rm *rm, struct dpu_global_state *global_state, uint32_t enc_id, enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size); -/** - * dpu_rm_print_state - output the RM private state - * @p: DRM printer - * @global_state: global state - */ void dpu_rm_print_state(struct drm_printer *p, const struct dpu_global_state *global_state); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c index 47c02b98eac3..2a551e455aa3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c @@ -204,6 +204,11 @@ void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms, vbif->ops.set_halt_ctrl(vbif, params->xin_id, false); } +/** + * dpu_vbif_set_qos_remap - set QoS priority level remap + * @dpu_kms: DPU handler + * @params: Pointer to QoS configuration parameters + */ void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms, struct dpu_vbif_set_qos_params *params) { @@ -245,6 +250,10 @@ void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms, } } +/** + * dpu_vbif_clear_errors - clear any vbif errors + * @dpu_kms: DPU handler + */ void dpu_vbif_clear_errors(struct dpu_kms *dpu_kms) { struct dpu_hw_vbif *vbif; @@ -262,6 +271,10 @@ void dpu_vbif_clear_errors(struct dpu_kms *dpu_kms) } } +/** + * dpu_vbif_init_memtypes - initialize xin memory types for vbif + * @dpu_kms: DPU handler + */ void dpu_vbif_init_memtypes(struct dpu_kms *dpu_kms) { struct dpu_hw_vbif *vbif; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.h index e1b1f7f4e4be..62e47ae1e3ee 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.h @@ -38,32 +38,14 @@ struct dpu_vbif_set_qos_params { bool is_rt; }; -/** - * dpu_vbif_set_ot_limit - set OT limit for vbif client - * @dpu_kms: DPU handler - * @params: Pointer to OT configuration parameters - */ void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms, struct dpu_vbif_set_ot_params *params); -/** - * dpu_vbif_set_qos_remap - set QoS priority level remap - * @dpu_kms: DPU handler - * @params: Pointer to QoS configuration parameters - */ void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms, struct dpu_vbif_set_qos_params *params); -/** - * dpu_vbif_clear_errors - clear any vbif errors - * @dpu_kms: DPU handler - */ void dpu_vbif_clear_errors(struct dpu_kms *dpu_kms); -/** - * dpu_vbif_init_memtypes - initialize xin memory types for vbif - * @dpu_kms: DPU handler - */ void dpu_vbif_init_memtypes(struct dpu_kms *dpu_kms); void dpu_debugfs_vbif_init(struct dpu_kms *dpu_kms, struct dentry *debugfs_root); diff --git a/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c b/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c index 4d55e3cf570f..07a2c1e87219 100644 --- a/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c +++ b/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c @@ -25,24 +25,21 @@ static void msm_disp_state_dump_regs(u32 **reg, u32 aligned_len, void __iomem *b addr = base_addr; end_addr = base_addr + aligned_len; - if (!(*reg)) - *reg = kvzalloc(len_padded, GFP_KERNEL); - - if (*reg) - dump_addr = *reg; + *reg = kvzalloc(len_padded, GFP_KERNEL); + if (!*reg) + return; + dump_addr = *reg; for (i = 0; i < num_rows; i++) { x0 = (addr < end_addr) ? readl_relaxed(addr + 0x0) : 0; x4 = (addr + 0x4 < end_addr) ? readl_relaxed(addr + 0x4) : 0; x8 = (addr + 0x8 < end_addr) ? readl_relaxed(addr + 0x8) : 0; xc = (addr + 0xc < end_addr) ? readl_relaxed(addr + 0xc) : 0; - if (dump_addr) { - dump_addr[i * 4] = x0; - dump_addr[i * 4 + 1] = x4; - dump_addr[i * 4 + 2] = x8; - dump_addr[i * 4 + 3] = xc; - } + dump_addr[i * 4] = x0; + dump_addr[i * 4 + 1] = x4; + dump_addr[i * 4 + 2] = x8; + dump_addr[i * 4 + 3] = xc; addr += REG_DUMP_ALIGN; } |