1 /* 2 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * Redistributions of source code must retain the above copyright notice, this 8 * list of conditions and the following disclaimer. 9 * 10 * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * Neither the name of ARM nor the names of its contributors may be used 15 * to endorse or promote products derived from this software without specific 16 * prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #ifndef __PMU_COM_H__ 32 #define __PMU_COM_H__ 33 34 #ifndef CHECK_CPU_WFIE_BASE 35 #define CHECK_CPU_WFIE_BASE (PMU_BASE + PMU_CORE_PWR_ST) 36 #endif 37 /* 38 * Use this macro to instantiate lock before it is used in below 39 * rockchip_pd_lock_xxx() macros 40 */ 41 DECLARE_BAKERY_LOCK(rockchip_pd_lock); 42 43 /* 44 * These are wrapper macros to the powe domain Bakery Lock API. 45 */ 46 #define rockchip_pd_lock_init() bakery_lock_init(&rockchip_pd_lock) 47 #define rockchip_pd_lock_get() bakery_lock_get(&rockchip_pd_lock) 48 #define rockchip_pd_lock_rls() bakery_lock_release(&rockchip_pd_lock) 49 50 /***************************************************************************** 51 * power domain on or off 52 *****************************************************************************/ 53 enum pmu_pd_state { 54 pmu_pd_on = 0, 55 pmu_pd_off = 1 56 }; 57 58 #pragma weak plat_ic_get_pending_interrupt_id 59 #pragma weak pmu_power_domain_ctr 60 #pragma weak check_cpu_wfie 61 62 static inline uint32_t pmu_power_domain_st(uint32_t pd) 63 { 64 uint32_t pwrdn_st = mmio_read_32(PMU_BASE + PMU_PWRDN_ST) & BIT(pd); 65 66 if (pwrdn_st) 67 return pmu_pd_off; 68 else 69 return pmu_pd_on; 70 } 71 72 static int pmu_power_domain_ctr(uint32_t pd, uint32_t pd_state) 73 { 74 uint32_t val; 75 uint32_t loop = 0; 76 int ret = 0; 77 78 rockchip_pd_lock_get(); 79 80 val = mmio_read_32(PMU_BASE + PMU_PWRDN_CON); 81 if (pd_state == pmu_pd_off) 82 val |= BIT(pd); 83 else 84 val &= ~BIT(pd); 85 86 mmio_write_32(PMU_BASE + PMU_PWRDN_CON, val); 87 dsb(); 88 89 while ((pmu_power_domain_st(pd) != pd_state) && (loop < PD_CTR_LOOP)) { 90 udelay(1); 91 loop++; 92 } 93 94 if (pmu_power_domain_st(pd) != pd_state) { 95 WARN("%s: %d, %d, error!\n", __func__, pd, pd_state); 96 ret = -EINVAL; 97 } 98 99 rockchip_pd_lock_rls(); 100 101 return ret; 102 } 103 104 static int check_cpu_wfie(uint32_t cpu_id, uint32_t wfie_msk) 105 { 106 uint32_t cluster_id, loop = 0; 107 108 if (cpu_id >= PLATFORM_CLUSTER0_CORE_COUNT) { 109 cluster_id = 1; 110 cpu_id -= PLATFORM_CLUSTER0_CORE_COUNT; 111 } else { 112 cluster_id = 0; 113 } 114 115 if (cluster_id) 116 wfie_msk <<= (clstb_cpu_wfe + cpu_id); 117 else 118 wfie_msk <<= (clstl_cpu_wfe + cpu_id); 119 120 while (!(mmio_read_32(CHECK_CPU_WFIE_BASE) & wfie_msk) && 121 (loop < CHK_CPU_LOOP)) { 122 udelay(1); 123 loop++; 124 } 125 126 if ((mmio_read_32(CHECK_CPU_WFIE_BASE) & wfie_msk) == 0) { 127 WARN("%s: %d, %d, %d, error!\n", __func__, 128 cluster_id, cpu_id, wfie_msk); 129 return -EINVAL; 130 } 131 132 return 0; 133 } 134 135 #endif /* __PMU_COM_H__ */ 136