linux/arch/powerpc/platforms/85xx/mpc85xx_mds.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2006-2010, 2012 Freescale Semiconductor, Inc.
   3 * All rights reserved.
   4 *
   5 * Author: Andy Fleming <afleming@freescale.com>
   6 *
   7 * Based on 83xx/mpc8360e_pb.c by:
   8 *         Li Yang <LeoLi@freescale.com>
   9 *         Yin Olivia <Hong-hua.Yin@freescale.com>
  10 *
  11 * Description:
  12 * MPC85xx MDS board specific routines.
  13 *
  14 * This program is free software; you can redistribute  it and/or modify it
  15 * under  the terms of  the GNU General  Public License as published by the
  16 * Free Software Foundation;  either version 2 of the  License, or (at your
  17 * option) any later version.
  18 */
  19
  20#include <linux/stddef.h>
  21#include <linux/kernel.h>
  22#include <linux/init.h>
  23#include <linux/errno.h>
  24#include <linux/reboot.h>
  25#include <linux/pci.h>
  26#include <linux/kdev_t.h>
  27#include <linux/major.h>
  28#include <linux/console.h>
  29#include <linux/delay.h>
  30#include <linux/seq_file.h>
  31#include <linux/initrd.h>
  32#include <linux/fsl_devices.h>
  33#include <linux/of_platform.h>
  34#include <linux/of_device.h>
  35#include <linux/phy.h>
  36#include <linux/memblock.h>
  37
  38#include <linux/atomic.h>
  39#include <asm/time.h>
  40#include <asm/io.h>
  41#include <asm/machdep.h>
  42#include <asm/pci-bridge.h>
  43#include <asm/irq.h>
  44#include <mm/mmu_decl.h>
  45#include <asm/prom.h>
  46#include <asm/udbg.h>
  47#include <sysdev/fsl_soc.h>
  48#include <sysdev/fsl_pci.h>
  49#include <sysdev/simple_gpio.h>
  50#include <asm/qe.h>
  51#include <asm/qe_ic.h>
  52#include <asm/mpic.h>
  53#include <asm/swiotlb.h>
  54#include <asm/fsl_guts.h>
  55#include "smp.h"
  56
  57#include "mpc85xx.h"
  58
  59#undef DEBUG
  60#ifdef DEBUG
  61#define DBG(fmt...) udbg_printf(fmt)
  62#else
  63#define DBG(fmt...)
  64#endif
  65
  66#define MV88E1111_SCR   0x10
  67#define MV88E1111_SCR_125CLK    0x0010
  68static int mpc8568_fixup_125_clock(struct phy_device *phydev)
  69{
  70        int scr;
  71        int err;
  72
  73        /* Workaround for the 125 CLK Toggle */
  74        scr = phy_read(phydev, MV88E1111_SCR);
  75
  76        if (scr < 0)
  77                return scr;
  78
  79        err = phy_write(phydev, MV88E1111_SCR, scr & ~(MV88E1111_SCR_125CLK));
  80
  81        if (err)
  82                return err;
  83
  84        err = phy_write(phydev, MII_BMCR, BMCR_RESET);
  85
  86        if (err)
  87                return err;
  88
  89        scr = phy_read(phydev, MV88E1111_SCR);
  90
  91        if (scr < 0)
  92                return scr;
  93
  94        err = phy_write(phydev, MV88E1111_SCR, scr | 0x0008);
  95
  96        return err;
  97}
  98
  99static int mpc8568_mds_phy_fixups(struct phy_device *phydev)
 100{
 101        int temp;
 102        int err;
 103
 104        /* Errata */
 105        err = phy_write(phydev,29, 0x0006);
 106
 107        if (err)
 108                return err;
 109
 110        temp = phy_read(phydev, 30);
 111
 112        if (temp < 0)
 113                return temp;
 114
 115        temp = (temp & (~0x8000)) | 0x4000;
 116        err = phy_write(phydev,30, temp);
 117
 118        if (err)
 119                return err;
 120
 121        err = phy_write(phydev,29, 0x000a);
 122
 123        if (err)
 124                return err;
 125
 126        temp = phy_read(phydev, 30);
 127
 128        if (temp < 0)
 129                return temp;
 130
 131        temp = phy_read(phydev, 30);
 132
 133        if (temp < 0)
 134                return temp;
 135
 136        temp &= ~0x0020;
 137
 138        err = phy_write(phydev,30,temp);
 139
 140        if (err)
 141                return err;
 142
 143        /* Disable automatic MDI/MDIX selection */
 144        temp = phy_read(phydev, 16);
 145
 146        if (temp < 0)
 147                return temp;
 148
 149        temp &= ~0x0060;
 150        err = phy_write(phydev,16,temp);
 151
 152        return err;
 153}
 154
 155/* ************************************************************************
 156 *
 157 * Setup the architecture
 158 *
 159 */
 160#ifdef CONFIG_QUICC_ENGINE
 161static void __init mpc85xx_mds_reset_ucc_phys(void)
 162{
 163        struct device_node *np;
 164        static u8 __iomem *bcsr_regs;
 165
 166        /* Map BCSR area */
 167        np = of_find_node_by_name(NULL, "bcsr");
 168        if (!np)
 169                return;
 170
 171        bcsr_regs = of_iomap(np, 0);
 172        of_node_put(np);
 173        if (!bcsr_regs)
 174                return;
 175
 176        if (machine_is(mpc8568_mds)) {
 177#define BCSR_UCC1_GETH_EN       (0x1 << 7)
 178#define BCSR_UCC2_GETH_EN       (0x1 << 7)
 179#define BCSR_UCC1_MODE_MSK      (0x3 << 4)
 180#define BCSR_UCC2_MODE_MSK      (0x3 << 0)
 181
 182                /* Turn off UCC1 & UCC2 */
 183                clrbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN);
 184                clrbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN);
 185
 186                /* Mode is RGMII, all bits clear */
 187                clrbits8(&bcsr_regs[11], BCSR_UCC1_MODE_MSK |
 188                                         BCSR_UCC2_MODE_MSK);
 189
 190                /* Turn UCC1 & UCC2 on */
 191                setbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN);
 192                setbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN);
 193        } else if (machine_is(mpc8569_mds)) {
 194#define BCSR7_UCC12_GETHnRST    (0x1 << 2)
 195#define BCSR8_UEM_MARVELL_RST   (0x1 << 1)
 196#define BCSR_UCC_RGMII          (0x1 << 6)
 197#define BCSR_UCC_RTBI           (0x1 << 5)
 198                /*
 199                 * U-Boot mangles interrupt polarity for Marvell PHYs,
 200                 * so reset built-in and UEM Marvell PHYs, this puts
 201                 * the PHYs into their normal state.
 202                 */
 203                clrbits8(&bcsr_regs[7], BCSR7_UCC12_GETHnRST);
 204                setbits8(&bcsr_regs[8], BCSR8_UEM_MARVELL_RST);
 205
 206                setbits8(&bcsr_regs[7], BCSR7_UCC12_GETHnRST);
 207                clrbits8(&bcsr_regs[8], BCSR8_UEM_MARVELL_RST);
 208
 209                for_each_compatible_node(np, "network", "ucc_geth") {
 210                        const unsigned int *prop;
 211                        int ucc_num;
 212
 213                        prop = of_get_property(np, "cell-index", NULL);
 214                        if (prop == NULL)
 215                                continue;
 216
 217                        ucc_num = *prop - 1;
 218
 219                        prop = of_get_property(np, "phy-connection-type", NULL);
 220                        if (prop == NULL)
 221                                continue;
 222
 223                        if (strcmp("rtbi", (const char *)prop) == 0)
 224                                clrsetbits_8(&bcsr_regs[7 + ucc_num],
 225                                        BCSR_UCC_RGMII, BCSR_UCC_RTBI);
 226                }
 227        } else if (machine_is(p1021_mds)) {
 228#define BCSR11_ENET_MICRST     (0x1 << 5)
 229                /* Reset Micrel PHY */
 230                clrbits8(&bcsr_regs[11], BCSR11_ENET_MICRST);
 231                setbits8(&bcsr_regs[11], BCSR11_ENET_MICRST);
 232        }
 233
 234        iounmap(bcsr_regs);
 235}
 236
 237static void __init mpc85xx_mds_qe_init(void)
 238{
 239        struct device_node *np;
 240
 241        np = of_find_compatible_node(NULL, NULL, "fsl,qe");
 242        if (!np) {
 243                np = of_find_node_by_name(NULL, "qe");
 244                if (!np)
 245                        return;
 246        }
 247
 248        if (!of_device_is_available(np)) {
 249                of_node_put(np);
 250                return;
 251        }
 252
 253        qe_reset();
 254        of_node_put(np);
 255
 256        np = of_find_node_by_name(NULL, "par_io");
 257        if (np) {
 258                struct device_node *ucc;
 259
 260                par_io_init(np);
 261                of_node_put(np);
 262
 263                for_each_node_by_name(ucc, "ucc")
 264                        par_io_of_config(ucc);
 265        }
 266
 267        mpc85xx_mds_reset_ucc_phys();
 268
 269        if (machine_is(p1021_mds)) {
 270
 271                struct ccsr_guts __iomem *guts;
 272
 273                np = of_find_node_by_name(NULL, "global-utilities");
 274                if (np) {
 275                        guts = of_iomap(np, 0);
 276                        if (!guts)
 277                                pr_err("mpc85xx-rdb: could not map global utilities register\n");
 278                        else{
 279                        /* P1021 has pins muxed for QE and other functions. To
 280                         * enable QE UEC mode, we need to set bit QE0 for UCC1
 281                         * in Eth mode, QE0 and QE3 for UCC5 in Eth mode, QE9
 282                         * and QE12 for QE MII management signals in PMUXCR
 283                         * register.
 284                         */
 285                                setbits32(&guts->pmuxcr, MPC85xx_PMUXCR_QE(0) |
 286                                                  MPC85xx_PMUXCR_QE(3) |
 287                                                  MPC85xx_PMUXCR_QE(9) |
 288                                                  MPC85xx_PMUXCR_QE(12));
 289                                iounmap(guts);
 290                        }
 291                        of_node_put(np);
 292                }
 293
 294        }
 295}
 296
 297static void __init mpc85xx_mds_qeic_init(void)
 298{
 299        struct device_node *np;
 300
 301        np = of_find_compatible_node(NULL, NULL, "fsl,qe");
 302        if (!of_device_is_available(np)) {
 303                of_node_put(np);
 304                return;
 305        }
 306
 307        np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
 308        if (!np) {
 309                np = of_find_node_by_type(NULL, "qeic");
 310                if (!np)
 311                        return;
 312        }
 313
 314        if (machine_is(p1021_mds))
 315                qe_ic_init(np, 0, qe_ic_cascade_low_mpic,
 316                                qe_ic_cascade_high_mpic);
 317        else
 318                qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL);
 319        of_node_put(np);
 320}
 321#else
 322static void __init mpc85xx_mds_qe_init(void) { }
 323static void __init mpc85xx_mds_qeic_init(void) { }
 324#endif  /* CONFIG_QUICC_ENGINE */
 325
 326static void __init mpc85xx_mds_setup_arch(void)
 327{
 328        if (ppc_md.progress)
 329                ppc_md.progress("mpc85xx_mds_setup_arch()", 0);
 330
 331        mpc85xx_smp_init();
 332
 333        mpc85xx_mds_qe_init();
 334
 335        fsl_pci_assign_primary();
 336
 337        swiotlb_detect_4g();
 338}
 339
 340
 341static int __init board_fixups(void)
 342{
 343        char phy_id[20];
 344        char *compstrs[2] = {"fsl,gianfar-mdio", "fsl,ucc-mdio"};
 345        struct device_node *mdio;
 346        struct resource res;
 347        int i;
 348
 349        for (i = 0; i < ARRAY_SIZE(compstrs); i++) {
 350                mdio = of_find_compatible_node(NULL, NULL, compstrs[i]);
 351
 352                of_address_to_resource(mdio, 0, &res);
 353                snprintf(phy_id, sizeof(phy_id), "%llx:%02x",
 354                        (unsigned long long)res.start, 1);
 355
 356                phy_register_fixup_for_id(phy_id, mpc8568_fixup_125_clock);
 357                phy_register_fixup_for_id(phy_id, mpc8568_mds_phy_fixups);
 358
 359                /* Register a workaround for errata */
 360                snprintf(phy_id, sizeof(phy_id), "%llx:%02x",
 361                        (unsigned long long)res.start, 7);
 362                phy_register_fixup_for_id(phy_id, mpc8568_mds_phy_fixups);
 363
 364                of_node_put(mdio);
 365        }
 366
 367        return 0;
 368}
 369machine_arch_initcall(mpc8568_mds, board_fixups);
 370machine_arch_initcall(mpc8569_mds, board_fixups);
 371
 372static int __init mpc85xx_publish_devices(void)
 373{
 374        if (machine_is(mpc8568_mds))
 375                simple_gpiochip_init("fsl,mpc8568mds-bcsr-gpio");
 376        if (machine_is(mpc8569_mds))
 377                simple_gpiochip_init("fsl,mpc8569mds-bcsr-gpio");
 378
 379        return mpc85xx_common_publish_devices();
 380}
 381
 382machine_arch_initcall(mpc8568_mds, mpc85xx_publish_devices);
 383machine_arch_initcall(mpc8569_mds, mpc85xx_publish_devices);
 384machine_arch_initcall(p1021_mds, mpc85xx_common_publish_devices);
 385
 386machine_arch_initcall(mpc8568_mds, swiotlb_setup_bus_notifier);
 387machine_arch_initcall(mpc8569_mds, swiotlb_setup_bus_notifier);
 388machine_arch_initcall(p1021_mds, swiotlb_setup_bus_notifier);
 389
 390static void __init mpc85xx_mds_pic_init(void)
 391{
 392        struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN |
 393                        MPIC_SINGLE_DEST_CPU,
 394                        0, 256, " OpenPIC  ");
 395        BUG_ON(mpic == NULL);
 396
 397        mpic_init(mpic);
 398        mpc85xx_mds_qeic_init();
 399}
 400
 401static int __init mpc85xx_mds_probe(void)
 402{
 403        unsigned long root = of_get_flat_dt_root();
 404
 405        return of_flat_dt_is_compatible(root, "MPC85xxMDS");
 406}
 407
 408define_machine(mpc8568_mds) {
 409        .name           = "MPC8568 MDS",
 410        .probe          = mpc85xx_mds_probe,
 411        .setup_arch     = mpc85xx_mds_setup_arch,
 412        .init_IRQ       = mpc85xx_mds_pic_init,
 413        .get_irq        = mpic_get_irq,
 414        .restart        = fsl_rstcr_restart,
 415        .calibrate_decr = generic_calibrate_decr,
 416        .progress       = udbg_progress,
 417#ifdef CONFIG_PCI
 418        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
 419#endif
 420};
 421
 422static int __init mpc8569_mds_probe(void)
 423{
 424        unsigned long root = of_get_flat_dt_root();
 425
 426        return of_flat_dt_is_compatible(root, "fsl,MPC8569EMDS");
 427}
 428
 429define_machine(mpc8569_mds) {
 430        .name           = "MPC8569 MDS",
 431        .probe          = mpc8569_mds_probe,
 432        .setup_arch     = mpc85xx_mds_setup_arch,
 433        .init_IRQ       = mpc85xx_mds_pic_init,
 434        .get_irq        = mpic_get_irq,
 435        .restart        = fsl_rstcr_restart,
 436        .calibrate_decr = generic_calibrate_decr,
 437        .progress       = udbg_progress,
 438#ifdef CONFIG_PCI
 439        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
 440#endif
 441};
 442
 443static int __init p1021_mds_probe(void)
 444{
 445        unsigned long root = of_get_flat_dt_root();
 446
 447        return of_flat_dt_is_compatible(root, "fsl,P1021MDS");
 448
 449}
 450
 451define_machine(p1021_mds) {
 452        .name           = "P1021 MDS",
 453        .probe          = p1021_mds_probe,
 454        .setup_arch     = mpc85xx_mds_setup_arch,
 455        .init_IRQ       = mpc85xx_mds_pic_init,
 456        .get_irq        = mpic_get_irq,
 457        .restart        = fsl_rstcr_restart,
 458        .calibrate_decr = generic_calibrate_decr,
 459        .progress       = udbg_progress,
 460#ifdef CONFIG_PCI
 461        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
 462#endif
 463};
 464
 465