hdmi_tx: auto set cd/cs

Auto set cd to 10bit if supported. Auto set cs to keep us in spec.

note: This is made up from the relavent parts of multiple commits from osmc and
coreelec 3.14 kernel, and tweaked to fit in the 4.9 kernel.
This commit is contained in:
cdu13a
2019-04-06 21:33:05 -04:00
committed by Dongjin Kim
parent 26b285b434
commit eae15b9ac5
4 changed files with 82 additions and 21 deletions

View File

@@ -461,6 +461,7 @@ static int set_disp_mode_auto(void)
struct hdmi_format_para *para = NULL;
unsigned char mode[32];
enum hdmi_vic vic = HDMI_Unknown;
enum hdmi_color_depth stream_cur_cd;
char* pix_fmt[] = {"RGB","YUV422","YUV444","YUV420"};
char* eotf[] = {"SDR","HDR","HDR10","HLG"};
char* range[] = {"default","limited","full"};
@@ -477,6 +478,13 @@ static int set_disp_mode_auto(void)
if ((info == NULL) || (info->name == NULL))
return -1;
stream_cur_cd = hdev->para->cd;
if (hdev->cur_video_param != NULL){
pr_info("hdmitx: display colourdepth was %d in cur_param 0x%08x (VIC: %d)\n",hdev->cur_video_param->color_depth * 2,
hdev->cur_video_param, hdev->cur_video_param->VIC);
}
pr_info(SYS "get current mode: %s\n", info->name);
if (!((strncmp(info->name, "480cvbs", 7) == 0) ||
@@ -502,6 +510,7 @@ static int set_disp_mode_auto(void)
hdev->HWOp.CntlConfig(hdev, CONF_CLR_VSDB_PACKET, 0);
hdev->HWOp.CntlMisc(hdev, MISC_TMDS_PHY_OP, TMDS_PHY_DISABLE);
hdev->para = hdmi_get_fmt_name("invalid", hdev->fmt_attr);
para->cd = stream_cur_cd;
return -1;
}
strncpy(mode, info->name, sizeof(mode));
@@ -521,18 +530,56 @@ static int set_disp_mode_auto(void)
}
}
/* In the file hdmi_common/hdmi_parameters.c,
* the data array all_fmt_paras[] treat 2160p60hz and 2160p60hz420
* as two different modes, such Scrambler
* So if node "attr" contains 420, need append 420 to mode.
*/
if (strstr(hdev->fmt_attr, "420")) {
if (!strstr(mode, "420"))
strncat(mode, "420", 3);
para = hdmi_get_fmt_name(mode, hdev->fmt_attr);
/* force 4k50/60Hz to 420 unless manually set */
if (strstr(hdmitx_device.fmt_attr,"422") == NULL){
switch ((para->vic) & 0xff) {
case HDMI_3840x2160p50_16x9:
case HDMI_3840x2160p60_16x9:
case HDMI_4096x2160p50_256x135:
case HDMI_4096x2160p60_256x135:
case HDMI_3840x2160p50_64x27:
case HDMI_3840x2160p60_64x27:
para->cs = COLORSPACE_YUV420;
break;
default:
break;
}
}
hdev->para = para;
if (hdev->cur_video_param != NULL){
if (strstr(hdmitx_device.fmt_attr,"bit") != NULL){
hdev->cur_video_param->color_depth = para->cd;
pr_info("hdmitx: display colourdepth set by attr to %d in cur_param 0x%08x (VIC: %d)\n",hdev->cur_video_param->color_depth * 2,
hdev->cur_video_param, hdev->cur_video_param->VIC);
} else {
hdev->cur_video_param->color_depth = COLORDEPTH_30B;
pr_info("hdmitx: display colourdepth is %d in cur_param 0x%08x (VIC: %d)\n",hdev->cur_video_param->color_depth * 2,
hdev->cur_video_param, hdev->cur_video_param->VIC);
}
if (hdev->cur_video_param->color_depth > COLORDEPTH_24B){
int dc_support = 0;
if (hdev->RXCap.ColorDeepSupport & 0x78 && hdev->para->cs != COLORSPACE_YUV420)
dc_support = 1;
else if ((hdev->RXCap.hf_ieeeoui) &&
((hdev->RXCap.dc_30bit_420 && hdev->cur_video_param->color_depth == COLORDEPTH_30B) ||
(hdev->RXCap.dc_36bit_420 && hdev->cur_video_param->color_depth == COLORDEPTH_36B) ||
(hdev->RXCap.dc_48bit_420 && hdev->cur_video_param->color_depth == COLORDEPTH_48B)))
dc_support = 1;
if (! dc_support){
pr_warn("Bitdepth is set to %d bits but display does not support deep colour",
hdev->cur_video_param->color_depth * 2);
/* drop to 8 bit unless forced */
if (strstr(hdmitx_device.fmt_attr,"bit") == NULL)
hdev->cur_video_param->color_depth = COLORDEPTH_24B;
}
}
}
para = hdmi_get_fmt_name(mode, hdev->fmt_attr);
hdev->para = para;
/* and recover the original bitstream bitdepth */
para->cd = stream_cur_cd;
vic = hdmitx_edid_get_VIC(hdev, mode, 1);
if (strncmp(info->name, "2160p30hz", strlen("2160p30hz")) == 0) {
vic = HDMI_4k2k_30;
@@ -4743,7 +4790,7 @@ static int amhdmitx_probe(struct platform_device *pdev)
HDMITX_Meson_Init(&hdmitx_device);
/* update fmt_attr */
hdmitx_init_fmt_attr(&hdmitx_device);
/*hdmitx_init_fmt_attr(&hdmitx_device); /**/
hdmitx_device.task = kthread_run(hdmi_task_handle,
&hdmitx_device, "kthread_hdmi");

View File

@@ -804,6 +804,8 @@ int hdmitx_set_display(struct hdmitx_dev *hdev, enum hdmi_vic VideoCode)
hdev->cur_VIC = vic;
param = hdmi_get_video_param(VideoCode);
if (hdev->cur_video_param != NULL)
param->color_depth = hdev->cur_video_param->color_depth;
hdev->cur_video_param = param;
if (param) {
param->color = param->color_prefer;
@@ -812,12 +814,14 @@ int hdmitx_set_display(struct hdmitx_dev *hdev, enum hdmi_vic VideoCode)
*/
switch (hdev->RXCap.native_Mode & 0x30) {
case 0x20:/*bit5==1, then support YCBCR444 + RGB*/
case 0x30:
param->color = COLORSPACE_YUV444;
break;
case 0x10:/*bit4==1, then support YCBCR422 + RGB*/
param->color = COLORSPACE_YUV422;
break;
case 0x30:
param->color = hdev->para->cs;
break;
default:
param->color = COLORSPACE_RGB444;
}

View File

@@ -2134,7 +2134,7 @@ do { \
case HDMI_4096x2160p25_256x135:
case HDMI_4096x2160p30_256x135:
if ((hdev->para->cs == COLORSPACE_YUV422)
|| (hdev->para->cd == COLORDEPTH_24B))
|| (hdev->cur_video_param->color_depth == COLORDEPTH_24B))
set_phy_by_mode(2);
else
set_phy_by_mode(1);
@@ -2152,7 +2152,7 @@ do { \
case HDMI_3840x2160p60_16x9_Y420:
case HDMI_4096x2160p50_256x135_Y420:
case HDMI_4096x2160p60_256x135_Y420:
if (hdev->para->cd == COLORDEPTH_24B)
if (hdev->cur_video_param->color_depth == COLORDEPTH_24B)
set_phy_by_mode(2);
else
set_phy_by_mode(1);
@@ -2160,7 +2160,7 @@ do { \
/* consider HPLL over 2Gbps */
case HDMI_2560x1600p60_8x5:
case HDMI_2560x1440p60_16x9:
if (hdev->para->cd == COLORDEPTH_24B)
if (hdev->cur_video_param->color_depth == COLORDEPTH_24B)
set_phy_by_mode(2);
else
set_phy_by_mode(1);
@@ -2205,7 +2205,7 @@ static void hdmitx_set_scdc(struct hdmitx_dev *hdev)
case HDMI_4096x2160p50_256x135:
case HDMI_4096x2160p60_256x135:
if ((hdev->para->cs == COLORSPACE_YUV420)
&& (hdev->para->cd == COLORDEPTH_24B))
&& (hdev->cur_video_param->color_depth == COLORDEPTH_24B))
hdev->para->tmds_clk_div40 = 0;
else
hdev->para->tmds_clk_div40 = 1;
@@ -2216,7 +2216,7 @@ static void hdmitx_set_scdc(struct hdmitx_dev *hdev)
case HDMI_4096x2160p60_256x135_Y420:
case HDMI_3840x2160p50_64x27_Y420:
case HDMI_3840x2160p60_64x27_Y420:
if (hdev->para->cd == COLORDEPTH_24B)
if (hdev->cur_video_param->color_depth == COLORDEPTH_24B)
hdev->para->tmds_clk_div40 = 0;
else
hdev->para->tmds_clk_div40 = 1;
@@ -2231,7 +2231,7 @@ static void hdmitx_set_scdc(struct hdmitx_dev *hdev)
case HDMI_3840x2160p30_64x27:
case HDMI_4096x2160p30_256x135:
if ((hdev->para->cs == COLORSPACE_YUV422)
|| (hdev->para->cd == COLORDEPTH_24B))
|| (hdev->cur_video_param->color_depth == COLORDEPTH_24B))
hdev->para->tmds_clk_div40 = 0;
else
hdev->para->tmds_clk_div40 = 1;
@@ -6248,10 +6248,10 @@ static void hdmitx_set_hw(struct hdmitx_dev *hdev)
}
pr_info(HW " config hdmitx IP vic = %d cd:%d cs: %d\n", vic,
hdev->para->cd, hdev->para->cs);
hdev->cur_video_param->color_depth, hdev->para->cs);
config_hdmi20_tx(vic, hdev,
hdev->para->cd,
hdev->cur_video_param->color_depth,
TX_INPUT_COLOR_FORMAT,
hdev->para->cs);
}

View File

@@ -972,9 +972,19 @@ static void hdmitx_set_clk_(struct hdmitx_dev *hdev)
struct hw_enc_clk_val_group *p_enc = NULL;
enum hdmi_vic vic = hdev->cur_VIC;
enum hdmi_color_space cs = hdev->para->cs;
enum hdmi_color_depth cd = hdev->para->cd;
enum hdmi_color_depth cd;
if (hdev->cur_video_param->color_depth && hdev->cur_video_param->color_depth > 0)
cd = hdev->cur_video_param->color_depth;
else
cd = hdev->para->cd;
struct hdmi_cea_timing *custom_timing;
frac_rate = hdev->frac_rate_policy;
if (hdev->para->cs == COLORSPACE_YUV420)
vic |= 256;
pr_info("hdmitx: set clk: VIC = %d cd = %d cs = %d frac_rate = %d\n", vic,
cd, hdev->para->cs, frac_rate);
/* YUV 422 always use 24B mode */
if (cs == COLORSPACE_YUV422)
cd = COLORDEPTH_24B;