1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2012 Freescale Semiconductor, Inc. 4 * Author: Fabio Estevam <fabio.estevam@freescale.com> 5 * 6 * Copyright (C) 2013, 2014 TQ-Systems (ported SabreSD to TQMa6x) 7 * Author: Markus Niebel <markus.niebel@tq-group.com> 8 */ 9 10#include <init.h> 11#include <net.h> 12#include <asm/io.h> 13#include <asm/arch/clock.h> 14#include <asm/arch/mx6-pins.h> 15#include <asm/arch/imx-regs.h> 16#include <asm/arch/iomux.h> 17#include <asm/arch/sys_proto.h> 18#include <linux/delay.h> 19#include <linux/errno.h> 20#include <asm/gpio.h> 21#include <asm/mach-imx/mxc_i2c.h> 22 23#include <common.h> 24#include <fsl_esdhc_imx.h> 25#include <linux/libfdt.h> 26#include <malloc.h> 27#include <i2c.h> 28#include <micrel.h> 29#include <miiphy.h> 30#include <mmc.h> 31#include <netdev.h> 32 33#include "tqma6_bb.h" 34 35#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ 36 PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS) 37 38#define USDHC_CLK_PAD_CTRL (PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \ 39 PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS) 40 41#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \ 42 PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS) 43 44#define GPIO_OUT_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_LOW | \ 45 PAD_CTL_DSE_40ohm | PAD_CTL_HYS) 46 47#define GPIO_IN_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_LOW | \ 48 PAD_CTL_DSE_40ohm | PAD_CTL_HYS) 49 50#define SPI_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ 51 PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS) 52 53#define I2C_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ 54 PAD_CTL_DSE_80ohm | PAD_CTL_HYS | \ 55 PAD_CTL_ODE | PAD_CTL_SRE_FAST) 56 57#if defined(CONFIG_TQMA6Q) 58 59#define IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII 0x02e0790 60#define IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM 0x02e07ac 61 62#elif defined(CONFIG_TQMA6S) || defined(CONFIG_TQMA6DL) 63 64#define IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII 0x02e0768 65#define IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM 0x02e0788 66 67#else 68 69#error "need to select module" 70 71#endif 72 73/* disable on die termination for RGMII */ 74#define IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM_DISABLE 0x00000000 75/* optimised drive strength for 1.0 .. 1.3 V signal on RGMII */ 76#define IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII_1P2V 0x00080000 77/* optimised drive strength for 1.3 .. 2.5 V signal on RGMII */ 78#define IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII_1P5V 0x000C0000 79 80static void mba6_setup_iomuxc_enet(void) 81{ 82 struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; 83 84 /* clear gpr1[ENET_CLK_SEL] for externel clock */ 85 clrbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_ENET_CLK_SEL_MASK); 86 87 __raw_writel(IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM_DISABLE, 88 (void *)IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM); 89 __raw_writel(IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII_1P5V, 90 (void *)IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII); 91} 92 93static iomux_v3_cfg_t const mba6_uart2_pads[] = { 94 NEW_PAD_CTRL(MX6_PAD_SD4_DAT4__UART2_RX_DATA, UART_PAD_CTRL), 95 NEW_PAD_CTRL(MX6_PAD_SD4_DAT7__UART2_TX_DATA, UART_PAD_CTRL), 96}; 97 98static void mba6_setup_iomuxc_uart(void) 99{ 100 imx_iomux_v3_setup_multiple_pads(mba6_uart2_pads, 101 ARRAY_SIZE(mba6_uart2_pads)); 102} 103 104int board_mmc_get_env_dev(int devno) 105{ 106 /* 107 * This assumes that the baseboard registered 108 * the boot device first ... 109 * Note: SDHC3 == idx2 110 */ 111 return (2 == devno) ? 0 : 1; 112} 113 114int board_phy_config(struct phy_device *phydev) 115{ 116/* 117 * optimized pad skew values depends on CPU variant on the TQMa6x module: 118 * CONFIG_TQMA6Q: i.MX6Q/D 119 * CONFIG_TQMA6S: i.MX6S 120 * CONFIG_TQMA6DL: i.MX6DL 121 */ 122#if defined(CONFIG_TQMA6Q) 123#define MBA6X_KSZ9031_CTRL_SKEW 0x0032 124#define MBA6X_KSZ9031_CLK_SKEW 0x03ff 125#define MBA6X_KSZ9031_RX_SKEW 0x3333 126#define MBA6X_KSZ9031_TX_SKEW 0x2036 127#elif defined(CONFIG_TQMA6S) || defined(CONFIG_TQMA6DL) 128#define MBA6X_KSZ9031_CTRL_SKEW 0x0030 129#define MBA6X_KSZ9031_CLK_SKEW 0x03ff 130#define MBA6X_KSZ9031_RX_SKEW 0x3333 131#define MBA6X_KSZ9031_TX_SKEW 0x2052 132#else 133#error 134#endif 135 /* min rx/tx ctrl delay */ 136 ksz9031_phy_extended_write(phydev, 2, 137 MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW, 138 MII_KSZ9031_MOD_DATA_NO_POST_INC, 139 MBA6X_KSZ9031_CTRL_SKEW); 140 /* min rx delay */ 141 ksz9031_phy_extended_write(phydev, 2, 142 MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW, 143 MII_KSZ9031_MOD_DATA_NO_POST_INC, 144 MBA6X_KSZ9031_RX_SKEW); 145 /* max tx delay */ 146 ksz9031_phy_extended_write(phydev, 2, 147 MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW, 148 MII_KSZ9031_MOD_DATA_NO_POST_INC, 149 MBA6X_KSZ9031_TX_SKEW); 150 /* rx/tx clk skew */ 151 ksz9031_phy_extended_write(phydev, 2, 152 MII_KSZ9031_EXT_RGMII_CLOCK_SKEW, 153 MII_KSZ9031_MOD_DATA_NO_POST_INC, 154 MBA6X_KSZ9031_CLK_SKEW); 155 156 phydev->drv->config(phydev); 157 158 return 0; 159} 160 161int tqma6_bb_board_early_init_f(void) 162{ 163 mba6_setup_iomuxc_uart(); 164 165 return 0; 166} 167 168int tqma6_bb_board_init(void) 169{ 170 mba6_setup_iomuxc_enet(); 171 172 return 0; 173} 174 175int tqma6_bb_board_late_init(void) 176{ 177 return 0; 178} 179 180const char *tqma6_bb_get_boardname(void) 181{ 182 return "MBa6x"; 183} 184 185/* 186 * Device Tree Support 187 */ 188#if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT) 189void tqma6_bb_ft_board_setup(void *blob, struct bd_info *bd) 190{ 191 /* TBD */ 192} 193#endif /* defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT) */ 194