uboot/board/freescale/p2020ds/p2020ds.c
<<
>>
Prefs
   1/*
   2 * Copyright 2007-2009 Freescale Semiconductor, Inc.
   3 *
   4 * See file CREDITS for list of people who contributed to this
   5 * project.
   6 *
   7 * This program is free software; you can redistribute it and/or
   8 * modify it under the terms of the GNU General Public License as
   9 * published by the Free Software Foundation; either version 2 of
  10 * the License, or (at your option) any later version.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program; if not, write to the Free Software
  19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20 * MA 02111-1307 USA
  21 */
  22
  23#include <common.h>
  24#include <command.h>
  25#include <pci.h>
  26#include <asm/processor.h>
  27#include <asm/mmu.h>
  28#include <asm/cache.h>
  29#include <asm/immap_85xx.h>
  30#include <asm/fsl_pci.h>
  31#include <asm/fsl_ddr_sdram.h>
  32#include <asm/io.h>
  33#include <miiphy.h>
  34#include <libfdt.h>
  35#include <fdt_support.h>
  36#include <tsec.h>
  37#include <asm/fsl_law.h>
  38#include <asm/mp.h>
  39#include <netdev.h>
  40
  41#include "../common/pixis.h"
  42#include "../common/sgmii_riser.h"
  43
  44DECLARE_GLOBAL_DATA_PTR;
  45
  46phys_size_t fixed_sdram(void);
  47
  48int checkboard(void)
  49{
  50        u8 sw7;
  51        u8 *pixis_base = (u8 *)PIXIS_BASE;
  52
  53        puts("Board: P2020DS ");
  54#ifdef CONFIG_PHYS_64BIT
  55        puts("(36-bit addrmap) ");
  56#endif
  57
  58        printf("Sys ID: 0x%02x, "
  59                "Sys Ver: 0x%02x, FPGA Ver: 0x%02x, ",
  60                in_8(pixis_base + PIXIS_ID), in_8(pixis_base + PIXIS_VER),
  61                in_8(pixis_base + PIXIS_PVER));
  62
  63        sw7 = in_8(pixis_base + PIXIS_SW(7));
  64        switch ((sw7 & PIXIS_SW7_LBMAP) >> 6) {
  65                case 0:
  66                case 1:
  67                        printf ("vBank: %d\n", ((sw7 & PIXIS_SW7_VBANK) >> 4));
  68                        break;
  69                case 2:
  70                case 3:
  71                        puts ("Promjet\n");
  72                        break;
  73        }
  74
  75        return 0;
  76}
  77
  78phys_size_t initdram(int board_type)
  79{
  80        phys_size_t dram_size = 0;
  81
  82        puts("Initializing....");
  83
  84#ifdef CONFIG_SPD_EEPROM
  85        dram_size = fsl_ddr_sdram();
  86#else
  87        dram_size = fixed_sdram();
  88
  89        if (set_ddr_laws(CONFIG_SYS_DDR_SDRAM_BASE,
  90                         dram_size,
  91                         LAW_TRGT_IF_DDR) < 0) {
  92                printf("ERROR setting Local Access Windows for DDR\n");
  93                return 0;
  94        };
  95#endif
  96        dram_size = setup_ddr_tlbs(dram_size / 0x100000);
  97        dram_size *= 0x100000;
  98
  99        puts("    DDR: ");
 100        return dram_size;
 101}
 102
 103#if !defined(CONFIG_SPD_EEPROM)
 104/*
 105 * Fixed sdram init -- doesn't use serial presence detect.
 106 */
 107
 108phys_size_t fixed_sdram(void)
 109{
 110        volatile ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC85xx_DDR_ADDR;
 111        uint d_init;
 112
 113        ddr->cs0_config = CONFIG_SYS_DDR_CS0_CONFIG;
 114        ddr->timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3;
 115        ddr->timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0;
 116        ddr->sdram_mode = CONFIG_SYS_DDR_MODE_1;
 117        ddr->sdram_mode_2 = CONFIG_SYS_DDR_MODE_2;
 118        ddr->sdram_md_cntl = CONFIG_SYS_DDR_MODE_CTRL;
 119        ddr->sdram_interval = CONFIG_SYS_DDR_INTERVAL;
 120        ddr->sdram_data_init = CONFIG_SYS_DDR_DATA_INIT;
 121        ddr->sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CTRL;
 122        ddr->sdram_cfg_2 = CONFIG_SYS_DDR_CONTROL2;
 123        ddr->ddr_zq_cntl = CONFIG_SYS_DDR_ZQ_CNTL;
 124        ddr->ddr_wrlvl_cntl = CONFIG_SYS_DDR_WRLVL_CNTL;
 125        ddr->ddr_cdr1 = CONFIG_SYS_DDR_CDR1;
 126        ddr->timing_cfg_4 = CONFIG_SYS_DDR_TIMING_4;
 127        ddr->timing_cfg_5 = CONFIG_SYS_DDR_TIMING_5;
 128
 129        if (!strcmp("performance", getenv("perf_mode"))) {
 130                /* Performance Mode Values */
 131
 132                ddr->cs1_config = CONFIG_SYS_DDR_CS1_CONFIG_PERF;
 133                ddr->cs0_bnds = CONFIG_SYS_DDR_CS0_BNDS_PERF;
 134                ddr->cs1_bnds = CONFIG_SYS_DDR_CS1_BNDS_PERF;
 135                ddr->timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1_PERF;
 136                ddr->timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2_PERF;
 137
 138                asm("sync;isync");
 139
 140                udelay(500);
 141
 142                ddr->sdram_cfg = CONFIG_SYS_DDR_CONTROL_PERF;
 143        } else {
 144                /* Stable Mode Values */
 145
 146                ddr->cs1_config = CONFIG_SYS_DDR_CS1_CONFIG;
 147                ddr->cs0_bnds = CONFIG_SYS_DDR_CS0_BNDS;
 148                ddr->cs1_bnds = CONFIG_SYS_DDR_CS1_BNDS;
 149                ddr->timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1;
 150                ddr->timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2;
 151
 152                /* ECC will be assumed in stable mode */
 153                ddr->err_int_en = CONFIG_SYS_DDR_ERR_INT_EN;
 154                ddr->err_disable = CONFIG_SYS_DDR_ERR_DIS;
 155                ddr->err_sbe = CONFIG_SYS_DDR_SBE;
 156
 157                asm("sync;isync");
 158
 159                udelay(500);
 160
 161                ddr->sdram_cfg = CONFIG_SYS_DDR_CONTROL;
 162        }
 163
 164#if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
 165        d_init = 1;
 166        debug("DDR - 1st controller: memory initializing\n");
 167        /*
 168         * Poll until memory is initialized.
 169         * 512 Meg at 400 might hit this 200 times or so.
 170         */
 171        while ((ddr->sdram_cfg_2 & (d_init << 4)) != 0)
 172                udelay(1000);
 173        debug("DDR: memory initialized\n\n");
 174        asm("sync; isync");
 175        udelay(500);
 176#endif
 177
 178        return CONFIG_SYS_SDRAM_SIZE * 1024 * 1024;
 179}
 180
 181#endif
 182
 183#ifdef CONFIG_PCIE1
 184static struct pci_controller pcie1_hose;
 185#endif
 186
 187#ifdef CONFIG_PCIE2
 188static struct pci_controller pcie2_hose;
 189#endif
 190
 191#ifdef CONFIG_PCIE3
 192static struct pci_controller pcie3_hose;
 193#endif
 194
 195#ifdef CONFIG_PCI
 196void pci_init_board(void)
 197{
 198        volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
 199        struct fsl_pci_info pci_info[3];
 200        u32 devdisr, pordevsr, io_sel, host_agent;
 201        int first_free_busno = 0;
 202        int num = 0;
 203
 204        int pcie_ep, pcie_configured;
 205
 206        devdisr = in_be32(&gur->devdisr);
 207        pordevsr = in_be32(&gur->pordevsr);
 208        io_sel = (pordevsr & MPC85xx_PORDEVSR_IO_SEL) >> 19;
 209        host_agent = (in_be32(&gur->porbmsr) & MPC85xx_PORBMSR_HA) >> 16;
 210
 211        debug("   pci_init_board: devdisr=%x, io_sel=%x, host_agent=%x\n",
 212                        devdisr, io_sel, host_agent);
 213
 214        if (!(pordevsr & MPC85xx_PORDEVSR_SGMII2_DIS))
 215                printf("    eTSEC2 is in sgmii mode.\n");
 216        if (!(pordevsr & MPC85xx_PORDEVSR_SGMII3_DIS))
 217                printf("    eTSEC3 is in sgmii mode.\n");
 218
 219        puts("\n");
 220#ifdef CONFIG_PCIE2
 221        pcie_ep = is_fsl_pci_agent(LAW_TRGT_IF_PCIE_2, host_agent);
 222        pcie_configured = is_fsl_pci_cfg(LAW_TRGT_IF_PCIE_2, io_sel);
 223
 224        if (pcie_configured && !(devdisr & MPC85xx_DEVDISR_PCIE2)) {
 225                SET_STD_PCIE_INFO(pci_info[num], 2);
 226                printf("    PCIE2 connected to ULI as %s (base addr %lx)\n",
 227                                pcie_ep ? "End Point" : "Root Complex",
 228                                pci_info[num].regs);
 229                first_free_busno = fsl_pci_init_port(&pci_info[num++],
 230                                        &pcie2_hose, first_free_busno);
 231
 232                /*
 233                 * The workaround doesn't work on p2020 because the location
 234                 * we try and read isn't valid on p2020, fix this later
 235                 */
 236#if 0
 237                /*
 238                 * Activate ULI1575 legacy chip by performing a fake
 239                 * memory access.  Needed to make ULI RTC work.
 240                 * Device 1d has the first on-board memory BAR.
 241                 */
 242
 243                pci_hose_read_config_dword(hose, PCI_BDF(2, 0x1d, 0),
 244                                PCI_BASE_ADDRESS_1, &temp32);
 245                if (temp32 >= CONFIG_SYS_PCIE3_MEM_BUS) {
 246                        void *p = pci_mem_to_virt(PCI_BDF(2, 0x1d, 0),
 247                                                        temp32, 4, 0);
 248                        debug(" uli1575 read to %p\n", p);
 249                        in_be32(p);
 250                }
 251#endif
 252        } else {
 253                printf("    PCIE2: disabled\n");
 254        }
 255        puts("\n");
 256#else
 257        setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_PCIE2); /* disable */
 258#endif
 259
 260#ifdef CONFIG_PCIE3
 261        pcie_ep = is_fsl_pci_agent(LAW_TRGT_IF_PCIE_3, host_agent);
 262        pcie_configured = is_fsl_pci_cfg(LAW_TRGT_IF_PCIE_3, io_sel);
 263
 264        if (pcie_configured && !(devdisr & MPC85xx_DEVDISR_PCIE3)) {
 265                SET_STD_PCIE_INFO(pci_info[num], 3);
 266                printf("    PCIE3 connected to Slot 1 as %s (base addr %lx)\n",
 267                                pcie_ep ? "End Point" : "Root Complex",
 268                                pci_info[num].regs);
 269                first_free_busno = fsl_pci_init_port(&pci_info[num++],
 270                                        &pcie3_hose, first_free_busno);
 271        } else {
 272                printf("    PCIE3: disabled\n");
 273        }
 274        puts("\n");
 275#else
 276        setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_PCIE3); /* disable */
 277#endif
 278
 279#ifdef CONFIG_PCIE1
 280        pcie_ep = is_fsl_pci_agent(LAW_TRGT_IF_PCIE_1, host_agent);
 281        pcie_configured = is_fsl_pci_cfg(LAW_TRGT_IF_PCIE_1, io_sel);
 282
 283        if (pcie_configured && !(devdisr & MPC85xx_DEVDISR_PCIE)) {
 284                SET_STD_PCIE_INFO(pci_info[num], 1);
 285                printf("    PCIE1 connected to Slot 2 as %s (base addr %lx)\n",
 286                                pcie_ep ? "End Point" : "Root Complex",
 287                                pci_info[num].regs);
 288                first_free_busno = fsl_pci_init_port(&pci_info[num++],
 289                                        &pcie1_hose, first_free_busno);
 290        } else {
 291                printf("    PCIE1: disabled\n");
 292        }
 293        puts("\n");
 294#else
 295        setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_PCIE); /* disable */
 296#endif
 297}
 298#endif
 299
 300int board_early_init_r(void)
 301{
 302        const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
 303        const u8 flash_esel = 2;
 304
 305        /*
 306         * Remap Boot flash + PROMJET region to caching-inhibited
 307         * so that flash can be erased properly.
 308         */
 309
 310        /* Flush d-cache and invalidate i-cache of any FLASH data */
 311        flush_dcache();
 312        invalidate_icache();
 313
 314        /* invalidate existing TLB entry for flash + promjet */
 315        disable_tlb(flash_esel);
 316
 317        set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS,
 318                        MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 319                        0, flash_esel, BOOKE_PAGESZ_256M, 1);
 320
 321        return 0;
 322}
 323
 324#ifdef CONFIG_GET_CLK_FROM_ICS307
 325/* decode S[0-2] to Output Divider (OD) */
 326static unsigned char ics307_S_to_OD[] = {
 327        10, 2, 8, 4, 5, 7, 3, 6
 328};
 329
 330/* Calculate frequency being generated by ICS307-02 clock chip based upon
 331 * the control bytes being programmed into it. */
 332/* XXX: This function should probably go into a common library */
 333static unsigned long
 334ics307_clk_freq(unsigned char cw0, unsigned char cw1, unsigned char cw2)
 335{
 336        const unsigned long InputFrequency = CONFIG_ICS307_REFCLK_HZ;
 337        unsigned long VDW = ((cw1 << 1) & 0x1FE) + ((cw2 >> 7) & 1);
 338        unsigned long RDW = cw2 & 0x7F;
 339        unsigned long OD = ics307_S_to_OD[cw0 & 0x7];
 340        unsigned long freq;
 341
 342        /* CLK1Frequency = InputFrequency * 2 * (VDW + 8) / ((RDW + 2) * OD) */
 343
 344        /* cw0:  C1 C0 TTL F1 F0 S2 S1 S0
 345         * cw1:  V8 V7 V6 V5 V4 V3 V2 V1
 346         * cw2:  V0 R6 R5 R4 R3 R2 R1 R0
 347         *
 348         * R6:R0 = Reference Divider Word (RDW)
 349         * V8:V0 = VCO Divider Word (VDW)
 350         * S2:S0 = Output Divider Select (OD)
 351         * F1:F0 = Function of CLK2 Output
 352         * TTL = duty cycle
 353         * C1:C0 = internal load capacitance for cyrstal
 354         */
 355
 356        /* Adding 1 to get a "nicely" rounded number, but this needs
 357         * more tweaking to get a "properly" rounded number. */
 358
 359        freq = 1 + (InputFrequency * 2 * (VDW + 8) / ((RDW + 2) * OD));
 360
 361        debug("ICS307: CW[0-2]: %02X %02X %02X => %lu Hz\n", cw0, cw1, cw2,
 362                        freq);
 363        return freq;
 364}
 365
 366unsigned long get_board_sys_clk(ulong dummy)
 367{
 368        return gd->bus_clk;
 369}
 370
 371unsigned long get_board_ddr_clk(ulong dummy)
 372{
 373        return gd->mem_clk;
 374}
 375
 376unsigned long
 377calculate_board_sys_clk(ulong dummy)
 378{
 379        ulong val;
 380        u8 *pixis_base = (u8 *)PIXIS_BASE;
 381
 382        val = ics307_clk_freq(
 383            in_8(pixis_base + PIXIS_VSYSCLK0),
 384            in_8(pixis_base + PIXIS_VSYSCLK1),
 385            in_8(pixis_base + PIXIS_VSYSCLK2));
 386        debug("sysclk val = %lu\n", val);
 387        return val;
 388}
 389
 390unsigned long
 391calculate_board_ddr_clk(ulong dummy)
 392{
 393        ulong val;
 394        u8 *pixis_base = (u8 *)PIXIS_BASE;
 395
 396        val = ics307_clk_freq(
 397            in_8(pixis_base + PIXIS_VDDRCLK0),
 398            in_8(pixis_base + PIXIS_VDDRCLK1),
 399            in_8(pixis_base + PIXIS_VDDRCLK2));
 400        debug("ddrclk val = %lu\n", val);
 401        return val;
 402}
 403#else
 404unsigned long get_board_sys_clk(ulong dummy)
 405{
 406        u8 i;
 407        ulong val = 0;
 408        u8 *pixis_base = (u8 *)PIXIS_BASE;
 409
 410        i = in_8(pixis_base + PIXIS_SPD);
 411        i &= 0x07;
 412
 413        switch (i) {
 414                case 0:
 415                        val = 33333333;
 416                        break;
 417                case 1:
 418                        val = 40000000;
 419                        break;
 420                case 2:
 421                        val = 50000000;
 422                        break;
 423                case 3:
 424                        val = 66666666;
 425                        break;
 426                case 4:
 427                        val = 83333333;
 428                        break;
 429                case 5:
 430                        val = 100000000;
 431                        break;
 432                case 6:
 433                        val = 133333333;
 434                        break;
 435                case 7:
 436                        val = 166666666;
 437                        break;
 438        }
 439
 440        return val;
 441}
 442
 443unsigned long get_board_ddr_clk(ulong dummy)
 444{
 445        u8 i;
 446        ulong val = 0;
 447        u8 *pixis_base = (u8 *)PIXIS_BASE;
 448
 449        i = in_8(pixis_base + PIXIS_SPD);
 450        i &= 0x38;
 451        i >>= 3;
 452
 453        switch (i) {
 454                case 0:
 455                        val = 33333333;
 456                        break;
 457                case 1:
 458                        val = 40000000;
 459                        break;
 460                case 2:
 461                        val = 50000000;
 462                        break;
 463                case 3:
 464                        val = 66666666;
 465                        break;
 466                case 4:
 467                        val = 83333333;
 468                        break;
 469                case 5:
 470                        val = 100000000;
 471                        break;
 472                case 6:
 473                        val = 133333333;
 474                        break;
 475                case 7:
 476                        val = 166666666;
 477                        break;
 478        }
 479        return val;
 480}
 481#endif
 482
 483#ifdef CONFIG_TSEC_ENET
 484int board_eth_init(bd_t *bis)
 485{
 486        struct tsec_info_struct tsec_info[4];
 487        volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
 488        int num = 0;
 489
 490#ifdef CONFIG_TSEC1
 491        SET_STD_TSEC_INFO(tsec_info[num], 1);
 492        num++;
 493#endif
 494#ifdef CONFIG_TSEC2
 495        SET_STD_TSEC_INFO(tsec_info[num], 2);
 496        if (!(gur->pordevsr & MPC85xx_PORDEVSR_SGMII2_DIS))
 497                tsec_info[num].flags |= TSEC_SGMII;
 498        num++;
 499#endif
 500#ifdef CONFIG_TSEC3
 501        SET_STD_TSEC_INFO(tsec_info[num], 3);
 502        if (!(gur->pordevsr & MPC85xx_PORDEVSR_SGMII3_DIS))
 503                tsec_info[num].flags |= TSEC_SGMII;
 504        num++;
 505#endif
 506
 507        if (!num) {
 508                printf("No TSECs initialized\n");
 509
 510                return 0;
 511        }
 512
 513#ifdef CONFIG_FSL_SGMII_RISER
 514        fsl_sgmii_riser_init(tsec_info, num);
 515#endif
 516
 517        tsec_eth_init(bis, tsec_info, num);
 518
 519        return pci_eth_init(bis);
 520}
 521#endif
 522
 523#if defined(CONFIG_OF_BOARD_SETUP)
 524void ft_board_setup(void *blob, bd_t *bd)
 525{
 526        phys_addr_t base;
 527        phys_size_t size;
 528
 529        ft_cpu_setup(blob, bd);
 530
 531        base = getenv_bootm_low();
 532        size = getenv_bootm_size();
 533
 534        fdt_fixup_memory(blob, (u64)base, (u64)size);
 535
 536#ifdef CONFIG_PCIE3
 537        ft_fsl_pci_setup(blob, "pci0", &pcie3_hose);
 538#endif
 539#ifdef CONFIG_PCIE2
 540        ft_fsl_pci_setup(blob, "pci1", &pcie2_hose);
 541#endif
 542#ifdef CONFIG_PCIE1
 543        ft_fsl_pci_setup(blob, "pci2", &pcie1_hose);
 544#endif
 545#ifdef CONFIG_FSL_SGMII_RISER
 546        fsl_sgmii_riser_fdt_fixup(blob);
 547#endif
 548}
 549#endif
 550
 551#ifdef CONFIG_MP
 552void board_lmb_reserve(struct lmb *lmb)
 553{
 554        cpu_mp_lmb_reserve(lmb);
 555}
 556#endif
 557