summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/imx/dpu/dpu-plane.c6
-rw-r--r--drivers/gpu/imx/dpu/dpu-fetchdecode.c19
-rw-r--r--drivers/gpu/imx/dpu/dpu-fetchunit.c25
-rw-r--r--include/video/dpu.h10
4 files changed, 54 insertions, 6 deletions
diff --git a/drivers/gpu/drm/imx/dpu/dpu-plane.c b/drivers/gpu/drm/imx/dpu/dpu-plane.c
index 42dbcf61a2c4..1f4a0b332e5b 100644
--- a/drivers/gpu/drm/imx/dpu/dpu-plane.c
+++ b/drivers/gpu/drm/imx/dpu/dpu-plane.c
@@ -423,7 +423,8 @@ static void dpu_plane_atomic_update(struct drm_plane *plane,
fu->ops->set_burstlength(fu, 0, 0, bpp, baseaddr, false);
fu->ops->set_src_bpp(fu, bpp);
- fu->ops->set_src_stride(fu, fb->pitches[0]);
+ fu->ops->set_src_stride(fu, src_w, 0, 0, bpp, fb->pitches[0],
+ baseaddr, false);
fu->ops->set_src_buf_dimensions(fu, src_w, src_h, 0, fb_is_interlaced);
fu->ops->set_fmt(fu, fb->format->format, fb_is_interlaced);
fu->ops->enable_src_buf(fu);
@@ -445,7 +446,8 @@ static void dpu_plane_atomic_update(struct drm_plane *plane,
(fd_dynamic_src_sel_t)fe_id);
fe->ops->set_burstlength(fe, 0, 0, bpp, uv_baseaddr, false);
fe->ops->set_src_bpp(fe, 16);
- fe->ops->set_src_stride(fe, fb->pitches[1]);
+ fe->ops->set_src_stride(fe, src_w, 0, 0, bpp, fb->pitches[1],
+ uv_baseaddr, false);
fe->ops->set_fmt(fe, fb->format->format, fb_is_interlaced);
fe->ops->set_src_buf_dimensions(fe, src_w, src_h,
fb->format->format,
diff --git a/drivers/gpu/imx/dpu/dpu-fetchdecode.c b/drivers/gpu/imx/dpu/dpu-fetchdecode.c
index f5cd810f65ce..471b4221b24b 100644
--- a/drivers/gpu/imx/dpu/dpu-fetchdecode.c
+++ b/drivers/gpu/imx/dpu/dpu-fetchdecode.c
@@ -133,10 +133,27 @@ static void fetchdecode_set_src_bpp(struct dpu_fetchunit *fu, int bpp)
}
static void
-fetchdecode_set_src_stride(struct dpu_fetchunit *fu, unsigned int stride)
+fetchdecode_set_src_stride(struct dpu_fetchunit *fu,
+ unsigned int width, unsigned int x_offset,
+ unsigned int mt_w, int bpp, unsigned int stride,
+ dma_addr_t baddr, bool use_prefetch)
{
+ unsigned int burst_size;
+ bool nonzero_mod = !!mt_w;
u32 val;
+ if (use_prefetch) {
+ /* consider PRG x offset to calculate buffer address */
+ if (nonzero_mod)
+ baddr += (x_offset % mt_w) * (bpp / 8);
+
+ burst_size = fetchunit_burst_size_fixup_tkt343664(baddr);
+
+ stride = width * (bpp / 8);
+ stride = fetchunit_stride_fixup_tkt339017(stride, burst_size,
+ baddr, nonzero_mod);
+ }
+
mutex_lock(&fu->mutex);
val = dpu_fu_read(fu, SOURCEBUFFERATTRIBUTES0);
val &= ~0xffff;
diff --git a/drivers/gpu/imx/dpu/dpu-fetchunit.c b/drivers/gpu/imx/dpu/dpu-fetchunit.c
index f950214bb7d5..8a1bbade7793 100644
--- a/drivers/gpu/imx/dpu/dpu-fetchunit.c
+++ b/drivers/gpu/imx/dpu/dpu-fetchunit.c
@@ -167,10 +167,33 @@ void fetchunit_set_src_bpp(struct dpu_fetchunit *fu, int bpp)
}
EXPORT_SYMBOL_GPL(fetchunit_set_src_bpp);
-void fetchunit_set_src_stride(struct dpu_fetchunit *fu, unsigned int stride)
+/*
+ * The arguments width and bpp are valid only when use_prefetch is true.
+ * For fetcheco, since the pixel format has to be NV12 or NV21 when
+ * use_prefetch is true, we assume width stands for how many UV we have
+ * in bytes for one line, while bpp should be 8bits for every U or V component.
+ */
+void fetchunit_set_src_stride(struct dpu_fetchunit *fu,
+ unsigned int width, unsigned int x_offset,
+ unsigned int mt_w, int bpp, unsigned int stride,
+ dma_addr_t baddr, bool use_prefetch)
{
+ unsigned int burst_size;
+ bool nonzero_mod = !!mt_w;
u32 val;
+ if (use_prefetch) {
+ /* consider PRG x offset to calculate buffer address */
+ if (nonzero_mod)
+ baddr += (x_offset % mt_w) * (bpp / 8);
+
+ burst_size = fetchunit_burst_size_fixup_tkt343664(baddr);
+
+ stride = width * (bpp / 8);
+ stride = fetchunit_stride_fixup_tkt339017(stride, burst_size,
+ baddr, nonzero_mod);
+ }
+
mutex_lock(&fu->mutex);
val = dpu_fu_read(fu, SOURCEBUFFERATTRIBUTES(fu->sub_id));
val &= ~0xffff;
diff --git a/include/video/dpu.h b/include/video/dpu.h
index 9fce4b6a339f..9c4ce0631da3 100644
--- a/include/video/dpu.h
+++ b/include/video/dpu.h
@@ -339,7 +339,10 @@ struct dpu_fetchunit_ops {
void (*set_src_bpp)(struct dpu_fetchunit *fu, int bpp);
- void (*set_src_stride)(struct dpu_fetchunit *fu, unsigned int stride);
+ void (*set_src_stride)(struct dpu_fetchunit *fu,
+ unsigned int width, unsigned int x_offset,
+ unsigned int mt_w, int bpp, unsigned int stride,
+ dma_addr_t baddr, bool use_prefetch);
void (*set_src_buf_dimensions)(struct dpu_fetchunit *fu,
unsigned int w, unsigned int h, u32 fmt,
@@ -587,7 +590,10 @@ void fetchunit_set_baseaddress(struct dpu_fetchunit *fu, unsigned int width,
unsigned int mt_w, unsigned int mt_h,
int bpp, dma_addr_t baddr);
void fetchunit_set_src_bpp(struct dpu_fetchunit *fu, int bpp);
-void fetchunit_set_src_stride(struct dpu_fetchunit *fu, unsigned int stride);
+void fetchunit_set_src_stride(struct dpu_fetchunit *fu,
+ unsigned int width, unsigned int x_offset,
+ unsigned int mt_w, int bpp, unsigned int stride,
+ dma_addr_t baddr, bool use_prefetch);
void fetchunit_enable_src_buf(struct dpu_fetchunit *fu);
void fetchunit_disable_src_buf(struct dpu_fetchunit *fu);
bool fetchunit_is_enabled(struct dpu_fetchunit *fu);