diff options
-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 |