diff --git a/drivers/media/vout/hdmitx21/hdmi_param.c b/drivers/media/vout/hdmitx21/hdmi_param.c index 1f7814f28..70a29d2f5 100644 --- a/drivers/media/vout/hdmitx21/hdmi_param.c +++ b/drivers/media/vout/hdmitx21/hdmi_param.c @@ -7,183 +7,11 @@ #include #include -struct hdmi_format_para *para; - -static struct hdmi_format_para fmt_para_non_hdmi_fmt = { - .timing = { - .vic = HDMI_0_UNKNOWN, - .name = "invalid", - .sname = "invalid", - .pixel_repetition_factor = 0, - .pi_mode = 1, - .h_pict = 16, - .v_pict = 9, - }, -}; - -static struct parse_cd parse_cd_[] = { - {COLORDEPTH_24B, "8bit",}, - {COLORDEPTH_30B, "10bit"}, - {COLORDEPTH_36B, "12bit"}, - {COLORDEPTH_48B, "16bit"}, -}; - -static struct parse_cs parse_cs_[] = { - {HDMI_COLORSPACE_RGB, "rgb",}, - {HDMI_COLORSPACE_YUV422, "422",}, - {HDMI_COLORSPACE_YUV444, "444",}, - {HDMI_COLORSPACE_YUV420, "420",}, -}; - -static struct parse_cr parse_cr_[] = { - {HDMI_QUANTIZATION_RANGE_LIMITED, "limit",}, - {HDMI_QUANTIZATION_RANGE_FULL, "full",}, -}; - -/* parse the name string to cs/cd/cr */ -static void _parse_hdmi_attr(char const *name, - enum hdmi_colorspace *cs, - enum hdmi_color_depth *cd, - enum hdmi_quantization_range *cr) -{ - int i; - - if (!cs || !cd || !cr) - return; - if (!name) { - /* assign defalut value*/ - *cs = HDMI_COLORSPACE_RGB; - *cd = COLORDEPTH_24B; - *cr = HDMI_QUANTIZATION_RANGE_FULL; - return; - } - - /* parse color depth */ - for (i = 0; i < sizeof(parse_cd_) / sizeof(struct parse_cd); i++) { - if (strstr(name, parse_cd_[i].name)) { - *cd = parse_cd_[i].cd; - break; - } - } - /* set default value */ - if (i == sizeof(parse_cd_) / sizeof(struct parse_cd)) - *cd = COLORDEPTH_24B; - - /* parse color space */ - for (i = 0; i < sizeof(parse_cs_) / sizeof(struct parse_cs); i++) { - if (strstr(name, parse_cs_[i].name)) { - *cs = parse_cs_[i].cs; - break; - } - } - /* set default value */ - if (i == sizeof(parse_cs_) / sizeof(struct parse_cs)) - *cs = HDMI_COLORSPACE_RGB; - - /* parse color range */ - for (i = 0; i < sizeof(parse_cr_) / sizeof(struct parse_cr); i++) { - if (strstr(name, parse_cr_[i].name)) { - *cr = parse_cr_[i].cr; - break; - } - } - /* set default value */ - if (i == sizeof(parse_cr_) / sizeof(struct parse_cr)) - *cr = HDMI_QUANTIZATION_RANGE_FULL; -} - -static u32 _calc_tmds_clk(u32 pixel_freq, enum hdmi_colorspace cs, - enum hdmi_color_depth cd) -{ - u32 tmds_clk = pixel_freq; - - if (cs == HDMI_COLORSPACE_YUV420) - tmds_clk = tmds_clk / 2; - if (cs != HDMI_COLORSPACE_YUV422) { - switch (cd) { - case COLORDEPTH_48B: - tmds_clk *= 2; - break; - case COLORDEPTH_36B: - tmds_clk = tmds_clk * 3 / 2; - break; - case COLORDEPTH_30B: - tmds_clk = tmds_clk * 5 / 4; - break; - case COLORDEPTH_24B: - default: - break; - } - } - - return tmds_clk; -} - struct hdmi_format_para *hdmitx21_get_vesa_paras(struct vesa_standard_timing *t) { return NULL; } -static int hdmitx21_construct_format_para_from_timing(const struct hdmi_timing *timing, - struct hdmi_format_para *para) -{ - para->vic = timing->vic; - para->name = timing->name; - para->sname = timing->sname; - - para->timing = *timing; - para->tmds_clk = _calc_tmds_clk(para->timing.pixel_freq, para->cs, para->cd); - - if (timing->vic == HDMIV_2560x1600p60hz) { - para->tmds_clk_div40 = 0; - para->scrambler_en = 0; - } else { - if (timing->pixel_freq > 340000) { - para->tmds_clk_div40 = 1; - para->scrambler_en = 1; - } else { - para->tmds_clk_div40 = 0; - para->scrambler_en = 0; - } - } - - para->frac_mode = 0; - - return 0; -} - -/* - * Parameter 'name' can should be full name as 1920x1080p60hz, - * 3840x2160p60hz, etc - * attr strings likes as '444,8bit' - */ -int hdmi21_get_fmt_para(enum hdmi_vic vic, - const char *attr, struct hdmi_format_para *para) -{ - const struct hdmi_timing *timing = NULL; - - memcpy(para, &fmt_para_non_hdmi_fmt, sizeof(struct hdmi_format_para)); - - if (!attr) - return -EINVAL; - - if (!para) { - pr_err("%s should pass valid para pointer to save\n", __func__); - return -EINVAL; - } - - timing = hdmitx_mode_vic_to_hdmi_timing(vic); - if (!timing) { - pr_err("%s: get timing from vic (%d) fail\n", __func__, vic); - return -EINVAL; - } - - _parse_hdmi_attr(attr, ¶->cs, ¶->cd, ¶->cr); - hdmitx21_construct_format_para_from_timing(timing, para); - - return 0; -} - /* Recommended N and Expected CTS for 32kHz */ static const struct hdmi_audio_fs_ncts aud_32k_para = { .array[0] = { @@ -602,55 +430,23 @@ u32 hdmi21_get_aud_n_paras(enum hdmi_audio_fs fs, return n * N_multiples; } -bool _is_hdmi14_4k(enum hdmi_vic vic) -{ - bool ret = 0; - int i; - enum hdmi_vic hdmi14_4k[] = { - HDMI_93_3840x2160p24_16x9, - HDMI_94_3840x2160p25_16x9, - HDMI_95_3840x2160p30_16x9, - HDMI_98_4096x2160p24_256x135, - }; +/* for csc coef */ +static const u8 coef_yc444_rgb_24bit_601[] = { + 0x20, 0x00, 0x69, 0x26, 0x74, 0xfd, 0x01, 0x0e, + 0x20, 0x00, 0x2c, 0xdd, 0x00, 0x00, 0x7e, 0x9a, + 0x20, 0x00, 0x00, 0x00, 0x38, 0xb4, 0x7e, 0x3b +}; - for (i = 0; i < ARRAY_SIZE(hdmi14_4k); i++) { - if (vic == hdmi14_4k[i]) { - ret = 1; - break; - } - } +static const u8 coef_yc444_rgb_24bit_709[] = { + 0x20, 0x00, 0x71, 0x06, 0x7a, 0x02, 0x00, 0xa7, + 0x20, 0x00, 0x32, 0x64, 0x00, 0x00, 0x7e, 0x6d, + 0x20, 0x00, 0x00, 0x00, 0x3b, 0x61, 0x7e, 0x25 +}; - return ret; -} +static const struct hdmi_csc_coef_table hdmi_csc_coef[] = { + {HDMI_COLORSPACE_YUV444, HDMI_COLORSPACE_RGB, COLORDEPTH_24B, 0, + sizeof(coef_yc444_rgb_24bit_601), coef_yc444_rgb_24bit_601}, + {HDMI_COLORSPACE_YUV444, HDMI_COLORSPACE_RGB, COLORDEPTH_24B, 1, + sizeof(coef_yc444_rgb_24bit_709), coef_yc444_rgb_24bit_709}, +}; -bool _is_y420_vic(enum hdmi_vic vic) -{ - int i; - enum hdmi_vic y420_vic[] = { - HDMI_96_3840x2160p50_16x9, - HDMI_97_3840x2160p60_16x9, - HDMI_101_4096x2160p50_256x135, - HDMI_102_4096x2160p60_256x135, - HDMI_106_3840x2160p50_64x27, - HDMI_107_3840x2160p60_64x27, - }; - const struct hdmi_timing *timing; - - for (i = 0; i < ARRAY_SIZE(y420_vic); i++) { - if (vic == y420_vic[i]) { - return 1; - } - } - - /* In Spec2.1 Table 7-34, greater than 2160p30hz will support y420 */ - timing = hdmitx_mode_vic_to_hdmi_timing(vic); - if (!timing) - return 0; - - if (timing->v_active >= 2160 && timing->v_freq > 30000) - return 1; - if (timing->v_active >= 4320) - return 1; - - return 0; -} diff --git a/drivers/media/vout/hdmitx21/hdmi_tx.h b/drivers/media/vout/hdmitx21/hdmi_tx.h index 270252c03..d3b4b1ad9 100644 --- a/drivers/media/vout/hdmitx21/hdmi_tx.h +++ b/drivers/media/vout/hdmitx21/hdmi_tx.h @@ -83,7 +83,7 @@ void hdmitx21_disable_clk(struct hdmitx_dev *hdev); u32 hdcp21_rd_hdcp22_ver(void); void hdmitx_infoframe_send(u16 info_type, u8 *body); -/* there are 2 ways to send out infoframes +/* there are 2 ways to send out infoframe * xxx_infoframe_set() will take use of struct xxx_infoframe_set * xxx_infoframe_rawset() will directly send with rawdata * if info, hb, or pb == NULL, disable send infoframe @@ -260,18 +260,6 @@ enum vrr_component_conf { CONF_BASE_REFRESH_RATE, }; -/* CONF_AVI_BT2020 */ -#define CLR_AVI_BT2020 0x0 -#define SET_AVI_BT2020 0x1 -/* CONF_AVI_Q01 */ -#define RGB_RANGE_DEFAULT 0 -#define RGB_RANGE_LIM 1 -#define RGB_RANGE_FUL 2 -#define RGB_RANGE_RSVD 3 -/* CONF_AVI_YQ01 */ -#define YCC_RANGE_LIM 0 -#define YCC_RANGE_FUL 1 -#define YCC_RANGE_RSVD 2 void hdmi_avi_infoframe_config(enum avi_component_conf conf, u8 val); int hdmitx_infoframe_rawget(u16 info_type, u8 *body); @@ -423,7 +411,6 @@ void hdmitx_setupirqs(struct hdmitx_dev *phdev); void ddc_toggle_sw_tpi(void); bool hdmitx_ddcm_read(u8 seg_index, u8 slave_addr, u8 reg_addr, u8 *p_buf, u16 len); bool hdmitx_ddcm_write(u8 seg_index, u8 slave_addr, u8 reg_addr, u8 data); -bool is_cur_mode_hdmi(void); extern unsigned long hdcp_reauth_dbg; extern unsigned long streamtype_dbg; diff --git a/drivers/media/vout/hdmitx21/hdmi_tx_audio.c b/drivers/media/vout/hdmitx21/hdmi_tx_audio.c index b0db109c5..f8adf0d57 100644 --- a/drivers/media/vout/hdmitx21/hdmi_tx_audio.c +++ b/drivers/media/vout/hdmitx21/hdmi_tx_audio.c @@ -230,7 +230,6 @@ int hdmitx21_set_audio(struct hdmitx_dev *hdev, struct hdmitx_audpara *audio_param) { int i, ret = -1; - /* struct hdmi_audio_infoframe *info = &hdev->infoframes.aud.audio; */ u8 CHAN_STAT_BUF[24 * 2]; u32 hdmi_ch = hdev->hdmi_ch; diff --git a/drivers/media/vout/hdmitx21/hdmi_tx_edid.c b/drivers/media/vout/hdmitx21/hdmi_tx_edid.c index 0cbbc398c..e1dd0c6d1 100644 --- a/drivers/media/vout/hdmitx21/hdmi_tx_edid.c +++ b/drivers/media/vout/hdmitx21/hdmi_tx_edid.c @@ -1126,7 +1126,7 @@ static int edid_parsingy420vdb(struct rx_cap *prxcap, u8 *buf) pos++; while (pos < data_end) { - if (_is_y420_vic(buf[pos])) { + if (hdmitx_edid_check_y420_support(prxcap, buf[pos])) { store_cea_idx(prxcap, buf[pos]); store_y420_idx(prxcap, buf[pos]); } @@ -1426,7 +1426,7 @@ static int edid_y420cmdb_postprocess(struct hdmitx_dev *hdev) for (j = 0; j < 8; j++) { valid = ((*p >> j) & 0x1); vic = prxcap->VIC[i * 8 + j]; - if (valid != 0 && _is_y420_vic(vic)) { + if (valid != 0 && hdmitx_edid_check_y420_support(prxcap, vic)) { store_cea_idx(prxcap, vic); store_y420_idx(prxcap, vic); } @@ -2798,283 +2798,6 @@ int hdmitx21_edid_parse(struct hdmitx_dev *hdmitx_device) return 0; } -enum hdmi_vic hdmitx21_edid_vic_tab_map_vic(const char *disp_mode) -{ - const struct hdmi_timing *timing = NULL; - enum hdmi_vic vic = HDMI_0_UNKNOWN; - - timing = hdmitx_mode_match_timing_name(disp_mode); - if (timing) - vic = timing->vic; - - return vic; -} - -const char *hdmitx21_edid_vic_to_string(enum hdmi_vic vic) -{ - const struct hdmi_timing *timing = NULL; - const char *disp_str = NULL; - - timing = hdmitx_mode_vic_to_hdmi_timing(vic); - if (timing) - disp_str = timing->name; - - return disp_str; -} - -static bool is_rx_support_y420(struct hdmitx_dev *hdev, enum hdmi_vic vic) -{ - int i; - struct rx_cap *prxcap = &hdev->tx_comm.rxcap; - const struct hdmi_timing *timing; - - for (i = 0; i < Y420_VIC_MAX_NUM; i++) { - if (prxcap->y420_vic[i] == vic) - return 1; - } - - /* In Spec2.1 Table 7-34, greater than 2160p30hz will support y420 */ - timing = hdmitx_mode_vic_to_hdmi_timing(vic); - if (!timing) - return 0; - - if (timing->v_active >= 2160 && timing->v_freq > 30000) - return 1; - if (timing->v_active >= 4320) - return 1; - - return 0; -} - -static bool hdmitx_check_4x3_16x9_mode(struct hdmitx_dev *hdev, - enum hdmi_vic vic) -{ - bool flag = 0; - int j; - struct rx_cap *prxcap = NULL; - - prxcap = &hdev->tx_comm.rxcap; - if (vic == HDMI_2_720x480p60_4x3 || - vic == HDMI_6_720x480i60_4x3 || - vic == HDMI_17_720x576p50_4x3 || - vic == HDMI_21_720x576i50_4x3) { - for (j = 0; (j < prxcap->VIC_count) && (j < VIC_MAX_NUM); j++) { - if ((vic + 1) == (prxcap->VIC[j] & 0xff)) { - flag = 1; - break; - } - } - } else if (vic == HDMI_3_720x480p60_16x9 || - vic == HDMI_7_720x480i60_16x9 || - vic == HDMI_18_720x576p50_16x9 || - vic == HDMI_22_720x576i50_16x9) { - for (j = 0; (j < prxcap->VIC_count) && (j < VIC_MAX_NUM); j++) { - if ((vic - 1) == (prxcap->VIC[j] & 0xff)) { - flag = 1; - break; - } - } - } - return flag; -} - -/* For some TV's EDID, there maybe exist some information ambiguous. - * Such as EDID declare support 2160p60hz(Y444 8bit), but no valid - * Max_TMDS_Clock2 to indicate that it can support 5.94G signal. - */ -bool hdmitx21_edid_check_valid_mode(struct hdmitx_dev *hdev, - struct hdmi_format_para *para) -{ - bool valid = 0; - struct rx_cap *prxcap = NULL; - const struct dv_info *dv = &hdev->tx_comm.rxcap.dv_info; - u32 rx_max_tmds_clk = 0; - u32 calc_tmds_clk = 0; - int i = 0; - int svd_flag = 0; - /* Default max color depth is 24 bit */ - enum hdmi_color_depth rx_y444_max_dc = COLORDEPTH_24B; - enum hdmi_color_depth rx_rgb_max_dc = COLORDEPTH_24B; - u32 rx_frl_bandwidth = 0; - u32 tx_frl_bandwidth = 0; - const struct hdmi_timing *timing; - - if (!hdev || !para) - return 0; - - /* if current limits to 1080p, here will check the freshrate and - * 4k resolution - */ - if (hdmitx21_limited_1080p()) { - if (hdmitx21_is_vic_over_limited_1080p(para->timing.vic)) { - pr_err("over limited vic%d in %s\n", para->timing.vic, - __func__); - return 0; - } - } - - prxcap = &hdev->tx_comm.rxcap; - /* exclude such as: 2160p60hz YCbCr444 10bit */ - if (hdev->data->chip_type < MESON_CPU_ID_S5) //todo, not in parse - prxcap->max_frl_rate = 0; //t7 not support frl - switch (para->timing.vic) { - case HDMI_96_3840x2160p50_16x9: - case HDMI_97_3840x2160p60_16x9: - case HDMI_101_4096x2160p50_256x135: - case HDMI_102_4096x2160p60_256x135: - case HDMI_106_3840x2160p50_64x27: - case HDMI_107_3840x2160p60_64x27: - if (para->cs == HDMI_COLORSPACE_RGB || - para->cs == HDMI_COLORSPACE_YUV444) - if (para->cd != COLORDEPTH_24B && !prxcap->max_frl_rate) - return 0; - break; - case HDMI_7_720x480i60_16x9: - case HDMI_22_720x576i50_16x9: - if (para->cs == HDMI_COLORSPACE_YUV422) - return 0; - default: - break; - } - - /* DVI case, only 8bit */ - if (prxcap->ieeeoui != HDMI_IEEE_OUI) { - if (para->cd != COLORDEPTH_24B) - return 0; - } - - /* target mode is not contained at RX SVD */ - for (i = 0; (i < prxcap->VIC_count) && (i < VIC_MAX_NUM); i++) { - if ((para->timing.vic & 0xff) == (prxcap->VIC[i] & 0xff)) { - svd_flag = 1; - break; - } else if (hdmitx_check_4x3_16x9_mode(hdev, para->timing.vic & 0xff)) { - svd_flag = 1; - break; - } - } - if (svd_flag == 0) - return 0; - - /* Get RX Max_TMDS_Clock */ - if (prxcap->Max_TMDS_Clock2) { - rx_max_tmds_clk = prxcap->Max_TMDS_Clock2 * 5; - } else { - /* Default min is 74.25 / 5 */ - if (prxcap->Max_TMDS_Clock1 < 0xf) - prxcap->Max_TMDS_Clock1 = 0x1e; - rx_max_tmds_clk = prxcap->Max_TMDS_Clock1 * 5; - } - - /* if current status already limited to 1080p, so here also needs to - * limit the rx_max_tmds_clk as 150 * 1.5 = 225 to make the valid mode - * checking works - */ - if (hdmitx21_limited_1080p()) { - if (rx_max_tmds_clk > 225) - rx_max_tmds_clk = 225; - } - - calc_tmds_clk = para->tmds_clk / 1000; - if (hdev->data->chip_type < MESON_CPU_ID_S5) //todo, not in parse - rx_frl_bandwidth = 0; - else - rx_frl_bandwidth = get_frl_bandwidth(prxcap->max_frl_rate); - timing = hdmitx_mode_vic_to_hdmi_timing(para->timing.vic); - if (!timing) - return 0; - /* tx_frl_bandwidth = timing->pixel_freq / 1000 * 24 * 1.122 */ - if (hdev->data->chip_type < MESON_CPU_ID_S5) { //todo, not in parse - tx_frl_bandwidth = 0; - } else { - tx_frl_bandwidth = calc_frl_bandwidth(timing->pixel_freq / 1000, - para->cs, para->cd); - if (tx_frl_bandwidth > get_frl_bandwidth(hdev->tx_max_frl_rate)) - return 0; - } - - if (calc_tmds_clk < rx_max_tmds_clk || tx_frl_bandwidth <= rx_frl_bandwidth) - valid = 1; - else - return 0; - - if (para->cs == HDMI_COLORSPACE_YUV444) { - /* Rx may not support Y444 */ - if (!(prxcap->native_Mode & (1 << 5))) - return 0; - if (prxcap->dc_y444 && (prxcap->dc_30bit || - dv->sup_10b_12b_444 == 0x1)) - rx_y444_max_dc = COLORDEPTH_30B; - if (prxcap->dc_y444 && (prxcap->dc_36bit || - dv->sup_10b_12b_444 == 0x2)) - rx_y444_max_dc = COLORDEPTH_36B; - if (para->cd <= rx_y444_max_dc) - valid = 1; - else - valid = 0; - return valid; - } - if (para->cs == HDMI_COLORSPACE_YUV422) { - /* Rx may not support Y422 */ - if (!(prxcap->native_Mode & (1 << 4))) - return 0; - return 1; - } - if (para->cs == HDMI_COLORSPACE_RGB) { - /* Always assume RX supports RGB444 */ - if (prxcap->dc_30bit || dv->sup_10b_12b_444 == 0x1) - rx_rgb_max_dc = COLORDEPTH_30B; - if (prxcap->dc_36bit || dv->sup_10b_12b_444 == 0x2) - rx_rgb_max_dc = COLORDEPTH_36B; - if (para->cd <= rx_rgb_max_dc) - valid = 1; - else - valid = 0; - return valid; - } - if (para->cs == HDMI_COLORSPACE_YUV420) { - if (!is_rx_support_y420(hdev, para->timing.vic)) - return 0; - if (!prxcap->dc_30bit_420) - if (para->cd == COLORDEPTH_30B) - return 0; - if (!prxcap->dc_36bit_420) - if (para->cd == COLORDEPTH_36B) - return 0; - valid = 1; - } - - return valid; -} - -/* force_flag: 0 means check with RX's edid */ -/* 1 means no check which RX's edid */ -enum hdmi_vic hdmitx21_edid_get_VIC(struct hdmitx_dev *hdev, - const char *disp_mode, - char force_flag) -{ - struct rx_cap *prxcap = &hdev->tx_comm.rxcap; - int j; - enum hdmi_vic vic = hdmitx21_edid_vic_tab_map_vic(disp_mode); - enum hdmi_vic vesa_vic; - - if (vic >= HDMITX_VESA_OFFSET) - vesa_vic = vic; - else - vesa_vic = HDMI_0_UNKNOWN; - if (vic != HDMI_0_UNKNOWN) { - if (force_flag == 0) { - for (j = 0; j < prxcap->VIC_count; j++) { - if (prxcap->VIC[j] == vic) - break; - } - if (j >= prxcap->VIC_count) - vic = HDMI_0_UNKNOWN; - } - } - return vic; -} - /* Clear HDMI Hardware Module EDID RAM and EDID Buffer */ void hdmitx21_edid_ram_buffer_clear(struct hdmitx_dev *hdmitx_device) { diff --git a/drivers/media/vout/hdmitx21/hdmi_tx_ext.c b/drivers/media/vout/hdmitx21/hdmi_tx_ext.c index 4199a9317..309cddf23 100644 --- a/drivers/media/vout/hdmitx21/hdmi_tx_ext.c +++ b/drivers/media/vout/hdmitx21/hdmi_tx_ext.c @@ -81,27 +81,13 @@ EXPORT_SYMBOL(get_hdmitx_phy_addr); void get_attr(char attr[16]) { -#if defined(CONFIG_AMLOGIC_HDMITX) - if (get_hdmitx20_init() == 1) - pr_err("Not support tx20 %s anymore.\n", __func__); -#endif -#if defined(CONFIG_AMLOGIC_HDMITX21) - if (get_hdmitx21_init() == 1) - get21_attr(attr); -#endif + pr_err("Not support tx20 %s anymore.\n", __func__); } EXPORT_SYMBOL(get_attr); void setup_attr(const char *buf) { -#if defined(CONFIG_AMLOGIC_HDMITX) - if (get_hdmitx20_init() == 1) - pr_err("Not support tx20 %s anymore.\n", __func__); -#endif -#if defined(CONFIG_AMLOGIC_HDMITX21) - if (get_hdmitx21_init() == 1) - setup21_attr(buf); -#endif + pr_err("Not support tx20 %s anymore.\n", __func__); } EXPORT_SYMBOL(setup_attr); diff --git a/drivers/media/vout/hdmitx21/hdmi_tx_ext.h b/drivers/media/vout/hdmitx21/hdmi_tx_ext.h index 5c81b4194..a3c7ae807 100644 --- a/drivers/media/vout/hdmitx21/hdmi_tx_ext.h +++ b/drivers/media/vout/hdmitx21/hdmi_tx_ext.h @@ -29,8 +29,6 @@ int hdmitx20_event_notifier_unregist(struct notifier_block *nb); int get_hdmitx20_init(void); int get20_hpd_state(void); struct vsdb_phyaddr *get_hdmitx20_phy_addr(void); -void setup20_attr(const char *buf); -void get20_attr(char attr[16]); void hdmitx20_audio_mute_op(unsigned int flag); void hdmitx20_video_mute_op(unsigned int flag); void hdmitx20_ext_set_audio_output(int enable); @@ -46,8 +44,6 @@ int hdmitx21_event_notifier_unregist(struct notifier_block *nb); int get_hdmitx21_init(void); int get21_hpd_state(void); struct vsdb_phyaddr *get_hdmitx21_phy_addr(void); -void get21_attr(char attr[16]); -void setup21_attr(const char *buf); void hdmitx21_video_mute_op(u32 flag, unsigned int path); void hdmitx21_audio_mute_op(u32 flag, unsigned int path); void hdmitx21_ext_set_audio_output(int enable); diff --git a/drivers/media/vout/hdmitx21/hdmi_tx_frl.c b/drivers/media/vout/hdmitx21/hdmi_tx_frl.c index fe4bb99f1..156077db6 100644 --- a/drivers/media/vout/hdmitx21/hdmi_tx_frl.c +++ b/drivers/media/vout/hdmitx21/hdmi_tx_frl.c @@ -24,59 +24,6 @@ ulong g_flt_1_e; /* record the clear time of FLT_UPDATE */ static bool frl_schedule_work(struct frl_train_t *p, u32 delay_ms, u32 period_ms); static bool frl_stop_work(struct frl_train_t *p); -/* get the corresponding bandwidth of current FRL_RATE, Unit: MHz */ -u32 get_frl_bandwidth(const enum frl_rate_enum rate) -{ - const u32 frl_bandwidth[] = { - [FRL_NONE] = 0, - [FRL_3G3L] = 9000, - [FRL_6G3L] = 18000, - [FRL_6G4L] = 24000, - [FRL_8G4L] = 32000, - [FRL_10G4L] = 40000, - [FRL_12G4L] = 48000, - }; - - if (rate > FRL_12G4L) - return 0; - return frl_bandwidth[rate]; -} - -u32 calc_frl_bandwidth(u32 pixel_freq, enum hdmi_colorspace cs, - enum hdmi_color_depth cd) -{ - u32 bandwidth; - - bandwidth = calc_tmds_bandwidth(pixel_freq, cs, cd); - - /* bandwidth = tmds_bandwidth * 24 * 1.122 */ - bandwidth = bandwidth * 24; - bandwidth = bandwidth * 561 / 500; - - return bandwidth; -} - -u32 calc_tmds_bandwidth(u32 pixel_freq, enum hdmi_colorspace cs, - enum hdmi_color_depth cd) -{ - u32 bandwidth = pixel_freq; - - if (cs == HDMI_COLORSPACE_YUV420) - bandwidth /= 2; - if (cs != HDMI_COLORSPACE_YUV422) { - if (cd == COLORDEPTH_48B) - bandwidth = bandwidth * 2; - else if (cd == COLORDEPTH_36B) - bandwidth = bandwidth * 3 / 2; - else if (cd == COLORDEPTH_30B) - bandwidth = bandwidth * 5 / 4; - else - bandwidth = bandwidth * 1; - } - - return bandwidth; -} - /* for legacy HDMI2.0 or earlier modes, still select TMDS */ /* TODO DSC modes */ enum frl_rate_enum hdmitx21_select_frl_rate(bool dsc_en, enum hdmi_vic vic, @@ -92,7 +39,7 @@ enum frl_rate_enum hdmitx21_select_frl_rate(bool dsc_en, enum hdmi_vic vic, if (!timing) return FRL_NONE; - tx_tmds_bandwidth = calc_tmds_bandwidth(timing->pixel_freq / 1000, cs, cd); + tx_tmds_bandwidth = hdmitx_calc_tmds_clk(timing->pixel_freq / 1000, cs, cd); pr_info("Hactive=%d Vactive=%d Vfreq=%d TMDS_BandWidth=%d\n", timing->h_active, timing->v_active, timing->v_freq, tx_tmds_bandwidth); @@ -106,7 +53,7 @@ enum frl_rate_enum hdmitx21_select_frl_rate(bool dsc_en, enum hdmi_vic vic, tx_frl_bandwidth = tx_tmds_bandwidth * 24; tx_frl_bandwidth = tx_frl_bandwidth * 561 / 500; for (rate = FRL_3G3L; rate < FRL_12G4L + 1; rate++) { - if (tx_frl_bandwidth <= get_frl_bandwidth(rate)) { + if (tx_frl_bandwidth <= hdmitx_get_frl_bandwidth(rate)) { pr_info("select frl_rate as %d\n", rate); return rate; } diff --git a/drivers/media/vout/hdmitx21/hdmi_tx_main.c b/drivers/media/vout/hdmitx21/hdmi_tx_main.c index 94e70ef8b..d4af7cf41 100644 --- a/drivers/media/vout/hdmitx21/hdmi_tx_main.c +++ b/drivers/media/vout/hdmitx21/hdmi_tx_main.c @@ -63,6 +63,7 @@ #include #include #include +#include #define HDMI_TX_COUNT 32 #define HDMI_TX_POOL_NUM 6 @@ -88,14 +89,9 @@ static void hdmitx_set_cuva_hdr_vs_emds(struct cuva_hdr_vs_emds_para *data); static void hdmitx_set_emp_pkt(u8 *data, u32 type, u32 size); static int check_fbc_special(u8 *edid_dat); -static void clear_rx_vinfo(struct hdmitx_dev *hdev); static void edidinfo_attach_to_vinfo(struct hdmitx_dev *hdev); static void edidinfo_detach_to_vinfo(struct hdmitx_dev *hdev); - -static int hdmi21_get_valid_fmt_para(struct hdmitx_dev *hdev, - char const *name, char const *attr, struct hdmi_format_para *para); -static void hdmitx21_reset_format_para(struct hdmi_format_para *para); -static void update_current_para(struct hdmitx_dev *hdev); +static void update_vinfo_from_formatpara(void); static void hdmi_tx_enable_ll_mode(bool enable); static int hdmitx_hook_drm(struct device *device); static int hdmitx_unhook_drm(struct device *device); @@ -103,8 +99,8 @@ static void tee_comm_dev_reg(struct hdmitx_dev *hdev); static void tee_comm_dev_unreg(struct hdmitx_dev *hdev); static bool is_cur_tmds_div40(struct hdmitx_dev *hdev); static void hdmitx_resend_div40(struct hdmitx_dev *hdev); -static int hdmitx_check_vic(int vic); static unsigned int hdmitx_get_frame_duration(void); +const struct hdmi_timing *hdmitx_mode_match_timing_name(const char *name); /* * Normally, after the HPD in or late resume, there will reading EDID, and @@ -200,8 +196,8 @@ static struct vout_device_s hdmitx_vdev = { .fresh_tx_cuva_hdr_vsif = hdmitx_set_cuva_hdr_vsif, .fresh_tx_cuva_hdr_vs_emds = hdmitx_set_cuva_hdr_vs_emds, .fresh_tx_emp_pkt = hdmitx_set_emp_pkt, - .get_attr = get21_attr, - .setup_attr = setup21_attr, + .get_attr = NULL, + .setup_attr = NULL, /* .video_mute = hdmitx21_video_mute_op, */ }; @@ -377,7 +373,6 @@ static void hdmitx_early_suspend(struct early_suspend *h) hdev->output_blank_flag = 0; hdmitx_set_vsif_pkt(0, 0, NULL, true); hdmitx_set_hdr10plus_pkt(0, NULL); - clear_rx_vinfo(hdev); hdmitx21_edid_clear(hdev); hdmitx21_edid_ram_buffer_clear(hdev); hdmitx_edid_done = false; @@ -392,19 +387,8 @@ static void hdmitx_early_suspend(struct early_suspend *h) mutex_unlock(&hdev->hdmimode_mutex); } -static int hdmitx_is_hdmi_vmode(char *mode_name) -{ - enum hdmi_vic vic = hdmitx21_edid_vic_tab_map_vic(mode_name); - - if (vic == HDMI_0_UNKNOWN) - return 0; - - return 1; -} - static void hdmitx_late_resume(struct early_suspend *h) { - const struct vinfo_s *info = hdmitx_get_current_vinfo(NULL); struct hdmitx_dev *hdev = (struct hdmitx_dev *)h->param; if (hdev->aon_output) { @@ -413,8 +397,6 @@ static void hdmitx_late_resume(struct early_suspend *h) } mutex_lock(&hdev->hdmimode_mutex); - if (info && info->name && (hdmitx_is_hdmi_vmode(info->name) == 1)) - hdev->tx_hw.cntlmisc(&hdev->tx_hw, MISC_HPLL_FAKE, 0); hdev->hpd_lock = 0; @@ -529,37 +511,19 @@ static void restore_mute(void) } } -int get21_cur_vout_index(void) -/* - * return value: 1, vout; 2, vout2; - */ -{ - int vout_index = 1; - return vout_index; -} - static int set_disp_mode(const char *mode) { int ret = -1; enum hdmi_vic vic; struct hdmitx_dev *hdev = get_hdmitx21_device(); + const struct hdmi_timing *timing = NULL; - vic = hdmitx21_edid_get_VIC(hdev, mode, 1); - if (strncmp(mode, "2160p30hz", strlen("2160p30hz")) == 0) - vic = HDMI_95_3840x2160p30_16x9; - else if (strncmp(mode, "2160p25hz", strlen("2160p25hz")) == 0) - vic = HDMI_94_3840x2160p25_16x9; - else if (strncmp(mode, "2160p24hz", strlen("2160p24hz")) == 0) - vic = HDMI_93_3840x2160p24_16x9; - else if (strncmp(mode, "smpte24hz", strlen("smpte24hz")) == 0) - vic = HDMI_98_4096x2160p24_256x135; - else - ;/* nothing */ + /*function for debug, only get vic and check if ip can support*/ + timing = hdmitx_mode_match_timing_name(mode); + if (!timing) + return 0; - if (strncmp(mode, "1080p60hz", strlen("1080p60hz")) == 0) - vic = HDMI_16_1920x1080p60_16x9; - if (strncmp(mode, "1080p50hz", strlen("1080p50hz")) == 0) - vic = HDMI_31_1920x1080p50_16x9; + vic = timing->vic; if (vic != HDMI_0_UNKNOWN) { hdev->mux_hpd_if_pin_high_flag = 1; @@ -595,16 +559,10 @@ static int set_disp_mode(const char *mode) return ret; } -static void hdmi_physical_size_update(struct hdmitx_dev *hdev) +static void hdmi_physical_size_to_vinfo(struct hdmitx_dev *hdev) { u32 width, height; - struct vinfo_s *info = NULL; - - info = hdmitx_get_current_vinfo(NULL); - if (!info || !info->name) { - pr_info("cann't get valid mode\n"); - return; - } + struct vinfo_s *info = &hdmitx21_device.tx_comm.hdmitx_vinfo; if (info->mode == VMODE_HDMI) { width = hdev->tx_comm.rxcap.physical_width; @@ -639,19 +597,9 @@ static void rxlatency_to_vinfo(struct vinfo_s *info, struct rx_cap *rx) static void edidinfo_attach_to_vinfo(struct hdmitx_dev *hdev) { - struct vinfo_s *info = NULL; + struct vinfo_s *info = &hdmitx21_device.tx_comm.hdmitx_vinfo; struct hdmi_format_para *para = &hdev->tx_comm.fmt_para; - /* get current vinfo */ - info = hdmitx_get_current_vinfo(NULL); - if (!info || !info->name) - return; - - if (strncmp(info->name, "480cvbs", 7) == 0 || - strncmp(info->name, "576cvbs", 7) == 0 || - strncmp(info->name, "null", 4) == 0) - return; - mutex_lock(&getedid_mutex); hdrinfo_to_vinfo(&info->hdr_info, hdev); memcpy(&ext_dvinfo, &hdev->tx_comm.rxcap.dv_info, sizeof(ext_dvinfo)); @@ -659,21 +607,20 @@ static void edidinfo_attach_to_vinfo(struct hdmitx_dev *hdev) memset(&info->hdr_info, 0, sizeof(struct hdr_info)); rxlatency_to_vinfo(info, &hdev->tx_comm.rxcap); hdmitx_vdev.dv_info = &hdev->tx_comm.rxcap.dv_info; + hdmi_physical_size_to_vinfo(&hdmitx21_device); mutex_unlock(&getedid_mutex); } static void edidinfo_detach_to_vinfo(struct hdmitx_dev *hdev) { - struct vinfo_s *info = NULL; + struct vinfo_s *info = &hdmitx21_device.tx_comm.hdmitx_vinfo; - /* get current vinfo */ - info = hdmitx_get_current_vinfo(NULL); - if (!info || !info->name) - return; - - edidinfo_attach_to_vinfo(hdev); - memset(&info->hdr_info, 0, sizeof(struct hdr_info)); + memset(&info->hdr_info, 0, sizeof(info->hdr_info)); + memset(&info->rx_latency, 0, sizeof(info->rx_latency)); hdmitx_vdev.dv_info = &dv_dummy; + + info->screen_real_width = 0; + info->screen_real_height = 0; } static void hdmitx_up_hdcp_timeout_handler(struct work_struct *work) @@ -758,94 +705,6 @@ static void hdmitx_start_hdcp_handler(struct work_struct *work) is_passthrough_switch = 0; } -static int check_vic_4x3_and_16x9(struct hdmitx_dev *hdev, enum hdmi_vic vic) -{ - if (vic == HDMI_3_720x480p60_16x9 || - vic == HDMI_7_720x480i60_16x9 || - vic == HDMI_18_720x576p50_16x9 || - vic == HDMI_22_720x576i50_16x9) { - if (hdmitx_check_vic(vic)) - return vic; - return vic - 1; - } else if (vic == HDMI_2_720x480p60_4x3 || - vic == HDMI_6_720x480i60_4x3 || - vic == HDMI_17_720x576p50_4x3 || - vic == HDMI_21_720x576i50_4x3) { - if (hdmitx_check_vic(vic)) - return vic; - return vic + 1; - } - - return vic; -} - -/* check the resolution is over 1920x1080 or not */ -static bool is_over_1080p(const struct hdmi_timing *timing) -{ - if (!timing) - return 1; - - if (timing->h_active > 1920 || timing->v_active > 1080) - return 1; - - return 0; -} - -/* check the fresh rate is over 60hz or not */ -static bool is_over_60hz(const struct hdmi_timing *timing) -{ - if (!timing) - return 1; - - if (timing->v_freq > 60000) - return 1; - - return 0; -} - -/* test current vic is over 150MHz or not */ -static bool is_over_pixel_150mhz(const struct hdmi_timing *timing) -{ - if (!timing) - return 1; - - if (timing->pixel_freq > 150000) - return 1; - - return 0; -} - -bool hdmitx21_is_vic_over_limited_1080p(enum hdmi_vic vic) -{ - const struct hdmi_timing *timing = NULL; - - timing = hdmitx_mode_vic_to_hdmi_timing(vic); - if (!timing || !timing->name) - return 1; - if (strncmp(timing->name, "invalid", strlen("invalid")) == 0) - return 1; - - /* if the vic equals to HDMI_0_UNKNOWN or VESA, - * then treated it as over limited - */ - if (vic == HDMI_0_UNKNOWN || vic >= HDMITX_VESA_OFFSET) - return 1; - - if (is_over_1080p(timing) || is_over_60hz(timing) || - is_over_pixel_150mhz(timing)) { - pr_err("over limited vic: %d\n", vic); - return 1; - } else { - return 0; - } -} - -/* the hdmitx output limits to 1080p */ -bool hdmitx21_limited_1080p(void) -{ - return res_1080p; -} - /*disp_mode attr*/ static ssize_t disp_mode_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -926,25 +785,6 @@ static ssize_t disp_mode_store(struct device *dev, return count; } -/*aud_mode attr*/ -void setup21_attr(const char *buf) -{ - char attr[16] = {0}; - struct hdmitx_dev *hdev = get_hdmitx21_device(); - struct hdmitx_common *tx_comm = &hdev->tx_comm; - - memcpy(attr, buf, sizeof(attr)); - memcpy(tx_comm->fmt_attr, attr, sizeof(tx_comm->fmt_attr)); -} - -void get21_attr(char attr[16]) -{ - struct hdmitx_dev *hdev = get_hdmitx21_device(); - struct hdmitx_common *tx_comm = &hdev->tx_comm; - - memcpy(attr, tx_comm->fmt_attr, sizeof(tx_comm->fmt_attr)); -} - /* todo *static int dump_edid_data(u32 type, char *path) *{ @@ -1152,24 +992,13 @@ static unsigned int hdmitx_get_frame_duration(void) return frame_duration; } -static int hdmitx_check_vic(int vic) -{ - struct hdmitx_dev *hdev = get_hdmitx21_device(); - int i; - - for (i = 0; i < hdev->tx_comm.rxcap.VIC_count && i < VIC_MAX_NUM; i++) { - if (vic == hdev->tx_comm.rxcap.VIC[i]) - return 1; - } - - return 0; -} - static int hdmitx_check_valid_aspect_ratio(enum hdmi_vic vic, int aspect_ratio) { + struct rx_cap *prxcap = &hdmitx21_device.tx_comm.rxcap; + switch (vic) { case HDMI_2_720x480p60_4x3: - if (hdmitx_check_vic(HDMI_3_720x480p60_16x9)) { + if (hdmitx_edid_validate_mode(prxcap, HDMI_3_720x480p60_16x9)) { if (aspect_ratio == AR_16X9) return 1; pr_info("same aspect_ratio = %d\n", aspect_ratio); @@ -1178,7 +1007,7 @@ static int hdmitx_check_valid_aspect_ratio(enum hdmi_vic vic, int aspect_ratio) } break; case HDMI_3_720x480p60_16x9: - if (hdmitx_check_vic(HDMI_2_720x480p60_4x3)) { + if (hdmitx_edid_validate_mode(prxcap, HDMI_2_720x480p60_4x3)) { if (aspect_ratio == AR_4X3) return 1; pr_info("same aspect_ratio = %d\n", aspect_ratio); @@ -1187,7 +1016,7 @@ static int hdmitx_check_valid_aspect_ratio(enum hdmi_vic vic, int aspect_ratio) } break; case HDMI_17_720x576p50_4x3: - if (hdmitx_check_vic(HDMI_18_720x576p50_16x9)) { + if (hdmitx_edid_validate_mode(prxcap, HDMI_18_720x576p50_16x9)) { if (aspect_ratio == AR_16X9) return 1; pr_info("same aspect_ratio = %d\n", aspect_ratio); @@ -1196,7 +1025,7 @@ static int hdmitx_check_valid_aspect_ratio(enum hdmi_vic vic, int aspect_ratio) } break; case HDMI_18_720x576p50_16x9: - if (hdmitx_check_vic(HDMI_17_720x576p50_4x3)) { + if (hdmitx_edid_validate_mode(prxcap, HDMI_17_720x576p50_4x3)) { if (aspect_ratio == AR_4X3) return 1; pr_info("same aspect_ratio = %d\n", aspect_ratio); @@ -1228,32 +1057,33 @@ int hdmitx21_get_aspect_ratio(void) struct aspect_ratio_list *hdmitx21_get_support_ar_list(void) { + struct rx_cap *prxcap = &hdmitx21_device.tx_comm.rxcap; static struct aspect_ratio_list ar_list[4]; int i = 0; memset(ar_list, 0, sizeof(ar_list)); - if (hdmitx_check_vic(HDMI_2_720x480p60_4x3)) { + if (hdmitx_edid_validate_mode(prxcap, HDMI_2_720x480p60_4x3)) { ar_list[i].vic = HDMI_2_720x480p60_4x3; ar_list[i].flag = TRUE; ar_list[i].aspect_ratio_num = 4; ar_list[i].aspect_ratio_den = 3; i++; } - if (hdmitx_check_vic(HDMI_3_720x480p60_16x9)) { + if (hdmitx_edid_validate_mode(prxcap, HDMI_3_720x480p60_16x9)) { ar_list[i].vic = HDMI_3_720x480p60_16x9; ar_list[i].flag = TRUE; ar_list[i].aspect_ratio_num = 16; ar_list[i].aspect_ratio_den = 9; i++; } - if (hdmitx_check_vic(HDMI_17_720x576p50_4x3)) { + if (hdmitx_edid_validate_mode(prxcap, HDMI_17_720x576p50_4x3)) { ar_list[i].vic = HDMI_17_720x576p50_4x3; ar_list[i].flag = TRUE; ar_list[i].aspect_ratio_num = 4; ar_list[i].aspect_ratio_den = 3; i++; } - if (hdmitx_check_vic(HDMI_18_720x576p50_16x9)) { + if (hdmitx_edid_validate_mode(prxcap, HDMI_18_720x576p50_16x9)) { ar_list[i].vic = HDMI_18_720x576p50_16x9; ar_list[i].flag = TRUE; ar_list[i].aspect_ratio_num = 16; @@ -1396,9 +1226,19 @@ static bool _check_hdmi_mode(void) return 0; } -bool is_cur_mode_hdmi(void) +static bool hdmitx21_hdr_en(void) { - return _check_hdmi_mode(); + return (hdmitx21_get_cur_hdr_st() & HDMI_HDR_TYPE) == HDMI_HDR_TYPE; +} + +static bool hdmitx21_dv_en(void) +{ + return (hdmitx21_get_cur_dv_st() & HDMI_DV_TYPE) == HDMI_DV_TYPE; +} + +static bool hdmitx21_hdr10p_en(void) +{ + return (hdmitx21_get_cur_hdr10p_st() & HDMI_HDR10P_TYPE) == HDMI_HDR10P_TYPE; } #define GET_LOW8BIT(a) ((a) & 0xff) @@ -1445,7 +1285,6 @@ static void hdmitx_set_drm_pkt(struct master_display_info_s *data) hdr_status_pos = 1; /* if VSIF/DV or VSIF/HDR10P packet is enabled, disable it */ if (hdmitx21_dv_en()) { - update_current_para(hdev); hdmi_avi_infoframe_config(CONF_AVI_CS, hdev->tx_comm.fmt_para.cs); /* if using VSIF/DOVI, then only clear DV_VS10_SIG, else disable VSIF */ if (hdev->tx_hw.cntlconfig(&hdev->tx_hw, CONF_CLR_DV_VS10_SIG, 0) == 0) @@ -1591,63 +1430,6 @@ static void hdmitx_set_drm_pkt(struct master_display_info_s *data) spin_unlock_irqrestore(&hdev->edid_spinlock, flags); } -/* fr_tab[] - * 1080p24hz, 24:1 - * 1080p23.976hz, 2997:125 - * 25/50/100/200hz, no change - */ -static struct frac_rate_table fr_tab[] = { - {"24hz", 24, 1, 2997, 125}, - {"30hz", 30, 1, 2997, 100}, - {"60hz", 60, 1, 2997, 50}, - {"120hz", 120, 1, 2997, 25}, - {"240hz", 120, 1, 5994, 25}, - {NULL}, -}; - -static void recalc_vinfo_sync_duration(struct vinfo_s *info, u32 frac) -{ - struct frac_rate_table *fr = &fr_tab[0]; - - if (!info) - return; - pr_info("hdmitx: recalc before %s %d %d, frac %d\n", info->name, - info->sync_duration_num, info->sync_duration_den, info->frac); - - while (fr->hz) { - if (strstr(info->name, fr->hz)) { - if (frac) { - info->sync_duration_num = fr->sync_num_dec; - info->sync_duration_den = fr->sync_den_dec; - info->frac = 1; - } else { - info->sync_duration_num = fr->sync_num_int; - info->sync_duration_den = fr->sync_den_int; - info->frac = 0; - } - break; - } - fr++; - } - - pr_info("recalc after %s %d %d, frac %d\n", info->name, - info->sync_duration_num, info->sync_duration_den, info->frac); -} - -static int hdmi21_get_valid_fmt_para(struct hdmitx_dev *hdev, - char const *name, char const *attr, struct hdmi_format_para *para) -{ - enum hdmi_vic vic = HDMI_0_UNKNOWN; - - vic = hdmitx21_edid_get_VIC(hdev, name, 0); - if (vic == HDMI_0_UNKNOWN) { - pr_err("%s: get vic from (%s) fail\n", __func__, name); - //return -EINVAL; - } - - return hdmi21_get_fmt_para(vic, attr, para); -} - static int calc_vinfo_from_hdmi_timing(const struct hdmi_timing *timing, struct vinfo_s *tx_vinfo) { struct hdmitx_dev *hdev = get_hdmitx21_device(); @@ -1671,8 +1453,6 @@ static int calc_vinfo_from_hdmi_timing(const struct hdmi_timing *timing, struct tx_vinfo->sync_duration_num = timing->v_freq; tx_vinfo->sync_duration_den = 1000; } - /* for 24/30/60/120/240hz, recalc sync duration */ - recalc_vinfo_sync_duration(tx_vinfo, hdev->tx_comm.frac_rate_policy); tx_vinfo->video_clk = timing->pixel_freq; tx_vinfo->htotal = timing->h_total; tx_vinfo->vtotal = timing->v_total; @@ -1687,6 +1467,26 @@ static int calc_vinfo_from_hdmi_timing(const struct hdmi_timing *timing, struct return 0; } +static void update_vinfo_from_formatpara(void) +{ + struct vinfo_s *vinfo = &hdmitx21_device.tx_comm.hdmitx_vinfo; + struct hdmi_format_para *fmtpara = &hdmitx21_device.tx_comm.fmt_para; + + /*update vinfo for out device.*/ + calc_vinfo_from_hdmi_timing(&fmtpara->timing, vinfo); + vinfo->info_3d = NON_3D; + if (hdmitx21_device.flag_3dfp) + vinfo->info_3d = FP_3D; + if (hdmitx21_device.flag_3dtb) + vinfo->info_3d = TB_3D; + if (hdmitx21_device.flag_3dss) + vinfo->info_3d = SS_3D; + vinfo->vout_device = &hdmitx_vdev; + /*dynamic info, always need set.*/ + vinfo->cs = fmtpara->cs; + vinfo->cd = fmtpara->cd; +} + static void hdmitx21_reset_format_para(struct hdmi_format_para *para) { if (!para) @@ -1702,45 +1502,29 @@ void update_para_from_mode(struct hdmitx_dev *hdev, const char *name, const char *fmt_attr, struct hdmi_format_para *update_para) { - struct vinfo_s *vinfo = &hdev->tx_comm.hdmitx_vinfo; + enum hdmi_vic vic = HDMI_0_UNKNOWN; - if (hdmi21_get_valid_fmt_para(hdev, name, fmt_attr, update_para) < 0) { - hdmitx21_reset_format_para(update_para); - pr_err("get format para failed (%s,%s)\n", name, fmt_attr); + vic = hdmitx_common_parse_vic_in_edid(&hdev->tx_comm, name); + if (vic == HDMI_0_UNKNOWN) { + pr_err("%s: get vic from (%s) fail\n", __func__, name); return; } + if (hdmitx_common_validate_vic(&hdev->tx_comm, vic) != 0) + return; + + hdmitx_parse_color_attr(fmt_attr, &update_para->cs, + &update_para->cd, &update_para->cr); + + if (hdmitx_common_build_format_para(&hdev->tx_comm, + update_para, vic, hdev->tx_comm.frac_rate_policy, + update_para->cs, update_para->cd, update_para->cr) != 0) { + pr_err("init format para failed (%s,%s)\n", name, fmt_attr); + hdmitx_format_para_reset(update_para); + } + pr_info("get_fmt_para from %s,%s -> %d,%s\n", name, fmt_attr, update_para->vic, update_para->sname ? update_para->sname : update_para->name); - - /*update vinfo for out device.*/ - calc_vinfo_from_hdmi_timing(&update_para->timing, vinfo); - vinfo->info_3d = NON_3D; - if (hdev->flag_3dfp) - vinfo->info_3d = FP_3D; - if (hdev->flag_3dtb) - vinfo->info_3d = TB_3D; - if (hdev->flag_3dss) - vinfo->info_3d = SS_3D; - vinfo->vout_device = &hdmitx_vdev; - /*dynamic info, always need set.*/ - vinfo->cs = update_para->cs; - vinfo->cd = update_para->cd; -} - -static void update_current_para(struct hdmitx_dev *hdev) -{ - struct vinfo_s *info = NULL; - u8 mode[32]; - - info = hdmitx_get_current_vinfo(NULL); - if (!info || !info->name) - return; - - memset(mode, 0, sizeof(mode)); - strncpy(mode, info->name, sizeof(mode) - 1); - update_para_from_mode(hdev, mode, - hdev->tx_comm.fmt_attr, &hdev->tx_comm.fmt_para); } static struct vsif_debug_save vsif_debug_info; @@ -1892,7 +1676,6 @@ static void hdmitx_set_vsif_pkt(enum eotf_type type, hdmi_vend_infoframe_rawset(NULL, NULL); if (signal_sdr) { pr_info("hdmitx: Dolby H14b VSIF, switching signal to SDR\n"); - update_current_para(hdev); hdmi_avi_infoframe_config(CONF_AVI_CS, fmt_para->cs); hdmi_avi_infoframe_config(CONF_AVI_Q01, RGB_RANGE_LIM); hdmi_avi_infoframe_config(CONF_AVI_YQ01, YCC_RANGE_LIM); @@ -2027,7 +1810,6 @@ static void hdmitx_set_vsif_pkt(enum eotf_type type, hdmi_vend_infoframe_rawset(ven_hb, db2); if (signal_sdr) { pr_info("hdmitx: Dolby VSIF, switching signal to SDR\n"); - update_current_para(hdev); pr_info("vic:%d, cd:%d, cs:%d, cr:%d\n", fmt_para->timing.vic, fmt_para->cd, fmt_para->cs, fmt_para->cr); @@ -3023,7 +2805,7 @@ static ssize_t allm_mode_store(struct device *dev, // disable ALLM tx_comm->allm_mode = 0; hdmitx21_construct_vsif(hdev, VT_ALLM, 0, NULL); - if (_is_hdmi14_4k(tx_comm->cur_VIC) && + if (hdmitx_edid_get_hdmi14_4k_vic(tx_comm->cur_VIC) > 0 && !hdmitx21_dv_en() && !hdmitx21_hdr10p_en()) hdmitx21_construct_vsif(hdev, VT_HDMI14_4K, 1, NULL); @@ -3076,7 +2858,7 @@ static void hdmi_tx_enable_ll_mode(bool enable) pr_info("%s: disabling ALLM before enabling game mode, enable:%d, allm:%d, cnc3:%d\n", __func__, enable, tx_comm->rxcap.allm, tx_comm->rxcap.cnc3); hdmitx21_construct_vsif(hdev, VT_ALLM, 0, NULL); - if (_is_hdmi14_4k(tx_comm->cur_VIC)) + if (hdmitx_edid_get_hdmi14_4k_vic(tx_comm->cur_VIC) > 0) hdmitx21_construct_vsif(hdev, VT_HDMI14_4K, 1, NULL); /* if not hdmi1.4 4k, need to sent > 4 frames and shorter than 1S * HF-VSIF with allm_mode = 0, and then disable HF-VSIF according @@ -3097,7 +2879,7 @@ static void hdmi_tx_enable_ll_mode(bool enable) pr_info("%s: disabling ALLM, enable:%d, allm:%d, cnc3:%d\n", __func__, enable, tx_comm->rxcap.allm, tx_comm->rxcap.cnc3); hdmitx21_construct_vsif(hdev, VT_ALLM, 0, NULL); - if (_is_hdmi14_4k(tx_comm->cur_VIC) && + if (hdmitx_edid_get_hdmi14_4k_vic(tx_comm->cur_VIC) > 0 && !hdmitx21_dv_en() && !hdmitx21_hdr10p_en()) hdmitx21_construct_vsif(hdev, VT_HDMI14_4K, 1, NULL); @@ -3118,7 +2900,7 @@ static void hdmi_tx_enable_ll_mode(bool enable) pr_info("%s: disabling ALLM, enable:%d, allm:%d, cnc3:%d\n", __func__, enable, tx_comm->rxcap.allm, tx_comm->rxcap.cnc3); hdmitx21_construct_vsif(hdev, VT_ALLM, 0, NULL); - if (_is_hdmi14_4k(tx_comm->cur_VIC) && + if (hdmitx_edid_get_hdmi14_4k_vic(tx_comm->cur_VIC) > 0 && !hdmitx21_dv_en() && !hdmitx21_hdr10p_en()) hdmitx21_construct_vsif(hdev, VT_HDMI14_4K, 1, NULL); @@ -3143,7 +2925,7 @@ static void drm_set_allm_mode(int mode) // disable ALLM tx_comm->allm_mode = 0; hdmitx21_construct_vsif(hdev, VT_ALLM, 0, NULL); - if (_is_hdmi14_4k(tx_comm->cur_VIC) && + if (hdmitx_edid_get_hdmi14_4k_vic(tx_comm->cur_VIC) > 0 && !hdmitx21_dv_en() && !hdmitx21_hdr10p_en()) hdmitx21_construct_vsif(hdev, VT_HDMI14_4K, 1, NULL); @@ -3344,7 +3126,7 @@ bool hdmitx_update_latency_info(struct tvin_latency_s *latency_info) tx_comm->allm_mode = 0; pr_info("%s: disabling ALLM before enable/disable game mode\n", __func__); hdmitx21_construct_vsif(hdev, VT_ALLM, 0, NULL); - if (_is_hdmi14_4k(tx_comm->cur_VIC) && + if (hdmitx_edid_get_hdmi14_4k_vic(tx_comm->cur_VIC) > 0 && !hdmitx21_dv_en() && !hdmitx21_hdr10p_en()) hdmitx21_construct_vsif(hdev, VT_HDMI14_4K, 1, NULL); @@ -4557,18 +4339,14 @@ static int hdmitx21_pre_enable_mode(struct hdmitx_common *tx_comm, struct hdmi_f static int hdmitx21_enable_mode(struct hdmitx_common *tx_comm, struct hdmi_format_para *para) { int ret; - enum hdmi_vic vic; struct hdmitx_dev *hdev = to_hdmitx21_dev(tx_comm); - edidinfo_detach_to_vinfo(hdev); - vic = check_vic_4x3_and_16x9(hdev, para->vic); - tx_comm->cur_VIC = HDMI_0_UNKNOWN; - ret = hdmitx21_set_display(hdev, vic); + ret = hdmitx21_set_display(hdev, para->vic); if (ret >= 0) { hdev->hwop.cntl(hdev, HDMITX_AVMUTE_CNTL, AVMUTE_CLEAR); - tx_comm->cur_VIC = vic; + tx_comm->cur_VIC = para->vic; hdev->audio_param_update_flag = 1; restore_mute(); } @@ -4601,6 +4379,7 @@ static int hdmitx21_post_enable_mode(struct hdmitx_common *tx_comm, struct hdmi_ } hdev->output_blank_flag = 1; edidinfo_attach_to_vinfo(hdev); + update_vinfo_from_formatpara(); /* wait for TV detect signal stable, * otherwise hdcp may easily auth fail */ @@ -4652,7 +4431,6 @@ static int hdmitx_set_current_vmode(enum vmode_e mode, void *data) * here get the current parameters of * output mode, which may be used later */ - update_current_para(hdev); if (tx_comm->rxcap.max_frl_rate) { hdev->frl_rate = hdmitx21_select_frl_rate(hdev->dsc_en, tx_comm->cur_VIC, hdev->tx_comm.fmt_para.cs, @@ -4662,6 +4440,7 @@ static int hdmitx_set_current_vmode(enum vmode_e mode, void *data) hdev->frl_rate, hdev->tx_max_frl_rate); } edidinfo_attach_to_vinfo(hdev); + update_vinfo_from_formatpara(); vinfo = get_current_vinfo(); if (vinfo) { vinfo->cur_enc_ppc = 1; @@ -4673,33 +4452,23 @@ static int hdmitx_set_current_vmode(enum vmode_e mode, void *data) return 0; } -static enum vmode_e hdmitx_validate_vmode(char *_mode, u32 frac, void *data) +static enum vmode_e hdmitx_validate_vmode(char *mode, u32 frac, void *data) { - struct hdmitx_dev *hdev = get_hdmitx21_device(); - struct hdmi_format_para fmt_para; - char mode[32] = {0}; - char *y420; + struct vinfo_s *vinfo = &hdmitx21_device.tx_comm.hdmitx_vinfo; + const struct hdmi_timing *timing = 0; - strncpy(mode, _mode, sizeof(mode)); - mode[31] = 0; - - /* if current mode contains string 420, subtract 420 */ - y420 = strstr(mode, "420"); - if (y420) - *y420 = '\0'; - - update_para_from_mode(hdev, mode, hdev->tx_comm.fmt_attr, &fmt_para); - if (1) { - /* //remove frac support for vout api - *if (frac) - * hdev->frac_rate_policy = 1; - *else - * hdev->frac_rate_policy = 0; - */ - hdev->tx_comm.hdmitx_vinfo.info_3d = NON_3D; - hdev->tx_comm.hdmitx_vinfo.vout_device = &hdmitx_vdev; + /* vout validate vmode only used to confirm the mode is + * supported by this server. And dont check with edid, + * maybe we dont have edid when this function called. + */ + timing = hdmitx_mode_match_timing_name(mode); + if (hdmitx_common_validate_vic(&hdmitx21_device.tx_comm, timing->vic) == 0) { + /*should save mode name to vinfo, will be used in set_vmode*/ + vinfo->name = timing->sname ? timing->sname : timing->name; return VMODE_HDMI; } + + pr_err("%s validate %s fail\n", __func__, mode); return VMODE_MAX; } @@ -5278,7 +5047,6 @@ static void hdmitx_hpd_plugin_handler(struct work_struct *work) if (hdev->repeater_tx) rx_repeat_hpd_state(1); hdev->cedst_policy = hdev->cedst_en & hdev->tx_comm.rxcap.scdc_present; - hdmi_physical_size_update(hdev); if (hdev->tx_comm.rxcap.ieeeoui != HDMI_IEEE_OUI) hdev->tx_hw.cntlconfig(&hdev->tx_hw, CONF_HDMI_DVI_MODE, DVI_MODE); @@ -5348,16 +5116,6 @@ static void hdmitx_hpd_plugin_handler(struct work_struct *work) hdmitx_hpd_notify_unlocked(&hdev->tx_comm); } -static void clear_rx_vinfo(struct hdmitx_dev *hdev) -{ - struct vinfo_s *info = hdmitx_get_current_vinfo(NULL); - - if (info) { - memset(&info->hdr_info, 0, sizeof(info->hdr_info)); - memset(&info->rx_latency, 0, sizeof(info->rx_latency)); - } -} - static void hdmitx_aud_hpd_plug_handler(struct work_struct *work) { int st; @@ -5396,13 +5154,11 @@ static void hdmitx_hpd_plugout_handler(struct work_struct *work) * NOTE: TV maybe changed(such as DV <-> non-DV) */ if (!hdev->systemcontrol_on && - hdmitx21_uboot_already_display(hdev)) { + hdev->tx_hw.getstate(&hdev->tx_hw, STAT_TX_OUTPUT, 0)) { plugout_mute_flg = true; /* edidinfo_detach_to_vinfo(hdev); */ - clear_rx_vinfo(hdev); hdev->hdmitx_event &= ~HDMI_TX_HPD_PLUGOUT; hdmitx21_edid_clear(hdev); - hdmi_physical_size_update(hdev); hdmitx21_edid_ram_buffer_clear(hdev); hdmitx_edid_done = false; hdev->tx_comm.hpd_state = 0; @@ -5441,9 +5197,7 @@ static void hdmitx_hpd_plugout_handler(struct work_struct *work) hdmitx21_rst_stream_type(hdev->am_hdcp); p_hdcp->saved_upstream_type = 0; p_hdcp->rx_update_flag = 0; - clear_rx_vinfo(hdev); hdmitx21_edid_clear(hdev); - hdmi_physical_size_update(hdev); hdmitx21_edid_ram_buffer_clear(hdev); hdmitx_edid_done = false; hdev->tx_comm.hpd_state = 0; @@ -5491,57 +5245,17 @@ int get21_hpd_state(void) /****************************** * hdmitx kernel task *******************************/ -/*TODO: called when there is no modesetting?*/ static bool is_cur_tmds_div40(struct hdmitx_dev *hdev) { - struct hdmitx_common *tx_comm = &hdev->tx_comm; - const struct hdmi_timing *timing = NULL; - struct hdmi_format_para tst_para; unsigned int act_clk = 0; - if (!hdev) - return 0; - - pr_info("hdmitx: get vic %d cs,cd %s\n", hdev->tx_comm.cur_VIC, tx_comm->fmt_attr); - - timing = hdmitx_mode_vic_to_hdmi_timing(hdev->tx_comm.cur_VIC); - if (!timing) { - pr_err("%s[%d] can't get timing from [%d]\n", - __func__, __LINE__, hdev->tx_comm.cur_VIC); + if (!hdev || hdev->tx_comm.fmt_para.vic == HDMI_0_UNKNOWN) { + pr_err("display is not ready\n"); return 0; } - if (hdmi21_get_valid_fmt_para(hdev, timing->name, tx_comm->fmt_attr, &tst_para) < 0) { - pr_info("%s[%d] fail exit.\n", __func__, __LINE__); - return 0; - } - - act_clk = tst_para.tmds_clk / 1000; - + act_clk = hdev->tx_comm.fmt_para.tmds_clk / 1000; pr_info("hdmitx: %s original clock %d\n", __func__, act_clk); - - if (tst_para.cs == HDMI_COLORSPACE_YUV420) - act_clk = act_clk / 2; - if (tst_para.cs != HDMI_COLORSPACE_YUV422) { - switch (tst_para.cd) { - case COLORDEPTH_30B: - act_clk = act_clk * 5 / 4; - break; - case COLORDEPTH_36B: - act_clk = act_clk * 3 / 2; - break; - case COLORDEPTH_48B: - act_clk = act_clk * 2; - break; - case COLORDEPTH_24B: - default: - act_clk = act_clk * 1; - break; - } - } - - pr_info("hdmitx: act clock: %d\n", act_clk); - if (act_clk > 340) return 1; @@ -6274,6 +5988,15 @@ static int amhdmitx_probe(struct platform_device *pdev) hdev->nb.notifier_call = hdmitx_reboot_notifier; register_reboot_notifier(&hdev->nb); hdmitx21_meson_init(hdev); + /*load fmt para from hw info.*/ + hdmitx_common_init_bootup_format_para(tx_comm, &tx_comm->fmt_para); + if (tx_comm->fmt_para.vic != HDMI_0_UNKNOWN) { + tx_comm->cur_VIC = tx_comm->fmt_para.vic; + hdev->ready = 1; + } + /* update fmt_attr string from fmt_para*/ + hdmitx_init_fmt_attr(hdev); + mutex_init(&hdev->hdmimode_mutex); tx_comm->hpd_state = !!(hdev->tx_hw.cntlmisc(&hdev->tx_hw, MISC_HPD_GPI_ST, 0)); @@ -6299,11 +6022,6 @@ static int amhdmitx_probe(struct platform_device *pdev) aout_register_client(&hdmitx_notifier_nb_a); #endif hdmitx_extcon_register(pdev, dev); - /** - * update fmt_attr string from fmt_para, - * because fmt_para may update in hdmitx_meson_init(). - */ - hdmitx_init_fmt_attr(hdev); tx_comm->hpd_state = !!hdev->tx_hw.cntlmisc(&hdev->tx_hw, MISC_HPD_GPI_ST, 0); diff --git a/drivers/media/vout/hdmitx21/hdmi_tx_video.c b/drivers/media/vout/hdmitx21/hdmi_tx_video.c index 7296d3033..697aff66f 100644 --- a/drivers/media/vout/hdmitx21/hdmi_tx_video.c +++ b/drivers/media/vout/hdmitx21/hdmi_tx_video.c @@ -323,7 +323,7 @@ int hdmitx21_construct_vsif(struct hdmitx_dev *hdev, enum vsif_type type, db[0] = GET_OUI_BYTE0(ieeeoui); db[1] = GET_OUI_BYTE1(ieeeoui); db[2] = GET_OUI_BYTE2(ieeeoui); - if (_is_hdmi14_4k(hdev->tx_comm.cur_VIC)) { + if (hdmitx_edid_get_hdmi14_4k_vic(hdev->tx_comm.cur_VIC) > 0) { fill_hdmi4k_vsif_data(hdev->tx_comm.cur_VIC, db, hb); hdmitx21_set_avi_vic(0); hdmi_vend_infoframe_rawset(hb, vsif_db); @@ -339,7 +339,7 @@ int hdmitx21_construct_vsif(struct hdmitx_dev *hdev, enum vsif_type type, db[3] = 0x1; /* Fixed value */ if (on) { db[4] |= 1 << 1; /* set bit1, ALLM_MODE */ - if (_is_hdmi14_4k(hdev->tx_comm.cur_VIC)) + if (hdmitx_edid_get_hdmi14_4k_vic(hdev->tx_comm.cur_VIC) > 0) hdmitx21_set_avi_vic(hdev->tx_comm.cur_VIC); hdmi_vend_infoframe2_rawset(hb, vsif_db); } else { diff --git a/drivers/media/vout/hdmitx21/hw/hdmi_tx_hw.c b/drivers/media/vout/hdmitx21/hw/hdmi_tx_hw.c index c69dde174..55e9fbe7e 100644 --- a/drivers/media/vout/hdmitx21/hw/hdmi_tx_hw.c +++ b/drivers/media/vout/hdmitx21/hw/hdmi_tx_hw.c @@ -39,6 +39,12 @@ #define to_hdmitx21_dev(x) container_of(x, struct hdmitx_dev, tx_hw) #define MESON_CPU_ID_T7 0 + +/*TODO: move to struct hdmitx_hw*/ +static u32 tx_max_frl_rate; +static u32 chip_type; +static struct hdmitx_infoframe *infoframes; + static void hdmi_phy_suspend(void); static void hdmi_phy_wakeup(struct hdmitx_dev *hdev); static void hdmitx_set_phy(struct hdmitx_dev *hdev); @@ -268,10 +274,10 @@ void hdmitx21_sys_reset(void) } } -bool hdmitx21_uboot_already_display(struct hdmitx_dev *hdev) +static bool hdmitx21_uboot_already_display(void) { - if (hdev->pxp_mode) - return 0; +// if (hdev->pxp_mode) +// return 0; if (hd21_read_reg(ANACTRL_HDMIPHY_CTRL0)) return 1; @@ -307,45 +313,46 @@ static enum hdmi_color_depth _get_colordepth(void) return depth; } -static enum hdmi_vic _get_vic_from_vsif(struct hdmitx_dev *hdev) -{ - int ret; - u8 body[32] = {0}; - enum hdmi_vic hdmi4k_vic = HDMI_0_UNKNOWN; - union hdmi_infoframe *infoframe = &hdev->infoframes.vend; - struct hdmi_vendor_infoframe *vendor = &infoframe->vendor.hdmi; - - ret = hdmitx_infoframe_rawget(HDMI_INFOFRAME_TYPE_VENDOR, body); - if (ret == -1 || ret == 0) - return hdmi4k_vic; - ret = hdmi_infoframe_unpack(infoframe, body, sizeof(body)); - if (ret < 0) { - pr_info("hdmitx21: parsing VEND failed %d\n", ret); - } else { - switch (vendor->vic) { - case 1: - hdmi4k_vic = HDMI_95_3840x2160p30_16x9; - break; - case 2: - hdmi4k_vic = HDMI_94_3840x2160p25_16x9; - break; - case 3: - hdmi4k_vic = HDMI_93_3840x2160p24_16x9; - break; - case 4: - hdmi4k_vic = HDMI_98_4096x2160p24_256x135; - break; - default: - break; - } - } - return hdmi4k_vic; -} +/* + *static enum hdmi_vic _get_vic_from_vsif(void) + *{ + * int ret; + * u8 body[32] = {0}; + * enum hdmi_vic hdmi 4k_vic = HDMI_0_UNKNOWN; + * union hdmi_infoframe *infoframe = &infoframes->vend; + * struct hdmi_vendor_infoframe *vendor = &infoframe->vendor.hdmi; + * + * ret = hdmitx_infoframe_rawget(HDMI_INFOFRAME_TYPE_VENDOR, body); + * if (ret == -1 || ret == 0) + * return hdmi4k_vic; + * ret = hdmi_infoframe_unpack(infoframe, body, sizeof(body)); + * if (ret < 0) { + * pr_info("hdmitx21: parsing VEND failed %d\n", ret); + * } else { + * switch (vendor->vic) { + * case 1: + * hdmi4k_vic = HDMI_95_3840x2160p30_16x9; + * break; + * case 2: + * hdmi4k_vic = HDMI_94_3840x2160p25_16x9; + * break; + * case 3: + * hdmi4k_vic = HDMI_93_3840x2160p24_16x9; + * break; + * case 4: + * hdmi4k_vic = HDMI_98_4096x2160p24_256x135; + * break; + * default: + * break; + * } + * } + * return hdmi4k_vic; + *} + */ static void hdmi_hwp_init(struct hdmitx_dev *hdev, u8 reset) { u32 data32; - struct hdmi_format_para tmp_para; if (hdev->data->chip_type >= MESON_CPU_ID_S5) { hd21_set_reg_bits(CLKCTRL_VID_CLK0_CTRL, 7, 0, 3); @@ -357,43 +364,8 @@ static void hdmi_hwp_init(struct hdmitx_dev *hdev, u8 reset) } pr_info("%s%d\n", __func__, __LINE__); - if (!reset && hdmitx21_uboot_already_display(hdev)) { - int ret; - u8 body[32] = {0}; - union hdmi_infoframe *infoframe = &hdev->infoframes.avi; - struct hdmi_avi_infoframe *avi = &infoframe->avi; - const struct hdmi_timing *tp; - const char *name; - enum hdmi_vic vic = HDMI_0_UNKNOWN; - - hdev->ready = 1; - ret = hdmitx_infoframe_rawget(HDMI_INFOFRAME_TYPE_AVI, body); - if (ret == -1 || ret == 0) { - pr_info("hdmitx21: AVI not enabled %d\n", ret); - return; - } - ret = hdmi_infoframe_unpack(infoframe, body, sizeof(body)); - if (ret < 0) { - pr_info("hdmitx21: parsing AVI failed %d\n", ret); - } else { - tmp_para.cs = avi->colorspace; - tmp_para.cd = _get_colordepth(); - if (tmp_para.cs == HDMI_COLORSPACE_YUV422) - tmp_para.cd = COLORDEPTH_36B; - hdmitx21_rebuild_fmt_attr_str(hdev, &tmp_para); - vic = avi->video_code; - if (vic == HDMI_0_UNKNOWN) - vic = _get_vic_from_vsif(hdev); - hdev->tx_comm.cur_VIC = vic; - tp = hdmitx_mode_vic_to_hdmi_timing(vic); - if (tp) { - name = tp->sname ? tp->sname : tp->name; - update_para_from_mode(hdev, name, hdev->tx_comm.fmt_attr, - &hdev->tx_comm.fmt_para); - } - pr_info("hdmitx21: parsing AVI CS%d CD%d VIC%d\n", - avi->colorspace, hdev->tx_comm.fmt_para.cd, hdev->tx_comm.cur_VIC); - } + if (!reset && hdmitx21_uboot_already_display()) { + pr_info("uboot already displayed\n"); return; } @@ -497,8 +469,38 @@ int hdmitx21_validate_mode(u32 vic) return 0; } +static int hdmitx21_calc_formatpara(struct hdmi_format_para *para) +{ + bool frl_enable = true; + + if (chip_type < MESON_CPU_ID_S5) //todo, not in parse + frl_enable = false; //t7 not support frl + + para->tmds_clk = hdmitx_calc_tmds_clk(para->timing.pixel_freq, + para->cs, para->cd); + + if (frl_enable) { + u32 tx_frl_bandwidth = 0; + + para->frl_clk = hdmitx_calc_frl_clk(para->timing.pixel_freq, + para->cs, para->cd); + tx_frl_bandwidth = para->frl_clk / 1000; + if (tx_frl_bandwidth > hdmitx_get_frl_bandwidth(tx_max_frl_rate)) + para->frl_clk = 0; + } else { + para->frl_clk = 0; + } + + return 0; +} + void hdmitx21_meson_init(struct hdmitx_dev *hdev) { + /*TODO: move to hdmitx_hw struct*/ + tx_max_frl_rate = hdev->tx_max_frl_rate; + chip_type = hdev->data->chip_type; + infoframes = &hdev->infoframes; + pr_info("%s%d\n", __func__, __LINE__); hdev->hwop.setdispmode = hdmitx_set_dispmode; hdev->hwop.setaudmode = hdmitx_set_audmode; @@ -512,6 +514,7 @@ void hdmitx21_meson_init(struct hdmitx_dev *hdev) hdev->tx_hw.cntlconfig = hdmitx_cntl_config; hdev->tx_hw.cntlmisc = hdmitx_cntl_misc; hdev->tx_hw.validatemode = hdmitx21_validate_mode; + hdev->tx_hw.calcformatpara = hdmitx21_calc_formatpara; hdmi_hwp_init(hdev, 0); hdmitx21_debugfs_init(); hdev->tx_hw.cntlmisc(&hdev->tx_hw, MISC_AVMUTE_OP, CLR_AVMUTE); @@ -933,7 +936,8 @@ static int hdmitx_set_dispmode(struct hdmitx_dev *hdev) (0 << 6) | (((para->cd == COLORDEPTH_24B) ? 1 : 0) << 10) | (0 << 12); - if (para->cd == COLORDEPTH_24B && hdmitx21_dv_en() == 0) + if (para->cd == COLORDEPTH_24B && + ((hdmitx21_get_cur_dv_st() & HDMI_DV_TYPE) == HDMI_DV_TYPE)) data32 |= (1 << 4); hd21_write_reg(VPU_HDMI_DITH_CNTL, data32); hdmitx21_dither_config(hdev); @@ -1216,21 +1220,6 @@ enum hdmi_tf_type hdmitx21_get_cur_hdr10p_st(void) return type; } -bool hdmitx21_hdr_en(void) -{ - return (hdmitx21_get_cur_hdr_st() & HDMI_HDR_TYPE) == HDMI_HDR_TYPE; -} - -bool hdmitx21_dv_en(void) -{ - return (hdmitx21_get_cur_dv_st() & HDMI_DV_TYPE) == HDMI_DV_TYPE; -} - -bool hdmitx21_hdr10p_en(void) -{ - return (hdmitx21_get_cur_hdr10p_st() & HDMI_HDR10P_TYPE) == HDMI_HDR10P_TYPE; -} - #define GET_OUTCHN_NO(a) (((a) >> 4) & 0xf) #define GET_OUTCHN_MSK(a) ((a) & 0xf) @@ -2600,6 +2589,57 @@ static enum hdmi_vic get_vic_from_pkt(void) return vic; } +static enum hdmi_colorspace get_cs_from_pkt(void) +{ + int ret; + u8 body[32] = {0}; + union hdmi_infoframe *infoframe = &infoframes->avi; + struct hdmi_avi_infoframe *avi = &infoframe->avi; + enum hdmi_colorspace cs = HDMI_COLORSPACE_RESERVED6; + + ret = hdmitx_infoframe_rawget(HDMI_INFOFRAME_TYPE_AVI, body); + if (ret == -1 || ret == 0) { + pr_info("hdmitx21: AVI not enabled %d\n", ret); + return cs; + } + + ret = hdmi_infoframe_unpack(infoframe, body, sizeof(body)); + if (ret < 0) + pr_info("hdmitx21: parsing AVI failed %d\n", ret); + else + cs = avi->colorspace; + + return cs; +} + +static enum hdmi_color_depth get_cd_from_pkt(void) +{ + int ret; + u8 body[32] = {0}; + union hdmi_infoframe *infoframe = &infoframes->avi; + struct hdmi_avi_infoframe *avi = &infoframe->avi; + enum hdmi_color_depth cd = COLORDEPTH_RESERVED; + enum hdmi_colorspace cs = HDMI_COLORSPACE_RESERVED6; + + ret = hdmitx_infoframe_rawget(HDMI_INFOFRAME_TYPE_AVI, body); + if (ret == -1 || ret == 0) { + pr_info("hdmitx21: AVI not enabled %d\n", ret); + return cd; + } + + ret = hdmi_infoframe_unpack(infoframe, body, sizeof(body)); + if (ret < 0) { + pr_info("hdmitx21: parsing AVI failed %d\n", ret); + } else { + cs = avi->colorspace; + cd = _get_colordepth(); + if (cs == HDMI_COLORSPACE_YUV422) + cd = COLORDEPTH_36B; + } + + return cd; +} + static int hdmitx_get_state(struct hdmitx_hw_common *tx_hw, u32 cmd, u32 argv) { @@ -2611,11 +2651,14 @@ static int hdmitx_get_state(struct hdmitx_hw_common *tx_hw, u32 cmd, switch (cmd) { case STAT_VIDEO_VIC: return (int)get_vic_from_pkt(); - case STAT_VIDEO_CLK: - break; - case STAT_HDR_TYPE: - return 0; + case STAT_VIDEO_CS: + return (int)get_cs_from_pkt(); + case STAT_VIDEO_CD: + return (int)get_cd_from_pkt(); + case STAT_TX_OUTPUT: + return hdmitx21_uboot_already_display(); default: + pr_err("Unsupported cmd %x\n", cmd); break; } return 0; @@ -3016,7 +3059,8 @@ void hdmitx21_dither_config(struct hdmitx_dev *hdev) { struct hdmi_format_para *para = &hdev->tx_comm.fmt_para; - if (para->cd == COLORDEPTH_24B && hdmitx21_dv_en() == 0) + if (para->cd == COLORDEPTH_24B && + ((hdmitx21_get_cur_dv_st() & HDMI_DV_TYPE) == HDMI_DV_TYPE)) hd21_set_reg_bits(VPU_HDMI_DITH_CNTL, 1, 4, 1); else hd21_set_reg_bits(VPU_HDMI_DITH_CNTL, 0, 4, 1); diff --git a/drivers/media/vout/hdmitx_common/hdmitx_edid.c b/drivers/media/vout/hdmitx_common/hdmitx_edid.c index 19054c684..2510516c1 100644 --- a/drivers/media/vout/hdmitx_common/hdmitx_edid.c +++ b/drivers/media/vout/hdmitx_common/hdmitx_edid.c @@ -263,7 +263,9 @@ int hdmitx_edid_validate_format_para(struct rx_cap *prxcap, if (para->cd != COLORDEPTH_24B && !para->frl_clk) return -EPERM; break; + case HDMI_6_720x480i60_4x3: case HDMI_7_720x480i60_16x9: + case HDMI_21_720x576i50_4x3: case HDMI_22_720x576i50_16x9: if (para->cs == HDMI_COLORSPACE_YUV422) return -EPERM; diff --git a/drivers/media/vout/hdmitx_common/hdmitx_hw_common.c b/drivers/media/vout/hdmitx_common/hdmitx_hw_common.c index 6296fcfc2..cf6ae223c 100644 --- a/drivers/media/vout/hdmitx_common/hdmitx_hw_common.c +++ b/drivers/media/vout/hdmitx_common/hdmitx_hw_common.c @@ -25,7 +25,7 @@ int hdmitx_hw_set_phy(struct hdmitx_hw_common *tx_hw, int flag) return 0; } -u32 hdmitx_hw_calc_frl_bandwidth(u32 pixel_freq, +u32 hdmitx_calc_frl_clk(u32 pixel_freq, enum hdmi_colorspace cs, enum hdmi_color_depth cd) { u32 bandwidth; diff --git a/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h b/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h index de8d64cb0..798d7fd48 100644 --- a/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h +++ b/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h @@ -631,7 +631,6 @@ unsigned int hdmitx_rd_reg(unsigned int addr); unsigned int hdmitx_rd_check_reg(unsigned int addr, unsigned int exp_data, unsigned int mask); bool hdmitx_get_bit(unsigned int addr, unsigned int bit_nr); -void vsem_init_cfg(struct hdmitx_dev *hdev); enum hdmi_tf_type hdmitx_get_cur_hdr_st(void); enum hdmi_tf_type hdmitx_get_cur_dv_st(void); diff --git a/include/linux/amlogic/media/vout/hdmi_tx21/hdmi_common.h b/include/linux/amlogic/media/vout/hdmi_tx21/hdmi_common.h index 34658d4bf..53d93854a 100644 --- a/include/linux/amlogic/media/vout/hdmi_tx21/hdmi_common.h +++ b/include/linux/amlogic/media/vout/hdmi_tx21/hdmi_common.h @@ -13,13 +13,6 @@ #include #include -#define HDMI_PACKET_TYPE_GCP 0x3 - -u32 calc_frl_bandwidth(u32 pixel_freq, enum hdmi_colorspace cs, - enum hdmi_color_depth cd); -u32 calc_tmds_bandwidth(u32 pixel_freq, enum hdmi_colorspace cs, - enum hdmi_color_depth cd); - enum hdmi_audio_fs; struct hdmi_csc_coef_table { diff --git a/include/linux/amlogic/media/vout/hdmi_tx21/hdmi_tx_module.h b/include/linux/amlogic/media/vout/hdmi_tx21/hdmi_tx_module.h index 0f37f51ca..2c168d767 100644 --- a/include/linux/amlogic/media/vout/hdmi_tx21/hdmi_tx_module.h +++ b/include/linux/amlogic/media/vout/hdmi_tx21/hdmi_tx_module.h @@ -226,15 +226,7 @@ struct hdmitx_dev { int (*cntlmisc)(struct hdmitx_dev *hdev, u32 cmd, u32 arg); int (*cntl)(struct hdmitx_dev *hdev, u32 cmd, u32 arg); /* Other control */ } hwop; - struct { - u32 enable; - union hdmi_infoframe vend; - union hdmi_infoframe avi; - union hdmi_infoframe spd; - union hdmi_infoframe aud; - union hdmi_infoframe drm; - union hdmi_infoframe emp; - } infoframes; + struct hdmitx_infoframe infoframes; struct hdmi_config_platform_data config_data; enum hdmi_event_t hdmitx_event; u32 irq_hpd; @@ -341,31 +333,21 @@ struct hdmitx_dev { }; struct hdmitx_dev *get_hdmitx21_device(void); +int hdmitx21_construct_vsif(struct hdmitx_dev *hdev, + enum vsif_type type, int on, void *param); /*********************************************************************** * hdmitx protocol level interface **********************************************************************/ -enum hdmi_vic hdmitx21_edid_vic_tab_map_vic(const char *disp_mode); int hdmitx21_edid_parse(struct hdmitx_dev *hdev); int check21_dvi_hdmi_edid_valid(u8 *buf); -enum hdmi_vic hdmitx21_edid_get_VIC(struct hdmitx_dev *hdev, - const char *disp_mode, - char force_flag); -bool hdmitx21_edid_check_valid_mode(struct hdmitx_dev *hdev, - struct hdmi_format_para *para); -const char *hdmitx21_edid_vic_to_string(enum hdmi_vic vic); void hdmitx21_edid_clear(struct hdmitx_dev *hdev); void hdmitx21_edid_ram_buffer_clear(struct hdmitx_dev *hdev); void hdmitx21_edid_buf_compare_print(struct hdmitx_dev *hdev); void hdmitx21_dither_config(struct hdmitx_dev *hdev); - -int hdmitx21_construct_vsif(struct hdmitx_dev *hdev, - enum vsif_type type, int on, void *param); - -/* if vic is 93 ~ 95, or 98 (HDMI14 4K), return 1 */ -bool _is_hdmi14_4k(enum hdmi_vic vic); -/* if vic is 96, 97, 101, 102, 106, 107, 4k 50/60hz, return 1 */ -bool _is_y420_vic(enum hdmi_vic vic); +enum hdmi_tf_type hdmitx21_get_cur_hdr_st(void); +enum hdmi_tf_type hdmitx21_get_cur_dv_st(void); +enum hdmi_tf_type hdmitx21_get_cur_hdr10p_st(void); /* set vic to AVI.VIC */ void hdmitx21_set_avi_vic(enum hdmi_vic vic); @@ -456,7 +438,6 @@ int hdmitx21_set_uevent(enum hdmitx_event type, int val); int hdmitx21_set_uevent_state(enum hdmitx_event type, int state); void hdmi_set_audio_para(int para); -int get21_cur_vout_index(void); void phy_hpll_off(void); int get21_hpd_state(void); void hdmitx21_event_notify(unsigned long state, void *arg); @@ -492,8 +473,6 @@ enum ddc_op { DDC_UNMUX_DDC, }; -int hdmitx21_ddc_hw_op(enum ddc_op cmd); - #define HDMITX_HWCMD_MUX_HPD_IF_PIN_HIGH 0x3 #define HDMITX_HWCMD_TURNOFF_HDMIHW 0x4 #define HDMITX_HWCMD_MUX_HPD 0x5 @@ -524,19 +503,5 @@ int hdmitx21_ddc_hw_op(enum ddc_op cmd); #define INTR_MASKN_DISABLE 1 #define INTR_CLEAR 2 -/* the hdmitx output limits to 1080p */ -bool hdmitx21_limited_1080p(void); -/* test current vic is over limited or not */ -bool hdmitx21_is_vic_over_limited_1080p(enum hdmi_vic vic); - -void vsem_init_cfg(struct hdmitx_dev *hdev); - -enum hdmi_tf_type hdmitx21_get_cur_hdr_st(void); -enum hdmi_tf_type hdmitx21_get_cur_dv_st(void); -enum hdmi_tf_type hdmitx21_get_cur_hdr10p_st(void); -bool hdmitx21_hdr_en(void); -bool hdmitx21_dv_en(void); -bool hdmitx21_hdr10p_en(void); u32 aud_sr_idx_to_val(enum hdmi_audio_fs e_sr_idx); -bool hdmitx21_uboot_already_display(struct hdmitx_dev *hdev); #endif diff --git a/include/linux/amlogic/media/vout/hdmitx_common/hdmitx_common.h b/include/linux/amlogic/media/vout/hdmitx_common/hdmitx_common.h index 28109453c..1b7e745e1 100644 --- a/include/linux/amlogic/media/vout/hdmitx_common/hdmitx_common.h +++ b/include/linux/amlogic/media/vout/hdmitx_common/hdmitx_common.h @@ -17,14 +17,6 @@ #define HDMI_INFOFRAME_TYPE_VENDOR2 (0x81 | 0x100) -struct frac_rate_table { - char *hz; - u32 sync_num_int; - u32 sync_den_int; - u32 sync_num_dec; - u32 sync_den_dec; -}; - struct hdmitx_ctrl_ops { int (*pre_enable_mode)(struct hdmitx_common *tx_comm, struct hdmi_format_para *para); int (*enable_mode)(struct hdmitx_common *tx_comm, struct hdmi_format_para *para); diff --git a/include/linux/amlogic/media/vout/hdmitx_common/hdmitx_types.h b/include/linux/amlogic/media/vout/hdmitx_common/hdmitx_types.h index 32534c4dc..a217cea81 100644 --- a/include/linux/amlogic/media/vout/hdmitx_common/hdmitx_types.h +++ b/include/linux/amlogic/media/vout/hdmitx_common/hdmitx_types.h @@ -58,6 +58,8 @@ enum hdmi_aspect_ratio { TV_ASPECT_RATIO_MAX }; +#define HDMI_INFOFRAME_TYPE_VENDOR2 (0x81 | 0x100) + enum frl_rate_enum { FRL_NONE = 0, FRL_3G3L = 1, @@ -84,4 +86,16 @@ struct size_map { enum hdmi_audio_sampsize ss; }; +#define HDMI_PACKET_TYPE_GCP 0x3 + +struct hdmitx_infoframe { + u32 enable; + union hdmi_infoframe vend; + union hdmi_infoframe avi; + union hdmi_infoframe spd; + union hdmi_infoframe aud; + union hdmi_infoframe drm; + union hdmi_infoframe emp; +}; + #endif