55//
66// Exynos - CPU PMU(Power Management Unit) support
77
8+ #include <linux/arm-smccc.h>
89#include <linux/of.h>
910#include <linux/of_address.h>
1011#include <linux/mfd/core.h>
1112#include <linux/mfd/syscon.h>
1213#include <linux/of_platform.h>
1314#include <linux/platform_device.h>
1415#include <linux/delay.h>
16+ #include <linux/regmap.h>
1517
1618#include <linux/soc/samsung/exynos-regs-pmu.h>
1719#include <linux/soc/samsung/exynos-pmu.h>
1820
1921#include "exynos-pmu.h"
2022
23+ #define PMUALIVE_MASK GENMASK(13, 0)
24+ #define TENSOR_SET_BITS (BIT(15) | BIT(14))
25+ #define TENSOR_CLR_BITS BIT(15)
26+ #define TENSOR_SMC_PMU_SEC_REG 0x82000504
27+ #define TENSOR_PMUREG_READ 0
28+ #define TENSOR_PMUREG_WRITE 1
29+ #define TENSOR_PMUREG_RMW 2
30+
2131struct exynos_pmu_context {
2232 struct device * dev ;
2333 const struct exynos_pmu_data * pmu_data ;
34+ struct regmap * pmureg ;
2435};
2536
2637void __iomem * pmu_base_addr ;
2738static struct exynos_pmu_context * pmu_context ;
39+ /* forward declaration */
40+ static struct platform_driver exynos_pmu_driver ;
41+
42+ /*
43+ * Tensor SoCs are configured so that PMU_ALIVE registers can only be written
44+ * from EL3, but are still read accessible. As Linux needs to write some of
45+ * these registers, the following functions are provided and exposed via
46+ * regmap.
47+ *
48+ * Note: This SMC interface is known to be implemented on gs101 and derivative
49+ * SoCs.
50+ */
51+
52+ /* Write to a protected PMU register. */
53+ static int tensor_sec_reg_write (void * context , unsigned int reg ,
54+ unsigned int val )
55+ {
56+ struct arm_smccc_res res ;
57+ unsigned long pmu_base = (unsigned long )context ;
58+
59+ arm_smccc_smc (TENSOR_SMC_PMU_SEC_REG , pmu_base + reg ,
60+ TENSOR_PMUREG_WRITE , val , 0 , 0 , 0 , 0 , & res );
61+
62+ /* returns -EINVAL if access isn't allowed or 0 */
63+ if (res .a0 )
64+ pr_warn ("%s(): SMC failed: %d\n" , __func__ , (int )res .a0 );
65+
66+ return (int )res .a0 ;
67+ }
68+
69+ /* Read/Modify/Write a protected PMU register. */
70+ static int tensor_sec_reg_rmw (void * context , unsigned int reg ,
71+ unsigned int mask , unsigned int val )
72+ {
73+ struct arm_smccc_res res ;
74+ unsigned long pmu_base = (unsigned long )context ;
75+
76+ arm_smccc_smc (TENSOR_SMC_PMU_SEC_REG , pmu_base + reg ,
77+ TENSOR_PMUREG_RMW , mask , val , 0 , 0 , 0 , & res );
78+
79+ /* returns -EINVAL if access isn't allowed or 0 */
80+ if (res .a0 )
81+ pr_warn ("%s(): SMC failed: %d\n" , __func__ , (int )res .a0 );
82+
83+ return (int )res .a0 ;
84+ }
85+
86+ /*
87+ * Read a protected PMU register. All PMU registers can be read by Linux.
88+ * Note: The SMC read register is not used, as only registers that can be
89+ * written are readable via SMC.
90+ */
91+ static int tensor_sec_reg_read (void * context , unsigned int reg ,
92+ unsigned int * val )
93+ {
94+ * val = pmu_raw_readl (reg );
95+ return 0 ;
96+ }
97+
98+ /*
99+ * For SoCs that have set/clear bit hardware this function can be used when
100+ * the PMU register will be accessed by multiple masters.
101+ *
102+ * For example, to set bits 13:8 in PMU reg offset 0x3e80
103+ * tensor_set_bits_atomic(ctx, 0x3e80, 0x3f00, 0x3f00);
104+ *
105+ * Set bit 8, and clear bits 13:9 PMU reg offset 0x3e80
106+ * tensor_set_bits_atomic(0x3e80, 0x100, 0x3f00);
107+ */
108+ static int tensor_set_bits_atomic (void * ctx , unsigned int offset , u32 val ,
109+ u32 mask )
110+ {
111+ int ret ;
112+ unsigned int i ;
113+
114+ for (i = 0 ; i < 32 ; i ++ ) {
115+ if (!(mask & BIT (i )))
116+ continue ;
117+
118+ offset &= ~TENSOR_SET_BITS ;
119+
120+ if (val & BIT (i ))
121+ offset |= TENSOR_SET_BITS ;
122+ else
123+ offset |= TENSOR_CLR_BITS ;
124+
125+ ret = tensor_sec_reg_write (ctx , offset , i );
126+ if (ret )
127+ return ret ;
128+ }
129+ return ret ;
130+ }
131+
132+ static int tensor_sec_update_bits (void * ctx , unsigned int reg ,
133+ unsigned int mask , unsigned int val )
134+ {
135+ /*
136+ * Use atomic operations for PMU_ALIVE registers (offset 0~0x3FFF)
137+ * as the target registers can be accessed by multiple masters.
138+ */
139+ if (reg > PMUALIVE_MASK )
140+ return tensor_sec_reg_rmw (ctx , reg , mask , val );
141+
142+ return tensor_set_bits_atomic (ctx , reg , val , mask );
143+ }
28144
29145void pmu_raw_writel (u32 val , u32 offset )
30146{
@@ -75,11 +191,41 @@ void exynos_sys_powerdown_conf(enum sys_powerdown mode)
75191#define exynos_pmu_data_arm_ptr (data ) NULL
76192#endif
77193
194+ static const struct regmap_config regmap_smccfg = {
195+ .name = "pmu_regs" ,
196+ .reg_bits = 32 ,
197+ .reg_stride = 4 ,
198+ .val_bits = 32 ,
199+ .fast_io = true,
200+ .use_single_read = true,
201+ .use_single_write = true,
202+ .reg_read = tensor_sec_reg_read ,
203+ .reg_write = tensor_sec_reg_write ,
204+ .reg_update_bits = tensor_sec_update_bits ,
205+ };
206+
207+ static const struct regmap_config regmap_mmiocfg = {
208+ .name = "pmu_regs" ,
209+ .reg_bits = 32 ,
210+ .reg_stride = 4 ,
211+ .val_bits = 32 ,
212+ .fast_io = true,
213+ .use_single_read = true,
214+ .use_single_write = true,
215+ };
216+
217+ static const struct exynos_pmu_data gs101_pmu_data = {
218+ .pmu_secure = true
219+ };
220+
78221/*
79222 * PMU platform driver and devicetree bindings.
80223 */
81224static const struct of_device_id exynos_pmu_of_device_ids [] = {
82225 {
226+ .compatible = "google,gs101-pmu" ,
227+ .data = & gs101_pmu_data ,
228+ }, {
83229 .compatible = "samsung,exynos3250-pmu" ,
84230 .data = exynos_pmu_data_arm_ptr (exynos3250_pmu_data ),
85231 }, {
@@ -113,19 +259,75 @@ static const struct mfd_cell exynos_pmu_devs[] = {
113259 { .name = "exynos-clkout" , },
114260};
115261
262+ /**
263+ * exynos_get_pmu_regmap() - Obtain pmureg regmap
264+ *
265+ * Find the pmureg regmap previously configured in probe() and return regmap
266+ * pointer.
267+ *
268+ * Return: A pointer to regmap if found or ERR_PTR error value.
269+ */
116270struct regmap * exynos_get_pmu_regmap (void )
117271{
118272 struct device_node * np = of_find_matching_node (NULL ,
119273 exynos_pmu_of_device_ids );
120274 if (np )
121- return syscon_node_to_regmap (np );
275+ return exynos_get_pmu_regmap_by_phandle (np , NULL );
122276 return ERR_PTR (- ENODEV );
123277}
124278EXPORT_SYMBOL_GPL (exynos_get_pmu_regmap );
125279
280+ /**
281+ * exynos_get_pmu_regmap_by_phandle() - Obtain pmureg regmap via phandle
282+ * @np: Device node holding PMU phandle property
283+ * @propname: Name of property holding phandle value
284+ *
285+ * Find the pmureg regmap previously configured in probe() and return regmap
286+ * pointer.
287+ *
288+ * Return: A pointer to regmap if found or ERR_PTR error value.
289+ */
290+ struct regmap * exynos_get_pmu_regmap_by_phandle (struct device_node * np ,
291+ const char * propname )
292+ {
293+ struct exynos_pmu_context * ctx ;
294+ struct device_node * pmu_np ;
295+ struct device * dev ;
296+
297+ if (propname )
298+ pmu_np = of_parse_phandle (np , propname , 0 );
299+ else
300+ pmu_np = np ;
301+
302+ if (!pmu_np )
303+ return ERR_PTR (- ENODEV );
304+
305+ /*
306+ * Determine if exynos-pmu device has probed and therefore regmap
307+ * has been created and can be returned to the caller. Otherwise we
308+ * return -EPROBE_DEFER.
309+ */
310+ dev = driver_find_device_by_of_node (& exynos_pmu_driver .driver ,
311+ (void * )pmu_np );
312+
313+ if (propname )
314+ of_node_put (pmu_np );
315+
316+ if (!dev )
317+ return ERR_PTR (- EPROBE_DEFER );
318+
319+ ctx = dev_get_drvdata (dev );
320+
321+ return ctx -> pmureg ;
322+ }
323+ EXPORT_SYMBOL_GPL (exynos_get_pmu_regmap_by_phandle );
324+
126325static int exynos_pmu_probe (struct platform_device * pdev )
127326{
128327 struct device * dev = & pdev -> dev ;
328+ struct regmap_config pmu_regmcfg ;
329+ struct regmap * regmap ;
330+ struct resource * res ;
129331 int ret ;
130332
131333 pmu_base_addr = devm_platform_ioremap_resource (pdev , 0 );
@@ -137,9 +339,38 @@ static int exynos_pmu_probe(struct platform_device *pdev)
137339 GFP_KERNEL );
138340 if (!pmu_context )
139341 return - ENOMEM ;
140- pmu_context -> dev = dev ;
342+
343+ res = platform_get_resource (pdev , IORESOURCE_MEM , 0 );
344+ if (!res )
345+ return - ENODEV ;
346+
141347 pmu_context -> pmu_data = of_device_get_match_data (dev );
142348
349+ /* For SoCs that secure PMU register writes use custom regmap */
350+ if (pmu_context -> pmu_data && pmu_context -> pmu_data -> pmu_secure ) {
351+ pmu_regmcfg = regmap_smccfg ;
352+ pmu_regmcfg .max_register = resource_size (res ) -
353+ pmu_regmcfg .reg_stride ;
354+ /* Need physical address for SMC call */
355+ regmap = devm_regmap_init (dev , NULL ,
356+ (void * )(uintptr_t )res -> start ,
357+ & pmu_regmcfg );
358+ } else {
359+ /* All other SoCs use a MMIO regmap */
360+ pmu_regmcfg = regmap_mmiocfg ;
361+ pmu_regmcfg .max_register = resource_size (res ) -
362+ pmu_regmcfg .reg_stride ;
363+ regmap = devm_regmap_init_mmio (dev , pmu_base_addr ,
364+ & pmu_regmcfg );
365+ }
366+
367+ if (IS_ERR (regmap ))
368+ return dev_err_probe (& pdev -> dev , PTR_ERR (regmap ),
369+ "regmap init failed\n" );
370+
371+ pmu_context -> pmureg = regmap ;
372+ pmu_context -> dev = dev ;
373+
143374 if (pmu_context -> pmu_data && pmu_context -> pmu_data -> pmu_init )
144375 pmu_context -> pmu_data -> pmu_init ();
145376
0 commit comments