fsl-imx6ul.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
  1. /*
  2. * Copyright (c) 2018 Jean-Christophe Dubois <jcd@tribudubois.net>
  3. *
  4. * i.MX6UL SOC emulation.
  5. *
  6. * Based on hw/arm/fsl-imx7.c
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. */
  18. #include "qemu/osdep.h"
  19. #include "qapi/error.h"
  20. #include "hw/arm/fsl-imx6ul.h"
  21. #include "hw/misc/unimp.h"
  22. #include "hw/usb/imx-usb-phy.h"
  23. #include "hw/boards.h"
  24. #include "sysemu/sysemu.h"
  25. #include "qemu/error-report.h"
  26. #include "qemu/module.h"
  27. #include "target/arm/cpu-qom.h"
  28. #define NAME_SIZE 20
  29. static void fsl_imx6ul_init(Object *obj)
  30. {
  31. FslIMX6ULState *s = FSL_IMX6UL(obj);
  32. char name[NAME_SIZE];
  33. int i;
  34. object_initialize_child(obj, "cpu0", &s->cpu,
  35. ARM_CPU_TYPE_NAME("cortex-a7"));
  36. /*
  37. * A7MPCORE
  38. */
  39. object_initialize_child(obj, "a7mpcore", &s->a7mpcore,
  40. TYPE_A15MPCORE_PRIV);
  41. /*
  42. * CCM
  43. */
  44. object_initialize_child(obj, "ccm", &s->ccm, TYPE_IMX6UL_CCM);
  45. /*
  46. * SRC
  47. */
  48. object_initialize_child(obj, "src", &s->src, TYPE_IMX6_SRC);
  49. /*
  50. * GPCv2
  51. */
  52. object_initialize_child(obj, "gpcv2", &s->gpcv2, TYPE_IMX_GPCV2);
  53. /*
  54. * SNVS
  55. */
  56. object_initialize_child(obj, "snvs", &s->snvs, TYPE_IMX7_SNVS);
  57. /*
  58. * GPIOs
  59. */
  60. for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
  61. snprintf(name, NAME_SIZE, "gpio%d", i);
  62. object_initialize_child(obj, name, &s->gpio[i], TYPE_IMX_GPIO);
  63. }
  64. /*
  65. * GPTs
  66. */
  67. for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
  68. snprintf(name, NAME_SIZE, "gpt%d", i);
  69. object_initialize_child(obj, name, &s->gpt[i], TYPE_IMX6UL_GPT);
  70. }
  71. /*
  72. * EPITs
  73. */
  74. for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
  75. snprintf(name, NAME_SIZE, "epit%d", i + 1);
  76. object_initialize_child(obj, name, &s->epit[i], TYPE_IMX_EPIT);
  77. }
  78. /*
  79. * eCSPIs
  80. */
  81. for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) {
  82. snprintf(name, NAME_SIZE, "spi%d", i + 1);
  83. object_initialize_child(obj, name, &s->spi[i], TYPE_IMX_SPI);
  84. }
  85. /*
  86. * I2Cs
  87. */
  88. for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) {
  89. snprintf(name, NAME_SIZE, "i2c%d", i + 1);
  90. object_initialize_child(obj, name, &s->i2c[i], TYPE_IMX_I2C);
  91. }
  92. /*
  93. * UARTs
  94. */
  95. for (i = 0; i < FSL_IMX6UL_NUM_UARTS; i++) {
  96. snprintf(name, NAME_SIZE, "uart%d", i);
  97. object_initialize_child(obj, name, &s->uart[i], TYPE_IMX_SERIAL);
  98. }
  99. /*
  100. * Ethernets
  101. */
  102. for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
  103. snprintf(name, NAME_SIZE, "eth%d", i);
  104. object_initialize_child(obj, name, &s->eth[i], TYPE_IMX_ENET);
  105. }
  106. /*
  107. * USB PHYs
  108. */
  109. for (i = 0; i < FSL_IMX6UL_NUM_USB_PHYS; i++) {
  110. snprintf(name, NAME_SIZE, "usbphy%d", i);
  111. object_initialize_child(obj, name, &s->usbphy[i], TYPE_IMX_USBPHY);
  112. }
  113. /*
  114. * USBs
  115. */
  116. for (i = 0; i < FSL_IMX6UL_NUM_USBS; i++) {
  117. snprintf(name, NAME_SIZE, "usb%d", i);
  118. object_initialize_child(obj, name, &s->usb[i], TYPE_CHIPIDEA);
  119. }
  120. /*
  121. * SDHCIs
  122. */
  123. for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
  124. snprintf(name, NAME_SIZE, "usdhc%d", i);
  125. object_initialize_child(obj, name, &s->usdhc[i], TYPE_IMX_USDHC);
  126. }
  127. /*
  128. * Watchdogs
  129. */
  130. for (i = 0; i < FSL_IMX6UL_NUM_WDTS; i++) {
  131. snprintf(name, NAME_SIZE, "wdt%d", i);
  132. object_initialize_child(obj, name, &s->wdt[i], TYPE_IMX2_WDT);
  133. }
  134. }
  135. static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
  136. {
  137. MachineState *ms = MACHINE(qdev_get_machine());
  138. FslIMX6ULState *s = FSL_IMX6UL(dev);
  139. int i;
  140. char name[NAME_SIZE];
  141. SysBusDevice *sbd;
  142. DeviceState *d;
  143. if (ms->smp.cpus > 1) {
  144. error_setg(errp, "%s: Only a single CPU is supported (%d requested)",
  145. TYPE_FSL_IMX6UL, ms->smp.cpus);
  146. return;
  147. }
  148. qdev_realize(DEVICE(&s->cpu), NULL, &error_abort);
  149. /*
  150. * A7MPCORE
  151. */
  152. object_property_set_int(OBJECT(&s->a7mpcore), "num-cpu", 1, &error_abort);
  153. object_property_set_int(OBJECT(&s->a7mpcore), "num-irq",
  154. FSL_IMX6UL_MAX_IRQ + GIC_INTERNAL, &error_abort);
  155. sysbus_realize(SYS_BUS_DEVICE(&s->a7mpcore), &error_abort);
  156. sysbus_mmio_map(SYS_BUS_DEVICE(&s->a7mpcore), 0, FSL_IMX6UL_A7MPCORE_ADDR);
  157. sbd = SYS_BUS_DEVICE(&s->a7mpcore);
  158. d = DEVICE(&s->cpu);
  159. sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(d, ARM_CPU_IRQ));
  160. sysbus_connect_irq(sbd, 1, qdev_get_gpio_in(d, ARM_CPU_FIQ));
  161. sysbus_connect_irq(sbd, 2, qdev_get_gpio_in(d, ARM_CPU_VIRQ));
  162. sysbus_connect_irq(sbd, 3, qdev_get_gpio_in(d, ARM_CPU_VFIQ));
  163. /*
  164. * A7MPCORE DAP
  165. */
  166. create_unimplemented_device("a7mpcore-dap", FSL_IMX6UL_A7MPCORE_DAP_ADDR,
  167. FSL_IMX6UL_A7MPCORE_DAP_SIZE);
  168. /*
  169. * MMDC
  170. */
  171. create_unimplemented_device("a7mpcore-mmdc", FSL_IMX6UL_MMDC_CFG_ADDR,
  172. FSL_IMX6UL_MMDC_CFG_SIZE);
  173. /*
  174. * OCOTP
  175. */
  176. create_unimplemented_device("a7mpcore-ocotp", FSL_IMX6UL_OCOTP_CTRL_ADDR,
  177. FSL_IMX6UL_OCOTP_CTRL_SIZE);
  178. /*
  179. * QSPI
  180. */
  181. create_unimplemented_device("a7mpcore-qspi", FSL_IMX6UL_QSPI_ADDR,
  182. FSL_IMX6UL_QSPI_SIZE);
  183. /*
  184. * CAAM
  185. */
  186. create_unimplemented_device("a7mpcore-qspi", FSL_IMX6UL_CAAM_ADDR,
  187. FSL_IMX6UL_CAAM_SIZE);
  188. /*
  189. * USBMISC
  190. */
  191. create_unimplemented_device("a7mpcore-usbmisc", FSL_IMX6UL_USBO2_USBMISC_ADDR,
  192. FSL_IMX6UL_USBO2_USBMISC_SIZE);
  193. /*
  194. * GPTs
  195. */
  196. for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
  197. static const hwaddr FSL_IMX6UL_GPTn_ADDR[FSL_IMX6UL_NUM_GPTS] = {
  198. FSL_IMX6UL_GPT1_ADDR,
  199. FSL_IMX6UL_GPT2_ADDR,
  200. };
  201. static const int FSL_IMX6UL_GPTn_IRQ[FSL_IMX6UL_NUM_GPTS] = {
  202. FSL_IMX6UL_GPT1_IRQ,
  203. FSL_IMX6UL_GPT2_IRQ,
  204. };
  205. s->gpt[i].ccm = IMX_CCM(&s->ccm);
  206. sysbus_realize(SYS_BUS_DEVICE(&s->gpt[i]), &error_abort);
  207. sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt[i]), 0,
  208. FSL_IMX6UL_GPTn_ADDR[i]);
  209. sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0,
  210. qdev_get_gpio_in(DEVICE(&s->a7mpcore),
  211. FSL_IMX6UL_GPTn_IRQ[i]));
  212. }
  213. /*
  214. * EPITs
  215. */
  216. for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
  217. static const hwaddr FSL_IMX6UL_EPITn_ADDR[FSL_IMX6UL_NUM_EPITS] = {
  218. FSL_IMX6UL_EPIT1_ADDR,
  219. FSL_IMX6UL_EPIT2_ADDR,
  220. };
  221. static const int FSL_IMX6UL_EPITn_IRQ[FSL_IMX6UL_NUM_EPITS] = {
  222. FSL_IMX6UL_EPIT1_IRQ,
  223. FSL_IMX6UL_EPIT2_IRQ,
  224. };
  225. s->epit[i].ccm = IMX_CCM(&s->ccm);
  226. sysbus_realize(SYS_BUS_DEVICE(&s->epit[i]), &error_abort);
  227. sysbus_mmio_map(SYS_BUS_DEVICE(&s->epit[i]), 0,
  228. FSL_IMX6UL_EPITn_ADDR[i]);
  229. sysbus_connect_irq(SYS_BUS_DEVICE(&s->epit[i]), 0,
  230. qdev_get_gpio_in(DEVICE(&s->a7mpcore),
  231. FSL_IMX6UL_EPITn_IRQ[i]));
  232. }
  233. /*
  234. * GPIOs
  235. */
  236. for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
  237. static const hwaddr FSL_IMX6UL_GPIOn_ADDR[FSL_IMX6UL_NUM_GPIOS] = {
  238. FSL_IMX6UL_GPIO1_ADDR,
  239. FSL_IMX6UL_GPIO2_ADDR,
  240. FSL_IMX6UL_GPIO3_ADDR,
  241. FSL_IMX6UL_GPIO4_ADDR,
  242. FSL_IMX6UL_GPIO5_ADDR,
  243. };
  244. static const int FSL_IMX6UL_GPIOn_LOW_IRQ[FSL_IMX6UL_NUM_GPIOS] = {
  245. FSL_IMX6UL_GPIO1_LOW_IRQ,
  246. FSL_IMX6UL_GPIO2_LOW_IRQ,
  247. FSL_IMX6UL_GPIO3_LOW_IRQ,
  248. FSL_IMX6UL_GPIO4_LOW_IRQ,
  249. FSL_IMX6UL_GPIO5_LOW_IRQ,
  250. };
  251. static const int FSL_IMX6UL_GPIOn_HIGH_IRQ[FSL_IMX6UL_NUM_GPIOS] = {
  252. FSL_IMX6UL_GPIO1_HIGH_IRQ,
  253. FSL_IMX6UL_GPIO2_HIGH_IRQ,
  254. FSL_IMX6UL_GPIO3_HIGH_IRQ,
  255. FSL_IMX6UL_GPIO4_HIGH_IRQ,
  256. FSL_IMX6UL_GPIO5_HIGH_IRQ,
  257. };
  258. sysbus_realize(SYS_BUS_DEVICE(&s->gpio[i]), &error_abort);
  259. sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0,
  260. FSL_IMX6UL_GPIOn_ADDR[i]);
  261. sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0,
  262. qdev_get_gpio_in(DEVICE(&s->a7mpcore),
  263. FSL_IMX6UL_GPIOn_LOW_IRQ[i]));
  264. sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 1,
  265. qdev_get_gpio_in(DEVICE(&s->a7mpcore),
  266. FSL_IMX6UL_GPIOn_HIGH_IRQ[i]));
  267. }
  268. /*
  269. * IOMUXC
  270. */
  271. create_unimplemented_device("iomuxc", FSL_IMX6UL_IOMUXC_ADDR,
  272. FSL_IMX6UL_IOMUXC_SIZE);
  273. create_unimplemented_device("iomuxc_gpr", FSL_IMX6UL_IOMUXC_GPR_ADDR,
  274. FSL_IMX6UL_IOMUXC_GPR_SIZE);
  275. /*
  276. * CCM
  277. */
  278. sysbus_realize(SYS_BUS_DEVICE(&s->ccm), &error_abort);
  279. sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX6UL_CCM_ADDR);
  280. /*
  281. * SRC
  282. */
  283. sysbus_realize(SYS_BUS_DEVICE(&s->src), &error_abort);
  284. sysbus_mmio_map(SYS_BUS_DEVICE(&s->src), 0, FSL_IMX6UL_SRC_ADDR);
  285. /*
  286. * GPCv2
  287. */
  288. sysbus_realize(SYS_BUS_DEVICE(&s->gpcv2), &error_abort);
  289. sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpcv2), 0, FSL_IMX6UL_GPC_ADDR);
  290. /*
  291. * ECSPIs
  292. */
  293. for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) {
  294. static const hwaddr FSL_IMX6UL_SPIn_ADDR[FSL_IMX6UL_NUM_ECSPIS] = {
  295. FSL_IMX6UL_ECSPI1_ADDR,
  296. FSL_IMX6UL_ECSPI2_ADDR,
  297. FSL_IMX6UL_ECSPI3_ADDR,
  298. FSL_IMX6UL_ECSPI4_ADDR,
  299. };
  300. static const int FSL_IMX6UL_SPIn_IRQ[FSL_IMX6UL_NUM_ECSPIS] = {
  301. FSL_IMX6UL_ECSPI1_IRQ,
  302. FSL_IMX6UL_ECSPI2_IRQ,
  303. FSL_IMX6UL_ECSPI3_IRQ,
  304. FSL_IMX6UL_ECSPI4_IRQ,
  305. };
  306. /* Initialize the SPI */
  307. sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), &error_abort);
  308. sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0,
  309. FSL_IMX6UL_SPIn_ADDR[i]);
  310. sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0,
  311. qdev_get_gpio_in(DEVICE(&s->a7mpcore),
  312. FSL_IMX6UL_SPIn_IRQ[i]));
  313. }
  314. /*
  315. * I2Cs
  316. */
  317. for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) {
  318. static const hwaddr FSL_IMX6UL_I2Cn_ADDR[FSL_IMX6UL_NUM_I2CS] = {
  319. FSL_IMX6UL_I2C1_ADDR,
  320. FSL_IMX6UL_I2C2_ADDR,
  321. FSL_IMX6UL_I2C3_ADDR,
  322. FSL_IMX6UL_I2C4_ADDR,
  323. };
  324. static const int FSL_IMX6UL_I2Cn_IRQ[FSL_IMX6UL_NUM_I2CS] = {
  325. FSL_IMX6UL_I2C1_IRQ,
  326. FSL_IMX6UL_I2C2_IRQ,
  327. FSL_IMX6UL_I2C3_IRQ,
  328. FSL_IMX6UL_I2C4_IRQ,
  329. };
  330. sysbus_realize(SYS_BUS_DEVICE(&s->i2c[i]), &error_abort);
  331. sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, FSL_IMX6UL_I2Cn_ADDR[i]);
  332. sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
  333. qdev_get_gpio_in(DEVICE(&s->a7mpcore),
  334. FSL_IMX6UL_I2Cn_IRQ[i]));
  335. }
  336. /*
  337. * UARTs
  338. */
  339. for (i = 0; i < FSL_IMX6UL_NUM_UARTS; i++) {
  340. static const hwaddr FSL_IMX6UL_UARTn_ADDR[FSL_IMX6UL_NUM_UARTS] = {
  341. FSL_IMX6UL_UART1_ADDR,
  342. FSL_IMX6UL_UART2_ADDR,
  343. FSL_IMX6UL_UART3_ADDR,
  344. FSL_IMX6UL_UART4_ADDR,
  345. FSL_IMX6UL_UART5_ADDR,
  346. FSL_IMX6UL_UART6_ADDR,
  347. FSL_IMX6UL_UART7_ADDR,
  348. FSL_IMX6UL_UART8_ADDR,
  349. };
  350. static const int FSL_IMX6UL_UARTn_IRQ[FSL_IMX6UL_NUM_UARTS] = {
  351. FSL_IMX6UL_UART1_IRQ,
  352. FSL_IMX6UL_UART2_IRQ,
  353. FSL_IMX6UL_UART3_IRQ,
  354. FSL_IMX6UL_UART4_IRQ,
  355. FSL_IMX6UL_UART5_IRQ,
  356. FSL_IMX6UL_UART6_IRQ,
  357. FSL_IMX6UL_UART7_IRQ,
  358. FSL_IMX6UL_UART8_IRQ,
  359. };
  360. qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", serial_hd(i));
  361. sysbus_realize(SYS_BUS_DEVICE(&s->uart[i]), &error_abort);
  362. sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0,
  363. FSL_IMX6UL_UARTn_ADDR[i]);
  364. sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0,
  365. qdev_get_gpio_in(DEVICE(&s->a7mpcore),
  366. FSL_IMX6UL_UARTn_IRQ[i]));
  367. }
  368. /*
  369. * Ethernets
  370. *
  371. * We must use two loops since phy_connected affects the other interface
  372. * and we have to set all properties before calling sysbus_realize().
  373. */
  374. for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
  375. object_property_set_bool(OBJECT(&s->eth[i]), "phy-connected",
  376. s->phy_connected[i], &error_abort);
  377. /*
  378. * If the MDIO bus on this controller is not connected, assume the
  379. * other controller provides support for it.
  380. */
  381. if (!s->phy_connected[i]) {
  382. object_property_set_link(OBJECT(&s->eth[1 - i]), "phy-consumer",
  383. OBJECT(&s->eth[i]), &error_abort);
  384. }
  385. }
  386. for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
  387. static const hwaddr FSL_IMX6UL_ENETn_ADDR[FSL_IMX6UL_NUM_ETHS] = {
  388. FSL_IMX6UL_ENET1_ADDR,
  389. FSL_IMX6UL_ENET2_ADDR,
  390. };
  391. static const int FSL_IMX6UL_ENETn_IRQ[FSL_IMX6UL_NUM_ETHS] = {
  392. FSL_IMX6UL_ENET1_IRQ,
  393. FSL_IMX6UL_ENET2_IRQ,
  394. };
  395. static const int FSL_IMX6UL_ENETn_TIMER_IRQ[FSL_IMX6UL_NUM_ETHS] = {
  396. FSL_IMX6UL_ENET1_TIMER_IRQ,
  397. FSL_IMX6UL_ENET2_TIMER_IRQ,
  398. };
  399. object_property_set_uint(OBJECT(&s->eth[i]), "phy-num",
  400. s->phy_num[i], &error_abort);
  401. object_property_set_uint(OBJECT(&s->eth[i]), "tx-ring-num",
  402. FSL_IMX6UL_ETH_NUM_TX_RINGS, &error_abort);
  403. qemu_configure_nic_device(DEVICE(&s->eth[i]), true, NULL);
  404. sysbus_realize(SYS_BUS_DEVICE(&s->eth[i]), &error_abort);
  405. sysbus_mmio_map(SYS_BUS_DEVICE(&s->eth[i]), 0,
  406. FSL_IMX6UL_ENETn_ADDR[i]);
  407. sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 0,
  408. qdev_get_gpio_in(DEVICE(&s->a7mpcore),
  409. FSL_IMX6UL_ENETn_IRQ[i]));
  410. sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 1,
  411. qdev_get_gpio_in(DEVICE(&s->a7mpcore),
  412. FSL_IMX6UL_ENETn_TIMER_IRQ[i]));
  413. }
  414. /*
  415. * USB PHYs
  416. */
  417. for (i = 0; i < FSL_IMX6UL_NUM_USB_PHYS; i++) {
  418. static const hwaddr
  419. FSL_IMX6UL_USB_PHYn_ADDR[FSL_IMX6UL_NUM_USB_PHYS] = {
  420. FSL_IMX6UL_USBPHY1_ADDR,
  421. FSL_IMX6UL_USBPHY2_ADDR,
  422. };
  423. sysbus_realize(SYS_BUS_DEVICE(&s->usbphy[i]), &error_abort);
  424. sysbus_mmio_map(SYS_BUS_DEVICE(&s->usbphy[i]), 0,
  425. FSL_IMX6UL_USB_PHYn_ADDR[i]);
  426. }
  427. /*
  428. * USBs
  429. */
  430. for (i = 0; i < FSL_IMX6UL_NUM_USBS; i++) {
  431. static const hwaddr FSL_IMX6UL_USB02_USBn_ADDR[FSL_IMX6UL_NUM_USBS] = {
  432. FSL_IMX6UL_USBO2_USB1_ADDR,
  433. FSL_IMX6UL_USBO2_USB2_ADDR,
  434. };
  435. static const int FSL_IMX6UL_USBn_IRQ[] = {
  436. FSL_IMX6UL_USB1_IRQ,
  437. FSL_IMX6UL_USB2_IRQ,
  438. };
  439. sysbus_realize(SYS_BUS_DEVICE(&s->usb[i]), &error_abort);
  440. sysbus_mmio_map(SYS_BUS_DEVICE(&s->usb[i]), 0,
  441. FSL_IMX6UL_USB02_USBn_ADDR[i]);
  442. sysbus_connect_irq(SYS_BUS_DEVICE(&s->usb[i]), 0,
  443. qdev_get_gpio_in(DEVICE(&s->a7mpcore),
  444. FSL_IMX6UL_USBn_IRQ[i]));
  445. }
  446. /*
  447. * USDHCs
  448. */
  449. for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
  450. static const hwaddr FSL_IMX6UL_USDHCn_ADDR[FSL_IMX6UL_NUM_USDHCS] = {
  451. FSL_IMX6UL_USDHC1_ADDR,
  452. FSL_IMX6UL_USDHC2_ADDR,
  453. };
  454. static const int FSL_IMX6UL_USDHCn_IRQ[FSL_IMX6UL_NUM_USDHCS] = {
  455. FSL_IMX6UL_USDHC1_IRQ,
  456. FSL_IMX6UL_USDHC2_IRQ,
  457. };
  458. object_property_set_uint(OBJECT(&s->usdhc[i]), "vendor",
  459. SDHCI_VENDOR_IMX, &error_abort);
  460. sysbus_realize(SYS_BUS_DEVICE(&s->usdhc[i]), &error_abort);
  461. sysbus_mmio_map(SYS_BUS_DEVICE(&s->usdhc[i]), 0,
  462. FSL_IMX6UL_USDHCn_ADDR[i]);
  463. sysbus_connect_irq(SYS_BUS_DEVICE(&s->usdhc[i]), 0,
  464. qdev_get_gpio_in(DEVICE(&s->a7mpcore),
  465. FSL_IMX6UL_USDHCn_IRQ[i]));
  466. }
  467. /*
  468. * SNVS
  469. */
  470. sysbus_realize(SYS_BUS_DEVICE(&s->snvs), &error_abort);
  471. sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0, FSL_IMX6UL_SNVS_HP_ADDR);
  472. /*
  473. * Watchdogs
  474. */
  475. for (i = 0; i < FSL_IMX6UL_NUM_WDTS; i++) {
  476. static const hwaddr FSL_IMX6UL_WDOGn_ADDR[FSL_IMX6UL_NUM_WDTS] = {
  477. FSL_IMX6UL_WDOG1_ADDR,
  478. FSL_IMX6UL_WDOG2_ADDR,
  479. FSL_IMX6UL_WDOG3_ADDR,
  480. };
  481. static const int FSL_IMX6UL_WDOGn_IRQ[FSL_IMX6UL_NUM_WDTS] = {
  482. FSL_IMX6UL_WDOG1_IRQ,
  483. FSL_IMX6UL_WDOG2_IRQ,
  484. FSL_IMX6UL_WDOG3_IRQ,
  485. };
  486. object_property_set_bool(OBJECT(&s->wdt[i]), "pretimeout-support",
  487. true, &error_abort);
  488. sysbus_realize(SYS_BUS_DEVICE(&s->wdt[i]), &error_abort);
  489. sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0,
  490. FSL_IMX6UL_WDOGn_ADDR[i]);
  491. sysbus_connect_irq(SYS_BUS_DEVICE(&s->wdt[i]), 0,
  492. qdev_get_gpio_in(DEVICE(&s->a7mpcore),
  493. FSL_IMX6UL_WDOGn_IRQ[i]));
  494. }
  495. /*
  496. * SDMA
  497. */
  498. create_unimplemented_device("sdma", FSL_IMX6UL_SDMA_ADDR,
  499. FSL_IMX6UL_SDMA_SIZE);
  500. /*
  501. * SAIs (Audio SSI (Synchronous Serial Interface))
  502. */
  503. for (i = 0; i < FSL_IMX6UL_NUM_SAIS; i++) {
  504. static const hwaddr FSL_IMX6UL_SAIn_ADDR[FSL_IMX6UL_NUM_SAIS] = {
  505. FSL_IMX6UL_SAI1_ADDR,
  506. FSL_IMX6UL_SAI2_ADDR,
  507. FSL_IMX6UL_SAI3_ADDR,
  508. };
  509. snprintf(name, NAME_SIZE, "sai%d", i);
  510. create_unimplemented_device(name, FSL_IMX6UL_SAIn_ADDR[i],
  511. FSL_IMX6UL_SAIn_SIZE);
  512. }
  513. /*
  514. * PWMs
  515. */
  516. for (i = 0; i < FSL_IMX6UL_NUM_PWMS; i++) {
  517. static const hwaddr FSL_IMX6UL_PWMn_ADDR[FSL_IMX6UL_NUM_PWMS] = {
  518. FSL_IMX6UL_PWM1_ADDR,
  519. FSL_IMX6UL_PWM2_ADDR,
  520. FSL_IMX6UL_PWM3_ADDR,
  521. FSL_IMX6UL_PWM4_ADDR,
  522. FSL_IMX6UL_PWM5_ADDR,
  523. FSL_IMX6UL_PWM6_ADDR,
  524. FSL_IMX6UL_PWM7_ADDR,
  525. FSL_IMX6UL_PWM8_ADDR,
  526. };
  527. snprintf(name, NAME_SIZE, "pwm%d", i);
  528. create_unimplemented_device(name, FSL_IMX6UL_PWMn_ADDR[i],
  529. FSL_IMX6UL_PWMn_SIZE);
  530. }
  531. /*
  532. * Audio ASRC (asynchronous sample rate converter)
  533. */
  534. create_unimplemented_device("asrc", FSL_IMX6UL_ASRC_ADDR,
  535. FSL_IMX6UL_ASRC_SIZE);
  536. /*
  537. * CANs
  538. */
  539. for (i = 0; i < FSL_IMX6UL_NUM_CANS; i++) {
  540. static const hwaddr FSL_IMX6UL_CANn_ADDR[FSL_IMX6UL_NUM_CANS] = {
  541. FSL_IMX6UL_CAN1_ADDR,
  542. FSL_IMX6UL_CAN2_ADDR,
  543. };
  544. snprintf(name, NAME_SIZE, "can%d", i);
  545. create_unimplemented_device(name, FSL_IMX6UL_CANn_ADDR[i],
  546. FSL_IMX6UL_CANn_SIZE);
  547. }
  548. /*
  549. * APHB_DMA
  550. */
  551. create_unimplemented_device("aphb_dma", FSL_IMX6UL_APBH_DMA_ADDR,
  552. FSL_IMX6UL_APBH_DMA_SIZE);
  553. /*
  554. * ADCs
  555. */
  556. for (i = 0; i < FSL_IMX6UL_NUM_ADCS; i++) {
  557. static const hwaddr FSL_IMX6UL_ADCn_ADDR[FSL_IMX6UL_NUM_ADCS] = {
  558. FSL_IMX6UL_ADC1_ADDR,
  559. FSL_IMX6UL_ADC2_ADDR,
  560. };
  561. snprintf(name, NAME_SIZE, "adc%d", i);
  562. create_unimplemented_device(name, FSL_IMX6UL_ADCn_ADDR[i],
  563. FSL_IMX6UL_ADCn_SIZE);
  564. }
  565. /*
  566. * LCD
  567. */
  568. create_unimplemented_device("lcdif", FSL_IMX6UL_LCDIF_ADDR,
  569. FSL_IMX6UL_LCDIF_SIZE);
  570. /*
  571. * CSU
  572. */
  573. create_unimplemented_device("csu", FSL_IMX6UL_CSU_ADDR,
  574. FSL_IMX6UL_CSU_SIZE);
  575. /*
  576. * TZASC
  577. */
  578. create_unimplemented_device("tzasc", FSL_IMX6UL_TZASC_ADDR,
  579. FSL_IMX6UL_TZASC_SIZE);
  580. /*
  581. * ROM memory
  582. */
  583. memory_region_init_rom(&s->rom, OBJECT(dev), "imx6ul.rom",
  584. FSL_IMX6UL_ROM_SIZE, &error_abort);
  585. memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_ROM_ADDR,
  586. &s->rom);
  587. /*
  588. * CAAM memory
  589. */
  590. memory_region_init_rom(&s->caam, OBJECT(dev), "imx6ul.caam",
  591. FSL_IMX6UL_CAAM_MEM_SIZE, &error_abort);
  592. memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_CAAM_MEM_ADDR,
  593. &s->caam);
  594. /*
  595. * OCRAM memory
  596. */
  597. memory_region_init_ram(&s->ocram, NULL, "imx6ul.ocram",
  598. FSL_IMX6UL_OCRAM_MEM_SIZE,
  599. &error_abort);
  600. memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_OCRAM_MEM_ADDR,
  601. &s->ocram);
  602. /*
  603. * internal OCRAM (128 KB) is aliased over 512 KB
  604. */
  605. memory_region_init_alias(&s->ocram_alias, OBJECT(dev),
  606. "imx6ul.ocram_alias", &s->ocram, 0,
  607. FSL_IMX6UL_OCRAM_ALIAS_SIZE);
  608. memory_region_add_subregion(get_system_memory(),
  609. FSL_IMX6UL_OCRAM_ALIAS_ADDR, &s->ocram_alias);
  610. }
  611. static const Property fsl_imx6ul_properties[] = {
  612. DEFINE_PROP_UINT32("fec1-phy-num", FslIMX6ULState, phy_num[0], 0),
  613. DEFINE_PROP_UINT32("fec2-phy-num", FslIMX6ULState, phy_num[1], 1),
  614. DEFINE_PROP_BOOL("fec1-phy-connected", FslIMX6ULState, phy_connected[0],
  615. true),
  616. DEFINE_PROP_BOOL("fec2-phy-connected", FslIMX6ULState, phy_connected[1],
  617. true),
  618. };
  619. static void fsl_imx6ul_class_init(ObjectClass *oc, void *data)
  620. {
  621. DeviceClass *dc = DEVICE_CLASS(oc);
  622. device_class_set_props(dc, fsl_imx6ul_properties);
  623. dc->realize = fsl_imx6ul_realize;
  624. dc->desc = "i.MX6UL SOC";
  625. /* Reason: Uses serial_hds and nd_table in realize() directly */
  626. dc->user_creatable = false;
  627. }
  628. static const TypeInfo fsl_imx6ul_type_info = {
  629. .name = TYPE_FSL_IMX6UL,
  630. .parent = TYPE_DEVICE,
  631. .instance_size = sizeof(FslIMX6ULState),
  632. .instance_init = fsl_imx6ul_init,
  633. .class_init = fsl_imx6ul_class_init,
  634. };
  635. static void fsl_imx6ul_register_types(void)
  636. {
  637. type_register_static(&fsl_imx6ul_type_info);
  638. }
  639. type_init(fsl_imx6ul_register_types)