Chinaunix首页 | 论坛 | 博客
  • 博客访问: 459407
  • 博文数量: 179
  • 博客积分: 3236
  • 博客等级: 中校
  • 技术积分: 1860
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-25 19:13
文章分类

全部博文(179)

文章存档

2011年(34)

2008年(8)

2007年(27)

2006年(110)

分类: 嵌入式

2011-05-12 20:21:27

//=============================================================================
// 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);

}


阅读(1440) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~