Skip to content

Commit 4389559

Browse files
committed
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>
1 parent 8005c49 commit 4389559

5 files changed

Lines changed: 20 additions & 20 deletions

File tree

drivers/gpu/drm/imx/imx-drm-core.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags)
340340
* imx_drm_add_crtc - add a new crtc
341341
*/
342342
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,
344344
const struct imx_drm_crtc_helper_funcs *imx_drm_helper_funcs,
345345
struct device_node *port)
346346
{
@@ -379,7 +379,7 @@ int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
379379
drm_crtc_helper_add(crtc,
380380
imx_drm_crtc->imx_drm_helper_funcs.crtc_helper_funcs);
381381

382-
drm_crtc_init(drm, crtc,
382+
drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL,
383383
imx_drm_crtc->imx_drm_helper_funcs.crtc_funcs);
384384

385385
return 0;

drivers/gpu/drm/imx/imx-drm.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ struct drm_display_mode;
99
struct drm_encoder;
1010
struct drm_fbdev_cma;
1111
struct drm_framebuffer;
12+
struct drm_plane;
1213
struct imx_drm_crtc;
1314
struct platform_device;
1415

@@ -24,7 +25,7 @@ struct imx_drm_crtc_helper_funcs {
2425
};
2526

2627
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,
2829
const struct imx_drm_crtc_helper_funcs *imx_helper_funcs,
2930
struct device_node *port);
3031
int imx_drm_remove_crtc(struct imx_drm_crtc *);

drivers/gpu/drm/imx/ipuv3-crtc.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,6 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
349349
struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
350350
int dp = -EINVAL;
351351
int ret;
352-
int id;
353352

354353
ret = ipu_get_resources(ipu_crtc, pdata);
355354
if (ret) {
@@ -358,18 +357,19 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
358357
return ret;
359358
}
360359

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+
361365
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);
363368
if (ret) {
364369
dev_err(ipu_crtc->dev, "adding crtc failed with %d.\n", ret);
365370
goto err_put_resources;
366371
}
367372

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);
373373
ret = ipu_plane_get_resources(ipu_crtc->plane[0]);
374374
if (ret) {
375375
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,
379379

380380
/* If this crtc is using the DP, add an overlay plane */
381381
if (pdata->dp >= 0 && pdata->dma[1] > 0) {
382-
ipu_crtc->plane[1] = ipu_plane_init(ipu_crtc->base.dev, ipu,
383-
pdata->dma[1],
384-
IPU_DP_FLOW_SYNC_FG,
385-
BIT(id), false);
382+
ipu_crtc->plane[1] = ipu_plane_init(drm, ipu, pdata->dma[1],
383+
IPU_DP_FLOW_SYNC_FG,
384+
drm_crtc_mask(&ipu_crtc->base),
385+
DRM_PLANE_TYPE_OVERLAY);
386386
if (IS_ERR(ipu_crtc->plane[1]))
387387
ipu_crtc->plane[1] = NULL;
388388
}

drivers/gpu/drm/imx/ipuv3-plane.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ static struct drm_plane_funcs ipu_plane_funcs = {
381381

382382
struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
383383
int dma, int dp, unsigned int possible_crtcs,
384-
bool priv)
384+
enum drm_plane_type type)
385385
{
386386
struct ipu_plane *ipu_plane;
387387
int ret;
@@ -399,10 +399,9 @@ struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
399399
ipu_plane->dma = dma;
400400
ipu_plane->dp_flow = dp;
401401

402-
ret = drm_plane_init(dev, &ipu_plane->base, possible_crtcs,
403-
&ipu_plane_funcs, ipu_plane_formats,
404-
ARRAY_SIZE(ipu_plane_formats),
405-
priv);
402+
ret = drm_universal_plane_init(dev, &ipu_plane->base, possible_crtcs,
403+
&ipu_plane_funcs, ipu_plane_formats,
404+
ARRAY_SIZE(ipu_plane_formats), type);
406405
if (ret) {
407406
DRM_ERROR("failed to initialize plane\n");
408407
kfree(ipu_plane);

drivers/gpu/drm/imx/ipuv3-plane.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ struct ipu_plane {
3434

3535
struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
3636
int dma, int dp, unsigned int possible_crtcs,
37-
bool priv);
37+
enum drm_plane_type type);
3838

3939
/* Init IDMAC, DMFC, DP */
4040
int ipu_plane_mode_set(struct ipu_plane *plane, struct drm_crtc *crtc,

0 commit comments

Comments
 (0)