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

Commit d7a02e72 authored by Aravind Venkateswaran's avatar Aravind Venkateswaran Committed by Kyle Yan
Browse files

msm: mdss: dsi: configure data lane swap for newer hw revisions



Starting with DSI PHY hardware revisions 3.0 and above, data lane swap
configurations need to be programmed via the DSI PHY interface. In other
cases, a new register interface has been introduced to program the lane
swap configuration for DSI controller revision 2.0 and above. Refactor
the existing implementation to account for these hardware changes.

Change-Id: I3772c614bfee0ed13f30a38535bb814158d23226
Signed-off-by: default avatarAravind Venkateswaran <aravindh@codeaurora.org>
parent 195ae4da
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -125,6 +125,28 @@ Optional properties:
					"lane_map_1032" = <1 0 3 2>
					"lane_map_2103" = <2 1 0 3>
					"lane_map_3210" = <3 2 1 0>
					where lane_map_ABCD means:
						Logical_Lane_A = Physical_Lane_0
						Logical_Lane_B = Physical_Lane_1
						Logical_Lane_C = Physical_Lane_2
						Logical_Lane_D = Physical_Lane_3
					The lane map can vary between multiple instances
					of the DSI controller and should be set accordingly in all
					of them based on the board configuration.
- qcom,lane-map-v2:			An array of size 4 uint8s specifying the corresponding
					mapping for each of the logical data lanes.
					For example, a value of <A B C D> means
						Logical_Lane_0 = Physical_Lane_A
						Logical_Lane_1 = Physical_Lane_B
						Logical_Lane_2 = Physical_Lane_C
						Logical_Lane_3 = Physical_Lane_D
					The default lane mapping is <0 1 2 3>.
					Since the values are of type uint8, they need to be
					specified as below:
						qcom,lane-map-v2 = /bits/ 8 <0 1 2 3>
					This binding supersedes qcom,lane-map binding and will
					override any lane swap setting specified by qcom,lane-map.
					Refer to qcom,lane-map for additional notes.
- qcom,pluggable			Boolean to enable hotplug feature.
- qcom,timing-db-mode:			Boolean specifies dsi timing mode registers are supported or not.
- qcom,display-id			A string indicates the display ID for the controller.
+118 −19
Original line number Diff line number Diff line
@@ -3037,10 +3037,32 @@ end:
	return rc;
}

static void mdss_dsi_ctrl_validate_lane_swap_config(
	struct mdss_dsi_ctrl_pdata *ctrl)
{
	struct mipi_panel_info *mipi = &ctrl->panel_data.panel_info.mipi;

	if (!mipi->data_lane0)
		ctrl->lane_map[DSI_LOGICAL_LANE_0] = DSI_PHYSICAL_LANE_INVALID;
	if (!mipi->data_lane1)
		ctrl->lane_map[DSI_LOGICAL_LANE_1] = DSI_PHYSICAL_LANE_INVALID;
	if (!mipi->data_lane2)
		ctrl->lane_map[DSI_LOGICAL_LANE_2] = DSI_PHYSICAL_LANE_INVALID;
	if (!mipi->data_lane3)
		ctrl->lane_map[DSI_LOGICAL_LANE_3] = DSI_PHYSICAL_LANE_INVALID;
}

static int mdss_dsi_ctrl_validate_config(struct mdss_dsi_ctrl_pdata *ctrl)
{
	int rc = 0;

	if (!ctrl) {
		rc = -EINVAL;
		goto error;
	}

	mdss_dsi_ctrl_validate_lane_swap_config(ctrl);

	/*
	 * check to make sure that the byte interface clock is specified for
	 * DSI ctrl version 2 and above.
@@ -3052,6 +3074,7 @@ static int mdss_dsi_ctrl_validate_config(struct mdss_dsi_ctrl_pdata *ctrl)
		rc = -EINVAL;
	}

error:
	return rc;
}

@@ -3807,28 +3830,105 @@ static int mdss_dsi_irq_init(struct device *dev, int irq_no,
	return ret;
}

static void mdss_dsi_parse_lane_swap(struct device_node *np, char *dlane_swap)
static void __set_lane_map(struct mdss_dsi_ctrl_pdata *ctrl,
	enum dsi_physical_lane_id lane0,
	enum dsi_physical_lane_id lane1,
	enum dsi_physical_lane_id lane2,
	enum dsi_physical_lane_id lane3)
{
	ctrl->lane_map[DSI_LOGICAL_LANE_0] = lane0;
	ctrl->lane_map[DSI_LOGICAL_LANE_1] = lane1;
	ctrl->lane_map[DSI_LOGICAL_LANE_2] = lane2;
	ctrl->lane_map[DSI_LOGICAL_LANE_3] = lane3;
}

static void mdss_dsi_parse_lane_swap(struct device_node *np,
	struct mdss_dsi_ctrl_pdata *ctrl)
{
	int rc;
	const char *data;
	u8 temp[DSI_LOGICAL_LANE_MAX];
	int i;

	/* First, check for the newer version of the binding */
	rc = of_property_read_u8_array(np, "qcom,lane-map-v2", temp,
		DSI_LOGICAL_LANE_MAX);
	if (!rc) {
		for (i = DSI_LOGICAL_LANE_0; i < DSI_LOGICAL_LANE_MAX; i++)
			ctrl->lane_map[i] = BIT(temp[i]);
		return;
	} else if (rc != -EINVAL) {
		pr_warn("%s: invalid lane map specfied. Defaulting to <0 1 2 3>\n",
			__func__);
		goto set_default;
	}

	*dlane_swap = DSI_LANE_MAP_0123;
	/* Check if an older version of the binding is present */
	data = of_get_property(np, "qcom,lane-map", NULL);
	if (data) {
		if (!strcmp(data, "lane_map_3012"))
			*dlane_swap = DSI_LANE_MAP_3012;
		else if (!strcmp(data, "lane_map_2301"))
			*dlane_swap = DSI_LANE_MAP_2301;
		else if (!strcmp(data, "lane_map_1230"))
			*dlane_swap = DSI_LANE_MAP_1230;
		else if (!strcmp(data, "lane_map_0321"))
			*dlane_swap = DSI_LANE_MAP_0321;
		else if (!strcmp(data, "lane_map_1032"))
			*dlane_swap = DSI_LANE_MAP_1032;
		else if (!strcmp(data, "lane_map_2103"))
			*dlane_swap = DSI_LANE_MAP_2103;
		else if (!strcmp(data, "lane_map_3210"))
			*dlane_swap = DSI_LANE_MAP_3210;
	if (!data)
		goto set_default;

	if (!strcmp(data, "lane_map_3012")) {
		ctrl->dlane_swap = DSI_LANE_MAP_3012;
		__set_lane_map(ctrl,
			DSI_PHYSICAL_LANE_1,
			DSI_PHYSICAL_LANE_2,
			DSI_PHYSICAL_LANE_3,
			DSI_PHYSICAL_LANE_0);
	} else if (!strcmp(data, "lane_map_2301")) {
		ctrl->dlane_swap = DSI_LANE_MAP_2301;
		__set_lane_map(ctrl,
			DSI_PHYSICAL_LANE_2,
			DSI_PHYSICAL_LANE_3,
			DSI_PHYSICAL_LANE_0,
			DSI_PHYSICAL_LANE_1);
	} else if (!strcmp(data, "lane_map_1230")) {
		ctrl->dlane_swap = DSI_LANE_MAP_1230;
		__set_lane_map(ctrl,
			DSI_PHYSICAL_LANE_3,
			DSI_PHYSICAL_LANE_0,
			DSI_PHYSICAL_LANE_1,
			DSI_PHYSICAL_LANE_2);
	} else if (!strcmp(data, "lane_map_0321")) {
		ctrl->dlane_swap = DSI_LANE_MAP_0321;
		__set_lane_map(ctrl,
			DSI_PHYSICAL_LANE_0,
			DSI_PHYSICAL_LANE_3,
			DSI_PHYSICAL_LANE_2,
			DSI_PHYSICAL_LANE_1);
	} else if (!strcmp(data, "lane_map_1032")) {
		ctrl->dlane_swap = DSI_LANE_MAP_1032;
		__set_lane_map(ctrl,
			DSI_PHYSICAL_LANE_1,
			DSI_PHYSICAL_LANE_0,
			DSI_PHYSICAL_LANE_3,
			DSI_PHYSICAL_LANE_2);
	} else if (!strcmp(data, "lane_map_2103")) {
		ctrl->dlane_swap = DSI_LANE_MAP_2103;
		__set_lane_map(ctrl,
			DSI_PHYSICAL_LANE_2,
			DSI_PHYSICAL_LANE_1,
			DSI_PHYSICAL_LANE_0,
			DSI_PHYSICAL_LANE_3);
	} else if (!strcmp(data, "lane_map_3210")) {
		ctrl->dlane_swap = DSI_LANE_MAP_3210;
		__set_lane_map(ctrl,
			DSI_PHYSICAL_LANE_3,
			DSI_PHYSICAL_LANE_2,
			DSI_PHYSICAL_LANE_1,
			DSI_PHYSICAL_LANE_0);
	} else {
		pr_warn("%s: invalid lane map %s specified. defaulting to lane_map0123\n",
			__func__, data);
	}

	return;

set_default:
	/* default lane mapping */
	__set_lane_map(ctrl, DSI_PHYSICAL_LANE_0, DSI_PHYSICAL_LANE_1,
		DSI_PHYSICAL_LANE_2, DSI_PHYSICAL_LANE_3);
	ctrl->dlane_swap = DSI_LANE_MAP_0123;
}

static int mdss_dsi_parse_ctrl_params(struct platform_device *ctrl_pdev,
@@ -3904,8 +4004,7 @@ static int mdss_dsi_parse_ctrl_params(struct platform_device *ctrl_pdev,
				ctrl_pdata->cmd_sync_wait_broadcast,
				ctrl_pdata->cmd_sync_wait_trigger);

	mdss_dsi_parse_lane_swap(ctrl_pdev->dev.of_node,
			&(ctrl_pdata->dlane_swap));
	mdss_dsi_parse_lane_swap(ctrl_pdev->dev.of_node, ctrl_pdata);

	pinfo->is_pluggable = of_property_read_bool(ctrl_pdev->dev.of_node,
		"qcom,pluggable");
+48 −1
Original line number Diff line number Diff line
@@ -127,6 +127,22 @@ enum dsi_lane_map_type {
	DSI_LANE_MAP_3210,
};

enum dsi_logical_lane_id {
	DSI_LOGICAL_LANE_0 = 0,
	DSI_LOGICAL_LANE_1,
	DSI_LOGICAL_LANE_2,
	DSI_LOGICAL_LANE_3,
	DSI_LOGICAL_LANE_MAX,
};

enum dsi_physical_lane_id {
	DSI_PHYSICAL_LANE_INVALID = 0,
	DSI_PHYSICAL_LANE_0 = BIT(0),
	DSI_PHYSICAL_LANE_1 = BIT(1),
	DSI_PHYSICAL_LANE_2 = BIT(2),
	DSI_PHYSICAL_LANE_3 = BIT(3),
};

enum dsi_pm_type {
	/* PANEL_PM not used as part of power_data in dsi_shared_data */
	DSI_PANEL_PM,
@@ -503,7 +519,17 @@ struct mdss_dsi_ctrl_pdata {
	bool ulps;
	bool core_power;
	bool mmss_clamp;
	char dlane_swap;	/* data lane swap */

	/*
	 * Data lane swap (logical to physical lane map):
	 *     dlane_swap: used for DSI controller versions < 2.0, where
	 *               dlane_swap is of type enum dsi_lane_map_type
	 *     lane_map: used for DSI controller versions > 2.0, where
	 *               lane_map[logical_lane_id] = physical_lane_id
	 */
	char dlane_swap;
	uint8_t lane_map[DSI_LOGICAL_LANE_MAX];

	bool is_phyreg_enabled;
	bool burst_mode_enabled;

@@ -879,4 +905,25 @@ static inline bool mdss_dsi_cmp_panel_reg(struct dsi_buf status_buf,
	return status_buf.data[i] == status_val[i];
}

static inline enum dsi_logical_lane_id mdss_dsi_physical_to_logical_lane(
		struct mdss_dsi_ctrl_pdata *ctrl, enum dsi_physical_lane_id id)
{
	int i;

	for (i = DSI_LOGICAL_LANE_0; i < DSI_LOGICAL_LANE_MAX; i++)
		if (ctrl->lane_map[i] == id)
			break;

	return i;
}

static inline enum dsi_physical_lane_id mdss_dsi_logical_to_physical_lane(
		struct mdss_dsi_ctrl_pdata *ctrl, enum dsi_logical_lane_id id)
{
	if (id >= DSI_LOGICAL_LANE_MAX)
		return DSI_PHYSICAL_LANE_INVALID;

	return ctrl->lane_map[id];
}

#endif /* MDSS_DSI_H */
+15 −2
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@
#define LANE_STATUS	0xA8

#define MDSS_DSI_INT_CTRL	0x0110
#define LANE_SWAP_CTRL			0x0B0
#define LOGICAL_LANE_SWAP_CTRL		0x310

struct mdss_dsi_ctrl_pdata *ctrl_list[DSI_CTRL_MAX];

@@ -303,6 +305,18 @@ void mdss_dsi_read_phy_revision(struct mdss_dsi_ctrl_pdata *ctrl)
		ctrl->shared_data->phy_rev = DSI_PHY_REV_UNKNOWN;
}

static void mdss_dsi_config_data_lane_swap(struct mdss_dsi_ctrl_pdata *ctrl)
{
	if (ctrl->shared_data->hw_rev < MDSS_DSI_HW_REV_200)
		MIPI_OUTP((ctrl->ctrl_base) + LANE_SWAP_CTRL, ctrl->dlane_swap);
	else
		MIPI_OUTP(ctrl->ctrl_base + LOGICAL_LANE_SWAP_CTRL,
			ctrl->lane_map[DSI_LOGICAL_LANE_0] |
			ctrl->lane_map[DSI_LOGICAL_LANE_1] << 4 |
			ctrl->lane_map[DSI_LOGICAL_LANE_2] << 8 |
			ctrl->lane_map[DSI_LOGICAL_LANE_3] << 12);
}

void mdss_dsi_host_init(struct mdss_panel_data *pdata)
{
	u32 dsi_ctrl, intr_ctrl;
@@ -400,8 +414,7 @@ void mdss_dsi_host_init(struct mdss_panel_data *pdata)
	MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0084,
				data); /* DSI_TRIG_CTRL */

	/* DSI_LAN_SWAP_CTRL */
	MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x00b0, ctrl_pdata->dlane_swap);
	mdss_dsi_config_data_lane_swap(ctrl_pdata);

	/* clock out ctrl */
	data = pinfo->t_clk_post & 0x3f;	/* 6 bits */
+12 −0
Original line number Diff line number Diff line
@@ -118,6 +118,16 @@ static void mdss_dsi_phy_v3_set_pll_source(
	DSI_PHY_W32(ctrl->phy_io.base, CMN_CLK_CFG1, reg);
}

static void mdss_dsi_phy_v3_lane_swap_config(struct mdss_dsi_ctrl_pdata *ctrl)
{
	DSI_PHY_W32(ctrl->phy_io.base, CMN_LANE_CFG0,
		ctrl->lane_map[DSI_LOGICAL_LANE_0] |
		ctrl->lane_map[DSI_LOGICAL_LANE_1] << 4);
	DSI_PHY_W32(ctrl->phy_io.base, CMN_LANE_CFG1,
		ctrl->lane_map[DSI_LOGICAL_LANE_2] |
		ctrl->lane_map[DSI_LOGICAL_LANE_3] << 4);
}

static void mdss_dsi_phy_v3_lanes_disable(struct mdss_dsi_ctrl_pdata *ctrl)
{
	u32 data = DSI_PHY_R32(ctrl->phy_io.base, CMN_CTRL_0);
@@ -343,6 +353,8 @@ int mdss_dsi_phy_v3_init(struct mdss_dsi_ctrl_pdata *ctrl,
	/* Enable LDO */
	DSI_PHY_W32(ctrl->phy_io.base, CMN_VREG_CTRL, 0x59);

	mdss_dsi_phy_v3_lane_swap_config(ctrl);

	mdss_dsi_phy_v3_config_timings(ctrl);

	/* Remove power down from all blocks */