diff options
Diffstat (limited to 'drivers/gpu/drm/msm/dsi/dsi_host.c')
-rw-r--r-- | drivers/gpu/drm/msm/dsi/dsi_host.c | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index de0400923303..932efabeef2e 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -219,6 +219,9 @@ struct msm_dsi_host { enum mipi_dsi_pixel_format format; unsigned long mode_flags; + /* external bridge info */ + struct device_node *ext_bridge_node; + u32 dma_cmd_ctrl_restore; bool registered; @@ -1372,6 +1375,7 @@ static int dsi_host_attach(struct mipi_dsi_host *host, struct mipi_dsi_device *dsi) { struct msm_dsi_host *msm_host = to_msm_dsi_host(host); + struct device_node *bridge, *np = msm_host->pdev->dev.of_node; int ret; msm_host->channel = dsi->channel; @@ -1379,6 +1383,13 @@ static int dsi_host_attach(struct mipi_dsi_host *host, msm_host->format = dsi->format; msm_host->mode_flags = dsi->mode_flags; + /* if we have an external bridge, don't populate panel data */ + bridge = of_get_child_by_name(np, "bridge"); + if (bridge) { + of_node_put(bridge); + return 0; + } + msm_host->panel_node = dsi->dev.of_node; /* Some gpios defined in panel DT need to be controlled by host */ @@ -1579,11 +1590,26 @@ int msm_dsi_host_register(struct mipi_dsi_host *host, bool check_defer) * create framebuffer. */ if (check_defer) { + /* + * first look for a child panel node, if a panel node + * exists but the corresponding panel device isn't + * probed, defer msm dsi's probe + * + * if a child panel isn't specified at all, try to look + * for a bridge phandle, defer probe if it there is a + * bridge phandle but the bridge device isn't added yet + */ node = of_get_child_by_name(msm_host->pdev->dev.of_node, "panel"); if (node) { if (!of_drm_find_panel(node)) return -EPROBE_DEFER; + } else { + struct drm_bridge *bridge; + + bridge = msm_dsi_host_get_ext_bridge(host); + if (!bridge) + return -EPROBE_DEFER; } } } @@ -1882,7 +1908,6 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host) DBG("dsi host already on"); goto unlock_ret; } - ret = dsi_calc_clk_rate(msm_host); if (ret) { pr_err("%s: unable to calc clk rate, %d\n", __func__, ret); @@ -1905,7 +1930,7 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host) dsi_phy_sw_reset(msm_host); ret = msm_dsi_manager_phy_enable(msm_host->id, msm_host->byte_clk_rate * 8, - clk_get_rate(msm_host->esc_clk), + 19200000,/*clk_get_rate(msm_host->esc_clk),*/ &clk_pre, &clk_post); dsi_bus_clk_disable(msm_host); if (ret) { @@ -2000,3 +2025,21 @@ struct drm_panel *msm_dsi_host_get_panel(struct mipi_dsi_host *host, return panel; } +struct drm_bridge *msm_dsi_host_get_ext_bridge(struct mipi_dsi_host *host) +{ + struct msm_dsi_host *msm_host = to_msm_dsi_host(host); + struct drm_bridge *bridge; + struct device_node *np = msm_host->pdev->dev.of_node; + + msm_host->ext_bridge_node = of_get_child_by_name(np, "bridge"); + if (!msm_host->ext_bridge_node) { + dev_err(&msm_host->pdev->dev, "bridge not found\n"); + return NULL; + } + + bridge = of_drm_find_bridge(msm_host->ext_bridge_node); + + of_node_put(msm_host->ext_bridge_node); + + return bridge; +} |