/*
 * udbg serial input/output routines for the Marvell MV64x60 (Discovery).
 *
 * Author: Dale Farnsworth <dale@farnsworth.org>
 *
 * 2007 (c) MontaVista Software, Inc.  This file is licensed under
 * the terms of the GNU General Public License version 2.  This program
 * is licensed "as is" without any warranty of any kind, whether express
 * or implied.
 */

#include <asm/io.h>
#include <asm/prom.h>
#include <asm/udbg.h>

#include <sysdev/mv64x60.h>

#define MPSC_0_CR1_OFFSET	0x000c

#define MPSC_0_CR2_OFFSET	0x0010
#define MPSC_CHR_2_TCS		(1 << 9)

#define MPSC_0_CHR_10_OFFSET	0x0030

#define MPSC_INTR_CAUSE_OFF_0	0x0004
#define MPSC_INTR_CAUSE_OFF_1	0x000c
#define MPSC_INTR_CAUSE_RCC	(1<<6)

static void __iomem *mpsc_base;
static void __iomem *mpsc_intr_cause;

static void mv64x60_udbg_putc(char c)
{
	if (c == '\n')
		mv64x60_udbg_putc('\r');

	while(in_le32(mpsc_base + MPSC_0_CR2_OFFSET) & MPSC_CHR_2_TCS)
		;
	out_le32(mpsc_base + MPSC_0_CR1_OFFSET, c);
	out_le32(mpsc_base + MPSC_0_CR2_OFFSET, MPSC_CHR_2_TCS);
}

static int mv64x60_udbg_testc(void)
{
	return (in_le32(mpsc_intr_cause) & MPSC_INTR_CAUSE_RCC) != 0;
}

static int mv64x60_udbg_getc(void)
{
	int cause = 0;
	int c;

	while (!mv64x60_udbg_testc())
		;

	c = in_8(mpsc_base + MPSC_0_CHR_10_OFFSET + 2);
	out_8(mpsc_base + MPSC_0_CHR_10_OFFSET + 2, c);
	out_le32(mpsc_intr_cause, cause & ~MPSC_INTR_CAUSE_RCC);
	return c;
}

static int mv64x60_udbg_getc_poll(void)
{
	if (!mv64x60_udbg_testc())
		return -1;

	return mv64x60_udbg_getc();
}

static void mv64x60_udbg_init(void)
{
	struct device_node *np, *mpscintr, *stdout = NULL;
	const char *path;
	const phandle *ph;
	struct resource r[2];
	const int *block_index;
	int intr_cause_offset;
	int err;

	path = of_get_property(of_chosen, "linux,stdout-path", NULL);
	if (!path)
		return;

	stdout = of_find_node_by_path(path);
	if (!stdout)
		return;

	for (np = NULL;
	     (np = of_find_compatible_node(np, "serial", "marvell,mpsc")); )
		if (np == stdout)
			break;

	of_node_put(stdout);
	if (!np)
		return;

	block_index = of_get_property(np, "block-index", NULL);
	if (!block_index)
		goto error;

	switch (*block_index) {
	case 0:
		intr_cause_offset = MPSC_INTR_CAUSE_OFF_0;
		break;
	case 1:
		intr_cause_offset = MPSC_INTR_CAUSE_OFF_1;
		break;
	default:
		goto error;
	}

	err = of_address_to_resource(np, 0, &r[0]);
	if (err)
		goto error;

	ph = of_get_property(np, "mpscintr", NULL);
	mpscintr = of_find_node_by_phandle(*ph);
	if (!mpscintr)
		goto error;

	err = of_address_to_resource(mpscintr, 0, &r[1]);
	of_node_put(mpscintr);
	if (err)
		goto error;

	of_node_put(np);

	mpsc_base = ioremap(r[0].start, r[0].end - r[0].start + 1);
	if (!mpsc_base)
		return;

	mpsc_intr_cause = ioremap(r[1].start, r[1].end - r[1].start + 1);
	if (!mpsc_intr_cause) {
		iounmap(mpsc_base);
		return;
	}
	mpsc_intr_cause += intr_cause_offset;

	udbg_putc = mv64x60_udbg_putc;
	udbg_getc = mv64x60_udbg_getc;
	udbg_getc_poll = mv64x60_udbg_getc_poll;

	return;

error:
	of_node_put(np);
}

void mv64x60_init_early(void)
{
	mv64x60_udbg_init();
}
