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.

PROCESSOR-SDK-AM64X: PRU IEP Time Synchronization issues

Part Number: PROCESSOR-SDK-AM64X
Other Parts Discussed in Thread: TMDS64EVM

Tool/software:

Dear TI team,

while experimenting with the QoS features of the icssg-prueth driver in the Linux SDK 11.00.09.04 we encountered some incomplete features or problems that haven't been considered regarding IEP PPS time synchronization.

Setup:

  • SoC: AM64X SR2.0 HS-FS
  • Model: Texas Instruments AM642 EVM
  • Board: AM64-EVM rev C
  • Image: PROCESSOR-SDK-LINUX-RT-AM64X Debian Trixie Version: 11.00.09.04

1st issue: IEP frequency offset at 333MHz

# install tools
apt install ethtool linuxptp memtool

# disable NTP
timedatectl set-ntp false

# synchronize CLOCK_REALTIME to the IEP
phc2sys -s /dev/ptp2 -c CLOCK_REALTIME -O 0 -l 7 -m

Since both clocks are derived from the same quartz one would expect them to be able to synchronize to +-0ppb frequency offset (minor jitter because of the software cross-timestamping). With the IEP running at 333MHz we observe a frequency offset of +2,000ppb:

phc2sys[466.360]: CLOCK_REALTIME phc offset 1893344 s0 freq -0 delay 270
phc2sys[467.360]: CLOCK_REALTIME phc offset 1895344 s1 freq +1998 delay 270
phc2sys[468.361]: CLOCK_REALTIME phc offset 4 s2 freq +2002 delay 265
phc2sys[469.361]: CLOCK_REALTIME phc offset 4 s2 freq +2003 delay 270
phc2sys[470.362]: CLOCK_REALTIME phc offset 2 s2 freq +2002 delay 270
phc2sys[471.362]: CLOCK_REALTIME phc offset -6 s2 freq +1995 delay 275
phc2sys[472.362]: CLOCK_REALTIME phc offset 4 s2 freq +2003 delay 270
phc2sys[473.363]: CLOCK_REALTIME phc offset -2 s2 freq +1998 delay 270
phc2sys[474.364]: CLOCK_REALTIME phc offset 1 s2 freq +2000 delay 270

This can be explained by looking at the way the IEP is generating the internal 1ms cycle from the 333MHz clock with these register settings:
0x00 IEP_GLOBAL_CFG_REG: 0x00000331 == 3ns increment per 333MHz clock cycle (no compensation per default)
0x7c IEP_CMP0_REG1: 0x000f423d == 999,997ns

Clock cycle 0: 0 cycles, 0ns
Clock cycle 1: 0 cycles, 3ns
...
Clock cycle 333,332: 0 cycles, 999,996ns
Clock cycle 333,333: 0 cycles, 999,999ns <- since 999,999ns >= 999,997ns (CMP0) the counter is reset at the next clock edge
Clock cycle 333,334: 1 cycles, 0ns <- the IEP has "added" 1ns instead of 3ns -> we are losing 2ns per 1ms cycle -> 2,000ppb

Q: Is this the intended behavior for the IEP? 1ms in the IEP clock domain does not really equal 1ms in "real time", it's only 999,998 ns long.
Q: Shouldn't the firmware take care of compensating this by setting a 2,000ppb frequency offset in the IEP compensation registers by default?
Q: Must the IEP run at the same clock speed as the prueth-firmware (333MHz)? If the IEP could run at 200MHz or 250MHz this would not be a problem.

2nd issue: PPS output with taprio schedule

For a customer application we would like to use the PPS output of the IEP to synchronize one or more other system clocks (e.g. the MAIN_CPTS0) to the IEP time while the prueth port is running an arbitrary taprio schedule.

# route AM64X_DEV_PRU_ICSSG1-pr1_edc0_sync0_out to AM64X_DEV_CPTS0-cpts_hw1_push through the TIMESYNC_EVENT_INTROUTER0
memtool mw -l 0x00A40044 0x1001d

# e.g. setup PRU for 4 TX queues
ip link set down end2
ethtool -L end2 rx 1 tx 4
ip link set up end2

# setup a 1ms schedule for 4 traffic classes
tc qdisc replace dev end2 parent root taprio \
num_tc 4 \
map 0 1 2 3 \
queues 1@0 1@1 1@2 1@3 \
base-time 0 \
sched-entry S 0x01 100000 \
sched-entry S 0xfe 900000 \
flags 0x2

# synchronize the MAIN_CPTS0 to the IEP clock
ts2phc -c /dev/ptp1 -s /dev/ptp2 -m -l7
...
ts2phc[1263.944]: adding tstamp 1746708674.000000000 to clock /dev/ptp1
ts2phc[1263.944]: adding tstamp 1746708674.000000000 to clock /dev/ptp2
ts2phc[1263.944]: /dev/ptp1 offset 0 s2 freq +2000
ts2phc[1264.944]: adding tstamp 1746708675.000000000 to clock /dev/ptp1
ts2phc[1264.944]: adding tstamp 1746708675.000000000 to clock /dev/ptp2
ts2phc[1264.944]: /dev/ptp1 offset 0 s2 freq +2000
ts2phc[1265.944]: adding tstamp 1746708676.000000000 to clock /dev/ptp1
ts2phc[1265.944]: adding tstamp 1746708676.000000000 to clock /dev/ptp2
ts2phc[1265.944]: /dev/ptp1 offset 0 s2 freq +2000

So far so good (sans the 2,000ppb frequency offset from 1.).
Unfortunately, changing to a schedule that is != 1ms long breaks the time synchronization:

# setup a 1.5ms schedule for 4 traffic classes
tc qdisc replace dev end2 parent root taprio \
num_tc 4 \
map 0 1 2 3 \
queues 1@0 1@1 1@2 1@3 \
base-time 0 \
sched-entry S 0x01 100000 \
sched-entry S 0xfe 900000 \
sched-entry S 0xf8 500000 \
flags 0x2

# Running synchronization in another shell:
ts2phc[1470.944]: adding tstamp 1746708881.000000000 to clock /dev/ptp1
ts2phc[1470.945]: adding tstamp 1746708881.000000000 to clock /dev/ptp2
ts2phc[1470.945]: /dev/ptp1 offset 0 s2 freq +1999
ts2phc[1472.165]: adding tstamp 1746708882.220498677 to clock /dev/ptp1
ts2phc[1472.167]: adding tstamp 1746708882.000000000 to clock /dev/ptp2
ts2phc[1472.167]: /dev/ptp1 offset 220498677 s2 freq +488281
ts2phc[1473.665]: adding tstamp 1746708883.719767564 to clock /dev/ptp1
ts2phc[1473.665]: adding tstamp 1746708883.000000000 to clock /dev/ptp2
ts2phc[1473.665]: /dev/ptp1 offset 719767564 s2 freq +488281
ts2phc[1475.165]: adding tstamp 1746708885.219035142 to clock /dev/ptp1
ts2phc[1475.165]: adding tstamp 1746708884.000000000 to clock /dev/ptp2
ts2phc[1475.165]: /dev/ptp1 offset 1219035142 s2 freq +488281
ts2phc[1476.665]: adding tstamp 1746708886.718302720 to clock /dev/ptp1
ts2phc[1476.665]: adding tstamp 1746708885.000000000 to clock /dev/ptp2
ts2phc[1476.665]: /dev/ptp1 offset 1718302720 s2 freq +488281

Even restarting the ts2phc application won't fix it. Looking at the implementation in the icss_iep.c/icssg_pruet.c kernel driver this is no surprise:

static int prueth_perout_enable(void *clockops_data,
struct ptp_perout_request *req, int on,
u64 *cmp)
{
struct prueth_emac *emac = clockops_data;
u32 reduction_factor = 0, offset = 0;
struct timespec64 ts;
u64 current_cycle;
u64 start_offset;
u64 ns_period;

if (!on)
return 0;

/* Any firmware specific stuff for PPS/PEROUT handling */
ts.tv_sec = req->period.sec;
ts.tv_nsec = req->period.nsec;
ns_period = timespec64_to_ns(&ts);

/* f/w doesn't support period less than cycle time */
if (ns_period < IEP_DEFAULT_CYCLE_TIME_NS)
return -ENXIO;

reduction_factor = ns_period / IEP_DEFAULT_CYCLE_TIME_NS;
offset = ns_period % IEP_DEFAULT_CYCLE_TIME_NS;

/* f/w requires at least 1uS within a cycle so CMP
* can trigger after SYNC is enabled
*/
if (offset < 5 * NSEC_PER_USEC)
offset = 5 * NSEC_PER_USEC;

/* if offset is close to cycle time then we will miss
* the CMP event for last tick when IEP rolls over.
* In normal mode, IEP tick is 4ns.
* In slow compensation it could be 0ns or 8ns at
* every slow compensation cycle.
*/
if (offset > IEP_DEFAULT_CYCLE_TIME_NS - 8)
offset = IEP_DEFAULT_CYCLE_TIME_NS - 8;

/* we're in shadow mode so need to set upper 32-bits */
*cmp = (u64)offset << 32;

writel(reduction_factor, emac->prueth->shram.va +
TIMESYNC_FW_WC_SYNCOUT_REDUCTION_FACTOR_OFFSET);

current_cycle = icssg_read_time(emac->prueth->shram.va +
TIMESYNC_FW_WC_CYCLECOUNT_OFFSET);

/* Rounding of current_cycle count to next second */
start_offset = roundup(current_cycle, MSEC_PER_SEC);

hi_lo_writeq(start_offset, emac->prueth->shram.va +
TIMESYNC_FW_WC_SYNCOUT_START_TIME_CYCLECOUNT_OFFSET);

return 0;
}

The PPS output configuration is calculated for the IEP_DEFAULT_CYCLE_TIME_NS (1,000,000ns), not the actual cycle time (1.5ms) after changing the taprio schedule.

Q: Will this be fixed in an upcoming Kernel version?

A simple fix, where one would have to restart the time synchronization after the schedule is changed would be sufficient for us for now.

Q: Are there any plans to fix this in the PRU firmware? In the cycle where the schedule is changed the firmware would need to recalculate and set the reduction factor and offset etc. if the PPS signal is enabled.

3rd issue: PPS output with offset (CMP1)

If we recalculate the register values for e.g. a 1.5ms cycle and set them accordingly in the IEP/Firmware registers we hit another issue. If 1s is not divisible by the cycle time the reduction factor (number of full cycles per second) and/or the offset (time in the cycle to get to 1s) would need to change every PPS cycle.

First the working 1ms cycle time:

reduction_factor: 1,000
offset: 5,000ns (because of firmware restrictions)

At 1ms cycle time the first PPS be at "start cycle" time:
-> 0 * 1ms + 5,000ns = 5,000ns

The second PPS signal would be at (activating the sync output in the 1000th cycle):
-> 995,000ns (remaining from last sync cylce) + 999 * 1ms + 5,000ns = 1,000,005,000ns

The third PPS signal would be at:
-> 995,000ns (remaining from last sync cylce) + 999 * 1ms + 5,000ns = 2,000,005,000ns


Now for the 1.5ms cycle time without any register update:

reduction_factor: 666
offset: 1,000,000ns

The first PPS would be at "start cycle" time:
-> 0 * 1.5ms + 1,000,000ns = 1,000,000ns

The second PPS would be at:
-> 500,000ns (remaining from the last cycle) + 665 * 1.5ms + 1,000,000ns = 1,000,000,000ns

The third PPS would be at:
-> 500,000ns (remaining from the last cycle) + 665 * 1.5ms + 1,000,000ns = 1.999.000.000ns

The fourth PPS would be at:
-> 500,000ns (remaining from the last cycle) + 665 * 1.5ms + 1,000,000ns = 2.998.000.000ns

After the second PPS it will be short 1ms every time.


This would have to be fixed by updating the offset and reduction_factor after every PPS output:

reduction_factor: 666
offset: 5,000ns

The first PPS would be at "start cycle" time:
-> 0 * 1.5ms + 1,000,000ns = 5,000ns

reduction_factor: 666
offset: 1,005,000ns

The second PPS would be at:
-> 1,495,000ns (remaining from the last cycle) + 665 * 1.5ms + 1,005,000ns = 1,000,005,000ns

reduction_factor: 667
offset: 5,000ns

The third PPS would be at:
-> 495,000ns (remaining from the last cycle) + 666 * 1.5ms + 5,000ns = 2,000,005,000ns

Implementing this outside of the PRU firmware would require an interrupt on the PPS in the Kernel driver and then racing against the reduction factor up-counter to set the reduction factor and offset before the next PPS output, which is why we believe that this needs to be fixed within the firmware.

Q: Shouldn't the firmware take care of these calculations if the PPS interval is not divisible by the cycle time? Are there any fixes planned?

Best Regards,

Dominic

  • Hi Dominic,

    1st issue

    Q: Is this the intended behavior for the IEP? 1ms in the IEP clock domain does not really equal 1ms in "real time", it's only 999,998 ns long.
    Q: Shouldn't the firmware take care of compensating this by setting a 2,000ppb frequency offset in the IEP compensation registers by default?
    Q: Must the IEP run at the same clock speed as the prueth-firmware (333MHz)? If the IEP could run at 200MHz or 250MHz this would not be a problem.

    I'm checking internally with the ICSS team to see if the firmware should be compensating for the 2000ppb freq offset and if this behavior is intended. From an initial test of phc2sys (even on SDK 10.01), I also see there is ~2000ppb offset.

    It looks like from the AM64x EVM (TMDS64EVM) device tree ("k3-am64-main.dtsi"), the IEP clock is sourced from the same clock as the ICSSG core clock ("ICSSGn_CORE_CLK), which is 333MHz. Based on the TRM, the IEP clock can alternatively be sourced from a separate clock source ("ICSSGn_IEP_CLK"). It may be possible to change the clock source of the IEP clock to a different clock in the device tree. Try applying similar changes as described in https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1049800/faq-pru_icssg-how-to-check-and-set-pru-core-frequency-in-linux/3959698?tisearch=e2e-sitesearch&keymatch=IEP%252525252520333MHz#3959698, but making sure to apply on the "icssg0_iepclk_mux" node.

    1ms in the IEP clock domain does not really equal 1ms in "real time", it's only 999,998 ns long.

    Also, why is it 999,998ns as opposed to 999,999,999ns as you explained in your calculation for the 333,333 clock cycle?

    -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    2nd issue

    Q: Will this be fixed in an upcoming Kernel version?

    A simple fix, where one would have to restart the time synchronization after the schedule is changed would be sufficient for us for now.

    Q: Are there any plans to fix this in the PRU firmware? In the cycle where the schedule is changed the firmware would need to recalculate and set the reduction factor and offset etc. if the PPS signal is enabled.

    I'm trying to check internally on if this is something that needs to be changed in the firmware. Based on your questions here, are you indicating this is something both the Kernel driver and firmware needs to fix?

    -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    3rd issue

    I have a couple questions regarding the 3rd issue:

    If we recalculate the register values for e.g. a 1.5ms cycle and set them accordingly in the IEP/Firmware registers we hit another issue.

    When you refer to "cycle time" for the 3rd issue relating to PPS, what exactly is the context of this "cycle time". Do you mean IEP cycle time (i.e. IEP_DEFAULT_CYCLE_TIME_NS) and is not the same as the taprio schedule cycle time from the 2nd issue?

    offset: 5,000ns (because of firmware restrictions)

    How did you determine/calculate the offset?

    The second PPS signal would be at (activating the sync output in the 1000th cycle):
    -> 995,000ns (remaining from last sync cylce) + 999 * 1ms + 5,000ns = 1,000,005,000ns

    How did you calculate the 995,000ns? What did you mean by "remaining from last sync cycle"? When I calculated 995,000+(999*1000000ns)+5000ns, I actually get 1,000,000,000 instead of 1,000,005,000ns?

    The second PPS signal would be at (activating the sync output in the 1000th cycle):
    -> 995,000ns (remaining from last sync cylce) + 999 * 1ms + 5,000ns = 1,000,005,000ns

    The third PPS signal would be at:
    -> 995,000ns (remaining from last sync cylce) + 999 * 1ms + 5,000ns = 2,000,005,000ns

    The formulas for the 2nd and 3rd PPS signal are the same as the 1st PPS signal? (i.e. 995,000ns (remaining from last sync cylce) + 999 * 1ms + 5,000ns) However the result is 1,000,000,000ns more?

    offset: 1,000,000ns

    Again, can you explain how you determined the offset?

    The second PPS would be at:
    -> 500,000ns (remaining from the last cycle) + 665 * 1.5ms + 1,000,000ns = 1,000,000,000ns

    Can you explain how you obtained the 500,000ns?

    The third PPS would be at:
    -> 500,000ns (remaining from the last cycle) + 665 * 1.5ms + 1,000,000ns = 1.999.000.000ns

    The fourth PPS would be at:
    -> 500,000ns (remaining from the last cycle) + 665 * 1.5ms + 1,000,000ns = 2.998.000.000ns

    The numbers in the formula for the third and fourth PPS look the same, but the result is different, how did you determine these numbers?

    -Daolin

  • Hello Daolin,

    thanks for your response.

    Also, why is it 999,998ns as opposed to 999,999,999ns as you explained in your calculation for the 333,333 clock cycle?

    The problem occurs from 333,333th clock cycle to 333,334th clock cycle. At that point the counter should read 1,000,000,002ns, but it only reads "1 cycle + 0ns", so 1,000,000,000ns, thus loosing 2ns.

    We would like to understand if there are any concerns regarding the firmware's use of the ICSS-G / IEP if we clocked the IEP asynchronously to the rest of the ICSS-G. Hardware-wise this is possible, and I'm pretty sure it can be configured (or adapted to being configurable), but there could be caveats regarding asynchronous clocks that we don't understand.

    I'm trying to check internally on if this is something that needs to be changed in the firmware. Based on your questions here, are you indicating this is something both the Kernel driver and firmware needs to fix?

    The kernel driver can fix only part of this issue, but a proper fix would probably require changes to the firmware, which in turn would require a kernel driver change, too.

    We modified the kernel driver (or rather implemented our own), and that works for the cases where 1s (for a PPS) is divisible by the cycle time (e.g. 1ms cycle, 2ms cycle time) but not for cases where there's a remainder (e.g. 1.5ms cycle time). This is the 3rd issue.

    Another problem with adapting only the kernel driver is that for some use-cases you want to be able to dynamically change the EST schedule. For the EST schedule this is already supported, but afterwards the PPS is broken again. Fixing that would require updating the PPS parameters (reduction factor and offset) synchronized to the EST schedule update.

    When you refer to "cycle time" for the 3rd issue relating to PPS, what exactly is the context of this "cycle time". Do you mean IEP cycle time (i.e. IEP_DEFAULT_CYCLE_TIME_NS) and is not the same as the taprio schedule cycle time from the 2nd issue?

    That is refering to a IEP kernel driver that we modified ourselves. We fixed the use of IEP_DEFAULT_CYCLE_TIME_NS and ran into the problem when the cycle time is not a multiple of 1 second, which is what this 3rd issue is about.

    offset: 5,000ns (because of firmware restrictions)

    How did you determine/calculate the offset?

    That happens in icssg_prueth.c: https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tree/drivers/net/ethernet/ti/icssg/icssg_prueth.c?h=ti-linux-6.12.y#n537

    The second PPS signal would be at (activating the sync output in the 1000th cycle):
    -> 995,000ns (remaining from last sync cylce) + 999 * 1ms + 5,000ns = 1,000,005,000ns

    How did you calculate the 995,000ns? What did you mean by "remaining from last sync cycle"? When I calculated 995,000+(999*1000000ns)+5000ns, I actually get 1,000,000,000 instead of 1,000,005,000ns?

    Sorry, these results are all "absolute" IEP time. So basically there's a "<time-of-last-pps> +" in front of all the formulas, e.g.:.

    1st PPS was in first cycle, offset 5us.

    <time-of-last-pps = 5,000) + 995,000ns (remaining from last sync cylce) + 999 * 1ms + 5,000ns = 1,000,005,000ns

    At 1ms cycle this is the working case. The delta between the 1st and the 2nd PPS is 1s, so everything is fine in this case.

    The formulas for the 2nd and 3rd PPS signal are the same as the 1st PPS signal? (i.e. 995,000ns (remaining from last sync cylce) + 999 * 1ms + 5,000ns) However the result is 1,000,000,000ns more?

    Same as above, that's the working case, and the results are in "absolute" IEP time.

    The second PPS would be at:
    -> 500,000ns (remaining from the last cycle) + 665 * 1.5ms + 1,000,000ns = 1,000,000,000ns

    Can you explain how you obtained the 500,000ns?

    That's the offset you get when dividing 1,000,000,000ns by 1,500,000ns: 666 cycles + 1,000,000ns offset in this line: https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tree/drivers/net/ethernet/ti/icssg/icssg_prueth.c?h=ti-linux-6.12.y#n530
    (after fixing the driver to use the actual cycle time instead of IEP_DEFAULT_CYCLE_TIME_NS).

    The first PPS is generated within the first cycle after 1ms.

    The second PPS would be at:
    -> 500,000ns (remaining from the last cycle) + 665 * 1.5ms + 1,000,000ns = 1,000,000,000ns

    Can you explain how you obtained the 500,000ns?

    After the first PPS at offset 1ms there are 500us left in the first cycle.

    The numbers in the formula for the third and fourth PPS look the same, but the result is different, how did you determine these numbers?

    See above, the resuls are in "absolute" IEP time:

    The first PPS would be at "start cycle" time:
    -> 0 * 1.5ms + 1,000,000ns = 1,000,000ns

    The second PPS would be at:
    -> <time-of-last-pps = 1,000,000ns> + 500,000ns (remaining from the last cycle) + 665 * 1.5ms + 1,000,000ns = 1,000,000,000ns

    -> the delta from 1st to 2nd was only 999ms.

    The third PPS would be at:
    -> <time-of-last-pps = 1,000,000,000ns> + 500,000ns (remaining from the last cycle) + 665 * 1.5ms + 1,000,000ns = 1.999.000.000ns

    -> the delta from 2nd to 3rd was only 999ms.

    The fourth PPS would be at:
    -> <time-of-last-pps = 1,999,000,000ns> + 500,000ns (remaining from the last cycle) + 665 * 1.5ms + 1,000,000ns = 2.998.000.000ns

    -> the delta from 3rd to 4th was only 999ms.

    This is all based on our custom kernel driver instead of icssg_prueth.c and a minimally modified icss_iep.c, but you could just as well adapt icssg_prueth.c to fix the 2nd issue, then you'd run into this 3rd issue.

    Regards,

    Dominic

  • We would like to understand if there are any concerns regarding the firmware's use of the ICSS-G / IEP if we clocked the IEP asynchronously to the rest of the ICSS-G. Hardware-wise this is possible, and I'm pretty sure it can be configured (or adapted to being configurable), but there could be caveats regarding asynchronous clocks that we don't understand.

    I will get back to you regarding if there are any concerns with clocking the IEP at a different clock rate than the ICSSG core.

    It appears the 1st issue (2000ppb offset) is not expected. I don't think we caught this issue because to my knowledge we did not specifically test phc2sys case. When I tried testing with ptp4l (what we normally use to test PTP), I couldn't see this offset so I'm guessing that is why it wasn't caught. The team is currently looking into this, and I will create an internal bug to track this. 

    The kernel driver can fix only part of this issue, but a proper fix would probably require changes to the firmware, which in turn would require a kernel driver change, too.

    We modified the kernel driver (or rather implemented our own), and that works for the cases where 1s (for a PPS) is divisible by the cycle time (e.g. 1ms cycle, 2ms cycle time) but not for cases where there's a remainder (e.g. 1.5ms cycle time). This is the 3rd issue.

    Another problem with adapting only the kernel driver is that for some use-cases you want to be able to dynamically change the EST schedule. For the EST schedule this is already supported, but afterwards the PPS is broken again. Fixing that would require updating the PPS parameters (reduction factor and offset) synchronized to the EST schedule update.

    Is this 2nd issue the same as the issue described below for what should have been fixed for SDK 11.0?

    https://sir.ext.ti.com/jira/browse/EXT_EP-12337 

    From SDK 11.0 AM64x Release Notes:

    EXT_EP-12337

    ICSSG: TAPRIO - Firmware can’t handle base-time which is not a multiple of cycle-time.

    -Daolin

  • The problem occurs from 333,333th clock cycle to 333,334th clock cycle. At that point the counter should read 1,000,000,002ns, but it only reads "1 cycle + 0ns", so 1,000,000,000ns, thus loosing 2ns.

    We would like to understand if there are any concerns regarding the firmware's use of the ICSS-G / IEP if we clocked the IEP asynchronously to the rest of the ICSS-G. Hardware-wise this is possible, and I'm pretty sure it can be configured (or adapted to being configurable), but there could be caveats regarding asynchronous clocks that we don't understand

    Hi Dominic

    For this issue, can you try configuring IEP_COUNT_RESET_VAL_REG0 to 2

    Regards

    Pratheesh

  • Hello Pratheesh,

    thanks for your comment. I'm not sure this would solve the 1st issue:

    On the first cycle it would work: 0...3...6...999999...2

    On the second and subsequent cycles, I believe we would be 1 ns too long: 2...5...8...999998...2

    That's basically the same thing as the 3rd issue: you run into problems when you have non-integer multiples of the base (IEP frequency vs. cycle time, cycle time vs. PPS period), and this can't be solved with a static configuration.

    Regards,

    Dominic Rath

  • Hello Daolin,

    Is this 2nd issue the same as the issue described below for what should have been fixed for SDK 11.0?

    The 2nd issue is about

    • the current kernel driver (icssg_prueth.c) using the hard-coded IEP_DEFAULT_CYCLE_TIME_NS where it should be using the currently configured cycle time
    • the problem that the cycle time gets updated by the firmware at a configurable time in the future (I believe that's "base time"), which is why I think the reduction factor and offset need to be updated by the firmware at "base time", too, not by the kernel.

    EXT_EP-12337 might be related to the 3rd issue, but I don't think it's the same. Could you check internally how exactly that was fixed?

    Regards,

    Dominic

  • Hi Dominic,

    I will get back to you regarding if there are any concerns with clocking the IEP at a different clock rate than the ICSSG core.

    Feedback I got internally was that running IEP at 250M or 200M shall be pretty harmless, only side effect is that access latency to IEP registers will be higher by 6 cycles in this case.

    EXT_EP-12337 might be related to the 3rd issue, but I don't think it's the same. Could you check internally how exactly that was fixed?

    Double checking on this and will update you once I find out more information.

    -Daolin

  • Hello Daolin,

    do you have any updates regarding these issues?

    Double checking on this and will update you once I find out more information.

    Have you been able to find out exactly what/how EXT_EP-12337 was fixed?

    Feedback I got internally was that running IEP at 250M or 200M shall be pretty harmless, only side effect is that access latency to IEP registers will be higher by 6 cycles in this case.

    What we're worried about is whether the firmware is prepared to handle this higher latency, or if it is designed with the 333 MHz in mind.

    Regards,

    Dominic

  • Hi Dominic, 

    Have you been able to find out exactly what/how EXT_EP-12337 was fixed?

    There hasn't been any feedback internally on this yet, but I'm asking internally once again. Thanks for the reminder!

    What we're worried about is whether the firmware is prepared to handle this higher latency, or if it is designed with the 333 MHz in mind.

    From what I understand, originally the PRU core clock was designed with 250 MHz (originally AM64x was using same firmware as AM65x) and was later changed to 333 MHz in order to improve the PRU firmware's gigabit line rate performance for use cases like short packets. If I remember correctly, by default the IEP clock is the sourced from the same clock source for the PRU core clock, implying that 250 MHz was used for the IEP clock rate as well.

    I will double check if the firmware used on AM64 now was specifically designed with 333 MHz in mind.

    -Daolin 

  • Hi Dominic, 

    Have you been able to find out exactly what/how EXT_EP-12337 was fixed?

    >> In firmware, the penultimate cycle (second cycle count to last) is calculated. 

    When TAS_CONFIG_CHANGE bis is set to 1, then following actions are taken.

    For ex: 

    AdminBaseTime(ABT) = 110600800 ns

    AdminCycle(AC) = 1000000 ns

    OperationCycleTime(OCT) = 1000000 ns

    CurrentTime (CT) = 800ns

    ((ABT-CT)/OCT) - 2

    CycleCount = ((110600800 - 800)/1000000) - 2 = 108 

    At 108th cycle count, reprogram the IEP shadow register with new cycleTimeExtension (EXT) as ABT is not multiple of CT.

    Calculate required extension (EXT) = (ABT Mod OCT)

    EXT = 110600800 % 1000000 = 600800

    At 109th cycle start, reprogram the IEP shadow register as 1ms (to the actual cycle time) and this cycle is extended to 1600800 instead of 1ms.

    At 110th cycle TAS schedule is applied and start to run at 1ms.

    All highlighted parts are implemented in the firmware.

    BR
    JC