1 /* 2 * Copyright (C) 2005 Sven Luther <sl@bplan-gmbh.de> 3 * Thanks to : 4 * Dale Farnsworth <dale@farnsworth.org> 5 * Mark A. Greer <mgreer@mvista.com> 6 * Nicolas DET <nd@bplan-gmbh.de> 7 * Benjamin Herrenschmidt <benh@kernel.crashing.org> 8 * And anyone else who helped me on this. 9 */ 10 11 #include <linux/types.h> 12 #include <linux/init.h> 13 #include <linux/ioport.h> 14 #include <linux/device.h> 15 #include <linux/platform_device.h> 16 #include <linux/mv643xx.h> 17 #include <linux/pci.h> 18 19 #define PEGASOS2_MARVELL_REGBASE (0xf1000000) 20 #define PEGASOS2_MARVELL_REGSIZE (0x00004000) 21 #define PEGASOS2_SRAM_BASE (0xf2000000) 22 #define PEGASOS2_SRAM_SIZE (256*1024) 23 24 #define PEGASOS2_SRAM_BASE_ETH0 (PEGASOS2_SRAM_BASE) 25 #define PEGASOS2_SRAM_BASE_ETH1 (PEGASOS2_SRAM_BASE_ETH0 + (PEGASOS2_SRAM_SIZE / 2) ) 26 27 28 #define PEGASOS2_SRAM_RXRING_SIZE (PEGASOS2_SRAM_SIZE/4) 29 #define PEGASOS2_SRAM_TXRING_SIZE (PEGASOS2_SRAM_SIZE/4) 30 31 #undef BE_VERBOSE 32 33 static struct resource mv643xx_eth_shared_resources[] = { 34 [0] = { 35 .name = "ethernet shared base", 36 .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS, 37 .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + 38 MV643XX_ETH_SHARED_REGS_SIZE - 1, 39 .flags = IORESOURCE_MEM, 40 }, 41 }; 42 43 static struct platform_device mv643xx_eth_shared_device = { 44 .name = MV643XX_ETH_SHARED_NAME, 45 .id = 0, 46 .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources), 47 .resource = mv643xx_eth_shared_resources, 48 }; 49 50 static struct resource mv643xx_eth0_resources[] = { 51 [0] = { 52 .name = "eth0 irq", 53 .start = 9, 54 .end = 9, 55 .flags = IORESOURCE_IRQ, 56 }, 57 }; 58 59 60 static struct mv643xx_eth_platform_data eth0_pd = { 61 .shared = &mv643xx_eth_shared_device, 62 .port_number = 0, 63 64 .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH0, 65 .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE, 66 .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16, 67 68 .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH0 + PEGASOS2_SRAM_TXRING_SIZE, 69 .rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE, 70 .rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16, 71 }; 72 73 static struct platform_device eth0_device = { 74 .name = MV643XX_ETH_NAME, 75 .id = 0, 76 .num_resources = ARRAY_SIZE(mv643xx_eth0_resources), 77 .resource = mv643xx_eth0_resources, 78 .dev = { 79 .platform_data = ð0_pd, 80 }, 81 }; 82 83 static struct resource mv643xx_eth1_resources[] = { 84 [0] = { 85 .name = "eth1 irq", 86 .start = 9, 87 .end = 9, 88 .flags = IORESOURCE_IRQ, 89 }, 90 }; 91 92 static struct mv643xx_eth_platform_data eth1_pd = { 93 .shared = &mv643xx_eth_shared_device, 94 .port_number = 1, 95 96 .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH1, 97 .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE, 98 .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16, 99 100 .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH1 + PEGASOS2_SRAM_TXRING_SIZE, 101 .rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE, 102 .rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16, 103 }; 104 105 static struct platform_device eth1_device = { 106 .name = MV643XX_ETH_NAME, 107 .id = 1, 108 .num_resources = ARRAY_SIZE(mv643xx_eth1_resources), 109 .resource = mv643xx_eth1_resources, 110 .dev = { 111 .platform_data = ð1_pd, 112 }, 113 }; 114 115 static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { 116 &mv643xx_eth_shared_device, 117 ð0_device, 118 ð1_device, 119 }; 120 121 /***********/ 122 /***********/ 123 #define MV_READ(offset,val) { val = readl(mv643xx_reg_base + offset); } 124 #define MV_WRITE(offset,data) writel(data, mv643xx_reg_base + offset) 125 126 static void __iomem *mv643xx_reg_base; 127 128 static int Enable_SRAM(void) 129 { 130 u32 ALong; 131 132 if (mv643xx_reg_base == NULL) 133 mv643xx_reg_base = ioremap(PEGASOS2_MARVELL_REGBASE, 134 PEGASOS2_MARVELL_REGSIZE); 135 136 if (mv643xx_reg_base == NULL) 137 return -ENOMEM; 138 139 #ifdef BE_VERBOSE 140 printk("Pegasos II/Marvell MV64361: register remapped from %p to %p\n", 141 (void *)PEGASOS2_MARVELL_REGBASE, (void *)mv643xx_reg_base); 142 #endif 143 144 MV_WRITE(MV64340_SRAM_CONFIG, 0); 145 146 MV_WRITE(MV64340_INTEGRATED_SRAM_BASE_ADDR, PEGASOS2_SRAM_BASE >> 16); 147 148 MV_READ(MV64340_BASE_ADDR_ENABLE, ALong); 149 ALong &= ~(1 << 19); 150 MV_WRITE(MV64340_BASE_ADDR_ENABLE, ALong); 151 152 ALong = 0x02; 153 ALong |= PEGASOS2_SRAM_BASE & 0xffff0000; 154 MV_WRITE(MV643XX_ETH_BAR_4, ALong); 155 156 MV_WRITE(MV643XX_ETH_SIZE_REG_4, (PEGASOS2_SRAM_SIZE-1) & 0xffff0000); 157 158 MV_READ(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong); 159 ALong &= ~(1 << 4); 160 MV_WRITE(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong); 161 162 #ifdef BE_VERBOSE 163 printk("Pegasos II/Marvell MV64361: register unmapped\n"); 164 printk("Pegasos II/Marvell MV64361: SRAM at %p, size=%x\n", (void*) PEGASOS2_SRAM_BASE, PEGASOS2_SRAM_SIZE); 165 #endif 166 167 iounmap(mv643xx_reg_base); 168 mv643xx_reg_base = NULL; 169 170 return 1; 171 } 172 173 174 /***********/ 175 /***********/ 176 static int __init mv643xx_eth_add_pds(void) 177 { 178 int ret = 0; 179 static struct pci_device_id pci_marvell_mv64360[] = { 180 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_MV64360) }, 181 { } 182 }; 183 184 #ifdef BE_VERBOSE 185 printk("Pegasos II/Marvell MV64361: init\n"); 186 #endif 187 188 if (pci_dev_present(pci_marvell_mv64360)) { 189 ret = platform_add_devices(mv643xx_eth_pd_devs, 190 ARRAY_SIZE(mv643xx_eth_pd_devs)); 191 192 if ( Enable_SRAM() < 0) 193 { 194 eth0_pd.tx_sram_addr = 0; 195 eth0_pd.tx_sram_size = 0; 196 eth0_pd.rx_sram_addr = 0; 197 eth0_pd.rx_sram_size = 0; 198 199 eth1_pd.tx_sram_addr = 0; 200 eth1_pd.tx_sram_size = 0; 201 eth1_pd.rx_sram_addr = 0; 202 eth1_pd.rx_sram_size = 0; 203 204 #ifdef BE_VERBOSE 205 printk("Pegasos II/Marvell MV64361: Can't enable the " 206 "SRAM\n"); 207 #endif 208 } 209 } 210 211 #ifdef BE_VERBOSE 212 printk("Pegasos II/Marvell MV64361: init is over\n"); 213 #endif 214 215 return ret; 216 } 217 218 device_initcall(mv643xx_eth_add_pds); 219