1 // SPDX-License-Identifier: GPL-2.0 2 /***************************************************************************/ 3 4 /* 5 * nettel.c -- startup code support for the NETtel boards 6 * 7 * Copyright (C) 2009, Greg Ungerer (gerg@snapgear.com) 8 */ 9 10 /***************************************************************************/ 11 12 #include <linux/kernel.h> 13 #include <linux/param.h> 14 #include <linux/init.h> 15 #include <linux/io.h> 16 #include <linux/platform_device.h> 17 #include <asm/coldfire.h> 18 #include <asm/mcfsim.h> 19 #include <asm/nettel.h> 20 21 /***************************************************************************/ 22 23 /* 24 * Define the IO and interrupt resources of the 2 SMC9196 interfaces. 25 */ 26 #define NETTEL_SMC0_ADDR 0x30600300 27 #define NETTEL_SMC0_IRQ 29 28 29 #define NETTEL_SMC1_ADDR 0x30600000 30 #define NETTEL_SMC1_IRQ 27 31 32 /* 33 * We need some access into the SMC9196 registers. Define those registers 34 * we will need here (including the smc91x.h doesn't seem to give us these 35 * in a simple form). 36 */ 37 #define SMC91xx_BANKSELECT 14 38 #define SMC91xx_BASEADDR 2 39 #define SMC91xx_BASEMAC 4 40 41 /***************************************************************************/ 42 43 static struct resource nettel_smc91x_0_resources[] = { 44 { 45 .start = NETTEL_SMC0_ADDR, 46 .end = NETTEL_SMC0_ADDR + 0x20, 47 .flags = IORESOURCE_MEM, 48 }, 49 { 50 .start = NETTEL_SMC0_IRQ, 51 .end = NETTEL_SMC0_IRQ, 52 .flags = IORESOURCE_IRQ, 53 }, 54 }; 55 56 static struct resource nettel_smc91x_1_resources[] = { 57 { 58 .start = NETTEL_SMC1_ADDR, 59 .end = NETTEL_SMC1_ADDR + 0x20, 60 .flags = IORESOURCE_MEM, 61 }, 62 { 63 .start = NETTEL_SMC1_IRQ, 64 .end = NETTEL_SMC1_IRQ, 65 .flags = IORESOURCE_IRQ, 66 }, 67 }; 68 69 static struct platform_device nettel_smc91x[] = { 70 { 71 .name = "smc91x", 72 .id = 0, 73 .num_resources = ARRAY_SIZE(nettel_smc91x_0_resources), 74 .resource = nettel_smc91x_0_resources, 75 }, 76 { 77 .name = "smc91x", 78 .id = 1, 79 .num_resources = ARRAY_SIZE(nettel_smc91x_1_resources), 80 .resource = nettel_smc91x_1_resources, 81 }, 82 }; 83 84 static struct platform_device *nettel_devices[] __initdata = { 85 &nettel_smc91x[0], 86 &nettel_smc91x[1], 87 }; 88 89 /***************************************************************************/ 90 91 static u8 nettel_macdefault[] __initdata = { 92 0x00, 0xd0, 0xcf, 0x00, 0x00, 0x01, 93 }; 94 95 /* 96 * Set flash contained MAC address into SMC9196 core. Make sure the flash 97 * MAC address is sane, and not an empty flash. If no good use the Moreton 98 * Bay default MAC address instead. 99 */ 100 101 static void __init nettel_smc91x_setmac(unsigned int ioaddr, unsigned int flashaddr) 102 { 103 u16 *macp; 104 105 macp = (u16 *) flashaddr; 106 if ((macp[0] == 0xffff) && (macp[1] == 0xffff) && (macp[2] == 0xffff)) 107 macp = (u16 *) &nettel_macdefault[0]; 108 109 writew(1, NETTEL_SMC0_ADDR + SMC91xx_BANKSELECT); 110 writew(macp[0], ioaddr + SMC91xx_BASEMAC); 111 writew(macp[1], ioaddr + SMC91xx_BASEMAC + 2); 112 writew(macp[2], ioaddr + SMC91xx_BASEMAC + 4); 113 } 114 115 /***************************************************************************/ 116 117 /* 118 * Re-map the address space of at least one of the SMC ethernet 119 * parts. Both parts power up decoding the same address, so we 120 * need to move one of them first, before doing anything else. 121 */ 122 123 static void __init nettel_smc91x_init(void) 124 { 125 writew(0x00ec, MCFSIM_PADDR); 126 mcf_setppdata(0, 0x0080); 127 writew(1, NETTEL_SMC0_ADDR + SMC91xx_BANKSELECT); 128 writew(0x0067, NETTEL_SMC0_ADDR + SMC91xx_BASEADDR); 129 mcf_setppdata(0x0080, 0); 130 131 /* Set correct chip select timing for SMC9196 accesses */ 132 writew(0x1180, MCFSIM_CSCR3); 133 134 /* Set the SMC interrupts to be auto-vectored */ 135 mcf_autovector(NETTEL_SMC0_IRQ); 136 mcf_autovector(NETTEL_SMC1_IRQ); 137 138 /* Set MAC addresses from flash for both interfaces */ 139 nettel_smc91x_setmac(NETTEL_SMC0_ADDR, 0xf0006000); 140 nettel_smc91x_setmac(NETTEL_SMC1_ADDR, 0xf0006006); 141 } 142 143 /***************************************************************************/ 144 145 static int __init init_nettel(void) 146 { 147 nettel_smc91x_init(); 148 platform_add_devices(nettel_devices, ARRAY_SIZE(nettel_devices)); 149 return 0; 150 } 151 152 arch_initcall(init_nettel); 153 154 /***************************************************************************/ 155