#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>
#include <asm/arch/mx6-ddr.h>
+#include "novena.h"
+
DECLARE_GLOBAL_DATA_PTR;
#define UART_PAD_CTRL \
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)
#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
*/
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),
};
{
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);
}
/*
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)
.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 */
/* 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 = {
.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
/* setup AIPS and disable watchdog */
arch_cpu_init();
+ ccgr_init();
+ gpr_init();
+
/* setup GP timer */
timer_init();
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)
-{
-}