Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit db97dd0e authored by Gerd Hoffmann's avatar Gerd Hoffmann
Browse files

drm/cirrus: add plane setup



Commit "f4bd542b 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: default avatarGerd Hoffmann <kraxel@redhat.com>
Reviewed-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/20190204110131.21467-1-kraxel@redhat.com
parent 1e55a53a
Loading
Loading
Loading
Loading
+69 −1
Original line number Diff line number Diff line
@@ -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;