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