Commit 74629c49 authored by Marek Vasut's avatar Marek Vasut Committed by Neil Armstrong
Browse files

drm: bridge: samsung-dsim: Implement support for clock/data polarity swap



Implement support for DSI clock and data lane DN/DP polarity swap by
means of decoding 'lane-polarities' DT property. The controller does
support DN/DP swap of clock lane and all data lanes, the controller
does not support polarity swap of individual data lane bundles, add
a check which verifies all data lanes have the same polarity.

This has been validated on an imx8mm board that actually has the MIPI DSI
clock lanes inverted.

Signed-off-by: default avatarMarek Vasut <marex@denx.de>
Signed-off-by: default avatarFabio Estevam <festevam@denx.de>
Reviewed-by: default avatarJagan Teki <jagan@amarulasolutions.com>
Signed-off-by: default avatarNeil Armstrong <neil.armstrong@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20230514114625.98372-2-festevam@gmail.com
parent ec7743c9
Loading
Loading
Loading
Loading
+26 −1
Original line number Diff line number Diff line
@@ -183,6 +183,8 @@
#define DSIM_AFC_CTL(x)			(((x) & 0x7) << 5)

/* DSIM_PLLCTRL */
#define DSIM_PLL_DPDNSWAP_CLK		(1 << 25)
#define DSIM_PLL_DPDNSWAP_DAT		(1 << 24)
#define DSIM_FREQ_BAND(x)		((x) << 24)
#define DSIM_PLL_EN			BIT(23)
#define DSIM_PLL_P(x, offset)		((x) << (offset))
@@ -622,6 +624,11 @@ static unsigned long samsung_dsim_set_pll(struct samsung_dsim *dsi,
		reg |= DSIM_FREQ_BAND(band);
	}

	if (dsi->swap_dn_dp_clk)
		reg |= DSIM_PLL_DPDNSWAP_CLK;
	if (dsi->swap_dn_dp_data)
		reg |= DSIM_PLL_DPDNSWAP_DAT;

	samsung_dsim_write(dsi, DSIM_PLLCTRL_REG, reg);

	timeout = 1000;
@@ -1696,7 +1703,9 @@ static int samsung_dsim_parse_dt(struct samsung_dsim *dsi)
{
	struct device *dev = dsi->dev;
	struct device_node *node = dev->of_node;
	int ret;
	u32 lane_polarities[5] = { 0 };
	struct device_node *endpoint;
	int i, nr_lanes, ret;

	ret = samsung_dsim_of_read_u32(node, "samsung,pll-clock-frequency",
				       &dsi->pll_clk_rate);
@@ -1713,6 +1722,22 @@ static int samsung_dsim_parse_dt(struct samsung_dsim *dsi)
	if (ret < 0)
		return ret;

	endpoint = of_graph_get_endpoint_by_regs(node, 1, -1);
	nr_lanes = of_property_count_u32_elems(endpoint, "data-lanes");
	if (nr_lanes > 0 && nr_lanes <= 4) {
		/* Polarity 0 is clock lane, 1..4 are data lanes. */
		of_property_read_u32_array(endpoint, "lane-polarities",
					   lane_polarities, nr_lanes + 1);
		for (i = 1; i <= nr_lanes; i++) {
			if (lane_polarities[1] != lane_polarities[i])
				DRM_DEV_ERROR(dsi->dev, "Data lanes polarities do not match");
		}
		if (lane_polarities[0])
			dsi->swap_dn_dp_clk = true;
		if (lane_polarities[1])
			dsi->swap_dn_dp_data = true;
	}

	return 0;
}

+2 −0
Original line number Diff line number Diff line
@@ -95,6 +95,8 @@ struct samsung_dsim {
	u32 mode_flags;
	u32 format;

	bool swap_dn_dp_clk;
	bool swap_dn_dp_data;
	int state;
	struct drm_property *brightness;
	struct completion completed;