linux/arch/mips/netlogic/xlr/platform.c
<<
>>
Prefs
   1/*
   2 * Copyright 2011, Netlogic Microsystems.
   3 * Copyright 2004, Matt Porter <mporter@kernel.crashing.org>
   4 *
   5 * This file is licensed under the terms of the GNU General Public
   6 * License version 2.  This program is licensed "as is" without any
   7 * warranty of any kind, whether express or implied.
   8 */
   9
  10#include <linux/device.h>
  11#include <linux/platform_device.h>
  12#include <linux/kernel.h>
  13#include <linux/init.h>
  14#include <linux/resource.h>
  15#include <linux/serial_8250.h>
  16#include <linux/serial_reg.h>
  17#include <linux/i2c.h>
  18#include <linux/usb/ehci_pdriver.h>
  19#include <linux/usb/ohci_pdriver.h>
  20
  21#include <asm/netlogic/haldefs.h>
  22#include <asm/netlogic/xlr/iomap.h>
  23#include <asm/netlogic/xlr/pic.h>
  24#include <asm/netlogic/xlr/xlr.h>
  25
  26static unsigned int nlm_xlr_uart_in(struct uart_port *p, int offset)
  27{
  28        uint64_t uartbase;
  29        unsigned int value;
  30
  31        /* sign extend to 64 bits, if needed */
  32        uartbase = (uint64_t)(long)p->membase;
  33        value = nlm_read_reg(uartbase, offset);
  34
  35        /* See XLR/XLS errata */
  36        if (offset == UART_MSR)
  37                value ^= 0xF0;
  38        else if (offset == UART_MCR)
  39                value ^= 0x3;
  40
  41        return value;
  42}
  43
  44static void nlm_xlr_uart_out(struct uart_port *p, int offset, int value)
  45{
  46        uint64_t uartbase;
  47
  48        /* sign extend to 64 bits, if needed */
  49        uartbase = (uint64_t)(long)p->membase;
  50
  51        /* See XLR/XLS errata */
  52        if (offset == UART_MSR)
  53                value ^= 0xF0;
  54        else if (offset == UART_MCR)
  55                value ^= 0x3;
  56
  57        nlm_write_reg(uartbase, offset, value);
  58}
  59
  60#define PORT(_irq)                                      \
  61        {                                               \
  62                .irq            = _irq,                 \
  63                .regshift       = 2,                    \
  64                .iotype         = UPIO_MEM32,           \
  65                .flags          = (UPF_SKIP_TEST |      \
  66                         UPF_FIXED_TYPE | UPF_BOOT_AUTOCONF),\
  67                .uartclk        = PIC_CLK_HZ,           \
  68                .type           = PORT_16550A,          \
  69                .serial_in      = nlm_xlr_uart_in,      \
  70                .serial_out     = nlm_xlr_uart_out,     \
  71        }
  72
  73static struct plat_serial8250_port xlr_uart_data[] = {
  74        PORT(PIC_UART_0_IRQ),
  75        PORT(PIC_UART_1_IRQ),
  76        {},
  77};
  78
  79static struct platform_device uart_device = {
  80        .name           = "serial8250",
  81        .id             = PLAT8250_DEV_PLATFORM,
  82        .dev = {
  83                .platform_data = xlr_uart_data,
  84        },
  85};
  86
  87static int __init nlm_uart_init(void)
  88{
  89        unsigned long uartbase;
  90
  91        uartbase = (unsigned long)nlm_mmio_base(NETLOGIC_IO_UART_0_OFFSET);
  92        xlr_uart_data[0].membase = (void __iomem *)uartbase;
  93        xlr_uart_data[0].mapbase = CPHYSADDR(uartbase);
  94
  95        uartbase = (unsigned long)nlm_mmio_base(NETLOGIC_IO_UART_1_OFFSET);
  96        xlr_uart_data[1].membase = (void __iomem *)uartbase;
  97        xlr_uart_data[1].mapbase = CPHYSADDR(uartbase);
  98
  99        return platform_device_register(&uart_device);
 100}
 101
 102arch_initcall(nlm_uart_init);
 103
 104#ifdef CONFIG_USB
 105/* Platform USB devices, only on XLS chips */
 106static u64 xls_usb_dmamask = ~(u32)0;
 107#define USB_PLATFORM_DEV(n, i, irq)                                     \
 108        {                                                               \
 109                .name           = n,                                    \
 110                .id             = i,                                    \
 111                .num_resources  = 2,                                    \
 112                .dev            = {                                     \
 113                        .dma_mask       = &xls_usb_dmamask,             \
 114                        .coherent_dma_mask = 0xffffffff,                \
 115                },                                                      \
 116                .resource       = (struct resource[]) {                 \
 117                        {                                               \
 118                                .flags = IORESOURCE_MEM,                \
 119                        },                                              \
 120                        {                                               \
 121                                .start  = irq,                          \
 122                                .end    = irq,                          \
 123                                .flags = IORESOURCE_IRQ,                \
 124                        },                                              \
 125                },                                                      \
 126        }
 127
 128static struct usb_ehci_pdata xls_usb_ehci_pdata = {
 129        .caps_offset    = 0,
 130};
 131
 132static struct usb_ohci_pdata xls_usb_ohci_pdata;
 133
 134static struct platform_device xls_usb_ehci_device =
 135                         USB_PLATFORM_DEV("ehci-platform", 0, PIC_USB_IRQ);
 136static struct platform_device xls_usb_ohci_device_0 =
 137                         USB_PLATFORM_DEV("ohci-platform", 1, PIC_USB_IRQ);
 138static struct platform_device xls_usb_ohci_device_1 =
 139                         USB_PLATFORM_DEV("ohci-platform", 2, PIC_USB_IRQ);
 140
 141static struct platform_device *xls_platform_devices[] = {
 142        &xls_usb_ehci_device,
 143        &xls_usb_ohci_device_0,
 144        &xls_usb_ohci_device_1,
 145};
 146
 147int xls_platform_usb_init(void)
 148{
 149        uint64_t usb_mmio, gpio_mmio;
 150        unsigned long memres;
 151        uint32_t val;
 152
 153        if (!nlm_chip_is_xls())
 154                return 0;
 155
 156        gpio_mmio = nlm_mmio_base(NETLOGIC_IO_GPIO_OFFSET);
 157        usb_mmio  = nlm_mmio_base(NETLOGIC_IO_USB_1_OFFSET);
 158
 159        /* Clear Rogue Phy INTs */
 160        nlm_write_reg(usb_mmio, 49, 0x10000000);
 161        /* Enable all interrupts */
 162        nlm_write_reg(usb_mmio, 50, 0x1f000000);
 163
 164        /* Enable ports */
 165        nlm_write_reg(usb_mmio,  1, 0x07000500);
 166
 167        val = nlm_read_reg(gpio_mmio, 21);
 168        if (((val >> 22) & 0x01) == 0) {
 169                pr_info("Detected USB Device mode - Not supported!\n");
 170                nlm_write_reg(usb_mmio,  0, 0x01000000);
 171                return 0;
 172        }
 173
 174        pr_info("Detected USB Host mode - Adding XLS USB devices.\n");
 175        /* Clear reset, host mode */
 176        nlm_write_reg(usb_mmio,  0, 0x02000000);
 177
 178        /* Memory resource for various XLS usb ports */
 179        usb_mmio = nlm_mmio_base(NETLOGIC_IO_USB_0_OFFSET);
 180        memres = CPHYSADDR((unsigned long)usb_mmio);
 181        xls_usb_ehci_device.resource[0].start = memres;
 182        xls_usb_ehci_device.resource[0].end = memres + 0x400 - 1;
 183        xls_usb_ehci_device.dev.platform_data = &xls_usb_ehci_pdata;
 184
 185        memres += 0x400;
 186        xls_usb_ohci_device_0.resource[0].start = memres;
 187        xls_usb_ohci_device_0.resource[0].end = memres + 0x400 - 1;
 188        xls_usb_ohci_device_0.dev.platform_data = &xls_usb_ohci_pdata;
 189
 190        memres += 0x400;
 191        xls_usb_ohci_device_1.resource[0].start = memres;
 192        xls_usb_ohci_device_1.resource[0].end = memres + 0x400 - 1;
 193        xls_usb_ohci_device_1.dev.platform_data = &xls_usb_ohci_pdata;
 194
 195        return platform_add_devices(xls_platform_devices,
 196                                ARRAY_SIZE(xls_platform_devices));
 197}
 198
 199arch_initcall(xls_platform_usb_init);
 200#endif
 201
 202#ifdef CONFIG_I2C
 203static struct i2c_board_info nlm_i2c_board_info1[] __initdata = {
 204        /* All XLR boards have this RTC and Max6657 Temp Chip */
 205        [0] = {
 206                .type   = "ds1374",
 207                .addr   = 0x68
 208        },
 209        [1] = {
 210                .type   = "lm90",
 211                .addr   = 0x4c
 212        },
 213};
 214
 215static struct resource i2c_resources[] = {
 216        [0] = {
 217                .start  = 0,    /* filled at init */
 218                .end    = 0,
 219                .flags  = IORESOURCE_MEM,
 220        },
 221};
 222
 223static struct platform_device nlm_xlr_i2c_1 = {
 224        .name           = "xlr-i2cbus",
 225        .id             = 1,
 226        .num_resources  = 1,
 227        .resource       = i2c_resources,
 228};
 229
 230static int __init nlm_i2c_init(void)
 231{
 232        int err = 0;
 233        unsigned int offset;
 234
 235        /* I2C bus 0 does not have any useful devices, configure only bus 1 */
 236        offset = NETLOGIC_IO_I2C_1_OFFSET;
 237        nlm_xlr_i2c_1.resource[0].start = CPHYSADDR(nlm_mmio_base(offset));
 238        nlm_xlr_i2c_1.resource[0].end = nlm_xlr_i2c_1.resource[0].start + 0xfff;
 239
 240        platform_device_register(&nlm_xlr_i2c_1);
 241
 242        err = i2c_register_board_info(1, nlm_i2c_board_info1,
 243                                ARRAY_SIZE(nlm_i2c_board_info1));
 244        if (err < 0)
 245                pr_err("nlm-i2c: cannot register board I2C devices\n");
 246        return err;
 247}
 248
 249arch_initcall(nlm_i2c_init);
 250#endif
 251