/** * CP hold procedure * 1. acquire fc mutex * 2. stop watchdog * 3. set bit CPR of register APRR to hold CP in reset * 4. set bits DSPR, BBR and DSRAMINT of register CPRR to hold MSA in reset * 5. wait several us * 6. mask bits CP_CLK_OFF_ACK, CP_HALT of register APMU_DEBUG to * disable ACK from CP * 7. release fc mutex */ void cp_holdcp(void) { int value; u8 apmu_debug; acquire_fc_mutex(); printk("%s: acquire fc mutex\n", __func__); watchDogCountStop(); printk("hold cp..."); value = __raw_readl(MPMU_APRR) | MPMU_APRR_CPR; //set CPR(bit[0]) bit of APRR register high __raw_writel(value, MPMU_APRR); printk("done!\n"); printk("hold msa..."); value = __raw_readl(MPMU_CPRR); value |= MPMU_CPRR_DSPR | MPMU_CPRR_BBR | MPMU_CPRR_DSRAMINT; //set DSPR(bit[2]), BBR(bit[3]) and DSRAMINT(bit[5]) bits of CPRR register high __raw_writel(value, MPMU_CPRR); printk("done!\n"); //recommended software wait several us after hold CP/MSA in reset status and then start load the new image //TODO: accurate the wait time udelay(100); /* * mask CP_CLK_OFF_ACK and CP_HALT */ printk("%s: mask cp halt and cp clk off ack bit\n", __func__); apmu_debug = __raw_readb(APMU_DEBUG); printk("%s: APMU_DEBUG before %02x\n", __func__, apmu_debug); apmu_debug |= (APMU_DEBUG_CP_HALT | APMU_DEBUG_CP_CLK_OFF_ACK); __raw_writeb(apmu_debug, APMU_DEBUG); printk("%s: APMU_DEBUG after %02x\n", __func__, __raw_readb(APMU_DEBUG)); release_fc_mutex(); printk("%s: release fc mutex\n", __func__); }
WATCHDOG_HW_RETURN_CODE watchDogDeactive(void) { unsigned int wvc0, wvc1, match,wmer; wvc0 = readl(comm_timer_base_addr + TMR_WVR); wvc1 = readl(comm_timer_base_addr + TMR_WVR); match = readl(comm_timer_base_addr + TMR_WMR); printk("Watch Value Before stop_2:%x %x match=%x\n",wvc0,wvc1,match); watchDogCountStop();//watchdog count stop watchDogInterruptClear(); watchDogHWKick(); disable_irq_nosync(IRQ_COMM_WDT_ID); wvc0 = readl(comm_timer_base_addr + TMR_WVR); wvc1 = readl(comm_timer_base_addr + TMR_WVR); match = readl(comm_timer_base_addr + TMR_WMR); wmer = readl(comm_timer_base_addr + TMR_WMER); printk("Watch Value After stop_2:%x %x match=%x wmer=%x\n",wvc0,wvc1,match, wmer); return SUCCESSFUL; }