mirror of
https://github.com/hardkernel/kernel_common_drivers.git
synced 2026-06-25 12:03:48 +09:00
hdmitx21: update to use hdmitx_common api [1/1]
PD#SWPL-138534 Problem: tx20/tx21 have different valid mode flow and api Solution: use common api instead Verify: verify on T7 Test: DRM-TX-19, DRM-TX-20,DRM-TX-22, DRM-TX-25, DRM-TX-27 Change-Id: I008e5931adb223391e79149f908d5ad1cb186889 Signed-off-by: sky zhou <sky.zhou@amlogic.com>
This commit is contained in:
@@ -7,183 +7,11 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/amlogic/media/vout/hdmi_tx21/hdmi_tx_module.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
#include <hdmitx_drm_hook.h>
|
||||
#include <hdmitx_sysfs_common.h>
|
||||
#include <linux/amlogic/media/vout/hdmitx_common/hdmitx_common.h>
|
||||
#include <linux/amlogic/media/vout/hdmitx_common/hdmitx_format_para.h>
|
||||
|
||||
#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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -13,13 +13,6 @@
|
||||
#include <linux/amlogic/media/vout/hdmitx_common/hdmitx_edid.h>
|
||||
#include <linux/amlogic/media/vout/hdmitx_common/hdmitx_mode.h>
|
||||
|
||||
#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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user