// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2012 Freescale Semiconductor, Inc. * Author: Fabio Estevam * * Copyright (C) 2013, 2014 TQ-Systems (ported SabreSD to TQMa6x) * Author: Markus Niebel */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "tqma6_bb.h" #if defined(CONFIG_TQMA6Q) #define IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII 0x02e0790 #define IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM 0x02e07ac #elif defined(CONFIG_TQMA6S) || defined(CONFIG_TQMA6DL) #define IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII 0x02e0768 #define IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM 0x02e0788 #else #error "need to select module" #endif /* disable on die termination for RGMII */ #define IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM_DISABLE 0x00000000 /* optimised drive strength for 1.0 .. 1.3 V signal on RGMII */ #define IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII_1P2V 0x00080000 /* optimised drive strength for 1.3 .. 2.5 V signal on RGMII */ #define IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII_1P5V 0x000C0000 static void mba6_setup_iomuxc_enet(void) { struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; /* clear gpr1[ENET_CLK_SEL] for externel clock */ clrbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_ENET_CLK_SEL_MASK); __raw_writel(IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM_DISABLE, (void *)IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM); __raw_writel(IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII_1P5V, (void *)IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII); } int board_mmc_get_env_dev(int devno) { /* * This assumes that the baseboard registered * the boot device first ... * Note: SDHC3 == idx2 */ return (2 == devno) ? 0 : 1; } int board_phy_config(struct phy_device *phydev) { /* * optimized pad skew values depends on CPU variant on the TQMa6x module: * CONFIG_TQMA6Q: i.MX6Q/D * CONFIG_TQMA6S: i.MX6S * CONFIG_TQMA6DL: i.MX6DL */ #if defined(CONFIG_TQMA6Q) #define MBA6X_KSZ9031_CTRL_SKEW 0x0032 #define MBA6X_KSZ9031_CLK_SKEW 0x03ff #define MBA6X_KSZ9031_RX_SKEW 0x3333 #define MBA6X_KSZ9031_TX_SKEW 0x2036 #elif defined(CONFIG_TQMA6S) || defined(CONFIG_TQMA6DL) #define MBA6X_KSZ9031_CTRL_SKEW 0x0030 #define MBA6X_KSZ9031_CLK_SKEW 0x03ff #define MBA6X_KSZ9031_RX_SKEW 0x3333 #define MBA6X_KSZ9031_TX_SKEW 0x2052 #else #error #endif /* min rx/tx ctrl delay */ ksz9031_phy_extended_write(phydev, 2, MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW, MII_KSZ9031_MOD_DATA_NO_POST_INC, MBA6X_KSZ9031_CTRL_SKEW); /* min rx delay */ ksz9031_phy_extended_write(phydev, 2, MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW, MII_KSZ9031_MOD_DATA_NO_POST_INC, MBA6X_KSZ9031_RX_SKEW); /* max tx delay */ ksz9031_phy_extended_write(phydev, 2, MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW, MII_KSZ9031_MOD_DATA_NO_POST_INC, MBA6X_KSZ9031_TX_SKEW); /* rx/tx clk skew */ ksz9031_phy_extended_write(phydev, 2, MII_KSZ9031_EXT_RGMII_CLOCK_SKEW, MII_KSZ9031_MOD_DATA_NO_POST_INC, MBA6X_KSZ9031_CLK_SKEW); phydev->drv->config(phydev); return 0; } int tqma6_bb_board_early_init_f(void) { return 0; } int tqma6_bb_board_init(void) { mba6_setup_iomuxc_enet(); return 0; } int tqma6_bb_board_late_init(void) { return 0; } const char *tqma6_bb_get_boardname(void) { return "MBa6x"; } /* * Device Tree Support */ #if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT) void tqma6_bb_ft_board_setup(void *blob, struct bd_info *bd) { /* TBD */ } #endif /* defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT) */