aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/mach-imx/imx8m/clock_imx8mm.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-imx/imx8m/clock_imx8mm.c')
-rw-r--r--arch/arm/mach-imx/imx8m/clock_imx8mm.c202
1 files changed, 85 insertions, 117 deletions
diff --git a/arch/arm/mach-imx/imx8m/clock_imx8mm.c b/arch/arm/mach-imx/imx8m/clock_imx8mm.c
index 64ad57e9b3..31c34b6031 100644
--- a/arch/arm/mach-imx/imx8m/clock_imx8mm.c
+++ b/arch/arm/mach-imx/imx8m/clock_imx8mm.c
@@ -15,6 +15,7 @@
#include <errno.h>
#include <linux/bitops.h>
#include <linux/delay.h>
+#include <phy.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -36,14 +37,14 @@ void enable_ocotp_clk(unsigned char enable)
int enable_i2c_clk(unsigned char enable, unsigned i2c_num)
{
- u8 i2c_ccgr[6] = {
+ u8 i2c_ccgr[] = {
CCGR_I2C1, CCGR_I2C2, CCGR_I2C3, CCGR_I2C4,
#if (IS_ENABLED(CONFIG_IMX8MP))
CCGR_I2C5_8MP, CCGR_I2C6_8MP
#endif
};
- if (i2c_num > ARRAY_SIZE(i2c_ccgr))
+ if (i2c_num >= ARRAY_SIZE(i2c_ccgr))
return -EINVAL;
clock_enable(i2c_ccgr[i2c_num], !!enable);
@@ -825,141 +826,108 @@ u32 mxc_get_clock(enum mxc_clock clk)
return 0;
}
-#ifdef CONFIG_DWC_ETH_QOS
-int set_clk_eqos(enum enet_freq type)
+#if defined(CONFIG_IMX8MP) && defined(CONFIG_DWC_ETH_QOS)
+static int imx8mp_eqos_interface_init(struct udevice *dev,
+ phy_interface_t interface_type)
{
- u32 target;
- u32 enet1_ref;
-
- switch (type) {
- case ENET_125MHZ:
- enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_125M_CLK;
- break;
- case ENET_50MHZ:
- enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_50M_CLK;
- break;
- case ENET_25MHZ:
- enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_25M_CLK;
+ struct iomuxc_gpr_base_regs *gpr =
+ (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR;
+
+ clrbits_le32(&gpr->gpr[1],
+ IOMUXC_GPR_GPR1_GPR_ENET_QOS_INTF_SEL_MASK |
+ IOMUXC_GPR_GPR1_GPR_ENET_QOS_RGMII_EN |
+ IOMUXC_GPR_GPR1_GPR_ENET_QOS_CLK_TX_CLK_SEL |
+ IOMUXC_GPR_GPR1_GPR_ENET_QOS_CLK_GEN_EN);
+
+ switch (interface_type) {
+ case PHY_INTERFACE_MODE_MII:
+ setbits_le32(&gpr->gpr[1],
+ IOMUXC_GPR_GPR1_GPR_ENET_QOS_CLK_GEN_EN |
+ IOMUXC_GPR_GPR1_GPR_ENET_QOS_INTF_SEL_MII);
+ break;
+ case PHY_INTERFACE_MODE_RMII:
+ setbits_le32(&gpr->gpr[1],
+ IOMUXC_GPR_GPR1_GPR_ENET_QOS_CLK_TX_CLK_SEL |
+ IOMUXC_GPR_GPR1_GPR_ENET_QOS_CLK_GEN_EN |
+ IOMUXC_GPR_GPR1_GPR_ENET_QOS_INTF_SEL_RMII);
+ break;
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ setbits_le32(&gpr->gpr[1],
+ IOMUXC_GPR_GPR1_GPR_ENET_QOS_RGMII_EN |
+ IOMUXC_GPR_GPR1_GPR_ENET_QOS_CLK_GEN_EN |
+ IOMUXC_GPR_GPR1_GPR_ENET_QOS_INTF_SEL_RGMII);
break;
default:
return -EINVAL;
}
- /* disable the clock first */
- clock_enable(CCGR_QOS_ETHENET, 0);
- clock_enable(CCGR_SDMA2, 0);
-
- /* set enet axi clock 266Mhz */
- target = CLK_ROOT_ON | ENET_AXI_CLK_ROOT_FROM_SYS1_PLL_266M |
- CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
- CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1);
- clock_set_target_val(ENET_AXI_CLK_ROOT, target);
-
- target = CLK_ROOT_ON | enet1_ref |
- CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
- CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1);
- clock_set_target_val(ENET_QOS_CLK_ROOT, target);
-
- target = CLK_ROOT_ON |
- ENET1_TIME_CLK_ROOT_FROM_PLL_ENET_MAIN_100M_CLK |
- CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
- CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4);
- clock_set_target_val(ENET_QOS_TIMER_CLK_ROOT, target);
-
- /* enable clock */
- clock_enable(CCGR_QOS_ETHENET, 1);
- clock_enable(CCGR_SDMA2, 1);
-
return 0;
}
-
-int imx_eqos_txclk_set_rate(ulong rate)
+#else
+static int imx8mp_eqos_interface_init(struct udevice *dev,
+ phy_interface_t interface_type)
{
- u32 val;
- u32 eqos_post_div;
-
- /* disable the clock first */
- clock_enable(CCGR_QOS_ETHENET, 0);
- clock_enable(CCGR_SDMA2, 0);
-
- switch (rate) {
- case 125000000:
- eqos_post_div = 1;
- break;
- case 25000000:
- eqos_post_div = 125000000 / 25000000;
- break;
- case 2500000:
- eqos_post_div = 125000000 / 2500000;
- break;
- default:
- return -EINVAL;
- }
-
- clock_get_target_val(ENET_QOS_CLK_ROOT, &val);
- val &= ~(CLK_ROOT_PRE_DIV_MASK | CLK_ROOT_POST_DIV_MASK);
- val |= CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
- CLK_ROOT_POST_DIV(eqos_post_div - 1);
- clock_set_target_val(ENET_QOS_CLK_ROOT, val);
-
- /* enable clock */
- clock_enable(CCGR_QOS_ETHENET, 1);
- clock_enable(CCGR_SDMA2, 1);
-
return 0;
}
-
-u32 imx_get_eqos_csr_clk(void)
-{
- return get_root_clk(ENET_AXI_CLK_ROOT);
-}
#endif
#ifdef CONFIG_FEC_MXC
-int set_clk_enet(enum enet_freq type)
+static int imx8mp_fec_interface_init(struct udevice *dev,
+ phy_interface_t interface_type,
+ bool mx8mp)
{
- u32 target;
- u32 enet1_ref;
-
- switch (type) {
- case ENET_125MHZ:
- enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_125M_CLK;
- break;
- case ENET_50MHZ:
- enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_50M_CLK;
- break;
- case ENET_25MHZ:
- enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_25M_CLK;
+ /* i.MX8MP has extra RGMII_EN bit in IOMUXC GPR1 register */
+ const u32 rgmii_en = mx8mp ? IOMUXC_GPR_GPR1_GPR_ENET1_RGMII_EN : 0;
+ struct iomuxc_gpr_base_regs *gpr =
+ (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR;
+
+ clrbits_le32(&gpr->gpr[1],
+ rgmii_en |
+ IOMUXC_GPR_GPR1_GPR_ENET1_TX_CLK_SEL);
+
+ switch (interface_type) {
+ case PHY_INTERFACE_MODE_MII:
+ case PHY_INTERFACE_MODE_RMII:
+ setbits_le32(&gpr->gpr[1], IOMUXC_GPR_GPR1_GPR_ENET1_TX_CLK_SEL);
+ break;
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ setbits_le32(&gpr->gpr[1], rgmii_en);
break;
default:
return -EINVAL;
}
- /* disable the clock first */
- clock_enable(CCGR_ENET1, 0);
- clock_enable(CCGR_SIM_ENET, 0);
-
- /* set enet axi clock 266Mhz */
- target = CLK_ROOT_ON | ENET_AXI_CLK_ROOT_FROM_SYS1_PLL_266M |
- CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
- CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1);
- clock_set_target_val(ENET_AXI_CLK_ROOT, target);
-
- target = CLK_ROOT_ON | enet1_ref |
- CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
- CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1);
- clock_set_target_val(ENET_REF_CLK_ROOT, target);
-
- target = CLK_ROOT_ON |
- ENET1_TIME_CLK_ROOT_FROM_PLL_ENET_MAIN_100M_CLK |
- CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
- CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4);
- clock_set_target_val(ENET_TIMER_CLK_ROOT, target);
-
- /* enable clock */
- clock_enable(CCGR_SIM_ENET, 1);
- clock_enable(CCGR_ENET1, 1);
-
return 0;
}
#endif
+
+int board_interface_eth_init(struct udevice *dev, phy_interface_t interface_type)
+{
+ if (IS_ENABLED(CONFIG_IMX8MM) &&
+ IS_ENABLED(CONFIG_FEC_MXC) &&
+ device_is_compatible(dev, "fsl,imx8mm-fec"))
+ return imx8mp_fec_interface_init(dev, interface_type, false);
+
+ if (IS_ENABLED(CONFIG_IMX8MN) &&
+ IS_ENABLED(CONFIG_FEC_MXC) &&
+ device_is_compatible(dev, "fsl,imx8mn-fec"))
+ return imx8mp_fec_interface_init(dev, interface_type, false);
+
+ if (IS_ENABLED(CONFIG_IMX8MP) &&
+ IS_ENABLED(CONFIG_FEC_MXC) &&
+ device_is_compatible(dev, "fsl,imx8mp-fec"))
+ return imx8mp_fec_interface_init(dev, interface_type, true);
+
+ if (IS_ENABLED(CONFIG_IMX8MP) &&
+ IS_ENABLED(CONFIG_DWC_ETH_QOS) &&
+ device_is_compatible(dev, "nxp,imx8mp-dwmac-eqos"))
+ return imx8mp_eqos_interface_init(dev, interface_type);
+
+ return -EINVAL;
+}