// SPDX-License-Identifier: MIT

#include <drm/drm_client.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_drv.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_print.h>

#include "drm_client_internal.h"

/*
 * struct drm_client_funcs
 */

static void drm_fbdev_client_free(struct drm_client_dev *client)
{
	struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);

	drm_fb_helper_unprepare(fb_helper);
	kfree(fb_helper);
}

static void drm_fbdev_client_unregister(struct drm_client_dev *client)
{
	struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);

	if (fb_helper->info) {
		/*
		 * Fully probed framebuffer device
		 */
		drm_fb_helper_unregister_info(fb_helper);
	} else {
		/*
		 * Partially initialized client, no framebuffer device yet
		 */
		drm_client_release(&fb_helper->client);
	}
}

static int drm_fbdev_client_restore(struct drm_client_dev *client, bool force)
{
	struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);

	drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper, force);

	return 0;
}

static int drm_fbdev_client_hotplug(struct drm_client_dev *client)
{
	struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
	struct drm_device *dev = client->dev;
	int ret;

	if (dev->fb_helper)
		return drm_fb_helper_hotplug_event(dev->fb_helper);

	ret = drm_fb_helper_init(dev, fb_helper);
	if (ret)
		goto err_drm_err;

	if (!drm_drv_uses_atomic_modeset(dev))
		drm_helper_disable_unused_functions(dev);

	ret = drm_fb_helper_initial_config(fb_helper);
	if (ret)
		goto err_drm_fb_helper_fini;

	return 0;

err_drm_fb_helper_fini:
	drm_fb_helper_fini(fb_helper);
err_drm_err:
	drm_err(dev, "fbdev: Failed to setup emulation (ret=%d)\n", ret);
	return ret;
}

static int drm_fbdev_client_suspend(struct drm_client_dev *client)
{
	struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);

	drm_fb_helper_set_suspend_unlocked(fb_helper, true);

	return 0;
}

static int drm_fbdev_client_resume(struct drm_client_dev *client)
{
	struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);

	drm_fb_helper_set_suspend_unlocked(fb_helper, false);

	return 0;
}

static const struct drm_client_funcs drm_fbdev_client_funcs = {
	.owner		= THIS_MODULE,
	.free		= drm_fbdev_client_free,
	.unregister	= drm_fbdev_client_unregister,
	.restore	= drm_fbdev_client_restore,
	.hotplug	= drm_fbdev_client_hotplug,
	.suspend	= drm_fbdev_client_suspend,
	.resume		= drm_fbdev_client_resume,
};

/**
 * drm_fbdev_client_setup() - Setup fbdev emulation
 * @dev: DRM device
 * @format: Preferred color format for the device. DRM_FORMAT_XRGB8888
 *          is used if this is zero.
 *
 * This function sets up fbdev emulation. Restore, hotplug events and
 * teardown are all taken care of. Drivers that do suspend/resume need
 * to call drm_client_dev_suspend() and drm_client_dev_resume() by
 * themselves. Simple drivers might use drm_mode_config_helper_suspend().
 *
 * This function is safe to call even when there are no connectors present.
 * Setup will be retried on the next hotplug event.
 *
 * The fbdev client is destroyed by drm_dev_unregister().
 *
 * Returns:
 * 0 on success, or a negative errno code otherwise.
 */
int drm_fbdev_client_setup(struct drm_device *dev, const struct drm_format_info *format)
{
	struct drm_fb_helper *fb_helper;
	unsigned int color_mode;
	int ret;

	/* TODO: Use format info throughout DRM */
	if (format) {
		unsigned int bpp = drm_format_info_bpp(format, 0);

		switch (bpp) {
		case 16:
			color_mode = format->depth; // could also be 15
			break;
		default:
			color_mode = bpp;
		}
	} else {
		switch (dev->mode_config.preferred_depth) {
		case 0:
		case 24:
			color_mode = 32;
			break;
		default:
			color_mode = dev->mode_config.preferred_depth;
		}
	}

	drm_WARN(dev, !dev->registered, "Device has not been registered.\n");
	drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n");

	fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL);
	if (!fb_helper)
		return -ENOMEM;
	drm_fb_helper_prepare(dev, fb_helper, color_mode, NULL);

	ret = drm_client_init(dev, &fb_helper->client, "fbdev", &drm_fbdev_client_funcs);
	if (ret) {
		drm_err(dev, "Failed to register client: %d\n", ret);
		goto err_drm_client_init;
	}

	drm_client_register(&fb_helper->client);

	return 0;

err_drm_client_init:
	drm_fb_helper_unprepare(fb_helper);
	kfree(fb_helper);
	return ret;
}
