/* | |
* Copyright 2017 NXP | |
* | |
* SPDX-License-Identifier: GPL-2.0+ | |
* | |
* Generated code from MX8M_DDR_tool | |
*/ | |
#include <common.h> | |
#include <errno.h> | |
#include <asm/arch/clock.h> | |
#include <asm/arch/ddr_memory_map.h> | |
#include <asm/io.h> | |
#include "ddr.h" | |
#ifndef SRC_DDRC_RCR_ADDR | |
#define SRC_DDRC_RCR_ADDR SRC_IPS_BASE_ADDR + 0x1000 | |
#endif | |
#ifndef DDR_CSD1_BASE_ADDR | |
#define DDR_CSD1_BASE_ADDR 0x40000000 | |
#endif | |
#define SILICON_TRAIN | |
void ddr_cfg_phy_hynix_1gb_evt(void); | |
static volatile unsigned int tmp, tmp_t, i; | |
void ddr_init_hynix_1gb_evt(void) { | |
/** Initialize DDR clock and DDRC registers **/ | |
reg32_write(0x3038a088, 0x7070000); | |
reg32_write(0x3038a084, 0x4030000); | |
reg32_write(0x303a00ec, 0xffff); | |
tmp = reg32_read(0x303a00f8); | |
tmp |= 0x20; | |
reg32_write(0x303a00f8, tmp); | |
reg32_write(0x30391000, 0x8f000000); | |
reg32_write(0x30391004, 0x8f000000); | |
reg32_write(0x30360068, 0xece580); | |
tmp = reg32_read(0x30360060); | |
tmp &= ~0x80; | |
reg32_write(0x30360060, tmp); | |
tmp = reg32_read(0x30360060); | |
tmp |= 0x200; | |
reg32_write(0x30360060, tmp); | |
tmp = reg32_read(0x30360060); | |
tmp &= ~0x20; | |
reg32_write(0x30360060, tmp); | |
tmp = reg32_read(0x30360060); | |
tmp &= ~0x10; | |
reg32_write(0x30360060, tmp); | |
do { | |
tmp = reg32_read(0x30360060); | |
if (tmp & 0x80000000) break; | |
} while (1); | |
reg32_write(0x30391000, 0x8f000006); | |
reg32_write(0x3d400304, 0x1); | |
reg32_write(0x3d400030, 0x1); | |
reg32_write(0x3d400000, 0xa1080020); | |
reg32_write(0x3d400028, 0x0); | |
reg32_write(0x3d400020, 0x203); | |
reg32_write(0x3d400024, 0x186a000); | |
reg32_write(0x3d400064, 0x610090); | |
reg32_write(0x3d4000d0, 0xc003061c); | |
reg32_write(0x3d4000d4, 0x9e0000); | |
reg32_write(0x3d4000dc, 0xd4002d); | |
reg32_write(0x3d4000e0, 0x310008); | |
reg32_write(0x3d4000e8, 0x66004a); | |
reg32_write(0x3d4000ec, 0x16004a); | |
reg32_write(0x3d400100, 0x1a201b22); | |
reg32_write(0x3d400104, 0x60633); | |
reg32_write(0x3d40010c, 0xc0c000); | |
reg32_write(0x3d400110, 0xf04080f); | |
reg32_write(0x3d400114, 0x2040c0c); | |
reg32_write(0x3d400118, 0x1010007); | |
reg32_write(0x3d40011c, 0x401); | |
reg32_write(0x3d400130, 0x20600); | |
reg32_write(0x3d400134, 0xc100002); | |
reg32_write(0x3d400138, 0x96); | |
reg32_write(0x3d400144, 0xa00050); | |
reg32_write(0x3d400180, 0xc3200018); | |
reg32_write(0x3d400184, 0x28061a8); | |
reg32_write(0x3d400188, 0x0); | |
reg32_write(0x3d400190, 0x497820a); | |
reg32_write(0x3d400194, 0x80303); | |
reg32_write(0x3d4001a0, 0xe0400018); | |
reg32_write(0x3d4001a4, 0xdf00e4); | |
reg32_write(0x3d4001a8, 0x80000000); | |
reg32_write(0x3d4001b0, 0x11); | |
reg32_write(0x3d4001b4, 0x170a); | |
reg32_write(0x3d4001c0, 0x1); | |
reg32_write(0x3d4001c4, 0x1); | |
reg32_write(0x3d4000f4, 0x639); | |
reg32_write(0x3d400108, 0x70e1214); | |
reg32_write(0x3d400200, 0x1f); | |
reg32_write(0x3d40020c, 0x0); | |
reg32_write(0x3d400210, 0x1f1f); | |
reg32_write(0x3d400204, 0x80808); | |
reg32_write(0x3d400214, 0x7070707); | |
reg32_write(0x3d400218, 0xf070707); | |
reg32_write(0x3d402020, 0x1); | |
reg32_write(0x3d402024, 0x518b00); | |
reg32_write(0x3d402050, 0x20d040); | |
reg32_write(0x3d402064, 0x14001f); | |
reg32_write(0x3d4020dc, 0x940009); | |
reg32_write(0x3d4020e0, 0x310000); | |
reg32_write(0x3d4020e8, 0x66004a); | |
reg32_write(0x3d4020ec, 0x16004a); | |
reg32_write(0x3d402100, 0xb070508); | |
reg32_write(0x3d402104, 0x3040b); | |
reg32_write(0x3d402108, 0x305090c); | |
reg32_write(0x3d40210c, 0x505000); | |
reg32_write(0x3d402110, 0x4040204); | |
reg32_write(0x3d402114, 0x2030303); | |
reg32_write(0x3d402118, 0x1010004); | |
reg32_write(0x3d40211c, 0x301); | |
reg32_write(0x3d402130, 0x20300); | |
reg32_write(0x3d402134, 0xa100002); | |
reg32_write(0x3d402138, 0x20); | |
reg32_write(0x3d402144, 0x220011); | |
reg32_write(0x3d402180, 0xc0a70006); | |
reg32_write(0x3d402190, 0x3858202); | |
reg32_write(0x3d402194, 0x80303); | |
reg32_write(0x3d4021b4, 0x502); | |
reg32_write(0x3d400244, 0x0); | |
reg32_write(0x3d400250, 0x29001505); | |
reg32_write(0x3d400254, 0x2c); | |
reg32_write(0x3d40025c, 0x5900575b); | |
reg32_write(0x3d400264, 0x90000096); | |
reg32_write(0x3d40026c, 0x1000012c); | |
reg32_write(0x3d400300, 0x16); | |
reg32_write(0x3d400304, 0x0); | |
reg32_write(0x3d40030c, 0x0); | |
reg32_write(0x3d400320, 0x1); | |
reg32_write(0x3d40036c, 0x11); | |
reg32_write(0x3d400400, 0x111); | |
reg32_write(0x3d400404, 0x10f3); | |
reg32_write(0x3d400408, 0x72ff); | |
reg32_write(0x3d400490, 0x1); | |
reg32_write(0x3d400494, 0xe00); | |
reg32_write(0x3d400498, 0x62ffff); | |
reg32_write(0x3d40049c, 0xe00); | |
reg32_write(0x3d4004a0, 0xffff); | |
reg32_write(0x30391000, 0x8f000004); | |
reg32_write(0x30391000, 0x8f000000); | |
reg32_write(0x3d400030, 0xa8); | |
do { | |
tmp = reg32_read(0x3d400004); | |
if (tmp & 0x223) break; | |
} while (1); | |
reg32_write(0x3d400320, 0x0); | |
reg32_write(0x3d000000, 0x1); | |
reg32_write(0x3d4001b0, 0x10); | |
reg32_write(0x3c040280, 0x0); | |
reg32_write(0x3c040284, 0x1); | |
reg32_write(0x3c040288, 0x2); | |
reg32_write(0x3c04028c, 0x3); | |
reg32_write(0x3c040290, 0x4); | |
reg32_write(0x3c040294, 0x5); | |
reg32_write(0x3c040298, 0x6); | |
reg32_write(0x3c04029c, 0x7); | |
reg32_write(0x3c044280, 0x0); | |
reg32_write(0x3c044284, 0x1); | |
reg32_write(0x3c044288, 0x2); | |
reg32_write(0x3c04428c, 0x3); | |
reg32_write(0x3c044290, 0x4); | |
reg32_write(0x3c044294, 0x5); | |
reg32_write(0x3c044298, 0x6); | |
reg32_write(0x3c04429c, 0x7); | |
reg32_write(0x3c048280, 0x0); | |
reg32_write(0x3c048284, 0x1); | |
reg32_write(0x3c048288, 0x2); | |
reg32_write(0x3c04828c, 0x3); | |
reg32_write(0x3c048290, 0x4); | |
reg32_write(0x3c048294, 0x5); | |
reg32_write(0x3c048298, 0x6); | |
reg32_write(0x3c04829c, 0x7); | |
reg32_write(0x3c04c280, 0x0); | |
reg32_write(0x3c04c284, 0x1); | |
reg32_write(0x3c04c288, 0x2); | |
reg32_write(0x3c04c28c, 0x3); | |
reg32_write(0x3c04c290, 0x4); | |
reg32_write(0x3c04c294, 0x5); | |
reg32_write(0x3c04c298, 0x6); | |
reg32_write(0x3c04c29c, 0x7); | |
/* Configure DDR PHY's registers */ | |
ddr_cfg_phy_hynix_1gb_evt(); | |
reg32_write(DDRC_RFSHCTL3(0), 0x00000000); | |
reg32_write(DDRC_SWCTL(0), 0x0000); | |
/* | |
* ------------------- 9 ------------------- | |
* Set DFIMISC.dfi_init_start to 1 | |
* ----------------------------------------- | |
*/ | |
reg32_write(DDRC_DFIMISC(0), 0x00000030); | |
reg32_write(DDRC_SWCTL(0), 0x0001); | |
/* wait DFISTAT.dfi_init_complete to 1 */ | |
tmp_t = 0; | |
while (tmp_t == 0) { | |
tmp = reg32_read(DDRC_DFISTAT(0)); | |
tmp_t = tmp & 0x01; | |
tmp = reg32_read(DDRC_MRSTAT(0)); | |
} | |
reg32_write(DDRC_SWCTL(0), 0x0000); | |
/* clear DFIMISC.dfi_init_complete_en */ | |
reg32_write(DDRC_DFIMISC(0), 0x00000010); | |
reg32_write(DDRC_DFIMISC(0), 0x00000011); | |
reg32_write(DDRC_PWRCTL(0), 0x00000088); | |
tmp = reg32_read(DDRC_CRCPARSTAT(0)); | |
/* | |
* set SWCTL.sw_done to enable quasi-dynamic register | |
* programming outside reset. | |
*/ | |
reg32_write(DDRC_SWCTL(0), 0x00000001); | |
/* wait SWSTAT.sw_done_ack to 1 */ | |
while ((reg32_read(DDRC_SWSTAT(0)) & 0x1) == 0) | |
; | |
/* wait STAT.operating_mode([1:0] for ddr3) to normal state */ | |
while ((reg32_read(DDRC_STAT(0)) & 0x3) != 0x1) | |
; | |
reg32_write(DDRC_PWRCTL(0), 0x00000088); | |
/* reg32_write(DDRC_PWRCTL(0), 0x018a); */ | |
tmp = reg32_read(DDRC_CRCPARSTAT(0)); | |
/* enable port 0 */ | |
reg32_write(DDRC_PCTRL_0(0), 0x00000001); | |
/* enable DDR auto-refresh mode */ | |
tmp = reg32_read(DDRC_RFSHCTL3(0)) & ~0x1; | |
reg32_write(DDRC_RFSHCTL3(0), tmp); | |
} |