aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Zabel <p.zabel@pengutronix.de>2015-11-06 05:08:02 -0500
committerPhilipp Zabel <p.zabel@pengutronix.de>2015-11-19 06:51:38 -0500
commit4389559980599ad99f39a004d6e9aaf9c2180ab8 (patch)
tree308a567f4b4f1534d1cc1611112a655b5ae85c11
parent8005c49d9aea74d382f474ce11afbbc7d7130bec (diff)
drm/imx: switch to universal planes
Use drm_universal_plane_init to create the planes, create the primary plane first and use drm_crtc_init_with_planes to associate it with the crtc. This gets rid of the unused fallback primary plane previously created by drm_crtc_init and fixes a NULL pointer dereference issue that can be triggered by a modeset from userspace when fbdev helpers are enabled [1]. [1] https://lkml.org/lkml/2015/11/4/107 Reported-by: Liu Ying <Ying.Liu@freescale.com> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> Acked-by: Liu Ying <Ying.Liu@freescale.com>
-rw-r--r--drivers/gpu/drm/imx/imx-drm-core.c4
-rw-r--r--drivers/gpu/drm/imx/imx-drm.h3
-rw-r--r--drivers/gpu/drm/imx/ipuv3-crtc.c22
-rw-r--r--drivers/gpu/drm/imx/ipuv3-plane.c9
-rw-r--r--drivers/gpu/drm/imx/ipuv3-plane.h2
5 files changed, 20 insertions, 20 deletions
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
index 64f16ea779ef..7b00ab8084a8 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -340,7 +340,7 @@ err_kms:
340 * imx_drm_add_crtc - add a new crtc 340 * imx_drm_add_crtc - add a new crtc
341 */ 341 */
342int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc, 342int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
343 struct imx_drm_crtc **new_crtc, 343 struct imx_drm_crtc **new_crtc, struct drm_plane *primary_plane,
344 const struct imx_drm_crtc_helper_funcs *imx_drm_helper_funcs, 344 const struct imx_drm_crtc_helper_funcs *imx_drm_helper_funcs,
345 struct device_node *port) 345 struct device_node *port)
346{ 346{
@@ -379,7 +379,7 @@ int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
379 drm_crtc_helper_add(crtc, 379 drm_crtc_helper_add(crtc,
380 imx_drm_crtc->imx_drm_helper_funcs.crtc_helper_funcs); 380 imx_drm_crtc->imx_drm_helper_funcs.crtc_helper_funcs);
381 381
382 drm_crtc_init(drm, crtc, 382 drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL,
383 imx_drm_crtc->imx_drm_helper_funcs.crtc_funcs); 383 imx_drm_crtc->imx_drm_helper_funcs.crtc_funcs);
384 384
385 return 0; 385 return 0;
diff --git a/drivers/gpu/drm/imx/imx-drm.h b/drivers/gpu/drm/imx/imx-drm.h
index 28e776d8d9d2..83284b4d4be1 100644
--- a/drivers/gpu/drm/imx/imx-drm.h
+++ b/drivers/gpu/drm/imx/imx-drm.h
@@ -9,6 +9,7 @@ struct drm_display_mode;
9struct drm_encoder; 9struct drm_encoder;
10struct drm_fbdev_cma; 10struct drm_fbdev_cma;
11struct drm_framebuffer; 11struct drm_framebuffer;
12struct drm_plane;
12struct imx_drm_crtc; 13struct imx_drm_crtc;
13struct platform_device; 14struct platform_device;
14 15
@@ -24,7 +25,7 @@ struct imx_drm_crtc_helper_funcs {
24}; 25};
25 26
26int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc, 27int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
27 struct imx_drm_crtc **new_crtc, 28 struct imx_drm_crtc **new_crtc, struct drm_plane *primary_plane,
28 const struct imx_drm_crtc_helper_funcs *imx_helper_funcs, 29 const struct imx_drm_crtc_helper_funcs *imx_helper_funcs,
29 struct device_node *port); 30 struct device_node *port);
30int imx_drm_remove_crtc(struct imx_drm_crtc *); 31int imx_drm_remove_crtc(struct imx_drm_crtc *);
diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c
index 7bc8301fafff..f11284d06538 100644
--- a/drivers/gpu/drm/imx/ipuv3-crtc.c
+++ b/drivers/gpu/drm/imx/ipuv3-crtc.c
@@ -349,7 +349,6 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
349 struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); 349 struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
350 int dp = -EINVAL; 350 int dp = -EINVAL;
351 int ret; 351 int ret;
352 int id;
353 352
354 ret = ipu_get_resources(ipu_crtc, pdata); 353 ret = ipu_get_resources(ipu_crtc, pdata);
355 if (ret) { 354 if (ret) {
@@ -358,18 +357,19 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
358 return ret; 357 return ret;
359 } 358 }
360 359
360 if (pdata->dp >= 0)
361 dp = IPU_DP_FLOW_SYNC_BG;
362 ipu_crtc->plane[0] = ipu_plane_init(drm, ipu, pdata->dma[0], dp, 0,
363 DRM_PLANE_TYPE_PRIMARY);
364
361 ret = imx_drm_add_crtc(drm, &ipu_crtc->base, &ipu_crtc->imx_crtc, 365 ret = imx_drm_add_crtc(drm, &ipu_crtc->base, &ipu_crtc->imx_crtc,
362 &ipu_crtc_helper_funcs, ipu_crtc->dev->of_node); 366 &ipu_crtc->plane[0]->base, &ipu_crtc_helper_funcs,
367 ipu_crtc->dev->of_node);
363 if (ret) { 368 if (ret) {
364 dev_err(ipu_crtc->dev, "adding crtc failed with %d.\n", ret); 369 dev_err(ipu_crtc->dev, "adding crtc failed with %d.\n", ret);
365 goto err_put_resources; 370 goto err_put_resources;
366 } 371 }
367 372
368 if (pdata->dp >= 0)
369 dp = IPU_DP_FLOW_SYNC_BG;
370 id = imx_drm_crtc_id(ipu_crtc->imx_crtc);
371 ipu_crtc->plane[0] = ipu_plane_init(ipu_crtc->base.dev, ipu,
372 pdata->dma[0], dp, BIT(id), true);
373 ret = ipu_plane_get_resources(ipu_crtc->plane[0]); 373 ret = ipu_plane_get_resources(ipu_crtc->plane[0]);
374 if (ret) { 374 if (ret) {
375 dev_err(ipu_crtc->dev, "getting plane 0 resources failed with %d.\n", 375 dev_err(ipu_crtc->dev, "getting plane 0 resources failed with %d.\n",
@@ -379,10 +379,10 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
379 379
380 /* If this crtc is using the DP, add an overlay plane */ 380 /* If this crtc is using the DP, add an overlay plane */
381 if (pdata->dp >= 0 && pdata->dma[1] > 0) { 381 if (pdata->dp >= 0 && pdata->dma[1] > 0) {
382 ipu_crtc->plane[1] = ipu_plane_init(ipu_crtc->base.dev, ipu, 382 ipu_crtc->plane[1] = ipu_plane_init(drm, ipu, pdata->dma[1],
383 pdata->dma[1], 383 IPU_DP_FLOW_SYNC_FG,
384 IPU_DP_FLOW_SYNC_FG, 384 drm_crtc_mask(&ipu_crtc->base),
385 BIT(id), false); 385 DRM_PLANE_TYPE_OVERLAY);
386 if (IS_ERR(ipu_crtc->plane[1])) 386 if (IS_ERR(ipu_crtc->plane[1]))
387 ipu_crtc->plane[1] = NULL; 387 ipu_crtc->plane[1] = NULL;
388 } 388 }
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c
index 575f4c84388f..e2ff410bab74 100644
--- a/drivers/gpu/drm/imx/ipuv3-plane.c
+++ b/drivers/gpu/drm/imx/ipuv3-plane.c
@@ -381,7 +381,7 @@ static struct drm_plane_funcs ipu_plane_funcs = {
381 381
382struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu, 382struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
383 int dma, int dp, unsigned int possible_crtcs, 383 int dma, int dp, unsigned int possible_crtcs,
384 bool priv) 384 enum drm_plane_type type)
385{ 385{
386 struct ipu_plane *ipu_plane; 386 struct ipu_plane *ipu_plane;
387 int ret; 387 int ret;
@@ -399,10 +399,9 @@ struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
399 ipu_plane->dma = dma; 399 ipu_plane->dma = dma;
400 ipu_plane->dp_flow = dp; 400 ipu_plane->dp_flow = dp;
401 401
402 ret = drm_plane_init(dev, &ipu_plane->base, possible_crtcs, 402 ret = drm_universal_plane_init(dev, &ipu_plane->base, possible_crtcs,
403 &ipu_plane_funcs, ipu_plane_formats, 403 &ipu_plane_funcs, ipu_plane_formats,
404 ARRAY_SIZE(ipu_plane_formats), 404 ARRAY_SIZE(ipu_plane_formats), type);
405 priv);
406 if (ret) { 405 if (ret) {
407 DRM_ERROR("failed to initialize plane\n"); 406 DRM_ERROR("failed to initialize plane\n");
408 kfree(ipu_plane); 407 kfree(ipu_plane);
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.h b/drivers/gpu/drm/imx/ipuv3-plane.h
index 9b5eff18f5b8..3a443b413c60 100644
--- a/drivers/gpu/drm/imx/ipuv3-plane.h
+++ b/drivers/gpu/drm/imx/ipuv3-plane.h
@@ -34,7 +34,7 @@ struct ipu_plane {
34 34
35struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu, 35struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
36 int dma, int dp, unsigned int possible_crtcs, 36 int dma, int dp, unsigned int possible_crtcs,
37 bool priv); 37 enum drm_plane_type type);
38 38
39/* Init IDMAC, DMFC, DP */ 39/* Init IDMAC, DMFC, DP */
40int ipu_plane_mode_set(struct ipu_plane *plane, struct drm_crtc *crtc, 40int ipu_plane_mode_set(struct ipu_plane *plane, struct drm_crtc *crtc,