Merge git://git.denx.de/u-boot-mpc85xx
[oweals/u-boot.git] / board / kosagi / novena / novena_spl.c
index a8389d9c6b9161c3d0cda73c16b1b09d51f718d1..b934d3678814661a2eb06873232bccf0b0b4d75f 100644 (file)
@@ -17,6 +17,7 @@
 #include <asm/imx-common/boot_mode.h>
 #include <asm/imx-common/iomux-v3.h>
 #include <asm/imx-common/mxc_i2c.h>
+#include <asm/arch/crm_regs.h>
 #include <i2c.h>
 #include <mmc.h>
 #include <fsl_esdhc.h>
@@ -24,6 +25,8 @@
 
 #include <asm/arch/mx6-ddr.h>
 
+#include "novena.h"
+
 DECLARE_GLOBAL_DATA_PTR;
 
 #define UART_PAD_CTRL                                          \
@@ -41,6 +44,10 @@ DECLARE_GLOBAL_DATA_PTR;
        PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED   |             \
        PAD_CTL_DSE_40ohm   | PAD_CTL_HYS)
 
+#define ENET_PHY_CFG_PAD_CTRL                                  \
+       (PAD_CTL_PKE | PAD_CTL_PUE |                            \
+       PAD_CTL_PUS_22K_UP | PAD_CTL_HYS)
+
 #define RGMII_PAD_CTRL                                         \
        (PAD_CTL_PKE | PAD_CTL_PUE |                            \
        PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
@@ -63,14 +70,6 @@ DECLARE_GLOBAL_DATA_PTR;
 
 #define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
 
-#define NOVENA_AUDIO_PWRON             IMX_GPIO_NR(5, 17)
-#define NOVENA_FPGA_RESET_N_GPIO       IMX_GPIO_NR(5, 7)
-#define NOVENA_HDMI_GHOST_HPD          IMX_GPIO_NR(5, 4)
-#define NOVENA_PCIE_RESET_GPIO         IMX_GPIO_NR(3, 29)
-#define NOVENA_PCIE_POWER_ON_GPIO      IMX_GPIO_NR(7, 12)
-#define NOVENA_PCIE_WAKE_UP_GPIO       IMX_GPIO_NR(3, 22)
-#define NOVENA_PCIE_DISABLE_GPIO       IMX_GPIO_NR(2, 16)
-
 /*
  * Audio
  */
@@ -98,18 +97,20 @@ static iomux_v3_cfg_t enet_pads1[] = {
        MX6_PAD_RGMII_TD3__RGMII_TD3            | MUX_PAD_CTRL(RGMII_PAD_CTRL),
        MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL      | MUX_PAD_CTRL(RGMII_PAD_CTRL),
        MX6_PAD_ENET_REF_CLK__ENET_TX_CLK       | MUX_PAD_CTRL(ENET_PAD_CTRL),
-       /* pin 35 - 1 (PHY_AD2) on reset */
-       MX6_PAD_RGMII_RXC__GPIO6_IO30           | MUX_PAD_CTRL(NO_PAD_CTRL),
-       /* pin 32 - 1 - (MODE0) all */
-       MX6_PAD_RGMII_RD0__GPIO6_IO25           | MUX_PAD_CTRL(NO_PAD_CTRL),
-       /* pin 31 - 1 - (MODE1) all */
-       MX6_PAD_RGMII_RD1__GPIO6_IO27           | MUX_PAD_CTRL(NO_PAD_CTRL),
-       /* pin 28 - 1 - (MODE2) all */
-       MX6_PAD_RGMII_RD2__GPIO6_IO28           | MUX_PAD_CTRL(NO_PAD_CTRL),
-       /* pin 27 - 1 - (MODE3) all */
-       MX6_PAD_RGMII_RD3__GPIO6_IO29           | MUX_PAD_CTRL(NO_PAD_CTRL),
-       /* pin 33 - 1 - (CLK125_EN) 125Mhz clockout enabled */
-       MX6_PAD_RGMII_RX_CTL__GPIO6_IO24        | MUX_PAD_CTRL(NO_PAD_CTRL),
+
+       /* pin 35, PHY_AD2 */
+       MX6_PAD_RGMII_RXC__GPIO6_IO30   | MUX_PAD_CTRL(ENET_PHY_CFG_PAD_CTRL),
+       /* pin 32, MODE0 */
+       MX6_PAD_RGMII_RD0__GPIO6_IO25   | MUX_PAD_CTRL(ENET_PHY_CFG_PAD_CTRL),
+       /* pin 31, MODE1 */
+       MX6_PAD_RGMII_RD1__GPIO6_IO27   | MUX_PAD_CTRL(ENET_PHY_CFG_PAD_CTRL),
+       /* pin 28, MODE2 */
+       MX6_PAD_RGMII_RD2__GPIO6_IO28   | MUX_PAD_CTRL(ENET_PHY_CFG_PAD_CTRL),
+       /* pin 27, MODE3 */
+       MX6_PAD_RGMII_RD3__GPIO6_IO29   | MUX_PAD_CTRL(ENET_PHY_CFG_PAD_CTRL),
+       /* pin 33, CLK125_EN */
+       MX6_PAD_RGMII_RX_CTL__GPIO6_IO24 | MUX_PAD_CTRL(ENET_PHY_CFG_PAD_CTRL),
+
        /* pin 42 PHY nRST */
        MX6_PAD_EIM_D23__GPIO3_IO23             | MUX_PAD_CTRL(NO_PAD_CTRL),
 };
@@ -127,15 +128,37 @@ static void novena_spl_setup_iomux_enet(void)
 {
        imx_iomux_v3_setup_multiple_pads(enet_pads1, ARRAY_SIZE(enet_pads1));
 
+       /* Assert Ethernet PHY nRST */
        gpio_direction_output(IMX_GPIO_NR(3, 23), 0);
-       gpio_direction_output(IMX_GPIO_NR(6, 30), 1);
-       gpio_direction_output(IMX_GPIO_NR(6, 25), 1);
-       gpio_direction_output(IMX_GPIO_NR(6, 27), 1);
-       gpio_direction_output(IMX_GPIO_NR(6, 28), 1);
-       gpio_direction_output(IMX_GPIO_NR(6, 29), 1);
-       gpio_direction_output(IMX_GPIO_NR(6, 24), 1);
 
+       /*
+        * Use imx6 internal pull-ups to drive PHY mode pins during PHY reset
+        * de-assertion. The intention is to use weak signal drivers (pull-ups)
+        * to prevent the conflict between PHY pins becoming outputs after
+        * reset and imx6 still driving the pins. The issue is described in PHY
+        * datasheet, p.14
+        */
+       gpio_direction_input(IMX_GPIO_NR(6, 30)); /* PHY_AD2 = 1 */
+       gpio_direction_input(IMX_GPIO_NR(6, 25)); /* MODE0 = 1 */
+       gpio_direction_input(IMX_GPIO_NR(6, 27)); /* MODE1 = 1 */
+       gpio_direction_input(IMX_GPIO_NR(6, 28)); /* MODE2 = 1 */
+       gpio_direction_input(IMX_GPIO_NR(6, 29)); /* MODE3 = 1 */
+       gpio_direction_input(IMX_GPIO_NR(6, 24)); /* CLK125_EN = 1 */
+
+       /* Following reset timing (p.53, fig.8 from the PHY datasheet) */
+       mdelay(10);
+
+       /* De-assert Ethernet PHY nRST */
+       gpio_set_value(IMX_GPIO_NR(3, 23), 1);
+
+       /* PHY is now configured, connect FEC to the pads */
        imx_iomux_v3_setup_multiple_pads(enet_pads2, ARRAY_SIZE(enet_pads2));
+
+       /*
+        * PHY datasheet recommends on p.53 to wait at least 100us after reset
+        * before using MII, so we enforce the delay here
+        */
+       udelay(100);
 }
 
 /*
@@ -363,6 +386,13 @@ static void novena_spl_setup_iomux_uart(void)
 static iomux_v3_cfg_t hdmi_pads[] = {
        /* "Ghost HPD" pin */
        MX6_PAD_EIM_A24__GPIO5_IO04 | MUX_PAD_CTRL(NO_PAD_CTRL),
+
+       /* LCD_PWR_CTL */
+       MX6_PAD_CSI0_DAT10__GPIO5_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL),
+       /* LCD_BL_ON */
+       MX6_PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
+       /* GPIO_PWM1 */
+       MX6_PAD_DISP0_DAT8__GPIO4_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
 };
 
 static void novena_spl_setup_iomux_video(void)
@@ -404,8 +434,8 @@ static struct mx6dq_iomux_ddr_regs novena_ddr_ioregs = {
        .dram_ras               = 0x00000038,
        .dram_reset             = 0x00000038,
        /* SDCKE[0:1]: 100k pull-up */
-       .dram_sdcke0            = 0x00003000,
-       .dram_sdcke1            = 0x00003000,
+       .dram_sdcke0            = 0x00000038,
+       .dram_sdcke1            = 0x00000038,
        /* SDBA2: pull-up disabled */
        .dram_sdba2             = 0x00000000,
        /* SDODT[0:1]: 100k pull-up, 40 ohm */
@@ -482,14 +512,16 @@ static struct mx6_ddr_sysinfo novena_ddr_info = {
        /* Single chip select */
        .ncs            = 1,
        .cs1_mirror     = 0,
-       .rtt_wr         = 1,    /* RTT_Wr = RZQ/4 */
-       .rtt_nom        = 2,    /* RTT_Nom = RZQ/2 */
-       .walat          = 3,    /* Write additional latency */
-       .ralat          = 7,    /* Read additional latency */
+       .rtt_wr         = 0,    /* RTT_Wr = RZQ/4 */
+       .rtt_nom        = 1,    /* RTT_Nom = RZQ/2 */
+       .walat          = 0,    /* Write additional latency */
+       .ralat          = 5,    /* Read additional latency */
        .mif3_mode      = 3,    /* Command prediction working mode */
        .bi_on          = 1,    /* Bank interleaving enabled */
        .sde_to_rst     = 0x10, /* 14 cycles, 200us (JEDEC default) */
        .rst_to_cke     = 0x23, /* 33 cycles, 500us (JEDEC default) */
+       .refsel = 1,    /* Refresh cycles at 32KHz */
+       .refr = 7,      /* 8 refresh commands per refresh cycle */
 };
 
 static struct mx6_ddr3_cfg elpida_4gib_1600 = {
@@ -500,11 +532,35 @@ static struct mx6_ddr3_cfg elpida_4gib_1600 = {
        .rowaddr        = 16,
        .coladdr        = 10,
        .pagesz         = 2,
-       .trcd           = 1300,
-       .trcmin         = 4900,
-       .trasmin        = 3590,
+       .trcd           = 1375,
+       .trcmin         = 4875,
+       .trasmin        = 3500,
 };
 
+static void ccgr_init(void)
+{
+       struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+
+       writel(0x00C03F3F, &ccm->CCGR0);
+       writel(0x0030FC03, &ccm->CCGR1);
+       writel(0x0FFFC000, &ccm->CCGR2);
+       writel(0x3FF00000, &ccm->CCGR3);
+       writel(0xFFFFF300, &ccm->CCGR4);
+       writel(0x0F0000C3, &ccm->CCGR5);
+       writel(0x000003FF, &ccm->CCGR6);
+}
+
+static void gpr_init(void)
+{
+       struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
+
+       /* enable AXI cache for VDOA/VPU/IPU */
+       writel(0xF00000CF, &iomux->gpr[4]);
+       /* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */
+       writel(0x007F007F, &iomux->gpr[6]);
+       writel(0x007F007F, &iomux->gpr[7]);
+}
+
 /*
  * called from C runtime startup code (arch/arm/lib/crt0.S:_main)
  * - we have a stack and a place to store GD, both in SRAM
@@ -515,6 +571,9 @@ void board_init_f(ulong dummy)
        /* setup AIPS and disable watchdog */
        arch_cpu_init();
 
+       ccgr_init();
+       gpr_init();
+
        /* setup GP timer */
        timer_init();
 
@@ -544,13 +603,14 @@ void board_init_f(ulong dummy)
        mx6dq_dram_iocfg(64, &novena_ddr_ioregs, &novena_grp_ioregs);
        mx6_dram_cfg(&novena_ddr_info, &novena_mmdc_calib, &elpida_4gib_1600);
 
+       /* Perform DDR DRAM calibration */
+       udelay(100);
+       mmdc_do_write_level_calibration(&novena_ddr_info);
+       mmdc_do_dqs_calibration(&novena_ddr_info);
+
        /* Clear the BSS. */
        memset(__bss_start, 0, __bss_end - __bss_start);
 
        /* load/boot image from boot device */
        board_init_r(NULL, 0);
 }
-
-void reset_cpu(ulong addr)
-{
-}