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 <fsl_esdhc_imx.h>
24 #include <linux/libfdt.h>
25 #include <malloc.h>
26 #include <i2c.h>
27 #include <micrel.h>
28 #include <miiphy.h>
29 #include <mmc.h>
30 #include <netdev.h>
31 
32 #include "tqma6_bb.h"
33 
34 #if defined(CONFIG_TQMA6Q)
35 
36 #define IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII	0x02e0790
37 #define IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM	0x02e07ac
38 
39 #elif defined(CONFIG_TQMA6S) || defined(CONFIG_TQMA6DL)
40 
41 #define IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII	0x02e0768
42 #define IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM	0x02e0788
43 
44 #else
45 
46 #error "need to select module"
47 
48 #endif
49 
50 /* disable on die termination for RGMII */
51 #define IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM_DISABLE	0x00000000
52 /* optimised drive strength for 1.0 .. 1.3 V signal on RGMII */
53 #define IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII_1P2V	0x00080000
54 /* optimised drive strength for 1.3 .. 2.5 V signal on RGMII */
55 #define IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII_1P5V	0x000C0000
56 
mba6_setup_iomuxc_enet(void)57 static void mba6_setup_iomuxc_enet(void)
58 {
59 	struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
60 
61 	/* clear gpr1[ENET_CLK_SEL] for externel clock */
62 	clrbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_ENET_CLK_SEL_MASK);
63 
64 	__raw_writel(IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM_DISABLE,
65 		     (void *)IOMUX_SW_PAD_CTRL_GRP_RGMII_TERM);
66 	__raw_writel(IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII_1P5V,
67 		     (void *)IOMUX_SW_PAD_CTRL_GRP_DDR_TYPE_RGMII);
68 }
69 
board_mmc_get_env_dev(int devno)70 int board_mmc_get_env_dev(int devno)
71 {
72 	/*
73 	 * This assumes that the baseboard registered
74 	 * the boot device first ...
75 	 * Note: SDHC3 == idx2
76 	 */
77 	return (2 == devno) ? 0 : 1;
78 }
79 
board_phy_config(struct phy_device * phydev)80 int board_phy_config(struct phy_device *phydev)
81 {
82 /*
83  * optimized pad skew values depends on CPU variant on the TQMa6x module:
84  * CONFIG_TQMA6Q: i.MX6Q/D
85  * CONFIG_TQMA6S: i.MX6S
86  * CONFIG_TQMA6DL: i.MX6DL
87  */
88 #if defined(CONFIG_TQMA6Q)
89 #define MBA6X_KSZ9031_CTRL_SKEW	0x0032
90 #define MBA6X_KSZ9031_CLK_SKEW	0x03ff
91 #define MBA6X_KSZ9031_RX_SKEW	0x3333
92 #define MBA6X_KSZ9031_TX_SKEW	0x2036
93 #elif defined(CONFIG_TQMA6S) || defined(CONFIG_TQMA6DL)
94 #define MBA6X_KSZ9031_CTRL_SKEW	0x0030
95 #define MBA6X_KSZ9031_CLK_SKEW	0x03ff
96 #define MBA6X_KSZ9031_RX_SKEW	0x3333
97 #define MBA6X_KSZ9031_TX_SKEW	0x2052
98 #else
99 #error
100 #endif
101 	/* min rx/tx ctrl delay */
102 	ksz9031_phy_extended_write(phydev, 2,
103 				   MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW,
104 				   MII_KSZ9031_MOD_DATA_NO_POST_INC,
105 				   MBA6X_KSZ9031_CTRL_SKEW);
106 	/* min rx delay */
107 	ksz9031_phy_extended_write(phydev, 2,
108 				   MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW,
109 				   MII_KSZ9031_MOD_DATA_NO_POST_INC,
110 				   MBA6X_KSZ9031_RX_SKEW);
111 	/* max tx delay */
112 	ksz9031_phy_extended_write(phydev, 2,
113 				   MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW,
114 				   MII_KSZ9031_MOD_DATA_NO_POST_INC,
115 				   MBA6X_KSZ9031_TX_SKEW);
116 	/* rx/tx clk skew */
117 	ksz9031_phy_extended_write(phydev, 2,
118 				   MII_KSZ9031_EXT_RGMII_CLOCK_SKEW,
119 				   MII_KSZ9031_MOD_DATA_NO_POST_INC,
120 				   MBA6X_KSZ9031_CLK_SKEW);
121 
122 	phydev->drv->config(phydev);
123 
124 	return 0;
125 }
126 
tqma6_bb_board_early_init_f(void)127 int tqma6_bb_board_early_init_f(void)
128 {
129 	return 0;
130 }
131 
tqma6_bb_board_init(void)132 int tqma6_bb_board_init(void)
133 {
134 	mba6_setup_iomuxc_enet();
135 
136 	return 0;
137 }
138 
tqma6_bb_board_late_init(void)139 int tqma6_bb_board_late_init(void)
140 {
141 	return 0;
142 }
143 
tqma6_bb_get_boardname(void)144 const char *tqma6_bb_get_boardname(void)
145 {
146 	return "MBa6x";
147 }
148 
149 /*
150  * Device Tree Support
151  */
152 #if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT)
tqma6_bb_ft_board_setup(void * blob,struct bd_info * bd)153 void tqma6_bb_ft_board_setup(void *blob, struct bd_info *bd)
154 {
155  /* TBD */
156 }
157 #endif /* defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT) */
158