linux/arch/powerpc/platforms/8xx/mpc885ads_setup.c
<<
>>
Prefs
   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
  46static u32 __iomem *bcsr, *bcsr5;
  47
  48struct cpm_pin {
  49        int port, pin, flags;
  50};
  51
  52static struct cpm_pin mpc885ads_pins[] = {
  53        /* SMC1 */
  54        {CPM_PORTB, 24, CPM_PIN_INPUT}, /* RX */
  55        {CPM_PORTB, 25, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TX */
  56
  57        /* SMC2 */
  58#ifndef CONFIG_MPC8xx_SECOND_ETH_FEC2
  59        {CPM_PORTE, 21, CPM_PIN_INPUT}, /* RX */
  60        {CPM_PORTE, 20, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TX */
  61#endif
  62
  63        /* SCC3 */
  64        {CPM_PORTA, 9, CPM_PIN_INPUT}, /* RX */
  65        {CPM_PORTA, 8, CPM_PIN_INPUT}, /* TX */
  66        {CPM_PORTC, 4, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_GPIO}, /* RENA */
  67        {CPM_PORTC, 5, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_GPIO}, /* CLSN */
  68        {CPM_PORTE, 27, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TENA */
  69        {CPM_PORTE, 17, CPM_PIN_INPUT}, /* CLK5 */
  70        {CPM_PORTE, 16, CPM_PIN_INPUT}, /* CLK6 */
  71
  72        /* MII1 */
  73        {CPM_PORTA, 0, CPM_PIN_INPUT},
  74        {CPM_PORTA, 1, CPM_PIN_INPUT},
  75        {CPM_PORTA, 2, CPM_PIN_INPUT},
  76        {CPM_PORTA, 3, CPM_PIN_INPUT},
  77        {CPM_PORTA, 4, CPM_PIN_OUTPUT},
  78        {CPM_PORTA, 10, CPM_PIN_OUTPUT},
  79        {CPM_PORTA, 11, CPM_PIN_OUTPUT},
  80        {CPM_PORTB, 19, CPM_PIN_INPUT},
  81        {CPM_PORTB, 31, CPM_PIN_INPUT},
  82        {CPM_PORTC, 12, CPM_PIN_INPUT},
  83        {CPM_PORTC, 13, CPM_PIN_INPUT},
  84        {CPM_PORTE, 30, CPM_PIN_OUTPUT},
  85        {CPM_PORTE, 31, CPM_PIN_OUTPUT},
  86
  87        /* MII2 */
  88#ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2
  89        {CPM_PORTE, 14, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
  90        {CPM_PORTE, 15, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
  91        {CPM_PORTE, 16, CPM_PIN_OUTPUT},
  92        {CPM_PORTE, 17, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
  93        {CPM_PORTE, 18, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
  94        {CPM_PORTE, 19, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
  95        {CPM_PORTE, 20, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
  96        {CPM_PORTE, 21, CPM_PIN_OUTPUT},
  97        {CPM_PORTE, 22, CPM_PIN_OUTPUT},
  98        {CPM_PORTE, 23, CPM_PIN_OUTPUT},
  99        {CPM_PORTE, 24, CPM_PIN_OUTPUT},
 100        {CPM_PORTE, 25, CPM_PIN_OUTPUT},
 101        {CPM_PORTE, 26, CPM_PIN_OUTPUT},
 102        {CPM_PORTE, 27, CPM_PIN_OUTPUT},
 103        {CPM_PORTE, 28, CPM_PIN_OUTPUT},
 104        {CPM_PORTE, 29, CPM_PIN_OUTPUT},
 105#endif
 106        /* I2C */
 107        {CPM_PORTB, 26, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN},
 108        {CPM_PORTB, 27, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN},
 109};
 110
 111static void __init init_ioports(void)
 112{
 113        int i;
 114
 115        for (i = 0; i < ARRAY_SIZE(mpc885ads_pins); i++) {
 116                struct cpm_pin *pin = &mpc885ads_pins[i];
 117                cpm1_set_pin(pin->port, pin->pin, pin->flags);
 118        }
 119
 120        cpm1_clk_setup(CPM_CLK_SMC1, CPM_BRG1, CPM_CLK_RTX);
 121        cpm1_clk_setup(CPM_CLK_SMC2, CPM_BRG2, CPM_CLK_RTX);
 122        cpm1_clk_setup(CPM_CLK_SCC3, CPM_CLK5, CPM_CLK_TX);
 123        cpm1_clk_setup(CPM_CLK_SCC3, CPM_CLK6, CPM_CLK_RX);
 124
 125        /* Set FEC1 and FEC2 to MII mode */
 126        clrbits32(&mpc8xx_immr->im_cpm.cp_cptr, 0x00000180);
 127}
 128
 129static void __init mpc885ads_setup_arch(void)
 130{
 131        struct device_node *np;
 132
 133        cpm_reset();
 134        init_ioports();
 135
 136        np = of_find_compatible_node(NULL, NULL, "fsl,mpc885ads-bcsr");
 137        if (!np) {
 138                printk(KERN_CRIT "Could not find fsl,mpc885ads-bcsr node\n");
 139                return;
 140        }
 141
 142        bcsr = of_iomap(np, 0);
 143        bcsr5 = of_iomap(np, 1);
 144        of_node_put(np);
 145
 146        if (!bcsr || !bcsr5) {
 147                printk(KERN_CRIT "Could not remap BCSR\n");
 148                return;
 149        }
 150
 151        clrbits32(&bcsr[1], BCSR1_RS232EN_1);
 152#ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2
 153        setbits32(&bcsr[1], BCSR1_RS232EN_2);
 154#else
 155        clrbits32(&bcsr[1], BCSR1_RS232EN_2);
 156#endif
 157
 158        clrbits32(bcsr5, BCSR5_MII1_EN);
 159        setbits32(bcsr5, BCSR5_MII1_RST);
 160        udelay(1000);
 161        clrbits32(bcsr5, BCSR5_MII1_RST);
 162
 163#ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2
 164        clrbits32(bcsr5, BCSR5_MII2_EN);
 165        setbits32(bcsr5, BCSR5_MII2_RST);
 166        udelay(1000);
 167        clrbits32(bcsr5, BCSR5_MII2_RST);
 168#else
 169        setbits32(bcsr5, BCSR5_MII2_EN);
 170#endif
 171
 172#ifdef CONFIG_MPC8xx_SECOND_ETH_SCC3
 173        clrbits32(&bcsr[4], BCSR4_ETH10_RST);
 174        udelay(1000);
 175        setbits32(&bcsr[4], BCSR4_ETH10_RST);
 176
 177        setbits32(&bcsr[1], BCSR1_ETHEN);
 178
 179        np = of_find_node_by_path("/soc@ff000000/cpm@9c0/serial@a80");
 180#else
 181        np = of_find_node_by_path("/soc@ff000000/cpm@9c0/ethernet@a40");
 182#endif
 183
 184        /* The SCC3 enet registers overlap the SMC1 registers, so
 185         * one of the two must be removed from the device tree.
 186         */
 187
 188        if (np) {
 189                of_detach_node(np);
 190                of_node_put(np);
 191        }
 192}
 193
 194static int __init mpc885ads_probe(void)
 195{
 196        return of_machine_is_compatible("fsl,mpc885ads");
 197}
 198
 199static const struct of_device_id of_bus_ids[] __initconst = {
 200        { .name = "soc", },
 201        { .name = "cpm", },
 202        { .name = "localbus", },
 203        {},
 204};
 205
 206static int __init declare_of_platform_devices(void)
 207{
 208        /* Publish the QE devices */
 209        of_platform_bus_probe(NULL, of_bus_ids, NULL);
 210
 211        return 0;
 212}
 213machine_device_initcall(mpc885_ads, declare_of_platform_devices);
 214
 215define_machine(mpc885_ads) {
 216        .name                   = "Freescale MPC885 ADS",
 217        .probe                  = mpc885ads_probe,
 218        .setup_arch             = mpc885ads_setup_arch,
 219        .init_IRQ               = mpc8xx_pics_init,
 220        .get_irq                = mpc8xx_get_irq,
 221        .restart                = mpc8xx_restart,
 222        .calibrate_decr         = mpc8xx_calibrate_decr,
 223        .progress               = udbg_progress,
 224};
 225