Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Cavium Networks CNS3420 Validation Board
0004  *
0005  * Copyright 2000 Deep Blue Solutions Ltd
0006  * Copyright 2008 ARM Limited
0007  * Copyright 2008 Cavium Networks
0008  *        Scott Shu
0009  * Copyright 2010 MontaVista Software, LLC.
0010  *        Anton Vorontsov <avorontsov@mvista.com>
0011  */
0012 
0013 #include <linux/init.h>
0014 #include <linux/kernel.h>
0015 #include <linux/compiler.h>
0016 #include <linux/io.h>
0017 #include <linux/dma-mapping.h>
0018 #include <linux/serial_core.h>
0019 #include <linux/serial_8250.h>
0020 #include <linux/platform_device.h>
0021 #include <linux/mtd/mtd.h>
0022 #include <linux/mtd/physmap.h>
0023 #include <linux/mtd/partitions.h>
0024 #include <linux/usb/ehci_pdriver.h>
0025 #include <linux/usb/ohci_pdriver.h>
0026 #include <asm/setup.h>
0027 #include <asm/mach-types.h>
0028 #include <asm/mach/arch.h>
0029 #include <asm/mach/map.h>
0030 #include <asm/mach/time.h>
0031 #include "cns3xxx.h"
0032 #include "pm.h"
0033 #include "core.h"
0034 #include "devices.h"
0035 
0036 /*
0037  * NOR Flash
0038  */
0039 static struct mtd_partition cns3420_nor_partitions[] = {
0040     {
0041         .name       = "uboot",
0042         .size       = 0x00040000,
0043         .offset     = 0,
0044         .mask_flags = MTD_WRITEABLE,
0045     }, {
0046         .name       = "kernel",
0047         .size       = 0x004C0000,
0048         .offset     = MTDPART_OFS_APPEND,
0049     }, {
0050         .name       = "filesystem",
0051         .size       = 0x7000000,
0052         .offset     = MTDPART_OFS_APPEND,
0053     }, {
0054         .name       = "filesystem2",
0055         .size       = 0x0AE0000,
0056         .offset     = MTDPART_OFS_APPEND,
0057     }, {
0058         .name       = "ubootenv",
0059         .size       = MTDPART_SIZ_FULL,
0060         .offset     = MTDPART_OFS_APPEND,
0061     },
0062 };
0063 
0064 static struct physmap_flash_data cns3420_nor_pdata = {
0065     .width = 2,
0066     .parts = cns3420_nor_partitions,
0067     .nr_parts = ARRAY_SIZE(cns3420_nor_partitions),
0068 };
0069 
0070 static struct resource cns3420_nor_res = {
0071     .start = CNS3XXX_FLASH_BASE,
0072     .end = CNS3XXX_FLASH_BASE + SZ_128M - 1,
0073     .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
0074 };
0075 
0076 static struct platform_device cns3420_nor_pdev = {
0077     .name = "physmap-flash",
0078     .id = 0,
0079     .resource = &cns3420_nor_res,
0080     .num_resources = 1,
0081     .dev = {
0082         .platform_data = &cns3420_nor_pdata,
0083     },
0084 };
0085 
0086 /*
0087  * UART
0088  */
0089 static void __init cns3420_early_serial_setup(void)
0090 {
0091 #ifdef CONFIG_SERIAL_8250_CONSOLE
0092     static struct uart_port cns3420_serial_port = {
0093         .membase        = (void __iomem *)CNS3XXX_UART0_BASE_VIRT,
0094         .mapbase        = CNS3XXX_UART0_BASE,
0095         .irq            = IRQ_CNS3XXX_UART0,
0096         .iotype         = UPIO_MEM,
0097         .flags          = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE,
0098         .regshift       = 2,
0099         .uartclk        = 24000000,
0100         .line           = 0,
0101         .type           = PORT_16550A,
0102         .fifosize       = 16,
0103     };
0104 
0105     early_serial_setup(&cns3420_serial_port);
0106 #endif
0107 }
0108 
0109 /*
0110  * USB
0111  */
0112 static struct resource cns3xxx_usb_ehci_resources[] = {
0113     [0] = {
0114         .start = CNS3XXX_USB_BASE,
0115         .end   = CNS3XXX_USB_BASE + SZ_16M - 1,
0116         .flags = IORESOURCE_MEM,
0117     },
0118     [1] = {
0119         .start = IRQ_CNS3XXX_USB_EHCI,
0120         .flags = IORESOURCE_IRQ,
0121     },
0122 };
0123 
0124 static u64 cns3xxx_usb_ehci_dma_mask = DMA_BIT_MASK(32);
0125 
0126 static int csn3xxx_usb_power_on(struct platform_device *pdev)
0127 {
0128     /*
0129      * EHCI and OHCI share the same clock and power,
0130      * resetting twice would cause the 1st controller been reset.
0131      * Therefore only do power up  at the first up device, and
0132      * power down at the last down device.
0133      *
0134      * Set USB AHB INCR length to 16
0135      */
0136     if (atomic_inc_return(&usb_pwr_ref) == 1) {
0137         cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
0138         cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
0139         cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST);
0140         __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)),
0141             MISC_CHIP_CONFIG_REG);
0142     }
0143 
0144     return 0;
0145 }
0146 
0147 static void csn3xxx_usb_power_off(struct platform_device *pdev)
0148 {
0149     /*
0150      * EHCI and OHCI share the same clock and power,
0151      * resetting twice would cause the 1st controller been reset.
0152      * Therefore only do power up  at the first up device, and
0153      * power down at the last down device.
0154      */
0155     if (atomic_dec_return(&usb_pwr_ref) == 0)
0156         cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
0157 }
0158 
0159 static struct usb_ehci_pdata cns3xxx_usb_ehci_pdata = {
0160     .power_on   = csn3xxx_usb_power_on,
0161     .power_off  = csn3xxx_usb_power_off,
0162 };
0163 
0164 static struct platform_device cns3xxx_usb_ehci_device = {
0165     .name          = "ehci-platform",
0166     .num_resources = ARRAY_SIZE(cns3xxx_usb_ehci_resources),
0167     .resource      = cns3xxx_usb_ehci_resources,
0168     .dev           = {
0169         .dma_mask          = &cns3xxx_usb_ehci_dma_mask,
0170         .coherent_dma_mask = DMA_BIT_MASK(32),
0171         .platform_data     = &cns3xxx_usb_ehci_pdata,
0172     },
0173 };
0174 
0175 static struct resource cns3xxx_usb_ohci_resources[] = {
0176     [0] = {
0177         .start = CNS3XXX_USB_OHCI_BASE,
0178         .end   = CNS3XXX_USB_OHCI_BASE + SZ_16M - 1,
0179         .flags = IORESOURCE_MEM,
0180     },
0181     [1] = {
0182         .start = IRQ_CNS3XXX_USB_OHCI,
0183         .flags = IORESOURCE_IRQ,
0184     },
0185 };
0186 
0187 static u64 cns3xxx_usb_ohci_dma_mask = DMA_BIT_MASK(32);
0188 
0189 static struct usb_ohci_pdata cns3xxx_usb_ohci_pdata = {
0190     .num_ports  = 1,
0191     .power_on   = csn3xxx_usb_power_on,
0192     .power_off  = csn3xxx_usb_power_off,
0193 };
0194 
0195 static struct platform_device cns3xxx_usb_ohci_device = {
0196     .name          = "ohci-platform",
0197     .num_resources = ARRAY_SIZE(cns3xxx_usb_ohci_resources),
0198     .resource      = cns3xxx_usb_ohci_resources,
0199     .dev           = {
0200         .dma_mask          = &cns3xxx_usb_ohci_dma_mask,
0201         .coherent_dma_mask = DMA_BIT_MASK(32),
0202         .platform_data     = &cns3xxx_usb_ohci_pdata,
0203     },
0204 };
0205 
0206 /*
0207  * Initialization
0208  */
0209 static struct platform_device *cns3420_pdevs[] __initdata = {
0210     &cns3420_nor_pdev,
0211     &cns3xxx_usb_ehci_device,
0212     &cns3xxx_usb_ohci_device,
0213 };
0214 
0215 static void __init cns3420_init(void)
0216 {
0217     cns3xxx_l2x0_init();
0218 
0219     platform_add_devices(cns3420_pdevs, ARRAY_SIZE(cns3420_pdevs));
0220 
0221     cns3xxx_ahci_init();
0222     cns3xxx_sdhci_init();
0223 
0224     pm_power_off = cns3xxx_power_off;
0225 }
0226 
0227 static struct map_desc cns3420_io_desc[] __initdata = {
0228     {
0229         .virtual    = CNS3XXX_UART0_BASE_VIRT,
0230         .pfn        = __phys_to_pfn(CNS3XXX_UART0_BASE),
0231         .length     = SZ_4K,
0232         .type       = MT_DEVICE,
0233     },
0234 };
0235 
0236 static void __init cns3420_map_io(void)
0237 {
0238     cns3xxx_map_io();
0239     iotable_init(cns3420_io_desc, ARRAY_SIZE(cns3420_io_desc));
0240 
0241     cns3420_early_serial_setup();
0242 }
0243 
0244 MACHINE_START(CNS3420VB, "Cavium Networks CNS3420 Validation Board")
0245     .atag_offset    = 0x100,
0246     .map_io     = cns3420_map_io,
0247     .init_irq   = cns3xxx_init_irq,
0248     .init_time  = cns3xxx_timer_init,
0249     .init_machine   = cns3420_init,
0250     .init_late      = cns3xxx_pcie_init_late,
0251     .restart    = cns3xxx_restart,
0252 MACHINE_END