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