diff options
Diffstat (limited to 'drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c')
-rw-r--r-- | drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 187 |
1 files changed, 98 insertions, 89 deletions
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 4246ab0b3bee..cf70a9bd1034 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c @@ -136,7 +136,7 @@ #define TS_CLK 19200000 -static int _sspp_subblk_offset(struct dpu_hw_pipe *ctx, +static int _sspp_subblk_offset(struct dpu_hw_sspp *ctx, int s_id, u32 *idx) { @@ -168,17 +168,16 @@ static int _sspp_subblk_offset(struct dpu_hw_pipe *ctx, return rc; } -static void dpu_hw_sspp_setup_multirect(struct dpu_hw_pipe *ctx, - enum dpu_sspp_multirect_index index, - enum dpu_sspp_multirect_mode mode) +static void dpu_hw_sspp_setup_multirect(struct dpu_sw_pipe *pipe) { + struct dpu_hw_sspp *ctx = pipe->sspp; u32 mode_mask; u32 idx; if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx)) return; - if (index == DPU_SSPP_RECT_SOLO) { + if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) { /** * if rect index is RECT_SOLO, we cannot expect a * virtual plane sharing the same SSPP id. So we go @@ -187,8 +186,8 @@ static void dpu_hw_sspp_setup_multirect(struct dpu_hw_pipe *ctx, mode_mask = 0; } else { mode_mask = DPU_REG_READ(&ctx->hw, SSPP_MULTIRECT_OPMODE + idx); - mode_mask |= index; - if (mode == DPU_SSPP_MULTIRECT_TIME_MX) + mode_mask |= pipe->multirect_index; + if (pipe->multirect_mode == DPU_SSPP_MULTIRECT_TIME_MX) mode_mask |= BIT(2); else mode_mask &= ~BIT(2); @@ -197,7 +196,7 @@ static void dpu_hw_sspp_setup_multirect(struct dpu_hw_pipe *ctx, DPU_REG_WRITE(&ctx->hw, SSPP_MULTIRECT_OPMODE + idx, mode_mask); } -static void _sspp_setup_opmode(struct dpu_hw_pipe *ctx, +static void _sspp_setup_opmode(struct dpu_hw_sspp *ctx, u32 mask, u8 en) { u32 idx; @@ -218,7 +217,7 @@ static void _sspp_setup_opmode(struct dpu_hw_pipe *ctx, DPU_REG_WRITE(&ctx->hw, SSPP_VIG_OP_MODE + idx, opmode); } -static void _sspp_setup_csc10_opmode(struct dpu_hw_pipe *ctx, +static void _sspp_setup_csc10_opmode(struct dpu_hw_sspp *ctx, u32 mask, u8 en) { u32 idx; @@ -239,10 +238,10 @@ static void _sspp_setup_csc10_opmode(struct dpu_hw_pipe *ctx, /* * Setup source pixel format, flip, */ -static void dpu_hw_sspp_setup_format(struct dpu_hw_pipe *ctx, - const struct dpu_format *fmt, u32 flags, - enum dpu_sspp_multirect_index rect_mode) +static void dpu_hw_sspp_setup_format(struct dpu_sw_pipe *pipe, + const struct dpu_format *fmt, u32 flags) { + struct dpu_hw_sspp *ctx = pipe->sspp; struct dpu_hw_blk_reg_map *c; u32 chroma_samp, unpack, src_format; u32 opmode = 0; @@ -253,7 +252,8 @@ static void dpu_hw_sspp_setup_format(struct dpu_hw_pipe *ctx, if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx) || !fmt) return; - if (rect_mode == DPU_SSPP_RECT_SOLO || rect_mode == DPU_SSPP_RECT_0) { + if (pipe->multirect_index == DPU_SSPP_RECT_SOLO || + pipe->multirect_index == DPU_SSPP_RECT_0) { op_mode_off = SSPP_SRC_OP_MODE; unpack_pat_off = SSPP_SRC_UNPACK_PATTERN; format_off = SSPP_SRC_FORMAT; @@ -307,25 +307,25 @@ static void dpu_hw_sspp_setup_format(struct dpu_hw_pipe *ctx, src_format |= (fmt->fetch_mode & 3) << 30; /*FRAME_FORMAT */ DPU_REG_WRITE(c, SSPP_FETCH_CONFIG, DPU_FETCH_CONFIG_RESET_VALUE | - ctx->mdp->highest_bank_bit << 18); - switch (ctx->catalog->caps->ubwc_version) { + ctx->ubwc->highest_bank_bit << 18); + switch (ctx->ubwc->ubwc_version) { case DPU_HW_UBWC_VER_10: fast_clear = fmt->alpha_enable ? BIT(31) : 0; DPU_REG_WRITE(c, SSPP_UBWC_STATIC_CTRL, - fast_clear | (ctx->mdp->ubwc_swizzle & 0x1) | + fast_clear | (ctx->ubwc->ubwc_swizzle & 0x1) | BIT(8) | - (ctx->mdp->highest_bank_bit << 4)); + (ctx->ubwc->highest_bank_bit << 4)); break; case DPU_HW_UBWC_VER_20: fast_clear = fmt->alpha_enable ? BIT(31) : 0; DPU_REG_WRITE(c, SSPP_UBWC_STATIC_CTRL, - fast_clear | (ctx->mdp->ubwc_swizzle) | - (ctx->mdp->highest_bank_bit << 4)); + fast_clear | (ctx->ubwc->ubwc_swizzle) | + (ctx->ubwc->highest_bank_bit << 4)); break; case DPU_HW_UBWC_VER_30: DPU_REG_WRITE(c, SSPP_UBWC_STATIC_CTRL, - BIT(30) | (ctx->mdp->ubwc_swizzle) | - (ctx->mdp->highest_bank_bit << 4)); + BIT(30) | (ctx->ubwc->ubwc_swizzle) | + (ctx->ubwc->highest_bank_bit << 4)); break; case DPU_HW_UBWC_VER_40: DPU_REG_WRITE(c, SSPP_UBWC_STATIC_CTRL, @@ -360,7 +360,7 @@ static void dpu_hw_sspp_setup_format(struct dpu_hw_pipe *ctx, DPU_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS + idx, BIT(31)); } -static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_pipe *ctx, +static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_sspp *ctx, struct dpu_hw_pixel_ext *pe_ext) { struct dpu_hw_blk_reg_map *c; @@ -418,23 +418,22 @@ static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_pipe *ctx, tot_req_pixels[3]); } -static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_pipe *ctx, - struct dpu_hw_pipe_cfg *sspp, - void *scaler_cfg) +static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_sspp *ctx, + struct dpu_hw_scaler3_cfg *scaler3_cfg, + const struct dpu_format *format) { u32 idx; - struct dpu_hw_scaler3_cfg *scaler3_cfg = scaler_cfg; - if (_sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED3, &idx) || !sspp + if (_sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED3, &idx) || !scaler3_cfg) return; dpu_hw_setup_scaler3(&ctx->hw, scaler3_cfg, idx, ctx->cap->sblk->scaler_blk.version, - sspp->layout.format); + format); } -static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_pipe *ctx) +static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_sspp *ctx) { u32 idx; @@ -447,12 +446,12 @@ static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_pipe *ctx) /* * dpu_hw_sspp_setup_rects() */ -static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx, - struct dpu_hw_pipe_cfg *cfg, - enum dpu_sspp_multirect_index rect_index) +static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe *pipe, + struct dpu_sw_pipe_cfg *cfg) { + struct dpu_hw_sspp *ctx = pipe->sspp; struct dpu_hw_blk_reg_map *c; - u32 src_size, src_xy, dst_size, dst_xy, ystride0, ystride1; + u32 src_size, src_xy, dst_size, dst_xy; u32 src_size_off, src_xy_off, out_size_off, out_xy_off; u32 idx; @@ -461,7 +460,8 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx, c = &ctx->hw; - if (rect_index == DPU_SSPP_RECT_SOLO || rect_index == DPU_SSPP_RECT_0) { + if (pipe->multirect_index == DPU_SSPP_RECT_SOLO || + pipe->multirect_index == DPU_SSPP_RECT_0) { src_size_off = SSPP_SRC_SIZE; src_xy_off = SSPP_SRC_XY; out_size_off = SSPP_OUT_SIZE; @@ -482,68 +482,69 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx, dst_size = (drm_rect_height(&cfg->dst_rect) << 16) | drm_rect_width(&cfg->dst_rect); - if (rect_index == DPU_SSPP_RECT_SOLO) { - ystride0 = (cfg->layout.plane_pitch[0]) | - (cfg->layout.plane_pitch[1] << 16); - ystride1 = (cfg->layout.plane_pitch[2]) | - (cfg->layout.plane_pitch[3] << 16); - } else { - ystride0 = DPU_REG_READ(c, SSPP_SRC_YSTRIDE0 + idx); - ystride1 = DPU_REG_READ(c, SSPP_SRC_YSTRIDE1 + idx); - - if (rect_index == DPU_SSPP_RECT_0) { - ystride0 = (ystride0 & 0xFFFF0000) | - (cfg->layout.plane_pitch[0] & 0x0000FFFF); - ystride1 = (ystride1 & 0xFFFF0000)| - (cfg->layout.plane_pitch[2] & 0x0000FFFF); - } else { - ystride0 = (ystride0 & 0x0000FFFF) | - ((cfg->layout.plane_pitch[0] << 16) & - 0xFFFF0000); - ystride1 = (ystride1 & 0x0000FFFF) | - ((cfg->layout.plane_pitch[2] << 16) & - 0xFFFF0000); - } - } - /* rectangle register programming */ DPU_REG_WRITE(c, src_size_off + idx, src_size); DPU_REG_WRITE(c, src_xy_off + idx, src_xy); DPU_REG_WRITE(c, out_size_off + idx, dst_size); DPU_REG_WRITE(c, out_xy_off + idx, dst_xy); - - DPU_REG_WRITE(c, SSPP_SRC_YSTRIDE0 + idx, ystride0); - DPU_REG_WRITE(c, SSPP_SRC_YSTRIDE1 + idx, ystride1); } -static void dpu_hw_sspp_setup_sourceaddress(struct dpu_hw_pipe *ctx, - struct dpu_hw_pipe_cfg *cfg, - enum dpu_sspp_multirect_index rect_mode) +static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe, + struct dpu_hw_fmt_layout *layout) { + struct dpu_hw_sspp *ctx = pipe->sspp; + u32 ystride0, ystride1; int i; u32 idx; if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx)) return; - if (rect_mode == DPU_SSPP_RECT_SOLO) { - for (i = 0; i < ARRAY_SIZE(cfg->layout.plane_addr); i++) + if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) { + for (i = 0; i < ARRAY_SIZE(layout->plane_addr); i++) DPU_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR + idx + i * 0x4, - cfg->layout.plane_addr[i]); - } else if (rect_mode == DPU_SSPP_RECT_0) { + layout->plane_addr[i]); + } else if (pipe->multirect_index == DPU_SSPP_RECT_0) { DPU_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR + idx, - cfg->layout.plane_addr[0]); + layout->plane_addr[0]); DPU_REG_WRITE(&ctx->hw, SSPP_SRC2_ADDR + idx, - cfg->layout.plane_addr[2]); + layout->plane_addr[2]); } else { DPU_REG_WRITE(&ctx->hw, SSPP_SRC1_ADDR + idx, - cfg->layout.plane_addr[0]); + layout->plane_addr[0]); DPU_REG_WRITE(&ctx->hw, SSPP_SRC3_ADDR + idx, - cfg->layout.plane_addr[2]); + layout->plane_addr[2]); } + + if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) { + ystride0 = (layout->plane_pitch[0]) | + (layout->plane_pitch[1] << 16); + ystride1 = (layout->plane_pitch[2]) | + (layout->plane_pitch[3] << 16); + } else { + ystride0 = DPU_REG_READ(&ctx->hw, SSPP_SRC_YSTRIDE0 + idx); + ystride1 = DPU_REG_READ(&ctx->hw, SSPP_SRC_YSTRIDE1 + idx); + + if (pipe->multirect_index == DPU_SSPP_RECT_0) { + ystride0 = (ystride0 & 0xFFFF0000) | + (layout->plane_pitch[0] & 0x0000FFFF); + ystride1 = (ystride1 & 0xFFFF0000)| + (layout->plane_pitch[2] & 0x0000FFFF); + } else { + ystride0 = (ystride0 & 0x0000FFFF) | + ((layout->plane_pitch[0] << 16) & + 0xFFFF0000); + ystride1 = (ystride1 & 0x0000FFFF) | + ((layout->plane_pitch[2] << 16) & + 0xFFFF0000); + } + } + + DPU_REG_WRITE(&ctx->hw, SSPP_SRC_YSTRIDE0 + idx, ystride0); + DPU_REG_WRITE(&ctx->hw, SSPP_SRC_YSTRIDE1 + idx, ystride1); } -static void dpu_hw_sspp_setup_csc(struct dpu_hw_pipe *ctx, +static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx, const struct dpu_csc_cfg *data) { u32 idx; @@ -560,22 +561,28 @@ static void dpu_hw_sspp_setup_csc(struct dpu_hw_pipe *ctx, dpu_hw_csc_setup(&ctx->hw, idx, data, csc10); } -static void dpu_hw_sspp_setup_solidfill(struct dpu_hw_pipe *ctx, u32 color, enum - dpu_sspp_multirect_index rect_index) +static void dpu_hw_sspp_setup_solidfill(struct dpu_sw_pipe *pipe, u32 color) { + struct dpu_hw_sspp *ctx = pipe->sspp; + struct dpu_hw_fmt_layout cfg; u32 idx; if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx)) return; - if (rect_index == DPU_SSPP_RECT_SOLO || rect_index == DPU_SSPP_RECT_0) + /* cleanup source addresses */ + memset(&cfg, 0, sizeof(cfg)); + ctx->ops.setup_sourceaddress(pipe, &cfg); + + if (pipe->multirect_index == DPU_SSPP_RECT_SOLO || + pipe->multirect_index == DPU_SSPP_RECT_0) DPU_REG_WRITE(&ctx->hw, SSPP_SRC_CONSTANT_COLOR + idx, color); else DPU_REG_WRITE(&ctx->hw, SSPP_SRC_CONSTANT_COLOR_REC1 + idx, color); } -static void dpu_hw_sspp_setup_danger_safe_lut(struct dpu_hw_pipe *ctx, +static void dpu_hw_sspp_setup_danger_safe_lut(struct dpu_hw_sspp *ctx, u32 danger_lut, u32 safe_lut) { @@ -588,7 +595,7 @@ static void dpu_hw_sspp_setup_danger_safe_lut(struct dpu_hw_pipe *ctx, DPU_REG_WRITE(&ctx->hw, SSPP_SAFE_LUT + idx, safe_lut); } -static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_pipe *ctx, +static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_sspp *ctx, u64 creq_lut) { u32 idx; @@ -605,7 +612,7 @@ static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_pipe *ctx, } } -static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_pipe *ctx, +static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_sspp *ctx, struct dpu_hw_pipe_qos_cfg *cfg) { u32 idx; @@ -630,10 +637,10 @@ static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_pipe *ctx, DPU_REG_WRITE(&ctx->hw, SSPP_QOS_CTRL + idx, qos_ctrl); } -static void dpu_hw_sspp_setup_cdp(struct dpu_hw_pipe *ctx, - struct dpu_hw_cdp_cfg *cfg, - enum dpu_sspp_multirect_index index) +static void dpu_hw_sspp_setup_cdp(struct dpu_sw_pipe *pipe, + struct dpu_hw_cdp_cfg *cfg) { + struct dpu_hw_sspp *ctx = pipe->sspp; u32 idx; u32 cdp_cntl = 0; u32 cdp_cntl_offset = 0; @@ -644,7 +651,8 @@ static void dpu_hw_sspp_setup_cdp(struct dpu_hw_pipe *ctx, if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx)) return; - if (index == DPU_SSPP_RECT_SOLO || index == DPU_SSPP_RECT_0) + if (pipe->multirect_index == DPU_SSPP_RECT_SOLO || + pipe->multirect_index == DPU_SSPP_RECT_0) cdp_cntl_offset = SSPP_CDP_CNTL; else cdp_cntl_offset = SSPP_CDP_CNTL_REC1; @@ -661,7 +669,7 @@ static void dpu_hw_sspp_setup_cdp(struct dpu_hw_pipe *ctx, DPU_REG_WRITE(&ctx->hw, cdp_cntl_offset, cdp_cntl); } -static void _setup_layer_ops(struct dpu_hw_pipe *c, +static void _setup_layer_ops(struct dpu_hw_sspp *c, unsigned long features) { if (test_bit(DPU_SSPP_SRC, &features)) { @@ -699,7 +707,8 @@ static void _setup_layer_ops(struct dpu_hw_pipe *c, } #ifdef CONFIG_DEBUG_FS -int _dpu_hw_sspp_init_debugfs(struct dpu_hw_pipe *hw_pipe, struct dpu_kms *kms, struct dentry *entry) +int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms, + struct dentry *entry) { const struct dpu_sspp_cfg *cfg = hw_pipe->cap; const struct dpu_sspp_sub_blks *sblk = cfg->sblk; @@ -783,10 +792,10 @@ static const struct dpu_sspp_cfg *_sspp_offset(enum dpu_sspp sspp, return ERR_PTR(-ENOMEM); } -struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx, +struct dpu_hw_sspp *dpu_hw_sspp_init(enum dpu_sspp idx, void __iomem *addr, const struct dpu_mdss_cfg *catalog) { - struct dpu_hw_pipe *hw_pipe; + struct dpu_hw_sspp *hw_pipe; const struct dpu_sspp_cfg *cfg; if (!addr || !catalog) @@ -804,7 +813,7 @@ struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx, /* Assign ops */ hw_pipe->catalog = catalog; - hw_pipe->mdp = &catalog->mdp[0]; + hw_pipe->ubwc = catalog->ubwc; hw_pipe->idx = idx; hw_pipe->cap = cfg; _setup_layer_ops(hw_pipe, hw_pipe->cap->features); @@ -812,7 +821,7 @@ struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx, return hw_pipe; } -void dpu_hw_sspp_destroy(struct dpu_hw_pipe *ctx) +void dpu_hw_sspp_destroy(struct dpu_hw_sspp *ctx) { kfree(ctx); } |