/*
 * Copyright 2018 NXP
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/component.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <drm/drmP.h>
#include <drm/drm_atomic_helper.h>
#include <video/imx-lcdif.h>
#include <video/videomode.h>

#include "imx-drm.h"
#include "lcdif-plane.h"
#include "lcdif-kms.h"

struct lcdif_crtc {
	struct device *dev;

	struct drm_crtc base;
	struct lcdif_plane *plane[2];

	int vbl_irq;
	u32 pix_fmt;		/* drm fourcc */
};

#define to_lcdif_crtc(crtc) container_of(crtc, struct lcdif_crtc, base)

static void lcdif_crtc_reset(struct drm_crtc *crtc)
{
	struct imx_crtc_state *state;

	if (crtc->state) {
		__drm_atomic_helper_crtc_destroy_state(crtc->state);

		state = to_imx_crtc_state(crtc->state);
		kfree(state);
		crtc->state = NULL;
	}

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

	crtc->state = &state->base;
	crtc->state->crtc = crtc;
}

static struct drm_crtc_state *lcdif_crtc_duplicate_state(struct drm_crtc *crtc)
{
	struct imx_crtc_state *state, *orig_state;

	if (WARN_ON(!crtc->state))
		return NULL;

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

	__drm_atomic_helper_crtc_duplicate_state(crtc, &state->base);

	orig_state = to_imx_crtc_state(crtc->state);
	state->bus_format = orig_state->bus_format;
	state->bus_flags = orig_state->bus_flags;
	state->di_hsync_pin = orig_state->di_hsync_pin;
	state->di_vsync_pin = orig_state->di_vsync_pin;

	return &state->base;
}

static void lcdif_crtc_destroy_state(struct drm_crtc *crtc,
				     struct drm_crtc_state *state)
{
	__drm_atomic_helper_crtc_destroy_state(state);
	kfree(to_imx_crtc_state(state));
}

static int lcdif_crtc_atomic_check(struct drm_crtc *crtc,
				   struct drm_crtc_state *state)
{
	struct lcdif_crtc *lcdif_crtc = to_lcdif_crtc(crtc);
	struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(state);

	/* Don't check 'bus_format' when CRTC is
	 * going to be disabled.
	 */
	if (!state->enable)
		return 0;

	/* For the commit that the CRTC is active
	 * without planes attached to it should be
	 * invalid.
	 */
	if (state->active && !state->plane_mask)
		return -EINVAL;

	/* check the requested bus format can be
	 * supported by LCDIF CTRC or not
	 */
	switch (imx_crtc_state->bus_format) {
	case MEDIA_BUS_FMT_RGB565_1X16:
	case MEDIA_BUS_FMT_RGB666_1X18:
	case MEDIA_BUS_FMT_RGB888_1X24:
		break;
	default:
		dev_err(lcdif_crtc->dev,
			"unsupported bus format: %#x\n",
			imx_crtc_state->bus_format);
		return -EINVAL;
	}

	return 0;
}

static void lcdif_crtc_atomic_begin(struct drm_crtc *crtc,
				    struct drm_crtc_state *old_crtc_state)
{
	drm_crtc_vblank_on(crtc);

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

static void lcdif_crtc_atomic_flush(struct drm_crtc *crtc,
				    struct drm_crtc_state *old_crtc_state)
{
	/* LCDIF doesn't have command buffer */
	return;
}

static void lcdif_crtc_atomic_enable(struct drm_crtc *crtc,
				     struct drm_crtc_state *old_crtc_state)
{
	struct lcdif_crtc *lcdif_crtc = to_lcdif_crtc(crtc);
	struct lcdif_soc *lcdif = dev_get_drvdata(lcdif_crtc->dev->parent);
	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
	struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc->state);
	struct videomode vm;

	drm_display_mode_to_videomode(mode, &vm);

	if (imx_crtc_state->bus_flags & DRM_BUS_FLAG_DE_HIGH)
		vm.flags |= DISPLAY_FLAGS_DE_HIGH;
	else
		vm.flags |= DISPLAY_FLAGS_DE_LOW;

	if (imx_crtc_state->bus_flags & DRM_BUS_FLAG_PIXDATA_POSEDGE)
		vm.flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE;
	else
		vm.flags |= DISPLAY_FLAGS_PIXDATA_NEGEDGE;

	pm_runtime_get_sync(lcdif_crtc->dev->parent);

	lcdif_set_mode(lcdif, &vm);

	/* config LCDIF output bus format */
	lcdif_set_bus_fmt(lcdif, imx_crtc_state->bus_format);

	/* defer the lcdif controller enable to plane update,
	 * since until then the lcdif config is complete to
	 * enable the controller to run actually.
	 */
}

static void lcdif_crtc_atomic_disable(struct drm_crtc *crtc,
				      struct drm_crtc_state *old_crtc_state)
{
	struct lcdif_crtc *lcdif_crtc = to_lcdif_crtc(crtc);
	struct lcdif_soc *lcdif = dev_get_drvdata(lcdif_crtc->dev->parent);

	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);

	drm_crtc_vblank_off(crtc);

	lcdif_disable_controller(lcdif);

	pm_runtime_put(lcdif_crtc->dev->parent);
}

static const struct drm_crtc_helper_funcs lcdif_helper_funcs = {
	.atomic_check	= lcdif_crtc_atomic_check,
	.atomic_begin	= lcdif_crtc_atomic_begin,
	.atomic_flush	= lcdif_crtc_atomic_flush,
	.atomic_enable	= lcdif_crtc_atomic_enable,
	.atomic_disable	= lcdif_crtc_atomic_disable,
};

static int lcdif_enable_vblank(struct drm_crtc *crtc)
{
	struct lcdif_crtc *lcdif_crtc = to_lcdif_crtc(crtc);
	struct lcdif_soc *lcdif = dev_get_drvdata(lcdif_crtc->dev->parent);

	lcdif_vblank_irq_enable(lcdif);
	enable_irq(lcdif_crtc->vbl_irq);

	return 0;
}

static void lcdif_disable_vblank(struct drm_crtc *crtc)
{
	struct lcdif_crtc *lcdif_crtc = to_lcdif_crtc(crtc);
	struct lcdif_soc *lcdif = dev_get_drvdata(lcdif_crtc->dev->parent);

	disable_irq_nosync(lcdif_crtc->vbl_irq);
	lcdif_vblank_irq_disable(lcdif);
}

static const struct drm_crtc_funcs lcdif_crtc_funcs = {
	.set_config = drm_atomic_helper_set_config,
	.destroy    = drm_crtc_cleanup,
	.page_flip  = drm_atomic_helper_page_flip,
	.reset      = lcdif_crtc_reset,
	.atomic_duplicate_state = lcdif_crtc_duplicate_state,
	.atomic_destroy_state	= lcdif_crtc_destroy_state,
	.enable_vblank	= lcdif_enable_vblank,
	.disable_vblank = lcdif_disable_vblank,
};

static irqreturn_t lcdif_crtc_vblank_irq_handler(int irq, void *dev_id)
{
	struct lcdif_crtc *lcdif_crtc = dev_id;
	struct lcdif_soc *lcdif = dev_get_drvdata(lcdif_crtc->dev->parent);

	drm_crtc_handle_vblank(&lcdif_crtc->base);

	lcdif_vblank_irq_clear(lcdif);

	return IRQ_HANDLED;
}

static int lcdif_crtc_init(struct lcdif_crtc *lcdif_crtc,
			   struct lcdif_client_platformdata *pdata,
			   struct drm_device *drm)
{
	int ret;
	struct lcdif_plane *primary = lcdif_crtc->plane[0];
	struct lcdif_soc *lcdif = dev_get_drvdata(lcdif_crtc->dev->parent);

	/* Primary plane
	 * The 'possible_crtcs' of primary plane will be
	 * recalculated during the 'crtc' initialization
	 * later.
	 */
	primary = lcdif_plane_init(drm, lcdif, 0, DRM_PLANE_TYPE_PRIMARY, 0);
	if (IS_ERR(primary))
		return PTR_ERR(primary);
	lcdif_crtc->plane[0] = primary;

	/* TODO: Overlay plane */

	lcdif_crtc->base.port = pdata->of_node;
	drm_crtc_helper_add(&lcdif_crtc->base, &lcdif_helper_funcs);
	ret = drm_crtc_init_with_planes(drm, &lcdif_crtc->base,
			&lcdif_crtc->plane[0]->base, NULL,
			&lcdif_crtc_funcs, NULL);
	if (ret) {
		dev_err(lcdif_crtc->dev, "failed to init crtc\n");
		goto primary_plane_deinit;
	}

	lcdif_crtc->vbl_irq = lcdif_vblank_irq_get(lcdif);
	WARN_ON(lcdif_crtc->vbl_irq < 0);

	ret = devm_request_irq(lcdif_crtc->dev, lcdif_crtc->vbl_irq,
			       lcdif_crtc_vblank_irq_handler, 0,
			       dev_name(lcdif_crtc->dev), lcdif_crtc);
	if (ret) {
		dev_err(lcdif_crtc->dev,
			"vblank irq request failed: %d\n", ret);
		goto primary_plane_deinit;
	}

	disable_irq(lcdif_crtc->vbl_irq);

	return 0;

primary_plane_deinit:
	lcdif_plane_deinit(drm, primary);

	return ret;
}

static int lcdif_crtc_bind(struct device *dev, struct device *master,
			   void *data)
{
	int ret;
	struct drm_device *drm = data;
	struct lcdif_crtc *lcdif_crtc;
	struct lcdif_client_platformdata *pdata = dev->platform_data;

	dev_dbg(dev, "%s: lcdif crtc bind begin\n", __func__);

	lcdif_crtc = devm_kzalloc(dev, sizeof(*lcdif_crtc), GFP_KERNEL);
	if (!lcdif_crtc)
		return -ENOMEM;

	lcdif_crtc->dev = dev;

	ret = lcdif_crtc_init(lcdif_crtc, pdata, drm);
	if (ret)
		return ret;

	if (!drm->mode_config.funcs)
		drm->mode_config.funcs = &lcdif_drm_mode_config_funcs;

	if (!drm->mode_config.helper_private)
		drm->mode_config.helper_private = &lcdif_drm_mode_config_helpers;

	/* limit the max width and height */
	drm->mode_config.max_width  = 1920;
	drm->mode_config.max_height = 1920;

	dev_set_drvdata(dev, lcdif_crtc);

	dev_dbg(dev, "%s: lcdif crtc bind end\n", __func__);

	return 0;
}

static void lcdif_crtc_unbind(struct device *dev, struct device *master,
			      void *data)
{
	struct drm_device *drm = data;
	struct lcdif_crtc *lcdif_crtc = dev_get_drvdata(dev);

	lcdif_plane_deinit(drm, lcdif_crtc->plane[0]);
}

static const struct component_ops lcdif_crtc_ops = {
	.bind   = lcdif_crtc_bind,
	.unbind = lcdif_crtc_unbind,
};

static int lcdif_crtc_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;

	dev_dbg(&pdev->dev, "%s: lcdif crtc probe begin\n", __func__);

	if (!dev->platform_data) {
		dev_err(dev, "no platform data\n");
		return -EINVAL;
	}

	return component_add(dev, &lcdif_crtc_ops);
}

static int lcdif_crtc_remove(struct platform_device *pdev)
{
	component_del(&pdev->dev, &lcdif_crtc_ops);

	return 0;
}

static struct platform_driver lcdif_crtc_driver = {
	.probe  = lcdif_crtc_probe,
	.remove = lcdif_crtc_remove,
	.driver = {
		.name = "imx-lcdif-crtc",
	},
};
module_platform_driver(lcdif_crtc_driver);

MODULE_DESCRIPTION("NXP i.MX LCDIF DRM CRTC driver");
MODULE_AUTHOR("Fancy Fang <chen.fang@nxp.com>");
MODULE_LICENSE("GPL");
