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
This commit is contained in:
parent
1e55a53a28
commit
db97dd0eef
|
@ -360,10 +360,70 @@ static const struct drm_crtc_helper_funcs cirrus_helper_funcs = {
|
|||
};
|
||||
|
||||
/* CRTC setup */
|
||||
static const uint32_t cirrus_formats_16[] = {
|
||||
DRM_FORMAT_RGB565,
|
||||
};
|
||||
|
||||
static const uint32_t cirrus_formats_24[] = {
|
||||
DRM_FORMAT_RGB888,
|
||||
DRM_FORMAT_RGB565,
|
||||
};
|
||||
|
||||
static const uint32_t cirrus_formats_32[] = {
|
||||
DRM_FORMAT_XRGB8888,
|
||||
DRM_FORMAT_ARGB8888,
|
||||
DRM_FORMAT_RGB888,
|
||||
DRM_FORMAT_RGB565,
|
||||
};
|
||||
|
||||
static struct drm_plane *cirrus_primary_plane(struct drm_device *dev)
|
||||
{
|
||||
const uint32_t *formats;
|
||||
uint32_t nformats;
|
||||
struct drm_plane *primary;
|
||||
int ret;
|
||||
|
||||
switch (cirrus_bpp) {
|
||||
case 16:
|
||||
formats = cirrus_formats_16;
|
||||
nformats = ARRAY_SIZE(cirrus_formats_16);
|
||||
break;
|
||||
case 24:
|
||||
formats = cirrus_formats_24;
|
||||
nformats = ARRAY_SIZE(cirrus_formats_24);
|
||||
break;
|
||||
case 32:
|
||||
formats = cirrus_formats_32;
|
||||
nformats = ARRAY_SIZE(cirrus_formats_32);
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
primary = kzalloc(sizeof(*primary), GFP_KERNEL);
|
||||
if (primary == NULL) {
|
||||
DRM_DEBUG_KMS("Failed to allocate primary plane\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = drm_universal_plane_init(dev, primary, 0,
|
||||
&drm_primary_helper_funcs,
|
||||
formats, nformats,
|
||||
NULL,
|
||||
DRM_PLANE_TYPE_PRIMARY, NULL);
|
||||
if (ret) {
|
||||
kfree(primary);
|
||||
primary = NULL;
|
||||
}
|
||||
|
||||
return primary;
|
||||
}
|
||||
|
||||
static void cirrus_crtc_init(struct drm_device *dev)
|
||||
{
|
||||
struct cirrus_device *cdev = dev->dev_private;
|
||||
struct cirrus_crtc *cirrus_crtc;
|
||||
struct drm_plane *primary;
|
||||
|
||||
cirrus_crtc = kzalloc(sizeof(struct cirrus_crtc) +
|
||||
(CIRRUSFB_CONN_LIMIT * sizeof(struct drm_connector *)),
|
||||
|
@ -372,7 +432,15 @@ static void cirrus_crtc_init(struct drm_device *dev)
|
|||
if (cirrus_crtc == NULL)
|
||||
return;
|
||||
|
||||
drm_crtc_init(dev, &cirrus_crtc->base, &cirrus_crtc_funcs);
|
||||
primary = cirrus_primary_plane(dev);
|
||||
if (primary == NULL) {
|
||||
kfree(cirrus_crtc);
|
||||
return;
|
||||
}
|
||||
|
||||
drm_crtc_init_with_planes(dev, &cirrus_crtc->base,
|
||||
primary, NULL,
|
||||
&cirrus_crtc_funcs, NULL);
|
||||
|
||||
drm_mode_crtc_set_gamma_size(&cirrus_crtc->base, CIRRUS_LUT_SIZE);
|
||||
cdev->mode_info.crtc = cirrus_crtc;
|
||||
|
|
Loading…
Reference in New Issue