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