/*
 * OMAP2 Remote Frame Buffer Interface support
 *
 * Copyright (C) 2005 Nokia Corporation
 * Author: Juha Yrjölä <juha.yrjola@nokia.com>
 *	   Imre Deak <imre.deak@nokia.com>
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/platform_device.h>

#include "omapfb.h"
#include "dispc.h"

/* To work around an RFBI transfer rate limitation */
#define OMAP_RFBI_RATE_LIMIT	1

#define RFBI_BASE		0x48050800
#define RFBI_REVISION		0x0000
#define RFBI_SYSCONFIG		0x0010
#define RFBI_SYSSTATUS		0x0014
#define RFBI_CONTROL		0x0040
#define RFBI_PIXEL_CNT		0x0044
#define RFBI_LINE_NUMBER	0x0048
#define RFBI_CMD		0x004c
#define RFBI_PARAM		0x0050
#define RFBI_DATA		0x0054
#define RFBI_READ		0x0058
#define RFBI_STATUS		0x005c
#define RFBI_CONFIG0		0x0060
#define RFBI_ONOFF_TIME0	0x0064
#define RFBI_CYCLE_TIME0	0x0068
#define RFBI_DATA_CYCLE1_0	0x006c
#define RFBI_DATA_CYCLE2_0	0x0070
#define RFBI_DATA_CYCLE3_0	0x0074
#define RFBI_VSYNC_WIDTH	0x0090
#define RFBI_HSYNC_WIDTH	0x0094

#define DISPC_BASE		0x48050400
#define DISPC_CONTROL		0x0040
#define DISPC_IRQ_FRAMEMASK     0x0001

static struct {
	void __iomem	*base;
	void		(*lcdc_callback)(void *data);
	void		*lcdc_callback_data;
	unsigned long	l4_khz;
	int		bits_per_cycle;
	struct omapfb_device *fbdev;
	struct clk	*dss_ick;
	struct clk	*dss1_fck;
	unsigned	tearsync_pin_cnt;
	unsigned	tearsync_mode;
} rfbi;

static inline void rfbi_write_reg(int idx, u32 val)
{
	__raw_writel(val, rfbi.base + idx);
}

static inline u32 rfbi_read_reg(int idx)
{
	return __raw_readl(rfbi.base + idx);
}

static int rfbi_get_clocks(void)
{
	rfbi.dss_ick = clk_get(&rfbi.fbdev->dssdev->dev, "ick");
	if (IS_ERR(rfbi.dss_ick)) {
		dev_err(rfbi.fbdev->dev, "can't get ick\n");
		return PTR_ERR(rfbi.dss_ick);
	}

	rfbi.dss1_fck = clk_get(&rfbi.fbdev->dssdev->dev, "fck");
	if (IS_ERR(rfbi.dss1_fck)) {
		dev_err(rfbi.fbdev->dev, "can't get dss1_fck\n");
		clk_put(rfbi.dss_ick);
		return PTR_ERR(rfbi.dss1_fck);
	}

	return 0;
}

static void rfbi_put_clocks(void)
{
	clk_put(rfbi.dss1_fck);
	clk_put(rfbi.dss_ick);
}

static void rfbi_enable_clocks(int enable)
{
	if (enable) {
		clk_enable(rfbi.dss_ick);
		clk_enable(rfbi.dss1_fck);
	} else {
		clk_disable(rfbi.dss1_fck);
		clk_disable(rfbi.dss_ick);
	}
}


#ifdef VERBOSE
static void rfbi_print_timings(void)
{
	u32 l;
	u32 time;

	l = rfbi_read_reg(RFBI_CONFIG0);
	time = 1000000000 / rfbi.l4_khz;
	if (l & (1 << 4))
		time *= 2;

	dev_dbg(rfbi.fbdev->dev, "Tick time %u ps\n", time);
	l = rfbi_read_reg(RFBI_ONOFF_TIME0);
	dev_dbg(rfbi.fbdev->dev,
		"CSONTIME %d, CSOFFTIME %d, WEONTIME %d, WEOFFTIME %d, "
		"REONTIME %d, REOFFTIME %d\n",
		l & 0x0f, (l >> 4) & 0x3f, (l >> 10) & 0x0f, (l >> 14) & 0x3f,
		(l >> 20) & 0x0f, (l >> 24) & 0x3f);

	l = rfbi_read_reg(RFBI_CYCLE_TIME0);
	dev_dbg(rfbi.fbdev->dev,
		"WECYCLETIME %d, RECYCLETIME %d, CSPULSEWIDTH %d, "
		"ACCESSTIME %d\n",
		(l & 0x3f), (l >> 6) & 0x3f, (l >> 12) & 0x3f,
		(l >> 22) & 0x3f);
}
#else
static void rfbi_print_timings(void) {}
#endif

static void rfbi_set_timings(const struct extif_timings *t)
{
	u32 l;

	BUG_ON(!t->converted);

	rfbi_enable_clocks(1);
	rfbi_write_reg(RFBI_ONOFF_TIME0, t->tim[0]);
	rfbi_write_reg(RFBI_CYCLE_TIME0, t->tim[1]);

	l = rfbi_read_reg(RFBI_CONFIG0);
	l &= ~(1 << 4);
	l |= (t->tim[2] ? 1 : 0) << 4;
	rfbi_write_reg(RFBI_CONFIG0, l);

	rfbi_print_timings();
	rfbi_enable_clocks(0);
}

static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div)
{
	*clk_period = 1000000000 / rfbi.l4_khz;
	*max_clk_div = 2;
}

static int ps_to_rfbi_ticks(int time, int div)
{
	unsigned long tick_ps;
	int ret;

	/* Calculate in picosecs to yield more exact results */
	tick_ps = 1000000000 / (rfbi.l4_khz) * div;

	ret = (time + tick_ps - 1) / tick_ps;

	return ret;
}

#ifdef OMAP_RFBI_RATE_LIMIT
static unsigned long rfbi_get_max_tx_rate(void)
{
	unsigned long	l4_rate, dss1_rate;
	int		min_l4_ticks = 0;
	int		i;

	/* According to TI this can't be calculated so make the
	 * adjustments for a couple of known frequencies and warn for
	 * others.
	 */
	static const struct {
		unsigned long l4_clk;		/* HZ */
		unsigned long dss1_clk;		/* HZ */
		unsigned long min_l4_ticks;
	} ftab[] = {
		{ 55,	132,	7, },		/* 7.86 MPix/s */
		{ 110,	110,	12, },		/* 9.16 MPix/s */
		{ 110,	132,	10, },		/* 11   Mpix/s */
		{ 120,	120,	10, },		/* 12   Mpix/s */
		{ 133,	133,	10, },		/* 13.3 Mpix/s */
	};

	l4_rate = rfbi.l4_khz / 1000;
	dss1_rate = clk_get_rate(rfbi.dss1_fck) / 1000000;

	for (i = 0; i < ARRAY_SIZE(ftab); i++) {
		/* Use a window instead of an exact match, to account
		 * for different DPLL multiplier / divider pairs.
		 */
		if (abs(ftab[i].l4_clk - l4_rate) < 3 &&
		    abs(ftab[i].dss1_clk - dss1_rate) < 3) {
			min_l4_ticks = ftab[i].min_l4_ticks;
			break;
		}
	}
	if (i == ARRAY_SIZE(ftab)) {
		/* Can't be sure, return anyway the maximum not
		 * rate-limited. This might cause a problem only for the
		 * tearing synchronisation.
		 */
		dev_err(rfbi.fbdev->dev,
			"can't determine maximum RFBI transfer rate\n");
		return rfbi.l4_khz * 1000;
	}
	return rfbi.l4_khz * 1000 / min_l4_ticks;
}
#else
static int rfbi_get_max_tx_rate(void)
{
	return rfbi.l4_khz * 1000;
}
#endif


static int rfbi_convert_timings(struct extif_timings *t)
{
	u32 l;
	int reon, reoff, weon, weoff, cson, csoff, cs_pulse;
	int actim, recyc, wecyc;
	int div = t->clk_div;

	if (div <= 0 || div > 2)
		return -1;

	/* Make sure that after conversion it still holds that:
	 * weoff > weon, reoff > reon, recyc >= reoff, wecyc >= weoff,
	 * csoff > cson, csoff >= max(weoff, reoff), actim > reon
	 */
	weon = ps_to_rfbi_ticks(t->we_on_time, div);
	weoff = ps_to_rfbi_ticks(t->we_off_time, div);
	if (weoff <= weon)
		weoff = weon + 1;
	if (weon > 0x0f)
		return -1;
	if (weoff > 0x3f)
		return -1;

	reon = ps_to_rfbi_ticks(t->re_on_time, div);
	reoff = ps_to_rfbi_ticks(t->re_off_time, div);
	if (reoff <= reon)
		reoff = reon + 1;
	if (reon > 0x0f)
		return -1;
	if (reoff > 0x3f)
		return -1;

	cson = ps_to_rfbi_ticks(t->cs_on_time, div);
	csoff = ps_to_rfbi_ticks(t->cs_off_time, div);
	if (csoff <= cson)
		csoff = cson + 1;
	if (csoff < max(weoff, reoff))
		csoff = max(weoff, reoff);
	if (cson > 0x0f)
		return -1;
	if (csoff > 0x3f)
		return -1;

	l =  cson;
	l |= csoff << 4;
	l |= weon  << 10;
	l |= weoff << 14;
	l |= reon  << 20;
	l |= reoff << 24;

	t->tim[0] = l;

	actim = ps_to_rfbi_ticks(t->access_time, div);
	if (actim <= reon)
		actim = reon + 1;
	if (actim > 0x3f)
		return -1;

	wecyc = ps_to_rfbi_ticks(t->we_cycle_time, div);
	if (wecyc < weoff)
		wecyc = weoff;
	if (wecyc > 0x3f)
		return -1;

	recyc = ps_to_rfbi_ticks(t->re_cycle_time, div);
	if (recyc < reoff)
		recyc = reoff;
	if (recyc > 0x3f)
		return -1;

	cs_pulse = ps_to_rfbi_ticks(t->cs_pulse_width, div);
	if (cs_pulse > 0x3f)
		return -1;

	l =  wecyc;
	l |= recyc    << 6;
	l |= cs_pulse << 12;
	l |= actim    << 22;

	t->tim[1] = l;

	t->tim[2] = div - 1;

	t->converted = 1;

	return 0;
}

static int rfbi_setup_tearsync(unsigned pin_cnt,
			       unsigned hs_pulse_time, unsigned vs_pulse_time,
			       int hs_pol_inv, int vs_pol_inv, int extif_div)
{
	int hs, vs;
	int min;
	u32 l;

	if (pin_cnt != 1 && pin_cnt != 2)
		return -EINVAL;

	hs = ps_to_rfbi_ticks(hs_pulse_time, 1);
	vs = ps_to_rfbi_ticks(vs_pulse_time, 1);
	if (hs < 2)
		return -EDOM;
	if (pin_cnt == 2)
		min = 2;
	else
		min = 4;
	if (vs < min)
		return -EDOM;
	if (vs == hs)
		return -EINVAL;
	rfbi.tearsync_pin_cnt = pin_cnt;
	dev_dbg(rfbi.fbdev->dev,
		"setup_tearsync: pins %d hs %d vs %d hs_inv %d vs_inv %d\n",
		pin_cnt, hs, vs, hs_pol_inv, vs_pol_inv);

	rfbi_enable_clocks(1);
	rfbi_write_reg(RFBI_HSYNC_WIDTH, hs);
	rfbi_write_reg(RFBI_VSYNC_WIDTH, vs);

	l = rfbi_read_reg(RFBI_CONFIG0);
	if (hs_pol_inv)
		l &= ~(1 << 21);
	else
		l |= 1 << 21;
	if (vs_pol_inv)
		l &= ~(1 << 20);
	else
		l |= 1 << 20;
	rfbi_enable_clocks(0);

	return 0;
}

static int rfbi_enable_tearsync(int enable, unsigned line)
{
	u32 l;

	dev_dbg(rfbi.fbdev->dev, "tearsync %d line %d mode %d\n",
		enable, line, rfbi.tearsync_mode);
	if (line > (1 << 11) - 1)
		return -EINVAL;

	rfbi_enable_clocks(1);
	l = rfbi_read_reg(RFBI_CONFIG0);
	l &= ~(0x3 << 2);
	if (enable) {
		rfbi.tearsync_mode = rfbi.tearsync_pin_cnt;
		l |= rfbi.tearsync_mode << 2;
	} else
		rfbi.tearsync_mode = 0;
	rfbi_write_reg(RFBI_CONFIG0, l);
	rfbi_write_reg(RFBI_LINE_NUMBER, line);
	rfbi_enable_clocks(0);

	return 0;
}

static void rfbi_write_command(const void *buf, unsigned int len)
{
	rfbi_enable_clocks(1);
	if (rfbi.bits_per_cycle == 16) {
		const u16 *w = buf;
		BUG_ON(len & 1);
		for (; len; len -= 2)
			rfbi_write_reg(RFBI_CMD, *w++);
	} else {
		const u8 *b = buf;
		BUG_ON(rfbi.bits_per_cycle != 8);
		for (; len; len--)
			rfbi_write_reg(RFBI_CMD, *b++);
	}
	rfbi_enable_clocks(0);
}

static void rfbi_read_data(void *buf, unsigned int len)
{
	rfbi_enable_clocks(1);
	if (rfbi.bits_per_cycle == 16) {
		u16 *w = buf;
		BUG_ON(len & ~1);
		for (; len; len -= 2) {
			rfbi_write_reg(RFBI_READ, 0);
			*w++ = rfbi_read_reg(RFBI_READ);
		}
	} else {
		u8 *b = buf;
		BUG_ON(rfbi.bits_per_cycle != 8);
		for (; len; len--) {
			rfbi_write_reg(RFBI_READ, 0);
			*b++ = rfbi_read_reg(RFBI_READ);
		}
	}
	rfbi_enable_clocks(0);
}

static void rfbi_write_data(const void *buf, unsigned int len)
{
	rfbi_enable_clocks(1);
	if (rfbi.bits_per_cycle == 16) {
		const u16 *w = buf;
		BUG_ON(len & 1);
		for (; len; len -= 2)
			rfbi_write_reg(RFBI_PARAM, *w++);
	} else {
		const u8 *b = buf;
		BUG_ON(rfbi.bits_per_cycle != 8);
		for (; len; len--)
			rfbi_write_reg(RFBI_PARAM, *b++);
	}
	rfbi_enable_clocks(0);
}

static void rfbi_transfer_area(int width, int height,
				void (callback)(void * data), void *data)
{
	u32 w;

	BUG_ON(callback == NULL);

	rfbi_enable_clocks(1);
	omap_dispc_set_lcd_size(width, height);

	rfbi.lcdc_callback = callback;
	rfbi.lcdc_callback_data = data;

	rfbi_write_reg(RFBI_PIXEL_CNT, width * height);

	w = rfbi_read_reg(RFBI_CONTROL);
	w |= 1;				/* enable */
	if (!rfbi.tearsync_mode)
		w |= 1 << 4;		/* internal trigger, reset by HW */
	rfbi_write_reg(RFBI_CONTROL, w);

	omap_dispc_enable_lcd_out(1);
}

static inline void _stop_transfer(void)
{
	u32 w;

	w = rfbi_read_reg(RFBI_CONTROL);
	rfbi_write_reg(RFBI_CONTROL, w & ~(1 << 0));
	rfbi_enable_clocks(0);
}

static void rfbi_dma_callback(void *data)
{
	_stop_transfer();
	rfbi.lcdc_callback(rfbi.lcdc_callback_data);
}

static void rfbi_set_bits_per_cycle(int bpc)
{
	u32 l;

	rfbi_enable_clocks(1);
	l = rfbi_read_reg(RFBI_CONFIG0);
	l &= ~(0x03 << 0);

	switch (bpc) {
	case 8:
		break;
	case 16:
		l |= 3;
		break;
	default:
		BUG();
	}
	rfbi_write_reg(RFBI_CONFIG0, l);
	rfbi.bits_per_cycle = bpc;
	rfbi_enable_clocks(0);
}

static int rfbi_init(struct omapfb_device *fbdev)
{
	u32 l;
	int r;

	rfbi.fbdev = fbdev;
	rfbi.base = ioremap(RFBI_BASE, SZ_1K);
	if (!rfbi.base) {
		dev_err(fbdev->dev, "can't ioremap RFBI\n");
		return -ENOMEM;
	}

	if ((r = rfbi_get_clocks()) < 0)
		return r;
	rfbi_enable_clocks(1);

	rfbi.l4_khz = clk_get_rate(rfbi.dss_ick) / 1000;

	/* Reset */
	rfbi_write_reg(RFBI_SYSCONFIG, 1 << 1);
	while (!(rfbi_read_reg(RFBI_SYSSTATUS) & (1 << 0)));

	l = rfbi_read_reg(RFBI_SYSCONFIG);
	/* Enable autoidle and smart-idle */
	l |= (1 << 0) | (2 << 3);
	rfbi_write_reg(RFBI_SYSCONFIG, l);

	/* 16-bit interface, ITE trigger mode, 16-bit data */
	l = (0x03 << 0) | (0x00 << 2) | (0x01 << 5) | (0x02 << 7);
	l |= (0 << 9) | (1 << 20) | (1 << 21);
	rfbi_write_reg(RFBI_CONFIG0, l);

	rfbi_write_reg(RFBI_DATA_CYCLE1_0, 0x00000010);

	l = rfbi_read_reg(RFBI_CONTROL);
	/* Select CS0, clear bypass mode */
	l = (0x01 << 2);
	rfbi_write_reg(RFBI_CONTROL, l);

	r = omap_dispc_request_irq(DISPC_IRQ_FRAMEMASK, rfbi_dma_callback,
				   NULL);
	if (r < 0) {
		dev_err(fbdev->dev, "can't get DISPC irq\n");
		rfbi_enable_clocks(0);
		return r;
	}

	l = rfbi_read_reg(RFBI_REVISION);
	pr_info("omapfb: RFBI version %d.%d initialized\n",
		(l >> 4) & 0x0f, l & 0x0f);

	rfbi_enable_clocks(0);

	return 0;
}

static void rfbi_cleanup(void)
{
	omap_dispc_free_irq(DISPC_IRQ_FRAMEMASK, rfbi_dma_callback, NULL);
	rfbi_put_clocks();
	iounmap(rfbi.base);
}

const struct lcd_ctrl_extif omap2_ext_if = {
	.init			= rfbi_init,
	.cleanup		= rfbi_cleanup,
	.get_clk_info		= rfbi_get_clk_info,
	.get_max_tx_rate	= rfbi_get_max_tx_rate,
	.set_bits_per_cycle	= rfbi_set_bits_per_cycle,
	.convert_timings	= rfbi_convert_timings,
	.set_timings		= rfbi_set_timings,
	.write_command		= rfbi_write_command,
	.read_data		= rfbi_read_data,
	.write_data		= rfbi_write_data,
	.transfer_area		= rfbi_transfer_area,
	.setup_tearsync		= rfbi_setup_tearsync,
	.enable_tearsync	= rfbi_enable_tearsync,

	.max_transmit_size	= (u32) ~0,
};

