1.. zephyr:board:: colibri_imx7d
2
3Overview
4********
5
6The i.MX7 SoC is a Hybrid multi-core processor composed by Single/Dual Cortex A7
7core and Single Cortex M4 core.
8Zephyr was ported to run on the M4 core. In a later release, it will also
9communicate with the A7 core (running Linux) via RPmsg.
10
11Hardware
12********
13
14- i.MX7 Single/Dual Cortex A7 (800MHz/1.0GHz) core and Single Cortex M4 (200MHz) core
15
16- Memory
17
18  - RAM -> A7: 256MB, 512MB and 1GB
19  - RAM -> M4: 3x32KB (TCML, TCMU, OCRAM_S), 1x128KB (OCRAM) and 1x256MB (DDR)
20  - Flash -> A7: 4Gb eMMC and 512Mb NAND
21
22- Display
23
24  - RGB 1920x1080x24bpp
25  - 4-wire Resistive touch
26
27- Multimedia
28
29  - 1x Camera Parallel Interface
30  - 1x Analog Audio Line in (Stereo)
31  - 1x Analog Audio Mic in (Mono)
32  - 1x Analog Audio Headphone out (Stereo)
33
34- Connectivity
35
36  - USB 2.0 OTG (High Speed)
37  - USB 2.0 host (High Speed)
38  - 10/100 Mbit/s Ethernet PHY
39  - 4x I2C
40  - 4x SPI
41  - 7x UART
42  - 1x IrDA
43  - 20x PWM
44  - Up to 125 GPIO
45  - 4x Analog Input (12 Bit)
46  - 2x SDIO/SD/MMC (8 Bit)
47  - 2x CAN
48
49For more information about the i.MX	7 SoC, Colibri iMX7 Computer on Module
50and Colibri Evaluation Board, see these references:
51
52- `i.MX 7 Series Website`_
53- `i.MX 7 Dual Datasheet`_
54- `i.MX 7 Dual Reference Manual`_
55- `Colibri iMX7 Website`_
56- `Colibri iMX7 User Guide`_
57- `Colibri iMX7 Datasheet`_
58- `Colibri Evaluation Board Website`_
59- `Colibri Evaluation Board Datasheet`_
60
61Supported Features
62==================
63
64The Colibri iMX7D Computer on Module with Colibri Evaluation Board configuration
65supports the following hardware features on the Cortex M4 Core:
66
67+-----------+------------+-------------------------------------+
68| Interface | Controller | Driver/Component                    |
69+===========+============+=====================================+
70| NVIC      | on-chip    | nested vector interrupt controller  |
71+-----------+------------+-------------------------------------+
72| SYSTICK   | on-chip    | systick                             |
73+-----------+------------+-------------------------------------+
74| GPIO      | on-chip    | gpio                                |
75+-----------+------------+-------------------------------------+
76| I2C       | on-chip    | i2c                                 |
77+-----------+------------+-------------------------------------+
78| PWM       | on-chip    | pwm                                 |
79+-----------+------------+-------------------------------------+
80| UART      | on-chip    | serial port-polling;                |
81|           |            | serial port-interrupt               |
82+-----------+------------+-------------------------------------+
83
84The default configuration can be found in the defconfig file:
85
86	:zephyr_file:`boards/toradex/colibri_imx7d/colibri_imx7d_mcimx7d_m4_defconfig`
87
88Other hardware features are not currently supported by the port.
89
90Connections and IOs
91===================
92
93The Colibri iMX7D Computer on Module with Colibri Evaluation Board
94was tested with the following pinmux controller configuration.
95
96+---------------+-----------------+---------------------------+
97| Board Name    | SoC Name        | Usage                     |
98+===============+=================+===========================+
99| UART_B RXD    | UART2_TXD       | UART Console              |
100+---------------+-----------------+---------------------------+
101| UART_B TXD    | UART2_RXD       | UART Console              |
102+---------------+-----------------+---------------------------+
103| SODIMM_135    | GPIO1_IO02      | LED0                      |
104+---------------+-----------------+---------------------------+
105| SODIMM_133    | GPIO2_IO26      | SW0                       |
106+---------------+-----------------+---------------------------+
107| SODIMM_194    | I2C4_SDA        | I2C_SDA                   |
108+---------------+-----------------+---------------------------+
109| SODIMM_196    | I2C4_SCL        | I2C_SCL                   |
110+---------------+-----------------+---------------------------+
111| SODIMM_59     | PWM1/GPIO1_IO08 | PWM                       |
112+---------------+-----------------+---------------------------+
113
114System Clock
115============
116
117The M4 Core is configured to run at a 200 MHz clock speed.
118
119Serial Port
120===========
121
122The iMX7D SoC has seven UARTs. The number 2 is configured for the console and
123the remaining are not used/tested.
124
125Programming and Debugging
126*************************
127
128The Colibri iMX7D doesn't have QSPI flash for the M4 and it needs to be started by
129the A7 core. The A7 core is responsible to load the M4 binary application into the
130RAM, put the M4 in reset, set the M4 Program Counter and Stack Pointer, and get
131the M4 out of reset.
132The A7 can perform these steps at bootloader level or after the Linux system has
133booted.
134
135The M4 can use up to 5 different RAMs. These are the memory mapping for A7 and M4:
136
137+------------+-----------------------+------------------------+-----------------------+----------------------+
138| Region     | Cortex-A7             | Cortex-M4 (System Bus) | Cortex-M4 (Code Bus)  | Size                 |
139+============+=======================+========================+=======================+======================+
140| DDR        | 0x80000000-0xFFFFFFFF | 0x80000000-0xDFFFFFFF  | 0x10000000-0x1FFEFFFF | 2048MB (less for M4) |
141+------------+-----------------------+------------------------+-----------------------+----------------------+
142| OCRAM      | 0x00900000-0x0091FFFF | 0x20200000-0x2021FFFF  | 0x00900000-0x0091FFFF | 128KB                |
143+------------+-----------------------+------------------------+-----------------------+----------------------+
144| TCMU       | 0x00800000-0x00807FFF | 0x20000000-0x20007FFF  |                       | 32KB                 |
145+------------+-----------------------+------------------------+-----------------------+----------------------+
146| TCML       | 0x007F8000-0x007FFFFF |                        | 0x1FFF8000-0x1FFFFFFF | 32KB                 |
147+------------+-----------------------+------------------------+-----------------------+----------------------+
148| OCRAM_S    | 0x00180000-0x00187FFF | 0x20180000-0x20187FFF  | 0x00000000-0x00007FFF | 32KB                 |
149+------------+-----------------------+------------------------+-----------------------+----------------------+
150| QSPI Flash |                       |                        | 0x08000000-0x0BFFFFFF | 64MB                 |
151+------------+-----------------------+------------------------+-----------------------+----------------------+
152
153
154References
155==========
156
157- `i.MX 7 Dual Reference Manual`_ from page 190 (section 2.1.2 and 2.1.3)
158- `Toradex Wiki`_
159
160
161At compilation time you have to choose which RAM will be used. This configuration is
162done in the file :zephyr_file:`boards/toradex/colibri_imx7d/colibri_imx7d_mcimx7d_m4.dts`
163with "zephyr,flash" (when CONFIG_XIP=y) and "zephyr,sram"
164properties. The available configurations are:
165
166.. code-block:: none
167
168   "zephyr,flash"
169   - &ddr_code
170   - &tcml_code
171   - &ocram_code
172   - &ocram_s_code
173   - &ocram_pxp_code
174   - &ocram_epdc_code
175
176   "zephyr,sram"
177   - &ddr_sys
178   - &tcmu_sys
179   - &ocram_sys
180   - &ocram_s_sys
181   - &ocram_pxp_sys
182   - &ocram_epdc_sys
183
184
185Below you will find the instructions to load and run Zephyr on M4 from A7 using u-boot.
186
187Copy the compiled zephyr.bin to the first EXT partition of the SD card and plug into the
188board. Power it up and stop the u-boot execution.
189Set the u-boot environment variables and run the zephyr.bin from the appropriated memory
190configured in the Zephyr compilation:
191
192.. code-block:: console
193
194   setenv bootm4 'ext4load mmc 0:1 $m4addr $m4fw && dcache flush && bootaux $m4addr'
195   # TCML
196   setenv m4tcml 'setenv m4fw zephyr.bin; setenv m4addr 0x007F8000'
197   setenv bootm4tcml 'run m4tcml && run bootm4'
198   run bootm4tcml
199   # TCMU
200   setenv m4tcmu 'setenv m4fw zephyr.bin; setenv m4addr 0x00800000'
201   setenv bootm4tcmu 'run m4tcmu && run bootm4'
202   run bootm4tcmu
203   # OCRAM
204   setenv m4ocram 'setenv m4fw zephyr.bin; setenv m4addr 0x00900000'
205   setenv bootm4ocram 'run m4ocram && run bootm4'
206   run bootm4ocram
207   # OCRAM_S
208   setenv m4ocrams 'setenv m4fw zephyr.bin; setenv m4addr 0x00180000'
209   setenv bootm4ocrams 'run m4ocrams && run bootm4'
210   run bootm4ocrams
211   # DDR
212   setenv m4ddr 'setenv m4fw zephyr.bin; setenv m4addr 0x80000000'
213   setenv bootm4ddr 'run m4ddr && run bootm4'
214   run bootm4ddr
215
216M4<->Linux IPC using RPMSG
217**************************
218
219The IMX7D soc supports the subsys/ipc/openamp_rsc_table sample to demonstrate the
220usage of rpmsg_tty as an inter processor communication.
221
222The board configuration is provided for the colibri_imx7d board.
223The boot process of the M4 core is handled solely by the Linux kernel using the RPROC
224framework.
225
226The sample was tested with Toradex's LTS BSP 6.6.0 Minimal Open Embedded image with
227upstream Linux kernel 6.1.83.
228
229Required kernel modules must be loaded for RPMSG to work:
230
231- imx_rproc
232- virtio_rpmsg_bus
233- rpmsg_tty (requiring rpmsg_core)
234
235You need to modify your Linux device tree to add the M4 definitions:
236
237- Enable MU_A
238- Reserve memory areas for the M4 so Linux won't touch them.
239- Define the M4 remoteproc node for the drivers.
240
241If you have not downloaded the BSP sources, you can modify the board's device tree
242from its currently loaded dtb file.
243
244
245.. code-block:: none
246
247   #Check the which fdtfile is loaded for your board in U-boot
248   printenv
249   #For a Colibri_imx7d on Viola Carrier on BSP 6.6.0
250   fdtfile = imx7d-colibri-emmc-eval-v3.dtb
251
252   #Copy this file to your Linux PC through SSH from /boot
253   #Convert the dtb into a dts
254   dtc -I dtb -O dts -f imx7d-colibri-emmc-eval-v3.dtb -o imx7d-colibri-emmc-eval-v3.dts
255
256   #You need to find the following phandle numbers:
257   # reset-controller
258   # mailbox@30aa0000
259
260   #Note down the phandle value (0xbd)
261   grep -A10 "mailbox@30aa0000 {" imx7d-colibri-emmc-eval-v3.dts
262   # outputs your DTS's mailbox definition
263   #		mailbox@30aa0000 {
264   #			compatible = "fsl,imx7s-mu\0fsl,imx6sx-mu";
265   #			reg = <0x30aa0000 0x10000>;
266   #			interrupts = <0x00 0x58 0x04>;
267   #			clocks = <0x01 0x1b1>;
268   #			#mbox-cells = <0x02>;
269   #			status = "disabled";
270   #			phandle = <0xbd>;
271   #		};
272
273   #Note down the phandle value (0x32)
274   grep -A8 "reset-controller@30390000 {" imx7d-colibri-emmc-eval-v3.dts
275   # outputs your DTS's reset-controller definition
276   #		reset-controller@30390000 {
277   #			compatible = "fsl,imx7d-src\0syscon";
278   #			reg = <0x30390000 0x10000>;
279   #			interrupts = <0x00 0x59 0x04>;
280   #			#reset-cells = <0x01>;
281   #			phandle = <0x32>;
282   #		};
283
284   #Node down the biggest phandle value
285   grep "phandle = <" imx7d-colibri-emmc-eval-v3.dts | sort -r | head -1
286   # outputs your DTS's largest phandle definition
287   #		phandle = <0xca>;
288
289   #Now we can add our nodes to the .dts file:
290   cp imx7d-colibri-emmc-eval-v3.dts imx7d-m4.dts
291   nano imx7d-m4.dts
292
293   #Modify MU_A node to enable it
294   mailbox@30aa0000 {
295      compatible = "fsl,imx7s-mu\0fsl,imx6sx-mu";
296      reg = <0x30aa0000 0x10000>;
297      interrupts = <0x00 0x58 0x04>;
298      clocks = <0x01 0x1b1>;
299      #mbox-cells = <0x02>;
300      status = "okay";
301      phandle = <0xbd>;
302   };
303
304   #Add these definitions under / { } just before the __symbols__
305   #Disgard the comments with #-->
306   reserved-memory {
307      #address-cells = <0x01>;
308      #size-cells = <0x01>;
309      ranges;
310
311      vdev0buffer0@90002000 {
312         compatible = "shared-dma-pool";
313         reg = <0x90002000 0x8000>;
314         no-map;
315         phandle = <0xcb>; #--> biggest phandle +1
316      };
317
318      vdev0vring0@90000000 {
319         compatible = "shared-dma-pool";
320         reg = <0x90000000 0x1000>;
321         no-map;
322         phandle = <0xcc>; #--> biggest phandle +2
323      };
324
325      vdev0vring1@90001000 {
326         compatible = "shared-dma-pool";
327         reg = <0x90001000 0x1000>;
328         no-map;
329         phandle = <0xcd>; #--> biggest phandle +3
330      };
331
332      cm4tcmcode@7f8000 {
333         compatible = "shared-dma-pool";
334         reg = <0x7f8000 0x8000>;
335         no-map;
336         phandle = <0xce>; #--> biggest phandle +4
337      };
338
339      cm4sramcode@900000 {
340         compatible = "shared-dma-pool";
341         reg = <0x900000 0x40000>;
342         no-map;
343         phandle = <0xcf>; #--> biggest phandle +5
344      };
345
346      cm4reserved@8ff00000 {
347         compatible = "shared-dma-pool";
348         reg = <0x8ff00000 0x100000>;
349         no-map;
350         phandle = <0xd0>; #--> biggest phandle +6
351      };
352   };
353
354   imx7d-cm4 {
355      compatible = "fsl,imx7d-cm4";
356      mbox-names = "tx\0rx\0rxdb";
357      mboxes = <0xbd 0x00 0x00 0xbd 0x01 0x00 0xbd 0x03 0x00>; #--> MU_A phandle (0xbd)
358      memory-region = <0xcb 0xcc 0xcd 0xce 0xcf 0xd0>; #--> All the previously defined phandles
359      syscon = <0x32>; #--> phandle for the reset-controller
360      clocks = <0x01 0x42>;
361   };
362
363   #Recompile the dts into a dtb
364   dtc -I dts -O dtb -f imx7d-m4.dts -o imx7d-m4.dtb
365
366   #Copy the new dtb to /boot on the Colibri IMX7 board
367   #Start in U-boot and update the device-tree
368   setenv fdtfile imx7d-m4.dtb
369   saveenv
370   boot
371
372When the OS has finished booting with your new device tree you can enable
373the drivers and start the M4 core.
374
375.. code-block:: console
376
377   #Copy zephyr_openamp_rsc_table.elf to /lib/firmware on your board
378   $ modprobe imx_rproc
379   $ modprobe virtio_rpmsg_bus
380   $ modprobe rpmsg_tty
381
382   #Request RPROC to load the M4 image
383   $ echo stop > /sys/class/remoteproc/remoteproc0/state
384   $ echo zephyr_openamp_rsc_table.elf > /sys/class/remoteproc/remoteproc0/firmware
385   $ echo start > /sys/class/remoteproc/remoteproc0/state
386
387   #dmesg will detail the boot process:
388   $ dmesg
389   [  497.120499] remoteproc remoteproc0: stopped remote processor imx-rproc
390   [  497.138938] remoteproc remoteproc0: powering up imx-rproc
391   [  497.168735] remoteproc remoteproc0: Booting fw image zephyr_openamp_rsc_table.elf, size 1267076
392   [  497.184826] rproc-virtio rproc-virtio.1.auto: assigned reserved memory node vdev0buffer0@90002000
393   [  497.221395] virtio_rpmsg_bus virtio0: rpmsg host is online
394   [  497.233806] virtio_rpmsg_bus virtio0: creating channel rpmsg-tty addr 0x400
395   [  497.236666] rproc-virtio rproc-virtio.1.auto: registered virtio0 (type 7)
396   [  497.259822] remoteproc remoteproc0: remote processor imx-rproc is now up
397   [  497.293913] virtio_rpmsg_bus virtio0: creating channel rpmsg-client-sample addr 0x401
398   [  497.308388] rpmsg_client_sample virtio0.rpmsg-client-sample.-1.1025: new channel: 0x401 -> 0x401!
399   [  497.337969] virtio_rpmsg_bus virtio0: creating channel rpmsg-tty addr 0x402
400
401   $ ls /dev | grep ttyRPMSG
402   ttyRPMSG0 -> used for zephyr shell interface
403   ttyRPMSG1 -> used for sample interface
404
405
406Debugging
407=========
408
409Download and install `J-Link Tools`_ and `NXP iMX7D Connect CortexM4.JLinkScript`_.
410
411To run Zephyr Binary using J-Link create the following script in order to
412get the Program Counter and Stack Pointer from zephyr.bin.
413
414get-pc-sp.sh:
415
416.. code-block:: console
417
418   #!/bin/sh
419
420   firmware=$1
421
422   pc=$(od -An -N 8 -t x4 $firmware | awk '{print $2;}')
423   sp=$(od -An -N 8 -t x4 $firmware | awk '{print $1;}')
424
425   echo pc=$pc
426   echo sp=$sp
427
428
429Get the SP and PC from firmware binary: ``./get-pc-sp.sh zephyr.bin``
430
431.. code-block:: console
432
433   pc=00900f01
434   sp=00905020
435
436Plug in the J-Link into the board and PC and run the J-Link command line tool:
437
438.. code-block:: console
439
440   /usr/bin/JLinkExe -device Cortex-M4 -if JTAG -speed 4000 -autoconnect 1 -jtagconf -1,-1 -jlinkscriptfile iMX7D_Connect_CortexM4.JLinkScript
441
442The following steps are necessary to run the zephyr.bin:
4431. Put the M4 core in reset
4442. Load the binary in the appropriate addr (TMCL, TCMU, OCRAM, OCRAM_S or DDR)
4453. Set PC (Program Counter)
4464. Set SP (Stack Pointer)
4475. Get the M4 core out of reset
448
449Issue the following commands inside J-Link commander:
450
451.. code-block:: console
452
453   w4 0x3039000C 0xAC
454   loadfile zephyr.bin,0x00900000
455   w4 0x00180000 00900f01
456   w4 0x00180004 00905020
457   w4 0x3039000C 0xAA
458
459With these mechanisms, applications for the ``colibri_imx7d/imx7d/m4`` board
460configuration can be built and debugged in the usual way (see
461:ref:`build_an_application` and :ref:`application_run` for more details).
462
463References
464==========
465
466- `Loading Code on Cortex-M4 from Linux for the i.MX 6SoloX and i.MX 7Dual/7Solo Application Processors`_
467- `J-Link iMX7D Instructions`_
468
469.. _Colibri Evaluation Board Website:
470   https://www.toradex.com/products/carrier-board/colibri-evaluation-carrier-board
471
472.. _Colibri Evaluation Board Datasheet:
473   https://docs.toradex.com/102284-colibri-evaluation-board-datasheet.pdf
474
475.. _Colibri iMX7 Website:
476   https://www.toradex.com/computer-on-modules/colibri-arm-family/nxp-freescale-imx7
477
478.. _Colibri iMX7 User Guide:
479   https://developer.toradex.com/products/colibri-imx7
480
481.. _Colibri iMX7 Datasheet:
482   https://docs.toradex.com/103125-colibri-arm-som-imx7-datasheet.pdf
483
484.. _i.MX 7 Series Website:
485   https://www.nxp.com/products/processors-and-microcontrollers/applications-processors/i.mx-applications-processors/i.mx-7-processors:IMX7-SERIES?fsrch=1&sr=1&pageNum=1
486
487.. _i.MX 7 Dual Datasheet:
488   https://www.nxp.com/docs/en/data-sheet/IMX7DCEC.pdf
489
490.. _i.MX 7 Dual Reference Manual:
491   https://www.nxp.com/webapp/Download?colCode=IMX7DRM
492
493.. _J-Link Tools:
494   https://www.segger.com/downloads/jlink/#J-LinkSoftwareAndDocumentationPack
495
496.. _NXP iMX7D Connect CortexM4.JLinkScript:
497   https://wiki.segger.com/images/8/86/NXP_iMX7D_Connect_CortexM4.JLinkScript
498
499.. _Loading Code on Cortex-M4 from Linux for the i.MX 6SoloX and i.MX 7Dual/7Solo Application Processors:
500   https://www.nxp.com/docs/en/application-note/AN5317.pdf
501
502.. _J-Link iMX7D Instructions:
503   https://wiki.segger.com/IMX7D
504
505.. _Toradex Wiki:
506   https://developer.toradex.com/knowledge-base/freertos-on-the-cortex-m4-of-a-colibri-imx7#Memory_areas
507