2
0

fsl-imx7.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775
  1. /*
  2. * Copyright (c) 2018, Impinj, Inc.
  3. *
  4. * i.MX7 SoC definitions
  5. *
  6. * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
  7. *
  8. * Based on hw/arm/fsl-imx6.c
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. */
  20. #include "qemu/osdep.h"
  21. #include "qapi/error.h"
  22. #include "hw/arm/fsl-imx7.h"
  23. #include "hw/misc/unimp.h"
  24. #include "hw/boards.h"
  25. #include "system/system.h"
  26. #include "qemu/error-report.h"
  27. #include "qemu/module.h"
  28. #include "target/arm/cpu-qom.h"
  29. #define NAME_SIZE 20
  30. static void fsl_imx7_init(Object *obj)
  31. {
  32. MachineState *ms = MACHINE(qdev_get_machine());
  33. FslIMX7State *s = FSL_IMX7(obj);
  34. char name[NAME_SIZE];
  35. int i;
  36. /*
  37. * CPUs
  38. */
  39. for (i = 0; i < MIN(ms->smp.cpus, FSL_IMX7_NUM_CPUS); i++) {
  40. snprintf(name, NAME_SIZE, "cpu%d", i);
  41. object_initialize_child(obj, name, &s->cpu[i],
  42. ARM_CPU_TYPE_NAME("cortex-a7"));
  43. }
  44. /*
  45. * A7MPCORE
  46. */
  47. object_initialize_child(obj, "a7mpcore", &s->a7mpcore,
  48. TYPE_A15MPCORE_PRIV);
  49. /*
  50. * GPIOs
  51. */
  52. for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
  53. snprintf(name, NAME_SIZE, "gpio%d", i);
  54. object_initialize_child(obj, name, &s->gpio[i], TYPE_IMX_GPIO);
  55. }
  56. /*
  57. * GPTs
  58. */
  59. for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
  60. snprintf(name, NAME_SIZE, "gpt%d", i);
  61. object_initialize_child(obj, name, &s->gpt[i], TYPE_IMX7_GPT);
  62. }
  63. /*
  64. * CCM
  65. */
  66. object_initialize_child(obj, "ccm", &s->ccm, TYPE_IMX7_CCM);
  67. /*
  68. * Analog
  69. */
  70. object_initialize_child(obj, "analog", &s->analog, TYPE_IMX7_ANALOG);
  71. /*
  72. * GPCv2
  73. */
  74. object_initialize_child(obj, "gpcv2", &s->gpcv2, TYPE_IMX_GPCV2);
  75. /*
  76. * SRC
  77. */
  78. object_initialize_child(obj, "src", &s->src, TYPE_IMX7_SRC);
  79. /*
  80. * ECSPIs
  81. */
  82. for (i = 0; i < FSL_IMX7_NUM_ECSPIS; i++) {
  83. snprintf(name, NAME_SIZE, "spi%d", i + 1);
  84. object_initialize_child(obj, name, &s->spi[i], TYPE_IMX_SPI);
  85. }
  86. /*
  87. * I2Cs
  88. */
  89. for (i = 0; i < FSL_IMX7_NUM_I2CS; i++) {
  90. snprintf(name, NAME_SIZE, "i2c%d", i + 1);
  91. object_initialize_child(obj, name, &s->i2c[i], TYPE_IMX_I2C);
  92. }
  93. /*
  94. * UARTs
  95. */
  96. for (i = 0; i < FSL_IMX7_NUM_UARTS; i++) {
  97. snprintf(name, NAME_SIZE, "uart%d", i);
  98. object_initialize_child(obj, name, &s->uart[i], TYPE_IMX_SERIAL);
  99. }
  100. /*
  101. * Ethernets
  102. */
  103. for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
  104. snprintf(name, NAME_SIZE, "eth%d", i);
  105. object_initialize_child(obj, name, &s->eth[i], TYPE_IMX_ENET);
  106. }
  107. /*
  108. * SDHCIs
  109. */
  110. for (i = 0; i < FSL_IMX7_NUM_USDHCS; i++) {
  111. snprintf(name, NAME_SIZE, "usdhc%d", i);
  112. object_initialize_child(obj, name, &s->usdhc[i], TYPE_IMX_USDHC);
  113. }
  114. /*
  115. * SNVS
  116. */
  117. object_initialize_child(obj, "snvs", &s->snvs, TYPE_IMX7_SNVS);
  118. /*
  119. * Watchdogs
  120. */
  121. for (i = 0; i < FSL_IMX7_NUM_WDTS; i++) {
  122. snprintf(name, NAME_SIZE, "wdt%d", i);
  123. object_initialize_child(obj, name, &s->wdt[i], TYPE_IMX2_WDT);
  124. }
  125. /*
  126. * GPR
  127. */
  128. object_initialize_child(obj, "gpr", &s->gpr, TYPE_IMX7_GPR);
  129. /*
  130. * PCIE
  131. */
  132. object_initialize_child(obj, "pcie", &s->pcie, TYPE_DESIGNWARE_PCIE_HOST);
  133. object_initialize_child(obj, "pcie4-msi-irq", &s->pcie4_msi_irq,
  134. TYPE_OR_IRQ);
  135. /*
  136. * USBs
  137. */
  138. for (i = 0; i < FSL_IMX7_NUM_USBS; i++) {
  139. snprintf(name, NAME_SIZE, "usb%d", i);
  140. object_initialize_child(obj, name, &s->usb[i], TYPE_CHIPIDEA);
  141. }
  142. }
  143. static void fsl_imx7_realize(DeviceState *dev, Error **errp)
  144. {
  145. MachineState *ms = MACHINE(qdev_get_machine());
  146. FslIMX7State *s = FSL_IMX7(dev);
  147. DeviceState *mpcore = DEVICE(&s->a7mpcore);
  148. DeviceState *gic;
  149. int i;
  150. qemu_irq irq;
  151. char name[NAME_SIZE];
  152. unsigned int smp_cpus = ms->smp.cpus;
  153. if (smp_cpus > FSL_IMX7_NUM_CPUS) {
  154. error_setg(errp, "%s: Only %d CPUs are supported (%d requested)",
  155. TYPE_FSL_IMX7, FSL_IMX7_NUM_CPUS, smp_cpus);
  156. return;
  157. }
  158. /*
  159. * CPUs
  160. */
  161. for (i = 0; i < smp_cpus; i++) {
  162. Object *o = OBJECT(&s->cpu[i]);
  163. /* On uniprocessor, the CBAR is set to 0 */
  164. if (smp_cpus > 1) {
  165. object_property_set_int(o, "reset-cbar", FSL_IMX7_A7MPCORE_ADDR,
  166. &error_abort);
  167. }
  168. if (i) {
  169. /*
  170. * Secondary CPUs start in powered-down state (and can be
  171. * powered up via the SRC system reset controller)
  172. */
  173. object_property_set_bool(o, "start-powered-off", true,
  174. &error_abort);
  175. }
  176. qdev_realize(DEVICE(o), NULL, &error_abort);
  177. }
  178. /*
  179. * A7MPCORE
  180. */
  181. object_property_set_int(OBJECT(mpcore), "num-cpu", smp_cpus, &error_abort);
  182. object_property_set_int(OBJECT(mpcore), "num-irq",
  183. FSL_IMX7_MAX_IRQ + GIC_INTERNAL, &error_abort);
  184. sysbus_realize(SYS_BUS_DEVICE(mpcore), &error_abort);
  185. sysbus_mmio_map(SYS_BUS_DEVICE(mpcore), 0, FSL_IMX7_A7MPCORE_ADDR);
  186. gic = mpcore;
  187. for (i = 0; i < smp_cpus; i++) {
  188. SysBusDevice *sbd = SYS_BUS_DEVICE(gic);
  189. DeviceState *d = DEVICE(qemu_get_cpu(i));
  190. irq = qdev_get_gpio_in(d, ARM_CPU_IRQ);
  191. sysbus_connect_irq(sbd, i, irq);
  192. irq = qdev_get_gpio_in(d, ARM_CPU_FIQ);
  193. sysbus_connect_irq(sbd, i + smp_cpus, irq);
  194. irq = qdev_get_gpio_in(d, ARM_CPU_VIRQ);
  195. sysbus_connect_irq(sbd, i + 2 * smp_cpus, irq);
  196. irq = qdev_get_gpio_in(d, ARM_CPU_VFIQ);
  197. sysbus_connect_irq(sbd, i + 3 * smp_cpus, irq);
  198. }
  199. /*
  200. * A7MPCORE DAP
  201. */
  202. create_unimplemented_device("a7mpcore-dap", FSL_IMX7_A7MPCORE_DAP_ADDR,
  203. FSL_IMX7_A7MPCORE_DAP_SIZE);
  204. /*
  205. * GPTs
  206. */
  207. for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
  208. static const hwaddr FSL_IMX7_GPTn_ADDR[FSL_IMX7_NUM_GPTS] = {
  209. FSL_IMX7_GPT1_ADDR,
  210. FSL_IMX7_GPT2_ADDR,
  211. FSL_IMX7_GPT3_ADDR,
  212. FSL_IMX7_GPT4_ADDR,
  213. };
  214. static const int FSL_IMX7_GPTn_IRQ[FSL_IMX7_NUM_GPTS] = {
  215. FSL_IMX7_GPT1_IRQ,
  216. FSL_IMX7_GPT2_IRQ,
  217. FSL_IMX7_GPT3_IRQ,
  218. FSL_IMX7_GPT4_IRQ,
  219. };
  220. s->gpt[i].ccm = IMX_CCM(&s->ccm);
  221. sysbus_realize(SYS_BUS_DEVICE(&s->gpt[i]), &error_abort);
  222. sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt[i]), 0, FSL_IMX7_GPTn_ADDR[i]);
  223. sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0,
  224. qdev_get_gpio_in(gic, FSL_IMX7_GPTn_IRQ[i]));
  225. }
  226. /*
  227. * GPIOs
  228. */
  229. for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
  230. static const hwaddr FSL_IMX7_GPIOn_ADDR[FSL_IMX7_NUM_GPIOS] = {
  231. FSL_IMX7_GPIO1_ADDR,
  232. FSL_IMX7_GPIO2_ADDR,
  233. FSL_IMX7_GPIO3_ADDR,
  234. FSL_IMX7_GPIO4_ADDR,
  235. FSL_IMX7_GPIO5_ADDR,
  236. FSL_IMX7_GPIO6_ADDR,
  237. FSL_IMX7_GPIO7_ADDR,
  238. };
  239. static const int FSL_IMX7_GPIOn_LOW_IRQ[FSL_IMX7_NUM_GPIOS] = {
  240. FSL_IMX7_GPIO1_LOW_IRQ,
  241. FSL_IMX7_GPIO2_LOW_IRQ,
  242. FSL_IMX7_GPIO3_LOW_IRQ,
  243. FSL_IMX7_GPIO4_LOW_IRQ,
  244. FSL_IMX7_GPIO5_LOW_IRQ,
  245. FSL_IMX7_GPIO6_LOW_IRQ,
  246. FSL_IMX7_GPIO7_LOW_IRQ,
  247. };
  248. static const int FSL_IMX7_GPIOn_HIGH_IRQ[FSL_IMX7_NUM_GPIOS] = {
  249. FSL_IMX7_GPIO1_HIGH_IRQ,
  250. FSL_IMX7_GPIO2_HIGH_IRQ,
  251. FSL_IMX7_GPIO3_HIGH_IRQ,
  252. FSL_IMX7_GPIO4_HIGH_IRQ,
  253. FSL_IMX7_GPIO5_HIGH_IRQ,
  254. FSL_IMX7_GPIO6_HIGH_IRQ,
  255. FSL_IMX7_GPIO7_HIGH_IRQ,
  256. };
  257. sysbus_realize(SYS_BUS_DEVICE(&s->gpio[i]), &error_abort);
  258. sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0,
  259. FSL_IMX7_GPIOn_ADDR[i]);
  260. sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0,
  261. qdev_get_gpio_in(gic, FSL_IMX7_GPIOn_LOW_IRQ[i]));
  262. sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 1,
  263. qdev_get_gpio_in(gic, FSL_IMX7_GPIOn_HIGH_IRQ[i]));
  264. }
  265. /*
  266. * IOMUXC and IOMUXC_LPSR
  267. */
  268. create_unimplemented_device("iomuxc", FSL_IMX7_IOMUXC_ADDR,
  269. FSL_IMX7_IOMUXC_SIZE);
  270. create_unimplemented_device("iomuxc_lspr", FSL_IMX7_IOMUXC_LPSR_ADDR,
  271. FSL_IMX7_IOMUXC_LPSR_SIZE);
  272. /*
  273. * CCM
  274. */
  275. sysbus_realize(SYS_BUS_DEVICE(&s->ccm), &error_abort);
  276. sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX7_CCM_ADDR);
  277. /*
  278. * Analog
  279. */
  280. sysbus_realize(SYS_BUS_DEVICE(&s->analog), &error_abort);
  281. sysbus_mmio_map(SYS_BUS_DEVICE(&s->analog), 0, FSL_IMX7_ANALOG_ADDR);
  282. /*
  283. * GPCv2
  284. */
  285. sysbus_realize(SYS_BUS_DEVICE(&s->gpcv2), &error_abort);
  286. sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpcv2), 0, FSL_IMX7_GPC_ADDR);
  287. /*
  288. * ECSPIs
  289. */
  290. for (i = 0; i < FSL_IMX7_NUM_ECSPIS; i++) {
  291. static const hwaddr FSL_IMX7_SPIn_ADDR[FSL_IMX7_NUM_ECSPIS] = {
  292. FSL_IMX7_ECSPI1_ADDR,
  293. FSL_IMX7_ECSPI2_ADDR,
  294. FSL_IMX7_ECSPI3_ADDR,
  295. FSL_IMX7_ECSPI4_ADDR,
  296. };
  297. static const int FSL_IMX7_SPIn_IRQ[FSL_IMX7_NUM_ECSPIS] = {
  298. FSL_IMX7_ECSPI1_IRQ,
  299. FSL_IMX7_ECSPI2_IRQ,
  300. FSL_IMX7_ECSPI3_IRQ,
  301. FSL_IMX7_ECSPI4_IRQ,
  302. };
  303. /* Initialize the SPI */
  304. sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), &error_abort);
  305. sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0,
  306. FSL_IMX7_SPIn_ADDR[i]);
  307. sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0,
  308. qdev_get_gpio_in(gic, FSL_IMX7_SPIn_IRQ[i]));
  309. }
  310. /*
  311. * I2Cs
  312. */
  313. for (i = 0; i < FSL_IMX7_NUM_I2CS; i++) {
  314. static const hwaddr FSL_IMX7_I2Cn_ADDR[FSL_IMX7_NUM_I2CS] = {
  315. FSL_IMX7_I2C1_ADDR,
  316. FSL_IMX7_I2C2_ADDR,
  317. FSL_IMX7_I2C3_ADDR,
  318. FSL_IMX7_I2C4_ADDR,
  319. };
  320. static const int FSL_IMX7_I2Cn_IRQ[FSL_IMX7_NUM_I2CS] = {
  321. FSL_IMX7_I2C1_IRQ,
  322. FSL_IMX7_I2C2_IRQ,
  323. FSL_IMX7_I2C3_IRQ,
  324. FSL_IMX7_I2C4_IRQ,
  325. };
  326. sysbus_realize(SYS_BUS_DEVICE(&s->i2c[i]), &error_abort);
  327. sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, FSL_IMX7_I2Cn_ADDR[i]);
  328. sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
  329. qdev_get_gpio_in(gic, FSL_IMX7_I2Cn_IRQ[i]));
  330. }
  331. /*
  332. * UARTs
  333. */
  334. for (i = 0; i < FSL_IMX7_NUM_UARTS; i++) {
  335. static const hwaddr FSL_IMX7_UARTn_ADDR[FSL_IMX7_NUM_UARTS] = {
  336. FSL_IMX7_UART1_ADDR,
  337. FSL_IMX7_UART2_ADDR,
  338. FSL_IMX7_UART3_ADDR,
  339. FSL_IMX7_UART4_ADDR,
  340. FSL_IMX7_UART5_ADDR,
  341. FSL_IMX7_UART6_ADDR,
  342. FSL_IMX7_UART7_ADDR,
  343. };
  344. static const int FSL_IMX7_UARTn_IRQ[FSL_IMX7_NUM_UARTS] = {
  345. FSL_IMX7_UART1_IRQ,
  346. FSL_IMX7_UART2_IRQ,
  347. FSL_IMX7_UART3_IRQ,
  348. FSL_IMX7_UART4_IRQ,
  349. FSL_IMX7_UART5_IRQ,
  350. FSL_IMX7_UART6_IRQ,
  351. FSL_IMX7_UART7_IRQ,
  352. };
  353. qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", serial_hd(i));
  354. sysbus_realize(SYS_BUS_DEVICE(&s->uart[i]), &error_abort);
  355. sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, FSL_IMX7_UARTn_ADDR[i]);
  356. irq = qdev_get_gpio_in(gic, FSL_IMX7_UARTn_IRQ[i]);
  357. sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0, irq);
  358. }
  359. /*
  360. * Ethernets
  361. *
  362. * We must use two loops since phy_connected affects the other interface
  363. * and we have to set all properties before calling sysbus_realize().
  364. */
  365. for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
  366. object_property_set_bool(OBJECT(&s->eth[i]), "phy-connected",
  367. s->phy_connected[i], &error_abort);
  368. /*
  369. * If the MDIO bus on this controller is not connected, assume the
  370. * other controller provides support for it.
  371. */
  372. if (!s->phy_connected[i]) {
  373. object_property_set_link(OBJECT(&s->eth[1 - i]), "phy-consumer",
  374. OBJECT(&s->eth[i]), &error_abort);
  375. }
  376. }
  377. for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
  378. static const hwaddr FSL_IMX7_ENETn_ADDR[FSL_IMX7_NUM_ETHS] = {
  379. FSL_IMX7_ENET1_ADDR,
  380. FSL_IMX7_ENET2_ADDR,
  381. };
  382. object_property_set_uint(OBJECT(&s->eth[i]), "phy-num",
  383. s->phy_num[i], &error_abort);
  384. object_property_set_uint(OBJECT(&s->eth[i]), "tx-ring-num",
  385. FSL_IMX7_ETH_NUM_TX_RINGS, &error_abort);
  386. qemu_configure_nic_device(DEVICE(&s->eth[i]), true, NULL);
  387. sysbus_realize(SYS_BUS_DEVICE(&s->eth[i]), &error_abort);
  388. sysbus_mmio_map(SYS_BUS_DEVICE(&s->eth[i]), 0, FSL_IMX7_ENETn_ADDR[i]);
  389. irq = qdev_get_gpio_in(gic, FSL_IMX7_ENET_IRQ(i, 0));
  390. sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 0, irq);
  391. irq = qdev_get_gpio_in(gic, FSL_IMX7_ENET_IRQ(i, 3));
  392. sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 1, irq);
  393. }
  394. /*
  395. * USDHCs
  396. */
  397. for (i = 0; i < FSL_IMX7_NUM_USDHCS; i++) {
  398. static const hwaddr FSL_IMX7_USDHCn_ADDR[FSL_IMX7_NUM_USDHCS] = {
  399. FSL_IMX7_USDHC1_ADDR,
  400. FSL_IMX7_USDHC2_ADDR,
  401. FSL_IMX7_USDHC3_ADDR,
  402. };
  403. static const int FSL_IMX7_USDHCn_IRQ[FSL_IMX7_NUM_USDHCS] = {
  404. FSL_IMX7_USDHC1_IRQ,
  405. FSL_IMX7_USDHC2_IRQ,
  406. FSL_IMX7_USDHC3_IRQ,
  407. };
  408. sysbus_realize(SYS_BUS_DEVICE(&s->usdhc[i]), &error_abort);
  409. sysbus_mmio_map(SYS_BUS_DEVICE(&s->usdhc[i]), 0,
  410. FSL_IMX7_USDHCn_ADDR[i]);
  411. irq = qdev_get_gpio_in(gic, FSL_IMX7_USDHCn_IRQ[i]);
  412. sysbus_connect_irq(SYS_BUS_DEVICE(&s->usdhc[i]), 0, irq);
  413. }
  414. /*
  415. * SNVS
  416. */
  417. sysbus_realize(SYS_BUS_DEVICE(&s->snvs), &error_abort);
  418. sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0, FSL_IMX7_SNVS_HP_ADDR);
  419. /*
  420. * SRC
  421. */
  422. sysbus_realize(SYS_BUS_DEVICE(&s->src), &error_abort);
  423. sysbus_mmio_map(SYS_BUS_DEVICE(&s->src), 0, FSL_IMX7_SRC_ADDR);
  424. /*
  425. * Watchdogs
  426. */
  427. for (i = 0; i < FSL_IMX7_NUM_WDTS; i++) {
  428. static const hwaddr FSL_IMX7_WDOGn_ADDR[FSL_IMX7_NUM_WDTS] = {
  429. FSL_IMX7_WDOG1_ADDR,
  430. FSL_IMX7_WDOG2_ADDR,
  431. FSL_IMX7_WDOG3_ADDR,
  432. FSL_IMX7_WDOG4_ADDR,
  433. };
  434. static const int FSL_IMX7_WDOGn_IRQ[FSL_IMX7_NUM_WDTS] = {
  435. FSL_IMX7_WDOG1_IRQ,
  436. FSL_IMX7_WDOG2_IRQ,
  437. FSL_IMX7_WDOG3_IRQ,
  438. FSL_IMX7_WDOG4_IRQ,
  439. };
  440. object_property_set_bool(OBJECT(&s->wdt[i]), "pretimeout-support",
  441. true, &error_abort);
  442. sysbus_realize(SYS_BUS_DEVICE(&s->wdt[i]), &error_abort);
  443. sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, FSL_IMX7_WDOGn_ADDR[i]);
  444. sysbus_connect_irq(SYS_BUS_DEVICE(&s->wdt[i]), 0,
  445. qdev_get_gpio_in(gic, FSL_IMX7_WDOGn_IRQ[i]));
  446. }
  447. /*
  448. * SDMA
  449. */
  450. create_unimplemented_device("sdma", FSL_IMX7_SDMA_ADDR, FSL_IMX7_SDMA_SIZE);
  451. /*
  452. * CAAM
  453. */
  454. create_unimplemented_device("caam", FSL_IMX7_CAAM_ADDR, FSL_IMX7_CAAM_SIZE);
  455. /*
  456. * PWMs
  457. */
  458. for (i = 0; i < FSL_IMX7_NUM_PWMS; i++) {
  459. static const hwaddr FSL_IMX7_PWMn_ADDR[FSL_IMX7_NUM_PWMS] = {
  460. FSL_IMX7_PWM1_ADDR,
  461. FSL_IMX7_PWM2_ADDR,
  462. FSL_IMX7_PWM3_ADDR,
  463. FSL_IMX7_PWM4_ADDR,
  464. };
  465. snprintf(name, NAME_SIZE, "pwm%d", i);
  466. create_unimplemented_device(name, FSL_IMX7_PWMn_ADDR[i],
  467. FSL_IMX7_PWMn_SIZE);
  468. }
  469. /*
  470. * CANs
  471. */
  472. for (i = 0; i < FSL_IMX7_NUM_CANS; i++) {
  473. static const hwaddr FSL_IMX7_CANn_ADDR[FSL_IMX7_NUM_CANS] = {
  474. FSL_IMX7_CAN1_ADDR,
  475. FSL_IMX7_CAN2_ADDR,
  476. };
  477. snprintf(name, NAME_SIZE, "can%d", i);
  478. create_unimplemented_device(name, FSL_IMX7_CANn_ADDR[i],
  479. FSL_IMX7_CANn_SIZE);
  480. }
  481. /*
  482. * SAIs (Audio SSI (Synchronous Serial Interface))
  483. */
  484. for (i = 0; i < FSL_IMX7_NUM_SAIS; i++) {
  485. static const hwaddr FSL_IMX7_SAIn_ADDR[FSL_IMX7_NUM_SAIS] = {
  486. FSL_IMX7_SAI1_ADDR,
  487. FSL_IMX7_SAI2_ADDR,
  488. FSL_IMX7_SAI3_ADDR,
  489. };
  490. snprintf(name, NAME_SIZE, "sai%d", i);
  491. create_unimplemented_device(name, FSL_IMX7_SAIn_ADDR[i],
  492. FSL_IMX7_SAIn_SIZE);
  493. }
  494. /*
  495. * OCOTP
  496. */
  497. create_unimplemented_device("ocotp", FSL_IMX7_OCOTP_ADDR,
  498. FSL_IMX7_OCOTP_SIZE);
  499. /*
  500. * GPR
  501. */
  502. sysbus_realize(SYS_BUS_DEVICE(&s->gpr), &error_abort);
  503. sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpr), 0, FSL_IMX7_IOMUXC_GPR_ADDR);
  504. /*
  505. * PCIE
  506. */
  507. sysbus_realize(SYS_BUS_DEVICE(&s->pcie), &error_abort);
  508. sysbus_mmio_map(SYS_BUS_DEVICE(&s->pcie), 0, FSL_IMX7_PCIE_REG_ADDR);
  509. object_property_set_int(OBJECT(&s->pcie4_msi_irq), "num-lines", 2,
  510. &error_abort);
  511. qdev_realize(DEVICE(&s->pcie4_msi_irq), NULL, &error_abort);
  512. irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTD_MSI_IRQ);
  513. qdev_connect_gpio_out(DEVICE(&s->pcie4_msi_irq), 0, irq);
  514. irq = qdev_get_gpio_in(gic, FSL_IMX7_PCI_INTA_IRQ);
  515. sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 0, irq);
  516. irq = qdev_get_gpio_in(gic, FSL_IMX7_PCI_INTB_IRQ);
  517. sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 1, irq);
  518. irq = qdev_get_gpio_in(gic, FSL_IMX7_PCI_INTC_IRQ);
  519. sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 2, irq);
  520. irq = qdev_get_gpio_in(DEVICE(&s->pcie4_msi_irq), 0);
  521. sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 3, irq);
  522. irq = qdev_get_gpio_in(DEVICE(&s->pcie4_msi_irq), 1);
  523. sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 4, irq);
  524. /*
  525. * USBs
  526. */
  527. for (i = 0; i < FSL_IMX7_NUM_USBS; i++) {
  528. static const hwaddr FSL_IMX7_USBMISCn_ADDR[FSL_IMX7_NUM_USBS] = {
  529. FSL_IMX7_USBMISC1_ADDR,
  530. FSL_IMX7_USBMISC2_ADDR,
  531. FSL_IMX7_USBMISC3_ADDR,
  532. };
  533. static const hwaddr FSL_IMX7_USBn_ADDR[FSL_IMX7_NUM_USBS] = {
  534. FSL_IMX7_USB1_ADDR,
  535. FSL_IMX7_USB2_ADDR,
  536. FSL_IMX7_USB3_ADDR,
  537. };
  538. static const int FSL_IMX7_USBn_IRQ[FSL_IMX7_NUM_USBS] = {
  539. FSL_IMX7_USB1_IRQ,
  540. FSL_IMX7_USB2_IRQ,
  541. FSL_IMX7_USB3_IRQ,
  542. };
  543. sysbus_realize(SYS_BUS_DEVICE(&s->usb[i]), &error_abort);
  544. sysbus_mmio_map(SYS_BUS_DEVICE(&s->usb[i]), 0,
  545. FSL_IMX7_USBn_ADDR[i]);
  546. irq = qdev_get_gpio_in(gic, FSL_IMX7_USBn_IRQ[i]);
  547. sysbus_connect_irq(SYS_BUS_DEVICE(&s->usb[i]), 0, irq);
  548. snprintf(name, NAME_SIZE, "usbmisc%d", i);
  549. create_unimplemented_device(name, FSL_IMX7_USBMISCn_ADDR[i],
  550. FSL_IMX7_USBMISCn_SIZE);
  551. }
  552. /*
  553. * ADCs
  554. */
  555. for (i = 0; i < FSL_IMX7_NUM_ADCS; i++) {
  556. static const hwaddr FSL_IMX7_ADCn_ADDR[FSL_IMX7_NUM_ADCS] = {
  557. FSL_IMX7_ADC1_ADDR,
  558. FSL_IMX7_ADC2_ADDR,
  559. };
  560. snprintf(name, NAME_SIZE, "adc%d", i);
  561. create_unimplemented_device(name, FSL_IMX7_ADCn_ADDR[i],
  562. FSL_IMX7_ADCn_SIZE);
  563. }
  564. /*
  565. * LCD
  566. */
  567. create_unimplemented_device("lcdif", FSL_IMX7_LCDIF_ADDR,
  568. FSL_IMX7_LCDIF_SIZE);
  569. /*
  570. * DMA APBH
  571. */
  572. create_unimplemented_device("dma-apbh", FSL_IMX7_DMA_APBH_ADDR,
  573. FSL_IMX7_DMA_APBH_SIZE);
  574. /*
  575. * PCIe PHY
  576. */
  577. create_unimplemented_device("pcie-phy", FSL_IMX7_PCIE_PHY_ADDR,
  578. FSL_IMX7_PCIE_PHY_SIZE);
  579. /*
  580. * CSU
  581. */
  582. create_unimplemented_device("csu", FSL_IMX7_CSU_ADDR,
  583. FSL_IMX7_CSU_SIZE);
  584. /*
  585. * TZASC
  586. */
  587. create_unimplemented_device("tzasc", FSL_IMX7_TZASC_ADDR,
  588. FSL_IMX7_TZASC_SIZE);
  589. /*
  590. * OCRAM memory
  591. */
  592. memory_region_init_ram(&s->ocram, NULL, "imx7.ocram",
  593. FSL_IMX7_OCRAM_MEM_SIZE,
  594. &error_abort);
  595. memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_MEM_ADDR,
  596. &s->ocram);
  597. /*
  598. * OCRAM EPDC memory
  599. */
  600. memory_region_init_ram(&s->ocram_epdc, NULL, "imx7.ocram_epdc",
  601. FSL_IMX7_OCRAM_EPDC_SIZE,
  602. &error_abort);
  603. memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_EPDC_ADDR,
  604. &s->ocram_epdc);
  605. /*
  606. * OCRAM PXP memory
  607. */
  608. memory_region_init_ram(&s->ocram_pxp, NULL, "imx7.ocram_pxp",
  609. FSL_IMX7_OCRAM_PXP_SIZE,
  610. &error_abort);
  611. memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_PXP_ADDR,
  612. &s->ocram_pxp);
  613. /*
  614. * OCRAM_S memory
  615. */
  616. memory_region_init_ram(&s->ocram_s, NULL, "imx7.ocram_s",
  617. FSL_IMX7_OCRAM_S_SIZE,
  618. &error_abort);
  619. memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_S_ADDR,
  620. &s->ocram_s);
  621. /*
  622. * ROM memory
  623. */
  624. memory_region_init_rom(&s->rom, OBJECT(dev), "imx7.rom",
  625. FSL_IMX7_ROM_SIZE, &error_abort);
  626. memory_region_add_subregion(get_system_memory(), FSL_IMX7_ROM_ADDR,
  627. &s->rom);
  628. /*
  629. * CAAM memory
  630. */
  631. memory_region_init_rom(&s->caam, OBJECT(dev), "imx7.caam",
  632. FSL_IMX7_CAAM_MEM_SIZE, &error_abort);
  633. memory_region_add_subregion(get_system_memory(), FSL_IMX7_CAAM_MEM_ADDR,
  634. &s->caam);
  635. }
  636. static const Property fsl_imx7_properties[] = {
  637. DEFINE_PROP_UINT32("fec1-phy-num", FslIMX7State, phy_num[0], 0),
  638. DEFINE_PROP_UINT32("fec2-phy-num", FslIMX7State, phy_num[1], 1),
  639. DEFINE_PROP_BOOL("fec1-phy-connected", FslIMX7State, phy_connected[0],
  640. true),
  641. DEFINE_PROP_BOOL("fec2-phy-connected", FslIMX7State, phy_connected[1],
  642. true),
  643. };
  644. static void fsl_imx7_class_init(ObjectClass *oc, void *data)
  645. {
  646. DeviceClass *dc = DEVICE_CLASS(oc);
  647. device_class_set_props(dc, fsl_imx7_properties);
  648. dc->realize = fsl_imx7_realize;
  649. /* Reason: Uses serial_hds and nd_table in realize() directly */
  650. dc->user_creatable = false;
  651. dc->desc = "i.MX7 SOC";
  652. }
  653. static const TypeInfo fsl_imx7_type_info = {
  654. .name = TYPE_FSL_IMX7,
  655. .parent = TYPE_DEVICE,
  656. .instance_size = sizeof(FslIMX7State),
  657. .instance_init = fsl_imx7_init,
  658. .class_init = fsl_imx7_class_init,
  659. };
  660. static void fsl_imx7_register_types(void)
  661. {
  662. type_register_static(&fsl_imx7_type_info);
  663. }
  664. type_init(fsl_imx7_register_types)