From 53920469cc62ffa2da84f90a6685ff21f99913bf Mon Sep 17 00:00:00 2001 From: hcy Date: Mon, 26 Jan 2015 09:13:52 +0800 Subject: [PATCH] Support 1.5GB and 3GB with 2CS on the DDR1 channel --- arch/arm/mach-rockchip/ddr_rk32.c | 67 ++++++++++++++++++++++++------- arch/arm/mm/init.c | 9 +++++ 2 files changed, 61 insertions(+), 15 deletions(-) diff --git a/arch/arm/mach-rockchip/ddr_rk32.c b/arch/arm/mach-rockchip/ddr_rk32.c index d9e996c99be1..556035a39b86 100755 --- a/arch/arm/mach-rockchip/ddr_rk32.c +++ b/arch/arm/mach-rockchip/ddr_rk32.c @@ -1380,6 +1380,7 @@ typedef struct CHANNEL_INFO_Tag DRAM_TYPE mem_type; // =DRAM_MAX, channel invalid uint32 ddr_speed_bin; // used for ddr3 only uint32 ddr_capability_per_die; // one chip cs capability + uint32 dtt_cs; //data training cs }CH_INFO,*pCH_INFO; struct ddr_freq_t { @@ -1716,6 +1717,7 @@ static void ddr_get_datatraing_addr(uint32 *pdtar) uint32 bank; uint32 bw; uint32 conf; + uint32 cap1; for(ch=0,chCnt=0;chdtt_cs = 0; } // caculate aglined physical address @@ -1752,7 +1755,23 @@ static void ddr_get_datatraing_addr(uint32 *pdtar) socAddr[1] = addr + strideSize; } ddr_print("socAddr[0]=0x%x, socAddr[1]=0x%x\n", socAddr[0], socAddr[1]); - if((stride >= 0x10) && (stride <= 0x13)) // 3GB stride + if(stride < 4) + { + cap1 = (1 << (READ_ROW_INFO(1,0)+READ_COL_INFO(1)+READ_BK_INFO(1)+READ_BW_INFO(1))); + if(READ_CS_INFO(1) > 1) + { + cap1 += cap1 >> (READ_ROW_INFO(1,0)-READ_ROW_INFO(1,1)); + } + if(READ_CH_ROW_INFO(1)) + { + cap1 = cap1*3/4; + } + chAddr[0] = addr; + chAddr[1] = cap1 - PAGE_SIZE; + if(READ_CS_INFO(1) > 1) + p_ddr_ch[1]->dtt_cs = 1; + } + else if((stride >= 0x10) && (stride <= 0x13)) // 3GB stride { //conver to ch addr if(addr < 0x40000000) @@ -1790,13 +1809,13 @@ static void ddr_get_datatraing_addr(uint32 *pdtar) chAddr[1] = socAddr[1] - halfCap; } } - ddr_print("chAddr[0]=0x%x, chAddr[1]=0x%x\n", chAddr[0], chAddr[1]); } else { chAddr[0] = addr; chAddr[1] = addr; } + ddr_print("chAddr[0]=0x%x, chAddr[1]=0x%x\n", chAddr[0], chAddr[1]); for(ch=0,chCnt=0;chPIR |= CLRSR; cs = ((pPHY_Reg->PGCR>>18) & 0xF); - pPHY_Reg->PGCR = (pPHY_Reg->PGCR & (~(0xF<<18))) | (1<<18); //use cs0 dtt + if(DATA(ddr_ch[ch]).dtt_cs == 0) + pPHY_Reg->PGCR = (pPHY_Reg->PGCR & (~(0xF<<18))) | (1<<18); //use cs0 dtt + else + pPHY_Reg->PGCR = (pPHY_Reg->PGCR & (~(0xF<<18))) | (2<<18); //use cs1 dtt // trigger DTT pPHY_Reg->PIR |= INIT | QSTRN | LOCKBYP | ZCALBYP | CLRSR | ICPC; return cs; @@ -2004,25 +2026,39 @@ static uint32 __sramfunc ddr_data_training_trigger(uint32 ch) //!0 DTTʧ°Ü static uint32 __sramfunc ddr_data_training(uint32 ch, uint32 cs) { - uint32 i,byte; + uint32 i,byte=2,cs_msk; pDDR_REG_T pDDR_Reg = DATA(ddr_ch[ch]).pDDR_Reg; pDDRPHY_REG_T pPHY_Reg = DATA(ddr_ch[ch]).pPHY_Reg; - + + if(DATA(ddr_ch[ch]).dtt_cs == 0){ + cs_msk = 1; + }else{ + cs_msk = 2; + } // wait echo byte DTDONE - while((pPHY_Reg->DATX8[0].DXGSR[0] & 1) != 1); - while((pPHY_Reg->DATX8[1].DXGSR[0] & 1) != 1); + while((pPHY_Reg->DATX8[0].DXGSR[0] & cs_msk) != cs_msk); + while((pPHY_Reg->DATX8[1].DXGSR[0] & cs_msk) != cs_msk); if(!(pDDR_Reg->PPCFG & 1)) { - while((pPHY_Reg->DATX8[2].DXGSR[0] & 1) != 1); - while((pPHY_Reg->DATX8[3].DXGSR[0] & 1) != 1); + while((pPHY_Reg->DATX8[2].DXGSR[0] & cs_msk) != cs_msk); + while((pPHY_Reg->DATX8[3].DXGSR[0] & cs_msk) != cs_msk); byte=4; } pPHY_Reg->PGCR = (pPHY_Reg->PGCR & (~(0xF<<18))) | (cs<<18); //restore cs - for(i=0;iDATX8[i].DXDQSTR = (pPHY_Reg->DATX8[i].DXDQSTR & (~((0x7<<3)|(0x3<<14)))) - | ((pPHY_Reg->DATX8[i].DXDQSTR & 0x7)<<3) - | (((pPHY_Reg->DATX8[i].DXDQSTR>>12) & 0x3)<<14); + if(DATA(ddr_ch[ch]).dtt_cs == 0){ + for(i=0;iDATX8[i].DXDQSTR = (pPHY_Reg->DATX8[i].DXDQSTR & (~((0x7<<3)|(0x3<<14))))\ + | ((pPHY_Reg->DATX8[i].DXDQSTR & 0x7)<<3)\ + | (((pPHY_Reg->DATX8[i].DXDQSTR>>12) & 0x3)<<14); + } + }else{ + for(i=0;iDATX8[i].DXDQSTR = (pPHY_Reg->DATX8[i].DXDQSTR & (~((0x7<<0)|(0x3<<12))))\ + | ((pPHY_Reg->DATX8[i].DXDQSTR>>3) & 0x7)\ + | (((pPHY_Reg->DATX8[i].DXDQSTR>>14) & 0x3)<<12); + } } // send some auto refresh to complement the lost while DTT£¬//²âµ½1¸öCSµÄDTT×ʱ¼äÊÇ10.7us¡£×î¶à²¹2´ÎˢРif(cs > 1) @@ -2056,6 +2092,7 @@ static uint32 __sramfunc ddr_data_training(uint32 ch, uint32 cs) } } + static void __sramfunc ddr_set_dll_bypass(uint32 ch, uint32 freq) { pDDR_REG_T pDDR_Reg = DATA(ddr_ch[ch]).pDDR_Reg; @@ -4499,7 +4536,7 @@ static int ddr_init(uint32 dram_speed_bin, uint32 freq) struct clk *clk; uint32 ch,cap=0,cs_cap; - ddr_print("version 1.00 20140603 \n"); + ddr_print("version 1.00 20150126 \n"); p_ddr_reg = kern_to_pie(rockchip_pie_chunk, &DATA(ddr_reg)); p_ddr_set_pll = fn_to_pie(rockchip_pie_chunk, &FUNC(ddr_set_pll)); diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index c12ae661d4ab..15468ce6f322 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -341,6 +341,15 @@ void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc) for (i = 0; i < mi->nr_banks; i++) memblock_add(mi->bank[i].start, mi->bank[i].size); +//#ifdef CONFIG_ARCH_ROCKCHIP + for (i = 1; i < memblock.memory.cnt; i++) { + struct memblock_region *rgn = &memblock.memory.regions[i]; + + if (rgn->size != memblock.memory.regions[i-1].size) + memblock_reserve(rgn->base+rgn->size-PAGE_SIZE, PAGE_SIZE); + } +//#endif + /* Register the kernel text, kernel data and initrd with memblock. */ #ifdef CONFIG_XIP_KERNEL memblock_reserve(__pa(_sdata), _end - _sdata); -- 2.34.1