Commit cd792726 authored by Archit Taneja's avatar Archit Taneja Committed by Rob Clark

drm/msm: Call pm_runtime_enable/disable for newly created devices

With the new device hierarchy for MDP5, we need to enable runtime PM
for both the toplevel MDSS device and the MDP5 device itself. Enable
runtime PM for the new devices.

Since MDP4 and MDP5 now have different places where runtime PM is
enabled, remove the previous pm_runtime_enable/disable calls, and
squash them in the respective kms drivers.

The new device hierarchy (as expressed in the DT bindings) has the GDSC
tied only to the MDSS wrapper device. This GDSC needs to be enabled for
accessing any register in the MDSS sub-blocks. Once every driver is
runtime adapted, the GDSC will be enabled when any sub-block device
calls runtime_get because of the parent-child relationship with MDSS.

Until then, we call pm_runtime_get_sync() once for the MDSS device to
ensure the GDSC is never disabled. This will be removed once all the
drivers are runtime PM adapted.

The error handling paths become a bit tricky when we call these runtime
PM funcs. There doesn't seem to be any helper that checks if runtime PM
is enabled already. Add bool variables in mdp4_kms/mdp5_kms structs to
check if the driver had managed to call pm_runtime_enable before bailing
out.
Signed-off-by: default avatarArchit Taneja <architt@codeaurora.org>
Signed-off-by: default avatarRob Clark <robdclark@gmail.com>
parent 031d63dd
...@@ -158,6 +158,7 @@ static const char * const iommu_ports[] = { ...@@ -158,6 +158,7 @@ static const char * const iommu_ports[] = {
static void mdp4_destroy(struct msm_kms *kms) static void mdp4_destroy(struct msm_kms *kms)
{ {
struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms)); struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
struct device *dev = mdp4_kms->dev->dev;
struct msm_mmu *mmu = mdp4_kms->mmu; struct msm_mmu *mmu = mdp4_kms->mmu;
if (mmu) { if (mmu) {
...@@ -169,6 +170,10 @@ static void mdp4_destroy(struct msm_kms *kms) ...@@ -169,6 +170,10 @@ static void mdp4_destroy(struct msm_kms *kms)
msm_gem_put_iova(mdp4_kms->blank_cursor_bo, mdp4_kms->id); msm_gem_put_iova(mdp4_kms->blank_cursor_bo, mdp4_kms->id);
if (mdp4_kms->blank_cursor_bo) if (mdp4_kms->blank_cursor_bo)
drm_gem_object_unreference_unlocked(mdp4_kms->blank_cursor_bo); drm_gem_object_unreference_unlocked(mdp4_kms->blank_cursor_bo);
if (mdp4_kms->rpm_enabled)
pm_runtime_disable(dev);
kfree(mdp4_kms); kfree(mdp4_kms);
} }
...@@ -511,6 +516,9 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) ...@@ -511,6 +516,9 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev)
clk_set_rate(mdp4_kms->clk, config->max_clk); clk_set_rate(mdp4_kms->clk, config->max_clk);
clk_set_rate(mdp4_kms->lut_clk, config->max_clk); clk_set_rate(mdp4_kms->lut_clk, config->max_clk);
pm_runtime_enable(dev->dev);
mdp4_kms->rpm_enabled = true;
/* make sure things are off before attaching iommu (bootloader could /* make sure things are off before attaching iommu (bootloader could
* have left things on, in which case we'll start getting faults if * have left things on, in which case we'll start getting faults if
* we don't disable): * we don't disable):
......
...@@ -47,6 +47,8 @@ struct mdp4_kms { ...@@ -47,6 +47,8 @@ struct mdp4_kms {
struct mdp_irq error_handler; struct mdp_irq error_handler;
bool rpm_enabled;
/* empty/blank cursor bo to use when cursor is "disabled" */ /* empty/blank cursor bo to use when cursor is "disabled" */
struct drm_gem_object *blank_cursor_bo; struct drm_gem_object *blank_cursor_bo;
uint32_t blank_cursor_iova; uint32_t blank_cursor_iova;
......
...@@ -668,6 +668,9 @@ static void mdp5_destroy(struct platform_device *pdev) ...@@ -668,6 +668,9 @@ static void mdp5_destroy(struct platform_device *pdev)
mdp5_smp_destroy(mdp5_kms->smp); mdp5_smp_destroy(mdp5_kms->smp);
if (mdp5_kms->cfg) if (mdp5_kms->cfg)
mdp5_cfg_destroy(mdp5_kms->cfg); mdp5_cfg_destroy(mdp5_kms->cfg);
if (mdp5_kms->rpm_enabled)
pm_runtime_disable(&pdev->dev);
} }
static int mdp5_init(struct platform_device *pdev, struct drm_device *dev) static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
...@@ -720,6 +723,9 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev) ...@@ -720,6 +723,9 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
*/ */
clk_set_rate(mdp5_kms->core_clk, 200000000); clk_set_rate(mdp5_kms->core_clk, 200000000);
pm_runtime_enable(&pdev->dev);
mdp5_kms->rpm_enabled = true;
read_mdp_hw_revision(mdp5_kms, &major, &minor); read_mdp_hw_revision(mdp5_kms, &major, &minor);
mdp5_kms->cfg = mdp5_cfg_init(mdp5_kms, major, minor); mdp5_kms->cfg = mdp5_cfg_init(mdp5_kms, major, minor);
......
...@@ -59,6 +59,8 @@ struct mdp5_kms { ...@@ -59,6 +59,8 @@ struct mdp5_kms {
*/ */
spinlock_t resource_lock; spinlock_t resource_lock;
bool rpm_enabled;
struct mdp_irq error_handler; struct mdp_irq error_handler;
}; };
#define to_mdp5_kms(x) container_of(x, struct mdp5_kms, base) #define to_mdp5_kms(x) container_of(x, struct mdp5_kms, base)
......
...@@ -152,6 +152,10 @@ void msm_mdss_destroy(struct drm_device *dev) ...@@ -152,6 +152,10 @@ void msm_mdss_destroy(struct drm_device *dev)
mdss->irqcontroller.domain = NULL; mdss->irqcontroller.domain = NULL;
regulator_disable(mdss->vdd); regulator_disable(mdss->vdd);
pm_runtime_put_sync(dev->dev);
pm_runtime_disable(dev->dev);
} }
int msm_mdss_init(struct drm_device *dev) int msm_mdss_init(struct drm_device *dev)
...@@ -215,6 +219,14 @@ int msm_mdss_init(struct drm_device *dev) ...@@ -215,6 +219,14 @@ int msm_mdss_init(struct drm_device *dev)
priv->mdss = mdss; priv->mdss = mdss;
pm_runtime_enable(dev->dev);
/*
* TODO: This is needed as the MDSS GDSC is only tied to MDSS's power
* domain. Remove this once runtime PM is adapted for all the devices.
*/
pm_runtime_get_sync(dev->dev);
return 0; return 0;
fail_irq: fail_irq:
regulator_disable(mdss->vdd); regulator_disable(mdss->vdd);
......
...@@ -215,10 +215,8 @@ static int msm_drm_uninit(struct device *dev) ...@@ -215,10 +215,8 @@ static int msm_drm_uninit(struct device *dev)
flush_workqueue(priv->atomic_wq); flush_workqueue(priv->atomic_wq);
destroy_workqueue(priv->atomic_wq); destroy_workqueue(priv->atomic_wq);
if (kms) { if (kms)
pm_runtime_disable(dev);
kms->funcs->destroy(kms); kms->funcs->destroy(kms);
}
if (gpu) { if (gpu) {
mutex_lock(&ddev->struct_mutex); mutex_lock(&ddev->struct_mutex);
...@@ -410,7 +408,6 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) ...@@ -410,7 +408,6 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
} }
if (kms) { if (kms) {
pm_runtime_enable(dev);
ret = kms->funcs->hw_init(kms); ret = kms->funcs->hw_init(kms);
if (ret) { if (ret) {
dev_err(dev, "kms hw init failed: %d\n", ret); dev_err(dev, "kms hw init failed: %d\n", ret);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment