enum sw_ic_ver sw_get_ic_ver(void) { uint32 reg_val; uint32 id; enable_ss_clk(); reg_val = mctl_read_w(SSCTL_REG_BASE + 0x00); //SS_CTL reg_val >>=16; reg_val &=0x3; mctl_write_w(SSCTL_REG_BASE + 0x00,reg_val); disable_ss_clk(); id = reg_val; if(id == 0) { reg_val = mctl_read_w(RTC_REG_BASE + 0x20c); reg_val |= 0x01; mctl_write_w(RTC_REG_BASE + 0x20c,reg_val); reg_val = mctl_read_w(RTC_REG_BASE + 0x20c); if(reg_val & 0x01){ return MAGIC_VER_A31A; } else { return MAGIC_VER_A31B; } } else if(id == 1) return MAGIC_VER_A31S; else if(id == 2) return MAGIC_VER_A3XP; else return MAGIC_VER_UNKNOWN; }
/* ********************************************************************************************************* * DRAM INIT * * Description: dram init function * * Arguments : para dram config parameter * * * Returns : result * * Note : ********************************************************************************************************* */ void mctl_ddr3_reset(void) { __u32 reg_val; __u32 i=0; mctl_write_w(TIMER_CPU_CFG_REG, 0); reg_val = mctl_read_w(TIMER_CPU_CFG_REG); reg_val >>=6; reg_val &=0x3; if(reg_val == 0) { reg_val = mctl_read_w(SDR_CR); reg_val &= ~(0x1<<12); mctl_write_w(SDR_CR, reg_val); standby_delay(0x100); reg_val = mctl_read_w(SDR_CR); reg_val |= (0x1<<12); mctl_write_w(SDR_CR, reg_val); } else { reg_val = mctl_read_w(SDR_CR); reg_val |= (0x1<<12); mctl_write_w(SDR_CR, reg_val); standby_delay(0x100); reg_val = mctl_read_w(SDR_CR); reg_val &= ~(0x1<<12); mctl_write_w(SDR_CR, reg_val); } }
void mctl_disable_dll(void) { __u32 reg_val; reg_val = mctl_read_w(SDR_DLLCR0); reg_val &= ~(0x1<<30); reg_val |= 0x1U<<31; mctl_write_w(SDR_DLLCR0, reg_val); reg_val = mctl_read_w(SDR_DLLCR1); reg_val &= ~(0x1<<30); reg_val |= 0x1U<<31; mctl_write_w(SDR_DLLCR1, reg_val); reg_val = mctl_read_w(SDR_DLLCR2); reg_val &= ~(0x1<<30); reg_val |= 0x1U<<31; mctl_write_w(SDR_DLLCR2, reg_val); reg_val = mctl_read_w(SDR_DLLCR3); reg_val &= ~(0x1<<30); reg_val |= 0x1U<<31; mctl_write_w(SDR_DLLCR3, reg_val); reg_val = mctl_read_w(SDR_DLLCR4); reg_val &= ~(0x1<<30); reg_val |= 0x1U<<31; mctl_write_w(SDR_DLLCR4, reg_val); }
void DRAMC_exit_selfrefresh(void) { __u32 i; __u32 reg_val; //exit self-refresh state mctl_mode_exit(); //issue a refresh command reg_val = mctl_read_w(SDR_DCR); reg_val &= ~(0x1fU<<27); reg_val |= 0x13U<<27; mctl_write_w(SDR_DCR, reg_val); while( mctl_read_w(SDR_DCR)& (0x1U<<31) ); standby_delay(0x100); //enable auto-fresh reg_val = mctl_read_w(SDR_DRR); reg_val &= ~(0x1U<<31); mctl_write_w(SDR_DRR, reg_val); //enable all port for(i=0; i<31; i++) { DRAMC_hostport_on_off(i, 0x1); } }
uint32 mctl_sys_init(void) { uint32 reg_val; //PLL5 enable reg_val = mctl_read_w(CCU_PLL5CFG); reg_val |= 0x1U<<31; reg_val |= 0x1U<<20; mctl_write_w(CCU_PLL5CFG, reg_val); #ifndef SYSTEM_SIMULATION aw_delay(0x20); #endif //MDFS clock enable reg_val = mctl_read_w(CCU_MDFS_CLK); reg_val |= 0x1U<<31; mctl_write_w(CCU_MDFS_CLK, reg_val); //select DRAM clock reg_val = mctl_read_w(CCU_MDFS_CFG); reg_val |= 0x1U<<16; mctl_write_w(CCU_MDFS_CFG, reg_val); //release DRAMC register reset reg_val = mctl_read_w(CCU_AHB1_RST); reg_val |= 0x1<<14; mctl_write_w(CCU_AHB1_RST, reg_val); //DRAMC AHB clok on reg_val = mctl_read_w(CCU_AHBGATE0); reg_val |= 0x1<<14; mctl_write_w(CCU_AHBGATE0, reg_val); return (1); }
void DRAMC_enter_selfrefresh(void) { __u32 i; __u32 reg_val; //disable all port for(i=0; i<31; i++) { DRAMC_hostport_on_off(i, 0x0); } /* //disable auto-fresh reg_val = mctl_read_w(SDR_DRR); reg_val |= 0x1U<<31; mctl_write_w(SDR_DRR, reg_val); */ //issue prechage all command mctl_precharge_all(); //enter into self-refresh reg_val = mctl_read_w(SDR_DCR); reg_val &= ~(0x1fU<<27); reg_val |= 0x12U<<27; mctl_write_w(SDR_DCR, reg_val); while( mctl_read_w(SDR_DCR)& (0x1U<<31) ); standby_delay(0x100); //dram pad odt hold mctl_write_w(SDR_DPCR, 0x1); }
/* ********************************************************************************************************* * DRAM INIT * * Description: dram init function * * Arguments : para dram config parameter * * * Returns : result * * Note : ********************************************************************************************************* */ void mctl_ddr3_reset(void) { __u32 reg_val; #ifdef CONFIG_ARCH_SUN4I __u32 i=0; mctl_write_w(TIMER_CPU_CFG_REG, 0); reg_val = mctl_read_w(TIMER_CPU_CFG_REG); reg_val >>=6; reg_val &=0x3; if(reg_val == 0) { #endif reg_val = mctl_read_w(SDR_CR); reg_val &= ~(0x1<<12); mctl_write_w(SDR_CR, reg_val); standby_delay(0x100); reg_val = mctl_read_w(SDR_CR); reg_val |= (0x1<<12); mctl_write_w(SDR_CR, reg_val); #ifdef CONFIG_ARCH_SUN4I } else { reg_val = mctl_read_w(SDR_CR); reg_val |= (0x1<<12); mctl_write_w(SDR_CR, reg_val); standby_delay(0x100); reg_val = mctl_read_w(SDR_CR); reg_val &= ~(0x1<<12); mctl_write_w(SDR_CR, reg_val); } #endif }
void DRAMC_enter_selfrefresh(void) { __u32 reg_val; // //disable all port // for(i=0; i<31; i++) // { // DRAMC_hostport_on_off(i, 0x0); // } // for(i=0; i<8; i++) // { // mctl_write_w(SDR_HPCR + (i<<2), 0); // } // // for(i=16; i<28; i++) // { // mctl_write_w(SDR_HPCR + (i<<2), 0); // } // // mctl_write_w(SDR_HPCR + (29<<2), 0); // mctl_write_w(SDR_HPCR + (31<<2), 0); /* //disable auto-fresh reg_val = mctl_read_w(SDR_DRR); reg_val |= 0x1U<<31; mctl_write_w(SDR_DRR, reg_val); */ //issue prechage all command // mctl_precharge_all(); //disable auto-fresh //by cpl 2013-5-6 reg_val = mctl_read_w(SDR_DRR); reg_val |= 0x1U<<31; mctl_write_w(SDR_DRR, reg_val); //enter into self-refresh reg_val = mctl_read_w(SDR_DCR); reg_val &= ~(0x1fU<<27); reg_val |= 0x12U<<27; mctl_write_w(SDR_DCR, reg_val); while( mctl_read_w(SDR_DCR)& (0x1U<<31) ); standby_delay(0x100); reg_val = mctl_read_w(SDR_CR); reg_val &= ~(0x3<<28); reg_val |= 0x2<<28; mctl_write_w(SDR_CR, reg_val); //dram pad odt hold mctl_write_w(SDR_DPCR, 0x16510001); while(!(mctl_read_w(SDR_DPCR) & 0x1)); standby_delay(0x100); }
*/ void mctl_ddr3_reset(void) { __u32 reg_val; reg_val = mctl_read_w(SDR_CR); reg_val &= ~(0x1<<12); mctl_write_w(SDR_CR, reg_val); mctl_delay(0x100); reg_val = mctl_read_w(SDR_CR); reg_val |= (0x1<<12); mctl_write_w(SDR_CR, reg_val);
void mctl_enable_dll0(void) { __u32 i = 0; mctl_write_w(SDR_DLLCR0, mctl_read_w(SDR_DLLCR0) & ~0x40000000 | 0x80000000); standby_delay(0x100); mctl_write_w(SDR_DLLCR0, mctl_read_w(SDR_DLLCR0) & ~0xC0000000); standby_delay(0x1000); mctl_write_w(SDR_DLLCR0, mctl_read_w(SDR_DLLCR0) & ~0x80000000 | 0x40000000); standby_delay(0x1000); }
/* ********************************************************************************************************* * DRAM ENTER SELF REFRESH * * Description: dram enter/exit self-refresh; * * Arguments : none * * Returns : none * * Note : ********************************************************************************************************* */ void mctl_precharge_all(void) { __u32 reg_val; reg_val = mctl_read_w(SDR_DCR); reg_val &= ~(0x1fU<<27); reg_val |= 0x15U<<27; mctl_write_w(SDR_DCR, reg_val); //check whether command has been executed while( mctl_read_w(SDR_DCR)& (0x1U<<31) ); standby_delay(0x100); }
static void disable_ss_clk(void) { uint32 reg_val; //disable SS working clock reg_val = mctl_read_w(CCMU_REG_BASE + 0x9C); //CCM_SS_SCLK_CTRL reg_val &= ~(0x1<<31); mctl_write_w(CCMU_REG_BASE + 0x9C, reg_val); //disable SS AHB clock reg_val = mctl_read_w(CCMU_REG_BASE + 0x60); //CCM_AHB1_GATE0_CTRL reg_val &= ~(0x1<<5); //SS AHB clock on mctl_write_w(CCMU_REG_BASE + 0x60, reg_val); }
/* ********************************************************************************************************* * DRAM POWER DOWN * * Description: enter/exit dram power down state * * Arguments : * * Returns : none; * * Note : ********************************************************************************************************* */ void DRAMC_enter_power_down(void) { __u32 i; __u32 reg_val; reg_val = mctl_read_w(SDR_DCR); reg_val &= ~(0x1fU<<27); reg_val |= 0x1eU<<27; mctl_write_w(SDR_DCR, reg_val); //check whether command has been executed while( mctl_read_w(SDR_DCR)& (0x1U<<31) ); standby_delay(0x100); }
void mctl_itm_enable(void) { __u32 reg_val = 0x0; reg_val = mctl_read_w(SDR_CCR); reg_val &= ~(0x1<<28); mctl_write_w(SDR_CCR, reg_val);
void mctl_itm_disable(void) { __u32 reg_val = 0x0; reg_val = mctl_read_w(SDR_CCR); reg_val |= 0x1<<28; mctl_write_w(SDR_CCR, reg_val); }
uint32 mctl_port_cfg(void) { uint32 reg_val; //enable DRAM AXI clock for CPU access reg_val = mctl_read_w(CCU_AXIGATE); reg_val |= 0x1; mctl_write_w(CCU_AXIGATE, reg_val); return (1); }
void mctl_itm_disable(void) { __u32 reg_val = 0x0; reg_val = mctl_read_w(SDR_CCR); reg_val |= 0x1<<28; reg_val &= ~(0x1U<<31); //danielwang, 2012-05-18 mctl_write_w(SDR_CCR, reg_val);
/* ********************************************************************************************************************** * DRAM GET HOSTPORT STATUS * * Description: dram get AHB FIFO status * * Arguments : __u32 port_idx host port index (0,1,...31) * * Returns : __u32 ret_val AHB FIFO status (0: FIFO not empty ,1: FIFO empty) * * Notes : * ********************************************************************************************************************** */ __u32 DRAMC_hostport_check_ahb_fifo_status(__u32 port_idx) { __u32 reg_val; if(port_idx<=31) { reg_val = mctl_read_w(SDR_CFSR); return ( (reg_val>>port_idx)&0x1 ); }
void mctl_set_drive(void) { __u32 reg_val; reg_val = mctl_read_w(SDR_CR); reg_val |= (0x6<<12); reg_val |= 0xFFC; reg_val &= ~0x3; mctl_write_w(SDR_CR, reg_val); }
int dram_enter_self_refresh(void) { unsigned int reg_val; mctl_self_refresh_entry(0); if(mctl_read_w(SDR_COM_CR) & (0x1<<19)) { mctl_self_refresh_entry(1); } //PLL5 disable reg_val = mctl_read_w(CCM_PLL5_DDR_CTRL); reg_val &= ~(0x1U<<31); mctl_write_w(CCM_PLL5_DDR_CTRL, reg_val); //PLL5 configuration update(validate PLL5) reg_val = mctl_read_w(CCM_PLL5_DDR_CTRL); reg_val |= 0x1U<<20; mctl_write_w(CCM_PLL5_DDR_CTRL, reg_val); mctl_write_w(0 + SDR_ACDLLCR,0xC0000000); mctl_write_w(0 + SDR_DX0DLLCR,0xC0000000); mctl_write_w(0 + SDR_DX1DLLCR,0xC0000000); mctl_write_w(0 + SDR_DX2DLLCR,0xC0000000); mctl_write_w(0 + SDR_DX3DLLCR,0xC0000000); if(mctl_read_w(SDR_COM_CR) & (0x1<<19)) { mctl_write_w(0x1000 + SDR_ACDLLCR,0xC0000000); mctl_write_w(0x1000 + SDR_DX0DLLCR,0xC0000000); mctl_write_w(0x1000 + SDR_DX1DLLCR,0xC0000000); mctl_write_w(0x1000 + SDR_DX2DLLCR,0xC0000000); mctl_write_w(0x1000 + SDR_DX3DLLCR,0xC0000000); } return 0; }
static void enable_ss_clk(void) { uint32 reg_val; //enable SS working clock reg_val = mctl_read_w(CCMU_REG_BASE + 0x9C); //CCM_SS_SCLK_CTRL //24MHz reg_val &= ~(0x3<<24); reg_val &= ~(0x3<<16); reg_val &= ~(0xf); reg_val |= 0x0<<16; reg_val |= 0; reg_val |= 0x1U<<31; mctl_write_w(CCMU_REG_BASE + 0x9C, reg_val); //enable SS AHB clock reg_val = mctl_read_w(CCMU_REG_BASE + 0x60); //CCM_AHB1_GATE0_CTRL reg_val |= 0x1<<5; //SS AHB clock on mctl_write_w(CCMU_REG_BASE + 0x60, reg_val); }
/* ********************************************************************************************************* * CHECK DDR READPIPE * * Description: check ddr readpipe; * * Arguments : none * * Returns : result, 0:fail, 1:success; * * Note : ********************************************************************************************************* */ __s32 DRAMC_scan_readpipe(void) { __u32 reg_val; //data training trigger reg_val = mctl_read_w(SDR_CCR); reg_val |= 0x1<<30; mctl_write_w(SDR_CCR, reg_val); //check whether data training process is end while(mctl_read_w(SDR_CCR) & (0x1<<30)) {}; //check data training result reg_val = mctl_read_w(SDR_CSR); if(reg_val & (0x1<<20)) { return -1; } return (0); }
uint32 mctl_reset_release(void) { uint32 reg_val; reg_val = mctl_read_w(CCU_MDFS_CFG); reg_val |= 0x1U<<31; mctl_write_w(CCU_MDFS_CFG, reg_val); #ifndef SYSTEM_SIMULATION aw_delay(0x20); #endif return (1); }
/* ********************************************************************************************************* * DRAM CLOCK CONTROL * * Description: dram get clock * * Arguments : on dram clock output (0: disable, 1: enable) * * Returns : none * * Note : ********************************************************************************************************* */ void DRAMC_clock_output_en(__u32 on) { __u32 reg_val; reg_val = mctl_read_w(DRAM_CCM_SDRAM_CLK_REG); if(on) reg_val |= 0x1<<15; else reg_val &= ~(0x1<<15); mctl_write_w(DRAM_CCM_SDRAM_CLK_REG, reg_val); }
/* ********************************************************************************************************************** * DRAM HOSTPORT CONTROL * * Description: dram host port enable/ disable * * Arguments : __u32 port_idx host port index (0,1,...31) * __u32 on enable or disable (0: diable, 1: enable) * * Returns : * * Notes : * ********************************************************************************************************************** */ void DRAMC_hostport_on_off(__u32 port_idx, __u32 on) { __u32 reg_val; if(port_idx<=31) { reg_val = mctl_read_w(SDR_HPCR + (port_idx<<2)); if(on) reg_val |= 0x1; else reg_val &= ~(0x1); mctl_write_w(SDR_HPCR + (port_idx<<2), reg_val); } }
void mctl_enable_dllx(void) { __u32 i = 0; for(i=1; i<5; i++) { mctl_write_w(SDR_DLLCR0+(i<<2), mctl_read_w(SDR_DLLCR0+(i<<2)) & ~0x40000000 | 0x80000000); } standby_delay(0x100); for(i=1; i<5; i++) { mctl_write_w(SDR_DLLCR0+(i<<2), mctl_read_w(SDR_DLLCR0+(i<<2)) & ~0xC0000000); } standby_delay(0x1000); for(i=1; i<5; i++) { mctl_write_w(SDR_DLLCR0+(i<<2), mctl_read_w(SDR_DLLCR0+(i<<2)) & ~0x80000000 | 0x40000000); } standby_delay(0x1000); }
//***************************************************************************** // void mctl_self_refresh_exit() // Description: Exit from self refresh state to active state // // Arguments: // // Return Value: 1: Success 0: Fail //***************************************************************************** void mctl_self_refresh_exit(uint32 channel_num) { uint32 reg_val; uint32 ch_id; if(channel_num == 1) ch_id = 0x1000; else ch_id = 0x0; //set SLEEP command reg_val = 0x4; mctl_write_w(ch_id + SDR_SCTL, reg_val); //check whether in Low Power State while( (mctl_read_w(ch_id + SDR_SSTAT)&0x7) != 0x3 ) {}; }
uint32 mctl_com_init(uint32 channel_num) { uint32 reg_val; //set COM memory organization register reg_val = 0; if(MCTL_CS_NUM == 2) reg_val |= 0x1; if(MCTL_BANK_SIZE==8) reg_val |= 0x1<<2; reg_val |= ((MCTL_ROW_WIDTH -1)&0xf)<<4; if(MCTL_PAGE_SIZE == 8) reg_val |= 0xa<<8; else if(MCTL_PAGE_SIZE == 4) reg_val |= 0x9<<8; else if(MCTL_PAGE_SIZE == 2) reg_val |= 0x8<<8; else if(MCTL_PAGE_SIZE == 1) reg_val |= 0x7<<8; else reg_val |= 0x6<<8; if(MCTL_BUS_WIDTH == 32) reg_val |= 0x3<<12; else reg_val |= 0x1<<12; if(MCTL_ACCESS_MODE == 0) reg_val |= 0x1<<15; reg_val |= MCTL_DDR_TYPE<<16; if(channel_num == 2) reg_val |= 0x1<<19; reg_val |= 0x1<<20; mctl_write_w(SDR_COM_CR, reg_val); #ifdef FPGA_PLATFORM //set preset readpipe value reg_val = mctl_read_w(SDR_COM_CR)&0x3fffff; reg_val |= 0x9<<22; reg_val |= 0x9<<27; mctl_write_w(SDR_COM_CR, reg_val); #endif //set COM sclk enable register // reg_val = 0x7; // mctl_write_w(SDR_COM_CCR, reg_val); return (1); }
int dram_power_save_process(void) { unsigned int reg_val; //mctl_deep_sleep_entry(); mctl_self_refresh_entry(0); //printk("enter self refresh\n"); //if(MCTL_CHANNEL_NUM == 2) if(mctl_read_w(SDR_COM_CR) & (0x1<<19)) { mctl_self_refresh_entry(1); } //8x8; dram = 19.7mA; sys = 157.8mA //ITM reset mctl_write_w(0 + SDR_PIR, 0x11); if(mctl_read_w(SDR_COM_CR) & (0x1<<19)) mctl_write_w(0x1000 + SDR_PIR, 0x11); //turn off SCLK reg_val = mctl_read_w(SDR_COM_CCR); reg_val &= ~(0x7<<0); mctl_write_w(SDR_COM_CCR, reg_val); //turn off SDRPLL reg_val = mctl_read_w(SDR_COM_CCR); reg_val |= (0x3<<3); mctl_write_w(SDR_COM_CCR, reg_val); //8x8; dram = 20.3mA; sys = 83.4mA //gate off DRAMC AHB clk reg_val = mctl_read_w(CCM_AHB1_GATE0_CTRL); reg_val &=~(0x1<<14); mctl_write_w(CCM_AHB1_GATE0_CTRL, reg_val); //gate off DRAMC MDFS clk reg_val = mctl_read_w(CCM_MDFS_CLK_CTRL); reg_val &= ~(0x1U<<31); mctl_write_w(CCM_MDFS_CLK_CTRL, reg_val); //8x8; dram = 20.7mA; sys = 80.3mA //turn off PLL5 // reg_val = mctl_read_w(CCM_PLL5_DDR_CTRL); // reg_val &= ~(0x1U<<31); // mctl_write_w(CCM_PLL5_DDR_CTRL, reg_val); // // //PLL5 configuration update(validate PLL5) // reg_val = mctl_read_w(CCM_PLL5_DDR_CTRL); // reg_val |= 0x1U<<20; // mctl_write_w(CCM_PLL5_DDR_CTRL, reg_val); // // while(mctl_read_w(CCM_PLL5_DDR_CTRL) & (0x1U<<20)); return 0; }
void mctl_setup_dram_clock(__u32 clk) { __u32 i; __u32 reg_val; //setup DRAM PLL reg_val = mctl_read_w(DRAM_CCM_SDRAM_PLL_REG); reg_val &= ~0x3; reg_val |= 0x1; //m factor reg_val &= ~(0x3<<4); reg_val |= 0x1<<4; //k factor reg_val &= ~(0x1f<<8); reg_val |= (standby_uldiv((__u64)clk, 24)&0x1f)<<8; //n factor reg_val &= ~(0x3<<16); reg_val |= 0x1<<16; //p factor reg_val &= ~(0x1<<29); //PLL on reg_val |= (__u32)0x1<<31; //PLL En mctl_write_w(DRAM_CCM_SDRAM_PLL_REG, reg_val); standby_delay(0x100000); reg_val = mctl_read_w(DRAM_CCM_SDRAM_PLL_REG); reg_val |= 0x1<<29; mctl_write_w(DRAM_CCM_SDRAM_PLL_REG, reg_val); //reset GPS reg_val = mctl_read_w(DRAM_CCM_GPS_CLK_REG); reg_val &= ~0x3; mctl_write_w(DRAM_CCM_GPS_CLK_REG, reg_val); reg_val = mctl_read_w(DRAM_CCM_AHB_GATE_REG); reg_val |= (0x1<<26); mctl_write_w(DRAM_CCM_AHB_GATE_REG, reg_val); standby_delay(0x20); reg_val = mctl_read_w(DRAM_CCM_AHB_GATE_REG); reg_val &= ~(0x1<<26); mctl_write_w(DRAM_CCM_AHB_GATE_REG, reg_val); //open DRAMC AHB clock //close it first reg_val = mctl_read_w(DRAM_CCM_AHB_GATE_REG); reg_val &= ~(0x1<<14); mctl_write_w(DRAM_CCM_AHB_GATE_REG, reg_val); standby_delay(0x1000); //then open it reg_val |= 0x1<<14; mctl_write_w(DRAM_CCM_AHB_GATE_REG, reg_val); standby_delay(0x1000); }