summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c25
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_catalog.h5
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_wb.c25
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_wb.h4
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);
};
/**