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

Commit 7180cae8 authored by Padmanabhan Komanduru's avatar Padmanabhan Komanduru Committed by Vishnuvardhan Prodduturi
Browse files

msm: mdss: dp: featurize MDSS display port configuration settings



Display port settings for logical to physical lane mapping and AUX
configurations are different between msm8998 and SDM660. Add support
to parse these settings from MDSS DT file. Add the relevant settings
for the same in msm8998 MDSS device tree node.

Change-Id: I5046b2523928e34ef42924f495dfc754d9ac6ea7
Signed-off-by: default avatarPadmanabhan Komanduru <pkomandu@codeaurora.org>
Signed-off-by: default avatarVishnuvardhan Prodduturi <vproddut@codeaurora.org>
parent 958e36a7
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ Required properties
- qcom,aux-en-gpio:			Specifies the aux-channel enable gpio.
- qcom,aux-sel-gpio:			Specifies the aux-channel select gpio.
- qcom,usbplug-cc-gpio:			Specifies the usbplug orientation gpio.
- qcom,aux-cfg-settings:		An array that specifies the DP AUX configuration settings.

Optional properties:
- qcom,<type>-supply-entries:		A node that lists the elements of the supply used by the
@@ -51,6 +52,7 @@ Optional properties:
- pinctrl-<0..n>:			Lists phandles each pointing to the pin configuration node within a pin
					controller. These pin configurations are installed in the pinctrl
					device node. Refer to pinctrl-bindings.txt
- qcom,logical2physical-lane-map:	An array that specifies the DP logical to physical lane map setting.

Example:
	mdss_dp_ctrl: qcom,dp_ctrl@c990000 {
@@ -83,6 +85,9 @@ Example:
			"core_aux_clk", "core_cfg_ahb_clk", "ctrl_link_clk",
			"ctrl_link_iface_clk", "ctrl_crypto_clk", "ctrl_pixel_clk";

		qcom,aux-cfg-settings = [00 13 00 10 0a 26 0a 03 8b 03];
		qcom,logical2physical-lane-map = [02 03 01 00];

		qcom,core-supply-entries {
			#address-cells = <1>;
			#size-cells = <0>;
+4 −1
Original line number Diff line number Diff line
/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -500,6 +500,9 @@

		qcom,msm_ext_disp = <&msm_ext_disp>;

		qcom,aux-cfg-settings = [00 13 00 10 0a 26 0a 03 8b 03];
		qcom,logical2physical-lane-map = [02 03 01 00];

		qcom,core-supply-entries {
			#address-cells = <1>;
			#size-cells = <0>;
+77 −24
Original line number Diff line number Diff line
@@ -129,6 +129,40 @@ static int mdss_dp_is_clk_prefix(const char *clk_prefix, const char *clk_name)
	return !strncmp(clk_name, clk_prefix, strlen(clk_prefix));
}

static int mdss_dp_parse_prop(struct platform_device *pdev,
			struct mdss_dp_drv_pdata *dp_drv)
{
	int len = 0, i = 0;
	const char *data;

	data = of_get_property(pdev->dev.of_node,
		"qcom,aux-cfg-settings", &len);
	if ((!data) || (len != AUX_CFG_LEN)) {
		pr_err("%s:%d, Unable to read DP AUX CFG settings",
			__func__, __LINE__);
		return -EINVAL;
	}

	for (i = 0; i < len; i++)
		dp_drv->aux_cfg[i] = data[i];

	data = of_get_property(pdev->dev.of_node,
		"qcom,logical2physical-lane-map", &len);
	if ((!data) || (len != DP_MAX_PHY_LN)) {
		pr_debug("%s:%d, lane mapping not defined, use default",
			__func__, __LINE__);
		dp_drv->l_map[DP_PHY_LN0] = DP_ML0;
		dp_drv->l_map[DP_PHY_LN1] = DP_ML1;
		dp_drv->l_map[DP_PHY_LN2] = DP_ML2;
		dp_drv->l_map[DP_PHY_LN3] = DP_ML3;
	} else {
		for (i = 0; i < len; i++)
			dp_drv->l_map[i] = data[i];
	}

	return 0;
}

static int mdss_dp_init_clk_power_data(struct device *dev,
		struct mdss_dp_drv_pdata *pdata)
{
@@ -1151,10 +1185,9 @@ static inline void mdss_dp_ack_state(struct mdss_dp_drv_pdata *dp, int val)
 * given usb plug orientation.
 */
static int mdss_dp_get_lane_mapping(struct mdss_dp_drv_pdata *dp,
		enum plug_orientation orientation,
		struct lane_mapping *lane_map)
		enum plug_orientation orientation, char *lane_map)
{
	int ret = 0;
	int ret = 0, i = 0, j = 0;

	pr_debug("enter: orientation = %d\n", orientation);

@@ -1164,22 +1197,35 @@ static int mdss_dp_get_lane_mapping(struct mdss_dp_drv_pdata *dp,
		goto exit;
	}

	/* Set the default lane mapping */
	lane_map->lane0 = 2;
	lane_map->lane1 = 3;
	lane_map->lane2 = 1;
	lane_map->lane3 = 0;

	/* For flip case, swap phy lanes with ML0 and ML3, ML1 and ML2 */
	if (orientation == ORIENTATION_CC2) {
		lane_map->lane0 = 1;
		lane_map->lane1 = 0;
		lane_map->lane2 = 2;
		lane_map->lane3 = 3;
		for (i = 0; i < DP_MAX_PHY_LN; i++) {
			if (dp->l_map[i] == DP_ML0) {
				for (j = 0; j < DP_MAX_PHY_LN; j++) {
					if (dp->l_map[j] == DP_ML3) {
						lane_map[i] = DP_ML3;
						lane_map[j] = DP_ML0;
						break;
					}
				}
			} else if (dp->l_map[i] == DP_ML1) {
				for (j = 0; j < DP_MAX_PHY_LN; j++) {
					if (dp->l_map[j] == DP_ML2) {
						lane_map[i] = DP_ML2;
						lane_map[j] = DP_ML1;
						break;
					}
				}
			}
		}
	} else {
		/* Normal orientation */
		for (i = 0; i < DP_MAX_PHY_LN; i++)
			lane_map[i] = dp->l_map[i];
	}

	pr_debug("lane0 = %d, lane1 = %d, lane2 =%d, lane3 =%d\n",
			lane_map->lane0, lane_map->lane1, lane_map->lane2,
			lane_map->lane3);
		lane_map[0], lane_map[1], lane_map[2], lane_map[3]);

exit:
	return ret;
@@ -1248,9 +1294,9 @@ static void mdss_dp_disable_mainlink_clocks(struct mdss_dp_drv_pdata *dp_drv)
 * configuration, output format and sink/panel timing information.
 */
static void mdss_dp_configure_source_params(struct mdss_dp_drv_pdata *dp,
		struct lane_mapping *lane_map)
		char *lane_map)
{
	mdss_dp_ctrl_lane_mapping(&dp->ctrl_io, *lane_map);
	mdss_dp_ctrl_lane_mapping(&dp->ctrl_io, lane_map);
	mdss_dp_fill_link_cfg(dp);
	mdss_dp_mainlink_ctrl(&dp->ctrl_io, true);
	mdss_dp_config_ctrl(dp);
@@ -1318,7 +1364,7 @@ end:
static int mdss_dp_on_irq(struct mdss_dp_drv_pdata *dp_drv, bool lt_needed)
{
	int ret = 0;
	struct lane_mapping ln_map;
	char ln_map[4];

	/* wait until link training is completed */
	pr_debug("enter, lt_needed=%s\n", lt_needed ? "true" : "false");
@@ -1331,7 +1377,7 @@ static int mdss_dp_on_irq(struct mdss_dp_drv_pdata *dp_drv, bool lt_needed)

		dp_init_panel_info(dp_drv, dp_drv->vic);
		ret = mdss_dp_get_lane_mapping(dp_drv, dp_drv->orientation,
				&ln_map);
				ln_map);
		if (ret)
			goto exit_loop;

@@ -1352,7 +1398,7 @@ static int mdss_dp_on_irq(struct mdss_dp_drv_pdata *dp_drv, bool lt_needed)
				goto exit_loop;
		}

		mdss_dp_configure_source_params(dp_drv, &ln_map);
		mdss_dp_configure_source_params(dp_drv, ln_map);

		reinit_completion(&dp_drv->idle_comp);

@@ -1385,7 +1431,7 @@ exit_loop:
int mdss_dp_on_hpd(struct mdss_dp_drv_pdata *dp_drv)
{
	int ret = 0;
	struct lane_mapping ln_map;
	char ln_map[4];

	/* wait until link training is completed */
	mutex_lock(&dp_drv->train_mutex);
@@ -1404,7 +1450,7 @@ int mdss_dp_on_hpd(struct mdss_dp_drv_pdata *dp_drv)
	}
	mdss_dp_hpd_configure(&dp_drv->ctrl_io, true);

	ret = mdss_dp_get_lane_mapping(dp_drv, dp_drv->orientation, &ln_map);
	ret = mdss_dp_get_lane_mapping(dp_drv, dp_drv->orientation, ln_map);
	if (ret)
		goto exit;

@@ -1427,7 +1473,7 @@ int mdss_dp_on_hpd(struct mdss_dp_drv_pdata *dp_drv)

	reinit_completion(&dp_drv->idle_comp);

	mdss_dp_configure_source_params(dp_drv, &ln_map);
	mdss_dp_configure_source_params(dp_drv, ln_map);

	if (dp_drv->psm_enabled) {
		ret = mdss_dp_aux_send_psm_request(dp_drv, false);
@@ -1689,7 +1735,7 @@ static int mdss_dp_host_init(struct mdss_panel_data *pdata)
	       mdss_dp_get_ctrl_hw_version(&dp_drv->ctrl_io),
	       mdss_dp_get_phy_hw_version(&dp_drv->phy_io));

	mdss_dp_phy_aux_setup(&dp_drv->phy_io);
	mdss_dp_phy_aux_setup(&dp_drv->phy_io, dp_drv->aux_cfg);

	mdss_dp_irq_enable(dp_drv);
	dp_drv->dp_initialized = true;
@@ -3704,6 +3750,13 @@ static int mdss_dp_probe(struct platform_device *pdev)
		goto probe_err;
	}

	ret = mdss_dp_parse_prop(pdev, dp_drv);
	if (ret) {
		DEV_ERR("DP properties parsing failed.ret=%d\n",
				ret);
		goto probe_err;
	}

	ret = mdss_dp_irq_setup(dp_drv);
	if (ret)
		goto probe_err;
+21 −0
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@
#define AUX_CMD_MAX		16
#define AUX_CMD_I2C_MAX		128

#define AUX_CFG_LEN	10

#define EDP_PORT_MAX		1
#define EDP_SINK_CAP_LEN	16

@@ -536,6 +538,10 @@ struct mdss_dp_drv_pdata {
	struct mdss_dp_event_data dp_event;
	struct task_struct *ev_thread;

	/* dt settings */
	char l_map[4];
	u32 aux_cfg[AUX_CFG_LEN];

	struct workqueue_struct *workq;
	struct delayed_work hdcp_cb_work;
	spinlock_t lock;
@@ -554,6 +560,21 @@ struct mdss_dp_drv_pdata {
	struct list_head attention_head;
};

enum dp_phy_lane_num {
	DP_PHY_LN0 = 0,
	DP_PHY_LN1 = 1,
	DP_PHY_LN2 = 2,
	DP_PHY_LN3 = 3,
	DP_MAX_PHY_LN = 4,
};

enum dp_mainlink_lane_num {
	DP_ML0 = 0,
	DP_ML1 = 1,
	DP_ML2 = 2,
	DP_ML3 = 3,
};

enum dp_lane_count {
	DP_LANE_COUNT_1	= 1,
	DP_LANE_COUNT_2	= 2,
+19 −15
Original line number Diff line number Diff line
@@ -859,30 +859,34 @@ void mdss_dp_setup_tr_unit(struct dss_io_data *ctrl_io, u8 link_rate,
	pr_debug("dp_tu=0x%x\n", dp_tu);
}

void mdss_dp_ctrl_lane_mapping(struct dss_io_data *ctrl_io,
				struct lane_mapping l_map)
void mdss_dp_ctrl_lane_mapping(struct dss_io_data *ctrl_io, char *l_map)
{
	u8 bits_per_lane = 2;
	u32 lane_map = ((l_map.lane0 << (bits_per_lane * 0))
			    | (l_map.lane1 << (bits_per_lane * 1))
			    | (l_map.lane2 << (bits_per_lane * 2))
			    | (l_map.lane3 << (bits_per_lane * 3)));
	u32 lane_map = ((l_map[0] << (bits_per_lane * 0))
			    | (l_map[1] << (bits_per_lane * 1))
			    | (l_map[2] << (bits_per_lane * 2))
			    | (l_map[3] << (bits_per_lane * 3)));
	pr_debug("%s: lane mapping reg = 0x%x\n", __func__, lane_map);
	writel_relaxed(lane_map,
		ctrl_io->base + DP_LOGICAL2PHYSCIAL_LANE_MAPPING);
}

void mdss_dp_phy_aux_setup(struct dss_io_data *phy_io)
void mdss_dp_phy_aux_setup(struct dss_io_data *phy_io, u32 *aux_cfg)
{
	writel_relaxed(0x3d, phy_io->base + DP_PHY_PD_CTL);
	writel_relaxed(0x13, phy_io->base + DP_PHY_AUX_CFG1);
	writel_relaxed(0x10, phy_io->base + DP_PHY_AUX_CFG3);
	writel_relaxed(0x0a, phy_io->base + DP_PHY_AUX_CFG4);
	writel_relaxed(0x26, phy_io->base + DP_PHY_AUX_CFG5);
	writel_relaxed(0x0a, phy_io->base + DP_PHY_AUX_CFG6);
	writel_relaxed(0x03, phy_io->base + DP_PHY_AUX_CFG7);
	writel_relaxed(0x8b, phy_io->base + DP_PHY_AUX_CFG8);
	writel_relaxed(0x03, phy_io->base + DP_PHY_AUX_CFG9);

	/* DP AUX CFG register programming */
	writel_relaxed(aux_cfg[0], phy_io->base + DP_PHY_AUX_CFG0);
	writel_relaxed(aux_cfg[1], phy_io->base + DP_PHY_AUX_CFG1);
	writel_relaxed(aux_cfg[2], phy_io->base + DP_PHY_AUX_CFG2);
	writel_relaxed(aux_cfg[3], phy_io->base + DP_PHY_AUX_CFG3);
	writel_relaxed(aux_cfg[4], phy_io->base + DP_PHY_AUX_CFG4);
	writel_relaxed(aux_cfg[5], phy_io->base + DP_PHY_AUX_CFG5);
	writel_relaxed(aux_cfg[6], phy_io->base + DP_PHY_AUX_CFG6);
	writel_relaxed(aux_cfg[7], phy_io->base + DP_PHY_AUX_CFG7);
	writel_relaxed(aux_cfg[8], phy_io->base + DP_PHY_AUX_CFG8);
	writel_relaxed(aux_cfg[9], phy_io->base + DP_PHY_AUX_CFG9);

	writel_relaxed(0x1f, phy_io->base + DP_PHY_AUX_INTERRUPT_MASK);
}

Loading