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