mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
media: rockchip: hdmirx: corrected color range/space judgment.
Change-Id: I4ba59410f06af6828e1bdf6c236e8998b616aa6a Signed-off-by: Wangqiang Guo <kay.guo@rock-chips.com>
This commit is contained in:
@@ -112,6 +112,18 @@ enum hdmirx_pix_fmt {
|
||||
HDMIRX_YUV420 = 3,
|
||||
};
|
||||
|
||||
enum hdmirx_cn_type {
|
||||
HDMIRX_CN_GRAPHICS = 0,
|
||||
HDMIRX_CN_PHOTO = 1,
|
||||
HDMIRX_CN_CINEMA = 2,
|
||||
HDMIRX_CN_GAME = 3,
|
||||
};
|
||||
|
||||
enum hdmirx_ycc_range {
|
||||
HDMIRX_YCC_LIMIT,
|
||||
HDMIRX_YCC_FULL,
|
||||
};
|
||||
|
||||
static const char * const pix_fmt_str[] = {
|
||||
"RGB888",
|
||||
"YUV422",
|
||||
@@ -372,7 +384,7 @@ static u8 edid_init_data_600M[] = {
|
||||
|
||||
static char *hdmirx_color_space[8] = {
|
||||
"xvYCC601", "xvYCC709", "sYCC601", "Adobe_YCC601",
|
||||
"Adobe_RGB", "BT2020_YcCbcCrc", "BT2020_RGB_OR_YCbCr"
|
||||
"Adobe_RGB", "BT2020_YcCbcCrc", "BT2020_RGB_OR_YCbCr", "RGB"
|
||||
};
|
||||
|
||||
static const struct v4l2_dv_timings_cap hdmirx_timings_cap = {
|
||||
@@ -771,7 +783,7 @@ try_loop:
|
||||
|
||||
static void hdmirx_get_color_space(struct rk_hdmirx_dev *hdmirx_dev)
|
||||
{
|
||||
u32 val;
|
||||
u32 val, EC2_0, C1_C0;
|
||||
struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev;
|
||||
|
||||
/*
|
||||
@@ -781,16 +793,58 @@ static void hdmirx_get_color_space(struct rk_hdmirx_dev *hdmirx_dev)
|
||||
*/
|
||||
hdmirx_readl(hdmirx_dev, PKTDEC_AVIIF_PH2_1);
|
||||
val = hdmirx_readl(hdmirx_dev, PKTDEC_AVIIF_PB3_0);
|
||||
hdmirx_dev->cur_color_space = (val & EXTEND_COLORIMETRY) >> 28;
|
||||
EC2_0 = (val & EXTEND_COLORIMETRY) >> 20;
|
||||
C1_C0 = (val & COLORIMETRY_MASK) >> 14;
|
||||
if (hdmirx_dev->pix_fmt == HDMIRX_RGB888) {
|
||||
if (EC2_0 == HDMIRX_ADOBE_RGB ||
|
||||
EC2_0 == HDMIRX_BT2020_RGB_OR_YCC)
|
||||
hdmirx_dev->cur_color_space = EC2_0;
|
||||
else
|
||||
hdmirx_dev->cur_color_space = HDMIRX_RGB;
|
||||
} else {
|
||||
switch (C1_C0) {
|
||||
case 0:
|
||||
hdmirx_dev->cur_color_space = HDMIRX_XVYCC709;
|
||||
break;
|
||||
case 1:
|
||||
hdmirx_dev->cur_color_space = HDMIRX_XVYCC601;
|
||||
break;
|
||||
case 2:
|
||||
hdmirx_dev->cur_color_space = HDMIRX_XVYCC709;
|
||||
break;
|
||||
default:
|
||||
hdmirx_dev->cur_color_space = EC2_0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
v4l2_dbg(2, debug, v4l2_dev, "%s: video standard: %s\n", __func__,
|
||||
hdmirx_color_space[hdmirx_dev->cur_color_space]);
|
||||
}
|
||||
|
||||
static bool IsColorRangeLimitFormat(uint32_t width, uint32_t height, bool interlace)
|
||||
{
|
||||
if (((width == 720) && (height == 240) && (interlace == false)) \
|
||||
|| ((width == 720) && (height == 1201) && (interlace == false)) \
|
||||
|| ((width == 720) && (height == 480) && (interlace == true)) \
|
||||
|| ((width == 720) && (height == 576) && (interlace == true)) \
|
||||
|| ((width == 1440) && (height == 480) && (interlace == true)) \
|
||||
|| ((width == 1440) && (height == 576) && (interlace == true)) \
|
||||
|| ((width == 1920) && (height == 1080) && (interlace == true)) \
|
||||
|| ((width == 2880) && (height == 480) && (interlace == true)) \
|
||||
|| ((width == 3840) && (height == 2160) && (interlace == false))) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void hdmirx_get_color_range(struct rk_hdmirx_dev *hdmirx_dev)
|
||||
{
|
||||
u32 val;
|
||||
int color_range;
|
||||
int rgb_range, yuv_range, cn_type;
|
||||
struct v4l2_dv_timings timings = hdmirx_dev->timings;
|
||||
struct v4l2_bt_timings *bt = &timings.bt;
|
||||
struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev;
|
||||
|
||||
/*
|
||||
@@ -800,16 +854,36 @@ static void hdmirx_get_color_range(struct rk_hdmirx_dev *hdmirx_dev)
|
||||
*/
|
||||
hdmirx_readl(hdmirx_dev, PKTDEC_AVIIF_PH2_1);
|
||||
val = hdmirx_readl(hdmirx_dev, PKTDEC_AVIIF_PB3_0);
|
||||
color_range = (val & RGB_QUANTIZATION_RANGE) >> 26;
|
||||
|
||||
/* byte3 bit[3:2]*/
|
||||
rgb_range = (val & RGB_QUANTIZATION_RANGE) >> 26;
|
||||
val = hdmirx_readl(hdmirx_dev, PKTDEC_AVIIF_PB7_4);
|
||||
/* byte5 bit[7:6]*/
|
||||
yuv_range = (val & YUV_QUANTIZATION_RANGE) >> 14;
|
||||
/* byte5 bit[5:4]*/
|
||||
cn_type = (val & CN_TYPE_MASK) >> 12;
|
||||
if (hdmirx_dev->pix_fmt != HDMIRX_RGB888) {
|
||||
hdmirx_dev->cur_color_range = color_range;
|
||||
if (yuv_range == HDMIRX_YCC_LIMIT)
|
||||
hdmirx_dev->cur_color_range = HDMIRX_LIMIT_RANGE;
|
||||
else if (yuv_range == HDMIRX_YCC_FULL)
|
||||
hdmirx_dev->cur_color_range = HDMIRX_FULL_RANGE;
|
||||
else
|
||||
hdmirx_dev->cur_color_range = HDMIRX_DEFAULT_RANGE;
|
||||
} else {
|
||||
if (color_range != HDMIRX_DEFAULT_RANGE) {
|
||||
hdmirx_dev->cur_color_range = color_range;
|
||||
if (rgb_range != HDMIRX_DEFAULT_RANGE) {
|
||||
(hdmirx_dev->is_dvi_mode) ?
|
||||
(hdmirx_dev->cur_color_range = HDMIRX_FULL_RANGE) :
|
||||
(hdmirx_dev->cur_color_range = rgb_range);
|
||||
} else {
|
||||
(hdmirx_dev->cur_vic) ?
|
||||
(hdmirx_dev->cur_color_range = HDMIRX_LIMIT_RANGE) :
|
||||
(hdmirx_dev->cur_color_range = HDMIRX_FULL_RANGE);
|
||||
if (cn_type == HDMIRX_CN_GRAPHICS) {
|
||||
hdmirx_dev->cur_color_range = HDMIRX_FULL_RANGE;
|
||||
} else {
|
||||
if (IsColorRangeLimitFormat(bt->width,
|
||||
bt->height, bt->interlaced))
|
||||
hdmirx_dev->cur_color_range = HDMIRX_LIMIT_RANGE;
|
||||
else
|
||||
hdmirx_dev->cur_color_range = HDMIRX_FULL_RANGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -259,10 +259,13 @@
|
||||
#define PKTDEC_ACR_PB7_4 0x1108
|
||||
#define PKTDEC_AVIIF_PH2_1 0x1200
|
||||
#define PKTDEC_AVIIF_PB3_0 0x1204
|
||||
#define COLORIMETRY_MASK GENMASK(23, 22)
|
||||
#define RGB_QUANTIZATION_RANGE GENMASK(27, 26)
|
||||
#define EXTEND_COLORIMETRY GENMASK(30, 28)
|
||||
#define PKTDEC_AVIIF_PB7_4 0x1208
|
||||
#define VIC_VAL_MASK GENMASK(6, 0)
|
||||
#define CN_TYPE_MASK GENMASK(13, 12)
|
||||
#define YUV_QUANTIZATION_RANGE GENMASK(15, 14)
|
||||
#define PKTDEC_AVIIF_PB11_8 0x120c
|
||||
#define PKTDEC_AVIIF_PB15_12 0x1210
|
||||
#define PKTDEC_AVIIF_PB19_16 0x1214
|
||||
|
||||
Reference in New Issue
Block a user