18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2005 Sven Luther <sl@bplan-gmbh.de> 48c2ecf20Sopenharmony_ci * Thanks to : 58c2ecf20Sopenharmony_ci * Dale Farnsworth <dale@farnsworth.org> 68c2ecf20Sopenharmony_ci * Mark A. Greer <mgreer@mvista.com> 78c2ecf20Sopenharmony_ci * Nicolas DET <nd@bplan-gmbh.de> 88c2ecf20Sopenharmony_ci * Benjamin Herrenschmidt <benh@kernel.crashing.org> 98c2ecf20Sopenharmony_ci * And anyone else who helped me on this. 108c2ecf20Sopenharmony_ci */ 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include <linux/types.h> 138c2ecf20Sopenharmony_ci#include <linux/init.h> 148c2ecf20Sopenharmony_ci#include <linux/ioport.h> 158c2ecf20Sopenharmony_ci#include <linux/device.h> 168c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 178c2ecf20Sopenharmony_ci#include <linux/mv643xx.h> 188c2ecf20Sopenharmony_ci#include <linux/pci.h> 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#define PEGASOS2_MARVELL_REGBASE (0xf1000000) 218c2ecf20Sopenharmony_ci#define PEGASOS2_MARVELL_REGSIZE (0x00004000) 228c2ecf20Sopenharmony_ci#define PEGASOS2_SRAM_BASE (0xf2000000) 238c2ecf20Sopenharmony_ci#define PEGASOS2_SRAM_SIZE (256*1024) 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci#define PEGASOS2_SRAM_BASE_ETH_PORT0 (PEGASOS2_SRAM_BASE) 268c2ecf20Sopenharmony_ci#define PEGASOS2_SRAM_BASE_ETH_PORT1 (PEGASOS2_SRAM_BASE_ETH_PORT0 + (PEGASOS2_SRAM_SIZE / 2) ) 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#define PEGASOS2_SRAM_RXRING_SIZE (PEGASOS2_SRAM_SIZE/4) 308c2ecf20Sopenharmony_ci#define PEGASOS2_SRAM_TXRING_SIZE (PEGASOS2_SRAM_SIZE/4) 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci#undef BE_VERBOSE 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_cistatic struct resource mv643xx_eth_shared_resources[] = { 358c2ecf20Sopenharmony_ci [0] = { 368c2ecf20Sopenharmony_ci .name = "ethernet shared base", 378c2ecf20Sopenharmony_ci .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS, 388c2ecf20Sopenharmony_ci .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + 398c2ecf20Sopenharmony_ci MV643XX_ETH_SHARED_REGS_SIZE - 1, 408c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 418c2ecf20Sopenharmony_ci }, 428c2ecf20Sopenharmony_ci}; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_cistatic struct platform_device mv643xx_eth_shared_device = { 458c2ecf20Sopenharmony_ci .name = MV643XX_ETH_SHARED_NAME, 468c2ecf20Sopenharmony_ci .id = 0, 478c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources), 488c2ecf20Sopenharmony_ci .resource = mv643xx_eth_shared_resources, 498c2ecf20Sopenharmony_ci}; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci/* 528c2ecf20Sopenharmony_ci * The orion mdio driver only covers shared + 0x4 up to shared + 0x84 - 1 538c2ecf20Sopenharmony_ci */ 548c2ecf20Sopenharmony_cistatic struct resource mv643xx_eth_mvmdio_resources[] = { 558c2ecf20Sopenharmony_ci [0] = { 568c2ecf20Sopenharmony_ci .name = "ethernet mdio base", 578c2ecf20Sopenharmony_ci .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS + 0x4, 588c2ecf20Sopenharmony_ci .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + 0x83, 598c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 608c2ecf20Sopenharmony_ci }, 618c2ecf20Sopenharmony_ci}; 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cistatic struct platform_device mv643xx_eth_mvmdio_device = { 648c2ecf20Sopenharmony_ci .name = "orion-mdio", 658c2ecf20Sopenharmony_ci .id = -1, 668c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(mv643xx_eth_mvmdio_resources), 678c2ecf20Sopenharmony_ci .resource = mv643xx_eth_mvmdio_resources, 688c2ecf20Sopenharmony_ci}; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_cistatic struct resource mv643xx_eth_port1_resources[] = { 718c2ecf20Sopenharmony_ci [0] = { 728c2ecf20Sopenharmony_ci .name = "eth port1 irq", 738c2ecf20Sopenharmony_ci .start = 9, 748c2ecf20Sopenharmony_ci .end = 9, 758c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 768c2ecf20Sopenharmony_ci }, 778c2ecf20Sopenharmony_ci}; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_cistatic struct mv643xx_eth_platform_data eth_port1_pd = { 808c2ecf20Sopenharmony_ci .shared = &mv643xx_eth_shared_device, 818c2ecf20Sopenharmony_ci .port_number = 1, 828c2ecf20Sopenharmony_ci .phy_addr = MV643XX_ETH_PHY_ADDR(7), 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH_PORT1, 858c2ecf20Sopenharmony_ci .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE, 868c2ecf20Sopenharmony_ci .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16, 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH_PORT1 + PEGASOS2_SRAM_TXRING_SIZE, 898c2ecf20Sopenharmony_ci .rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE, 908c2ecf20Sopenharmony_ci .rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16, 918c2ecf20Sopenharmony_ci}; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_cistatic struct platform_device eth_port1_device = { 948c2ecf20Sopenharmony_ci .name = MV643XX_ETH_NAME, 958c2ecf20Sopenharmony_ci .id = 1, 968c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(mv643xx_eth_port1_resources), 978c2ecf20Sopenharmony_ci .resource = mv643xx_eth_port1_resources, 988c2ecf20Sopenharmony_ci .dev = { 998c2ecf20Sopenharmony_ci .platform_data = ð_port1_pd, 1008c2ecf20Sopenharmony_ci }, 1018c2ecf20Sopenharmony_ci}; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_cistatic struct platform_device *mv643xx_eth_pd_devs[] __initdata = { 1048c2ecf20Sopenharmony_ci &mv643xx_eth_shared_device, 1058c2ecf20Sopenharmony_ci &mv643xx_eth_mvmdio_device, 1068c2ecf20Sopenharmony_ci ð_port1_device, 1078c2ecf20Sopenharmony_ci}; 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci/***********/ 1108c2ecf20Sopenharmony_ci/***********/ 1118c2ecf20Sopenharmony_ci#define MV_READ(offset,val) { val = readl(mv643xx_reg_base + offset); } 1128c2ecf20Sopenharmony_ci#define MV_WRITE(offset,data) writel(data, mv643xx_reg_base + offset) 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_cistatic void __iomem *mv643xx_reg_base; 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_cistatic int Enable_SRAM(void) 1178c2ecf20Sopenharmony_ci{ 1188c2ecf20Sopenharmony_ci u32 ALong; 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci if (mv643xx_reg_base == NULL) 1218c2ecf20Sopenharmony_ci mv643xx_reg_base = ioremap(PEGASOS2_MARVELL_REGBASE, 1228c2ecf20Sopenharmony_ci PEGASOS2_MARVELL_REGSIZE); 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci if (mv643xx_reg_base == NULL) 1258c2ecf20Sopenharmony_ci return -ENOMEM; 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci#ifdef BE_VERBOSE 1288c2ecf20Sopenharmony_ci printk("Pegasos II/Marvell MV64361: register remapped from %p to %p\n", 1298c2ecf20Sopenharmony_ci (void *)PEGASOS2_MARVELL_REGBASE, (void *)mv643xx_reg_base); 1308c2ecf20Sopenharmony_ci#endif 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci MV_WRITE(MV64340_SRAM_CONFIG, 0); 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci MV_WRITE(MV64340_INTEGRATED_SRAM_BASE_ADDR, PEGASOS2_SRAM_BASE >> 16); 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci MV_READ(MV64340_BASE_ADDR_ENABLE, ALong); 1378c2ecf20Sopenharmony_ci ALong &= ~(1 << 19); 1388c2ecf20Sopenharmony_ci MV_WRITE(MV64340_BASE_ADDR_ENABLE, ALong); 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci ALong = 0x02; 1418c2ecf20Sopenharmony_ci ALong |= PEGASOS2_SRAM_BASE & 0xffff0000; 1428c2ecf20Sopenharmony_ci MV_WRITE(MV643XX_ETH_BAR_4, ALong); 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci MV_WRITE(MV643XX_ETH_SIZE_REG_4, (PEGASOS2_SRAM_SIZE-1) & 0xffff0000); 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci MV_READ(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong); 1478c2ecf20Sopenharmony_ci ALong &= ~(1 << 4); 1488c2ecf20Sopenharmony_ci MV_WRITE(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong); 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci#ifdef BE_VERBOSE 1518c2ecf20Sopenharmony_ci printk("Pegasos II/Marvell MV64361: register unmapped\n"); 1528c2ecf20Sopenharmony_ci printk("Pegasos II/Marvell MV64361: SRAM at %p, size=%x\n", (void*) PEGASOS2_SRAM_BASE, PEGASOS2_SRAM_SIZE); 1538c2ecf20Sopenharmony_ci#endif 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci iounmap(mv643xx_reg_base); 1568c2ecf20Sopenharmony_ci mv643xx_reg_base = NULL; 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci return 1; 1598c2ecf20Sopenharmony_ci} 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci/***********/ 1638c2ecf20Sopenharmony_ci/***********/ 1648c2ecf20Sopenharmony_cistatic int __init mv643xx_eth_add_pds(void) 1658c2ecf20Sopenharmony_ci{ 1668c2ecf20Sopenharmony_ci int ret = 0; 1678c2ecf20Sopenharmony_ci static struct pci_device_id pci_marvell_mv64360[] = { 1688c2ecf20Sopenharmony_ci { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_MV64360) }, 1698c2ecf20Sopenharmony_ci { } 1708c2ecf20Sopenharmony_ci }; 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci#ifdef BE_VERBOSE 1738c2ecf20Sopenharmony_ci printk("Pegasos II/Marvell MV64361: init\n"); 1748c2ecf20Sopenharmony_ci#endif 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci if (pci_dev_present(pci_marvell_mv64360)) { 1778c2ecf20Sopenharmony_ci ret = platform_add_devices(mv643xx_eth_pd_devs, 1788c2ecf20Sopenharmony_ci ARRAY_SIZE(mv643xx_eth_pd_devs)); 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci if ( Enable_SRAM() < 0) 1818c2ecf20Sopenharmony_ci { 1828c2ecf20Sopenharmony_ci eth_port1_pd.tx_sram_addr = 0; 1838c2ecf20Sopenharmony_ci eth_port1_pd.tx_sram_size = 0; 1848c2ecf20Sopenharmony_ci eth_port1_pd.rx_sram_addr = 0; 1858c2ecf20Sopenharmony_ci eth_port1_pd.rx_sram_size = 0; 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci#ifdef BE_VERBOSE 1888c2ecf20Sopenharmony_ci printk("Pegasos II/Marvell MV64361: Can't enable the " 1898c2ecf20Sopenharmony_ci "SRAM\n"); 1908c2ecf20Sopenharmony_ci#endif 1918c2ecf20Sopenharmony_ci } 1928c2ecf20Sopenharmony_ci } 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci#ifdef BE_VERBOSE 1958c2ecf20Sopenharmony_ci printk("Pegasos II/Marvell MV64361: init is over\n"); 1968c2ecf20Sopenharmony_ci#endif 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci return ret; 1998c2ecf20Sopenharmony_ci} 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_cidevice_initcall(mv643xx_eth_add_pds); 202