Commit e35a29d5 authored by Rob Clark's avatar Rob Clark

drm/msm: split power control from prepare/complete_commit

With atomic commit, ->prepare_commit() and ->complete_commit() may not
be evenly balanced (although ->complete_commit() will complete each
crtc that had been previously prepared).  So these will no longer be
a good place to enable/disable clocks needed for hw access.
Signed-off-by: default avatarRob Clark <robdclark@chromium.org>
Reviewed-by: default avatarSean Paul <sean@poorly.run>
parent 9f6b6564
...@@ -250,6 +250,18 @@ static void dpu_kms_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc) ...@@ -250,6 +250,18 @@ static void dpu_kms_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
dpu_crtc_vblank(crtc, false); dpu_crtc_vblank(crtc, false);
} }
static void dpu_kms_enable_commit(struct msm_kms *kms)
{
struct dpu_kms *dpu_kms = to_dpu_kms(kms);
pm_runtime_get_sync(&dpu_kms->pdev->dev);
}
static void dpu_kms_disable_commit(struct msm_kms *kms)
{
struct dpu_kms *dpu_kms = to_dpu_kms(kms);
pm_runtime_put_sync(&dpu_kms->pdev->dev);
}
static void dpu_kms_prepare_commit(struct msm_kms *kms, static void dpu_kms_prepare_commit(struct msm_kms *kms,
struct drm_atomic_state *state) struct drm_atomic_state *state)
{ {
...@@ -269,7 +281,6 @@ static void dpu_kms_prepare_commit(struct msm_kms *kms, ...@@ -269,7 +281,6 @@ static void dpu_kms_prepare_commit(struct msm_kms *kms,
if (!dev || !dev->dev_private) if (!dev || !dev->dev_private)
return; return;
priv = dev->dev_private; priv = dev->dev_private;
pm_runtime_get_sync(&dpu_kms->pdev->dev);
/* Call prepare_commit for all affected encoders */ /* Call prepare_commit for all affected encoders */
for_each_new_crtc_in_state(state, crtc, crtc_state, i) { for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
...@@ -337,8 +348,6 @@ static void dpu_kms_complete_commit(struct msm_kms *kms, unsigned crtc_mask) ...@@ -337,8 +348,6 @@ static void dpu_kms_complete_commit(struct msm_kms *kms, unsigned crtc_mask)
for_each_crtc_mask(dpu_kms->dev, crtc, crtc_mask) for_each_crtc_mask(dpu_kms->dev, crtc, crtc_mask)
dpu_crtc_complete_commit(crtc); dpu_crtc_complete_commit(crtc);
pm_runtime_put_sync(&dpu_kms->pdev->dev);
DPU_ATRACE_END("kms_complete_commit"); DPU_ATRACE_END("kms_complete_commit");
} }
...@@ -684,6 +693,8 @@ static const struct msm_kms_funcs kms_funcs = { ...@@ -684,6 +693,8 @@ static const struct msm_kms_funcs kms_funcs = {
.irq_preinstall = dpu_irq_preinstall, .irq_preinstall = dpu_irq_preinstall,
.irq_uninstall = dpu_irq_uninstall, .irq_uninstall = dpu_irq_uninstall,
.irq = dpu_irq, .irq = dpu_irq,
.enable_commit = dpu_kms_enable_commit,
.disable_commit = dpu_kms_disable_commit,
.prepare_commit = dpu_kms_prepare_commit, .prepare_commit = dpu_kms_prepare_commit,
.flush_commit = dpu_kms_flush_commit, .flush_commit = dpu_kms_flush_commit,
.commit = dpu_kms_commit, .commit = dpu_kms_commit,
......
...@@ -96,15 +96,24 @@ static int mdp4_hw_init(struct msm_kms *kms) ...@@ -96,15 +96,24 @@ static int mdp4_hw_init(struct msm_kms *kms)
return ret; return ret;
} }
static void mdp4_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state) static void mdp4_enable_commit(struct msm_kms *kms)
{
struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
mdp4_enable(mdp4_kms);
}
static void mdp4_disable_commit(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));
mdp4_disable(mdp4_kms);
}
static void mdp4_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state)
{
int i; int i;
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state; struct drm_crtc_state *crtc_state;
mdp4_enable(mdp4_kms);
/* see 119ecb7fd */ /* see 119ecb7fd */
for_each_new_crtc_in_state(state, crtc, crtc_state, i) for_each_new_crtc_in_state(state, crtc, crtc_state, i)
drm_crtc_vblank_get(crtc); drm_crtc_vblank_get(crtc);
...@@ -132,8 +141,6 @@ static void mdp4_complete_commit(struct msm_kms *kms, unsigned crtc_mask) ...@@ -132,8 +141,6 @@ static void mdp4_complete_commit(struct msm_kms *kms, unsigned crtc_mask)
/* see 119ecb7fd */ /* see 119ecb7fd */
for_each_crtc_mask(mdp4_kms->dev, crtc, crtc_mask) for_each_crtc_mask(mdp4_kms->dev, crtc, crtc_mask)
drm_crtc_vblank_put(crtc); drm_crtc_vblank_put(crtc);
mdp4_disable(mdp4_kms);
} }
static long mdp4_round_pixclk(struct msm_kms *kms, unsigned long rate, static long mdp4_round_pixclk(struct msm_kms *kms, unsigned long rate,
...@@ -185,6 +192,8 @@ static const struct mdp_kms_funcs kms_funcs = { ...@@ -185,6 +192,8 @@ static const struct mdp_kms_funcs kms_funcs = {
.irq = mdp4_irq, .irq = mdp4_irq,
.enable_vblank = mdp4_enable_vblank, .enable_vblank = mdp4_enable_vblank,
.disable_vblank = mdp4_disable_vblank, .disable_vblank = mdp4_disable_vblank,
.enable_commit = mdp4_enable_commit,
.disable_commit = mdp4_disable_commit,
.prepare_commit = mdp4_prepare_commit, .prepare_commit = mdp4_prepare_commit,
.flush_commit = mdp4_flush_commit, .flush_commit = mdp4_flush_commit,
.wait_flush = mdp4_wait_flush, .wait_flush = mdp4_wait_flush,
......
...@@ -146,16 +146,25 @@ static int mdp5_global_obj_init(struct mdp5_kms *mdp5_kms) ...@@ -146,16 +146,25 @@ static int mdp5_global_obj_init(struct mdp5_kms *mdp5_kms)
return 0; return 0;
} }
static void mdp5_enable_commit(struct msm_kms *kms)
{
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
pm_runtime_get_sync(&mdp5_kms->pdev->dev);
}
static void mdp5_disable_commit(struct msm_kms *kms)
{
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
pm_runtime_put_sync(&mdp5_kms->pdev->dev);
}
static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state) static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state)
{ {
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
struct device *dev = &mdp5_kms->pdev->dev;
struct mdp5_global_state *global_state; struct mdp5_global_state *global_state;
global_state = mdp5_get_existing_global_state(mdp5_kms); global_state = mdp5_get_existing_global_state(mdp5_kms);
pm_runtime_get_sync(dev);
if (mdp5_kms->smp) if (mdp5_kms->smp)
mdp5_smp_prepare_commit(mdp5_kms->smp, &global_state->smp); mdp5_smp_prepare_commit(mdp5_kms->smp, &global_state->smp);
} }
...@@ -177,15 +186,12 @@ static void mdp5_wait_flush(struct msm_kms *kms, unsigned crtc_mask) ...@@ -177,15 +186,12 @@ static void mdp5_wait_flush(struct msm_kms *kms, unsigned crtc_mask)
static void mdp5_complete_commit(struct msm_kms *kms, unsigned crtc_mask) static void mdp5_complete_commit(struct msm_kms *kms, unsigned crtc_mask)
{ {
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
struct device *dev = &mdp5_kms->pdev->dev;
struct mdp5_global_state *global_state; struct mdp5_global_state *global_state;
global_state = mdp5_get_existing_global_state(mdp5_kms); global_state = mdp5_get_existing_global_state(mdp5_kms);
if (mdp5_kms->smp) if (mdp5_kms->smp)
mdp5_smp_complete_commit(mdp5_kms->smp, &global_state->smp); mdp5_smp_complete_commit(mdp5_kms->smp, &global_state->smp);
pm_runtime_put_sync(dev);
} }
static long mdp5_round_pixclk(struct msm_kms *kms, unsigned long rate, static long mdp5_round_pixclk(struct msm_kms *kms, unsigned long rate,
...@@ -284,6 +290,8 @@ static const struct mdp_kms_funcs kms_funcs = { ...@@ -284,6 +290,8 @@ static const struct mdp_kms_funcs kms_funcs = {
.enable_vblank = mdp5_enable_vblank, .enable_vblank = mdp5_enable_vblank,
.disable_vblank = mdp5_disable_vblank, .disable_vblank = mdp5_disable_vblank,
.flush_commit = mdp5_flush_commit, .flush_commit = mdp5_flush_commit,
.enable_commit = mdp5_enable_commit,
.disable_commit = mdp5_disable_commit,
.prepare_commit = mdp5_prepare_commit, .prepare_commit = mdp5_prepare_commit,
.wait_flush = mdp5_wait_flush, .wait_flush = mdp5_wait_flush,
.complete_commit = mdp5_complete_commit, .complete_commit = mdp5_complete_commit,
......
...@@ -49,6 +49,7 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state) ...@@ -49,6 +49,7 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state)
struct msm_kms *kms = priv->kms; struct msm_kms *kms = priv->kms;
unsigned crtc_mask = get_crtc_mask(state); unsigned crtc_mask = get_crtc_mask(state);
kms->funcs->enable_commit(kms);
kms->funcs->prepare_commit(kms, state); kms->funcs->prepare_commit(kms, state);
/* /*
...@@ -69,6 +70,7 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state) ...@@ -69,6 +70,7 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state)
kms->funcs->wait_flush(kms, crtc_mask); kms->funcs->wait_flush(kms, crtc_mask);
kms->funcs->complete_commit(kms, crtc_mask); kms->funcs->complete_commit(kms, crtc_mask);
kms->funcs->disable_commit(kms);
drm_atomic_helper_commit_hw_done(state); drm_atomic_helper_commit_hw_done(state);
......
...@@ -35,6 +35,16 @@ struct msm_kms_funcs { ...@@ -35,6 +35,16 @@ struct msm_kms_funcs {
* Atomic commit handling: * Atomic commit handling:
*/ */
/**
* Enable/disable power/clks needed for hw access done in other
* commit related methods.
*
* If mdp4 is migrated to runpm, we could probably drop these
* and use runpm directly.
*/
void (*enable_commit)(struct msm_kms *kms);
void (*disable_commit)(struct msm_kms *kms);
/** /**
* Prepare for atomic commit. This is called after any previous * Prepare for atomic commit. This is called after any previous
* (async or otherwise) commit has completed. * (async or otherwise) commit has completed.
......
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