blob: 21021e973793d43bba3402fe7c3a38764da6d15c [file] [log] [blame]
/*
* Copyright (C) 2007 Imagination Technologies
*/
#include <linux/dma-mapping.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/of_platform.h>
#include <linux/serial_8250.h>
#include <linux/fsl_devices.h>
#include <linux/spi/spi_img.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/mach/arch.h>
#include <asm/soc-chorus2/c2_irqnums.h>
#include <asm/soc-chorus2/gpio.h>
#include <asm/soc-chorus2/setup.h>
#define CHORUS2_UART_REF_CLK 0x020000A4
#define CHORUS2_UART_ENABLE 0x4
/* USB starts at this address, EHCI regs are 0x100 above */
#define CHORUS2_USB_BASE 0x0200C000
#define CHORUS2_USB_LEN 0x00001000
#define EHCI_OFFSET 0x00000100
#define CHORUS2_EHCI_BASE (CHORUS2_USB_BASE + EHCI_OFFSET)
#define CHORUS2_EHCI_LEN (CHORUS2_USB_LEN - EHCI_OFFSET)
#define CHORUS2_SPI1_HWBASE 0x02008000
#define CHORUS2_SCBA_BASE 0x0200A000
#define CHORUS2_SCBB_BASE 0x0200B000
#define MISC_CLOCK_CTRL_REG 0x020000bc
#define DMATRIG_SPI1O_NUM 10 /* SPI 1 output DMA */
#define DMATRIG_SPI1I_NUM 11 /* SPI 1 input DMA */
static void __init chorus2_serial_init(void)
{
chorus2_gpio_disable(GPIO_E_PIN(8)); /* S1 In */
chorus2_gpio_disable(GPIO_E_PIN(9)); /* S1 Out */
/* Enable the UART clock - set for the default 1.8432 MHz */
writel(CHORUS2_UART_ENABLE, CHORUS2_UART_REF_CLK);
}
#ifdef CONFIG_USB_EHCI_HCD
static struct resource usb_resources[] = {
[0] = {
.start = CHORUS2_EHCI_BASE,
.end = CHORUS2_EHCI_BASE + CHORUS2_EHCI_LEN - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = USB_IRQ_NUM,
/* mapped in chorus2_usb_init() */
.flags = IORESOURCE_IRQ,
},
};
static u64 ehci_dmamask = DMA_BIT_MASK(32);
static struct platform_device usb_device = {
.name = "chorus2-ehci",
.id = 0,
.dev = {
.dma_mask = &ehci_dmamask,
.coherent_dma_mask = 0xffffffff,
},
.num_resources = ARRAY_SIZE(usb_resources),
.resource = usb_resources,
};
#else
static struct resource usb_resources[] = {
[0] = {
.start = CHORUS2_USB_BASE,
.end = CHORUS2_USB_BASE + CHORUS2_USB_LEN - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = USB_IRQ_NUM,
/* mapped in chorus2_usb_init() */
.flags = IORESOURCE_IRQ,
},
};
static struct fsl_usb2_platform_data fsl_usb_data = {
.operating_mode = FSL_USB2_DR_DEVICE,
.phy_mode = FSL_USB2_PHY_UTMI,
};
static u64 fsl_usb_dmamask = DMA_BIT_MASK(32);
static struct platform_device usb_device = {
.name = "fsl-usb2-udc",
.id = 0,
.dev = {
.dma_mask = &fsl_usb_dmamask,
.coherent_dma_mask = 0xffffffff,
.platform_data = &fsl_usb_data,
},
.num_resources = ARRAY_SIZE(usb_resources),
.resource = usb_resources,
};
#endif
static void __init chorus2_usb_init(void)
{
int irq;
u32 val;
/* Map the IRQ */
irq = external_irq_map(usb_resources[1].start);
if (irq < 0) {
pr_err("%s: irq map failed (%d)\n",
__func__, irq);
return;
}
usb_resources[1].start = irq;
usb_resources[1].end = irq;
/*
* Rev C and later silicon require this bit to be set to disable
* IDDQ mode.
*/
val = readl(MISC_CLOCK_CTRL_REG);
writel(val | 0x2, MISC_CLOCK_CTRL_REG);
platform_device_register(&usb_device);
}
static struct resource spi_resources[] = {
[0] = {
.start = SPI1_DMAR_IRQ_NUM,
/* mapped in chorus2_spi_init() */
.flags = IORESOURCE_IRQ,
},
[1] = {
.start = CHORUS2_SPI1_HWBASE,
.end = CHORUS2_SPI1_HWBASE + 0xfff,
.flags = IORESOURCE_MEM,
},
};
static struct img_spi_master spi_platform_data = {
.num_chipselect = 3,
.tx_dma_channel_num = -1, /*auto allocate*/
.tx_dma_peripheral_num = DMATRIG_SPI1O_NUM,
.rx_dma_channel_num = -1,
.rx_dma_peripheral_num = DMATRIG_SPI1I_NUM,
};
static u64 spi_dmamask = DMA_BIT_MASK(32);
static struct platform_device spi_master_device = {
.name = "img-spi",
.id = 0,
.num_resources = ARRAY_SIZE(spi_resources),
.resource = spi_resources,
.dev = {
.dma_mask = &spi_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(64),
.platform_data = &spi_platform_data, /* Passed to driver */
},
};
static void __init chorus2_spi_init(void)
{
int irq;
/* Map the IRQ */
irq = external_irq_map(spi_resources[0].start);
if (irq < 0) {
pr_err("%s: irq map failed (%d)\n",
__func__, irq);
return;
}
spi_resources[0].start = irq;
spi_resources[0].end = irq;
platform_device_register(&spi_master_device);
}
static struct platform_device asoc_device = {
.name = "chorus2-pcm-audio",
.id = -1,
};
static struct platform_device *chorus2_devices[] __initdata = {
&asoc_device,
};
void __init chorus2_init_machine(void)
{
chorus2_serial_init();
chorus2_usb_init();
chorus2_spi_init();
platform_add_devices(chorus2_devices, ARRAY_SIZE(chorus2_devices));
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
}
static const char *chorus2_boards_compat[] __initdata = {
"frontier,chorus2",
NULL,
};
MACHINE_START(CHORUS2, "Generic Chorus2")
.dt_compat = chorus2_boards_compat,
CHORUS2_MACHINE_DEFAULTS,
MACHINE_END