Skip to content

Commit 89578d0

Browse files
Alexandru Gheorghedliviu
authored andcommitted
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>
1 parent 69be198 commit 89578d0

File tree

4 files changed

+48
-7
lines changed

4 files changed

+48
-7
lines changed

drivers/gpu/drm/arm/malidp_hw.c

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,8 @@ static long malidp500_se_calc_mclk(struct malidp_hw_device *hwdev,
384384

385385
static int malidp500_enable_memwrite(struct malidp_hw_device *hwdev,
386386
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)
388389
{
389390
u32 base = MALIDP500_SE_MEMWRITE_BASE;
390391
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,
416417

417418
malidp_hw_write(hwdev, MALIDP_DE_H_ACTIVE(w) | MALIDP_DE_V_ACTIVE(h),
418419
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+
419430
malidp_hw_setbits(hwdev, MALIDP_SE_MEMWRITE_EN, MALIDP500_SE_CONTROL);
420431

421432
return 0;
@@ -658,7 +669,8 @@ static long malidp550_se_calc_mclk(struct malidp_hw_device *hwdev,
658669

659670
static int malidp550_enable_memwrite(struct malidp_hw_device *hwdev,
660671
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)
662674
{
663675
u32 base = MALIDP550_SE_MEMWRITE_BASE;
664676
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,
689701
malidp_hw_setbits(hwdev, MALIDP550_SE_MEMWRITE_ONESHOT | MALIDP_SE_MEMWRITE_EN,
690702
MALIDP550_SE_CONTROL);
691703

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+
692713
return 0;
693714
}
694715

drivers/gpu/drm/arm/malidp_hw.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,8 @@ struct malidp_hw {
191191
* @param fmt_id - internal format ID of output buffer
192192
*/
193193
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);
195196

196197
/*
197198
* Disable the writing to memory of the next frame's content.

drivers/gpu/drm/arm/malidp_mw.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ struct malidp_mw_connector_state {
2626
s32 pitches[2];
2727
u8 format;
2828
u8 n_planes;
29+
bool rgb2yuv_initialized;
30+
const s16 *rgb2yuv_coeffs;
2931
};
3032

3133
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)
8486
static struct drm_connector_state *
8587
malidp_mw_connector_duplicate_state(struct drm_connector *connector)
8688
{
87-
struct malidp_mw_connector_state *mw_state;
89+
struct malidp_mw_connector_state *mw_state, *mw_current_state;
8890

8991
if (WARN_ON(!connector->state))
9092
return NULL;
@@ -93,7 +95,10 @@ malidp_mw_connector_duplicate_state(struct drm_connector *connector)
9395
if (!mw_state)
9496
return NULL;
9597

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+
97102
__drm_atomic_helper_connector_duplicate_state(connector, &mw_state->base);
98103

99104
return &mw_state->base;
@@ -108,6 +113,13 @@ static const struct drm_connector_funcs malidp_mw_connector_funcs = {
108113
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
109114
};
110115

116+
static 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+
111123
static int
112124
malidp_mw_encoder_atomic_check(struct drm_encoder *encoder,
113125
struct drm_crtc_state *crtc_state,
@@ -157,6 +169,9 @@ malidp_mw_encoder_atomic_check(struct drm_encoder *encoder,
157169
}
158170
mw_state->n_planes = n_planes;
159171

172+
if (fb->format->is_yuv)
173+
mw_state->rgb2yuv_coeffs = rgb2yuv_coeffs_bt709_limited;
174+
160175
return 0;
161176
}
162177

@@ -239,10 +254,12 @@ void malidp_mw_atomic_commit(struct drm_device *drm,
239254

240255
drm_writeback_queue_job(mw_conn, conn_state->writeback_job);
241256
conn_state->writeback_job = NULL;
242-
243257
hwdev->hw->enable_memwrite(hwdev, mw_state->addrs,
244258
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;
246263
} else {
247264
DRM_DEV_DEBUG_DRIVER(drm->dev, "Disable memwrite\n");
248265
hwdev->hw->disable_memwrite(hwdev);

drivers/gpu/drm/arm/malidp_regs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@
205205
#define MALIDP500_SE_BASE 0x00c00
206206
#define MALIDP500_SE_CONTROL 0x00c0c
207207
#define MALIDP500_SE_MEMWRITE_OUT_SIZE 0x00c2c
208+
#define MALIDP500_SE_RGB_YUV_COEFFS 0x00C74
208209
#define MALIDP500_SE_MEMWRITE_BASE 0x00e00
209210
#define MALIDP500_DC_IRQ_BASE 0x00f00
210211
#define MALIDP500_CONFIG_VALID 0x00f00
@@ -238,6 +239,7 @@
238239
#define MALIDP550_SE_CONTROL 0x08010
239240
#define MALIDP550_SE_MEMWRITE_ONESHOT (1 << 7)
240241
#define MALIDP550_SE_MEMWRITE_OUT_SIZE 0x08030
242+
#define MALIDP550_SE_RGB_YUV_COEFFS 0x08078
241243
#define MALIDP550_SE_MEMWRITE_BASE 0x08100
242244
#define MALIDP550_DC_BASE 0x0c000
243245
#define MALIDP550_DC_CONTROL 0x0c010

0 commit comments

Comments
 (0)