xref: /qemu/hw/misc/imx6_src.c (revision 70ce076fa6dff60585c229a4b641b13e64bf03cf)
1 /*
2  * IMX6 System Reset Controller
3  *
4  * Copyright (c) 2015 Jean-Christophe Dubois <jcd@tribudubois.net>
5  *
6  * This work is licensed under the terms of the GNU GPL, version 2 or later.
7  * See the COPYING file in the top-level directory.
8  *
9  */
10 
11 #include "qemu/osdep.h"
12 #include "hw/misc/imx6_src.h"
13 #include "migration/vmstate.h"
14 #include "qemu/bitops.h"
15 #include "qemu/log.h"
16 #include "qemu/main-loop.h"
17 #include "qemu/module.h"
18 #include "target/arm/arm-powerctl.h"
19 #include "hw/core/cpu.h"
20 #include "trace.h"
21 
22 static const char *imx6_src_reg_name(uint32_t reg)
23 {
24     static char unknown[20];
25 
26     switch (reg) {
27     case SRC_SCR:
28         return "SRC_SCR";
29     case SRC_SBMR1:
30         return "SRC_SBMR1";
31     case SRC_SRSR:
32         return "SRC_SRSR";
33     case SRC_SISR:
34         return "SRC_SISR";
35     case SRC_SIMR:
36         return "SRC_SIMR";
37     case SRC_SBMR2:
38         return "SRC_SBMR2";
39     case SRC_GPR1:
40         return "SRC_GPR1";
41     case SRC_GPR2:
42         return "SRC_GPR2";
43     case SRC_GPR3:
44         return "SRC_GPR3";
45     case SRC_GPR4:
46         return "SRC_GPR4";
47     case SRC_GPR5:
48         return "SRC_GPR5";
49     case SRC_GPR6:
50         return "SRC_GPR6";
51     case SRC_GPR7:
52         return "SRC_GPR7";
53     case SRC_GPR8:
54         return "SRC_GPR8";
55     case SRC_GPR9:
56         return "SRC_GPR9";
57     case SRC_GPR10:
58         return "SRC_GPR10";
59     default:
60         snprintf(unknown, sizeof(unknown), "%u ?", reg);
61         return unknown;
62     }
63 }
64 
65 static const VMStateDescription vmstate_imx6_src = {
66     .name = TYPE_IMX6_SRC,
67     .version_id = 1,
68     .minimum_version_id = 1,
69     .fields = (const VMStateField[]) {
70         VMSTATE_UINT32_ARRAY(regs, IMX6SRCState, SRC_MAX),
71         VMSTATE_END_OF_LIST()
72     },
73 };
74 
75 static void imx6_src_reset(DeviceState *dev)
76 {
77     IMX6SRCState *s = IMX6_SRC(dev);
78 
79     trace_imx6_src_reset();
80 
81     memset(s->regs, 0, sizeof(s->regs));
82 
83     /* Set reset values */
84     s->regs[SRC_SCR] = 0x521;
85     s->regs[SRC_SRSR] = 0x1;
86     s->regs[SRC_SIMR] = 0x1F;
87 }
88 
89 static uint64_t imx6_src_read(void *opaque, hwaddr offset, unsigned size)
90 {
91     uint32_t value = 0;
92     IMX6SRCState *s = (IMX6SRCState *)opaque;
93     uint32_t index = offset >> 2;
94 
95     if (index < SRC_MAX) {
96         value = s->regs[index];
97     } else {
98         qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
99                       HWADDR_PRIx "\n", TYPE_IMX6_SRC, __func__, offset);
100 
101     }
102 
103     trace_imx6_src_read(imx6_src_reg_name(index), value);
104 
105     return value;
106 }
107 
108 
109 /* The reset is asynchronous so we need to defer clearing the reset
110  * bit until the work is completed.
111  */
112 
113 struct SRCSCRResetInfo {
114     IMX6SRCState *s;
115     int reset_bit;
116 };
117 
118 static void imx6_clear_reset_bit(CPUState *cpu, run_on_cpu_data data)
119 {
120     struct SRCSCRResetInfo *ri = data.host_ptr;
121     IMX6SRCState *s = ri->s;
122 
123     assert(bql_locked());
124 
125     s->regs[SRC_SCR] = deposit32(s->regs[SRC_SCR], ri->reset_bit, 1, 0);
126     trace_imx6_clear_reset_bit(imx6_src_reg_name(SRC_SCR), s->regs[SRC_SCR]);
127 
128     g_free(ri);
129 }
130 
131 static void imx6_defer_clear_reset_bit(int cpuid,
132                                        IMX6SRCState *s,
133                                        unsigned long reset_shift)
134 {
135     struct SRCSCRResetInfo *ri;
136     CPUState *cpu = arm_get_cpu_by_id(cpuid);
137 
138     if (!cpu) {
139         return;
140     }
141 
142     ri = g_new(struct SRCSCRResetInfo, 1);
143     ri->s = s;
144     ri->reset_bit = reset_shift;
145 
146     async_run_on_cpu(cpu, imx6_clear_reset_bit, RUN_ON_CPU_HOST_PTR(ri));
147 }
148 
149 
150 static void imx6_src_write(void *opaque, hwaddr offset, uint64_t value,
151                            unsigned size)
152 {
153     IMX6SRCState *s = (IMX6SRCState *)opaque;
154     uint32_t index = offset >> 2;
155     unsigned long change_mask;
156     unsigned long current_value = value;
157 
158     if (index >=  SRC_MAX) {
159         qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
160                       HWADDR_PRIx "\n", TYPE_IMX6_SRC, __func__, offset);
161         return;
162     }
163 
164     trace_imx6_src_write(imx6_src_reg_name(index), value);
165 
166     change_mask = s->regs[index] ^ (uint32_t)current_value;
167 
168     switch (index) {
169     case SRC_SCR:
170         /*
171          * On real hardware when the system reset controller starts a
172          * secondary CPU it runs through some boot ROM code which reads
173          * the SRC_GPRX registers controlling the start address and branches
174          * to it.
175          * Here we are taking a short cut and branching directly to the
176          * requested address (we don't want to run the boot ROM code inside
177          * QEMU)
178          */
179         if (EXTRACT(change_mask, CORE3_ENABLE)) {
180             if (EXTRACT(current_value, CORE3_ENABLE)) {
181                 /* CORE 3 is brought up */
182                 arm_set_cpu_on(3, s->regs[SRC_GPR7], s->regs[SRC_GPR8],
183                                3, false);
184             } else {
185                 /* CORE 3 is shut down */
186                 arm_set_cpu_off(3);
187             }
188             /* We clear the reset bits as the processor changed state */
189             imx6_defer_clear_reset_bit(3, s, CORE3_RST_SHIFT);
190             clear_bit(CORE3_RST_SHIFT, &change_mask);
191         }
192         if (EXTRACT(change_mask, CORE2_ENABLE)) {
193             if (EXTRACT(current_value, CORE2_ENABLE)) {
194                 /* CORE 2 is brought up */
195                 arm_set_cpu_on(2, s->regs[SRC_GPR5], s->regs[SRC_GPR6],
196                                3, false);
197             } else {
198                 /* CORE 2 is shut down */
199                 arm_set_cpu_off(2);
200             }
201             /* We clear the reset bits as the processor changed state */
202             imx6_defer_clear_reset_bit(2, s, CORE2_RST_SHIFT);
203             clear_bit(CORE2_RST_SHIFT, &change_mask);
204         }
205         if (EXTRACT(change_mask, CORE1_ENABLE)) {
206             if (EXTRACT(current_value, CORE1_ENABLE)) {
207                 /* CORE 1 is brought up */
208                 arm_set_cpu_on(1, s->regs[SRC_GPR3], s->regs[SRC_GPR4],
209                                3, false);
210             } else {
211                 /* CORE 1 is shut down */
212                 arm_set_cpu_off(1);
213             }
214             /* We clear the reset bits as the processor changed state */
215             imx6_defer_clear_reset_bit(1, s, CORE1_RST_SHIFT);
216             clear_bit(CORE1_RST_SHIFT, &change_mask);
217         }
218         if (EXTRACT(change_mask, CORE0_RST)) {
219             arm_reset_cpu(0);
220             imx6_defer_clear_reset_bit(0, s, CORE0_RST_SHIFT);
221         }
222         if (EXTRACT(change_mask, CORE1_RST)) {
223             arm_reset_cpu(1);
224             imx6_defer_clear_reset_bit(1, s, CORE1_RST_SHIFT);
225         }
226         if (EXTRACT(change_mask, CORE2_RST)) {
227             arm_reset_cpu(2);
228             imx6_defer_clear_reset_bit(2, s, CORE2_RST_SHIFT);
229         }
230         if (EXTRACT(change_mask, CORE3_RST)) {
231             arm_reset_cpu(3);
232             imx6_defer_clear_reset_bit(3, s, CORE3_RST_SHIFT);
233         }
234         if (EXTRACT(change_mask, SW_IPU2_RST)) {
235             /* We pretend the IPU2 is reset */
236             clear_bit(SW_IPU2_RST_SHIFT, &current_value);
237         }
238         if (EXTRACT(change_mask, SW_IPU1_RST)) {
239             /* We pretend the IPU1 is reset */
240             clear_bit(SW_IPU1_RST_SHIFT, &current_value);
241         }
242         s->regs[index] = current_value;
243         break;
244     default:
245         s->regs[index] = current_value;
246         break;
247     }
248 }
249 
250 static const struct MemoryRegionOps imx6_src_ops = {
251     .read = imx6_src_read,
252     .write = imx6_src_write,
253     .endianness = DEVICE_NATIVE_ENDIAN,
254     .valid = {
255         /*
256          * Our device would not work correctly if the guest was doing
257          * unaligned access. This might not be a limitation on the real
258          * device but in practice there is no reason for a guest to access
259          * this device unaligned.
260          */
261         .min_access_size = 4,
262         .max_access_size = 4,
263         .unaligned = false,
264     },
265 };
266 
267 static void imx6_src_realize(DeviceState *dev, Error **errp)
268 {
269     IMX6SRCState *s = IMX6_SRC(dev);
270 
271     memory_region_init_io(&s->iomem, OBJECT(dev), &imx6_src_ops, s,
272                           TYPE_IMX6_SRC, 0x1000);
273     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
274 }
275 
276 static void imx6_src_class_init(ObjectClass *klass, void *data)
277 {
278     DeviceClass *dc = DEVICE_CLASS(klass);
279 
280     dc->realize = imx6_src_realize;
281     device_class_set_legacy_reset(dc, imx6_src_reset);
282     dc->vmsd = &vmstate_imx6_src;
283     dc->desc = "i.MX6 System Reset Controller";
284 }
285 
286 static const TypeInfo imx6_src_info = {
287     .name          = TYPE_IMX6_SRC,
288     .parent        = TYPE_SYS_BUS_DEVICE,
289     .instance_size = sizeof(IMX6SRCState),
290     .class_init    = imx6_src_class_init,
291 };
292 
293 static void imx6_src_register_types(void)
294 {
295     type_register_static(&imx6_src_info);
296 }
297 
298 type_init(imx6_src_register_types)
299