diff options
author | Ye.Li <B37916@freescale.com> | 2014-02-26 18:30:54 +0800 |
---|---|---|
committer | Ye.Li <B37916@freescale.com> | 2014-03-05 16:09:14 +0800 |
commit | a116c531da6e7685e8c562ddbcdf8f8afb5b485e (patch) | |
tree | 5141bca1ef31bce6bf95f83e28a1323f348b7d23 | |
parent | f94e50c82f14136d95afa54c5539bf00c764594d (diff) | |
download | u-boot-imx-a116c531da6e7685e8c562ddbcdf8f8afb5b485e.zip u-boot-imx-a116c531da6e7685e8c562ddbcdf8f8afb5b485e.tar.gz u-boot-imx-a116c531da6e7685e8c562ddbcdf8f8afb5b485e.tar.bz2 |
ENGR00301441-2 iMX6SX/SL: Modify SOC to support two ENET
iMX6SX has different enet system clocks with iMX6SL, and has two ENET
controllers. So update clocks and soc APIs accordingly to support this
features.
1. Modify the clock API "enable_fec_clock" to enable enet system clock
for each enet controller.
2. Enet RGMII TX clock source may come from external or internal PLL.
By default, use the external phy CLK_25M output as TX clock source.
Add a configuration "CONFIG_FEC_CLOCK_FROM_ANATOP" for using internal
PLL
3. Add clock API "fec_set_rate" to set the RGMII clocks from internal PLL.
4. Modify the MAC address function "imx_get_mac_from_fuse" to get either
ENET MAC address.
5. Add clock API "enable_fec_25m_clock" to enable ENET 25Mhz reference clock.
6. Modify 17x17 arm2 BSP and imx6slevk BSP to fit the new APIs.
Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Ye.Li <B37916@freescale.com>
-rw-r--r-- | arch/arm/cpu/armv7/mx6/clock.c | 74 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/mx6/soc.c | 25 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-mx6/clock.h | 4 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-mx6/crm_regs.h | 11 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-mx6/imx-regs.h | 17 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-mx6/iomux.h | 12 | ||||
-rw-r--r-- | board/freescale/mx6slevk/mx6slevk.c | 2 | ||||
-rw-r--r-- | board/freescale/mx6sx_17x17_arm2/mx6sx_17x17_arm2.c | 7 | ||||
-rw-r--r-- | include/configs/mx6slevk.h | 1 |
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 |