uboot/board/kosagi/novena/novena_spl.c
<<
>>
Prefs
   1/*
   2 * Novena SPL
   3 *
   4 * Copyright (C) 2014 Marek Vasut <marex@denx.de>
   5 *
   6 * SPDX-License-Identifier:     GPL-2.0+
   7 */
   8
   9#include <common.h>
  10#include <asm/io.h>
  11#include <asm/arch/clock.h>
  12#include <asm/arch/iomux.h>
  13#include <asm/arch/mx6-ddr.h>
  14#include <asm/arch/mx6-pins.h>
  15#include <asm/arch/sys_proto.h>
  16#include <asm/gpio.h>
  17#include <asm/mach-imx/boot_mode.h>
  18#include <asm/mach-imx/iomux-v3.h>
  19#include <asm/mach-imx/mxc_i2c.h>
  20#include <asm/arch/crm_regs.h>
  21#include <i2c.h>
  22#include <mmc.h>
  23#include <fsl_esdhc.h>
  24#include <spl.h>
  25
  26#include <asm/arch/mx6-ddr.h>
  27
  28#include "novena.h"
  29
  30DECLARE_GLOBAL_DATA_PTR;
  31
  32#define UART_PAD_CTRL                                           \
  33        (PAD_CTL_PKE | PAD_CTL_PUE |                            \
  34        PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |               \
  35        PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
  36
  37#define USDHC_PAD_CTRL                                          \
  38        (PAD_CTL_PKE | PAD_CTL_PUE |                            \
  39        PAD_CTL_PUS_47K_UP  | PAD_CTL_SPEED_LOW |               \
  40        PAD_CTL_DSE_80ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
  41
  42#define ENET_PAD_CTRL                                           \
  43        (PAD_CTL_PKE | PAD_CTL_PUE |                            \
  44        PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED   |             \
  45        PAD_CTL_DSE_40ohm   | PAD_CTL_HYS)
  46
  47#define ENET_PHY_CFG_PAD_CTRL                                   \
  48        (PAD_CTL_PKE | PAD_CTL_PUE |                            \
  49        PAD_CTL_PUS_22K_UP | PAD_CTL_HYS)
  50
  51#define RGMII_PAD_CTRL                                          \
  52        (PAD_CTL_PKE | PAD_CTL_PUE |                            \
  53        PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
  54
  55#define SPI_PAD_CTRL                                            \
  56        (PAD_CTL_HYS |                                          \
  57        PAD_CTL_PUS_100K_DOWN | PAD_CTL_SPEED_MED |             \
  58        PAD_CTL_DSE_40ohm     | PAD_CTL_SRE_FAST)
  59
  60#define I2C_PAD_CTRL                                            \
  61        (PAD_CTL_PKE | PAD_CTL_PUE |                            \
  62        PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_LOW |               \
  63        PAD_CTL_DSE_240ohm  | PAD_CTL_HYS |                     \
  64        PAD_CTL_ODE)
  65
  66#define BUTTON_PAD_CTRL                                         \
  67        (PAD_CTL_PKE | PAD_CTL_PUE |                            \
  68        PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED   |             \
  69        PAD_CTL_DSE_40ohm   | PAD_CTL_HYS)
  70
  71#define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
  72
  73/*
  74 * Audio
  75 */
  76static iomux_v3_cfg_t audio_pads[] = {
  77        /* AUD_PWRON */
  78        MX6_PAD_DISP0_DAT23__GPIO5_IO17 | MUX_PAD_CTRL(NO_PAD_CTRL),
  79};
  80
  81static void novena_spl_setup_iomux_audio(void)
  82{
  83        imx_iomux_v3_setup_multiple_pads(audio_pads, ARRAY_SIZE(audio_pads));
  84        gpio_direction_output(NOVENA_AUDIO_PWRON, 1);
  85}
  86
  87/*
  88 * ENET
  89 */
  90static iomux_v3_cfg_t enet_pads1[] = {
  91        MX6_PAD_ENET_MDIO__ENET_MDIO            | MUX_PAD_CTRL(ENET_PAD_CTRL),
  92        MX6_PAD_ENET_MDC__ENET_MDC              | MUX_PAD_CTRL(ENET_PAD_CTRL),
  93        MX6_PAD_RGMII_TXC__RGMII_TXC            | MUX_PAD_CTRL(RGMII_PAD_CTRL),
  94        MX6_PAD_RGMII_TD0__RGMII_TD0            | MUX_PAD_CTRL(RGMII_PAD_CTRL),
  95        MX6_PAD_RGMII_TD1__RGMII_TD1            | MUX_PAD_CTRL(RGMII_PAD_CTRL),
  96        MX6_PAD_RGMII_TD2__RGMII_TD2            | MUX_PAD_CTRL(RGMII_PAD_CTRL),
  97        MX6_PAD_RGMII_TD3__RGMII_TD3            | MUX_PAD_CTRL(RGMII_PAD_CTRL),
  98        MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL      | MUX_PAD_CTRL(RGMII_PAD_CTRL),
  99        MX6_PAD_ENET_REF_CLK__ENET_TX_CLK       | MUX_PAD_CTRL(ENET_PAD_CTRL),
 100
 101        /* pin 35, PHY_AD2 */
 102        MX6_PAD_RGMII_RXC__GPIO6_IO30   | MUX_PAD_CTRL(ENET_PHY_CFG_PAD_CTRL),
 103        /* pin 32, MODE0 */
 104        MX6_PAD_RGMII_RD0__GPIO6_IO25   | MUX_PAD_CTRL(ENET_PHY_CFG_PAD_CTRL),
 105        /* pin 31, MODE1 */
 106        MX6_PAD_RGMII_RD1__GPIO6_IO27   | MUX_PAD_CTRL(ENET_PHY_CFG_PAD_CTRL),
 107        /* pin 28, MODE2 */
 108        MX6_PAD_RGMII_RD2__GPIO6_IO28   | MUX_PAD_CTRL(ENET_PHY_CFG_PAD_CTRL),
 109        /* pin 27, MODE3 */
 110        MX6_PAD_RGMII_RD3__GPIO6_IO29   | MUX_PAD_CTRL(ENET_PHY_CFG_PAD_CTRL),
 111        /* pin 33, CLK125_EN */
 112        MX6_PAD_RGMII_RX_CTL__GPIO6_IO24 | MUX_PAD_CTRL(ENET_PHY_CFG_PAD_CTRL),
 113
 114        /* pin 42 PHY nRST */
 115        MX6_PAD_EIM_D23__GPIO3_IO23             | MUX_PAD_CTRL(NO_PAD_CTRL),
 116};
 117
 118static iomux_v3_cfg_t enet_pads2[] = {
 119        MX6_PAD_RGMII_RXC__RGMII_RXC            | MUX_PAD_CTRL(RGMII_PAD_CTRL),
 120        MX6_PAD_RGMII_RD0__RGMII_RD0            | MUX_PAD_CTRL(RGMII_PAD_CTRL),
 121        MX6_PAD_RGMII_RD1__RGMII_RD1            | MUX_PAD_CTRL(RGMII_PAD_CTRL),
 122        MX6_PAD_RGMII_RD2__RGMII_RD2            | MUX_PAD_CTRL(RGMII_PAD_CTRL),
 123        MX6_PAD_RGMII_RD3__RGMII_RD3            | MUX_PAD_CTRL(RGMII_PAD_CTRL),
 124        MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL      | MUX_PAD_CTRL(RGMII_PAD_CTRL),
 125};
 126
 127static void novena_spl_setup_iomux_enet(void)
 128{
 129        imx_iomux_v3_setup_multiple_pads(enet_pads1, ARRAY_SIZE(enet_pads1));
 130
 131        /* Assert Ethernet PHY nRST */
 132        gpio_direction_output(IMX_GPIO_NR(3, 23), 0);
 133
 134        /*
 135         * Use imx6 internal pull-ups to drive PHY mode pins during PHY reset
 136         * de-assertion. The intention is to use weak signal drivers (pull-ups)
 137         * to prevent the conflict between PHY pins becoming outputs after
 138         * reset and imx6 still driving the pins. The issue is described in PHY
 139         * datasheet, p.14
 140         */
 141        gpio_direction_input(IMX_GPIO_NR(6, 30)); /* PHY_AD2 = 1 */
 142        gpio_direction_input(IMX_GPIO_NR(6, 25)); /* MODE0 = 1 */
 143        gpio_direction_input(IMX_GPIO_NR(6, 27)); /* MODE1 = 1 */
 144        gpio_direction_input(IMX_GPIO_NR(6, 28)); /* MODE2 = 1 */
 145        gpio_direction_input(IMX_GPIO_NR(6, 29)); /* MODE3 = 1 */
 146        gpio_direction_input(IMX_GPIO_NR(6, 24)); /* CLK125_EN = 1 */
 147
 148        /* Following reset timing (p.53, fig.8 from the PHY datasheet) */
 149        mdelay(10);
 150
 151        /* De-assert Ethernet PHY nRST */
 152        gpio_set_value(IMX_GPIO_NR(3, 23), 1);
 153
 154        /* PHY is now configured, connect FEC to the pads */
 155        imx_iomux_v3_setup_multiple_pads(enet_pads2, ARRAY_SIZE(enet_pads2));
 156
 157        /*
 158         * PHY datasheet recommends on p.53 to wait at least 100us after reset
 159         * before using MII, so we enforce the delay here
 160         */
 161        udelay(100);
 162}
 163
 164/*
 165 * FPGA
 166 */
 167static iomux_v3_cfg_t fpga_pads[] = {
 168        /* FPGA_RESET_N */
 169        MX6_PAD_DISP0_DAT13__GPIO5_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
 170};
 171
 172static void novena_spl_setup_iomux_fpga(void)
 173{
 174        imx_iomux_v3_setup_multiple_pads(fpga_pads, ARRAY_SIZE(fpga_pads));
 175        gpio_direction_output(NOVENA_FPGA_RESET_N_GPIO, 0);
 176}
 177
 178/*
 179 * GPIO Button
 180 */
 181static iomux_v3_cfg_t button_pads[] = {
 182        /* Debug */
 183        MX6_PAD_KEY_COL4__GPIO4_IO14 | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
 184};
 185
 186static void novena_spl_setup_iomux_buttons(void)
 187{
 188        imx_iomux_v3_setup_multiple_pads(button_pads, ARRAY_SIZE(button_pads));
 189}
 190
 191/*
 192 * I2C
 193 */
 194/*
 195 * I2C1:
 196 *  0x1d ... MMA7455L
 197 *  0x30 ... SO-DIMM temp sensor
 198 *  0x44 ... STMPE610
 199 *  0x50 ... SO-DIMM ID
 200 */
 201struct i2c_pads_info i2c_pad_info0 = {
 202        .scl = {
 203                .i2c_mode       = MX6_PAD_EIM_D21__I2C1_SCL | PC,
 204                .gpio_mode      = MX6_PAD_EIM_D21__GPIO3_IO21 | PC,
 205                .gp             = IMX_GPIO_NR(3, 21)
 206        },
 207        .sda = {
 208                .i2c_mode       = MX6_PAD_EIM_D28__I2C1_SDA | PC,
 209                .gpio_mode      = MX6_PAD_EIM_D28__GPIO3_IO28 | PC,
 210                .gp             = IMX_GPIO_NR(3, 28)
 211        }
 212};
 213
 214/*
 215 * I2C2:
 216 *  0x08 ... PMIC
 217 *  0x3a ... HDMI DCC
 218 *  0x50 ... HDMI DCC
 219 */
 220static struct i2c_pads_info i2c_pad_info1 = {
 221        .scl = {
 222                .i2c_mode       = MX6_PAD_EIM_EB2__I2C2_SCL | PC,
 223                .gpio_mode      = MX6_PAD_EIM_EB2__GPIO2_IO30 | PC,
 224                .gp             = IMX_GPIO_NR(2, 30)
 225        },
 226        .sda = {
 227                .i2c_mode       = MX6_PAD_EIM_D16__I2C2_SDA | PC,
 228                .gpio_mode      = MX6_PAD_EIM_D16__GPIO3_IO16 | PC,
 229                .gp             = IMX_GPIO_NR(3, 16)
 230        }
 231};
 232
 233/*
 234 * I2C3:
 235 *  0x11 ... ES8283
 236 *  0x50 ... LCD EDID
 237 *  0x56 ... EEPROM
 238 */
 239static struct i2c_pads_info i2c_pad_info2 = {
 240        .scl = {
 241                .i2c_mode       = MX6_PAD_EIM_D17__I2C3_SCL | PC,
 242                .gpio_mode      = MX6_PAD_EIM_D17__GPIO3_IO17 | PC,
 243                .gp             = IMX_GPIO_NR(3, 17)
 244        },
 245        .sda = {
 246                .i2c_mode       = MX6_PAD_EIM_D18__I2C3_SDA | PC,
 247                .gpio_mode      = MX6_PAD_EIM_D18__GPIO3_IO18 | PC,
 248                .gp             = IMX_GPIO_NR(3, 18)
 249        }
 250};
 251
 252static void novena_spl_setup_iomux_i2c(void)
 253{
 254        setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info0);
 255        setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
 256        setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2);
 257}
 258
 259/*
 260 * PCI express
 261 */
 262#ifdef CONFIG_CMD_PCI
 263static iomux_v3_cfg_t pcie_pads[] = {
 264        /* "Reset" pin */
 265        MX6_PAD_EIM_D29__GPIO3_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
 266        /* "Power on" pin */
 267        MX6_PAD_GPIO_17__GPIO7_IO12 | MUX_PAD_CTRL(NO_PAD_CTRL),
 268        /* "Wake up" pin (input) */
 269        MX6_PAD_EIM_D22__GPIO3_IO22 | MUX_PAD_CTRL(NO_PAD_CTRL),
 270        /* "Disable endpoint" (rfkill) pin */
 271        MX6_PAD_EIM_A22__GPIO2_IO16 | MUX_PAD_CTRL(NO_PAD_CTRL),
 272};
 273
 274static void novena_spl_setup_iomux_pcie(void)
 275{
 276        imx_iomux_v3_setup_multiple_pads(pcie_pads, ARRAY_SIZE(pcie_pads));
 277
 278        /* Ensure PCIe is powered down */
 279        gpio_direction_output(NOVENA_PCIE_POWER_ON_GPIO, 0);
 280
 281        /* Put the card into reset */
 282        gpio_direction_output(NOVENA_PCIE_RESET_GPIO, 0);
 283
 284        /* Input signal to wake system from mPCIe card */
 285        gpio_direction_input(NOVENA_PCIE_WAKE_UP_GPIO);
 286
 287        /* Drive RFKILL high, to ensure the radio is turned on */
 288        gpio_direction_output(NOVENA_PCIE_DISABLE_GPIO, 1);
 289}
 290#else
 291static inline void novena_spl_setup_iomux_pcie(void) {}
 292#endif
 293
 294/*
 295 * SDHC
 296 */
 297static iomux_v3_cfg_t usdhc2_pads[] = {
 298        MX6_PAD_SD2_CLK__SD2_CLK    | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 299        MX6_PAD_SD2_CMD__SD2_CMD    | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 300        MX6_PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 301        MX6_PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 302        MX6_PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 303        MX6_PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 304        MX6_PAD_GPIO_2__GPIO1_IO02  | MUX_PAD_CTRL(NO_PAD_CTRL), /* WP */
 305        MX6_PAD_GPIO_4__GPIO1_IO04  | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
 306};
 307
 308static iomux_v3_cfg_t usdhc3_pads[] = {
 309        MX6_PAD_SD3_CLK__SD3_CLK    | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 310        MX6_PAD_SD3_CMD__SD3_CMD    | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 311        MX6_PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 312        MX6_PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 313        MX6_PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 314        MX6_PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
 315};
 316
 317static void novena_spl_setup_iomux_sdhc(void)
 318{
 319        imx_iomux_v3_setup_multiple_pads(usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
 320        imx_iomux_v3_setup_multiple_pads(usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
 321
 322        /* Big SD write-protect and card-detect */
 323        gpio_direction_input(IMX_GPIO_NR(1, 2));
 324        gpio_direction_input(IMX_GPIO_NR(1, 4));
 325}
 326
 327/*
 328 * SPI
 329 */
 330#ifdef CONFIG_MXC_SPI
 331static iomux_v3_cfg_t ecspi3_pads[] = {
 332        /* SS1 */
 333        MX6_PAD_DISP0_DAT1__ECSPI3_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL),
 334        MX6_PAD_DISP0_DAT2__ECSPI3_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL),
 335        MX6_PAD_DISP0_DAT0__ECSPI3_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
 336        MX6_PAD_DISP0_DAT3__GPIO4_IO24 | MUX_PAD_CTRL(SPI_PAD_CTRL),
 337        MX6_PAD_DISP0_DAT4__GPIO4_IO25 | MUX_PAD_CTRL(SPI_PAD_CTRL),
 338        MX6_PAD_DISP0_DAT5__GPIO4_IO26 | MUX_PAD_CTRL(SPI_PAD_CTRL),
 339        MX6_PAD_DISP0_DAT7__ECSPI3_RDY | MUX_PAD_CTRL(SPI_PAD_CTRL),
 340};
 341
 342static void novena_spl_setup_iomux_spi(void)
 343{
 344        imx_iomux_v3_setup_multiple_pads(ecspi3_pads, ARRAY_SIZE(ecspi3_pads));
 345        /* De-assert the nCS */
 346        gpio_direction_output(MX6_PAD_DISP0_DAT3__GPIO4_IO24, 1);
 347        gpio_direction_output(MX6_PAD_DISP0_DAT4__GPIO4_IO25, 1);
 348        gpio_direction_output(MX6_PAD_DISP0_DAT5__GPIO4_IO26, 1);
 349}
 350#else
 351static void novena_spl_setup_iomux_spi(void) {}
 352#endif
 353
 354/*
 355 * UART
 356 */
 357static iomux_v3_cfg_t const uart2_pads[] = {
 358        MX6_PAD_EIM_D26__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
 359        MX6_PAD_EIM_D27__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
 360};
 361
 362static iomux_v3_cfg_t const uart3_pads[] = {
 363        MX6_PAD_EIM_D24__UART3_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
 364        MX6_PAD_EIM_D25__UART3_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
 365};
 366
 367static iomux_v3_cfg_t const uart4_pads[] = {
 368        MX6_PAD_KEY_COL0__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
 369        MX6_PAD_KEY_ROW0__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
 370        MX6_PAD_CSI0_DAT16__UART4_CTS_B | MUX_PAD_CTRL(UART_PAD_CTRL),
 371        MX6_PAD_CSI0_DAT17__UART4_RTS_B | MUX_PAD_CTRL(UART_PAD_CTRL),
 372
 373};
 374
 375static void novena_spl_setup_iomux_uart(void)
 376{
 377        imx_iomux_v3_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads));
 378        imx_iomux_v3_setup_multiple_pads(uart3_pads, ARRAY_SIZE(uart3_pads));
 379        imx_iomux_v3_setup_multiple_pads(uart4_pads, ARRAY_SIZE(uart4_pads));
 380}
 381
 382/*
 383 * Video
 384 */
 385#ifdef CONFIG_VIDEO
 386static iomux_v3_cfg_t hdmi_pads[] = {
 387        /* "Ghost HPD" pin */
 388        MX6_PAD_EIM_A24__GPIO5_IO04 | MUX_PAD_CTRL(NO_PAD_CTRL),
 389
 390        /* LCD_PWR_CTL */
 391        MX6_PAD_CSI0_DAT10__GPIO5_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL),
 392        /* LCD_BL_ON */
 393        MX6_PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
 394        /* GPIO_PWM1 */
 395        MX6_PAD_DISP0_DAT8__GPIO4_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
 396};
 397
 398static void novena_spl_setup_iomux_video(void)
 399{
 400        imx_iomux_v3_setup_multiple_pads(hdmi_pads, ARRAY_SIZE(hdmi_pads));
 401        gpio_direction_input(NOVENA_HDMI_GHOST_HPD);
 402}
 403#else
 404static inline void novena_spl_setup_iomux_video(void) {}
 405#endif
 406
 407/*
 408 * SPL boots from uSDHC card
 409 */
 410#ifdef CONFIG_FSL_ESDHC
 411static struct fsl_esdhc_cfg usdhc_cfg = {
 412        USDHC3_BASE_ADDR, 0, 4
 413};
 414
 415int board_mmc_getcd(struct mmc *mmc)
 416{
 417        /* There is no CD for a microSD card, assume always present. */
 418        return 1;
 419}
 420
 421int board_mmc_init(bd_t *bis)
 422{
 423        usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
 424        return fsl_esdhc_initialize(bis, &usdhc_cfg);
 425}
 426#endif
 427
 428/* Configure MX6Q/DUAL mmdc DDR io registers */
 429static struct mx6dq_iomux_ddr_regs novena_ddr_ioregs = {
 430        /* SDCLK[0:1], CAS, RAS, Reset: Differential input, 40ohm */
 431        .dram_sdclk_0           = 0x00020038,
 432        .dram_sdclk_1           = 0x00020038,
 433        .dram_cas               = 0x00000038,
 434        .dram_ras               = 0x00000038,
 435        .dram_reset             = 0x00000038,
 436        /* SDCKE[0:1]: 100k pull-up */
 437        .dram_sdcke0            = 0x00000038,
 438        .dram_sdcke1            = 0x00000038,
 439        /* SDBA2: pull-up disabled */
 440        .dram_sdba2             = 0x00000000,
 441        /* SDODT[0:1]: 100k pull-up, 40 ohm */
 442        .dram_sdodt0            = 0x00000038,
 443        .dram_sdodt1            = 0x00000038,
 444        /* SDQS[0:7]: Differential input, 40 ohm */
 445        .dram_sdqs0             = 0x00000038,
 446        .dram_sdqs1             = 0x00000038,
 447        .dram_sdqs2             = 0x00000038,
 448        .dram_sdqs3             = 0x00000038,
 449        .dram_sdqs4             = 0x00000038,
 450        .dram_sdqs5             = 0x00000038,
 451        .dram_sdqs6             = 0x00000038,
 452        .dram_sdqs7             = 0x00000038,
 453
 454        /* DQM[0:7]: Differential input, 40 ohm */
 455        .dram_dqm0              = 0x00000038,
 456        .dram_dqm1              = 0x00000038,
 457        .dram_dqm2              = 0x00000038,
 458        .dram_dqm3              = 0x00000038,
 459        .dram_dqm4              = 0x00000038,
 460        .dram_dqm5              = 0x00000038,
 461        .dram_dqm6              = 0x00000038,
 462        .dram_dqm7              = 0x00000038,
 463};
 464
 465/* Configure MX6Q/DUAL mmdc GRP io registers */
 466static struct mx6dq_iomux_grp_regs novena_grp_ioregs = {
 467        /* DDR3 */
 468        .grp_ddr_type           = 0x000c0000,
 469        .grp_ddrmode_ctl        = 0x00020000,
 470        /* Disable DDR pullups */
 471        .grp_ddrpke             = 0x00000000,
 472        /* ADDR[00:16], SDBA[0:1]: 40 ohm */
 473        .grp_addds              = 0x00000038,
 474        /* CS0/CS1/SDBA2/CKE0/CKE1/SDWE: 40 ohm */
 475        .grp_ctlds              = 0x00000038,
 476        /* DATA[00:63]: Differential input, 40 ohm */
 477        .grp_ddrmode            = 0x00020000,
 478        .grp_b0ds               = 0x00000038,
 479        .grp_b1ds               = 0x00000038,
 480        .grp_b2ds               = 0x00000038,
 481        .grp_b3ds               = 0x00000038,
 482        .grp_b4ds               = 0x00000038,
 483        .grp_b5ds               = 0x00000038,
 484        .grp_b6ds               = 0x00000038,
 485        .grp_b7ds               = 0x00000038,
 486};
 487
 488static struct mx6_mmdc_calibration novena_mmdc_calib = {
 489        /* write leveling calibration determine */
 490        .p0_mpwldectrl0         = 0x00420048,
 491        .p0_mpwldectrl1         = 0x006f0059,
 492        .p1_mpwldectrl0         = 0x005a0104,
 493        .p1_mpwldectrl1         = 0x01070113,
 494        /* Read DQS Gating calibration */
 495        .p0_mpdgctrl0           = 0x437c040b,
 496        .p0_mpdgctrl1           = 0x0413040e,
 497        .p1_mpdgctrl0           = 0x444f0446,
 498        .p1_mpdgctrl1           = 0x044d0422,
 499        /* Read Calibration: DQS delay relative to DQ read access */
 500        .p0_mprddlctl           = 0x4c424249,
 501        .p1_mprddlctl           = 0x4e48414f,
 502        /* Write Calibration: DQ/DM delay relative to DQS write access */
 503        .p0_mpwrdlctl           = 0x42414641,
 504        .p1_mpwrdlctl           = 0x46374b43,
 505};
 506
 507static struct mx6_ddr_sysinfo novena_ddr_info = {
 508        /* Width of data bus: 0=16, 1=32, 2=64 */
 509        .dsize          = 2,
 510        /* Config for full 4GB range so that get_mem_size() works */
 511        .cs_density     = 32,   /* 32Gb per CS */
 512        /* Single chip select */
 513        .ncs            = 1,
 514        .cs1_mirror     = 0,
 515        .rtt_wr         = 0,    /* RTT_Wr = RZQ/4 */
 516        .rtt_nom        = 1,    /* RTT_Nom = RZQ/2 */
 517        .walat          = 0,    /* Write additional latency */
 518        .ralat          = 5,    /* Read additional latency */
 519        .mif3_mode      = 3,    /* Command prediction working mode */
 520        .bi_on          = 1,    /* Bank interleaving enabled */
 521        .sde_to_rst     = 0x10, /* 14 cycles, 200us (JEDEC default) */
 522        .rst_to_cke     = 0x23, /* 33 cycles, 500us (JEDEC default) */
 523        .refsel = 1,    /* Refresh cycles at 32KHz */
 524        .refr = 7,      /* 8 refresh commands per refresh cycle */
 525};
 526
 527static struct mx6_ddr3_cfg elpida_4gib_1600 = {
 528        .mem_speed      = 1600,
 529        .density        = 4,
 530        .width          = 64,
 531        .banks          = 8,
 532        .rowaddr        = 16,
 533        .coladdr        = 10,
 534        .pagesz         = 2,
 535        .trcd           = 1375,
 536        .trcmin         = 4875,
 537        .trasmin        = 3500,
 538};
 539
 540static void ccgr_init(void)
 541{
 542        struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 543
 544        writel(0x00C03F3F, &ccm->CCGR0);
 545        writel(0x0030FC03, &ccm->CCGR1);
 546        writel(0x0FFFC000, &ccm->CCGR2);
 547        writel(0x3FF00000, &ccm->CCGR3);
 548        writel(0xFFFFF300, &ccm->CCGR4);
 549        writel(0x0F0000C3, &ccm->CCGR5);
 550        writel(0x000003FF, &ccm->CCGR6);
 551}
 552
 553/*
 554 * called from C runtime startup code (arch/arm/lib/crt0.S:_main)
 555 * - we have a stack and a place to store GD, both in SRAM
 556 * - no variable global data is available
 557 */
 558void board_init_f(ulong dummy)
 559{
 560        /* setup AIPS and disable watchdog */
 561        arch_cpu_init();
 562
 563        ccgr_init();
 564        gpr_init();
 565
 566        /* setup GP timer */
 567        timer_init();
 568
 569#ifdef CONFIG_BOARD_POSTCLK_INIT
 570        board_postclk_init();
 571#endif
 572#ifdef CONFIG_FSL_ESDHC
 573        get_clocks();
 574#endif
 575
 576        /* Setup IOMUX and configure basics. */
 577        novena_spl_setup_iomux_audio();
 578        novena_spl_setup_iomux_buttons();
 579        novena_spl_setup_iomux_enet();
 580        novena_spl_setup_iomux_fpga();
 581        novena_spl_setup_iomux_i2c();
 582        novena_spl_setup_iomux_pcie();
 583        novena_spl_setup_iomux_sdhc();
 584        novena_spl_setup_iomux_spi();
 585        novena_spl_setup_iomux_uart();
 586        novena_spl_setup_iomux_video();
 587
 588        /* UART clocks enabled and gd valid - init serial console */
 589        preloader_console_init();
 590
 591        /* Start the DDR DRAM */
 592        mx6dq_dram_iocfg(64, &novena_ddr_ioregs, &novena_grp_ioregs);
 593        mx6_dram_cfg(&novena_ddr_info, &novena_mmdc_calib, &elpida_4gib_1600);
 594
 595        /* Perform DDR DRAM calibration */
 596        udelay(100);
 597        mmdc_do_write_level_calibration(&novena_ddr_info);
 598        mmdc_do_dqs_calibration(&novena_ddr_info);
 599}
 600