/*
 * Copyright 2011, Netlogic Microsystems.
 * Copyright 2004, Matt Porter <mporter@kernel.crashing.org>
 *
 * 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 <linux/device.h>
#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/resource.h>
#include <linux/serial_8250.h>
#include <linux/serial_reg.h>
#include <linux/i2c.h>
#include <linux/usb/ehci_pdriver.h>
#include <linux/usb/ohci_pdriver.h>

#include <asm/netlogic/haldefs.h>
#include <asm/netlogic/xlr/iomap.h>
#include <asm/netlogic/xlr/pic.h>
#include <asm/netlogic/xlr/xlr.h>

static unsigned int nlm_xlr_uart_in(struct uart_port *p, int offset)
{
	uint64_t uartbase;
	unsigned int value;

	/* sign extend to 64 bits, if needed */
	uartbase = (uint64_t)(long)p->membase;
	value = nlm_read_reg(uartbase, offset);

	/* See XLR/XLS errata */
	if (offset == UART_MSR)
		value ^= 0xF0;
	else if (offset == UART_MCR)
		value ^= 0x3;

	return value;
}

static void nlm_xlr_uart_out(struct uart_port *p, int offset, int value)
{
	uint64_t uartbase;

	/* sign extend to 64 bits, if needed */
	uartbase = (uint64_t)(long)p->membase;

	/* See XLR/XLS errata */
	if (offset == UART_MSR)
		value ^= 0xF0;
	else if (offset == UART_MCR)
		value ^= 0x3;

	nlm_write_reg(uartbase, offset, value);
}

#define PORT(_irq)					\
	{						\
		.irq		= _irq,			\
		.regshift	= 2,			\
		.iotype		= UPIO_MEM32,		\
		.flags		= (UPF_SKIP_TEST |	\
			 UPF_FIXED_TYPE | UPF_BOOT_AUTOCONF),\
		.uartclk	= PIC_CLK_HZ,		\
		.type		= PORT_16550A,		\
		.serial_in	= nlm_xlr_uart_in,	\
		.serial_out	= nlm_xlr_uart_out,	\
	}

static struct plat_serial8250_port xlr_uart_data[] = {
	PORT(PIC_UART_0_IRQ),
	PORT(PIC_UART_1_IRQ),
	{},
};

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

static int __init nlm_uart_init(void)
{
	unsigned long uartbase;

	uartbase = (unsigned long)nlm_mmio_base(NETLOGIC_IO_UART_0_OFFSET);
	xlr_uart_data[0].membase = (void __iomem *)uartbase;
	xlr_uart_data[0].mapbase = CPHYSADDR(uartbase);

	uartbase = (unsigned long)nlm_mmio_base(NETLOGIC_IO_UART_1_OFFSET);
	xlr_uart_data[1].membase = (void __iomem *)uartbase;
	xlr_uart_data[1].mapbase = CPHYSADDR(uartbase);

	return platform_device_register(&uart_device);
}

arch_initcall(nlm_uart_init);

#ifdef CONFIG_USB
/* Platform USB devices, only on XLS chips */
static u64 xls_usb_dmamask = ~(u32)0;
#define USB_PLATFORM_DEV(n, i, irq)					\
	{								\
		.name		= n,					\
		.id		= i,					\
		.num_resources	= 2,					\
		.dev		= {					\
			.dma_mask	= &xls_usb_dmamask,		\
			.coherent_dma_mask = 0xffffffff,		\
		},							\
		.resource	= (struct resource[]) {			\
			{						\
				.flags = IORESOURCE_MEM,		\
			},						\
			{						\
				.start	= irq,				\
				.end	= irq,				\
				.flags = IORESOURCE_IRQ,		\
			},						\
		},							\
	}

static struct usb_ehci_pdata xls_usb_ehci_pdata = {
	.caps_offset	= 0,
};

static struct usb_ohci_pdata xls_usb_ohci_pdata;

static struct platform_device xls_usb_ehci_device =
			 USB_PLATFORM_DEV("ehci-platform", 0, PIC_USB_IRQ);
static struct platform_device xls_usb_ohci_device_0 =
			 USB_PLATFORM_DEV("ohci-platform", 1, PIC_USB_IRQ);
static struct platform_device xls_usb_ohci_device_1 =
			 USB_PLATFORM_DEV("ohci-platform", 2, PIC_USB_IRQ);

static struct platform_device *xls_platform_devices[] = {
	&xls_usb_ehci_device,
	&xls_usb_ohci_device_0,
	&xls_usb_ohci_device_1,
};

int xls_platform_usb_init(void)
{
	uint64_t usb_mmio, gpio_mmio;
	unsigned long memres;
	uint32_t val;

	if (!nlm_chip_is_xls())
		return 0;

	gpio_mmio = nlm_mmio_base(NETLOGIC_IO_GPIO_OFFSET);
	usb_mmio  = nlm_mmio_base(NETLOGIC_IO_USB_1_OFFSET);

	/* Clear Rogue Phy INTs */
	nlm_write_reg(usb_mmio, 49, 0x10000000);
	/* Enable all interrupts */
	nlm_write_reg(usb_mmio, 50, 0x1f000000);

	/* Enable ports */
	nlm_write_reg(usb_mmio,	 1, 0x07000500);

	val = nlm_read_reg(gpio_mmio, 21);
	if (((val >> 22) & 0x01) == 0) {
		pr_info("Detected USB Device mode - Not supported!\n");
		nlm_write_reg(usb_mmio,	 0, 0x01000000);
		return 0;
	}

	pr_info("Detected USB Host mode - Adding XLS USB devices.\n");
	/* Clear reset, host mode */
	nlm_write_reg(usb_mmio,	 0, 0x02000000);

	/* Memory resource for various XLS usb ports */
	usb_mmio = nlm_mmio_base(NETLOGIC_IO_USB_0_OFFSET);
	memres = CPHYSADDR((unsigned long)usb_mmio);
	xls_usb_ehci_device.resource[0].start = memres;
	xls_usb_ehci_device.resource[0].end = memres + 0x400 - 1;
	xls_usb_ehci_device.dev.platform_data = &xls_usb_ehci_pdata;

	memres += 0x400;
	xls_usb_ohci_device_0.resource[0].start = memres;
	xls_usb_ohci_device_0.resource[0].end = memres + 0x400 - 1;
	xls_usb_ohci_device_0.dev.platform_data = &xls_usb_ohci_pdata;

	memres += 0x400;
	xls_usb_ohci_device_1.resource[0].start = memres;
	xls_usb_ohci_device_1.resource[0].end = memres + 0x400 - 1;
	xls_usb_ohci_device_1.dev.platform_data = &xls_usb_ohci_pdata;

	return platform_add_devices(xls_platform_devices,
				ARRAY_SIZE(xls_platform_devices));
}

arch_initcall(xls_platform_usb_init);
#endif

#ifdef CONFIG_I2C
static struct i2c_board_info nlm_i2c_board_info1[] __initdata = {
	/* All XLR boards have this RTC and Max6657 Temp Chip */
	[0] = {
		.type	= "ds1374",
		.addr	= 0x68
	},
	[1] = {
		.type	= "lm90",
		.addr	= 0x4c
	},
};

static struct resource i2c_resources[] = {
	[0] = {
		.start	= 0,	/* filled at init */
		.end	= 0,
		.flags	= IORESOURCE_MEM,
	},
};

static struct platform_device nlm_xlr_i2c_1 = {
	.name		= "xlr-i2cbus",
	.id		= 1,
	.num_resources	= 1,
	.resource	= i2c_resources,
};

static int __init nlm_i2c_init(void)
{
	int err = 0;
	unsigned int offset;

	/* I2C bus 0 does not have any useful devices, configure only bus 1 */
	offset = NETLOGIC_IO_I2C_1_OFFSET;
	nlm_xlr_i2c_1.resource[0].start = CPHYSADDR(nlm_mmio_base(offset));
	nlm_xlr_i2c_1.resource[0].end = nlm_xlr_i2c_1.resource[0].start + 0xfff;

	platform_device_register(&nlm_xlr_i2c_1);

	err = i2c_register_board_info(1, nlm_i2c_board_info1,
				ARRAY_SIZE(nlm_i2c_board_info1));
	if (err < 0)
		pr_err("nlm-i2c: cannot register board I2C devices\n");
	return err;
}

arch_initcall(nlm_i2c_init);
#endif
