cns3420vb.c (6248B)
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