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.

[FAQ] PROCESSOR-SDK-AM57X: U-boot patch for Linux addressing AM57xx errata i2446

Part Number: PROCESSOR-SDK-AM57X


Tool/software:

This is a patch to made for U-boot as an example of how to implement the workaround for  AM57xx errata i2446:

  • Setup

    • The patch is implemented from u-boot source and utilizes EDMA3 driver. – drivers/dma/ti-edma3.c

    • This driver is enabled by enabling TI_QSPI, which should be enabled by default in defconfig file – am57xx_evm_defconfig Implementation

    Procedure

    • It uses the EDMA3 API to make a single 16-Byte transfer to both PRU-ICSS clk registers, enabling them one after the other

    • Based on usage example with QSPI: drivers/spi/ti_qspi.c::ti_qspi_copy_mmap()

    • EDMA3_transfer transfers 16 bytes from OCM memory to CM_L4PER2_PRUSS1_CLKCTRL and CM_L4PER2_PRUSS2_CLKCTRL registers under 20 ns.

    Patch

    Patch originally made for ti-u-boot-2019.01

    diff --git a/arch/arm/mach-omap2/omap5/hw_data.c b/arch/arm/mach-omap2/omap5/hw_data.c
    index 955e721682..727235cee1 100644
    --- a/arch/arm/mach-omap2/omap5/hw_data.c
    +++ b/arch/arm/mach-omap2/omap5/hw_data.c
    @@ -8,6 +8,7 @@
      *
      * Sricharan R <r.sricharan@ti.com>
      */
    +
     #include <common.h>
     #include <palmas.h>
     #include <asm/arch/omap.h>
    @@ -17,6 +18,7 @@
     #include <asm/omap_gpio.h>
     #include <asm/io.h>
     #include <asm/emif.h>
    +#include <asm/ti-common/ti-edma3.h>
     
     struct prcm_regs const **prcm =
     			(struct prcm_regs const **) OMAP_SRAM_SCRATCH_PRCM_PTR;
    @@ -516,6 +518,34 @@ void enable_basic_clocks(void)
     			OPTFCLKEN_SCRM_CORE_MASK);
     }
     
    +#if defined(CONFIG_DRA7XX)
    +static void do_edma3_copy(void *addrs, void *src_data, size_t len)
    +{
    +	unsigned int			edma_slot_num = 1;
    +
    +	/* enable edma3 clocks */
    +	enable_edma3_clocks();
    +
    +	/* Call edma3 api to do actual DMA transfer	*/
    +	edma3_transfer(EDMA3_BASE, edma_slot_num, addrs, src_data, len);
    +
    +	/* disable edma3 clocks */
    +	disable_edma3_clocks();
    +}
    +#endif
    +
    +#if defined(CONFIG_DRA7XX)
    +void do_enable_pruss_clocks(void)
    +{
    +	unsigned int *address = (unsigned int *) 0x4A009718;
    +
    +	unsigned int data[4] = {0x2,0x0,0x2,0x0};
    +
    +	do_edma3_copy(address,data,16);
    +
    +}
    +#endif
    +
     void enable_basic_uboot_clocks(void)
     {
     	u32 const clk_domains_essential[] = {
    @@ -548,6 +578,10 @@ void enable_basic_uboot_clocks(void)
     			 clk_modules_hw_auto_essential,
     			 clk_modules_explicit_en_essential,
     			 1);
    +
    +#if defined(CONFIG_DRA7XX)
    +	do_enable_pruss_clocks();
    +#endif
     }
     
     #ifdef CONFIG_TI_EDMA3

    Test for this failure

    In order to verify that this errata is indeed what is causing the A15 to crash, one can test this at u-boot prompt using memory dumps to access the PRUSS global counters:

    – PRUSS_IEP_GLOBAL_CFG (PRUSS1_IEP)

    – PRUSS_IEP_GLOBAL_CFG (PRUSS2_IEP)

    U-Boot Prompt

    => md.l 0x4B22E000 1

    => md.l 0x4B2AE000 1

    Example: