xref: /rk3399_ARM-atf/plat/rockchip/common/drivers/pmu/pmu_com.h (revision 9ff67fa6f25c5a0285eec27f3e86362ae535aac3)
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  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24  * POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #ifndef __PMU_COM_H__
28 #define __PMU_COM_H__
29 
30 DEFINE_BAKERY_LOCK(rockchip_pd_lock);
31 
32 #define rockchip_pd_lock_get() bakery_lock_get(&rockchip_pd_lock)
33 
34 #define rockchip_pd_lock_rls() bakery_lock_release(&rockchip_pd_lock)
35 
36 #define rockchip_pd_lock_init() bakery_lock_init(&rockchip_pd_lock)
37 /*****************************************************************************
38  * power domain on or off
39  *****************************************************************************/
40 enum pmu_pd_state {
41 	pmu_pd_on = 0,
42 	pmu_pd_off = 1
43 };
44 
45 #pragma weak plat_ic_get_pending_interrupt_id
46 #pragma weak pmu_power_domain_ctr
47 #pragma weak check_cpu_wfie
48 
49 static inline uint32_t pmu_power_domain_st(uint32_t pd)
50 {
51 	uint32_t pwrdn_st = mmio_read_32(PMU_BASE + PMU_PWRDN_ST) &  BIT(pd);
52 
53 	if (pwrdn_st)
54 		return pmu_pd_off;
55 	else
56 		return pmu_pd_on;
57 }
58 
59 static int pmu_power_domain_ctr(uint32_t pd, uint32_t pd_state)
60 {
61 	uint32_t val;
62 	uint32_t loop = 0;
63 	int ret = 0;
64 
65 	rockchip_pd_lock_get();
66 
67 	val = mmio_read_32(PMU_BASE + PMU_PWRDN_CON);
68 	if (pd_state == pmu_pd_off)
69 		val |=  BIT(pd);
70 	else
71 		val &= ~BIT(pd);
72 
73 	mmio_write_32(PMU_BASE + PMU_PWRDN_CON, val);
74 	dsb();
75 
76 	while ((pmu_power_domain_st(pd) != pd_state) && (loop < PD_CTR_LOOP)) {
77 		udelay(1);
78 		loop++;
79 	}
80 
81 	if (pmu_power_domain_st(pd) != pd_state) {
82 		WARN("%s: %d, %d, error!\n", __func__, pd, pd_state);
83 		ret = -EINVAL;
84 	}
85 
86 	rockchip_pd_lock_rls();
87 
88 	return ret;
89 }
90 
91 static int check_cpu_wfie(uint32_t cpu_id, uint32_t wfie_msk)
92 {
93 	uint32_t cluster_id, loop = 0;
94 
95 	if (cpu_id >= PLATFORM_CLUSTER0_CORE_COUNT) {
96 		cluster_id = 1;
97 		cpu_id -= PLATFORM_CLUSTER0_CORE_COUNT;
98 	} else {
99 		cluster_id = 0;
100 	}
101 
102 	if (cluster_id)
103 		wfie_msk <<= (clstb_cpu_wfe + cpu_id);
104 	else
105 		wfie_msk <<= (clstl_cpu_wfe + cpu_id);
106 
107 	while (!(mmio_read_32(PMU_BASE + PMU_CORE_PWR_ST) & wfie_msk) &&
108 	       (loop < CHK_CPU_LOOP)) {
109 		udelay(1);
110 		loop++;
111 	}
112 
113 	if ((mmio_read_32(PMU_BASE + PMU_CORE_PWR_ST) & wfie_msk) == 0) {
114 		WARN("%s: %d, %d, %d, error!\n", __func__,
115 		     cluster_id, cpu_id, wfie_msk);
116 		return -EINVAL;
117 	}
118 
119 	return 0;
120 }
121 
122 #endif /* __PMU_COM_H__ */
123