uboot/board/freescale/mpc837xemds/mpc837xemds.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2007,2010 Freescale Semiconductor, Inc.
   3 * Dave Liu <daveliu@freescale.com>
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8#include <common.h>
   9#include <hwconfig.h>
  10#include <i2c.h>
  11#include <asm/io.h>
  12#include <asm/fsl_mpc83xx_serdes.h>
  13#include <spd_sdram.h>
  14#include <tsec.h>
  15#include <libfdt.h>
  16#include <fdt_support.h>
  17#include <fsl_esdhc.h>
  18#include <fsl_mdio.h>
  19#include <phy.h>
  20#include "pci.h"
  21#include "../common/pq-mds-pib.h"
  22
  23DECLARE_GLOBAL_DATA_PTR;
  24
  25int board_early_init_f(void)
  26{
  27        u8 *bcsr = (u8 *)CONFIG_SYS_BCSR;
  28
  29        /* Enable flash write */
  30        bcsr[0x9] &= ~0x04;
  31        /* Clear all of the interrupt of BCSR */
  32        bcsr[0xe] = 0xff;
  33
  34#ifdef CONFIG_FSL_SERDES
  35        immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
  36        u32 spridr = in_be32(&immr->sysconf.spridr);
  37
  38        /* we check only part num, and don't look for CPU revisions */
  39        switch (PARTID_NO_E(spridr)) {
  40        case SPR_8377:
  41                fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_SATA,
  42                                FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V);
  43                break;
  44        case SPR_8378:
  45                fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_SGMII,
  46                                FSL_SERDES_CLK_125, FSL_SERDES_VDD_1V);
  47                break;
  48        case SPR_8379:
  49                fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_SATA,
  50                                FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V);
  51                fsl_setup_serdes(CONFIG_FSL_SERDES2, FSL_SERDES_PROTO_SATA,
  52                                FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V);
  53                break;
  54        default:
  55                printf("serdes not configured: unknown CPU part number: "
  56                                "%04x\n", spridr >> 16);
  57                break;
  58        }
  59#endif /* CONFIG_FSL_SERDES */
  60        return 0;
  61}
  62
  63#ifdef CONFIG_FSL_ESDHC
  64int board_mmc_init(bd_t *bd)
  65{
  66        struct immap __iomem *im = (struct immap __iomem *)CONFIG_SYS_IMMR;
  67        u8 *bcsr = (u8 *)CONFIG_SYS_BCSR;
  68
  69        if (!hwconfig("esdhc"))
  70                return 0;
  71
  72        /* Set SPI_SD, SER_SD, and IRQ4_WP so that SD signals go through */
  73        bcsr[0xc] |= 0x4c;
  74
  75        /* Set proper bits in SICR to allow SD signals through */
  76        clrsetbits_be32(&im->sysconf.sicrl, SICRL_USB_B, SICRL_USB_B_SD);
  77        clrsetbits_be32(&im->sysconf.sicrh, SICRH_GPIO2_E | SICRH_SPI,
  78                        SICRH_GPIO2_E_SD | SICRH_SPI_SD);
  79
  80        return fsl_esdhc_mmc_init(bd);
  81}
  82#endif
  83
  84#if defined(CONFIG_TSEC1) || defined(CONFIG_TSEC2)
  85int board_eth_init(bd_t *bd)
  86{
  87        struct fsl_pq_mdio_info mdio_info;
  88        struct tsec_info_struct tsec_info[2];
  89        struct immap __iomem *im = (struct immap __iomem *)CONFIG_SYS_IMMR;
  90        u32 rcwh = in_be32(&im->reset.rcwh);
  91        u32 tsec_mode;
  92        int num = 0;
  93
  94        /* New line after Net: */
  95        printf("\n");
  96
  97#ifdef CONFIG_TSEC1
  98        SET_STD_TSEC_INFO(tsec_info[num], 1);
  99
 100        printf(CONFIG_TSEC1_NAME ": ");
 101
 102        tsec_mode = rcwh & HRCWH_TSEC1M_MASK;
 103        if (tsec_mode == HRCWH_TSEC1M_IN_RGMII) {
 104                printf("RGMII\n");
 105                /* this is default, no need to fixup */
 106        } else if (tsec_mode == HRCWH_TSEC1M_IN_SGMII) {
 107                printf("SGMII\n");
 108                tsec_info[num].phyaddr = TSEC1_PHY_ADDR_SGMII;
 109                tsec_info[num].flags = TSEC_GIGABIT;
 110        } else {
 111                printf("unsupported PHY type\n");
 112        }
 113        num++;
 114#endif
 115#ifdef CONFIG_TSEC2
 116        SET_STD_TSEC_INFO(tsec_info[num], 2);
 117
 118        printf(CONFIG_TSEC2_NAME ": ");
 119
 120        tsec_mode = rcwh & HRCWH_TSEC2M_MASK;
 121        if (tsec_mode == HRCWH_TSEC2M_IN_RGMII) {
 122                printf("RGMII\n");
 123                /* this is default, no need to fixup */
 124        } else if (tsec_mode == HRCWH_TSEC2M_IN_SGMII) {
 125                printf("SGMII\n");
 126                tsec_info[num].phyaddr = TSEC2_PHY_ADDR_SGMII;
 127                tsec_info[num].flags = TSEC_GIGABIT;
 128        } else {
 129                printf("unsupported PHY type\n");
 130        }
 131        num++;
 132#endif
 133
 134        mdio_info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR;
 135        mdio_info.name = DEFAULT_MII_NAME;
 136        fsl_pq_mdio_init(bd, &mdio_info);
 137
 138        return tsec_eth_init(bd, tsec_info, num);
 139}
 140
 141static void __ft_tsec_fixup(void *blob, bd_t *bd, const char *alias,
 142                            int phy_addr)
 143{
 144        const u32 *ph;
 145        int off;
 146        int err;
 147
 148        off = fdt_path_offset(blob, alias);
 149        if (off < 0) {
 150                printf("WARNING: could not find %s alias: %s.\n", alias,
 151                        fdt_strerror(off));
 152                return;
 153        }
 154
 155        err = fdt_fixup_phy_connection(blob, off, PHY_INTERFACE_MODE_SGMII);
 156
 157        if (err) {
 158                printf("WARNING: could not set phy-connection-type for %s: "
 159                        "%s.\n", alias, fdt_strerror(err));
 160                return;
 161        }
 162
 163        ph = (u32 *)fdt_getprop(blob, off, "phy-handle", 0);
 164        if (!ph) {
 165                printf("WARNING: could not get phy-handle for %s.\n",
 166                        alias);
 167                return;
 168        }
 169
 170        off = fdt_node_offset_by_phandle(blob, *ph);
 171        if (off < 0) {
 172                printf("WARNING: could not get phy node for %s: %s\n", alias,
 173                        fdt_strerror(off));
 174                return;
 175        }
 176
 177        phy_addr = cpu_to_fdt32(phy_addr);
 178        err = fdt_setprop(blob, off, "reg", &phy_addr, sizeof(phy_addr));
 179        if (err < 0) {
 180                printf("WARNING: could not set phy node's reg for %s: "
 181                        "%s.\n", alias, fdt_strerror(err));
 182                return;
 183        }
 184}
 185
 186static void ft_tsec_fixup(void *blob, bd_t *bd)
 187{
 188        struct immap __iomem *im = (struct immap __iomem *)CONFIG_SYS_IMMR;
 189        u32 rcwh = in_be32(&im->reset.rcwh);
 190        u32 tsec_mode;
 191
 192#ifdef CONFIG_TSEC1
 193        tsec_mode = rcwh & HRCWH_TSEC1M_MASK;
 194        if (tsec_mode == HRCWH_TSEC1M_IN_SGMII)
 195                __ft_tsec_fixup(blob, bd, "ethernet0", TSEC1_PHY_ADDR_SGMII);
 196#endif
 197
 198#ifdef CONFIG_TSEC2
 199        tsec_mode = rcwh & HRCWH_TSEC2M_MASK;
 200        if (tsec_mode == HRCWH_TSEC2M_IN_SGMII)
 201                __ft_tsec_fixup(blob, bd, "ethernet1", TSEC2_PHY_ADDR_SGMII);
 202#endif
 203}
 204#else
 205static inline void ft_tsec_fixup(void *blob, bd_t *bd) {}
 206#endif /* defined(CONFIG_TSEC1) || defined(CONFIG_TSEC2) */
 207
 208int board_early_init_r(void)
 209{
 210#ifdef CONFIG_PQ_MDS_PIB
 211        pib_init();
 212#endif
 213        return 0;
 214}
 215
 216#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
 217extern void ddr_enable_ecc(unsigned int dram_size);
 218#endif
 219int fixed_sdram(void);
 220
 221int dram_init(void)
 222{
 223        volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
 224        u32 msize = 0;
 225
 226        if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32) im)
 227                return -ENXIO;
 228
 229#if defined(CONFIG_SPD_EEPROM)
 230        msize = spd_sdram();
 231#else
 232        msize = fixed_sdram();
 233#endif
 234
 235#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
 236        /* Initialize DDR ECC byte */
 237        ddr_enable_ecc(msize * 1024 * 1024);
 238#endif
 239
 240        /* return total bus DDR size(bytes) */
 241        gd->ram_size = msize * 1024 * 1024;
 242
 243        return 0;
 244}
 245
 246#if !defined(CONFIG_SPD_EEPROM)
 247/*************************************************************************
 248 *  fixed sdram init -- doesn't use serial presence detect.
 249 ************************************************************************/
 250int fixed_sdram(void)
 251{
 252        volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
 253        u32 msize = CONFIG_SYS_DDR_SIZE * 1024 * 1024;
 254        u32 msize_log2 = __ilog2(msize);
 255
 256        im->sysconf.ddrlaw[0].bar = CONFIG_SYS_DDR_SDRAM_BASE & 0xfffff000;
 257        im->sysconf.ddrlaw[0].ar = LBLAWAR_EN | (msize_log2 - 1);
 258
 259#if (CONFIG_SYS_DDR_SIZE != 512)
 260#warning Currenly any ddr size other than 512 is not supported
 261#endif
 262        im->sysconf.ddrcdr = CONFIG_SYS_DDRCDR_VALUE;
 263        udelay(50000);
 264
 265        im->ddr.sdram_clk_cntl = CONFIG_SYS_DDR_SDRAM_CLK_CNTL;
 266        udelay(1000);
 267
 268        im->ddr.csbnds[0].csbnds = CONFIG_SYS_DDR_CS0_BNDS;
 269        im->ddr.cs_config[0] = CONFIG_SYS_DDR_CS0_CONFIG;
 270        udelay(1000);
 271
 272        im->ddr.timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0;
 273        im->ddr.timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1;
 274        im->ddr.timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2;
 275        im->ddr.timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3;
 276        im->ddr.sdram_cfg = CONFIG_SYS_DDR_SDRAM_CFG;
 277        im->ddr.sdram_cfg2 = CONFIG_SYS_DDR_SDRAM_CFG2;
 278        im->ddr.sdram_mode = CONFIG_SYS_DDR_MODE;
 279        im->ddr.sdram_mode2 = CONFIG_SYS_DDR_MODE2;
 280        im->ddr.sdram_interval = CONFIG_SYS_DDR_INTERVAL;
 281        __asm__ __volatile__("sync");
 282        udelay(1000);
 283
 284        im->ddr.sdram_cfg |= SDRAM_CFG_MEM_EN;
 285        udelay(2000);
 286        return CONFIG_SYS_DDR_SIZE;
 287}
 288#endif /*!CONFIG_SYS_SPD_EEPROM */
 289
 290int checkboard(void)
 291{
 292        puts("Board: Freescale MPC837xEMDS\n");
 293        return 0;
 294}
 295
 296#ifdef CONFIG_PCI
 297int board_pci_host_broken(void)
 298{
 299        struct immap __iomem *im = (struct immap __iomem *)CONFIG_SYS_IMMR;
 300        const u32 rcw_mask = HRCWH_PCI1_ARBITER_ENABLE | HRCWH_PCI_HOST;
 301
 302        /* It's always OK in case of external arbiter. */
 303        if (hwconfig_subarg_cmp("pci", "arbiter", "external"))
 304                return 0;
 305
 306        if ((in_be32(&im->reset.rcwh) & rcw_mask) != rcw_mask)
 307                return 1;
 308
 309        return 0;
 310}
 311
 312static void ft_pci_fixup(void *blob, bd_t *bd)
 313{
 314        const char *status = "broken (no arbiter)";
 315        int off;
 316        int err;
 317
 318        off = fdt_path_offset(blob, "pci0");
 319        if (off < 0) {
 320                printf("WARNING: could not find pci0 alias: %s.\n",
 321                        fdt_strerror(off));
 322                return;
 323        }
 324
 325        err = fdt_setprop(blob, off, "status", status, strlen(status) + 1);
 326        if (err) {
 327                printf("WARNING: could not set status for pci0: %s.\n",
 328                        fdt_strerror(err));
 329                return;
 330        }
 331}
 332#endif
 333
 334#if defined(CONFIG_OF_BOARD_SETUP)
 335int ft_board_setup(void *blob, bd_t *bd)
 336{
 337        ft_cpu_setup(blob, bd);
 338        ft_tsec_fixup(blob, bd);
 339        fsl_fdt_fixup_dr_usb(blob, bd);
 340        fdt_fixup_esdhc(blob, bd);
 341#ifdef CONFIG_PCI
 342        ft_pci_setup(blob, bd);
 343        if (board_pci_host_broken())
 344                ft_pci_fixup(blob, bd);
 345        ft_pcie_fixup(blob, bd);
 346#endif
 347
 348        return 0;
 349}
 350#endif /* CONFIG_OF_BOARD_SETUP */
 351