[PATCH v2] drm/malidp: Fix writeback in NV12
Liviu Dudau
liviu.dudau at arm.com
Thu Aug 23 15:41:49 UTC 2018
On Wed, Aug 22, 2018 at 04:18:19PM +0100, Alexandru Gheorghe wrote:
> When we want to writeback to memory in NV12 format we need to program
> the RGB2YUV coefficients. Currently, we don't program the coefficients
> and NV12 doesn't work at all.
>
> This patchset fixes that by programming a sane default(bt709, limited
> range) as rgb2yuv coefficients.
>
> In the long run, probably we need to think of a way for userspace to
> be able to program that, but for now I think this is better than not
> working at all or not advertising NV12 as a supported format for
> memwrite.
>
> Changes since v1:
> - Write the rgb2yuv coefficients only once, since we don't change
> them at all, just write them the first time NV12 is programmed,
> suggested by Brian Starkey, here [1]
>
> [1] https://lists.freedesktop.org/archives/dri-devel/2018-August/186819.html
>
> Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe at arm.com>
Acked-by: Liviu Dudau <liviu.dudau at arm.com>
> ---
> drivers/gpu/drm/arm/malidp_hw.c | 25 +++++++++++++++++++++++--
> drivers/gpu/drm/arm/malidp_hw.h | 3 ++-
> drivers/gpu/drm/arm/malidp_mw.c | 25 +++++++++++++++++++++----
> drivers/gpu/drm/arm/malidp_regs.h | 2 ++
> 4 files changed, 48 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
> index c94a4422e0e9..2781e462c1ed 100644
> --- a/drivers/gpu/drm/arm/malidp_hw.c
> +++ b/drivers/gpu/drm/arm/malidp_hw.c
> @@ -384,7 +384,8 @@ static long malidp500_se_calc_mclk(struct malidp_hw_device *hwdev,
>
> static int malidp500_enable_memwrite(struct malidp_hw_device *hwdev,
> dma_addr_t *addrs, s32 *pitches,
> - int num_planes, u16 w, u16 h, u32 fmt_id)
> + int num_planes, u16 w, u16 h, u32 fmt_id,
> + const s16 *rgb2yuv_coeffs)
> {
> u32 base = MALIDP500_SE_MEMWRITE_BASE;
> u32 de_base = malidp_get_block_base(hwdev, MALIDP_DE_BLOCK);
> @@ -416,6 +417,16 @@ static int malidp500_enable_memwrite(struct malidp_hw_device *hwdev,
>
> malidp_hw_write(hwdev, MALIDP_DE_H_ACTIVE(w) | MALIDP_DE_V_ACTIVE(h),
> MALIDP500_SE_MEMWRITE_OUT_SIZE);
> +
> + if (rgb2yuv_coeffs) {
> + int i;
> +
> + for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; i++) {
> + malidp_hw_write(hwdev, rgb2yuv_coeffs[i],
> + MALIDP500_SE_RGB_YUV_COEFFS + i * 4);
> + }
> + }
> +
> malidp_hw_setbits(hwdev, MALIDP_SE_MEMWRITE_EN, MALIDP500_SE_CONTROL);
>
> return 0;
> @@ -658,7 +669,8 @@ static long malidp550_se_calc_mclk(struct malidp_hw_device *hwdev,
>
> static int malidp550_enable_memwrite(struct malidp_hw_device *hwdev,
> dma_addr_t *addrs, s32 *pitches,
> - int num_planes, u16 w, u16 h, u32 fmt_id)
> + int num_planes, u16 w, u16 h, u32 fmt_id,
> + const s16 *rgb2yuv_coeffs)
> {
> u32 base = MALIDP550_SE_MEMWRITE_BASE;
> u32 de_base = malidp_get_block_base(hwdev, MALIDP_DE_BLOCK);
> @@ -689,6 +701,15 @@ static int malidp550_enable_memwrite(struct malidp_hw_device *hwdev,
> malidp_hw_setbits(hwdev, MALIDP550_SE_MEMWRITE_ONESHOT | MALIDP_SE_MEMWRITE_EN,
> MALIDP550_SE_CONTROL);
>
> + if (rgb2yuv_coeffs) {
> + int i;
> +
> + for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; i++) {
> + malidp_hw_write(hwdev, rgb2yuv_coeffs[i],
> + MALIDP550_SE_RGB_YUV_COEFFS + i * 4);
> + }
> + }
> +
> return 0;
> }
>
> diff --git a/drivers/gpu/drm/arm/malidp_hw.h b/drivers/gpu/drm/arm/malidp_hw.h
> index ad2e96915d44..9fc94c08190f 100644
> --- a/drivers/gpu/drm/arm/malidp_hw.h
> +++ b/drivers/gpu/drm/arm/malidp_hw.h
> @@ -191,7 +191,8 @@ struct malidp_hw {
> * @param fmt_id - internal format ID of output buffer
> */
> int (*enable_memwrite)(struct malidp_hw_device *hwdev, dma_addr_t *addrs,
> - s32 *pitches, int num_planes, u16 w, u16 h, u32 fmt_id);
> + s32 *pitches, int num_planes, u16 w, u16 h, u32 fmt_id,
> + const s16 *rgb2yuv_coeffs);
>
> /*
> * Disable the writing to memory of the next frame's content.
> diff --git a/drivers/gpu/drm/arm/malidp_mw.c b/drivers/gpu/drm/arm/malidp_mw.c
> index cfd718e7e97c..429a11e6473b 100644
> --- a/drivers/gpu/drm/arm/malidp_mw.c
> +++ b/drivers/gpu/drm/arm/malidp_mw.c
> @@ -26,6 +26,8 @@ struct malidp_mw_connector_state {
> s32 pitches[2];
> u8 format;
> u8 n_planes;
> + bool rgb2yuv_initialized;
> + const s16 *rgb2yuv_coeffs;
> };
>
> static int malidp_mw_connector_get_modes(struct drm_connector *connector)
> @@ -84,7 +86,7 @@ static void malidp_mw_connector_destroy(struct drm_connector *connector)
> static struct drm_connector_state *
> malidp_mw_connector_duplicate_state(struct drm_connector *connector)
> {
> - struct malidp_mw_connector_state *mw_state;
> + struct malidp_mw_connector_state *mw_state, *mw_current_state;
>
> if (WARN_ON(!connector->state))
> return NULL;
> @@ -93,7 +95,10 @@ malidp_mw_connector_duplicate_state(struct drm_connector *connector)
> if (!mw_state)
> return NULL;
>
> - /* No need to preserve any of our driver-local data */
> + mw_current_state = to_mw_state(connector->state);
> + mw_state->rgb2yuv_coeffs = mw_current_state->rgb2yuv_coeffs;
> + mw_state->rgb2yuv_initialized = mw_current_state->rgb2yuv_initialized;
> +
> __drm_atomic_helper_connector_duplicate_state(connector, &mw_state->base);
>
> return &mw_state->base;
> @@ -108,6 +113,13 @@ static const struct drm_connector_funcs malidp_mw_connector_funcs = {
> .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
> };
>
> +static const s16 rgb2yuv_coeffs_bt709_limited[MALIDP_COLORADJ_NUM_COEFFS] = {
> + 47, 157, 16,
> + -26, -87, 112,
> + 112, -102, -10,
> + 16, 128, 128
> +};
> +
> static int
> malidp_mw_encoder_atomic_check(struct drm_encoder *encoder,
> struct drm_crtc_state *crtc_state,
> @@ -157,6 +169,9 @@ malidp_mw_encoder_atomic_check(struct drm_encoder *encoder,
> }
> mw_state->n_planes = n_planes;
>
> + if (fb->format->is_yuv)
> + mw_state->rgb2yuv_coeffs = rgb2yuv_coeffs_bt709_limited;
> +
> return 0;
> }
>
> @@ -239,10 +254,12 @@ void malidp_mw_atomic_commit(struct drm_device *drm,
>
> drm_writeback_queue_job(mw_conn, conn_state->writeback_job);
> conn_state->writeback_job = NULL;
> -
> hwdev->hw->enable_memwrite(hwdev, mw_state->addrs,
> mw_state->pitches, mw_state->n_planes,
> - fb->width, fb->height, mw_state->format);
> + fb->width, fb->height, mw_state->format,
> + !mw_state->rgb2yuv_initialized ?
> + mw_state->rgb2yuv_coeffs : NULL);
> + mw_state->rgb2yuv_initialized = !!mw_state->rgb2yuv_coeffs;
> } else {
> DRM_DEV_DEBUG_DRIVER(drm->dev, "Disable memwrite\n");
> hwdev->hw->disable_memwrite(hwdev);
> diff --git a/drivers/gpu/drm/arm/malidp_regs.h b/drivers/gpu/drm/arm/malidp_regs.h
> index 3579d36b2a71..6ffe849774f2 100644
> --- a/drivers/gpu/drm/arm/malidp_regs.h
> +++ b/drivers/gpu/drm/arm/malidp_regs.h
> @@ -205,6 +205,7 @@
> #define MALIDP500_SE_BASE 0x00c00
> #define MALIDP500_SE_CONTROL 0x00c0c
> #define MALIDP500_SE_MEMWRITE_OUT_SIZE 0x00c2c
> +#define MALIDP500_SE_RGB_YUV_COEFFS 0x00C74
> #define MALIDP500_SE_MEMWRITE_BASE 0x00e00
> #define MALIDP500_DC_IRQ_BASE 0x00f00
> #define MALIDP500_CONFIG_VALID 0x00f00
> @@ -238,6 +239,7 @@
> #define MALIDP550_SE_CONTROL 0x08010
> #define MALIDP550_SE_MEMWRITE_ONESHOT (1 << 7)
> #define MALIDP550_SE_MEMWRITE_OUT_SIZE 0x08030
> +#define MALIDP550_SE_RGB_YUV_COEFFS 0x08078
> #define MALIDP550_SE_MEMWRITE_BASE 0x08100
> #define MALIDP550_DC_BASE 0x0c000
> #define MALIDP550_DC_CONTROL 0x0c010
> --
> 2.18.0
>
--
====================
| I would like to |
| fix the world, |
| but they're not |
| giving me the |
\ source code! /
---------------
¯\_(ツ)_/¯
More information about the dri-devel
mailing list