linux/arch/arm/mach-cns3xxx/cns3420vb.c
<<
>>
Prefs
   1/*
   2 * Cavium Networks CNS3420 Validation Board
   3 *
   4 * Copyright 2000 Deep Blue Solutions Ltd
   5 * Copyright 2008 ARM Limited
   6 * Copyright 2008 Cavium Networks
   7 *                Scott Shu
   8 * Copyright 2010 MontaVista Software, LLC.
   9 *                Anton Vorontsov <avorontsov@mvista.com>
  10 *
  11 * This file is free software; you can redistribute it and/or modify
  12 * it under the terms of the GNU General Public License, Version 2, as
  13 * published by the Free Software Foundation.
  14 */
  15
  16#include <linux/init.h>
  17#include <linux/kernel.h>
  18#include <linux/compiler.h>
  19#include <linux/io.h>
  20#include <linux/dma-mapping.h>
  21#include <linux/serial_core.h>
  22#include <linux/serial_8250.h>
  23#include <linux/platform_device.h>
  24#include <linux/mtd/mtd.h>
  25#include <linux/mtd/physmap.h>
  26#include <linux/mtd/partitions.h>
  27#include <linux/usb/ehci_pdriver.h>
  28#include <linux/usb/ohci_pdriver.h>
  29#include <asm/setup.h>
  30#include <asm/mach-types.h>
  31#include <asm/mach/arch.h>
  32#include <asm/mach/map.h>
  33#include <asm/mach/time.h>
  34#include "cns3xxx.h"
  35#include "pm.h"
  36#include "core.h"
  37#include "devices.h"
  38
  39/*
  40 * NOR Flash
  41 */
  42static struct mtd_partition cns3420_nor_partitions[] = {
  43        {
  44                .name           = "uboot",
  45                .size           = 0x00040000,
  46                .offset         = 0,
  47                .mask_flags     = MTD_WRITEABLE,
  48        }, {
  49                .name           = "kernel",
  50                .size           = 0x004C0000,
  51                .offset         = MTDPART_OFS_APPEND,
  52        }, {
  53                .name           = "filesystem",
  54                .size           = 0x7000000,
  55                .offset         = MTDPART_OFS_APPEND,
  56        }, {
  57                .name           = "filesystem2",
  58                .size           = 0x0AE0000,
  59                .offset         = MTDPART_OFS_APPEND,
  60        }, {
  61                .name           = "ubootenv",
  62                .size           = MTDPART_SIZ_FULL,
  63                .offset         = MTDPART_OFS_APPEND,
  64        },
  65};
  66
  67static struct physmap_flash_data cns3420_nor_pdata = {
  68        .width = 2,
  69        .parts = cns3420_nor_partitions,
  70        .nr_parts = ARRAY_SIZE(cns3420_nor_partitions),
  71};
  72
  73static struct resource cns3420_nor_res = {
  74        .start = CNS3XXX_FLASH_BASE,
  75        .end = CNS3XXX_FLASH_BASE + SZ_128M - 1,
  76        .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
  77};
  78
  79static struct platform_device cns3420_nor_pdev = {
  80        .name = "physmap-flash",
  81        .id = 0,
  82        .resource = &cns3420_nor_res,
  83        .num_resources = 1,
  84        .dev = {
  85                .platform_data = &cns3420_nor_pdata,
  86        },
  87};
  88
  89/*
  90 * UART
  91 */
  92static void __init cns3420_early_serial_setup(void)
  93{
  94#ifdef CONFIG_SERIAL_8250_CONSOLE
  95        static struct uart_port cns3420_serial_port = {
  96                .membase        = (void __iomem *)CNS3XXX_UART0_BASE_VIRT,
  97                .mapbase        = CNS3XXX_UART0_BASE,
  98                .irq            = IRQ_CNS3XXX_UART0,
  99                .iotype         = UPIO_MEM,
 100                .flags          = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE,
 101                .regshift       = 2,
 102                .uartclk        = 24000000,
 103                .line           = 0,
 104                .type           = PORT_16550A,
 105                .fifosize       = 16,
 106        };
 107
 108        early_serial_setup(&cns3420_serial_port);
 109#endif
 110}
 111
 112/*
 113 * USB
 114 */
 115static struct resource cns3xxx_usb_ehci_resources[] = {
 116        [0] = {
 117                .start = CNS3XXX_USB_BASE,
 118                .end   = CNS3XXX_USB_BASE + SZ_16M - 1,
 119                .flags = IORESOURCE_MEM,
 120        },
 121        [1] = {
 122                .start = IRQ_CNS3XXX_USB_EHCI,
 123                .flags = IORESOURCE_IRQ,
 124        },
 125};
 126
 127static u64 cns3xxx_usb_ehci_dma_mask = DMA_BIT_MASK(32);
 128
 129static int csn3xxx_usb_power_on(struct platform_device *pdev)
 130{
 131        /*
 132         * EHCI and OHCI share the same clock and power,
 133         * resetting twice would cause the 1st controller been reset.
 134         * Therefore only do power up  at the first up device, and
 135         * power down at the last down device.
 136         *
 137         * Set USB AHB INCR length to 16
 138         */
 139        if (atomic_inc_return(&usb_pwr_ref) == 1) {
 140                cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
 141                cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
 142                cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST);
 143                __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)),
 144                        MISC_CHIP_CONFIG_REG);
 145        }
 146
 147        return 0;
 148}
 149
 150static void csn3xxx_usb_power_off(struct platform_device *pdev)
 151{
 152        /*
 153         * EHCI and OHCI share the same clock and power,
 154         * resetting twice would cause the 1st controller been reset.
 155         * Therefore only do power up  at the first up device, and
 156         * power down at the last down device.
 157         */
 158        if (atomic_dec_return(&usb_pwr_ref) == 0)
 159                cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
 160}
 161
 162static struct usb_ehci_pdata cns3xxx_usb_ehci_pdata = {
 163        .power_on       = csn3xxx_usb_power_on,
 164        .power_off      = csn3xxx_usb_power_off,
 165};
 166
 167static struct platform_device cns3xxx_usb_ehci_device = {
 168        .name          = "ehci-platform",
 169        .num_resources = ARRAY_SIZE(cns3xxx_usb_ehci_resources),
 170        .resource      = cns3xxx_usb_ehci_resources,
 171        .dev           = {
 172                .dma_mask          = &cns3xxx_usb_ehci_dma_mask,
 173                .coherent_dma_mask = DMA_BIT_MASK(32),
 174                .platform_data     = &cns3xxx_usb_ehci_pdata,
 175        },
 176};
 177
 178static struct resource cns3xxx_usb_ohci_resources[] = {
 179        [0] = {
 180                .start = CNS3XXX_USB_OHCI_BASE,
 181                .end   = CNS3XXX_USB_OHCI_BASE + SZ_16M - 1,
 182                .flags = IORESOURCE_MEM,
 183        },
 184        [1] = {
 185                .start = IRQ_CNS3XXX_USB_OHCI,
 186                .flags = IORESOURCE_IRQ,
 187        },
 188};
 189
 190static u64 cns3xxx_usb_ohci_dma_mask = DMA_BIT_MASK(32);
 191
 192static struct usb_ohci_pdata cns3xxx_usb_ohci_pdata = {
 193        .num_ports      = 1,
 194        .power_on       = csn3xxx_usb_power_on,
 195        .power_off      = csn3xxx_usb_power_off,
 196};
 197
 198static struct platform_device cns3xxx_usb_ohci_device = {
 199        .name          = "ohci-platform",
 200        .num_resources = ARRAY_SIZE(cns3xxx_usb_ohci_resources),
 201        .resource      = cns3xxx_usb_ohci_resources,
 202        .dev           = {
 203                .dma_mask          = &cns3xxx_usb_ohci_dma_mask,
 204                .coherent_dma_mask = DMA_BIT_MASK(32),
 205                .platform_data     = &cns3xxx_usb_ohci_pdata,
 206        },
 207};
 208
 209/*
 210 * Initialization
 211 */
 212static struct platform_device *cns3420_pdevs[] __initdata = {
 213        &cns3420_nor_pdev,
 214        &cns3xxx_usb_ehci_device,
 215        &cns3xxx_usb_ohci_device,
 216};
 217
 218static void __init cns3420_init(void)
 219{
 220        cns3xxx_l2x0_init();
 221
 222        platform_add_devices(cns3420_pdevs, ARRAY_SIZE(cns3420_pdevs));
 223
 224        cns3xxx_ahci_init();
 225        cns3xxx_sdhci_init();
 226
 227        pm_power_off = cns3xxx_power_off;
 228}
 229
 230static struct map_desc cns3420_io_desc[] __initdata = {
 231        {
 232                .virtual        = CNS3XXX_UART0_BASE_VIRT,
 233                .pfn            = __phys_to_pfn(CNS3XXX_UART0_BASE),
 234                .length         = SZ_4K,
 235                .type           = MT_DEVICE,
 236        },
 237};
 238
 239static void __init cns3420_map_io(void)
 240{
 241        cns3xxx_map_io();
 242        iotable_init(cns3420_io_desc, ARRAY_SIZE(cns3420_io_desc));
 243
 244        cns3420_early_serial_setup();
 245}
 246
 247MACHINE_START(CNS3420VB, "Cavium Networks CNS3420 Validation Board")
 248        .atag_offset    = 0x100,
 249        .nr_irqs        = NR_IRQS_CNS3XXX,
 250        .map_io         = cns3420_map_io,
 251        .init_irq       = cns3xxx_init_irq,
 252        .init_time      = cns3xxx_timer_init,
 253        .init_machine   = cns3420_init,
 254        .restart        = cns3xxx_restart,
 255MACHINE_END
 256