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