diff options
Diffstat (limited to 'drivers/gpu/drm/msm/dsi')
-rw-r--r-- | drivers/gpu/drm/msm/dsi/dsi.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/dsi/dsi.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/dsi/dsi_host.c | 108 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/dsi/dsi_manager.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 2 |
5 files changed, 68 insertions, 50 deletions
diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c index 311c1c1e7d6c..98742d7af6dc 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.c +++ b/drivers/gpu/drm/msm/dsi/dsi.c @@ -161,12 +161,17 @@ static const struct of_device_id dt_match[] = { {} }; +static const struct dev_pm_ops dsi_pm_ops = { + SET_RUNTIME_PM_OPS(msm_dsi_runtime_suspend, msm_dsi_runtime_resume, NULL) +}; + static struct platform_driver dsi_driver = { .probe = dsi_dev_probe, .remove = dsi_dev_remove, .driver = { .name = "msm_dsi", .of_match_table = dt_match, + .pm = &dsi_pm_ops, }, }; diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h index 9e6017387efb..2302046197a8 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.h +++ b/drivers/gpu/drm/msm/dsi/dsi.h @@ -179,6 +179,8 @@ void msm_dsi_host_destroy(struct mipi_dsi_host *host); int msm_dsi_host_modeset_init(struct mipi_dsi_host *host, struct drm_device *dev); int msm_dsi_host_init(struct msm_dsi *msm_dsi); +int msm_dsi_runtime_suspend(struct device *dev); +int msm_dsi_runtime_resume(struct device *dev); /* dsi phy */ struct msm_dsi_phy; diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 9e9c5696bc03..dbb31a014419 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -135,7 +135,6 @@ struct msm_dsi_host { struct completion video_comp; struct mutex dev_mutex; struct mutex cmd_mutex; - struct mutex clk_mutex; spinlock_t intr_lock; /* Protect interrupt ctrl register */ u32 err_work_state; @@ -221,6 +220,8 @@ static const struct msm_dsi_cfg_handler *dsi_get_config( goto put_gdsc; } + pm_runtime_get_sync(dev); + ret = regulator_enable(gdsc_reg); if (ret) { pr_err("%s: unable to enable gdsc\n", __func__); @@ -247,6 +248,7 @@ disable_clks: clk_disable_unprepare(ahb_clk); disable_gdsc: regulator_disable(gdsc_reg); + pm_runtime_put_autosuspend(dev); put_clk: clk_put(ahb_clk); put_gdsc: @@ -455,6 +457,34 @@ static void dsi_bus_clk_disable(struct msm_dsi_host *msm_host) clk_disable_unprepare(msm_host->bus_clks[i]); } +int msm_dsi_runtime_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct msm_dsi *msm_dsi = platform_get_drvdata(pdev); + struct mipi_dsi_host *host = msm_dsi->host; + struct msm_dsi_host *msm_host = to_msm_dsi_host(host); + + if (!msm_host->cfg_hnd) + return 0; + + dsi_bus_clk_disable(msm_host); + + return 0; +} + +int msm_dsi_runtime_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct msm_dsi *msm_dsi = platform_get_drvdata(pdev); + struct mipi_dsi_host *host = msm_dsi->host; + struct msm_dsi_host *msm_host = to_msm_dsi_host(host); + + if (!msm_host->cfg_hnd) + return 0; + + return dsi_bus_clk_enable(msm_host); +} + static int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host) { int ret; @@ -596,35 +626,6 @@ static void dsi_link_clk_disable(struct msm_dsi_host *msm_host) } } -static int dsi_clk_ctrl(struct msm_dsi_host *msm_host, bool enable) -{ - int ret = 0; - - mutex_lock(&msm_host->clk_mutex); - if (enable) { - ret = dsi_bus_clk_enable(msm_host); - if (ret) { - pr_err("%s: Can not enable bus clk, %d\n", - __func__, ret); - goto unlock_ret; - } - ret = dsi_link_clk_enable(msm_host); - if (ret) { - pr_err("%s: Can not enable link clk, %d\n", - __func__, ret); - dsi_bus_clk_disable(msm_host); - goto unlock_ret; - } - } else { - dsi_link_clk_disable(msm_host); - dsi_bus_clk_disable(msm_host); - } - -unlock_ret: - mutex_unlock(&msm_host->clk_mutex); - return ret; -} - static int dsi_calc_clk_rate(struct msm_dsi_host *msm_host) { struct drm_display_mode *mode = msm_host->mode; @@ -1699,6 +1700,7 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi) } msm_host->pdev = pdev; + msm_dsi->host = &msm_host->base; ret = dsi_host_parse_dt(msm_host); if (ret) { @@ -1713,6 +1715,8 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi) goto fail; } + pm_runtime_enable(&pdev->dev); + msm_host->cfg_hnd = dsi_get_config(msm_host); if (!msm_host->cfg_hnd) { ret = -EINVAL; @@ -1753,7 +1757,6 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi) init_completion(&msm_host->video_comp); mutex_init(&msm_host->dev_mutex); mutex_init(&msm_host->cmd_mutex); - mutex_init(&msm_host->clk_mutex); spin_lock_init(&msm_host->intr_lock); /* setup workqueue */ @@ -1761,7 +1764,6 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi) INIT_WORK(&msm_host->err_work, dsi_err_worker); INIT_WORK(&msm_host->hpd_work, dsi_hpd_worker); - msm_dsi->host = &msm_host->base; msm_dsi->id = msm_host->id; DBG("Dsi Host %d initialized", msm_host->id); @@ -1783,9 +1785,10 @@ void msm_dsi_host_destroy(struct mipi_dsi_host *host) msm_host->workqueue = NULL; } - mutex_destroy(&msm_host->clk_mutex); mutex_destroy(&msm_host->cmd_mutex); mutex_destroy(&msm_host->dev_mutex); + + pm_runtime_disable(&msm_host->pdev->dev); } int msm_dsi_host_modeset_init(struct mipi_dsi_host *host, @@ -1881,7 +1884,8 @@ int msm_dsi_host_xfer_prepare(struct mipi_dsi_host *host, * mdss interrupt is generated in mdp core clock domain * mdp clock need to be enabled to receive dsi interrupt */ - dsi_clk_ctrl(msm_host, 1); + pm_runtime_get_sync(&msm_host->pdev->dev); + dsi_link_clk_enable(msm_host); /* TODO: vote for bus bandwidth */ @@ -1911,7 +1915,8 @@ void msm_dsi_host_xfer_restore(struct mipi_dsi_host *host, /* TODO: unvote for bus bandwidth */ - dsi_clk_ctrl(msm_host, 0); + dsi_link_clk_disable(msm_host); + pm_runtime_put_autosuspend(&msm_host->pdev->dev); } int msm_dsi_host_cmd_tx(struct mipi_dsi_host *host, @@ -2137,6 +2142,13 @@ void msm_dsi_host_get_phy_clk_req(struct mipi_dsi_host *host, struct msm_dsi_phy_clk_request *clk_req) { struct msm_dsi_host *msm_host = to_msm_dsi_host(host); + int ret; + + ret = dsi_calc_clk_rate(msm_host); + if (ret) { + pr_err("%s: unable to calc clk rate, %d\n", __func__, ret); + return; + } clk_req->bitclk_rate = msm_host->byte_clk_rate * 8; clk_req->escclk_rate = msm_host->esc_clk_rate; @@ -2153,8 +2165,11 @@ int msm_dsi_host_enable(struct mipi_dsi_host *host) * and only turned on before MDP START. * This part of code should be enabled once mdp driver support it. */ - /* if (msm_panel->mode == MSM_DSI_CMD_MODE) - dsi_clk_ctrl(msm_host, 0); */ + /* if (msm_panel->mode == MSM_DSI_CMD_MODE) { + * dsi_link_clk_disable(msm_host); + * pm_runtime_put_autosuspend(&msm_host->pdev->dev); + * } + */ return 0; } @@ -2210,9 +2225,11 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host, goto unlock_ret; } - ret = dsi_clk_ctrl(msm_host, 1); + pm_runtime_get_sync(&msm_host->pdev->dev); + ret = dsi_link_clk_enable(msm_host); if (ret) { - pr_err("%s: failed to enable clocks. ret=%d\n", __func__, ret); + pr_err("%s: failed to enable link clocks. ret=%d\n", + __func__, ret); goto fail_disable_reg; } @@ -2236,7 +2253,8 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host, return 0; fail_disable_clk: - dsi_clk_ctrl(msm_host, 0); + dsi_link_clk_disable(msm_host); + pm_runtime_put_autosuspend(&msm_host->pdev->dev); fail_disable_reg: dsi_host_regulator_disable(msm_host); unlock_ret: @@ -2261,7 +2279,8 @@ int msm_dsi_host_power_off(struct mipi_dsi_host *host) pinctrl_pm_select_sleep_state(&msm_host->pdev->dev); - dsi_clk_ctrl(msm_host, 0); + dsi_link_clk_disable(msm_host); + pm_runtime_put_autosuspend(&msm_host->pdev->dev); dsi_host_regulator_disable(msm_host); @@ -2280,7 +2299,6 @@ int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host, struct drm_display_mode *mode) { struct msm_dsi_host *msm_host = to_msm_dsi_host(host); - int ret; if (msm_host->mode) { drm_mode_destroy(msm_host->dev, msm_host->mode); @@ -2293,12 +2311,6 @@ int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host, return -ENOMEM; } - ret = dsi_calc_clk_rate(msm_host); - if (ret) { - pr_err("%s: unable to calc clk rate, %d\n", __func__, ret); - return ret; - } - return 0; } diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c index a879ffa534b4..855248132b2b 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -626,7 +626,6 @@ static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge, } static const struct drm_connector_funcs dsi_mgr_connector_funcs = { - .dpms = drm_atomic_helper_connector_dpms, .detect = dsi_mgr_connector_detect, .fill_modes = drm_helper_probe_single_connector_modes, .destroy = dsi_mgr_connector_destroy, diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c index 0c2eb9c9a1fc..7c9bf91bc22b 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c @@ -373,7 +373,7 @@ static int dsi_phy_enable_resource(struct msm_dsi_phy *phy) static void dsi_phy_disable_resource(struct msm_dsi_phy *phy) { clk_disable_unprepare(phy->ahb_clk); - pm_runtime_put_sync(&phy->pdev->dev); + pm_runtime_put_autosuspend(&phy->pdev->dev); } static const struct of_device_id dsi_phy_dt_match[] = { |