1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2012 Freescale Semiconductor, Inc. 4 * 5 * Author: Fabio Estevam <fabio.estevam@freescale.com> 6 */ 7 8#include <common.h> 9#include <image.h> 10#include <init.h> 11#include <net.h> 12#include <asm/global_data.h> 13#include <asm/io.h> 14#include <asm/arch/clock.h> 15#include <asm/arch/imx-regs.h> 16#include <asm/arch/iomux.h> 17#include <asm/arch/mx6-pins.h> 18#include <asm/sections.h> 19#include <env.h> 20#include <linux/errno.h> 21#include <asm/gpio.h> 22#include <asm/mach-imx/iomux-v3.h> 23#include <asm/mach-imx/boot_mode.h> 24#include <asm/mach-imx/spi.h> 25#include <mmc.h> 26#include <fsl_esdhc_imx.h> 27#include <miiphy.h> 28#include <asm/arch/sys_proto.h> 29#include <input.h> 30#include <asm/arch/mxc_hdmi.h> 31#include <asm/mach-imx/video.h> 32#include <asm/arch/crm_regs.h> 33#include <pca953x.h> 34#include <power/pmic.h> 35#include <power/pfuze100_pmic.h> 36#include "../common/pfuze.h" 37 38DECLARE_GLOBAL_DATA_PTR; 39 40#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ 41 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ 42 PAD_CTL_SRE_FAST | PAD_CTL_HYS) 43 44#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \ 45 PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \ 46 PAD_CTL_SRE_FAST | PAD_CTL_HYS) 47 48#define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ 49 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS) 50 51#define GPMI_PAD_CTRL0 (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP) 52#define GPMI_PAD_CTRL1 (PAD_CTL_DSE_40ohm | PAD_CTL_SPEED_MED | \ 53 PAD_CTL_SRE_FAST) 54#define GPMI_PAD_CTRL2 (GPMI_PAD_CTRL0 | GPMI_PAD_CTRL1) 55 56#define WEIM_NOR_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ 57 PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ 58 PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) 59 60int dram_init(void) 61{ 62 gd->ram_size = imx_ddr_size(); 63 64 return 0; 65} 66 67static iomux_v3_cfg_t const uart4_pads[] = { 68 IOMUX_PADS(PAD_KEY_COL0__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), 69 IOMUX_PADS(PAD_KEY_ROW0__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), 70}; 71 72static iomux_v3_cfg_t const port_exp[] = { 73 IOMUX_PADS(PAD_SD2_DAT0__GPIO1_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL)), 74}; 75 76#ifdef CONFIG_MTD_NOR_FLASH 77static iomux_v3_cfg_t const eimnor_pads[] = { 78 IOMUX_PADS(PAD_EIM_D16__EIM_DATA16 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 79 IOMUX_PADS(PAD_EIM_D17__EIM_DATA17 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 80 IOMUX_PADS(PAD_EIM_D18__EIM_DATA18 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 81 IOMUX_PADS(PAD_EIM_D19__EIM_DATA19 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 82 IOMUX_PADS(PAD_EIM_D20__EIM_DATA20 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 83 IOMUX_PADS(PAD_EIM_D21__EIM_DATA21 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 84 IOMUX_PADS(PAD_EIM_D22__EIM_DATA22 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 85 IOMUX_PADS(PAD_EIM_D23__EIM_DATA23 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 86 IOMUX_PADS(PAD_EIM_D24__EIM_DATA24 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 87 IOMUX_PADS(PAD_EIM_D25__EIM_DATA25 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 88 IOMUX_PADS(PAD_EIM_D26__EIM_DATA26 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 89 IOMUX_PADS(PAD_EIM_D27__EIM_DATA27 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 90 IOMUX_PADS(PAD_EIM_D28__EIM_DATA28 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 91 IOMUX_PADS(PAD_EIM_D29__EIM_DATA29 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 92 IOMUX_PADS(PAD_EIM_D30__EIM_DATA30 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 93 IOMUX_PADS(PAD_EIM_D31__EIM_DATA31 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 94 IOMUX_PADS(PAD_EIM_DA0__EIM_AD00 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 95 IOMUX_PADS(PAD_EIM_DA1__EIM_AD01 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 96 IOMUX_PADS(PAD_EIM_DA2__EIM_AD02 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 97 IOMUX_PADS(PAD_EIM_DA3__EIM_AD03 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 98 IOMUX_PADS(PAD_EIM_DA4__EIM_AD04 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 99 IOMUX_PADS(PAD_EIM_DA5__EIM_AD05 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 100 IOMUX_PADS(PAD_EIM_DA6__EIM_AD06 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 101 IOMUX_PADS(PAD_EIM_DA7__EIM_AD07 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 102 IOMUX_PADS(PAD_EIM_DA8__EIM_AD08 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 103 IOMUX_PADS(PAD_EIM_DA9__EIM_AD09 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 104 IOMUX_PADS(PAD_EIM_DA10__EIM_AD10 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 105 IOMUX_PADS(PAD_EIM_DA11__EIM_AD11 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 106 IOMUX_PADS(PAD_EIM_DA12__EIM_AD12 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 107 IOMUX_PADS(PAD_EIM_DA13__EIM_AD13 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 108 IOMUX_PADS(PAD_EIM_DA14__EIM_AD14 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 109 IOMUX_PADS(PAD_EIM_DA15__EIM_AD15 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 110 IOMUX_PADS(PAD_EIM_A16__EIM_ADDR16 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 111 IOMUX_PADS(PAD_EIM_A17__EIM_ADDR17 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 112 IOMUX_PADS(PAD_EIM_A18__EIM_ADDR18 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 113 IOMUX_PADS(PAD_EIM_A19__EIM_ADDR19 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 114 IOMUX_PADS(PAD_EIM_A20__EIM_ADDR20 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 115 IOMUX_PADS(PAD_EIM_A21__EIM_ADDR21 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 116 IOMUX_PADS(PAD_EIM_A22__EIM_ADDR22 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 117 IOMUX_PADS(PAD_EIM_A23__EIM_ADDR23 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), 118 IOMUX_PADS(PAD_EIM_OE__EIM_OE_B | MUX_PAD_CTRL(NO_PAD_CTRL)), 119 IOMUX_PADS(PAD_EIM_RW__EIM_RW | MUX_PAD_CTRL(NO_PAD_CTRL)), 120 IOMUX_PADS(PAD_EIM_CS0__EIM_CS0_B | MUX_PAD_CTRL(NO_PAD_CTRL)), 121}; 122 123static void eimnor_cs_setup(void) 124{ 125 struct weim *weim_regs = (struct weim *)WEIM_BASE_ADDR; 126 127 writel(0x00020181, &weim_regs->cs0gcr1); 128 writel(0x00000001, &weim_regs->cs0gcr2); 129 writel(0x0a020000, &weim_regs->cs0rcr1); 130 writel(0x0000c000, &weim_regs->cs0rcr2); 131 writel(0x0804a240, &weim_regs->cs0wcr1); 132 writel(0x00000120, &weim_regs->wcr); 133 134 set_chipselect_size(CS0_128); 135} 136 137static void eim_clk_setup(void) 138{ 139 struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; 140 int cscmr1, ccgr6; 141 142 143 /* Turn off EIM clock */ 144 ccgr6 = readl(&imx_ccm->CCGR6); 145 ccgr6 &= ~(0x3 << 10); 146 writel(ccgr6, &imx_ccm->CCGR6); 147 148 /* 149 * Configure clk_eim_slow_sel = 00 --> derive clock from AXI clk root 150 * and aclk_eim_slow_podf = 01 --> divide by 2 151 * so that we can have EIM at the maximum clock of 132MHz 152 */ 153 cscmr1 = readl(&imx_ccm->cscmr1); 154 cscmr1 &= ~(MXC_CCM_CSCMR1_ACLK_EMI_SLOW_MASK | 155 MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK); 156 cscmr1 |= (1 << MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_OFFSET); 157 writel(cscmr1, &imx_ccm->cscmr1); 158 159 /* Turn on EIM clock */ 160 ccgr6 |= (0x3 << 10); 161 writel(ccgr6, &imx_ccm->CCGR6); 162} 163 164static void setup_iomux_eimnor(void) 165{ 166 SETUP_IOMUX_PADS(eimnor_pads); 167 168 gpio_direction_output(IMX_GPIO_NR(5, 4), 0); 169 170 eimnor_cs_setup(); 171} 172#endif 173 174 175static iomux_v3_cfg_t const usdhc3_pads[] = { 176 IOMUX_PADS(PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)), 177 IOMUX_PADS(PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)), 178 IOMUX_PADS(PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), 179 IOMUX_PADS(PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), 180 IOMUX_PADS(PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), 181 IOMUX_PADS(PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), 182 IOMUX_PADS(PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), 183 IOMUX_PADS(PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), 184 IOMUX_PADS(PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), 185 IOMUX_PADS(PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), 186 IOMUX_PADS(PAD_GPIO_18__SD3_VSELECT | MUX_PAD_CTRL(USDHC_PAD_CTRL)), 187 IOMUX_PADS(PAD_NANDF_CS2__GPIO6_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL)), 188}; 189 190static void setup_iomux_uart(void) 191{ 192 SETUP_IOMUX_PADS(uart4_pads); 193} 194 195#ifdef CONFIG_FSL_ESDHC_IMX 196static struct fsl_esdhc_cfg usdhc_cfg[1] = { 197 {USDHC3_BASE_ADDR}, 198}; 199 200int board_mmc_getcd(struct mmc *mmc) 201{ 202 gpio_direction_input(IMX_GPIO_NR(6, 15)); 203 return !gpio_get_value(IMX_GPIO_NR(6, 15)); 204} 205 206int board_mmc_init(struct bd_info *bis) 207{ 208 SETUP_IOMUX_PADS(usdhc3_pads); 209 210 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); 211 return fsl_esdhc_initialize(bis, &usdhc_cfg[0]); 212} 213#endif 214 215#ifdef CONFIG_NAND_MXS 216static iomux_v3_cfg_t gpmi_pads[] = { 217 IOMUX_PADS(PAD_NANDF_CLE__NAND_CLE | MUX_PAD_CTRL(GPMI_PAD_CTRL2)), 218 IOMUX_PADS(PAD_NANDF_ALE__NAND_ALE | MUX_PAD_CTRL(GPMI_PAD_CTRL2)), 219 IOMUX_PADS(PAD_NANDF_WP_B__NAND_WP_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2)), 220 IOMUX_PADS(PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(GPMI_PAD_CTRL0)), 221 IOMUX_PADS(PAD_NANDF_CS0__NAND_CE0_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2)), 222 IOMUX_PADS(PAD_SD4_CMD__NAND_RE_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2)), 223 IOMUX_PADS(PAD_SD4_CLK__NAND_WE_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2)), 224 IOMUX_PADS(PAD_NANDF_D0__NAND_DATA00 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)), 225 IOMUX_PADS(PAD_NANDF_D1__NAND_DATA01 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)), 226 IOMUX_PADS(PAD_NANDF_D2__NAND_DATA02 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)), 227 IOMUX_PADS(PAD_NANDF_D3__NAND_DATA03 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)), 228 IOMUX_PADS(PAD_NANDF_D4__NAND_DATA04 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)), 229 IOMUX_PADS(PAD_NANDF_D5__NAND_DATA05 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)), 230 IOMUX_PADS(PAD_NANDF_D6__NAND_DATA06 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)), 231 IOMUX_PADS(PAD_NANDF_D7__NAND_DATA07 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)), 232 IOMUX_PADS(PAD_SD4_DAT0__NAND_DQS | MUX_PAD_CTRL(GPMI_PAD_CTRL1)), 233}; 234 235static void setup_gpmi_nand(void) 236{ 237 struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; 238 239 /* config gpmi nand iomux */ 240 SETUP_IOMUX_PADS(gpmi_pads); 241 242 setup_gpmi_io_clk((MXC_CCM_CS2CDR_ENFC_CLK_PODF(0) | 243 MXC_CCM_CS2CDR_ENFC_CLK_PRED(3) | 244 MXC_CCM_CS2CDR_ENFC_CLK_SEL(3))); 245 246 /* enable apbh clock gating */ 247 setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK); 248} 249#endif 250 251#ifdef CONFIG_REVISION_TAG 252u32 get_board_rev(void) 253{ 254 int rev = nxp_board_rev(); 255 256 return (get_cpu_rev() & ~(0xF << 8)) | rev; 257} 258#endif 259 260static int ar8031_phy_fixup(struct phy_device *phydev) 261{ 262 unsigned short val; 263 264 /* To enable AR8031 ouput a 125MHz clk from CLK_25M */ 265 phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7); 266 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016); 267 phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007); 268 269 val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe); 270 val &= 0xffe3; 271 val |= 0x18; 272 phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val); 273 274 /* introduce tx clock delay */ 275 phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5); 276 val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e); 277 val |= 0x0100; 278 phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val); 279 280 return 0; 281} 282 283int board_phy_config(struct phy_device *phydev) 284{ 285 ar8031_phy_fixup(phydev); 286 287 if (phydev->drv->config) 288 phydev->drv->config(phydev); 289 290 return 0; 291} 292 293#if defined(CONFIG_VIDEO_IPUV3) 294static void disable_lvds(struct display_info_t const *dev) 295{ 296 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; 297 298 clrbits_le32(&iomux->gpr[2], 299 IOMUXC_GPR2_LVDS_CH0_MODE_MASK | 300 IOMUXC_GPR2_LVDS_CH1_MODE_MASK); 301} 302 303static void do_enable_hdmi(struct display_info_t const *dev) 304{ 305 disable_lvds(dev); 306 imx_enable_hdmi_phy(); 307} 308 309struct display_info_t const displays[] = {{ 310 .bus = -1, 311 .addr = 0, 312 .pixfmt = IPU_PIX_FMT_RGB666, 313 .detect = NULL, 314 .enable = NULL, 315 .mode = { 316 .name = "Hannstar-XGA", 317 .refresh = 60, 318 .xres = 1024, 319 .yres = 768, 320 .pixclock = 15385, 321 .left_margin = 220, 322 .right_margin = 40, 323 .upper_margin = 21, 324 .lower_margin = 7, 325 .hsync_len = 60, 326 .vsync_len = 10, 327 .sync = FB_SYNC_EXT, 328 .vmode = FB_VMODE_NONINTERLACED 329} }, { 330 .bus = -1, 331 .addr = 0, 332 .pixfmt = IPU_PIX_FMT_RGB24, 333 .detect = detect_hdmi, 334 .enable = do_enable_hdmi, 335 .mode = { 336 .name = "HDMI", 337 .refresh = 60, 338 .xres = 1024, 339 .yres = 768, 340 .pixclock = 15385, 341 .left_margin = 220, 342 .right_margin = 40, 343 .upper_margin = 21, 344 .lower_margin = 7, 345 .hsync_len = 60, 346 .vsync_len = 10, 347 .sync = FB_SYNC_EXT, 348 .vmode = FB_VMODE_NONINTERLACED, 349} } }; 350size_t display_count = ARRAY_SIZE(displays); 351 352iomux_v3_cfg_t const backlight_pads[] = { 353 IOMUX_PADS(PAD_SD4_DAT1__GPIO2_IO09 | MUX_PAD_CTRL(ENET_PAD_CTRL)), 354}; 355 356static void setup_iomux_backlight(void) 357{ 358 gpio_request(IMX_GPIO_NR(2, 9), "backlight"); 359 gpio_direction_output(IMX_GPIO_NR(2, 9), 1); 360 SETUP_IOMUX_PADS(backlight_pads); 361} 362 363static void setup_display(void) 364{ 365 struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; 366 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; 367 int reg; 368 369 setup_iomux_backlight(); 370 enable_ipu_clock(); 371 imx_setup_hdmi(); 372 373 /* Turn on LDB_DI0 and LDB_DI1 clocks */ 374 reg = readl(&mxc_ccm->CCGR3); 375 reg |= MXC_CCM_CCGR3_LDB_DI0_MASK | MXC_CCM_CCGR3_LDB_DI1_MASK; 376 writel(reg, &mxc_ccm->CCGR3); 377 378 /* Set LDB_DI0 and LDB_DI1 clk select to 3b'011 */ 379 reg = readl(&mxc_ccm->cs2cdr); 380 reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK | 381 MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK); 382 reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET) | 383 (3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET); 384 writel(reg, &mxc_ccm->cs2cdr); 385 386 reg = readl(&mxc_ccm->cscmr2); 387 reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV | MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV; 388 writel(reg, &mxc_ccm->cscmr2); 389 390 reg = readl(&mxc_ccm->chsccdr); 391 reg |= (CHSCCDR_CLK_SEL_LDB_DI0 392 << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET); 393 reg |= (CHSCCDR_CLK_SEL_LDB_DI0 << 394 MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET); 395 writel(reg, &mxc_ccm->chsccdr); 396 397 reg = IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW | 398 IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW | 399 IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG | 400 IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT | 401 IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG | 402 IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT | 403 IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0 | 404 IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED; 405 writel(reg, &iomux->gpr[2]); 406 407 reg = readl(&iomux->gpr[3]); 408 reg &= ~(IOMUXC_GPR3_LVDS0_MUX_CTL_MASK | 409 IOMUXC_GPR3_HDMI_MUX_CTL_MASK); 410 reg |= (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 << 411 IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET) | 412 (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 << 413 IOMUXC_GPR3_HDMI_MUX_CTL_OFFSET); 414 writel(reg, &iomux->gpr[3]); 415} 416#endif /* CONFIG_VIDEO_IPUV3 */ 417 418/* 419 * Do not overwrite the console 420 * Use always serial for U-Boot console 421 */ 422int overwrite_console(void) 423{ 424 return 1; 425} 426 427int board_early_init_f(void) 428{ 429 setup_iomux_uart(); 430 431#ifdef CONFIG_NAND_MXS 432 setup_gpmi_nand(); 433#endif 434 435#ifdef CONFIG_MTD_NOR_FLASH 436 eim_clk_setup(); 437#endif 438 return 0; 439} 440 441int board_init(void) 442{ 443 /* address of boot parameters */ 444 gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; 445 446 /* I2C 3 Steer */ 447 gpio_request(IMX_GPIO_NR(5, 4), "steer logic"); 448 gpio_direction_output(IMX_GPIO_NR(5, 4), 1); 449 450 gpio_request(IMX_GPIO_NR(1, 15), "expander en"); 451 gpio_direction_output(IMX_GPIO_NR(1, 15), 1); 452 SETUP_IOMUX_PADS(port_exp); 453 454#ifdef CONFIG_VIDEO_IPUV3 455 setup_display(); 456#endif 457 458#ifdef CONFIG_MTD_NOR_FLASH 459 setup_iomux_eimnor(); 460#endif 461 return 0; 462} 463 464#ifdef CONFIG_MXC_SPI 465int board_spi_cs_gpio(unsigned bus, unsigned cs) 466{ 467 return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(4, 9)) : -1; 468} 469#endif 470 471int power_init_board(void) 472{ 473 struct udevice *dev; 474 unsigned int value; 475 int ret; 476 477 ret = pmic_get("pfuze100@8", &dev); 478 if (ret == -ENODEV) 479 return 0; 480 481 if (ret != 0) 482 return ret; 483 484 485 if (is_mx6dqp()) { 486 /* set SW2 staby volatage 0.975V*/ 487 value = pmic_reg_read(dev, PFUZE100_SW2STBY); 488 value &= ~0x3f; 489 value |= 0x17; 490 pmic_reg_write(dev, PFUZE100_SW2STBY, value); 491 } 492 493 return pfuze_mode_init(dev, APS_PFM); 494} 495 496#ifdef CONFIG_CMD_BMODE 497static const struct boot_mode board_boot_modes[] = { 498 /* 4 bit bus width */ 499 {"mmc0", MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)}, 500 {NULL, 0}, 501}; 502#endif 503 504int board_late_init(void) 505{ 506#ifdef CONFIG_CMD_BMODE 507 add_board_boot_modes(board_boot_modes); 508#endif 509 510#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG 511 env_set("board_name", "SABREAUTO"); 512 513 if (is_mx6dqp()) 514 env_set("board_rev", "MX6QP"); 515 else if (is_mx6dq()) 516 env_set("board_rev", "MX6Q"); 517 else if (is_mx6sdl()) 518 env_set("board_rev", "MX6DL"); 519#endif 520 521 return 0; 522} 523 524int checkboard(void) 525{ 526 printf("Board: MX6Q-Sabreauto rev%c\n", nxp_board_rev_string()); 527 528 return 0; 529} 530 531#ifdef CONFIG_USB_EHCI_MX6 532int board_ehci_hcd_init(int port) 533{ 534 switch (port) { 535 case 0: 536 /* 537 * Set daisy chain for otg_pin_id on 6q. 538 * For 6dl, this bit is reserved. 539 */ 540 imx_iomux_set_gpr_register(1, 13, 1, 0); 541 break; 542 case 1: 543 break; 544 default: 545 printf("MXC USB port %d not yet supported\n", port); 546 return -EINVAL; 547 } 548 return 0; 549} 550#endif 551 552#ifdef CONFIG_SPL_BUILD 553#include <asm/arch/mx6-ddr.h> 554#include <spl.h> 555#include <linux/libfdt.h> 556 557#ifdef CONFIG_SPL_OS_BOOT 558int spl_start_uboot(void) 559{ 560 return 0; 561} 562#endif 563 564static void ccgr_init(void) 565{ 566 struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; 567 568 writel(0x00C03F3F, &ccm->CCGR0); 569 writel(0x0030FC03, &ccm->CCGR1); 570 writel(0x0FFFC000, &ccm->CCGR2); 571 writel(0x3FF00000, &ccm->CCGR3); 572 writel(0x00FFF300, &ccm->CCGR4); 573 writel(0x0F0000C3, &ccm->CCGR5); 574 writel(0x000003FF, &ccm->CCGR6); 575} 576 577static int mx6q_dcd_table[] = { 578 0x020e0798, 0x000C0000, 579 0x020e0758, 0x00000000, 580 0x020e0588, 0x00000030, 581 0x020e0594, 0x00000030, 582 0x020e056c, 0x00000030, 583 0x020e0578, 0x00000030, 584 0x020e074c, 0x00000030, 585 0x020e057c, 0x00000030, 586 0x020e058c, 0x00000000, 587 0x020e059c, 0x00000030, 588 0x020e05a0, 0x00000030, 589 0x020e078c, 0x00000030, 590 0x020e0750, 0x00020000, 591 0x020e05a8, 0x00000028, 592 0x020e05b0, 0x00000028, 593 0x020e0524, 0x00000028, 594 0x020e051c, 0x00000028, 595 0x020e0518, 0x00000028, 596 0x020e050c, 0x00000028, 597 0x020e05b8, 0x00000028, 598 0x020e05c0, 0x00000028, 599 0x020e0774, 0x00020000, 600 0x020e0784, 0x00000028, 601 0x020e0788, 0x00000028, 602 0x020e0794, 0x00000028, 603 0x020e079c, 0x00000028, 604 0x020e07a0, 0x00000028, 605 0x020e07a4, 0x00000028, 606 0x020e07a8, 0x00000028, 607 0x020e0748, 0x00000028, 608 0x020e05ac, 0x00000028, 609 0x020e05b4, 0x00000028, 610 0x020e0528, 0x00000028, 611 0x020e0520, 0x00000028, 612 0x020e0514, 0x00000028, 613 0x020e0510, 0x00000028, 614 0x020e05bc, 0x00000028, 615 0x020e05c4, 0x00000028, 616 0x021b0800, 0xa1390003, 617 0x021b080c, 0x001F001F, 618 0x021b0810, 0x001F001F, 619 0x021b480c, 0x001F001F, 620 0x021b4810, 0x001F001F, 621 0x021b083c, 0x43260335, 622 0x021b0840, 0x031A030B, 623 0x021b483c, 0x4323033B, 624 0x021b4840, 0x0323026F, 625 0x021b0848, 0x483D4545, 626 0x021b4848, 0x44433E48, 627 0x021b0850, 0x41444840, 628 0x021b4850, 0x4835483E, 629 0x021b081c, 0x33333333, 630 0x021b0820, 0x33333333, 631 0x021b0824, 0x33333333, 632 0x021b0828, 0x33333333, 633 0x021b481c, 0x33333333, 634 0x021b4820, 0x33333333, 635 0x021b4824, 0x33333333, 636 0x021b4828, 0x33333333, 637 0x021b08b8, 0x00000800, 638 0x021b48b8, 0x00000800, 639 0x021b0004, 0x00020036, 640 0x021b0008, 0x09444040, 641 0x021b000c, 0x8A8F7955, 642 0x021b0010, 0xFF328F64, 643 0x021b0014, 0x01FF00DB, 644 0x021b0018, 0x00001740, 645 0x021b001c, 0x00008000, 646 0x021b002c, 0x000026d2, 647 0x021b0030, 0x008F1023, 648 0x021b0040, 0x00000047, 649 0x021b0000, 0x841A0000, 650 0x021b001c, 0x04088032, 651 0x021b001c, 0x00008033, 652 0x021b001c, 0x00048031, 653 0x021b001c, 0x09408030, 654 0x021b001c, 0x04008040, 655 0x021b0020, 0x00005800, 656 0x021b0818, 0x00011117, 657 0x021b4818, 0x00011117, 658 0x021b0004, 0x00025576, 659 0x021b0404, 0x00011006, 660 0x021b001c, 0x00000000, 661 0x020c4068, 0x00C03F3F, 662 0x020c406c, 0x0030FC03, 663 0x020c4070, 0x0FFFC000, 664 0x020c4074, 0x3FF00000, 665 0x020c4078, 0xFFFFF300, 666 0x020c407c, 0x0F0000F3, 667 0x020c4080, 0x00000FFF, 668 0x020e0010, 0xF00000CF, 669 0x020e0018, 0x007F007F, 670 0x020e001c, 0x007F007F, 671}; 672 673static int mx6qp_dcd_table[] = { 674 0x020e0798, 0x000C0000, 675 0x020e0758, 0x00000000, 676 0x020e0588, 0x00000030, 677 0x020e0594, 0x00000030, 678 0x020e056c, 0x00000030, 679 0x020e0578, 0x00000030, 680 0x020e074c, 0x00000030, 681 0x020e057c, 0x00000030, 682 0x020e058c, 0x00000000, 683 0x020e059c, 0x00000030, 684 0x020e05a0, 0x00000030, 685 0x020e078c, 0x00000030, 686 0x020e0750, 0x00020000, 687 0x020e05a8, 0x00000030, 688 0x020e05b0, 0x00000030, 689 0x020e0524, 0x00000030, 690 0x020e051c, 0x00000030, 691 0x020e0518, 0x00000030, 692 0x020e050c, 0x00000030, 693 0x020e05b8, 0x00000030, 694 0x020e05c0, 0x00000030, 695 0x020e0774, 0x00020000, 696 0x020e0784, 0x00000030, 697 0x020e0788, 0x00000030, 698 0x020e0794, 0x00000030, 699 0x020e079c, 0x00000030, 700 0x020e07a0, 0x00000030, 701 0x020e07a4, 0x00000030, 702 0x020e07a8, 0x00000030, 703 0x020e0748, 0x00000030, 704 0x020e05ac, 0x00000030, 705 0x020e05b4, 0x00000030, 706 0x020e0528, 0x00000030, 707 0x020e0520, 0x00000030, 708 0x020e0514, 0x00000030, 709 0x020e0510, 0x00000030, 710 0x020e05bc, 0x00000030, 711 0x020e05c4, 0x00000030, 712 0x021b0800, 0xa1390003, 713 0x021b080c, 0x001b001e, 714 0x021b0810, 0x002e0029, 715 0x021b480c, 0x001b002a, 716 0x021b4810, 0x0019002c, 717 0x021b083c, 0x43240334, 718 0x021b0840, 0x0324031a, 719 0x021b483c, 0x43340344, 720 0x021b4840, 0x03280276, 721 0x021b0848, 0x44383A3E, 722 0x021b4848, 0x3C3C3846, 723 0x021b0850, 0x2e303230, 724 0x021b4850, 0x38283E34, 725 0x021b081c, 0x33333333, 726 0x021b0820, 0x33333333, 727 0x021b0824, 0x33333333, 728 0x021b0828, 0x33333333, 729 0x021b481c, 0x33333333, 730 0x021b4820, 0x33333333, 731 0x021b4824, 0x33333333, 732 0x021b4828, 0x33333333, 733 0x021b08c0, 0x24912492, 734 0x021b48c0, 0x24912492, 735 0x021b08b8, 0x00000800, 736 0x021b48b8, 0x00000800, 737 0x021b0004, 0x00020036, 738 0x021b0008, 0x09444040, 739 0x021b000c, 0x898E7955, 740 0x021b0010, 0xFF328F64, 741 0x021b0014, 0x01FF00DB, 742 0x021b0018, 0x00001740, 743 0x021b001c, 0x00008000, 744 0x021b002c, 0x000026d2, 745 0x021b0030, 0x008E1023, 746 0x021b0040, 0x00000047, 747 0x021b0400, 0x14420000, 748 0x021b0000, 0x841A0000, 749 0x00bb0008, 0x00000004, 750 0x00bb000c, 0x2891E41A, 751 0x00bb0038, 0x00000564, 752 0x00bb0014, 0x00000040, 753 0x00bb0028, 0x00000020, 754 0x00bb002c, 0x00000020, 755 0x021b001c, 0x04088032, 756 0x021b001c, 0x00008033, 757 0x021b001c, 0x00048031, 758 0x021b001c, 0x09408030, 759 0x021b001c, 0x04008040, 760 0x021b0020, 0x00005800, 761 0x021b0818, 0x00011117, 762 0x021b4818, 0x00011117, 763 0x021b0004, 0x00025576, 764 0x021b0404, 0x00011006, 765 0x021b001c, 0x00000000, 766 0x020c4068, 0x00C03F3F, 767 0x020c406c, 0x0030FC03, 768 0x020c4070, 0x0FFFC000, 769 0x020c4074, 0x3FF00000, 770 0x020c4078, 0xFFFFF300, 771 0x020c407c, 0x0F0000F3, 772 0x020c4080, 0x00000FFF, 773 0x020e0010, 0xF00000CF, 774 0x020e0018, 0x77177717, 775 0x020e001c, 0x77177717, 776}; 777 778static int mx6dl_dcd_table[] = { 779 0x020e0774, 0x000C0000, 780 0x020e0754, 0x00000000, 781 0x020e04ac, 0x00000030, 782 0x020e04b0, 0x00000030, 783 0x020e0464, 0x00000030, 784 0x020e0490, 0x00000030, 785 0x020e074c, 0x00000030, 786 0x020e0494, 0x00000030, 787 0x020e04a0, 0x00000000, 788 0x020e04b4, 0x00000030, 789 0x020e04b8, 0x00000030, 790 0x020e076c, 0x00000030, 791 0x020e0750, 0x00020000, 792 0x020e04bc, 0x00000028, 793 0x020e04c0, 0x00000028, 794 0x020e04c4, 0x00000028, 795 0x020e04c8, 0x00000028, 796 0x020e04cc, 0x00000028, 797 0x020e04d0, 0x00000028, 798 0x020e04d4, 0x00000028, 799 0x020e04d8, 0x00000028, 800 0x020e0760, 0x00020000, 801 0x020e0764, 0x00000028, 802 0x020e0770, 0x00000028, 803 0x020e0778, 0x00000028, 804 0x020e077c, 0x00000028, 805 0x020e0780, 0x00000028, 806 0x020e0784, 0x00000028, 807 0x020e078c, 0x00000028, 808 0x020e0748, 0x00000028, 809 0x020e0470, 0x00000028, 810 0x020e0474, 0x00000028, 811 0x020e0478, 0x00000028, 812 0x020e047c, 0x00000028, 813 0x020e0480, 0x00000028, 814 0x020e0484, 0x00000028, 815 0x020e0488, 0x00000028, 816 0x020e048c, 0x00000028, 817 0x021b0800, 0xa1390003, 818 0x021b080c, 0x001F001F, 819 0x021b0810, 0x001F001F, 820 0x021b480c, 0x001F001F, 821 0x021b4810, 0x001F001F, 822 0x021b083c, 0x42190217, 823 0x021b0840, 0x017B017B, 824 0x021b483c, 0x4176017B, 825 0x021b4840, 0x015F016C, 826 0x021b0848, 0x4C4C4D4C, 827 0x021b4848, 0x4A4D4C48, 828 0x021b0850, 0x3F3F3F40, 829 0x021b4850, 0x3538382E, 830 0x021b081c, 0x33333333, 831 0x021b0820, 0x33333333, 832 0x021b0824, 0x33333333, 833 0x021b0828, 0x33333333, 834 0x021b481c, 0x33333333, 835 0x021b4820, 0x33333333, 836 0x021b4824, 0x33333333, 837 0x021b4828, 0x33333333, 838 0x021b08b8, 0x00000800, 839 0x021b48b8, 0x00000800, 840 0x021b0004, 0x00020025, 841 0x021b0008, 0x00333030, 842 0x021b000c, 0x676B5313, 843 0x021b0010, 0xB66E8B63, 844 0x021b0014, 0x01FF00DB, 845 0x021b0018, 0x00001740, 846 0x021b001c, 0x00008000, 847 0x021b002c, 0x000026d2, 848 0x021b0030, 0x006B1023, 849 0x021b0040, 0x00000047, 850 0x021b0000, 0x841A0000, 851 0x021b001c, 0x04008032, 852 0x021b001c, 0x00008033, 853 0x021b001c, 0x00048031, 854 0x021b001c, 0x05208030, 855 0x021b001c, 0x04008040, 856 0x021b0020, 0x00005800, 857 0x021b0818, 0x00011117, 858 0x021b4818, 0x00011117, 859 0x021b0004, 0x00025565, 860 0x021b0404, 0x00011006, 861 0x021b001c, 0x00000000, 862 0x020c4068, 0x00C03F3F, 863 0x020c406c, 0x0030FC03, 864 0x020c4070, 0x0FFFC000, 865 0x020c4074, 0x3FF00000, 866 0x020c4078, 0xFFFFF300, 867 0x020c407c, 0x0F0000C3, 868 0x020c4080, 0x00000FFF, 869 0x020e0010, 0xF00000CF, 870 0x020e0018, 0x007F007F, 871 0x020e001c, 0x007F007F, 872}; 873 874static void ddr_init(int *table, int size) 875{ 876 int i; 877 878 for (i = 0; i < size / 2 ; i++) 879 writel(table[2 * i + 1], table[2 * i]); 880} 881 882static void spl_dram_init(void) 883{ 884 if (is_mx6dq()) 885 ddr_init(mx6q_dcd_table, ARRAY_SIZE(mx6q_dcd_table)); 886 else if (is_mx6dqp()) 887 ddr_init(mx6qp_dcd_table, ARRAY_SIZE(mx6qp_dcd_table)); 888 else if (is_mx6sdl()) 889 ddr_init(mx6dl_dcd_table, ARRAY_SIZE(mx6dl_dcd_table)); 890} 891 892void board_init_f(ulong dummy) 893{ 894 /* DDR initialization */ 895 spl_dram_init(); 896 897 /* setup AIPS and disable watchdog */ 898 arch_cpu_init(); 899 900 ccgr_init(); 901 gpr_init(); 902 903 board_early_init_f(); 904 905 /* setup GP timer */ 906 timer_init(); 907 908 /* UART clocks enabled and gd valid - init serial console */ 909 preloader_console_init(); 910 911 /* Clear the BSS. */ 912 memset(__bss_start, 0, __bss_end - __bss_start); 913 914 /* load/boot image from boot device */ 915 board_init_r(NULL, 0); 916} 917#endif 918 919#ifdef CONFIG_SPL_LOAD_FIT 920int board_fit_config_name_match(const char *name) 921{ 922 if (is_mx6dq()) { 923 if (!strcmp(name, "imx6q-sabreauto")) 924 return 0; 925 } else if (is_mx6dqp()) { 926 if (!strcmp(name, "imx6qp-sabreauto")) 927 return 0; 928 } else if (is_mx6dl()) { 929 if (!strcmp(name, "imx6dl-sabreauto")) 930 return 0; 931 } 932 933 return -1; 934} 935#endif 936