|
@@ -127,6 +127,7 @@ struct dispc_features {
|
|
|
const unsigned int num_reg_fields;
|
|
const unsigned int num_reg_fields;
|
|
|
const enum omap_overlay_caps *overlay_caps;
|
|
const enum omap_overlay_caps *overlay_caps;
|
|
|
const u32 **supported_color_modes;
|
|
const u32 **supported_color_modes;
|
|
|
|
|
+ const u32 *supported_scaler_color_modes;
|
|
|
unsigned int num_mgrs;
|
|
unsigned int num_mgrs;
|
|
|
unsigned int num_ovls;
|
|
unsigned int num_ovls;
|
|
|
unsigned int buffer_size_unit;
|
|
unsigned int buffer_size_unit;
|
|
@@ -916,32 +917,91 @@ static void dispc_wb_write_color_conv_coef(struct dispc_device *dispc,
|
|
|
#undef CVAL
|
|
#undef CVAL
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static void dispc_setup_color_conv_coef(struct dispc_device *dispc)
|
|
|
|
|
|
|
+/* YUV -> RGB, ITU-R BT.601, full range */
|
|
|
|
|
+const static struct csc_coef_yuv2rgb coefs_yuv2rgb_bt601_full = {
|
|
|
|
|
+ 256, 0, 358, /* ry, rcb, rcr |1.000 0.000 1.402|*/
|
|
|
|
|
+ 256, -88, -182, /* gy, gcb, gcr |1.000 -0.344 -0.714|*/
|
|
|
|
|
+ 256, 452, 0, /* by, bcb, bcr |1.000 1.772 0.000|*/
|
|
|
|
|
+ true, /* full range */
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/* YUV -> RGB, ITU-R BT.601, limited range */
|
|
|
|
|
+const static struct csc_coef_yuv2rgb coefs_yuv2rgb_bt601_lim = {
|
|
|
|
|
+ 298, 0, 409, /* ry, rcb, rcr |1.164 0.000 1.596|*/
|
|
|
|
|
+ 298, -100, -208, /* gy, gcb, gcr |1.164 -0.392 -0.813|*/
|
|
|
|
|
+ 298, 516, 0, /* by, bcb, bcr |1.164 2.017 0.000|*/
|
|
|
|
|
+ false, /* limited range */
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/* YUV -> RGB, ITU-R BT.709, full range */
|
|
|
|
|
+const static struct csc_coef_yuv2rgb coefs_yuv2rgb_bt709_full = {
|
|
|
|
|
+ 256, 0, 402, /* ry, rcb, rcr |1.000 0.000 1.570|*/
|
|
|
|
|
+ 256, -48, -120, /* gy, gcb, gcr |1.000 -0.187 -0.467|*/
|
|
|
|
|
+ 256, 475, 0, /* by, bcb, bcr |1.000 1.856 0.000|*/
|
|
|
|
|
+ true, /* full range */
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/* YUV -> RGB, ITU-R BT.709, limited range */
|
|
|
|
|
+const static struct csc_coef_yuv2rgb coefs_yuv2rgb_bt709_lim = {
|
|
|
|
|
+ 298, 0, 459, /* ry, rcb, rcr |1.164 0.000 1.793|*/
|
|
|
|
|
+ 298, -55, -136, /* gy, gcb, gcr |1.164 -0.213 -0.533|*/
|
|
|
|
|
+ 298, 541, 0, /* by, bcb, bcr |1.164 2.112 0.000|*/
|
|
|
|
|
+ false, /* limited range */
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/* RGB -> YUV, ITU-R BT.601, limited range */
|
|
|
|
|
+const static struct csc_coef_rgb2yuv coefs_rgb2yuv_bt601_lim = {
|
|
|
|
|
+ 66, 129, 25, /* yr, yg, yb | 0.257 0.504 0.098|*/
|
|
|
|
|
+ -38, -74, 112, /* cbr, cbg, cbb |-0.148 -0.291 0.439|*/
|
|
|
|
|
+ 112, -94, -18, /* crr, crg, crb | 0.439 -0.368 -0.071|*/
|
|
|
|
|
+ false, /* limited range */
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/* RGB -> YUV, ITU-R BT.601, full range */
|
|
|
|
|
+const static struct csc_coef_rgb2yuv coefs_rgb2yuv_bt601_full = {
|
|
|
|
|
+ 77, 150, 29, /* yr, yg, yb | 0.299 0.587 0.114|*/
|
|
|
|
|
+ -43, -85, 128, /* cbr, cbg, cbb |-0.173 -0.339 0.511|*/
|
|
|
|
|
+ 128, -107, -21, /* crr, crg, crb | 0.511 -0.428 -0.083|*/
|
|
|
|
|
+ true, /* full range */
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/* RGB -> YUV, ITU-R BT.709, limited range */
|
|
|
|
|
+const static struct csc_coef_rgb2yuv coefs_rgb2yuv_bt701_lim = {
|
|
|
|
|
+ 47, 157, 16, /* yr, yg, yb | 0.1826 0.6142 0.0620|*/
|
|
|
|
|
+ -26, -87, 112, /* cbr, cbg, cbb |-0.1006 -0.3386 0.4392|*/
|
|
|
|
|
+ 112, -102, -10, /* crr, crg, crb | 0.4392 -0.3989 -0.0403|*/
|
|
|
|
|
+ false, /* limited range */
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+static int dispc_ovl_set_csc(struct dispc_device *dispc,
|
|
|
|
|
+ enum omap_plane_id plane,
|
|
|
|
|
+ enum drm_color_encoding color_encoding,
|
|
|
|
|
+ enum drm_color_range color_range)
|
|
|
{
|
|
{
|
|
|
- int i;
|
|
|
|
|
- int num_ovl = dispc_get_num_ovls(dispc);
|
|
|
|
|
-
|
|
|
|
|
- /* YUV -> RGB, ITU-R BT.601, limited range */
|
|
|
|
|
- const struct csc_coef_yuv2rgb coefs_yuv2rgb_bt601_lim = {
|
|
|
|
|
- 298, 0, 409, /* ry, rcb, rcr */
|
|
|
|
|
- 298, -100, -208, /* gy, gcb, gcr */
|
|
|
|
|
- 298, 516, 0, /* by, bcb, bcr */
|
|
|
|
|
- false, /* limited range */
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ const struct csc_coef_yuv2rgb *csc;
|
|
|
|
|
|
|
|
- /* RGB -> YUV, ITU-R BT.601, limited range */
|
|
|
|
|
- const struct csc_coef_rgb2yuv coefs_rgb2yuv_bt601_lim = {
|
|
|
|
|
- 66, 129, 25, /* yr, yg, yb */
|
|
|
|
|
- -38, -74, 112, /* cbr, cbg, cbb */
|
|
|
|
|
- 112, -94, -18, /* crr, crg, crb */
|
|
|
|
|
- false, /* limited range */
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ switch (color_encoding) {
|
|
|
|
|
+ case DRM_COLOR_YCBCR_BT601:
|
|
|
|
|
+ if (color_range == DRM_COLOR_YCBCR_FULL_RANGE)
|
|
|
|
|
+ csc = &coefs_yuv2rgb_bt601_full;
|
|
|
|
|
+ else
|
|
|
|
|
+ csc = &coefs_yuv2rgb_bt601_lim;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case DRM_COLOR_YCBCR_BT709:
|
|
|
|
|
+ if (color_range == DRM_COLOR_YCBCR_FULL_RANGE)
|
|
|
|
|
+ csc = &coefs_yuv2rgb_bt709_full;
|
|
|
|
|
+ else
|
|
|
|
|
+ csc = &coefs_yuv2rgb_bt709_lim;
|
|
|
|
|
+ break;
|
|
|
|
|
+ default:
|
|
|
|
|
+ DSSERR("Unsupported CSC mode %d for plane %d\n",
|
|
|
|
|
+ color_encoding, plane);
|
|
|
|
|
+ return -EINVAL;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- for (i = 1; i < num_ovl; i++)
|
|
|
|
|
- dispc_ovl_write_color_conv_coef(dispc, i, &coefs_yuv2rgb_bt601_lim);
|
|
|
|
|
|
|
+ dispc_ovl_write_color_conv_coef(dispc, plane, csc);
|
|
|
|
|
|
|
|
- if (dispc->feat->has_writeback)
|
|
|
|
|
- dispc_wb_write_color_conv_coef(dispc, &coefs_rgb2yuv_bt601_lim);
|
|
|
|
|
|
|
+ return 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static void dispc_ovl_set_ba0(struct dispc_device *dispc,
|
|
static void dispc_ovl_set_ba0(struct dispc_device *dispc,
|
|
@@ -2529,6 +2589,19 @@ static int dispc_ovl_calc_scaling(struct dispc_device *dispc,
|
|
|
if (width == out_width && height == out_height)
|
|
if (width == out_width && height == out_height)
|
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
+ if (dispc->feat->supported_scaler_color_modes) {
|
|
|
|
|
+ const u32 *modes = dispc->feat->supported_scaler_color_modes;
|
|
|
|
|
+ int i;
|
|
|
|
|
+
|
|
|
|
|
+ for (i = 0; modes[i]; ++i) {
|
|
|
|
|
+ if (modes[i] == fourcc)
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (modes[i] == 0)
|
|
|
|
|
+ return -EINVAL;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (plane == OMAP_DSS_WB) {
|
|
if (plane == OMAP_DSS_WB) {
|
|
|
switch (fourcc) {
|
|
switch (fourcc) {
|
|
|
case DRM_FORMAT_NV12:
|
|
case DRM_FORMAT_NV12:
|
|
@@ -2622,7 +2695,9 @@ static int dispc_ovl_setup_common(struct dispc_device *dispc,
|
|
|
u8 pre_mult_alpha, u8 global_alpha,
|
|
u8 pre_mult_alpha, u8 global_alpha,
|
|
|
enum omap_dss_rotation_type rotation_type,
|
|
enum omap_dss_rotation_type rotation_type,
|
|
|
bool replication, const struct videomode *vm,
|
|
bool replication, const struct videomode *vm,
|
|
|
- bool mem_to_mem)
|
|
|
|
|
|
|
+ bool mem_to_mem,
|
|
|
|
|
+ enum drm_color_encoding color_encoding,
|
|
|
|
|
+ enum drm_color_range color_range)
|
|
|
{
|
|
{
|
|
|
bool five_taps = true;
|
|
bool five_taps = true;
|
|
|
bool fieldmode = false;
|
|
bool fieldmode = false;
|
|
@@ -2771,6 +2846,9 @@ static int dispc_ovl_setup_common(struct dispc_device *dispc,
|
|
|
fieldmode, fourcc, rotation);
|
|
fieldmode, fourcc, rotation);
|
|
|
dispc_ovl_set_output_size(dispc, plane, out_width, out_height);
|
|
dispc_ovl_set_output_size(dispc, plane, out_width, out_height);
|
|
|
dispc_ovl_set_vid_color_conv(dispc, plane, cconv);
|
|
dispc_ovl_set_vid_color_conv(dispc, plane, cconv);
|
|
|
|
|
+
|
|
|
|
|
+ if (plane != OMAP_DSS_WB)
|
|
|
|
|
+ dispc_ovl_set_csc(dispc, plane, color_encoding, color_range);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
dispc_ovl_set_rotation_attrs(dispc, plane, rotation, rotation_type,
|
|
dispc_ovl_set_rotation_attrs(dispc, plane, rotation, rotation_type,
|
|
@@ -2807,7 +2885,8 @@ static int dispc_ovl_setup(struct dispc_device *dispc,
|
|
|
oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height,
|
|
oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height,
|
|
|
oi->out_width, oi->out_height, oi->fourcc, oi->rotation,
|
|
oi->out_width, oi->out_height, oi->fourcc, oi->rotation,
|
|
|
oi->zorder, oi->pre_mult_alpha, oi->global_alpha,
|
|
oi->zorder, oi->pre_mult_alpha, oi->global_alpha,
|
|
|
- oi->rotation_type, replication, vm, mem_to_mem);
|
|
|
|
|
|
|
+ oi->rotation_type, replication, vm, mem_to_mem,
|
|
|
|
|
+ oi->color_encoding, oi->color_range);
|
|
|
|
|
|
|
|
return r;
|
|
return r;
|
|
|
}
|
|
}
|
|
@@ -2840,7 +2919,8 @@ static int dispc_wb_setup(struct dispc_device *dispc,
|
|
|
wi->buf_width, pos_x, pos_y, in_width, in_height, wi->width,
|
|
wi->buf_width, pos_x, pos_y, in_width, in_height, wi->width,
|
|
|
wi->height, wi->fourcc, wi->rotation, zorder,
|
|
wi->height, wi->fourcc, wi->rotation, zorder,
|
|
|
wi->pre_mult_alpha, global_alpha, wi->rotation_type,
|
|
wi->pre_mult_alpha, global_alpha, wi->rotation_type,
|
|
|
- replication, vm, mem_to_mem);
|
|
|
|
|
|
|
+ replication, vm, mem_to_mem, DRM_COLOR_YCBCR_BT601,
|
|
|
|
|
+ DRM_COLOR_YCBCR_LIMITED_RANGE);
|
|
|
if (r)
|
|
if (r)
|
|
|
return r;
|
|
return r;
|
|
|
|
|
|
|
@@ -3972,7 +4052,8 @@ static void _omap_dispc_initial_config(struct dispc_device *dispc)
|
|
|
dispc->feat->has_gamma_table)
|
|
dispc->feat->has_gamma_table)
|
|
|
REG_FLD_MOD(dispc, DISPC_CONFIG, 1, 9, 9);
|
|
REG_FLD_MOD(dispc, DISPC_CONFIG, 1, 9, 9);
|
|
|
|
|
|
|
|
- dispc_setup_color_conv_coef(dispc);
|
|
|
|
|
|
|
+ if (dispc->feat->has_writeback)
|
|
|
|
|
+ dispc_wb_write_color_conv_coef(dispc, &coefs_rgb2yuv_bt601_full);
|
|
|
|
|
|
|
|
dispc_set_loadmode(dispc, OMAP_DSS_LOAD_FRAME_ONLY);
|
|
dispc_set_loadmode(dispc, OMAP_DSS_LOAD_FRAME_ONLY);
|
|
|
|
|
|
|
@@ -4251,6 +4332,12 @@ static const u32 *omap4_dispc_supported_color_modes[] = {
|
|
|
DRM_FORMAT_RGBX8888),
|
|
DRM_FORMAT_RGBX8888),
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+static const u32 omap3_dispc_supported_scaler_color_modes[] = {
|
|
|
|
|
+ DRM_FORMAT_XRGB8888, DRM_FORMAT_RGB565, DRM_FORMAT_YUYV,
|
|
|
|
|
+ DRM_FORMAT_UYVY,
|
|
|
|
|
+ 0,
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
static const struct dispc_features omap24xx_dispc_feats = {
|
|
static const struct dispc_features omap24xx_dispc_feats = {
|
|
|
.sw_start = 5,
|
|
.sw_start = 5,
|
|
|
.fp_start = 15,
|
|
.fp_start = 15,
|
|
@@ -4281,6 +4368,7 @@ static const struct dispc_features omap24xx_dispc_feats = {
|
|
|
.num_reg_fields = ARRAY_SIZE(omap2_dispc_reg_fields),
|
|
.num_reg_fields = ARRAY_SIZE(omap2_dispc_reg_fields),
|
|
|
.overlay_caps = omap2_dispc_overlay_caps,
|
|
.overlay_caps = omap2_dispc_overlay_caps,
|
|
|
.supported_color_modes = omap2_dispc_supported_color_modes,
|
|
.supported_color_modes = omap2_dispc_supported_color_modes,
|
|
|
|
|
+ .supported_scaler_color_modes = COLOR_ARRAY(DRM_FORMAT_XRGB8888),
|
|
|
.num_mgrs = 2,
|
|
.num_mgrs = 2,
|
|
|
.num_ovls = 3,
|
|
.num_ovls = 3,
|
|
|
.buffer_size_unit = 1,
|
|
.buffer_size_unit = 1,
|
|
@@ -4317,6 +4405,7 @@ static const struct dispc_features omap34xx_rev1_0_dispc_feats = {
|
|
|
.num_reg_fields = ARRAY_SIZE(omap3_dispc_reg_fields),
|
|
.num_reg_fields = ARRAY_SIZE(omap3_dispc_reg_fields),
|
|
|
.overlay_caps = omap3430_dispc_overlay_caps,
|
|
.overlay_caps = omap3430_dispc_overlay_caps,
|
|
|
.supported_color_modes = omap3_dispc_supported_color_modes,
|
|
.supported_color_modes = omap3_dispc_supported_color_modes,
|
|
|
|
|
+ .supported_scaler_color_modes = omap3_dispc_supported_scaler_color_modes,
|
|
|
.num_mgrs = 2,
|
|
.num_mgrs = 2,
|
|
|
.num_ovls = 3,
|
|
.num_ovls = 3,
|
|
|
.buffer_size_unit = 1,
|
|
.buffer_size_unit = 1,
|
|
@@ -4353,6 +4442,7 @@ static const struct dispc_features omap34xx_rev3_0_dispc_feats = {
|
|
|
.num_reg_fields = ARRAY_SIZE(omap3_dispc_reg_fields),
|
|
.num_reg_fields = ARRAY_SIZE(omap3_dispc_reg_fields),
|
|
|
.overlay_caps = omap3430_dispc_overlay_caps,
|
|
.overlay_caps = omap3430_dispc_overlay_caps,
|
|
|
.supported_color_modes = omap3_dispc_supported_color_modes,
|
|
.supported_color_modes = omap3_dispc_supported_color_modes,
|
|
|
|
|
+ .supported_scaler_color_modes = omap3_dispc_supported_scaler_color_modes,
|
|
|
.num_mgrs = 2,
|
|
.num_mgrs = 2,
|
|
|
.num_ovls = 3,
|
|
.num_ovls = 3,
|
|
|
.buffer_size_unit = 1,
|
|
.buffer_size_unit = 1,
|
|
@@ -4389,6 +4479,7 @@ static const struct dispc_features omap36xx_dispc_feats = {
|
|
|
.num_reg_fields = ARRAY_SIZE(omap3_dispc_reg_fields),
|
|
.num_reg_fields = ARRAY_SIZE(omap3_dispc_reg_fields),
|
|
|
.overlay_caps = omap3630_dispc_overlay_caps,
|
|
.overlay_caps = omap3630_dispc_overlay_caps,
|
|
|
.supported_color_modes = omap3_dispc_supported_color_modes,
|
|
.supported_color_modes = omap3_dispc_supported_color_modes,
|
|
|
|
|
+ .supported_scaler_color_modes = omap3_dispc_supported_scaler_color_modes,
|
|
|
.num_mgrs = 2,
|
|
.num_mgrs = 2,
|
|
|
.num_ovls = 3,
|
|
.num_ovls = 3,
|
|
|
.buffer_size_unit = 1,
|
|
.buffer_size_unit = 1,
|
|
@@ -4425,6 +4516,7 @@ static const struct dispc_features am43xx_dispc_feats = {
|
|
|
.num_reg_fields = ARRAY_SIZE(omap3_dispc_reg_fields),
|
|
.num_reg_fields = ARRAY_SIZE(omap3_dispc_reg_fields),
|
|
|
.overlay_caps = omap3430_dispc_overlay_caps,
|
|
.overlay_caps = omap3430_dispc_overlay_caps,
|
|
|
.supported_color_modes = omap3_dispc_supported_color_modes,
|
|
.supported_color_modes = omap3_dispc_supported_color_modes,
|
|
|
|
|
+ .supported_scaler_color_modes = omap3_dispc_supported_scaler_color_modes,
|
|
|
.num_mgrs = 1,
|
|
.num_mgrs = 1,
|
|
|
.num_ovls = 3,
|
|
.num_ovls = 3,
|
|
|
.buffer_size_unit = 1,
|
|
.buffer_size_unit = 1,
|