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.

AM623: PRU SW of AM3356 can be used in AM62x?

Part Number: AM623
Other Parts Discussed in Thread: AM3356

Dear Champs,

My customer is trying to upgrade their product based on AM3356 to AM623x, and there is PRU SW to send data using PRU-GPIO.

They want to check if PRU SW of AM3356 can be used in AM623x without change when only PRU-GPIO was used.

If not, they want to check if below scenario can be used in AM623x just with register address change. Could you please check below scenario can be worked on AM623x?

Their target OS on A53 is Llinux.

I'm worrying their SDK version of AM3356 was too old and it can not be used in AM62x.

~~~~~~~

1. PRU_INIT

- PRU RESET using Power Reset Module Peripheral Register(0x44e0 0c00)

2. PRU_DISABLE

- PRU_DISABLE using PRU_ICSS_START_ADDR(0x4A30 0000) + OFFSET_PRU_ICSS_PRU0_CONTROL(0x2 2000) register

3. PRU_UPLOAD

- PRU RESET using Power Reset Module Peripheral Register(0x44e0 0c00)

- module enable using Clock Module Peripheral Registers (0x44e00000) + CM_PER_ICSS_CLKCTRL (0xe8) .

- activate OCP clock using Clock Module Peripheral Registers (0x44e00000) + CM_PER_ICSS_CLKSTCTRL(0x140).

- After activate OCP clock, userspace application will read PRU0.bin file through kernel device driver(char) and mmap/remap_pfn_range of '/dev/pru_control', and this PRU binary file was wrote into PRU_ICSS_START_ADDR (0x4a30_0000) + 0x3_4000 = 0x4A33_4000.

 

4.PRU_ENABLE

- PRU_ENABLE using PRU_ICSS_START_ADDR (0x4a30_0000) + OFFSET_PRU_ICSS_PRU0_CONTROL(0x2_2000) register

Thanks and Best Regards,

SI.

  • The subject matter expert is currently out of the office. Please allow a couple of days for a response. Thanks.

  • Hello SI,

    Apologies for the delayed response here. Yes, PRU code that was developed on the AM335x PRU-ICSS can also be run on the AM62x PRUSS. You can find our PRU resources here:

    https://software-dl.ti.com/processor-sdk-linux/esd/AM62X/08_06_00_42/exports/docs/common/PRU-ICSS/Overview.html

    I'm not sure why you are enabling the PRU with direct register writes though. Linux uses the RemoteProc driver to initialize remote cores, including PRU cores.

    Another thing to note: newer processors like AM62x do not require you to enable the OCP port before the PRU core can access memory regions outside of the PRU subsystem.

    Regards,

    NIck

  • Hello Nick,

    Thanks for the response.

    Is there any device tree example to run PRU interrupt in AM62x?

    When they tried to modify device tree to use PRU in AM62x by referring AM335x, they failed to compile it and faced compiler error.

    Could you please share device tree for PRU in AM62x? 

    Thanks and Best Regards,

    SI.

  • Hello SI,

    Please reference the comments in the INTC configuration files for these PRU Software Support Package examples:
    https://git.ti.com/cgit/pru-software-support-package/pru-software-support-package/tree/examples/am62x/PRU_RPMsg_Echo_Interrupt0/intc_map_0.h
    https://git.ti.com/cgit/pru-software-support-package/pru-software-support-package/tree/examples/am62x/PRU_RPMsg_Echo_Interrupt0/intc_map_0.h

    You can find more documentation about INTC configuration in Linux kernel 5.10 and later here:
    https://software-dl.ti.com/processor-sdk-linux/esd/AM62X/08_06_00_42/exports/docs/common/PRU-ICSS/INTC_Configuration.html

    If the customer cannot get their example running, please provide:
    1) What version of Linux is being used
    2) What changes are being made to which Linux devicetree?
    3) What are the steps to compile, and the errors that are observed?

    Regards,

    Nick

  • Hello Nick,

    SDK : ti-processor-sdk-linux-am62xx-evm-08.05.00.21

    PRU : Programmable Real-time Unit (PRU) Software Support Package v6.1.0

    When they added interrupt-parent nodes as below,

    kkk_common {

            pinctrl-0 = <&kisan_system_pins>;

     

            compatible = "kisan_common";

            status = "okay";

           

            UDP_PORT = <7890>;

            SIG_NUM  = <44>;

     

            interrupt-parent = <&icssg0_intc>;

            interrupts = <21 2 2>, <22 3 3>;

            interrupt-names = "pru_icss_evtout0", "pru_icss_evtout1";

        };

    They faced an error that there is no 'icssg0_intc' as below.

    DTC     arch/arm64/boot/dts/ti/k3-am625-sk.dtb

    arch/arm64/boot/dts/ti/k3-am625-sk.dts:45.15-57.4: ERROR (phandle_references): /kkk_common: Reference to non-existent node or label "icssg0_intc"

    By referring 'K3-am62-main.dtsi', they changed to pruss_intc in interrupt_parent as below, and they success to build.

    kkk_common {

            pinctrl-0 = <&kisan_system_pins>;

     

            compatible = "kisan_common";

            status = "okay";

           

            UDP_PORT = <7890>;

            SIG_NUM  = <44>;

     

            interrupt-parent = <&pruss_intc>;

            interrupts = <21 2 2>, <22 3 3>;

            interrupt-names = "pru_icss_evtout0", "pru_icss_evtout1";

        };

    After this success in build, they tried to get IRQ allocation through irq_of_parse_and_map as below, and faced error in below.

    static int kkk_common_probe(struct platform_device *pdev)

    {

        struct StructKisanCommonData *pdata = NULL;

        struct device_node *np = pdev->dev.of_node;

        int nErr = 0;

    int nIrq = 0;

     

        pdata = devm_kzalloc(&pdev->dev, sizeof(struct StructKisanCommonData), GFP_KERNEL);

        if(!pdata) {

            printk(KERN_ERR "[%s:%4d] Failed to devm_kzalloc...\n", __FILENAME__, __LINE__);

            return -ENOMEM;

        }

     

    pdata->pdev = pdev;

        pdata->mdev.minor = MISC_DYNAMIC_MINOR;

        pdata->mdev.name = "kisan_common";

        pdata->mdev.fops = &kisan_common_fops;

     

    nErr = misc_register(&pdata->mdev);

        if(nErr) {

            dev_err(&pdev->dev,"failed to register misc device\n");

            devm_kfree(&pdev->dev, pdata);

            return nErr;

        }

     

    platform_set_drvdata(pdev, pdata);

     

        nIrq = irq_of_parse_and_map(np, 0);

        printk(KERN_DEBUG "[%s:%4d] pru_icss_evtout%d PRU IRQ# %d \n", __FILENAME__, __LINE__, 0, nIrq);

        irq_set_irq_type(nIrq, IRQ_TYPE_DEFAULT);

     

    They faced error in below.

    Could you please help how they can resolve this?

    [    0.755474] irq: no irq domain found for interrupt-controller@20000 !

    [    0.762061] [kkk_common.c: 641] pru_icss_evtout0 PRU IRQ# 0

    Thanks and Best Regards,

    SI.

  • Hello SI,

    We are starting to move into territory where I have not run experiments myself. Please let me know what the solution is when the customer figures it out.

    One potential template is the PRU Ethernet driver on other PRU devices. For example, on AM64x:

    devicetree information in arch/arm64/boot/dts/ti/k3-am642-evm.dts: 

    icssg1_eth: icssg1-eth {
                    compatible = "ti,am642-icssg-prueth";
                    pinctrl-names = "default";
                    pinctrl-0 = <&icssg1_rgmii1_pins_default>;
    
    ...
                    interrupt-parent = <&icssg1_intc>;
                    interrupts = <24 0 2>, <25 1 3>;
                    interrupt-names = "tx_ts0", "tx_ts1";
    

    Potentially useful driver information in drivers/net/ethernet/ti/icssg_prueth.c:

            irq_name = "tx_ts0";
            if (emac->port_id == PRUETH_PORT_MII1)
                    irq_name = "tx_ts1";
            emac->tx_ts_irq = platform_get_irq_byname_optional(prueth->pdev, irq_name);
            if (emac->tx_ts_irq < 0) {
                    ret = dev_err_probe(prueth->dev, emac->tx_ts_irq, "could not get tx_ts_irq\n");
                    goto free;
            }
    ...
            if (!emac->is_sr1) {
                    ret = request_threaded_irq(emac->tx_ts_irq, NULL, prueth_tx_ts_irq,
                                               IRQF_ONESHOT, dev_name(dev), emac);
                    if (ret)
                            goto stop;
            }
    

    Regards,

    Nick