diff options
author | Wolfgang Denk <wd@denx.de> | 2012-08-09 21:04:05 +0200 |
---|---|---|
committer | Wolfgang Denk <wd@denx.de> | 2012-08-09 21:04:05 +0200 |
commit | 1d56f63dab2d9b1ea60601f5f3ae22d8664d8aa5 (patch) | |
tree | 249c74a50e495c32d6b8f387112f712430e38d22 /board | |
parent | d764c5043d6d72e012f3e50092344ebd57a0c242 (diff) | |
parent | 5c5befda58e4a3f198a033e8a9952b2b309acc86 (diff) | |
download | u-boot-imx-1d56f63dab2d9b1ea60601f5f3ae22d8664d8aa5.zip u-boot-imx-1d56f63dab2d9b1ea60601f5f3ae22d8664d8aa5.tar.gz u-boot-imx-1d56f63dab2d9b1ea60601f5f3ae22d8664d8aa5.tar.bz2 |
Merge branch 'master' of git://git.denx.de/u-boot-mpc85xx
* 'master' of git://git.denx.de/u-boot-mpc85xx:
powerpc/85xx: use CONFIG_SYS_FSL_PCIE_COMPAT macro when setting the PCI LIODNs
powerpc/mpc85xx: Ignore E bit for BSC9130/1
powerpc/sgmii: To support PHY link state auto detect in SGMII mode
powerpc/85xx: improve definition of BR_PHYS_ADDR macro
powerpc/p2041: configure the CPLD lane_mux according to RCW
powerpc/ddr: fix fsl_ddr_get_dimm_params compile error
powerpc/corenet: fix compile error when CONFIG_SYS_NO_FLASH is defined
powerpc/mpc8xxx: fix workaround for errata DDR111 and DDR134 for DDR over 4GB
powerpc/p1022ds: fix DIU/LBC switching with NAND enabled
powerpc/p1022ds: add support for SPI and SD boot
Signed-off-by: Wolfgang Denk <wd@denx.de>
Diffstat (limited to 'board')
-rw-r--r-- | board/freescale/common/sgmii_riser.c | 57 | ||||
-rw-r--r-- | board/freescale/p1022ds/diu.c | 82 | ||||
-rw-r--r-- | board/freescale/p1022ds/p1022ds.c | 4 | ||||
-rw-r--r-- | board/freescale/p1022ds/tlb.c | 14 | ||||
-rw-r--r-- | board/freescale/p2041rdb/eth.c | 39 |
5 files changed, 180 insertions, 16 deletions
diff --git a/board/freescale/common/sgmii_riser.c b/board/freescale/common/sgmii_riser.c index 4f40a1d..5c3c593 100644 --- a/board/freescale/common/sgmii_riser.c +++ b/board/freescale/common/sgmii_riser.c @@ -17,6 +17,7 @@ #include <net.h> #include <libfdt.h> #include <tsec.h> +#include <fdt_support.h> void fsl_sgmii_riser_init(struct tsec_info_struct *tsec_info, int num) { @@ -31,6 +32,7 @@ void fsl_sgmii_riser_fdt_fixup(void *fdt) { struct eth_device *dev; int node; + int mdio_node; int i = -1; int etsec_num = 0; @@ -40,16 +42,38 @@ void fsl_sgmii_riser_fdt_fixup(void *fdt) while ((dev = eth_get_dev_by_index(++i)) != NULL) { struct tsec_private *priv; + int phy_node; int enet_node; + uint32_t ph; + char sgmii_phy[16]; char enet[16]; const u32 *phyh; - int phynode; const char *model; const char *path; if (!strstr(dev->name, "eTSEC")) continue; + priv = dev->priv; + if (!(priv->flags & TSEC_SGMII)) { + etsec_num++; + continue; + } + + mdio_node = fdt_node_offset_by_compatible(fdt, -1, + "fsl,gianfar-mdio"); + if (mdio_node < 0) + return; + + sprintf(sgmii_phy, "sgmii-phy@%d", etsec_num); + phy_node = fdt_subnode_offset(fdt, mdio_node, sgmii_phy); + if (phy_node > 0) { + fdt_increase_size(fdt, 32); + ph = fdt_create_phandle(fdt, phy_node); + if (!ph) + continue; + } + sprintf(enet, "ethernet%d", etsec_num++); path = fdt_getprop(fdt, node, enet, NULL); if (!path) { @@ -74,15 +98,32 @@ void fsl_sgmii_riser_fdt_fixup(void *fdt) if (!strstr(model, "TSEC")) continue; - phyh = fdt_getprop(fdt, enet_node, "phy-handle", NULL); - if (!phyh) - continue; + if (phy_node < 0) { + /* + * This part is only for old device tree without + * sgmii_phy nodes. It's kept just for compatible + * reason. Soon to be deprecated if all device tree + * get updated. + */ + phyh = fdt_getprop(fdt, enet_node, "phy-handle", NULL); + if (!phyh) + continue; - phynode = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*phyh)); + phy_node = fdt_node_offset_by_phandle(fdt, + fdt32_to_cpu(*phyh)); - priv = dev->priv; + priv = dev->priv; - if (priv->flags & TSEC_SGMII) - fdt_setprop_cell(fdt, phynode, "reg", priv->phyaddr); + if (priv->flags & TSEC_SGMII) + fdt_setprop_cell(fdt, phy_node, "reg", + priv->phyaddr); + } else { + fdt_setprop(fdt, enet_node, "phy-handle", &ph, + sizeof(ph)); + fdt_setprop_string(fdt, enet_node, + "phy-connection-type", + phy_string_for_interface( + PHY_INTERFACE_MODE_SGMII)); + } } } diff --git a/board/freescale/p1022ds/diu.c b/board/freescale/p1022ds/diu.c index d5428ea..898f4c7 100644 --- a/board/freescale/p1022ds/diu.c +++ b/board/freescale/p1022ds/diu.c @@ -63,6 +63,8 @@ static u8 px_brdcfg0; static u32 pmuxcr; static void *lbc_lcs0_ba; static void *lbc_lcs1_ba; +static u32 old_br0, old_or0, old_br1, old_or1; +static u32 new_br0, new_or0, new_br1, new_or1; void diu_set_pixel_clock(unsigned int pixclock) { @@ -88,10 +90,63 @@ int platform_diu_init(unsigned int xres, unsigned int yres, const char *port) const char *name; u32 pixel_format; u8 temp; + phys_addr_t phys0, phys1; /* BR0/BR1 physical addresses */ - /* Save the LBC LCS0 and LCS1 addresses for the DIU mux functions */ - lbc_lcs0_ba = (void *)(get_lbc_br(0) & get_lbc_or(0) & 0xFFFF8000); - lbc_lcs1_ba = (void *)(get_lbc_br(1) & get_lbc_or(1) & 0xFFFF8000); + /* + * Indirect mode requires both BR0 and BR1 to be set to "GPCM", + * otherwise writes to these addresses won't actually appear on the + * local bus, and so the PIXIS won't see them. + * + * In FCM mode, writes go to the NAND controller, which does not pass + * them to the localbus directly. So we force BR0 and BR1 into GPCM + * mode, since we don't care about what's behind the localbus any + * more. However, we save those registers first, so that we can + * restore them when necessary. + */ + new_br0 = old_br0 = get_lbc_br(0); + new_br1 = old_br1 = get_lbc_br(1); + new_or0 = old_or0 = get_lbc_or(0); + new_or1 = old_or1 = get_lbc_or(1); + + /* + * Use the existing BRx/ORx values if it's already GPCM. Otherwise, + * force the values to simple 32KB GPCM windows with the most + * conservative timing. + */ + if ((old_br0 & BR_MSEL) != BR_MS_GPCM) { + new_br0 = (get_lbc_br(0) & BR_BA) | BR_V; + new_or0 = OR_AM_32KB | 0xFF7; + set_lbc_br(0, new_br0); + set_lbc_or(0, new_or0); + } + if ((old_br1 & BR_MSEL) != BR_MS_GPCM) { + new_br1 = (get_lbc_br(1) & BR_BA) | BR_V; + new_or1 = OR_AM_32KB | 0xFF7; + set_lbc_br(1, new_br1); + set_lbc_or(1, new_or1); + } + + /* + * Determine the physical addresses for Chip Selects 0 and 1. The + * BR0/BR1 registers contain the truncated physical addresses for the + * chip selects, mapped via the localbus LAW. Since the BRx registers + * only contain the lower 32 bits of the address, we have to determine + * the upper 4 bits some other way. The proper way is to scan the LAW + * table looking for a matching localbus address. Instead, we cheat. + * We know that the upper bits are 0 for 32-bit addressing, or 0xF for + * 36-bit addressing. + */ +#ifdef CONFIG_PHYS_64BIT + phys0 = 0xf00000000ULL | (old_br0 & old_or0 & BR_BA); + phys1 = 0xf00000000ULL | (old_br1 & old_or1 & BR_BA); +#else + phys0 = old_br0 & old_or0 & BR_BA; + phys1 = old_br1 & old_or1 & BR_BA; +#endif + + /* Save the LBC LCS0 and LCS1 addresses for the DIU mux functions */ + lbc_lcs0_ba = map_physmem(phys0, 1, 0); + lbc_lcs1_ba = map_physmem(phys1, 1, 0); pixel_format = cpu_to_le32(AD_BYTE_F | (3 << AD_ALPHA_C_SHIFT) | (0 << AD_BLUE_C_SHIFT) | (1 << AD_GREEN_C_SHIFT) | @@ -134,6 +189,7 @@ int platform_diu_init(unsigned int xres, unsigned int yres, const char *port) out_8(lbc_lcs0_ba, offsetof(ngpixis_t, brdcfg0)); px_brdcfg0 = in_8(lbc_lcs1_ba); out_8(lbc_lcs1_ba, px_brdcfg0 | PX_BRDCFG0_ELBC_DIU); + in_8(lbc_lcs1_ba); /* Set PMUXCR to switch the muxed pins from the LBC to the DIU */ clrsetbits_be32(&gur->pmuxcr, PMUXCR_ELBCDIU_MASK, PMUXCR_ELBCDIU_DIU); @@ -168,12 +224,10 @@ static int set_mux_to_lbc(void) * In DIU mode, the PIXIS can only be accessed indirectly * since we can't read/write the LBC directly. */ - /* Set the board mux to LBC. This will disable the display. */ out_8(lbc_lcs0_ba, offsetof(ngpixis_t, brdcfg0)); - px_brdcfg0 = in_8(lbc_lcs1_ba); - out_8(lbc_lcs1_ba, (px_brdcfg0 & ~(PX_BRDCFG0_ELBC_SPI_MASK - | PX_BRDCFG0_ELBC_DIU)) | PX_BRDCFG0_ELBC_SPI_ELBC); + out_8(lbc_lcs1_ba, px_brdcfg0); + in_8(lbc_lcs1_ba); /* Disable indirect PIXIS mode */ out_8(lbc_lcs0_ba, offsetof(ngpixis_t, csr)); @@ -184,6 +238,12 @@ static int set_mux_to_lbc(void) PMUXCR_ELBCDIU_NOR16); in_be32(&gur->pmuxcr); + /* Restore the BR0 and BR1 settings */ + set_lbc_br(0, old_br0); + set_lbc_or(0, old_or0); + set_lbc_br(1, old_br1); + set_lbc_or(1, old_or1); + return 1; } @@ -199,12 +259,18 @@ static void set_mux_to_diu(void) { ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; + /* Set BR0 and BR1 to GPCM mode */ + set_lbc_br(0, new_br0); + set_lbc_or(0, new_or0); + set_lbc_br(1, new_br1); + set_lbc_or(1, new_or1); + /* Enable indirect PIXIS mode */ setbits_8(&pixis->csr, PX_CTL_ALTACC); /* Set the board mux to DIU. This will enable the display. */ out_8(lbc_lcs0_ba, offsetof(ngpixis_t, brdcfg0)); - out_8(lbc_lcs1_ba, px_brdcfg0); + out_8(lbc_lcs1_ba, px_brdcfg0 | PX_BRDCFG0_ELBC_DIU); in_8(lbc_lcs1_ba); /* Set the chip mux to DIU mode. */ diff --git a/board/freescale/p1022ds/p1022ds.c b/board/freescale/p1022ds/p1022ds.c index 56dfcce..25fdc2a 100644 --- a/board/freescale/p1022ds/p1022ds.c +++ b/board/freescale/p1022ds/p1022ds.c @@ -39,6 +39,10 @@ int board_early_init_f(void) /* Set pmuxcr to allow both i2c1 and i2c2 */ setbits_be32(&gur->pmuxcr, 0x1000); +#ifdef CONFIG_SYS_RAMBOOT + setbits_be32(&gur->pmuxcr, + in_be32(&gur->pmuxcr) | MPC85xx_PMUXCR_SD_DATA); +#endif /* Read back the register to synchronize the write. */ in_be32(&gur->pmuxcr); diff --git a/board/freescale/p1022ds/tlb.c b/board/freescale/p1022ds/tlb.c index e620112..71e71f7 100644 --- a/board/freescale/p1022ds/tlb.c +++ b/board/freescale/p1022ds/tlb.c @@ -71,6 +71,20 @@ struct fsl_e_tlb_entry tlb_table[] = { SET_TLB_ENTRY(1, PIXIS_BASE, PIXIS_BASE_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 7, BOOKE_PAGESZ_4K, 1), + +#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), + + /* 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 +# }; int num_tlb_entries = ARRAY_SIZE(tlb_table); diff --git a/board/freescale/p2041rdb/eth.c b/board/freescale/p2041rdb/eth.c index 4b0d577..fec9777 100644 --- a/board/freescale/p2041rdb/eth.c +++ b/board/freescale/p2041rdb/eth.c @@ -136,6 +136,11 @@ void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr, } #endif /* #ifdef CONFIG_FMAN_ENET */ +#define CPLD_LANE_A_SEL 0x1 +#define CPLD_LANE_G_SEL 0x2 +#define CPLD_LANE_C_SEL 0x4 +#define CPLD_LANE_D_SEL 0x8 + int board_eth_init(bd_t *bis) { #ifdef CONFIG_FMAN_ENET @@ -143,6 +148,10 @@ int board_eth_init(bd_t *bis) struct tgec_mdio_info tgec_mdio_info; unsigned int i, slot; int lane; + ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; + int srds_prtcl = (in_be32(&gur->rcwsr[4]) & + FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26; + u8 mux = CPLD_READ(serdes_mux); printf("Initializing Fman\n"); @@ -172,6 +181,36 @@ int board_eth_init(bd_t *bis) 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); + mux &= ~(CPLD_LANE_A_SEL | CPLD_LANE_C_SEL | CPLD_LANE_D_SEL); + switch (srds_prtcl) { + case 0x2: + case 0xf: + mux &= ~CPLD_LANE_G_SEL; + break; + case 0x5: + case 0x9: + case 0xa: + case 0x17: + mux |= CPLD_LANE_G_SEL; + break; + case 0x14: + mux = (mux & (~CPLD_LANE_G_SEL)) | CPLD_LANE_A_SEL; + break; + case 0x8: + case 0x16: + case 0x19: + case 0x1a: + mux |= CPLD_LANE_G_SEL | CPLD_LANE_C_SEL | CPLD_LANE_D_SEL; + break; + case 0x1c: + mux |= CPLD_LANE_G_SEL | CPLD_LANE_A_SEL; + break; + default: + printf("Fman:Unsupported SerDes Protocol 0x%02x\n", srds_prtcl); + break; + } + CPLD_WRITE(serdes_mux, mux); + for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { int idx = i - FM1_DTSEC1; |