diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c index d248eaa4e4ea..c09c4c7a9b60 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c @@ -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"); diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_video.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_video.c index 1fcd328b9191..26494535a3f2 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_video.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_video.c @@ -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; } diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c index 488a5f8c2e4d..6529de67790e 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c @@ -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); } diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_clk.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_clk.c index d215ca4e73a2..af6f20b2f82d 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_clk.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_clk.c @@ -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;