17d116dccSCC Ma /* 27d116dccSCC Ma * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. 37d116dccSCC Ma * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 57d116dccSCC Ma */ 6*09d40e0eSAntonio Nino Diaz 7*09d40e0eSAntonio Nino Diaz #include <common/debug.h> 8*09d40e0eSAntonio Nino Diaz #include <lib/bakery_lock.h> 9*09d40e0eSAntonio Nino Diaz #include <lib/mmio.h> 10*09d40e0eSAntonio Nino Diaz 117d116dccSCC Ma #include <mt8173_def.h> 127d116dccSCC Ma #include <spm.h> 137d116dccSCC Ma #include <spm_suspend.h> 147d116dccSCC Ma 157d116dccSCC Ma /* 167d116dccSCC Ma * System Power Manager (SPM) is a hardware module, which controls cpu or 177d116dccSCC Ma * system power for different power scenarios using different firmware, i.e., 187d116dccSCC Ma * - spm_hotplug.c for cpu power control in cpu hotplug flow. 197d116dccSCC Ma * - spm_mcdi.c for cpu power control in cpu idle power saving state. 207d116dccSCC Ma * - spm_suspend.c for system power control in system suspend scenario. 217d116dccSCC Ma * 227d116dccSCC Ma * This file provide utility functions common to hotplug, mcdi(idle), suspend 237d116dccSCC Ma * power scenarios. A bakery lock (software lock) is incoporated to protect 247d116dccSCC Ma * certain critical sections to avoid kicking different SPM firmware 257d116dccSCC Ma * concurrently. 267d116dccSCC Ma */ 277d116dccSCC Ma 287d116dccSCC Ma #define SPM_SYSCLK_SETTLE 128 /* 3.9ms */ 297d116dccSCC Ma 30c3ec0b9eSVikram Kanigiri DEFINE_BAKERY_LOCK(spm_lock); 31c3ec0b9eSVikram Kanigiri 3265cd299fSSoren Brinkmann static int spm_hotplug_ready __section("tzfw_coherent_mem"); 3365cd299fSSoren Brinkmann static int spm_mcdi_ready __section("tzfw_coherent_mem"); 3465cd299fSSoren Brinkmann static int spm_suspend_ready __section("tzfw_coherent_mem"); 357d116dccSCC Ma 367d116dccSCC Ma void spm_lock_init(void) 377d116dccSCC Ma { 387d116dccSCC Ma bakery_lock_init(&spm_lock); 397d116dccSCC Ma } 407d116dccSCC Ma 417d116dccSCC Ma void spm_lock_get(void) 427d116dccSCC Ma { 437d116dccSCC Ma bakery_lock_get(&spm_lock); 447d116dccSCC Ma } 457d116dccSCC Ma 467d116dccSCC Ma void spm_lock_release(void) 477d116dccSCC Ma { 487d116dccSCC Ma bakery_lock_release(&spm_lock); 497d116dccSCC Ma } 507d116dccSCC Ma 517d116dccSCC Ma int is_mcdi_ready(void) 527d116dccSCC Ma { 537d116dccSCC Ma return spm_mcdi_ready; 547d116dccSCC Ma } 557d116dccSCC Ma 567d116dccSCC Ma int is_hotplug_ready(void) 577d116dccSCC Ma { 587d116dccSCC Ma return spm_hotplug_ready; 597d116dccSCC Ma } 607d116dccSCC Ma 617d116dccSCC Ma int is_suspend_ready(void) 627d116dccSCC Ma { 637d116dccSCC Ma return spm_suspend_ready; 647d116dccSCC Ma } 657d116dccSCC Ma 667d116dccSCC Ma void set_mcdi_ready(void) 677d116dccSCC Ma { 687d116dccSCC Ma spm_mcdi_ready = 1; 697d116dccSCC Ma spm_hotplug_ready = 0; 707d116dccSCC Ma spm_suspend_ready = 0; 717d116dccSCC Ma } 727d116dccSCC Ma 737d116dccSCC Ma void set_hotplug_ready(void) 747d116dccSCC Ma { 757d116dccSCC Ma spm_mcdi_ready = 0; 767d116dccSCC Ma spm_hotplug_ready = 1; 777d116dccSCC Ma spm_suspend_ready = 0; 787d116dccSCC Ma } 797d116dccSCC Ma 807d116dccSCC Ma void set_suspend_ready(void) 817d116dccSCC Ma { 827d116dccSCC Ma spm_mcdi_ready = 0; 837d116dccSCC Ma spm_hotplug_ready = 0; 847d116dccSCC Ma spm_suspend_ready = 1; 857d116dccSCC Ma } 867d116dccSCC Ma 877d116dccSCC Ma void clear_all_ready(void) 887d116dccSCC Ma { 897d116dccSCC Ma spm_mcdi_ready = 0; 907d116dccSCC Ma spm_hotplug_ready = 0; 917d116dccSCC Ma spm_suspend_ready = 0; 927d116dccSCC Ma } 937d116dccSCC Ma 947d116dccSCC Ma void spm_register_init(void) 957d116dccSCC Ma { 967d116dccSCC Ma mmio_write_32(SPM_POWERON_CONFIG_SET, SPM_REGWR_CFG_KEY | SPM_REGWR_EN); 977d116dccSCC Ma 987d116dccSCC Ma mmio_write_32(SPM_POWER_ON_VAL0, 0); 997d116dccSCC Ma mmio_write_32(SPM_POWER_ON_VAL1, POWER_ON_VAL1_DEF); 1007d116dccSCC Ma mmio_write_32(SPM_PCM_PWR_IO_EN, 0); 1017d116dccSCC Ma 1027d116dccSCC Ma mmio_write_32(SPM_PCM_CON0, CON0_CFG_KEY | CON0_PCM_SW_RESET); 1037d116dccSCC Ma mmio_write_32(SPM_PCM_CON0, CON0_CFG_KEY); 1047d116dccSCC Ma if (mmio_read_32(SPM_PCM_FSM_STA) != PCM_FSM_STA_DEF) 1057d116dccSCC Ma WARN("PCM reset failed\n"); 1067d116dccSCC Ma 1077d116dccSCC Ma mmio_write_32(SPM_PCM_CON0, CON0_CFG_KEY | CON0_IM_SLEEP_DVS); 1087d116dccSCC Ma mmio_write_32(SPM_PCM_CON1, CON1_CFG_KEY | CON1_EVENT_LOCK_EN | 1097d116dccSCC Ma CON1_SPM_SRAM_ISO_B | CON1_SPM_SRAM_SLP_B | CON1_MIF_APBEN); 1107d116dccSCC Ma mmio_write_32(SPM_PCM_IM_PTR, 0); 1117d116dccSCC Ma mmio_write_32(SPM_PCM_IM_LEN, 0); 1127d116dccSCC Ma 1137d116dccSCC Ma mmio_write_32(SPM_CLK_CON, CC_SYSCLK0_EN_1 | CC_SYSCLK0_EN_0 | 1147d116dccSCC Ma CC_SYSCLK1_EN_0 | CC_SRCLKENA_MASK_0 | CC_CLKSQ1_SEL | 1157d116dccSCC Ma CC_CXO32K_RM_EN_MD2 | CC_CXO32K_RM_EN_MD1 | CC_MD32_DCM_EN); 1167d116dccSCC Ma 1177d116dccSCC Ma mmio_write_32(SPM_SLEEP_ISR_MASK, 0xff0c); 1187d116dccSCC Ma mmio_write_32(SPM_SLEEP_ISR_STATUS, 0xc); 1197d116dccSCC Ma mmio_write_32(SPM_PCM_SW_INT_CLEAR, 0xff); 1207d116dccSCC Ma mmio_write_32(SPM_MD32_SRAM_CON, 0xff0); 1217d116dccSCC Ma } 1227d116dccSCC Ma 1237d116dccSCC Ma void spm_reset_and_init_pcm(void) 1247d116dccSCC Ma { 1257d116dccSCC Ma unsigned int con1; 1267d116dccSCC Ma int i = 0; 1277d116dccSCC Ma 1287d116dccSCC Ma mmio_write_32(SPM_PCM_CON0, CON0_CFG_KEY | CON0_PCM_SW_RESET); 1297d116dccSCC Ma mmio_write_32(SPM_PCM_CON0, CON0_CFG_KEY); 1307d116dccSCC Ma while (mmio_read_32(SPM_PCM_FSM_STA) != PCM_FSM_STA_DEF) { 1317d116dccSCC Ma i++; 1327d116dccSCC Ma if (i > 1000) { 1337d116dccSCC Ma i = 0; 1347d116dccSCC Ma WARN("PCM reset failed\n"); 1357d116dccSCC Ma break; 1367d116dccSCC Ma } 1377d116dccSCC Ma } 1387d116dccSCC Ma 1397d116dccSCC Ma mmio_write_32(SPM_PCM_CON0, CON0_CFG_KEY | CON0_IM_SLEEP_DVS); 1407d116dccSCC Ma 1417d116dccSCC Ma con1 = mmio_read_32(SPM_PCM_CON1) & 1427d116dccSCC Ma (CON1_PCM_WDT_WAKE_MODE | CON1_PCM_WDT_EN); 1437d116dccSCC Ma mmio_write_32(SPM_PCM_CON1, con1 | CON1_CFG_KEY | CON1_EVENT_LOCK_EN | 1447d116dccSCC Ma CON1_SPM_SRAM_ISO_B | CON1_SPM_SRAM_SLP_B | 1457d116dccSCC Ma CON1_IM_NONRP_EN | CON1_MIF_APBEN); 1467d116dccSCC Ma } 1477d116dccSCC Ma 1487d116dccSCC Ma void spm_init_pcm_register(void) 1497d116dccSCC Ma { 1507d116dccSCC Ma mmio_write_32(SPM_PCM_REG_DATA_INI, mmio_read_32(SPM_POWER_ON_VAL0)); 1517d116dccSCC Ma mmio_write_32(SPM_PCM_PWR_IO_EN, PCM_RF_SYNC_R0); 1527d116dccSCC Ma mmio_write_32(SPM_PCM_PWR_IO_EN, 0); 1537d116dccSCC Ma 1547d116dccSCC Ma mmio_write_32(SPM_PCM_REG_DATA_INI, mmio_read_32(SPM_POWER_ON_VAL1)); 1557d116dccSCC Ma mmio_write_32(SPM_PCM_PWR_IO_EN, PCM_RF_SYNC_R7); 1567d116dccSCC Ma mmio_write_32(SPM_PCM_PWR_IO_EN, 0); 1577d116dccSCC Ma } 1587d116dccSCC Ma 1597d116dccSCC Ma void spm_set_power_control(const struct pwr_ctrl *pwrctrl) 1607d116dccSCC Ma { 1617d116dccSCC Ma mmio_write_32(SPM_AP_STANBY_CON, (!pwrctrl->md32_req_mask << 21) | 1627d116dccSCC Ma (!pwrctrl->mfg_req_mask << 17) | 1637d116dccSCC Ma (!pwrctrl->disp_req_mask << 16) | 1647d116dccSCC Ma (!!pwrctrl->mcusys_idle_mask << 7) | 1657d116dccSCC Ma (!!pwrctrl->ca15top_idle_mask << 6) | 1667d116dccSCC Ma (!!pwrctrl->ca7top_idle_mask << 5) | 1677d116dccSCC Ma (!!pwrctrl->wfi_op << 4)); 1687d116dccSCC Ma mmio_write_32(SPM_PCM_SRC_REQ, (!!pwrctrl->pcm_apsrc_req << 0)); 1697d116dccSCC Ma mmio_write_32(SPM_PCM_PASR_DPD_2, 0); 1707d116dccSCC Ma 1717d116dccSCC Ma mmio_clrsetbits_32(SPM_CLK_CON, CC_SRCLKENA_MASK_0, 1727d116dccSCC Ma (pwrctrl->srclkenai_mask ? CC_SRCLKENA_MASK_0 : 0)); 1737d116dccSCC Ma 1747d116dccSCC Ma mmio_write_32(SPM_SLEEP_CA15_WFI0_EN, !!pwrctrl->ca15_wfi0_en); 1757d116dccSCC Ma mmio_write_32(SPM_SLEEP_CA15_WFI1_EN, !!pwrctrl->ca15_wfi1_en); 1767d116dccSCC Ma mmio_write_32(SPM_SLEEP_CA15_WFI2_EN, !!pwrctrl->ca15_wfi2_en); 1777d116dccSCC Ma mmio_write_32(SPM_SLEEP_CA15_WFI3_EN, !!pwrctrl->ca15_wfi3_en); 1787d116dccSCC Ma mmio_write_32(SPM_SLEEP_CA7_WFI0_EN, !!pwrctrl->ca7_wfi0_en); 1797d116dccSCC Ma mmio_write_32(SPM_SLEEP_CA7_WFI1_EN, !!pwrctrl->ca7_wfi1_en); 1807d116dccSCC Ma mmio_write_32(SPM_SLEEP_CA7_WFI2_EN, !!pwrctrl->ca7_wfi2_en); 1817d116dccSCC Ma mmio_write_32(SPM_SLEEP_CA7_WFI3_EN, !!pwrctrl->ca7_wfi3_en); 1827d116dccSCC Ma } 1837d116dccSCC Ma 1847d116dccSCC Ma void spm_set_wakeup_event(const struct pwr_ctrl *pwrctrl) 1857d116dccSCC Ma { 1867d116dccSCC Ma unsigned int val, mask; 1877d116dccSCC Ma 1887d116dccSCC Ma if (pwrctrl->timer_val_cust == 0) 1897d116dccSCC Ma val = pwrctrl->timer_val ? pwrctrl->timer_val : PCM_TIMER_MAX; 1907d116dccSCC Ma else 1917d116dccSCC Ma val = pwrctrl->timer_val_cust; 1927d116dccSCC Ma 1937d116dccSCC Ma mmio_write_32(SPM_PCM_TIMER_VAL, val); 1947d116dccSCC Ma mmio_setbits_32(SPM_PCM_CON1, CON1_CFG_KEY); 1957d116dccSCC Ma 1967d116dccSCC Ma if (pwrctrl->wake_src_cust == 0) 1977d116dccSCC Ma mask = pwrctrl->wake_src; 1987d116dccSCC Ma else 1997d116dccSCC Ma mask = pwrctrl->wake_src_cust; 2007d116dccSCC Ma 2017d116dccSCC Ma if (pwrctrl->syspwreq_mask) 2027d116dccSCC Ma mask &= ~WAKE_SRC_SYSPWREQ; 2037d116dccSCC Ma 2047d116dccSCC Ma mmio_write_32(SPM_SLEEP_WAKEUP_EVENT_MASK, ~mask); 2057d116dccSCC Ma mmio_write_32(SPM_SLEEP_ISR_MASK, 0xfe04); 2067d116dccSCC Ma } 2077d116dccSCC Ma 2087d116dccSCC Ma void spm_get_wakeup_status(struct wake_status *wakesta) 2097d116dccSCC Ma { 2107d116dccSCC Ma wakesta->assert_pc = mmio_read_32(SPM_PCM_REG_DATA_INI); 2117d116dccSCC Ma wakesta->r12 = mmio_read_32(SPM_PCM_REG12_DATA); 2127d116dccSCC Ma wakesta->raw_sta = mmio_read_32(SPM_SLEEP_ISR_RAW_STA); 2137d116dccSCC Ma wakesta->wake_misc = mmio_read_32(SPM_SLEEP_WAKEUP_MISC); 2147d116dccSCC Ma wakesta->timer_out = mmio_read_32(SPM_PCM_TIMER_OUT); 2157d116dccSCC Ma wakesta->r13 = mmio_read_32(SPM_PCM_REG13_DATA); 2167d116dccSCC Ma wakesta->idle_sta = mmio_read_32(SPM_SLEEP_SUBSYS_IDLE_STA); 2177d116dccSCC Ma wakesta->debug_flag = mmio_read_32(SPM_PCM_PASR_DPD_3); 2187d116dccSCC Ma wakesta->event_reg = mmio_read_32(SPM_PCM_EVENT_REG_STA); 2197d116dccSCC Ma wakesta->isr = mmio_read_32(SPM_SLEEP_ISR_STATUS); 2207d116dccSCC Ma } 2217d116dccSCC Ma 2227d116dccSCC Ma void spm_init_event_vector(const struct pcm_desc *pcmdesc) 2237d116dccSCC Ma { 2247d116dccSCC Ma /* init event vector register */ 2257d116dccSCC Ma mmio_write_32(SPM_PCM_EVENT_VECTOR0, pcmdesc->vec0); 2267d116dccSCC Ma mmio_write_32(SPM_PCM_EVENT_VECTOR1, pcmdesc->vec1); 2277d116dccSCC Ma mmio_write_32(SPM_PCM_EVENT_VECTOR2, pcmdesc->vec2); 2287d116dccSCC Ma mmio_write_32(SPM_PCM_EVENT_VECTOR3, pcmdesc->vec3); 2297d116dccSCC Ma mmio_write_32(SPM_PCM_EVENT_VECTOR4, pcmdesc->vec4); 2307d116dccSCC Ma mmio_write_32(SPM_PCM_EVENT_VECTOR5, pcmdesc->vec5); 2317d116dccSCC Ma mmio_write_32(SPM_PCM_EVENT_VECTOR6, pcmdesc->vec6); 2327d116dccSCC Ma mmio_write_32(SPM_PCM_EVENT_VECTOR7, pcmdesc->vec7); 2337d116dccSCC Ma 2347d116dccSCC Ma /* event vector will be enabled by PCM itself */ 2357d116dccSCC Ma } 2367d116dccSCC Ma 2377d116dccSCC Ma void spm_kick_im_to_fetch(const struct pcm_desc *pcmdesc) 2387d116dccSCC Ma { 2397d116dccSCC Ma unsigned int ptr = 0, len, con0; 2407d116dccSCC Ma 2417d116dccSCC Ma ptr = (unsigned int)(unsigned long)(pcmdesc->base); 2427d116dccSCC Ma len = pcmdesc->size - 1; 2437d116dccSCC Ma if (mmio_read_32(SPM_PCM_IM_PTR) != ptr || 2447d116dccSCC Ma mmio_read_32(SPM_PCM_IM_LEN) != len || 2457d116dccSCC Ma pcmdesc->sess > 2) { 2467d116dccSCC Ma mmio_write_32(SPM_PCM_IM_PTR, ptr); 2477d116dccSCC Ma mmio_write_32(SPM_PCM_IM_LEN, len); 2487d116dccSCC Ma } else { 2497d116dccSCC Ma mmio_setbits_32(SPM_PCM_CON1, CON1_CFG_KEY | CON1_IM_SLAVE); 2507d116dccSCC Ma } 2517d116dccSCC Ma 2527d116dccSCC Ma /* kick IM to fetch (only toggle IM_KICK) */ 2537d116dccSCC Ma con0 = mmio_read_32(SPM_PCM_CON0) & ~(CON0_IM_KICK | CON0_PCM_KICK); 2547d116dccSCC Ma mmio_write_32(SPM_PCM_CON0, con0 | CON0_CFG_KEY | CON0_IM_KICK); 2557d116dccSCC Ma mmio_write_32(SPM_PCM_CON0, con0 | CON0_CFG_KEY); 2567d116dccSCC Ma 2577d116dccSCC Ma /* kick IM to fetch (only toggle PCM_KICK) */ 2587d116dccSCC Ma con0 = mmio_read_32(SPM_PCM_CON0) & ~(CON0_IM_KICK | CON0_PCM_KICK); 2597d116dccSCC Ma mmio_write_32(SPM_PCM_CON0, con0 | CON0_CFG_KEY | CON0_PCM_KICK); 2607d116dccSCC Ma mmio_write_32(SPM_PCM_CON0, con0 | CON0_CFG_KEY); 2617d116dccSCC Ma } 2627d116dccSCC Ma 2637d116dccSCC Ma void spm_set_sysclk_settle(void) 2647d116dccSCC Ma { 2657d116dccSCC Ma mmio_write_32(SPM_CLK_SETTLE, SPM_SYSCLK_SETTLE); 2667d116dccSCC Ma 2677d116dccSCC Ma INFO("settle = %u\n", mmio_read_32(SPM_CLK_SETTLE)); 2687d116dccSCC Ma } 2697d116dccSCC Ma 2707d116dccSCC Ma void spm_kick_pcm_to_run(struct pwr_ctrl *pwrctrl) 2717d116dccSCC Ma { 2727d116dccSCC Ma unsigned int con1; 2737d116dccSCC Ma 2747d116dccSCC Ma con1 = mmio_read_32(SPM_PCM_CON1) & 2757d116dccSCC Ma ~(CON1_PCM_WDT_WAKE_MODE | CON1_PCM_WDT_EN); 2767d116dccSCC Ma 2777d116dccSCC Ma mmio_write_32(SPM_PCM_CON1, CON1_CFG_KEY | con1); 2787d116dccSCC Ma 2797d116dccSCC Ma if (mmio_read_32(SPM_PCM_TIMER_VAL) > PCM_TIMER_MAX) 2807d116dccSCC Ma mmio_write_32(SPM_PCM_TIMER_VAL, PCM_TIMER_MAX); 2817d116dccSCC Ma 2827d116dccSCC Ma mmio_write_32(SPM_PCM_WDT_TIMER_VAL, 2837d116dccSCC Ma mmio_read_32(SPM_PCM_TIMER_VAL) + PCM_WDT_TIMEOUT); 2847d116dccSCC Ma 2857d116dccSCC Ma mmio_write_32(SPM_PCM_CON1, con1 | CON1_CFG_KEY | CON1_PCM_WDT_EN); 2867d116dccSCC Ma mmio_write_32(SPM_PCM_PASR_DPD_0, 0); 2877d116dccSCC Ma 2887d116dccSCC Ma mmio_write_32(SPM_PCM_MAS_PAUSE_MASK, 0xffffffff); 2897d116dccSCC Ma mmio_write_32(SPM_PCM_REG_DATA_INI, 0); 2907d116dccSCC Ma mmio_clrbits_32(SPM_CLK_CON, CC_DISABLE_DORM_PWR); 2917d116dccSCC Ma 2927d116dccSCC Ma mmio_write_32(SPM_PCM_FLAGS, pwrctrl->pcm_flags); 2937d116dccSCC Ma 2947d116dccSCC Ma mmio_clrsetbits_32(SPM_CLK_CON, CC_LOCK_INFRA_DCM, 2957d116dccSCC Ma (pwrctrl->infra_dcm_lock ? CC_LOCK_INFRA_DCM : 0)); 2967d116dccSCC Ma 2977d116dccSCC Ma mmio_write_32(SPM_PCM_PWR_IO_EN, 2987d116dccSCC Ma (pwrctrl->r0_ctrl_en ? PCM_PWRIO_EN_R0 : 0) | 2997d116dccSCC Ma (pwrctrl->r7_ctrl_en ? PCM_PWRIO_EN_R7 : 0)); 3007d116dccSCC Ma } 3017d116dccSCC Ma 3027d116dccSCC Ma void spm_clean_after_wakeup(void) 3037d116dccSCC Ma { 3047d116dccSCC Ma mmio_clrsetbits_32(SPM_PCM_CON1, CON1_PCM_WDT_EN, CON1_CFG_KEY); 3057d116dccSCC Ma 3067d116dccSCC Ma mmio_write_32(SPM_PCM_PWR_IO_EN, 0); 3077d116dccSCC Ma mmio_write_32(SPM_SLEEP_CPU_WAKEUP_EVENT, 0); 3087d116dccSCC Ma mmio_clrsetbits_32(SPM_PCM_CON1, CON1_PCM_TIMER_EN, CON1_CFG_KEY); 3097d116dccSCC Ma 3107d116dccSCC Ma mmio_write_32(SPM_SLEEP_WAKEUP_EVENT_MASK, ~0); 3117d116dccSCC Ma mmio_write_32(SPM_SLEEP_ISR_MASK, 0xFF0C); 3127d116dccSCC Ma mmio_write_32(SPM_SLEEP_ISR_STATUS, 0xC); 3137d116dccSCC Ma mmio_write_32(SPM_PCM_SW_INT_CLEAR, 0xFF); 3147d116dccSCC Ma } 3157d116dccSCC Ma 3167d116dccSCC Ma enum wake_reason_t spm_output_wake_reason(struct wake_status *wakesta) 3177d116dccSCC Ma { 3187d116dccSCC Ma enum wake_reason_t wr; 3197d116dccSCC Ma int i; 3207d116dccSCC Ma 3217d116dccSCC Ma wr = WR_UNKNOWN; 3227d116dccSCC Ma 3237d116dccSCC Ma if (wakesta->assert_pc != 0) { 3247d116dccSCC Ma ERROR("PCM ASSERT AT %u, r12=0x%x, r13=0x%x, debug_flag=0x%x\n", 3257d116dccSCC Ma wakesta->assert_pc, wakesta->r12, wakesta->r13, 3267d116dccSCC Ma wakesta->debug_flag); 3277d116dccSCC Ma return WR_PCM_ASSERT; 3287d116dccSCC Ma } 3297d116dccSCC Ma 3307d116dccSCC Ma if (wakesta->r12 & WAKE_SRC_SPM_MERGE) { 3317d116dccSCC Ma if (wakesta->wake_misc & WAKE_MISC_PCM_TIMER) 3327d116dccSCC Ma wr = WR_PCM_TIMER; 3337d116dccSCC Ma if (wakesta->wake_misc & WAKE_MISC_CPU_WAKE) 3347d116dccSCC Ma wr = WR_WAKE_SRC; 3357d116dccSCC Ma } 3367d116dccSCC Ma 3377d116dccSCC Ma for (i = 1; i < 32; i++) { 3387d116dccSCC Ma if (wakesta->r12 & (1U << i)) 3397d116dccSCC Ma wr = WR_WAKE_SRC; 3407d116dccSCC Ma } 3417d116dccSCC Ma 3427d116dccSCC Ma if ((wakesta->event_reg & 0x100000) == 0) { 3437d116dccSCC Ma INFO("pcm sleep abort!\n"); 3447d116dccSCC Ma wr = WR_PCM_ABORT; 3457d116dccSCC Ma } 3467d116dccSCC Ma 3477d116dccSCC Ma INFO("timer_out = %u, r12 = 0x%x, r13 = 0x%x, debug_flag = 0x%x\n", 3487d116dccSCC Ma wakesta->timer_out, wakesta->r12, wakesta->r13, 3497d116dccSCC Ma wakesta->debug_flag); 3507d116dccSCC Ma 3517d116dccSCC Ma INFO("raw_sta = 0x%x, idle_sta = 0x%x, event_reg = 0x%x, isr = 0x%x\n", 3527d116dccSCC Ma wakesta->raw_sta, wakesta->idle_sta, wakesta->event_reg, 3537d116dccSCC Ma wakesta->isr); 3547d116dccSCC Ma 3557d116dccSCC Ma return wr; 3567d116dccSCC Ma } 3577d116dccSCC Ma 3587d116dccSCC Ma void spm_boot_init(void) 3597d116dccSCC Ma { 360a1e0c01fSJimmy Huang /* set spm transaction to secure mode */ 361a1e0c01fSJimmy Huang mmio_write_32(DEVAPC0_APC_CON, 0x0); 362a1e0c01fSJimmy Huang mmio_write_32(DEVAPC0_MAS_SEC_0, 0x200); 363a1e0c01fSJimmy Huang 3647d116dccSCC Ma /* Only CPU0 is online during boot, initialize cpu online reserve bit */ 3657d116dccSCC Ma mmio_write_32(SPM_PCM_RESERVE, 0xFE); 3663c454d52SJimmy Huang mmio_clrbits_32(AP_PLL_CON3, 0xFFFFF); 3673c454d52SJimmy Huang mmio_clrbits_32(AP_PLL_CON4, 0xF); 3687d116dccSCC Ma spm_lock_init(); 3697d116dccSCC Ma spm_register_init(); 3707d116dccSCC Ma } 371