]> git.sur5r.net Git - u-boot/commitdiff
powerpc/p3060: Add SoC related support for P3060 platform
authorShengzhou Liu <Shengzhou.Liu@freescale.com>
Wed, 31 Aug 2011 09:48:18 +0000 (17:48 +0800)
committerKumar Gala <galak@kernel.crashing.org>
Mon, 3 Oct 2011 14:36:28 +0000 (09:36 -0500)
Add P3060 SoC specific information:cores setup, LIODN setup, etc

The P3060 SoC combines six e500mc Power Architecture processor cores with
high-performance datapath acceleration architecture(DPAA), CoreNet fabric
infrastructure, as well as network and peripheral interfaces.

Signed-off-by: Shengzhou Liu <Shengzhou.Liu@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
arch/powerpc/cpu/mpc85xx/Makefile
arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c
arch/powerpc/cpu/mpc85xx/p3060_ids.c [new file with mode: 0644]
arch/powerpc/cpu/mpc85xx/p3060_serdes.c [new file with mode: 0644]
arch/powerpc/cpu/mpc8xxx/cpu.c
arch/powerpc/include/asm/config_mpc85xx.h
arch/powerpc/include/asm/immap_85xx.h
arch/powerpc/include/asm/processor.h
drivers/net/fm/Makefile
drivers/net/fm/p3060.c [new file with mode: 0644]

index 7026bca609710656c22df5479ad8d0864f10aad2..058d609f1709768f8374551762be5b88c089c718 100644 (file)
@@ -67,6 +67,7 @@ COBJS-$(CONFIG_P2020) += ddr-gen3.o
 COBJS-$(CONFIG_PPC_P2040)      += ddr-gen3.o
 COBJS-$(CONFIG_PPC_P2041)      += ddr-gen3.o
 COBJS-$(CONFIG_PPC_P3041)      += ddr-gen3.o
+COBJS-$(CONFIG_PPC_P3060)      += ddr-gen3.o
 COBJS-$(CONFIG_PPC_P4080)      += ddr-gen3.o
 COBJS-$(CONFIG_PPC_P5020)      += ddr-gen3.o
 
@@ -81,6 +82,7 @@ COBJS-$(CONFIG_SYS_DPAA_QBMAN) += portals.o
 COBJS-$(CONFIG_PPC_P2040) += p2041_ids.o
 COBJS-$(CONFIG_PPC_P2041) += p2041_ids.o
 COBJS-$(CONFIG_PPC_P3041) += p3041_ids.o
+COBJS-$(CONFIG_PPC_P3060) += p3060_ids.o
 COBJS-$(CONFIG_PPC_P4080) += p4080_ids.o
 COBJS-$(CONFIG_PPC_P5020) += p5020_ids.o
 
@@ -114,6 +116,7 @@ COBJS-$(CONFIG_P2020)       += p2020_serdes.o
 COBJS-$(CONFIG_PPC_P2040) += p2041_serdes.o
 COBJS-$(CONFIG_PPC_P2041) += p2041_serdes.o
 COBJS-$(CONFIG_PPC_P3041) += p3041_serdes.o
+COBJS-$(CONFIG_PPC_P3060) += p3060_serdes.o
 COBJS-$(CONFIG_PPC_P4080) += p4080_serdes.o
 COBJS-$(CONFIG_PPC_P5020) += p5020_serdes.o
 
index 4307a4ccbb5349074b2352ef1fa43dcd0ae17c72..07e58ed024a14bc41d5b11bcb36d497df761a2ff 100644 (file)
@@ -482,6 +482,13 @@ static void wait_for_rstdone(unsigned int bank)
                printf("SERDES: timeout resetting bank %u\n", bank + 1);
 }
 
+
+void __soc_serdes_init(void)
+{
+       /* Allow for SoC-specific initialization in <SOC>_serdes.c  */
+};
+void soc_serdes_init(void) __attribute__((weak, alias("__soc_serdes_init")));
+
 void fsl_serdes_init(void)
 {
        ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
@@ -570,6 +577,8 @@ void fsl_serdes_init(void)
                }
        }
 
+       soc_serdes_init();
+
 #ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8
        /*
         * Bank two uses the clock from bank three, so if bank two is enabled,
diff --git a/arch/powerpc/cpu/mpc85xx/p3060_ids.c b/arch/powerpc/cpu/mpc85xx/p3060_ids.c
new file mode 100644 (file)
index 0000000..07703d4
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * 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_portals.h>
+#include <asm/fsl_liodn.h>
+
+#ifdef CONFIG_SYS_DPAA_QBMAN
+struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = {
+       /* dqrr liodn, frame data liodn, liodn off, sdest */
+       SET_QP_INFO( 1,  2,  1, 0),
+       SET_QP_INFO( 3,  4,  2, 1),
+       SET_QP_INFO( 5,  6,  3, 2),
+       SET_QP_INFO( 7,  8,  4, 3),
+       SET_QP_INFO( 9, 10,  5, 4),
+       SET_QP_INFO(11, 12,  6, 5),
+       SET_QP_INFO(13, 14,  7, 6),
+       SET_QP_INFO(15, 16,  8, 7),
+       SET_QP_INFO(17, 18,  9, 0), /* for now sdest to 0 */
+       SET_QP_INFO(19, 20, 10, 0), /* for now sdest to 0 */
+};
+#endif
+
+struct liodn_id_table liodn_tbl[] = {
+       SET_USB_LIODN(1, "fsl-usb2-mph", 127),
+       SET_USB_LIODN(2, "fsl-usb2-dr", 157),
+
+       SET_PCI_LIODN("fsl,qoriq-pcie-v2.2", 1, 193),
+       SET_PCI_LIODN("fsl,qoriq-pcie-v2.2", 2, 194),
+
+       SET_DMA_LIODN(1, 196),
+       SET_DMA_LIODN(2, 197),
+
+       SET_GUTS_LIODN("fsl,rapidio-delta", 198, rio1liodnr, 0),
+       SET_GUTS_LIODN(NULL, 199, rio2liodnr, 0),
+       SET_GUTS_LIODN(NULL, 200, rmuliodnr, 0),
+
+#ifdef CONFIG_SYS_DPAA_QBMAN
+       SET_QMAN_LIODN(31),
+       SET_BMAN_LIODN(32),
+#endif
+       SET_PME_LIODN(128),
+};
+int liodn_tbl_sz = ARRAY_SIZE(liodn_tbl);
+
+#ifdef CONFIG_SYS_DPAA_FMAN
+struct liodn_id_table fman1_liodn_tbl[] = {
+       SET_FMAN_RX_1G_LIODN(1, 0, 11),
+       SET_FMAN_RX_1G_LIODN(1, 1, 12),
+       SET_FMAN_RX_1G_LIODN(1, 2, 13),
+       SET_FMAN_RX_1G_LIODN(1, 3, 14),
+};
+int fman1_liodn_tbl_sz = ARRAY_SIZE(fman1_liodn_tbl);
+
+#if (CONFIG_SYS_NUM_FMAN == 2)
+struct liodn_id_table fman2_liodn_tbl[] = {
+       SET_FMAN_RX_1G_LIODN(2, 0, 16),
+       SET_FMAN_RX_1G_LIODN(2, 1, 17),
+       SET_FMAN_RX_1G_LIODN(2, 2, 18),
+       SET_FMAN_RX_1G_LIODN(2, 3, 19),
+};
+int fman2_liodn_tbl_sz = ARRAY_SIZE(fman2_liodn_tbl);
+#endif
+#endif
+
+struct liodn_id_table sec_liodn_tbl[] = {
+       SET_SEC_JR_LIODN_ENTRY(0, 146, 154),
+       SET_SEC_JR_LIODN_ENTRY(1, 147, 155),
+       SET_SEC_JR_LIODN_ENTRY(2, 178, 186),
+       SET_SEC_JR_LIODN_ENTRY(3, 179, 187),
+       SET_SEC_RTIC_LIODN_ENTRY(a, 144),
+       SET_SEC_RTIC_LIODN_ENTRY(b, 145),
+       SET_SEC_RTIC_LIODN_ENTRY(c, 176),
+       SET_SEC_RTIC_LIODN_ENTRY(d, 177),
+       SET_SEC_DECO_LIODN_ENTRY(0, 129, 161),
+       SET_SEC_DECO_LIODN_ENTRY(1, 130, 162),
+       SET_SEC_DECO_LIODN_ENTRY(2, 131, 163),
+       SET_SEC_DECO_LIODN_ENTRY(3, 132, 164),
+       SET_SEC_DECO_LIODN_ENTRY(4, 133, 165),
+};
+int sec_liodn_tbl_sz = ARRAY_SIZE(sec_liodn_tbl);
+
+struct liodn_id_table liodn_bases[] = {
+       [FSL_HW_PORTAL_SEC]  = SET_LIODN_BASE_2(96, 106),
+#ifdef CONFIG_SYS_DPAA_FMAN
+       [FSL_HW_PORTAL_FMAN1] = SET_LIODN_BASE_1(32),
+#if (CONFIG_SYS_NUM_FMAN == 2)
+       [FSL_HW_PORTAL_FMAN2] = SET_LIODN_BASE_1(64),
+#endif
+#endif
+#ifdef CONFIG_SYS_DPAA_PME
+       [FSL_HW_PORTAL_PME]   = SET_LIODN_BASE_2(116, 133),
+#endif
+};
diff --git a/arch/powerpc/cpu/mpc85xx/p3060_serdes.c b/arch/powerpc/cpu/mpc85xx/p3060_serdes.c
new file mode 100644 (file)
index 0000000..6387276
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * 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/io.h>
+#include <asm/fsl_serdes.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include "fsl_corenet_serdes.h"
+
+static u8 serdes_cfg_tbl[][SRDS_MAX_LANES] = {
+       [0x03] = {PCIE1, PCIE1, PCIE1, PCIE1, PCIE2, PCIE2, PCIE2, PCIE2,
+                 SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4, SGMII_FM2_DTSEC1,
+                 SGMII_FM1_DTSEC1, SGMII_FM2_DTSEC2, SGMII_FM1_DTSEC2,
+                 NONE, NONE, AURORA, AURORA},
+       [0x06] = {PCIE1, PCIE1, PCIE1, PCIE1, NONE, NONE, SGMII_FM2_DTSEC3,
+                 SGMII_FM1_DTSEC3, SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4,
+                 SGMII_FM2_DTSEC1, SGMII_FM1_DTSEC1, SGMII_FM2_DTSEC2,
+                 SGMII_FM1_DTSEC2, NONE, NONE, AURORA, AURORA},
+       [0x16] = {SRIO2, SRIO2, SRIO2, SRIO2, SRIO1, SRIO1, SRIO1, SRIO1,
+                 AURORA, AURORA, SGMII_FM2_DTSEC1, SGMII_FM1_DTSEC1,
+                 SGMII_FM2_DTSEC2, SGMII_FM1_DTSEC2, SGMII_FM2_DTSEC3,
+                 SGMII_FM1_DTSEC3, SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4},
+       [0x19] = {SRIO2, SRIO2, SRIO2, SRIO2, SRIO1, SRIO1, SRIO1, SRIO1,
+                 AURORA, AURORA, PCIE2, PCIE2, PCIE2, PCIE2, SGMII_FM2_DTSEC3,
+                 SGMII_FM1_DTSEC3, SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4},
+       [0x1c] = {NONE, NONE, SRIO1, SRIO2,  NONE, NONE, NONE, NONE,
+                 AURORA, AURORA, SGMII_FM2_DTSEC1, SGMII_FM1_DTSEC1,
+                 SGMII_FM2_DTSEC2, SGMII_FM1_DTSEC2, SGMII_FM2_DTSEC3,
+                 SGMII_FM1_DTSEC3, SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4},
+};
+
+enum srds_prtcl serdes_get_prtcl(int cfg, int lane)
+{
+       if (!serdes_lane_enabled(lane))
+               return NONE;
+
+       return serdes_cfg_tbl[cfg][lane];
+}
+
+int is_serdes_prtcl_valid(u32 prtcl)
+{
+       int i;
+
+       if (prtcl > ARRAY_SIZE(serdes_cfg_tbl))
+               return 0;
+
+       for (i = 0; i < SRDS_MAX_LANES; i++) {
+               if (serdes_cfg_tbl[prtcl][i] != NONE)
+                       return 1;
+       }
+
+       return 0;
+}
+
+void soc_serdes_init(void)
+{
+       /*
+        * On the P3060 the devdisr2 register does not correctly reflect
+        * the state of the MACs based on the RCW fields. So disable the MACs
+        * based on the srds_prtcl and ec1, ec2, ec3 fields
+        */
+
+       ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+       u32 devdisr2 = in_be32(&gur->devdisr2);
+       u32 rcwsr11 = in_be32(&gur->rcwsr[11]);
+       u32 rcwsr13 = in_be32(&gur->rcwsr[13]);
+       u32 ec1_ext, ec2_ext;
+
+       /* NOTE: Leave FM1-1,FM1-2 alone for MDIO access */
+
+       if (!is_serdes_configured(SGMII_FM1_DTSEC3))
+               devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC1_3;
+
+       if (!is_serdes_configured(SGMII_FM1_DTSEC4))
+               devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC1_4;
+
+       if (!is_serdes_configured(SGMII_FM2_DTSEC1))
+               devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC2_1;
+
+       if (!is_serdes_configured(SGMII_FM2_DTSEC2))
+               devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC2_2;
+
+       if (!is_serdes_configured(SGMII_FM2_DTSEC3))
+               devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC2_3;
+
+       if (!is_serdes_configured(SGMII_FM2_DTSEC4))
+               devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC2_4;
+
+       if ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) ==
+               FSL_CORENET_RCWSR11_EC2_FM1_DTSEC2) {
+               devdisr2 &= ~FSL_CORENET_DEVDISR2_DTSEC1_2;
+       }
+
+       if ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) ==
+               FSL_CORENET_RCWSR11_EC2_FM2_DTSEC1) {
+               devdisr2 &= ~FSL_CORENET_DEVDISR2_DTSEC2_1;
+       }
+
+       ec1_ext = rcwsr13 & FSL_CORENET_RCWSR13_EC1_EXT;
+       if (ec1_ext) {
+               if ((ec1_ext == FSL_CORENET_RCWSR13_EC1_EXT_FM1_DTSEC4_RGMII) ||
+                       (ec1_ext == FSL_CORENET_RCWSR13_EC1_EXT_FM1_DTSEC4_MII))
+                       devdisr2 &= ~FSL_CORENET_DEVDISR2_DTSEC1_4;
+       }
+
+       ec2_ext = rcwsr13 & FSL_CORENET_RCWSR13_EC2_EXT;
+       if (ec2_ext) {
+               if ((ec2_ext == FSL_CORENET_RCWSR13_EC2_EXT_FM2_DTSEC4_RGMII) ||
+                       (ec2_ext == FSL_CORENET_RCWSR13_EC2_EXT_FM2_DTSEC4_MII))
+                       devdisr2 &= ~FSL_CORENET_DEVDISR2_DTSEC2_4;
+       }
+
+       if ((rcwsr13 & FSL_CORENET_RCWSR13_EC3) ==
+               FSL_CORENET_RCWSR13_EC3_FM2_DTSEC4_MII)
+               devdisr2 &= ~FSL_CORENET_DEVDISR2_DTSEC2_4;
+
+       out_be32(&gur->devdisr2, devdisr2);
+}
index c80567a075cdc13480b88402a49b22c7ada2c3d9..0365ca8aa23ac67e15725cb2a099574ddb471415 100644 (file)
@@ -103,6 +103,8 @@ struct cpu_type cpu_type_list [] = {
        CPU_TYPE_ENTRY(P2041, P2041_E, 4),
        CPU_TYPE_ENTRY(P3041, P3041, 4),
        CPU_TYPE_ENTRY(P3041, P3041_E, 4),
+       CPU_TYPE_ENTRY_MASK(P3060, P3060, 6, 0xf3),
+       CPU_TYPE_ENTRY_MASK(P3060, P3060_E, 6, 0xf3),
        CPU_TYPE_ENTRY(P4040, P4040, 4),
        CPU_TYPE_ENTRY(P4040, P4040_E, 4),
        CPU_TYPE_ENTRY(P4080, P4080, 8),
index fc78c58d036445289d44ab47459994946716d683..c3d6ba9e9973907c6ebef7bc114a76f256b6a64f 100644 (file)
 #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 
+#elif defined(CONFIG_PPC_P3060)
+#define CONFIG_MAX_CPUS                        8
+#define CONFIG_SYS_FSL_NUM_CC_PLLS     4
+#define CONFIG_SYS_FSL_NUM_LAWS                32
+#define CONFIG_SYS_FSL_SEC_COMPAT      4
+#define CONFIG_SYS_NUM_FMAN            2
+#define CONFIG_SYS_NUM_FM1_DTSEC       4
+#define CONFIG_SYS_NUM_FM2_DTSEC       4
+#define CONFIG_NUM_DDR_CONTROLLERS     1
+#define CONFIG_SYS_FM_MURAM_SIZE       0x28000
+#define CONFIG_SYS_FSL_TBCLK_DIV       16
+#define CONFIG_SYS_FSL_PCIE_COMPAT     "fsl,qoriq-pcie-v2.2"
+#define CONFIG_SYS_CCSRBAR_DEFAULT     0xfe000000
+#define CONFIG_SYS_FSL_ERRATUM_DDR_A003
+
 #elif defined(CONFIG_PPC_P4040)
 #define CONFIG_MAX_CPUS                        4
 #define CONFIG_SYS_FSL_NUM_CC_PLLS     4
index 769ca8573b068d0d98124860b96f4e6e9386e257..fb5ef916cce00783131de36e3e10e977d051691c 100644 (file)
@@ -1700,7 +1700,7 @@ typedef struct ccsr_gur {
 #define FSL_CORENET_RCWSR8_HOST_AGT_B1         0x00e00000
 #define FSL_CORENET_RCWSR8_HOST_AGT_B2         0x00100000
 #define FSL_CORENET_RCWSR11_EC1                        0x00c00000 /* bits 360..361 */
-#if defined(CONFIG_PPC_P4080)
+#if defined(CONFIG_PPC_P4080) || defined(CONFIG_PPC_P3060)
 #define FSL_CORENET_RCWSR11_EC1_FM1_DTSEC1             0x00000000
 #define FSL_CORENET_RCWSR11_EC1_FM1_USB1               0x00800000
 #define FSL_CORENET_RCWSR11_EC2                        0x001c0000 /* bits 363..365 */
@@ -1708,6 +1708,16 @@ typedef struct ccsr_gur {
 #define FSL_CORENET_RCWSR11_EC2_FM1_DTSEC2             0x00080000
 #define FSL_CORENET_RCWSR11_EC2_USB2                   0x00100000
 #endif
+#if defined(CONFIG_PPC_P3060)
+#define FSL_CORENET_RCWSR13_EC1_EXT                    0x1c000000
+#define FSL_CORENET_RCWSR13_EC1_EXT_FM1_DTSEC4_RGMII   0x04000000
+#define FSL_CORENET_RCWSR13_EC1_EXT_FM1_DTSEC4_MII     0x08000000
+#define FSL_CORENET_RCWSR13_EC2_EXT                    0x01c00000
+#define FSL_CORENET_RCWSR13_EC2_EXT_FM2_DTSEC4_RGMII   0x00400000
+#define FSL_CORENET_RCWSR13_EC2_EXT_FM2_DTSEC4_MII     0x00800000
+#define FSL_CORENET_RCWSR13_EC3                                0x00380000
+#define FSL_CORENET_RCWSR13_EC3_FM2_DTSEC4_MII         0x00100000
+#endif
 #if defined(CONFIG_PPC_P2040) || defined(CONFIG_PPC_P2041) \
        || defined(CONFIG_PPC_P3041) || defined(CONFIG_PPC_P5020)
 #define FSL_CORENET_RCWSR11_EC1_FM1_DTSEC4_RGMII       0x00000000
index 46f9989756678e66c5ff9623e0af7ce33a5ea1d4..1b96b84dcb57337f0a664253c05de0ad142b2e14 100644 (file)
 #define SVR_P2041_E    0x821801
 #define SVR_P3041      0x821103
 #define SVR_P3041_E    0x821903
+#define SVR_P3060      0x820002
+#define SVR_P3060_E    0x820802
 #define SVR_P4040      0x820100
 #define SVR_P4040_E    0x820900
 #define SVR_P4080      0x820000
index 9692575dc83017f8836c9e14c8bc3224f5a5a16c..072b178a04acd289e3a748c72363b6563d41d1c4 100644 (file)
@@ -39,6 +39,7 @@ COBJS-$(CONFIG_P1023) += p1023.o
 COBJS-$(CONFIG_PPC_P2040) += p5020.o
 COBJS-$(CONFIG_PPC_P2041) += p5020.o
 COBJS-$(CONFIG_PPC_P3041) += p5020.o
+COBJS-$(CONFIG_PPC_P3060) += p3060.o
 COBJS-$(CONFIG_PPC_P4080) += p4080.o
 COBJS-$(CONFIG_PPC_P5020) += p5020.o
 endif
diff --git a/drivers/net/fm/p3060.c b/drivers/net/fm/p3060.c
new file mode 100644 (file)
index 0000000..b25bca7
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * 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
+ */
+#include <common.h>
+#include <phy.h>
+#include <fm_eth.h>
+#include <asm/io.h>
+#include <asm/immap_85xx.h>
+#include <asm/fsl_serdes.h>
+
+u32 port_to_devdisr[] = {
+       [FM1_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC1_1,
+       [FM1_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC1_2,
+       [FM1_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC1_3,
+       [FM1_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC1_4,
+       [FM2_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC2_1,
+       [FM2_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC2_2,
+       [FM2_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC2_3,
+       [FM2_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC2_4,
+};
+
+static int is_device_disabled(enum fm_port port)
+{
+       ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+       u32 devdisr2 = in_be32(&gur->devdisr2);
+
+       return port_to_devdisr[port] & devdisr2;
+}
+
+void fman_disable_port(enum fm_port port)
+{
+       ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+       setbits_be32(&gur->devdisr2, port_to_devdisr[port]);
+}
+
+phy_interface_t fman_port_enet_if(enum fm_port port)
+{
+       ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+       u32 rcwsr11 = in_be32(&gur->rcwsr[11]);
+       u32 rcwsr13 = in_be32(&gur->rcwsr[13]);
+
+       if (is_device_disabled(port))
+               return PHY_INTERFACE_MODE_NONE;
+
+       /* handle RGMII/MII first */
+       if ((port == FM1_DTSEC1) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC1) ==
+               FSL_CORENET_RCWSR11_EC1_FM1_DTSEC1))
+               return PHY_INTERFACE_MODE_RGMII;
+
+       if ((port == FM1_DTSEC2) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) ==
+               FSL_CORENET_RCWSR11_EC2_FM1_DTSEC2))
+               return PHY_INTERFACE_MODE_RGMII;
+
+       if ((port == FM2_DTSEC1) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) ==
+               FSL_CORENET_RCWSR11_EC2_FM2_DTSEC1))
+               return PHY_INTERFACE_MODE_RGMII;
+
+       if ((port == FM1_DTSEC4) && ((rcwsr13 & FSL_CORENET_RCWSR13_EC1_EXT) ==
+               FSL_CORENET_RCWSR13_EC1_EXT_FM1_DTSEC4_RGMII))
+               return PHY_INTERFACE_MODE_RGMII;
+
+       if ((port == FM1_DTSEC4) && ((rcwsr13 & FSL_CORENET_RCWSR13_EC1_EXT) ==
+               FSL_CORENET_RCWSR13_EC1_EXT_FM1_DTSEC4_MII))
+               return PHY_INTERFACE_MODE_MII;
+
+       if ((port == FM2_DTSEC4) && ((rcwsr13 & FSL_CORENET_RCWSR13_EC2_EXT) ==
+               FSL_CORENET_RCWSR13_EC2_EXT_FM2_DTSEC4_RGMII))
+               return PHY_INTERFACE_MODE_RGMII;
+
+       if ((port == FM2_DTSEC4) && ((rcwsr13 & FSL_CORENET_RCWSR13_EC2_EXT) ==
+               FSL_CORENET_RCWSR13_EC2_EXT_FM2_DTSEC4_MII))
+               return PHY_INTERFACE_MODE_MII;
+
+       switch (port) {
+       case FM1_DTSEC1:
+       case FM1_DTSEC2:
+       case FM1_DTSEC3:
+       case FM1_DTSEC4:
+               if (is_serdes_configured(SGMII_FM1_DTSEC1 + port - FM1_DTSEC1))
+                       return PHY_INTERFACE_MODE_SGMII;
+               break;
+       case FM2_DTSEC1:
+       case FM2_DTSEC2:
+       case FM2_DTSEC3:
+       case FM2_DTSEC4:
+               if (is_serdes_configured(SGMII_FM2_DTSEC1 + port - FM2_DTSEC1))
+                       return PHY_INTERFACE_MODE_SGMII;
+               break;
+       default:
+               return PHY_INTERFACE_MODE_NONE;
+       }
+
+       return PHY_INTERFACE_MODE_NONE;
+}