/*
 * Copyright 2015 Freescale Semiconductor, Inc.
 *
 * Freescale DCU drm device driver
 *
 * 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.
 */

#include <linux/clk.h>
#include <linux/regmap.h>

#include <drm/drmP.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>

#include "fsl_dcu_drm_crtc.h"
#include "fsl_dcu_drm_drv.h"
#include "fsl_dcu_drm_plane.h"

static void fsl_dcu_drm_crtc_atomic_begin(struct drm_crtc *crtc,
					  struct drm_crtc_state *old_crtc_state)
{
}

static int fsl_dcu_drm_crtc_atomic_check(struct drm_crtc *crtc,
					 struct drm_crtc_state *state)
{
	return 0;
}

static void fsl_dcu_drm_crtc_atomic_flush(struct drm_crtc *crtc,
					  struct drm_crtc_state *old_crtc_state)
{
}

static void fsl_dcu_drm_disable_crtc(struct drm_crtc *crtc)
{
	struct drm_device *dev = crtc->dev;
	struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
	int ret;

	ret = regmap_update_bits(fsl_dev->regmap, DCU_DCU_MODE,
				 DCU_MODE_DCU_MODE_MASK,
				 DCU_MODE_DCU_MODE(DCU_MODE_OFF));
	if (ret)
		dev_err(fsl_dev->dev, "Disable CRTC failed\n");
	ret = regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE,
			   DCU_UPDATE_MODE_READREG);
	if (ret)
		dev_err(fsl_dev->dev, "Enable CRTC failed\n");
}

static void fsl_dcu_drm_crtc_enable(struct drm_crtc *crtc)
{
	struct drm_device *dev = crtc->dev;
	struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
	int ret;

	ret = regmap_update_bits(fsl_dev->regmap, DCU_DCU_MODE,
				 DCU_MODE_DCU_MODE_MASK,
				 DCU_MODE_DCU_MODE(DCU_MODE_NORMAL));
	if (ret)
		dev_err(fsl_dev->dev, "Enable CRTC failed\n");
	ret = regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE,
			   DCU_UPDATE_MODE_READREG);
	if (ret)
		dev_err(fsl_dev->dev, "Enable CRTC failed\n");
}

static bool fsl_dcu_drm_crtc_mode_fixup(struct drm_crtc *crtc,
					const struct drm_display_mode *mode,
					struct drm_display_mode *adjusted_mode)
{
	return true;
}

static void fsl_dcu_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
{
	struct drm_device *dev = crtc->dev;
	struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
	struct drm_display_mode *mode = &crtc->state->mode;
	unsigned int hbp, hfp, hsw, vbp, vfp, vsw, div, index;
	unsigned long dcuclk;
	int ret;

	index = drm_crtc_index(crtc);
	dcuclk = clk_get_rate(fsl_dev->clk);
	div = dcuclk / mode->clock / 1000;

	/* Configure timings: */
	hbp = mode->htotal - mode->hsync_end;
	hfp = mode->hsync_start - mode->hdisplay;
	hsw = mode->hsync_end - mode->hsync_start;
	vbp = mode->vtotal - mode->vsync_end;
	vfp = mode->vsync_start - mode->vdisplay;
	vsw = mode->vsync_end - mode->vsync_start;

	ret = regmap_write(fsl_dev->regmap, DCU_HSYN_PARA,
			   DCU_HSYN_PARA_BP(hbp) |
			   DCU_HSYN_PARA_PW(hsw) |
			   DCU_HSYN_PARA_FP(hfp));
	if (ret)
		goto set_failed;
	ret = regmap_write(fsl_dev->regmap, DCU_VSYN_PARA,
			   DCU_VSYN_PARA_BP(vbp) |
			   DCU_VSYN_PARA_PW(vsw) |
			   DCU_VSYN_PARA_FP(vfp));
	if (ret)
		goto set_failed;
	ret = regmap_write(fsl_dev->regmap, DCU_DISP_SIZE,
			   DCU_DISP_SIZE_DELTA_Y(mode->vdisplay) |
			   DCU_DISP_SIZE_DELTA_X(mode->hdisplay));
	if (ret)
		goto set_failed;
	ret = regmap_write(fsl_dev->regmap, DCU_DIV_RATIO, div);
	if (ret)
		goto set_failed;
	ret = regmap_write(fsl_dev->regmap, DCU_SYN_POL,
			   DCU_SYN_POL_INV_VS_LOW | DCU_SYN_POL_INV_HS_LOW);
	if (ret)
		goto set_failed;
	ret = regmap_write(fsl_dev->regmap, DCU_BGND, DCU_BGND_R(0) |
			   DCU_BGND_G(0) | DCU_BGND_B(0));
	if (ret)
		goto set_failed;
	ret = regmap_write(fsl_dev->regmap, DCU_DCU_MODE,
			   DCU_MODE_BLEND_ITER(1) | DCU_MODE_RASTER_EN);
	if (ret)
		goto set_failed;
	ret = regmap_write(fsl_dev->regmap, DCU_THRESHOLD,
			   DCU_THRESHOLD_LS_BF_VS(BF_VS_VAL) |
			   DCU_THRESHOLD_OUT_BUF_HIGH(BUF_MAX_VAL) |
			   DCU_THRESHOLD_OUT_BUF_LOW(BUF_MIN_VAL));
	if (ret)
		goto set_failed;
	ret = regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE,
			   DCU_UPDATE_MODE_READREG);
	if (ret)
		goto set_failed;
	return;
set_failed:
	dev_err(dev->dev, "set DCU register failed\n");
}

static const struct drm_crtc_helper_funcs fsl_dcu_drm_crtc_helper_funcs = {
	.atomic_begin = fsl_dcu_drm_crtc_atomic_begin,
	.atomic_check = fsl_dcu_drm_crtc_atomic_check,
	.atomic_flush = fsl_dcu_drm_crtc_atomic_flush,
	.disable = fsl_dcu_drm_disable_crtc,
	.enable = fsl_dcu_drm_crtc_enable,
	.mode_fixup = fsl_dcu_drm_crtc_mode_fixup,
	.mode_set_nofb = fsl_dcu_drm_crtc_mode_set_nofb,
};

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

int fsl_dcu_drm_crtc_create(struct fsl_dcu_drm_device *fsl_dev)
{
	struct drm_plane *primary;
	struct drm_crtc *crtc = &fsl_dev->crtc;
	unsigned int i, j, reg_num;
	int ret;

	primary = fsl_dcu_drm_primary_create_plane(fsl_dev->drm);
	ret = drm_crtc_init_with_planes(fsl_dev->drm, crtc, primary, NULL,
					&fsl_dcu_drm_crtc_funcs);
	if (ret < 0)
		return ret;

	drm_crtc_helper_add(crtc, &fsl_dcu_drm_crtc_helper_funcs);

	if (!strcmp(fsl_dev->soc->name, "ls1021a"))
		reg_num = LS1021A_LAYER_REG_NUM;
	else
		reg_num = VF610_LAYER_REG_NUM;
	for (i = 0; i <= fsl_dev->soc->total_layer; i++) {
		for (j = 0; j < reg_num; j++) {
			ret = regmap_write(fsl_dev->regmap,
					   DCU_CTRLDESCLN(i, j), 0);
			if (ret)
				goto init_failed;
		}
	}
	ret = regmap_update_bits(fsl_dev->regmap, DCU_DCU_MODE,
				 DCU_MODE_DCU_MODE_MASK,
				 DCU_MODE_DCU_MODE(DCU_MODE_OFF));
	if (ret)
		goto init_failed;
	ret = regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE,
			   DCU_UPDATE_MODE_READREG);
	if (ret)
		goto init_failed;

	return 0;
init_failed:
	dev_err(fsl_dev->dev, "init DCU register failed\n");
	return ret;
}
