/*
 * arch/arm/mach-omap2/serial.c
 *
 * OMAP2 serial support.
 *
 * Copyright (C) 2005 Nokia Corporation
 * Author: Paul Mundt <paul.mundt@nokia.com>
 *
 * Based off of arch/arm/mach-omap/omap1/serial.c
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License. See the file "COPYING" in the main directory of this archive
 * for more details.
 */
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/serial_8250.h>
#include <linux/serial_reg.h>
#include <linux/clk.h>

#include <asm/io.h>

#include <asm/arch/common.h>
#include <asm/arch/board.h>

static struct clk * uart1_ick = NULL;
static struct clk * uart1_fck = NULL;
static struct clk * uart2_ick = NULL;
static struct clk * uart2_fck = NULL;
static struct clk * uart3_ick = NULL;
static struct clk * uart3_fck = NULL;

static struct plat_serial8250_port serial_platform_data[] = {
	{
		.membase	= (char *)IO_ADDRESS(OMAP_UART1_BASE),
		.mapbase	= (unsigned long)OMAP_UART1_BASE,
		.irq		= 72,
		.flags		= UPF_BOOT_AUTOCONF,
		.iotype		= UPIO_MEM,
		.regshift	= 2,
		.uartclk	= OMAP16XX_BASE_BAUD * 16,
	}, {
		.membase	= (char *)IO_ADDRESS(OMAP_UART2_BASE),
		.mapbase	= (unsigned long)OMAP_UART2_BASE,
		.irq		= 73,
		.flags		= UPF_BOOT_AUTOCONF,
		.iotype		= UPIO_MEM,
		.regshift	= 2,
		.uartclk	= OMAP16XX_BASE_BAUD * 16,
	}, {
		.membase	= (char *)IO_ADDRESS(OMAP_UART3_BASE),
		.mapbase	= (unsigned long)OMAP_UART3_BASE,
		.irq		= 74,
		.flags		= UPF_BOOT_AUTOCONF,
		.iotype		= UPIO_MEM,
		.regshift	= 2,
		.uartclk	= OMAP16XX_BASE_BAUD * 16,
	}, {
		.flags		= 0
	}
};

static inline unsigned int serial_read_reg(struct plat_serial8250_port *up,
					   int offset)
{
	offset <<= up->regshift;
	return (unsigned int)__raw_readb(up->membase + offset);
}

static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
				    int value)
{
	offset <<= p->regshift;
	__raw_writeb(value, (unsigned long)(p->membase + offset));
}

/*
 * Internal UARTs need to be initialized for the 8250 autoconfig to work
 * properly. Note that the TX watermark initialization may not be needed
 * once the 8250.c watermark handling code is merged.
 */
static inline void __init omap_serial_reset(struct plat_serial8250_port *p)
{
	serial_write_reg(p, UART_OMAP_MDR1, 0x07);
	serial_write_reg(p, UART_OMAP_SCR, 0x08);
	serial_write_reg(p, UART_OMAP_MDR1, 0x00);
	serial_write_reg(p, UART_OMAP_SYSC, (0x02 << 3) | (1 << 2) | (1 << 0));
}

void __init omap_serial_init()
{
	int i;
	const struct omap_uart_config *info;

	/*
	 * Make sure the serial ports are muxed on at this point.
	 * You have to mux them off in device drivers later on
	 * if not needed.
	 */

	info = omap_get_config(OMAP_TAG_UART,
			       struct omap_uart_config);

	if (info == NULL)
		return;

	for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
		struct plat_serial8250_port *p = serial_platform_data + i;

		if (!(info->enabled_uarts & (1 << i))) {
			p->membase = 0;
			p->mapbase = 0;
			continue;
		}

		switch (i) {
		case 0:
			uart1_ick = clk_get(NULL, "uart1_ick");
			if (IS_ERR(uart1_ick))
				printk("Could not get uart1_ick\n");
			else {
				clk_enable(uart1_ick);
			}

			uart1_fck = clk_get(NULL, "uart1_fck");
			if (IS_ERR(uart1_fck))
				printk("Could not get uart1_fck\n");
			else {
				clk_enable(uart1_fck);
			}
			break;
		case 1:
			uart2_ick = clk_get(NULL, "uart2_ick");
			if (IS_ERR(uart2_ick))
				printk("Could not get uart2_ick\n");
			else {
				clk_enable(uart2_ick);
			}

			uart2_fck = clk_get(NULL, "uart2_fck");
			if (IS_ERR(uart2_fck))
				printk("Could not get uart2_fck\n");
			else {
				clk_enable(uart2_fck);
			}
			break;
		case 2:
			uart3_ick = clk_get(NULL, "uart3_ick");
			if (IS_ERR(uart3_ick))
				printk("Could not get uart3_ick\n");
			else {
				clk_enable(uart3_ick);
			}

			uart3_fck = clk_get(NULL, "uart3_fck");
			if (IS_ERR(uart3_fck))
				printk("Could not get uart3_fck\n");
			else {
				clk_enable(uart3_fck);
			}
			break;
		}

		omap_serial_reset(p);
	}
}

static struct platform_device serial_device = {
	.name			= "serial8250",
	.id			= PLAT8250_DEV_PLATFORM,
	.dev			= {
		.platform_data	= serial_platform_data,
	},
};

static int __init omap_init(void)
{
	return platform_device_register(&serial_device);
}
arch_initcall(omap_init);
