diff options
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 21 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c | 27 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 49 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 3 |
6 files changed, 78 insertions, 36 deletions
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c index aa7402e03f67..60790df91bfa 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c @@ -192,6 +192,7 @@ int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder, { struct mdp5_encoder *mdp5_cmd_enc = to_mdp5_encoder(encoder); struct mdp5_kms *mdp5_kms; + struct device *dev; int intf_num; u32 data = 0; @@ -214,14 +215,16 @@ int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder, /* Smart Panel, Sync mode */ data |= MDP5_SPLIT_DPL_UPPER_SMART_PANEL; + dev = &mdp5_kms->pdev->dev; + /* Make sure clocks are on when connectors calling this function. */ - mdp5_enable(mdp5_kms); + pm_runtime_get_sync(dev); mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_UPPER, data); mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_LOWER, MDP5_SPLIT_DPL_LOWER_SMART_PANEL); mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_EN, 1); - mdp5_disable(mdp5_kms); + pm_runtime_put_autosuspend(dev); return 0; } diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index 735a87a699fa..aa9d56972e3d 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c @@ -414,6 +414,7 @@ static void mdp5_crtc_disable(struct drm_crtc *crtc) struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state); struct mdp5_kms *mdp5_kms = get_kms(crtc); + struct device *dev = &mdp5_kms->pdev->dev; DBG("%s", crtc->name); @@ -424,7 +425,7 @@ static void mdp5_crtc_disable(struct drm_crtc *crtc) mdp_irq_unregister(&mdp5_kms->base, &mdp5_crtc->pp_done); mdp_irq_unregister(&mdp5_kms->base, &mdp5_crtc->err); - mdp5_disable(mdp5_kms); + pm_runtime_put_autosuspend(dev); mdp5_crtc->enabled = false; } @@ -434,13 +435,14 @@ static void mdp5_crtc_enable(struct drm_crtc *crtc) struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state); struct mdp5_kms *mdp5_kms = get_kms(crtc); + struct device *dev = &mdp5_kms->pdev->dev; DBG("%s", crtc->name); if (WARN_ON(mdp5_crtc->enabled)) return; - mdp5_enable(mdp5_kms); + pm_runtime_get_sync(dev); mdp_irq_register(&mdp5_kms->base, &mdp5_crtc->err); if (mdp5_cstate->cmd_mode) @@ -725,6 +727,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, struct mdp5_pipeline *pipeline = &mdp5_cstate->pipeline; struct drm_device *dev = crtc->dev; struct mdp5_kms *mdp5_kms = get_kms(crtc); + struct platform_device *pdev = mdp5_kms->pdev; struct msm_kms *kms = &mdp5_kms->base.base; struct drm_gem_object *cursor_bo, *old_bo = NULL; uint32_t blendcfg, stride; @@ -753,7 +756,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, if (!handle) { DBG("Cursor off"); cursor_enable = false; - mdp5_enable(mdp5_kms); + pm_runtime_get_sync(&pdev->dev); goto set_cursor; } @@ -768,6 +771,8 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, lm = mdp5_cstate->pipeline.mixer->lm; stride = width * drm_format_plane_cpp(DRM_FORMAT_ARGB8888, 0); + pm_runtime_get_sync(&pdev->dev); + spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags); old_bo = mdp5_crtc->cursor.scanout_bo; @@ -777,8 +782,6 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, get_roi(crtc, &roi_w, &roi_h); - mdp5_enable(mdp5_kms); - mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_STRIDE(lm), stride); mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_FORMAT(lm), MDP5_LM_CURSOR_FORMAT_FORMAT(CURSOR_FMT_ARGB8888)); @@ -796,6 +799,8 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, spin_unlock_irqrestore(&mdp5_crtc->cursor.lock, flags); + pm_runtime_put_autosuspend(&pdev->dev); + set_cursor: ret = mdp5_ctl_set_cursor(ctl, pipeline, 0, cursor_enable); if (ret) { @@ -807,7 +812,7 @@ set_cursor: crtc_flush(crtc, flush_mask); end: - mdp5_disable(mdp5_kms); + pm_runtime_put_autosuspend(&pdev->dev); if (old_bo) { drm_flip_work_queue(&mdp5_crtc->unref_cursor_work, old_bo); /* enable vblank to complete cursor work: */ @@ -840,7 +845,7 @@ static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) get_roi(crtc, &roi_w, &roi_h); - mdp5_enable(mdp5_kms); + pm_runtime_get_sync(&mdp5_kms->pdev->dev); spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags); mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_SIZE(lm), @@ -853,7 +858,7 @@ static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) crtc_flush(crtc, flush_mask); - mdp5_disable(mdp5_kms); + pm_runtime_put_autosuspend(&mdp5_kms->pdev->dev); return 0; } diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c index 70bef51245af..0ca9e4033bb6 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c @@ -350,6 +350,7 @@ int mdp5_vid_encoder_set_split_display(struct drm_encoder *encoder, struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); struct mdp5_encoder *mdp5_slave_enc = to_mdp5_encoder(slave_encoder); struct mdp5_kms *mdp5_kms; + struct device *dev; int intf_num; u32 data = 0; @@ -369,8 +370,10 @@ int mdp5_vid_encoder_set_split_display(struct drm_encoder *encoder, else return -EINVAL; + dev = &mdp5_kms->pdev->dev; /* Make sure clocks are on when connectors calling this function. */ - mdp5_enable(mdp5_kms); + pm_runtime_get_sync(dev); + /* Dumb Panel, Sync mode */ mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_UPPER, 0); mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_LOWER, data); @@ -378,7 +381,7 @@ int mdp5_vid_encoder_set_split_display(struct drm_encoder *encoder, mdp5_ctl_pair(mdp5_encoder->ctl, mdp5_slave_enc->ctl, true); - mdp5_disable(mdp5_kms); + pm_runtime_put_autosuspend(dev); return 0; } diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c index 3ce8b9dec9c1..bb5deb00c899 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c @@ -49,16 +49,19 @@ static void mdp5_irq_error_handler(struct mdp_irq *irq, uint32_t irqstatus) void mdp5_irq_preinstall(struct msm_kms *kms) { struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); - mdp5_enable(mdp5_kms); + struct device *dev = &mdp5_kms->pdev->dev; + + pm_runtime_get_sync(dev); mdp5_write(mdp5_kms, REG_MDP5_INTR_CLEAR, 0xffffffff); mdp5_write(mdp5_kms, REG_MDP5_INTR_EN, 0x00000000); - mdp5_disable(mdp5_kms); + pm_runtime_put_autosuspend(dev); } int mdp5_irq_postinstall(struct msm_kms *kms) { struct mdp_kms *mdp_kms = to_mdp_kms(kms); struct mdp5_kms *mdp5_kms = to_mdp5_kms(mdp_kms); + struct device *dev = &mdp5_kms->pdev->dev; struct mdp_irq *error_handler = &mdp5_kms->error_handler; error_handler->irq = mdp5_irq_error_handler; @@ -67,9 +70,9 @@ int mdp5_irq_postinstall(struct msm_kms *kms) MDP5_IRQ_INTF2_UNDER_RUN | MDP5_IRQ_INTF3_UNDER_RUN; - mdp5_enable(mdp5_kms); + pm_runtime_get_sync(dev); mdp_irq_register(mdp_kms, error_handler); - mdp5_disable(mdp5_kms); + pm_runtime_put_autosuspend(dev); return 0; } @@ -77,9 +80,11 @@ int mdp5_irq_postinstall(struct msm_kms *kms) void mdp5_irq_uninstall(struct msm_kms *kms) { struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); - mdp5_enable(mdp5_kms); + struct device *dev = &mdp5_kms->pdev->dev; + + pm_runtime_get_sync(dev); mdp5_write(mdp5_kms, REG_MDP5_INTR_EN, 0x00000000); - mdp5_disable(mdp5_kms); + pm_runtime_put_autosuspend(dev); } irqreturn_t mdp5_irq(struct msm_kms *kms) @@ -109,11 +114,12 @@ irqreturn_t mdp5_irq(struct msm_kms *kms) int mdp5_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc) { struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); + struct device *dev = &mdp5_kms->pdev->dev; - mdp5_enable(mdp5_kms); + pm_runtime_get_sync(dev); mdp_update_vblank_mask(to_mdp_kms(kms), mdp5_crtc_vblank(crtc), true); - mdp5_disable(mdp5_kms); + pm_runtime_put_autosuspend(dev); return 0; } @@ -121,9 +127,10 @@ int mdp5_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc) void mdp5_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc) { struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); + struct device *dev = &mdp5_kms->pdev->dev; - mdp5_enable(mdp5_kms); + pm_runtime_get_sync(dev); mdp_update_vblank_mask(to_mdp_kms(kms), mdp5_crtc_vblank(crtc), false); - mdp5_disable(mdp5_kms); + pm_runtime_put_autosuspend(dev); } diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 1c603aef3c59..b0800bad8ac8 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c @@ -30,11 +30,10 @@ static const char *iommu_ports[] = { static int mdp5_hw_init(struct msm_kms *kms) { struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); - struct platform_device *pdev = mdp5_kms->pdev; + struct device *dev = &mdp5_kms->pdev->dev; unsigned long flags; - pm_runtime_get_sync(&pdev->dev); - mdp5_enable(mdp5_kms); + pm_runtime_get_sync(dev); /* Magic unknown register writes: * @@ -66,8 +65,7 @@ static int mdp5_hw_init(struct msm_kms *kms) mdp5_ctlm_hw_reset(mdp5_kms->ctlm); - mdp5_disable(mdp5_kms); - pm_runtime_put_sync(&pdev->dev); + pm_runtime_put_sync(dev); return 0; } @@ -111,8 +109,9 @@ static void mdp5_swap_state(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 device *dev = &mdp5_kms->pdev->dev; - mdp5_enable(mdp5_kms); + pm_runtime_get_sync(dev); if (mdp5_kms->smp) mdp5_smp_prepare_commit(mdp5_kms->smp, &mdp5_kms->state->smp); @@ -121,11 +120,12 @@ static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *st static void mdp5_complete_commit(struct msm_kms *kms, struct drm_atomic_state *state) { struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); + struct device *dev = &mdp5_kms->pdev->dev; if (mdp5_kms->smp) mdp5_smp_complete_commit(mdp5_kms->smp, &mdp5_kms->state->smp); - mdp5_disable(mdp5_kms); + pm_runtime_put_autosuspend(dev); } static void mdp5_wait_for_crtc_commit_done(struct msm_kms *kms, @@ -486,11 +486,12 @@ fail: static void read_mdp_hw_revision(struct mdp5_kms *mdp5_kms, u32 *major, u32 *minor) { + struct device *dev = &mdp5_kms->pdev->dev; u32 version; - mdp5_enable(mdp5_kms); + pm_runtime_get_sync(dev); version = mdp5_read(mdp5_kms, REG_MDP5_HW_VERSION); - mdp5_disable(mdp5_kms); + pm_runtime_put_autosuspend(dev); *major = FIELD(version, MDP5_HW_VERSION_MAJOR); *minor = FIELD(version, MDP5_HW_VERSION_MINOR); @@ -643,7 +644,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) * have left things on, in which case we'll start getting faults if * we don't disable): */ - mdp5_enable(mdp5_kms); + pm_runtime_get_sync(&pdev->dev); for (i = 0; i < MDP5_INTF_NUM_MAX; i++) { if (mdp5_cfg_intf_is_virtual(config->hw->intf.connect[i]) || !config->hw->intf.base[i]) @@ -652,7 +653,6 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) mdp5_write(mdp5_kms, REG_MDP5_INTF_FRAME_LINE_COUNT_EN(i), 0x3); } - mdp5_disable(mdp5_kms); mdelay(16); if (config->platform.iommu) { @@ -678,6 +678,8 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) aspace = NULL;; } + pm_runtime_put_autosuspend(&pdev->dev); + ret = modeset_init(mdp5_kms); if (ret) { dev_err(&pdev->dev, "modeset_init failed: %d\n", ret); @@ -1005,6 +1007,30 @@ static int mdp5_dev_remove(struct platform_device *pdev) return 0; } +static int mdp5_runtime_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct mdp5_kms *mdp5_kms = platform_get_drvdata(pdev); + + DBG(""); + + return mdp5_disable(mdp5_kms); +} + +static int mdp5_runtime_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct mdp5_kms *mdp5_kms = platform_get_drvdata(pdev); + + DBG(""); + + return mdp5_enable(mdp5_kms); +} + +static const struct dev_pm_ops mdp5_pm_ops = { + SET_RUNTIME_PM_OPS(mdp5_runtime_suspend, mdp5_runtime_resume, NULL) +}; + static const struct of_device_id mdp5_dt_match[] = { { .compatible = "qcom,mdp5", }, /* to support downstream DT files */ @@ -1019,6 +1045,7 @@ static struct platform_driver mdp5_driver = { .driver = { .name = "msm_mdp", .of_match_table = mdp5_dt_match, + .pm = &mdp5_pm_ops, }, }; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h index 17caa0e8c8ae..b42461cda22d 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h @@ -255,9 +255,6 @@ static inline uint32_t lm2ppdone(struct mdp5_hw_mixer *mixer) return MDP5_IRQ_PING_PONG_0_DONE << mixer->pp; } -int mdp5_disable(struct mdp5_kms *mdp5_kms); -int mdp5_enable(struct mdp5_kms *mdp5_kms); - void mdp5_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask, uint32_t old_irqmask); void mdp5_irq_preinstall(struct msm_kms *kms); |