Skip to content

Commit db97dd0

Browse files
committed
drm/cirrus: add plane setup
Commit "f4bd542bca drm/fb-helper: Scale back depth to supported maximum" uncovered a bug in the cirrus driver. It must create its own primary plane, using the correct format list, depending on the bpp module parameter, so it is consistent with mode_config->preferred_depth. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/20190204110131.21467-1-kraxel@redhat.com
1 parent 1e55a53 commit db97dd0

File tree

1 file changed

+69
-1
lines changed

1 file changed

+69
-1
lines changed

drivers/gpu/drm/cirrus/cirrus_mode.c

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,10 +360,70 @@ static const struct drm_crtc_helper_funcs cirrus_helper_funcs = {
360360
};
361361

362362
/* CRTC setup */
363+
static const uint32_t cirrus_formats_16[] = {
364+
DRM_FORMAT_RGB565,
365+
};
366+
367+
static const uint32_t cirrus_formats_24[] = {
368+
DRM_FORMAT_RGB888,
369+
DRM_FORMAT_RGB565,
370+
};
371+
372+
static const uint32_t cirrus_formats_32[] = {
373+
DRM_FORMAT_XRGB8888,
374+
DRM_FORMAT_ARGB8888,
375+
DRM_FORMAT_RGB888,
376+
DRM_FORMAT_RGB565,
377+
};
378+
379+
static struct drm_plane *cirrus_primary_plane(struct drm_device *dev)
380+
{
381+
const uint32_t *formats;
382+
uint32_t nformats;
383+
struct drm_plane *primary;
384+
int ret;
385+
386+
switch (cirrus_bpp) {
387+
case 16:
388+
formats = cirrus_formats_16;
389+
nformats = ARRAY_SIZE(cirrus_formats_16);
390+
break;
391+
case 24:
392+
formats = cirrus_formats_24;
393+
nformats = ARRAY_SIZE(cirrus_formats_24);
394+
break;
395+
case 32:
396+
formats = cirrus_formats_32;
397+
nformats = ARRAY_SIZE(cirrus_formats_32);
398+
break;
399+
default:
400+
return NULL;
401+
}
402+
403+
primary = kzalloc(sizeof(*primary), GFP_KERNEL);
404+
if (primary == NULL) {
405+
DRM_DEBUG_KMS("Failed to allocate primary plane\n");
406+
return NULL;
407+
}
408+
409+
ret = drm_universal_plane_init(dev, primary, 0,
410+
&drm_primary_helper_funcs,
411+
formats, nformats,
412+
NULL,
413+
DRM_PLANE_TYPE_PRIMARY, NULL);
414+
if (ret) {
415+
kfree(primary);
416+
primary = NULL;
417+
}
418+
419+
return primary;
420+
}
421+
363422
static void cirrus_crtc_init(struct drm_device *dev)
364423
{
365424
struct cirrus_device *cdev = dev->dev_private;
366425
struct cirrus_crtc *cirrus_crtc;
426+
struct drm_plane *primary;
367427

368428
cirrus_crtc = kzalloc(sizeof(struct cirrus_crtc) +
369429
(CIRRUSFB_CONN_LIMIT * sizeof(struct drm_connector *)),
@@ -372,7 +432,15 @@ static void cirrus_crtc_init(struct drm_device *dev)
372432
if (cirrus_crtc == NULL)
373433
return;
374434

375-
drm_crtc_init(dev, &cirrus_crtc->base, &cirrus_crtc_funcs);
435+
primary = cirrus_primary_plane(dev);
436+
if (primary == NULL) {
437+
kfree(cirrus_crtc);
438+
return;
439+
}
440+
441+
drm_crtc_init_with_planes(dev, &cirrus_crtc->base,
442+
primary, NULL,
443+
&cirrus_crtc_funcs, NULL);
376444

377445
drm_mode_crtc_set_gamma_size(&cirrus_crtc->base, CIRRUS_LUT_SIZE);
378446
cdev->mode_info.crtc = cirrus_crtc;

0 commit comments

Comments
 (0)