summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/cpu/armv7/mx6/clock.c74
-rw-r--r--arch/arm/cpu/armv7/mx6/soc.c25
-rw-r--r--arch/arm/include/asm/arch-mx6/clock.h4
-rw-r--r--arch/arm/include/asm/arch-mx6/crm_regs.h11
-rw-r--r--arch/arm/include/asm/arch-mx6/imx-regs.h17
-rw-r--r--arch/arm/include/asm/arch-mx6/iomux.h12
-rw-r--r--board/freescale/mx6slevk/mx6slevk.c2
-rw-r--r--board/freescale/mx6sx_17x17_arm2/mx6sx_17x17_arm2.c7
-rw-r--r--include/configs/mx6slevk.h1
9 files changed, 144 insertions, 9 deletions
diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c
index 2feb61f..026174a 100644
--- a/arch/arm/cpu/armv7/mx6/clock.c
+++ b/arch/arm/cpu/armv7/mx6/clock.c
@@ -299,9 +299,19 @@ static u32 get_mmdc_ch0_clk(void)
}
-int enable_fec_clock(void)
+void enable_fec_25m_clock()
{
u32 reg = 0;
+ reg = readl(ANATOP_BASE_ADDR + 0xe0);
+ reg |= BM_ANADIG_PLL_ENET_REF_25M_ENABLE;
+ writel(reg, ANATOP_BASE_ADDR + 0xe0);
+}
+
+int enable_fec_clock(int fec_id)
+{
+ u32 reg = 0;
+
+#ifdef CONFIG_FEC_CLOCK_FROM_ANATOP
s32 timeout = 100000;
reg = readl(ANATOP_BASE_ADDR + 0xe0);
@@ -319,9 +329,67 @@ int enable_fec_clock(void)
}
/* Enable FEC clock */
- reg |= BM_ANADIG_PLL_ENET_ENABLE;
+ if (0 == fec_id)
+ reg |= BM_ANADIG_PLL_ENET_ENABLE;
+ else
+ reg |= BM_ANADIG_PLL_ENET2_ENABLE;
reg &= ~BM_ANADIG_PLL_ENET_BYPASS;
writel(reg, ANATOP_BASE_ADDR + 0xe0);
+#endif
+
+#ifdef CONFIG_MX6SX
+ /* set enet ahb clock 200Mhz
+ * pll2_pfd2_396m-> ENET_PODF-> ENET_AHB
+ */
+ reg = __raw_readl(&imx_ccm->chsccdr);
+ reg &= ~(MXC_CCM_CHSCCDR_ENET_PRE_CLK_SEL_MASK
+ | MXC_CCM_CHSCCDR_ENET_PODF_MASK | MXC_CCM_CHSCCDR_ENET_CLK_SEL_MASK);
+ /* PLL2 PFD2 */
+ reg |= (4 << MXC_CCM_CHSCCDR_ENET_PRE_CLK_SEL_OFFSET);
+ /* Div = 2*/
+ reg |= (1 << MXC_CCM_CHSCCDR_ENET_PODF_OFFSET);
+ reg |= (0 << MXC_CCM_CHSCCDR_ENET_CLK_SEL_OFFSET);
+ writel(reg, &imx_ccm->chsccdr);
+
+ /* Enable enet system clock */
+ reg = readl(&imx_ccm->CCGR3);
+ reg |= MXC_CCM_CCGR3_ENET_MASK;
+ writel(reg, &imx_ccm->CCGR3);
+#endif
+ return 0;
+}
+
+int fec_set_rate(int fec_id, unsigned long rate)
+{
+ unsigned int reg, div = 1;
+
+ switch (rate) {
+ case 25000000:
+ div = 0;
+ break;
+ case 50000000:
+ div = 1;
+ break;
+ case 100000000:
+ div = 2;
+ break;
+ case 125000000:
+ div = 3;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ reg = readl(ANATOP_BASE_ADDR + 0xe0);
+
+ if (0 == fec_id) {
+ reg &= ~BM_ANADIG_PLL_ENET_DIV_SELECT;
+ reg |= BF_ANADIG_PLL_ENET_DIV_SELECT(div);
+ } else {
+ reg &= ~BM_ANADIG_PLL_ENET2_DIV_SELECT;
+ reg |= BF_ANADIG_PLL_ENET2_DIV_SELECT(div);
+ }
+ writel(reg, ANATOP_BASE_ADDR + 0xe0);
return 0;
}
@@ -335,7 +403,7 @@ static u32 get_mmdc_ch0_clk(void)
return get_periph_clk() / (mmdc_ch0_podf + 1);
}
-int enable_fec_clock(void)
+int enable_fec_clock(int fec_id)
{
return 0;
}
diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c
index e5826a6..c1b4bb7 100644
--- a/arch/arm/cpu/armv7/mx6/soc.c
+++ b/arch/arm/cpu/armv7/mx6/soc.c
@@ -436,6 +436,29 @@ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
struct fuse_bank4_regs *fuse =
(struct fuse_bank4_regs *)bank->fuse_regs;
+#ifdef CONFIG_MX6SX
+ if (0 == dev_id) {
+ u32 value = readl(&fuse->mac_addr1);
+ mac[0] = (value >> 8);
+ mac[1] = value ;
+
+ value = readl(&fuse->mac_addr0);
+ mac[2] = value >> 24 ;
+ mac[3] = value >> 16 ;
+ mac[4] = value >> 8 ;
+ mac[5] = value ;
+ } else {
+ u32 value = readl(&fuse->mac_addr2);
+ mac[0] = value >> 24 ;
+ mac[1] = value >> 16 ;
+ mac[2] = value >> 8 ;
+ mac[3] = value ;
+
+ value = readl(&fuse->mac_addr1);
+ mac[4] = value >> 24 ;
+ mac[5] = value >> 16 ;
+ }
+#else
u32 value = readl(&fuse->mac_addr_high);
mac[0] = (value >> 8);
mac[1] = value ;
@@ -445,7 +468,7 @@ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
mac[3] = value >> 16 ;
mac[4] = value >> 8 ;
mac[5] = value ;
-
+#endif
}
#endif
diff --git a/arch/arm/include/asm/arch-mx6/clock.h b/arch/arm/include/asm/arch-mx6/clock.h
index fcf4046..941ff14 100644
--- a/arch/arm/include/asm/arch-mx6/clock.h
+++ b/arch/arm/include/asm/arch-mx6/clock.h
@@ -65,7 +65,9 @@ void enable_ocotp_clk(unsigned char enable);
void enable_usboh3_clk(unsigned char enable);
int enable_sata_clock(void);
int enable_i2c_clk(unsigned char enable, unsigned i2c_num);
-int enable_fec_clock(void);
+int enable_fec_clock(int fec_id);
+int fec_set_rate(int fec_id, unsigned long rate);
+void enable_fec_25m_clock(void);
void enable_ipu_clock(void);
void enable_qspi_clk(void);
#endif /* __ASM_ARCH_CLOCK_H */
diff --git a/arch/arm/include/asm/arch-mx6/crm_regs.h b/arch/arm/include/asm/arch-mx6/crm_regs.h
index 12b508c..f9156ef 100644
--- a/arch/arm/include/asm/arch-mx6/crm_regs.h
+++ b/arch/arm/include/asm/arch-mx6/crm_regs.h
@@ -125,7 +125,11 @@ struct mxc_ccm_reg {
#define MXC_CCM_CCR_WB_COUNT_MASK 0x7
#define MXC_CCM_CCR_WB_COUNT_OFFSET (1 << 16)
#define MXC_CCM_CCR_COSC_EN (1 << 12)
+#ifdef CONFIG_MX6SX
+#define MXC_CCM_CCR_OSCNT_MASK 0x7F
+#else
#define MXC_CCM_CCR_OSCNT_MASK 0xFF
+#endif
#define MXC_CCM_CCR_OSCNT_OFFSET 0
/* Define the bits in register CCDR */
@@ -1007,6 +1011,8 @@ struct mxc_ccm_reg {
#define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__ANACLK_1 0x1
#define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__ANACLK_2 0x2
#define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__XOR 0x3
+#define BM_ANADIG_PLL_ENET_REF_25M_ENABLE 0x00200000
+#define BM_ANADIG_PLL_ENET2_ENABLE 0x00100000
#define BM_ANADIG_PLL_ENET_ENABLE 0x00002000
#define BM_ANADIG_PLL_ENET_POWERDOWN 0x00001000
#define BM_ANADIG_PLL_ENET_HOLD_RING_OFF 0x00000800
@@ -1023,6 +1029,11 @@ struct mxc_ccm_reg {
#define BF_ANADIG_PLL_ENET_DIV_SELECT(v) \
(((v) << 0) & BM_ANADIG_PLL_ENET_DIV_SELECT)
+#define BM_ANADIG_PLL_ENET2_DIV_SELECT 0x0000000C
+#define BF_ANADIG_PLL_ENET2_DIV_SELECT(v) \
+ (((v) << 2) & BM_ANADIG_PLL_ENET2_DIV_SELECT)
+
+
#define BM_ANADIG_PFD_480_PFD3_CLKGATE 0x80000000
#define BM_ANADIG_PFD_480_PFD3_STABLE 0x40000000
#define BP_ANADIG_PFD_480_PFD3_FRAC 24
diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h
index eb1f7ad..f6eec71 100644
--- a/arch/arm/include/asm/arch-mx6/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx6/imx-regs.h
@@ -647,6 +647,22 @@ struct fuse_bank1_regs {
u32 ana2;
};
+#ifdef CONFIG_MX6SX
+struct fuse_bank4_regs {
+ u32 sjc_resp_low;
+ u32 rsvd0[3];
+ u32 sjc_resp_high;
+ u32 rsvd1[3];
+ u32 mac_addr0;
+ u32 rsvd2[3];
+ u32 mac_addr1;
+ u32 rsvd3[3];
+ u32 mac_addr2;
+ u32 rsvd4[7];
+ u32 gp1;
+ u32 rsvd5[7];
+};
+#else
struct fuse_bank4_regs {
u32 sjc_resp_low;
u32 rsvd0[3];
@@ -659,6 +675,7 @@ struct fuse_bank4_regs {
u32 gp1;
u32 rsvd4[7];
};
+#endif
struct aipstz_regs {
u32 mprot0;
diff --git a/arch/arm/include/asm/arch-mx6/iomux.h b/arch/arm/include/asm/arch-mx6/iomux.h
index 1fba965..2e90c38 100644
--- a/arch/arm/include/asm/arch-mx6/iomux.h
+++ b/arch/arm/include/asm/arch-mx6/iomux.h
@@ -169,4 +169,16 @@
#define IOMUX_GPR1_FEC_CLOCK_MUX2_SEL_MASK (0x1 << 14)
#define IOMUX_GPR1_FEC_MASK (IOMUX_GPR1_FEC_CLOCK_MUX1_SEL_MASK \
| IOMUX_GPR1_FEC_CLOCK_MUX2_SEL_MASK)
+
+#define IOMUX_GPR1_FEC1_CLOCK_MUX1_SEL_MASK (0x1 << 17)
+#define IOMUX_GPR1_FEC1_CLOCK_MUX2_SEL_MASK (0x1 << 13)
+#define IOMUX_GPR1_FEC1_MASK (IOMUX_GPR1_FEC1_CLOCK_MUX1_SEL_MASK \
+ | IOMUX_GPR1_FEC1_CLOCK_MUX2_SEL_MASK)
+
+#define IOMUX_GPR1_FEC2_CLOCK_MUX1_SEL_MASK (0x1 << 18)
+#define IOMUX_GPR1_FEC2_CLOCK_MUX2_SEL_MASK (0x1 << 14)
+#define IOMUX_GPR1_FEC2_MASK (IOMUX_GPR1_FEC2_CLOCK_MUX1_SEL_MASK \
+ | IOMUX_GPR1_FEC2_CLOCK_MUX2_SEL_MASK)
+
+
#endif /* __ASM_ARCH_IOMUX_H__ */
diff --git a/board/freescale/mx6slevk/mx6slevk.c b/board/freescale/mx6slevk/mx6slevk.c
index 33c82d9..68c100e 100644
--- a/board/freescale/mx6slevk/mx6slevk.c
+++ b/board/freescale/mx6slevk/mx6slevk.c
@@ -611,7 +611,7 @@ static int setup_fec(void)
/* clear gpr1[14], gpr1[18:17] to select anatop clock */
clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC_MASK, 0);
- ret = enable_fec_clock();
+ ret = enable_fec_clock(0);
if (ret)
return ret;
diff --git a/board/freescale/mx6sx_17x17_arm2/mx6sx_17x17_arm2.c b/board/freescale/mx6sx_17x17_arm2/mx6sx_17x17_arm2.c
index f78375b..38391ad 100644
--- a/board/freescale/mx6sx_17x17_arm2/mx6sx_17x17_arm2.c
+++ b/board/freescale/mx6sx_17x17_arm2/mx6sx_17x17_arm2.c
@@ -248,7 +248,8 @@ int board_eth_init(bd_t *bis)
setup_iomux_fec1();
- ret = cpu_eth_init(bis);
+ ret = fecmxc_initialize_multi(bis, 0,
+ CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE);
if (ret)
printf("FEC1 MXC: %s:failed\n", __func__);
@@ -271,12 +272,12 @@ static int setup_fec(void)
clrbits_le32(&iomuxc_gpr_regs->gpr[1], IOMUX_GPR1_FEC1_CLOCK_MUX1_SEL_MASK);
#endif
- ret = enable_fec_clock();
+ ret = enable_fec_clock(0);
if (ret)
return ret;
#ifdef CONFIG_FEC_CLOCK_FROM_ANATOP
- fec_set_rate(125000000);
+ fec_set_rate(0, 125000000);
#endif
#ifdef CONFIG_FEC_ENABLE_MAX7322
diff --git a/include/configs/mx6slevk.h b/include/configs/mx6slevk.h
index aad4615..7bbb993 100644
--- a/include/configs/mx6slevk.h
+++ b/include/configs/mx6slevk.h
@@ -79,6 +79,7 @@
#define CONFIG_FEC_XCV_TYPE RMII
#define CONFIG_ETHPRIME "FEC"
#define CONFIG_FEC_MXC_PHYADDR 0
+#define CONFIG_FEC_CLOCK_FROM_ANATOP
#define CONFIG_PHYLIB
#define CONFIG_PHY_SMSC