1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2017 NXP Semiconductors
4  */
5 
6 #include <asm/arch/clock.h>
7 #include <asm/arch/crm_regs.h>
8 #include <asm/arch/imx-regs.h>
9 #include <asm/arch/mx7-pins.h>
10 #include <asm/arch/sys_proto.h>
11 #include <asm/gpio.h>
12 #include <asm/mach-imx/iomux-v3.h>
13 #include <asm/mach-imx/mxc_i2c.h>
14 #include <asm/io.h>
15 #include <common.h>
16 #include <fsl_esdhc.h>
17 #include <i2c.h>
18 #include <miiphy.h>
19 #include <mmc.h>
20 #include <netdev.h>
21 #include <usb.h>
22 #include <power/pmic.h>
23 #include <power/pfuze3000_pmic.h>
24 #include "../../freescale/common/pfuze.h"
25 
26 DECLARE_GLOBAL_DATA_PTR;
27 
28 #define UART_PAD_CTRL  (PAD_CTL_DSE_3P3V_49OHM | \
29 	PAD_CTL_PUS_PU100KOHM | PAD_CTL_HYS)
30 
31 #define USDHC_PAD_CTRL (PAD_CTL_DSE_3P3V_32OHM | PAD_CTL_SRE_SLOW | \
32 	PAD_CTL_HYS | PAD_CTL_PUE | PAD_CTL_PUS_PU47KOHM)
33 
34 #define ENET_PAD_CTRL  (PAD_CTL_PUS_PU100KOHM | PAD_CTL_DSE_3P3V_49OHM)
35 #define ENET_PAD_CTRL_MII  (PAD_CTL_DSE_3P3V_32OHM)
36 
37 #define ENET_RX_PAD_CTRL  (PAD_CTL_PUS_PU100KOHM | PAD_CTL_DSE_3P3V_49OHM)
38 
39 #define I2C_PAD_CTRL    (PAD_CTL_DSE_3P3V_32OHM | PAD_CTL_SRE_SLOW | \
40 	PAD_CTL_HYS | PAD_CTL_PUE | PAD_CTL_PUS_PU100KOHM)
41 
42 #ifdef CONFIG_SYS_I2C_MXC
43 #define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
44 /* I2C4 for PMIC */
45 static struct i2c_pads_info i2c_pad_info4 = {
46 	.scl = {
47 		.i2c_mode = MX7D_PAD_SAI1_RX_SYNC__I2C4_SCL | PC,
48 		.gpio_mode = MX7D_PAD_SAI1_RX_SYNC__GPIO6_IO16 | PC,
49 		.gp = IMX_GPIO_NR(6, 16),
50 	},
51 	.sda = {
52 		.i2c_mode = MX7D_PAD_SAI1_RX_BCLK__I2C4_SDA | PC,
53 		.gpio_mode = MX7D_PAD_SAI1_RX_BCLK__GPIO6_IO17 | PC,
54 		.gp = IMX_GPIO_NR(6, 17),
55 	},
56 };
57 #endif
58 
59 int dram_init(void)
60 {
61 	gd->ram_size = imx_ddr_size();
62 
63 	return 0;
64 }
65 
66 #ifdef CONFIG_POWER
67 #define I2C_PMIC	3
68 int power_init_board(void)
69 {
70 	struct pmic *p;
71 	int ret;
72 	unsigned int reg, rev_id;
73 
74 	ret = power_pfuze3000_init(I2C_PMIC);
75 	if (ret)
76 		return ret;
77 
78 	p = pmic_get("PFUZE3000");
79 	ret = pmic_probe(p);
80 	if (ret)
81 		return ret;
82 
83 	pmic_reg_read(p, PFUZE3000_DEVICEID, &reg);
84 	pmic_reg_read(p, PFUZE3000_REVID, &rev_id);
85 	printf("PMIC:  PFUZE3000 DEV_ID=0x%x REV_ID=0x%x\n", reg, rev_id);
86 
87 	/* disable Low Power Mode during standby mode */
88 	pmic_reg_read(p, PFUZE3000_LDOGCTL, &reg);
89 	reg |= 0x1;
90 	pmic_reg_write(p, PFUZE3000_LDOGCTL, reg);
91 
92 	/* SW1A/1B mode set to APS/APS */
93 	reg = 0x8;
94 	pmic_reg_write(p, PFUZE3000_SW1AMODE, reg);
95 	pmic_reg_write(p, PFUZE3000_SW1BMODE, reg);
96 
97 	/* SW1A/1B standby voltage set to 1.025V */
98 	reg = 0xd;
99 	pmic_reg_write(p, PFUZE3000_SW1ASTBY, reg);
100 	pmic_reg_write(p, PFUZE3000_SW1BSTBY, reg);
101 
102 	/* decrease SW1B normal voltage to 0.975V */
103 	pmic_reg_read(p, PFUZE3000_SW1BVOLT, &reg);
104 	reg &= ~0x1f;
105 	reg |= PFUZE3000_SW1AB_SETP(975);
106 	pmic_reg_write(p, PFUZE3000_SW1BVOLT, reg);
107 
108 	return 0;
109 }
110 #endif
111 
112 static iomux_v3_cfg_t const wdog_pads[] = {
113 	MX7D_PAD_GPIO1_IO00__WDOG1_WDOG_B | MUX_PAD_CTRL(NO_PAD_CTRL),
114 };
115 
116 static iomux_v3_cfg_t const uart5_pads[] = {
117 	MX7D_PAD_I2C4_SCL__UART5_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
118 	MX7D_PAD_I2C4_SDA__UART5_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
119 };
120 
121 static iomux_v3_cfg_t const usdhc3_emmc_pads[] = {
122 	MX7D_PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
123 	MX7D_PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
124 	MX7D_PAD_SD3_DATA0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
125 	MX7D_PAD_SD3_DATA1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
126 	MX7D_PAD_SD3_DATA2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
127 	MX7D_PAD_SD3_DATA3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
128 	MX7D_PAD_SD3_DATA4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
129 	MX7D_PAD_SD3_DATA5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
130 	MX7D_PAD_SD3_DATA6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
131 	MX7D_PAD_SD3_DATA7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
132 	MX7D_PAD_GPIO1_IO14__GPIO1_IO14 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
133 };
134 
135 #ifdef CONFIG_FEC_MXC
136 static iomux_v3_cfg_t const fec1_pads[] = {
137 	MX7D_PAD_SD2_CD_B__ENET1_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL_MII),
138 	MX7D_PAD_SD2_WP__ENET1_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL_MII),
139 	MX7D_PAD_ENET1_RGMII_TXC__ENET1_RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
140 	MX7D_PAD_ENET1_RGMII_TD0__ENET1_RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
141 	MX7D_PAD_ENET1_RGMII_TD1__ENET1_RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
142 	MX7D_PAD_ENET1_RGMII_TD2__ENET1_RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
143 	MX7D_PAD_ENET1_RGMII_TD3__ENET1_RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
144 	MX7D_PAD_ENET1_RGMII_TX_CTL__ENET1_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
145 	MX7D_PAD_ENET1_RGMII_RXC__ENET1_RGMII_RXC | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
146 	MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
147 	MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
148 	MX7D_PAD_ENET1_RGMII_RD2__ENET1_RGMII_RD2 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
149 	MX7D_PAD_ENET1_RGMII_RD3__ENET1_RGMII_RD3 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
150 	MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
151 	MX7D_PAD_SD3_STROBE__GPIO6_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL),
152 	MX7D_PAD_SD3_RESET_B__GPIO6_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL),
153 };
154 
155 #define FEC1_RST_GPIO	IMX_GPIO_NR(6, 11)
156 
157 static void setup_iomux_fec(void)
158 {
159 	imx_iomux_v3_setup_multiple_pads(fec1_pads, ARRAY_SIZE(fec1_pads));
160 
161 	gpio_direction_output(FEC1_RST_GPIO, 0);
162 	udelay(500);
163 	gpio_set_value(FEC1_RST_GPIO, 1);
164 }
165 
166 int board_eth_init(bd_t *bis)
167 {
168 	setup_iomux_fec();
169 
170 	return fecmxc_initialize_multi(bis, 0,
171 		CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE);
172 }
173 
174 static int setup_fec(void)
175 {
176 	struct iomuxc_gpr_base_regs *const iomuxc_gpr_regs
177 		= (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR;
178 
179 	/* Use 125M anatop REF_CLK1 for ENET1, clear gpr1[13], gpr1[17] */
180 	clrsetbits_le32(&iomuxc_gpr_regs->gpr[1],
181 			(IOMUXC_GPR_GPR1_GPR_ENET1_TX_CLK_SEL_MASK |
182 			IOMUXC_GPR_GPR1_GPR_ENET1_CLK_DIR_MASK), 0);
183 
184 	return set_clk_enet(ENET_125MHZ);
185 }
186 
187 int board_phy_config(struct phy_device *phydev)
188 {
189 	unsigned short val;
190 
191 	/* To enable AR8035 ouput a 125MHz clk from CLK_25M */
192 	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7);
193 	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
194 	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
195 
196 	val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
197 	val &= 0xffe7;
198 	val |= 0x18;
199 	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
200 
201 	/* introduce tx clock delay */
202 	phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
203 	val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
204 	val |= 0x0100;
205 	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
206 
207 	if (phydev->drv->config)
208 		phydev->drv->config(phydev);
209 
210 	return 0;
211 }
212 #endif
213 
214 static void setup_iomux_uart(void)
215 {
216 	imx_iomux_v3_setup_multiple_pads(uart5_pads, ARRAY_SIZE(uart5_pads));
217 }
218 
219 static struct fsl_esdhc_cfg usdhc_cfg[1] = {
220 	{USDHC3_BASE_ADDR},
221 };
222 
223 int board_mmc_getcd(struct mmc *mmc)
224 {
225 	/* Assume uSDHC3 emmc is always present */
226 	return 1;
227 }
228 
229 int board_mmc_init(bd_t *bis)
230 {
231 	imx_iomux_v3_setup_multiple_pads(
232 			usdhc3_emmc_pads, ARRAY_SIZE(usdhc3_emmc_pads));
233 	usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
234 
235 	return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
236 }
237 
238 int board_early_init_f(void)
239 {
240 	setup_iomux_uart();
241 
242 #ifdef CONFIG_SYS_I2C_MXC
243 	setup_i2c(3, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info4);
244 #endif
245 
246 	return 0;
247 }
248 
249 int board_init(void)
250 {
251 	/* address of boot parameters */
252 	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
253 
254 #ifdef CONFIG_FEC_MXC
255 	setup_fec();
256 #endif
257 
258 	return 0;
259 }
260 
261 int board_late_init(void)
262 {
263 	struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR;
264 
265 	imx_iomux_v3_setup_multiple_pads(wdog_pads, ARRAY_SIZE(wdog_pads));
266 
267 	set_wdog_reset(wdog);
268 
269 	/*
270 	 * Do not assert internal WDOG_RESET_B_DEB(controlled by bit 4),
271 	 * since we use PMIC_PWRON to reset the board.
272 	 */
273 	clrsetbits_le16(&wdog->wcr, 0, 0x10);
274 
275 	return 0;
276 }
277 
278 int checkboard(void)
279 {
280 	puts("Board: i.MX7D PICOSOM\n");
281 
282 	return 0;
283 }
284 
285 static iomux_v3_cfg_t const usb_otg2_pads[] = {
286 	MX7D_PAD_UART3_CTS_B__USB_OTG2_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
287 };
288 
289 int board_ehci_hcd_init(int port)
290 {
291 	switch (port) {
292 	case 0:
293 		break;
294 	case 1:
295 		imx_iomux_v3_setup_multiple_pads(usb_otg2_pads,
296 						 ARRAY_SIZE(usb_otg2_pads));
297 		break;
298 	default:
299 		return -EINVAL;
300 	}
301 	return 0;
302 }
303 
304 int board_usb_phy_mode(int port)
305 {
306 	switch (port) {
307 	case 0:
308 		return USB_INIT_DEVICE;
309 	case 1:
310 		return USB_INIT_HOST;
311 	default:
312 		return -EINVAL;
313 	}
314 	return 0;
315 }
316