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> 123f0e935fSSimon Glass #include <dm.h> 13e32028a7SNikita Kiryanov #include <fsl_esdhc.h> 1402b1343eSNikita Kiryanov #include <miiphy.h> 1502b1343eSNikita Kiryanov #include <netdev.h> 16*4377859aSNikita Kiryanov #include <errno.h> 1702b1343eSNikita Kiryanov #include <fdt_support.h> 18206f38f7SNikita Kiryanov #include <sata.h> 19f82eb2faSNikita Kiryanov #include <splash.h> 20a6b0652bSNikita Kiryanov #include <asm/arch/crm_regs.h> 21e32028a7SNikita Kiryanov #include <asm/arch/sys_proto.h> 220f3effb9SNikita Kiryanov #include <asm/arch/iomux.h> 23deb94d61SNikita Kiryanov #include <asm/arch/mxc_hdmi.h> 24f42b2f60SNikita Kiryanov #include <asm/imx-common/mxc_i2c.h> 25206f38f7SNikita Kiryanov #include <asm/imx-common/sata.h> 26deb94d61SNikita Kiryanov #include <asm/imx-common/video.h> 27a6b0652bSNikita Kiryanov #include <asm/io.h> 2802b1343eSNikita Kiryanov #include <asm/gpio.h> 2986256b79SMasahiro Yamada #include <dm/platform_data/serial_mxc.h> 30e32028a7SNikita Kiryanov #include "common.h" 31f66113c0SNikita Kiryanov #include "../common/eeprom.h" 323a236a35SNikita Kiryanov #include "../common/common.h" 33e32028a7SNikita Kiryanov 34e32028a7SNikita Kiryanov DECLARE_GLOBAL_DATA_PTR; 35e32028a7SNikita Kiryanov 363a236a35SNikita Kiryanov #ifdef CONFIG_SPLASH_SCREEN 373a236a35SNikita Kiryanov static struct splash_location cm_fx6_splash_locations[] = { 383a236a35SNikita Kiryanov { 393a236a35SNikita Kiryanov .name = "sf", 403a236a35SNikita Kiryanov .storage = SPLASH_STORAGE_SF, 413a236a35SNikita Kiryanov .offset = 0x100000, 423a236a35SNikita Kiryanov }, 433a236a35SNikita Kiryanov }; 443a236a35SNikita Kiryanov 453a236a35SNikita Kiryanov int splash_screen_prepare(void) 463a236a35SNikita Kiryanov { 47f82eb2faSNikita Kiryanov return splash_source_load(cm_fx6_splash_locations, 483a236a35SNikita Kiryanov ARRAY_SIZE(cm_fx6_splash_locations)); 493a236a35SNikita Kiryanov } 503a236a35SNikita Kiryanov #endif 513a236a35SNikita Kiryanov 52deb94d61SNikita Kiryanov #ifdef CONFIG_IMX_HDMI 53deb94d61SNikita Kiryanov static void cm_fx6_enable_hdmi(struct display_info_t const *dev) 54deb94d61SNikita Kiryanov { 55deb94d61SNikita Kiryanov imx_enable_hdmi_phy(); 56deb94d61SNikita Kiryanov } 57deb94d61SNikita Kiryanov 58*4377859aSNikita Kiryanov static struct display_info_t preset_hdmi_1024X768 = { 59deb94d61SNikita Kiryanov .bus = -1, 60deb94d61SNikita Kiryanov .addr = 0, 61deb94d61SNikita Kiryanov .pixfmt = IPU_PIX_FMT_RGB24, 62deb94d61SNikita Kiryanov .enable = cm_fx6_enable_hdmi, 63deb94d61SNikita Kiryanov .mode = { 64deb94d61SNikita Kiryanov .name = "HDMI", 65deb94d61SNikita Kiryanov .refresh = 60, 66deb94d61SNikita Kiryanov .xres = 1024, 67deb94d61SNikita Kiryanov .yres = 768, 68deb94d61SNikita Kiryanov .pixclock = 40385, 69deb94d61SNikita Kiryanov .left_margin = 220, 70deb94d61SNikita Kiryanov .right_margin = 40, 71deb94d61SNikita Kiryanov .upper_margin = 21, 72deb94d61SNikita Kiryanov .lower_margin = 7, 73deb94d61SNikita Kiryanov .hsync_len = 60, 74deb94d61SNikita Kiryanov .vsync_len = 10, 75deb94d61SNikita Kiryanov .sync = FB_SYNC_EXT, 76deb94d61SNikita Kiryanov .vmode = FB_VMODE_NONINTERLACED, 77deb94d61SNikita Kiryanov } 78deb94d61SNikita Kiryanov }; 79deb94d61SNikita Kiryanov 80deb94d61SNikita Kiryanov static void cm_fx6_setup_display(void) 81deb94d61SNikita Kiryanov { 82deb94d61SNikita Kiryanov struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; 8375dbbbfdSNikita Kiryanov struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; 84deb94d61SNikita Kiryanov int reg; 85deb94d61SNikita Kiryanov 86deb94d61SNikita Kiryanov enable_ipu_clock(); 87deb94d61SNikita Kiryanov imx_setup_hdmi(); 88deb94d61SNikita Kiryanov reg = __raw_readl(&mxc_ccm->CCGR3); 89deb94d61SNikita Kiryanov reg |= MXC_CCM_CCGR3_IPU1_IPU_DI0_MASK; 90deb94d61SNikita Kiryanov writel(reg, &mxc_ccm->CCGR3); 9175dbbbfdSNikita Kiryanov clrbits_le32(&iomuxc_regs->gpr[3], MXC_CCM_CCGR3_IPU1_IPU_DI0_MASK); 92deb94d61SNikita Kiryanov } 93*4377859aSNikita Kiryanov 94*4377859aSNikita Kiryanov int board_video_skip(void) 95*4377859aSNikita Kiryanov { 96*4377859aSNikita Kiryanov int ret; 97*4377859aSNikita Kiryanov struct display_info_t *preset; 98*4377859aSNikita Kiryanov char const *panel = getenv("panel"); 99*4377859aSNikita Kiryanov 100*4377859aSNikita Kiryanov if (!panel) 101*4377859aSNikita Kiryanov return -ENOENT; 102*4377859aSNikita Kiryanov 103*4377859aSNikita Kiryanov if (!strcmp(panel, "HDMI")) 104*4377859aSNikita Kiryanov preset = &preset_hdmi_1024X768; 105*4377859aSNikita Kiryanov else 106*4377859aSNikita Kiryanov return -EINVAL; 107*4377859aSNikita Kiryanov 108*4377859aSNikita Kiryanov ret = ipuv3_fb_init(&preset->mode, 0, preset->pixfmt); 109*4377859aSNikita Kiryanov if (ret) { 110*4377859aSNikita Kiryanov printf("Can't init display %s: %d\n", preset->mode.name, ret); 111*4377859aSNikita Kiryanov return ret; 112*4377859aSNikita Kiryanov } 113*4377859aSNikita Kiryanov 114*4377859aSNikita Kiryanov preset->enable(preset); 115*4377859aSNikita Kiryanov printf("Display: %s (%ux%u)\n", preset->mode.name, preset->mode.xres, 116*4377859aSNikita Kiryanov preset->mode.yres); 117*4377859aSNikita Kiryanov 118*4377859aSNikita Kiryanov return 0; 119*4377859aSNikita Kiryanov } 120deb94d61SNikita Kiryanov #else 121deb94d61SNikita Kiryanov static inline void cm_fx6_setup_display(void) {} 122deb94d61SNikita Kiryanov #endif /* CONFIG_VIDEO_IPUV3 */ 123deb94d61SNikita Kiryanov 124206f38f7SNikita Kiryanov #ifdef CONFIG_DWC_AHSATA 125206f38f7SNikita Kiryanov static int cm_fx6_issd_gpios[] = { 126206f38f7SNikita Kiryanov /* The order of the GPIOs in the array is important! */ 127b65cbab1SNikita Kiryanov CM_FX6_SATA_LDO_EN, 128206f38f7SNikita Kiryanov CM_FX6_SATA_PHY_SLP, 129206f38f7SNikita Kiryanov CM_FX6_SATA_NRSTDLY, 130206f38f7SNikita Kiryanov CM_FX6_SATA_PWREN, 131206f38f7SNikita Kiryanov CM_FX6_SATA_NSTANDBY1, 132206f38f7SNikita Kiryanov CM_FX6_SATA_NSTANDBY2, 133206f38f7SNikita Kiryanov }; 134206f38f7SNikita Kiryanov 135206f38f7SNikita Kiryanov static void cm_fx6_sata_power(int on) 136206f38f7SNikita Kiryanov { 137206f38f7SNikita Kiryanov int i; 138206f38f7SNikita Kiryanov 139206f38f7SNikita Kiryanov if (!on) { /* tell the iSSD that the power will be removed */ 140206f38f7SNikita Kiryanov gpio_direction_output(CM_FX6_SATA_PWLOSS_INT, 1); 141206f38f7SNikita Kiryanov mdelay(10); 142206f38f7SNikita Kiryanov } 143206f38f7SNikita Kiryanov 144206f38f7SNikita Kiryanov for (i = 0; i < ARRAY_SIZE(cm_fx6_issd_gpios); i++) { 145206f38f7SNikita Kiryanov gpio_direction_output(cm_fx6_issd_gpios[i], on); 146206f38f7SNikita Kiryanov udelay(100); 147206f38f7SNikita Kiryanov } 148206f38f7SNikita Kiryanov 149206f38f7SNikita Kiryanov if (!on) /* for compatibility lower the power loss interrupt */ 150206f38f7SNikita Kiryanov gpio_direction_output(CM_FX6_SATA_PWLOSS_INT, 0); 151206f38f7SNikita Kiryanov } 152206f38f7SNikita Kiryanov 153206f38f7SNikita Kiryanov static iomux_v3_cfg_t const sata_pads[] = { 154206f38f7SNikita Kiryanov /* SATA PWR */ 155206f38f7SNikita Kiryanov IOMUX_PADS(PAD_ENET_TX_EN__GPIO1_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL)), 156206f38f7SNikita Kiryanov IOMUX_PADS(PAD_EIM_A22__GPIO2_IO16 | MUX_PAD_CTRL(NO_PAD_CTRL)), 157206f38f7SNikita Kiryanov IOMUX_PADS(PAD_EIM_D20__GPIO3_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL)), 158206f38f7SNikita Kiryanov IOMUX_PADS(PAD_EIM_A25__GPIO5_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL)), 159206f38f7SNikita Kiryanov /* SATA CTRL */ 160206f38f7SNikita Kiryanov IOMUX_PADS(PAD_ENET_TXD0__GPIO1_IO30 | MUX_PAD_CTRL(NO_PAD_CTRL)), 161206f38f7SNikita Kiryanov IOMUX_PADS(PAD_EIM_D23__GPIO3_IO23 | MUX_PAD_CTRL(NO_PAD_CTRL)), 162206f38f7SNikita Kiryanov IOMUX_PADS(PAD_EIM_D29__GPIO3_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL)), 163206f38f7SNikita Kiryanov IOMUX_PADS(PAD_EIM_A23__GPIO6_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL)), 164206f38f7SNikita Kiryanov IOMUX_PADS(PAD_EIM_BCLK__GPIO6_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL)), 165206f38f7SNikita Kiryanov }; 166206f38f7SNikita Kiryanov 1678f488c1bSNikita Kiryanov static int cm_fx6_setup_issd(void) 168206f38f7SNikita Kiryanov { 1698f488c1bSNikita Kiryanov int ret, i; 170206f38f7SNikita Kiryanov 1718f488c1bSNikita Kiryanov SETUP_IOMUX_PADS(sata_pads); 1728f488c1bSNikita Kiryanov 1738f488c1bSNikita Kiryanov for (i = 0; i < ARRAY_SIZE(cm_fx6_issd_gpios); i++) { 1748f488c1bSNikita Kiryanov ret = gpio_request(cm_fx6_issd_gpios[i], "sata"); 1758f488c1bSNikita Kiryanov if (ret) 1768f488c1bSNikita Kiryanov return ret; 1778f488c1bSNikita Kiryanov } 1788f488c1bSNikita Kiryanov 1798f488c1bSNikita Kiryanov ret = gpio_request(CM_FX6_SATA_PWLOSS_INT, "sata_pwloss_int"); 1808f488c1bSNikita Kiryanov if (ret) 1818f488c1bSNikita Kiryanov return ret; 1828f488c1bSNikita Kiryanov 1838f488c1bSNikita Kiryanov return 0; 184206f38f7SNikita Kiryanov } 185206f38f7SNikita Kiryanov 186206f38f7SNikita Kiryanov #define CM_FX6_SATA_INIT_RETRIES 10 187206f38f7SNikita Kiryanov int sata_initialize(void) 188206f38f7SNikita Kiryanov { 189206f38f7SNikita Kiryanov int err, i; 190206f38f7SNikita Kiryanov 1918f488c1bSNikita Kiryanov /* Make sure this gpio has logical 0 value */ 1928f488c1bSNikita Kiryanov gpio_direction_output(CM_FX6_SATA_PWLOSS_INT, 0); 1938f488c1bSNikita Kiryanov udelay(100); 1948f488c1bSNikita Kiryanov cm_fx6_sata_power(1); 1958f488c1bSNikita Kiryanov 196206f38f7SNikita Kiryanov for (i = 0; i < CM_FX6_SATA_INIT_RETRIES; i++) { 197206f38f7SNikita Kiryanov err = setup_sata(); 198206f38f7SNikita Kiryanov if (err) { 199206f38f7SNikita Kiryanov printf("SATA setup failed: %d\n", err); 200206f38f7SNikita Kiryanov return err; 201206f38f7SNikita Kiryanov } 202206f38f7SNikita Kiryanov 203206f38f7SNikita Kiryanov udelay(100); 204206f38f7SNikita Kiryanov 205206f38f7SNikita Kiryanov err = __sata_initialize(); 206206f38f7SNikita Kiryanov if (!err) 207206f38f7SNikita Kiryanov break; 208206f38f7SNikita Kiryanov 209206f38f7SNikita Kiryanov /* There is no device on the SATA port */ 210206f38f7SNikita Kiryanov if (sata_port_status(0, 0) == 0) 211206f38f7SNikita Kiryanov break; 212206f38f7SNikita Kiryanov 213206f38f7SNikita Kiryanov /* There's a device, but link not established. Retry */ 214206f38f7SNikita Kiryanov } 215206f38f7SNikita Kiryanov 216206f38f7SNikita Kiryanov return err; 217206f38f7SNikita Kiryanov } 2189cad3544SNikita Kiryanov 2199cad3544SNikita Kiryanov int sata_stop(void) 2209cad3544SNikita Kiryanov { 2219cad3544SNikita Kiryanov __sata_stop(); 2229cad3544SNikita Kiryanov cm_fx6_sata_power(0); 2239cad3544SNikita Kiryanov mdelay(250); 2249cad3544SNikita Kiryanov 2259cad3544SNikita Kiryanov return 0; 2269cad3544SNikita Kiryanov } 2278f488c1bSNikita Kiryanov #else 2288f488c1bSNikita Kiryanov static int cm_fx6_setup_issd(void) { return 0; } 229206f38f7SNikita Kiryanov #endif 230206f38f7SNikita Kiryanov 231f42b2f60SNikita Kiryanov #ifdef CONFIG_SYS_I2C_MXC 232f42b2f60SNikita Kiryanov #define I2C_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ 233f42b2f60SNikita Kiryanov PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ 234f42b2f60SNikita Kiryanov PAD_CTL_ODE | PAD_CTL_SRE_FAST) 235f42b2f60SNikita Kiryanov 236f42b2f60SNikita Kiryanov I2C_PADS(i2c0_pads, 237f42b2f60SNikita Kiryanov PAD_EIM_D21__I2C1_SCL | MUX_PAD_CTRL(I2C_PAD_CTRL), 238f42b2f60SNikita Kiryanov PAD_EIM_D21__GPIO3_IO21 | MUX_PAD_CTRL(I2C_PAD_CTRL), 239f42b2f60SNikita Kiryanov IMX_GPIO_NR(3, 21), 240f42b2f60SNikita Kiryanov PAD_EIM_D28__I2C1_SDA | MUX_PAD_CTRL(I2C_PAD_CTRL), 241f42b2f60SNikita Kiryanov PAD_EIM_D28__GPIO3_IO28 | MUX_PAD_CTRL(I2C_PAD_CTRL), 242f42b2f60SNikita Kiryanov IMX_GPIO_NR(3, 28)); 243f42b2f60SNikita Kiryanov 244f42b2f60SNikita Kiryanov I2C_PADS(i2c1_pads, 245f42b2f60SNikita Kiryanov PAD_KEY_COL3__I2C2_SCL | MUX_PAD_CTRL(I2C_PAD_CTRL), 246f42b2f60SNikita Kiryanov PAD_KEY_COL3__GPIO4_IO12 | MUX_PAD_CTRL(I2C_PAD_CTRL), 247f42b2f60SNikita Kiryanov IMX_GPIO_NR(4, 12), 248f42b2f60SNikita Kiryanov PAD_KEY_ROW3__I2C2_SDA | MUX_PAD_CTRL(I2C_PAD_CTRL), 249f42b2f60SNikita Kiryanov PAD_KEY_ROW3__GPIO4_IO13 | MUX_PAD_CTRL(I2C_PAD_CTRL), 250f42b2f60SNikita Kiryanov IMX_GPIO_NR(4, 13)); 251f42b2f60SNikita Kiryanov 252f42b2f60SNikita Kiryanov I2C_PADS(i2c2_pads, 253f42b2f60SNikita Kiryanov PAD_GPIO_3__I2C3_SCL | MUX_PAD_CTRL(I2C_PAD_CTRL), 254f42b2f60SNikita Kiryanov PAD_GPIO_3__GPIO1_IO03 | MUX_PAD_CTRL(I2C_PAD_CTRL), 255f42b2f60SNikita Kiryanov IMX_GPIO_NR(1, 3), 256f42b2f60SNikita Kiryanov PAD_GPIO_6__I2C3_SDA | MUX_PAD_CTRL(I2C_PAD_CTRL), 257f42b2f60SNikita Kiryanov PAD_GPIO_6__GPIO1_IO06 | MUX_PAD_CTRL(I2C_PAD_CTRL), 258f42b2f60SNikita Kiryanov IMX_GPIO_NR(1, 6)); 259f42b2f60SNikita Kiryanov 260f42b2f60SNikita Kiryanov 261edbf8b4fSSimon Glass static int cm_fx6_setup_one_i2c(int busnum, struct i2c_pads_info *pads) 262f42b2f60SNikita Kiryanov { 263edbf8b4fSSimon Glass int ret; 264edbf8b4fSSimon Glass 265edbf8b4fSSimon Glass ret = setup_i2c(busnum, CONFIG_SYS_I2C_SPEED, 0x7f, pads); 266edbf8b4fSSimon Glass if (ret) 267edbf8b4fSSimon Glass printf("Warning: I2C%d setup failed: %d\n", busnum, ret); 268edbf8b4fSSimon Glass 269edbf8b4fSSimon Glass return ret; 270edbf8b4fSSimon Glass } 271edbf8b4fSSimon Glass 272edbf8b4fSSimon Glass static int cm_fx6_setup_i2c(void) 273edbf8b4fSSimon Glass { 274edbf8b4fSSimon Glass int ret = 0, err; 275edbf8b4fSSimon Glass 276edbf8b4fSSimon Glass /* i2c<x>_pads are wierd macro variables; we can't use an array */ 277edbf8b4fSSimon Glass err = cm_fx6_setup_one_i2c(0, I2C_PADS_INFO(i2c0_pads)); 278edbf8b4fSSimon Glass if (err) 279edbf8b4fSSimon Glass ret = err; 280edbf8b4fSSimon Glass err = cm_fx6_setup_one_i2c(1, I2C_PADS_INFO(i2c1_pads)); 281edbf8b4fSSimon Glass if (err) 282edbf8b4fSSimon Glass ret = err; 283edbf8b4fSSimon Glass err = cm_fx6_setup_one_i2c(2, I2C_PADS_INFO(i2c2_pads)); 284edbf8b4fSSimon Glass if (err) 285edbf8b4fSSimon Glass ret = err; 286edbf8b4fSSimon Glass 287edbf8b4fSSimon Glass return ret; 288f42b2f60SNikita Kiryanov } 289f42b2f60SNikita Kiryanov #else 290edbf8b4fSSimon Glass static int cm_fx6_setup_i2c(void) { return 0; } 291f42b2f60SNikita Kiryanov #endif 292f42b2f60SNikita Kiryanov 2930f3effb9SNikita Kiryanov #ifdef CONFIG_USB_EHCI_MX6 2940f3effb9SNikita Kiryanov #define WEAK_PULLDOWN (PAD_CTL_PUS_100K_DOWN | \ 2950f3effb9SNikita Kiryanov PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ 2960f3effb9SNikita Kiryanov PAD_CTL_HYS | PAD_CTL_SRE_SLOW) 2978f488c1bSNikita Kiryanov #define MX6_USBNC_BASEADDR 0x2184800 2988f488c1bSNikita Kiryanov #define USBNC_USB_H1_PWR_POL (1 << 9) 2990f3effb9SNikita Kiryanov 3008f488c1bSNikita Kiryanov static int cm_fx6_setup_usb_host(void) 3010f3effb9SNikita Kiryanov { 3020f3effb9SNikita Kiryanov int err; 3030f3effb9SNikita Kiryanov 3040f3effb9SNikita Kiryanov err = gpio_request(CM_FX6_USB_HUB_RST, "usb hub rst"); 3058f488c1bSNikita Kiryanov if (err) 3068f488c1bSNikita Kiryanov return err; 3070f3effb9SNikita Kiryanov 3088f488c1bSNikita Kiryanov SETUP_IOMUX_PAD(PAD_GPIO_0__USB_H1_PWR | MUX_PAD_CTRL(NO_PAD_CTRL)); 3090f3effb9SNikita Kiryanov SETUP_IOMUX_PAD(PAD_SD3_RST__GPIO7_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL)); 3100f3effb9SNikita Kiryanov 3110f3effb9SNikita Kiryanov return 0; 3120f3effb9SNikita Kiryanov } 3130f3effb9SNikita Kiryanov 3148f488c1bSNikita Kiryanov static int cm_fx6_setup_usb_otg(void) 3150f3effb9SNikita Kiryanov { 3168f488c1bSNikita Kiryanov int err; 3170f3effb9SNikita Kiryanov struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; 3180f3effb9SNikita Kiryanov 3198f488c1bSNikita Kiryanov err = gpio_request(SB_FX6_USB_OTG_PWR, "usb-pwr"); 3208f488c1bSNikita Kiryanov if (err) { 3218f488c1bSNikita Kiryanov printf("USB OTG pwr gpio request failed: %d\n", err); 3228f488c1bSNikita Kiryanov return err; 3230f3effb9SNikita Kiryanov } 3240f3effb9SNikita Kiryanov 3250f3effb9SNikita Kiryanov SETUP_IOMUX_PAD(PAD_EIM_D22__GPIO3_IO22 | MUX_PAD_CTRL(NO_PAD_CTRL)); 3260f3effb9SNikita Kiryanov SETUP_IOMUX_PAD(PAD_ENET_RX_ER__USB_OTG_ID | 3270f3effb9SNikita Kiryanov MUX_PAD_CTRL(WEAK_PULLDOWN)); 3280f3effb9SNikita Kiryanov clrbits_le32(&iomux->gpr[1], IOMUXC_GPR1_OTG_ID_MASK); 3290f3effb9SNikita Kiryanov /* disable ext. charger detect, or it'll affect signal quality at dp. */ 3300f3effb9SNikita Kiryanov return gpio_direction_output(SB_FX6_USB_OTG_PWR, 0); 3310f3effb9SNikita Kiryanov } 3320f3effb9SNikita Kiryanov 3330f3effb9SNikita Kiryanov int board_ehci_hcd_init(int port) 3340f3effb9SNikita Kiryanov { 3358f488c1bSNikita Kiryanov int ret; 3360f3effb9SNikita Kiryanov u32 *usbnc_usb_uh1_ctrl = (u32 *)(MX6_USBNC_BASEADDR + 4); 3370f3effb9SNikita Kiryanov 3388f488c1bSNikita Kiryanov /* Only 1 host controller in use. port 0 is OTG & needs no attention */ 3398f488c1bSNikita Kiryanov if (port != 1) 3408f488c1bSNikita Kiryanov return 0; 3410f3effb9SNikita Kiryanov 3420f3effb9SNikita Kiryanov /* Set PWR polarity to match power switch's enable polarity */ 3430f3effb9SNikita Kiryanov setbits_le32(usbnc_usb_uh1_ctrl, USBNC_USB_H1_PWR_POL); 3448f488c1bSNikita Kiryanov ret = gpio_direction_output(CM_FX6_USB_HUB_RST, 0); 3458f488c1bSNikita Kiryanov if (ret) 3468f488c1bSNikita Kiryanov return ret; 3478f488c1bSNikita Kiryanov 3488f488c1bSNikita Kiryanov udelay(10); 3498f488c1bSNikita Kiryanov ret = gpio_direction_output(CM_FX6_USB_HUB_RST, 1); 3508f488c1bSNikita Kiryanov if (ret) 3518f488c1bSNikita Kiryanov return ret; 3528f488c1bSNikita Kiryanov 3538f488c1bSNikita Kiryanov mdelay(1); 3540f3effb9SNikita Kiryanov 3550f3effb9SNikita Kiryanov return 0; 3560f3effb9SNikita Kiryanov } 3570f3effb9SNikita Kiryanov 3580f3effb9SNikita Kiryanov int board_ehci_power(int port, int on) 3590f3effb9SNikita Kiryanov { 3600f3effb9SNikita Kiryanov if (port == 0) 3610f3effb9SNikita Kiryanov return gpio_direction_output(SB_FX6_USB_OTG_PWR, on); 3620f3effb9SNikita Kiryanov 3630f3effb9SNikita Kiryanov return 0; 3640f3effb9SNikita Kiryanov } 3658f488c1bSNikita Kiryanov #else 3668f488c1bSNikita Kiryanov static int cm_fx6_setup_usb_otg(void) { return 0; } 3678f488c1bSNikita Kiryanov static int cm_fx6_setup_usb_host(void) { return 0; } 3680f3effb9SNikita Kiryanov #endif 3690f3effb9SNikita Kiryanov 37002b1343eSNikita Kiryanov #ifdef CONFIG_FEC_MXC 37102b1343eSNikita Kiryanov #define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ 37202b1343eSNikita Kiryanov PAD_CTL_DSE_40ohm | PAD_CTL_HYS) 37302b1343eSNikita Kiryanov 37402b1343eSNikita Kiryanov static int mx6_rgmii_rework(struct phy_device *phydev) 37502b1343eSNikita Kiryanov { 37602b1343eSNikita Kiryanov unsigned short val; 37702b1343eSNikita Kiryanov 37802b1343eSNikita Kiryanov /* Ar8031 phy SmartEEE feature cause link status generates glitch, 37902b1343eSNikita Kiryanov * which cause ethernet link down/up issue, so disable SmartEEE 38002b1343eSNikita Kiryanov */ 38102b1343eSNikita Kiryanov phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x3); 38202b1343eSNikita Kiryanov phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x805d); 38302b1343eSNikita Kiryanov phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4003); 38402b1343eSNikita Kiryanov val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe); 38502b1343eSNikita Kiryanov val &= ~(0x1 << 8); 38602b1343eSNikita Kiryanov phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val); 38702b1343eSNikita Kiryanov 38802b1343eSNikita Kiryanov /* To enable AR8031 ouput a 125MHz clk from CLK_25M */ 38902b1343eSNikita Kiryanov phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7); 39002b1343eSNikita Kiryanov phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016); 39102b1343eSNikita Kiryanov phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007); 39202b1343eSNikita Kiryanov 39302b1343eSNikita Kiryanov val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe); 39402b1343eSNikita Kiryanov val &= 0xffe3; 39502b1343eSNikita Kiryanov val |= 0x18; 39602b1343eSNikita Kiryanov phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val); 39702b1343eSNikita Kiryanov 39802b1343eSNikita Kiryanov /* introduce tx clock delay */ 39902b1343eSNikita Kiryanov phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5); 40002b1343eSNikita Kiryanov val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e); 40102b1343eSNikita Kiryanov val |= 0x0100; 40202b1343eSNikita Kiryanov phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val); 40302b1343eSNikita Kiryanov 40402b1343eSNikita Kiryanov return 0; 40502b1343eSNikita Kiryanov } 40602b1343eSNikita Kiryanov 40702b1343eSNikita Kiryanov int board_phy_config(struct phy_device *phydev) 40802b1343eSNikita Kiryanov { 40902b1343eSNikita Kiryanov mx6_rgmii_rework(phydev); 41002b1343eSNikita Kiryanov 41102b1343eSNikita Kiryanov if (phydev->drv->config) 41202b1343eSNikita Kiryanov return phydev->drv->config(phydev); 41302b1343eSNikita Kiryanov 41402b1343eSNikita Kiryanov return 0; 41502b1343eSNikita Kiryanov } 41602b1343eSNikita Kiryanov 41702b1343eSNikita Kiryanov static iomux_v3_cfg_t const enet_pads[] = { 41802b1343eSNikita Kiryanov IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL)), 41902b1343eSNikita Kiryanov IOMUX_PADS(PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL)), 42002b1343eSNikita Kiryanov IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL)), 42102b1343eSNikita Kiryanov IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)), 42202b1343eSNikita Kiryanov IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)), 42302b1343eSNikita Kiryanov IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)), 42402b1343eSNikita Kiryanov IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)), 42502b1343eSNikita Kiryanov IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL)), 42602b1343eSNikita Kiryanov IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)), 42702b1343eSNikita Kiryanov IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)), 42802b1343eSNikita Kiryanov IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)), 42902b1343eSNikita Kiryanov IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)), 43002b1343eSNikita Kiryanov IOMUX_PADS(PAD_GPIO_0__CCM_CLKO1 | MUX_PAD_CTRL(NO_PAD_CTRL)), 43102b1343eSNikita Kiryanov IOMUX_PADS(PAD_GPIO_3__CCM_CLKO2 | MUX_PAD_CTRL(NO_PAD_CTRL)), 43202b1343eSNikita Kiryanov IOMUX_PADS(PAD_SD4_DAT0__GPIO2_IO08 | MUX_PAD_CTRL(0x84)), 43302b1343eSNikita Kiryanov IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK | 43402b1343eSNikita Kiryanov MUX_PAD_CTRL(ENET_PAD_CTRL)), 43502b1343eSNikita Kiryanov IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL | 43602b1343eSNikita Kiryanov MUX_PAD_CTRL(ENET_PAD_CTRL)), 43702b1343eSNikita Kiryanov IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL | 43802b1343eSNikita Kiryanov MUX_PAD_CTRL(ENET_PAD_CTRL)), 43902b1343eSNikita Kiryanov }; 44002b1343eSNikita Kiryanov 441eab29802SNikita Kiryanov static int handle_mac_address(char *env_var, uint eeprom_bus) 442f66113c0SNikita Kiryanov { 443f66113c0SNikita Kiryanov unsigned char enetaddr[6]; 444f66113c0SNikita Kiryanov int rc; 445f66113c0SNikita Kiryanov 446eab29802SNikita Kiryanov rc = eth_getenv_enetaddr(env_var, enetaddr); 447f66113c0SNikita Kiryanov if (rc) 448f66113c0SNikita Kiryanov return 0; 449f66113c0SNikita Kiryanov 450eab29802SNikita Kiryanov rc = cl_eeprom_read_mac_addr(enetaddr, eeprom_bus); 451f66113c0SNikita Kiryanov if (rc) 452f66113c0SNikita Kiryanov return rc; 453f66113c0SNikita Kiryanov 4540adb5b76SJoe Hershberger if (!is_valid_ethaddr(enetaddr)) 455f66113c0SNikita Kiryanov return -1; 456f66113c0SNikita Kiryanov 457eab29802SNikita Kiryanov return eth_setenv_enetaddr(env_var, enetaddr); 458f66113c0SNikita Kiryanov } 459f66113c0SNikita Kiryanov 460eab29802SNikita Kiryanov #define SB_FX6_I2C_EEPROM_BUS 0 461eab29802SNikita Kiryanov #define NO_MAC_ADDR "No MAC address found for %s\n" 46202b1343eSNikita Kiryanov int board_eth_init(bd_t *bis) 46302b1343eSNikita Kiryanov { 4648f488c1bSNikita Kiryanov int err; 4658f488c1bSNikita Kiryanov 466eab29802SNikita Kiryanov if (handle_mac_address("ethaddr", CONFIG_SYS_I2C_EEPROM_BUS)) 467eab29802SNikita Kiryanov printf(NO_MAC_ADDR, "primary NIC"); 468eab29802SNikita Kiryanov 469eab29802SNikita Kiryanov if (handle_mac_address("eth1addr", SB_FX6_I2C_EEPROM_BUS)) 470eab29802SNikita Kiryanov printf(NO_MAC_ADDR, "secondary NIC"); 471f66113c0SNikita Kiryanov 47202b1343eSNikita Kiryanov SETUP_IOMUX_PADS(enet_pads); 47302b1343eSNikita Kiryanov /* phy reset */ 4748f488c1bSNikita Kiryanov err = gpio_request(CM_FX6_ENET_NRST, "enet_nrst"); 4758f488c1bSNikita Kiryanov if (err) 4768f488c1bSNikita Kiryanov printf("Etnernet NRST gpio request failed: %d\n", err); 47702b1343eSNikita Kiryanov gpio_direction_output(CM_FX6_ENET_NRST, 0); 47802b1343eSNikita Kiryanov udelay(500); 47902b1343eSNikita Kiryanov gpio_set_value(CM_FX6_ENET_NRST, 1); 48002b1343eSNikita Kiryanov enable_enet_clk(1); 48102b1343eSNikita Kiryanov return cpu_eth_init(bis); 48202b1343eSNikita Kiryanov } 48302b1343eSNikita Kiryanov #endif 48402b1343eSNikita Kiryanov 485a6b0652bSNikita Kiryanov #ifdef CONFIG_NAND_MXS 486a6b0652bSNikita Kiryanov static iomux_v3_cfg_t const nand_pads[] = { 487a6b0652bSNikita Kiryanov IOMUX_PADS(PAD_NANDF_CLE__NAND_CLE | MUX_PAD_CTRL(NO_PAD_CTRL)), 488a6b0652bSNikita Kiryanov IOMUX_PADS(PAD_NANDF_ALE__NAND_ALE | MUX_PAD_CTRL(NO_PAD_CTRL)), 489a6b0652bSNikita Kiryanov IOMUX_PADS(PAD_NANDF_CS0__NAND_CE0_B | MUX_PAD_CTRL(NO_PAD_CTRL)), 490a6b0652bSNikita Kiryanov IOMUX_PADS(PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(NO_PAD_CTRL)), 491a6b0652bSNikita Kiryanov IOMUX_PADS(PAD_NANDF_D0__NAND_DATA00 | MUX_PAD_CTRL(NO_PAD_CTRL)), 492a6b0652bSNikita Kiryanov IOMUX_PADS(PAD_NANDF_D1__NAND_DATA01 | MUX_PAD_CTRL(NO_PAD_CTRL)), 493a6b0652bSNikita Kiryanov IOMUX_PADS(PAD_NANDF_D2__NAND_DATA02 | MUX_PAD_CTRL(NO_PAD_CTRL)), 494a6b0652bSNikita Kiryanov IOMUX_PADS(PAD_NANDF_D3__NAND_DATA03 | MUX_PAD_CTRL(NO_PAD_CTRL)), 495a6b0652bSNikita Kiryanov IOMUX_PADS(PAD_NANDF_D4__NAND_DATA04 | MUX_PAD_CTRL(NO_PAD_CTRL)), 496a6b0652bSNikita Kiryanov IOMUX_PADS(PAD_NANDF_D5__NAND_DATA05 | MUX_PAD_CTRL(NO_PAD_CTRL)), 497a6b0652bSNikita Kiryanov IOMUX_PADS(PAD_NANDF_D6__NAND_DATA06 | MUX_PAD_CTRL(NO_PAD_CTRL)), 498a6b0652bSNikita Kiryanov IOMUX_PADS(PAD_NANDF_D7__NAND_DATA07 | MUX_PAD_CTRL(NO_PAD_CTRL)), 499a6b0652bSNikita Kiryanov IOMUX_PADS(PAD_SD4_CMD__NAND_RE_B | MUX_PAD_CTRL(NO_PAD_CTRL)), 500a6b0652bSNikita Kiryanov IOMUX_PADS(PAD_SD4_CLK__NAND_WE_B | MUX_PAD_CTRL(NO_PAD_CTRL)), 501a6b0652bSNikita Kiryanov }; 502a6b0652bSNikita Kiryanov 503a6b0652bSNikita Kiryanov static void cm_fx6_setup_gpmi_nand(void) 504a6b0652bSNikita Kiryanov { 505a6b0652bSNikita Kiryanov SETUP_IOMUX_PADS(nand_pads); 506a6b0652bSNikita Kiryanov /* Enable clock roots */ 507a6b0652bSNikita Kiryanov enable_usdhc_clk(1, 3); 508a6b0652bSNikita Kiryanov enable_usdhc_clk(1, 4); 509a6b0652bSNikita Kiryanov 510a6b0652bSNikita Kiryanov setup_gpmi_io_clk(MXC_CCM_CS2CDR_ENFC_CLK_PODF(0xf) | 511a6b0652bSNikita Kiryanov MXC_CCM_CS2CDR_ENFC_CLK_PRED(1) | 512a6b0652bSNikita Kiryanov MXC_CCM_CS2CDR_ENFC_CLK_SEL(0)); 513a6b0652bSNikita Kiryanov } 514a6b0652bSNikita Kiryanov #else 515a6b0652bSNikita Kiryanov static void cm_fx6_setup_gpmi_nand(void) {} 516a6b0652bSNikita Kiryanov #endif 517a6b0652bSNikita Kiryanov 518e32028a7SNikita Kiryanov #ifdef CONFIG_FSL_ESDHC 519e32028a7SNikita Kiryanov static struct fsl_esdhc_cfg usdhc_cfg[3] = { 520e32028a7SNikita Kiryanov {USDHC1_BASE_ADDR}, 521e32028a7SNikita Kiryanov {USDHC2_BASE_ADDR}, 522e32028a7SNikita Kiryanov {USDHC3_BASE_ADDR}, 523e32028a7SNikita Kiryanov }; 524e32028a7SNikita Kiryanov 525e32028a7SNikita Kiryanov static enum mxc_clock usdhc_clk[3] = { 526e32028a7SNikita Kiryanov MXC_ESDHC_CLK, 527e32028a7SNikita Kiryanov MXC_ESDHC2_CLK, 528e32028a7SNikita Kiryanov MXC_ESDHC3_CLK, 529e32028a7SNikita Kiryanov }; 530e32028a7SNikita Kiryanov 531e32028a7SNikita Kiryanov int board_mmc_init(bd_t *bis) 532e32028a7SNikita Kiryanov { 533e32028a7SNikita Kiryanov int i; 534e32028a7SNikita Kiryanov 535e32028a7SNikita Kiryanov cm_fx6_set_usdhc_iomux(); 536e32028a7SNikita Kiryanov for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { 537e32028a7SNikita Kiryanov usdhc_cfg[i].sdhc_clk = mxc_get_clock(usdhc_clk[i]); 538e32028a7SNikita Kiryanov usdhc_cfg[i].max_bus_width = 4; 539e32028a7SNikita Kiryanov fsl_esdhc_initialize(bis, &usdhc_cfg[i]); 540e32028a7SNikita Kiryanov enable_usdhc_clk(1, i); 541e32028a7SNikita Kiryanov } 542e32028a7SNikita Kiryanov 543e32028a7SNikita Kiryanov return 0; 544e32028a7SNikita Kiryanov } 545e32028a7SNikita Kiryanov #endif 546e32028a7SNikita Kiryanov 5478f488c1bSNikita Kiryanov #ifdef CONFIG_MXC_SPI 5488f488c1bSNikita Kiryanov int cm_fx6_setup_ecspi(void) 5498f488c1bSNikita Kiryanov { 5508f488c1bSNikita Kiryanov cm_fx6_set_ecspi_iomux(); 5518f488c1bSNikita Kiryanov return gpio_request(CM_FX6_ECSPI_BUS0_CS0, "ecspi_bus0_cs0"); 5528f488c1bSNikita Kiryanov } 5538f488c1bSNikita Kiryanov #else 5548f488c1bSNikita Kiryanov int cm_fx6_setup_ecspi(void) { return 0; } 5558f488c1bSNikita Kiryanov #endif 5568f488c1bSNikita Kiryanov 55702b1343eSNikita Kiryanov #ifdef CONFIG_OF_BOARD_SETUP 558e895a4b0SSimon Glass int ft_board_setup(void *blob, bd_t *bd) 55902b1343eSNikita Kiryanov { 56002b1343eSNikita Kiryanov uint8_t enetaddr[6]; 56102b1343eSNikita Kiryanov 56202b1343eSNikita Kiryanov /* MAC addr */ 56302b1343eSNikita Kiryanov if (eth_getenv_enetaddr("ethaddr", enetaddr)) { 564cc67f4a6SNikita Kiryanov fdt_find_and_setprop(blob, 565cc67f4a6SNikita Kiryanov "/soc/aips-bus@02100000/ethernet@02188000", 566cc67f4a6SNikita Kiryanov "local-mac-address", enetaddr, 6, 1); 56702b1343eSNikita Kiryanov } 568e895a4b0SSimon Glass 569eab29802SNikita Kiryanov if (eth_getenv_enetaddr("eth1addr", enetaddr)) { 570eab29802SNikita Kiryanov fdt_find_and_setprop(blob, "/eth@pcie", "local-mac-address", 571eab29802SNikita Kiryanov enetaddr, 6, 1); 572eab29802SNikita Kiryanov } 573eab29802SNikita Kiryanov 574e895a4b0SSimon Glass return 0; 57502b1343eSNikita Kiryanov } 57602b1343eSNikita Kiryanov #endif 57702b1343eSNikita Kiryanov 578e32028a7SNikita Kiryanov int board_init(void) 579e32028a7SNikita Kiryanov { 580edbf8b4fSSimon Glass int ret; 581edbf8b4fSSimon Glass 582e32028a7SNikita Kiryanov gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; 583a6b0652bSNikita Kiryanov cm_fx6_setup_gpmi_nand(); 584edbf8b4fSSimon Glass 5858f488c1bSNikita Kiryanov ret = cm_fx6_setup_ecspi(); 5868f488c1bSNikita Kiryanov if (ret) 5878f488c1bSNikita Kiryanov printf("Warning: ECSPI setup failed: %d\n", ret); 5888f488c1bSNikita Kiryanov 5898f488c1bSNikita Kiryanov ret = cm_fx6_setup_usb_otg(); 5908f488c1bSNikita Kiryanov if (ret) 5918f488c1bSNikita Kiryanov printf("Warning: USB OTG setup failed: %d\n", ret); 5928f488c1bSNikita Kiryanov 5938f488c1bSNikita Kiryanov ret = cm_fx6_setup_usb_host(); 5948f488c1bSNikita Kiryanov if (ret) 5958f488c1bSNikita Kiryanov printf("Warning: USB host setup failed: %d\n", ret); 5968f488c1bSNikita Kiryanov 5978f488c1bSNikita Kiryanov /* 5988f488c1bSNikita Kiryanov * cm-fx6 may have iSSD not assembled and in this case it has 5998f488c1bSNikita Kiryanov * bypasses for a (m)SATA socket on the baseboard. The socketed 6008f488c1bSNikita Kiryanov * device is not controlled by those GPIOs. So just print a warning 6018f488c1bSNikita Kiryanov * if the setup fails. 6028f488c1bSNikita Kiryanov */ 6038f488c1bSNikita Kiryanov ret = cm_fx6_setup_issd(); 6048f488c1bSNikita Kiryanov if (ret) 6058f488c1bSNikita Kiryanov printf("Warning: iSSD setup failed: %d\n", ret); 6068f488c1bSNikita Kiryanov 607edbf8b4fSSimon Glass /* Warn on failure but do not abort boot */ 608edbf8b4fSSimon Glass ret = cm_fx6_setup_i2c(); 609edbf8b4fSSimon Glass if (ret) 610edbf8b4fSSimon Glass printf("Warning: I2C setup failed: %d\n", ret); 611a6b0652bSNikita Kiryanov 612deb94d61SNikita Kiryanov cm_fx6_setup_display(); 613deb94d61SNikita Kiryanov 614e32028a7SNikita Kiryanov return 0; 615e32028a7SNikita Kiryanov } 616e32028a7SNikita Kiryanov 617e32028a7SNikita Kiryanov int checkboard(void) 618e32028a7SNikita Kiryanov { 619e32028a7SNikita Kiryanov puts("Board: CM-FX6\n"); 620e32028a7SNikita Kiryanov return 0; 621e32028a7SNikita Kiryanov } 622e32028a7SNikita Kiryanov 623e32028a7SNikita Kiryanov void dram_init_banksize(void) 624e32028a7SNikita Kiryanov { 625e32028a7SNikita Kiryanov gd->bd->bi_dram[0].start = PHYS_SDRAM_1; 626e32028a7SNikita Kiryanov gd->bd->bi_dram[1].start = PHYS_SDRAM_2; 627e32028a7SNikita Kiryanov 628e32028a7SNikita Kiryanov switch (gd->ram_size) { 629e32028a7SNikita Kiryanov case 0x10000000: /* DDR_16BIT_256MB */ 630e32028a7SNikita Kiryanov gd->bd->bi_dram[0].size = 0x10000000; 631e32028a7SNikita Kiryanov gd->bd->bi_dram[1].size = 0; 632e32028a7SNikita Kiryanov break; 633e32028a7SNikita Kiryanov case 0x20000000: /* DDR_32BIT_512MB */ 634e32028a7SNikita Kiryanov gd->bd->bi_dram[0].size = 0x20000000; 635e32028a7SNikita Kiryanov gd->bd->bi_dram[1].size = 0; 636e32028a7SNikita Kiryanov break; 637e32028a7SNikita Kiryanov case 0x40000000: 638e32028a7SNikita Kiryanov if (is_cpu_type(MXC_CPU_MX6SOLO)) { /* DDR_32BIT_1GB */ 639e32028a7SNikita Kiryanov gd->bd->bi_dram[0].size = 0x20000000; 640e32028a7SNikita Kiryanov gd->bd->bi_dram[1].size = 0x20000000; 641e32028a7SNikita Kiryanov } else { /* DDR_64BIT_1GB */ 642e32028a7SNikita Kiryanov gd->bd->bi_dram[0].size = 0x40000000; 643e32028a7SNikita Kiryanov gd->bd->bi_dram[1].size = 0; 644e32028a7SNikita Kiryanov } 645e32028a7SNikita Kiryanov break; 646e32028a7SNikita Kiryanov case 0x80000000: /* DDR_64BIT_2GB */ 647e32028a7SNikita Kiryanov gd->bd->bi_dram[0].size = 0x40000000; 648e32028a7SNikita Kiryanov gd->bd->bi_dram[1].size = 0x40000000; 649e32028a7SNikita Kiryanov break; 650e32028a7SNikita Kiryanov case 0xEFF00000: /* DDR_64BIT_4GB */ 651e32028a7SNikita Kiryanov gd->bd->bi_dram[0].size = 0x70000000; 652e32028a7SNikita Kiryanov gd->bd->bi_dram[1].size = 0x7FF00000; 653e32028a7SNikita Kiryanov break; 654e32028a7SNikita Kiryanov } 655e32028a7SNikita Kiryanov } 656e32028a7SNikita Kiryanov 657e32028a7SNikita Kiryanov int dram_init(void) 658e32028a7SNikita Kiryanov { 659e32028a7SNikita Kiryanov gd->ram_size = imx_ddr_size(); 660e32028a7SNikita Kiryanov switch (gd->ram_size) { 661e32028a7SNikita Kiryanov case 0x10000000: 662e32028a7SNikita Kiryanov case 0x20000000: 663e32028a7SNikita Kiryanov case 0x40000000: 664e32028a7SNikita Kiryanov case 0x80000000: 665e32028a7SNikita Kiryanov break; 666e32028a7SNikita Kiryanov case 0xF0000000: 667e32028a7SNikita Kiryanov gd->ram_size -= 0x100000; 668e32028a7SNikita Kiryanov break; 669e32028a7SNikita Kiryanov default: 670e32028a7SNikita Kiryanov printf("ERROR: Unsupported DRAM size 0x%lx\n", gd->ram_size); 671e32028a7SNikita Kiryanov return -1; 672e32028a7SNikita Kiryanov } 673e32028a7SNikita Kiryanov 674e32028a7SNikita Kiryanov return 0; 675e32028a7SNikita Kiryanov } 676f66113c0SNikita Kiryanov 677f66113c0SNikita Kiryanov u32 get_board_rev(void) 678f66113c0SNikita Kiryanov { 679f66113c0SNikita Kiryanov return cl_eeprom_get_board_rev(); 680f66113c0SNikita Kiryanov } 681f66113c0SNikita Kiryanov 6823f0e935fSSimon Glass static struct mxc_serial_platdata cm_fx6_mxc_serial_plat = { 6833f0e935fSSimon Glass .reg = (struct mxc_uart *)UART4_BASE, 6843f0e935fSSimon Glass }; 6853f0e935fSSimon Glass 6863f0e935fSSimon Glass U_BOOT_DEVICE(cm_fx6_serial) = { 6873f0e935fSSimon Glass .name = "serial_mxc", 6883f0e935fSSimon Glass .platdata = &cm_fx6_mxc_serial_plat, 6893f0e935fSSimon Glass }; 690