@@ -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:
@@ -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;
}
@@ -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;
}
/*
@@ -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;
}
@@ -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;
@@ -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;
@@ -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];