1 /* 2 * Platform setup for the Freescale mpc885ads board 3 * 4 * Vitaly Bordug <vbordug@ru.mvista.com> 5 * 6 * Copyright 2005 MontaVista Software Inc. 7 * 8 * Heavily modified by Scott Wood <scottwood@freescale.com> 9 * Copyright 2007 Freescale Semiconductor, Inc. 10 * 11 * This file is licensed under the terms of the GNU General Public License 12 * version 2. This program is licensed "as is" without any warranty of any 13 * kind, whether express or implied. 14 */ 15 16 #include <linux/init.h> 17 #include <linux/module.h> 18 #include <linux/param.h> 19 #include <linux/string.h> 20 #include <linux/ioport.h> 21 #include <linux/device.h> 22 #include <linux/delay.h> 23 24 #include <linux/fs_enet_pd.h> 25 #include <linux/fs_uart_pd.h> 26 #include <linux/fsl_devices.h> 27 #include <linux/mii.h> 28 #include <linux/of_address.h> 29 #include <linux/of_fdt.h> 30 #include <linux/of_platform.h> 31 32 #include <asm/delay.h> 33 #include <asm/io.h> 34 #include <asm/machdep.h> 35 #include <asm/page.h> 36 #include <asm/processor.h> 37 #include <asm/time.h> 38 #include <asm/8xx_immap.h> 39 #include <asm/cpm1.h> 40 #include <asm/fs_pd.h> 41 #include <asm/udbg.h> 42 43 #include "mpc885ads.h" 44 #include "mpc8xx.h" 45 #include "pic.h" 46 47 static u32 __iomem *bcsr, *bcsr5; 48 49 struct cpm_pin { 50 int port, pin, flags; 51 }; 52 53 static struct cpm_pin mpc885ads_pins[] = { 54 /* SMC1 */ 55 {CPM_PORTB, 24, CPM_PIN_INPUT}, /* RX */ 56 {CPM_PORTB, 25, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TX */ 57 58 /* SMC2 */ 59 #ifndef CONFIG_MPC8xx_SECOND_ETH_FEC2 60 {CPM_PORTE, 21, CPM_PIN_INPUT}, /* RX */ 61 {CPM_PORTE, 20, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TX */ 62 #endif 63 64 /* SCC3 */ 65 {CPM_PORTA, 9, CPM_PIN_INPUT}, /* RX */ 66 {CPM_PORTA, 8, CPM_PIN_INPUT}, /* TX */ 67 {CPM_PORTC, 4, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_GPIO}, /* RENA */ 68 {CPM_PORTC, 5, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_GPIO}, /* CLSN */ 69 {CPM_PORTE, 27, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TENA */ 70 {CPM_PORTE, 17, CPM_PIN_INPUT}, /* CLK5 */ 71 {CPM_PORTE, 16, CPM_PIN_INPUT}, /* CLK6 */ 72 73 /* MII1 */ 74 {CPM_PORTA, 0, CPM_PIN_INPUT}, 75 {CPM_PORTA, 1, CPM_PIN_INPUT}, 76 {CPM_PORTA, 2, CPM_PIN_INPUT}, 77 {CPM_PORTA, 3, CPM_PIN_INPUT}, 78 {CPM_PORTA, 4, CPM_PIN_OUTPUT}, 79 {CPM_PORTA, 10, CPM_PIN_OUTPUT}, 80 {CPM_PORTA, 11, CPM_PIN_OUTPUT}, 81 {CPM_PORTB, 19, CPM_PIN_INPUT}, 82 {CPM_PORTB, 31, CPM_PIN_INPUT}, 83 {CPM_PORTC, 12, CPM_PIN_INPUT}, 84 {CPM_PORTC, 13, CPM_PIN_INPUT}, 85 {CPM_PORTE, 30, CPM_PIN_OUTPUT}, 86 {CPM_PORTE, 31, CPM_PIN_OUTPUT}, 87 88 /* MII2 */ 89 #ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2 90 {CPM_PORTE, 14, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, 91 {CPM_PORTE, 15, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, 92 {CPM_PORTE, 16, CPM_PIN_OUTPUT}, 93 {CPM_PORTE, 17, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, 94 {CPM_PORTE, 18, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, 95 {CPM_PORTE, 19, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, 96 {CPM_PORTE, 20, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, 97 {CPM_PORTE, 21, CPM_PIN_OUTPUT}, 98 {CPM_PORTE, 22, CPM_PIN_OUTPUT}, 99 {CPM_PORTE, 23, CPM_PIN_OUTPUT}, 100 {CPM_PORTE, 24, CPM_PIN_OUTPUT}, 101 {CPM_PORTE, 25, CPM_PIN_OUTPUT}, 102 {CPM_PORTE, 26, CPM_PIN_OUTPUT}, 103 {CPM_PORTE, 27, CPM_PIN_OUTPUT}, 104 {CPM_PORTE, 28, CPM_PIN_OUTPUT}, 105 {CPM_PORTE, 29, CPM_PIN_OUTPUT}, 106 #endif 107 /* I2C */ 108 {CPM_PORTB, 26, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN}, 109 {CPM_PORTB, 27, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN}, 110 }; 111 112 static void __init init_ioports(void) 113 { 114 int i; 115 116 for (i = 0; i < ARRAY_SIZE(mpc885ads_pins); i++) { 117 struct cpm_pin *pin = &mpc885ads_pins[i]; 118 cpm1_set_pin(pin->port, pin->pin, pin->flags); 119 } 120 121 cpm1_clk_setup(CPM_CLK_SMC1, CPM_BRG1, CPM_CLK_RTX); 122 cpm1_clk_setup(CPM_CLK_SMC2, CPM_BRG2, CPM_CLK_RTX); 123 cpm1_clk_setup(CPM_CLK_SCC3, CPM_CLK5, CPM_CLK_TX); 124 cpm1_clk_setup(CPM_CLK_SCC3, CPM_CLK6, CPM_CLK_RX); 125 126 /* Set FEC1 and FEC2 to MII mode */ 127 clrbits32(&mpc8xx_immr->im_cpm.cp_cptr, 0x00000180); 128 } 129 130 static void __init mpc885ads_setup_arch(void) 131 { 132 struct device_node *np; 133 134 cpm_reset(); 135 init_ioports(); 136 137 np = of_find_compatible_node(NULL, NULL, "fsl,mpc885ads-bcsr"); 138 if (!np) { 139 printk(KERN_CRIT "Could not find fsl,mpc885ads-bcsr node\n"); 140 return; 141 } 142 143 bcsr = of_iomap(np, 0); 144 bcsr5 = of_iomap(np, 1); 145 of_node_put(np); 146 147 if (!bcsr || !bcsr5) { 148 printk(KERN_CRIT "Could not remap BCSR\n"); 149 return; 150 } 151 152 clrbits32(&bcsr[1], BCSR1_RS232EN_1); 153 #ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2 154 setbits32(&bcsr[1], BCSR1_RS232EN_2); 155 #else 156 clrbits32(&bcsr[1], BCSR1_RS232EN_2); 157 #endif 158 159 clrbits32(bcsr5, BCSR5_MII1_EN); 160 setbits32(bcsr5, BCSR5_MII1_RST); 161 udelay(1000); 162 clrbits32(bcsr5, BCSR5_MII1_RST); 163 164 #ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2 165 clrbits32(bcsr5, BCSR5_MII2_EN); 166 setbits32(bcsr5, BCSR5_MII2_RST); 167 udelay(1000); 168 clrbits32(bcsr5, BCSR5_MII2_RST); 169 #else 170 setbits32(bcsr5, BCSR5_MII2_EN); 171 #endif 172 173 #ifdef CONFIG_MPC8xx_SECOND_ETH_SCC3 174 clrbits32(&bcsr[4], BCSR4_ETH10_RST); 175 udelay(1000); 176 setbits32(&bcsr[4], BCSR4_ETH10_RST); 177 178 setbits32(&bcsr[1], BCSR1_ETHEN); 179 180 np = of_find_node_by_path("/soc@ff000000/cpm@9c0/serial@a80"); 181 #else 182 np = of_find_node_by_path("/soc@ff000000/cpm@9c0/ethernet@a40"); 183 #endif 184 185 /* The SCC3 enet registers overlap the SMC1 registers, so 186 * one of the two must be removed from the device tree. 187 */ 188 189 if (np) { 190 of_detach_node(np); 191 of_node_put(np); 192 } 193 } 194 195 static int __init mpc885ads_probe(void) 196 { 197 return of_machine_is_compatible("fsl,mpc885ads"); 198 } 199 200 static const struct of_device_id of_bus_ids[] __initconst = { 201 { .name = "soc", }, 202 { .name = "cpm", }, 203 { .name = "localbus", }, 204 {}, 205 }; 206 207 static int __init declare_of_platform_devices(void) 208 { 209 /* Publish the QE devices */ 210 of_platform_bus_probe(NULL, of_bus_ids, NULL); 211 212 return 0; 213 } 214 machine_device_initcall(mpc885_ads, declare_of_platform_devices); 215 216 define_machine(mpc885_ads) { 217 .name = "Freescale MPC885 ADS", 218 .probe = mpc885ads_probe, 219 .setup_arch = mpc885ads_setup_arch, 220 .init_IRQ = mpc8xx_pic_init, 221 .get_irq = mpc8xx_get_irq, 222 .restart = mpc8xx_restart, 223 .calibrate_decr = mpc8xx_calibrate_decr, 224 .progress = udbg_progress, 225 }; 226