Loading drivers/video/msm/mdss/mdss_hdmi_edid.c +54 −47 Original line number Diff line number Diff line Loading @@ -188,8 +188,6 @@ static ssize_t hdmi_edid_sysfs_rda_modes(struct device *dev, if (edid_ctrl->sink_data.num_of_elements) { u32 *video_mode = edid_ctrl->sink_data.disp_mode_list; for (i = 0; i < edid_ctrl->sink_data.num_of_elements; ++i) { if (!hdmi_get_supported_mode(*video_mode)) continue; if (ret > 0) ret += scnprintf(buf + ret, PAGE_SIZE - ret, ",%d", *video_mode++); Loading Loading @@ -746,7 +744,8 @@ static u32 hdmi_edid_check_header(const u8 *edid_buf) && (edid_buf[6] == 0xff) && (edid_buf[7] == 0x00); } /* hdmi_edid_check_header */ static void hdmi_edid_detail_desc(const u8 *data_buf, u32 *disp_mode) static void hdmi_edid_detail_desc(struct hdmi_edid_ctrl *edid_ctrl, const u8 *data_buf, u32 *disp_mode) { u32 aspect_ratio_4_3 = false; u32 interlaced = false; Loading Loading @@ -831,23 +830,25 @@ static void hdmi_edid_detail_desc(const u8 *data_buf, u32 *disp_mode) *disp_mode = HDMI_VFRMT_FORCE_32BIT; for (ndx = HDMI_VFRMT_UNKNOWN + 1; ndx < HDMI_VFRMT_MAX; ndx++) { const struct msm_hdmi_mode_timing_info *timing = NULL; timing = hdmi_get_supported_mode(ndx); struct msm_hdmi_mode_timing_info timing = {0}; u32 ret = hdmi_get_supported_mode(&timing, edid_ctrl->init_data.ds_data, ndx); if (!timing) if (ret || !timing.supported) continue; if ((interlaced == timing->interlaced) && (active_h == timing->active_h) && (blank_h == (timing->front_porch_h + timing->pulse_width_h + timing->back_porch_h)) && (blank_v == (timing->front_porch_v + timing->pulse_width_v + timing->back_porch_v)) && ((active_v == timing->active_v) || (active_v == (timing->active_v + 1)))) { *disp_mode = timing->video_format; if ((interlaced == timing.interlaced) && (active_h == timing.active_h) && (blank_h == (timing.front_porch_h + timing.pulse_width_h + timing.back_porch_h)) && (blank_v == (timing.front_porch_v + timing.pulse_width_v + timing.back_porch_v)) && ((active_v == timing.active_v) || (active_v == (timing.active_v + 1)))) { *disp_mode = timing.video_format; /* * There can be 16:9 and 4:3 aspect ratio of same Loading @@ -856,10 +857,10 @@ static void hdmi_edid_detail_desc(const u8 *data_buf, u32 *disp_mode) */ if (aspect_ratio_4_3 && (timing->ar != HDMI_RES_AR_4_3)) (timing.ar != HDMI_RES_AR_4_3)) continue; else if (!aspect_ratio_4_3 && (timing->ar == HDMI_RES_AR_4_3)) (timing.ar == HDMI_RES_AR_4_3)) continue; else break; Loading Loading @@ -894,12 +895,15 @@ static void hdmi_edid_add_sink_3d_format(struct hdmi_edid_sink_data *sink_data, string, added ? "added" : "NOT added"); } /* hdmi_edid_add_sink_3d_format */ static void hdmi_edid_add_sink_video_format( struct hdmi_edid_sink_data *sink_data, u32 video_format) static void hdmi_edid_add_sink_video_format(struct hdmi_edid_ctrl *edid_ctrl, u32 video_format) { const struct msm_hdmi_mode_timing_info *timing = hdmi_get_supported_mode(video_format); u32 supported = timing != NULL; struct msm_hdmi_mode_timing_info timing = {0}; u32 ret = hdmi_get_supported_mode(&timing, edid_ctrl->init_data.ds_data, video_format); u32 supported = timing.supported; struct hdmi_edid_sink_data *sink_data = &edid_ctrl->sink_data; if (video_format >= HDMI_VFRMT_MAX) { DEV_ERR("%s: video format: %s is not supported\n", __func__, Loading @@ -911,7 +915,7 @@ static void hdmi_edid_add_sink_video_format( video_format, msm_hdmi_mode_2string(video_format), supported ? "Supported" : "Not-Supported"); if (supported) { if (!ret && supported) { /* todo: MHL */ sink_data->disp_mode_list[sink_data->num_of_elements++] = video_format; Loading Loading @@ -1100,7 +1104,7 @@ static void hdmi_edid_get_extended_video_formats( for (i = 0; i < hdmi_vic_len; i++) { video_format = HDMI_VFRMT_END + vsd[offset + 2 + i]; hdmi_edid_add_sink_video_format(&edid_ctrl->sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, video_format); } } Loading Loading @@ -1145,7 +1149,7 @@ static void hdmi_edid_parse_et3(struct hdmi_edid_ctrl *edid_ctrl, iter++; if (edid_blk0[iter] & BIT(3)) { pr_debug("%s: DMT 848x480@60\n", __func__); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_848x480p60_16_9); } Loading @@ -1153,13 +1157,13 @@ static void hdmi_edid_parse_et3(struct hdmi_edid_ctrl *edid_ctrl, iter++; if (edid_blk0[iter] & BIT(1)) { pr_debug("%s: DMT 1280x1024@60\n", __func__); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_1280x1024p60_5_4); } if (edid_blk0[iter] & BIT(3)) { pr_debug("%s: DMT 1280x960@60\n", __func__); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_1280x960p60_4_3); } Loading @@ -1167,19 +1171,19 @@ static void hdmi_edid_parse_et3(struct hdmi_edid_ctrl *edid_ctrl, iter++; if (edid_blk0[iter] & BIT(1)) { pr_debug("%s: DMT 1400x1050@60\n", __func__); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_1400x1050p60_4_3); } if (edid_blk0[iter] & BIT(5)) { pr_debug("%s: DMT 1440x900@60\n", __func__); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_1440x900p60_16_10); } if (edid_blk0[iter] & BIT(7)) { pr_debug("%s: DMT 1360x768@60\n", __func__); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_1360x768p60_16_9); } Loading @@ -1187,13 +1191,13 @@ static void hdmi_edid_parse_et3(struct hdmi_edid_ctrl *edid_ctrl, iter++; if (edid_blk0[iter] & BIT(2)) { pr_debug("%s: DMT 1600x1200@60\n", __func__); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_1600x1200p60_4_3); } if (edid_blk0[iter] & BIT(5)) { pr_debug("%s: DMT 1680x1050@60\n", __func__); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_1680x1050p60_16_10); } Loading @@ -1201,7 +1205,7 @@ static void hdmi_edid_parse_et3(struct hdmi_edid_ctrl *edid_ctrl, iter++; if (edid_blk0[iter] & BIT(0)) { pr_debug("%s: DMT 1920x1200@60\n", __func__); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_1920x1200p60_16_10); } Loading Loading @@ -1256,7 +1260,7 @@ static void hdmi_edid_get_display_mode(struct hdmi_edid_ctrl *edid_ctrl, * CEA_861D spec */ video_format = (*svd & 0x7F); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, video_format); /* Make a note of the preferred video format */ if (i == 0) Loading Loading @@ -1296,14 +1300,15 @@ static void hdmi_edid_get_display_mode(struct hdmi_edid_ctrl *edid_ctrl, * timing descriptor has block size of 18 */ while (4 > i && 0 != edid_blk0[0x36+desc_offset]) { hdmi_edid_detail_desc(edid_blk0+0x36+desc_offset, hdmi_edid_detail_desc(edid_ctrl, edid_blk0+0x36+desc_offset, &video_format); DEV_DBG("[%s:%d] Block-0 Adding vid fmt = [%s]\n", __func__, __LINE__, msm_hdmi_mode_2string(video_format)); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, video_format); if (video_format == HDMI_VFRMT_640x480p60_4_3) Loading @@ -1325,14 +1330,15 @@ static void hdmi_edid_get_display_mode(struct hdmi_edid_ctrl *edid_ctrl, * Read EDID block[0] as above */ while (4 > i && 0 != edid_blk0[0x36+desc_offset]) { hdmi_edid_detail_desc(edid_blk0+0x36+desc_offset, hdmi_edid_detail_desc(edid_ctrl, edid_blk0+0x36+desc_offset, &video_format); DEV_DBG("[%s:%d] Block-0 Adding vid fmt = [%s]\n", __func__, __LINE__, msm_hdmi_mode_2string(video_format)); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, video_format); if (video_format == HDMI_VFRMT_640x480p60_4_3) Loading @@ -1358,14 +1364,15 @@ static void hdmi_edid_get_display_mode(struct hdmi_edid_ctrl *edid_ctrl, */ desc_offset = edid_blk1[0x02]; while (0 != edid_blk1[desc_offset]) { hdmi_edid_detail_desc(edid_blk1+desc_offset, hdmi_edid_detail_desc(edid_ctrl, edid_blk1+desc_offset, &video_format); DEV_DBG("[%s:%d] Block-1 Adding vid fmt = [%s]\n", __func__, __LINE__, msm_hdmi_mode_2string(video_format)); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, video_format); if (video_format == HDMI_VFRMT_640x480p60_4_3) has480p = true; Loading @@ -1387,14 +1394,14 @@ static void hdmi_edid_get_display_mode(struct hdmi_edid_ctrl *edid_ctrl, (edid_blk0[0x26 + offset + 1] == 0x80)) { pr_debug("%s: 108MHz: off=[%x] stdblk=[%x]\n", __func__, offset, std_blk); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_1280x1024p60_5_4); } if ((edid_blk0[0x26 + offset] == 0x61) && (edid_blk0[0x26 + offset + 1] == 0x40)) { pr_debug("%s: 65MHz: off=[%x] stdblk=[%x]\n", __func__, offset, std_blk); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_1024x768p60_4_3); break; } else { Loading @@ -1406,7 +1413,7 @@ static void hdmi_edid_get_display_mode(struct hdmi_edid_ctrl *edid_ctrl, /* Established Timing I */ if (edid_blk0[0x23] & BIT(0)) { pr_debug("%s: DMT: ETI: HDMI_VFRMT_800x600_4_3\n", __func__); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_800x600p60_4_3); } Loading @@ -1414,7 +1421,7 @@ static void hdmi_edid_get_display_mode(struct hdmi_edid_ctrl *edid_ctrl, if (edid_blk0[0x24] & BIT(3)) { pr_debug("%s: DMT: ETII: HDMI_VFRMT_1024x768p60_4_3\n", __func__); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_1024x768p60_4_3); } Loading Loading @@ -1462,7 +1469,7 @@ static void hdmi_edid_get_display_mode(struct hdmi_edid_ctrl *edid_ctrl, * All DTV sink devices should support this mode */ if (!has480p) hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_640x480p60_4_3); } /* hdmi_edid_get_display_mode */ Loading drivers/video/msm/mdss/mdss_hdmi_edid.h +1 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ struct hdmi_edid_init_data { struct kobject *sysfs_kobj; struct hdmi_tx_ddc_ctrl *ddc_ctrl; struct hdmi_util_ds_data *ds_data; }; int hdmi_edid_read(void *edid_ctrl); Loading drivers/video/msm/mdss/mdss_hdmi_tx.c +125 −67 Original line number Diff line number Diff line Loading @@ -438,7 +438,12 @@ static int hdmi_tx_get_vic_from_panel_info(struct hdmi_tx_ctrl *hdmi_ctrl, } if (pinfo->vic) { if (hdmi_get_supported_mode(pinfo->vic)) { struct msm_hdmi_mode_timing_info info = {0}; u32 ret = hdmi_get_supported_mode(&info, &hdmi_ctrl->ds_data, pinfo->vic); u32 supported = info.supported; if (!ret && supported) { new_vic = pinfo->vic; DEV_DBG("%s: %s is supported\n", __func__, msm_hdmi_mode_2string(new_vic)); Loading Loading @@ -479,7 +484,7 @@ static int hdmi_tx_get_vic_from_panel_info(struct hdmi_tx_ctrl *hdmi_ctrl, DEV_DBG("%s: pixel_freq=%d refresh_rate=%d\n", __func__, timing.pixel_freq, timing.refresh_rate); new_vic = hdmi_get_video_id_code(&timing); new_vic = hdmi_get_video_id_code(&timing, &hdmi_ctrl->ds_data); } return new_vic; Loading Loading @@ -708,7 +713,7 @@ static ssize_t hdmi_tx_sysfs_wta_hpd(struct device *dev, return rc; } if (hdmi_ctrl->mhl_max_pclk && hpd && if (hdmi_ctrl->ds_registered && hpd && (!hdmi_ctrl->mhl_hpd_on || hdmi_ctrl->hpd_feature_on)) return 0; Loading Loading @@ -992,6 +997,72 @@ static ssize_t hdmi_tx_sysfs_wta_avi_cn_bits(struct device *dev, return ret; } /* hdmi_tx_sysfs_wta_cn_bits */ static ssize_t hdmi_tx_sysfs_wta_res_info(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int rc, res_info_id; ssize_t ret = strnlen(buf, PAGE_SIZE); struct hdmi_tx_ctrl *hdmi_ctrl = NULL; hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev); if (!hdmi_ctrl) { DEV_ERR("%s: invalid input\n", __func__); return -EINVAL; } rc = kstrtoint(buf, 10, &res_info_id); if (rc) { DEV_ERR("%s: kstrtoint failed. rc=%d\n", __func__, rc); return rc; } if (res_info_id >= 0 && res_info_id < HDMI_VFRMT_MAX) hdmi_ctrl->res_info_id = res_info_id; else hdmi_ctrl->res_info_id = 0; DEV_DBG("%s: %d\n", __func__, hdmi_ctrl->res_info_id); return ret; } static ssize_t hdmi_tx_sysfs_rda_res_info(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t ret; struct msm_hdmi_mode_timing_info info = {0}; struct hdmi_tx_ctrl *hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev); u32 size = sizeof(info) < PAGE_SIZE ? sizeof(info) : PAGE_SIZE; if (!hdmi_ctrl) { DEV_ERR("%s: invalid input\n", __func__); return -EINVAL; } if (!hdmi_ctrl->res_info_id) return -EINVAL; ret = hdmi_get_supported_mode(&info, &hdmi_ctrl->ds_data, hdmi_ctrl->res_info_id); if (ret) return -EINVAL; memcpy(buf, &info, size); DEV_DBG("%s: %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n", __func__, info.video_format, info.active_h, info.front_porch_h, info.pulse_width_h, info.back_porch_h, info.active_low_h, info.active_v, info.front_porch_v, info.pulse_width_v, info.back_porch_v, info.active_low_v, info.pixel_freq, info.refresh_rate, info.interlaced, info.supported, info.ar); return size; } static DEVICE_ATTR(connected, S_IRUGO, hdmi_tx_sysfs_rda_connected, NULL); static DEVICE_ATTR(video_mode, S_IRUGO, hdmi_tx_sysfs_rda_video_mode, NULL); static DEVICE_ATTR(hpd, S_IRUGO | S_IWUSR, hdmi_tx_sysfs_rda_hpd, Loading @@ -1003,6 +1074,8 @@ static DEVICE_ATTR(product_description, S_IRUGO | S_IWUSR, hdmi_tx_sysfs_wta_product_description); static DEVICE_ATTR(avi_itc, S_IWUSR, NULL, hdmi_tx_sysfs_wta_avi_itc); static DEVICE_ATTR(avi_cn0_1, S_IWUSR, NULL, hdmi_tx_sysfs_wta_avi_cn_bits); static DEVICE_ATTR(res_info, S_IRUGO | S_IWUSR, hdmi_tx_sysfs_rda_res_info, hdmi_tx_sysfs_wta_res_info); static struct attribute *hdmi_tx_fs_attrs[] = { &dev_attr_connected.attr, Loading @@ -1012,6 +1085,7 @@ static struct attribute *hdmi_tx_fs_attrs[] = { &dev_attr_product_description.attr, &dev_attr_avi_itc.attr, &dev_attr_avi_cn0_1.attr, &dev_attr_res_info.attr, NULL, }; static struct attribute_group hdmi_tx_fs_attrs_group = { Loading Loading @@ -1186,6 +1260,7 @@ static int hdmi_tx_init_features(struct hdmi_tx_ctrl *hdmi_ctrl) edid_init_data.mutex = &hdmi_ctrl->mutex; edid_init_data.sysfs_kobj = hdmi_ctrl->kobj; edid_init_data.ddc_ctrl = &hdmi_ctrl->ddc_ctrl; edid_init_data.ds_data = &hdmi_ctrl->ds_data; hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID] = hdmi_edid_init(&edid_init_data); Loading Loading @@ -1253,31 +1328,33 @@ static inline u32 hdmi_tx_is_controller_on(struct hdmi_tx_ctrl *hdmi_ctrl) static int hdmi_tx_init_panel_info(struct hdmi_tx_ctrl *hdmi_ctrl) { struct mdss_panel_info *pinfo; const struct msm_hdmi_mode_timing_info *timing; struct msm_hdmi_mode_timing_info timing = {0}; u32 ret; if (!hdmi_ctrl) { DEV_ERR("%s: invalid input\n", __func__); return -EINVAL; } timing = hdmi_get_supported_mode(hdmi_ctrl->video_resolution); ret = hdmi_get_supported_mode(&timing, &hdmi_ctrl->ds_data, hdmi_ctrl->video_resolution); pinfo = &hdmi_ctrl->panel_data.panel_info; if (!timing || !pinfo) { if (ret || !timing.supported || !pinfo) { DEV_ERR("%s: invalid timing data\n", __func__); return -EINVAL; } pinfo->xres = timing->active_h; pinfo->yres = timing->active_v; pinfo->clk_rate = timing->pixel_freq*1000; pinfo->xres = timing.active_h; pinfo->yres = timing.active_v; pinfo->clk_rate = timing.pixel_freq * 1000; pinfo->lcdc.h_back_porch = timing->back_porch_h; pinfo->lcdc.h_front_porch = timing->front_porch_h; pinfo->lcdc.h_pulse_width = timing->pulse_width_h; pinfo->lcdc.v_back_porch = timing->back_porch_v; pinfo->lcdc.v_front_porch = timing->front_porch_v; pinfo->lcdc.v_pulse_width = timing->pulse_width_v; pinfo->lcdc.h_back_porch = timing.back_porch_h; pinfo->lcdc.h_front_porch = timing.front_porch_h; pinfo->lcdc.h_pulse_width = timing.pulse_width_h; pinfo->lcdc.v_back_porch = timing.back_porch_v; pinfo->lcdc.v_front_porch = timing.front_porch_v; pinfo->lcdc.v_pulse_width = timing.pulse_width_v; pinfo->type = DTV_PANEL; pinfo->pdest = DISPLAY_2; Loading @@ -1294,30 +1371,6 @@ static int hdmi_tx_init_panel_info(struct hdmi_tx_ctrl *hdmi_ctrl) return 0; } /* hdmi_tx_init_panel_info */ /* Table tuned to indicate video formats supported by the MHL Tx */ /* Valid pclk rates (Mhz): 25.2, 27, 27.03, 74.25 */ static void hdmi_tx_setup_mhl_video_mode_lut(struct hdmi_tx_ctrl *hdmi_ctrl) { u32 i; struct msm_hdmi_mode_timing_info *temp_timing; if (!hdmi_ctrl->mhl_max_pclk) { DEV_WARN("%s: mhl max pclk not set!\n", __func__); return; } DEV_DBG("%s: max mode set to [%u]\n", __func__, hdmi_ctrl->mhl_max_pclk); for (i = 0; i < HDMI_VFRMT_MAX; i++) { temp_timing = (struct msm_hdmi_mode_timing_info *)hdmi_get_supported_mode(i); if (!temp_timing) continue; /* formats that exceed max mhl line clk bw */ if (temp_timing->pixel_freq > hdmi_ctrl->mhl_max_pclk) hdmi_del_supported_mode(i); } } /* hdmi_tx_setup_mhl_video_mode_lut */ static int hdmi_tx_read_sink_info(struct hdmi_tx_ctrl *hdmi_ctrl) { int status; Loading Loading @@ -1442,8 +1495,9 @@ static int hdmi_tx_set_video_fmt(struct hdmi_tx_ctrl *hdmi_ctrl, struct mdss_panel_info *pinfo) { int new_vic = -1; const struct msm_hdmi_mode_timing_info *timing = NULL; struct msm_hdmi_mode_timing_info timing = {0}; int res_changed = RESOLUTION_UNCHANGED; u32 ret; if (!hdmi_ctrl || !pinfo) { DEV_ERR("%s: invalid input\n", __func__); Loading @@ -1465,16 +1519,17 @@ static int hdmi_tx_set_video_fmt(struct hdmi_tx_ctrl *hdmi_ctrl, hdmi_ctrl->video_resolution = (u32)new_vic; timing = hdmi_get_supported_mode(hdmi_ctrl->video_resolution); ret = hdmi_get_supported_mode(&timing, &hdmi_ctrl->ds_data, hdmi_ctrl->video_resolution); if (!timing) { if (ret || !timing.supported) { DEV_ERR("%s: invalid input\n", __func__); return -EINVAL; } /* todo: find a better way */ hdmi_ctrl->pdata.power_data[HDMI_TX_CORE_PM].clk_config[0].rate = timing->pixel_freq * 1000; timing.pixel_freq * 1000; hdmi_edid_set_video_resolution( hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID], Loading @@ -1494,9 +1549,11 @@ static int hdmi_tx_video_setup(struct hdmi_tx_ctrl *hdmi_ctrl, u32 end_v = 0; struct dss_io_data *io = NULL; const struct msm_hdmi_mode_timing_info *timing = hdmi_get_supported_mode(video_format); if (timing == NULL) { struct msm_hdmi_mode_timing_info timing = {0}; u32 ret = hdmi_get_supported_mode(&timing, &hdmi_ctrl->ds_data, video_format); if (ret || !timing.supported) { DEV_ERR("%s: video format not supported: %d\n", __func__, video_format); return -EPERM; Loading @@ -1513,10 +1570,10 @@ static int hdmi_tx_video_setup(struct hdmi_tx_ctrl *hdmi_ctrl, return -EPERM; } total_h = timing->active_h + timing->front_porch_h + timing->back_porch_h + timing->pulse_width_h - 1; total_v = timing->active_v + timing->front_porch_v + timing->back_porch_v + timing->pulse_width_v - 1; total_h = timing.active_h + timing.front_porch_h + timing.back_porch_h + timing.pulse_width_h - 1; total_v = timing.active_v + timing.front_porch_v + timing.back_porch_v + timing.pulse_width_v - 1; if (((total_v << 16) & 0xE0000000) || (total_h & 0xFFFFE000)) { DEV_ERR("%s: total v=%d or h=%d is larger than supported\n", __func__, total_v, total_h); Loading @@ -1524,8 +1581,8 @@ static int hdmi_tx_video_setup(struct hdmi_tx_ctrl *hdmi_ctrl, } DSS_REG_W(io, HDMI_TOTAL, (total_v << 16) | (total_h << 0)); start_h = timing->back_porch_h + timing->pulse_width_h; end_h = (total_h + 1) - timing->front_porch_h; start_h = timing.back_porch_h + timing.pulse_width_h; end_h = (total_h + 1) - timing.front_porch_h; if (((end_h << 16) & 0xE0000000) || (start_h & 0xFFFFE000)) { DEV_ERR("%s: end_h=%d or start_h=%d is larger than supported\n", __func__, end_h, start_h); Loading @@ -1533,8 +1590,8 @@ static int hdmi_tx_video_setup(struct hdmi_tx_ctrl *hdmi_ctrl, } DSS_REG_W(io, HDMI_ACTIVE_H, (end_h << 16) | (start_h << 0)); start_v = timing->back_porch_v + timing->pulse_width_v - 1; end_v = total_v - timing->front_porch_v; start_v = timing.back_porch_v + timing.pulse_width_v - 1; end_v = total_v - timing.front_porch_v; if (((end_v << 16) & 0xE0000000) || (start_v & 0xFFFFE000)) { DEV_ERR("%s: end_v=%d or start_v=%d is larger than supported\n", __func__, end_v, start_v); Loading @@ -1542,7 +1599,7 @@ static int hdmi_tx_video_setup(struct hdmi_tx_ctrl *hdmi_ctrl, } DSS_REG_W(io, HDMI_ACTIVE_V, (end_v << 16) | (start_v << 0)); if (timing->interlaced) { if (timing.interlaced) { DSS_REG_W(io, HDMI_V_TOTAL_F2, (total_v + 1) << 0); DSS_REG_W(io, HDMI_ACTIVE_V_F2, ((end_v + 1) << 16) | ((start_v + 1) << 0)); Loading @@ -1552,9 +1609,9 @@ static int hdmi_tx_video_setup(struct hdmi_tx_ctrl *hdmi_ctrl, } DSS_REG_W(io, HDMI_FRAME_CTRL, ((timing->interlaced << 31) & 0x80000000) | ((timing->active_low_h << 29) & 0x20000000) | ((timing->active_low_v << 28) & 0x10000000)); ((timing.interlaced << 31) & 0x80000000) | ((timing.active_low_h << 29) & 0x20000000) | ((timing.active_low_v << 28) & 0x10000000)); return 0; } /* hdmi_tx_video_setup */ Loading Loading @@ -2231,28 +2288,29 @@ static int hdmi_tx_audio_acr_setup(struct hdmi_tx_ctrl *hdmi_ctrl, acr_pck_ctrl_reg = DSS_REG_R(io, HDMI_ACR_PKT_CTRL); if (enabled) { const struct msm_hdmi_mode_timing_info *timing = hdmi_get_supported_mode(hdmi_ctrl->video_resolution); struct msm_hdmi_mode_timing_info timing = {0}; u32 ret = hdmi_get_supported_mode(&timing, &hdmi_ctrl->ds_data, hdmi_ctrl->video_resolution); const struct hdmi_tx_audio_acr_arry *audio_acr = &hdmi_tx_audio_acr_lut[0]; const int lut_size = sizeof(hdmi_tx_audio_acr_lut) / sizeof(*hdmi_tx_audio_acr_lut); u32 i, n, cts, layout, multiplier, aud_pck_ctrl_2_reg; if (timing == NULL) { DEV_WARN("%s: video format %d not supported\n", if (ret || !timing.supported) { DEV_ERR("%s: video format %d not supported\n", __func__, hdmi_ctrl->video_resolution); return -EPERM; } for (i = 0; i < lut_size; audio_acr = &hdmi_tx_audio_acr_lut[++i]) { if (audio_acr->pclk == timing->pixel_freq) if (audio_acr->pclk == timing.pixel_freq) break; } if (i >= lut_size) { DEV_WARN("%s: pixel clk %d not supported\n", __func__, timing->pixel_freq); timing.pixel_freq); return -EPERM; } Loading Loading @@ -2569,12 +2627,13 @@ static int hdmi_tx_set_mhl_max_pclk(struct platform_device *pdev, u32 max_val) return -ENODEV; } if (max_val) { hdmi_ctrl->mhl_max_pclk = max_val; hdmi_tx_setup_mhl_video_mode_lut(hdmi_ctrl); hdmi_ctrl->ds_data.ds_max_clk = max_val; hdmi_ctrl->ds_data.ds_registered = true; } else { DEV_ERR("%s: invalid max pclk val\n", __func__); return -EINVAL; } return 0; } Loading Loading @@ -3218,7 +3277,6 @@ static int hdmi_tx_dev_init(struct hdmi_tx_ctrl *hdmi_ctrl) /* irq enable/disable will be handled in hpd on/off */ hdmi_tx_hw.ptr = (void *)hdmi_ctrl; hdmi_setup_video_mode_lut(); mutex_init(&hdmi_ctrl->mutex); mutex_init(&hdmi_ctrl->lut_lock); mutex_init(&hdmi_ctrl->cable_notify_mutex); Loading drivers/video/msm/mdss/mdss_hdmi_tx.h +3 −1 Original line number Diff line number Diff line Loading @@ -89,9 +89,11 @@ struct hdmi_tx_ctrl { u32 hpd_feature_on; u32 hpd_initialized; u32 vote_hdmi_core_on; u32 res_info_id; u8 timing_gen_on; u32 mhl_max_pclk; u8 mhl_hpd_on; struct hdmi_util_ds_data ds_data; struct completion hpd_done; struct work_struct hpd_int_work; Loading drivers/video/msm/mdss/mdss_hdmi_util.c +51 −73 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
drivers/video/msm/mdss/mdss_hdmi_edid.c +54 −47 Original line number Diff line number Diff line Loading @@ -188,8 +188,6 @@ static ssize_t hdmi_edid_sysfs_rda_modes(struct device *dev, if (edid_ctrl->sink_data.num_of_elements) { u32 *video_mode = edid_ctrl->sink_data.disp_mode_list; for (i = 0; i < edid_ctrl->sink_data.num_of_elements; ++i) { if (!hdmi_get_supported_mode(*video_mode)) continue; if (ret > 0) ret += scnprintf(buf + ret, PAGE_SIZE - ret, ",%d", *video_mode++); Loading Loading @@ -746,7 +744,8 @@ static u32 hdmi_edid_check_header(const u8 *edid_buf) && (edid_buf[6] == 0xff) && (edid_buf[7] == 0x00); } /* hdmi_edid_check_header */ static void hdmi_edid_detail_desc(const u8 *data_buf, u32 *disp_mode) static void hdmi_edid_detail_desc(struct hdmi_edid_ctrl *edid_ctrl, const u8 *data_buf, u32 *disp_mode) { u32 aspect_ratio_4_3 = false; u32 interlaced = false; Loading Loading @@ -831,23 +830,25 @@ static void hdmi_edid_detail_desc(const u8 *data_buf, u32 *disp_mode) *disp_mode = HDMI_VFRMT_FORCE_32BIT; for (ndx = HDMI_VFRMT_UNKNOWN + 1; ndx < HDMI_VFRMT_MAX; ndx++) { const struct msm_hdmi_mode_timing_info *timing = NULL; timing = hdmi_get_supported_mode(ndx); struct msm_hdmi_mode_timing_info timing = {0}; u32 ret = hdmi_get_supported_mode(&timing, edid_ctrl->init_data.ds_data, ndx); if (!timing) if (ret || !timing.supported) continue; if ((interlaced == timing->interlaced) && (active_h == timing->active_h) && (blank_h == (timing->front_porch_h + timing->pulse_width_h + timing->back_porch_h)) && (blank_v == (timing->front_porch_v + timing->pulse_width_v + timing->back_porch_v)) && ((active_v == timing->active_v) || (active_v == (timing->active_v + 1)))) { *disp_mode = timing->video_format; if ((interlaced == timing.interlaced) && (active_h == timing.active_h) && (blank_h == (timing.front_porch_h + timing.pulse_width_h + timing.back_porch_h)) && (blank_v == (timing.front_porch_v + timing.pulse_width_v + timing.back_porch_v)) && ((active_v == timing.active_v) || (active_v == (timing.active_v + 1)))) { *disp_mode = timing.video_format; /* * There can be 16:9 and 4:3 aspect ratio of same Loading @@ -856,10 +857,10 @@ static void hdmi_edid_detail_desc(const u8 *data_buf, u32 *disp_mode) */ if (aspect_ratio_4_3 && (timing->ar != HDMI_RES_AR_4_3)) (timing.ar != HDMI_RES_AR_4_3)) continue; else if (!aspect_ratio_4_3 && (timing->ar == HDMI_RES_AR_4_3)) (timing.ar == HDMI_RES_AR_4_3)) continue; else break; Loading Loading @@ -894,12 +895,15 @@ static void hdmi_edid_add_sink_3d_format(struct hdmi_edid_sink_data *sink_data, string, added ? "added" : "NOT added"); } /* hdmi_edid_add_sink_3d_format */ static void hdmi_edid_add_sink_video_format( struct hdmi_edid_sink_data *sink_data, u32 video_format) static void hdmi_edid_add_sink_video_format(struct hdmi_edid_ctrl *edid_ctrl, u32 video_format) { const struct msm_hdmi_mode_timing_info *timing = hdmi_get_supported_mode(video_format); u32 supported = timing != NULL; struct msm_hdmi_mode_timing_info timing = {0}; u32 ret = hdmi_get_supported_mode(&timing, edid_ctrl->init_data.ds_data, video_format); u32 supported = timing.supported; struct hdmi_edid_sink_data *sink_data = &edid_ctrl->sink_data; if (video_format >= HDMI_VFRMT_MAX) { DEV_ERR("%s: video format: %s is not supported\n", __func__, Loading @@ -911,7 +915,7 @@ static void hdmi_edid_add_sink_video_format( video_format, msm_hdmi_mode_2string(video_format), supported ? "Supported" : "Not-Supported"); if (supported) { if (!ret && supported) { /* todo: MHL */ sink_data->disp_mode_list[sink_data->num_of_elements++] = video_format; Loading Loading @@ -1100,7 +1104,7 @@ static void hdmi_edid_get_extended_video_formats( for (i = 0; i < hdmi_vic_len; i++) { video_format = HDMI_VFRMT_END + vsd[offset + 2 + i]; hdmi_edid_add_sink_video_format(&edid_ctrl->sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, video_format); } } Loading Loading @@ -1145,7 +1149,7 @@ static void hdmi_edid_parse_et3(struct hdmi_edid_ctrl *edid_ctrl, iter++; if (edid_blk0[iter] & BIT(3)) { pr_debug("%s: DMT 848x480@60\n", __func__); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_848x480p60_16_9); } Loading @@ -1153,13 +1157,13 @@ static void hdmi_edid_parse_et3(struct hdmi_edid_ctrl *edid_ctrl, iter++; if (edid_blk0[iter] & BIT(1)) { pr_debug("%s: DMT 1280x1024@60\n", __func__); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_1280x1024p60_5_4); } if (edid_blk0[iter] & BIT(3)) { pr_debug("%s: DMT 1280x960@60\n", __func__); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_1280x960p60_4_3); } Loading @@ -1167,19 +1171,19 @@ static void hdmi_edid_parse_et3(struct hdmi_edid_ctrl *edid_ctrl, iter++; if (edid_blk0[iter] & BIT(1)) { pr_debug("%s: DMT 1400x1050@60\n", __func__); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_1400x1050p60_4_3); } if (edid_blk0[iter] & BIT(5)) { pr_debug("%s: DMT 1440x900@60\n", __func__); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_1440x900p60_16_10); } if (edid_blk0[iter] & BIT(7)) { pr_debug("%s: DMT 1360x768@60\n", __func__); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_1360x768p60_16_9); } Loading @@ -1187,13 +1191,13 @@ static void hdmi_edid_parse_et3(struct hdmi_edid_ctrl *edid_ctrl, iter++; if (edid_blk0[iter] & BIT(2)) { pr_debug("%s: DMT 1600x1200@60\n", __func__); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_1600x1200p60_4_3); } if (edid_blk0[iter] & BIT(5)) { pr_debug("%s: DMT 1680x1050@60\n", __func__); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_1680x1050p60_16_10); } Loading @@ -1201,7 +1205,7 @@ static void hdmi_edid_parse_et3(struct hdmi_edid_ctrl *edid_ctrl, iter++; if (edid_blk0[iter] & BIT(0)) { pr_debug("%s: DMT 1920x1200@60\n", __func__); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_1920x1200p60_16_10); } Loading Loading @@ -1256,7 +1260,7 @@ static void hdmi_edid_get_display_mode(struct hdmi_edid_ctrl *edid_ctrl, * CEA_861D spec */ video_format = (*svd & 0x7F); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, video_format); /* Make a note of the preferred video format */ if (i == 0) Loading Loading @@ -1296,14 +1300,15 @@ static void hdmi_edid_get_display_mode(struct hdmi_edid_ctrl *edid_ctrl, * timing descriptor has block size of 18 */ while (4 > i && 0 != edid_blk0[0x36+desc_offset]) { hdmi_edid_detail_desc(edid_blk0+0x36+desc_offset, hdmi_edid_detail_desc(edid_ctrl, edid_blk0+0x36+desc_offset, &video_format); DEV_DBG("[%s:%d] Block-0 Adding vid fmt = [%s]\n", __func__, __LINE__, msm_hdmi_mode_2string(video_format)); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, video_format); if (video_format == HDMI_VFRMT_640x480p60_4_3) Loading @@ -1325,14 +1330,15 @@ static void hdmi_edid_get_display_mode(struct hdmi_edid_ctrl *edid_ctrl, * Read EDID block[0] as above */ while (4 > i && 0 != edid_blk0[0x36+desc_offset]) { hdmi_edid_detail_desc(edid_blk0+0x36+desc_offset, hdmi_edid_detail_desc(edid_ctrl, edid_blk0+0x36+desc_offset, &video_format); DEV_DBG("[%s:%d] Block-0 Adding vid fmt = [%s]\n", __func__, __LINE__, msm_hdmi_mode_2string(video_format)); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, video_format); if (video_format == HDMI_VFRMT_640x480p60_4_3) Loading @@ -1358,14 +1364,15 @@ static void hdmi_edid_get_display_mode(struct hdmi_edid_ctrl *edid_ctrl, */ desc_offset = edid_blk1[0x02]; while (0 != edid_blk1[desc_offset]) { hdmi_edid_detail_desc(edid_blk1+desc_offset, hdmi_edid_detail_desc(edid_ctrl, edid_blk1+desc_offset, &video_format); DEV_DBG("[%s:%d] Block-1 Adding vid fmt = [%s]\n", __func__, __LINE__, msm_hdmi_mode_2string(video_format)); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, video_format); if (video_format == HDMI_VFRMT_640x480p60_4_3) has480p = true; Loading @@ -1387,14 +1394,14 @@ static void hdmi_edid_get_display_mode(struct hdmi_edid_ctrl *edid_ctrl, (edid_blk0[0x26 + offset + 1] == 0x80)) { pr_debug("%s: 108MHz: off=[%x] stdblk=[%x]\n", __func__, offset, std_blk); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_1280x1024p60_5_4); } if ((edid_blk0[0x26 + offset] == 0x61) && (edid_blk0[0x26 + offset + 1] == 0x40)) { pr_debug("%s: 65MHz: off=[%x] stdblk=[%x]\n", __func__, offset, std_blk); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_1024x768p60_4_3); break; } else { Loading @@ -1406,7 +1413,7 @@ static void hdmi_edid_get_display_mode(struct hdmi_edid_ctrl *edid_ctrl, /* Established Timing I */ if (edid_blk0[0x23] & BIT(0)) { pr_debug("%s: DMT: ETI: HDMI_VFRMT_800x600_4_3\n", __func__); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_800x600p60_4_3); } Loading @@ -1414,7 +1421,7 @@ static void hdmi_edid_get_display_mode(struct hdmi_edid_ctrl *edid_ctrl, if (edid_blk0[0x24] & BIT(3)) { pr_debug("%s: DMT: ETII: HDMI_VFRMT_1024x768p60_4_3\n", __func__); hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_1024x768p60_4_3); } Loading Loading @@ -1462,7 +1469,7 @@ static void hdmi_edid_get_display_mode(struct hdmi_edid_ctrl *edid_ctrl, * All DTV sink devices should support this mode */ if (!has480p) hdmi_edid_add_sink_video_format(sink_data, hdmi_edid_add_sink_video_format(edid_ctrl, HDMI_VFRMT_640x480p60_4_3); } /* hdmi_edid_get_display_mode */ Loading
drivers/video/msm/mdss/mdss_hdmi_edid.h +1 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ struct hdmi_edid_init_data { struct kobject *sysfs_kobj; struct hdmi_tx_ddc_ctrl *ddc_ctrl; struct hdmi_util_ds_data *ds_data; }; int hdmi_edid_read(void *edid_ctrl); Loading
drivers/video/msm/mdss/mdss_hdmi_tx.c +125 −67 Original line number Diff line number Diff line Loading @@ -438,7 +438,12 @@ static int hdmi_tx_get_vic_from_panel_info(struct hdmi_tx_ctrl *hdmi_ctrl, } if (pinfo->vic) { if (hdmi_get_supported_mode(pinfo->vic)) { struct msm_hdmi_mode_timing_info info = {0}; u32 ret = hdmi_get_supported_mode(&info, &hdmi_ctrl->ds_data, pinfo->vic); u32 supported = info.supported; if (!ret && supported) { new_vic = pinfo->vic; DEV_DBG("%s: %s is supported\n", __func__, msm_hdmi_mode_2string(new_vic)); Loading Loading @@ -479,7 +484,7 @@ static int hdmi_tx_get_vic_from_panel_info(struct hdmi_tx_ctrl *hdmi_ctrl, DEV_DBG("%s: pixel_freq=%d refresh_rate=%d\n", __func__, timing.pixel_freq, timing.refresh_rate); new_vic = hdmi_get_video_id_code(&timing); new_vic = hdmi_get_video_id_code(&timing, &hdmi_ctrl->ds_data); } return new_vic; Loading Loading @@ -708,7 +713,7 @@ static ssize_t hdmi_tx_sysfs_wta_hpd(struct device *dev, return rc; } if (hdmi_ctrl->mhl_max_pclk && hpd && if (hdmi_ctrl->ds_registered && hpd && (!hdmi_ctrl->mhl_hpd_on || hdmi_ctrl->hpd_feature_on)) return 0; Loading Loading @@ -992,6 +997,72 @@ static ssize_t hdmi_tx_sysfs_wta_avi_cn_bits(struct device *dev, return ret; } /* hdmi_tx_sysfs_wta_cn_bits */ static ssize_t hdmi_tx_sysfs_wta_res_info(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int rc, res_info_id; ssize_t ret = strnlen(buf, PAGE_SIZE); struct hdmi_tx_ctrl *hdmi_ctrl = NULL; hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev); if (!hdmi_ctrl) { DEV_ERR("%s: invalid input\n", __func__); return -EINVAL; } rc = kstrtoint(buf, 10, &res_info_id); if (rc) { DEV_ERR("%s: kstrtoint failed. rc=%d\n", __func__, rc); return rc; } if (res_info_id >= 0 && res_info_id < HDMI_VFRMT_MAX) hdmi_ctrl->res_info_id = res_info_id; else hdmi_ctrl->res_info_id = 0; DEV_DBG("%s: %d\n", __func__, hdmi_ctrl->res_info_id); return ret; } static ssize_t hdmi_tx_sysfs_rda_res_info(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t ret; struct msm_hdmi_mode_timing_info info = {0}; struct hdmi_tx_ctrl *hdmi_ctrl = hdmi_tx_get_drvdata_from_sysfs_dev(dev); u32 size = sizeof(info) < PAGE_SIZE ? sizeof(info) : PAGE_SIZE; if (!hdmi_ctrl) { DEV_ERR("%s: invalid input\n", __func__); return -EINVAL; } if (!hdmi_ctrl->res_info_id) return -EINVAL; ret = hdmi_get_supported_mode(&info, &hdmi_ctrl->ds_data, hdmi_ctrl->res_info_id); if (ret) return -EINVAL; memcpy(buf, &info, size); DEV_DBG("%s: %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n", __func__, info.video_format, info.active_h, info.front_porch_h, info.pulse_width_h, info.back_porch_h, info.active_low_h, info.active_v, info.front_porch_v, info.pulse_width_v, info.back_porch_v, info.active_low_v, info.pixel_freq, info.refresh_rate, info.interlaced, info.supported, info.ar); return size; } static DEVICE_ATTR(connected, S_IRUGO, hdmi_tx_sysfs_rda_connected, NULL); static DEVICE_ATTR(video_mode, S_IRUGO, hdmi_tx_sysfs_rda_video_mode, NULL); static DEVICE_ATTR(hpd, S_IRUGO | S_IWUSR, hdmi_tx_sysfs_rda_hpd, Loading @@ -1003,6 +1074,8 @@ static DEVICE_ATTR(product_description, S_IRUGO | S_IWUSR, hdmi_tx_sysfs_wta_product_description); static DEVICE_ATTR(avi_itc, S_IWUSR, NULL, hdmi_tx_sysfs_wta_avi_itc); static DEVICE_ATTR(avi_cn0_1, S_IWUSR, NULL, hdmi_tx_sysfs_wta_avi_cn_bits); static DEVICE_ATTR(res_info, S_IRUGO | S_IWUSR, hdmi_tx_sysfs_rda_res_info, hdmi_tx_sysfs_wta_res_info); static struct attribute *hdmi_tx_fs_attrs[] = { &dev_attr_connected.attr, Loading @@ -1012,6 +1085,7 @@ static struct attribute *hdmi_tx_fs_attrs[] = { &dev_attr_product_description.attr, &dev_attr_avi_itc.attr, &dev_attr_avi_cn0_1.attr, &dev_attr_res_info.attr, NULL, }; static struct attribute_group hdmi_tx_fs_attrs_group = { Loading Loading @@ -1186,6 +1260,7 @@ static int hdmi_tx_init_features(struct hdmi_tx_ctrl *hdmi_ctrl) edid_init_data.mutex = &hdmi_ctrl->mutex; edid_init_data.sysfs_kobj = hdmi_ctrl->kobj; edid_init_data.ddc_ctrl = &hdmi_ctrl->ddc_ctrl; edid_init_data.ds_data = &hdmi_ctrl->ds_data; hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID] = hdmi_edid_init(&edid_init_data); Loading Loading @@ -1253,31 +1328,33 @@ static inline u32 hdmi_tx_is_controller_on(struct hdmi_tx_ctrl *hdmi_ctrl) static int hdmi_tx_init_panel_info(struct hdmi_tx_ctrl *hdmi_ctrl) { struct mdss_panel_info *pinfo; const struct msm_hdmi_mode_timing_info *timing; struct msm_hdmi_mode_timing_info timing = {0}; u32 ret; if (!hdmi_ctrl) { DEV_ERR("%s: invalid input\n", __func__); return -EINVAL; } timing = hdmi_get_supported_mode(hdmi_ctrl->video_resolution); ret = hdmi_get_supported_mode(&timing, &hdmi_ctrl->ds_data, hdmi_ctrl->video_resolution); pinfo = &hdmi_ctrl->panel_data.panel_info; if (!timing || !pinfo) { if (ret || !timing.supported || !pinfo) { DEV_ERR("%s: invalid timing data\n", __func__); return -EINVAL; } pinfo->xres = timing->active_h; pinfo->yres = timing->active_v; pinfo->clk_rate = timing->pixel_freq*1000; pinfo->xres = timing.active_h; pinfo->yres = timing.active_v; pinfo->clk_rate = timing.pixel_freq * 1000; pinfo->lcdc.h_back_porch = timing->back_porch_h; pinfo->lcdc.h_front_porch = timing->front_porch_h; pinfo->lcdc.h_pulse_width = timing->pulse_width_h; pinfo->lcdc.v_back_porch = timing->back_porch_v; pinfo->lcdc.v_front_porch = timing->front_porch_v; pinfo->lcdc.v_pulse_width = timing->pulse_width_v; pinfo->lcdc.h_back_porch = timing.back_porch_h; pinfo->lcdc.h_front_porch = timing.front_porch_h; pinfo->lcdc.h_pulse_width = timing.pulse_width_h; pinfo->lcdc.v_back_porch = timing.back_porch_v; pinfo->lcdc.v_front_porch = timing.front_porch_v; pinfo->lcdc.v_pulse_width = timing.pulse_width_v; pinfo->type = DTV_PANEL; pinfo->pdest = DISPLAY_2; Loading @@ -1294,30 +1371,6 @@ static int hdmi_tx_init_panel_info(struct hdmi_tx_ctrl *hdmi_ctrl) return 0; } /* hdmi_tx_init_panel_info */ /* Table tuned to indicate video formats supported by the MHL Tx */ /* Valid pclk rates (Mhz): 25.2, 27, 27.03, 74.25 */ static void hdmi_tx_setup_mhl_video_mode_lut(struct hdmi_tx_ctrl *hdmi_ctrl) { u32 i; struct msm_hdmi_mode_timing_info *temp_timing; if (!hdmi_ctrl->mhl_max_pclk) { DEV_WARN("%s: mhl max pclk not set!\n", __func__); return; } DEV_DBG("%s: max mode set to [%u]\n", __func__, hdmi_ctrl->mhl_max_pclk); for (i = 0; i < HDMI_VFRMT_MAX; i++) { temp_timing = (struct msm_hdmi_mode_timing_info *)hdmi_get_supported_mode(i); if (!temp_timing) continue; /* formats that exceed max mhl line clk bw */ if (temp_timing->pixel_freq > hdmi_ctrl->mhl_max_pclk) hdmi_del_supported_mode(i); } } /* hdmi_tx_setup_mhl_video_mode_lut */ static int hdmi_tx_read_sink_info(struct hdmi_tx_ctrl *hdmi_ctrl) { int status; Loading Loading @@ -1442,8 +1495,9 @@ static int hdmi_tx_set_video_fmt(struct hdmi_tx_ctrl *hdmi_ctrl, struct mdss_panel_info *pinfo) { int new_vic = -1; const struct msm_hdmi_mode_timing_info *timing = NULL; struct msm_hdmi_mode_timing_info timing = {0}; int res_changed = RESOLUTION_UNCHANGED; u32 ret; if (!hdmi_ctrl || !pinfo) { DEV_ERR("%s: invalid input\n", __func__); Loading @@ -1465,16 +1519,17 @@ static int hdmi_tx_set_video_fmt(struct hdmi_tx_ctrl *hdmi_ctrl, hdmi_ctrl->video_resolution = (u32)new_vic; timing = hdmi_get_supported_mode(hdmi_ctrl->video_resolution); ret = hdmi_get_supported_mode(&timing, &hdmi_ctrl->ds_data, hdmi_ctrl->video_resolution); if (!timing) { if (ret || !timing.supported) { DEV_ERR("%s: invalid input\n", __func__); return -EINVAL; } /* todo: find a better way */ hdmi_ctrl->pdata.power_data[HDMI_TX_CORE_PM].clk_config[0].rate = timing->pixel_freq * 1000; timing.pixel_freq * 1000; hdmi_edid_set_video_resolution( hdmi_ctrl->feature_data[HDMI_TX_FEAT_EDID], Loading @@ -1494,9 +1549,11 @@ static int hdmi_tx_video_setup(struct hdmi_tx_ctrl *hdmi_ctrl, u32 end_v = 0; struct dss_io_data *io = NULL; const struct msm_hdmi_mode_timing_info *timing = hdmi_get_supported_mode(video_format); if (timing == NULL) { struct msm_hdmi_mode_timing_info timing = {0}; u32 ret = hdmi_get_supported_mode(&timing, &hdmi_ctrl->ds_data, video_format); if (ret || !timing.supported) { DEV_ERR("%s: video format not supported: %d\n", __func__, video_format); return -EPERM; Loading @@ -1513,10 +1570,10 @@ static int hdmi_tx_video_setup(struct hdmi_tx_ctrl *hdmi_ctrl, return -EPERM; } total_h = timing->active_h + timing->front_porch_h + timing->back_porch_h + timing->pulse_width_h - 1; total_v = timing->active_v + timing->front_porch_v + timing->back_porch_v + timing->pulse_width_v - 1; total_h = timing.active_h + timing.front_porch_h + timing.back_porch_h + timing.pulse_width_h - 1; total_v = timing.active_v + timing.front_porch_v + timing.back_porch_v + timing.pulse_width_v - 1; if (((total_v << 16) & 0xE0000000) || (total_h & 0xFFFFE000)) { DEV_ERR("%s: total v=%d or h=%d is larger than supported\n", __func__, total_v, total_h); Loading @@ -1524,8 +1581,8 @@ static int hdmi_tx_video_setup(struct hdmi_tx_ctrl *hdmi_ctrl, } DSS_REG_W(io, HDMI_TOTAL, (total_v << 16) | (total_h << 0)); start_h = timing->back_porch_h + timing->pulse_width_h; end_h = (total_h + 1) - timing->front_porch_h; start_h = timing.back_porch_h + timing.pulse_width_h; end_h = (total_h + 1) - timing.front_porch_h; if (((end_h << 16) & 0xE0000000) || (start_h & 0xFFFFE000)) { DEV_ERR("%s: end_h=%d or start_h=%d is larger than supported\n", __func__, end_h, start_h); Loading @@ -1533,8 +1590,8 @@ static int hdmi_tx_video_setup(struct hdmi_tx_ctrl *hdmi_ctrl, } DSS_REG_W(io, HDMI_ACTIVE_H, (end_h << 16) | (start_h << 0)); start_v = timing->back_porch_v + timing->pulse_width_v - 1; end_v = total_v - timing->front_porch_v; start_v = timing.back_porch_v + timing.pulse_width_v - 1; end_v = total_v - timing.front_porch_v; if (((end_v << 16) & 0xE0000000) || (start_v & 0xFFFFE000)) { DEV_ERR("%s: end_v=%d or start_v=%d is larger than supported\n", __func__, end_v, start_v); Loading @@ -1542,7 +1599,7 @@ static int hdmi_tx_video_setup(struct hdmi_tx_ctrl *hdmi_ctrl, } DSS_REG_W(io, HDMI_ACTIVE_V, (end_v << 16) | (start_v << 0)); if (timing->interlaced) { if (timing.interlaced) { DSS_REG_W(io, HDMI_V_TOTAL_F2, (total_v + 1) << 0); DSS_REG_W(io, HDMI_ACTIVE_V_F2, ((end_v + 1) << 16) | ((start_v + 1) << 0)); Loading @@ -1552,9 +1609,9 @@ static int hdmi_tx_video_setup(struct hdmi_tx_ctrl *hdmi_ctrl, } DSS_REG_W(io, HDMI_FRAME_CTRL, ((timing->interlaced << 31) & 0x80000000) | ((timing->active_low_h << 29) & 0x20000000) | ((timing->active_low_v << 28) & 0x10000000)); ((timing.interlaced << 31) & 0x80000000) | ((timing.active_low_h << 29) & 0x20000000) | ((timing.active_low_v << 28) & 0x10000000)); return 0; } /* hdmi_tx_video_setup */ Loading Loading @@ -2231,28 +2288,29 @@ static int hdmi_tx_audio_acr_setup(struct hdmi_tx_ctrl *hdmi_ctrl, acr_pck_ctrl_reg = DSS_REG_R(io, HDMI_ACR_PKT_CTRL); if (enabled) { const struct msm_hdmi_mode_timing_info *timing = hdmi_get_supported_mode(hdmi_ctrl->video_resolution); struct msm_hdmi_mode_timing_info timing = {0}; u32 ret = hdmi_get_supported_mode(&timing, &hdmi_ctrl->ds_data, hdmi_ctrl->video_resolution); const struct hdmi_tx_audio_acr_arry *audio_acr = &hdmi_tx_audio_acr_lut[0]; const int lut_size = sizeof(hdmi_tx_audio_acr_lut) / sizeof(*hdmi_tx_audio_acr_lut); u32 i, n, cts, layout, multiplier, aud_pck_ctrl_2_reg; if (timing == NULL) { DEV_WARN("%s: video format %d not supported\n", if (ret || !timing.supported) { DEV_ERR("%s: video format %d not supported\n", __func__, hdmi_ctrl->video_resolution); return -EPERM; } for (i = 0; i < lut_size; audio_acr = &hdmi_tx_audio_acr_lut[++i]) { if (audio_acr->pclk == timing->pixel_freq) if (audio_acr->pclk == timing.pixel_freq) break; } if (i >= lut_size) { DEV_WARN("%s: pixel clk %d not supported\n", __func__, timing->pixel_freq); timing.pixel_freq); return -EPERM; } Loading Loading @@ -2569,12 +2627,13 @@ static int hdmi_tx_set_mhl_max_pclk(struct platform_device *pdev, u32 max_val) return -ENODEV; } if (max_val) { hdmi_ctrl->mhl_max_pclk = max_val; hdmi_tx_setup_mhl_video_mode_lut(hdmi_ctrl); hdmi_ctrl->ds_data.ds_max_clk = max_val; hdmi_ctrl->ds_data.ds_registered = true; } else { DEV_ERR("%s: invalid max pclk val\n", __func__); return -EINVAL; } return 0; } Loading Loading @@ -3218,7 +3277,6 @@ static int hdmi_tx_dev_init(struct hdmi_tx_ctrl *hdmi_ctrl) /* irq enable/disable will be handled in hpd on/off */ hdmi_tx_hw.ptr = (void *)hdmi_ctrl; hdmi_setup_video_mode_lut(); mutex_init(&hdmi_ctrl->mutex); mutex_init(&hdmi_ctrl->lut_lock); mutex_init(&hdmi_ctrl->cable_notify_mutex); Loading
drivers/video/msm/mdss/mdss_hdmi_tx.h +3 −1 Original line number Diff line number Diff line Loading @@ -89,9 +89,11 @@ struct hdmi_tx_ctrl { u32 hpd_feature_on; u32 hpd_initialized; u32 vote_hdmi_core_on; u32 res_info_id; u8 timing_gen_on; u32 mhl_max_pclk; u8 mhl_hpd_on; struct hdmi_util_ds_data ds_data; struct completion hpd_done; struct work_struct hpd_int_work; Loading
drivers/video/msm/mdss/mdss_hdmi_util.c +51 −73 File changed.Preview size limit exceeded, changes collapsed. Show changes