]>
Commit | Line | Data |
---|---|---|
2874c5fd | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
56f1ba28 | 2 | /* |
3 | * MPC85xx PM operators | |
4 | * | |
5 | * Copyright 2015 Freescale Semiconductor Inc. | |
56f1ba28 | 6 | */ |
7 | ||
8 | #define pr_fmt(fmt) "%s: " fmt, __func__ | |
9 | ||
10 | #include <linux/kernel.h> | |
11 | #include <linux/of.h> | |
12 | #include <linux/of_address.h> | |
13 | #include <linux/fsl/guts.h> | |
14 | ||
15 | #include <asm/io.h> | |
16 | #include <asm/fsl_pm.h> | |
17 | ||
18 | static struct ccsr_guts __iomem *guts; | |
19 | ||
20 | static void mpc85xx_irq_mask(int cpu) | |
21 | { | |
22 | ||
23 | } | |
24 | ||
25 | static void mpc85xx_irq_unmask(int cpu) | |
26 | { | |
27 | ||
28 | } | |
29 | ||
30 | static void mpc85xx_cpu_die(int cpu) | |
31 | { | |
32 | u32 tmp; | |
33 | ||
34 | tmp = (mfspr(SPRN_HID0) & ~(HID0_DOZE|HID0_SLEEP)) | HID0_NAP; | |
35 | mtspr(SPRN_HID0, tmp); | |
36 | ||
37 | /* Enter NAP mode. */ | |
38 | tmp = mfmsr(); | |
39 | tmp |= MSR_WE; | |
40 | asm volatile( | |
41 | "msync\n" | |
42 | "mtmsr %0\n" | |
43 | "isync\n" | |
44 | : | |
45 | : "r" (tmp)); | |
46 | } | |
47 | ||
48 | static void mpc85xx_cpu_up_prepare(int cpu) | |
49 | { | |
50 | ||
51 | } | |
52 | ||
53 | static void mpc85xx_freeze_time_base(bool freeze) | |
54 | { | |
55 | uint32_t mask; | |
56 | ||
57 | mask = CCSR_GUTS_DEVDISR_TB0 | CCSR_GUTS_DEVDISR_TB1; | |
58 | if (freeze) | |
59 | setbits32(&guts->devdisr, mask); | |
60 | else | |
61 | clrbits32(&guts->devdisr, mask); | |
62 | ||
63 | in_be32(&guts->devdisr); | |
64 | } | |
65 | ||
66 | static const struct of_device_id mpc85xx_smp_guts_ids[] = { | |
67 | { .compatible = "fsl,mpc8572-guts", }, | |
68 | { .compatible = "fsl,p1020-guts", }, | |
69 | { .compatible = "fsl,p1021-guts", }, | |
70 | { .compatible = "fsl,p1022-guts", }, | |
71 | { .compatible = "fsl,p1023-guts", }, | |
72 | { .compatible = "fsl,p2020-guts", }, | |
73 | { .compatible = "fsl,bsc9132-guts", }, | |
74 | {}, | |
75 | }; | |
76 | ||
77 | static const struct fsl_pm_ops mpc85xx_pm_ops = { | |
78 | .freeze_time_base = mpc85xx_freeze_time_base, | |
79 | .irq_mask = mpc85xx_irq_mask, | |
80 | .irq_unmask = mpc85xx_irq_unmask, | |
81 | .cpu_die = mpc85xx_cpu_die, | |
82 | .cpu_up_prepare = mpc85xx_cpu_up_prepare, | |
83 | }; | |
84 | ||
85 | int __init mpc85xx_setup_pmc(void) | |
86 | { | |
87 | struct device_node *np; | |
88 | ||
89 | np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids); | |
90 | if (np) { | |
91 | guts = of_iomap(np, 0); | |
92 | of_node_put(np); | |
93 | if (!guts) { | |
94 | pr_err("Could not map guts node address\n"); | |
95 | return -ENOMEM; | |
96 | } | |
97 | } | |
98 | ||
99 | qoriq_pm_ops = &mpc85xx_pm_ops; | |
100 | ||
101 | return 0; | |
102 | } |