diff options
| -rw-r--r-- | arch/mips/momentum/jaguar_atx/Makefile | 2 | ||||
| -rw-r--r-- | arch/mips/momentum/jaguar_atx/platform.c | 235 | ||||
| -rw-r--r-- | arch/mips/momentum/jaguar_atx/prom.c | 55 |
3 files changed, 236 insertions, 56 deletions
diff --git a/arch/mips/momentum/jaguar_atx/Makefile b/arch/mips/momentum/jaguar_atx/Makefile index 67372f3f9654..2e8cebd49bc0 100644 --- a/arch/mips/momentum/jaguar_atx/Makefile +++ b/arch/mips/momentum/jaguar_atx/Makefile | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | # unless it's something special (ie not a .c file). | 6 | # unless it's something special (ie not a .c file). |
| 7 | # | 7 | # |
| 8 | 8 | ||
| 9 | obj-y += irq.o prom.o reset.o setup.o | 9 | obj-y += irq.o platform.o prom.o reset.o setup.o |
| 10 | 10 | ||
| 11 | obj-$(CONFIG_SERIAL_8250_CONSOLE) += ja-console.o | 11 | obj-$(CONFIG_SERIAL_8250_CONSOLE) += ja-console.o |
| 12 | obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o | 12 | obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o |
diff --git a/arch/mips/momentum/jaguar_atx/platform.c b/arch/mips/momentum/jaguar_atx/platform.c new file mode 100644 index 000000000000..035ea5137c71 --- /dev/null +++ b/arch/mips/momentum/jaguar_atx/platform.c | |||
| @@ -0,0 +1,235 @@ | |||
| 1 | #include <linux/delay.h> | ||
| 2 | #include <linux/if_ether.h> | ||
| 3 | #include <linux/ioport.h> | ||
| 4 | #include <linux/mv643xx.h> | ||
| 5 | #include <linux/platform_device.h> | ||
| 6 | |||
| 7 | #include "jaguar_atx_fpga.h" | ||
| 8 | |||
| 9 | #if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) | ||
| 10 | |||
| 11 | static struct resource mv643xx_eth_shared_resources[] = { | ||
| 12 | [0] = { | ||
| 13 | .name = "ethernet shared base", | ||
| 14 | .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS, | ||
| 15 | .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + | ||
| 16 | MV643XX_ETH_SHARED_REGS_SIZE - 1, | ||
| 17 | .flags = IORESOURCE_MEM, | ||
| 18 | }, | ||
| 19 | }; | ||
| 20 | |||
| 21 | static struct platform_device mv643xx_eth_shared_device = { | ||
| 22 | .name = MV643XX_ETH_SHARED_NAME, | ||
| 23 | .id = 0, | ||
| 24 | .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources), | ||
| 25 | .resource = mv643xx_eth_shared_resources, | ||
| 26 | }; | ||
| 27 | |||
| 28 | #define MV_SRAM_BASE 0xfe000000UL | ||
| 29 | #define MV_SRAM_SIZE (256 * 1024) | ||
| 30 | |||
| 31 | #define MV_SRAM_RXRING_SIZE (MV_SRAM_SIZE / 4) | ||
| 32 | #define MV_SRAM_TXRING_SIZE (MV_SRAM_SIZE / 4) | ||
| 33 | |||
| 34 | #define MV_SRAM_BASE_ETH0 MV_SRAM_BASE | ||
| 35 | #define MV_SRAM_BASE_ETH1 (MV_SRAM_BASE + (MV_SRAM_SIZE / 2)) | ||
| 36 | |||
| 37 | #define MV64x60_IRQ_ETH_0 48 | ||
| 38 | #define MV64x60_IRQ_ETH_1 49 | ||
| 39 | #define MV64x60_IRQ_ETH_2 50 | ||
| 40 | |||
| 41 | #ifdef CONFIG_MV643XX_ETH_0 | ||
| 42 | |||
| 43 | static struct resource mv64x60_eth0_resources[] = { | ||
| 44 | [0] = { | ||
| 45 | .name = "eth0 irq", | ||
| 46 | .start = MV64x60_IRQ_ETH_0, | ||
| 47 | .end = MV64x60_IRQ_ETH_0, | ||
| 48 | .flags = IORESOURCE_IRQ, | ||
| 49 | }, | ||
| 50 | }; | ||
| 51 | |||
| 52 | static char eth0_mac_addr[ETH_ALEN]; | ||
| 53 | |||
| 54 | static struct mv643xx_eth_platform_data eth0_pd = { | ||
| 55 | .mac_addr = eth0_mac_addr, | ||
| 56 | |||
| 57 | .tx_sram_addr = MV_SRAM_BASE_ETH0, | ||
| 58 | .tx_sram_size = MV_SRAM_TXRING_SIZE, | ||
| 59 | .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, | ||
| 60 | |||
| 61 | .rx_sram_addr = MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE, | ||
| 62 | .rx_sram_size = MV_SRAM_RXRING_SIZE, | ||
| 63 | .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, | ||
| 64 | }; | ||
| 65 | |||
| 66 | static struct platform_device eth0_device = { | ||
| 67 | .name = MV643XX_ETH_NAME, | ||
| 68 | .id = 0, | ||
| 69 | .num_resources = ARRAY_SIZE(mv64x60_eth0_resources), | ||
| 70 | .resource = mv64x60_eth0_resources, | ||
| 71 | .dev = { | ||
| 72 | .platform_data = ð0_pd, | ||
| 73 | }, | ||
| 74 | }; | ||
| 75 | #endif /* CONFIG_MV643XX_ETH_0 */ | ||
| 76 | |||
| 77 | #ifdef CONFIG_MV643XX_ETH_1 | ||
| 78 | |||
| 79 | static struct resource mv64x60_eth1_resources[] = { | ||
| 80 | [0] = { | ||
| 81 | .name = "eth1 irq", | ||
| 82 | .start = MV64x60_IRQ_ETH_1, | ||
| 83 | .end = MV64x60_IRQ_ETH_1, | ||
| 84 | .flags = IORESOURCE_IRQ, | ||
| 85 | }, | ||
| 86 | }; | ||
| 87 | |||
| 88 | static char eth1_mac_addr[ETH_ALEN]; | ||
| 89 | |||
| 90 | static struct mv643xx_eth_platform_data eth1_pd = { | ||
| 91 | .mac_addr = eth1_mac_addr, | ||
| 92 | |||
| 93 | .tx_sram_addr = MV_SRAM_BASE_ETH1, | ||
| 94 | .tx_sram_size = MV_SRAM_TXRING_SIZE, | ||
| 95 | .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, | ||
| 96 | |||
| 97 | .rx_sram_addr = MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE, | ||
| 98 | .rx_sram_size = MV_SRAM_RXRING_SIZE, | ||
| 99 | .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, | ||
| 100 | }; | ||
| 101 | |||
| 102 | static struct platform_device eth1_device = { | ||
| 103 | .name = MV643XX_ETH_NAME, | ||
| 104 | .id = 1, | ||
| 105 | .num_resources = ARRAY_SIZE(mv64x60_eth1_resources), | ||
| 106 | .resource = mv64x60_eth1_resources, | ||
| 107 | .dev = { | ||
| 108 | .platform_data = ð1_pd, | ||
| 109 | }, | ||
| 110 | }; | ||
| 111 | #endif /* CONFIG_MV643XX_ETH_1 */ | ||
| 112 | |||
| 113 | #ifdef CONFIG_MV643XX_ETH_2 | ||
| 114 | |||
| 115 | static struct resource mv64x60_eth2_resources[] = { | ||
| 116 | [0] = { | ||
| 117 | .name = "eth2 irq", | ||
| 118 | .start = MV64x60_IRQ_ETH_2, | ||
| 119 | .end = MV64x60_IRQ_ETH_2, | ||
| 120 | .flags = IORESOURCE_IRQ, | ||
| 121 | }, | ||
| 122 | }; | ||
| 123 | |||
| 124 | static char eth2_mac_addr[ETH_ALEN]; | ||
| 125 | |||
| 126 | static struct mv643xx_eth_platform_data eth2_pd = { | ||
| 127 | .mac_addr = eth2_mac_addr, | ||
| 128 | }; | ||
| 129 | |||
| 130 | static struct platform_device eth2_device = { | ||
| 131 | .name = MV643XX_ETH_NAME, | ||
| 132 | .id = 1, | ||
| 133 | .num_resources = ARRAY_SIZE(mv64x60_eth2_resources), | ||
| 134 | .resource = mv64x60_eth2_resources, | ||
| 135 | .dev = { | ||
| 136 | .platform_data = ð2_pd, | ||
| 137 | }, | ||
| 138 | }; | ||
| 139 | #endif /* CONFIG_MV643XX_ETH_2 */ | ||
| 140 | |||
| 141 | static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { | ||
| 142 | &mv643xx_eth_shared_device, | ||
| 143 | #ifdef CONFIG_MV643XX_ETH_0 | ||
| 144 | ð0_device, | ||
| 145 | #endif | ||
| 146 | #ifdef CONFIG_MV643XX_ETH_1 | ||
| 147 | ð1_device, | ||
| 148 | #endif | ||
| 149 | #ifdef CONFIG_MV643XX_ETH_2 | ||
| 150 | ð2_device, | ||
| 151 | #endif | ||
| 152 | }; | ||
| 153 | |||
| 154 | static u8 __init exchange_bit(u8 val, u8 cs) | ||
| 155 | { | ||
| 156 | /* place the data */ | ||
| 157 | JAGUAR_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); | ||
| 158 | udelay(1); | ||
| 159 | |||
| 160 | /* turn the clock on */ | ||
| 161 | JAGUAR_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); | ||
| 162 | udelay(1); | ||
| 163 | |||
| 164 | /* turn the clock off and read-strobe */ | ||
| 165 | JAGUAR_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); | ||
| 166 | |||
| 167 | /* return the data */ | ||
| 168 | return (JAGUAR_FPGA_READ(EEPROM_MODE) >> 3) & 0x1; | ||
| 169 | } | ||
| 170 | |||
| 171 | static void __init get_mac(char dest[6]) | ||
| 172 | { | ||
| 173 | u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; | ||
| 174 | int i,j; | ||
| 175 | |||
| 176 | for (i = 0; i < 12; i++) | ||
| 177 | exchange_bit(read_opcode[i], 1); | ||
| 178 | |||
| 179 | for (j = 0; j < 6; j++) { | ||
| 180 | dest[j] = 0; | ||
| 181 | for (i = 0; i < 8; i++) { | ||
| 182 | dest[j] <<= 1; | ||
| 183 | dest[j] |= exchange_bit(0, 1); | ||
| 184 | } | ||
| 185 | } | ||
| 186 | |||
| 187 | /* turn off CS */ | ||
| 188 | exchange_bit(0,0); | ||
| 189 | } | ||
| 190 | |||
| 191 | /* | ||
| 192 | * Copy and increment ethernet MAC address by a small value. | ||
| 193 | * | ||
| 194 | * This is useful for systems where the only one MAC address is stored in | ||
| 195 | * non-volatile memory for multiple ports. | ||
| 196 | */ | ||
| 197 | static inline void eth_mac_add(unsigned char *dst, unsigned char *src, | ||
| 198 | unsigned int add) | ||
| 199 | { | ||
| 200 | int i; | ||
| 201 | |||
| 202 | BUG_ON(add >= 256); | ||
| 203 | |||
| 204 | for (i = ETH_ALEN; i >= 0; i--) { | ||
| 205 | dst[i] = src[i] + add; | ||
| 206 | add = dst[i] < src[i]; /* compute carry */ | ||
| 207 | } | ||
| 208 | |||
| 209 | WARN_ON(add); | ||
| 210 | } | ||
| 211 | |||
| 212 | static int __init mv643xx_eth_add_pds(void) | ||
| 213 | { | ||
| 214 | unsigned char mac[ETH_ALEN]; | ||
| 215 | int ret; | ||
| 216 | |||
| 217 | get_mac(mac); | ||
| 218 | #ifdef CONFIG_MV643XX_ETH_0 | ||
| 219 | eth_mac_add(eth1_mac_addr, mac, 0); | ||
| 220 | #endif | ||
| 221 | #ifdef CONFIG_MV643XX_ETH_1 | ||
| 222 | eth_mac_add(eth1_mac_addr, mac, 1); | ||
| 223 | #endif | ||
| 224 | #ifdef CONFIG_MV643XX_ETH_2 | ||
| 225 | eth_mac_add(eth2_mac_addr, mac, 2); | ||
| 226 | #endif | ||
| 227 | ret = platform_add_devices(mv643xx_eth_pd_devs, | ||
| 228 | ARRAY_SIZE(mv643xx_eth_pd_devs)); | ||
| 229 | |||
| 230 | return ret; | ||
| 231 | } | ||
| 232 | |||
| 233 | device_initcall(mv643xx_eth_add_pds); | ||
| 234 | |||
| 235 | #endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */ | ||
diff --git a/arch/mips/momentum/jaguar_atx/prom.c b/arch/mips/momentum/jaguar_atx/prom.c index 66371ffa2196..5dd154ee58f6 100644 --- a/arch/mips/momentum/jaguar_atx/prom.c +++ b/arch/mips/momentum/jaguar_atx/prom.c | |||
| @@ -39,56 +39,6 @@ const char *get_system_type(void) | |||
| 39 | return "Momentum Jaguar-ATX"; | 39 | return "Momentum Jaguar-ATX"; |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | #ifdef CONFIG_MV643XX_ETH | ||
| 43 | extern unsigned char prom_mac_addr_base[6]; | ||
| 44 | |||
| 45 | static void burn_clocks(void) | ||
| 46 | { | ||
| 47 | int i; | ||
| 48 | |||
| 49 | /* this loop should burn at least 1us -- this should be plenty */ | ||
| 50 | for (i = 0; i < 0x10000; i++) | ||
| 51 | ; | ||
| 52 | } | ||
| 53 | |||
| 54 | static u8 exchange_bit(u8 val, u8 cs) | ||
| 55 | { | ||
| 56 | /* place the data */ | ||
| 57 | JAGUAR_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); | ||
| 58 | burn_clocks(); | ||
| 59 | |||
| 60 | /* turn the clock on */ | ||
| 61 | JAGUAR_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); | ||
| 62 | burn_clocks(); | ||
| 63 | |||
| 64 | /* turn the clock off and read-strobe */ | ||
| 65 | JAGUAR_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); | ||
| 66 | |||
| 67 | /* return the data */ | ||
| 68 | return ((JAGUAR_FPGA_READ(EEPROM_MODE) >> 3) & 0x1); | ||
| 69 | } | ||
| 70 | |||
| 71 | void get_mac(char dest[6]) | ||
| 72 | { | ||
| 73 | u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; | ||
| 74 | int i,j; | ||
| 75 | |||
| 76 | for (i = 0; i < 12; i++) | ||
| 77 | exchange_bit(read_opcode[i], 1); | ||
| 78 | |||
| 79 | for (j = 0; j < 6; j++) { | ||
| 80 | dest[j] = 0; | ||
| 81 | for (i = 0; i < 8; i++) { | ||
| 82 | dest[j] <<= 1; | ||
| 83 | dest[j] |= exchange_bit(0, 1); | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | /* turn off CS */ | ||
| 88 | exchange_bit(0,0); | ||
| 89 | } | ||
| 90 | #endif | ||
| 91 | |||
| 92 | #ifdef CONFIG_64BIT | 42 | #ifdef CONFIG_64BIT |
| 93 | 43 | ||
| 94 | unsigned long signext(unsigned long addr) | 44 | unsigned long signext(unsigned long addr) |
| @@ -228,11 +178,6 @@ void __init prom_init(void) | |||
| 228 | #endif /* CONFIG_64BIT */ | 178 | #endif /* CONFIG_64BIT */ |
| 229 | mips_machgroup = MACH_GROUP_MOMENCO; | 179 | mips_machgroup = MACH_GROUP_MOMENCO; |
| 230 | mips_machtype = MACH_MOMENCO_JAGUAR_ATX; | 180 | mips_machtype = MACH_MOMENCO_JAGUAR_ATX; |
| 231 | |||
| 232 | #ifdef CONFIG_MV643XX_ETH | ||
| 233 | /* get the base MAC address for on-board ethernet ports */ | ||
| 234 | get_mac(prom_mac_addr_base); | ||
| 235 | #endif | ||
| 236 | } | 181 | } |
| 237 | 182 | ||
| 238 | void __init prom_free_prom_memory(void) | 183 | void __init prom_free_prom_memory(void) |
