1 /* 2 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #ifndef __PMU_COM_H__ 8 #define __PMU_COM_H__ 9 10 /* 11 * Use this macro to instantiate lock before it is used in below 12 * rockchip_pd_lock_xxx() macros 13 */ 14 DECLARE_BAKERY_LOCK(rockchip_pd_lock); 15 16 /* 17 * These are wrapper macros to the powe domain Bakery Lock API. 18 */ 19 #define rockchip_pd_lock_init() bakery_lock_init(&rockchip_pd_lock) 20 #define rockchip_pd_lock_get() bakery_lock_get(&rockchip_pd_lock) 21 #define rockchip_pd_lock_rls() bakery_lock_release(&rockchip_pd_lock) 22 23 /***************************************************************************** 24 * power domain on or off 25 *****************************************************************************/ 26 enum pmu_pd_state { 27 pmu_pd_on = 0, 28 pmu_pd_off = 1 29 }; 30 31 #pragma weak plat_ic_get_pending_interrupt_id 32 #pragma weak pmu_power_domain_ctr 33 #pragma weak check_cpu_wfie 34 35 static inline uint32_t pmu_power_domain_st(uint32_t pd) 36 { 37 uint32_t pwrdn_st = mmio_read_32(PMU_BASE + PMU_PWRDN_ST) & BIT(pd); 38 39 if (pwrdn_st) 40 return pmu_pd_off; 41 else 42 return pmu_pd_on; 43 } 44 45 static int pmu_power_domain_ctr(uint32_t pd, uint32_t pd_state) 46 { 47 uint32_t val; 48 uint32_t loop = 0; 49 int ret = 0; 50 51 rockchip_pd_lock_get(); 52 53 val = mmio_read_32(PMU_BASE + PMU_PWRDN_CON); 54 if (pd_state == pmu_pd_off) 55 val |= BIT(pd); 56 else 57 val &= ~BIT(pd); 58 59 mmio_write_32(PMU_BASE + PMU_PWRDN_CON, val); 60 dsb(); 61 62 while ((pmu_power_domain_st(pd) != pd_state) && (loop < PD_CTR_LOOP)) { 63 udelay(1); 64 loop++; 65 } 66 67 if (pmu_power_domain_st(pd) != pd_state) { 68 WARN("%s: %d, %d, error!\n", __func__, pd, pd_state); 69 ret = -EINVAL; 70 } 71 72 rockchip_pd_lock_rls(); 73 74 return ret; 75 } 76 77 static int check_cpu_wfie(uint32_t cpu_id, uint32_t wfie_msk) 78 { 79 uint32_t cluster_id, loop = 0; 80 81 if (cpu_id >= PLATFORM_CLUSTER0_CORE_COUNT) { 82 cluster_id = 1; 83 cpu_id -= PLATFORM_CLUSTER0_CORE_COUNT; 84 } else { 85 cluster_id = 0; 86 } 87 88 if (cluster_id) 89 wfie_msk <<= (clstb_cpu_wfe + cpu_id); 90 else 91 wfie_msk <<= (clstl_cpu_wfe + cpu_id); 92 93 while (!(mmio_read_32(PMU_BASE + PMU_CORE_PWR_ST) & wfie_msk) && 94 (loop < CHK_CPU_LOOP)) { 95 udelay(1); 96 loop++; 97 } 98 99 if ((mmio_read_32(PMU_BASE + PMU_CORE_PWR_ST) & wfie_msk) == 0) { 100 WARN("%s: %d, %d, %d, error!\n", __func__, 101 cluster_id, cpu_id, wfie_msk); 102 return -EINVAL; 103 } 104 105 return 0; 106 } 107 108 #endif /* __PMU_COM_H__ */ 109