This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Tool/software: Linux
Hi,
So I have a problem being able to load compiled TI-RTOS DSP Firmware from my Linux.
This DSP firmware is a modified TI-RTOS example, it's the USB Audio Example that is compiled for the OMAP-L138.
I have a added a custom resource table to the project and tried to modify the .bld file and the RTSC configuration file using some settings from the MessageQSingle example but the end results in the Linux kernel locking up completely after loading the firmware and the firmware doesn't actually work when loaded this way.
The Firmware works when loaded through the CCS Debug directly into the C6748 inside the chip through a JTAG Debugger.
root@omapl138-lcdk:~/Projects# cd /lib/firmware/ root@omapl138-lcdk:/lib/firmware# ls ipc rproc-dsp-fw root@omapl138-lcdk:/lib/firmware# unlink rproc-dsp-fw root@omapl138-lcdk:/lib/firmware# ln -s ipc/ti_platforms_evmOMAPL138_DSP/omapl138_usb_audio_dsp.out rproc-dsp-fw root@omapl138-lcdk:/lib/firmware# ls -l drwxr-xr-x 3 root root 4096 Jun 4 2018 ipc lrwxrwxrwx 1 root root 59 Mar 26 15:31 rproc-dsp-fw -> ipc/ti_platforms_evmOMAPL138_DSP/omapl138_usb_audio_dsp.out root@omapl138-lcdk:/lib/firmware# cd /sys/bus/platform/drivers/davinci-rproc/ root@omapl138-lcdk:/sys/bus/platform/drivers/davinci-rproc# echo davinci-rproc.0> unbind remoteproc remoteproc0: releasing dsp root@omapl138-lcdk:/sys/bus/platform/drivers/davinci-rproc# echo davinci-rproc.0> bind davinci-rproc davinci-rproc.0: assigned reserved memory node dsp_cma@c3000000 remoteproc remoteproc0: dsp is available root@omapl138-lcdk:/sys/bus/platform/drivers/davinci-rproc# remoteproc remoteproc0: powering up dsp remoteproc remoteproc0: Booting fw image rproc-dsp-fw, size 5462468 virtio_rpmsg_bus virtio0: rpmsg host is online remoteproc remoteproc0: registered virtio0 (type 7) remoteproc remoteproc0: remote processor dsp is now up
This is the set of commands executes to copy the built .out file I compiled in the CCS, linking it to the system link file and then using remoteproc to execute it.
Following this, the Linux kernel locks up and the LCDK Boards has to be restarted. The Linux kernel is running from an SD Card.
In order to get the IPC source table to work, I had to modify the RTSC board settings file for the evmOMAPL138.
I had to modify the DDR to be 0xC100000 since IPC uses 0xC0000000 to 0xC1000000.
I attached the configuration, build and the project files.
I want to just be able to load the firmware via the remoteproc and the later attach Shared Memory support to be able utilize the 128 KB of ARM/DSP shared
memory to share data buffers.
Hello Dmitriy,
Just an FYI, you can change the memory configuration directly from the config.bld instead of changing the RTSC platform. All you have to do is append :dsp to your platform in project properties and it will automatically pick up the platform table specified in config.bld.
The nice thing about the config.bld is that you can make memory configuration changes directly from the application level. Your method works too, I just wanted to let you know about this option.
Now, to get this example running on the DSP when the ARM is running Linux, you will need to make sure the cores are not trying to use and initialize the same peripherals. You can look at the device tree source (DTS) files to see what is being used by the ARM core. For OMAP-L138, da850.dtsi contains the SoC-level definitions, and da850-lcdk.dts contains the board level definitions (da850 and omapl138 are equivalent devices). These files are located under ti-processor-sdk-linux/board-support/linux/arch/arm/boot/dts.
For starters, by looking at mcasp_cfg.h on the DSP side, and the DTS files, I can see that both cores are trying to use MCASP0, EDMA0, and I2C0.
You have a few options:
For example, to disable UART3 and prevent the kernel from putting it to sleep, you would add the following to the device tree:
&uart3 { status = "disabled"; ti,no-idle; };
3. Change the DSP cfg or device tree so that the cores are using different instances of each peripheral, i.e., ARM uses MCASP0 and DSP uses MCASP1.
The wiki linked below explains how to add IPC to an existing application for AM572x. It's for a different device, but the process is the same as what you are doing here.
If you have any questions please let me know.
Hi Sahin, I was able to compile and load the the Firmware into the DSP from the ARM, however it doesn't work, I think because McASP isn't initialized because I commented out "board_init" function inside this function.
void configureAudio(void) { Board_STATUS stat = BOARD_SOK; Board_initCfg arg = BOARD_INIT_PINMUX_CONFIG | BOARD_INIT_UART_STDIO; //stat = Board_init(arg); return; }
I followed instructions in this link, but I don't think McASP nor USB is starting because of the board_init function. I have disabled USB/MCASP/EDMA/I2C inside the device tree and the Linux Kernel Menuconfig.
The example uses UART, specifically UART2, so you will still need to initialize it on the DSP side. The pinmuxing is done on the Linux side so you can remove that call.
So the modified code should look like this:
void configureAudio(void) { Board_STATUS stat = BOARD_SOK; Board_initCfg arg = BOARD_INIT_UART_STDIO; stat = Board_init(arg); return; }
I don't believe UART2 is being used by Linux but please double-check the device tree files to make sure.
The example in that wiki is a simpler implementation of adding IPC to an application. What you are doing here is much more complicated and may take a few iterations for us to get right.
I'm going to loop in the Linux IPC expert to see if there's anything we may have missed on the Linux side (I handle the DSP IPC side).
In the meantime, please try the above modifications and let us know how it goes.
root@omapl138-lcdk:~/Projects# cp omapl138_usb_audio_dsp.out /lib/firmware/rproc-dsp-fw root@omapl138-lcdk:~/Projects# ls /lib/firmware ipc rproc-dsp-fw root@omapl138-lcdk:~/Projects# ls -l /lib/firmware drwxr-xr-x 3 root root 4096 Jun 12 2018 ipc -rw-r--r-- 1 root root 5776812 Mar 26 14:59 rproc-dsp-fw root@omapl138-lcdk:~/Projects# cd /sys/bus/platform/drivers/davinci-rproc/ root@omapl138-lcdk:/sys/bus/platform/drivers/davinci-rproc# echo davinci-rproc.0 > unbind remoteproc remoteproc0: releasing dsp root@omapl138-lcdk:/sys/bus/platform/drivers/davinci-rproc# echo davinci-rproc.0 > bind davinci-rproc davinci-rproc.0: assigned reserved memory node dsp_cma@c3000000 remoteproc remoteproc0: dsp is available root@omapl138-lcdk:/sys/bus/platform/drivers/davinci-rproc# remoteproc remoteproc0: powering up dsp remoteproc remoteproc0: Booting fw image rproc-dsp-fw, size 5776812 virtio_rpmsg_bus virtio0: rpmsg host is online remoteproc remoteproc0: registered virtio0 (type 7) ▒m}▒-▒▒}"-m}▒-▒▒}▒▒▒▒▒mߑ-▒}-▒▒}▒B▒/▒ э▒▒▒/▒▒▒i
It still causes the kernel to crash when I use Board_init.
I have attached my device-tree files, but UART isn't being used in any of them.
/* * Copyright (c) 2016 BayLibre, Inc. * * Licensed under GPLv2. */ /dts-v1/; #include "da850.dtsi" #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/input.h> / { model = "DA850/AM1808/OMAP-L138 LCDK"; compatible = "ti,da850-lcdk", "ti,da850"; aliases { serial2 = &serial2; ethernet0 = ð0; }; chosen { stdout-path = "serial2:115200n8"; }; memory { device_type = "memory"; reg = <0xc0000000 0x08000000>; }; reserved-memory { #address-cells = <1>; #size-cells = <1>; ranges; dsp_cma_pool: dsp_cma@c3000000 { compatible = "shared-dma-pool"; reg = <0xc3000000 0x1000000>; reusable; status = "okay"; }; }; sound { compatible = "simple-audio-card"; simple-audio-card,name = "DA850/OMAP-L138 LCDK"; simple-audio-card,widgets = "Line", "Line In", "Line", "Line Out"; simple-audio-card,routing = "LINE1L", "Line In", "LINE1R", "Line In", "Line Out", "LLOUT", "Line Out", "RLOUT"; simple-audio-card,format = "dsp_b"; simple-audio-card,bitclock-master = <&link0_codec>; simple-audio-card,frame-master = <&link0_codec>; simple-audio-card,bitclock-inversion; simple-audio-card,cpu { sound-dai = <&mcasp0>; system-clock-frequency = <24576000>; }; link0_codec: simple-audio-card,codec { sound-dai = <&tlv320aic3106>; system-clock-frequency = <24576000>; }; }; gpio-keys { compatible = "gpio-keys"; autorepeat; user1 { label = "GPIO Key USER1"; linux,code = <BTN_0>; gpios = <&gpio 36 GPIO_ACTIVE_LOW>; }; user2 { label = "GPIO Key USER2"; linux,code = <BTN_1>; gpios = <&gpio 37 GPIO_ACTIVE_LOW>; }; }; vga-bridge { compatible = "ti,ths8135"; #address-cells = <1>; #size-cells = <0>; ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; vga_bridge_in: endpoint { remote-endpoint = <&lcdc_out_vga>; }; }; port@1 { reg = <1>; vga_bridge_out: endpoint { remote-endpoint = <&vga_con_in>; }; }; }; }; vga { compatible = "vga-connector"; ddc-i2c-bus = <&i2c0>; port { vga_con_in: endpoint { remote-endpoint = <&vga_bridge_out>; }; }; }; }; &pmx_core { status = "okay"; mcasp0_pins: pinmux_mcasp0_pins { pinctrl-single,bits = < /* AHCLKX AFSX ACLKX */ 0x00 0x00101010 0x00f0f0f0 /* ARX13 ARX14 */ 0x04 0x00000110 0x00000ff0 >; }; nand_pins: nand_pins { pinctrl-single,bits = < /* EMA_WAIT[0], EMA_OE, EMA_WE, EMA_CS[3] */ 0x1c 0x10110010 0xf0ff00f0 /* * EMA_D[0], EMA_D[1], EMA_D[2], * EMA_D[3], EMA_D[4], EMA_D[5], * EMA_D[6], EMA_D[7] */ 0x24 0x11111111 0xffffffff /* * EMA_D[8], EMA_D[9], EMA_D[10], * EMA_D[11], EMA_D[12], EMA_D[13], * EMA_D[14], EMA_D[15] */ 0x20 0x11111111 0xffffffff /* EMA_A[1], EMA_A[2] */ 0x30 0x01100000 0x0ff00000 >; }; }; &serial2 { pinctrl-names = "default"; pinctrl-0 = <&serial2_rxtx_pins>; status = "okay"; }; &wdt { status = "okay"; }; &rtc0 { status = "okay"; }; &gpio { status = "okay"; }; &sata { status = "okay"; }; &mdio { pinctrl-names = "default"; pinctrl-0 = <&mdio_pins>; bus_freq = <2200000>; status = "okay"; }; ð0 { pinctrl-names = "default"; pinctrl-0 = <&mii_pins>; status = "okay"; }; &mmc0 { max-frequency = <50000000>; bus-width = <4>; pinctrl-names = "default"; pinctrl-0 = <&mmc0_pins>; cd-gpios = <&gpio 64 GPIO_ACTIVE_LOW>; status = "okay"; }; &i2c0 { pinctrl-names = "default"; pinctrl-0 = <&i2c0_pins>; clock-frequency = <100000>; status = "disabled"; tlv320aic3106: tlv320aic3106@18 { #sound-dai-cells = <0>; compatible = "ti,tlv320aic3106"; reg = <0x18>; status = "disabled"; }; }; &mcasp0 { #sound-dai-cells = <0>; pinctrl-names = "default"; pinctrl-0 = <&mcasp0_pins>; status = "disabled"; op-mode = <0>; /* DAVINCI_MCASP_IIS_MODE */ tdm-slots = <2>; serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 0 >; tx-num-evt = <32>; rx-num-evt = <32>; }; &usb_phy { status = "okay"; }; &usb0 { status = "okay"; }; &usb1 { status = "okay"; }; &aemif { pinctrl-names = "default"; pinctrl-0 = <&nand_pins>; status = "okay"; cs3 { #address-cells = <2>; #size-cells = <1>; clock-ranges; ranges; ti,cs-chipselect = <3>; nand@2000000,0 { compatible = "ti,davinci-nand"; #address-cells = <1>; #size-cells = <1>; reg = <0 0x02000000 0x02000000 1 0x00000000 0x00008000>; ti,davinci-chipselect = <1>; ti,davinci-mask-ale = <0>; ti,davinci-mask-cle = <0>; ti,davinci-mask-chipsel = <0>; ti,davinci-nand-buswidth = <16>; ti,davinci-ecc-mode = "hw"; ti,davinci-ecc-bits = <4>; ti,davinci-nand-use-bbt; /* * The OMAP-L132/L138 Bootloader doc SPRAB41E reads: * "To boot from NAND Flash, the AIS should be written * to NAND block 1 (NAND block 0 is not used by default)". * The same doc mentions that for ROM "Silicon Revision 2.1", * "Updated NAND boot mode to offer boot from block 0 or block 1". * However the limitaion is left here by default for compatibility * with older silicon and because it needs new boot pin settings * not possible in stock LCDK. */ partitions { compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; partition@0 { label = "u-boot env"; reg = <0 0x020000>; }; partition@0x020000 { /* The LCDK defaults to booting from this partition */ label = "u-boot"; reg = <0x020000 0x080000>; }; partition@0x0a0000 { label = "free space"; reg = <0x0a0000 0>; }; }; }; }; }; &prictrl { status = "okay"; }; &memctrl { status = "okay"; }; &lcdc { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&lcd_pins>; port { lcdc_out_vga: endpoint { remote-endpoint = <&vga_bridge_in>; }; }; }; &vpif { pinctrl-names = "default"; pinctrl-0 = <&vpif_capture_pins>; status = "okay"; /* VPIF capture port */ port { vpif_ch0: endpoint { bus-width = <8>; }; }; }; &dsp { status = "okay"; memory-region = <&dsp_cma_pool>; };
So this example is only able to load if I don't perform Board_init. USB also doesn't work, but I'm not sure if Board_init does anything with the USB.
Hey Rex,
After looking through the related posts and the code I couldn't find anywhere where it used CSL_xbarDmaConfigure or did anything to the MMR_LOCK_2 register. The firmware itself seems to not lock up the system if I comment out the BoardInit function, however if I don't comment it out then it locks up the processor. Going through that function through the JTAG debugger I still couldn't find it doing anything to the MMR_LOCK_2 register.
There is a
static inline void CSL_SysCfgUnlockKicker (void) { hSysCfg->KICK0R = 0x83E70B13; hSysCfg->KICK1R = 0x95A4F1E0; hSysCfg->CFGCHIP3 |= 0x4; return; }
that is executed through
if (cfg & BOARD_INIT_UNLOCK_MMR) ret = Board_unlockMMR(); if (ret != BOARD_SOK) return ret;
I'm not sure whether that toggles MMR_LOCK_2 or not, because I can't find any reference to it anywhere else.
I'm using Processor SDK 04.03.00.05 and same with the RTOS.
Hello Rex,
Commenting out Board_unlockMMR() which calls CSL_SysCfgUnlockKicker() to Unlock the KICK0R and KICK1R doesn't stop the code from going into
static inline void CSL_SysCfgUnlockKicker (void) { //hSysCfg->KICK0R = 0x83E70B13; //hSysCfg->KICK1R = 0x95A4F1E0; //hSysCfg->CFGCHIP3 |= 0x4; return; }
When I use a JTAG debuffer, the code still goes into here even if the directed functions that call the CSL_SysCfgUnlockKicker() are commented out.
There's also a
static inline void CSL_SysCfgLockKicker (void) { hSysCfg->KICK0R = 0x1; hSysCfg->KICK1R = 0x1; return; }
but it doesn't appear to be called anywhere from the code.
I checked the KICK0R and KICK1R registers at 0x01C14038 and 0x01C1403C, but they always remain 0. So they don't even get changed to the respective values from what I see.
So this is Board_Init from the lcdkOMAPL138.c file
Board_STATUS Board_init(Board_initCfg cfg) { Board_STATUS ret = BOARD_SOK; if (cfg & BOARD_INIT_UNLOCK_MMR) ret = Board_unlockMMR(); if (ret != BOARD_SOK) return ret; if (cfg & BOARD_INIT_MODULE_CLOCK) ret = Board_moduleClockInit(); if (ret != BOARD_SOK) return ret; if (cfg & BOARD_INIT_PLL) ret = Board_PLLInit(); if (ret != BOARD_SOK) return ret; if (cfg & BOARD_INIT_DDR) ret = Board_DDR3Init(); if (ret != BOARD_SOK) return ret; if (cfg & BOARD_INIT_WATCHDOG_DISABLE) return BOARD_UNSUPPORTED_FEATURE; if (cfg & BOARD_INIT_PINMUX_CONFIG) ret = Board_pinmuxConfig(); if (ret != BOARD_SOK) return ret; if (cfg & BOARD_INIT_EMIF_PINMUX) ret = Board_configEmifPinMux(); if (ret != BOARD_SOK) return ret; if (cfg & BOARD_INIT_UART_STDIO) ret = Board_uartStdioInit(); if (ret != BOARD_SOK) return ret; return ret; }
When this function is called with Board_Init, the cfg input is equal to BOARD_INIT_UART_STDIO.
But for some reason the debugger still jumps to
static inline void CSL_SysCfgUnlockKicker (void) { hSysCfg->KICK0R = 0x83E70B13; hSysCfg->KICK1R = 0x95A4F1E0; hSysCfg->CFGCHIP3 |= 0x4; return; }
Which is only callable through
Board_STATUS Board_unlockMMR(void) { CSL_SysCfgUnlockKicker(); return BOARD_SOK; }
and Board_unlockMMR is only callable from Board_init, but it's never ACTUALLY called.
Aka Board_init doesn't actually call Board_unlockMMR, but the code still jumps to CSL_SysCfgUnlockKicker.
However, after that, KICK0R and KICK1R register still don't change, the memory values remain at 0, so they're not unlocked or locked.
It seems that it's only the UART. I can still SSH into the Board via its IP. So the Kernel itself doesn't crash.
Yes, the DSP image is the PDK build USB Audio example, it's modified with the given to me instructions to try it make into an IPC example.
The standalone example pdk example works, but the USB is crackled (not sure why that happens.) There are other issues with this example, but I have a thread open for that.
This is the dmesg from a new ssh I opened after I loaded the firmware using the USB Serial connection. The UART USB connection crashes after it's loaded, which probably crashes the actual firmware since, but it does load as can be seen from the dmesg, it doesn't do anything though. The Kernel remains alive since I ssh into it.
[ 199.172842] remoteproc remoteproc0: releasing dsp [ 201.976401] davinci-rproc davinci-rproc.0: assigned reserved memory node dsp_cma@c3000000 [ 202.003207] remoteproc remoteproc0: dsp is available [ 202.168358] remoteproc remoteproc0: powering up dsp [ 202.172043] remoteproc remoteproc0: Booting fw image rproc-dsp-fw, size 5783988 [ 202.260585] virtio_rpmsg_bus virtio0: rpmsg host is online [ 202.264942] remoteproc remoteproc0: registered virtio0 (type 7) [ 202.318808] remoteproc remoteproc0: remote processor dsp is now up
Hey Rex,
The dmesg is from the OMAPL-138 LCDK that is trying to start my modified PDK USB Audio example.
The remoteproc0 name yields this:
root@omapl138-lcdk:~# cat /sys/kernel/debug/remoteproc/remoteproc0/name dsp
The remoteproc0 trace0 yields this:
3 Resource entries at 0xc3100000 [t=0x002e4459] {module#82}: {evt: 5, args=[0x0, 0x230 ...]} Timer create failed