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