summaryrefslogtreecommitdiffstats
path: root/board/freescale
diff options
context:
space:
mode:
authorWolfgang Denk <wd@denx.de>2012-08-09 21:04:05 +0200
committerWolfgang Denk <wd@denx.de>2012-08-09 21:04:05 +0200
commit1d56f63dab2d9b1ea60601f5f3ae22d8664d8aa5 (patch)
tree249c74a50e495c32d6b8f387112f712430e38d22 /board/freescale
parentd764c5043d6d72e012f3e50092344ebd57a0c242 (diff)
parent5c5befda58e4a3f198a033e8a9952b2b309acc86 (diff)
downloadblackbird-obmc-uboot-1d56f63dab2d9b1ea60601f5f3ae22d8664d8aa5.tar.gz
blackbird-obmc-uboot-1d56f63dab2d9b1ea60601f5f3ae22d8664d8aa5.zip
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/freescale')
-rw-r--r--board/freescale/common/sgmii_riser.c57
-rw-r--r--board/freescale/p1022ds/diu.c82
-rw-r--r--board/freescale/p1022ds/p1022ds.c4
-rw-r--r--board/freescale/p1022ds/tlb.c14
-rw-r--r--board/freescale/p2041rdb/eth.c39
5 files changed, 180 insertions, 16 deletions
diff --git a/board/freescale/common/sgmii_riser.c b/board/freescale/common/sgmii_riser.c
index 4f40a1d6d4..5c3c59375c 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 d5428ea16d..898f4c7b19 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 56dfcce410..25fdc2a740 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 e6201127a9..71e71f7070 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 4b0d577e2c..fec97773ea 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;
OpenPOWER on IntegriCloud