From: Sean Paul <seanp...@chromium.org> drm core already tracks this, so we can just lean on that instead of tracking ourselves.
Signed-off-by: Sean Paul <seanp...@chromium.org> --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 9 ++- drivers/gpu/drm/msm/disp/mdp4/mdp4_irq.c | 10 +-- drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c | 4 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_irq.c | 10 +-- drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 12 +--- drivers/gpu/drm/msm/msm_drv.c | 79 +++++++++++++----------- drivers/gpu/drm/msm/msm_drv.h | 3 - 7 files changed, 62 insertions(+), 65 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 1969f0d07d865..3796a2978a40b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -497,6 +497,7 @@ static void _dpu_kms_setup_displays(struct drm_device *dev, static void _dpu_kms_drm_obj_destroy(struct dpu_kms *dpu_kms) { struct msm_drm_private *priv; + struct drm_crtc *crtc; int i; if (!dpu_kms) { @@ -511,9 +512,8 @@ static void _dpu_kms_drm_obj_destroy(struct dpu_kms *dpu_kms) } priv = dpu_kms->dev->dev_private; - for (i = 0; i < priv->num_crtcs; i++) - priv->crtcs[i]->funcs->destroy(priv->crtcs[i]); - priv->num_crtcs = 0; + drm_for_each_crtc(crtc, dpu_kms->dev) + crtc->funcs->destroy(crtc); for (i = 0; i < priv->num_planes; i++) priv->planes[i]->funcs->destroy(priv->planes[i]); @@ -598,12 +598,11 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms) ret = PTR_ERR(crtc); goto fail; } - priv->crtcs[priv->num_crtcs++] = crtc; } /* All CRTCs are compatible with all encoders */ for (i = 0; i < priv->num_encoders; i++) - priv->encoders[i]->possible_crtcs = (1 << priv->num_crtcs) - 1; + priv->encoders[i]->possible_crtcs = (1 << max_crtc_count) - 1; return 0; fail: diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_irq.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_irq.c index b764d7f103127..7c597d21c97ba 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_irq.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_irq.c @@ -15,6 +15,7 @@ * this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <drm/drm_crtc.h> #include <drm/drm_print.h> #include "msm_drv.h" @@ -79,8 +80,7 @@ irqreturn_t mdp4_irq(struct msm_kms *kms) struct mdp_kms *mdp_kms = to_mdp_kms(kms); struct mdp4_kms *mdp4_kms = to_mdp4_kms(mdp_kms); struct drm_device *dev = mdp4_kms->dev; - struct msm_drm_private *priv = dev->dev_private; - unsigned int id; + struct drm_crtc *crtc; uint32_t status, enable; enable = mdp4_read(mdp4_kms, REG_MDP4_INTR_ENABLE); @@ -91,9 +91,9 @@ irqreturn_t mdp4_irq(struct msm_kms *kms) mdp_dispatch_irqs(mdp_kms, status); - for (id = 0; id < priv->num_crtcs; id++) - if (status & mdp4_crtc_vblank(priv->crtcs[id])) - drm_handle_vblank(dev, id); + drm_for_each_crtc(crtc, dev) + if (status & mdp4_crtc_vblank(crtc)) + drm_handle_vblank(dev, drm_crtc_index(crtc)); return IRQ_HANDLED; } diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c index e437aa806f7be..f7f678c55e3ac 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c @@ -373,7 +373,7 @@ static int modeset_init(struct mdp4_kms *mdp4_kms) goto fail; } - crtc = mdp4_crtc_init(dev, plane, priv->num_crtcs, i, + crtc = mdp4_crtc_init(dev, plane, ARRAY_SIZE(mdp4_crtcs), i, mdp4_crtcs[i]); if (IS_ERR(crtc)) { DRM_DEV_ERROR(dev->dev, "failed to construct crtc for %s\n", @@ -381,8 +381,6 @@ static int modeset_init(struct mdp4_kms *mdp4_kms) ret = PTR_ERR(crtc); goto fail; } - - priv->crtcs[priv->num_crtcs++] = crtc; } /* diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_irq.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_irq.c index 280e368bc9bb8..c66a7fbd9b9c3 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_irq.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_irq.c @@ -17,6 +17,7 @@ #include <linux/irq.h> +#include <drm/drm_crtc.h> #include <drm/drm_print.h> #include "msm_drv.h" @@ -92,8 +93,7 @@ irqreturn_t mdp5_irq(struct msm_kms *kms) struct mdp_kms *mdp_kms = to_mdp_kms(kms); struct mdp5_kms *mdp5_kms = to_mdp5_kms(mdp_kms); struct drm_device *dev = mdp5_kms->dev; - struct msm_drm_private *priv = dev->dev_private; - unsigned int id; + struct drm_crtc *crtc; uint32_t status, enable; enable = mdp5_read(mdp5_kms, REG_MDP5_INTR_EN); @@ -104,9 +104,9 @@ irqreturn_t mdp5_irq(struct msm_kms *kms) mdp_dispatch_irqs(mdp_kms, status); - for (id = 0; id < priv->num_crtcs; id++) - if (status & mdp5_crtc_vblank(priv->crtcs[id])) - drm_handle_vblank(dev, id); + drm_for_each_crtc(crtc, dev) + if (status & mdp5_crtc_vblank(crtc)) + drm_handle_vblank(dev, drm_crtc_index(crtc)); return IRQ_HANDLED; } diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c index d27e35a217bd7..4fb70532b0484 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c @@ -520,7 +520,6 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) DRM_DEV_ERROR(dev->dev, "failed to construct crtc %d (%d)\n", i, ret); goto fail; } - priv->crtcs[priv->num_crtcs++] = crtc; } /* @@ -530,7 +529,7 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) for (i = 0; i < priv->num_encoders; i++) { struct drm_encoder *encoder = priv->encoders[i]; - encoder->possible_crtcs = (1 << priv->num_crtcs) - 1; + encoder->possible_crtcs = (1 << num_crtcs) - 1; } return 0; @@ -589,12 +588,11 @@ static bool mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode) { - struct msm_drm_private *priv = dev->dev_private; struct drm_crtc *crtc; struct drm_encoder *encoder; int line, vsw, vbp, vactive_start, vactive_end, vfp_end; - crtc = priv->crtcs[pipe]; + crtc = drm_crtc_from_index(dev, pipe); if (!crtc) { DRM_ERROR("Invalid crtc %d\n", pipe); return false; @@ -646,14 +644,10 @@ static bool mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, static u32 mdp5_get_vblank_counter(struct drm_device *dev, unsigned int pipe) { - struct msm_drm_private *priv = dev->dev_private; struct drm_crtc *crtc; struct drm_encoder *encoder; - if (pipe >= priv->num_crtcs) - return 0; - - crtc = priv->crtcs[pipe]; + crtc = drm_crtc_from_index(dev, pipe); if (!crtc) return 0; diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 81bfac744a555..dcc671eba24dc 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -224,15 +224,19 @@ static void vblank_ctrl_worker(struct kthread_work *work) spin_lock_irqsave(&vbl_ctrl->lock, flags); list_for_each_entry_safe(vbl_ev, tmp, &vbl_ctrl->event_list, node) { + struct drm_crtc *crtc = drm_crtc_from_index(priv->dev, + vbl_ev->crtc_id); + + if (WARN_ON(!crtc)) + continue; + list_del(&vbl_ev->node); spin_unlock_irqrestore(&vbl_ctrl->lock, flags); if (vbl_ev->enable) - kms->funcs->enable_vblank(kms, - priv->crtcs[vbl_ev->crtc_id]); + kms->funcs->enable_vblank(kms, crtc); else - kms->funcs->disable_vblank(kms, - priv->crtcs[vbl_ev->crtc_id]); + kms->funcs->disable_vblank(kms, crtc); kfree(vbl_ev); @@ -270,12 +274,12 @@ static int msm_drm_uninit(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct drm_device *ddev = platform_get_drvdata(pdev); + struct drm_crtc *crtc; struct msm_drm_private *priv = ddev->dev_private; struct msm_kms *kms = priv->kms; struct msm_mdss *mdss = priv->mdss; struct msm_vblank_ctrl *vbl_ctrl = &priv->vblank_ctrl; struct vblank_event *vbl_ev, *tmp; - int i; /* We must cancel and cleanup any pending vblank enable/disable * work before drm_irq_uninstall() to avoid work re-enabling an @@ -288,17 +292,18 @@ static int msm_drm_uninit(struct device *dev) } /* clean up display commit/event worker threads */ - for (i = 0; i < priv->num_crtcs; i++) { - if (priv->disp_thread[i].thread) { - kthread_flush_worker(&priv->disp_thread[i].worker); - kthread_stop(priv->disp_thread[i].thread); - priv->disp_thread[i].thread = NULL; + drm_for_each_crtc(crtc, ddev) { + unsigned int pipe = drm_crtc_index(crtc); + if (priv->disp_thread[pipe].thread) { + kthread_flush_worker(&priv->disp_thread[pipe].worker); + kthread_stop(priv->disp_thread[pipe].thread); + priv->disp_thread[pipe].thread = NULL; } - if (priv->event_thread[i].thread) { - kthread_flush_worker(&priv->event_thread[i].worker); - kthread_stop(priv->event_thread[i].thread); - priv->event_thread[i].thread = NULL; + if (priv->event_thread[pipe].thread) { + kthread_flush_worker(&priv->event_thread[pipe].worker); + kthread_stop(priv->event_thread[pipe].thread); + priv->event_thread[pipe].thread = NULL; } } @@ -438,10 +443,11 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) { struct platform_device *pdev = to_platform_device(dev); struct drm_device *ddev; + struct drm_crtc *crtc; struct msm_drm_private *priv; struct msm_kms *kms; struct msm_mdss *mdss; - int ret, i; + int ret; struct sched_param param; ddev = drm_dev_alloc(drv, dev); @@ -547,39 +553,42 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) * other real time and normal priority task */ param.sched_priority = 16; - for (i = 0; i < priv->num_crtcs; i++) { + drm_for_each_crtc(crtc, ddev) { + unsigned int pipe = drm_crtc_index(crtc); /* initialize display thread */ - priv->disp_thread[i].crtc_id = priv->crtcs[i]->base.id; - kthread_init_worker(&priv->disp_thread[i].worker); - priv->disp_thread[i].dev = ddev; - priv->disp_thread[i].thread = + priv->disp_thread[pipe].crtc_id = crtc->base.id; + kthread_init_worker(&priv->disp_thread[pipe].worker); + priv->disp_thread[pipe].dev = ddev; + priv->disp_thread[pipe].thread = kthread_run(kthread_worker_fn, - &priv->disp_thread[i].worker, - "crtc_commit:%d", priv->disp_thread[i].crtc_id); - if (IS_ERR(priv->disp_thread[i].thread)) { + &priv->disp_thread[pipe].worker, + "crtc_commit:%d", + priv->disp_thread[pipe].crtc_id); + if (IS_ERR(priv->disp_thread[pipe].thread)) { DRM_DEV_ERROR(dev, "failed to create crtc_commit kthread\n"); - priv->disp_thread[i].thread = NULL; + priv->disp_thread[pipe].thread = NULL; goto err_msm_uninit; } - ret = sched_setscheduler(priv->disp_thread[i].thread, + ret = sched_setscheduler(priv->disp_thread[pipe].thread, SCHED_FIFO, ¶m); if (ret) dev_warn(dev, "disp_thread set priority failed: %d\n", ret); /* initialize event thread */ - priv->event_thread[i].crtc_id = priv->crtcs[i]->base.id; - kthread_init_worker(&priv->event_thread[i].worker); - priv->event_thread[i].dev = ddev; - priv->event_thread[i].thread = + priv->event_thread[pipe].crtc_id = crtc->base.id; + kthread_init_worker(&priv->event_thread[pipe].worker); + priv->event_thread[pipe].dev = ddev; + priv->event_thread[pipe].thread = kthread_run(kthread_worker_fn, - &priv->event_thread[i].worker, - "crtc_event:%d", priv->event_thread[i].crtc_id); - if (IS_ERR(priv->event_thread[i].thread)) { + &priv->event_thread[pipe].worker, + "crtc_event:%d", + priv->event_thread[pipe].crtc_id); + if (IS_ERR(priv->event_thread[pipe].thread)) { DRM_DEV_ERROR(dev, "failed to create crtc_event kthread\n"); - priv->event_thread[i].thread = NULL; + priv->event_thread[pipe].thread = NULL; goto err_msm_uninit; } @@ -590,14 +599,14 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) * frame_pending counters beyond 2. This can lead to commit * failure at crtc commit level. */ - ret = sched_setscheduler(priv->event_thread[i].thread, + ret = sched_setscheduler(priv->event_thread[pipe].thread, SCHED_FIFO, ¶m); if (ret) dev_warn(dev, "event_thread set priority failed:%d\n", ret); } - ret = drm_vblank_init(ddev, priv->num_crtcs); + ret = drm_vblank_init(ddev, ddev->mode_config.num_crtc); if (ret < 0) { DRM_DEV_ERROR(dev, "failed to initialize vblank\n"); goto err_msm_uninit; diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 71a03ce21da53..fc677da06e33b 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -194,9 +194,6 @@ struct msm_drm_private { unsigned int num_planes; struct drm_plane *planes[MAX_PLANES]; - unsigned int num_crtcs; - struct drm_crtc *crtcs[MAX_CRTCS]; - struct msm_drm_thread disp_thread[MAX_CRTCS]; struct msm_drm_thread event_thread[MAX_CRTCS]; -- Sean Paul, Software Engineer, Google / Chromium OS _______________________________________________ Freedreno mailing list Freedreno@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/freedreno