xref: /rk3399_rockchip-uboot/board/compulab/cm_fx6/cm_fx6.c (revision b65cbab194307d29cdff2e246e2f97738d9b6a15)
1e32028a7SNikita Kiryanov /*
2e32028a7SNikita Kiryanov  * Board functions for Compulab CM-FX6 board
3e32028a7SNikita Kiryanov  *
4e32028a7SNikita Kiryanov  * Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/
5e32028a7SNikita Kiryanov  *
6e32028a7SNikita Kiryanov  * Author: Nikita Kiryanov <nikita@compulab.co.il>
7e32028a7SNikita Kiryanov  *
8e32028a7SNikita Kiryanov  * SPDX-License-Identifier:	GPL-2.0+
9e32028a7SNikita Kiryanov  */
10e32028a7SNikita Kiryanov 
11e32028a7SNikita Kiryanov #include <common.h>
12e32028a7SNikita Kiryanov #include <fsl_esdhc.h>
1302b1343eSNikita Kiryanov #include <miiphy.h>
1402b1343eSNikita Kiryanov #include <netdev.h>
1502b1343eSNikita Kiryanov #include <fdt_support.h>
16206f38f7SNikita Kiryanov #include <sata.h>
17a6b0652bSNikita Kiryanov #include <asm/arch/crm_regs.h>
18e32028a7SNikita Kiryanov #include <asm/arch/sys_proto.h>
190f3effb9SNikita Kiryanov #include <asm/arch/iomux.h>
20f42b2f60SNikita Kiryanov #include <asm/imx-common/mxc_i2c.h>
21206f38f7SNikita Kiryanov #include <asm/imx-common/sata.h>
22a6b0652bSNikita Kiryanov #include <asm/io.h>
2302b1343eSNikita Kiryanov #include <asm/gpio.h>
24e32028a7SNikita Kiryanov #include "common.h"
25f66113c0SNikita Kiryanov #include "../common/eeprom.h"
26e32028a7SNikita Kiryanov 
27e32028a7SNikita Kiryanov DECLARE_GLOBAL_DATA_PTR;
28e32028a7SNikita Kiryanov 
29206f38f7SNikita Kiryanov #ifdef CONFIG_DWC_AHSATA
30206f38f7SNikita Kiryanov static int cm_fx6_issd_gpios[] = {
31206f38f7SNikita Kiryanov 	/* The order of the GPIOs in the array is important! */
32*b65cbab1SNikita Kiryanov 	CM_FX6_SATA_LDO_EN,
33206f38f7SNikita Kiryanov 	CM_FX6_SATA_PHY_SLP,
34206f38f7SNikita Kiryanov 	CM_FX6_SATA_NRSTDLY,
35206f38f7SNikita Kiryanov 	CM_FX6_SATA_PWREN,
36206f38f7SNikita Kiryanov 	CM_FX6_SATA_NSTANDBY1,
37206f38f7SNikita Kiryanov 	CM_FX6_SATA_NSTANDBY2,
38206f38f7SNikita Kiryanov };
39206f38f7SNikita Kiryanov 
40206f38f7SNikita Kiryanov static void cm_fx6_sata_power(int on)
41206f38f7SNikita Kiryanov {
42206f38f7SNikita Kiryanov 	int i;
43206f38f7SNikita Kiryanov 
44206f38f7SNikita Kiryanov 	if (!on) { /* tell the iSSD that the power will be removed */
45206f38f7SNikita Kiryanov 		gpio_direction_output(CM_FX6_SATA_PWLOSS_INT, 1);
46206f38f7SNikita Kiryanov 		mdelay(10);
47206f38f7SNikita Kiryanov 	}
48206f38f7SNikita Kiryanov 
49206f38f7SNikita Kiryanov 	for (i = 0; i < ARRAY_SIZE(cm_fx6_issd_gpios); i++) {
50206f38f7SNikita Kiryanov 		gpio_direction_output(cm_fx6_issd_gpios[i], on);
51206f38f7SNikita Kiryanov 		udelay(100);
52206f38f7SNikita Kiryanov 	}
53206f38f7SNikita Kiryanov 
54206f38f7SNikita Kiryanov 	if (!on) /* for compatibility lower the power loss interrupt */
55206f38f7SNikita Kiryanov 		gpio_direction_output(CM_FX6_SATA_PWLOSS_INT, 0);
56206f38f7SNikita Kiryanov }
57206f38f7SNikita Kiryanov 
58206f38f7SNikita Kiryanov static iomux_v3_cfg_t const sata_pads[] = {
59206f38f7SNikita Kiryanov 	/* SATA PWR */
60206f38f7SNikita Kiryanov 	IOMUX_PADS(PAD_ENET_TX_EN__GPIO1_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL)),
61206f38f7SNikita Kiryanov 	IOMUX_PADS(PAD_EIM_A22__GPIO2_IO16    | MUX_PAD_CTRL(NO_PAD_CTRL)),
62206f38f7SNikita Kiryanov 	IOMUX_PADS(PAD_EIM_D20__GPIO3_IO20    | MUX_PAD_CTRL(NO_PAD_CTRL)),
63206f38f7SNikita Kiryanov 	IOMUX_PADS(PAD_EIM_A25__GPIO5_IO02    | MUX_PAD_CTRL(NO_PAD_CTRL)),
64206f38f7SNikita Kiryanov 	/* SATA CTRL */
65206f38f7SNikita Kiryanov 	IOMUX_PADS(PAD_ENET_TXD0__GPIO1_IO30  | MUX_PAD_CTRL(NO_PAD_CTRL)),
66206f38f7SNikita Kiryanov 	IOMUX_PADS(PAD_EIM_D23__GPIO3_IO23    | MUX_PAD_CTRL(NO_PAD_CTRL)),
67206f38f7SNikita Kiryanov 	IOMUX_PADS(PAD_EIM_D29__GPIO3_IO29    | MUX_PAD_CTRL(NO_PAD_CTRL)),
68206f38f7SNikita Kiryanov 	IOMUX_PADS(PAD_EIM_A23__GPIO6_IO06    | MUX_PAD_CTRL(NO_PAD_CTRL)),
69206f38f7SNikita Kiryanov 	IOMUX_PADS(PAD_EIM_BCLK__GPIO6_IO31   | MUX_PAD_CTRL(NO_PAD_CTRL)),
70206f38f7SNikita Kiryanov };
71206f38f7SNikita Kiryanov 
72206f38f7SNikita Kiryanov static void cm_fx6_setup_issd(void)
73206f38f7SNikita Kiryanov {
74206f38f7SNikita Kiryanov 	SETUP_IOMUX_PADS(sata_pads);
75206f38f7SNikita Kiryanov 	/* Make sure this gpio has logical 0 value */
76206f38f7SNikita Kiryanov 	gpio_direction_output(CM_FX6_SATA_PWLOSS_INT, 0);
77206f38f7SNikita Kiryanov 	udelay(100);
78206f38f7SNikita Kiryanov 
79206f38f7SNikita Kiryanov 	cm_fx6_sata_power(0);
80206f38f7SNikita Kiryanov 	mdelay(250);
81206f38f7SNikita Kiryanov 	cm_fx6_sata_power(1);
82206f38f7SNikita Kiryanov }
83206f38f7SNikita Kiryanov 
84206f38f7SNikita Kiryanov #define CM_FX6_SATA_INIT_RETRIES	10
85206f38f7SNikita Kiryanov int sata_initialize(void)
86206f38f7SNikita Kiryanov {
87206f38f7SNikita Kiryanov 	int err, i;
88206f38f7SNikita Kiryanov 
89206f38f7SNikita Kiryanov 	cm_fx6_setup_issd();
90206f38f7SNikita Kiryanov 	for (i = 0; i < CM_FX6_SATA_INIT_RETRIES; i++) {
91206f38f7SNikita Kiryanov 		err = setup_sata();
92206f38f7SNikita Kiryanov 		if (err) {
93206f38f7SNikita Kiryanov 			printf("SATA setup failed: %d\n", err);
94206f38f7SNikita Kiryanov 			return err;
95206f38f7SNikita Kiryanov 		}
96206f38f7SNikita Kiryanov 
97206f38f7SNikita Kiryanov 		udelay(100);
98206f38f7SNikita Kiryanov 
99206f38f7SNikita Kiryanov 		err = __sata_initialize();
100206f38f7SNikita Kiryanov 		if (!err)
101206f38f7SNikita Kiryanov 			break;
102206f38f7SNikita Kiryanov 
103206f38f7SNikita Kiryanov 		/* There is no device on the SATA port */
104206f38f7SNikita Kiryanov 		if (sata_port_status(0, 0) == 0)
105206f38f7SNikita Kiryanov 			break;
106206f38f7SNikita Kiryanov 
107206f38f7SNikita Kiryanov 		/* There's a device, but link not established. Retry */
108206f38f7SNikita Kiryanov 	}
109206f38f7SNikita Kiryanov 
110206f38f7SNikita Kiryanov 	return err;
111206f38f7SNikita Kiryanov }
112206f38f7SNikita Kiryanov #endif
113206f38f7SNikita Kiryanov 
114f42b2f60SNikita Kiryanov #ifdef CONFIG_SYS_I2C_MXC
115f42b2f60SNikita Kiryanov #define I2C_PAD_CTRL	(PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
116f42b2f60SNikita Kiryanov 			PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \
117f42b2f60SNikita Kiryanov 			PAD_CTL_ODE | PAD_CTL_SRE_FAST)
118f42b2f60SNikita Kiryanov 
119f42b2f60SNikita Kiryanov I2C_PADS(i2c0_pads,
120f42b2f60SNikita Kiryanov 	 PAD_EIM_D21__I2C1_SCL | MUX_PAD_CTRL(I2C_PAD_CTRL),
121f42b2f60SNikita Kiryanov 	 PAD_EIM_D21__GPIO3_IO21 | MUX_PAD_CTRL(I2C_PAD_CTRL),
122f42b2f60SNikita Kiryanov 	 IMX_GPIO_NR(3, 21),
123f42b2f60SNikita Kiryanov 	 PAD_EIM_D28__I2C1_SDA | MUX_PAD_CTRL(I2C_PAD_CTRL),
124f42b2f60SNikita Kiryanov 	 PAD_EIM_D28__GPIO3_IO28 | MUX_PAD_CTRL(I2C_PAD_CTRL),
125f42b2f60SNikita Kiryanov 	 IMX_GPIO_NR(3, 28));
126f42b2f60SNikita Kiryanov 
127f42b2f60SNikita Kiryanov I2C_PADS(i2c1_pads,
128f42b2f60SNikita Kiryanov 	 PAD_KEY_COL3__I2C2_SCL | MUX_PAD_CTRL(I2C_PAD_CTRL),
129f42b2f60SNikita Kiryanov 	 PAD_KEY_COL3__GPIO4_IO12 | MUX_PAD_CTRL(I2C_PAD_CTRL),
130f42b2f60SNikita Kiryanov 	 IMX_GPIO_NR(4, 12),
131f42b2f60SNikita Kiryanov 	 PAD_KEY_ROW3__I2C2_SDA | MUX_PAD_CTRL(I2C_PAD_CTRL),
132f42b2f60SNikita Kiryanov 	 PAD_KEY_ROW3__GPIO4_IO13 | MUX_PAD_CTRL(I2C_PAD_CTRL),
133f42b2f60SNikita Kiryanov 	 IMX_GPIO_NR(4, 13));
134f42b2f60SNikita Kiryanov 
135f42b2f60SNikita Kiryanov I2C_PADS(i2c2_pads,
136f42b2f60SNikita Kiryanov 	 PAD_GPIO_3__I2C3_SCL | MUX_PAD_CTRL(I2C_PAD_CTRL),
137f42b2f60SNikita Kiryanov 	 PAD_GPIO_3__GPIO1_IO03 | MUX_PAD_CTRL(I2C_PAD_CTRL),
138f42b2f60SNikita Kiryanov 	 IMX_GPIO_NR(1, 3),
139f42b2f60SNikita Kiryanov 	 PAD_GPIO_6__I2C3_SDA | MUX_PAD_CTRL(I2C_PAD_CTRL),
140f42b2f60SNikita Kiryanov 	 PAD_GPIO_6__GPIO1_IO06 | MUX_PAD_CTRL(I2C_PAD_CTRL),
141f42b2f60SNikita Kiryanov 	 IMX_GPIO_NR(1, 6));
142f42b2f60SNikita Kiryanov 
143f42b2f60SNikita Kiryanov 
144f42b2f60SNikita Kiryanov static void cm_fx6_setup_i2c(void)
145f42b2f60SNikita Kiryanov {
146f42b2f60SNikita Kiryanov 	setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, I2C_PADS_INFO(i2c0_pads));
147f42b2f60SNikita Kiryanov 	setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, I2C_PADS_INFO(i2c1_pads));
148f42b2f60SNikita Kiryanov 	setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, I2C_PADS_INFO(i2c2_pads));
149f42b2f60SNikita Kiryanov }
150f42b2f60SNikita Kiryanov #else
151f42b2f60SNikita Kiryanov static void cm_fx6_setup_i2c(void) { }
152f42b2f60SNikita Kiryanov #endif
153f42b2f60SNikita Kiryanov 
1540f3effb9SNikita Kiryanov #ifdef CONFIG_USB_EHCI_MX6
1550f3effb9SNikita Kiryanov #define WEAK_PULLDOWN	(PAD_CTL_PUS_100K_DOWN |		\
1560f3effb9SNikita Kiryanov 			PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |	\
1570f3effb9SNikita Kiryanov 			PAD_CTL_HYS | PAD_CTL_SRE_SLOW)
1580f3effb9SNikita Kiryanov 
1590f3effb9SNikita Kiryanov static int cm_fx6_usb_hub_reset(void)
1600f3effb9SNikita Kiryanov {
1610f3effb9SNikita Kiryanov 	int err;
1620f3effb9SNikita Kiryanov 
1630f3effb9SNikita Kiryanov 	err = gpio_request(CM_FX6_USB_HUB_RST, "usb hub rst");
1640f3effb9SNikita Kiryanov 	if (err) {
1650f3effb9SNikita Kiryanov 		printf("USB hub rst gpio request failed: %d\n", err);
1660f3effb9SNikita Kiryanov 		return -1;
1670f3effb9SNikita Kiryanov 	}
1680f3effb9SNikita Kiryanov 
1690f3effb9SNikita Kiryanov 	SETUP_IOMUX_PAD(PAD_SD3_RST__GPIO7_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL));
1700f3effb9SNikita Kiryanov 	gpio_direction_output(CM_FX6_USB_HUB_RST, 0);
1710f3effb9SNikita Kiryanov 	udelay(10);
1720f3effb9SNikita Kiryanov 	gpio_direction_output(CM_FX6_USB_HUB_RST, 1);
1730f3effb9SNikita Kiryanov 	mdelay(1);
1740f3effb9SNikita Kiryanov 
1750f3effb9SNikita Kiryanov 	return 0;
1760f3effb9SNikita Kiryanov }
1770f3effb9SNikita Kiryanov 
1780f3effb9SNikita Kiryanov static int cm_fx6_init_usb_otg(void)
1790f3effb9SNikita Kiryanov {
1800f3effb9SNikita Kiryanov 	int ret;
1810f3effb9SNikita Kiryanov 	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
1820f3effb9SNikita Kiryanov 
1830f3effb9SNikita Kiryanov 	ret = gpio_request(SB_FX6_USB_OTG_PWR, "usb-pwr");
1840f3effb9SNikita Kiryanov 	if (ret) {
1850f3effb9SNikita Kiryanov 		printf("USB OTG pwr gpio request failed: %d\n", ret);
1860f3effb9SNikita Kiryanov 		return ret;
1870f3effb9SNikita Kiryanov 	}
1880f3effb9SNikita Kiryanov 
1890f3effb9SNikita Kiryanov 	SETUP_IOMUX_PAD(PAD_EIM_D22__GPIO3_IO22 | MUX_PAD_CTRL(NO_PAD_CTRL));
1900f3effb9SNikita Kiryanov 	SETUP_IOMUX_PAD(PAD_ENET_RX_ER__USB_OTG_ID |
1910f3effb9SNikita Kiryanov 						MUX_PAD_CTRL(WEAK_PULLDOWN));
1920f3effb9SNikita Kiryanov 	clrbits_le32(&iomux->gpr[1], IOMUXC_GPR1_OTG_ID_MASK);
1930f3effb9SNikita Kiryanov 	/* disable ext. charger detect, or it'll affect signal quality at dp. */
1940f3effb9SNikita Kiryanov 	return gpio_direction_output(SB_FX6_USB_OTG_PWR, 0);
1950f3effb9SNikita Kiryanov }
1960f3effb9SNikita Kiryanov 
1970f3effb9SNikita Kiryanov #define MX6_USBNC_BASEADDR	0x2184800
1980f3effb9SNikita Kiryanov #define USBNC_USB_H1_PWR_POL	(1 << 9)
1990f3effb9SNikita Kiryanov int board_ehci_hcd_init(int port)
2000f3effb9SNikita Kiryanov {
2010f3effb9SNikita Kiryanov 	u32 *usbnc_usb_uh1_ctrl = (u32 *)(MX6_USBNC_BASEADDR + 4);
2020f3effb9SNikita Kiryanov 
2030f3effb9SNikita Kiryanov 	switch (port) {
2040f3effb9SNikita Kiryanov 	case 0:
2050f3effb9SNikita Kiryanov 		return cm_fx6_init_usb_otg();
2060f3effb9SNikita Kiryanov 	case 1:
2070f3effb9SNikita Kiryanov 		SETUP_IOMUX_PAD(PAD_GPIO_0__USB_H1_PWR |
2080f3effb9SNikita Kiryanov 				MUX_PAD_CTRL(NO_PAD_CTRL));
2090f3effb9SNikita Kiryanov 
2100f3effb9SNikita Kiryanov 		/* Set PWR polarity to match power switch's enable polarity */
2110f3effb9SNikita Kiryanov 		setbits_le32(usbnc_usb_uh1_ctrl, USBNC_USB_H1_PWR_POL);
2120f3effb9SNikita Kiryanov 		return cm_fx6_usb_hub_reset();
2130f3effb9SNikita Kiryanov 	default:
2140f3effb9SNikita Kiryanov 		break;
2150f3effb9SNikita Kiryanov 	}
2160f3effb9SNikita Kiryanov 
2170f3effb9SNikita Kiryanov 	return 0;
2180f3effb9SNikita Kiryanov }
2190f3effb9SNikita Kiryanov 
2200f3effb9SNikita Kiryanov int board_ehci_power(int port, int on)
2210f3effb9SNikita Kiryanov {
2220f3effb9SNikita Kiryanov 	if (port == 0)
2230f3effb9SNikita Kiryanov 		return gpio_direction_output(SB_FX6_USB_OTG_PWR, on);
2240f3effb9SNikita Kiryanov 
2250f3effb9SNikita Kiryanov 	return 0;
2260f3effb9SNikita Kiryanov }
2270f3effb9SNikita Kiryanov #endif
2280f3effb9SNikita Kiryanov 
22902b1343eSNikita Kiryanov #ifdef CONFIG_FEC_MXC
23002b1343eSNikita Kiryanov #define ENET_PAD_CTRL		(PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
23102b1343eSNikita Kiryanov 				 PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
23202b1343eSNikita Kiryanov 
23302b1343eSNikita Kiryanov static int mx6_rgmii_rework(struct phy_device *phydev)
23402b1343eSNikita Kiryanov {
23502b1343eSNikita Kiryanov 	unsigned short val;
23602b1343eSNikita Kiryanov 
23702b1343eSNikita Kiryanov 	/* Ar8031 phy SmartEEE feature cause link status generates glitch,
23802b1343eSNikita Kiryanov 	 * which cause ethernet link down/up issue, so disable SmartEEE
23902b1343eSNikita Kiryanov 	 */
24002b1343eSNikita Kiryanov 	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x3);
24102b1343eSNikita Kiryanov 	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x805d);
24202b1343eSNikita Kiryanov 	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4003);
24302b1343eSNikita Kiryanov 	val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
24402b1343eSNikita Kiryanov 	val &= ~(0x1 << 8);
24502b1343eSNikita Kiryanov 	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
24602b1343eSNikita Kiryanov 
24702b1343eSNikita Kiryanov 	/* To enable AR8031 ouput a 125MHz clk from CLK_25M */
24802b1343eSNikita Kiryanov 	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7);
24902b1343eSNikita Kiryanov 	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
25002b1343eSNikita Kiryanov 	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
25102b1343eSNikita Kiryanov 
25202b1343eSNikita Kiryanov 	val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
25302b1343eSNikita Kiryanov 	val &= 0xffe3;
25402b1343eSNikita Kiryanov 	val |= 0x18;
25502b1343eSNikita Kiryanov 	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
25602b1343eSNikita Kiryanov 
25702b1343eSNikita Kiryanov 	/* introduce tx clock delay */
25802b1343eSNikita Kiryanov 	phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
25902b1343eSNikita Kiryanov 	val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
26002b1343eSNikita Kiryanov 	val |= 0x0100;
26102b1343eSNikita Kiryanov 	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
26202b1343eSNikita Kiryanov 
26302b1343eSNikita Kiryanov 	return 0;
26402b1343eSNikita Kiryanov }
26502b1343eSNikita Kiryanov 
26602b1343eSNikita Kiryanov int board_phy_config(struct phy_device *phydev)
26702b1343eSNikita Kiryanov {
26802b1343eSNikita Kiryanov 	mx6_rgmii_rework(phydev);
26902b1343eSNikita Kiryanov 
27002b1343eSNikita Kiryanov 	if (phydev->drv->config)
27102b1343eSNikita Kiryanov 		return phydev->drv->config(phydev);
27202b1343eSNikita Kiryanov 
27302b1343eSNikita Kiryanov 	return 0;
27402b1343eSNikita Kiryanov }
27502b1343eSNikita Kiryanov 
27602b1343eSNikita Kiryanov static iomux_v3_cfg_t const enet_pads[] = {
27702b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL)),
27802b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_ENET_MDC__ENET_MDC   | MUX_PAD_CTRL(ENET_PAD_CTRL)),
27902b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
28002b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
28102b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
28202b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
28302b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
28402b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
28502b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
28602b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
28702b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
28802b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
28902b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_GPIO_0__CCM_CLKO1    | MUX_PAD_CTRL(NO_PAD_CTRL)),
29002b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_GPIO_3__CCM_CLKO2    | MUX_PAD_CTRL(NO_PAD_CTRL)),
29102b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_SD4_DAT0__GPIO2_IO08 | MUX_PAD_CTRL(0x84)),
29202b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK  |
29302b1343eSNikita Kiryanov 						MUX_PAD_CTRL(ENET_PAD_CTRL)),
29402b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL |
29502b1343eSNikita Kiryanov 						MUX_PAD_CTRL(ENET_PAD_CTRL)),
29602b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL |
29702b1343eSNikita Kiryanov 						MUX_PAD_CTRL(ENET_PAD_CTRL)),
29802b1343eSNikita Kiryanov };
29902b1343eSNikita Kiryanov 
300f66113c0SNikita Kiryanov static int handle_mac_address(void)
301f66113c0SNikita Kiryanov {
302f66113c0SNikita Kiryanov 	unsigned char enetaddr[6];
303f66113c0SNikita Kiryanov 	int rc;
304f66113c0SNikita Kiryanov 
305f66113c0SNikita Kiryanov 	rc = eth_getenv_enetaddr("ethaddr", enetaddr);
306f66113c0SNikita Kiryanov 	if (rc)
307f66113c0SNikita Kiryanov 		return 0;
308f66113c0SNikita Kiryanov 
309f66113c0SNikita Kiryanov 	rc = cl_eeprom_read_mac_addr(enetaddr);
310f66113c0SNikita Kiryanov 	if (rc)
311f66113c0SNikita Kiryanov 		return rc;
312f66113c0SNikita Kiryanov 
313f66113c0SNikita Kiryanov 	if (!is_valid_ether_addr(enetaddr))
314f66113c0SNikita Kiryanov 		return -1;
315f66113c0SNikita Kiryanov 
316f66113c0SNikita Kiryanov 	return eth_setenv_enetaddr("ethaddr", enetaddr);
317f66113c0SNikita Kiryanov }
318f66113c0SNikita Kiryanov 
31902b1343eSNikita Kiryanov int board_eth_init(bd_t *bis)
32002b1343eSNikita Kiryanov {
321f66113c0SNikita Kiryanov 	int res = handle_mac_address();
322f66113c0SNikita Kiryanov 	if (res)
323f66113c0SNikita Kiryanov 		puts("No MAC address found\n");
324f66113c0SNikita Kiryanov 
32502b1343eSNikita Kiryanov 	SETUP_IOMUX_PADS(enet_pads);
32602b1343eSNikita Kiryanov 	/* phy reset */
32702b1343eSNikita Kiryanov 	gpio_direction_output(CM_FX6_ENET_NRST, 0);
32802b1343eSNikita Kiryanov 	udelay(500);
32902b1343eSNikita Kiryanov 	gpio_set_value(CM_FX6_ENET_NRST, 1);
33002b1343eSNikita Kiryanov 	enable_enet_clk(1);
33102b1343eSNikita Kiryanov 	return cpu_eth_init(bis);
33202b1343eSNikita Kiryanov }
33302b1343eSNikita Kiryanov #endif
33402b1343eSNikita Kiryanov 
335a6b0652bSNikita Kiryanov #ifdef CONFIG_NAND_MXS
336a6b0652bSNikita Kiryanov static iomux_v3_cfg_t const nand_pads[] = {
337a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_NANDF_CLE__NAND_CLE     | MUX_PAD_CTRL(NO_PAD_CTRL)),
338a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_NANDF_ALE__NAND_ALE     | MUX_PAD_CTRL(NO_PAD_CTRL)),
339a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_NANDF_CS0__NAND_CE0_B   | MUX_PAD_CTRL(NO_PAD_CTRL)),
340a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(NO_PAD_CTRL)),
341a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_NANDF_D0__NAND_DATA00   | MUX_PAD_CTRL(NO_PAD_CTRL)),
342a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_NANDF_D1__NAND_DATA01   | MUX_PAD_CTRL(NO_PAD_CTRL)),
343a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_NANDF_D2__NAND_DATA02   | MUX_PAD_CTRL(NO_PAD_CTRL)),
344a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_NANDF_D3__NAND_DATA03   | MUX_PAD_CTRL(NO_PAD_CTRL)),
345a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_NANDF_D4__NAND_DATA04   | MUX_PAD_CTRL(NO_PAD_CTRL)),
346a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_NANDF_D5__NAND_DATA05   | MUX_PAD_CTRL(NO_PAD_CTRL)),
347a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_NANDF_D6__NAND_DATA06   | MUX_PAD_CTRL(NO_PAD_CTRL)),
348a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_NANDF_D7__NAND_DATA07   | MUX_PAD_CTRL(NO_PAD_CTRL)),
349a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_SD4_CMD__NAND_RE_B      | MUX_PAD_CTRL(NO_PAD_CTRL)),
350a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_SD4_CLK__NAND_WE_B      | MUX_PAD_CTRL(NO_PAD_CTRL)),
351a6b0652bSNikita Kiryanov };
352a6b0652bSNikita Kiryanov 
353a6b0652bSNikita Kiryanov static void cm_fx6_setup_gpmi_nand(void)
354a6b0652bSNikita Kiryanov {
355a6b0652bSNikita Kiryanov 	SETUP_IOMUX_PADS(nand_pads);
356a6b0652bSNikita Kiryanov 	/* Enable clock roots */
357a6b0652bSNikita Kiryanov 	enable_usdhc_clk(1, 3);
358a6b0652bSNikita Kiryanov 	enable_usdhc_clk(1, 4);
359a6b0652bSNikita Kiryanov 
360a6b0652bSNikita Kiryanov 	setup_gpmi_io_clk(MXC_CCM_CS2CDR_ENFC_CLK_PODF(0xf) |
361a6b0652bSNikita Kiryanov 			  MXC_CCM_CS2CDR_ENFC_CLK_PRED(1)   |
362a6b0652bSNikita Kiryanov 			  MXC_CCM_CS2CDR_ENFC_CLK_SEL(0));
363a6b0652bSNikita Kiryanov }
364a6b0652bSNikita Kiryanov #else
365a6b0652bSNikita Kiryanov static void cm_fx6_setup_gpmi_nand(void) {}
366a6b0652bSNikita Kiryanov #endif
367a6b0652bSNikita Kiryanov 
368e32028a7SNikita Kiryanov #ifdef CONFIG_FSL_ESDHC
369e32028a7SNikita Kiryanov static struct fsl_esdhc_cfg usdhc_cfg[3] = {
370e32028a7SNikita Kiryanov 	{USDHC1_BASE_ADDR},
371e32028a7SNikita Kiryanov 	{USDHC2_BASE_ADDR},
372e32028a7SNikita Kiryanov 	{USDHC3_BASE_ADDR},
373e32028a7SNikita Kiryanov };
374e32028a7SNikita Kiryanov 
375e32028a7SNikita Kiryanov static enum mxc_clock usdhc_clk[3] = {
376e32028a7SNikita Kiryanov 	MXC_ESDHC_CLK,
377e32028a7SNikita Kiryanov 	MXC_ESDHC2_CLK,
378e32028a7SNikita Kiryanov 	MXC_ESDHC3_CLK,
379e32028a7SNikita Kiryanov };
380e32028a7SNikita Kiryanov 
381e32028a7SNikita Kiryanov int board_mmc_init(bd_t *bis)
382e32028a7SNikita Kiryanov {
383e32028a7SNikita Kiryanov 	int i;
384e32028a7SNikita Kiryanov 
385e32028a7SNikita Kiryanov 	cm_fx6_set_usdhc_iomux();
386e32028a7SNikita Kiryanov 	for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
387e32028a7SNikita Kiryanov 		usdhc_cfg[i].sdhc_clk = mxc_get_clock(usdhc_clk[i]);
388e32028a7SNikita Kiryanov 		usdhc_cfg[i].max_bus_width = 4;
389e32028a7SNikita Kiryanov 		fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
390e32028a7SNikita Kiryanov 		enable_usdhc_clk(1, i);
391e32028a7SNikita Kiryanov 	}
392e32028a7SNikita Kiryanov 
393e32028a7SNikita Kiryanov 	return 0;
394e32028a7SNikita Kiryanov }
395e32028a7SNikita Kiryanov #endif
396e32028a7SNikita Kiryanov 
39702b1343eSNikita Kiryanov #ifdef CONFIG_OF_BOARD_SETUP
39802b1343eSNikita Kiryanov void ft_board_setup(void *blob, bd_t *bd)
39902b1343eSNikita Kiryanov {
40002b1343eSNikita Kiryanov 	uint8_t enetaddr[6];
40102b1343eSNikita Kiryanov 
40202b1343eSNikita Kiryanov 	/* MAC addr */
40302b1343eSNikita Kiryanov 	if (eth_getenv_enetaddr("ethaddr", enetaddr)) {
40402b1343eSNikita Kiryanov 		fdt_find_and_setprop(blob, "/fec", "local-mac-address",
40502b1343eSNikita Kiryanov 				     enetaddr, 6, 1);
40602b1343eSNikita Kiryanov 	}
40702b1343eSNikita Kiryanov }
40802b1343eSNikita Kiryanov #endif
40902b1343eSNikita Kiryanov 
410e32028a7SNikita Kiryanov int board_init(void)
411e32028a7SNikita Kiryanov {
412e32028a7SNikita Kiryanov 	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
413a6b0652bSNikita Kiryanov 	cm_fx6_setup_gpmi_nand();
414f42b2f60SNikita Kiryanov 	cm_fx6_setup_i2c();
415a6b0652bSNikita Kiryanov 
416e32028a7SNikita Kiryanov 	return 0;
417e32028a7SNikita Kiryanov }
418e32028a7SNikita Kiryanov 
419e32028a7SNikita Kiryanov int checkboard(void)
420e32028a7SNikita Kiryanov {
421e32028a7SNikita Kiryanov 	puts("Board: CM-FX6\n");
422e32028a7SNikita Kiryanov 	return 0;
423e32028a7SNikita Kiryanov }
424e32028a7SNikita Kiryanov 
425e32028a7SNikita Kiryanov void dram_init_banksize(void)
426e32028a7SNikita Kiryanov {
427e32028a7SNikita Kiryanov 	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
428e32028a7SNikita Kiryanov 	gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
429e32028a7SNikita Kiryanov 
430e32028a7SNikita Kiryanov 	switch (gd->ram_size) {
431e32028a7SNikita Kiryanov 	case 0x10000000: /* DDR_16BIT_256MB */
432e32028a7SNikita Kiryanov 		gd->bd->bi_dram[0].size = 0x10000000;
433e32028a7SNikita Kiryanov 		gd->bd->bi_dram[1].size = 0;
434e32028a7SNikita Kiryanov 		break;
435e32028a7SNikita Kiryanov 	case 0x20000000: /* DDR_32BIT_512MB */
436e32028a7SNikita Kiryanov 		gd->bd->bi_dram[0].size = 0x20000000;
437e32028a7SNikita Kiryanov 		gd->bd->bi_dram[1].size = 0;
438e32028a7SNikita Kiryanov 		break;
439e32028a7SNikita Kiryanov 	case 0x40000000:
440e32028a7SNikita Kiryanov 		if (is_cpu_type(MXC_CPU_MX6SOLO)) { /* DDR_32BIT_1GB */
441e32028a7SNikita Kiryanov 			gd->bd->bi_dram[0].size = 0x20000000;
442e32028a7SNikita Kiryanov 			gd->bd->bi_dram[1].size = 0x20000000;
443e32028a7SNikita Kiryanov 		} else { /* DDR_64BIT_1GB */
444e32028a7SNikita Kiryanov 			gd->bd->bi_dram[0].size = 0x40000000;
445e32028a7SNikita Kiryanov 			gd->bd->bi_dram[1].size = 0;
446e32028a7SNikita Kiryanov 		}
447e32028a7SNikita Kiryanov 		break;
448e32028a7SNikita Kiryanov 	case 0x80000000: /* DDR_64BIT_2GB */
449e32028a7SNikita Kiryanov 		gd->bd->bi_dram[0].size = 0x40000000;
450e32028a7SNikita Kiryanov 		gd->bd->bi_dram[1].size = 0x40000000;
451e32028a7SNikita Kiryanov 		break;
452e32028a7SNikita Kiryanov 	case 0xEFF00000: /* DDR_64BIT_4GB */
453e32028a7SNikita Kiryanov 		gd->bd->bi_dram[0].size = 0x70000000;
454e32028a7SNikita Kiryanov 		gd->bd->bi_dram[1].size = 0x7FF00000;
455e32028a7SNikita Kiryanov 		break;
456e32028a7SNikita Kiryanov 	}
457e32028a7SNikita Kiryanov }
458e32028a7SNikita Kiryanov 
459e32028a7SNikita Kiryanov int dram_init(void)
460e32028a7SNikita Kiryanov {
461e32028a7SNikita Kiryanov 	gd->ram_size = imx_ddr_size();
462e32028a7SNikita Kiryanov 	switch (gd->ram_size) {
463e32028a7SNikita Kiryanov 	case 0x10000000:
464e32028a7SNikita Kiryanov 	case 0x20000000:
465e32028a7SNikita Kiryanov 	case 0x40000000:
466e32028a7SNikita Kiryanov 	case 0x80000000:
467e32028a7SNikita Kiryanov 		break;
468e32028a7SNikita Kiryanov 	case 0xF0000000:
469e32028a7SNikita Kiryanov 		gd->ram_size -= 0x100000;
470e32028a7SNikita Kiryanov 		break;
471e32028a7SNikita Kiryanov 	default:
472e32028a7SNikita Kiryanov 		printf("ERROR: Unsupported DRAM size 0x%lx\n", gd->ram_size);
473e32028a7SNikita Kiryanov 		return -1;
474e32028a7SNikita Kiryanov 	}
475e32028a7SNikita Kiryanov 
476e32028a7SNikita Kiryanov 	return 0;
477e32028a7SNikita Kiryanov }
478f66113c0SNikita Kiryanov 
479f66113c0SNikita Kiryanov u32 get_board_rev(void)
480f66113c0SNikita Kiryanov {
481f66113c0SNikita Kiryanov 	return cl_eeprom_get_board_rev();
482f66113c0SNikita Kiryanov }
483f66113c0SNikita Kiryanov 
484