mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 12:57:06 +09:00
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:
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user