xref: /rk3399_rockchip-uboot/board/compulab/cm_fx6/cm_fx6.c (revision 0f3effb99fdabf41e6152e5aec2e5fceee7616f9)
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>
16a6b0652bSNikita Kiryanov #include <asm/arch/crm_regs.h>
17e32028a7SNikita Kiryanov #include <asm/arch/sys_proto.h>
18*0f3effb9SNikita Kiryanov #include <asm/arch/iomux.h>
19a6b0652bSNikita Kiryanov #include <asm/io.h>
2002b1343eSNikita Kiryanov #include <asm/gpio.h>
21e32028a7SNikita Kiryanov #include "common.h"
22e32028a7SNikita Kiryanov 
23e32028a7SNikita Kiryanov DECLARE_GLOBAL_DATA_PTR;
24e32028a7SNikita Kiryanov 
25*0f3effb9SNikita Kiryanov #ifdef CONFIG_USB_EHCI_MX6
26*0f3effb9SNikita Kiryanov #define WEAK_PULLDOWN	(PAD_CTL_PUS_100K_DOWN |		\
27*0f3effb9SNikita Kiryanov 			PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |	\
28*0f3effb9SNikita Kiryanov 			PAD_CTL_HYS | PAD_CTL_SRE_SLOW)
29*0f3effb9SNikita Kiryanov 
30*0f3effb9SNikita Kiryanov static int cm_fx6_usb_hub_reset(void)
31*0f3effb9SNikita Kiryanov {
32*0f3effb9SNikita Kiryanov 	int err;
33*0f3effb9SNikita Kiryanov 
34*0f3effb9SNikita Kiryanov 	err = gpio_request(CM_FX6_USB_HUB_RST, "usb hub rst");
35*0f3effb9SNikita Kiryanov 	if (err) {
36*0f3effb9SNikita Kiryanov 		printf("USB hub rst gpio request failed: %d\n", err);
37*0f3effb9SNikita Kiryanov 		return -1;
38*0f3effb9SNikita Kiryanov 	}
39*0f3effb9SNikita Kiryanov 
40*0f3effb9SNikita Kiryanov 	SETUP_IOMUX_PAD(PAD_SD3_RST__GPIO7_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL));
41*0f3effb9SNikita Kiryanov 	gpio_direction_output(CM_FX6_USB_HUB_RST, 0);
42*0f3effb9SNikita Kiryanov 	udelay(10);
43*0f3effb9SNikita Kiryanov 	gpio_direction_output(CM_FX6_USB_HUB_RST, 1);
44*0f3effb9SNikita Kiryanov 	mdelay(1);
45*0f3effb9SNikita Kiryanov 
46*0f3effb9SNikita Kiryanov 	return 0;
47*0f3effb9SNikita Kiryanov }
48*0f3effb9SNikita Kiryanov 
49*0f3effb9SNikita Kiryanov static int cm_fx6_init_usb_otg(void)
50*0f3effb9SNikita Kiryanov {
51*0f3effb9SNikita Kiryanov 	int ret;
52*0f3effb9SNikita Kiryanov 	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
53*0f3effb9SNikita Kiryanov 
54*0f3effb9SNikita Kiryanov 	ret = gpio_request(SB_FX6_USB_OTG_PWR, "usb-pwr");
55*0f3effb9SNikita Kiryanov 	if (ret) {
56*0f3effb9SNikita Kiryanov 		printf("USB OTG pwr gpio request failed: %d\n", ret);
57*0f3effb9SNikita Kiryanov 		return ret;
58*0f3effb9SNikita Kiryanov 	}
59*0f3effb9SNikita Kiryanov 
60*0f3effb9SNikita Kiryanov 	SETUP_IOMUX_PAD(PAD_EIM_D22__GPIO3_IO22 | MUX_PAD_CTRL(NO_PAD_CTRL));
61*0f3effb9SNikita Kiryanov 	SETUP_IOMUX_PAD(PAD_ENET_RX_ER__USB_OTG_ID |
62*0f3effb9SNikita Kiryanov 						MUX_PAD_CTRL(WEAK_PULLDOWN));
63*0f3effb9SNikita Kiryanov 	clrbits_le32(&iomux->gpr[1], IOMUXC_GPR1_OTG_ID_MASK);
64*0f3effb9SNikita Kiryanov 	/* disable ext. charger detect, or it'll affect signal quality at dp. */
65*0f3effb9SNikita Kiryanov 	return gpio_direction_output(SB_FX6_USB_OTG_PWR, 0);
66*0f3effb9SNikita Kiryanov }
67*0f3effb9SNikita Kiryanov 
68*0f3effb9SNikita Kiryanov #define MX6_USBNC_BASEADDR	0x2184800
69*0f3effb9SNikita Kiryanov #define USBNC_USB_H1_PWR_POL	(1 << 9)
70*0f3effb9SNikita Kiryanov int board_ehci_hcd_init(int port)
71*0f3effb9SNikita Kiryanov {
72*0f3effb9SNikita Kiryanov 	u32 *usbnc_usb_uh1_ctrl = (u32 *)(MX6_USBNC_BASEADDR + 4);
73*0f3effb9SNikita Kiryanov 
74*0f3effb9SNikita Kiryanov 	switch (port) {
75*0f3effb9SNikita Kiryanov 	case 0:
76*0f3effb9SNikita Kiryanov 		return cm_fx6_init_usb_otg();
77*0f3effb9SNikita Kiryanov 	case 1:
78*0f3effb9SNikita Kiryanov 		SETUP_IOMUX_PAD(PAD_GPIO_0__USB_H1_PWR |
79*0f3effb9SNikita Kiryanov 				MUX_PAD_CTRL(NO_PAD_CTRL));
80*0f3effb9SNikita Kiryanov 
81*0f3effb9SNikita Kiryanov 		/* Set PWR polarity to match power switch's enable polarity */
82*0f3effb9SNikita Kiryanov 		setbits_le32(usbnc_usb_uh1_ctrl, USBNC_USB_H1_PWR_POL);
83*0f3effb9SNikita Kiryanov 		return cm_fx6_usb_hub_reset();
84*0f3effb9SNikita Kiryanov 	default:
85*0f3effb9SNikita Kiryanov 		break;
86*0f3effb9SNikita Kiryanov 	}
87*0f3effb9SNikita Kiryanov 
88*0f3effb9SNikita Kiryanov 	return 0;
89*0f3effb9SNikita Kiryanov }
90*0f3effb9SNikita Kiryanov 
91*0f3effb9SNikita Kiryanov int board_ehci_power(int port, int on)
92*0f3effb9SNikita Kiryanov {
93*0f3effb9SNikita Kiryanov 	if (port == 0)
94*0f3effb9SNikita Kiryanov 		return gpio_direction_output(SB_FX6_USB_OTG_PWR, on);
95*0f3effb9SNikita Kiryanov 
96*0f3effb9SNikita Kiryanov 	return 0;
97*0f3effb9SNikita Kiryanov }
98*0f3effb9SNikita Kiryanov #endif
99*0f3effb9SNikita Kiryanov 
10002b1343eSNikita Kiryanov #ifdef CONFIG_FEC_MXC
10102b1343eSNikita Kiryanov #define ENET_PAD_CTRL		(PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
10202b1343eSNikita Kiryanov 				 PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
10302b1343eSNikita Kiryanov 
10402b1343eSNikita Kiryanov static int mx6_rgmii_rework(struct phy_device *phydev)
10502b1343eSNikita Kiryanov {
10602b1343eSNikita Kiryanov 	unsigned short val;
10702b1343eSNikita Kiryanov 
10802b1343eSNikita Kiryanov 	/* Ar8031 phy SmartEEE feature cause link status generates glitch,
10902b1343eSNikita Kiryanov 	 * which cause ethernet link down/up issue, so disable SmartEEE
11002b1343eSNikita Kiryanov 	 */
11102b1343eSNikita Kiryanov 	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x3);
11202b1343eSNikita Kiryanov 	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x805d);
11302b1343eSNikita Kiryanov 	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4003);
11402b1343eSNikita Kiryanov 	val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
11502b1343eSNikita Kiryanov 	val &= ~(0x1 << 8);
11602b1343eSNikita Kiryanov 	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
11702b1343eSNikita Kiryanov 
11802b1343eSNikita Kiryanov 	/* To enable AR8031 ouput a 125MHz clk from CLK_25M */
11902b1343eSNikita Kiryanov 	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7);
12002b1343eSNikita Kiryanov 	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
12102b1343eSNikita Kiryanov 	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
12202b1343eSNikita Kiryanov 
12302b1343eSNikita Kiryanov 	val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
12402b1343eSNikita Kiryanov 	val &= 0xffe3;
12502b1343eSNikita Kiryanov 	val |= 0x18;
12602b1343eSNikita Kiryanov 	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
12702b1343eSNikita Kiryanov 
12802b1343eSNikita Kiryanov 	/* introduce tx clock delay */
12902b1343eSNikita Kiryanov 	phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
13002b1343eSNikita Kiryanov 	val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
13102b1343eSNikita Kiryanov 	val |= 0x0100;
13202b1343eSNikita Kiryanov 	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
13302b1343eSNikita Kiryanov 
13402b1343eSNikita Kiryanov 	return 0;
13502b1343eSNikita Kiryanov }
13602b1343eSNikita Kiryanov 
13702b1343eSNikita Kiryanov int board_phy_config(struct phy_device *phydev)
13802b1343eSNikita Kiryanov {
13902b1343eSNikita Kiryanov 	mx6_rgmii_rework(phydev);
14002b1343eSNikita Kiryanov 
14102b1343eSNikita Kiryanov 	if (phydev->drv->config)
14202b1343eSNikita Kiryanov 		return phydev->drv->config(phydev);
14302b1343eSNikita Kiryanov 
14402b1343eSNikita Kiryanov 	return 0;
14502b1343eSNikita Kiryanov }
14602b1343eSNikita Kiryanov 
14702b1343eSNikita Kiryanov static iomux_v3_cfg_t const enet_pads[] = {
14802b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL)),
14902b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_ENET_MDC__ENET_MDC   | MUX_PAD_CTRL(ENET_PAD_CTRL)),
15002b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
15102b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
15202b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
15302b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
15402b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
15502b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
15602b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
15702b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
15802b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
15902b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
16002b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_GPIO_0__CCM_CLKO1    | MUX_PAD_CTRL(NO_PAD_CTRL)),
16102b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_GPIO_3__CCM_CLKO2    | MUX_PAD_CTRL(NO_PAD_CTRL)),
16202b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_SD4_DAT0__GPIO2_IO08 | MUX_PAD_CTRL(0x84)),
16302b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK  |
16402b1343eSNikita Kiryanov 						MUX_PAD_CTRL(ENET_PAD_CTRL)),
16502b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL |
16602b1343eSNikita Kiryanov 						MUX_PAD_CTRL(ENET_PAD_CTRL)),
16702b1343eSNikita Kiryanov 	IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL |
16802b1343eSNikita Kiryanov 						MUX_PAD_CTRL(ENET_PAD_CTRL)),
16902b1343eSNikita Kiryanov };
17002b1343eSNikita Kiryanov 
17102b1343eSNikita Kiryanov int board_eth_init(bd_t *bis)
17202b1343eSNikita Kiryanov {
17302b1343eSNikita Kiryanov 	SETUP_IOMUX_PADS(enet_pads);
17402b1343eSNikita Kiryanov 	/* phy reset */
17502b1343eSNikita Kiryanov 	gpio_direction_output(CM_FX6_ENET_NRST, 0);
17602b1343eSNikita Kiryanov 	udelay(500);
17702b1343eSNikita Kiryanov 	gpio_set_value(CM_FX6_ENET_NRST, 1);
17802b1343eSNikita Kiryanov 	enable_enet_clk(1);
17902b1343eSNikita Kiryanov 	return cpu_eth_init(bis);
18002b1343eSNikita Kiryanov }
18102b1343eSNikita Kiryanov #endif
18202b1343eSNikita Kiryanov 
183a6b0652bSNikita Kiryanov #ifdef CONFIG_NAND_MXS
184a6b0652bSNikita Kiryanov static iomux_v3_cfg_t const nand_pads[] = {
185a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_NANDF_CLE__NAND_CLE     | MUX_PAD_CTRL(NO_PAD_CTRL)),
186a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_NANDF_ALE__NAND_ALE     | MUX_PAD_CTRL(NO_PAD_CTRL)),
187a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_NANDF_CS0__NAND_CE0_B   | MUX_PAD_CTRL(NO_PAD_CTRL)),
188a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(NO_PAD_CTRL)),
189a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_NANDF_D0__NAND_DATA00   | MUX_PAD_CTRL(NO_PAD_CTRL)),
190a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_NANDF_D1__NAND_DATA01   | MUX_PAD_CTRL(NO_PAD_CTRL)),
191a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_NANDF_D2__NAND_DATA02   | MUX_PAD_CTRL(NO_PAD_CTRL)),
192a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_NANDF_D3__NAND_DATA03   | MUX_PAD_CTRL(NO_PAD_CTRL)),
193a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_NANDF_D4__NAND_DATA04   | MUX_PAD_CTRL(NO_PAD_CTRL)),
194a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_NANDF_D5__NAND_DATA05   | MUX_PAD_CTRL(NO_PAD_CTRL)),
195a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_NANDF_D6__NAND_DATA06   | MUX_PAD_CTRL(NO_PAD_CTRL)),
196a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_NANDF_D7__NAND_DATA07   | MUX_PAD_CTRL(NO_PAD_CTRL)),
197a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_SD4_CMD__NAND_RE_B      | MUX_PAD_CTRL(NO_PAD_CTRL)),
198a6b0652bSNikita Kiryanov 	IOMUX_PADS(PAD_SD4_CLK__NAND_WE_B      | MUX_PAD_CTRL(NO_PAD_CTRL)),
199a6b0652bSNikita Kiryanov };
200a6b0652bSNikita Kiryanov 
201a6b0652bSNikita Kiryanov static void cm_fx6_setup_gpmi_nand(void)
202a6b0652bSNikita Kiryanov {
203a6b0652bSNikita Kiryanov 	SETUP_IOMUX_PADS(nand_pads);
204a6b0652bSNikita Kiryanov 	/* Enable clock roots */
205a6b0652bSNikita Kiryanov 	enable_usdhc_clk(1, 3);
206a6b0652bSNikita Kiryanov 	enable_usdhc_clk(1, 4);
207a6b0652bSNikita Kiryanov 
208a6b0652bSNikita Kiryanov 	setup_gpmi_io_clk(MXC_CCM_CS2CDR_ENFC_CLK_PODF(0xf) |
209a6b0652bSNikita Kiryanov 			  MXC_CCM_CS2CDR_ENFC_CLK_PRED(1)   |
210a6b0652bSNikita Kiryanov 			  MXC_CCM_CS2CDR_ENFC_CLK_SEL(0));
211a6b0652bSNikita Kiryanov }
212a6b0652bSNikita Kiryanov #else
213a6b0652bSNikita Kiryanov static void cm_fx6_setup_gpmi_nand(void) {}
214a6b0652bSNikita Kiryanov #endif
215a6b0652bSNikita Kiryanov 
216e32028a7SNikita Kiryanov #ifdef CONFIG_FSL_ESDHC
217e32028a7SNikita Kiryanov static struct fsl_esdhc_cfg usdhc_cfg[3] = {
218e32028a7SNikita Kiryanov 	{USDHC1_BASE_ADDR},
219e32028a7SNikita Kiryanov 	{USDHC2_BASE_ADDR},
220e32028a7SNikita Kiryanov 	{USDHC3_BASE_ADDR},
221e32028a7SNikita Kiryanov };
222e32028a7SNikita Kiryanov 
223e32028a7SNikita Kiryanov static enum mxc_clock usdhc_clk[3] = {
224e32028a7SNikita Kiryanov 	MXC_ESDHC_CLK,
225e32028a7SNikita Kiryanov 	MXC_ESDHC2_CLK,
226e32028a7SNikita Kiryanov 	MXC_ESDHC3_CLK,
227e32028a7SNikita Kiryanov };
228e32028a7SNikita Kiryanov 
229e32028a7SNikita Kiryanov int board_mmc_init(bd_t *bis)
230e32028a7SNikita Kiryanov {
231e32028a7SNikita Kiryanov 	int i;
232e32028a7SNikita Kiryanov 
233e32028a7SNikita Kiryanov 	cm_fx6_set_usdhc_iomux();
234e32028a7SNikita Kiryanov 	for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
235e32028a7SNikita Kiryanov 		usdhc_cfg[i].sdhc_clk = mxc_get_clock(usdhc_clk[i]);
236e32028a7SNikita Kiryanov 		usdhc_cfg[i].max_bus_width = 4;
237e32028a7SNikita Kiryanov 		fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
238e32028a7SNikita Kiryanov 		enable_usdhc_clk(1, i);
239e32028a7SNikita Kiryanov 	}
240e32028a7SNikita Kiryanov 
241e32028a7SNikita Kiryanov 	return 0;
242e32028a7SNikita Kiryanov }
243e32028a7SNikita Kiryanov #endif
244e32028a7SNikita Kiryanov 
24502b1343eSNikita Kiryanov #ifdef CONFIG_OF_BOARD_SETUP
24602b1343eSNikita Kiryanov void ft_board_setup(void *blob, bd_t *bd)
24702b1343eSNikita Kiryanov {
24802b1343eSNikita Kiryanov 	uint8_t enetaddr[6];
24902b1343eSNikita Kiryanov 
25002b1343eSNikita Kiryanov 	/* MAC addr */
25102b1343eSNikita Kiryanov 	if (eth_getenv_enetaddr("ethaddr", enetaddr)) {
25202b1343eSNikita Kiryanov 		fdt_find_and_setprop(blob, "/fec", "local-mac-address",
25302b1343eSNikita Kiryanov 				     enetaddr, 6, 1);
25402b1343eSNikita Kiryanov 	}
25502b1343eSNikita Kiryanov }
25602b1343eSNikita Kiryanov #endif
25702b1343eSNikita Kiryanov 
258e32028a7SNikita Kiryanov int board_init(void)
259e32028a7SNikita Kiryanov {
260e32028a7SNikita Kiryanov 	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
261a6b0652bSNikita Kiryanov 	cm_fx6_setup_gpmi_nand();
262a6b0652bSNikita Kiryanov 
263e32028a7SNikita Kiryanov 	return 0;
264e32028a7SNikita Kiryanov }
265e32028a7SNikita Kiryanov 
266e32028a7SNikita Kiryanov int checkboard(void)
267e32028a7SNikita Kiryanov {
268e32028a7SNikita Kiryanov 	puts("Board: CM-FX6\n");
269e32028a7SNikita Kiryanov 	return 0;
270e32028a7SNikita Kiryanov }
271e32028a7SNikita Kiryanov 
272e32028a7SNikita Kiryanov void dram_init_banksize(void)
273e32028a7SNikita Kiryanov {
274e32028a7SNikita Kiryanov 	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
275e32028a7SNikita Kiryanov 	gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
276e32028a7SNikita Kiryanov 
277e32028a7SNikita Kiryanov 	switch (gd->ram_size) {
278e32028a7SNikita Kiryanov 	case 0x10000000: /* DDR_16BIT_256MB */
279e32028a7SNikita Kiryanov 		gd->bd->bi_dram[0].size = 0x10000000;
280e32028a7SNikita Kiryanov 		gd->bd->bi_dram[1].size = 0;
281e32028a7SNikita Kiryanov 		break;
282e32028a7SNikita Kiryanov 	case 0x20000000: /* DDR_32BIT_512MB */
283e32028a7SNikita Kiryanov 		gd->bd->bi_dram[0].size = 0x20000000;
284e32028a7SNikita Kiryanov 		gd->bd->bi_dram[1].size = 0;
285e32028a7SNikita Kiryanov 		break;
286e32028a7SNikita Kiryanov 	case 0x40000000:
287e32028a7SNikita Kiryanov 		if (is_cpu_type(MXC_CPU_MX6SOLO)) { /* DDR_32BIT_1GB */
288e32028a7SNikita Kiryanov 			gd->bd->bi_dram[0].size = 0x20000000;
289e32028a7SNikita Kiryanov 			gd->bd->bi_dram[1].size = 0x20000000;
290e32028a7SNikita Kiryanov 		} else { /* DDR_64BIT_1GB */
291e32028a7SNikita Kiryanov 			gd->bd->bi_dram[0].size = 0x40000000;
292e32028a7SNikita Kiryanov 			gd->bd->bi_dram[1].size = 0;
293e32028a7SNikita Kiryanov 		}
294e32028a7SNikita Kiryanov 		break;
295e32028a7SNikita Kiryanov 	case 0x80000000: /* DDR_64BIT_2GB */
296e32028a7SNikita Kiryanov 		gd->bd->bi_dram[0].size = 0x40000000;
297e32028a7SNikita Kiryanov 		gd->bd->bi_dram[1].size = 0x40000000;
298e32028a7SNikita Kiryanov 		break;
299e32028a7SNikita Kiryanov 	case 0xEFF00000: /* DDR_64BIT_4GB */
300e32028a7SNikita Kiryanov 		gd->bd->bi_dram[0].size = 0x70000000;
301e32028a7SNikita Kiryanov 		gd->bd->bi_dram[1].size = 0x7FF00000;
302e32028a7SNikita Kiryanov 		break;
303e32028a7SNikita Kiryanov 	}
304e32028a7SNikita Kiryanov }
305e32028a7SNikita Kiryanov 
306e32028a7SNikita Kiryanov int dram_init(void)
307e32028a7SNikita Kiryanov {
308e32028a7SNikita Kiryanov 	gd->ram_size = imx_ddr_size();
309e32028a7SNikita Kiryanov 	switch (gd->ram_size) {
310e32028a7SNikita Kiryanov 	case 0x10000000:
311e32028a7SNikita Kiryanov 	case 0x20000000:
312e32028a7SNikita Kiryanov 	case 0x40000000:
313e32028a7SNikita Kiryanov 	case 0x80000000:
314e32028a7SNikita Kiryanov 		break;
315e32028a7SNikita Kiryanov 	case 0xF0000000:
316e32028a7SNikita Kiryanov 		gd->ram_size -= 0x100000;
317e32028a7SNikita Kiryanov 		break;
318e32028a7SNikita Kiryanov 	default:
319e32028a7SNikita Kiryanov 		printf("ERROR: Unsupported DRAM size 0x%lx\n", gd->ram_size);
320e32028a7SNikita Kiryanov 		return -1;
321e32028a7SNikita Kiryanov 	}
322e32028a7SNikita Kiryanov 
323e32028a7SNikita Kiryanov 	return 0;
324e32028a7SNikita Kiryanov }
325