diff options
author | Shengzhou Liu <Shengzhou.Liu@freescale.com> | 2011-11-22 16:51:13 +0800 |
---|---|---|
committer | Kumar Gala <galak@kernel.crashing.org> | 2011-11-29 08:48:06 -0600 |
commit | ae6b03fefc1a8b27d834ef12e0a586f4237fdb1f (patch) | |
tree | 4eefe39f8dc470c3caaa36ec3327328aa126951f /board/freescale/p3060qds | |
parent | f2717b47eac74fe262d89c6d8f6bb5a047a77229 (diff) | |
download | u-boot-imx-ae6b03fefc1a8b27d834ef12e0a586f4237fdb1f.zip u-boot-imx-ae6b03fefc1a8b27d834ef12e0a586f4237fdb1f.tar.gz u-boot-imx-ae6b03fefc1a8b27d834ef12e0a586f4237fdb1f.tar.bz2 |
powerpc/p3060qds: Add board related support for P3060QDS platform
The P3060QDS is a Freescale reference board for the six-core P3060 SOC.
P3060QDS Board Overview:
Memory subsystem:
- 2G Bytes unbuffered DDR3 SDRAM SO-DIMM(64bit bus)
- 128M Bytes NOR flash single-chip memory
- 16M Bytes SPI flash
- 8K Bytes AT24C64 I2C EEPROM for RCW
Ethernet:
- Eight Ethernet controllers (4x1G + 4x1G/2.5G)
- Three VSC8641 PHYs on board (2xRGMII + 1xMII)
- Suport multiple Vitesse VSC8234 SGMII Cards in Slot1/2/3
PCIe: Two PCI Express 2.0 controllers/ports
USB: Two USB2.0, USB1(TYPE-A) and USB2(TYPE-AB) on board
I2C: Four I2C controllers
UART: Supports two dUARTs up to 115200 bps for console
RapidIO: Two RapidIO, sRIO1 and sRIO2
Signed-off-by: Shengzhou Liu <Shengzhou.Liu@freescale.com>
Signed-off-by: York Sun <yorksun@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'board/freescale/p3060qds')
-rw-r--r-- | board/freescale/p3060qds/Makefile | 54 | ||||
-rw-r--r-- | board/freescale/p3060qds/ddr.c | 248 | ||||
-rw-r--r-- | board/freescale/p3060qds/eth.c | 482 | ||||
-rw-r--r-- | board/freescale/p3060qds/fixed_ddr.c | 214 | ||||
-rw-r--r-- | board/freescale/p3060qds/p3060qds.c | 341 | ||||
-rw-r--r-- | board/freescale/p3060qds/p3060qds.h | 30 | ||||
-rw-r--r-- | board/freescale/p3060qds/p3060qds_qixis.h | 74 |
7 files changed, 1443 insertions, 0 deletions
diff --git a/board/freescale/p3060qds/Makefile b/board/freescale/p3060qds/Makefile new file mode 100644 index 0000000..ae136f4 --- /dev/null +++ b/board/freescale/p3060qds/Makefile @@ -0,0 +1,54 @@ +# +# Copyright 2011 Freescale Semiconductor, Inc. +# (C) Copyright 2001-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).o + +COBJS-y += $(BOARD).o +COBJS-y += ddr.o +COBJS-y += eth.o +COBJS-y += fixed_ddr.o + +SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(OBJS) $(SOBJS) + $(call cmd_link_o_target, $(OBJS)) + +clean: + rm -f $(OBJS) $(SOBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/freescale/p3060qds/ddr.c b/board/freescale/p3060qds/ddr.c new file mode 100644 index 0000000..9affbf0 --- /dev/null +++ b/board/freescale/p3060qds/ddr.c @@ -0,0 +1,248 @@ +/* + * Copyright 2009-2011 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * Version 2 as published by the Free Software Foundation. + */ + +#include <common.h> +#include <i2c.h> +#include <hwconfig.h> +#include <asm/mmu.h> +#include <asm/fsl_ddr_sdram.h> +#include <asm/fsl_ddr_dimm_params.h> +#include <asm/fsl_law.h> + +#include "p3060qds.h" + +/* + * Fixed sdram init -- doesn't use serial presence detect. + */ + +phys_size_t fixed_sdram(void) +{ + int i; + char buf[32]; + fsl_ddr_cfg_regs_t ddr_cfg_regs; + phys_size_t ddr_size; + unsigned int lawbar1_target_id; + ulong ddr_freq, ddr_freq_mhz; + + ddr_freq = get_ddr_freq(0); + ddr_freq_mhz = ddr_freq / 1000000; + + printf("Configuring DDR for %s MT/s data rate\n", + strmhz(buf, ddr_freq)); + + for (i = 0; fixed_ddr_parm_0[i].max_freq > 0; i++) { + if ((ddr_freq_mhz > fixed_ddr_parm_0[i].min_freq) && + (ddr_freq_mhz <= fixed_ddr_parm_0[i].max_freq)) { + memcpy(&ddr_cfg_regs, + fixed_ddr_parm_0[i].ddr_settings, + sizeof(ddr_cfg_regs)); + break; + } + } + + if (fixed_ddr_parm_0[i].max_freq == 0) + panic("Unsupported DDR data rate %s MT/s data rate\n", + strmhz(buf, ddr_freq)); + + ddr_size = (phys_size_t) CONFIG_SYS_SDRAM_SIZE * 1024 * 1024; + ddr_cfg_regs.ddr_cdr1 = DDR_CDR1_DHC_EN; + fsl_ddr_set_memctl_regs(&ddr_cfg_regs, 0); + + /* + * setup laws for DDR. If not interleaving, presuming half memory on + * DDR1 and the other half on DDR2 + */ + if (fixed_ddr_parm_0[i].ddr_settings->cs[0].config & 0x20000000) { + if (set_ddr_laws(CONFIG_SYS_DDR_SDRAM_BASE, + ddr_size, + LAW_TRGT_IF_DDR_INTRLV) < 0) { + printf("ERROR setting Local Access Windows for DDR\n"); + return 0; + } + } else { + lawbar1_target_id = LAW_TRGT_IF_DDR_1; + if (set_ddr_laws(CONFIG_SYS_DDR_SDRAM_BASE, + ddr_size, + lawbar1_target_id) < 0) { + printf("ERROR setting Local Access Windows for DDR\n"); + return 0; + } + } + return ddr_size; +} + +struct board_specific_params { + u32 n_ranks; + u32 datarate_mhz_high; + u32 clk_adjust; + u32 wrlvl_start; + u32 cpo; + u32 write_data_delay; + u32 force_2T; +}; + +/* + * This table contains all valid speeds we want to override with board + * specific parameters. datarate_mhz_high values need to be in ascending order + * for each n_ranks group. + */ +static const struct board_specific_params udimm[] = { + /* + * memory controller 0 + * num| hi| clk| wrlvl | cpo |wrdata|2T + * ranks| mhz|adjst| start | |delay | + */ + {4, 850, 4, 6, 0xff, 2, 0}, + {4, 950, 5, 7, 0xff, 2, 0}, + {4, 1050, 5, 8, 0xff, 2, 0}, + {4, 1250, 5, 10, 0xff, 2, 0}, + {4, 1350, 5, 11, 0xff, 2, 0}, + {4, 1666, 5, 12, 0xff, 2, 0}, + {2, 850, 5, 6, 0xff, 2, 0}, + {2, 950, 5, 7, 0xff, 2, 0}, + {2, 1250, 4, 6, 0xff, 2, 0}, + {2, 1350, 5, 7, 0xff, 2, 0}, + {2, 1666, 5, 8, 0xff, 2, 0}, + {1, 850, 4, 5, 0xff, 2, 0}, + {1, 950, 4, 7, 0xff, 2, 0}, + {1, 1666, 4, 8, 0xff, 2, 0}, + {} +}; + +static const struct board_specific_params rdimm[] = { + /* + * memory controller 0 + * num| hi| clk| wrlvl | cpo |wrdata|2T + * ranks| mhz|adjst| start | |delay | + */ + {4, 850, 4, 6, 0xff, 2, 0}, + {4, 950, 5, 7, 0xff, 2, 0}, + {4, 1050, 5, 8, 0xff, 2, 0}, + {4, 1250, 5, 10, 0xff, 2, 0}, + {4, 1350, 5, 11, 0xff, 2, 0}, + {4, 1666, 5, 12, 0xff, 2, 0}, + {2, 850, 4, 6, 0xff, 2, 0}, + {2, 1050, 4, 7, 0xff, 2, 0}, + {2, 1666, 4, 8, 0xff, 2, 0}, + {1, 850, 4, 5, 0xff, 2, 0}, + {1, 950, 4, 7, 0xff, 2, 0}, + {1, 1666, 4, 8, 0xff, 2, 0}, + {} +}; + +void fsl_ddr_board_options(memctl_options_t *popts, + dimm_params_t *pdimm, + unsigned int ctrl_num) +{ + const struct board_specific_params *pbsp, *pbsp_highest = NULL; + ulong ddr_freq; + + if (ctrl_num) { + printf("Wrong parameter for controller number %d", ctrl_num); + return; + } + if (!pdimm->n_ranks) + return; + + if (popts->registered_dimm_en) + pbsp = rdimm; + else + pbsp = udimm; + + /* Get clk_adjust, cpo, write_data_delay,2T, according to the board ddr + * freqency and n_banks specified in board_specific_parameters table. + */ + ddr_freq = get_ddr_freq(0) / 1000000; + while (pbsp->datarate_mhz_high) { + if (pbsp->n_ranks == pdimm->n_ranks) { + if (ddr_freq <= pbsp->datarate_mhz_high) { + popts->cpo_override = pbsp->cpo; + popts->write_data_delay = + pbsp->write_data_delay; + popts->clk_adjust = pbsp->clk_adjust; + popts->wrlvl_start = pbsp->wrlvl_start; + popts->twoT_en = pbsp->force_2T; + goto found; + } + pbsp_highest = pbsp; + } + pbsp++; + } + + if (pbsp_highest) { + printf("Error: board specific timing not found " + "for data rate %lu MT/s!\n" + "Trying to use the highest speed (%u) parameters\n", + ddr_freq, pbsp_highest->datarate_mhz_high); + popts->cpo_override = pbsp_highest->cpo; + popts->write_data_delay = pbsp_highest->write_data_delay; + popts->clk_adjust = pbsp_highest->clk_adjust; + popts->wrlvl_start = pbsp_highest->wrlvl_start; + popts->twoT_en = pbsp_highest->force_2T; + } else { + panic("DIMM is not supported by this board"); + } + + +found: + + /* + * The datasheet of HMT125U7BFR8C-H9 blocks CL=7 as reservered. + * However SPD still claims CL=7 is supported. Extensive tests + * confirmed this board cannot work stably with CL=7 with this + * particular DIMM. + */ + if (ddr_freq >= 800 && ddr_freq < 1066 && \ + !strncmp(pdimm[0].mpart, "HMT125U7BFR8C-H9", 16)) { + popts->cas_latency_override = 1; + popts->cas_latency_override_value = 8; + debug("Override CL to 8\n"); + } + /* + * Factors to consider for half-strength driver enable: + * - number of DIMMs installed + */ + popts->half_strength_driver_enable = 0; + /* + * Write leveling override + */ + popts->wrlvl_override = 1; + popts->wrlvl_sample = 0xf; + + /* + * Rtt and Rtt_WR override + */ + popts->rtt_override = 0; + + /* Enable ZQ calibration */ + popts->zq_en = 1; + + /* DHC_EN =1, ODT = 60 Ohm */ + popts->ddr_cdr1 = DDR_CDR1_DHC_EN; +} + +phys_size_t initdram(int board_type) +{ + phys_size_t dram_size; + + puts("Initializing...."); + + if (fsl_use_spd()) { + puts("using SPD\n"); + dram_size = fsl_ddr_sdram(); + } else { + puts("using fixed parameters\n"); + dram_size = fixed_sdram(); + } + + dram_size = setup_ddr_tlbs(dram_size / 0x100000); + dram_size *= 0x100000; + + debug(" DDR: "); + return dram_size; +} diff --git a/board/freescale/p3060qds/eth.c b/board/freescale/p3060qds/eth.c new file mode 100644 index 0000000..3f812db --- /dev/null +++ b/board/freescale/p3060qds/eth.c @@ -0,0 +1,482 @@ +/* + * Copyright 2011 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <netdev.h> +#include <asm/mmu.h> +#include <asm/processor.h> +#include <asm/cache.h> +#include <asm/immap_85xx.h> +#include <asm/fsl_law.h> +#include <asm/fsl_ddr_sdram.h> +#include <asm/fsl_serdes.h> +#include <asm/fsl_portals.h> +#include <asm/fsl_liodn.h> +#include <malloc.h> +#include <fm_eth.h> +#include <fsl_mdio.h> +#include <miiphy.h> +#include <phy.h> +#include <asm/fsl_dtsec.h> + +#include "../common/qixis.h" +#include "../common/fman.h" + +#include "p3060qds_qixis.h" + +#define EMI_NONE 0xffffffff +#define EMI1_RGMII1 0 +#define EMI1_SLOT1 1 +#define EMI1_SLOT2 2 +#define EMI1_SLOT3 3 +#define EMI1_RGMII2 4 + +static int mdio_mux[NUM_FM_PORTS]; + +static char *mdio_names[5] = { + "P3060QDS_MDIO0", + "P3060QDS_MDIO1", + "P3060QDS_MDIO2", + "P3060QDS_MDIO3", + "P3060QDS_MDIO4", +}; + +/* + * Mapping of all 18 SERDES lanes to board slots. + * A value of '0' here means that the mapping must be determined + * dynamically, Lane 8/9/16/17 map to Slot1 or Aurora debug + */ +static u8 lane_to_slot[] = { + 4, 4, 4, 4, 3, 3, 3, 3, 0, 0, 2, 2, 2, 2, 1, 1, 0, 0 +}; + +static char *p3060qds_mdio_name_for_muxval(u32 muxval) +{ + return mdio_names[muxval]; +} + +struct mii_dev *mii_dev_for_muxval(u32 muxval) +{ + struct mii_dev *bus; + char *name = p3060qds_mdio_name_for_muxval(muxval); + + if (!name) { + printf("No bus for muxval %x\n", muxval); + return NULL; + } + + bus = miiphy_get_dev_by_name(name); + + if (!bus) { + printf("No bus by name %s\n", name); + return NULL; + } + + return bus; +} + +struct p3060qds_mdio { + u32 muxval; + struct mii_dev *realbus; +}; + +static void p3060qds_mux_mdio(u32 muxval) +{ + u8 brdcfg4; + + brdcfg4 = QIXIS_READ(brdcfg[4]); + brdcfg4 &= ~BRDCFG4_EMISEL_MASK; + brdcfg4 |= (muxval << 4); + QIXIS_WRITE(brdcfg[4], brdcfg4); +} + +static int p3060qds_mdio_read(struct mii_dev *bus, int addr, int devad, + int regnum) +{ + struct p3060qds_mdio *priv = bus->priv; + + p3060qds_mux_mdio(priv->muxval); + + return priv->realbus->read(priv->realbus, addr, devad, regnum); +} + +static int p3060qds_mdio_write(struct mii_dev *bus, int addr, int devad, + int regnum, u16 value) +{ + struct p3060qds_mdio *priv = bus->priv; + + p3060qds_mux_mdio(priv->muxval); + + return priv->realbus->write(priv->realbus, addr, devad, regnum, value); +} + +static int p3060qds_mdio_reset(struct mii_dev *bus) +{ + struct p3060qds_mdio *priv = bus->priv; + + return priv->realbus->reset(priv->realbus); +} + +static int p3060qds_mdio_init(char *realbusname, u32 muxval) +{ + struct p3060qds_mdio *pmdio; + struct mii_dev *bus = mdio_alloc(); + + if (!bus) { + printf("Failed to allocate P3060QDS MDIO bus\n"); + return -1; + } + + pmdio = malloc(sizeof(*pmdio)); + if (!pmdio) { + printf("Failed to allocate P3060QDS private data\n"); + free(bus); + return -1; + } + + bus->read = p3060qds_mdio_read; + bus->write = p3060qds_mdio_write; + bus->reset = p3060qds_mdio_reset; + sprintf(bus->name, p3060qds_mdio_name_for_muxval(muxval)); + + pmdio->realbus = miiphy_get_dev_by_name(realbusname); + + if (!pmdio->realbus) { + printf("No bus with name %s\n", realbusname); + free(bus); + free(pmdio); + return -1; + } + + pmdio->muxval = muxval; + bus->priv = pmdio; + + return mdio_register(bus); +} + +void board_ft_fman_fixup_port(void *blob, char * prop, phys_addr_t pa, + enum fm_port port, int offset) +{ + ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + int srds_prtcl = (in_be32(&gur->rcwsr[4]) & + FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26; + + if (mdio_mux[port] == EMI1_RGMII1) + fdt_set_phy_handle(blob, prop, pa, "phy_rgmii1"); + + if (mdio_mux[port] == EMI1_RGMII2) + fdt_set_phy_handle(blob, prop, pa, "phy_rgmii2"); + + if ((mdio_mux[port] == EMI1_SLOT1) && ((srds_prtcl == 0x3) + || (srds_prtcl == 0x6))) { + switch (port) { + case FM2_DTSEC4: + fdt_set_phy_handle(blob, prop, pa, "phy2_slot1"); + break; + case FM1_DTSEC4: + fdt_set_phy_handle(blob, prop, pa, "phy3_slot1"); + break; + default: + break; + } + } + + if (mdio_mux[port] == EMI1_SLOT3) { + switch (port) { + case FM2_DTSEC3: + fdt_set_phy_handle(blob, prop, pa, "phy0_slot3"); + break; + case FM1_DTSEC3: + fdt_set_phy_handle(blob, prop, pa, "phy1_slot3"); + break; + default: + break; + } + } +} + +void fdt_fixup_board_enet(void *fdt) +{ + int i, lane, idx; + + for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { + idx = i - FM1_DTSEC1; + switch (fm_info_get_enet_if(i)) { + case PHY_INTERFACE_MODE_SGMII: + lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + idx); + if (lane < 0) + break; + + switch (mdio_mux[i]) { + case EMI1_SLOT1: + if (lane >= 14) { + fdt_status_okay_by_alias(fdt, + "emi1_slot1"); + fdt_status_disabled_by_alias(fdt, + "emi1_slot1_bk1"); + } else { + fdt_status_disabled_by_alias(fdt, + "emi1_slot1"); + fdt_status_okay_by_alias(fdt, + "emi1_slot1_bk1"); + } + break; + case EMI1_SLOT2: + fdt_status_okay_by_alias(fdt, "emi1_slot2"); + break; + case EMI1_SLOT3: + fdt_status_okay_by_alias(fdt, "emi1_slot3"); + break; + } + break; + case PHY_INTERFACE_MODE_RGMII: + if (i == FM1_DTSEC1) + fdt_status_okay_by_alias(fdt, "emi1_rgmii1"); + + if (i == FM1_DTSEC2) + fdt_status_okay_by_alias(fdt, "emi1_rgmii2"); + break; + default: + break; + } + } +#if (CONFIG_SYS_NUM_FMAN == 2) + for (i = FM2_DTSEC1; i < FM2_DTSEC1 + CONFIG_SYS_NUM_FM2_DTSEC; i++) { + idx = i - FM2_DTSEC1; + switch (fm_info_get_enet_if(i)) { + case PHY_INTERFACE_MODE_SGMII: + lane = serdes_get_first_lane(SGMII_FM2_DTSEC1 + idx); + if (lane >= 0) { + switch (mdio_mux[i]) { + case EMI1_SLOT1: + if (lane >= 14) + fdt_status_okay_by_alias(fdt, + "emi1_slot1"); + else + fdt_status_okay_by_alias(fdt, + "emi1_slot1_bk1"); + break; + case EMI1_SLOT2: + fdt_status_okay_by_alias(fdt, + "emi1_slot2"); + break; + case EMI1_SLOT3: + fdt_status_okay_by_alias(fdt, + "emi1_slot3"); + break; + } + } + break; + default: + break; + } + } +#endif +} + +static void initialize_lane_to_slot(void) +{ + ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + int sdprtl = (in_be32(&gur->rcwsr[4]) & + FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26; + + switch (sdprtl) { + case 0x03: + case 0x06: + lane_to_slot[8] = 1; + lane_to_slot[9] = lane_to_slot[8]; + lane_to_slot[16] = 5; + lane_to_slot[17] = lane_to_slot[16]; + break; + case 0x16: + case 0x19: + case 0x1C: + lane_to_slot[8] = 5; + lane_to_slot[9] = lane_to_slot[8]; + lane_to_slot[16] = 1; + lane_to_slot[17] = lane_to_slot[16]; + break; + default: + puts("Invalid SerDes protocol for P3060QDS\n"); + break; + } +} + +int board_eth_init(bd_t *bis) +{ +#ifdef CONFIG_FMAN_ENET + struct dtsec *tsec = (void *)CONFIG_SYS_FSL_FM1_DTSEC1_ADDR; + int i; + struct fsl_pq_mdio_info dtsec_mdio_info; + ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + int srds_cfg = (in_be32(&gur->rcwsr[4]) & + FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26; + + initialize_lane_to_slot(); + + /* + * Set TBIPA on FM1@DTSEC1. This is needed for configurations + * where FM1@DTSEC1 isn't used directly, since it provides + * MDIO for other ports. + */ + out_be32(&tsec->tbipa, CONFIG_SYS_TBIPA_VALUE); + + /* Initialize the mdio_mux array so we can recognize empty elements */ + for (i = 0; i < NUM_FM_PORTS; i++) + mdio_mux[i] = EMI_NONE; + + dtsec_mdio_info.regs = + (struct tsec_mii_mng *)CONFIG_SYS_FM1_DTSEC1_MDIO_ADDR; + dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME; + + /* Register the 1G MDIO bus */ + fsl_pq_mdio_init(bis, &dtsec_mdio_info); + + /* Register the 5 muxing front-ends to the MDIO buses */ + if (fm_info_get_enet_if(FM1_DTSEC1) == PHY_INTERFACE_MODE_RGMII) + p3060qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII1); + + if (fm_info_get_enet_if(FM1_DTSEC2) == PHY_INTERFACE_MODE_RGMII) + p3060qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII2); + p3060qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT1); + p3060qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT2); + p3060qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT3); + + if (fm_info_get_enet_if(FM1_DTSEC1) == PHY_INTERFACE_MODE_RGMII) + fm_info_set_phy_address(FM1_DTSEC1, 1); /* RGMII1 */ + else if (fm_info_get_enet_if(FM1_DTSEC1) == PHY_INTERFACE_MODE_SGMII) + fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT2_PHY_ADDR); + + if (fm_info_get_enet_if(FM1_DTSEC2) == PHY_INTERFACE_MODE_RGMII) + fm_info_set_phy_address(FM1_DTSEC2, 2); /* RGMII2 */ + else if (fm_info_get_enet_if(FM1_DTSEC2) == PHY_INTERFACE_MODE_SGMII) + fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR); + + fm_info_set_phy_address(FM2_DTSEC1, SGMII_CARD_PORT1_PHY_ADDR); + fm_info_set_phy_address(FM2_DTSEC2, SGMII_CARD_PORT3_PHY_ADDR); + + switch (srds_cfg) { + case 0x03: + case 0x06: + fm_info_set_phy_address(FM2_DTSEC3, SGMII_CARD_PORT3_PHY_ADDR); + fm_info_set_phy_address(FM1_DTSEC3, SGMII_CARD_PORT4_PHY_ADDR); + fm_info_set_phy_address(FM2_DTSEC4, SGMII_CARD_PORT1_PHY_ADDR); + fm_info_set_phy_address(FM1_DTSEC4, SGMII_CARD_PORT2_PHY_ADDR); + break; + case 0x16: + case 0x19: + case 0x1C: + fm_info_set_phy_address(FM2_DTSEC3, SGMII_CARD_PORT1_PHY_ADDR); + fm_info_set_phy_address(FM1_DTSEC3, SGMII_CARD_PORT2_PHY_ADDR); + fm_info_set_phy_address(FM2_DTSEC4, SGMII_CARD_PORT3_PHY_ADDR); + fm_info_set_phy_address(FM1_DTSEC4, SGMII_CARD_PORT4_PHY_ADDR); + break; + default: + puts("Invalid SerDes protocol for P3060QDS\n"); + break; + } + + for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { + int idx = i - FM1_DTSEC1, lane, slot; + switch (fm_info_get_enet_if(i)) { + case PHY_INTERFACE_MODE_SGMII: + lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + idx); + if (lane < 0) + break; + slot = lane_to_slot[lane]; + if (QIXIS_READ(present) & (1 << (slot - 1))) + fm_disable_port(i); + switch (slot) { + case 1: + mdio_mux[i] = EMI1_SLOT1; + fm_info_set_mdio(i, + mii_dev_for_muxval(mdio_mux[i])); + break; + case 2: + mdio_mux[i] = EMI1_SLOT2; + fm_info_set_mdio(i, + mii_dev_for_muxval(mdio_mux[i])); + break; + case 3: + mdio_mux[i] = EMI1_SLOT3; + fm_info_set_mdio(i, + mii_dev_for_muxval(mdio_mux[i])); + break; + }; + break; + case PHY_INTERFACE_MODE_RGMII: + if (i == FM1_DTSEC1) { + mdio_mux[i] = EMI1_RGMII1; + fm_info_set_mdio(i, + mii_dev_for_muxval(mdio_mux[i])); + } else if (i == FM1_DTSEC2) { + mdio_mux[i] = EMI1_RGMII2; + fm_info_set_mdio(i, + mii_dev_for_muxval(mdio_mux[i])); + } + break; + default: + break; + } + } + +#if (CONFIG_SYS_NUM_FMAN == 2) + for (i = FM2_DTSEC1; i < FM2_DTSEC1 + CONFIG_SYS_NUM_FM2_DTSEC; i++) { + int idx = i - FM2_DTSEC1, lane, slot; + switch (fm_info_get_enet_if(i)) { + case PHY_INTERFACE_MODE_SGMII: + lane = serdes_get_first_lane(SGMII_FM2_DTSEC1 + idx); + if (lane < 0) + break; + slot = lane_to_slot[lane]; + if (QIXIS_READ(present) & (1 << (slot - 1))) + fm_disable_port(i); + switch (slot) { + case 1: + mdio_mux[i] = EMI1_SLOT1; + fm_info_set_mdio(i, + mii_dev_for_muxval(mdio_mux[i])); + break; + case 2: + mdio_mux[i] = EMI1_SLOT2; + fm_info_set_mdio(i, + mii_dev_for_muxval(mdio_mux[i])); + break; + case 3: + mdio_mux[i] = EMI1_SLOT3; + fm_info_set_mdio(i, + mii_dev_for_muxval(mdio_mux[i])); + break; + }; + break; + default: + break; + } + } +#endif /* CONFIG_SYS_NUM_FMAN */ + + cpu_eth_init(bis); +#endif /* CONFIG_FMAN_ENET */ + + return pci_eth_init(bis); +} diff --git a/board/freescale/p3060qds/fixed_ddr.c b/board/freescale/p3060qds/fixed_ddr.c new file mode 100644 index 0000000..125988d --- /dev/null +++ b/board/freescale/p3060qds/fixed_ddr.c @@ -0,0 +1,214 @@ +/* + * Copyright 2009-2011 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * Version 2 as published by the Free Software Foundation. + */ + +#include <common.h> +#include <asm/fsl_ddr_sdram.h> + +#define CONFIG_SYS_DDR_TIMING_3_1200 0x01030000 +#define CONFIG_SYS_DDR_TIMING_0_1200 0xCC550104 +#define CONFIG_SYS_DDR_TIMING_1_1200 0x868FAA45 +#define CONFIG_SYS_DDR_TIMING_2_1200 0x0FB8A912 +#define CONFIG_SYS_DDR_MODE_1_1200 0x00441A40 +#define CONFIG_SYS_DDR_MODE_2_1200 0x00100000 +#define CONFIG_SYS_DDR_INTERVAL_1200 0x12480100 +#define CONFIG_SYS_DDR_CLK_CTRL_1200 0x02800000 + +#define CONFIG_SYS_DDR_TIMING_3_1000 0x00020000 +#define CONFIG_SYS_DDR_TIMING_0_1000 0xCC440104 +#define CONFIG_SYS_DDR_TIMING_1_1000 0x727DF944 +#define CONFIG_SYS_DDR_TIMING_2_1000 0x0FB088CF +#define CONFIG_SYS_DDR_MODE_1_1000 0x00441830 +#define CONFIG_SYS_DDR_MODE_2_1000 0x00080000 +#define CONFIG_SYS_DDR_INTERVAL_1000 0x0F3C0100 +#define CONFIG_SYS_DDR_CLK_CTRL_1000 0x02800000 + +#define CONFIG_SYS_DDR_TIMING_3_900 0x00020000 +#define CONFIG_SYS_DDR_TIMING_0_900 0xCC440104 +#define CONFIG_SYS_DDR_TIMING_1_900 0x616ba844 +#define CONFIG_SYS_DDR_TIMING_2_900 0x0fb088ce +#define CONFIG_SYS_DDR_MODE_1_900 0x00441620 +#define CONFIG_SYS_DDR_MODE_2_900 0x00080000 +#define CONFIG_SYS_DDR_INTERVAL_900 0x0db60100 +#define CONFIG_SYS_DDR_CLK_CTRL_900 0x02800000 + +#define CONFIG_SYS_DDR_TIMING_3_800 0x00020000 +#define CONFIG_SYS_DDR_TIMING_0_800 0xcc330104 +#define CONFIG_SYS_DDR_TIMING_1_800 0x6f6b4744 +#define CONFIG_SYS_DDR_TIMING_2_800 0x0fa888cc +#define CONFIG_SYS_DDR_MODE_1_800 0x00441420 +#define CONFIG_SYS_DDR_MODE_2_800 0x00000000 +#define CONFIG_SYS_DDR_INTERVAL_800 0x0c300100 +#define CONFIG_SYS_DDR_CLK_CTRL_800 0x02800000 + +#define CONFIG_SYS_DDR_CS0_BNDS 0x000000FF +#define CONFIG_SYS_DDR_CS1_BNDS 0x00000000 +#define CONFIG_SYS_DDR_CS2_BNDS 0x000000FF +#define CONFIG_SYS_DDR_CS3_BNDS 0x000000FF +#define CONFIG_SYS_DDR2_CS0_BNDS 0x000000FF +#define CONFIG_SYS_DDR2_CS1_BNDS 0x00000000 +#define CONFIG_SYS_DDR2_CS2_BNDS 0x000000FF +#define CONFIG_SYS_DDR2_CS3_BNDS 0x000000FF +#define CONFIG_SYS_DDR_CS0_CONFIG 0xA0044202 +#define CONFIG_SYS_DDR_CS0_CONFIG_2 0x00000000 +#define CONFIG_SYS_DDR_CS1_CONFIG 0x80004202 +#define CONFIG_SYS_DDR_CS2_CONFIG 0x00000000 +#define CONFIG_SYS_DDR_CS3_CONFIG 0x00000000 +#define CONFIG_SYS_DDR2_CS0_CONFIG 0x80044202 +#define CONFIG_SYS_DDR2_CS1_CONFIG 0x80004202 +#define CONFIG_SYS_DDR2_CS2_CONFIG 0x00000000 +#define CONFIG_SYS_DDR2_CS3_CONFIG 0x00000000 +#define CONFIG_SYS_DDR_INIT_ADDR 0x00000000 +#define CONFIG_SYS_DDR_INIT_EXT_ADDR 0x00000000 +#define CONFIG_SYS_DDR_CS1_CONFIG 0x80004202 +#define CONFIG_SYS_DDR_DATA_INIT 0xdeadbeef +#define CONFIG_SYS_DDR_TIMING_4 0x00000001 +#define CONFIG_SYS_DDR_TIMING_5 0x02401400 +#define CONFIG_SYS_DDR_MODE_CONTROL 0x00000000 +#define CONFIG_SYS_DDR_ZQ_CNTL 0x89080600 +#define CONFIG_SYS_DDR_WRLVL_CNTL 0x8675F607 +#define CONFIG_SYS_DDR_SDRAM_CFG 0xE7044000 +#define CONFIG_SYS_DDR_SDRAM_CFG2 0x24401031 +#define CONFIG_SYS_DDR_RCW_1 0x00000000 +#define CONFIG_SYS_DDR_RCW_2 0x00000000 +#define CONFIG_MEM_INIT_VALUE 0xdeadbeef + +fsl_ddr_cfg_regs_t ddr_cfg_regs_800 = { + .cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS, + .cs[1].bnds = CONFIG_SYS_DDR_CS1_BNDS, + .cs[2].bnds = CONFIG_SYS_DDR_CS2_BNDS, + .cs[3].bnds = CONFIG_SYS_DDR_CS3_BNDS, + .cs[0].config = CONFIG_SYS_DDR_CS0_CONFIG, + .cs[0].config_2 = CONFIG_SYS_DDR_CS0_CONFIG_2, + .cs[1].config = CONFIG_SYS_DDR_CS1_CONFIG, + .cs[2].config = CONFIG_SYS_DDR_CS2_CONFIG, + .cs[3].config = CONFIG_SYS_DDR_CS3_CONFIG, + .timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3_800, + .timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0_800, + .timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1_800, + .timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2_800, + .ddr_sdram_cfg = CONFIG_SYS_DDR_SDRAM_CFG, + .ddr_sdram_cfg_2 = CONFIG_SYS_DDR_SDRAM_CFG2, + .ddr_sdram_mode = CONFIG_SYS_DDR_MODE_1_800, + .ddr_sdram_mode_2 = CONFIG_SYS_DDR_MODE_2_800, + .ddr_sdram_md_cntl = CONFIG_SYS_DDR_MODE_CONTROL, + .ddr_sdram_interval = CONFIG_SYS_DDR_INTERVAL_800, + .ddr_data_init = CONFIG_MEM_INIT_VALUE, + .ddr_sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CTRL_800, + .ddr_init_addr = CONFIG_SYS_DDR_INIT_ADDR, + .ddr_init_ext_addr = CONFIG_SYS_DDR_INIT_EXT_ADDR, + .timing_cfg_4 = CONFIG_SYS_DDR_TIMING_4, + .timing_cfg_5 = CONFIG_SYS_DDR_TIMING_5, + .ddr_zq_cntl = CONFIG_SYS_DDR_ZQ_CNTL, + .ddr_wrlvl_cntl = CONFIG_SYS_DDR_WRLVL_CNTL, + .ddr_sdram_rcw_1 = CONFIG_SYS_DDR_RCW_1, + .ddr_sdram_rcw_2 = CONFIG_SYS_DDR_RCW_2 +}; + +fsl_ddr_cfg_regs_t ddr_cfg_regs_900 = { + .cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS, + .cs[1].bnds = CONFIG_SYS_DDR_CS1_BNDS, + .cs[2].bnds = CONFIG_SYS_DDR_CS2_BNDS, + .cs[3].bnds = CONFIG_SYS_DDR_CS3_BNDS, + .cs[0].config = CONFIG_SYS_DDR_CS0_CONFIG, + .cs[0].config_2 = CONFIG_SYS_DDR_CS0_CONFIG_2, + .cs[1].config = CONFIG_SYS_DDR_CS1_CONFIG, + .cs[2].config = CONFIG_SYS_DDR_CS2_CONFIG, + .cs[3].config = CONFIG_SYS_DDR_CS3_CONFIG, + .timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3_900, + .timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0_900, + .timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1_900, + .timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2_900, + .ddr_sdram_cfg = CONFIG_SYS_DDR_SDRAM_CFG, + .ddr_sdram_cfg_2 = CONFIG_SYS_DDR_SDRAM_CFG2, + .ddr_sdram_mode = CONFIG_SYS_DDR_MODE_1_900, + .ddr_sdram_mode_2 = CONFIG_SYS_DDR_MODE_2_900, + .ddr_sdram_md_cntl = CONFIG_SYS_DDR_MODE_CONTROL, + .ddr_sdram_interval = CONFIG_SYS_DDR_INTERVAL_900, + .ddr_data_init = CONFIG_MEM_INIT_VALUE, + .ddr_sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CTRL_900, + .ddr_init_addr = CONFIG_SYS_DDR_INIT_ADDR, + .ddr_init_ext_addr = CONFIG_SYS_DDR_INIT_EXT_ADDR, + .timing_cfg_4 = CONFIG_SYS_DDR_TIMING_4, + .timing_cfg_5 = CONFIG_SYS_DDR_TIMING_5, + .ddr_zq_cntl = CONFIG_SYS_DDR_ZQ_CNTL, + .ddr_wrlvl_cntl = CONFIG_SYS_DDR_WRLVL_CNTL, + .ddr_sdram_rcw_1 = CONFIG_SYS_DDR_RCW_1, + .ddr_sdram_rcw_2 = CONFIG_SYS_DDR_RCW_2 +}; + +fsl_ddr_cfg_regs_t ddr_cfg_regs_1000 = { + .cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS, + .cs[1].bnds = CONFIG_SYS_DDR_CS1_BNDS, + .cs[2].bnds = CONFIG_SYS_DDR_CS2_BNDS, + .cs[3].bnds = CONFIG_SYS_DDR_CS3_BNDS, + .cs[0].config = CONFIG_SYS_DDR_CS0_CONFIG, + .cs[0].config_2 = CONFIG_SYS_DDR_CS0_CONFIG_2, + .cs[1].config = CONFIG_SYS_DDR_CS1_CONFIG, + .cs[2].config = CONFIG_SYS_DDR_CS2_CONFIG, + .cs[3].config = CONFIG_SYS_DDR_CS3_CONFIG, + .timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3_1000, + .timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0_1000, + .timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1_1000, + .timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2_1000, + .ddr_sdram_cfg = CONFIG_SYS_DDR_SDRAM_CFG, + .ddr_sdram_cfg_2 = CONFIG_SYS_DDR_SDRAM_CFG2, + .ddr_sdram_mode = CONFIG_SYS_DDR_MODE_1_1000, + .ddr_sdram_mode_2 = CONFIG_SYS_DDR_MODE_2_1000, + .ddr_sdram_md_cntl = CONFIG_SYS_DDR_MODE_CONTROL, + .ddr_sdram_interval = CONFIG_SYS_DDR_INTERVAL_1000, + .ddr_data_init = CONFIG_MEM_INIT_VALUE, + .ddr_sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CTRL_1000, + .ddr_init_addr = CONFIG_SYS_DDR_INIT_ADDR, + .ddr_init_ext_addr = CONFIG_SYS_DDR_INIT_EXT_ADDR, + .timing_cfg_4 = CONFIG_SYS_DDR_TIMING_4, + .timing_cfg_5 = CONFIG_SYS_DDR_TIMING_5, + .ddr_zq_cntl = CONFIG_SYS_DDR_ZQ_CNTL, + .ddr_wrlvl_cntl = CONFIG_SYS_DDR_WRLVL_CNTL, + .ddr_sdram_rcw_1 = CONFIG_SYS_DDR_RCW_1, + .ddr_sdram_rcw_2 = CONFIG_SYS_DDR_RCW_2 +}; + +fsl_ddr_cfg_regs_t ddr_cfg_regs_1200 = { + .cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS, + .cs[1].bnds = CONFIG_SYS_DDR_CS1_BNDS, + .cs[2].bnds = CONFIG_SYS_DDR_CS2_BNDS, + .cs[3].bnds = CONFIG_SYS_DDR_CS3_BNDS, + .cs[0].config = CONFIG_SYS_DDR_CS0_CONFIG, + .cs[0].config_2 = CONFIG_SYS_DDR_CS0_CONFIG_2, + .cs[1].config = CONFIG_SYS_DDR_CS1_CONFIG, + .cs[2].config = CONFIG_SYS_DDR_CS2_CONFIG, + .cs[3].config = CONFIG_SYS_DDR_CS3_CONFIG, + .timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3_1200, + .timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0_1200, + .timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1_1200, + .timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2_1200, + .ddr_sdram_cfg = CONFIG_SYS_DDR_SDRAM_CFG, + .ddr_sdram_cfg_2 = CONFIG_SYS_DDR_SDRAM_CFG2, + .ddr_sdram_mode = CONFIG_SYS_DDR_MODE_1_1200, + .ddr_sdram_mode_2 = CONFIG_SYS_DDR_MODE_2_1200, + .ddr_sdram_md_cntl = CONFIG_SYS_DDR_MODE_CONTROL, + .ddr_sdram_interval = CONFIG_SYS_DDR_INTERVAL_1200, + .ddr_data_init = CONFIG_MEM_INIT_VALUE, + .ddr_sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CTRL_1200, + .ddr_init_addr = CONFIG_SYS_DDR_INIT_ADDR, + .ddr_init_ext_addr = CONFIG_SYS_DDR_INIT_EXT_ADDR, + .timing_cfg_4 = CONFIG_SYS_DDR_TIMING_4, + .timing_cfg_5 = CONFIG_SYS_DDR_TIMING_5, + .ddr_zq_cntl = CONFIG_SYS_DDR_ZQ_CNTL, + .ddr_wrlvl_cntl = CONFIG_SYS_DDR_WRLVL_CNTL, + .ddr_sdram_rcw_1 = CONFIG_SYS_DDR_RCW_1, + .ddr_sdram_rcw_2 = CONFIG_SYS_DDR_RCW_2 +}; + +fixed_ddr_parm_t fixed_ddr_parm_0[] = { + {750, 850, &ddr_cfg_regs_800}, + {850, 950, &ddr_cfg_regs_900}, + {950, 1050, &ddr_cfg_regs_1000}, + {1050, 1250, &ddr_cfg_regs_1200}, + {0, 0, NULL} +}; diff --git a/board/freescale/p3060qds/p3060qds.c b/board/freescale/p3060qds/p3060qds.c new file mode 100644 index 0000000..c6c74f2 --- /dev/null +++ b/board/freescale/p3060qds/p3060qds.c @@ -0,0 +1,341 @@ +/* + * Copyright 2011 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <netdev.h> +#include <linux/compiler.h> +#include <asm/mmu.h> +#include <asm/processor.h> +#include <asm/cache.h> +#include <asm/immap_85xx.h> +#include <asm/fsl_law.h> +#include <asm/fsl_serdes.h> +#include <asm/fsl_portals.h> +#include <asm/fsl_liodn.h> +#include <fm_eth.h> +#include <configs/P3060QDS.h> +#include <libfdt.h> +#include <fdt_support.h> + +#include "../common/qixis.h" +#include "p3060qds.h" +#include "p3060qds_qixis.h" + +DECLARE_GLOBAL_DATA_PTR; + +int checkboard(void) +{ + u8 sw; + struct cpu_type *cpu = gd->cpu; + ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; + unsigned int i; + + printf("Board: %s", cpu->name); + puts("QDS, "); + + printf("Sys ID: 0x%02x, Sys Ver: 0x%02x, FPGA Ver: 0x%02x, ", + QIXIS_READ(id), QIXIS_READ(arch), QIXIS_READ(scver)); + + sw = QIXIS_READ(brdcfg[0]); + sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT; + + if (sw < 0x8) + printf("vBank: %d\n", sw); + else if (sw == 0x8) + puts("Promjet\n"); + else if (sw == 0x9) + puts("NAND\n"); + else + printf("invalid setting of SW%u\n", PIXIS_LBMAP_SWITCH); + +#ifdef CONFIG_PHYS_64BIT + puts("36-bit Addressing\n"); +#endif + puts("Reset Configuration Word (RCW):"); + for (i = 0; i < ARRAY_SIZE(gur->rcwsr); i++) { + u32 rcw = in_be32(&gur->rcwsr[i]); + + if ((i % 4) == 0) + printf("\n %08x:", i * 4); + printf(" %08x", rcw); + } + puts("\n"); + + puts("SERDES Reference Clocks: "); + sw = QIXIS_READ(brdcfg[2]); + for (i = 0; i < 3; i++) { + static const char * const freq[] = {"100", "125", "Reserved", + "156.25"}; + unsigned int clock = (sw >> (2 * i)) & 3; + + printf("Bank%u=%sMhz ", i+1, freq[clock]); + } + puts("\n"); + + return 0; +} + +int board_early_init_f(void) +{ + ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + + /* only single DDR controller on QDS board, disable DDR1_MCK4/5 */ + setbits_be32(&gur->ddrclkdr, 0x00030000); + + return 0; +} + +void board_config_serdes_mux(void) +{ + ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + int cfg = (in_be32(&gur->rcwsr[4]) & + FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26; + + switch (cfg) { + case 0x03: + case 0x06: + /* set Lane I,J as SGMII */ + QIXIS_WRITE(brdcfg[6], BRDCFG6_SD4MX_B | BRDCFG6_SD3MX_A | + BRDCFG6_SD2MX_B | BRDCFG6_SD1MX_A); + break; + case 0x16: + case 0x19: + case 0x1c: + /* set Lane I,J as Aurora Debug */ + QIXIS_WRITE(brdcfg[6], BRDCFG6_SD4MX_A | BRDCFG6_SD3MX_B | + BRDCFG6_SD2MX_A | BRDCFG6_SD1MX_B); + break; + default: + puts("Invalid SerDes protocol for P3060QDS\n"); + break; + } +} + +void board_config_usb_mux(void) +{ + u8 brdcfg4, brdcfg5, brdcfg7; + ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + u32 rcwsr11 = in_be32(&gur->rcwsr[11]); + u32 ec1 = rcwsr11 & FSL_CORENET_RCWSR11_EC1; + u32 ec2 = rcwsr11 & FSL_CORENET_RCWSR11_EC2; + + brdcfg4 = QIXIS_READ(brdcfg[4]); + brdcfg4 &= ~BRDCFG4_EC_MODE_MASK; + if ((ec1 == FSL_CORENET_RCWSR11_EC1_FM1_USB1) && + (ec2 == FSL_CORENET_RCWSR11_EC2_USB2)) { + brdcfg4 |= BRDCFG4_EC2_USB_EC1_USB; + + } else if ((ec1 == FSL_CORENET_RCWSR11_EC1_FM1_USB1) && + ((ec2 == FSL_CORENET_RCWSR11_EC2_FM1_DTSEC2) || + (ec2 == FSL_CORENET_RCWSR11_EC2_FM2_DTSEC1))) { + brdcfg4 |= BRDCFG4_EC2_RGMII_EC1_USB; + + } else if ((ec1 == FSL_CORENET_RCWSR11_EC1_FM1_DTSEC1) && + (ec2 == FSL_CORENET_RCWSR11_EC2_USB2)) { + brdcfg4 |= BRDCFG4_EC2_USB_EC1_RGMII; + + } else if ((ec1 == FSL_CORENET_RCWSR11_EC1_FM1_DTSEC1) && + ((ec2 == FSL_CORENET_RCWSR11_EC2_FM1_DTSEC2) || + (ec2 == FSL_CORENET_RCWSR11_EC2_FM2_DTSEC1))) { + brdcfg4 |= BRDCFG4_EC2_RGMII_EC1_RGMII; + } else { + brdcfg4 |= BRDCFG4_EC2_MII_EC1_MII; + } + QIXIS_WRITE(brdcfg[4], brdcfg4); + + brdcfg5 = QIXIS_READ(brdcfg[5]); + brdcfg5 &= ~(BRDCFG5_USB1ID_MASK | BRDCFG5_USB2ID_MASK); + brdcfg5 |= (BRDCFG5_USB1ID_CTRL | BRDCFG5_USB2ID_CTRL); + QIXIS_WRITE(brdcfg[5], brdcfg5); + + brdcfg7 = BRDCFG7_JTAGMX_COP_JTAG | BRDCFG7_IQ1MX_IRQ_EVT | + BRDCFG7_G1MX_USB1 | BRDCFG7_D1MX_TSEC3USB | BRDCFG7_I3MX_USB1; + QIXIS_WRITE(brdcfg[7], brdcfg7); +} + +int board_early_init_r(void) +{ + const unsigned int flashbase = CONFIG_SYS_FLASH_BASE; + const u8 flash_esel = find_tlb_idx((void *)flashbase, 1); + + /* + * Remap Boot flash + PROMJET region to caching-inhibited + * so that flash can be erased properly. + */ + + /* Flush d-cache and invalidate i-cache of any FLASH data */ + flush_dcache(); + invalidate_icache(); + + /* invalidate existing TLB entry for flash + promjet */ + disable_tlb(flash_esel); + + set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, flash_esel, BOOKE_PAGESZ_256M, 1); + + set_liodns(); +#ifdef CONFIG_SYS_DPAA_QBMAN + setup_portals(); +#endif + board_config_serdes_mux(); + board_config_usb_mux(); + + return 0; +} + +static const char *serdes_clock_to_string(u32 clock) +{ + switch (clock) { + case SRDS_PLLCR0_RFCK_SEL_100: + return "100"; + case SRDS_PLLCR0_RFCK_SEL_125: + return "125"; + case SRDS_PLLCR0_RFCK_SEL_156_25: + return "156.25"; + default: + return "150"; + } +} + +#define NUM_SRDS_BANKS 3 + +int misc_init_r(void) +{ + serdes_corenet_t *srds_regs; + u32 actual[NUM_SRDS_BANKS]; + unsigned int i; + u8 sw; + + sw = QIXIS_READ(brdcfg[2]); + for (i = 0; i < 3; i++) { + unsigned int clock = (sw >> (2 * i)) & 3; + switch (clock) { + case 0: + actual[i] = SRDS_PLLCR0_RFCK_SEL_100; + break; + case 1: + actual[i] = SRDS_PLLCR0_RFCK_SEL_125; + break; + case 3: + actual[i] = SRDS_PLLCR0_RFCK_SEL_156_25; + break; + default: + printf("Warning: SDREFCLK%u switch setting of '10' is " + "unsupported\n", i + 1); + break; + } + } + + srds_regs = (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR; + for (i = 0; i < NUM_SRDS_BANKS; i++) { + u32 pllcr0 = in_be32(&srds_regs->bank[i].pllcr0); + u32 expected = pllcr0 & SRDS_PLLCR0_RFCK_SEL_MASK; + if (expected != actual[i]) { + printf("Warning: SERDES bank %u expects reference clock" + " %sMHz, but actual is %sMHz\n", i + 1, + serdes_clock_to_string(expected), + serdes_clock_to_string(actual[i])); + } + } + + return 0; +} + +/* + * This is map of CVDD values. 33 means CVDD is 3.3v, 25 means CVDD is 2.5v, + * 18 means CVDD is 1.8v. + */ +static u8 IO_VSEL[] = { + 33, 33, 33, 25, 25, 25, 18, 18, 18, + 33, 33, 33, 25, 25, 25, 18, 18, 18, + 33, 33, 33, 25, 25, 25, 18, 18, 18, + 33, 33, 33, 33, 33 +}; + +#define IO_VSEL_MASK 0x1f + +/* + * different CVDD selects diffenert spi flashs, read dutcfg[3] to get CVDD, + * then set status of spi flash nodes to 'disabled' according to CVDD. + * CVDD '33' will select spi flash0 and flash1, CVDD '25' will select spi + * flash2, CVDD '18' will select spi flash3. + */ +void fdt_fixup_board_spi(void *blob) +{ + u8 sw5 = QIXIS_READ(dutcfg[3]); + + switch (IO_VSEL[sw5 & IO_VSEL_MASK]) { + /* 3.3v */ + case 33: + do_fixup_by_compat(blob, "atmel,at45db081d", "status", + "disabled", strlen("disabled") + 1, 1); + do_fixup_by_compat(blob, "spansion,sst25wf040", "status", + "disabled", strlen("disabled") + 1, 1); + break; + /* 2.5v */ + case 25: + do_fixup_by_compat(blob, "spansion,s25sl12801", "status", + "disabled", strlen("disabled") + 1, 1); + do_fixup_by_compat(blob, "spansion,en25q32", "status", + "disabled", strlen("disabled") + 1, 1); + do_fixup_by_compat(blob, "spansion,sst25wf040", "status", + "disabled", strlen("disabled") + 1, 1); + break; + /* 1.8v */ + case 18: + do_fixup_by_compat(blob, "spansion,s25sl12801", "status", + "disabled", strlen("disabled") + 1, 1); + do_fixup_by_compat(blob, "spansion,en25q32", "status", + "disabled", strlen("disabled") + 1, 1); + do_fixup_by_compat(blob, "atmel,at45db081d", "status", + "disabled", strlen("disabled") + 1, 1); + break; + } +} + +void ft_board_setup(void *blob, bd_t *bd) +{ + phys_addr_t base; + phys_size_t size; + + ft_cpu_setup(blob, bd); + + base = getenv_bootm_low(); + size = getenv_bootm_size(); + + fdt_fixup_memory(blob, (u64)base, (u64)size); + +#ifdef CONFIG_PCI + pci_of_setup(blob, bd); +#endif + + fdt_fixup_liodn(blob); + fdt_fixup_dr_usb(blob, bd); + fdt_fixup_board_spi(blob); + +#ifdef CONFIG_SYS_DPAA_FMAN + fdt_fixup_fman_ethernet(blob); + fdt_fixup_board_enet(blob); +#endif +} diff --git a/board/freescale/p3060qds/p3060qds.h b/board/freescale/p3060qds/p3060qds.h new file mode 100644 index 0000000..3da6815 --- /dev/null +++ b/board/freescale/p3060qds/p3060qds.h @@ -0,0 +1,30 @@ +/* + * Copyright 2011 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __P3060QDS_H__ +#define __P3060QDS_H__ + +#include <asm/fsl_ddr_sdram.h> +#include <asm/u-boot.h> + +void fdt_fixup_board_enet(void *blob); +void pci_of_setup(void *blob, bd_t *bd); +extern fixed_ddr_parm_t fixed_ddr_parm_0[]; + +#endif diff --git a/board/freescale/p3060qds/p3060qds_qixis.h b/board/freescale/p3060qds/p3060qds_qixis.h new file mode 100644 index 0000000..4d5d6a2 --- /dev/null +++ b/board/freescale/p3060qds/p3060qds_qixis.h @@ -0,0 +1,74 @@ +/* + * Copyright 2011 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __P3060QDS_QIXIS_H__ +#define __P3060QDS_QIXIS_H__ + +/* Definitions of QIXIS Registers for P3060QDS */ + +/* BRDCFG4[4:7]] select EC1 and EC2 as a pair */ +#define BRDCFG4_EC_MODE_MASK 0x0F +#define BRDCFG4_EC2_MII_EC1_MII 0x00 +#define BRDCFG4_EC2_MII_EC1_USB 0x03 +#define BRDCFG4_EC2_USB_EC1_MII 0x0C +#define BRDCFG4_EC2_USB_EC1_USB 0x0F +#define BRDCFG4_EC2_USB_EC1_RGMII 0x0E +#define BRDCFG4_EC2_RGMII_EC1_USB 0x0B +#define BRDCFG4_EC2_RGMII_EC1_RGMII 0x0A +#define BRDCFG4_EMISEL_MASK 0xF0 + +#define BRDCFG5_ECLKS_MASK 0x80 +#define BRDCFG5_USB1ID_MASK 0x40 +#define BRDCFG5_USB2ID_MASK 0x20 +#define BRDCFG5_GC2MX_MASK 0x0C +#define BRDCFG5_T15MX_MASK 0x03 +#define BRDCFG5_ECLKS_IEEE1588_CM 0x80 +#define BRDCFG5_USB1ID_CTRL 0x40 +#define BRDCFG5_USB2ID_CTRL 0x20 + +#define BRDCFG6_SD1MX_A 0x01 +#define BRDCFG6_SD1MX_B 0x00 +#define BRDCFG6_SD2MX_A 0x02 +#define BRDCFG6_SD2MX_B 0x00 +#define BRDCFG6_SD3MX_A 0x04 +#define BRDCFG6_SD3MX_B 0x00 +#define BRDCFG6_SD4MX_A 0x08 +#define BRDCFG6_SD4MX_B 0x00 + +#define BRDCFG7_JTAGMX_MASK 0xC0 +#define BRDCFG7_IQ1MX_MASK 0x20 +#define BRDCFG7_G1MX_MASK 0x10 +#define BRDCFG7_D1MX_MASK 0x0C +#define BRDCFG7_I3MX_MASK 0x03 +#define BRDCFG7_JTAGMX_AURORA 0x00 +#define BRDCFG7_JTAGMX_FPGA 0x80 +#define BRDCFG7_JTAGMX_COP_JTAG 0xC0 +#define BRDCFG7_IQ1MX_IRQ_EVT 0x00 +#define BRDCFG7_IQ1MX_USB2 0x20 +#define BRDCFG7_G1MX_USB1 0x00 +#define BRDCFG7_G1MX_TSEC3 0x10 +#define BRDCFG7_D1MX_DMA 0x00 +#define BRDCFG7_D1MX_TSEC3USB 0x04 +#define BRDCFG7_D1MX_HDLC2 0x08 +#define BRDCFG7_I3MX_UART2_I2C34 0x00 +#define BRDCFG7_I3MX_GPIO_EVT 0x01 +#define BRDCFG7_I3MX_USB1 0x02 +#define BRDCFG7_I3MX_TSEC3 0x03 + +#endif |