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