diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index 43ee0fe14c88..5ebc08ca5b5a 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -244,6 +244,7 @@ struct dw_mipi_dsi { struct device *dev; void __iomem *base; + struct reset_control *apb_rst; struct clk *pclk; unsigned int lane_mbps; /* per lane */ @@ -909,6 +910,12 @@ static void dw_mipi_dsi_mode_set(struct dw_mipi_dsi *dsi, clk_prepare_enable(dsi->pclk); + if (dsi->apb_rst) { + reset_control_assert(dsi->apb_rst); + usleep_range(10, 20); + reset_control_deassert(dsi->apb_rst); + } + ret = phy_ops->get_lane_mbps(priv_data, adjusted_mode, dsi->mode_flags, lanes, dsi->format, &dsi->lane_mbps); if (ret) @@ -943,6 +950,9 @@ static void dw_mipi_dsi_mode_set(struct dw_mipi_dsi *dsi, if (phy_ops->power_on) phy_ops->power_on(dsi->plat_data->priv_data); + + DRM_DEV_INFO(dsi->dev, "final DSI-Link bandwidth: %u x %d Mbps\n", + dsi->lane_mbps, dsi->slave ? dsi->lanes * 2 : dsi->lanes); } static void dw_mipi_dsi_bridge_mode_set(struct drm_bridge *bridge, @@ -1098,7 +1108,6 @@ __dw_mipi_dsi_probe(struct platform_device *pdev, const struct dw_mipi_dsi_plat_data *plat_data) { struct device *dev = &pdev->dev; - struct reset_control *apb_rst; struct dw_mipi_dsi *dsi; int ret; @@ -1135,9 +1144,9 @@ __dw_mipi_dsi_probe(struct platform_device *pdev, * Note that the reset was not defined in the initial device tree, so * we have to be prepared for it not being found. */ - apb_rst = devm_reset_control_get_optional_exclusive(dev, "apb"); - if (IS_ERR(apb_rst)) { - ret = PTR_ERR(apb_rst); + dsi->apb_rst = devm_reset_control_get_optional_exclusive(dev, "apb"); + if (IS_ERR(dsi->apb_rst)) { + ret = PTR_ERR(dsi->apb_rst); if (ret != -EPROBE_DEFER) dev_err(dev, "Unable to get reset control: %d\n", ret); @@ -1145,20 +1154,6 @@ __dw_mipi_dsi_probe(struct platform_device *pdev, return ERR_PTR(ret); } - if (apb_rst) { - ret = clk_prepare_enable(dsi->pclk); - if (ret) { - dev_err(dev, "%s: Failed to enable pclk\n", __func__); - return ERR_PTR(ret); - } - - reset_control_assert(apb_rst); - usleep_range(10, 20); - reset_control_deassert(apb_rst); - - clk_disable_unprepare(dsi->pclk); - } - dw_mipi_dsi_debugfs_init(dsi); pm_runtime_enable(dev); @@ -1202,6 +1197,15 @@ void dw_mipi_dsi_set_slave(struct dw_mipi_dsi *dsi, struct dw_mipi_dsi *slave) } EXPORT_SYMBOL_GPL(dw_mipi_dsi_set_slave); +void dw_mipi_dsi_loader_protect(struct dw_mipi_dsi *dsi, bool on) +{ + if (on) + clk_prepare_enable(dsi->pclk); + else + clk_disable_unprepare(dsi->pclk); +} +EXPORT_SYMBOL_GPL(dw_mipi_dsi_loader_protect); + /* * Probe/remove API, used from platforms based on the DRM bridge API. */ diff --git a/include/drm/bridge/dw_mipi_dsi.h b/include/drm/bridge/dw_mipi_dsi.h index f89b0476aafd..481dd64fe701 100644 --- a/include/drm/bridge/dw_mipi_dsi.h +++ b/include/drm/bridge/dw_mipi_dsi.h @@ -67,5 +67,6 @@ int dw_mipi_dsi_bind(struct dw_mipi_dsi *dsi, struct drm_encoder *encoder); void dw_mipi_dsi_unbind(struct dw_mipi_dsi *dsi); void dw_mipi_dsi_set_slave(struct dw_mipi_dsi *dsi, struct dw_mipi_dsi *slave); struct drm_connector *dw_mipi_dsi_get_connector(struct dw_mipi_dsi *dsi); +void dw_mipi_dsi_loader_protect(struct dw_mipi_dsi *dsi, bool on); #endif /* __DW_MIPI_DSI__ */