diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/arm/malidp_hw.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/malidp_hw.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/malidp_planes.c | 79 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/malidp_regs.h | 11 |
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[] = { }; static const struct malidp_layer malidp500_layers[] = { - { DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE, MALIDP_DE_LV_STRIDE0 }, - { DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE, MALIDP_DE_LG_STRIDE }, - { DE_GRAPHICS2, MALIDP500_DE_LG2_BASE, MALIDP500_DE_LG2_PTR_BASE, MALIDP_DE_LG_STRIDE }, + { DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE, MALIDP_DE_LV_STRIDE0, MALIDP500_LV_YUV2RGB }, + { DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE, MALIDP_DE_LG_STRIDE, 0 }, + { DE_GRAPHICS2, MALIDP500_DE_LG2_BASE, MALIDP500_DE_LG2_PTR_BASE, MALIDP_DE_LG_STRIDE, 0 }, }; static const struct malidp_layer malidp550_layers[] = { - { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE, MALIDP_DE_LV_STRIDE0 }, - { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE, MALIDP_DE_LG_STRIDE }, - { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE, MALIDP_DE_LV_STRIDE0 }, - { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE, MALIDP550_DE_LS_R1_STRIDE }, + { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE, MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB }, + { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE, MALIDP_DE_LG_STRIDE, 0 }, + { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE, MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB }, + { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE, MALIDP550_DE_LS_R1_STRIDE, 0 }, }; #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 { u16 id; /* layer ID */ u16 base; /* address offset for the register bank */ u16 ptr; /* address offset for the pointer register */ - u16 stride_offset; /* Offset to the first stride register. */ + u16 stride_offset; /* offset to the first stride register. */ + s16 yuv2rgb_offset; /* offset to the YUV->RGB matrix entries */ }; enum 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, mp->layer->stride_offset + i * 4); } +static const s16 +malidp_yuv2rgb_coeffs[][DRM_COLOR_RANGE_MAX][MALIDP_COLORADJ_NUM_COEFFS] = { + [DRM_COLOR_YCBCR_BT601][DRM_COLOR_YCBCR_LIMITED_RANGE] = { + 1192, 0, 1634, + 1192, -401, -832, + 1192, 2066, 0, + 64, 512, 512 + }, + [DRM_COLOR_YCBCR_BT601][DRM_COLOR_YCBCR_FULL_RANGE] = { + 1024, 0, 1436, + 1024, -352, -731, + 1024, 1815, 0, + 0, 512, 512 + }, + [DRM_COLOR_YCBCR_BT709][DRM_COLOR_YCBCR_LIMITED_RANGE] = { + 1192, 0, 1836, + 1192, -218, -546, + 1192, 2163, 0, + 64, 512, 512 + }, + [DRM_COLOR_YCBCR_BT709][DRM_COLOR_YCBCR_FULL_RANGE] = { + 1024, 0, 1613, + 1024, -192, -479, + 1024, 1900, 0, + 0, 512, 512 + }, + [DRM_COLOR_YCBCR_BT2020][DRM_COLOR_YCBCR_LIMITED_RANGE] = { + 1024, 0, 1476, + 1024, -165, -572, + 1024, 1884, 0, + 0, 512, 512 + }, + [DRM_COLOR_YCBCR_BT2020][DRM_COLOR_YCBCR_FULL_RANGE] = { + 1024, 0, 1510, + 1024, -168, -585, + 1024, 1927, 0, + 0, 512, 512 + } +}; + +static void malidp_de_set_color_encoding(struct malidp_plane *plane, + enum drm_color_encoding enc, + enum drm_color_range range) +{ + unsigned int i; + + for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; i++) { + /* coefficients are signed, two's complement values */ + malidp_hw_write(plane->hwdev, malidp_yuv2rgb_coeffs[enc][range][i], + plane->layer->base + plane->layer->yuv2rgb_offset + + i * 4); + } +} + static void malidp_de_plane_update(struct drm_plane *plane, struct drm_plane_state *old_state) { @@ -297,6 +351,11 @@ static void malidp_de_plane_update(struct drm_plane *plane, malidp_de_set_plane_pitches(mp, ms->n_planes, plane->state->fb->pitches); + if ((plane->state->color_encoding != old_state->color_encoding) || + (plane->state->color_range != old_state->color_range)) + malidp_de_set_color_encoding(mp, plane->state->color_encoding, + plane->state->color_range); + malidp_hw_write(mp->hwdev, LAYER_H_VAL(src_w) | LAYER_V_VAL(src_h), mp->layer->base + MALIDP_LAYER_SIZE); @@ -438,6 +497,26 @@ int malidp_de_planes_init(struct drm_device *drm) drm_plane_create_rotation_property(&plane->base, DRM_MODE_ROTATE_0, flags); malidp_hw_write(malidp->dev, MALIDP_ALPHA_LUT, plane->layer->base + MALIDP_LAYER_COMPOSE); + + /* Attach the YUV->RGB property only to video layers */ + if (id & (DE_VIDEO1 | DE_VIDEO2)) { + /* default encoding for YUV->RGB is BT601 NARROW */ + enum drm_color_encoding enc = DRM_COLOR_YCBCR_BT601; + enum drm_color_range range = DRM_COLOR_YCBCR_LIMITED_RANGE; + + ret = drm_plane_create_color_properties(&plane->base, + BIT(DRM_COLOR_YCBCR_BT601) | \ + BIT(DRM_COLOR_YCBCR_BT709) | \ + BIT(DRM_COLOR_YCBCR_BT2020), + BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | \ + BIT(DRM_COLOR_YCBCR_FULL_RANGE), + enc, range); + if (!ret) + /* program the HW registers */ + malidp_de_set_color_encoding(plane, enc, range); + else + DRM_WARN("Failed to create video layer %d color properties\n", id); + } } 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 @@ #define MALIDP500_CONFIG_3D 0x00038 #define MALIDP500_BGND_COLOR 0x0003c #define MALIDP500_OUTPUT_DEPTH 0x00044 -#define MALIDP500_YUV_RGB_COEF 0x00048 -#define MALIDP500_COLOR_ADJ_COEF 0x00078 -#define MALIDP500_COEF_TABLE_ADDR 0x000a8 -#define MALIDP500_COEF_TABLE_DATA 0x000ac +#define MALIDP500_COEFFS_BASE 0x00078 /* * The YUV2RGB coefficients on the DP500 are not in the video layer's register @@ -181,11 +178,6 @@ * the negative offset. */ #define MALIDP500_LV_YUV2RGB ((s16)(-0xB8)) -/* - * To match DP550/650, the start of the coeffs registers is - * at COLORADJ_COEFF0 instead of at YUV_RGB_COEF1. - */ -#define MALIDP500_COEFFS_BASE 0x00078 #define MALIDP500_DE_LV_BASE 0x00100 #define MALIDP500_DE_LV_PTR_BASE 0x00124 #define MALIDP500_DE_LG1_BASE 0x00200 @@ -213,6 +205,7 @@ #define MALIDP550_DE_BGND_COLOR 0x00044 #define MALIDP550_DE_OUTPUT_DEPTH 0x0004c #define MALIDP550_COEFFS_BASE 0x00050 +#define MALIDP550_LV_YUV2RGB 0x00084 #define MALIDP550_DE_LV1_BASE 0x00100 #define MALIDP550_DE_LV1_PTR_BASE 0x00124 #define MALIDP550_DE_LV2_BASE 0x00200 |