/*
 * T1042 platform DIU operation
 *
 * Copyright 2014 Freescale Semiconductor Inc.
 *
 * 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/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>

#include <sysdev/fsl_soc.h>

/*DIU Pixel ClockCR offset in scfg*/
#define CCSR_SCFG_PIXCLKCR      0x28

/* DIU Pixel Clock bits of the PIXCLKCR */
#define PIXCLKCR_PXCKEN		0x80000000
#define PIXCLKCR_PXCKINV	0x40000000
#define PIXCLKCR_PXCKDLY	0x0000FF00
#define PIXCLKCR_PXCLK_MASK	0x00FF0000

/* Some CPLD register definitions */
#define CPLD_DIUCSR		0x16
#define CPLD_DIUCSR_DVIEN	0x80
#define CPLD_DIUCSR_BACKLIGHT	0x0f

struct device_node *cpld_node;

/**
 * t1042rdb_set_monitor_port: switch the output to a different monitor port
 */
static void t1042rdb_set_monitor_port(enum fsl_diu_monitor_port port)
{
	static void __iomem *cpld_base;

	cpld_base = of_iomap(cpld_node, 0);
	if (!cpld_base) {
		pr_err("%s: Could not map cpld registers\n", __func__);
		goto exit;
	}

	switch (port) {
	case FSL_DIU_PORT_DVI:
		/* Enable the DVI(HDMI) port, disable the DFP and
		 * the backlight
		 */
		clrbits8(cpld_base + CPLD_DIUCSR, CPLD_DIUCSR_DVIEN);
		break;
	case FSL_DIU_PORT_LVDS:
		/*
		 * LVDS also needs backlight enabled, otherwise the display
		 * will be blank.
		 */
		/* Enable the DFP port, disable the DVI*/
		setbits8(cpld_base + CPLD_DIUCSR, 0x01 << 8);
		setbits8(cpld_base + CPLD_DIUCSR, 0x01 << 4);
		setbits8(cpld_base + CPLD_DIUCSR, CPLD_DIUCSR_BACKLIGHT);
		break;
	default:
		pr_err("%s: Unsupported monitor port %i\n", __func__, port);
	}

	iounmap(cpld_base);
exit:
	of_node_put(cpld_node);
}

/**
 * t1042rdb_set_pixel_clock: program the DIU's clock
 * @pixclock: pixel clock in ps (pico seconds)
 */
static void t1042rdb_set_pixel_clock(unsigned int pixclock)
{
	struct device_node *scfg_np;
	void __iomem *scfg;
	unsigned long freq;
	u64 temp;
	u32 pxclk;

	scfg_np = of_find_compatible_node(NULL, NULL, "fsl,t1040-scfg");
	if (!scfg_np) {
		pr_err("%s: Missing scfg node. Can not display video.\n",
		       __func__);
		return;
	}

	scfg = of_iomap(scfg_np, 0);
	of_node_put(scfg_np);
	if (!scfg) {
		pr_err("%s: Could not map device. Can not display video.\n",
		       __func__);
		return;
	}

	/* Convert pixclock into frequency */
	temp = 1000000000000ULL;
	do_div(temp, pixclock);
	freq = temp;

	/*
	 * 'pxclk' is the ratio of the platform clock to the pixel clock.
	 * This number is programmed into the PIXCLKCR register, and the valid
	 * range of values is 2-255.
	 */
	pxclk = DIV_ROUND_CLOSEST(fsl_get_sys_freq(), freq);
	pxclk = clamp_t(u32, pxclk, 2, 255);

	/* Disable the pixel clock, and set it to non-inverted and no delay */
	clrbits32(scfg + CCSR_SCFG_PIXCLKCR,
		  PIXCLKCR_PXCKEN | PIXCLKCR_PXCKDLY | PIXCLKCR_PXCLK_MASK);

	/* Enable the clock and set the pxclk */
	setbits32(scfg + CCSR_SCFG_PIXCLKCR, PIXCLKCR_PXCKEN | (pxclk << 16));

	iounmap(scfg);
}

/**
 * t1042rdb_valid_monitor_port: set the monitor port for sysfs
 */
static enum fsl_diu_monitor_port
t1042rdb_valid_monitor_port(enum fsl_diu_monitor_port port)
{
	switch (port) {
	case FSL_DIU_PORT_DVI:
	case FSL_DIU_PORT_LVDS:
		return port;
	default:
		return FSL_DIU_PORT_DVI; /* Dual-link LVDS is not supported */
	}
}

static int __init t1042rdb_diu_init(void)
{
	cpld_node = of_find_compatible_node(NULL, NULL, "fsl,t1042rdb-cpld");
	if (!cpld_node)
		return 0;

	diu_ops.set_monitor_port	= t1042rdb_set_monitor_port;
	diu_ops.set_pixel_clock		= t1042rdb_set_pixel_clock;
	diu_ops.valid_monitor_port	= t1042rdb_valid_monitor_port;

	return 0;
}

early_initcall(t1042rdb_diu_init);

MODULE_LICENSE("GPL");
