]> git.sur5r.net Git - u-boot/blob - board/compulab/cm_fx6/cm_fx6.c
arm: mx6: cm-fx6: add support for displaytype env var
[u-boot] / board / compulab / cm_fx6 / cm_fx6.c
1 /*
2  * Board functions for Compulab CM-FX6 board
3  *
4  * Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/
5  *
6  * Author: Nikita Kiryanov <nikita@compulab.co.il>
7  *
8  * SPDX-License-Identifier:     GPL-2.0+
9  */
10
11 #include <common.h>
12 #include <dm.h>
13 #include <fsl_esdhc.h>
14 #include <miiphy.h>
15 #include <netdev.h>
16 #include <errno.h>
17 #include <fdt_support.h>
18 #include <sata.h>
19 #include <splash.h>
20 #include <asm/arch/crm_regs.h>
21 #include <asm/arch/sys_proto.h>
22 #include <asm/arch/iomux.h>
23 #include <asm/arch/mxc_hdmi.h>
24 #include <asm/imx-common/mxc_i2c.h>
25 #include <asm/imx-common/sata.h>
26 #include <asm/imx-common/video.h>
27 #include <asm/io.h>
28 #include <asm/gpio.h>
29 #include <dm/platform_data/serial_mxc.h>
30 #include "common.h"
31 #include "../common/eeprom.h"
32 #include "../common/common.h"
33
34 DECLARE_GLOBAL_DATA_PTR;
35
36 #ifdef CONFIG_SPLASH_SCREEN
37 static struct splash_location cm_fx6_splash_locations[] = {
38         {
39                 .name = "sf",
40                 .storage = SPLASH_STORAGE_SF,
41                 .offset = 0x100000,
42         },
43 };
44
45 int splash_screen_prepare(void)
46 {
47         return splash_source_load(cm_fx6_splash_locations,
48                                   ARRAY_SIZE(cm_fx6_splash_locations));
49 }
50 #endif
51
52 #ifdef CONFIG_IMX_HDMI
53 static void cm_fx6_enable_hdmi(struct display_info_t const *dev)
54 {
55         imx_enable_hdmi_phy();
56 }
57
58 static struct display_info_t preset_hdmi_1024X768 = {
59         .bus    = -1,
60         .addr   = 0,
61         .pixfmt = IPU_PIX_FMT_RGB24,
62         .enable = cm_fx6_enable_hdmi,
63         .mode   = {
64                 .name           = "HDMI",
65                 .refresh        = 60,
66                 .xres           = 1024,
67                 .yres           = 768,
68                 .pixclock       = 40385,
69                 .left_margin    = 220,
70                 .right_margin   = 40,
71                 .upper_margin   = 21,
72                 .lower_margin   = 7,
73                 .hsync_len      = 60,
74                 .vsync_len      = 10,
75                 .sync           = FB_SYNC_EXT,
76                 .vmode          = FB_VMODE_NONINTERLACED,
77         }
78 };
79
80 static void cm_fx6_setup_display(void)
81 {
82         struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
83         struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
84         int reg;
85
86         enable_ipu_clock();
87         imx_setup_hdmi();
88         reg = __raw_readl(&mxc_ccm->CCGR3);
89         reg |= MXC_CCM_CCGR3_IPU1_IPU_DI0_MASK;
90         writel(reg, &mxc_ccm->CCGR3);
91         clrbits_le32(&iomuxc_regs->gpr[3], MXC_CCM_CCGR3_IPU1_IPU_DI0_MASK);
92 }
93
94 int board_video_skip(void)
95 {
96         int ret;
97         struct display_info_t *preset;
98         char const *panel = getenv("displaytype");
99
100         if (!panel) /* Also accept panel for backward compatibility */
101                 panel = getenv("panel");
102
103         if (!panel)
104                 return -ENOENT;
105
106         if (!strcmp(panel, "HDMI"))
107                 preset = &preset_hdmi_1024X768;
108         else
109                 return -EINVAL;
110
111         ret = ipuv3_fb_init(&preset->mode, 0, preset->pixfmt);
112         if (ret) {
113                 printf("Can't init display %s: %d\n", preset->mode.name, ret);
114                 return ret;
115         }
116
117         preset->enable(preset);
118         printf("Display: %s (%ux%u)\n", preset->mode.name, preset->mode.xres,
119                preset->mode.yres);
120
121         return 0;
122 }
123 #else
124 static inline void cm_fx6_setup_display(void) {}
125 #endif /* CONFIG_VIDEO_IPUV3 */
126
127 #ifdef CONFIG_DWC_AHSATA
128 static int cm_fx6_issd_gpios[] = {
129         /* The order of the GPIOs in the array is important! */
130         CM_FX6_SATA_LDO_EN,
131         CM_FX6_SATA_PHY_SLP,
132         CM_FX6_SATA_NRSTDLY,
133         CM_FX6_SATA_PWREN,
134         CM_FX6_SATA_NSTANDBY1,
135         CM_FX6_SATA_NSTANDBY2,
136 };
137
138 static void cm_fx6_sata_power(int on)
139 {
140         int i;
141
142         if (!on) { /* tell the iSSD that the power will be removed */
143                 gpio_direction_output(CM_FX6_SATA_PWLOSS_INT, 1);
144                 mdelay(10);
145         }
146
147         for (i = 0; i < ARRAY_SIZE(cm_fx6_issd_gpios); i++) {
148                 gpio_direction_output(cm_fx6_issd_gpios[i], on);
149                 udelay(100);
150         }
151
152         if (!on) /* for compatibility lower the power loss interrupt */
153                 gpio_direction_output(CM_FX6_SATA_PWLOSS_INT, 0);
154 }
155
156 static iomux_v3_cfg_t const sata_pads[] = {
157         /* SATA PWR */
158         IOMUX_PADS(PAD_ENET_TX_EN__GPIO1_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL)),
159         IOMUX_PADS(PAD_EIM_A22__GPIO2_IO16    | MUX_PAD_CTRL(NO_PAD_CTRL)),
160         IOMUX_PADS(PAD_EIM_D20__GPIO3_IO20    | MUX_PAD_CTRL(NO_PAD_CTRL)),
161         IOMUX_PADS(PAD_EIM_A25__GPIO5_IO02    | MUX_PAD_CTRL(NO_PAD_CTRL)),
162         /* SATA CTRL */
163         IOMUX_PADS(PAD_ENET_TXD0__GPIO1_IO30  | MUX_PAD_CTRL(NO_PAD_CTRL)),
164         IOMUX_PADS(PAD_EIM_D23__GPIO3_IO23    | MUX_PAD_CTRL(NO_PAD_CTRL)),
165         IOMUX_PADS(PAD_EIM_D29__GPIO3_IO29    | MUX_PAD_CTRL(NO_PAD_CTRL)),
166         IOMUX_PADS(PAD_EIM_A23__GPIO6_IO06    | MUX_PAD_CTRL(NO_PAD_CTRL)),
167         IOMUX_PADS(PAD_EIM_BCLK__GPIO6_IO31   | MUX_PAD_CTRL(NO_PAD_CTRL)),
168 };
169
170 static int cm_fx6_setup_issd(void)
171 {
172         int ret, i;
173
174         SETUP_IOMUX_PADS(sata_pads);
175
176         for (i = 0; i < ARRAY_SIZE(cm_fx6_issd_gpios); i++) {
177                 ret = gpio_request(cm_fx6_issd_gpios[i], "sata");
178                 if (ret)
179                         return ret;
180         }
181
182         ret = gpio_request(CM_FX6_SATA_PWLOSS_INT, "sata_pwloss_int");
183         if (ret)
184                 return ret;
185
186         return 0;
187 }
188
189 #define CM_FX6_SATA_INIT_RETRIES        10
190 int sata_initialize(void)
191 {
192         int err, i;
193
194         /* Make sure this gpio has logical 0 value */
195         gpio_direction_output(CM_FX6_SATA_PWLOSS_INT, 0);
196         udelay(100);
197         cm_fx6_sata_power(1);
198
199         for (i = 0; i < CM_FX6_SATA_INIT_RETRIES; i++) {
200                 err = setup_sata();
201                 if (err) {
202                         printf("SATA setup failed: %d\n", err);
203                         return err;
204                 }
205
206                 udelay(100);
207
208                 err = __sata_initialize();
209                 if (!err)
210                         break;
211
212                 /* There is no device on the SATA port */
213                 if (sata_port_status(0, 0) == 0)
214                         break;
215
216                 /* There's a device, but link not established. Retry */
217         }
218
219         return err;
220 }
221
222 int sata_stop(void)
223 {
224         __sata_stop();
225         cm_fx6_sata_power(0);
226         mdelay(250);
227
228         return 0;
229 }
230 #else
231 static int cm_fx6_setup_issd(void) { return 0; }
232 #endif
233
234 #ifdef CONFIG_SYS_I2C_MXC
235 #define I2C_PAD_CTRL    (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
236                         PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \
237                         PAD_CTL_ODE | PAD_CTL_SRE_FAST)
238
239 I2C_PADS(i2c0_pads,
240          PAD_EIM_D21__I2C1_SCL | MUX_PAD_CTRL(I2C_PAD_CTRL),
241          PAD_EIM_D21__GPIO3_IO21 | MUX_PAD_CTRL(I2C_PAD_CTRL),
242          IMX_GPIO_NR(3, 21),
243          PAD_EIM_D28__I2C1_SDA | MUX_PAD_CTRL(I2C_PAD_CTRL),
244          PAD_EIM_D28__GPIO3_IO28 | MUX_PAD_CTRL(I2C_PAD_CTRL),
245          IMX_GPIO_NR(3, 28));
246
247 I2C_PADS(i2c1_pads,
248          PAD_KEY_COL3__I2C2_SCL | MUX_PAD_CTRL(I2C_PAD_CTRL),
249          PAD_KEY_COL3__GPIO4_IO12 | MUX_PAD_CTRL(I2C_PAD_CTRL),
250          IMX_GPIO_NR(4, 12),
251          PAD_KEY_ROW3__I2C2_SDA | MUX_PAD_CTRL(I2C_PAD_CTRL),
252          PAD_KEY_ROW3__GPIO4_IO13 | MUX_PAD_CTRL(I2C_PAD_CTRL),
253          IMX_GPIO_NR(4, 13));
254
255 I2C_PADS(i2c2_pads,
256          PAD_GPIO_3__I2C3_SCL | MUX_PAD_CTRL(I2C_PAD_CTRL),
257          PAD_GPIO_3__GPIO1_IO03 | MUX_PAD_CTRL(I2C_PAD_CTRL),
258          IMX_GPIO_NR(1, 3),
259          PAD_GPIO_6__I2C3_SDA | MUX_PAD_CTRL(I2C_PAD_CTRL),
260          PAD_GPIO_6__GPIO1_IO06 | MUX_PAD_CTRL(I2C_PAD_CTRL),
261          IMX_GPIO_NR(1, 6));
262
263
264 static int cm_fx6_setup_one_i2c(int busnum, struct i2c_pads_info *pads)
265 {
266         int ret;
267
268         ret = setup_i2c(busnum, CONFIG_SYS_I2C_SPEED, 0x7f, pads);
269         if (ret)
270                 printf("Warning: I2C%d setup failed: %d\n", busnum, ret);
271
272         return ret;
273 }
274
275 static int cm_fx6_setup_i2c(void)
276 {
277         int ret = 0, err;
278
279         /* i2c<x>_pads are wierd macro variables; we can't use an array */
280         err = cm_fx6_setup_one_i2c(0, I2C_PADS_INFO(i2c0_pads));
281         if (err)
282                 ret = err;
283         err = cm_fx6_setup_one_i2c(1, I2C_PADS_INFO(i2c1_pads));
284         if (err)
285                 ret = err;
286         err = cm_fx6_setup_one_i2c(2, I2C_PADS_INFO(i2c2_pads));
287         if (err)
288                 ret = err;
289
290         return ret;
291 }
292 #else
293 static int cm_fx6_setup_i2c(void) { return 0; }
294 #endif
295
296 #ifdef CONFIG_USB_EHCI_MX6
297 #define WEAK_PULLDOWN   (PAD_CTL_PUS_100K_DOWN |                \
298                         PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \
299                         PAD_CTL_HYS | PAD_CTL_SRE_SLOW)
300 #define MX6_USBNC_BASEADDR      0x2184800
301 #define USBNC_USB_H1_PWR_POL    (1 << 9)
302
303 static int cm_fx6_setup_usb_host(void)
304 {
305         int err;
306
307         err = gpio_request(CM_FX6_USB_HUB_RST, "usb hub rst");
308         if (err)
309                 return err;
310
311         SETUP_IOMUX_PAD(PAD_GPIO_0__USB_H1_PWR | MUX_PAD_CTRL(NO_PAD_CTRL));
312         SETUP_IOMUX_PAD(PAD_SD3_RST__GPIO7_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL));
313
314         return 0;
315 }
316
317 static int cm_fx6_setup_usb_otg(void)
318 {
319         int err;
320         struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
321
322         err = gpio_request(SB_FX6_USB_OTG_PWR, "usb-pwr");
323         if (err) {
324                 printf("USB OTG pwr gpio request failed: %d\n", err);
325                 return err;
326         }
327
328         SETUP_IOMUX_PAD(PAD_EIM_D22__GPIO3_IO22 | MUX_PAD_CTRL(NO_PAD_CTRL));
329         SETUP_IOMUX_PAD(PAD_ENET_RX_ER__USB_OTG_ID |
330                                                 MUX_PAD_CTRL(WEAK_PULLDOWN));
331         clrbits_le32(&iomux->gpr[1], IOMUXC_GPR1_OTG_ID_MASK);
332         /* disable ext. charger detect, or it'll affect signal quality at dp. */
333         return gpio_direction_output(SB_FX6_USB_OTG_PWR, 0);
334 }
335
336 int board_ehci_hcd_init(int port)
337 {
338         int ret;
339         u32 *usbnc_usb_uh1_ctrl = (u32 *)(MX6_USBNC_BASEADDR + 4);
340
341         /* Only 1 host controller in use. port 0 is OTG & needs no attention */
342         if (port != 1)
343                 return 0;
344
345         /* Set PWR polarity to match power switch's enable polarity */
346         setbits_le32(usbnc_usb_uh1_ctrl, USBNC_USB_H1_PWR_POL);
347         ret = gpio_direction_output(CM_FX6_USB_HUB_RST, 0);
348         if (ret)
349                 return ret;
350
351         udelay(10);
352         ret = gpio_direction_output(CM_FX6_USB_HUB_RST, 1);
353         if (ret)
354                 return ret;
355
356         mdelay(1);
357
358         return 0;
359 }
360
361 int board_ehci_power(int port, int on)
362 {
363         if (port == 0)
364                 return gpio_direction_output(SB_FX6_USB_OTG_PWR, on);
365
366         return 0;
367 }
368 #else
369 static int cm_fx6_setup_usb_otg(void) { return 0; }
370 static int cm_fx6_setup_usb_host(void) { return 0; }
371 #endif
372
373 #ifdef CONFIG_FEC_MXC
374 #define ENET_PAD_CTRL           (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
375                                  PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
376
377 static int mx6_rgmii_rework(struct phy_device *phydev)
378 {
379         unsigned short val;
380
381         /* Ar8031 phy SmartEEE feature cause link status generates glitch,
382          * which cause ethernet link down/up issue, so disable SmartEEE
383          */
384         phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x3);
385         phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x805d);
386         phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4003);
387         val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
388         val &= ~(0x1 << 8);
389         phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
390
391         /* To enable AR8031 ouput a 125MHz clk from CLK_25M */
392         phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7);
393         phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
394         phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
395
396         val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
397         val &= 0xffe3;
398         val |= 0x18;
399         phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
400
401         /* introduce tx clock delay */
402         phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
403         val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
404         val |= 0x0100;
405         phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
406
407         return 0;
408 }
409
410 int board_phy_config(struct phy_device *phydev)
411 {
412         mx6_rgmii_rework(phydev);
413
414         if (phydev->drv->config)
415                 return phydev->drv->config(phydev);
416
417         return 0;
418 }
419
420 static iomux_v3_cfg_t const enet_pads[] = {
421         IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL)),
422         IOMUX_PADS(PAD_ENET_MDC__ENET_MDC   | MUX_PAD_CTRL(ENET_PAD_CTRL)),
423         IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
424         IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
425         IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
426         IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
427         IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
428         IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
429         IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
430         IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
431         IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
432         IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
433         IOMUX_PADS(PAD_GPIO_0__CCM_CLKO1    | MUX_PAD_CTRL(NO_PAD_CTRL)),
434         IOMUX_PADS(PAD_GPIO_3__CCM_CLKO2    | MUX_PAD_CTRL(NO_PAD_CTRL)),
435         IOMUX_PADS(PAD_SD4_DAT0__GPIO2_IO08 | MUX_PAD_CTRL(0x84)),
436         IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK  |
437                                                 MUX_PAD_CTRL(ENET_PAD_CTRL)),
438         IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL |
439                                                 MUX_PAD_CTRL(ENET_PAD_CTRL)),
440         IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL |
441                                                 MUX_PAD_CTRL(ENET_PAD_CTRL)),
442 };
443
444 static int handle_mac_address(char *env_var, uint eeprom_bus)
445 {
446         unsigned char enetaddr[6];
447         int rc;
448
449         rc = eth_getenv_enetaddr(env_var, enetaddr);
450         if (rc)
451                 return 0;
452
453         rc = cl_eeprom_read_mac_addr(enetaddr, eeprom_bus);
454         if (rc)
455                 return rc;
456
457         if (!is_valid_ethaddr(enetaddr))
458                 return -1;
459
460         return eth_setenv_enetaddr(env_var, enetaddr);
461 }
462
463 #define SB_FX6_I2C_EEPROM_BUS   0
464 #define NO_MAC_ADDR             "No MAC address found for %s\n"
465 int board_eth_init(bd_t *bis)
466 {
467         int err;
468
469         if (handle_mac_address("ethaddr", CONFIG_SYS_I2C_EEPROM_BUS))
470                 printf(NO_MAC_ADDR, "primary NIC");
471
472         if (handle_mac_address("eth1addr", SB_FX6_I2C_EEPROM_BUS))
473                 printf(NO_MAC_ADDR, "secondary NIC");
474
475         SETUP_IOMUX_PADS(enet_pads);
476         /* phy reset */
477         err = gpio_request(CM_FX6_ENET_NRST, "enet_nrst");
478         if (err)
479                 printf("Etnernet NRST gpio request failed: %d\n", err);
480         gpio_direction_output(CM_FX6_ENET_NRST, 0);
481         udelay(500);
482         gpio_set_value(CM_FX6_ENET_NRST, 1);
483         enable_enet_clk(1);
484         return cpu_eth_init(bis);
485 }
486 #endif
487
488 #ifdef CONFIG_NAND_MXS
489 static iomux_v3_cfg_t const nand_pads[] = {
490         IOMUX_PADS(PAD_NANDF_CLE__NAND_CLE     | MUX_PAD_CTRL(NO_PAD_CTRL)),
491         IOMUX_PADS(PAD_NANDF_ALE__NAND_ALE     | MUX_PAD_CTRL(NO_PAD_CTRL)),
492         IOMUX_PADS(PAD_NANDF_CS0__NAND_CE0_B   | MUX_PAD_CTRL(NO_PAD_CTRL)),
493         IOMUX_PADS(PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(NO_PAD_CTRL)),
494         IOMUX_PADS(PAD_NANDF_D0__NAND_DATA00   | MUX_PAD_CTRL(NO_PAD_CTRL)),
495         IOMUX_PADS(PAD_NANDF_D1__NAND_DATA01   | MUX_PAD_CTRL(NO_PAD_CTRL)),
496         IOMUX_PADS(PAD_NANDF_D2__NAND_DATA02   | MUX_PAD_CTRL(NO_PAD_CTRL)),
497         IOMUX_PADS(PAD_NANDF_D3__NAND_DATA03   | MUX_PAD_CTRL(NO_PAD_CTRL)),
498         IOMUX_PADS(PAD_NANDF_D4__NAND_DATA04   | MUX_PAD_CTRL(NO_PAD_CTRL)),
499         IOMUX_PADS(PAD_NANDF_D5__NAND_DATA05   | MUX_PAD_CTRL(NO_PAD_CTRL)),
500         IOMUX_PADS(PAD_NANDF_D6__NAND_DATA06   | MUX_PAD_CTRL(NO_PAD_CTRL)),
501         IOMUX_PADS(PAD_NANDF_D7__NAND_DATA07   | MUX_PAD_CTRL(NO_PAD_CTRL)),
502         IOMUX_PADS(PAD_SD4_CMD__NAND_RE_B      | MUX_PAD_CTRL(NO_PAD_CTRL)),
503         IOMUX_PADS(PAD_SD4_CLK__NAND_WE_B      | MUX_PAD_CTRL(NO_PAD_CTRL)),
504 };
505
506 static void cm_fx6_setup_gpmi_nand(void)
507 {
508         SETUP_IOMUX_PADS(nand_pads);
509         /* Enable clock roots */
510         enable_usdhc_clk(1, 3);
511         enable_usdhc_clk(1, 4);
512
513         setup_gpmi_io_clk(MXC_CCM_CS2CDR_ENFC_CLK_PODF(0xf) |
514                           MXC_CCM_CS2CDR_ENFC_CLK_PRED(1)   |
515                           MXC_CCM_CS2CDR_ENFC_CLK_SEL(0));
516 }
517 #else
518 static void cm_fx6_setup_gpmi_nand(void) {}
519 #endif
520
521 #ifdef CONFIG_FSL_ESDHC
522 static struct fsl_esdhc_cfg usdhc_cfg[3] = {
523         {USDHC1_BASE_ADDR},
524         {USDHC2_BASE_ADDR},
525         {USDHC3_BASE_ADDR},
526 };
527
528 static enum mxc_clock usdhc_clk[3] = {
529         MXC_ESDHC_CLK,
530         MXC_ESDHC2_CLK,
531         MXC_ESDHC3_CLK,
532 };
533
534 int board_mmc_init(bd_t *bis)
535 {
536         int i;
537
538         cm_fx6_set_usdhc_iomux();
539         for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
540                 usdhc_cfg[i].sdhc_clk = mxc_get_clock(usdhc_clk[i]);
541                 usdhc_cfg[i].max_bus_width = 4;
542                 fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
543                 enable_usdhc_clk(1, i);
544         }
545
546         return 0;
547 }
548 #endif
549
550 #ifdef CONFIG_MXC_SPI
551 int cm_fx6_setup_ecspi(void)
552 {
553         cm_fx6_set_ecspi_iomux();
554         return gpio_request(CM_FX6_ECSPI_BUS0_CS0, "ecspi_bus0_cs0");
555 }
556 #else
557 int cm_fx6_setup_ecspi(void) { return 0; }
558 #endif
559
560 #ifdef CONFIG_OF_BOARD_SETUP
561 int ft_board_setup(void *blob, bd_t *bd)
562 {
563         uint8_t enetaddr[6];
564
565         /* MAC addr */
566         if (eth_getenv_enetaddr("ethaddr", enetaddr)) {
567                 fdt_find_and_setprop(blob,
568                                      "/soc/aips-bus@02100000/ethernet@02188000",
569                                      "local-mac-address", enetaddr, 6, 1);
570         }
571
572         if (eth_getenv_enetaddr("eth1addr", enetaddr)) {
573                 fdt_find_and_setprop(blob, "/eth@pcie", "local-mac-address",
574                                      enetaddr, 6, 1);
575         }
576
577         return 0;
578 }
579 #endif
580
581 int board_init(void)
582 {
583         int ret;
584
585         gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
586         cm_fx6_setup_gpmi_nand();
587
588         ret = cm_fx6_setup_ecspi();
589         if (ret)
590                 printf("Warning: ECSPI setup failed: %d\n", ret);
591
592         ret = cm_fx6_setup_usb_otg();
593         if (ret)
594                 printf("Warning: USB OTG setup failed: %d\n", ret);
595
596         ret = cm_fx6_setup_usb_host();
597         if (ret)
598                 printf("Warning: USB host setup failed: %d\n", ret);
599
600         /*
601          * cm-fx6 may have iSSD not assembled and in this case it has
602          * bypasses for a (m)SATA socket on the baseboard. The socketed
603          * device is not controlled by those GPIOs. So just print a warning
604          * if the setup fails.
605          */
606         ret = cm_fx6_setup_issd();
607         if (ret)
608                 printf("Warning: iSSD setup failed: %d\n", ret);
609
610         /* Warn on failure but do not abort boot */
611         ret = cm_fx6_setup_i2c();
612         if (ret)
613                 printf("Warning: I2C setup failed: %d\n", ret);
614
615         cm_fx6_setup_display();
616
617         return 0;
618 }
619
620 int checkboard(void)
621 {
622         puts("Board: CM-FX6\n");
623         return 0;
624 }
625
626 void dram_init_banksize(void)
627 {
628         gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
629         gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
630
631         switch (gd->ram_size) {
632         case 0x10000000: /* DDR_16BIT_256MB */
633                 gd->bd->bi_dram[0].size = 0x10000000;
634                 gd->bd->bi_dram[1].size = 0;
635                 break;
636         case 0x20000000: /* DDR_32BIT_512MB */
637                 gd->bd->bi_dram[0].size = 0x20000000;
638                 gd->bd->bi_dram[1].size = 0;
639                 break;
640         case 0x40000000:
641                 if (is_cpu_type(MXC_CPU_MX6SOLO)) { /* DDR_32BIT_1GB */
642                         gd->bd->bi_dram[0].size = 0x20000000;
643                         gd->bd->bi_dram[1].size = 0x20000000;
644                 } else { /* DDR_64BIT_1GB */
645                         gd->bd->bi_dram[0].size = 0x40000000;
646                         gd->bd->bi_dram[1].size = 0;
647                 }
648                 break;
649         case 0x80000000: /* DDR_64BIT_2GB */
650                 gd->bd->bi_dram[0].size = 0x40000000;
651                 gd->bd->bi_dram[1].size = 0x40000000;
652                 break;
653         case 0xEFF00000: /* DDR_64BIT_4GB */
654                 gd->bd->bi_dram[0].size = 0x70000000;
655                 gd->bd->bi_dram[1].size = 0x7FF00000;
656                 break;
657         }
658 }
659
660 int dram_init(void)
661 {
662         gd->ram_size = imx_ddr_size();
663         switch (gd->ram_size) {
664         case 0x10000000:
665         case 0x20000000:
666         case 0x40000000:
667         case 0x80000000:
668                 break;
669         case 0xF0000000:
670                 gd->ram_size -= 0x100000;
671                 break;
672         default:
673                 printf("ERROR: Unsupported DRAM size 0x%lx\n", gd->ram_size);
674                 return -1;
675         }
676
677         return 0;
678 }
679
680 u32 get_board_rev(void)
681 {
682         return cl_eeprom_get_board_rev();
683 }
684
685 static struct mxc_serial_platdata cm_fx6_mxc_serial_plat = {
686         .reg = (struct mxc_uart *)UART4_BASE,
687 };
688
689 U_BOOT_DEVICE(cm_fx6_serial) = {
690         .name   = "serial_mxc",
691         .platdata = &cm_fx6_mxc_serial_plat,
692 };