Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7c5d5032 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: mdss: hdmi: optimize resolution data base"

parents 104b805b 62df9e99
Loading
Loading
Loading
Loading
+54 −47
Original line number Diff line number Diff line
@@ -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++);
@@ -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;
@@ -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
@@ -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;
@@ -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__,
@@ -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;
@@ -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);
		}
	}
@@ -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);
		}

@@ -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);
		}

@@ -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);
		}

@@ -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);
		}

@@ -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);
		}

@@ -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)
@@ -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)
@@ -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)
@@ -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;
@@ -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 {
@@ -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);
	}

@@ -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);
	}

@@ -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 */

+1 −0
Original line number Diff line number Diff line
@@ -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);
+125 −67
Original line number Diff line number Diff line
@@ -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));
@@ -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;
@@ -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;

@@ -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,
@@ -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,
@@ -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 = {
@@ -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);
@@ -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;
@@ -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;
@@ -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__);
@@ -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],
@@ -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;
@@ -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);
@@ -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);
@@ -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);
@@ -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));
@@ -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 */
@@ -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;
		}

@@ -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;
}

@@ -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);
+3 −1
Original line number Diff line number Diff line
@@ -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;

+51 −73

File changed.

Preview size limit exceeded, changes collapsed.

Loading