Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Platform setup for the Freescale mpc885ads board
0003  *
0004  * Vitaly Bordug <vbordug@ru.mvista.com>
0005  *
0006  * Copyright 2005 MontaVista Software Inc.
0007  *
0008  * Heavily modified by Scott Wood <scottwood@freescale.com>
0009  * Copyright 2007 Freescale Semiconductor, Inc.
0010  *
0011  * This file is licensed under the terms of the GNU General Public License
0012  * version 2. This program is licensed "as is" without any warranty of any
0013  * kind, whether express or implied.
0014  */
0015 
0016 #include <linux/init.h>
0017 #include <linux/module.h>
0018 #include <linux/param.h>
0019 #include <linux/string.h>
0020 #include <linux/ioport.h>
0021 #include <linux/device.h>
0022 #include <linux/delay.h>
0023 
0024 #include <linux/fs_enet_pd.h>
0025 #include <linux/fs_uart_pd.h>
0026 #include <linux/fsl_devices.h>
0027 #include <linux/mii.h>
0028 #include <linux/of_address.h>
0029 #include <linux/of_fdt.h>
0030 #include <linux/of_platform.h>
0031 
0032 #include <asm/delay.h>
0033 #include <asm/io.h>
0034 #include <asm/machdep.h>
0035 #include <asm/page.h>
0036 #include <asm/processor.h>
0037 #include <asm/time.h>
0038 #include <asm/8xx_immap.h>
0039 #include <asm/cpm1.h>
0040 #include <asm/fs_pd.h>
0041 #include <asm/udbg.h>
0042 
0043 #include "mpc885ads.h"
0044 #include "mpc8xx.h"
0045 #include "pic.h"
0046 
0047 static u32 __iomem *bcsr, *bcsr5;
0048 
0049 struct cpm_pin {
0050     int port, pin, flags;
0051 };
0052 
0053 static struct cpm_pin mpc885ads_pins[] = {
0054     /* SMC1 */
0055     {CPM_PORTB, 24, CPM_PIN_INPUT}, /* RX */
0056     {CPM_PORTB, 25, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TX */
0057 
0058     /* SMC2 */
0059 #ifndef CONFIG_MPC8xx_SECOND_ETH_FEC2
0060     {CPM_PORTE, 21, CPM_PIN_INPUT}, /* RX */
0061     {CPM_PORTE, 20, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TX */
0062 #endif
0063 
0064     /* SCC3 */
0065     {CPM_PORTA, 9, CPM_PIN_INPUT}, /* RX */
0066     {CPM_PORTA, 8, CPM_PIN_INPUT}, /* TX */
0067     {CPM_PORTC, 4, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_GPIO}, /* RENA */
0068     {CPM_PORTC, 5, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_GPIO}, /* CLSN */
0069     {CPM_PORTE, 27, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TENA */
0070     {CPM_PORTE, 17, CPM_PIN_INPUT}, /* CLK5 */
0071     {CPM_PORTE, 16, CPM_PIN_INPUT}, /* CLK6 */
0072 
0073     /* MII1 */
0074     {CPM_PORTA, 0, CPM_PIN_INPUT},
0075     {CPM_PORTA, 1, CPM_PIN_INPUT},
0076     {CPM_PORTA, 2, CPM_PIN_INPUT},
0077     {CPM_PORTA, 3, CPM_PIN_INPUT},
0078     {CPM_PORTA, 4, CPM_PIN_OUTPUT},
0079     {CPM_PORTA, 10, CPM_PIN_OUTPUT},
0080     {CPM_PORTA, 11, CPM_PIN_OUTPUT},
0081     {CPM_PORTB, 19, CPM_PIN_INPUT},
0082     {CPM_PORTB, 31, CPM_PIN_INPUT},
0083     {CPM_PORTC, 12, CPM_PIN_INPUT},
0084     {CPM_PORTC, 13, CPM_PIN_INPUT},
0085     {CPM_PORTE, 30, CPM_PIN_OUTPUT},
0086     {CPM_PORTE, 31, CPM_PIN_OUTPUT},
0087 
0088     /* MII2 */
0089 #ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2
0090     {CPM_PORTE, 14, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
0091     {CPM_PORTE, 15, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
0092     {CPM_PORTE, 16, CPM_PIN_OUTPUT},
0093     {CPM_PORTE, 17, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
0094     {CPM_PORTE, 18, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
0095     {CPM_PORTE, 19, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
0096     {CPM_PORTE, 20, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
0097     {CPM_PORTE, 21, CPM_PIN_OUTPUT},
0098     {CPM_PORTE, 22, CPM_PIN_OUTPUT},
0099     {CPM_PORTE, 23, CPM_PIN_OUTPUT},
0100     {CPM_PORTE, 24, CPM_PIN_OUTPUT},
0101     {CPM_PORTE, 25, CPM_PIN_OUTPUT},
0102     {CPM_PORTE, 26, CPM_PIN_OUTPUT},
0103     {CPM_PORTE, 27, CPM_PIN_OUTPUT},
0104     {CPM_PORTE, 28, CPM_PIN_OUTPUT},
0105     {CPM_PORTE, 29, CPM_PIN_OUTPUT},
0106 #endif
0107     /* I2C */
0108     {CPM_PORTB, 26, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN},
0109     {CPM_PORTB, 27, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN},
0110 };
0111 
0112 static void __init init_ioports(void)
0113 {
0114     int i;
0115 
0116     for (i = 0; i < ARRAY_SIZE(mpc885ads_pins); i++) {
0117         struct cpm_pin *pin = &mpc885ads_pins[i];
0118         cpm1_set_pin(pin->port, pin->pin, pin->flags);
0119     }
0120 
0121     cpm1_clk_setup(CPM_CLK_SMC1, CPM_BRG1, CPM_CLK_RTX);
0122     cpm1_clk_setup(CPM_CLK_SMC2, CPM_BRG2, CPM_CLK_RTX);
0123     cpm1_clk_setup(CPM_CLK_SCC3, CPM_CLK5, CPM_CLK_TX);
0124     cpm1_clk_setup(CPM_CLK_SCC3, CPM_CLK6, CPM_CLK_RX);
0125 
0126     /* Set FEC1 and FEC2 to MII mode */
0127     clrbits32(&mpc8xx_immr->im_cpm.cp_cptr, 0x00000180);
0128 }
0129 
0130 static void __init mpc885ads_setup_arch(void)
0131 {
0132     struct device_node *np;
0133 
0134     cpm_reset();
0135     init_ioports();
0136 
0137     np = of_find_compatible_node(NULL, NULL, "fsl,mpc885ads-bcsr");
0138     if (!np) {
0139         printk(KERN_CRIT "Could not find fsl,mpc885ads-bcsr node\n");
0140         return;
0141     }
0142 
0143     bcsr = of_iomap(np, 0);
0144     bcsr5 = of_iomap(np, 1);
0145     of_node_put(np);
0146 
0147     if (!bcsr || !bcsr5) {
0148         printk(KERN_CRIT "Could not remap BCSR\n");
0149         return;
0150     }
0151 
0152     clrbits32(&bcsr[1], BCSR1_RS232EN_1);
0153 #ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2
0154     setbits32(&bcsr[1], BCSR1_RS232EN_2);
0155 #else
0156     clrbits32(&bcsr[1], BCSR1_RS232EN_2);
0157 #endif
0158 
0159     clrbits32(bcsr5, BCSR5_MII1_EN);
0160     setbits32(bcsr5, BCSR5_MII1_RST);
0161     udelay(1000);
0162     clrbits32(bcsr5, BCSR5_MII1_RST);
0163 
0164 #ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2
0165     clrbits32(bcsr5, BCSR5_MII2_EN);
0166     setbits32(bcsr5, BCSR5_MII2_RST);
0167     udelay(1000);
0168     clrbits32(bcsr5, BCSR5_MII2_RST);
0169 #else
0170     setbits32(bcsr5, BCSR5_MII2_EN);
0171 #endif
0172 
0173 #ifdef CONFIG_MPC8xx_SECOND_ETH_SCC3
0174     clrbits32(&bcsr[4], BCSR4_ETH10_RST);
0175     udelay(1000);
0176     setbits32(&bcsr[4], BCSR4_ETH10_RST);
0177 
0178     setbits32(&bcsr[1], BCSR1_ETHEN);
0179 
0180     np = of_find_node_by_path("/soc@ff000000/cpm@9c0/serial@a80");
0181 #else
0182     np = of_find_node_by_path("/soc@ff000000/cpm@9c0/ethernet@a40");
0183 #endif
0184 
0185     /* The SCC3 enet registers overlap the SMC1 registers, so
0186      * one of the two must be removed from the device tree.
0187      */
0188 
0189     if (np) {
0190         of_detach_node(np);
0191         of_node_put(np);
0192     }
0193 }
0194 
0195 static int __init mpc885ads_probe(void)
0196 {
0197     return of_machine_is_compatible("fsl,mpc885ads");
0198 }
0199 
0200 static const struct of_device_id of_bus_ids[] __initconst = {
0201     { .name = "soc", },
0202     { .name = "cpm", },
0203     { .name = "localbus", },
0204     {},
0205 };
0206 
0207 static int __init declare_of_platform_devices(void)
0208 {
0209     /* Publish the QE devices */
0210     of_platform_bus_probe(NULL, of_bus_ids, NULL);
0211 
0212     return 0;
0213 }
0214 machine_device_initcall(mpc885_ads, declare_of_platform_devices);
0215 
0216 define_machine(mpc885_ads) {
0217     .name           = "Freescale MPC885 ADS",
0218     .probe          = mpc885ads_probe,
0219     .setup_arch     = mpc885ads_setup_arch,
0220     .init_IRQ       = mpc8xx_pic_init,
0221     .get_irq        = mpc8xx_get_irq,
0222     .restart        = mpc8xx_restart,
0223     .calibrate_decr     = mpc8xx_calibrate_decr,
0224     .progress       = udbg_progress,
0225 };