LF-842-1: drm/bridge: nwl-dsi: Change mipi clocks re-parenting

The MIPI clock parenting is made in dts file, causing the MIPI clocks to
be parented even if that specific MIPI node is needed or not, causing
issues to the LVDS block (which has a shared PHY with MIPI on 8QXP).
In order to avoid these problems with the shared PHY on 8QXP, store the
MIPI parent clock for phy and escape clocks, along with their rates and
do the re-parenting in the MIPI driver only when a bridge (or panel) is
attached to it.

Signed-off-by: Robert Chiras <robert.chiras@nxp.com>
Tested-by: Dong Aisheng <aisheng.dong@nxp.com>
[Aisheng: Tested on MX8QM/QXP with single LVDS-HDMI or MIPI panel]
Reviewed-by: Dong Aisheng <aisheng.dong@nxp.com>
Reviewed-by: Liu Ying <victor.liu@nxp.com>

(cherry picked from commit 2f794bb2f8)
This commit is contained in:
Robert Chiras 2020-02-06 17:22:32 +02:00 committed by Jason Liu
parent aa8170d1ed
commit a29e420506
3 changed files with 44 additions and 36 deletions

View File

@ -149,19 +149,14 @@
<&clk IMX_SC_R_MIPI_0 IMX_SC_PM_CLK_BYPASS>,
<&clk IMX_SC_R_MIPI_0 IMX_SC_PM_CLK_PHY>,
<&clk IMX_SC_R_MIPI_0 IMX_SC_PM_CLK_MST_BUS>,
<&clk IMX_SC_R_MIPI_0 IMX_SC_PM_CLK_SLV_BUS>;
<&clk IMX_SC_R_MIPI_0 IMX_SC_PM_CLK_SLV_BUS>,
<&mipi_pll_div2_clk>;
clock-names = "pixel",
"bypass",
"phy_ref",
"tx_esc",
"rx_esc";
assigned-clocks = <&clk IMX_SC_R_MIPI_0 IMX_SC_PM_CLK_PHY>,
<&clk IMX_SC_R_MIPI_0 IMX_SC_PM_CLK_MST_BUS>,
<&clk IMX_SC_R_MIPI_0 IMX_SC_PM_CLK_SLV_BUS>;
assigned-clock-parents = <&mipi_pll_div2_clk>,
<&mipi_pll_div2_clk>,
<&mipi_pll_div2_clk>;
assigned-clock-rates = <0>, <18000000>, <72000000>;
"rx_esc",
"phy_parent";
interrupts = <16>;
interrupt-parent = <&irqsteer_mipi0>;
power-domains = <&pd IMX_SC_R_MIPI_0>;
@ -319,19 +314,14 @@
<&clk IMX_SC_R_MIPI_1 IMX_SC_PM_CLK_BYPASS>,
<&clk IMX_SC_R_MIPI_1 IMX_SC_PM_CLK_PHY>,
<&clk IMX_SC_R_MIPI_1 IMX_SC_PM_CLK_MST_BUS>,
<&clk IMX_SC_R_MIPI_1 IMX_SC_PM_CLK_SLV_BUS>;
<&clk IMX_SC_R_MIPI_1 IMX_SC_PM_CLK_SLV_BUS>,
<&mipi_pll_div2_clk>;
clock-names = "pixel",
"bypass",
"phy_ref",
"tx_esc",
"rx_esc";
assigned-clocks = <&clk IMX_SC_R_MIPI_1 IMX_SC_PM_CLK_PHY>,
<&clk IMX_SC_R_MIPI_1 IMX_SC_PM_CLK_MST_BUS>,
<&clk IMX_SC_R_MIPI_1 IMX_SC_PM_CLK_SLV_BUS>;
assigned-clock-parents = <&mipi_pll_div2_clk>,
<&mipi_pll_div2_clk>,
<&mipi_pll_div2_clk>;
assigned-clock-rates = <0>, <18000000>, <72000000>;
"rx_esc",
"phy_parent";
interrupts = <16>;
interrupt-parent = <&irqsteer_mipi1>;
power-domains = <&pd IMX_SC_R_MIPI_1>;

View File

@ -224,19 +224,14 @@
<&clk IMX_SC_R_MIPI_0 IMX_SC_PM_CLK_BYPASS>,
<&clk IMX_SC_R_MIPI_0 IMX_SC_PM_CLK_PHY>,
<&clk IMX_SC_R_MIPI_0 IMX_SC_PM_CLK_MST_BUS>,
<&clk IMX_SC_R_MIPI_0 IMX_SC_PM_CLK_SLV_BUS>;
<&clk IMX_SC_R_MIPI_0 IMX_SC_PM_CLK_SLV_BUS>,
<&mipi_pll_div2_clk>;
clock-names = "pixel",
"bypass",
"phy_ref",
"tx_esc",
"rx_esc";
assigned-clocks = <&clk IMX_SC_R_MIPI_0 IMX_SC_PM_CLK_PHY>,
<&clk IMX_SC_R_MIPI_0 IMX_SC_PM_CLK_MST_BUS>,
<&clk IMX_SC_R_MIPI_0 IMX_SC_PM_CLK_SLV_BUS>;
assigned-clock-parents = <&mipi_pll_div2_clk>,
<&mipi_pll_div2_clk>,
<&mipi_pll_div2_clk>;
assigned-clock-rates = <0>, <18000000>, <72000000>;
"rx_esc",
"phy_parent";
interrupts = <16>;
interrupt-parent = <&irqsteer_mipi_lvds0>;
power-domains = <&pd IMX_SC_R_MIPI_0>;
@ -390,19 +385,14 @@
<&clk IMX_SC_R_MIPI_1 IMX_SC_PM_CLK_BYPASS>,
<&clk IMX_SC_R_MIPI_1 IMX_SC_PM_CLK_PHY>,
<&clk IMX_SC_R_MIPI_1 IMX_SC_PM_CLK_MST_BUS>,
<&clk IMX_SC_R_MIPI_1 IMX_SC_PM_CLK_SLV_BUS>;
<&clk IMX_SC_R_MIPI_1 IMX_SC_PM_CLK_SLV_BUS>,
<&mipi_pll_div2_clk>;
clock-names = "pixel",
"bypass",
"phy_ref",
"tx_esc",
"rx_esc";
assigned-clocks = <&clk IMX_SC_R_MIPI_1 IMX_SC_PM_CLK_PHY>,
<&clk IMX_SC_R_MIPI_1 IMX_SC_PM_CLK_MST_BUS>,
<&clk IMX_SC_R_MIPI_1 IMX_SC_PM_CLK_SLV_BUS>;
assigned-clock-parents = <&mipi_pll_div2_clk>,
<&mipi_pll_div2_clk>,
<&mipi_pll_div2_clk>;
assigned-clock-rates = <0>, <18000000>, <72000000>;
"rx_esc",
"phy_parent";
interrupts = <16>;
interrupt-parent = <&irqsteer_mipi_lvds1>;
power-domains = <&pd IMX_SC_R_MIPI_1>;

View File

@ -95,6 +95,8 @@ struct nwl_dsi_platform_data {
u32 reg_tx_ulps;
u32 reg_pxl2dpi;
u32 max_instances;
u32 tx_clk_rate;
u32 rx_clk_rate;
bool mux_present;
bool shared_phy;
};
@ -593,6 +595,7 @@ static int nwl_dsi_bridge_attach(struct drm_bridge *bridge)
struct nwl_dsi *dsi = bridge->driver_private;
struct drm_bridge *panel_bridge;
struct drm_panel *panel;
struct clk *phy_parent;
int ret;
ret = drm_of_find_panel_or_bridge(dsi->dev->of_node, 1, 0, &panel,
@ -612,6 +615,27 @@ static int nwl_dsi_bridge_attach(struct drm_bridge *bridge)
if (!dsi->panel_bridge)
return -EPROBE_DEFER;
phy_parent = devm_clk_get(dsi->dev, "phy_parent");
if (!IS_ERR_OR_NULL(phy_parent)) {
ret = clk_set_parent(dsi->phy_ref_clk, phy_parent);
ret |= clk_set_parent(dsi->tx_esc_clk, phy_parent);
ret |= clk_set_parent(dsi->rx_esc_clk, phy_parent);
if (ret) {
dev_err(dsi->dev,
"Error re-parenting phy/tx/rx clocks: %d",
ret);
return ret;
}
if (dsi->pdata->tx_clk_rate)
clk_set_rate(dsi->tx_esc_clk, dsi->pdata->tx_clk_rate);
if (dsi->pdata->rx_clk_rate)
clk_set_rate(dsi->rx_esc_clk, dsi->pdata->rx_clk_rate);
}
return drm_bridge_attach(bridge->encoder, dsi->panel_bridge, bridge);
}
@ -1032,6 +1056,8 @@ static const struct nwl_dsi_platform_data imx8qm_dev = {
.reg_tx_ulps = 0x00,
.reg_pxl2dpi = 0x04,
.max_instances = 2,
.tx_clk_rate = 18000000,
.rx_clk_rate = 72000000,
.shared_phy = false,
};
@ -1046,6 +1072,8 @@ static const struct nwl_dsi_platform_data imx8qx_dev = {
.reg_tx_ulps = 0x30,
.reg_pxl2dpi = 0x40,
.max_instances = 2,
.tx_clk_rate = 18000000,
.rx_clk_rate = 72000000,
.shared_phy = true,
};