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