18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Cavium Networks CNS3420 Validation Board 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright 2000 Deep Blue Solutions Ltd 68c2ecf20Sopenharmony_ci * Copyright 2008 ARM Limited 78c2ecf20Sopenharmony_ci * Copyright 2008 Cavium Networks 88c2ecf20Sopenharmony_ci * Scott Shu 98c2ecf20Sopenharmony_ci * Copyright 2010 MontaVista Software, LLC. 108c2ecf20Sopenharmony_ci * Anton Vorontsov <avorontsov@mvista.com> 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <linux/init.h> 148c2ecf20Sopenharmony_ci#include <linux/kernel.h> 158c2ecf20Sopenharmony_ci#include <linux/compiler.h> 168c2ecf20Sopenharmony_ci#include <linux/io.h> 178c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h> 188c2ecf20Sopenharmony_ci#include <linux/serial_core.h> 198c2ecf20Sopenharmony_ci#include <linux/serial_8250.h> 208c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 218c2ecf20Sopenharmony_ci#include <linux/mtd/mtd.h> 228c2ecf20Sopenharmony_ci#include <linux/mtd/physmap.h> 238c2ecf20Sopenharmony_ci#include <linux/mtd/partitions.h> 248c2ecf20Sopenharmony_ci#include <linux/usb/ehci_pdriver.h> 258c2ecf20Sopenharmony_ci#include <linux/usb/ohci_pdriver.h> 268c2ecf20Sopenharmony_ci#include <asm/setup.h> 278c2ecf20Sopenharmony_ci#include <asm/mach-types.h> 288c2ecf20Sopenharmony_ci#include <asm/mach/arch.h> 298c2ecf20Sopenharmony_ci#include <asm/mach/map.h> 308c2ecf20Sopenharmony_ci#include <asm/mach/time.h> 318c2ecf20Sopenharmony_ci#include "cns3xxx.h" 328c2ecf20Sopenharmony_ci#include "pm.h" 338c2ecf20Sopenharmony_ci#include "core.h" 348c2ecf20Sopenharmony_ci#include "devices.h" 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci/* 378c2ecf20Sopenharmony_ci * NOR Flash 388c2ecf20Sopenharmony_ci */ 398c2ecf20Sopenharmony_cistatic struct mtd_partition cns3420_nor_partitions[] = { 408c2ecf20Sopenharmony_ci { 418c2ecf20Sopenharmony_ci .name = "uboot", 428c2ecf20Sopenharmony_ci .size = 0x00040000, 438c2ecf20Sopenharmony_ci .offset = 0, 448c2ecf20Sopenharmony_ci .mask_flags = MTD_WRITEABLE, 458c2ecf20Sopenharmony_ci }, { 468c2ecf20Sopenharmony_ci .name = "kernel", 478c2ecf20Sopenharmony_ci .size = 0x004C0000, 488c2ecf20Sopenharmony_ci .offset = MTDPART_OFS_APPEND, 498c2ecf20Sopenharmony_ci }, { 508c2ecf20Sopenharmony_ci .name = "filesystem", 518c2ecf20Sopenharmony_ci .size = 0x7000000, 528c2ecf20Sopenharmony_ci .offset = MTDPART_OFS_APPEND, 538c2ecf20Sopenharmony_ci }, { 548c2ecf20Sopenharmony_ci .name = "filesystem2", 558c2ecf20Sopenharmony_ci .size = 0x0AE0000, 568c2ecf20Sopenharmony_ci .offset = MTDPART_OFS_APPEND, 578c2ecf20Sopenharmony_ci }, { 588c2ecf20Sopenharmony_ci .name = "ubootenv", 598c2ecf20Sopenharmony_ci .size = MTDPART_SIZ_FULL, 608c2ecf20Sopenharmony_ci .offset = MTDPART_OFS_APPEND, 618c2ecf20Sopenharmony_ci }, 628c2ecf20Sopenharmony_ci}; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_cistatic struct physmap_flash_data cns3420_nor_pdata = { 658c2ecf20Sopenharmony_ci .width = 2, 668c2ecf20Sopenharmony_ci .parts = cns3420_nor_partitions, 678c2ecf20Sopenharmony_ci .nr_parts = ARRAY_SIZE(cns3420_nor_partitions), 688c2ecf20Sopenharmony_ci}; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_cistatic struct resource cns3420_nor_res = { 718c2ecf20Sopenharmony_ci .start = CNS3XXX_FLASH_BASE, 728c2ecf20Sopenharmony_ci .end = CNS3XXX_FLASH_BASE + SZ_128M - 1, 738c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, 748c2ecf20Sopenharmony_ci}; 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_cistatic struct platform_device cns3420_nor_pdev = { 778c2ecf20Sopenharmony_ci .name = "physmap-flash", 788c2ecf20Sopenharmony_ci .id = 0, 798c2ecf20Sopenharmony_ci .resource = &cns3420_nor_res, 808c2ecf20Sopenharmony_ci .num_resources = 1, 818c2ecf20Sopenharmony_ci .dev = { 828c2ecf20Sopenharmony_ci .platform_data = &cns3420_nor_pdata, 838c2ecf20Sopenharmony_ci }, 848c2ecf20Sopenharmony_ci}; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci/* 878c2ecf20Sopenharmony_ci * UART 888c2ecf20Sopenharmony_ci */ 898c2ecf20Sopenharmony_cistatic void __init cns3420_early_serial_setup(void) 908c2ecf20Sopenharmony_ci{ 918c2ecf20Sopenharmony_ci#ifdef CONFIG_SERIAL_8250_CONSOLE 928c2ecf20Sopenharmony_ci static struct uart_port cns3420_serial_port = { 938c2ecf20Sopenharmony_ci .membase = (void __iomem *)CNS3XXX_UART0_BASE_VIRT, 948c2ecf20Sopenharmony_ci .mapbase = CNS3XXX_UART0_BASE, 958c2ecf20Sopenharmony_ci .irq = IRQ_CNS3XXX_UART0, 968c2ecf20Sopenharmony_ci .iotype = UPIO_MEM, 978c2ecf20Sopenharmony_ci .flags = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE, 988c2ecf20Sopenharmony_ci .regshift = 2, 998c2ecf20Sopenharmony_ci .uartclk = 24000000, 1008c2ecf20Sopenharmony_ci .line = 0, 1018c2ecf20Sopenharmony_ci .type = PORT_16550A, 1028c2ecf20Sopenharmony_ci .fifosize = 16, 1038c2ecf20Sopenharmony_ci }; 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci early_serial_setup(&cns3420_serial_port); 1068c2ecf20Sopenharmony_ci#endif 1078c2ecf20Sopenharmony_ci} 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci/* 1108c2ecf20Sopenharmony_ci * USB 1118c2ecf20Sopenharmony_ci */ 1128c2ecf20Sopenharmony_cistatic struct resource cns3xxx_usb_ehci_resources[] = { 1138c2ecf20Sopenharmony_ci [0] = { 1148c2ecf20Sopenharmony_ci .start = CNS3XXX_USB_BASE, 1158c2ecf20Sopenharmony_ci .end = CNS3XXX_USB_BASE + SZ_16M - 1, 1168c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 1178c2ecf20Sopenharmony_ci }, 1188c2ecf20Sopenharmony_ci [1] = { 1198c2ecf20Sopenharmony_ci .start = IRQ_CNS3XXX_USB_EHCI, 1208c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 1218c2ecf20Sopenharmony_ci }, 1228c2ecf20Sopenharmony_ci}; 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_cistatic u64 cns3xxx_usb_ehci_dma_mask = DMA_BIT_MASK(32); 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_cistatic int csn3xxx_usb_power_on(struct platform_device *pdev) 1278c2ecf20Sopenharmony_ci{ 1288c2ecf20Sopenharmony_ci /* 1298c2ecf20Sopenharmony_ci * EHCI and OHCI share the same clock and power, 1308c2ecf20Sopenharmony_ci * resetting twice would cause the 1st controller been reset. 1318c2ecf20Sopenharmony_ci * Therefore only do power up at the first up device, and 1328c2ecf20Sopenharmony_ci * power down at the last down device. 1338c2ecf20Sopenharmony_ci * 1348c2ecf20Sopenharmony_ci * Set USB AHB INCR length to 16 1358c2ecf20Sopenharmony_ci */ 1368c2ecf20Sopenharmony_ci if (atomic_inc_return(&usb_pwr_ref) == 1) { 1378c2ecf20Sopenharmony_ci cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB); 1388c2ecf20Sopenharmony_ci cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST); 1398c2ecf20Sopenharmony_ci cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST); 1408c2ecf20Sopenharmony_ci __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)), 1418c2ecf20Sopenharmony_ci MISC_CHIP_CONFIG_REG); 1428c2ecf20Sopenharmony_ci } 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci return 0; 1458c2ecf20Sopenharmony_ci} 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_cistatic void csn3xxx_usb_power_off(struct platform_device *pdev) 1488c2ecf20Sopenharmony_ci{ 1498c2ecf20Sopenharmony_ci /* 1508c2ecf20Sopenharmony_ci * EHCI and OHCI share the same clock and power, 1518c2ecf20Sopenharmony_ci * resetting twice would cause the 1st controller been reset. 1528c2ecf20Sopenharmony_ci * Therefore only do power up at the first up device, and 1538c2ecf20Sopenharmony_ci * power down at the last down device. 1548c2ecf20Sopenharmony_ci */ 1558c2ecf20Sopenharmony_ci if (atomic_dec_return(&usb_pwr_ref) == 0) 1568c2ecf20Sopenharmony_ci cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST); 1578c2ecf20Sopenharmony_ci} 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_cistatic struct usb_ehci_pdata cns3xxx_usb_ehci_pdata = { 1608c2ecf20Sopenharmony_ci .power_on = csn3xxx_usb_power_on, 1618c2ecf20Sopenharmony_ci .power_off = csn3xxx_usb_power_off, 1628c2ecf20Sopenharmony_ci}; 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_cistatic struct platform_device cns3xxx_usb_ehci_device = { 1658c2ecf20Sopenharmony_ci .name = "ehci-platform", 1668c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(cns3xxx_usb_ehci_resources), 1678c2ecf20Sopenharmony_ci .resource = cns3xxx_usb_ehci_resources, 1688c2ecf20Sopenharmony_ci .dev = { 1698c2ecf20Sopenharmony_ci .dma_mask = &cns3xxx_usb_ehci_dma_mask, 1708c2ecf20Sopenharmony_ci .coherent_dma_mask = DMA_BIT_MASK(32), 1718c2ecf20Sopenharmony_ci .platform_data = &cns3xxx_usb_ehci_pdata, 1728c2ecf20Sopenharmony_ci }, 1738c2ecf20Sopenharmony_ci}; 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_cistatic struct resource cns3xxx_usb_ohci_resources[] = { 1768c2ecf20Sopenharmony_ci [0] = { 1778c2ecf20Sopenharmony_ci .start = CNS3XXX_USB_OHCI_BASE, 1788c2ecf20Sopenharmony_ci .end = CNS3XXX_USB_OHCI_BASE + SZ_16M - 1, 1798c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 1808c2ecf20Sopenharmony_ci }, 1818c2ecf20Sopenharmony_ci [1] = { 1828c2ecf20Sopenharmony_ci .start = IRQ_CNS3XXX_USB_OHCI, 1838c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 1848c2ecf20Sopenharmony_ci }, 1858c2ecf20Sopenharmony_ci}; 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_cistatic u64 cns3xxx_usb_ohci_dma_mask = DMA_BIT_MASK(32); 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_cistatic struct usb_ohci_pdata cns3xxx_usb_ohci_pdata = { 1908c2ecf20Sopenharmony_ci .num_ports = 1, 1918c2ecf20Sopenharmony_ci .power_on = csn3xxx_usb_power_on, 1928c2ecf20Sopenharmony_ci .power_off = csn3xxx_usb_power_off, 1938c2ecf20Sopenharmony_ci}; 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_cistatic struct platform_device cns3xxx_usb_ohci_device = { 1968c2ecf20Sopenharmony_ci .name = "ohci-platform", 1978c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(cns3xxx_usb_ohci_resources), 1988c2ecf20Sopenharmony_ci .resource = cns3xxx_usb_ohci_resources, 1998c2ecf20Sopenharmony_ci .dev = { 2008c2ecf20Sopenharmony_ci .dma_mask = &cns3xxx_usb_ohci_dma_mask, 2018c2ecf20Sopenharmony_ci .coherent_dma_mask = DMA_BIT_MASK(32), 2028c2ecf20Sopenharmony_ci .platform_data = &cns3xxx_usb_ohci_pdata, 2038c2ecf20Sopenharmony_ci }, 2048c2ecf20Sopenharmony_ci}; 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci/* 2078c2ecf20Sopenharmony_ci * Initialization 2088c2ecf20Sopenharmony_ci */ 2098c2ecf20Sopenharmony_cistatic struct platform_device *cns3420_pdevs[] __initdata = { 2108c2ecf20Sopenharmony_ci &cns3420_nor_pdev, 2118c2ecf20Sopenharmony_ci &cns3xxx_usb_ehci_device, 2128c2ecf20Sopenharmony_ci &cns3xxx_usb_ohci_device, 2138c2ecf20Sopenharmony_ci}; 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_cistatic void __init cns3420_init(void) 2168c2ecf20Sopenharmony_ci{ 2178c2ecf20Sopenharmony_ci cns3xxx_l2x0_init(); 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci platform_add_devices(cns3420_pdevs, ARRAY_SIZE(cns3420_pdevs)); 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci cns3xxx_ahci_init(); 2228c2ecf20Sopenharmony_ci cns3xxx_sdhci_init(); 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci pm_power_off = cns3xxx_power_off; 2258c2ecf20Sopenharmony_ci} 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_cistatic struct map_desc cns3420_io_desc[] __initdata = { 2288c2ecf20Sopenharmony_ci { 2298c2ecf20Sopenharmony_ci .virtual = CNS3XXX_UART0_BASE_VIRT, 2308c2ecf20Sopenharmony_ci .pfn = __phys_to_pfn(CNS3XXX_UART0_BASE), 2318c2ecf20Sopenharmony_ci .length = SZ_4K, 2328c2ecf20Sopenharmony_ci .type = MT_DEVICE, 2338c2ecf20Sopenharmony_ci }, 2348c2ecf20Sopenharmony_ci}; 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_cistatic void __init cns3420_map_io(void) 2378c2ecf20Sopenharmony_ci{ 2388c2ecf20Sopenharmony_ci cns3xxx_map_io(); 2398c2ecf20Sopenharmony_ci iotable_init(cns3420_io_desc, ARRAY_SIZE(cns3420_io_desc)); 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci cns3420_early_serial_setup(); 2428c2ecf20Sopenharmony_ci} 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ciMACHINE_START(CNS3420VB, "Cavium Networks CNS3420 Validation Board") 2458c2ecf20Sopenharmony_ci .atag_offset = 0x100, 2468c2ecf20Sopenharmony_ci .map_io = cns3420_map_io, 2478c2ecf20Sopenharmony_ci .init_irq = cns3xxx_init_irq, 2488c2ecf20Sopenharmony_ci .init_time = cns3xxx_timer_init, 2498c2ecf20Sopenharmony_ci .init_machine = cns3420_init, 2508c2ecf20Sopenharmony_ci .init_late = cns3xxx_pcie_init_late, 2518c2ecf20Sopenharmony_ci .restart = cns3xxx_restart, 2528c2ecf20Sopenharmony_ciMACHINE_END 253