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.

Linux/AM4376: PRU porting under RT

Part Number: AM4376
Other Parts Discussed in Thread: AM4372

Tool/software: Linux

Hello,

we use mainline kernel 4.9.61 with RT-patch on a custom board with AM4376. 

The goal is to use PRU: all 4 cores (without PRU ETH)

So I have ported the PRU related stuff from TI BSP: am437x-evm-linux-rt-sdk-src-04.02.00.09

Here the dmesg output at the start of PRU subsystem:

[   87.545684] ti-pruss 54400000.pruss: creating PRU cores and other child platform devices
[   87.582027] ti-pruss 54440000.pruss: creating PRU cores and other child platform devices
[   88.085916] pru-rproc 54434000.pru0: memory     iram: pa 0x54434000 size 0x3000 va e0b2c000
[   88.085950] pru-rproc 54434000.pru0: memory  control: pa 0x54422000 size 0x400 va e0b5d000
[   88.085965] pru-rproc 54434000.pru0: memory    debug: pa 0x54422400 size 0x100 va e0b5f400
[   88.085982] pru-rproc 54434000.pru0: mbox_request_channel failed: -19
[   88.091492] remoteproc remoteproc0: 54434000.pru0 is available
[   88.091625] pru-rproc 54434000.pru0: PRU rproc node /ocp@44000000/pruss_soc_bus@54426000/pruss@54400000/pru@54434000 probed successfully
[   88.093318] pru-rproc 54438000.pru1: memory     iram: pa 0x54438000 size 0x3000 va e0b64000
[   88.093365] pru-rproc 54438000.pru1: memory  control: pa 0x54424000 size 0x400 va e0b61000
[   88.093382] pru-rproc 54438000.pru1: memory    debug: pa 0x54424400 size 0x100 va e0b68400
[   88.093394] pru-rproc 54438000.pru1: mbox_request_channel failed: -19
[   88.097845] remoteproc remoteproc1: 54438000.pru1 is available
[   88.099976] pru-rproc 54438000.pru1: PRU rproc node /ocp@44000000/pruss_soc_bus@54426000/pruss@54400000/pru@54438000 probed successfully
[   88.101376] pru-rproc 54474000.pru0: memory     iram: pa 0x54474000 size 0x1000 va e0b6a000
[   88.101424] pru-rproc 54474000.pru0: memory  control: pa 0x54462000 size 0x400 va e0b6c000
[   88.101440] pru-rproc 54474000.pru0: memory    debug: pa 0x54462400 size 0x100 va e0b6e400
[   88.101453] pru-rproc 54474000.pru0: mbox_request_channel failed: -19
[   88.108919] remoteproc remoteproc2: 54474000.pru0 is available
[   88.111589] pru-rproc 54474000.pru0: PRU rproc node /ocp@44000000/pruss_soc_bus@54426000/pruss@54440000/pru@54474000 probed successfully
[   88.112675] pru-rproc 54478000.pru1: memory     iram: pa 0x54478000 size 0x1000 va e0b70000
[   88.114844] pru-rproc 54478000.pru1: memory  control: pa 0x54464000 size 0x400 va e0b72000
[   88.114869] pru-rproc 54478000.pru1: memory    debug: pa 0x54464400 size 0x100 va e0b74400
[   88.114887] pru-rproc 54478000.pru1: mbox_request_channel failed: -19
[   88.118688] remoteproc remoteproc3: 54478000.pru1 is available
[   88.122896] pru-rproc 54478000.pru1: PRU rproc node /ocp@44000000/pruss_soc_bus@54426000/pruss@54440000/pru@54478000 probed successfully

It seems to be the device tree issue (see /drivers/mailbox/mailbox.c):

struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index)
{
	struct device *dev = cl->dev;
	struct mbox_controller *mbox;
	struct of_phandle_args spec;
	struct mbox_chan *chan;
	unsigned long flags;
	int ret;

	if (!dev || !dev->of_node) {
		pr_debug("%s: No owner device node\n", __func__);
		return ERR_PTR(-ENODEV);
	}

	mutex_lock(&con_mutex);

	if (of_parse_phandle_with_args(dev->of_node, "mboxes",
				       "#mbox-cells", index, &spec)) {
		dev_dbg(dev, "%s: can't parse \"mboxes\" property\n", __func__);
		mutex_unlock(&con_mutex);
		return ERR_PTR(-ENODEV);
	}

Here is our dts patch:

diff -urwN a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
--- a/arch/arm/boot/dts/am4372.dtsi	2018-01-03 08:26:14.553435200 +0100
+++ b/arch/arm/boot/dts/am4372.dtsi	2018-01-10 09:44:20.312435400 +0100
@@ -342,6 +342,14 @@
 				ti,mbox-tx = <0 0="">;
 				ti,mbox-rx = <0 0="" 3="">;
 			};
+			mbox_pru1_0: mbox_pru1_0 {
+				ti,mbox-tx = <2 0="">;
+				ti,mbox-rx = <3 0="">;
+			};
+			mbox_pru1_1: mbox_pru1_1 {
+				ti,mbox-tx = <4 0="">;
+				ti,mbox-rx = <5 0="">;
+			};
 		};
 
 		timer1: timer@44e31000 {
@@ -926,6 +934,140 @@
 			interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		pruss_soc_bus: pruss_soc_bus@54426000 {
+			compatible = "ti,am4376-pruss-soc-bus";
+			reg = <0x54426000 0x2000="">;
+			ti,hwmods = "pruss";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+			status = "disabled";
+
+			pruss1: pruss@54400000 {
+				compatible = "ti,am4376-pruss";
+				reg = <0x54400000 0x2000="">,
+				      <0x54402000 0x2000="">,
+				      <0x54410000 0x8000="">,
+				      <0x54426000 0x2000="">,
+				      <0x5442e000 0x31c="">,
+				      <0x54432000 0x58="">;
+				reg-names = "dram0", "dram1", "shrdram2", "cfg",
+					    "iep", "mii_rt";
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges;
+				status = "disabled";
+
+				pruss1_intc: intc@54420000 {
+					compatible = "ti,am4376-pruss-intc";
+					reg = <0x54420000 0x2000="">;
+					reg-names = "intc";
+					interrupts =
+					    <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH
+					     GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH
+					     GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH
+					     GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH
+					     GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH
+					     GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH
+					     GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+					interrupt-names = "host2", "host3",
+							  "host4", "host5",
+							  "host6", "host8",
+							  "host9";
+					interrupt-controller;
+					#interrupt-cells = <1>;
+				};
+
+				pru1_0: pru@54434000 {
+					compatible = "ti,am4376-pru";
+					reg = <0x54434000 0x3000="">,
+					      <0x54422000 0x400="">,
+					      <0x54422400 0x100="">;
+					reg-names = "iram", "control", "debug";
+					label = "pru0";
+					interrupt-parent = <&pruss1_intc>;
+					interrupts = <16>, <17>;
+					interrupt-names = "vring", "kick";
+					status = "disabled";
+				};
+
+				pru1_1: pru@54438000 {
+					compatible = "ti,am4376-pru";
+					reg = <0x54438000 0x3000="">,
+					      <0x54424000 0x400="">,
+					      <0x54424400 0x100="">;
+					reg-names = "iram", "control", "debug";
+					label = "pru1";
+					interrupt-parent = <&pruss1_intc>;
+					interrupts = <18>, <19>;
+					interrupt-names = "vring", "kick";
+
+					status = "disabled";
+				};
+			};
+
+			pruss0: pruss@54440000 {
+				compatible = "ti,am4376-pruss";
+				reg = <0x54440000 0x1000="">,
+				      <0x54442000 0x1000="">,
+				      <0x54466000 0x2000="">,
+				      <0x5446e000 0x31c="">,
+				      <0x54472000 0x58="">;
+				reg-names = "dram0", "dram1", "cfg",
+					    "iep", "mii_rt";
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges;
+				status = "disabled";
+
+				pruss0_intc: intc@54460000 {
+					compatible = "ti,am4376-pruss-intc";
+					reg = <0x54460000 0x2000="">;
+					reg-names = "intc";
+					interrupts =
+					    <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH
+					     GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH
+					     GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH
+					     GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH
+					     GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH
+					     GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH
+					     GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
+					interrupt-names = "host2", "host3",
+							  "host4", "host5",
+							  "host6", "host8",
+							  "host9";
+					interrupt-controller;
+					#interrupt-cells = <1>;
+				};
+
+				pru0_0: pru@54474000 {
+					compatible = "ti,am4376-pru";
+					reg = <0x54474000 0x1000="">,
+					      <0x54462000 0x400="">,
+					      <0x54462400 0x100="">;
+					reg-names = "iram", "control", "debug";
+					label = "pru0";
+					interrupt-parent = <&pruss0_intc>;
+					interrupts = <16>, <17>;
+					interrupt-names = "vring", "kick";
+					status = "disabled";
+				};
+
+				pru0_1: pru@54478000 {
+					compatible = "ti,am4376-pru";
+					reg = <0x54478000 0x1000="">,
+					      <0x54464000 0x400="">,
+					      <0x54464400 0x100="">;
+					reg-names = "iram", "control", "debug";
+					label = "pru1";
+					interrupt-parent = <&pruss0_intc>;
+					interrupts = <18>, <19>;
+					interrupt-names = "vring", "kick";
+					status = "disabled";
+				};
+			};
+		};
+
 		mcasp0: mcasp@48038000 {
 			compatible = "ti,am33xx-mcasp-audio";
 			ti,hwmods = "mcasp0";

In my opinion "mboxes" statement is missing. But in which shape ?

Please help us to integrate PRU.

P.S.: I didn't test it with TI board and BSP, but I think the problem is there also present.

Best regards

Walter Wagner ABB

  • Hi,

    This forum supports only the Processor SDK as released by TI: software-dl.ti.com/.../index_FDS.html Latest released Linux-RT kernel is v4.9.28. Other versions are not supported here.
  • Hi Biser,

    does PRU work under latest supported v4.9.28 ?

    Best Regards
    Walter
  • As far as I know there have been not issues reported so far. I have asked the PRU experts to comment too. They will respond here.
  • Hello Walter, 

    1) Did you program ="" throughout your code above, or was that added accidentally when you added code to your post? I'm not familiar with the usage of ="" in a device tree.

    2) The descriptor properties of your mailbox child nodes (ti,mbox-tx and ti,mbox-rx) should have 3 cells of data each, not 2. This documentation is from Linux RT Processor SDK - there is binding documentation that explains how to program mailboxes in your device tree:

    ti-processor-sdk-linux-rt-am437x-evm-04.02.00.09/board-support/linux-rt-4.9.59+gitAUTOINC+273202a0d3-g273202a0d3/Documentation/devicetree/bindings/mailbox/omap-mailbox.txt

    Sub-mailbox Descriptor Data
    ---------------------------
    Each of the above ti,mbox-tx and ti,mbox-rx properties should have 3 cells of
    data that represent the following:
        Cell #1 (fifo_id) - mailbox fifo id used either for transmitting
                            (ti,mbox-tx) or for receiving (ti,mbox-rx)
        Cell #2 (irq_id)  - irq identifier index number to use from the parent's
                            interrupts data. Should be 0 for most of the cases, a
                            positive index value is seen only on mailboxes that have
                            multiple interrupt lines connected to the MPU processor.
        Cell #3 (usr_id)  - mailbox user id for identifying the interrupt line
                            associated with generating a tx/rx fifo interrupt.
    

    this document may have additional useful information for setting up the pru mailboxes.

    Here is a sample from am4372.dtsi in the 4.02 Linux RT SDK:

    		mailbox: mailbox@480C8000 {
    			compatible = "ti,omap4-mailbox";
    			reg = <0x480C8000 0x200>;
    			interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
    			ti,hwmods = "mailbox";
    			#mbox-cells = <1>;
    			ti,mbox-num-users = <4>;
    			ti,mbox-num-fifos = <8>;
    			mbox_wkupm3: wkup_m3 {
    				ti,mbox-send-noirq;
    				ti,mbox-tx = <0 0 0>;
    				ti,mbox-rx = <0 0 3>;
    			};
    			mbox_pru1_0: mbox_pru1_0 {
    				ti,mbox-tx = <2 0 0>;
    				ti,mbox-rx = <3 0 0>;
    			};
    			mbox_pru1_1: mbox_pru1_1 {
    				ti,mbox-tx = <4 0 0>;
    				ti,mbox-rx = <5 0 0>;
    			};
    		};
    

    Regards, 

    Nick

  • Hello Nick,

    many thanks for your answer.

    Sorry for the wrong HTML-view of the device tree fragments.

    Here hopefully the correct on:

    		mailbox: mailbox@480C8000 {
    			compatible = "ti,omap4-mailbox";
    			reg = <0x480C8000 0x200>;
    			interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
    			ti,hwmods = "mailbox";
    			#mbox-cells = <1>;
    			ti,mbox-num-users = <4>;
    			ti,mbox-num-fifos = <8>;
    			mbox_wkupm3: wkup_m3 {
    				ti,mbox-send-noirq;
    				ti,mbox-tx = <0 0 0>;
    				ti,mbox-rx = <0 0 3>;
    			};
    			mbox_pru1_0: mbox_pru1_0 {
    				ti,mbox-tx = <2 0 0>;
    				ti,mbox-rx = <3 0 0>;
    			};
    			mbox_pru1_1: mbox_pru1_1 {
    				ti,mbox-tx = <4 0 0>;
    				ti,mbox-rx = <5 0 0>;
    			};
    		};


    My problem was, I got a debug message at probe: mbox_request_channel failed: -19.
    So I thought, that would be lead to the error later.
    This is not correctly: PRU works properly.
    I do not understand, why mbox_pru1_0 and and mbox_pru1_1 are defined in the device tree.
    In my opinion they can be omitted.
    Anyway, my problem was solved.
    Mane thanks for your support.

  • Hello Walter,

    Short answer: You are correct, the mbox_pru code from Processor SDK 04.02 is only there for backwards compatibility. Your code uses PRU interrupts instead. mbox_request_channel failed: -19 is a kernel debug level output which simply means that your PRU is not using mailboxes for rpmsg functionality.

    Long answer: 

    Sitara devices initially used mailboxes for RPMsg. Newer Processor SDKs use PRU events instead. The mailbox in the sample PRU code was included for backwards compatibility, but may be phased out of future examples.

    Your code specifies interrupt-parent and interrupts, so it uses the PRU interrupts. As per the PRU Child Node section of the pruicss bindings document: (ti-processor-sdk-linux-rt-am437x-evm-04.02.00.09/board-support/linux-rt-4.9.59+gitAUTOINC+273202a0d3-g273202a0d3/Documentation/devicetree/bindings/remoteproc/ti,pruss-
    remoteproc.txt)

    Optional Properties:
    --------------------
    The virtio based communication between the MPU and a PRU core _requires_
    either the 'mboxes' property, or the set of 'interrupt-parent', 'interrupts'
    and 'interrupt-names' properties to be defined. The 'mboxes' property is not
    applicable for 66AK2G SoCs.

    The debug output is from the below section of driver code:

    (ti-processor-sdk-linux-rt-am437x-evm-04.02.00.09/board-support/linux-rt-4.9.59+gitAUTOINC+273202a0d3-g273202a0d3/drivers/remoteproc/pru_rproc.c)

    This code simply checks if mbox is used, if PRU interrupts are used, or if both are enabled. 

     

    if (IS_ERR(pru->mbox)) {
    
      ret = PTR_ERR(pru->mbox);
    
      pru->mbox = NULL;
    
      dev_dbg(dev, "mbox_request_channel failed: %d\n", ret);
    
     }
    
     pru->irq_vring = platform_get_irq_byname(pdev, "vring");
    
     if (pru->irq_vring <= 0) {
    
      ret = pru->irq_vring;
    
      if (ret == -EPROBE_DEFER)
    
       goto free_rproc;
    
      dev_dbg(dev, "unable to get vring interrupt, status = %d\n",
    
       ret);
    
     }
    
     pru->irq_kick = platform_get_irq_byname(pdev, "kick");
    
     if (pru->irq_kick <= 0) {
    
      ret = pru->irq_kick;
    
      if (ret == -EPROBE_DEFER)
    
       goto free_rproc;
    
      dev_dbg(dev, "unable to get kick interrupt, status = %d\n",
    
       ret);
    
     }
    
     if (pru->mbox && (pru->irq_vring > 0 || pru->irq_kick > 0))
    
      dev_warn(dev, "both mailbox and vring/kick system events defined\n");
    
            if (IS_ERR(pru->mbox)) {
                     ret = PTR_ERR(pru->mbox);
                     pru->mbox = NULL;
                     dev_dbg(dev, "mbox_request_channel failed: %d\n", ret);
             }
    
    pru->irq_vring = platform_get_irq_byname(pdev, "vring");
             if (pru->irq_vring <= 0) {
                     ret = pru->irq_vring;
                     if (ret == -EPROBE_DEFER)
                             goto free_rproc;
                     dev_dbg(dev, "unable to get vring interrupt, status = %d\n",
                             ret);
             }
    
    pru->irq_kick = platform_get_irq_byname(pdev, "kick");
             if (pru->irq_kick <= 0) {
                     ret = pru->irq_kick;
                     if (ret == -EPROBE_DEFER)
                             goto free_rproc;
                     dev_dbg(dev, "unable to get kick interrupt, status = %d\n",
                             ret);
             }
    
    if (pru->mbox && (pru->irq_vring > 0 || pru->irq_kick > 0))
                     dev_warn(dev, "both mailbox and vring/kick system events defined\n");
    

     

    Regards,

    Nick