2
0

imx6_src.c 8.9 KB

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