SPRZ570A November   2023  – May 2024 AM263P4 , AM263P4-Q1

 

  1.   1
  2.   Abstract
  3. 1Usage Notes and Advisories Matrices
  4. 2Silicon Revision 1.0 Usage Notes and Advisories
    1. 2.1 Silicon Revision 1.0 Usage Notes
      1.      i2324
    2. 2.2 Silicon Revision 1.0 Advisories
      1.      i2189
      2.      i2310
      3.      i2374
      4.      i2311
      5.      i2345
      6.      i2351
      7.      i2352
      8.      i2353
      9.      i2354
      10.      i2356
      11.      i2357
      12.      i2358
      13.      i2359
      14.      i2383
      15.      i2392
      16.      i2393
      17.      i2394
      18.      i2401
      19.      i2403
      20.      i2404
      21.      i2405
      22.      i2426
      23.      i2427
      24.      i2428
      25.      i2433
      26.      i2438
      27.      i2439
  5. 3Trademarks
  6. 4Revision History

i2433

ICSS: Reading the 64-bit IEP timer does not have a lock MSW logic when LSW is read

Details:

IEPx 64-bit timestamp can be incorrect when lower 32-bit data is 0xFFFFFFFC or above (at 250MHz). In this case the upper 32-bit value is updated but lower value is the old number. The issue is seen when IEP counter (IEP_COUNT_REG1 : IEP_COUNT_REG0) is read back-to-back from ICSS PRU cores.

Example 1:

1st read : 0x000000D0(Upper):0xFFFFFFFC(lower)

2nd read : 0x000000D0(Upper):0x00000028(lower)

Example 2:

1st read : 0x000000D7(Upper):0xFFFFFFFC(lower)

2nd read : 0x000000D7(Upper):0x0000002C(lower)

Example 3:

1st read : 0x000000D6(Upper):0xFFFFFFF0(lower)

2nd read : 0x000000D7(Upper):0xFFFFFFFC((lower)

As shown above, this leads to timer increment behavior that is non-monotonic or timer differences to be unusually large as in Example 3 . This is due to 1 cycle race condition when loading 64-bit value from IEPx counter.

Workaround(s):

Note: these workarounds exist in SDK9.2 and later

Workaround in C for PRU:

uint64_t timestamp = (uint64_t) (0x2E0010); 

/* Workaround starts here */

if ((timestamp & 0xFFFFFFFF) >= 0xFFFFFFFC)

{     timestamp = *(uint64_t*) (0x2E0010); } 

/* Workaround ends here */

Workaround in assembly for PRU:

 ldi32 r4, 0xFFFFFFFC ; 0-4 for 250MHz clock
    ;load 64-bit timestamp to r2:r3
    lbco &r2, c26, 0x10, 8
    qbgt skip_iep_read_errata. r2, r4
    ;re-read IEP if IEP_COUNTER_LOW >= 0xFFFF_FFFC
    lbco &r2, c26, 0x10, 8
skip_iep_read_errata: 

Workaround in C for R5F, A53:

uint64_t getIepTimeStamp64 (void)
{
    uint64_t u64Timestamp1 = (volatile uint64_t)(0x300AE010);
    uint64_t u64Timestamp2 = (volatile uint64_t)(0x300AE010);
    if (u64Timestamp2 > u64Timestamp1)
    {
#ifdef __DEBUG
        if (((u64Timestamp2 >> 32)-(u64Timestamp1 >> 32)) == 1)
        {
            /* HW errata fixed due to picking u64Timestamp1*/
            if ((u64Timestamp2 & 0xFFFFFFFF) >= (u64Timestamp1 & 0xFFFFFFFF))
           

{                 DebugP_log ("Errata fixed (1): %llx : %llx\r\n", 
        u64Timestamp1, u64Timestamp2);             }

        }
#endif
        return u64Timestamp1;
    }
    else
    {
#ifdef __DEBUG
        if ((u64Timestamp2 & 0xFFFFFFFF) < (u64Timestamp1 & 0xFFFFFFFF))
       

{             /* Adjust the IEP MSW in the case running into HW errata */             
    DebugP_log ("Errata fixed (2): %llx : %llx\r\n", u64Timestamp1, 
u64Timestamp2);         }

#endif
        /* HW errata fixed due to picking u64Timestamp2*/
        return u64Timestamp2;
    }
}