linux/arch/powerpc/platforms/52xx/mpc52xx_common.c
<<
>>
Prefs
   1/*
   2 *
   3 * Utility functions for the Freescale MPC52xx.
   4 *
   5 * Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
   6 *
   7 * This file is licensed under the terms of the GNU General Public License
   8 * version 2. This program is licensed "as is" without any warranty of any
   9 * kind, whether express or implied.
  10 *
  11 */
  12
  13#undef DEBUG
  14
  15#include <linux/gpio.h>
  16#include <linux/kernel.h>
  17#include <linux/spinlock.h>
  18#include <linux/of_platform.h>
  19#include <linux/of_gpio.h>
  20#include <linux/export.h>
  21#include <asm/io.h>
  22#include <asm/prom.h>
  23#include <asm/mpc52xx.h>
  24
  25/* MPC5200 device tree match tables */
  26static struct of_device_id mpc52xx_xlb_ids[] __initdata = {
  27        { .compatible = "fsl,mpc5200-xlb", },
  28        { .compatible = "mpc5200-xlb", },
  29        {}
  30};
  31static struct of_device_id mpc52xx_bus_ids[] __initdata = {
  32        { .compatible = "fsl,mpc5200-immr", },
  33        { .compatible = "fsl,mpc5200b-immr", },
  34        { .compatible = "simple-bus", },
  35
  36        /* depreciated matches; shouldn't be used in new device trees */
  37        { .compatible = "fsl,lpb", },
  38        { .type = "builtin", .compatible = "mpc5200", }, /* efika */
  39        { .type = "soc", .compatible = "mpc5200", }, /* lite5200 */
  40        {}
  41};
  42
  43/*
  44 * This variable is mapped in mpc52xx_map_wdt() and used in mpc52xx_restart().
  45 * Permanent mapping is required because mpc52xx_restart() can be called
  46 * from interrupt context while node mapping (which calls ioremap())
  47 * cannot be used at such point.
  48 */
  49static DEFINE_SPINLOCK(mpc52xx_lock);
  50static struct mpc52xx_gpt __iomem *mpc52xx_wdt;
  51static struct mpc52xx_cdm __iomem *mpc52xx_cdm;
  52
  53/*
  54 * Configure the XLB arbiter settings to match what Linux expects.
  55 */
  56void __init
  57mpc5200_setup_xlb_arbiter(void)
  58{
  59        struct device_node *np;
  60        struct mpc52xx_xlb  __iomem *xlb;
  61
  62        np = of_find_matching_node(NULL, mpc52xx_xlb_ids);
  63        xlb = of_iomap(np, 0);
  64        of_node_put(np);
  65        if (!xlb) {
  66                printk(KERN_ERR __FILE__ ": "
  67                        "Error mapping XLB in mpc52xx_setup_cpu(). "
  68                        "Expect some abnormal behavior\n");
  69                return;
  70        }
  71
  72        /* Configure the XLB Arbiter priorities */
  73        out_be32(&xlb->master_pri_enable, 0xff);
  74        out_be32(&xlb->master_priority, 0x11111111);
  75
  76        /*
  77         * Disable XLB pipelining
  78         * (cfr errate 292. We could do this only just before ATA PIO
  79         *  transaction and re-enable it afterwards ...)
  80         * Not needed on MPC5200B.
  81         */
  82        if ((mfspr(SPRN_SVR) & MPC5200_SVR_MASK) == MPC5200_SVR)
  83                out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_PLDIS);
  84
  85        iounmap(xlb);
  86}
  87
  88/*
  89 * This variable is mapped in mpc52xx_map_common_devices and
  90 * used in mpc5200_psc_ac97_gpio_reset().
  91 */
  92static DEFINE_SPINLOCK(gpio_lock);
  93struct mpc52xx_gpio __iomem *simple_gpio;
  94struct mpc52xx_gpio_wkup __iomem *wkup_gpio;
  95
  96/**
  97 * mpc52xx_declare_of_platform_devices: register internal devices and children
  98 *                                      of the localplus bus to the of_platform
  99 *                                      bus.
 100 */
 101void __init
 102mpc52xx_declare_of_platform_devices(void)
 103{
 104        /* Find every child of the SOC node and add it to of_platform */
 105        if (of_platform_bus_probe(NULL, mpc52xx_bus_ids, NULL))
 106                printk(KERN_ERR __FILE__ ": "
 107                        "Error while probing of_platform bus\n");
 108}
 109
 110/*
 111 * match tables used by mpc52xx_map_common_devices()
 112 */
 113static struct of_device_id mpc52xx_gpt_ids[] __initdata = {
 114        { .compatible = "fsl,mpc5200-gpt", },
 115        { .compatible = "mpc5200-gpt", }, /* old */
 116        {}
 117};
 118static struct of_device_id mpc52xx_cdm_ids[] __initdata = {
 119        { .compatible = "fsl,mpc5200-cdm", },
 120        { .compatible = "mpc5200-cdm", }, /* old */
 121        {}
 122};
 123static const struct of_device_id mpc52xx_gpio_simple[] = {
 124        { .compatible = "fsl,mpc5200-gpio", },
 125        {}
 126};
 127static const struct of_device_id mpc52xx_gpio_wkup[] = {
 128        { .compatible = "fsl,mpc5200-gpio-wkup", },
 129        {}
 130};
 131
 132
 133/**
 134 * mpc52xx_map_common_devices: iomap devices required by common code
 135 */
 136void __init
 137mpc52xx_map_common_devices(void)
 138{
 139        struct device_node *np;
 140
 141        /* mpc52xx_wdt is mapped here and used in mpc52xx_restart,
 142         * possibly from a interrupt context. wdt is only implement
 143         * on a gpt0, so check has-wdt property before mapping.
 144         */
 145        for_each_matching_node(np, mpc52xx_gpt_ids) {
 146                if (of_get_property(np, "fsl,has-wdt", NULL) ||
 147                    of_get_property(np, "has-wdt", NULL)) {
 148                        mpc52xx_wdt = of_iomap(np, 0);
 149                        of_node_put(np);
 150                        break;
 151                }
 152        }
 153
 154        /* Clock Distribution Module, used by PSC clock setting function */
 155        np = of_find_matching_node(NULL, mpc52xx_cdm_ids);
 156        mpc52xx_cdm = of_iomap(np, 0);
 157        of_node_put(np);
 158
 159        /* simple_gpio registers */
 160        np = of_find_matching_node(NULL, mpc52xx_gpio_simple);
 161        simple_gpio = of_iomap(np, 0);
 162        of_node_put(np);
 163
 164        /* wkup_gpio registers */
 165        np = of_find_matching_node(NULL, mpc52xx_gpio_wkup);
 166        wkup_gpio = of_iomap(np, 0);
 167        of_node_put(np);
 168}
 169
 170/**
 171 * mpc52xx_set_psc_clkdiv: Set clock divider in the CDM for PSC ports
 172 *
 173 * @psc_id: id of psc port; must be 1,2,3 or 6
 174 * @clkdiv: clock divider value to put into CDM PSC register.
 175 */
 176int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv)
 177{
 178        unsigned long flags;
 179        u16 __iomem *reg;
 180        u32 val;
 181        u32 mask;
 182        u32 mclken_div;
 183
 184        if (!mpc52xx_cdm)
 185                return -ENODEV;
 186
 187        mclken_div = 0x8000 | (clkdiv & 0x1FF);
 188        switch (psc_id) {
 189        case 1: reg = &mpc52xx_cdm->mclken_div_psc1; mask = 0x20; break;
 190        case 2: reg = &mpc52xx_cdm->mclken_div_psc2; mask = 0x40; break;
 191        case 3: reg = &mpc52xx_cdm->mclken_div_psc3; mask = 0x80; break;
 192        case 6: reg = &mpc52xx_cdm->mclken_div_psc6; mask = 0x10; break;
 193        default:
 194                return -ENODEV;
 195        }
 196
 197        /* Set the rate and enable the clock */
 198        spin_lock_irqsave(&mpc52xx_lock, flags);
 199        out_be16(reg, mclken_div);
 200        val = in_be32(&mpc52xx_cdm->clk_enables);
 201        out_be32(&mpc52xx_cdm->clk_enables, val | mask);
 202        spin_unlock_irqrestore(&mpc52xx_lock, flags);
 203
 204        return 0;
 205}
 206EXPORT_SYMBOL(mpc52xx_set_psc_clkdiv);
 207
 208/**
 209 * mpc52xx_get_xtal_freq - Get SYS_XTAL_IN frequency for a device
 210 *
 211 * @node: device node
 212 *
 213 * Returns the frequency of the external oscillator clock connected
 214 * to the SYS_XTAL_IN pin, or 0 if it cannot be determined.
 215 */
 216unsigned int mpc52xx_get_xtal_freq(struct device_node *node)
 217{
 218        u32 val;
 219        unsigned int freq;
 220
 221        if (!mpc52xx_cdm)
 222                return 0;
 223
 224        freq = mpc5xxx_get_bus_frequency(node);
 225        if (!freq)
 226                return 0;
 227
 228        if (in_8(&mpc52xx_cdm->ipb_clk_sel) & 0x1)
 229                freq *= 2;
 230
 231        val  = in_be32(&mpc52xx_cdm->rstcfg);
 232        if (val & (1 << 5))
 233                freq *= 8;
 234        else
 235                freq *= 4;
 236        if (val & (1 << 6))
 237                freq /= 12;
 238        else
 239                freq /= 16;
 240
 241        return freq;
 242}
 243EXPORT_SYMBOL(mpc52xx_get_xtal_freq);
 244
 245/**
 246 * mpc52xx_restart: ppc_md->restart hook for mpc5200 using the watchdog timer
 247 */
 248void
 249mpc52xx_restart(char *cmd)
 250{
 251        local_irq_disable();
 252
 253        /* Turn on the watchdog and wait for it to expire.
 254         * It effectively does a reset. */
 255        if (mpc52xx_wdt) {
 256                out_be32(&mpc52xx_wdt->mode, 0x00000000);
 257                out_be32(&mpc52xx_wdt->count, 0x000000ff);
 258                out_be32(&mpc52xx_wdt->mode, 0x00009004);
 259        } else
 260                printk(KERN_ERR __FILE__ ": "
 261                        "mpc52xx_restart: Can't access wdt. "
 262                        "Restart impossible, system halted.\n");
 263
 264        while (1);
 265}
 266
 267#define PSC1_RESET     0x1
 268#define PSC1_SYNC      0x4
 269#define PSC1_SDATA_OUT 0x1
 270#define PSC2_RESET     0x2
 271#define PSC2_SYNC      (0x4<<4)
 272#define PSC2_SDATA_OUT (0x1<<4)
 273#define MPC52xx_GPIO_PSC1_MASK 0x7
 274#define MPC52xx_GPIO_PSC2_MASK (0x7<<4)
 275
 276/**
 277 * mpc5200_psc_ac97_gpio_reset: Use gpio pins to reset the ac97 bus
 278 *
 279 * @psc: psc number to reset (only psc 1 and 2 support ac97)
 280 */
 281int mpc5200_psc_ac97_gpio_reset(int psc_number)
 282{
 283        unsigned long flags;
 284        u32 gpio;
 285        u32 mux;
 286        int out;
 287        int reset;
 288        int sync;
 289
 290        if ((!simple_gpio) || (!wkup_gpio))
 291                return -ENODEV;
 292
 293        switch (psc_number) {
 294        case 0:
 295                reset   = PSC1_RESET;           /* AC97_1_RES */
 296                sync    = PSC1_SYNC;            /* AC97_1_SYNC */
 297                out     = PSC1_SDATA_OUT;       /* AC97_1_SDATA_OUT */
 298                gpio    = MPC52xx_GPIO_PSC1_MASK;
 299                break;
 300        case 1:
 301                reset   = PSC2_RESET;           /* AC97_2_RES */
 302                sync    = PSC2_SYNC;            /* AC97_2_SYNC */
 303                out     = PSC2_SDATA_OUT;       /* AC97_2_SDATA_OUT */
 304                gpio    = MPC52xx_GPIO_PSC2_MASK;
 305                break;
 306        default:
 307                pr_err(__FILE__ ": Unable to determine PSC, no ac97 "
 308                       "cold-reset will be performed\n");
 309                return -ENODEV;
 310        }
 311
 312        spin_lock_irqsave(&gpio_lock, flags);
 313
 314        /* Reconfiure pin-muxing to gpio */
 315        mux = in_be32(&simple_gpio->port_config);
 316        out_be32(&simple_gpio->port_config, mux & (~gpio));
 317
 318        /* enable gpio pins for output */
 319        setbits8(&wkup_gpio->wkup_gpioe, reset);
 320        setbits32(&simple_gpio->simple_gpioe, sync | out);
 321
 322        setbits8(&wkup_gpio->wkup_ddr, reset);
 323        setbits32(&simple_gpio->simple_ddr, sync | out);
 324
 325        /* Assert cold reset */
 326        clrbits32(&simple_gpio->simple_dvo, sync | out);
 327        clrbits8(&wkup_gpio->wkup_dvo, reset);
 328
 329        /* wait for 1 us */
 330        udelay(1);
 331
 332        /* Deassert reset */
 333        setbits8(&wkup_gpio->wkup_dvo, reset);
 334
 335        /* wait at least 200ns */
 336        /* 7 ~= (200ns * timebase) / ns2sec */
 337        __delay(7);
 338
 339        /* Restore pin-muxing */
 340        out_be32(&simple_gpio->port_config, mux);
 341
 342        spin_unlock_irqrestore(&gpio_lock, flags);
 343
 344        return 0;
 345}
 346EXPORT_SYMBOL(mpc5200_psc_ac97_gpio_reset);
 347