diff options
-rw-r--r-- | drivers/gpu/drm/imx/dpu/dpu-plane.c | 6 | ||||
-rw-r--r-- | drivers/gpu/imx/dpu/dpu-fetchdecode.c | 19 | ||||
-rw-r--r-- | drivers/gpu/imx/dpu/dpu-fetchunit.c | 25 | ||||
-rw-r--r-- | include/video/dpu.h | 10 |
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); |