Commit 41137443 authored by Thomas Zimmermann's avatar Thomas Zimmermann
Browse files

drm/ofdrm: Add CRTC state



Add a dedicated CRTC state to ofdrm to later store information for
palette updates.

v3:
	* rework CRTC state helpers (Javier)

Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: default avatarJavier Martinez Canillas <javierm@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20221011150712.3928-3-tzimmermann@suse.de
parent c8a17756
Loading
Loading
Loading
Loading
+56 −3
Original line number Diff line number Diff line
@@ -278,6 +278,21 @@ static struct resource *ofdrm_find_fb_resource(struct ofdrm_device *odev,
 * Modesetting
 */

struct ofdrm_crtc_state {
	struct drm_crtc_state base;
};

static struct ofdrm_crtc_state *to_ofdrm_crtc_state(struct drm_crtc_state *base)
{
	return container_of(base, struct ofdrm_crtc_state, base);
}

static void ofdrm_crtc_state_destroy(struct ofdrm_crtc_state *ofdrm_crtc_state)
{
	__drm_atomic_helper_crtc_destroy_state(&ofdrm_crtc_state->base);
	kfree(ofdrm_crtc_state);
}

/*
 * Support all formats of OF display and maybe more; in order
 * of preference. The display's update function will do any
@@ -431,13 +446,51 @@ static const struct drm_crtc_helper_funcs ofdrm_crtc_helper_funcs = {
	.atomic_check = ofdrm_crtc_helper_atomic_check,
};

static void ofdrm_crtc_reset(struct drm_crtc *crtc)
{
	struct ofdrm_crtc_state *ofdrm_crtc_state =
		kzalloc(sizeof(*ofdrm_crtc_state), GFP_KERNEL);

	if (crtc->state)
		ofdrm_crtc_state_destroy(to_ofdrm_crtc_state(crtc->state));

	if (ofdrm_crtc_state)
		__drm_atomic_helper_crtc_reset(crtc, &ofdrm_crtc_state->base);
	else
		__drm_atomic_helper_crtc_reset(crtc, NULL);
}

static struct drm_crtc_state *ofdrm_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
{
	struct drm_device *dev = crtc->dev;
	struct drm_crtc_state *crtc_state = crtc->state;
	struct ofdrm_crtc_state *new_ofdrm_crtc_state;

	if (drm_WARN_ON(dev, !crtc_state))
		return NULL;

	new_ofdrm_crtc_state = kzalloc(sizeof(*new_ofdrm_crtc_state), GFP_KERNEL);
	if (!new_ofdrm_crtc_state)
		return NULL;

	__drm_atomic_helper_crtc_duplicate_state(crtc, &new_ofdrm_crtc_state->base);

	return &new_ofdrm_crtc_state->base;
}

static void ofdrm_crtc_atomic_destroy_state(struct drm_crtc *crtc,
					    struct drm_crtc_state *crtc_state)
{
	ofdrm_crtc_state_destroy(to_ofdrm_crtc_state(crtc_state));
}

static const struct drm_crtc_funcs ofdrm_crtc_funcs = {
	.reset = drm_atomic_helper_crtc_reset,
	.reset = ofdrm_crtc_reset,
	.destroy = drm_crtc_cleanup,
	.set_config = drm_atomic_helper_set_config,
	.page_flip = drm_atomic_helper_page_flip,
	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
	.atomic_duplicate_state = ofdrm_crtc_atomic_duplicate_state,
	.atomic_destroy_state = ofdrm_crtc_atomic_destroy_state,
};

static int ofdrm_connector_helper_get_modes(struct drm_connector *connector)