diff options
author | Fugang Duan <fugang.duan@nxp.com> | 2017-12-19 13:36:00 +0800 |
---|---|---|
committer | Fugang Duan <fugang.duan@nxp.com> | 2018-01-08 14:12:02 +0800 |
commit | 21253ef7cd0b79c249ddbcf144bd74dac210ece1 (patch) | |
tree | 7eaaf8bf9cbe00f0b3a47e0d4219038912fc184d | |
parent | 7fa12bc9427ba86d51a0d7f364a7a93349dc250a (diff) |
MLK-17290-03 drm/bridge: request/free irq in dynamical
Request/free irq in dynamical can runtime manage the irq domain's
clock and power if irq domain support runtime pm and manage its
clock in its pm callback.
Signed-off-by: Fugang Duan <fugang.duan@nxp.com>
Tested-by: Guoniu.Zhou <guoniu.zhou@nxp.com>
Acked-by: Robert Chiras <robert.chiras@nxp.com>
(cherry picked from commit: 1ddd124d5e3c361a567e3da4f22d041cade28d92)
-rw-r--r-- | drivers/gpu/drm/bridge/nwl-dsi.c | 161 |
1 files changed, 81 insertions, 80 deletions
diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c index fd5b82e49c9b..fc0516577e97 100644 --- a/drivers/gpu/drm/bridge/nwl-dsi.c +++ b/drivers/gpu/drm/bridge/nwl-dsi.c @@ -441,76 +441,6 @@ static void nwl_dsi_init_interrupts(struct nwl_mipi_dsi *dsi) nwl_dsi_write(dsi, IRQ_MASK, irq_enable); } -static void nwl_dsi_bridge_enable(struct drm_bridge *bridge) -{ - struct nwl_mipi_dsi *dsi = bridge->driver_private; - struct device *dev = dsi->dev; - int ret; - - if (dsi->enabled || (!dsi->panel && !dsi->next_bridge)) - return; - - if (!dsi->lanes) { - DRM_DEV_ERROR(dev, "Bridge not set up properly!\n"); - return; - } - - nwl_dsi_enable_clocks(dsi, CLK_PHY_REF | CLK_TX_ESC); - - nwl_dsi_config_host(dsi); - nwl_dsi_config_dpi(dsi); - - phy_init(dsi->phy); - - ret = phy_power_on(dsi->phy); - if (ret < 0) { - DRM_DEV_ERROR(dev, "Failed to power on DPHY (%d)\n", ret); - return; - } - - nwl_dsi_init_interrupts(dsi); - - if (dsi->panel && drm_panel_prepare(dsi->panel)) { - DRM_DEV_ERROR(dev, "Failed to setup panel\n"); - return; - } - - if (dsi->dsi_mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) - nwl_dsi_write(dsi, CFG_NONCONTINUOUS_CLK, 0x00); - - if (dsi->panel && drm_panel_enable(dsi->panel)) { - DRM_DEV_ERROR(dev, "Failed to enable panel\n"); - drm_panel_unprepare(dsi->panel); - return; - } - - dsi->enabled = true; -} - -static void nwl_dsi_bridge_disable(struct drm_bridge *bridge) -{ - struct nwl_mipi_dsi *dsi = bridge->driver_private; - struct device *dev = dsi->dev; - - if (!dsi->enabled) - return; - - if (dsi->panel) { - if (drm_panel_disable(dsi->panel)) { - DRM_DEV_ERROR(dev, "failed to disable panel\n"); - return; - } - drm_panel_unprepare(dsi->panel); - } - - nwl_dsi_disable_clocks(dsi, CLK_PHY_REF | CLK_TX_ESC); - - phy_power_off(dsi->phy); - phy_exit(dsi->phy); - - dsi->enabled = false; -} - static bool nwl_dsi_bridge_mode_fixup(struct drm_bridge *bridge, const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) @@ -1077,6 +1007,85 @@ static void nwl_dsi_bridge_detach(struct drm_bridge *bridge) mipi_dsi_host_unregister(&dsi->host); } +static void nwl_dsi_bridge_enable(struct drm_bridge *bridge) +{ + struct nwl_mipi_dsi *dsi = bridge->driver_private; + struct device *dev = dsi->dev; + int ret; + + if (dsi->enabled || (!dsi->panel && !dsi->next_bridge)) + return; + + if (!dsi->lanes) { + DRM_DEV_ERROR(dev, "Bridge not set up properly!\n"); + return; + } + + ret = devm_request_irq(dev, dsi->irq, + nwl_dsi_irq_handler, 0, IRQ_NAME, dsi); + if (ret < 0) { + DRM_DEV_ERROR(dev, "Failed to request IRQ: %d (%d)\n", + dsi->irq, ret); + return; + } + + nwl_dsi_enable_clocks(dsi, CLK_PHY_REF | CLK_TX_ESC); + + nwl_dsi_config_host(dsi); + nwl_dsi_config_dpi(dsi); + + phy_init(dsi->phy); + + ret = phy_power_on(dsi->phy); + if (ret < 0) { + DRM_DEV_ERROR(dev, "Failed to power on DPHY (%d)\n", ret); + return; + } + + nwl_dsi_init_interrupts(dsi); + + if (dsi->panel && drm_panel_prepare(dsi->panel)) { + DRM_DEV_ERROR(dev, "Failed to setup panel\n"); + return; + } + + if (dsi->dsi_mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) + nwl_dsi_write(dsi, CFG_NONCONTINUOUS_CLK, 0x00); + + if (dsi->panel && drm_panel_enable(dsi->panel)) { + DRM_DEV_ERROR(dev, "Failed to enable panel\n"); + drm_panel_unprepare(dsi->panel); + return; + } + + dsi->enabled = true; +} + +static void nwl_dsi_bridge_disable(struct drm_bridge *bridge) +{ + struct nwl_mipi_dsi *dsi = bridge->driver_private; + struct device *dev = dsi->dev; + + if (!dsi->enabled) + return; + + if (dsi->panel) { + if (drm_panel_disable(dsi->panel)) { + DRM_DEV_ERROR(dev, "failed to disable panel\n"); + return; + } + drm_panel_unprepare(dsi->panel); + } + + nwl_dsi_disable_clocks(dsi, CLK_PHY_REF | CLK_TX_ESC); + devm_free_irq(dev, dsi->irq, dsi); + + phy_power_off(dsi->phy); + phy_exit(dsi->phy); + + dsi->enabled = false; +} + static const struct drm_bridge_funcs nwl_dsi_bridge_funcs = { .enable = nwl_dsi_bridge_enable, .disable = nwl_dsi_bridge_disable, @@ -1092,7 +1101,6 @@ static int nwl_dsi_probe(struct platform_device *pdev) struct nwl_mipi_dsi *dsi; struct clk *clk; struct resource *res; - int irq; int ret; dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); @@ -1149,19 +1157,12 @@ static int nwl_dsi_probe(struct platform_device *pdev) if (IS_ERR(dsi->base)) return PTR_ERR(dsi->base); - irq = platform_get_irq(pdev, 0); - if (irq < 0) { + dsi->irq = platform_get_irq(pdev, 0); + if (dsi->irq < 0) { DRM_DEV_ERROR(dev, "Failed to get device IRQ!\n"); return -EINVAL; } - ret = devm_request_irq(dev, irq, - nwl_dsi_irq_handler, 0, IRQ_NAME, dsi); - if (ret < 0) { - dev_err(dev, "Failed to request IRQ: %d (%d)\n", dsi->irq, ret); - return ret; - } - dsi->dev = dev; platform_set_drvdata(pdev, dsi); |