]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/soc/qcom/spm.c
Merge remote-tracking branch 'usb-chipidea-next/ci-for-usb-next'
[karo-tx-linux.git] / drivers / soc / qcom / spm.c
1 /*
2  * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
3  * Copyright (c) 2014,2015, Linaro Ltd.
4  *
5  * SAW power controller driver
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 and
9  * only version 2 as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  */
16
17 #include <linux/kernel.h>
18 #include <linux/init.h>
19 #include <linux/io.h>
20 #include <linux/slab.h>
21 #include <linux/of.h>
22 #include <linux/of_address.h>
23 #include <linux/of_device.h>
24 #include <linux/err.h>
25 #include <linux/platform_device.h>
26 #include <linux/cpuidle.h>
27 #include <linux/cpu_pm.h>
28 #include <linux/qcom_scm.h>
29
30 #include <asm/cpuidle.h>
31 #include <asm/proc-fns.h>
32 #include <asm/suspend.h>
33
34 #define MAX_PMIC_DATA           2
35 #define MAX_SEQ_DATA            64
36 #define SPM_CTL_INDEX           0x7f
37 #define SPM_CTL_INDEX_SHIFT     4
38 #define SPM_CTL_EN              BIT(0)
39
40 enum pm_sleep_mode {
41         PM_SLEEP_MODE_STBY,
42         PM_SLEEP_MODE_RET,
43         PM_SLEEP_MODE_SPC,
44         PM_SLEEP_MODE_PC,
45         PM_SLEEP_MODE_NR,
46 };
47
48 enum spm_reg {
49         SPM_REG_CFG,
50         SPM_REG_SPM_CTL,
51         SPM_REG_DLY,
52         SPM_REG_PMIC_DLY,
53         SPM_REG_PMIC_DATA_0,
54         SPM_REG_PMIC_DATA_1,
55         SPM_REG_VCTL,
56         SPM_REG_SEQ_ENTRY,
57         SPM_REG_SPM_STS,
58         SPM_REG_PMIC_STS,
59         SPM_REG_NR,
60 };
61
62 struct spm_reg_data {
63         const u8 *reg_offset;
64         u32 spm_cfg;
65         u32 spm_dly;
66         u32 pmic_dly;
67         u32 pmic_data[MAX_PMIC_DATA];
68         u8 seq[MAX_SEQ_DATA];
69         u8 start_index[PM_SLEEP_MODE_NR];
70 };
71
72 struct spm_driver_data {
73         void __iomem *reg_base;
74         const struct spm_reg_data *reg_data;
75 };
76
77 static const u8 spm_reg_offset_v2_1[SPM_REG_NR] = {
78         [SPM_REG_CFG]           = 0x08,
79         [SPM_REG_SPM_CTL]       = 0x30,
80         [SPM_REG_DLY]           = 0x34,
81         [SPM_REG_SEQ_ENTRY]     = 0x80,
82 };
83
84 /* SPM register data for 8974, 8084 */
85 static const struct spm_reg_data spm_reg_8974_8084_cpu  = {
86         .reg_offset = spm_reg_offset_v2_1,
87         .spm_cfg = 0x1,
88         .spm_dly = 0x3C102800,
89         .seq = { 0x03, 0x0B, 0x0F, 0x00, 0x20, 0x80, 0x10, 0xE8, 0x5B, 0x03,
90                 0x3B, 0xE8, 0x5B, 0x82, 0x10, 0x0B, 0x30, 0x06, 0x26, 0x30,
91                 0x0F },
92         .start_index[PM_SLEEP_MODE_STBY] = 0,
93         .start_index[PM_SLEEP_MODE_SPC] = 3,
94 };
95
96 static const u8 spm_reg_offset_v1_1[SPM_REG_NR] = {
97         [SPM_REG_CFG]           = 0x08,
98         [SPM_REG_SPM_CTL]       = 0x20,
99         [SPM_REG_PMIC_DLY]      = 0x24,
100         [SPM_REG_PMIC_DATA_0]   = 0x28,
101         [SPM_REG_PMIC_DATA_1]   = 0x2C,
102         [SPM_REG_SEQ_ENTRY]     = 0x80,
103 };
104
105 /* SPM register data for 8064 */
106 static const struct spm_reg_data spm_reg_8064_cpu = {
107         .reg_offset = spm_reg_offset_v1_1,
108         .spm_cfg = 0x1F,
109         .pmic_dly = 0x02020004,
110         .pmic_data[0] = 0x0084009C,
111         .pmic_data[1] = 0x00A4001C,
112         .seq = { 0x03, 0x0F, 0x00, 0x24, 0x54, 0x10, 0x09, 0x03, 0x01,
113                 0x10, 0x54, 0x30, 0x0C, 0x24, 0x30, 0x0F },
114         .start_index[PM_SLEEP_MODE_STBY] = 0,
115         .start_index[PM_SLEEP_MODE_SPC] = 2,
116 };
117
118 static DEFINE_PER_CPU(struct spm_driver_data *, cpu_spm_drv);
119
120 typedef int (*idle_fn)(void);
121 static DEFINE_PER_CPU(idle_fn*, qcom_idle_ops);
122
123 static inline void spm_register_write(struct spm_driver_data *drv,
124                                         enum spm_reg reg, u32 val)
125 {
126         if (drv->reg_data->reg_offset[reg])
127                 writel_relaxed(val, drv->reg_base +
128                                 drv->reg_data->reg_offset[reg]);
129 }
130
131 /* Ensure a guaranteed write, before return */
132 static inline void spm_register_write_sync(struct spm_driver_data *drv,
133                                         enum spm_reg reg, u32 val)
134 {
135         u32 ret;
136
137         if (!drv->reg_data->reg_offset[reg])
138                 return;
139
140         do {
141                 writel_relaxed(val, drv->reg_base +
142                                 drv->reg_data->reg_offset[reg]);
143                 ret = readl_relaxed(drv->reg_base +
144                                 drv->reg_data->reg_offset[reg]);
145                 if (ret == val)
146                         break;
147                 cpu_relax();
148         } while (1);
149 }
150
151 static inline u32 spm_register_read(struct spm_driver_data *drv,
152                                         enum spm_reg reg)
153 {
154         return readl_relaxed(drv->reg_base + drv->reg_data->reg_offset[reg]);
155 }
156
157 static void spm_set_low_power_mode(struct spm_driver_data *drv,
158                                         enum pm_sleep_mode mode)
159 {
160         u32 start_index;
161         u32 ctl_val;
162
163         start_index = drv->reg_data->start_index[mode];
164
165         ctl_val = spm_register_read(drv, SPM_REG_SPM_CTL);
166         ctl_val &= ~(SPM_CTL_INDEX << SPM_CTL_INDEX_SHIFT);
167         ctl_val |= start_index << SPM_CTL_INDEX_SHIFT;
168         ctl_val |= SPM_CTL_EN;
169         spm_register_write_sync(drv, SPM_REG_SPM_CTL, ctl_val);
170 }
171
172 static int qcom_pm_collapse(unsigned long int unused)
173 {
174         qcom_scm_cpu_power_down(QCOM_SCM_CPU_PWR_DOWN_L2_ON);
175
176         /*
177          * Returns here only if there was a pending interrupt and we did not
178          * power down as a result.
179          */
180         return -1;
181 }
182
183 static int qcom_cpu_spc(void)
184 {
185         int ret;
186         struct spm_driver_data *drv = __this_cpu_read(cpu_spm_drv);
187
188         spm_set_low_power_mode(drv, PM_SLEEP_MODE_SPC);
189         ret = cpu_suspend(0, qcom_pm_collapse);
190         /*
191          * ARM common code executes WFI without calling into our driver and
192          * if the SPM mode is not reset, then we may accidently power down the
193          * cpu when we intended only to gate the cpu clock.
194          * Ensure the state is set to standby before returning.
195          */
196         spm_set_low_power_mode(drv, PM_SLEEP_MODE_STBY);
197
198         return ret;
199 }
200
201 static int qcom_idle_enter(unsigned long index)
202 {
203         return __this_cpu_read(qcom_idle_ops)[index]();
204 }
205
206 static const struct of_device_id qcom_idle_state_match[] __initconst = {
207         { .compatible = "qcom,idle-state-spc", .data = qcom_cpu_spc },
208         { },
209 };
210
211 static int __init qcom_cpuidle_init(struct device_node *cpu_node, int cpu)
212 {
213         const struct of_device_id *match_id;
214         struct device_node *state_node;
215         int i;
216         int state_count = 1;
217         idle_fn idle_fns[CPUIDLE_STATE_MAX];
218         idle_fn *fns;
219         cpumask_t mask;
220         bool use_scm_power_down = false;
221
222         for (i = 0; ; i++) {
223                 state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
224                 if (!state_node)
225                         break;
226
227                 if (!of_device_is_available(state_node))
228                         continue;
229
230                 if (i == CPUIDLE_STATE_MAX) {
231                         pr_warn("%s: cpuidle states reached max possible\n",
232                                         __func__);
233                         break;
234                 }
235
236                 match_id = of_match_node(qcom_idle_state_match, state_node);
237                 if (!match_id)
238                         return -ENODEV;
239
240                 idle_fns[state_count] = match_id->data;
241
242                 /* Check if any of the states allow power down */
243                 if (match_id->data == qcom_cpu_spc)
244                         use_scm_power_down = true;
245
246                 state_count++;
247         }
248
249         if (state_count == 1)
250                 goto check_spm;
251
252         fns = devm_kcalloc(get_cpu_device(cpu), state_count, sizeof(*fns),
253                         GFP_KERNEL);
254         if (!fns)
255                 return -ENOMEM;
256
257         for (i = 1; i < state_count; i++)
258                 fns[i] = idle_fns[i];
259
260         if (use_scm_power_down) {
261                 /* We have atleast one power down mode */
262                 cpumask_clear(&mask);
263                 cpumask_set_cpu(cpu, &mask);
264                 qcom_scm_set_warm_boot_addr(cpu_resume_arm, &mask);
265         }
266
267         per_cpu(qcom_idle_ops, cpu) = fns;
268
269         /*
270          * SPM probe for the cpu should have happened by now, if the
271          * SPM device does not exist, return -ENXIO to indicate that the
272          * cpu does not support idle states.
273          */
274 check_spm:
275         return per_cpu(cpu_spm_drv, cpu) ? 0 : -ENXIO;
276 }
277
278 static struct cpuidle_ops qcom_cpuidle_ops __initdata = {
279         .suspend = qcom_idle_enter,
280         .init = qcom_cpuidle_init,
281 };
282
283 CPUIDLE_METHOD_OF_DECLARE(qcom_idle_v1, "qcom,kpss-acc-v1", &qcom_cpuidle_ops);
284 CPUIDLE_METHOD_OF_DECLARE(qcom_idle_v2, "qcom,kpss-acc-v2", &qcom_cpuidle_ops);
285
286 static struct spm_driver_data *spm_get_drv(struct platform_device *pdev,
287                 int *spm_cpu)
288 {
289         struct spm_driver_data *drv = NULL;
290         struct device_node *cpu_node, *saw_node;
291         int cpu;
292         bool found = 0;
293
294         for_each_possible_cpu(cpu) {
295                 cpu_node = of_cpu_device_node_get(cpu);
296                 if (!cpu_node)
297                         continue;
298                 saw_node = of_parse_phandle(cpu_node, "qcom,saw", 0);
299                 found = (saw_node == pdev->dev.of_node);
300                 of_node_put(saw_node);
301                 of_node_put(cpu_node);
302                 if (found)
303                         break;
304         }
305
306         if (found) {
307                 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
308                 if (drv)
309                         *spm_cpu = cpu;
310         }
311
312         return drv;
313 }
314
315 static const struct of_device_id spm_match_table[] = {
316         { .compatible = "qcom,msm8974-saw2-v2.1-cpu",
317           .data = &spm_reg_8974_8084_cpu },
318         { .compatible = "qcom,apq8084-saw2-v2.1-cpu",
319           .data = &spm_reg_8974_8084_cpu },
320         { .compatible = "qcom,apq8064-saw2-v1.1-cpu",
321           .data = &spm_reg_8064_cpu },
322         { },
323 };
324
325 static int spm_dev_probe(struct platform_device *pdev)
326 {
327         struct spm_driver_data *drv;
328         struct resource *res;
329         const struct of_device_id *match_id;
330         void __iomem *addr;
331         int cpu;
332
333         drv = spm_get_drv(pdev, &cpu);
334         if (!drv)
335                 return -EINVAL;
336
337         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
338         drv->reg_base = devm_ioremap_resource(&pdev->dev, res);
339         if (IS_ERR(drv->reg_base))
340                 return PTR_ERR(drv->reg_base);
341
342         match_id = of_match_node(spm_match_table, pdev->dev.of_node);
343         if (!match_id)
344                 return -ENODEV;
345
346         drv->reg_data = match_id->data;
347
348         /* Write the SPM sequences first.. */
349         addr = drv->reg_base + drv->reg_data->reg_offset[SPM_REG_SEQ_ENTRY];
350         __iowrite32_copy(addr, drv->reg_data->seq,
351                         ARRAY_SIZE(drv->reg_data->seq) / 4);
352
353         /*
354          * ..and then the control registers.
355          * On some SoC if the control registers are written first and if the
356          * CPU was held in reset, the reset signal could trigger the SPM state
357          * machine, before the sequences are completely written.
358          */
359         spm_register_write(drv, SPM_REG_CFG, drv->reg_data->spm_cfg);
360         spm_register_write(drv, SPM_REG_DLY, drv->reg_data->spm_dly);
361         spm_register_write(drv, SPM_REG_PMIC_DLY, drv->reg_data->pmic_dly);
362         spm_register_write(drv, SPM_REG_PMIC_DATA_0,
363                                 drv->reg_data->pmic_data[0]);
364         spm_register_write(drv, SPM_REG_PMIC_DATA_1,
365                                 drv->reg_data->pmic_data[1]);
366
367         /* Set up Standby as the default low power mode */
368         spm_set_low_power_mode(drv, PM_SLEEP_MODE_STBY);
369
370         per_cpu(cpu_spm_drv, cpu) = drv;
371
372         return 0;
373 }
374
375 static struct platform_driver spm_driver = {
376         .probe = spm_dev_probe,
377         .driver = {
378                 .name = "saw",
379                 .of_match_table = spm_match_table,
380         },
381 };
382
383 builtin_platform_driver(spm_driver);