diff options
author | Wolfgang Denk <wd@denx.de> | 2011-10-04 22:08:13 +0200 |
---|---|---|
committer | Wolfgang Denk <wd@denx.de> | 2011-10-04 22:08:13 +0200 |
commit | 1fed668b3fb9c35932f58af00ff5539239fa4e1d (patch) | |
tree | eaaaead8ca19924af1823caae040f504be9b6d98 /board | |
parent | c52575350fd6e794717f6bee4f81dbb8038fe22e (diff) | |
parent | 6d7b061af153bc5beb633c3bd15348284716a067 (diff) | |
download | u-boot-imx-1fed668b3fb9c35932f58af00ff5539239fa4e1d.zip u-boot-imx-1fed668b3fb9c35932f58af00ff5539239fa4e1d.tar.gz u-boot-imx-1fed668b3fb9c35932f58af00ff5539239fa4e1d.tar.bz2 |
Merge branch 'master' of git://git.denx.de/u-boot-mpc85xx
* 'master' of git://git.denx.de/u-boot-mpc85xx:
powerpc/p3060: Add SoC related support for P3060 platform
powerpc/85xx: Add support for setting up RAID engine liodns on P5020
powerpc/85xx: Refactor some defines out of corenet_ds.h
fm-eth: Add ability for board code to disable a port
powerpc/mpc8548: Add workaround for erratum NMG_LBC103
powerpc/mpc8548: Add workaround for erratum NMG_DDR120
powerpc/mpc85xxcds: Fix PCI speed
powerpc/mpc8548cds: Fix booting message
powerpc/p4080: Add support for secure boot flow
powerpc/85xx: Add Secure Boot support on P1010RDB for NOR, NAND & SPIFLASH
powerpc/85xx: Add PBL & SECUREBOOT support on P3041/P5020DS boards
powerpc/p2041rdb: remove watch dog related codes
powerpc/p2041rdb: updated description of cpld command
powerpc/p2041rdb: add more ddr frequencies support
powerpc/p2041rdb: set sysclk according to status of physical switch SW1
powerpc/p2041rdb: update cpld reset command according to CPLD 2.0
powerpc/mpc8349emds: Migrate from spd_sdram to unified DDR driver
powerpc/mpc83xx: Migrate from spd_sdram to unified DDR driver
powerpc/mpc8xxx: Add DDR2 to unified DDR driver
powerpc/mpc8xxx: Fix picos_to_mclk() and get_memory_clk_period_ps()
powerpc/mpc8xxx: Add SPD EEPROM address for single controller 2 slots
powerpc/mpc8xxx: Fix DDR code for empty first DIMM slot and enable DQS_en
powerpc/85xx: Refactor P2041RDB to use common p_corenet files
powerpc/85xx: refactor common P-Series CoreNet files for FSL boards
powerpc/85xx: Enable CMD_REGINFO on corenet boards
powerpc/85xx: p2041rdb - Remove unused 'execute' perm in TLB entries
powerpc/85xx: Fix USB protocol definitions for P1020RDB
powerpc/corenet_ds: Use separated speed tables for UDIMM and RDIMM
powerpc/mpc8xxx: Move DDR RCW overriding to common code
powerpc/mpc8xxx: Extend CWL table
powerpc/85xx: Cleanup how SVR_MAJ() is defined on MPC8536
powerpc/85xx: Cleanup extern in corenet_ds board code
powerpc/p2041rdb: Add ethernet support on P2041RDB board
powerpc/85xx: Add networking support to P1023RDS
powerpc/hydra: Add ethernet support on P5020/P3041 DS boards
powerpc/85xx: Add FMan ethernet support to P4080DS
powerpc/85xx: Add support for FMan ethernet in Independent mode
powerpc/mpc8548cds: Cleanup mpc8548cds.c
powerpc/mp: add support for discontiguous cores
powerpc/85xx: corenet_ds - Remove unused 'execute' perm in TLB entries
fdt: Add new fdt_create_phandle helper
fdt: Rename fdt_create_phandle to fdt_set_phandle
powerpc/85xx: Fix compile warnings/errors if CONFIG_SYS_DPAA_FMAN isn't set
fsl_ifc: Add the workaround for erratum IFC A-003399(enabled on P1010)
powerpc/P1010: Add workaround for erratum P1010-A003549 (related to IFC)
fsl_ifc: Add the workaround for erratum IFC-A002769 (enable on P1010)
powerpc/85xx: Expanding the window of CCSRBAR in AS=1 from 4k to 1M
powerpc/85xx: Add NAND/NAND_SPL support to P1010RDB
nand: Freescale Integrated Flash Controller NAND support
powerpc/85xx: Add basic support for P1010RDB
powerpc/85xx: Add support for new P102x/P2020 RDB style boards
powerpc/85xx: relocate CCSR before creating the initial RAM area
powerpc/85xx: introduce and document CONFIG_SYS_CCSRBAR macros
powerpc/85xx: Enable internal USB UTMI PHY on p204x/p3041/p50x0
powerpc/85xx: Add ULPI and UTMI USB Phy support for P1010/P1014
Diffstat (limited to 'board')
38 files changed, 3451 insertions, 267 deletions
diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile index c47d10d..b27f054 100644 --- a/board/freescale/common/Makefile +++ b/board/freescale/common/Makefile @@ -31,6 +31,7 @@ LIB = $(obj)libfreescale.o COBJS-$(CONFIG_FSL_CADMUS) += cadmus.o COBJS-$(CONFIG_FSL_VIA) += cds_via.o +COBJS-$(CONFIG_FMAN_ENET) += fman.o COBJS-$(CONFIG_FSL_PIXIS) += pixis.o COBJS-$(CONFIG_FSL_NGPIXIS) += ngpixis.o COBJS-$(CONFIG_PQ_MDS_PIB) += pq-mds-pib.o @@ -52,12 +53,22 @@ COBJS-$(CONFIG_P3041DS) += ics307_clk.o COBJS-$(CONFIG_P4080DS) += ics307_clk.o COBJS-$(CONFIG_P5020DS) += ics307_clk.o +# deal with common files for P-series corenet based devices +SUBLIB-$(CONFIG_P2041RDB) += p_corenet/libp_corenet.o +SUBLIB-$(CONFIG_P3041DS) += p_corenet/libp_corenet.o +SUBLIB-$(CONFIG_P4080DS) += p_corenet/libp_corenet.o +SUBLIB-$(CONFIG_P5020DS) += p_corenet/libp_corenet.o + SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(COBJS-y)) SOBJS := $(addprefix $(obj),$(SOBJS)) +SUBLIB := $(addprefix $(obj),$(SUBLIB-y)) + +$(LIB): $(obj).depend $(OBJS) $(SUBLIB) + $(call cmd_link_o_target, $(OBJS) $(SUBLIB)) -$(LIB): $(obj).depend $(OBJS) - $(call cmd_link_o_target, $(OBJS)) +$(SUBLIB): $(obj).depend + $(MAKE) -C $(dir $(subst $(obj),,$@)) clean: rm -f $(SOBJS) $(OBJS) diff --git a/board/freescale/common/cadmus.c b/board/freescale/common/cadmus.c index db54bc4..50b6e9f 100644 --- a/board/freescale/common/cadmus.c +++ b/board/freescale/common/cadmus.c @@ -1,5 +1,5 @@ /* - * Copyright 2004 Freescale Semiconductor. + * Copyright 2004, 2011 Freescale Semiconductor. * * See file CREDITS for list of people who contributed to this * project. @@ -61,12 +61,12 @@ get_clock_freq(void) uint pci1_speed = (cadmus->cm_pci >> 2) & 0x3; /* PSPEED in [4:5] */ if (pci1_speed == 0) { - return 33000000; + return 33333333; } else if (pci1_speed == 1) { - return 66000000; + return 66666666; } else { /* Really, unknown. Be safe? */ - return 33000000; + return 33333333; } } diff --git a/board/freescale/common/fman.c b/board/freescale/common/fman.c new file mode 100644 index 0000000..8a55fde --- /dev/null +++ b/board/freescale/common/fman.c @@ -0,0 +1,67 @@ +/* + * 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 <libfdt.h> +#include <libfdt_env.h> +#include <fdt_support.h> + +/* + * Given the following ... + * + * 1) A pointer to an Fman Ethernet node (as identified by the 'compat' + * compatible string and 'addr' physical address) + * + * 2) The name of an alias that points to the ethernet-phy node (usually inside + * a virtual MDIO node) + * + * ... update that Ethernet node's phy-handle property to point to the + * ethernet-phy node. This is how we link an Ethernet node to its PHY, so each + * PHY in a virtual MDIO node must have an alias. + */ +void fdt_set_phy_handle(void *fdt, char *compat, phys_addr_t addr, + const char *alias) +{ + int offset, ph; + const char *path; + + /* Get a path to the node that 'alias' points to */ + path = fdt_get_alias(fdt, alias); + if (path) { + /* Get the offset of that node */ + int off = fdt_path_offset(fdt, path); + if (off > 0) + ph = fdt_create_phandle(fdt, off); + else + return; + } else { + return ; + } + + /* failed to create a phandle */ + if (ph <= 0) + return ; + + offset = fdt_node_offset_by_compat_reg(fdt, compat, addr); + if (offset > 0) + fdt_setprop(fdt, offset, "phy-handle", &ph, sizeof(ph)); +} diff --git a/board/freescale/p2041rdb/pci.c b/board/freescale/common/fman.h index 1ab4cdf..19ef7c4 100644 --- a/board/freescale/p2041rdb/pci.c +++ b/board/freescale/common/fman.h @@ -1,9 +1,6 @@ /* * 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 @@ -20,20 +17,10 @@ * MA 02111-1307 USA */ -#include <common.h> -#include <command.h> -#include <pci.h> -#include <asm/fsl_pci.h> -#include <libfdt.h> -#include <fdt_support.h> -#include <asm/fsl_serdes.h> +#ifndef __FMAN_BOARD_HELPER__ +#define __FMAN_BOARD_HELPER__ -void pci_init_board(void) -{ - fsl_pcie_init_board(0); -} +void fdt_set_phy_handle(void *fdt, char *compat, phys_addr_t addr, + const char *alias); -void pci_of_setup(void *blob, bd_t *bd) -{ - FT_FSL_PCI_SETUP; -} +#endif diff --git a/board/freescale/common/p_corenet/Makefile b/board/freescale/common/p_corenet/Makefile new file mode 100644 index 0000000..a76f590 --- /dev/null +++ b/board/freescale/common/p_corenet/Makefile @@ -0,0 +1,31 @@ +# +# (C) Copyright 2002-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 = libp_corenet.o + +COBJS-y += law.o +COBJS-$(CONFIG_PCI) += pci.o +COBJS-y += tlb.o + +include $(TOPDIR)/post/rules.mk diff --git a/board/freescale/corenet_ds/law.c b/board/freescale/common/p_corenet/law.c index 58f23c5..09ef561 100644 --- a/board/freescale/corenet_ds/law.c +++ b/board/freescale/common/p_corenet/law.c @@ -35,7 +35,12 @@ struct law_entry law_table[] = { #ifdef CONFIG_SYS_QMAN_MEM_PHYS SET_LAW(CONFIG_SYS_QMAN_MEM_PHYS, LAW_SIZE_2M, LAW_TRGT_IF_QMAN), #endif +#ifdef PIXIS_BASE_PHYS SET_LAW(PIXIS_BASE_PHYS, LAW_SIZE_4K, LAW_TRGT_IF_LBC), +#endif +#ifdef CPLD_BASE_PHYS + SET_LAW(CPLD_BASE_PHYS, LAW_SIZE_4K, LAW_TRGT_IF_LBC), +#endif #ifdef CONFIG_SYS_DCSRBAR_PHYS /* Limit DCSR to 32M to access NPC Trace Buffer */ SET_LAW(CONFIG_SYS_DCSRBAR_PHYS, LAW_SIZE_32M, LAW_TRGT_IF_DCSR), diff --git a/board/freescale/corenet_ds/pci.c b/board/freescale/common/p_corenet/pci.c index 18a75de..18a75de 100644 --- a/board/freescale/corenet_ds/pci.c +++ b/board/freescale/common/p_corenet/pci.c diff --git a/board/freescale/corenet_ds/tlb.c b/board/freescale/common/p_corenet/tlb.c index 2ce7004..6a0026a 100644 --- a/board/freescale/corenet_ds/tlb.c +++ b/board/freescale/common/p_corenet/tlb.c @@ -30,24 +30,31 @@ struct fsl_e_tlb_entry tlb_table[] = { /* TLB 0 - for temp stack in cache */ SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR, CONFIG_SYS_INIT_RAM_ADDR_PHYS, - MAS3_SX|MAS3_SW|MAS3_SR, 0, + MAS3_SW|MAS3_SR, 0, 0, 0, BOOKE_PAGESZ_4K, 0), SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 4 * 1024, CONFIG_SYS_INIT_RAM_ADDR_PHYS + 4 * 1024, - MAS3_SX|MAS3_SW|MAS3_SR, 0, + MAS3_SW|MAS3_SR, 0, 0, 0, BOOKE_PAGESZ_4K, 0), SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 8 * 1024, CONFIG_SYS_INIT_RAM_ADDR_PHYS + 8 * 1024, - MAS3_SX|MAS3_SW|MAS3_SR, 0, + MAS3_SW|MAS3_SR, 0, 0, 0, BOOKE_PAGESZ_4K, 0), SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 12 * 1024, CONFIG_SYS_INIT_RAM_ADDR_PHYS + 12 * 1024, - MAS3_SX|MAS3_SW|MAS3_SR, 0, + MAS3_SW|MAS3_SR, 0, 0, 0, BOOKE_PAGESZ_4K, 0), +#ifdef CPLD_BASE + SET_TLB_ENTRY(0, CPLD_BASE, CPLD_BASE_PHYS, + MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 0, BOOKE_PAGESZ_4K, 0), +#endif +#ifdef PIXIS_BASE SET_TLB_ENTRY(0, PIXIS_BASE, PIXIS_BASE_PHYS, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 0, BOOKE_PAGESZ_4K, 0), +#endif /* TLB 1 */ /* *I*** - Covers boot page */ @@ -67,7 +74,7 @@ struct fsl_e_tlb_entry tlb_table[] = { /* *I*G* - CCSRBAR */ SET_TLB_ENTRY(1, CONFIG_SYS_CCSRBAR, CONFIG_SYS_CCSRBAR_PHYS, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 1, BOOKE_PAGESZ_16M, 1), /* *I*G* - Flash, localbus */ @@ -78,47 +85,47 @@ struct fsl_e_tlb_entry tlb_table[] = { /* *I*G* - PCI */ SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_MEM_VIRT, CONFIG_SYS_PCIE1_MEM_PHYS, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 3, BOOKE_PAGESZ_1G, 1), /* *I*G* - PCI */ SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_MEM_VIRT + 0x40000000, CONFIG_SYS_PCIE1_MEM_PHYS + 0x40000000, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 4, BOOKE_PAGESZ_256M, 1), SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_MEM_VIRT + 0x50000000, CONFIG_SYS_PCIE1_MEM_PHYS + 0x50000000, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 5, BOOKE_PAGESZ_256M, 1), /* *I*G* - PCI I/O */ SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_IO_VIRT, CONFIG_SYS_PCIE1_IO_PHYS, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 6, BOOKE_PAGESZ_256K, 1), /* Bman/Qman */ #ifdef CONFIG_SYS_BMAN_MEM_PHYS SET_TLB_ENTRY(1, CONFIG_SYS_BMAN_MEM_BASE, CONFIG_SYS_BMAN_MEM_PHYS, - MAS3_SX|MAS3_SW|MAS3_SR, 0, + MAS3_SW|MAS3_SR, 0, 0, 9, BOOKE_PAGESZ_1M, 1), SET_TLB_ENTRY(1, CONFIG_SYS_BMAN_MEM_BASE + 0x00100000, CONFIG_SYS_BMAN_MEM_PHYS + 0x00100000, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 10, BOOKE_PAGESZ_1M, 1), #endif #ifdef CONFIG_SYS_QMAN_MEM_PHYS SET_TLB_ENTRY(1, CONFIG_SYS_QMAN_MEM_BASE, CONFIG_SYS_QMAN_MEM_PHYS, - MAS3_SX|MAS3_SW|MAS3_SR, 0, + MAS3_SW|MAS3_SR, 0, 0, 11, BOOKE_PAGESZ_1M, 1), SET_TLB_ENTRY(1, CONFIG_SYS_QMAN_MEM_BASE + 0x00100000, CONFIG_SYS_QMAN_MEM_PHYS + 0x00100000, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 12, BOOKE_PAGESZ_1M, 1), #endif #ifdef CONFIG_SYS_DCSRBAR_PHYS SET_TLB_ENTRY(1, CONFIG_SYS_DCSRBAR, CONFIG_SYS_DCSRBAR_PHYS, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 13, BOOKE_PAGESZ_4M, 1), #endif #ifdef CONFIG_SYS_NAND_BASE diff --git a/board/freescale/corenet_ds/Makefile b/board/freescale/corenet_ds/Makefile index 69e81a4..7e33007 100644 --- a/board/freescale/corenet_ds/Makefile +++ b/board/freescale/corenet_ds/Makefile @@ -28,12 +28,12 @@ LIB = $(obj)lib$(BOARD).o COBJS-y += $(BOARD).o COBJS-y += ddr.o +COBJS-$(CONFIG_P3041DS) += eth_hydra.o +COBJS-$(CONFIG_P4080DS) += eth_p4080.o +COBJS-$(CONFIG_P5020DS) += eth_hydra.o COBJS-$(CONFIG_P3041DS) += p3041ds_ddr.o COBJS-$(CONFIG_P4080DS) += p4080ds_ddr.o COBJS-$(CONFIG_P5020DS) += p5020ds_ddr.o -COBJS-$(CONFIG_PCI) += pci.o -COBJS-y += law.o -COBJS-y += tlb.o SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(COBJS-y)) diff --git a/board/freescale/corenet_ds/corenet_ds.c b/board/freescale/corenet_ds/corenet_ds.c index b1e7823..b1eecc4 100644 --- a/board/freescale/corenet_ds/corenet_ds.c +++ b/board/freescale/corenet_ds/corenet_ds.c @@ -32,10 +32,10 @@ #include <asm/fsl_serdes.h> #include <asm/fsl_portals.h> #include <asm/fsl_liodn.h> - -extern void pci_of_setup(void *blob, bd_t *bd); +#include <fm_eth.h> #include "../common/ngpixis.h" +#include "corenet_ds.h" DECLARE_GLOBAL_DATA_PTR; @@ -237,9 +237,9 @@ void ft_board_setup(void *blob, bd_t *bd) fdt_fixup_liodn(blob); fdt_fixup_dr_usb(blob, bd); -} -int board_eth_init(bd_t *bis) -{ - return pci_eth_init(bis); +#ifdef CONFIG_SYS_DPAA_FMAN + fdt_fixup_fman_ethernet(blob); + fdt_fixup_board_enet(blob); +#endif } diff --git a/board/freescale/corenet_ds/corenet_ds.h b/board/freescale/corenet_ds/corenet_ds.h new file mode 100644 index 0000000..9cdd47d --- /dev/null +++ b/board/freescale/corenet_ds/corenet_ds.h @@ -0,0 +1,26 @@ +/* + * 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 __CORENET_DS_H__ +#define __CORENET_DS_H__ + +void fdt_fixup_board_enet(void *blob); +void pci_of_setup(void *blob, bd_t *bd); + +#endif diff --git a/board/freescale/corenet_ds/ddr.c b/board/freescale/corenet_ds/ddr.c index b937015..3b4dfa3 100644 --- a/board/freescale/corenet_ds/ddr.c +++ b/board/freescale/corenet_ds/ddr.c @@ -118,53 +118,111 @@ typedef struct { u32 force_2T; } board_specific_parameters_t; -/* ranges for parameters: - * wr_data_delay = 0-6 - * clk adjust = 0-8 - * cpo 2-0x1E (30) - */ - - -/* XXX: these values need to be checked for all interleaving modes. */ -/* XXX: No reliable dual-rank 800 MHz setting has been found. It may - * seem reliable, but errors will appear when memory intensive - * program is run. */ -/* XXX: Single rank at 800 MHz is OK. */ -const board_specific_parameters_t board_specific_parameters[][30] = { +const board_specific_parameters_t board_specific_parameters_udimm[][30] = { { /* * memory controller 0 * lo| hi| num| clk| wrlvl | cpo |wrdata|2T - * mhz| mhz|ranks|adjst| start | delay| + * mhz| mhz|ranks|adjst| start | |delay | */ { 0, 850, 4, 4, 6, 0xff, 2, 0}, {851, 950, 4, 5, 7, 0xff, 2, 0}, {951, 1050, 4, 5, 8, 0xff, 2, 0}, {1051, 1250, 4, 5, 10, 0xff, 2, 0}, {1251, 1350, 4, 5, 11, 0xff, 2, 0}, + {1351, 1666, 4, 5, 12, 0xff, 2, 0}, { 0, 850, 2, 5, 6, 0xff, 2, 0}, {851, 950, 2, 5, 7, 0xff, 2, 0}, {951, 1050, 2, 5, 7, 0xff, 2, 0}, {1051, 1250, 2, 4, 6, 0xff, 2, 0}, {1251, 1350, 2, 5, 7, 0xff, 2, 0}, + {1351, 1666, 2, 5, 8, 0xff, 2, 0}, + { 0, 850, 1, 4, 5, 0xff, 2, 0}, + {851, 950, 1, 4, 7, 0xff, 2, 0}, + {951, 1050, 1, 4, 8, 0xff, 2, 0}, + {1051, 1250, 1, 4, 8, 0xff, 2, 0}, + {1251, 1350, 1, 4, 8, 0xff, 2, 0}, + {1351, 1666, 1, 4, 8, 0xff, 2, 0}, }, { /* * memory controller 1 * lo| hi| num| clk| wrlvl | cpo |wrdata|2T - * mhz| mhz|ranks|adjst| start | delay| + * mhz| mhz|ranks|adjst| start | |delay | */ { 0, 850, 4, 4, 6, 0xff, 2, 0}, {851, 950, 4, 5, 7, 0xff, 2, 0}, {951, 1050, 4, 5, 8, 0xff, 2, 0}, {1051, 1250, 4, 5, 10, 0xff, 2, 0}, {1251, 1350, 4, 5, 11, 0xff, 2, 0}, + {1351, 1666, 4, 5, 12, 0xff, 2, 0}, { 0, 850, 2, 5, 6, 0xff, 2, 0}, {851, 950, 2, 5, 7, 0xff, 2, 0}, {951, 1050, 2, 5, 7, 0xff, 2, 0}, {1051, 1250, 2, 4, 6, 0xff, 2, 0}, {1251, 1350, 2, 5, 7, 0xff, 2, 0}, + {1351, 1666, 2, 5, 8, 0xff, 2, 0}, + { 0, 850, 1, 4, 5, 0xff, 2, 0}, + {851, 950, 1, 4, 7, 0xff, 2, 0}, + {951, 1050, 1, 4, 8, 0xff, 2, 0}, + {1051, 1250, 1, 4, 8, 0xff, 2, 0}, + {1251, 1350, 1, 4, 8, 0xff, 2, 0}, + {1351, 1666, 1, 4, 8, 0xff, 2, 0}, + } +}; + +const board_specific_parameters_t board_specific_parameters_rdimm[][30] = { + { + /* + * memory controller 0 + * lo| hi| num| clk| wrlvl | cpo |wrdata|2T + * mhz| mhz|ranks|adjst| start | |delay | + */ + { 0, 850, 4, 4, 6, 0xff, 2, 0}, + {851, 950, 4, 5, 7, 0xff, 2, 0}, + {951, 1050, 4, 5, 8, 0xff, 2, 0}, + {1051, 1250, 4, 5, 10, 0xff, 2, 0}, + {1251, 1350, 4, 5, 11, 0xff, 2, 0}, + {1351, 1666, 4, 5, 12, 0xff, 2, 0}, + { 0, 850, 2, 4, 6, 0xff, 2, 0}, + {851, 950, 2, 4, 7, 0xff, 2, 0}, + {951, 1050, 2, 4, 7, 0xff, 2, 0}, + {1051, 1250, 2, 4, 8, 0xff, 2, 0}, + {1251, 1350, 2, 4, 8, 0xff, 2, 0}, + {1351, 1666, 2, 4, 8, 0xff, 2, 0}, + { 0, 850, 1, 4, 5, 0xff, 2, 0}, + {851, 950, 1, 4, 7, 0xff, 2, 0}, + {951, 1050, 1, 4, 8, 0xff, 2, 0}, + {1051, 1250, 1, 4, 8, 0xff, 2, 0}, + {1251, 1350, 1, 4, 8, 0xff, 2, 0}, + {1351, 1666, 1, 4, 8, 0xff, 2, 0}, + }, + + { + /* + * memory controller 1 + * lo| hi| num| clk| wrlvl | cpo |wrdata|2T + * mhz| mhz|ranks|adjst| start | |delay | + */ + { 0, 850, 4, 4, 6, 0xff, 2, 0}, + {851, 950, 4, 5, 7, 0xff, 2, 0}, + {951, 1050, 4, 5, 8, 0xff, 2, 0}, + {1051, 1250, 4, 5, 10, 0xff, 2, 0}, + {1251, 1350, 4, 5, 11, 0xff, 2, 0}, + {1351, 1666, 4, 5, 12, 0xff, 2, 0}, + { 0, 850, 2, 4, 6, 0xff, 2, 0}, + {851, 950, 2, 4, 7, 0xff, 2, 0}, + {951, 1050, 2, 4, 7, 0xff, 2, 0}, + {1051, 1250, 2, 4, 8, 0xff, 2, 0}, + {1251, 1350, 2, 4, 8, 0xff, 2, 0}, + {1351, 1666, 2, 4, 8, 0xff, 2, 0}, + { 0, 850, 1, 4, 5, 0xff, 2, 0}, + {851, 950, 1, 4, 7, 0xff, 2, 0}, + {951, 1050, 1, 4, 8, 0xff, 2, 0}, + {1051, 1250, 1, 4, 8, 0xff, 2, 0}, + {1251, 1350, 1, 4, 8, 0xff, 2, 0}, + {1351, 1666, 1, 4, 8, 0xff, 2, 0}, } }; @@ -172,13 +230,20 @@ void fsl_ddr_board_options(memctl_options_t *popts, dimm_params_t *pdimm, unsigned int ctrl_num) { - const board_specific_parameters_t *pbsp = - &(board_specific_parameters[ctrl_num][0]); - u32 num_params = sizeof(board_specific_parameters[ctrl_num]) / - sizeof(board_specific_parameters[0][0]); + const board_specific_parameters_t *pbsp; + u32 num_params; u32 i; ulong ddr_freq; + if (popts->registered_dimm_en) { + pbsp = &(board_specific_parameters_rdimm[ctrl_num][0]); + num_params = sizeof(board_specific_parameters_rdimm[ctrl_num]) / + sizeof(board_specific_parameters_rdimm[0][0]); + } else { + pbsp = &(board_specific_parameters_udimm[ctrl_num][0]); + num_params = sizeof(board_specific_parameters_udimm[ctrl_num]) / + sizeof(board_specific_parameters_udimm[0][0]); + } /* Get clk_adjust, cpo, write_data_delay,2T, according to the board ddr * freqency and n_banks specified in board_specific_parameters table. */ @@ -223,20 +288,6 @@ void fsl_ddr_board_options(memctl_options_t *popts, /* DHC_EN =1, ODT = 60 Ohm */ popts->ddr_cdr1 = DDR_CDR1_DHC_EN; - - /* override SPD values. rcw_2 should vary at differnt speed */ - if (pdimm[0].registered_dimm == 1) { - popts->rcw_override = 1; - popts->rcw_1 = 0x000a5a00; - if (ddr_freq <= 800) - popts->rcw_2 = 0x00000000; - else if (ddr_freq <= 1066) - popts->rcw_2 = 0x00100000; - else if (ddr_freq <= 1333) - popts->rcw_2 = 0x00200000; - else - popts->rcw_2 = 0x00300000; - } } phys_size_t initdram(int board_type) diff --git a/board/freescale/corenet_ds/eth_hydra.c b/board/freescale/corenet_ds/eth_hydra.c new file mode 100644 index 0000000..91b3408 --- /dev/null +++ b/board/freescale/corenet_ds/eth_hydra.c @@ -0,0 +1,553 @@ +/* + * Copyright 2009-2011 Freescale Semiconductor, Inc. + * Author: Timur Tabi <timur@freescale.com> + * + * 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 + */ + +/* + * This file handles the board muxing between the Fman Ethernet MACs and + * the RGMII/SGMII/XGMII PHYs on a Freescale P3041/P5020 "Hydra" reference + * board. The RGMII PHYs are the two on-board 1Gb ports. The SGMII PHYs are + * provided by the standard Freescale four-port SGMII riser card. The 10Gb + * XGMII PHY is provided via the XAUI riser card. Since there is only one + * Fman device on a P3041 and P5020, we only support one SGMII card and one + * RGMII card. + * + * Muxing is handled via the PIXIS BRDCFG1 register. The EMI1 bits control + * muxing among the RGMII PHYs and the SGMII PHYs. The value for RGMII is + * always the same (0). The value for SGMII depends on which slot the riser is + * inserted in. The EMI2 bits control muxing for the the XGMII. Like SGMII, + * the value is based on which slot the XAUI is inserted in. + * + * The SERDES configuration is used to determine where the SGMII and XAUI cards + * exist, and also which Fman MACs are routed to which PHYs. So for a given + * Fman MAC, there is one and only PHY it connects to. MACs cannot be routed + * to PHYs dynamically. + * + * + * This file also updates the device tree in three ways: + * + * 1) The status of each virtual MDIO node that is referenced by an Ethernet + * node is set to "okay". + * + * 2) The phy-handle property of each active Ethernet MAC node is set to the + * appropriate PHY node. + * + * 3) The "mux value" for each virtual MDIO node is set to the correct value, + * if necessary. Some virtual MDIO nodes do not have configurable mux + * values, so those values are hard-coded in the DTS. On the HYDRA board, + * the virtual MDIO node for the SGMII card needs to be updated. + * + * For all this to work, the device tree needs to have the following: + * + * 1) An alias for each PHY node that an Ethernet node could be routed to. + * + * 2) An alias for each real and virtual MDIO node that is disabled by default + * and might need to be enabled, and also might need to have its mux-value + * updated. + */ + +#include <common.h> +#include <netdev.h> +#include <asm/fsl_serdes.h> +#include <fm_eth.h> +#include <fsl_mdio.h> +#include <malloc.h> +#include <asm/fsl_dtsec.h> + +#include "../common/ngpixis.h" +#include "../common/fman.h" + +#ifdef CONFIG_FMAN_ENET + +#define BRDCFG1_EMI1_SEL_MASK 0x70 +#define BRDCFG1_EMI1_SEL_SLOT1 0x10 +#define BRDCFG1_EMI1_SEL_SLOT2 0x20 +#define BRDCFG1_EMI1_SEL_SLOT5 0x30 +#define BRDCFG1_EMI1_SEL_SLOT6 0x40 +#define BRDCFG1_EMI1_SEL_SLOT7 0x50 +#define BRDCFG1_EMI1_SEL_RGMII 0x00 +#define BRDCFG1_EMI1_EN 0x08 +#define BRDCFG1_EMI2_SEL_MASK 0x06 +#define BRDCFG1_EMI2_SEL_SLOT1 0x00 +#define BRDCFG1_EMI2_SEL_SLOT2 0x02 + +#define BRDCFG2_REG_GPIO_SEL 0x20 + +/* + * BRDCFG1 mask and value for each MAC + * + * This array contains the BRDCFG1 values (in mask/val format) that route the + * MDIO bus to a particular RGMII or SGMII PHY. + */ +struct { + u8 mask; + u8 val; +} mdio_mux[NUM_FM_PORTS]; + +/* + * Mapping of all 18 SERDES lanes to board slots. A value of '0' here means + * that the mapping must be determined dynamically, or that the lane maps to + * something other than a board slot + */ +static u8 lane_to_slot[] = { + 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 0, 0 +}; + +/* + * Set the board muxing for a given MAC + * + * The MDIO layer calls this function every time it wants to talk to a PHY. + */ +void hydra_mux_mdio(u8 mask, u8 val) +{ + clrsetbits_8(&pixis->brdcfg1, mask, val); +} + +struct hydra_mdio { + u8 mask; + u8 val; + struct mii_dev *realbus; +}; + +static int hydra_mdio_read(struct mii_dev *bus, int addr, int devad, + int regnum) +{ + struct hydra_mdio *priv = bus->priv; + + hydra_mux_mdio(priv->mask, priv->val); + + return priv->realbus->read(priv->realbus, addr, devad, regnum); +} + +static int hydra_mdio_write(struct mii_dev *bus, int addr, int devad, + int regnum, u16 value) +{ + struct hydra_mdio *priv = bus->priv; + + hydra_mux_mdio(priv->mask, priv->val); + + return priv->realbus->write(priv->realbus, addr, devad, regnum, value); +} + +static int hydra_mdio_reset(struct mii_dev *bus) +{ + struct hydra_mdio *priv = bus->priv; + + return priv->realbus->reset(priv->realbus); +} + +static void hydra_mdio_set_mux(char *name, u8 mask, u8 val) +{ + struct mii_dev *bus = miiphy_get_dev_by_name(name); + struct hydra_mdio *priv = bus->priv; + + priv->mask = mask; + priv->val = val; +} + +static int hydra_mdio_init(char *realbusname, char *fakebusname) +{ + struct hydra_mdio *hmdio; + struct mii_dev *bus = mdio_alloc(); + + if (!bus) { + printf("Failed to allocate Hydra MDIO bus\n"); + return -1; + } + + hmdio = malloc(sizeof(*hmdio)); + if (!hmdio) { + printf("Failed to allocate Hydra private data\n"); + free(bus); + return -1; + } + + bus->read = hydra_mdio_read; + bus->write = hydra_mdio_write; + bus->reset = hydra_mdio_reset; + sprintf(bus->name, fakebusname); + + hmdio->realbus = miiphy_get_dev_by_name(realbusname); + + if (!hmdio->realbus) { + printf("No bus with name %s\n", realbusname); + free(bus); + free(hmdio); + return -1; + } + + bus->priv = hmdio; + + return mdio_register(bus); +} + +/* + * Given an alias or a path for a node, set the status of that node. + * + * If 'alias' is not a valid alias, then it is treated as a full path to the + * node. No error checking is performed. + * + * This function is normally called to set the status for a virtual MDIO node. + */ +static void fdt_set_node_status(void *fdt, const char *alias, + const char *status) +{ + const char *path = fdt_get_alias(fdt, alias); + + if (!path) + path = alias; + + do_fixup_by_path(fdt, path, "status", status, strlen(status) + 1, 1); +} + +/* + * Given an alias or a path for a node, set the mux value of that node. + * + * If 'alias' is not a valid alias, then it is treated as a full path to the + * node. No error checking is performed. + * + * This function is normally called to set the fsl,hydra-mdio-muxval property + * of a virtual MDIO node. + */ +static void fdt_set_mdio_mux(void *fdt, const char *alias, u32 mux) +{ + const char *path = fdt_get_alias(fdt, alias); + + if (!path) + path = alias; + + do_fixup_by_path(fdt, path, "fsl,hydra-mdio-muxval", + &mux, sizeof(mux), 1); +} + +/* + * Given the following ... + * + * 1) A pointer to an Fman Ethernet node (as identified by the 'compat' + * compatible string and 'addr' physical address) + * + * 2) An Fman port + * + * ... update the phy-handle property of the Ethernet node to point to the + * right PHY. This assumes that we already know the PHY for each port. That + * information is stored in mdio_mux[]. + * + * The offset of the Fman Ethernet node is also passed in for convenience, but + * it is not used, and we recalculate the offset anyway. + * + * Note that what we call "Fman ports" (enum fm_port) is really an Fman MAC. + * Inside the Fman, "ports" are things that connect to MACs. We only call them + * ports in U-Boot because on previous Ethernet devices (e.g. Gianfar), MACs + * and ports are the same thing. + * + * Note that this code would be cleaner if had a function called + * fm_info_get_phy_address(), which returns a value from the fm1_dtsec_info[] + * array. That's because all we're doing is figuring out the PHY address for + * a given Fman MAC and writing it to the device tree. Well, we already did + * the hard work to figure that out in board_eth_init(), so it's silly to + * repeat that here. + */ +void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr, + enum fm_port port, int offset) +{ + unsigned int mux = mdio_mux[port].val & mdio_mux[port].mask; + char phy[16]; + + if (port == FM1_10GEC1) { + /* XAUI */ + int lane = serdes_get_first_lane(XAUI_FM1); + if (lane >= 0) { + /* The XAUI PHY is identified by the slot */ + sprintf(phy, "phy_xgmii_%u", lane_to_slot[lane]); + fdt_set_phy_handle(fdt, compat, addr, phy); + } + return; + } + + if (mux == BRDCFG1_EMI1_SEL_RGMII) { + /* RGMII */ + /* The RGMII PHY is identified by the MAC connected to it */ + sprintf(phy, "phy_rgmii_%u", port == FM1_DTSEC4 ? 0 : 1); + fdt_set_phy_handle(fdt, compat, addr, phy); + } + + /* If it's not RGMII or XGMII, it must be SGMII */ + if (mux) { + /* The SGMII PHY is identified by the MAC connected to it */ + sprintf(phy, "phy_sgmii_%x", + CONFIG_SYS_FM1_DTSEC1_PHY_ADDR + (port - FM1_DTSEC1)); + fdt_set_phy_handle(fdt, compat, addr, phy); + } +} + +#define PIXIS_SW2_LANE_23_SEL 0x80 +#define PIXIS_SW2_LANE_45_SEL 0x40 +#define PIXIS_SW2_LANE_67_SEL_MASK 0x30 +#define PIXIS_SW2_LANE_67_SEL_5 0x00 +#define PIXIS_SW2_LANE_67_SEL_6 0x20 +#define PIXIS_SW2_LANE_67_SEL_7 0x10 +#define PIXIS_SW2_LANE_8_SEL 0x08 +#define PIXIS_SW2_LANE_1617_SEL 0x04 + +/* + * Initialize the lane_to_slot[] array. + * + * On the P4080DS "Expedition" board, the mapping of SERDES lanes to board + * slots is hard-coded. On the Hydra board, however, the mapping is controlled + * by board switch SW2, so the lane_to_slot[] array needs to be dynamically + * initialized. + */ +static void initialize_lane_to_slot(void) +{ + u8 sw2 = in_8(&PIXIS_SW(2)); + + lane_to_slot[2] = (sw2 & PIXIS_SW2_LANE_23_SEL) ? 7 : 4; + lane_to_slot[3] = lane_to_slot[2]; + + lane_to_slot[4] = (sw2 & PIXIS_SW2_LANE_45_SEL) ? 7 : 6; + lane_to_slot[5] = lane_to_slot[4]; + + switch (sw2 & PIXIS_SW2_LANE_67_SEL_MASK) { + case PIXIS_SW2_LANE_67_SEL_5: + lane_to_slot[6] = 5; + break; + case PIXIS_SW2_LANE_67_SEL_6: + lane_to_slot[6] = 6; + break; + case PIXIS_SW2_LANE_67_SEL_7: + lane_to_slot[6] = 7; + break; + } + lane_to_slot[7] = lane_to_slot[6]; + + lane_to_slot[8] = (sw2 & PIXIS_SW2_LANE_8_SEL) ? 3 : 0; + + lane_to_slot[16] = (sw2 & PIXIS_SW2_LANE_1617_SEL) ? 1 : 0; + lane_to_slot[17] = lane_to_slot[16]; +} + +#endif /* #ifdef CONFIG_FMAN_ENET */ + +/* + * Configure the status for the virtual MDIO nodes + * + * Rather than create the virtual MDIO nodes from scratch for each active + * virtual MDIO, we expect the DTS to have the nodes defined already, and we + * only enable the ones that are actually active. + * + * We assume that the DTS already hard-codes the status for all the + * virtual MDIO nodes to "disabled", so all we need to do is enable the + * active ones. + * + * For SGMII, we also need to set the mux value in the node. + */ +void fdt_fixup_board_enet(void *fdt) +{ +#ifdef CONFIG_FMAN_ENET + unsigned int i; + int lane; + + for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { + int 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) { + fdt_set_node_status(fdt, "emi1_sgmii", "okay"); + /* Also set the MUX value */ + fdt_set_mdio_mux(fdt, "emi1_sgmii", + mdio_mux[i].val); + } + break; + case PHY_INTERFACE_MODE_RGMII: + fdt_set_node_status(fdt, "emi1_rgmii", "okay"); + break; + default: + break; + } + } + + lane = serdes_get_first_lane(XAUI_FM1); + if (lane >= 0) + fdt_set_node_status(fdt, "emi2_xgmii", "okay"); +#endif +} + +int board_eth_init(bd_t *bis) +{ +#ifdef CONFIG_FMAN_ENET + struct dtsec *tsec = (void *)CONFIG_SYS_FSL_FM1_DTSEC1_ADDR; + struct fsl_pq_mdio_info dtsec_mdio_info; + struct tgec_mdio_info tgec_mdio_info; + unsigned int i, slot; + int lane; + + printf("Initializing Fman\n"); + + 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); + + /* We want to use the PIXIS to configure MUX routing, not GPIOs. */ + setbits_8(&pixis->brdcfg2, BRDCFG2_REG_GPIO_SEL); + + memset(mdio_mux, 0, sizeof(mdio_mux)); + + dtsec_mdio_info.regs = + (struct tsec_mii_mng *)CONFIG_SYS_FM1_DTSEC1_MDIO_ADDR; + dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME; + + /* Register the real 1G MDIO bus */ + fsl_pq_mdio_init(bis, &dtsec_mdio_info); + + tgec_mdio_info.regs = + (struct tgec_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR; + tgec_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME; + + /* Register the real 10G MDIO bus */ + fm_tgec_mdio_init(bis, &tgec_mdio_info); + + /* Register the three virtual MDIO front-ends */ + hydra_mdio_init(DEFAULT_FM_MDIO_NAME, "HYDRA_RGMII_MDIO"); + hydra_mdio_init(DEFAULT_FM_MDIO_NAME, "HYDRA_SGMII_MDIO"); + + /* + * Program the DTSEC PHY addresses assuming that they are all SGMII. + * For any DTSEC that's RGMII, we'll override its PHY address later. + * We assume that DTSEC5 is only used for RGMII. + */ + fm_info_set_phy_address(FM1_DTSEC1, CONFIG_SYS_FM1_DTSEC1_PHY_ADDR); + fm_info_set_phy_address(FM1_DTSEC2, CONFIG_SYS_FM1_DTSEC2_PHY_ADDR); + fm_info_set_phy_address(FM1_DTSEC3, CONFIG_SYS_FM1_DTSEC3_PHY_ADDR); + fm_info_set_phy_address(FM1_DTSEC4, CONFIG_SYS_FM1_DTSEC4_PHY_ADDR); + + for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { + int 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; + slot = lane_to_slot[lane]; + mdio_mux[i].mask = BRDCFG1_EMI1_SEL_MASK; + switch (slot) { + case 1: + /* Always DTSEC5 on Bank 3 */ + mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT1 | + BRDCFG1_EMI1_EN; + break; + case 2: + mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT2 | + BRDCFG1_EMI1_EN; + break; + case 5: + mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT5 | + BRDCFG1_EMI1_EN; + break; + case 6: + mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT6 | + BRDCFG1_EMI1_EN; + break; + case 7: + mdio_mux[i].val = BRDCFG1_EMI1_SEL_SLOT7 | + BRDCFG1_EMI1_EN; + break; + }; + + hydra_mdio_set_mux("HYDRA_SGMII_MDIO", + mdio_mux[i].mask, mdio_mux[i].val); + fm_info_set_mdio(i, + miiphy_get_dev_by_name("HYDRA_SGMII_MDIO")); + break; + case PHY_INTERFACE_MODE_RGMII: + /* + * If DTSEC4 is RGMII, then it's routed via via EC1 to + * the first on-board RGMII port. If DTSEC5 is RGMII, + * then it's routed via via EC2 to the second on-board + * RGMII port. The other DTSECs cannot be routed to + * RGMII. + */ + fm_info_set_phy_address(i, i == FM1_DTSEC4 ? 0 : 1); + mdio_mux[i].mask = BRDCFG1_EMI1_SEL_MASK; + mdio_mux[i].val = BRDCFG1_EMI1_SEL_RGMII | + BRDCFG1_EMI1_EN; + hydra_mdio_set_mux("HYDRA_RGMII_MDIO", + mdio_mux[i].mask, mdio_mux[i].val); + fm_info_set_mdio(i, + miiphy_get_dev_by_name("HYDRA_RGMII_MDIO")); + break; + case PHY_INTERFACE_MODE_NONE: + fm_info_set_phy_address(i, 0); + break; + default: + printf("Fman1: DTSEC%u set to unknown interface %i\n", + idx + 1, fm_info_get_enet_if(i)); + fm_info_set_phy_address(i, 0); + break; + } + } + + /* + * For 10G, we only support one XAUI card per Fman. If present, then we + * force its routing and never touch those bits again, which removes the + * need for Linux to do any muxing. This works because of the way + * BRDCFG1 is defined, but it's a bit hackish. + * + * The PHY address for the XAUI card depends on which slot it's in. The + * macros we use imply that the PHY address is based on which FM, but + * that's not true. On the P4080DS, FM1 could only use XAUI in slot 5, + * and FM2 could only use a XAUI in slot 4. On the Hydra board, we + * check the actual slot and just use the macros as-is, even though + * the P3041 and P5020 only have one Fman. + */ + lane = serdes_get_first_lane(XAUI_FM1); + if (lane >= 0) { + slot = lane_to_slot[lane]; + if (slot == 1) { + /* XAUI card is in slot 1 */ + clrsetbits_8(&pixis->brdcfg1, BRDCFG1_EMI2_SEL_MASK, + BRDCFG1_EMI2_SEL_SLOT1); + fm_info_set_phy_address(FM1_10GEC1, + CONFIG_SYS_FM1_10GEC1_PHY_ADDR); + } else { + /* XAUI card is in slot 2 */ + clrsetbits_8(&pixis->brdcfg1, BRDCFG1_EMI2_SEL_MASK, + BRDCFG1_EMI2_SEL_SLOT2); + fm_info_set_phy_address(FM1_10GEC1, + CONFIG_SYS_FM2_10GEC1_PHY_ADDR); + } + } + + fm_info_set_mdio(FM1_10GEC1, + miiphy_get_dev_by_name(DEFAULT_FM_TGEC_MDIO_NAME)); + + cpu_eth_init(bis); +#endif + + return pci_eth_init(bis); +} diff --git a/board/freescale/corenet_ds/eth_p4080.c b/board/freescale/corenet_ds/eth_p4080.c new file mode 100644 index 0000000..d4657f7 --- /dev/null +++ b/board/freescale/corenet_ds/eth_p4080.c @@ -0,0 +1,506 @@ +/* + * Copyright 2009-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 "../common/ngpixis.h" +#include "../common/fman.h" +#include <asm/fsl_dtsec.h> + +#define EMI_NONE 0xffffffff +#define EMI_MASK 0xf0000000 +#define EMI1_RGMII 0x0 +#define EMI1_SLOT3 0x80000000 /* bank1 EFGH */ +#define EMI1_SLOT4 0x40000000 /* bank2 ABCD */ +#define EMI1_SLOT5 0xc0000000 /* bank3 ABCD */ +#define EMI2_SLOT4 0x10000000 /* bank2 ABCD */ +#define EMI2_SLOT5 0x30000000 /* bank3 ABCD */ +#define EMI1_MASK 0xc0000000 +#define EMI2_MASK 0x30000000 + +static int mdio_mux[NUM_FM_PORTS]; + +static char *mdio_names[16] = { + "P4080DS_MDIO0", + "P4080DS_MDIO1", + NULL, + "P4080DS_MDIO3", + "P4080DS_MDIO4", + NULL, NULL, NULL, + "P4080DS_MDIO8", + NULL, NULL, NULL, + "P4080DS_MDIO12", + NULL, NULL, NULL, +}; + +static char *p4080ds_mdio_name_for_muxval(u32 muxval) +{ + return mdio_names[(muxval & EMI_MASK) >> 28]; +} + +struct mii_dev *mii_dev_for_muxval(u32 muxval) +{ + struct mii_dev *bus; + char *name = p4080ds_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; +} + +#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES9 +int board_phy_config(struct phy_device *phydev) +{ + /* + * If this is the 10G PHY, and we switched it to fiber, + * we need to reset the serdes link for SERDES9 + */ + if ((phydev->port == PORT_FIBRE) && (phydev->drv->uid == 0x00a19410)) { + enum srds_prtcl device; + + switch (phydev->addr) { + case 4: + device = XAUI_FM1; + break; + case 0: + device = XAUI_FM2; + break; + default: + device = NONE; + } + + serdes_reset_rx(device); + } + + return 0; +} +#endif + +struct p4080ds_mdio { + u32 muxval; + struct mii_dev *realbus; +}; + +static void p4080ds_mux_mdio(u32 muxval) +{ + ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR); + uint gpioval = in_be32(&pgpio->gpdat) & ~(EMI_MASK); + gpioval |= muxval; + + out_be32(&pgpio->gpdat, gpioval); +} + +static int p4080ds_mdio_read(struct mii_dev *bus, int addr, int devad, + int regnum) +{ + struct p4080ds_mdio *priv = bus->priv; + + p4080ds_mux_mdio(priv->muxval); + + return priv->realbus->read(priv->realbus, addr, devad, regnum); +} + +static int p4080ds_mdio_write(struct mii_dev *bus, int addr, int devad, + int regnum, u16 value) +{ + struct p4080ds_mdio *priv = bus->priv; + + p4080ds_mux_mdio(priv->muxval); + + return priv->realbus->write(priv->realbus, addr, devad, regnum, value); +} + +static int p4080ds_mdio_reset(struct mii_dev *bus) +{ + struct p4080ds_mdio *priv = bus->priv; + + return priv->realbus->reset(priv->realbus); +} + +static int p4080ds_mdio_init(char *realbusname, u32 muxval) +{ + struct p4080ds_mdio *pmdio; + struct mii_dev *bus = mdio_alloc(); + + if (!bus) { + printf("Failed to allocate P4080DS MDIO bus\n"); + return -1; + } + + pmdio = malloc(sizeof(*pmdio)); + if (!pmdio) { + printf("Failed to allocate P4080DS private data\n"); + free(bus); + return -1; + } + + bus->read = p4080ds_mdio_read; + bus->write = p4080ds_mdio_write; + bus->reset = p4080ds_mdio_reset; + sprintf(bus->name, p4080ds_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); +} + +/* + * Sets the specified node's status to the value contained in "status" + * If the first character of the specified path is "/" then we use + * alias as a path. Otherwise, we look for an alias of that name + */ +static void fdt_set_node_status(void *fdt, const char *alias, + const char *status) +{ + const char *path = fdt_get_alias(fdt, alias); + + if (!path) + path = alias; + + do_fixup_by_path(fdt, path, "status", status, strlen(status) + 1, 1); +} + +void board_ft_fman_fixup_port(void *blob, char * prop, phys_addr_t pa, + enum fm_port port, int offset) +{ + if (mdio_mux[port] == EMI1_RGMII) + fdt_set_phy_handle(blob, prop, pa, "phy_rgmii"); + + if (mdio_mux[port] == EMI1_SLOT3) { + int idx = port - FM2_DTSEC1 + 5; + char phy[16]; + + sprintf(phy, "phy%d_slot3", idx); + + fdt_set_phy_handle(blob, prop, pa, phy); + } +} + +void fdt_fixup_board_enet(void *fdt) +{ + int i; + + /* + * P4080DS can be configured in many different ways, supporting a number + * of combinations of ethernet devices and phy types. In order to + * have just one device tree for all of those configurations, we fix up + * the tree here. By default, the device tree configures FM1 and FM2 + * for SGMII, and configures XAUI on both 10G interfaces. So we have + * a number of different variables to track: + * + * 1) Whether the device is configured at all. Whichever devices are + * not enabled should be disabled by setting the "status" property + * to "disabled". + * 2) What the PHY interface is. If this is an RGMII connection, + * we should change the "phy-connection-type" property to + * "rgmii" + * 3) Which PHY is being used. Because the MDIO buses are muxed, + * we need to redirect the "phy-handle" property to point at the + * PHY on the right slot/bus. + */ + + /* We've got six MDIO nodes that may or may not need to exist */ + fdt_set_node_status(fdt, "emi1_slot3", "disabled"); + fdt_set_node_status(fdt, "emi1_slot4", "disabled"); + fdt_set_node_status(fdt, "emi1_slot5", "disabled"); + fdt_set_node_status(fdt, "emi2_slot4", "disabled"); + fdt_set_node_status(fdt, "emi2_slot5", "disabled"); + + for (i = 0; i < NUM_FM_PORTS; i++) { + switch (mdio_mux[i]) { + case EMI1_SLOT3: + fdt_set_node_status(fdt, "emi1_slot3", "okay"); + break; + case EMI1_SLOT4: + fdt_set_node_status(fdt, "emi1_slot4", "okay"); + break; + case EMI1_SLOT5: + fdt_set_node_status(fdt, "emi1_slot5", "okay"); + break; + case EMI2_SLOT4: + fdt_set_node_status(fdt, "emi2_slot4", "okay"); + break; + case EMI2_SLOT5: + fdt_set_node_status(fdt, "emi2_slot5", "okay"); + break; + } + } +} + +enum board_slots { + SLOT1 = 1, + SLOT2, + SLOT3, + SLOT4, + SLOT5, + SLOT6, +}; + +int board_eth_init(bd_t *bis) +{ +#ifdef CONFIG_FMAN_ENET + ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR); + struct dtsec *tsec = (void *)CONFIG_SYS_FSL_FM1_DTSEC1_ADDR; + int i; + struct fsl_pq_mdio_info dtsec_mdio_info; + struct tgec_mdio_info tgec_mdio_info; + + u8 lane_to_slot[] = { + SLOT1, /* 0 - Bank 1:A */ + SLOT1, /* 1 - Bank 1:B */ + SLOT2, /* 2 - Bank 1:C */ + SLOT2, /* 3 - Bank 1:D */ + SLOT3, /* 4 - Bank 1:E */ + SLOT3, /* 5 - Bank 1:F */ + SLOT3, /* 6 - Bank 1:G */ + SLOT3, /* 7 - Bank 1:H */ + SLOT6, /* 8 - Bank 1:I */ + SLOT6, /* 9 - Bank 1:J */ + SLOT4, /* 10 - Bank 2:A */ + SLOT4, /* 11 - Bank 2:B */ + SLOT4, /* 12 - Bank 2:C */ + SLOT4, /* 13 - Bank 2:D */ + SLOT5, /* 14 - Bank 3:A */ + SLOT5, /* 15 - Bank 3:B */ + SLOT5, /* 16 - Bank 3:C */ + SLOT5, /* 17 - Bank 3:D */ + }; + + /* + * 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; + + /* The first 4 GPIOs are outputs to control MDIO bus muxing */ + out_be32(&pgpio->gpdir, EMI_MASK); + + 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); + + tgec_mdio_info.regs = + (struct tgec_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR; + tgec_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME; + + /* Register the 10G MDIO bus */ + fm_tgec_mdio_init(bis, &tgec_mdio_info); + + /* Register the 6 muxing front-ends to the MDIO buses */ + p4080ds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII); + p4080ds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT3); + p4080ds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT4); + p4080ds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT5); + p4080ds_mdio_init(DEFAULT_FM_TGEC_MDIO_NAME, EMI2_SLOT4); + p4080ds_mdio_init(DEFAULT_FM_TGEC_MDIO_NAME, EMI2_SLOT5); + + fm_info_set_phy_address(FM1_DTSEC1, CONFIG_SYS_FM1_DTSEC1_PHY_ADDR); + fm_info_set_phy_address(FM1_DTSEC2, CONFIG_SYS_FM1_DTSEC2_PHY_ADDR); + fm_info_set_phy_address(FM1_DTSEC3, CONFIG_SYS_FM1_DTSEC3_PHY_ADDR); + fm_info_set_phy_address(FM1_DTSEC4, CONFIG_SYS_FM1_DTSEC4_PHY_ADDR); + fm_info_set_phy_address(FM1_10GEC1, CONFIG_SYS_FM1_10GEC1_PHY_ADDR); + +#if (CONFIG_SYS_NUM_FMAN == 2) + fm_info_set_phy_address(FM2_DTSEC1, CONFIG_SYS_FM2_DTSEC1_PHY_ADDR); + fm_info_set_phy_address(FM2_DTSEC2, CONFIG_SYS_FM2_DTSEC2_PHY_ADDR); + fm_info_set_phy_address(FM2_DTSEC3, CONFIG_SYS_FM2_DTSEC3_PHY_ADDR); + fm_info_set_phy_address(FM2_DTSEC4, CONFIG_SYS_FM2_DTSEC4_PHY_ADDR); + fm_info_set_phy_address(FM2_10GEC1, CONFIG_SYS_FM2_10GEC1_PHY_ADDR); +#endif + + 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]; + switch (slot) { + case SLOT3: + mdio_mux[i] = EMI1_SLOT3; + fm_info_set_mdio(i, + mii_dev_for_muxval(mdio_mux[i])); + break; + case SLOT4: + mdio_mux[i] = EMI1_SLOT4; + fm_info_set_mdio(i, + mii_dev_for_muxval(mdio_mux[i])); + break; + case SLOT5: + mdio_mux[i] = EMI1_SLOT5; + fm_info_set_mdio(i, + mii_dev_for_muxval(mdio_mux[i])); + break; + }; + break; + case PHY_INTERFACE_MODE_RGMII: + fm_info_set_phy_address(i, 0); + mdio_mux[i] = EMI1_RGMII; + fm_info_set_mdio(i, + mii_dev_for_muxval(mdio_mux[i])); + break; + default: + break; + } + } + + for (i = FM1_10GEC1; i < FM1_10GEC1 + CONFIG_SYS_NUM_FM1_10GEC; i++) { + int idx = i - FM1_10GEC1, lane, slot; + switch (fm_info_get_enet_if(i)) { + case PHY_INTERFACE_MODE_XGMII: + lane = serdes_get_first_lane(XAUI_FM1 + idx); + if (lane < 0) + break; + slot = lane_to_slot[lane]; + switch (slot) { + case SLOT4: + mdio_mux[i] = EMI2_SLOT4; + fm_info_set_mdio(i, + mii_dev_for_muxval(mdio_mux[i])); + break; + case SLOT5: + mdio_mux[i] = EMI2_SLOT5; + fm_info_set_mdio(i, + mii_dev_for_muxval(mdio_mux[i])); + break; + }; + 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]; + switch (slot) { + case SLOT3: + mdio_mux[i] = EMI1_SLOT3; + fm_info_set_mdio(i, + mii_dev_for_muxval(mdio_mux[i])); + break; + case SLOT4: + mdio_mux[i] = EMI1_SLOT4; + fm_info_set_mdio(i, + mii_dev_for_muxval(mdio_mux[i])); + break; + case SLOT5: + mdio_mux[i] = EMI1_SLOT5; + fm_info_set_mdio(i, + mii_dev_for_muxval(mdio_mux[i])); + break; + }; + break; + case PHY_INTERFACE_MODE_RGMII: + fm_info_set_phy_address(i, 0); + mdio_mux[i] = EMI1_RGMII; + fm_info_set_mdio(i, + mii_dev_for_muxval(mdio_mux[i])); + break; + default: + break; + } + } + + for (i = FM2_10GEC1; i < FM2_10GEC1 + CONFIG_SYS_NUM_FM2_10GEC; i++) { + int idx = i - FM2_10GEC1, lane, slot; + switch (fm_info_get_enet_if(i)) { + case PHY_INTERFACE_MODE_XGMII: + lane = serdes_get_first_lane(XAUI_FM2 + idx); + if (lane < 0) + break; + slot = lane_to_slot[lane]; + switch (slot) { + case SLOT4: + mdio_mux[i] = EMI2_SLOT4; + fm_info_set_mdio(i, + mii_dev_for_muxval(mdio_mux[i])); + break; + case SLOT5: + mdio_mux[i] = EMI2_SLOT5; + fm_info_set_mdio(i, + mii_dev_for_muxval(mdio_mux[i])); + break; + }; + break; + default: + break; + } + } +#endif + + cpu_eth_init(bis); +#endif /* CONFIG_FMAN_ENET */ + + return pci_eth_init(bis); +} diff --git a/board/freescale/mpc8349emds/Makefile b/board/freescale/mpc8349emds/Makefile index 4f76eab..601c3bf 100644 --- a/board/freescale/mpc8349emds/Makefile +++ b/board/freescale/mpc8349emds/Makefile @@ -27,6 +27,7 @@ LIB = $(obj)lib$(BOARD).o COBJS-y += $(BOARD).o COBJS-$(CONFIG_PCI) += pci.o +COBJS-$(CONFIG_FSL_DDR2) += ddr.o COBJS := $(COBJS-y) SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) diff --git a/board/freescale/mpc8349emds/ddr.c b/board/freescale/mpc8349emds/ddr.c new file mode 100644 index 0000000..0209c1e --- /dev/null +++ b/board/freescale/mpc8349emds/ddr.c @@ -0,0 +1,107 @@ +/* + * 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 <asm/fsl_ddr_sdram.h> +#include <asm/fsl_ddr_dimm_params.h> + +struct board_specific_parameters { + u32 datarate_mhz_low; + u32 datarate_mhz_high; + u32 n_ranks; + u32 clk_adjust; + u32 cpo; + u32 write_data_delay; + u32 force_2T; +}; + +const struct board_specific_parameters board_specific_parameters_udimm[][20] = { + { + /* + * memory controller 0 + * lo| hi| num| clk| cpo|wrdata|2T + * mhz| mhz|ranks|adjst| | delay| + */ + { 0, 300, 2, 4, 4, 2, 0}, + {301, 365, 2, 4, 6, 2, 0}, + {366, 450, 2, 4, 7, 2, 0}, + {451, 850, 2, 4, 31, 2, 0}, + { 0, 300, 1, 4, 4, 2, 0}, + {301, 365, 1, 4, 6, 2, 0}, + {366, 450, 1, 4, 7, 2, 0}, + {451, 850, 1, 4, 31, 2, 0} + } +}; + +void fsl_ddr_board_options(memctl_options_t *popts, + dimm_params_t *pdimm, + unsigned int ctrl_num) +{ + const struct board_specific_parameters *pbsp; + u32 num_params; + u32 i, dimm_num; + ulong ddr_freq; + + if (ctrl_num != 0) /* we have only one controller */ + return; + for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) { + if (pdimm[i].n_ranks) + break; + } + if (i >= CONFIG_DIMM_SLOTS_PER_CTLR) /* no DIMM */ + return; + + dimm_num = i; + pbsp = &(board_specific_parameters_udimm[ctrl_num][0]); + num_params = sizeof(board_specific_parameters_udimm[ctrl_num]) / + sizeof(board_specific_parameters_udimm[0][0]); + + /* 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; + for (i = 0; i < num_params; i++) { + if (ddr_freq >= pbsp->datarate_mhz_low && + ddr_freq <= pbsp->datarate_mhz_high && + pdimm[dimm_num].n_ranks == pbsp->n_ranks) { + popts->clk_adjust = pbsp->clk_adjust; + popts->cpo_override = pbsp->cpo; + popts->write_data_delay = pbsp->write_data_delay; + popts->twoT_en = pbsp->force_2T; + break; + } + pbsp++; + } + + if (i == num_params) { + printf("Warning: board specific timing not found " + "for data rate %lu MT/s!\n", ddr_freq); + } + + /* + * Factors to consider for half-strength driver enable: + * - number of DIMMs installed + */ + popts->half_strength_driver_enable = 0; + popts->DQS_config = 0; /* only true DQS signal is used on board */ +} diff --git a/board/freescale/mpc8349emds/mpc8349emds.c b/board/freescale/mpc8349emds/mpc8349emds.c index 365ac37..620540f 100644 --- a/board/freescale/mpc8349emds/mpc8349emds.c +++ b/board/freescale/mpc8349emds/mpc8349emds.c @@ -29,7 +29,11 @@ #include <i2c.h> #include <spi.h> #include <miiphy.h> +#ifdef CONFIG_FSL_DDR2 +#include <asm/fsl_ddr_sdram.h> +#else #include <spd_sdram.h> +#endif #if defined(CONFIG_OF_LIBFDT) #include <libfdt.h> @@ -62,7 +66,7 @@ int board_early_init_f (void) phys_size_t initdram (int board_type) { volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR; - u32 msize = 0; + phys_size_t msize = 0; if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32)im) return -1; @@ -70,24 +74,24 @@ phys_size_t initdram (int board_type) /* DDR SDRAM - Main SODIMM */ im->sysconf.ddrlaw[0].bar = CONFIG_SYS_DDR_BASE & LAWBAR_BAR; #if defined(CONFIG_SPD_EEPROM) - msize = spd_sdram(); +#ifndef CONFIG_FSL_DDR2 + msize = spd_sdram() * 1024 * 1024; +#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) + ddr_enable_ecc(msize); +#endif +#else + msize = fsl_ddr_sdram(); +#endif #else - msize = fixed_sdram(); + msize = fixed_sdram() * 1024 * 1024; #endif /* * Initialize SDRAM if it is on local bus. */ sdram_init(); -#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) - /* - * Initialize and enable DDR ECC. - */ - ddr_enable_ecc(msize * 1024 * 1024); -#endif - /* return total bus SDRAM size(bytes) -- DDR */ - return (msize * 1024 * 1024); + return msize; } #if !defined(CONFIG_SPD_EEPROM) diff --git a/board/freescale/mpc8541cds/mpc8541cds.c b/board/freescale/mpc8541cds/mpc8541cds.c index 0d3752d..d127137 100644 --- a/board/freescale/mpc8541cds/mpc8541cds.c +++ b/board/freescale/mpc8541cds/mpc8541cds.c @@ -1,5 +1,5 @@ /* - * Copyright 2004 Freescale Semiconductor. + * Copyright 2004, 2011 Freescale Semiconductor. * * (C) Copyright 2002 Scott McNutt <smcnutt@artesyncp.com> * @@ -200,6 +200,7 @@ const iop_conf_t iop_conf_tab[4][32] = { int checkboard (void) { volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + char buf[32]; /* PCI slot in USER bits CSR[6:7] by convention. */ uint pci_slot = get_pci_slot (); @@ -222,8 +223,7 @@ int checkboard (void) printf("PCI1: %d bit, %s MHz, %s\n", (pci1_32) ? 32 : 64, - (pci1_speed == 33000000) ? "33" : - (pci1_speed == 66000000) ? "66" : "unknown", + strmhz(buf, pci1_speed), pci1_clk_sel ? "sync" : "async"); if (pci_dual) { diff --git a/board/freescale/mpc8548cds/mpc8548cds.c b/board/freescale/mpc8548cds/mpc8548cds.c index 5ffae47..3bcaac4 100644 --- a/board/freescale/mpc8548cds/mpc8548cds.c +++ b/board/freescale/mpc8548cds/mpc8548cds.c @@ -30,7 +30,6 @@ #include <asm/fsl_pci.h> #include <asm/fsl_ddr_sdram.h> #include <asm/fsl_serdes.h> -#include <spd_sdram.h> #include <miiphy.h> #include <libfdt.h> #include <fdt_support.h> @@ -39,8 +38,6 @@ #include "../common/eeprom.h" #include "../common/via.h" -DECLARE_GLOBAL_DATA_PTR; - void local_bus_init(void); int checkboard (void) @@ -123,7 +120,7 @@ void lbc_sdram_init(void) puts("LBC SDRAM: "); print_size(CONFIG_SYS_LBC_SDRAM_SIZE * 1024 * 1024, - "\n "); + "\n"); /* * Setup SDRAM Base and Option Registers @@ -210,10 +207,6 @@ static struct pci_config_table pci_mpc85xxcds_config_table[] = { static struct pci_controller pci1_hose; #endif /* CONFIG_PCI */ -#ifdef CONFIG_PCI2 -static struct pci_controller pci2_hose; -#endif /* CONFIG_PCI2 */ - void pci_init_board(void) { volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); @@ -221,6 +214,7 @@ void pci_init_board(void) u32 devdisr, pordevsr, io_sel; u32 porpllsr, pci_agent, pci_speed, pci_32, pci_arb, pci_clk_sel; int first_free_busno = 0; + char buf[32]; devdisr = in_be32(&gur->devdisr); pordevsr = in_be32(&gur->pordevsr); @@ -243,10 +237,9 @@ void pci_init_board(void) law_size_bits(pci_info.io_size), pci_info.law); pci_agent = fsl_setup_hose(&pci1_hose, pci_info.regs); - printf("PCI: %d bit, %s MHz, %s, %s, %s (base address %lx)\n", + printf("PCI1: %d bit, %s MHz, %s, %s, %s (base address %lx)\n", (pci_32) ? 32 : 64, - (pci_speed == 33333000) ? "33" : - (pci_speed == 66666000) ? "66" : "unknown", + strmhz(buf, pci_speed), pci_clk_sel ? "sync" : "async", pci_agent ? "agent" : "host", pci_arb ? "arbiter" : "external-arbiter", @@ -268,7 +261,7 @@ void pci_init_board(void) } #endif } else { - printf("PCI: disabled\n"); + printf("PCI1: disabled\n"); } puts("\n"); diff --git a/board/freescale/mpc8555cds/mpc8555cds.c b/board/freescale/mpc8555cds/mpc8555cds.c index 60d1758..48ede98 100644 --- a/board/freescale/mpc8555cds/mpc8555cds.c +++ b/board/freescale/mpc8555cds/mpc8555cds.c @@ -1,5 +1,5 @@ /* - * Copyright 2004 Freescale Semiconductor. + * Copyright 2004, 2011 Freescale Semiconductor. * * See file CREDITS for list of people who contributed to this * project. @@ -198,6 +198,7 @@ const iop_conf_t iop_conf_tab[4][32] = { int checkboard (void) { volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + char buf[32]; /* PCI slot in USER bits CSR[6:7] by convention. */ uint pci_slot = get_pci_slot (); @@ -220,8 +221,7 @@ int checkboard (void) printf("PCI1: %d bit, %s MHz, %s\n", (pci1_32) ? 32 : 64, - (pci1_speed == 33000000) ? "33" : - (pci1_speed == 66000000) ? "66" : "unknown", + strmhz(buf, pci1_speed), pci1_clk_sel ? "sync" : "async"); if (pci_dual) { diff --git a/board/freescale/p1010rdb/Makefile b/board/freescale/p1010rdb/Makefile new file mode 100644 index 0000000..1dcd490 --- /dev/null +++ b/board/freescale/p1010rdb/Makefile @@ -0,0 +1,52 @@ +# +# Copyright 2010-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 $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).o + +COBJS-y += $(BOARD).o +COBJS-y += ddr.o +COBJS-y += law.o +COBJS-y += tlb.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/p1010rdb/ddr.c b/board/freescale/p1010rdb/ddr.c new file mode 100644 index 0000000..e5d8423 --- /dev/null +++ b/board/freescale/p1010rdb/ddr.c @@ -0,0 +1,250 @@ +/* + * Copyright 2010-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 <asm/mmu.h> +#include <asm/immap_85xx.h> +#include <asm/processor.h> +#include <asm/fsl_ddr_sdram.h> +#include <asm/fsl_ddr_dimm_params.h> +#include <asm/io.h> +#include <asm/fsl_law.h> + +DECLARE_GLOBAL_DATA_PTR; + +#ifndef CONFIG_DDR_RAW_TIMING +#define CONFIG_SYS_DRAM_SIZE 1024 + +fsl_ddr_cfg_regs_t ddr_cfg_regs_800 = { + .cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS, + .cs[0].config = CONFIG_SYS_DDR_CS0_CONFIG, + .cs[0].config_2 = CONFIG_SYS_DDR_CS0_CONFIG_2, + .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_CONTROL, + .ddr_sdram_cfg_2 = CONFIG_SYS_DDR_CONTROL_2, + .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_CONTROL, + .ddr_wrlvl_cntl = CONFIG_SYS_DDR_WRLVL_CONTROL_800, + .ddr_sr_cntr = CONFIG_SYS_DDR_SR_CNTR, + .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_667 = { + .cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS, + .cs[0].config = CONFIG_SYS_DDR_CS0_CONFIG, + .cs[0].config_2 = CONFIG_SYS_DDR_CS0_CONFIG_2, + .timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3_667, + .timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0_667, + .timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1_667, + .timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2_667, + .ddr_sdram_cfg = CONFIG_SYS_DDR_CONTROL, + .ddr_sdram_cfg_2 = CONFIG_SYS_DDR_CONTROL_2, + .ddr_sdram_mode = CONFIG_SYS_DDR_MODE_1_667, + .ddr_sdram_mode_2 = CONFIG_SYS_DDR_MODE_2_667, + .ddr_sdram_md_cntl = CONFIG_SYS_DDR_MODE_CONTROL, + .ddr_sdram_interval = CONFIG_SYS_DDR_INTERVAL_667, + .ddr_data_init = CONFIG_MEM_INIT_VALUE, + .ddr_sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CTRL_667, + .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_CONTROL, + .ddr_wrlvl_cntl = CONFIG_SYS_DDR_WRLVL_CONTROL_667, + .ddr_sr_cntr = CONFIG_SYS_DDR_SR_CNTR, + .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}, + {607, 749, &ddr_cfg_regs_667}, + {0, 0, NULL} +}; + +unsigned long get_sdram_size(void) +{ + struct cpu_type *cpu; + phys_size_t ddr_size; + + cpu = gd->cpu; + /* P1014 and it's derivatives support max 16it DDR width */ + if (cpu->soc_ver == SVR_P1014 || cpu->soc_ver == SVR_P1014_E) + ddr_size = (CONFIG_SYS_DRAM_SIZE / 2); + else + ddr_size = CONFIG_SYS_DRAM_SIZE; + + return ddr_size; +} + +/* + * 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; + ulong ddr_freq, ddr_freq_mhz; + struct cpu_type *cpu; + +#if defined(CONFIG_SYS_RAMBOOT) + return CONFIG_SYS_SDRAM_SIZE * 1024 * 1024; +#endif + + 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)); + + cpu = gd->cpu; + /* P1014 and it's derivatives support max 16bit DDR width */ + if (cpu->soc_ver == SVR_P1014 || cpu->soc_ver == SVR_P1014_E) { + ddr_cfg_regs.ddr_sdram_cfg |= SDRAM_CFG_16_BE; + ddr_cfg_regs.cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS >> 1; + ddr_cfg_regs.ddr_sdram_cfg &= ~0x00180000; + ddr_cfg_regs.ddr_sdram_cfg |= 0x001080000; + } + + ddr_size = (phys_size_t) CONFIG_SYS_SDRAM_SIZE * 1024 * 1024; + fsl_ddr_set_memctl_regs(&ddr_cfg_regs, 0); + + if (set_ddr_laws(CONFIG_SYS_DDR_SDRAM_BASE, ddr_size, + LAW_TRGT_IF_DDR_1) < 0) { + printf("ERROR setting Local Access Windows for DDR\n"); + return 0; + } + + return ddr_size; +} + +#else /* CONFIG_DDR_RAW_TIMING */ +/* + * Samsung K4B2G0846C-HCF8 + * The following timing are for "downshift" + * i.e. to use CL9 part as CL7 + * otherwise, tAA, tRCD, tRP will be 13500ps + * and tRC will be 49500ps + */ +dimm_params_t ddr_raw_timing = { + .n_ranks = 1, + .rank_density = 1073741824u, + .capacity = 1073741824u, + .primary_sdram_width = 32, + .ec_sdram_width = 0, + .registered_dimm = 0, + .mirrored_dimm = 0, + .n_row_addr = 15, + .n_col_addr = 10, + .n_banks_per_sdram_device = 8, + .edc_config = 0, + .burst_lengths_bitmask = 0x0c, + + .tCKmin_X_ps = 1875, + .caslat_X = 0x1e << 4, /* 5,6,7,8 */ + .tAA_ps = 13125, + .tWR_ps = 15000, + .tRCD_ps = 13125, + .tRRD_ps = 7500, + .tRP_ps = 13125, + .tRAS_ps = 37500, + .tRC_ps = 50625, + .tRFC_ps = 160000, + .tWTR_ps = 7500, + .tRTP_ps = 7500, + .refresh_rate_ps = 7800000, + .tFAW_ps = 37500, +}; + +int fsl_ddr_get_dimm_params(dimm_params_t *pdimm, + unsigned int controller_number, + unsigned int dimm_number) +{ + const char dimm_model[] = "Fixed DDR on board"; + + if ((controller_number == 0) && (dimm_number == 0)) { + memcpy(pdimm, &ddr_raw_timing, sizeof(dimm_params_t)); + memset(pdimm->mpart, 0, sizeof(pdimm->mpart)); + memcpy(pdimm->mpart, dimm_model, sizeof(dimm_model) - 1); + } + + return 0; +} + +void fsl_ddr_board_options(memctl_options_t *popts, + dimm_params_t *pdimm, + unsigned int ctrl_num) +{ + struct cpu_type *cpu; + int i; + popts->clk_adjust = 6; + popts->cpo_override = 0x1f; + popts->write_data_delay = 2; + popts->half_strength_driver_enable = 1; + /* Write leveling override */ + popts->wrlvl_en = 1; + popts->wrlvl_override = 1; + popts->wrlvl_sample = 0xf; + popts->wrlvl_start = 0x8; + popts->trwt_override = 1; + popts->trwt = 0; + + cpu = gd->cpu; + /* P1014 and it's derivatives support max 16it DDR width */ + if (cpu->soc_ver == SVR_P1014 || cpu->soc_ver == SVR_P1014_E) + popts->data_bus_width = DDR_DATA_BUS_WIDTH_16; + + for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { + popts->cs_local_opts[i].odt_rd_cfg = FSL_DDR_ODT_NEVER; + popts->cs_local_opts[i].odt_wr_cfg = FSL_DDR_ODT_CS; + } +} + +#endif /* CONFIG_DDR_RAW_TIMING */ diff --git a/board/freescale/p1010rdb/law.c b/board/freescale/p1010rdb/law.c new file mode 100644 index 0000000..3ed77fc --- /dev/null +++ b/board/freescale/p1010rdb/law.c @@ -0,0 +1,35 @@ +/* + * Copyright 2010-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 <asm/fsl_law.h> +#include <asm/mmu.h> + +struct law_entry law_table[] = { +#ifndef CONFIG_SDCARD + SET_LAW(CONFIG_SYS_FLASH_BASE_PHYS, LAW_SIZE_32M, LAW_TRGT_IF_IFC), + SET_LAW(CONFIG_SYS_CPLD_BASE_PHYS, LAW_SIZE_128K, LAW_TRGT_IF_IFC), + SET_LAW(CONFIG_SYS_NAND_BASE_PHYS, LAW_SIZE_1M, LAW_TRGT_IF_IFC), +#endif +}; + +int num_law_entries = ARRAY_SIZE(law_table); diff --git a/board/freescale/p1010rdb/p1010rdb.c b/board/freescale/p1010rdb/p1010rdb.c new file mode 100644 index 0000000..03e9da1 --- /dev/null +++ b/board/freescale/p1010rdb/p1010rdb.c @@ -0,0 +1,330 @@ +/* + * Copyright 2010-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 <asm/processor.h> +#include <asm/mmu.h> +#include <asm/cache.h> +#include <asm/immap_85xx.h> +#include <asm/io.h> +#include <miiphy.h> +#include <libfdt.h> +#include <fdt_support.h> +#include <fsl_mdio.h> +#include <tsec.h> +#include <mmc.h> +#include <netdev.h> +#include <pci.h> +#include <asm/fsl_serdes.h> +#include <asm/fsl_ifc.h> +#include <asm/fsl_pci.h> + +#ifndef CONFIG_SDCARD +#include <hwconfig.h> +#endif + +DECLARE_GLOBAL_DATA_PTR; + +#define GPIO4_PCIE_RESET_SET 0x08000000 +#define MUX_CPLD_CAN_UART 0x00 +#define MUX_CPLD_TDM 0x01 +#define MUX_CPLD_SPICS0_FLASH 0x00 +#define MUX_CPLD_SPICS0_SLIC 0x02 + +#ifndef CONFIG_SDCARD +struct cpld_data { + u8 cpld_ver; /* cpld revision */ + u8 pcba_ver; /* pcb revision number */ + u8 twindie_ddr3; + u8 res1[6]; + u8 bank_sel; /* NOR Flash bank */ + u8 res2[5]; + u8 usb2_sel; + u8 res3[1]; + u8 porsw_sel; + u8 tdm_can_sel; + u8 spi_cs0_sel; /* SPI CS0 SLIC/SPI Flash */ + u8 por0; /* POR Options */ + u8 por1; /* POR Options */ + u8 por2; /* POR Options */ + u8 por3; /* POR Options */ +}; + +void cpld_show(void) +{ + struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE); + + printf("CPLD: V%x.%x PCBA: V%x.0\n", + in_8(&cpld_data->cpld_ver) & 0xF0, + in_8(&cpld_data->cpld_ver) & 0x0F, + in_8(&cpld_data->pcba_ver) & 0x0F); + +#ifdef CONFIG_DEBUG + printf("twindie_ddr =%x\n", + in_8(&cpld_data->twindie_ddr3)); + printf("bank_sel =%x\n", + in_8(&cpld_data->bank_sel)); + printf("usb2_sel =%x\n", + in_8(&cpld_data->usb2_sel)); + printf("porsw_sel =%x\n", + in_8(&cpld_data->porsw_sel)); + printf("tdm_can_sel =%x\n", + in_8(&cpld_data->tdm_can_sel)); + printf("tdm_can_sel =%x\n", + in_8(&cpld_data->tdm_can_sel)); + printf("spi_cs0_sel =%x\n", + in_8(&cpld_data->spi_cs0_sel)); + printf("bcsr0 =%x\n", + in_8(&cpld_data->bcsr0)); + printf("bcsr1 =%x\n", + in_8(&cpld_data->bcsr1)); + printf("bcsr2 =%x\n", + in_8(&cpld_data->bcsr2)); + printf("bcsr3 =%x\n", + in_8(&cpld_data->bcsr3)); +#endif +} +#endif + +int board_early_init_f(void) +{ + ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR); +#ifndef CONFIG_SDCARD + struct fsl_ifc *ifc = (void *)CONFIG_SYS_IFC_ADDR; + + /* Clock configuration to access CPLD using IFC(GPCM) */ + setbits_be32(&ifc->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT); +#endif + /* + * Reset PCIe slots via GPIO4 + */ + setbits_be32(&pgpio->gpdir, GPIO4_PCIE_RESET_SET); + setbits_be32(&pgpio->gpdat, GPIO4_PCIE_RESET_SET); + + return 0; +} + +int board_early_init_r(void) +{ +#ifndef CONFIG_SDCARD + const unsigned int flashbase = CONFIG_SYS_FLASH_BASE; + const u8 flash_esel = find_tlb_idx((void *)flashbase, 1); + + /* + * Remap Boot flash 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 */ + 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_16M, 1); + + set_tlb(1, flashbase + 0x1000000, + CONFIG_SYS_FLASH_BASE_PHYS + 0x1000000, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, flash_esel+1, BOOKE_PAGESZ_16M, 1); +#endif + return 0; +} + +#ifdef CONFIG_PCI +void pci_init_board(void) +{ + fsl_pcie_init_board(0); +} +#endif /* ifdef CONFIG_PCI */ + +int checkboard(void) +{ + struct cpu_type *cpu; + + cpu = gd->cpu; + printf("Board: %sRDB ", cpu->name); +#ifdef CONFIG_PHYS_64BIT + puts("(36-bit addrmap)"); +#endif + puts("\n"); + + return 0; +} + +#ifdef CONFIG_TSEC_ENET +int board_eth_init(bd_t *bis) +{ + struct fsl_pq_mdio_info mdio_info; + struct tsec_info_struct tsec_info[4]; + struct cpu_type *cpu; + int num = 0; + + cpu = gd->cpu; + +#ifdef CONFIG_TSEC1 + SET_STD_TSEC_INFO(tsec_info[num], 1); + num++; +#endif +#ifdef CONFIG_TSEC2 + SET_STD_TSEC_INFO(tsec_info[num], 2); + num++; +#endif +#ifdef CONFIG_TSEC3 + /* P1014 and it's derivatives do not support eTSEC3 */ + if (cpu->soc_ver != SVR_P1014 && cpu->soc_ver != SVR_P1014_E) { + SET_STD_TSEC_INFO(tsec_info[num], 3); + num++; + } +#endif + if (!num) { + printf("No TSECs initialized\n"); + return 0; + } + + mdio_info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR; + mdio_info.name = DEFAULT_MII_NAME; + + fsl_pq_mdio_init(bis, &mdio_info); + + tsec_eth_init(bis, tsec_info, num); + + return pci_eth_init(bis); +} +#endif + +#if defined(CONFIG_OF_BOARD_SETUP) +void fdt_del_flexcan(void *blob) +{ + int nodeoff = 0; + + while ((nodeoff = fdt_node_offset_by_compatible(blob, 0, + "fsl,flexcan-v1.0")) >= 0) { + fdt_del_node(blob, nodeoff); + } +} + +void fdt_del_spi_flash(void *blob) +{ + int nodeoff = 0; + + while ((nodeoff = fdt_node_offset_by_compatible(blob, 0, + "spansion,s25sl12801")) >= 0) { + fdt_del_node(blob, nodeoff); + } +} + +void fdt_del_spi_slic(void *blob) +{ + int nodeoff = 0; + + while ((nodeoff = fdt_node_offset_by_compatible(blob, 0, + "zarlink,le88266")) >= 0) { + fdt_del_node(blob, nodeoff); + } +} + +void fdt_del_tdm(void *blob) +{ + int nodeoff = 0; + + while ((nodeoff = fdt_node_offset_by_compatible(blob, 0, + "fsl,starlite-tdm")) >= 0) { + fdt_del_node(blob, nodeoff); + } +} + +void ft_board_setup(void *blob, bd_t *bd) +{ + phys_addr_t base; + phys_size_t size; + struct cpu_type *cpu; + + cpu = gd->cpu; + + ft_cpu_setup(blob, bd); + + base = getenv_bootm_low(); + size = getenv_bootm_size(); + +#if defined(CONFIG_PCI) + FT_FSL_PCI_SETUP; +#endif + + fdt_fixup_memory(blob, (u64)base, (u64)size); + + fdt_fixup_dr_usb(blob, bd); + + /* P1014 and it's derivatives don't support CAN and eTSEC3 */ + if (cpu->soc_ver == SVR_P1014 || cpu->soc_ver == SVR_P1014_E) { + fdt_del_flexcan(blob); + fdt_del_node_and_alias(blob, "ethernet2"); + } +#ifndef CONFIG_SDCARD + if (hwconfig_subarg_cmp("fsl_p1010mux", "tdm_can", "can")) { + printf("fdt CAN"); + fdt_del_tdm(blob); + fdt_del_spi_slic(blob); + } +#ifndef CONFIG_SPIFLASH + else if (hwconfig_subarg_cmp("fsl_p1010mux", "tdm_can", "tdm")) { + printf("fdt TDM"); + fdt_del_flexcan(blob); + fdt_del_spi_flash(blob); + } +#endif +#endif +} +#endif + +#ifndef CONFIG_SDCARD +int misc_init_r(void) +{ + struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE); + ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + + if (hwconfig_subarg_cmp("fsl_p1010mux", "tdm_can", "can")) { + clrbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_CAN1_TDM | + MPC85xx_PMUXCR_CAN1_UART | + MPC85xx_PMUXCR_CAN2_TDM | + MPC85xx_PMUXCR_CAN2_UART); + out_8(&cpld_data->tdm_can_sel, MUX_CPLD_CAN_UART); + } +#ifndef CONFIG_SPIFLASH + if (hwconfig_subarg_cmp("fsl_p1010mux", "tdm_can", "tdm")) { + printf("TDM"); + clrbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_CAN2_UART | + MPC85xx_PMUXCR_CAN1_UART); + setbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_CAN2_TDM | + MPC85xx_PMUXCR_CAN1_TDM); + clrbits_be32(&gur->pmuxcr2, MPC85xx_PMUXCR2_UART_GPIO); + setbits_be32(&gur->pmuxcr2, MPC85xx_PMUXCR2_UART_TDM); + out_8(&cpld_data->tdm_can_sel, MUX_CPLD_TDM); + out_8(&cpld_data->spi_cs0_sel, MUX_CPLD_SPICS0_SLIC); + } +#endif + return 0; +} +#endif diff --git a/board/freescale/p1010rdb/tlb.c b/board/freescale/p1010rdb/tlb.c new file mode 100644 index 0000000..4256bf4 --- /dev/null +++ b/board/freescale/p1010rdb/tlb.c @@ -0,0 +1,98 @@ +/* + * Copyright 2010-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 <asm/mmu.h> + +struct fsl_e_tlb_entry tlb_table[] = { + /* TLB 0 - for temp stack in cache */ + SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR, CONFIG_SYS_INIT_RAM_ADDR, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 4 * 1024 , + CONFIG_SYS_INIT_RAM_ADDR + 4 * 1024, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 8 * 1024 , + CONFIG_SYS_INIT_RAM_ADDR + 8 * 1024, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 12 * 1024 , + CONFIG_SYS_INIT_RAM_ADDR + 12 * 1024, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + + /* TLB 1 */ + /* *I*** - Covers boot page */ + SET_TLB_ENTRY(1, 0xfffff000, 0xfffff000, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 0, BOOKE_PAGESZ_4K, 1), + + /* *I*G* - CCSRBAR */ + SET_TLB_ENTRY(1, CONFIG_SYS_CCSRBAR, CONFIG_SYS_CCSRBAR_PHYS, + MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 1, BOOKE_PAGESZ_1M, 1), + +#ifndef CONFIG_NAND_SPL +#ifndef CONFIG_SDCARD + SET_TLB_ENTRY(1, CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE_PHYS, + MAS3_SX|MAS3_SR, MAS2_W|MAS2_G, + 0, 2, BOOKE_PAGESZ_16M, 1), + + SET_TLB_ENTRY(1, CONFIG_SYS_FLASH_BASE + 0x1000000, + CONFIG_SYS_FLASH_BASE_PHYS + 0x1000000, + MAS3_SX|MAS3_SR, MAS2_W|MAS2_G, + 0, 3, BOOKE_PAGESZ_16M, 1), +#endif + +#ifdef CONFIG_PCI + /* *I*G* - PCI */ + SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_MEM_VIRT, CONFIG_SYS_PCIE1_MEM_PHYS, + MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 4, BOOKE_PAGESZ_1G, 1), + + /* *I*G* - PCI I/O */ + SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_IO_VIRT, CONFIG_SYS_PCIE1_IO_PHYS, + MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 5, BOOKE_PAGESZ_256K, 1), +#endif +#endif + +#ifndef CONFIG_SDCARD + /* *I*G - Board CPLD */ + SET_TLB_ENTRY(1, CONFIG_SYS_CPLD_BASE, CONFIG_SYS_CPLD_BASE_PHYS, + MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 6, BOOKE_PAGESZ_256K, 1), + + SET_TLB_ENTRY(1, CONFIG_SYS_NAND_BASE, CONFIG_SYS_NAND_BASE_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 7, BOOKE_PAGESZ_1M, 1), +#endif + +#if defined(CONFIG_SYS_RAMBOOT) + SET_TLB_ENTRY(1, CONFIG_SYS_DDR_SDRAM_BASE, CONFIG_SYS_DDR_SDRAM_BASE, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 8, BOOKE_PAGESZ_1G, 1) +#endif +}; + +int num_tlb_entries = ARRAY_SIZE(tlb_table); diff --git a/board/freescale/p1023rds/p1023rds.c b/board/freescale/p1023rds/p1023rds.c index 8cfd199..546819c 100644 --- a/board/freescale/p1023rds/p1023rds.c +++ b/board/freescale/p1023rds/p1023rds.c @@ -38,6 +38,11 @@ #include <fdt_support.h> #include <netdev.h> #include <malloc.h> +#include <fm_eth.h> +#include <fsl_mdio.h> +#include <miiphy.h> +#include <phy.h> +#include <asm/fsl_dtsec.h> #include "bcsr.h" @@ -143,6 +148,39 @@ unsigned long get_board_ddr_clk(ulong dummy) int board_eth_init(bd_t *bis) { + u8 *bcsr = (u8 *)BCSR_ACCESS_REG_ADDR; + ccsr_gur_t *gur = (ccsr_gur_t *)CONFIG_SYS_MPC85xx_GUTS_ADDR; + struct fsl_pq_mdio_info dtsec_mdio_info; + + /* + * Need to set dTSEC 1 pin multiplexing to TSEC. The default setting + * is not correct. + */ + setbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_TSEC1_1); + + 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); + + fm_info_set_phy_address(FM1_DTSEC1, CONFIG_SYS_FM1_DTSEC1_PHY_ADDR); + fm_info_set_phy_address(FM1_DTSEC2, CONFIG_SYS_FM1_DTSEC2_PHY_ADDR); + + fm_info_set_mdio(FM1_DTSEC1, + miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME)); + fm_info_set_mdio(FM1_DTSEC2, + miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME)); + + /* Make SERDES connected to SGMII by cleaing bcsr19[7] */ + if (fm_info_get_enet_if(FM1_DTSEC1) == PHY_INTERFACE_MODE_SGMII) + clrbits_8(&bcsr[19], BCSR19_SGMII_SEL_L); + +#ifdef CONFIG_FMAN_ENET + cpu_eth_init(bis); +#endif + return pci_eth_init(bis); } @@ -158,5 +196,7 @@ void ft_board_setup(void *blob, bd_t *bd) size = getenv_bootm_size(); fdt_fixup_memory(blob, (u64)base, (u64)size); + + fdt_fixup_fman_ethernet(blob); } #endif diff --git a/board/freescale/p1_p2_rdb_pc/Makefile b/board/freescale/p1_p2_rdb_pc/Makefile new file mode 100644 index 0000000..8056af8 --- /dev/null +++ b/board/freescale/p1_p2_rdb_pc/Makefile @@ -0,0 +1,52 @@ +# +# Copyright 2010-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 $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).o + +COBJS-y += $(BOARD).o +COBJS-y += ddr.o +COBJS-y += law.o +COBJS-y += tlb.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/p1_p2_rdb_pc/ddr.c b/board/freescale/p1_p2_rdb_pc/ddr.c new file mode 100644 index 0000000..f0cbde7 --- /dev/null +++ b/board/freescale/p1_p2_rdb_pc/ddr.c @@ -0,0 +1,292 @@ +/* + * Copyright 2010-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/mmu.h> +#include <asm/immap_85xx.h> +#include <asm/processor.h> +#include <asm/fsl_ddr_sdram.h> +#include <asm/fsl_ddr_dimm_params.h> +#include <asm/io.h> +#include <asm/fsl_law.h> + +#ifdef CONFIG_DDR_RAW_TIMING +#if defined(CONFIG_P1020RDB_PROTO) || \ + defined(CONFIG_P1021RDB) || \ + defined(CONFIG_P1020UTM) +/* Micron MT41J256M8_187E */ +dimm_params_t ddr_raw_timing = { + .n_ranks = 1, + .rank_density = 1073741824u, + .capacity = 1073741824u, + .primary_sdram_width = 32, + .ec_sdram_width = 0, + .registered_dimm = 0, + .mirrored_dimm = 0, + .n_row_addr = 15, + .n_col_addr = 10, + .n_banks_per_sdram_device = 8, + .edc_config = 0, + .burst_lengths_bitmask = 0x0c, + + .tCKmin_X_ps = 1870, + .caslat_X = 0x1e << 4, /* 5,6,7,8 */ + .tAA_ps = 13125, + .tWR_ps = 15000, + .tRCD_ps = 13125, + .tRRD_ps = 7500, + .tRP_ps = 13125, + .tRAS_ps = 37500, + .tRC_ps = 50625, + .tRFC_ps = 160000, + .tWTR_ps = 7500, + .tRTP_ps = 7500, + .refresh_rate_ps = 7800000, + .tFAW_ps = 37500, +}; +#elif defined(CONFIG_P2020RDB) +/* Micron MT41J128M16_15E */ +dimm_params_t ddr_raw_timing = { + .n_ranks = 1, + .rank_density = 1073741824u, + .capacity = 1073741824u, + .primary_sdram_width = 64, + .ec_sdram_width = 0, + .registered_dimm = 0, + .mirrored_dimm = 0, + .n_row_addr = 14, + .n_col_addr = 10, + .n_banks_per_sdram_device = 8, + .edc_config = 0, + .burst_lengths_bitmask = 0x0c, + + .tCKmin_X_ps = 1500, + .caslat_X = 0x7e << 4, /* 5,6,7,8,9,10 */ + .tAA_ps = 13500, + .tWR_ps = 15000, + .tRCD_ps = 13500, + .tRRD_ps = 6000, + .tRP_ps = 13500, + .tRAS_ps = 36000, + .tRC_ps = 49500, + .tRFC_ps = 160000, + .tWTR_ps = 7500, + .tRTP_ps = 7500, + .refresh_rate_ps = 7800000, + .tFAW_ps = 30000, +}; +#elif defined(CONFIG_P1020MBG) +/* Micron MT41J512M8_187E */ +dimm_params_t ddr_raw_timing = { + .n_ranks = 2, + .rank_density = 1073741824u, + .capacity = 2147483648u, + .primary_sdram_width = 32, + .ec_sdram_width = 0, + .registered_dimm = 0, + .mirrored_dimm = 0, + .n_row_addr = 15, + .n_col_addr = 10, + .n_banks_per_sdram_device = 8, + .edc_config = 0, + .burst_lengths_bitmask = 0x0c, + + .tCKmin_X_ps = 1870, + .caslat_X = 0x1e << 4, /* 5,6,7,8 */ + .tAA_ps = 13125, + .tWR_ps = 15000, + .tRCD_ps = 13125, + .tRRD_ps = 7500, + .tRP_ps = 13125, + .tRAS_ps = 37500, + .tRC_ps = 50625, + .tRFC_ps = 160000, + .tWTR_ps = 7500, + .tRTP_ps = 7500, + .refresh_rate_ps = 7800000, + .tFAW_ps = 37500, +}; +#elif defined(CONFIG_P1020RDB) +/* + * Samsung K4B2G0846C-HCF8 + * The following timing are for "downshift" + * i.e. to use CL9 part as CL7 + * otherwise, tAA, tRCD, tRP will be 13500ps + * and tRC will be 49500ps + */ +dimm_params_t ddr_raw_timing = { + .n_ranks = 1, + .rank_density = 1073741824u, + .capacity = 1073741824u, + .primary_sdram_width = 32, + .ec_sdram_width = 0, + .registered_dimm = 0, + .mirrored_dimm = 0, + .n_row_addr = 15, + .n_col_addr = 10, + .n_banks_per_sdram_device = 8, + .edc_config = 0, + .burst_lengths_bitmask = 0x0c, + + .tCKmin_X_ps = 1875, + .caslat_X = 0x1e << 4, /* 5,6,7,8 */ + .tAA_ps = 13125, + .tWR_ps = 15000, + .tRCD_ps = 13125, + .tRRD_ps = 7500, + .tRP_ps = 13125, + .tRAS_ps = 37500, + .tRC_ps = 50625, + .tRFC_ps = 160000, + .tWTR_ps = 7500, + .tRTP_ps = 7500, + .refresh_rate_ps = 7800000, + .tFAW_ps = 37500, +}; +#elif defined(CONFIG_P1024RDB) || \ + defined(CONFIG_P1025RDB) +/* + * Samsung K4B2G0846C-HCH9 + * The following timing are for "downshift" + * i.e. to use CL9 part as CL7 + * otherwise, tAA, tRCD, tRP will be 13500ps + * and tRC will be 49500ps + */ +dimm_params_t ddr_raw_timing = { + .n_ranks = 1, + .rank_density = 1073741824u, + .capacity = 1073741824u, + .primary_sdram_width = 32, + .ec_sdram_width = 0, + .registered_dimm = 0, + .mirrored_dimm = 0, + .n_row_addr = 15, + .n_col_addr = 10, + .n_banks_per_sdram_device = 8, + .edc_config = 0, + .burst_lengths_bitmask = 0x0c, + + .tCKmin_X_ps = 1500, + .caslat_X = 0x3e << 4, /* 5,6,7,8,9 */ + .tAA_ps = 13125, + .tWR_ps = 15000, + .tRCD_ps = 13125, + .tRRD_ps = 6000, + .tRP_ps = 13125, + .tRAS_ps = 36000, + .tRC_ps = 49125, + .tRFC_ps = 160000, + .tWTR_ps = 7500, + .tRTP_ps = 7500, + .refresh_rate_ps = 7800000, + .tFAW_ps = 30000, +}; +#else +#error Missing raw timing data for this board +#endif + +int fsl_ddr_get_dimm_params(dimm_params_t *pdimm, + unsigned int controller_number, + unsigned int dimm_number) +{ + const char dimm_model[] = "Fixed DDR on board"; + + if ((controller_number == 0) && (dimm_number == 0)) { + memcpy(pdimm, &ddr_raw_timing, sizeof(dimm_params_t)); + memset(pdimm->mpart, 0, sizeof(pdimm->mpart)); + memcpy(pdimm->mpart, dimm_model, sizeof(dimm_model) - 1); + } + + return 0; +} +#endif /* CONFIG_DDR_RAW_TIMING */ + +/* Fixed sdram init -- doesn't use serial presence detect. */ +phys_size_t fixed_sdram(void) +{ + sys_info_t sysinfo; + char buf[32]; + size_t ddr_size; + fsl_ddr_cfg_regs_t ddr_cfg_regs = { + .cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS, + .cs[0].config = CONFIG_SYS_DDR_CS0_CONFIG, + .cs[0].config_2 = CONFIG_SYS_DDR_CS0_CONFIG_2, +#if CONFIG_CHIP_SELECTS_PER_CTRL > 1 + .cs[1].bnds = CONFIG_SYS_DDR_CS1_BNDS, + .cs[1].config = CONFIG_SYS_DDR_CS1_CONFIG, + .cs[1].config_2 = CONFIG_SYS_DDR_CS1_CONFIG_2, +#endif + .timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3, + .timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0, + .timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1, + .timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2, + .ddr_sdram_cfg = CONFIG_SYS_DDR_CONTROL, + .ddr_sdram_cfg_2 = CONFIG_SYS_DDR_CONTROL_2, + .ddr_sdram_mode = CONFIG_SYS_DDR_MODE_1, + .ddr_sdram_mode_2 = CONFIG_SYS_DDR_MODE_2, + .ddr_sdram_md_cntl = CONFIG_SYS_DDR_MODE_CONTROL, + .ddr_sdram_interval = CONFIG_SYS_DDR_INTERVAL, + .ddr_data_init = CONFIG_SYS_DDR_DATA_INIT, + .ddr_sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CTRL, + .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_CONTROL, + .ddr_wrlvl_cntl = CONFIG_SYS_DDR_WRLVL_CONTROL, + .ddr_sr_cntr = CONFIG_SYS_DDR_SR_CNTR, + .ddr_sdram_rcw_1 = CONFIG_SYS_DDR_RCW_1, + .ddr_sdram_rcw_2 = CONFIG_SYS_DDR_RCW_2 + }; + + get_sys_info(&sysinfo); + printf("Configuring DDR for %s MT/s data rate\n", + strmhz(buf, sysinfo.freqDDRBus)); + + ddr_size = CONFIG_SYS_SDRAM_SIZE * 1024 * 1024; + + fsl_ddr_set_memctl_regs(&ddr_cfg_regs, 0); + + if (set_ddr_laws(CONFIG_SYS_DDR_SDRAM_BASE, + ddr_size, LAW_TRGT_IF_DDR_1) < 0) { + printf("ERROR setting Local Access Windows for DDR\n"); + return 0; + }; + + return ddr_size; +} + +void fsl_ddr_board_options(memctl_options_t *popts, + dimm_params_t *pdimm, + unsigned int ctrl_num) +{ + int i; + popts->clk_adjust = 6; + popts->cpo_override = 0x1f; + popts->write_data_delay = 2; + popts->half_strength_driver_enable = 1; + /* Write leveling override */ + popts->wrlvl_en = 1; + popts->wrlvl_override = 1; + popts->wrlvl_sample = 0xf; + popts->wrlvl_start = 0x8; + popts->trwt_override = 1; + popts->trwt = 0; + + if (pdimm->primary_sdram_width == 64) + popts->data_bus_width = 0; + else if (pdimm->primary_sdram_width == 32) + popts->data_bus_width = 1; + else + printf("Error in DDR bus width configuration!\n"); + + for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { + popts->cs_local_opts[i].odt_rd_cfg = FSL_DDR_ODT_NEVER; + popts->cs_local_opts[i].odt_wr_cfg = FSL_DDR_ODT_CS; + } +} diff --git a/board/freescale/p2041rdb/law.c b/board/freescale/p1_p2_rdb_pc/law.c index 127a478..5ff6ea6 100644 --- a/board/freescale/p2041rdb/law.c +++ b/board/freescale/p1_p2_rdb_pc/law.c @@ -1,5 +1,5 @@ /* - * Copyright 2011 Freescale Semiconductor, Inc. + * Copyright 2010-2011 Freescale Semiconductor, Inc. * * See file CREDITS for list of people who contributed to this * project. @@ -25,12 +25,14 @@ #include <asm/mmu.h> struct law_entry law_table[] = { - SET_LAW(CONFIG_SYS_FLASH_BASE_PHYS, LAW_SIZE_256M, LAW_TRGT_IF_LBC), - SET_LAW(CONFIG_SYS_BMAN_MEM_PHYS, LAW_SIZE_2M, LAW_TRGT_IF_BMAN), - SET_LAW(CONFIG_SYS_QMAN_MEM_PHYS, LAW_SIZE_2M, LAW_TRGT_IF_QMAN), - SET_LAW(CPLD_BASE_PHYS, LAW_SIZE_4K, LAW_TRGT_IF_LBC), -#ifdef CONFIG_SYS_DCSRBAR_PHYS - SET_LAW(CONFIG_SYS_DCSRBAR_PHYS, LAW_SIZE_32M, LAW_TRGT_IF_DCSR), + SET_LAW(CONFIG_SYS_FLASH_BASE_PHYS, LAW_SIZE_64M, LAW_TRGT_IF_LBC), + SET_LAW(CONFIG_SYS_CPLD_BASE_PHYS, LAW_SIZE_1M, LAW_TRGT_IF_LBC), + SET_LAW(CONFIG_SYS_PMC_BASE_PHYS, LAW_SIZE_64K, LAW_TRGT_IF_LBC), +#ifdef CONFIG_SYS_NAND_BASE_PHYS + SET_LAW(CONFIG_SYS_NAND_BASE_PHYS, LAW_SIZE_1M, LAW_TRGT_IF_LBC), +#endif +#ifdef CONFIG_VSC7385_ENET + SET_LAW(CONFIG_SYS_VSC7385_BASE_PHYS, LAW_SIZE_1M, LAW_TRGT_IF_LBC), #endif }; diff --git a/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c b/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c new file mode 100644 index 0000000..4671128 --- /dev/null +++ b/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c @@ -0,0 +1,449 @@ +/* + * Copyright 2010-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 <hwconfig.h> +#include <pci.h> +#include <i2c.h> +#include <asm/processor.h> +#include <asm/mmu.h> +#include <asm/cache.h> +#include <asm/immap_85xx.h> +#include <asm/fsl_pci.h> +#include <asm/fsl_ddr_sdram.h> +#include <asm/io.h> +#include <asm/fsl_law.h> +#include <asm/fsl_lbc.h> +#include <asm/mp.h> +#include <miiphy.h> +#include <libfdt.h> +#include <fdt_support.h> +#include <fsl_mdio.h> +#include <tsec.h> +#include <vsc7385.h> +#include <ioports.h> +#include <asm/fsl_serdes.h> +#include <netdev.h> + +#ifdef CONFIG_QE + +#define GPIO_GETH_SW_PORT 1 +#define GPIO_GETH_SW_PIN 29 +#define GPIO_GETH_SW_DATA (1 << (31 - GPIO_GETH_SW_PIN)) + +#define GPIO_SLIC_PORT 1 +#define GPIO_SLIC_PIN 30 +#define GPIO_SLIC_DATA (1 << (31 - GPIO_SLIC_PIN)) + + +#if defined(CONFIG_P1025RDB) || defined(CONFIG_P1021RDB) +#define PCA_IOPORT_I2C_ADDR 0x23 +#define PCA_IOPORT_OUTPUT_CMD 0x2 +#define PCA_IOPORT_CFG_CMD 0x6 +#define PCA_IOPORT_QE_PIN_ENABLE 0xf8 +#define PCA_IOPORT_QE_TDM_ENABLE 0xf6 +#endif + +const qe_iop_conf_t qe_iop_conf_tab[] = { + /* GPIO */ + {1, 1, 2, 0, 0}, /* GPIO7/PB1 - LOAD_DEFAULT_N */ +#if 0 + {1, 8, 1, 1, 0}, /* GPIO10/PB8 - DDR_RST */ +#endif + {0, 15, 1, 0, 0}, /* GPIO11/A15 - WDI */ + {GPIO_GETH_SW_PORT, GPIO_GETH_SW_PIN, 1, 0, 0}, /* RST_GETH_SW_N */ + {GPIO_SLIC_PORT, GPIO_SLIC_PIN, 1, 0, 0}, /* RST_SLIC_N */ + +#ifdef CONFIG_P1025RDB + /* QE_MUX_MDC */ + {1, 19, 1, 0, 1}, /* QE_MUX_MDC */ + + /* QE_MUX_MDIO */ + {1, 20, 3, 0, 1}, /* QE_MUX_MDIO */ + + /* UCC_1_MII */ + {0, 23, 2, 0, 2}, /* CLK12 */ + {0, 24, 2, 0, 1}, /* CLK9 */ + {0, 7, 1, 0, 2}, /* ENET1_TXD0_SER1_TXD0 */ + {0, 9, 1, 0, 2}, /* ENET1_TXD1_SER1_TXD1 */ + {0, 11, 1, 0, 2}, /* ENET1_TXD2_SER1_TXD2 */ + {0, 12, 1, 0, 2}, /* ENET1_TXD3_SER1_TXD3 */ + {0, 6, 2, 0, 2}, /* ENET1_RXD0_SER1_RXD0 */ + {0, 10, 2, 0, 2}, /* ENET1_RXD1_SER1_RXD1 */ + {0, 14, 2, 0, 2}, /* ENET1_RXD2_SER1_RXD2 */ + {0, 15, 2, 0, 2}, /* ENET1_RXD3_SER1_RXD3 */ + {0, 5, 1, 0, 2}, /* ENET1_TX_EN_SER1_RTS_B */ + {0, 13, 1, 0, 2}, /* ENET1_TX_ER */ + {0, 4, 2, 0, 2}, /* ENET1_RX_DV_SER1_CTS_B */ + {0, 8, 2, 0, 2}, /* ENET1_RX_ER_SER1_CD_B */ + {0, 17, 2, 0, 2}, /* ENET1_CRS */ + {0, 16, 2, 0, 2}, /* ENET1_COL */ + + /* UCC_5_RMII */ + {1, 11, 2, 0, 1}, /* CLK13 */ + {1, 7, 1, 0, 2}, /* ENET5_TXD0_SER5_TXD0 */ + {1, 10, 1, 0, 2}, /* ENET5_TXD1_SER5_TXD1 */ + {1, 6, 2, 0, 2}, /* ENET5_RXD0_SER5_RXD0 */ + {1, 9, 2, 0, 2}, /* ENET5_RXD1_SER5_RXD1 */ + {1, 5, 1, 0, 2}, /* ENET5_TX_EN_SER5_RTS_B */ + {1, 4, 2, 0, 2}, /* ENET5_RX_DV_SER5_CTS_B */ + {1, 8, 2, 0, 2}, /* ENET5_RX_ER_SER5_CD_B */ +#endif + + {0, 0, 0, 0, QE_IOP_TAB_END} /* END of table */ +}; +#endif + +struct cpld_data { + u8 cpld_rev_major; + u8 pcba_rev; + u8 wd_cfg; + u8 rst_bps_sw; + u8 load_default_n; + u8 rst_bps_wd; + u8 bypass_enable; + u8 bps_led; + u8 status_led; /* offset: 0x8 */ + u8 fxo_led; /* offset: 0x9 */ + u8 fxs_led; /* offset: 0xa */ + u8 rev4[2]; + u8 system_rst; /* offset: 0xd */ + u8 bps_out; + u8 rev5[3]; + u8 cpld_rev_minor; +}; + +#define CPLD_WD_CFG 0x03 +#define CPLD_RST_BSW 0x00 +#define CPLD_RST_BWD 0x00 +#define CPLD_BYPASS_EN 0x03 +#define CPLD_STATUS_LED 0x01 +#define CPLD_FXO_LED 0x01 +#define CPLD_FXS_LED 0x0F +#define CPLD_SYS_RST 0x00 + +void board_cpld_init(void) +{ + struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE); + + out_8(&cpld_data->wd_cfg, CPLD_WD_CFG); + out_8(&cpld_data->status_led, CPLD_STATUS_LED); + out_8(&cpld_data->fxo_led, CPLD_FXO_LED); + out_8(&cpld_data->fxs_led, CPLD_FXS_LED); + out_8(&cpld_data->system_rst, CPLD_SYS_RST); +} + +void board_gpio_init(void) +{ +#ifdef CONFIG_QE + ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + par_io_t *par_io = (par_io_t *) &(gur->qe_par_io); + + /* Enable VSC7385 switch */ + setbits_be32(&par_io[GPIO_GETH_SW_PORT].cpdat, GPIO_GETH_SW_DATA); + + /* Enable SLIC */ + setbits_be32(&par_io[GPIO_SLIC_PORT].cpdat, GPIO_SLIC_DATA); +#else + + ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR); + + /* + * GPIO10 DDR Reset, open drain + * GPIO7 LOAD_DEFAULT_N Input + * GPIO11 WDI (watchdog input) + * GPIO12 Ethernet Switch Reset + * GPIO13 SLIC Reset + */ + + setbits_be32(&pgpio->gpdir, 0x02130000); +#ifndef CONFIG_SYS_RAMBOOT + /* init DDR3 reset signal */ + setbits_be32(&pgpio->gpdir, 0x00200000); + setbits_be32(&pgpio->gpodr, 0x00200000); + clrbits_be32(&pgpio->gpdat, 0x00200000); + udelay(1000); + setbits_be32(&pgpio->gpdat, 0x00200000); + udelay(1000); + clrbits_be32(&pgpio->gpdir, 0x00200000); +#endif + +#ifdef CONFIG_VSC7385_ENET + /* reset VSC7385 Switch */ + setbits_be32(&pgpio->gpdir, 0x00080000); + setbits_be32(&pgpio->gpdat, 0x00080000); +#endif + +#ifdef CONFIG_SLIC + /* reset SLIC */ + setbits_be32(&pgpio->gpdir, 0x00040000); + setbits_be32(&pgpio->gpdat, 0x00040000); +#endif +#endif +} + +int board_early_init_f(void) +{ + ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + + setbits_be32(&gur->pmuxcr, + (MPC85xx_PMUXCR_SDHC_CD | MPC85xx_PMUXCR_SDHC_WP)); + clrbits_be32(&gur->sdhcdcr, SDHCDCR_CD_INV); + + clrbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_SD_DATA); + setbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_TDM_ENA); + + board_gpio_init(); + board_cpld_init(); + + return 0; +} + +int checkboard(void) +{ + struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE); + ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + u8 in, out, io_config, val; + + printf("Board: %s ", CONFIG_BOARDNAME); + +#ifdef CONFIG_PHYS_64BIT + puts("(36-bit addrmap) "); +#endif + + printf("CPLD: V%d.%d PCBA: V%d.0\n", + in_8(&cpld_data->cpld_rev_major) & 0x0F, + in_8(&cpld_data->cpld_rev_minor) & 0x0F, + in_8(&cpld_data->pcba_rev) & 0x0F); + + /* Initialize i2c early for rom_loc and flash bank information */ + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); + + if (i2c_read(CONFIG_SYS_I2C_PCA9557_ADDR, 0, 1, &in, 1) < 0 || + i2c_read(CONFIG_SYS_I2C_PCA9557_ADDR, 1, 1, &out, 1) < 0 || + i2c_read(CONFIG_SYS_I2C_PCA9557_ADDR, 3, 1, &io_config, 1) < 0) { + printf("Error reading i2c boot information!\n"); + return 0; /* Don't want to hang() on this error */ + } + + val = (in & io_config) | (out & (~io_config)); + + puts("rom_loc: "); + if ((val & (~__SW_BOOT_MASK)) == __SW_BOOT_SD) { + puts("sd"); +#ifdef __SW_BOOT_SPI + } else if ((val & (~__SW_BOOT_MASK)) == __SW_BOOT_SPI) { + puts("spi"); +#endif +#ifdef __SW_BOOT_NAND + } else if ((val & (~__SW_BOOT_MASK)) == __SW_BOOT_NAND) { + puts("nand"); +#endif +#ifdef __SW_BOOT_PCIE + } else if ((val & (~__SW_BOOT_MASK)) == __SW_BOOT_PCIE) { + puts("pcie"); +#endif + } else { + if (val & 0x2) + puts("nor lower bank"); + else + puts("nor upper bank"); + } + puts("\n"); + + if (val & 0x1) { + setbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_SD_DATA); + puts("SD/MMC : 8-bit Mode\n"); + puts("eSPI : Disabled\n"); + } else { + puts("SD/MMC : 4-bit Mode\n"); + puts("eSPI : Enabled\n"); + } + + return 0; +} + +#ifdef CONFIG_PCI +void pci_init_board(void) +{ + fsl_pcie_init_board(0); +} +#endif + +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 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 */ + disable_tlb(flash_esel); + + set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS, /* tlb, epn, rpn */ + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,/* perms, wimge */ + 0, flash_esel, BOOKE_PAGESZ_64M, 1);/* ts, esel, tsize, iprot */ + return 0; +} + +int board_eth_init(bd_t *bis) +{ + struct fsl_pq_mdio_info mdio_info; + struct tsec_info_struct tsec_info[4]; + ccsr_gur_t *gur __attribute__((unused)) = + (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + int num = 0; +#ifdef CONFIG_VSC7385_ENET + char *tmp; + unsigned int vscfw_addr; +#endif + +#ifdef CONFIG_TSEC1 + SET_STD_TSEC_INFO(tsec_info[num], 1); + num++; +#endif +#ifdef CONFIG_TSEC2 + SET_STD_TSEC_INFO(tsec_info[num], 2); + if (is_serdes_configured(SGMII_TSEC2)) { + printf("eTSEC2 is in sgmii mode.\n"); + tsec_info[num].flags |= TSEC_SGMII; + } + num++; +#endif +#ifdef CONFIG_TSEC3 + SET_STD_TSEC_INFO(tsec_info[num], 3); + num++; +#endif + + if (!num) { + printf("No TSECs initialized\n"); + return 0; + } + +#ifdef CONFIG_VSC7385_ENET + /* If a VSC7385 microcode image is present, then upload it. */ + if ((tmp = getenv("vscfw_addr")) != NULL) { + vscfw_addr = simple_strtoul(tmp, NULL, 16); + printf("uploading VSC7385 microcode from %x\n", vscfw_addr); + if (vsc7385_upload_firmware((void *) vscfw_addr, + CONFIG_VSC7385_IMAGE_SIZE)) + puts("Failure uploading VSC7385 microcode.\n"); + } else + puts("No address specified for VSC7385 microcode.\n"); +#endif + + mdio_info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR; + mdio_info.name = DEFAULT_MII_NAME; + + fsl_pq_mdio_init(bis, &mdio_info); + + tsec_eth_init(bis, tsec_info, num); + +#if defined(CONFIG_UEC_ETH) + /* QE0 and QE3 need to be exposed for UCC1 and UCC5 Eth mode */ + setbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_QE0); + setbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_QE3); + + uec_standard_init(bis); +#endif + + return pci_eth_init(bis); +} + +#if defined(CONFIG_QE) && \ + (defined(CONFIG_P1025RDB) || defined(CONFIG_P1021RDB)) +static void fdt_board_fixup_qe_pins(void *blob) +{ + unsigned int oldbus; + u8 val8; + int node; + fsl_lbc_t *lbc = LBC_BASE_ADDR; + + if (hwconfig("qe")) { + /* For QE and eLBC pins multiplexing, + * there is a PCA9555 device on P1025RDB. + * It control the multiplex pins' functions, + * and setting the PCA9555 can switch the + * function between QE and eLBC. + */ + oldbus = i2c_get_bus_num(); + i2c_set_bus_num(0); + if (hwconfig("tdm")) + val8 = PCA_IOPORT_QE_TDM_ENABLE; + else + val8 = PCA_IOPORT_QE_PIN_ENABLE; + i2c_write(PCA_IOPORT_I2C_ADDR, PCA_IOPORT_CFG_CMD, + 1, &val8, 1); + i2c_write(PCA_IOPORT_I2C_ADDR, PCA_IOPORT_OUTPUT_CMD, + 1, &val8, 1); + i2c_set_bus_num(oldbus); + /* if run QE TDM, Set ABSWP to implement + * conversion of addresses in the eLBC. + */ + if (hwconfig("tdm")) { + set_lbc_or(2, CONFIG_PMC_OR_PRELIM); + set_lbc_br(2, CONFIG_PMC_BR_PRELIM); + setbits_be32(&lbc->lbcr, CONFIG_SYS_LBC_LBCR); + } + } else { + node = fdt_path_offset(blob, "/qe"); + if (node >= 0) + fdt_del_node(blob, node); + } + + return; +} +#endif + +#ifdef CONFIG_OF_BOARD_SETUP +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); + + FT_FSL_PCI_SETUP; + +#ifdef CONFIG_QE + do_fixup_by_compat(blob, "fsl,qe", "status", "okay", + sizeof("okay"), 0); +#if defined(CONFIG_P1025RDB) || defined(CONFIG_P1021RDB) + fdt_board_fixup_qe_pins(blob); +#endif +#endif + fdt_fixup_dr_usb(blob, bd); +} +#endif diff --git a/board/freescale/p1_p2_rdb_pc/tlb.c b/board/freescale/p1_p2_rdb_pc/tlb.c new file mode 100644 index 0000000..6d22463 --- /dev/null +++ b/board/freescale/p1_p2_rdb_pc/tlb.c @@ -0,0 +1,114 @@ +/* + * Copyright 2010-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 <asm/mmu.h> + +struct fsl_e_tlb_entry tlb_table[] = { + /* TLB 0 - for temp stack in cache */ + SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR, + CONFIG_SYS_INIT_RAM_ADDR_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 4 * 1024 , + CONFIG_SYS_INIT_RAM_ADDR_PHYS + 4 * 1024, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 8 * 1024 , + CONFIG_SYS_INIT_RAM_ADDR_PHYS + 8 * 1024, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 12 * 1024 , + CONFIG_SYS_INIT_RAM_ADDR_PHYS + 12 * 1024, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + + /* TLB 1 */ + /* *I*** - Covers boot page */ + SET_TLB_ENTRY(1, 0xfffff000, 0xfffff000, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I, + 0, 0, BOOKE_PAGESZ_4K, 1), + + /* *I*G* - CCSRBAR */ + SET_TLB_ENTRY(1, CONFIG_SYS_CCSRBAR, CONFIG_SYS_CCSRBAR_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 1, BOOKE_PAGESZ_1M, 1), + +#ifndef CONFIG_NAND_SPL + /* W**G* - Flash/promjet, localbus */ + /* This will be changed to *I*G* after relocation to RAM. */ + SET_TLB_ENTRY(1, CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE_PHYS, + MAS3_SX|MAS3_SR, MAS2_W|MAS2_G, + 0, 2, BOOKE_PAGESZ_64M, 1), + +#ifdef CONFIG_PCI + /* *I*G* - PCI memory 1.5G */ + SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_MEM_VIRT, CONFIG_SYS_PCIE1_MEM_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 3, BOOKE_PAGESZ_1G, 1), + + /* *I*G* - PCI I/O effective: 192K */ + SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_IO_VIRT, CONFIG_SYS_PCIE1_IO_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 4, BOOKE_PAGESZ_256K, 1), +#endif + +#ifdef CONFIG_VSC7385_ENET + /* *I*G - VSC7385 Switch */ + SET_TLB_ENTRY(1, CONFIG_SYS_VSC7385_BASE, CONFIG_SYS_VSC7385_BASE_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 5, BOOKE_PAGESZ_1M, 1), +#endif + + SET_TLB_ENTRY(1, CONFIG_SYS_CPLD_BASE, CONFIG_SYS_CPLD_BASE_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 6, BOOKE_PAGESZ_1M, 1), + SET_TLB_ENTRY(1, CONFIG_SYS_PMC_BASE, CONFIG_SYS_PMC_BASE_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 10, BOOKE_PAGESZ_64K, 1), +#endif + +#ifdef CONFIG_SYS_NAND_BASE + /* *I*G - NAND */ + SET_TLB_ENTRY(1, CONFIG_SYS_NAND_BASE, CONFIG_SYS_NAND_BASE_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 7, BOOKE_PAGESZ_1M, 1), +#endif + +#ifdef CONFIG_SYS_RAMBOOT + /* *I*G - eSDHC/eSPI/NAND boot */ + SET_TLB_ENTRY(1, CONFIG_SYS_DDR_SDRAM_BASE, CONFIG_SYS_DDR_SDRAM_BASE, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, 8, BOOKE_PAGESZ_1G, 1), + +#ifdef CONFIG_P1020MBG + /* 2G DDR on P1020MBG, map the second 1G */ + SET_TLB_ENTRY(1, CONFIG_SYS_DDR_SDRAM_BASE + 0x40000000, + CONFIG_SYS_DDR_SDRAM_BASE + 0x40000000, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 0, 9, BOOKE_PAGESZ_1G, 1), +#endif +#endif + +}; + +int num_tlb_entries = ARRAY_SIZE(tlb_table); diff --git a/board/freescale/p2041rdb/Makefile b/board/freescale/p2041rdb/Makefile index 65f348f..8d4da3a 100644 --- a/board/freescale/p2041rdb/Makefile +++ b/board/freescale/p2041rdb/Makefile @@ -29,9 +29,7 @@ LIB = $(obj)lib$(BOARD).o COBJS-y += $(BOARD).o COBJS-y += cpld.o COBJS-y += ddr.o -COBJS-y += law.o -COBJS-y += tlb.o -COBJS-$(CONFIG_PCI) += pci.o +COBJS-y += eth.o SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(COBJS-y)) diff --git a/board/freescale/p2041rdb/cpld.c b/board/freescale/p2041rdb/cpld.c index 8e1f46e..a4bcc18 100644 --- a/board/freescale/p2041rdb/cpld.c +++ b/board/freescale/p2041rdb/cpld.c @@ -53,7 +53,11 @@ void cpld_reset(void) __attribute__((weak, alias("__cpld_reset"))); */ void __cpld_set_altbank(void) { + u8 reg5 = CPLD_READ(sw_ctl_on); + + CPLD_WRITE(sw_ctl_on, reg5 | CPLD_SWITCH_BANK_ENABLE); CPLD_WRITE(fbank_sel, 1); + CPLD_WRITE(system_rst, 1); } void cpld_set_altbank(void) __attribute__((weak, alias("__cpld_set_altbank"))); @@ -61,12 +65,12 @@ void cpld_set_altbank(void) /** * Set the boot bank to the default bank */ -void __cpld_clear_altbank(void) +void __cpld_set_defbank(void) { - CPLD_WRITE(fbank_sel, 0); + CPLD_WRITE(system_rst_default, 1); } -void cpld_clear_altbank(void) - __attribute__((weak, alias("__cpld_clear_altbank"))); +void cpld_set_defbank(void) + __attribute__((weak, alias("__cpld_set_defbank"))); #ifdef DEBUG static void cpld_dump_regs(void) @@ -75,7 +79,6 @@ static void cpld_dump_regs(void) printf("cpld_ver_sub = 0x%02x\n", CPLD_READ(cpld_ver_sub)); printf("pcba_ver = 0x%02x\n", CPLD_READ(pcba_ver)); printf("system_rst = 0x%02x\n", CPLD_READ(system_rst)); - printf("wd_cfg = 0x%02x\n", CPLD_READ(wd_cfg)); printf("sw_ctl_on = 0x%02x\n", CPLD_READ(sw_ctl_on)); printf("por_cfg = 0x%02x\n", CPLD_READ(por_cfg)); printf("switch_strobe = 0x%02x\n", CPLD_READ(switch_strobe)); @@ -92,7 +95,6 @@ static void cpld_dump_regs(void) int cpld_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int rc = 0; - unsigned int i; if (argc <= 1) return cmd_usage(cmdtp); @@ -101,16 +103,7 @@ int cpld_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (strcmp(argv[2], "altbank") == 0) cpld_set_altbank(); else - cpld_clear_altbank(); - - cpld_reset(); - } else if (strcmp(argv[1], "watchdog") == 0) { - static char *period[8] = {"1ms", "10ms", "30ms", "disable", - "100ms", "1s", "10s", "60s"}; - for (i = 0; i < ARRAY_SIZE(period); i++) { - if (strcmp(argv[2], period[i]) == 0) - CPLD_WRITE(wd_cfg, i); - } + cpld_set_defbank(); } else if (strcmp(argv[1], "lane_mux") == 0) { u32 lane = simple_strtoul(argv[2], NULL, 16); u8 val = (u8)simple_strtoul(argv[3], NULL, 16); @@ -154,17 +147,15 @@ U_BOOT_CMD( "Reset the board or pin mulexing selection using the CPLD sequencer", "reset - hard reset to default bank\n" "cpld_cmd reset altbank - reset to alternate bank\n" - "cpld_cmd watchdog <watchdog_period> - set the watchdog period\n" - " period: 1ms 10ms 30ms 100ms 1s 10s 60s disable\n" "cpld_cmd lane_mux <lane> <mux_value> - set multiplexed lane pin\n" - " lane 6: 0 -> slot1 (Default)\n" - " 1 -> SGMII\n" - " lane a: 0 -> slot2 (Default)\n" - " 1 -> AURORA\n" - " lane c: 0 -> slot2 (Default)\n" - " 1 -> SATA0\n" - " lane d: 0 -> slot2 (Default)\n" - " 1 -> SATA1\n" + " lane 6: 0 -> slot1\n" + " 1 -> SGMII (Default)\n" + " lane a: 0 -> slot2\n" + " 1 -> AURORA (Default)\n" + " lane c: 0 -> slot2\n" + " 1 -> SATA0 (Default)\n" + " lane d: 0 -> slot2\n" + " 1 -> SATA1 (Default)\n" #ifdef DEBUG "cpld_cmd dump - display the CPLD registers\n" #endif diff --git a/board/freescale/p2041rdb/cpld.h b/board/freescale/p2041rdb/cpld.h index 3b24cb0..2e3e7b1 100644 --- a/board/freescale/p2041rdb/cpld.h +++ b/board/freescale/p2041rdb/cpld.h @@ -19,7 +19,7 @@ typedef struct cpld_data { u8 cpld_ver_sub; /* 0x1 - CPLD Minor Revision Register */ u8 pcba_ver; /* 0x2 - PCBA Revision Register */ u8 system_rst; /* 0x3 - system reset register */ - u8 wd_cfg; /* 0x4 - Watchdog Period Setting Register */ + u8 res0; /* 0x4 - not used */ u8 sw_ctl_on; /* 0x5 - Switch Control Enable Register */ u8 por_cfg; /* 0x6 - POR Control Register */ u8 switch_strobe; /* 0x7 - Multiplexed pin Select Register */ @@ -29,6 +29,8 @@ typedef struct cpld_data { u8 fbank_sel; /* 0xb - Flash bank selection */ u8 serdes_mux; /* 0xc - Multiplexed pin Select Register */ u8 sw[1]; /* 0xd - SW2 Status */ + u8 system_rst_default; /* 0xe - system reset to default register */ + u8 sysclk_sw1; /* 0xf - sysclk configuration register */ } __attribute__ ((packed)) cpld_data_t; #define SERDES_MUX_LANE_6_MASK 0x2 @@ -39,6 +41,9 @@ typedef struct cpld_data { #define SERDES_MUX_LANE_C_SHIFT 2 #define SERDES_MUX_LANE_D_MASK 0x8 #define SERDES_MUX_LANE_D_SHIFT 3 +#define CPLD_SWITCH_BANK_ENABLE 0x40 +#define CPLD_SYSCLK_83 0x1 /* system clock 83.3MHz */ +#define CPLD_SYSCLK_100 0x2 /* system clock 100MHz */ /* Pointer to the CPLD register set */ #define cpld ((cpld_data_t *)CPLD_BASE) diff --git a/board/freescale/p2041rdb/ddr.c b/board/freescale/p2041rdb/ddr.c index e9c699c..3637093 100644 --- a/board/freescale/p2041rdb/ddr.c +++ b/board/freescale/p2041rdb/ddr.c @@ -37,7 +37,10 @@ const board_specific_parameters_t board_specific_parameters[] = { * lo| hi| num| clk| wrlvl | cpo |wrdata|2T * mhz| mhz|ranks|adjst| start | delay| */ - { 1017, 1116, 2, 4, 6, 0xff, 2, 0}, + { 0, 750, 2, 3, 5, 0xff, 2, 0}, + { 751, 1250, 2, 4, 6, 0xff, 2, 0}, + { 1251, 1350, 2, 5, 7, 0xff, 2, 0}, + { 1351, 1666, 2, 5, 8, 0xff, 2, 0}, }; void fsl_ddr_board_options(memctl_options_t *popts, diff --git a/board/freescale/p2041rdb/eth.c b/board/freescale/p2041rdb/eth.c new file mode 100644 index 0000000..0a1dfa7 --- /dev/null +++ b/board/freescale/p2041rdb/eth.c @@ -0,0 +1,225 @@ +/* + * Copyright 2011 Freescale Semiconductor, Inc. + * Author: Mingkai Hu <Mingkai.hu@freescale.com> + * + * 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 + */ + +/* + * The RGMII PHYs are provided by the two on-board PHY. The SGMII PHYs + * are provided by the three on-board PHY or by the standard Freescale + * four-port SGMII riser card. We need to change the phy-handle in the + * kernel dts file to point to the correct PHY according to serdes mux + * and serdes protocol selection. + */ + +#include <common.h> +#include <netdev.h> +#include <asm/fsl_serdes.h> +#include <fm_eth.h> +#include <fsl_mdio.h> +#include <malloc.h> +#include <asm/fsl_dtsec.h> + +#include "cpld.h" +#include "../common/fman.h" + +#ifdef CONFIG_FMAN_ENET +/* + * Mapping of all 18 SERDES lanes to board slots. A value of '0' here means + * that the mapping must be determined dynamically, or that the lane maps to + * something other than a board slot + */ +static u8 lane_to_slot[] = { + 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0 +}; + +static int riser_phy_addr[] = { + CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR, + CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR, + CONFIG_SYS_FM1_DTSEC3_RISER_PHY_ADDR, + CONFIG_SYS_FM1_DTSEC4_RISER_PHY_ADDR, +}; + +/* + * Initialize the lane_to_slot[] array. + * + * On the P2040RDB board the mapping is controlled by CPLD register. + */ +static void initialize_lane_to_slot(void) +{ + u8 mux = CPLD_READ(serdes_mux); + + lane_to_slot[6] = (mux & SERDES_MUX_LANE_6_MASK) ? 0 : 1; + lane_to_slot[10] = (mux & SERDES_MUX_LANE_A_MASK) ? 0 : 2; + lane_to_slot[12] = (mux & SERDES_MUX_LANE_C_MASK) ? 0 : 2; + lane_to_slot[13] = (mux & SERDES_MUX_LANE_D_MASK) ? 0 : 2; +} + +/* + * Given the following ... + * + * 1) A pointer to an Fman Ethernet node (as identified by the 'compat' + * compatible string and 'addr' physical address) + * + * 2) An Fman port + * + * ... update the phy-handle property of the Ethernet node to point to the + * right PHY. This assumes that we already know the PHY for each port. + * + * The offset of the Fman Ethernet node is also passed in for convenience, but + * it is not used, and we recalculate the offset anyway. + * + * Note that what we call "Fman ports" (enum fm_port) is really an Fman MAC. + * Inside the Fman, "ports" are things that connect to MACs. We only call them + * ports in U-Boot because on previous Ethernet devices (e.g. Gianfar), MACs + * and ports are the same thing. + * + */ +void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr, + enum fm_port port, int offset) +{ + phy_interface_t intf = fm_info_get_enet_if(port); + char phy[16]; + + /* The RGMII PHY is identified by the MAC connected to it */ + if (intf == PHY_INTERFACE_MODE_RGMII) { + sprintf(phy, "phy_rgmii_%u", port == FM1_DTSEC5 ? 0 : 1); + fdt_set_phy_handle(fdt, compat, addr, phy); + } + + /* The SGMII PHY is identified by the MAC connected to it */ + if (intf == PHY_INTERFACE_MODE_SGMII) { + int lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + port); + u8 slot; + if (lane < 0) + return; + slot = lane_to_slot[lane]; + if (slot) { + sprintf(phy, "phy_sgmii_%x", + CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR + + (port - FM1_DTSEC1)); + fdt_set_phy_handle(fdt, compat, addr, phy); + } else { + sprintf(phy, "phy_sgmii_%x", + CONFIG_SYS_FM1_DTSEC1_PHY_ADDR + + (port - FM1_DTSEC1)); + fdt_set_phy_handle(fdt, compat, addr, phy); + } + } + + if (intf == PHY_INTERFACE_MODE_XGMII) { + /* XAUI */ + int lane = serdes_get_first_lane(XAUI_FM1); + if (lane >= 0) { + /* The XAUI PHY is identified by the slot */ + sprintf(phy, "phy_xgmii_%u", lane_to_slot[lane]); + fdt_set_phy_handle(fdt, compat, addr, phy); + } + } +} +#endif /* #ifdef CONFIG_FMAN_ENET */ + +int board_eth_init(bd_t *bis) +{ +#ifdef CONFIG_FMAN_ENET + struct dtsec *tsec = (void *)CONFIG_SYS_FSL_FM1_DTSEC1_ADDR; + struct fsl_pq_mdio_info dtsec_mdio_info; + struct tgec_mdio_info tgec_mdio_info; + unsigned int i, slot; + int lane; + + printf("Initializing Fman\n"); + + 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); + + dtsec_mdio_info.regs = + (struct tsec_mii_mng *)CONFIG_SYS_FM1_DTSEC1_MDIO_ADDR; + dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME; + + /* Register the real 1G MDIO bus */ + fsl_pq_mdio_init(bis, &dtsec_mdio_info); + + tgec_mdio_info.regs = + (struct tgec_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR; + tgec_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME; + + /* Register the real 10G MDIO bus */ + fm_tgec_mdio_init(bis, &tgec_mdio_info); + + /* + * Program the three on-board SGMII PHY addresses. If the SGMII Riser + * card used, we'll override the PHY address later. For any DTSEC that + * is RGMII, we'll also override its PHY address later. We assume that + * DTSEC4 and DTSEC5 are used for RGMII. + */ + fm_info_set_phy_address(FM1_DTSEC1, CONFIG_SYS_FM1_DTSEC1_PHY_ADDR); + fm_info_set_phy_address(FM1_DTSEC2, CONFIG_SYS_FM1_DTSEC2_PHY_ADDR); + fm_info_set_phy_address(FM1_DTSEC3, CONFIG_SYS_FM1_DTSEC3_PHY_ADDR); + + for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { + int 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; + slot = lane_to_slot[lane]; + if (slot) + fm_info_set_phy_address(i, riser_phy_addr[i]); + break; + case PHY_INTERFACE_MODE_RGMII: + /* Only DTSEC4 and DTSEC5 can be routed to RGMII */ + fm_info_set_phy_address(i, i == FM1_DTSEC5 ? + CONFIG_SYS_FM1_DTSEC5_PHY_ADDR : + CONFIG_SYS_FM1_DTSEC4_PHY_ADDR); + break; + default: + printf("Fman1: DTSEC%u set to unknown interface %i\n", + idx + 1, fm_info_get_enet_if(i)); + break; + } + + fm_info_set_mdio(i, + miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME)); + } + + lane = serdes_get_first_lane(XAUI_FM1); + if (lane >= 0) { + slot = lane_to_slot[lane]; + if (slot) + fm_info_set_phy_address(FM1_10GEC1, + CONFIG_SYS_FM1_10GEC1_PHY_ADDR); + } + + fm_info_set_mdio(FM1_10GEC1, + miiphy_get_dev_by_name(DEFAULT_FM_TGEC_MDIO_NAME)); + cpu_eth_init(bis); +#endif + + return pci_eth_init(bis); +} diff --git a/board/freescale/p2041rdb/p2041rdb.c b/board/freescale/p2041rdb/p2041rdb.c index 52269d3..6461bd7 100644 --- a/board/freescale/p2041rdb/p2041rdb.c +++ b/board/freescale/p2041rdb/p2041rdb.c @@ -32,6 +32,7 @@ #include <asm/fsl_serdes.h> #include <asm/fsl_portals.h> #include <asm/fsl_liodn.h> +#include <fm_eth.h> extern void pci_of_setup(void *blob, bd_t *bd); @@ -129,6 +130,20 @@ int board_early_init_r(void) return 0; } +unsigned long get_board_sys_clk(unsigned long dummy) +{ + u8 sysclk_conf = CPLD_READ(sysclk_sw1); + + switch (sysclk_conf & 0x7) { + case CPLD_SYSCLK_83: + return 83333333; + case CPLD_SYSCLK_100: + return 100000000; + default: + return 66666666; + } +} + static const char *serdes_clock_to_string(u32 clock) { switch (clock) { @@ -200,4 +215,7 @@ void ft_board_setup(void *blob, bd_t *bd) #endif fdt_fixup_liodn(blob); +#ifdef CONFIG_SYS_DPAA_FMAN + fdt_fixup_fman_ethernet(blob); +#endif } diff --git a/board/freescale/p2041rdb/tlb.c b/board/freescale/p2041rdb/tlb.c deleted file mode 100644 index 43f28ed..0000000 --- a/board/freescale/p2041rdb/tlb.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * 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 <asm/mmu.h> - -struct fsl_e_tlb_entry tlb_table[] = { - /* TLB 0 - for temp stack in cache */ - SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR, - CONFIG_SYS_INIT_RAM_ADDR_PHYS, - MAS3_SX|MAS3_SW|MAS3_SR, 0, - 0, 0, BOOKE_PAGESZ_4K, 0), - SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 4 * 1024, - CONFIG_SYS_INIT_RAM_ADDR_PHYS + 4 * 1024, - MAS3_SX|MAS3_SW|MAS3_SR, 0, - 0, 0, BOOKE_PAGESZ_4K, 0), - SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 8 * 1024, - CONFIG_SYS_INIT_RAM_ADDR_PHYS + 8 * 1024, - MAS3_SX|MAS3_SW|MAS3_SR, 0, - 0, 0, BOOKE_PAGESZ_4K, 0), - SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 12 * 1024, - CONFIG_SYS_INIT_RAM_ADDR_PHYS + 12 * 1024, - MAS3_SX|MAS3_SW|MAS3_SR, 0, - 0, 0, BOOKE_PAGESZ_4K, 0), - - SET_TLB_ENTRY(0, CPLD_BASE, CPLD_BASE_PHYS, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, - 0, 0, BOOKE_PAGESZ_4K, 0), - - /* TLB 1 */ - /* *I*** - Covers boot page */ -#if defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SYS_INIT_L3_ADDR) - /* - * *I*G - L3SRAM. When L3 is used as 1M SRAM, the address of the - * SRAM is at 0xfff00000, it covered the 0xfffff000. - */ - SET_TLB_ENTRY(1, CONFIG_SYS_INIT_L3_ADDR, CONFIG_SYS_INIT_L3_ADDR, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, - 0, 0, BOOKE_PAGESZ_1M, 1), -#else - SET_TLB_ENTRY(1, 0xfffff000, 0xfffff000, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, - 0, 0, BOOKE_PAGESZ_4K, 1), -#endif - - /* *I*G* - CCSRBAR */ - SET_TLB_ENTRY(1, CONFIG_SYS_CCSRBAR, CONFIG_SYS_CCSRBAR_PHYS, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, - 0, 1, BOOKE_PAGESZ_16M, 1), - - /* *I*G* - Flash, localbus */ - /* This will be changed to *I*G* after relocation to RAM. */ - SET_TLB_ENTRY(1, CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE_PHYS, - MAS3_SX|MAS3_SR, MAS2_W|MAS2_G, - 0, 2, BOOKE_PAGESZ_256M, 1), - - /* *I*G* - PCI */ - SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_MEM_VIRT, CONFIG_SYS_PCIE1_MEM_PHYS, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, - 0, 3, BOOKE_PAGESZ_1G, 1), - - /* *I*G* - PCI */ - SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_MEM_VIRT + 0x40000000, - CONFIG_SYS_PCIE1_MEM_PHYS + 0x40000000, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, - 0, 4, BOOKE_PAGESZ_256M, 1), - - SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_MEM_VIRT + 0x50000000, - CONFIG_SYS_PCIE1_MEM_PHYS + 0x50000000, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, - 0, 5, BOOKE_PAGESZ_256M, 1), - - /* *I*G* - PCI I/O */ - SET_TLB_ENTRY(1, CONFIG_SYS_PCIE1_IO_VIRT, CONFIG_SYS_PCIE1_IO_PHYS, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, - 0, 6, BOOKE_PAGESZ_256K, 1), - - /* Bman/Qman */ - SET_TLB_ENTRY(1, CONFIG_SYS_BMAN_MEM_BASE, CONFIG_SYS_BMAN_MEM_PHYS, - MAS3_SX|MAS3_SW|MAS3_SR, 0, - 0, 9, BOOKE_PAGESZ_1M, 1), - SET_TLB_ENTRY(1, CONFIG_SYS_BMAN_MEM_BASE + 0x00100000, - CONFIG_SYS_BMAN_MEM_PHYS + 0x00100000, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, - 0, 10, BOOKE_PAGESZ_1M, 1), - SET_TLB_ENTRY(1, CONFIG_SYS_QMAN_MEM_BASE, CONFIG_SYS_QMAN_MEM_PHYS, - MAS3_SX|MAS3_SW|MAS3_SR, 0, - 0, 11, BOOKE_PAGESZ_1M, 1), - SET_TLB_ENTRY(1, CONFIG_SYS_QMAN_MEM_BASE + 0x00100000, - CONFIG_SYS_QMAN_MEM_PHYS + 0x00100000, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, - 0, 12, BOOKE_PAGESZ_1M, 1), -#ifdef CONFIG_SYS_DCSRBAR_PHYS - SET_TLB_ENTRY(1, CONFIG_SYS_DCSRBAR, CONFIG_SYS_DCSRBAR_PHYS, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, - 0, 13, BOOKE_PAGESZ_4M, 1), -#endif -}; - -int num_tlb_entries = ARRAY_SIZE(tlb_table); |