Unverified Commit dcda7c28 authored by Maxime Ripard's avatar Maxime Ripard
Browse files

drm/vc4: kms: Add functions to create the state objects



In order to make the vc4_kms_load code and error path a bit easier to
read and extend, add functions to create state objects, and use managed
actions to cleanup if needed.

Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
Acked-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20201029190104.2181730-6-maxime@cerno.tech
parent 84d7d472
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -324,9 +324,6 @@ static void vc4_drm_unbind(struct device *dev)
	drm_dev_unregister(drm);

	drm_atomic_helper_shutdown(drm);

	drm_atomic_private_obj_fini(&vc4->load_tracker);
	drm_atomic_private_obj_fini(&vc4->ctm_manager);
}

static const struct component_master_ops vc4_drm_ops = {
+57 −21
Original line number Diff line number Diff line
@@ -93,6 +93,29 @@ static const struct drm_private_state_funcs vc4_ctm_state_funcs = {
	.atomic_destroy_state = vc4_ctm_destroy_state,
};

static void vc4_ctm_obj_fini(struct drm_device *dev, void *unused)
{
	struct vc4_dev *vc4 = to_vc4_dev(dev);

	drm_atomic_private_obj_fini(&vc4->ctm_manager);
}

static int vc4_ctm_obj_init(struct vc4_dev *vc4)
{
	struct vc4_ctm_state *ctm_state;

	drm_modeset_lock_init(&vc4->ctm_state_lock);

	ctm_state = kzalloc(sizeof(*ctm_state), GFP_KERNEL);
	if (!ctm_state)
		return -ENOMEM;

	drm_atomic_private_obj_init(&vc4->base, &vc4->ctm_manager, &ctm_state->base,
				    &vc4_ctm_state_funcs);

	return drmm_add_action(&vc4->base, vc4_ctm_obj_fini, NULL);
}

/* Converts a DRM S31.32 value to the HW S0.9 format. */
static u16 vc4_ctm_s31_32_to_s0_9(u64 in)
{
@@ -609,6 +632,34 @@ static const struct drm_private_state_funcs vc4_load_tracker_state_funcs = {
	.atomic_destroy_state = vc4_load_tracker_destroy_state,
};

static void vc4_load_tracker_obj_fini(struct drm_device *dev, void *unused)
{
	struct vc4_dev *vc4 = to_vc4_dev(dev);

	if (!vc4->load_tracker_available)
		return;

	drm_atomic_private_obj_fini(&vc4->load_tracker);
}

static int vc4_load_tracker_obj_init(struct vc4_dev *vc4)
{
	struct vc4_load_tracker_state *load_state;

	if (!vc4->load_tracker_available)
		return 0;

	load_state = kzalloc(sizeof(*load_state), GFP_KERNEL);
	if (!load_state)
		return -ENOMEM;

	drm_atomic_private_obj_init(&vc4->base, &vc4->load_tracker,
				    &load_state->base,
				    &vc4_load_tracker_state_funcs);

	return drmm_add_action(&vc4->base, vc4_load_tracker_obj_fini, NULL);
}

#define NUM_OUTPUTS  6
#define NUM_CHANNELS 3

@@ -711,8 +762,6 @@ static const struct drm_mode_config_funcs vc4_mode_funcs = {
int vc4_kms_load(struct drm_device *dev)
{
	struct vc4_dev *vc4 = to_vc4_dev(dev);
	struct vc4_ctm_state *ctm_state;
	struct vc4_load_tracker_state *load_state;
	bool is_vc5 = of_device_is_compatible(dev->dev->of_node,
					      "brcm,bcm2711-vc5");
	int ret;
@@ -751,26 +800,13 @@ int vc4_kms_load(struct drm_device *dev)
	dev->mode_config.async_page_flip = true;
	dev->mode_config.allow_fb_modifiers = true;

	drm_modeset_lock_init(&vc4->ctm_state_lock);

	ctm_state = kzalloc(sizeof(*ctm_state), GFP_KERNEL);
	if (!ctm_state)
		return -ENOMEM;

	drm_atomic_private_obj_init(dev, &vc4->ctm_manager, &ctm_state->base,
				    &vc4_ctm_state_funcs);

	if (vc4->load_tracker_available) {
		load_state = kzalloc(sizeof(*load_state), GFP_KERNEL);
		if (!load_state) {
			drm_atomic_private_obj_fini(&vc4->ctm_manager);
			return -ENOMEM;
		}
	ret = vc4_ctm_obj_init(vc4);
	if (ret)
		return ret;

		drm_atomic_private_obj_init(dev, &vc4->load_tracker,
					    &load_state->base,
					    &vc4_load_tracker_state_funcs);
	}
	ret = vc4_load_tracker_obj_init(vc4);
	if (ret)
		return ret;

	drm_mode_config_reset(dev);