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