diff options
author | Philipp Zabel <p.zabel@pengutronix.de> | 2015-11-06 05:08:02 -0500 |
---|---|---|
committer | Philipp Zabel <p.zabel@pengutronix.de> | 2015-11-19 06:51:38 -0500 |
commit | 4389559980599ad99f39a004d6e9aaf9c2180ab8 (patch) | |
tree | 308a567f4b4f1534d1cc1611112a655b5ae85c11 | |
parent | 8005c49d9aea74d382f474ce11afbbc7d7130bec (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.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/imx/imx-drm.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/imx/ipuv3-crtc.c | 22 | ||||
-rw-r--r-- | drivers/gpu/drm/imx/ipuv3-plane.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/imx/ipuv3-plane.h | 2 |
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 | */ |
342 | int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc, | 342 | int 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; | |||
9 | struct drm_encoder; | 9 | struct drm_encoder; |
10 | struct drm_fbdev_cma; | 10 | struct drm_fbdev_cma; |
11 | struct drm_framebuffer; | 11 | struct drm_framebuffer; |
12 | struct drm_plane; | ||
12 | struct imx_drm_crtc; | 13 | struct imx_drm_crtc; |
13 | struct platform_device; | 14 | struct platform_device; |
14 | 15 | ||
@@ -24,7 +25,7 @@ struct imx_drm_crtc_helper_funcs { | |||
24 | }; | 25 | }; |
25 | 26 | ||
26 | int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc, | 27 | int 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); |
30 | int imx_drm_remove_crtc(struct imx_drm_crtc *); | 31 | int 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 | ||
382 | struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu, | 382 | struct 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 | ||
35 | struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu, | 35 | struct 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 */ |
40 | int ipu_plane_mode_set(struct ipu_plane *plane, struct drm_crtc *crtc, | 40 | int ipu_plane_mode_set(struct ipu_plane *plane, struct drm_crtc *crtc, |