aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>2018-08-22 11:18:19 -0400
committerLiviu Dudau <Liviu.Dudau@arm.com>2018-10-02 06:54:26 -0400
commitb11507815d1be0173e27990ffcae6da58eadbc10 (patch)
tree1ec4ce0f8c2ebf0df24bc795a58863dbe9165b24
parentcabce6343fdff516f954c367d0d57dd566244942 (diff)
drm/malidp: Fix writeback in NV12
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@arm.com> Acked-by: Liviu Dudau <liviu.dudau@arm.com> Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
-rw-r--r--drivers/gpu/drm/arm/malidp_hw.c25
-rw-r--r--drivers/gpu/drm/arm/malidp_hw.h3
-rw-r--r--drivers/gpu/drm/arm/malidp_mw.c25
-rw-r--r--drivers/gpu/drm/arm/malidp_regs.h2
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,
384 384
385static int malidp500_enable_memwrite(struct malidp_hw_device *hwdev, 385static int malidp500_enable_memwrite(struct malidp_hw_device *hwdev,
386 dma_addr_t *addrs, s32 *pitches, 386 dma_addr_t *addrs, s32 *pitches,
387 int num_planes, u16 w, u16 h, u32 fmt_id) 387 int num_planes, u16 w, u16 h, u32 fmt_id,
388 const s16 *rgb2yuv_coeffs)
388{ 389{
389 u32 base = MALIDP500_SE_MEMWRITE_BASE; 390 u32 base = MALIDP500_SE_MEMWRITE_BASE;
390 u32 de_base = malidp_get_block_base(hwdev, MALIDP_DE_BLOCK); 391 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,
416 417
417 malidp_hw_write(hwdev, MALIDP_DE_H_ACTIVE(w) | MALIDP_DE_V_ACTIVE(h), 418 malidp_hw_write(hwdev, MALIDP_DE_H_ACTIVE(w) | MALIDP_DE_V_ACTIVE(h),
418 MALIDP500_SE_MEMWRITE_OUT_SIZE); 419 MALIDP500_SE_MEMWRITE_OUT_SIZE);
420
421 if (rgb2yuv_coeffs) {
422 int i;
423
424 for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; i++) {
425 malidp_hw_write(hwdev, rgb2yuv_coeffs[i],
426 MALIDP500_SE_RGB_YUV_COEFFS + i * 4);
427 }
428 }
429
419 malidp_hw_setbits(hwdev, MALIDP_SE_MEMWRITE_EN, MALIDP500_SE_CONTROL); 430 malidp_hw_setbits(hwdev, MALIDP_SE_MEMWRITE_EN, MALIDP500_SE_CONTROL);
420 431
421 return 0; 432 return 0;
@@ -658,7 +669,8 @@ static long malidp550_se_calc_mclk(struct malidp_hw_device *hwdev,
658 669
659static int malidp550_enable_memwrite(struct malidp_hw_device *hwdev, 670static int malidp550_enable_memwrite(struct malidp_hw_device *hwdev,
660 dma_addr_t *addrs, s32 *pitches, 671 dma_addr_t *addrs, s32 *pitches,
661 int num_planes, u16 w, u16 h, u32 fmt_id) 672 int num_planes, u16 w, u16 h, u32 fmt_id,
673 const s16 *rgb2yuv_coeffs)
662{ 674{
663 u32 base = MALIDP550_SE_MEMWRITE_BASE; 675 u32 base = MALIDP550_SE_MEMWRITE_BASE;
664 u32 de_base = malidp_get_block_base(hwdev, MALIDP_DE_BLOCK); 676 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,
689 malidp_hw_setbits(hwdev, MALIDP550_SE_MEMWRITE_ONESHOT | MALIDP_SE_MEMWRITE_EN, 701 malidp_hw_setbits(hwdev, MALIDP550_SE_MEMWRITE_ONESHOT | MALIDP_SE_MEMWRITE_EN,
690 MALIDP550_SE_CONTROL); 702 MALIDP550_SE_CONTROL);
691 703
704 if (rgb2yuv_coeffs) {
705 int i;
706
707 for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; i++) {
708 malidp_hw_write(hwdev, rgb2yuv_coeffs[i],
709 MALIDP550_SE_RGB_YUV_COEFFS + i * 4);
710 }
711 }
712
692 return 0; 713 return 0;
693} 714}
694 715
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 {
191 * @param fmt_id - internal format ID of output buffer 191 * @param fmt_id - internal format ID of output buffer
192 */ 192 */
193 int (*enable_memwrite)(struct malidp_hw_device *hwdev, dma_addr_t *addrs, 193 int (*enable_memwrite)(struct malidp_hw_device *hwdev, dma_addr_t *addrs,
194 s32 *pitches, int num_planes, u16 w, u16 h, u32 fmt_id); 194 s32 *pitches, int num_planes, u16 w, u16 h, u32 fmt_id,
195 const s16 *rgb2yuv_coeffs);
195 196
196 /* 197 /*
197 * Disable the writing to memory of the next frame's content. 198 * 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 ba6ae66387c9..91472e5e0c8b 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 {
26 s32 pitches[2]; 26 s32 pitches[2];
27 u8 format; 27 u8 format;
28 u8 n_planes; 28 u8 n_planes;
29 bool rgb2yuv_initialized;
30 const s16 *rgb2yuv_coeffs;
29}; 31};
30 32
31static int malidp_mw_connector_get_modes(struct drm_connector *connector) 33static int malidp_mw_connector_get_modes(struct drm_connector *connector)
@@ -84,7 +86,7 @@ static void malidp_mw_connector_destroy(struct drm_connector *connector)
84static struct drm_connector_state * 86static struct drm_connector_state *
85malidp_mw_connector_duplicate_state(struct drm_connector *connector) 87malidp_mw_connector_duplicate_state(struct drm_connector *connector)
86{ 88{
87 struct malidp_mw_connector_state *mw_state; 89 struct malidp_mw_connector_state *mw_state, *mw_current_state;
88 90
89 if (WARN_ON(!connector->state)) 91 if (WARN_ON(!connector->state))
90 return NULL; 92 return NULL;
@@ -93,7 +95,10 @@ malidp_mw_connector_duplicate_state(struct drm_connector *connector)
93 if (!mw_state) 95 if (!mw_state)
94 return NULL; 96 return NULL;
95 97
96 /* No need to preserve any of our driver-local data */ 98 mw_current_state = to_mw_state(connector->state);
99 mw_state->rgb2yuv_coeffs = mw_current_state->rgb2yuv_coeffs;
100 mw_state->rgb2yuv_initialized = mw_current_state->rgb2yuv_initialized;
101
97 __drm_atomic_helper_connector_duplicate_state(connector, &mw_state->base); 102 __drm_atomic_helper_connector_duplicate_state(connector, &mw_state->base);
98 103
99 return &mw_state->base; 104 return &mw_state->base;
@@ -108,6 +113,13 @@ static const struct drm_connector_funcs malidp_mw_connector_funcs = {
108 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 113 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
109}; 114};
110 115
116static const s16 rgb2yuv_coeffs_bt709_limited[MALIDP_COLORADJ_NUM_COEFFS] = {
117 47, 157, 16,
118 -26, -87, 112,
119 112, -102, -10,
120 16, 128, 128
121};
122
111static int 123static int
112malidp_mw_encoder_atomic_check(struct drm_encoder *encoder, 124malidp_mw_encoder_atomic_check(struct drm_encoder *encoder,
113 struct drm_crtc_state *crtc_state, 125 struct drm_crtc_state *crtc_state,
@@ -157,6 +169,9 @@ malidp_mw_encoder_atomic_check(struct drm_encoder *encoder,
157 } 169 }
158 mw_state->n_planes = n_planes; 170 mw_state->n_planes = n_planes;
159 171
172 if (fb->format->is_yuv)
173 mw_state->rgb2yuv_coeffs = rgb2yuv_coeffs_bt709_limited;
174
160 return 0; 175 return 0;
161} 176}
162 177
@@ -239,10 +254,12 @@ void malidp_mw_atomic_commit(struct drm_device *drm,
239 254
240 drm_writeback_queue_job(mw_conn, conn_state->writeback_job); 255 drm_writeback_queue_job(mw_conn, conn_state->writeback_job);
241 conn_state->writeback_job = NULL; 256 conn_state->writeback_job = NULL;
242
243 hwdev->hw->enable_memwrite(hwdev, mw_state->addrs, 257 hwdev->hw->enable_memwrite(hwdev, mw_state->addrs,
244 mw_state->pitches, mw_state->n_planes, 258 mw_state->pitches, mw_state->n_planes,
245 fb->width, fb->height, mw_state->format); 259 fb->width, fb->height, mw_state->format,
260 !mw_state->rgb2yuv_initialized ?
261 mw_state->rgb2yuv_coeffs : NULL);
262 mw_state->rgb2yuv_initialized = !!mw_state->rgb2yuv_coeffs;
246 } else { 263 } else {
247 DRM_DEV_DEBUG_DRIVER(drm->dev, "Disable memwrite\n"); 264 DRM_DEV_DEBUG_DRIVER(drm->dev, "Disable memwrite\n");
248 hwdev->hw->disable_memwrite(hwdev); 265 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 @@
205#define MALIDP500_SE_BASE 0x00c00 205#define MALIDP500_SE_BASE 0x00c00
206#define MALIDP500_SE_CONTROL 0x00c0c 206#define MALIDP500_SE_CONTROL 0x00c0c
207#define MALIDP500_SE_MEMWRITE_OUT_SIZE 0x00c2c 207#define MALIDP500_SE_MEMWRITE_OUT_SIZE 0x00c2c
208#define MALIDP500_SE_RGB_YUV_COEFFS 0x00C74
208#define MALIDP500_SE_MEMWRITE_BASE 0x00e00 209#define MALIDP500_SE_MEMWRITE_BASE 0x00e00
209#define MALIDP500_DC_IRQ_BASE 0x00f00 210#define MALIDP500_DC_IRQ_BASE 0x00f00
210#define MALIDP500_CONFIG_VALID 0x00f00 211#define MALIDP500_CONFIG_VALID 0x00f00
@@ -238,6 +239,7 @@
238#define MALIDP550_SE_CONTROL 0x08010 239#define MALIDP550_SE_CONTROL 0x08010
239#define MALIDP550_SE_MEMWRITE_ONESHOT (1 << 7) 240#define MALIDP550_SE_MEMWRITE_ONESHOT (1 << 7)
240#define MALIDP550_SE_MEMWRITE_OUT_SIZE 0x08030 241#define MALIDP550_SE_MEMWRITE_OUT_SIZE 0x08030
242#define MALIDP550_SE_RGB_YUV_COEFFS 0x08078
241#define MALIDP550_SE_MEMWRITE_BASE 0x08100 243#define MALIDP550_SE_MEMWRITE_BASE 0x08100
242#define MALIDP550_DC_BASE 0x0c000 244#define MALIDP550_DC_BASE 0x0c000
243#define MALIDP550_DC_CONTROL 0x0c010 245#define MALIDP550_DC_CONTROL 0x0c010