diff options
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c | 25 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_hw_catalog.h | 5 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_hw_wb.c | 25 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_hw_wb.h | 4 |
4 files changed, 52 insertions, 7 deletions
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c index f279a2817ca4..980dea5f3bfd 100644 --- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c +++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c @@ -217,13 +217,25 @@ static void sde_encoder_phys_wb_setup_fb(struct sde_encoder_phys *phys_enc, SDE_ERROR("failed to get format %x\n", format->pixel_format); return; } + wb_cfg->roi = *wb_roi; - ret = sde_format_populate_layout_with_roi(mmu_id, fb, wb_roi, + if (hw_wb->caps->features & BIT(SDE_WB_XY_ROI_OFFSET)) { + ret = sde_format_populate_layout(mmu_id, fb, &wb_cfg->dest); + if (ret) { + SDE_DEBUG("failed to populate layout %d\n", ret); + return; + } + wb_cfg->dest.width = fb->width; + wb_cfg->dest.height = fb->height; + wb_cfg->dest.num_planes = wb_cfg->dest.format->num_planes; + } else { + ret = sde_format_populate_layout_with_roi(mmu_id, fb, wb_roi, &wb_cfg->dest); - if (ret) { - /* this error should be detected during atomic_check */ - SDE_DEBUG("failed to populate layout %d\n", ret); - return; + if (ret) { + /* this error should be detected during atomic_check */ + SDE_DEBUG("failed to populate layout %d\n", ret); + return; + } } if ((wb_cfg->dest.format->fetch_planes == SDE_PLANE_PLANAR) && @@ -241,6 +253,9 @@ static void sde_encoder_phys_wb_setup_fb(struct sde_encoder_phys *phys_enc, wb_cfg->dest.plane_pitch[2], wb_cfg->dest.plane_pitch[3]); + if (hw_wb->ops.setup_roi) + hw_wb->ops.setup_roi(hw_wb, wb_cfg); + if (hw_wb->ops.setup_outformat) hw_wb->ops.setup_outformat(hw_wb, wb_cfg); diff --git a/drivers/gpu/drm/msm/sde/sde_hw_catalog.h b/drivers/gpu/drm/msm/sde/sde_hw_catalog.h index 6bdc20507eaf..9d344d5282cb 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_catalog.h +++ b/drivers/gpu/drm/msm/sde/sde_hw_catalog.h @@ -175,9 +175,11 @@ enum { * @SDE_WB_TRAFFIC_SHAPER, Writeback traffic shaper bloc * @SDE_WB_UBWC_1_0, Writeback Universal bandwidth compression 1.0 * support - * @SDE_WB_WBWC_1_5 UBWC 1.5 support + * @SDE_WB_UBWC_1_5 UBWC 1.5 support * @SDE_WB_YUV_CONFIG Writeback supports output of YUV colorspace * @SDE_WB_PIPE_ALPHA Writeback supports pipe alpha + * @SDE_WB_XY_ROI_OFFSET Writeback supports x/y-offset of out ROI in + * the destination image * @SDE_WB_MAX maximum value */ enum { @@ -192,6 +194,7 @@ enum { SDE_WB_UBWC_1_0, SDE_WB_YUV_CONFIG, SDE_WB_PIPE_ALPHA, + SDE_WB_XY_ROI_OFFSET, SDE_WB_MAX }; diff --git a/drivers/gpu/drm/msm/sde/sde_hw_wb.c b/drivers/gpu/drm/msm/sde/sde_hw_wb.c index 60141dcf9be5..3c7f2fe843aa 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_wb.c +++ b/drivers/gpu/drm/msm/sde/sde_hw_wb.c @@ -43,6 +43,8 @@ #define WB_CSC_BASE 0x260 #define WB_DST_ADDR_SW_STATUS 0x2B0 #define WB_CDP_CTRL 0x2B4 +#define WB_OUT_IMAGE_SIZE 0x2C0 +#define WB_OUT_XY 0x2C4 static struct sde_wb_cfg *_wb_offset(enum sde_wb wb, struct sde_mdss_cfg *m, @@ -119,7 +121,11 @@ static void sde_hw_wb_setup_format(struct sde_hw_wb *ctx, (data->dest.plane_pitch[1] << 16); ystride1 = data->dest.plane_pitch[2] | (data->dest.plane_pitch[3] << 16); - outsize = (data->dest.height << 16) | data->dest.width; + + if (data->roi.h && data->roi.w) + outsize = (data->roi.h << 16) | data->roi.w; + else + outsize = (data->dest.height << 16) | data->dest.width; if (SDE_FORMAT_IS_UBWC(fmt)) { opmode |= BIT(0); @@ -164,6 +170,20 @@ static void sde_hw_wb_traffic_shaper(struct sde_hw_wb *ctx, &data->ts_cfg); } +static void sde_hw_wb_roi(struct sde_hw_wb *ctx, struct sde_hw_wb_cfg *wb) +{ + struct sde_hw_blk_reg_map *c = &ctx->hw; + u32 image_size, out_size, out_xy; + + image_size = (wb->dest.height << 16) | wb->dest.width; + out_xy = (wb->roi.y << 16) | wb->roi.x; + out_size = (wb->roi.h << 16) | wb->roi.w; + + SDE_REG_WRITE(c, WB_OUT_IMAGE_SIZE, image_size); + SDE_REG_WRITE(c, WB_OUT_XY, out_xy); + SDE_REG_WRITE(c, WB_OUT_SIZE, out_size); +} + static void _setup_wb_ops(struct sde_hw_wb_ops *ops, unsigned long features) { @@ -172,6 +192,9 @@ static void _setup_wb_ops(struct sde_hw_wb_ops *ops, if (test_bit(SDE_WB_TRAFFIC_SHAPER, &features)) ops->setup_trafficshaper = sde_hw_wb_traffic_shaper; + + if (test_bit(SDE_WB_XY_ROI_OFFSET, &features)) + ops->setup_roi = sde_hw_wb_roi; } struct sde_hw_wb *sde_hw_wb_init(enum sde_wb idx, diff --git a/drivers/gpu/drm/msm/sde/sde_hw_wb.h b/drivers/gpu/drm/msm/sde/sde_hw_wb.h index e01750baf950..52a5ee5b06a5 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_wb.h +++ b/drivers/gpu/drm/msm/sde/sde_hw_wb.h @@ -24,6 +24,7 @@ struct sde_hw_wb_cfg { struct sde_hw_fmt_layout dest; enum sde_intf_mode intf_mode; struct traffic_shaper_cfg ts_cfg; + struct sde_rect roi; bool is_secure; }; @@ -53,6 +54,9 @@ struct sde_hw_wb_ops { void (*setup_trafficshaper)(struct sde_hw_wb *ctx, struct sde_hw_wb_cfg *wb); + + void (*setup_roi)(struct sde_hw_wb *ctx, + struct sde_hw_wb_cfg *wb); }; /** |
