aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMihail Atanassov <mihail.atanassov@arm.com>2017-11-07 10:30:46 -0500
committerLiviu Dudau <Liviu.Dudau@arm.com>2018-03-14 07:41:01 -0400
commit6e810eb508f4b937bc2a718bd4e5cd74cca55500 (patch)
tree810d91419b893a863a4a5e2853ff0031ed8c1ae6 /drivers
parent57085dca982bd042f64aa23f5e03747595b2c8c0 (diff)
drm: mali-dp: Add YUV->RGB conversion support for video layers
Internally Mali DP uses an RGB pipeline so video layers that support YUV input buffers need to convert the input data to RGB. The YUV buffers can have various encodings and this patch introduces support for BT.601, BT.709 and BT.2020 encodings, both limited and full ranges. This patch adds support for specifying the color encoding of the input buffers for the planes that are backed by the video layers and programs the YUV2RGB coefficients into hardware based on the selected encoding. Signed-off-by: Mihail Atanassov <mihail.atanassov@arm.com> [updated to use standard properties] Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/arm/malidp_hw.c14
-rw-r--r--drivers/gpu/drm/arm/malidp_hw.h3
-rw-r--r--drivers/gpu/drm/arm/malidp_planes.c79
-rw-r--r--drivers/gpu/drm/arm/malidp_regs.h11
4 files changed, 90 insertions, 17 deletions
diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
index 8abd335ec313..d789b46dc817 100644
--- a/drivers/gpu/drm/arm/malidp_hw.c
+++ b/drivers/gpu/drm/arm/malidp_hw.c
@@ -75,16 +75,16 @@ static const struct malidp_format_id malidp550_de_formats[] = {
75}; 75};
76 76
77static const struct malidp_layer malidp500_layers[] = { 77static const struct malidp_layer malidp500_layers[] = {
78 { DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE, MALIDP_DE_LV_STRIDE0 }, 78 { DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE, MALIDP_DE_LV_STRIDE0, MALIDP500_LV_YUV2RGB },
79 { DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE, MALIDP_DE_LG_STRIDE }, 79 { DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE, MALIDP_DE_LG_STRIDE, 0 },
80 { DE_GRAPHICS2, MALIDP500_DE_LG2_BASE, MALIDP500_DE_LG2_PTR_BASE, MALIDP_DE_LG_STRIDE }, 80 { DE_GRAPHICS2, MALIDP500_DE_LG2_BASE, MALIDP500_DE_LG2_PTR_BASE, MALIDP_DE_LG_STRIDE, 0 },
81}; 81};
82 82
83static const struct malidp_layer malidp550_layers[] = { 83static const struct malidp_layer malidp550_layers[] = {
84 { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE, MALIDP_DE_LV_STRIDE0 }, 84 { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE, MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB },
85 { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE, MALIDP_DE_LG_STRIDE }, 85 { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE, MALIDP_DE_LG_STRIDE, 0 },
86 { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE, MALIDP_DE_LV_STRIDE0 }, 86 { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE, MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB },
87 { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE, MALIDP550_DE_LS_R1_STRIDE }, 87 { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE, MALIDP550_DE_LS_R1_STRIDE, 0 },
88}; 88};
89 89
90#define SE_N_SCALING_COEFFS 96 90#define SE_N_SCALING_COEFFS 96
diff --git a/drivers/gpu/drm/arm/malidp_hw.h b/drivers/gpu/drm/arm/malidp_hw.h
index 42d3e7b9ba98..b5dd6c73ec9f 100644
--- a/drivers/gpu/drm/arm/malidp_hw.h
+++ b/drivers/gpu/drm/arm/malidp_hw.h
@@ -58,7 +58,8 @@ struct malidp_layer {
58 u16 id; /* layer ID */ 58 u16 id; /* layer ID */
59 u16 base; /* address offset for the register bank */ 59 u16 base; /* address offset for the register bank */
60 u16 ptr; /* address offset for the pointer register */ 60 u16 ptr; /* address offset for the pointer register */
61 u16 stride_offset; /* Offset to the first stride register. */ 61 u16 stride_offset; /* offset to the first stride register. */
62 s16 yuv2rgb_offset; /* offset to the YUV->RGB matrix entries */
62}; 63};
63 64
64enum malidp_scaling_coeff_set { 65enum malidp_scaling_coeff_set {
diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c
index 5e64060cc8fc..7a44897c50fe 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -266,6 +266,60 @@ static void malidp_de_set_plane_pitches(struct malidp_plane *mp,
266 mp->layer->stride_offset + i * 4); 266 mp->layer->stride_offset + i * 4);
267} 267}
268 268
269static const s16
270malidp_yuv2rgb_coeffs[][DRM_COLOR_RANGE_MAX][MALIDP_COLORADJ_NUM_COEFFS] = {
271 [DRM_COLOR_YCBCR_BT601][DRM_COLOR_YCBCR_LIMITED_RANGE] = {
272 1192, 0, 1634,
273 1192, -401, -832,
274 1192, 2066, 0,
275 64, 512, 512
276 },
277 [DRM_COLOR_YCBCR_BT601][DRM_COLOR_YCBCR_FULL_RANGE] = {
278 1024, 0, 1436,
279 1024, -352, -731,
280 1024, 1815, 0,
281 0, 512, 512
282 },
283 [DRM_COLOR_YCBCR_BT709][DRM_COLOR_YCBCR_LIMITED_RANGE] = {
284 1192, 0, 1836,
285 1192, -218, -546,
286 1192, 2163, 0,
287 64, 512, 512
288 },
289 [DRM_COLOR_YCBCR_BT709][DRM_COLOR_YCBCR_FULL_RANGE] = {
290 1024, 0, 1613,
291 1024, -192, -479,
292 1024, 1900, 0,
293 0, 512, 512
294 },
295 [DRM_COLOR_YCBCR_BT2020][DRM_COLOR_YCBCR_LIMITED_RANGE] = {
296 1024, 0, 1476,
297 1024, -165, -572,
298 1024, 1884, 0,
299 0, 512, 512
300 },
301 [DRM_COLOR_YCBCR_BT2020][DRM_COLOR_YCBCR_FULL_RANGE] = {
302 1024, 0, 1510,
303 1024, -168, -585,
304 1024, 1927, 0,
305 0, 512, 512
306 }
307};
308
309static void malidp_de_set_color_encoding(struct malidp_plane *plane,
310 enum drm_color_encoding enc,
311 enum drm_color_range range)
312{
313 unsigned int i;
314
315 for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; i++) {
316 /* coefficients are signed, two's complement values */
317 malidp_hw_write(plane->hwdev, malidp_yuv2rgb_coeffs[enc][range][i],
318 plane->layer->base + plane->layer->yuv2rgb_offset +
319 i * 4);
320 }
321}
322
269static void malidp_de_plane_update(struct drm_plane *plane, 323static void malidp_de_plane_update(struct drm_plane *plane,
270 struct drm_plane_state *old_state) 324 struct drm_plane_state *old_state)
271{ 325{
@@ -297,6 +351,11 @@ static void malidp_de_plane_update(struct drm_plane *plane,
297 malidp_de_set_plane_pitches(mp, ms->n_planes, 351 malidp_de_set_plane_pitches(mp, ms->n_planes,
298 plane->state->fb->pitches); 352 plane->state->fb->pitches);
299 353
354 if ((plane->state->color_encoding != old_state->color_encoding) ||
355 (plane->state->color_range != old_state->color_range))
356 malidp_de_set_color_encoding(mp, plane->state->color_encoding,
357 plane->state->color_range);
358
300 malidp_hw_write(mp->hwdev, LAYER_H_VAL(src_w) | LAYER_V_VAL(src_h), 359 malidp_hw_write(mp->hwdev, LAYER_H_VAL(src_w) | LAYER_V_VAL(src_h),
301 mp->layer->base + MALIDP_LAYER_SIZE); 360 mp->layer->base + MALIDP_LAYER_SIZE);
302 361
@@ -438,6 +497,26 @@ int malidp_de_planes_init(struct drm_device *drm)
438 drm_plane_create_rotation_property(&plane->base, DRM_MODE_ROTATE_0, flags); 497 drm_plane_create_rotation_property(&plane->base, DRM_MODE_ROTATE_0, flags);
439 malidp_hw_write(malidp->dev, MALIDP_ALPHA_LUT, 498 malidp_hw_write(malidp->dev, MALIDP_ALPHA_LUT,
440 plane->layer->base + MALIDP_LAYER_COMPOSE); 499 plane->layer->base + MALIDP_LAYER_COMPOSE);
500
501 /* Attach the YUV->RGB property only to video layers */
502 if (id & (DE_VIDEO1 | DE_VIDEO2)) {
503 /* default encoding for YUV->RGB is BT601 NARROW */
504 enum drm_color_encoding enc = DRM_COLOR_YCBCR_BT601;
505 enum drm_color_range range = DRM_COLOR_YCBCR_LIMITED_RANGE;
506
507 ret = drm_plane_create_color_properties(&plane->base,
508 BIT(DRM_COLOR_YCBCR_BT601) | \
509 BIT(DRM_COLOR_YCBCR_BT709) | \
510 BIT(DRM_COLOR_YCBCR_BT2020),
511 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | \
512 BIT(DRM_COLOR_YCBCR_FULL_RANGE),
513 enc, range);
514 if (!ret)
515 /* program the HW registers */
516 malidp_de_set_color_encoding(plane, enc, range);
517 else
518 DRM_WARN("Failed to create video layer %d color properties\n", id);
519 }
441 } 520 }
442 521
443 kfree(formats); 522 kfree(formats);
diff --git a/drivers/gpu/drm/arm/malidp_regs.h b/drivers/gpu/drm/arm/malidp_regs.h
index 2039f857f77d..149024fb4432 100644
--- a/drivers/gpu/drm/arm/malidp_regs.h
+++ b/drivers/gpu/drm/arm/malidp_regs.h
@@ -170,10 +170,7 @@
170#define MALIDP500_CONFIG_3D 0x00038 170#define MALIDP500_CONFIG_3D 0x00038
171#define MALIDP500_BGND_COLOR 0x0003c 171#define MALIDP500_BGND_COLOR 0x0003c
172#define MALIDP500_OUTPUT_DEPTH 0x00044 172#define MALIDP500_OUTPUT_DEPTH 0x00044
173#define MALIDP500_YUV_RGB_COEF 0x00048 173#define MALIDP500_COEFFS_BASE 0x00078
174#define MALIDP500_COLOR_ADJ_COEF 0x00078
175#define MALIDP500_COEF_TABLE_ADDR 0x000a8
176#define MALIDP500_COEF_TABLE_DATA 0x000ac
177 174
178/* 175/*
179 * The YUV2RGB coefficients on the DP500 are not in the video layer's register 176 * The YUV2RGB coefficients on the DP500 are not in the video layer's register
@@ -181,11 +178,6 @@
181 * the negative offset. 178 * the negative offset.
182 */ 179 */
183#define MALIDP500_LV_YUV2RGB ((s16)(-0xB8)) 180#define MALIDP500_LV_YUV2RGB ((s16)(-0xB8))
184/*
185 * To match DP550/650, the start of the coeffs registers is
186 * at COLORADJ_COEFF0 instead of at YUV_RGB_COEF1.
187 */
188#define MALIDP500_COEFFS_BASE 0x00078
189#define MALIDP500_DE_LV_BASE 0x00100 181#define MALIDP500_DE_LV_BASE 0x00100
190#define MALIDP500_DE_LV_PTR_BASE 0x00124 182#define MALIDP500_DE_LV_PTR_BASE 0x00124
191#define MALIDP500_DE_LG1_BASE 0x00200 183#define MALIDP500_DE_LG1_BASE 0x00200
@@ -213,6 +205,7 @@
213#define MALIDP550_DE_BGND_COLOR 0x00044 205#define MALIDP550_DE_BGND_COLOR 0x00044
214#define MALIDP550_DE_OUTPUT_DEPTH 0x0004c 206#define MALIDP550_DE_OUTPUT_DEPTH 0x0004c
215#define MALIDP550_COEFFS_BASE 0x00050 207#define MALIDP550_COEFFS_BASE 0x00050
208#define MALIDP550_LV_YUV2RGB 0x00084
216#define MALIDP550_DE_LV1_BASE 0x00100 209#define MALIDP550_DE_LV1_BASE 0x00100
217#define MALIDP550_DE_LV1_PTR_BASE 0x00124 210#define MALIDP550_DE_LV1_PTR_BASE 0x00124
218#define MALIDP550_DE_LV2_BASE 0x00200 211#define MALIDP550_DE_LV2_BASE 0x00200