//=============================================================================
// File Name : InitSystem.c
// Function : Initialize DRAM, Clock and LCD setting value.
//
//
//=============================================================================
#include
#include
#include
#include "soc_cfg.h"
#include "S5PC100_dramcon.h"
#include "S5PC100_base_regs.h"
#include "S5PC100_Syscon.h"
#include "S5PC100_regs_for_BL.h"
#ifdef SMDKC100_POP_NONE
#define SMDKC100_POP POP_NONE
#elif defined(SMDKC100_POP_A)
#define SMDKC100_POP POP_A
#elif defined(SMDKC100_POP_D)
#define SMDKC100_POP POP_D
#else
#define SMDKC100_POP POP_NONE // Invalid POP type, set with POP_NONE.
#endif
#define LPCON_MAXPOWER 0
#define LPCON_MAXPERFORMANCE 1
#define LPCON_BALANCE 2
//------------------------------------------------------------------------------
// Define LPCON level
//
// LPCON_MAXPOWER Maximum power saving state
// LPCON_MAXPERFORMANCE Maximum performance state
// LPCON_BALANCE Balanced state
#define LPCON_LEVEL LPCON_MAXPERFORMANCE // We only use max performance
void InitClockCONforBL(void);
void InitClockCONforOS(void);
void InitLPCON(void);
void InitClockCONforBL(void)
{
unsigned int ReadVal;
// SetClockDiviReadValer
//SetReg32(rCLK_DIV1, 0x00011110);
SetReg32(rCLK_DIV1, ((HCLK12PCLK1_RATIO-1)< ((MPLL2HCLK1_RATIO-1)< (0< (0< (0< // bit[18:16] - PCLKD1
// bit[14:12] - HCLKD1
// bit[8] - MPLL2
// bit[5:4] - MPLL
SetReg32(rCLK_DIV2, ((HCLK12PCLK1_RATIO-1)<<0));
// bit[3:0] - UART
//SetReg32(rCLK_DIV0, 0x00011301)
SetReg32(rCLK_DIV0, (1<<16)|((HCLK02PCLK0_RATIO_BL-1)<<12)|((ARM2HCLK0_RATIO_BL-1)<<8)|(0<<4)|((APLL2ARM_RATIO-1)<<0));
// bit[28:24] - CAM_DIV :0
// bit[21:20] - ONENAND :0
// bit[18:16] - SECSS
// bit[14:12] - PCLKD0
// bit[10:8] - HCLKD0
// bit[6:4] - ARMCLK
// bit[0] - APLL
// SetLockTime & StartPLL
SetReg32(rAPLL_LOCK, 0x00000e10); // Lock Time = 300us*12Mhz = 3600(=0xe10)
//SetReg32(rAPLL_CON, 0x81BC0400);
SetReg32(rAPLL_CON, (1u<<31)|(APLL_MDIV_BL<<16)|(APLL_PDIV_BL<<8)|(APLL_SDIV_BL<<0));
SetReg32(rMPLL_LOCK, 0x00000e10); // Lock Time = 300us*12Mhz = 3600(=0xe10)
//SetReg32(rMPLL_CON, 0x80850302);
SetReg32(rMPLL_CON, (1u<<31)|(MPLL_MDIV<<16)|(MPLL_PDIV<<8)|(MPLL_SDIV<<0));
SetReg32(rEPLL_LOCK, 0x00000e10); // Lock Time = 300us*12Mhz = 3600(=0xe10)
SetReg32(rEPLL_CON, (1u<<31)|(EPLL_MDIV<<16)|(EPLL_PDIV<<8)|(EPLL_SDIV<<0));
GetReg32(rCLK_SRC0, ReadVal);
//SetReg32(rCLK_SRC0, 0x00000011);
SetReg32(rCLK_SRC0, (ReadVal&~(1<<20))|(0<<20)); // HPLL source clock = HREF_FIN27M
SetReg32(rHPLL_LOCK, 0x00000e10); // Lock Time = 300us*12Mhz = 3600(=0xe10)
SetReg32(rHPLL_CON, (1u<<31)|(HPLL_MDIV<<16)|(HPLL_PDIV<<8)|(HPLL_SDIV<<0));
// SetSourceClock
GetReg32(rCLK_SRC0, ReadVal);
SetReg32(rCLK_SRC0, (ReadVal&~(0x11111))|(0<<16)|(1<<12)|(1<<8)|(1<<4)|(1<<0));
// bit[16] - muxAM (0: MOUTMPLL, 1: DOUTAPLL2)
// bit[12] - muxHPLL (0: CLK27M, 1: FOUTHPLL)
// bit[8] - muxEPLL (0: FINEPLL, 1: FOUTEPLL)
// bit[4] - muxMPLL (0: FINMPLL, 1: FOUTMPLL)
// bit[0] - muxAPLL (0: FINAPLL, 1: FOUTAPLL)
SetReg32(rCLK_SRC1, (1<<24)|(1<<0));
// bit[24] - muxCLK48M (0: XUSBXTI, 1: OTG_PHY)
// bit[0] - muxUART (0: MOUTEPLL, 1: DOUTMPLL)
// Internal clock can be monitored through XCLKOUT PAD.
// * SMDKC100 Single(none POP): TP80 on CPU B'd(EVM)
// * SMDKC100 POP A type : TP73 on CPU B'd(EVM)
SetReg32(rCLK_OUT, (0<<20)|(6<<12));
// bit[23:20] - DiviReadValer value
// bit[16:12] - Clock out type (6: PCLKD1)
}
void InitClockCONforOS(void)
{
unsigned int ReadVal;
// SetClockDiviReadValer
SetReg32(rCLK_DIV1, ((HCLK12PCLK1_RATIO-1)< ((MPLL2HCLK1_RATIO-1)< (0< (0< (0< // bit[18:16] - PCLKD1
// bit[14:12] - HCLKD1
// bit[8] - MPLL2
// bit[5:4] - MPLL
SetReg32(rCLK_DIV2, ((HCLK12PCLK1_RATIO-1)<<0));
// bit[3:0] - UART
// SetLockTime & StartPLL
SetReg32(rAPLL_LOCK, 0x00000e10); // Lock Time = 300us*12Mhz = 3600(=0xe10)
SetReg32(rAPLL_CON, (1u<<31)|(APLL_MDIV<<16)|(APLL_PDIV<<8)|(APLL_SDIV<<0));
SetReg32(rCLK_DIV0, (1<<16)|((HCLK02PCLK0_RATIO-1)<<12)|((ARM2HCLK0_RATIO-1)<<8)|(0<<4)|((APLL2ARM_RATIO-1)<<0));
// bit[28:24] - CAM_DIV :0
// bit[21:20] - ONENAND :0
// bit[18:16] - SECSS
// bit[14:12] - PCLKD0
// bit[10:8] - HCLKD0
// bit[6:4] - ARMCLK
// bit[0] - APLL
SetReg32(rMPLL_LOCK, 0x00000e10); // Lock Time = 300us*12Mhz = 3600(=0xe10)
SetReg32(rMPLL_CON, (1u<<31)|(MPLL_MDIV<<16)|(MPLL_PDIV<<8)|(MPLL_SDIV<<0));
SetReg32(rEPLL_LOCK, 0x00000e10); // Lock Time = 300us*12Mhz = 3600(=0xe10)
SetReg32(rEPLL_CON, (1u<<31)|(EPLL_MDIV<<16)|(EPLL_PDIV<<8)|(EPLL_SDIV<<0));
GetReg32(rCLK_SRC0, ReadVal);
SetReg32(rCLK_SRC0, (ReadVal&~(1<<20))|(0<<20)); // HPLL source clock = HREF_FIN27M
SetReg32(rHPLL_LOCK, 0x00000e10); // Lock Time = 300us*12Mhz = 3600(=0xe10)
SetReg32(rHPLL_CON, (1u<<31)|(HPLL_MDIV<<16)|(HPLL_PDIV<<8)|(HPLL_SDIV<<0));
// SetSourceClock
GetReg32(rCLK_SRC0, ReadVal);
SetReg32(rCLK_SRC0, (ReadVal&~(0x11111))|(0<<16)|(1<<12)|(1<<8)|(1<<4)|(1<<0));
// bit[16] - muxAM (0: MOUTMPLL, 1: DOUTAPLL2)
// bit[12] - muxHPLL (0: CLK27M, 1: FOUTHPLL)
// bit[8] - muxEPLL (0: FINEPLL, 1: FOUTEPLL)
// bit[4] - muxMPLL (0: FINMPLL, 1: FOUTMPLL)
// bit[0] - muxAPLL (0: FINAPLL, 1: FOUTAPLL)
SetReg32(rCLK_SRC1, (1<<24)|(1<<0));
// bit[24] - muxCLK48M (0: XUSBXTI, 1: OTG_PHY)
// bit[0] - muxUART (0: MOUTEPLL, 1: DOUTMPLL)
// Internal clock can be monitored through XCLKOUT PAD.
// * SMDKC100 Single(none POP): TP80 on CPU B'd
// * SMDKC100 POP A type : TP73 on CPU B'd
SetReg32(rCLK_OUT, (0<<20)|(9<<12));
// bit[23:20] - DiviReadValer value
// bit[16:12] - Clock out type (9: ARMCLK_DIV4)
}
// We only need to care about performance.
void InitLPCON()
{
UINT32 ReadVal;
UINT32 ReadValStat;
#if INIT_QoS
volatile unsigned int *rTMP;
#endif
// ---------------------------------------------------------------
// 1. Config PHY
// ---------------------------------------------------------------
// [ 1. Config PHY ]
#if ENABLE_PHY_DLL // Now, we use ENABLE_PHY_DLL
SetReg32(rLPCON_PHY_CONTROL0, 0x50101008);
//SetReg32(rLPCON_PHY_CONTROL0, 0x50<<24|0x10<<16|0x10<<8|0<<4|1<<3|0<<2|0<<1|0<<0);
// [31:24] DLL force delay
// [23:16] DLL delay increment
// [15:8] DLL lock start point
// [7:5] Should be zero.
// [4] DLL CRC
// [3] ctrl_dfdqs
// [2] ctrl_half
// [1] ctrl_dll_on
// [0] ctrl_start
SetReg32(rLPCON_PHY_CONTROL1, 0xf6<<0);
//SetReg32(rLPCON_PHY_CONTROL1, 0xf4<<0);
SetReg32(rLPCON_PHY_CONTROL2, 0<<24|0<<16|0<<8|0<<0);
GetReg32(rLPCON_PHY_CONTROL0, ReadVal);
SetReg32(rLPCON_PHY_CONTROL0, ReadVal|=(1<<1)); // DLL on
SetReg32(rLPCON_PHY_CONTROL0, ReadVal|=(1<<0)); // DLL start
do
{
GetReg32(rLPCON_PHY_STATUS0, ReadVal);
} while ((ReadVal&0x4) != 0x4); // wait until PLL lock.
GetReg32(rLPCON_PHY_STATUS0, ReadValStat);
ReadValStat = (ReadValStat>>6)&0xff; // locked delay
GetReg32(rLPCON_PHY_CONTROL0, ReadVal);
ReadVal &= ~(0xff<<24);
SetReg32(rLPCON_PHY_CONTROL0, ReadVal|=(ReadValStat<<24)); // force locking value for DLL off
SetReg32(rLPCON_PHY_CONTROL0, ReadVal&=~(1<<1)); // DLL off
#endif
// ---------------------------------------------------------------
// 2. Config DMC itself
// ---------------------------------------------------------------
SetReg32(rLPCON_CON_CONTROL, 0xFF001010);
//SetReg32(rLPCON_CON_CONTROL, 0xff<<16|1<<12|0<<10|0<<9|0<<8|0<<7|0<<6|0<<5|1<<4|0<<1|0<<0);
// [27:16] Default timeout cycles (n aclk cycles)
// [15:12] Read data fetch cycles (n mclk cycles)
// [10] DQ swap
// [9] Command queue status of chip1 (RO)
// [8] Command queue status of chip0 (RO)
// [7] PHY driving
// [6] Read cycle gap for two different chips (0=disable, 1=enable)
// [5] Auto refresh counter (0=disable, 1=enable)
// [4] Out of order scheduling (0=disable, 1=enable)
// [3:1] aclk:mclk (0=1:1, 3=2:1)
// [0] (0=sync, 1=async)
SetReg32(rLPCON_MEM_CONTROL, 0x00212400);
//SetReg32(rLPCON_MEM_CONTROL, 2<<20|1<<16|2<<12|MEM_TYPE<<8|0<<6|1<<5|1<<4|0<<2|0<<1|0<<0);
// [22:20] Memory burst length (1=2, 2=4, 3=8, 4=16)
// [19:16] Number of Memory chips (0=1chip, 1=2chips)
// [15:12] Width of Memory data bus (1=16bit, 2=32bit)
// [11:8] Type of Memory (1=LPDDR, 2=LPDDR2, 3=DDR, 4=DDR2)
// [7:6] Additional latency for PALL
// [5] Dynamic self refresh (0=disable, 1=enable)
// [4] Force precharge (1=Auto-precharge)
// [3:2] Type of dynamic power down
// [1] Dynamic power down
// [0] Dynamic clock control
#if (SMDKC100_POP == POP_A)
SetReg32(rLPCON_MEM_CONFIG0, 0x28<<24|0xf8<<16|0<<12|2<<8|2<<4|2<<0); // OneDRAM
SetReg32(rLPCON_MEM_CONFIG1, 0x20<<24|0xf8<<16|1<<12|2<<8|2<<4|2<<0); // mDDR
#elif (SMDKC100_POP == POP_D)
SetReg32(rLPCON_MEM_CONFIG0, 0x30<<24|0xf0<<16|1<<12|3<<8|1<<4|2<<0); // mDDR 128MB 13bit, COL:10bit, 4banks
SetReg32(rLPCON_MEM_CONFIG1, 0x20<<24|0xf0<<16|1<<12|3<<8|2<<4|2<<0); // mDDR 256MB 14bit, COL:10bit, 4banks
#elif (SMDKC100_POP == POP_NONE)
SetReg32(rLPCON_MEM_CONFIG0, 0x20F00313);
//SetReg32(rLPCON_MEM_CONFIG0, 0x20<<24|0xf0<<16|1<<12|3<<8|1<<4|3<<0);
SetReg32(rLPCON_MEM_CONFIG1, 0x40F00313);
//SetReg32(rLPCON_MEM_CONFIG1, 0x40<<24|0xf0<<16|1<<12|3<<8|1<<4|3<<0);
#else
#error // Invalid POP type
#endif
// [31:24] AXI base address
// [23:16] AXI base address mask
// [15:12] Address mapping methid (0=bank/row/col, 1=row/bank/col)
// [11:8] Number of column address bits (0=7bits, 1=8bits, 2=9bits, 3=10bits, ... 5=12bits)
// [7:4] Number of row address bits (0=12bits, 1=13bits, 2=14bits, 3=15bits)
// [3:0] Number of banks (0=1banks, 1=2banks, 2=4banks, 3=8banks)
SetReg32(rLPCON_PRECH_CONFIG, 0x20<<24|0<<8|0<<0);
// [31:24] Force precharge cycle (if MEM_CONTROL[4] is set.)
// [15:8] Memory chip1 precharge bank selective policy (1=close page policy) ???
// [7:0] Memory chip0 precharge bank selective policy (1=close page policy) ???
//SetReg32(rLPCON_PWRDN_CONFIG, 0x10<<16|4); ///
// [31:16] Number of cycles for dynamic self refresh entry
// [7:0] Number of cycles for dynamic power down entry
//#ifdef SLOWAHB
//SetReg32(rLPCON_TIMING_AREF, 0x287); // 7.8us*83MHz=0x287
//#else
SetReg32(rLPCON_TIMING_AREF, 0x50e); // 7.8us*166MHz=0x50e
//#endif // S5PCxxx_SLOWAHB
// [15:0] Average periodic refresh interval
SetReg32(rLPCON_TIMING_ROW, 0x16233288);
//SetReg32(rLPCON_TIMING_ROW, 22<<24|2<<20|3<<16|3<<12|10<<6|8<<0);
// [31:24] tRFC = 132ns/6ns = 22
// [23:20] tRRD = 12ns/6ns = 2
// [19:16] tRP = 18ns/6ns = 3
// [15:12] tRCD = 18ns/6ns = 3
// [11:6] tRC = 60ns/6ns = 10
// [5:0] tRAS = 48ns/6ns = 8
SetReg32(rLPCON_TIMING_DATA, 0x23260304);
//SetReg32(rLPCON_TIMING_DATA, 2<<28|3<<24|2<<20|CAS_DELAY<<16|3<<8|4<<0);
// [31:28] tWTR (Internal write to Read command delay) (at least 2)
// [27:24] tWR = 18ns/6ns = 3
// [23:20] tRTP (Internal read to Precharge command delay) (maybe 3)
// [19:16] CL = 5
// [11:8] WL (for only LPDDR2)
// [3:0] RL (for only LPDDR2)
SetReg32(rLPCON_TIMING_POWER, 0x09C80232);
//SetReg32(rLPCON_TIMING_POWER, 9<<24|200<<16|2<<8|3<<4|2<<0);
// [29:24] tFAW = Four active window (maybe 50ns)
// [23:16] tXSR = 200
// [15:8] tXP (Exit power down to next valid command delay) (2)
// [7:4] tCKE = CLE minimun pulse width (3)
// [3:0] tMRD = 2
#if INIT_QoS
// ---------------------------------------------------------------
// 3.Initialize QoS
// ---------------------------------------------------------------
rTMP = rLPCON_QOS_CONTROL0;
for (ReadVal=0; ReadVal<8; rTMP++)
SetReg32(rTMP, 0x00ff0000);
rTMP = rLPCON_QOS_CONFIG0;
for (ReadVal=0; ReadVal<8; rTMP++)
SetReg32(rTMP, 0x00000000);
#endif
// ---------------------------------------------------------------
// 4.Initialize DRAM (rLPCON_DIRECT_CMD)
// ---------------------------------------------------------------
// [27:24] Type of direct command (0=MRS/EMRS, 1=PALL, 2=PRE, 3=DPD, 4=REFS, 5=REFA, 6=CKEL, 7=NOP, 8=REFSX, 9=MRR)
// [20] The chip number to send the direct command to (0=chip0, 1=chip1)
// [18:16] Bits mapped to the bank address pins
// [14:0] Bits mapped to the address pins
// for chip 0
SetReg32(rLPCON_DIRECT_CMD, 7<<24); // chip0 Deselect (NOP)
SetReg32(rLPCON_DIRECT_CMD, 1<<24); // chip0 PALL
SetReg32(rLPCON_DIRECT_CMD, 0x02<<16); // chip0 EMRS2
SetReg32(rLPCON_DIRECT_CMD, 0x03<<16); // chip0 EMRS3
SetReg32(rLPCON_DIRECT_CMD, 1<<16 | 4<<8); // chip0 EMRS1
SetReg32(rLPCON_DIRECT_CMD, 0x762<<0); // chip0 MRS
SetReg32(rLPCON_DIRECT_CMD, 1<<24); // chip0 PALL
SetReg32(rLPCON_DIRECT_CMD, 5<<24); // chip0 REFA
SetReg32(rLPCON_DIRECT_CMD, 5<<24); // chip0 REFA
SetReg32(rLPCON_DIRECT_CMD, 0x662<<0); // chip0 MRS
SetReg32(rLPCON_DIRECT_CMD, 0x10780<<0); // chip0 EMRS1
SetReg32(rLPCON_DIRECT_CMD, 0x01<<16 | 4<<8); // chip0 EMRS1
//SetReg32(rLPCON_DIRECT_CMD, 0<<24 | 0<<16 | CAS_DELAY<<4 | 2<<0); // chip0 MRS
// for chip 1
SetReg32(rLPCON_DIRECT_CMD, 7<<24 | 1<<20); // chip1 Deselect (NOP)
SetReg32(rLPCON_DIRECT_CMD, 1<<24 | 1<<20); // chip1 PALL
SetReg32(rLPCON_DIRECT_CMD, 0x02<<16 | 1<<20); // chip1 EMRS2
SetReg32(rLPCON_DIRECT_CMD, 0x03<<16 | 1<<20); // chip1 EMRS3
SetReg32(rLPCON_DIRECT_CMD, 0x104<<8 | 4<<8 | 1<<20); // chip1 EMRS1
SetReg32(rLPCON_DIRECT_CMD, 0x762<<0 | 1<<20); // chip1 MRS
SetReg32(rLPCON_DIRECT_CMD, 1<<24 | 1<<20); // chip1 PALL
SetReg32(rLPCON_DIRECT_CMD, 0x51<<20 | 1<<20); // chip1 REFA
SetReg32(rLPCON_DIRECT_CMD, 0x51<<20 | 1<<20); // chip1 REFA
SetReg32(rLPCON_DIRECT_CMD, 0x662<<20 | 1<<20); // chip1 MRS
SetReg32(rLPCON_DIRECT_CMD, 0x117080<<0 | 1<<20); // chip1 EMRS1
SetReg32(rLPCON_DIRECT_CMD, 0x110400<<0 | 1<<20); // chip1 EMRS1
// SetReg32(rLPCON_DIRECT_CMD, 5<<24 | 1<<20); // chip1 REFA
// SetReg32(rLPCON_DIRECT_CMD, 5<<24 | 1<<20); // chip1 REFA
// SetReg32(rLPCON_DIRECT_CMD, 0<<24 | 1<<20 | 0<<16 | CAS_DELAY<<4 | 2<<0); // chip1 MRS
// [8] DLL Reset,
// [6:4] CAS Delay
// [3] 0=Sequential
// [2:0] Burst (1=2, 2=4, 3=8)
//SetReg32(rLPCON_DIRECT_CMD, 0<<24|4<<16|0<<5|0<<0); // chip0 EMRS ///
// [17:16] 4 for DDR2
// [6:5] Drive strength (0=full, 1=half, 2=quater, 3=octant)
// [2:0] Partial Self Refresh (0=full array, 1=half array, 2=quater array)
//SetReg32(rLPCON_DIRECT_CMD, 7<<24); // chip0 Deselect (NOP) ///
// ---------------------------------------------------------------
// 5. Start the DMC.
// ---------------------------------------------------------------
SetReg32(rLPCON_CON_CONTROL, 0x0FF01030); // auto fresh on
//GetReg32(rLPCON_CON_CONTROL, ReadVal);
//SetReg32(rLPCON_CON_CONTROL, ReadVal|=(1<<5));
SetReg32(rLPCON_PWRDN_CONFIG, 0x10<<16|4); // add
// [31:16] Number of cycles for dynamic self refresh entry
// [7:0] Number of cycles for dynamic power down entry
//GetReg32(rLPCON_MEM_CONTROL, ReadVal);
//SetReg32(rLPCON_MEM_CONTROL, ReadVal&=(~0xff));
SetReg32(rLPCON_MEM_CONTROL, 0x00212400);
}
阅读(1451) | 评论(0) | 转发(0) |