void mmc_wakeup(void) { int stat; stat = APB_Rd(MMC_LP_CTRL1); serial_put_hex(stat,32); f_serial_puts("MMC_LP_CTRL1\n"); wait_uart_empty(); stat = APB_Rd(MMC_CLK_CNTL); serial_put_hex(stat,32); f_serial_puts("MMC_CLK_CNTL\n"); wait_uart_empty(); do { stat = APB_Rd(UPCTL_STAT_ADDR); stat &= 0x7; if(stat == UPCTL_STAT_LOW_POWER) { APB_Wr(UPCTL_SCTL_ADDR, SCTL_CMD_WAKEUP); //while(stat != UPCTL_STAT_LOW_POWER); } else if(stat == UPCTL_STAT_INIT) { APB_Wr(UPCTL_SCTL_ADDR, SCTL_CMD_CONFIG); //while(stat != UPCTL_STAT_CONFIG); } else if(stat == UPCTL_STAT_CONFIG) { APB_Wr(UPCTL_SCTL_ADDR, SCTL_CMD_GO); //while(stat != UPCTL_STAT_ACCESS); } stat = APB_Rd(UPCTL_STAT_ADDR); stat &= 0x7; } while(stat != UPCTL_STAT_ACCESS); }
void reset_mmc(void) { // writel((1 <<3), P_RESET1_REGISTER); // reset the whole MMC modules. #ifdef POWER_DOWN_DDRPHY APB_Wr(MMC_SOFT_RST, 0x0); // keep all MMC submodules in reset mode. #endif //Enable DDR DLL clock input from PLL. writel(0xc0000080, P_MMC_CLK_CNTL); // @@@ select the final mux from PLL output directly. writel(0xc00000c0, P_MMC_CLK_CNTL); //enable the clock. writel(0x400000c0, P_MMC_CLK_CNTL); __udelay(10); // wait clock stable //reset all sub module APB_Wr(MMC_SOFT_RST, 0x0); while((APB_Rd(MMC_RST_STS)&0xffff) != 0x0); //deseart all reset. APB_Wr(MMC_SOFT_RST, 0xffff); while((APB_Rd(MMC_RST_STS)&0xffff) != 0xffff); __udelay(100); // wait DLL lock. }
void disable_mmc_req(void) { APB_Wr(MMC_REQ_CTRL,0X0); while(APB_Rd(MMC_CHAN_STS) == 0){ __udelay(100); } }
void mmc_sleep(void) { int stat; do { stat = APB_Rd(UPCTL_STAT_ADDR); stat &= 0x7; if(stat == UPCTL_STAT_INIT) { APB_Wr(UPCTL_SCTL_ADDR, SCTL_CMD_CONFIG); } else if(stat == UPCTL_STAT_CONFIG) { APB_Wr(UPCTL_SCTL_ADDR, SCTL_CMD_GO); } else if(stat == UPCTL_STAT_ACCESS) { APB_Wr(UPCTL_SCTL_ADDR, SCTL_CMD_SLEEP); } }while(stat != UPCTL_STAT_LOW_POWER); }
void enter_power_down() { int i; unsigned v1,v2,v; unsigned rtc_ctrl; unsigned power_key; //******************************************* //* power down flow //******************************************* f_serial_puts("\n"); wait_uart_empty(); // disable jtag setbits_le32(P_AO_RTI_PIN_MUX_REG, 1<<13); clrbits_le32(P_AO_RTI_PIN_MUX_REG, 1<<14); // turn off mali clock clrbits_le32(P_HHI_MALI_CLK_CNTL, 1 << 8); // disable all memory accesses. disable_mmc_req(); //save registers for clk and ddr store_restore_plls(1); //mmc enter sleep mmc_sleep(); // delay_ms(20); // save ddr power APB_Wr(MMC_PHY_CTRL, APB_Rd(MMC_PHY_CTRL)|(1<<0)|(1<<8)|(1<<13)); APB_Wr(PCTL_PHYCR_ADDR, APB_Rd(PCTL_PHYCR_ADDR)|(1<<6)); APB_Wr(PCTL_DLLCR9_ADDR, APB_Rd(PCTL_DLLCR9_ADDR)|(1<<31)); // delay_ms(20); // power down DDR writel(readl(P_HHI_DDR_PLL_CNTL)|(1<<15),P_HHI_DDR_PLL_CNTL); // enable retention enable_retention(); writel(0,P_AO_RTI_STATUS_REG1); // reset A9 // setbits_le32(P_A9_CFG2, 7<<16); clrbits_le32(P_HHI_SYS_CPU_CLK_CNTL, 1<<4); // disable APB_CLK clrbits_le32(P_HHI_SYS_CPU_CLK_CNTL, 1<<5); // disable AT_CLK setbits_le32(P_HHI_SYS_CPU_CLK_CNTL,1<<19); udelay(10); // enable iso ee for A9 writel(readl(P_AO_RTI_PWR_CNTL_REG0)&(~(1<<4)),P_AO_RTI_PWR_CNTL_REG0); udelay(1000); #ifdef POWER_OFF_HDMI_VCC reg7_off(); #endif #ifdef POWER_OFF_AVDD33 reg5_off(); #endif #ifdef POWER_OFF_EE //iso EE from AO //comment isolate EE. otherwise cannot detect power key. // writel(readl(P_AO_RTI_PWR_CNTL_REG0)&(~(1<<0)),P_AO_RTI_PWR_CNTL_REG0); writel(readl(P_AO_RTI_PWR_CNTL_REG0)&(~(1<<2)),P_AO_RTI_PWR_CNTL_REG0); writel(readl(P_AO_RTI_PWR_CNTL_REG0)&(~(1<<3)),P_AO_RTI_PWR_CNTL_REG0); //?? Gate off clk81 to EE domain writel(readl(P_AO_RTI_GEN_CNTL_REG0)&(~(1<<12)),P_AO_RTI_GEN_CNTL_REG0); //------------------------------- //turn off EE voltage //v = readl(0xC8100024); //v &= ~(1<<9); //v &= ~(1<<25); //writel(v,0xC8100024); #else // ee use 32k writel(readl(P_HHI_MPEG_CLK_CNTL)|(1<<9),P_HHI_MPEG_CLK_CNTL); #endif // change RTC filter for 32k rtc_ctrl = readl(0xC810074c); //writel(0x00800000,0xC810074c); writel(0,0xC810074c); // switch to 32k writel(readl(P_AO_RTI_PWR_CNTL_REG0)|(1<<8),P_AO_RTI_PWR_CNTL_REG0); udelay(100); #ifdef POWER_OFF_VDDIO vddio_off(); #endif #ifdef POWER_OFF_AVDD25 reg6_off(); #endif #ifdef POWER_OFF_VCC power_off_VCC(0); #endif udelay(100); #if (defined(POWER_DOWN_VCC12) || defined(POWER_DOWN_DDR)) switch_voltage(1); #endif #ifdef POWER_DOWN_DDR powerdown_ddr(); #endif #ifdef POWER_DOWN_VCC12 powerdown_vcc12(); #endif // gate off REMOTE, UART //writel(readl(P_AO_RTI_GEN_CNTL_REG0)&(~(0xF)),P_AO_RTI_GEN_CNTL_REG0); // wait key #if 1 //backup the remote config (on arm) backup_remote_register(); //set the ir_remote to 32k mode at ARC init_custom_trigger(); //set the detect gpio //setbits_le32(P_AO_GPIO_O_EN_N,(1<<3)); while(1) { //detect remote key power_key=readl(P_AO_IR_DEC_FRAME); if(power_key==0xf50a7748) break; //detect IO key /*power_key=readl(P_AO_GPIO_I); power_key=power_key&(1<<3); if(!power_key) break; */ #ifdef RTC_AUTO_WAKE_UP power_key = readl(0xc8100744); if((power_key&8) != 0) break; #endif } #elif 1 power_key = readl(0Xc8100744); while (((power_key&4) != 0)&&((power_key&8) == 0)) { power_key = readl(0Xc8100744); } #else for(i=0;i<64;i++) { udelay(1000); //udelay(1000); } #endif // gate on REMOTE, I2C s/m, UART //writel(readl(P_AO_RTI_GEN_CNTL_REG0)|0xF, P_AO_RTI_GEN_CNTL_REG0); udelay(10); #ifdef POWER_DOWN_DDR powerup_ddr(); #endif #ifdef POWER_DOWN_VCC12 powerup_vcc12(); #endif #if (defined(POWER_DOWN_VCC12) || defined(POWER_DOWN_DDR)) switch_voltage(0); #endif #ifdef POWER_OFF_VCC power_off_VCC(1); #endif #ifdef POWER_OFF_AVDD25 reg6_on(); #endif #ifdef POWER_OFF_VDDIO vddio_on(); #endif udelay(100); // switch to clk81 writel(readl(P_AO_RTI_PWR_CNTL_REG0)&(~(0x1<<8)),P_AO_RTI_PWR_CNTL_REG0); udelay(100); // restore RTC filter writel(rtc_ctrl,0xC810074c); // set AO interrupt mask writel(0xFFFF,P_AO_IRQ_STAT_CLR); #ifdef POWER_OFF_EE //turn on EE voltage //v = readl(0xC8100024); //v &= ~(1<<9); //v |= (1<<25); //writel(v,0xC8100024); //delay_ms(200); // un-iso AO domain from EE bit0=signals, bit1=reset, bit2=irq, bit3=test_mode writel(readl(P_AO_RTI_PWR_CNTL_REG0)|(0xD<<0),P_AO_RTI_PWR_CNTL_REG0); //un isolate the reset in the EE writel(readl(P_AO_RTI_PWR_CNTL_REG0)|(0x1<<5),P_AO_RTI_PWR_CNTL_REG0); writel(readl(P_AO_RTI_PWR_CNTL_REG0)|(0x1<<5)|(1<<3)|(1<<2)|(1<<1)|(1<<0), \ P_AO_RTI_PWR_CNTL_REG0); #else // ee go back to clk81 writel(readl(P_HHI_MPEG_CLK_CNTL)&(~(0x1<<9)),P_HHI_MPEG_CLK_CNTL); #endif #ifdef POWER_OFF_AVDD33 reg5_on(); #endif #ifdef POWER_OFF_HDMI_VCC reg7_on(); #endif store_restore_plls(0); init_ddr_pll(); udelay(1000); uart_reset(); reset_mmc(); // initialize mmc and put it to sleep init_pctl(); mmc_sleep(); // disable retention disable_retention(); // Next, we wake up mmc_wakeup(); // Next, we enable all requests enable_mmc_req(); // f_serial_puts("restart arm...\n"); //0. make sure a9 reset setbits_le32(P_A9_CFG2,1<<17); // release APB reset udelay(1000); setbits_le32(P_A9_CFG2,1<<16); // release AXI reset udelay(1000); setbits_le32(P_A9_CFG2,1<<18); // release A9DBG reset udelay(1000); setbits_le32(P_HHI_SYS_CPU_CLK_CNTL,1<<19); udelay(1000); //1. write flag if (power_key&8) writel(0xabcd1234,P_AO_RTI_STATUS_REG2); else writel(0x1234abcd,P_AO_RTI_STATUS_REG2); //2. remap AHB SRAM writel(3,P_AO_REMAP_REG0); writel(2,P_AHB_ARBDEC_REG); //3. turn off romboot clock writel(readl(P_HHI_GCLK_MPEG1)&0x7fffffff,P_HHI_GCLK_MPEG1); //4. Release ISO for A9 domain. setbits_le32(P_AO_RTI_PWR_CNTL_REG0,1<<4); udelay(1000); writel( (0 << 9) | // select xtal as clock source (0 << 0) , P_HHI_MALI_CLK_CNTL); delay_ms(1); setbits_le32(P_HHI_SYS_CPU_CLK_CNTL, (1<<14)|(1<<15)); // soft reset udelay(10); clrbits_le32(P_HHI_SYS_CPU_CLK_CNTL, (1<<14)|(1<<15)); // soft reset udelay(1000); //reset A9 writel(0xF,P_RESET4_REGISTER);// -- reset arm.ww writel(1<<14,P_RESET2_REGISTER);// -- reset arm.mali udelay(1000); clrbits_le32(P_A9_CFG2,1<<17); // release APB reset udelay(1000); clrbits_le32(P_A9_CFG2,1<<16); // release AXI reset udelay(1000); clrbits_le32(P_A9_CFG2,1<<18); // release A9DBG reset udelay(1000); setbits_le32(P_HHI_SYS_CPU_CLK_CNTL, 1<<4); // enable APB_CLK udelay(10); clrbits_le32(P_HHI_SYS_CPU_CLK_CNTL,1<<19); // release A9 reset udelay(1000); //reset the IR REMOTE resume_remote_register(); // delay_1s(); // delay_1s(); // delay_1s(); }
void power_down_ddr_phy(void) { APB_Wr(PUB_DXCCR_ADDR,APB_Rd(PUB_DXCCR_ADDR)|(3<<2)); APB_Wr(PUB_DX0GCR_ADDR,APB_Rd(PUB_DX0GCR_ADDR)|(7<<4)); APB_Wr(PUB_DX1GCR_ADDR,APB_Rd(PUB_DX1GCR_ADDR)|(7<<4)); APB_Wr(PUB_DX2GCR_ADDR,APB_Rd(PUB_DX2GCR_ADDR)|(7<<4)); APB_Wr(PUB_DX3GCR_ADDR,APB_Rd(PUB_DX3GCR_ADDR)|(7<<4)); APB_Wr(PUB_DX4GCR_ADDR,APB_Rd(PUB_DX4GCR_ADDR)|(7<<4)); APB_Wr(PUB_DX5GCR_ADDR,APB_Rd(PUB_DX5GCR_ADDR)|(7<<4)); APB_Wr(PUB_DX6GCR_ADDR,APB_Rd(PUB_DX6GCR_ADDR)|(7<<4)); APB_Wr(PUB_DX7GCR_ADDR,APB_Rd(PUB_DX7GCR_ADDR)|(7<<4)); APB_Wr(PUB_DLLGCR_ADDR,APB_Rd(PUB_DLLGCR_ADDR)|(7<<2)); //ACDLLCR APB_Wr(PUB_ACDLLCR_ADDR,APB_Rd(PUB_ACDLLCR_ADDR)|(1<<31)); //ACIOCR APB_Wr(PUB_ACIOCR_ADDR,APB_Rd(PUB_ACIOCR_ADDR)|(1<<3)|(7<<8)); //DLLBYP APB_Wr(PUB_PIR_ADDR,APB_Rd(PUB_PIR_ADDR)|(1<<17)); }