// SPDX-License-Identifier: GPL-2.0
/*
 * ZynqMP DisplayPort Subsystem - KMS API
 *
 * Copyright (C) 2017 - 2021 Xilinx, Inc.
 *
 * Authors:
 * - Hyun Woo Kwon <hyun.kwon@xilinx.com>
 * - Laurent Pinchart <laurent.pinchart@ideasonboard.com>
 */

#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_blend.h>
#include <drm/drm_bridge.h>
#include <drm/drm_bridge_connector.h>
#include <drm/drm_connector.h>
#include <drm/drm_crtc.h>
#include <drm/drm_device.h>
#include <drm/drm_drv.h>
#include <drm/drm_encoder.h>
#include <drm/drm_fbdev_dma.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_managed.h>
#include <drm/drm_mode_config.h>
#include <drm/drm_plane.h>
#include <drm/drm_plane_helper.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_simple_kms_helper.h>
#include <drm/drm_vblank.h>

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/pm_runtime.h>
#include <linux/spinlock.h>

#include "zynqmp_disp.h"
#include "zynqmp_dp.h"
#include "zynqmp_dpsub.h"
#include "zynqmp_kms.h"

static inline struct zynqmp_dpsub *to_zynqmp_dpsub(struct drm_device *drm)
{
	return container_of(drm, struct zynqmp_dpsub_drm, dev)->dpsub;
}

/* -----------------------------------------------------------------------------
 * DRM Planes
 */

static int zynqmp_dpsub_plane_atomic_check(struct drm_plane *plane,
					   struct drm_atomic_state *state)
{
	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
										 plane);
	struct drm_crtc_state *crtc_state;

	if (!new_plane_state->crtc)
		return 0;

	crtc_state = drm_atomic_get_crtc_state(state, new_plane_state->crtc);
	if (IS_ERR(crtc_state))
		return PTR_ERR(crtc_state);

	return drm_atomic_helper_check_plane_state(new_plane_state,
						   crtc_state,
						   DRM_PLANE_NO_SCALING,
						   DRM_PLANE_NO_SCALING,
						   false, false);
}

static void zynqmp_dpsub_plane_atomic_disable(struct drm_plane *plane,
					      struct drm_atomic_state *state)
{
	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
									   plane);
	struct zynqmp_dpsub *dpsub = to_zynqmp_dpsub(plane->dev);
	struct zynqmp_disp_layer *layer = dpsub->layers[plane->index];

	if (!old_state->fb)
		return;

	zynqmp_disp_layer_disable(layer);

	if (plane->index == ZYNQMP_DPSUB_LAYER_GFX)
		zynqmp_disp_blend_set_global_alpha(dpsub->disp, false,
						   plane->state->alpha >> 8);
}

static void zynqmp_dpsub_plane_atomic_update(struct drm_plane *plane,
					     struct drm_atomic_state *state)
{
	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, plane);
	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, plane);
	struct zynqmp_dpsub *dpsub = to_zynqmp_dpsub(plane->dev);
	struct zynqmp_disp_layer *layer = dpsub->layers[plane->index];
	bool format_changed = false;

	if (!old_state->fb ||
	    old_state->fb->format->format != new_state->fb->format->format)
		format_changed = true;

	/*
	 * If the format has changed (including going from a previously
	 * disabled state to any format), reconfigure the format. Disable the
	 * plane first if needed.
	 */
	if (format_changed) {
		if (old_state->fb)
			zynqmp_disp_layer_disable(layer);

		zynqmp_disp_layer_set_format(layer, new_state->fb->format);
	}

	zynqmp_disp_layer_update(layer, new_state);

	if (plane->index == ZYNQMP_DPSUB_LAYER_GFX)
		zynqmp_disp_blend_set_global_alpha(dpsub->disp, true,
						   plane->state->alpha >> 8);

	/* Enable or re-enable the plane if the format has changed. */
	if (format_changed)
		zynqmp_disp_layer_enable(layer, ZYNQMP_DPSUB_LAYER_NONLIVE);
}

static const struct drm_plane_helper_funcs zynqmp_dpsub_plane_helper_funcs = {
	.atomic_check		= zynqmp_dpsub_plane_atomic_check,
	.atomic_update		= zynqmp_dpsub_plane_atomic_update,
	.atomic_disable		= zynqmp_dpsub_plane_atomic_disable,
};

static const struct drm_plane_funcs zynqmp_dpsub_plane_funcs = {
	.update_plane		= drm_atomic_helper_update_plane,
	.disable_plane		= drm_atomic_helper_disable_plane,
	.destroy		= drm_plane_cleanup,
	.reset			= drm_atomic_helper_plane_reset,
	.atomic_duplicate_state	= drm_atomic_helper_plane_duplicate_state,
	.atomic_destroy_state	= drm_atomic_helper_plane_destroy_state,
};

static int zynqmp_dpsub_create_planes(struct zynqmp_dpsub *dpsub)
{
	unsigned int i;
	int ret;

	for (i = 0; i < ARRAY_SIZE(dpsub->drm->planes); i++) {
		struct zynqmp_disp_layer *layer = dpsub->layers[i];
		struct drm_plane *plane = &dpsub->drm->planes[i];
		enum drm_plane_type type;
		unsigned int num_formats;
		u32 *formats;

		formats = zynqmp_disp_layer_drm_formats(layer, &num_formats);
		if (!formats)
			return -ENOMEM;

		/* Graphics layer is primary, and video layer is overlay. */
		type = i == ZYNQMP_DPSUB_LAYER_VID
		     ? DRM_PLANE_TYPE_OVERLAY : DRM_PLANE_TYPE_PRIMARY;
		ret = drm_universal_plane_init(&dpsub->drm->dev, plane, 0,
					       &zynqmp_dpsub_plane_funcs,
					       formats, num_formats,
					       NULL, type, NULL);
		kfree(formats);
		if (ret)
			return ret;

		drm_plane_helper_add(plane, &zynqmp_dpsub_plane_helper_funcs);

		drm_plane_create_zpos_immutable_property(plane, i);
		if (i == ZYNQMP_DPSUB_LAYER_GFX)
			drm_plane_create_alpha_property(plane);
	}

	return 0;
}

/* -----------------------------------------------------------------------------
 * DRM CRTC
 */

static inline struct zynqmp_dpsub *crtc_to_dpsub(struct drm_crtc *crtc)
{
	return container_of(crtc, struct zynqmp_dpsub_drm, crtc)->dpsub;
}

static void zynqmp_dpsub_crtc_atomic_enable(struct drm_crtc *crtc,
					    struct drm_atomic_state *state)
{
	struct zynqmp_dpsub *dpsub = crtc_to_dpsub(crtc);
	struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
	int ret, vrefresh;

	pm_runtime_get_sync(dpsub->dev);

	zynqmp_disp_setup_clock(dpsub->disp, adjusted_mode->clock * 1000);

	ret = clk_prepare_enable(dpsub->vid_clk);
	if (ret) {
		dev_err(dpsub->dev, "failed to enable a pixel clock\n");
		pm_runtime_put_sync(dpsub->dev);
		return;
	}

	zynqmp_disp_enable(dpsub->disp);

	/* Delay of 3 vblank intervals for timing gen to be stable */
	vrefresh = (adjusted_mode->clock * 1000) /
		   (adjusted_mode->vtotal * adjusted_mode->htotal);
	msleep(3 * 1000 / vrefresh);
}

static void zynqmp_dpsub_crtc_atomic_disable(struct drm_crtc *crtc,
					     struct drm_atomic_state *state)
{
	struct zynqmp_dpsub *dpsub = crtc_to_dpsub(crtc);
	struct drm_plane_state *old_plane_state;

	/*
	 * Disable the plane if active. The old plane state can be NULL in the
	 * .shutdown() path if the plane is already disabled, skip
	 * zynqmp_disp_plane_atomic_disable() in that case.
	 */
	old_plane_state = drm_atomic_get_old_plane_state(state, crtc->primary);
	if (old_plane_state)
		zynqmp_dpsub_plane_atomic_disable(crtc->primary, state);

	zynqmp_disp_disable(dpsub->disp);

	drm_crtc_vblank_off(crtc);

	spin_lock_irq(&crtc->dev->event_lock);
	if (crtc->state->event) {
		drm_crtc_send_vblank_event(crtc, crtc->state->event);
		crtc->state->event = NULL;
	}
	spin_unlock_irq(&crtc->dev->event_lock);

	clk_disable_unprepare(dpsub->vid_clk);
	pm_runtime_put_sync(dpsub->dev);
}

static int zynqmp_dpsub_crtc_atomic_check(struct drm_crtc *crtc,
					  struct drm_atomic_state *state)
{
	return drm_atomic_add_affected_planes(state, crtc);
}

static void zynqmp_dpsub_crtc_atomic_begin(struct drm_crtc *crtc,
					   struct drm_atomic_state *state)
{
	drm_crtc_vblank_on(crtc);
}

static void zynqmp_dpsub_crtc_atomic_flush(struct drm_crtc *crtc,
					   struct drm_atomic_state *state)
{
	if (crtc->state->event) {
		struct drm_pending_vblank_event *event;

		/* Consume the flip_done event from atomic helper. */
		event = crtc->state->event;
		crtc->state->event = NULL;

		event->pipe = drm_crtc_index(crtc);

		WARN_ON(drm_crtc_vblank_get(crtc) != 0);

		spin_lock_irq(&crtc->dev->event_lock);
		drm_crtc_arm_vblank_event(crtc, event);
		spin_unlock_irq(&crtc->dev->event_lock);
	}
}

static const struct drm_crtc_helper_funcs zynqmp_dpsub_crtc_helper_funcs = {
	.atomic_enable	= zynqmp_dpsub_crtc_atomic_enable,
	.atomic_disable	= zynqmp_dpsub_crtc_atomic_disable,
	.atomic_check	= zynqmp_dpsub_crtc_atomic_check,
	.atomic_begin	= zynqmp_dpsub_crtc_atomic_begin,
	.atomic_flush	= zynqmp_dpsub_crtc_atomic_flush,
};

static int zynqmp_dpsub_crtc_enable_vblank(struct drm_crtc *crtc)
{
	struct zynqmp_dpsub *dpsub = crtc_to_dpsub(crtc);

	zynqmp_dp_enable_vblank(dpsub->dp);

	return 0;
}

static void zynqmp_dpsub_crtc_disable_vblank(struct drm_crtc *crtc)
{
	struct zynqmp_dpsub *dpsub = crtc_to_dpsub(crtc);

	zynqmp_dp_disable_vblank(dpsub->dp);
}

static const struct drm_crtc_funcs zynqmp_dpsub_crtc_funcs = {
	.destroy		= drm_crtc_cleanup,
	.set_config		= drm_atomic_helper_set_config,
	.page_flip		= drm_atomic_helper_page_flip,
	.reset			= drm_atomic_helper_crtc_reset,
	.atomic_duplicate_state	= drm_atomic_helper_crtc_duplicate_state,
	.atomic_destroy_state	= drm_atomic_helper_crtc_destroy_state,
	.enable_vblank		= zynqmp_dpsub_crtc_enable_vblank,
	.disable_vblank		= zynqmp_dpsub_crtc_disable_vblank,
};

static int zynqmp_dpsub_create_crtc(struct zynqmp_dpsub *dpsub)
{
	struct drm_plane *plane = &dpsub->drm->planes[ZYNQMP_DPSUB_LAYER_GFX];
	struct drm_crtc *crtc = &dpsub->drm->crtc;
	int ret;

	ret = drm_crtc_init_with_planes(&dpsub->drm->dev, crtc, plane,
					NULL, &zynqmp_dpsub_crtc_funcs, NULL);
	if (ret < 0)
		return ret;

	drm_crtc_helper_add(crtc, &zynqmp_dpsub_crtc_helper_funcs);

	/* Start with vertical blanking interrupt reporting disabled. */
	drm_crtc_vblank_off(crtc);

	return 0;
}

static void zynqmp_dpsub_map_crtc_to_plane(struct zynqmp_dpsub *dpsub)
{
	u32 possible_crtcs = drm_crtc_mask(&dpsub->drm->crtc);
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(dpsub->drm->planes); i++)
		dpsub->drm->planes[i].possible_crtcs = possible_crtcs;
}

/**
 * zynqmp_dpsub_drm_handle_vblank - Handle the vblank event
 * @dpsub: DisplayPort subsystem
 *
 * This function handles the vblank interrupt, and sends an event to
 * CRTC object. This will be called by the DP vblank interrupt handler.
 */
void zynqmp_dpsub_drm_handle_vblank(struct zynqmp_dpsub *dpsub)
{
	drm_crtc_handle_vblank(&dpsub->drm->crtc);
}

/* -----------------------------------------------------------------------------
 * Dumb Buffer & Framebuffer Allocation
 */

static int zynqmp_dpsub_dumb_create(struct drm_file *file_priv,
				    struct drm_device *drm,
				    struct drm_mode_create_dumb *args)
{
	struct zynqmp_dpsub *dpsub = to_zynqmp_dpsub(drm);
	unsigned int pitch = DIV_ROUND_UP(args->width * args->bpp, 8);

	/* Enforce the alignment constraints of the DMA engine. */
	args->pitch = ALIGN(pitch, dpsub->dma_align);

	return drm_gem_dma_dumb_create_internal(file_priv, drm, args);
}

static struct drm_framebuffer *
zynqmp_dpsub_fb_create(struct drm_device *drm, struct drm_file *file_priv,
		       const struct drm_mode_fb_cmd2 *mode_cmd)
{
	struct zynqmp_dpsub *dpsub = to_zynqmp_dpsub(drm);
	struct drm_mode_fb_cmd2 cmd = *mode_cmd;
	unsigned int i;

	/* Enforce the alignment constraints of the DMA engine. */
	for (i = 0; i < ARRAY_SIZE(cmd.pitches); ++i)
		cmd.pitches[i] = ALIGN(cmd.pitches[i], dpsub->dma_align);

	return drm_gem_fb_create(drm, file_priv, &cmd);
}

static const struct drm_mode_config_funcs zynqmp_dpsub_mode_config_funcs = {
	.fb_create		= zynqmp_dpsub_fb_create,
	.atomic_check		= drm_atomic_helper_check,
	.atomic_commit		= drm_atomic_helper_commit,
};

/* -----------------------------------------------------------------------------
 * DRM/KMS Driver
 */

DEFINE_DRM_GEM_DMA_FOPS(zynqmp_dpsub_drm_fops);

static const struct drm_driver zynqmp_dpsub_drm_driver = {
	.driver_features		= DRIVER_MODESET | DRIVER_GEM |
					  DRIVER_ATOMIC,

	DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(zynqmp_dpsub_dumb_create),

	.fops				= &zynqmp_dpsub_drm_fops,

	.name				= "zynqmp-dpsub",
	.desc				= "Xilinx DisplayPort Subsystem Driver",
	.date				= "20130509",
	.major				= 1,
	.minor				= 0,
};

static int zynqmp_dpsub_kms_init(struct zynqmp_dpsub *dpsub)
{
	struct drm_encoder *encoder = &dpsub->drm->encoder;
	struct drm_connector *connector;
	int ret;

	/* Create the planes and the CRTC. */
	ret = zynqmp_dpsub_create_planes(dpsub);
	if (ret)
		return ret;

	ret = zynqmp_dpsub_create_crtc(dpsub);
	if (ret < 0)
		return ret;

	zynqmp_dpsub_map_crtc_to_plane(dpsub);

	/* Create the encoder and attach the bridge. */
	encoder->possible_crtcs |= drm_crtc_mask(&dpsub->drm->crtc);
	drm_simple_encoder_init(&dpsub->drm->dev, encoder, DRM_MODE_ENCODER_NONE);

	ret = drm_bridge_attach(encoder, dpsub->bridge, NULL,
				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
	if (ret) {
		dev_err(dpsub->dev, "failed to attach bridge to encoder\n");
		return ret;
	}

	/* Create the connector for the chain of bridges. */
	connector = drm_bridge_connector_init(&dpsub->drm->dev, encoder);
	if (IS_ERR(connector)) {
		dev_err(dpsub->dev, "failed to created connector\n");
		return PTR_ERR(connector);
	}

	ret = drm_connector_attach_encoder(connector, encoder);
	if (ret < 0) {
		dev_err(dpsub->dev, "failed to attach connector to encoder\n");
		return ret;
	}

	return 0;
}

static void zynqmp_dpsub_drm_release(struct drm_device *drm, void *res)
{
	struct zynqmp_dpsub_drm *dpdrm = res;

	zynqmp_dpsub_release(dpdrm->dpsub);
}

int zynqmp_dpsub_drm_init(struct zynqmp_dpsub *dpsub)
{
	struct zynqmp_dpsub_drm *dpdrm;
	struct drm_device *drm;
	int ret;

	/*
	 * Allocate the drm_device and immediately add a cleanup action to
	 * release the zynqmp_dpsub instance. If any of those operations fail,
	 * dpsub->drm will remain NULL, which tells the caller that it must
	 * cleanup manually.
	 */
	dpdrm = devm_drm_dev_alloc(dpsub->dev, &zynqmp_dpsub_drm_driver,
				   struct zynqmp_dpsub_drm, dev);
	if (IS_ERR(dpdrm))
		return PTR_ERR(dpdrm);

	dpdrm->dpsub = dpsub;
	drm = &dpdrm->dev;

	ret = drmm_add_action(drm, zynqmp_dpsub_drm_release, dpdrm);
	if (ret < 0)
		return ret;

	dpsub->drm = dpdrm;

	/* Initialize mode config, vblank and the KMS poll helper. */
	ret = drmm_mode_config_init(drm);
	if (ret < 0)
		return ret;

	drm->mode_config.funcs = &zynqmp_dpsub_mode_config_funcs;
	drm->mode_config.min_width = 0;
	drm->mode_config.min_height = 0;
	drm->mode_config.max_width = ZYNQMP_DISP_MAX_WIDTH;
	drm->mode_config.max_height = ZYNQMP_DISP_MAX_HEIGHT;

	ret = drm_vblank_init(drm, 1);
	if (ret)
		return ret;

	drm_kms_helper_poll_init(drm);

	ret = zynqmp_dpsub_kms_init(dpsub);
	if (ret < 0)
		goto err_poll_fini;

	/* Reset all components and register the DRM device. */
	drm_mode_config_reset(drm);

	ret = drm_dev_register(drm, 0);
	if (ret < 0)
		goto err_poll_fini;

	/* Initialize fbdev generic emulation. */
	drm_fbdev_dma_setup(drm, 24);

	return 0;

err_poll_fini:
	drm_kms_helper_poll_fini(drm);
	return ret;
}

void zynqmp_dpsub_drm_cleanup(struct zynqmp_dpsub *dpsub)
{
	struct drm_device *drm = &dpsub->drm->dev;

	drm_dev_unregister(drm);
	drm_atomic_helper_shutdown(drm);
	drm_kms_helper_poll_fini(drm);
}
