UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Visitor wzmuda
Visitor
379 Views
Registered: ‎01-29-2019

CoreSight ETMv4 timestamp on Ultrascale+

Jump to solution

Hi,

 

I'm working on enabling CoreSight subsystem in Linux on ZCU104 with Ultrascale+. So far, I managed to enable CoreSight components, so they are visible in sysfs. Using perf with OpenCSD, I'm able to get trace data from ETF. However, I'm observing timestamp packets with value 0x0 instead of a real timestamp.

Idx:1740; ID:10;        I_ATOM_F6 : Atom format 6.; EEEEEEEEEEN                                        
Idx:1741; ID:10;        I_ATOM_F6 : Atom format 6.; EEEEEEEEEEEEEEEEEEEEEEEE                           
Idx:1742; ID:10;        I_ATOM_F6 : Atom format 6.; EEEEEEEEEEN                                        
Idx:1744; ID:10;        I_ATOM_F2 : Atom format 2.; NE                                                 
Idx:1745; ID:10;        I_ADDR_L_64IS0 : Address, Long, 64 bit, IS0.; Addr=0x0000000000400934;         
Idx:1754; ID:10;        I_TIMESTAMP : Timestamp.; Updated val = 0x0
Idx:1776; ID:10; I_ASYNC : Alignment Synchronisation.


After analyzing Ultrascale's TRM, I came to conclusion, that the timestamp generator has a separate clock source named DBG_TSTMP_CLK (according to Table 39-10). I suspect this clock migt be powered off. Is there any way to enable this clock, preferably using Linux or U-Boot device tree?

 

Thanks

1 Solution

Accepted Solutions
Visitor wzmuda
Visitor
302 Views
Registered: ‎01-29-2019

Re: CoreSight ETMv4 timestamp on Ultrascale+

Jump to solution

Thanks to the guys from the Linaro mailing list, here's how to enable timestamping in ETM:

Before booting Linux, break into U-Boot shell and do:

mw fe900000 1

This will enable the CNTCR_EN bit of the TSGEN register, enabling the timestamp generator block in the SoC. After that, boot to Linux and you can now get timestamps in perf:

        Idx:82685; ID:16;       I_TIMESTAMP : Timestamp.; Updated val = 0x143dba290                            
        Idx:82978; ID:16;       I_TIMESTAMP : Timestamp.; Updated val = 0x143dbdc28                            
        Idx:83713; ID:10;       I_TIMESTAMP : Timestamp.; Updated val = 0x14565a9ff                            
        Idx:87068; ID:10;       I_TIMESTAMP : Timestamp.; Updated val = 0x14568896e                            
        Idx:87828; ID:10;       I_TIMESTAMP : Timestamp.; Updated val = 0x146f25d9f                            
        Idx:91159; ID:10;       I_TIMESTAMP : Timestamp.; Updated val = 0x146f536ac

I used mainline kernel for that with the only change being my DTS with for CoreSight components. These clock driver hacks I tried in the previous post are not necessary for this.

Details are in this thread: https://lists.linaro.org/pipermail/coresight/2019-February/002214.html

View solution in original post

0 Kudos
2 Replies
Visitor wzmuda
Visitor
331 Views
Registered: ‎01-29-2019

Re: CoreSight ETMv4 timestamp on Ultrascale+

Jump to solution

Since I couldn't deduce how new clock nodes in DTS should look like, I decided to hack the Linux clock driver a bit, to force-enable the debug clocks.

First, I noticed that debug/timestamp related clocks are seen as disabled by Linux:

 

root@zynq:~# cat /sys/kernel/debug/clk/clk_summary
                                 enable  prepare  protect                                duty
   clock                          count    count    count        rate   accuracy phase  cycle
---------------------------------------------------------------------------------------------
...
                   timestamp_ref_mux       0        0        0  1499999985          0     0  50000
                      timestamp_ref_div1       0        0        0    99999999          0     0  50000
                         timestamp_ref       0        0        0    99999999          0     0  50000
...
                   dbg_lpd_mux        0        0        0  1499999985          0     0  50000
                      dbg_lpd_div1       0        0        0   249999998          0     0  50000
                         dbg_lpd       0        0        0   249999998          0     0  50000
                      dbg_tstmp_mux       0        0        0   499999995          0     0  50000
                         dbg_tstmp       0        0        0   249999998          0     0  50000
                      dbg_trace_mux       0        0        0   499999995          0     0  50000
                         dbg_trace_div1       0        0        0    13513514          0     0  50000
                            dbg_trace       0        0        0    13513514          0     0  50000
                      dbg_fpd_mux       0        0        0   499999995          0     0  50000
                         dbg_fpd_div1       0        0        0   249999998          0     0  50000
                            dbg_fpd       0        0        0   249999998          0     0  50000
...

 

 

Then, I analyzed the clock driver and found a place where clocks are received from the PMU:

 

diff --git a/drivers/clk/zynqmp/clkc.c b/drivers/clk/zynqmp/clkc.c
index 3209b679f1fe..55b5a8f30c19 100644
--- a/drivers/clk/zynqmp/clkc.c
+++ b/drivers/clk/zynqmp/clkc.c

@@ -619,6 +622,12 @@ static void zynqmp_get_clock_info(void)

        /* Get topology of all clock */
        for (i = 0; i < clock_max_idx; i++) {
+               pr_err("xxx: clock found:\n");
+               pr_err("xxx: \tname: %s (%d)\n", clock[i].clk_name, i);
+               pr_err("xxx: \tvalid: %d\n", clock[i].valid);
+               pr_err("xxx: \tinit_enable: %d\n", clock[i].init_enable);
+               pr_err("xxx: \ttype: %d (%s)\n", clock[i].type, clock[i].type ? "external" : "output");

 

 

Running code with such addition showed in dmesg a list of clock names and their IDs. I noticed they match the list documented in DT clock bindings for US+ MPSoC. Then, I modified the clock driver so that the following clocks are enabled, even if PMU reports they should not be: dbg_lpd, dbg_fpd, dbg_tstmp, dbg_trace and timstamp_ref.

 

diff --git a/drivers/clk/zynqmp/clkc.c b/drivers/clk/zynqmp/clkc.c
index 3209b679f1fe..55b5a8f30c19 100644
--- a/drivers/clk/zynqmp/clkc.c
+++ b/drivers/clk/zynqmp/clkc.c
@@ -573,8 +573,11 @@ static int zynqmp_register_clocks(struct device_node *np)
                                                              parent_names);

                /* Enable clock if init_enable flag is 1 */
-               if (clock[i].init_enable)
+               if (clock[i].init_enable ||
+                               (((i > 11 && i < 16) || i == 69) && !clock[i].init_enable)) {
+                       pr_err("xxx: clk_prepare_enable(%d == %s)\n", i, clock[i].clk_name);
                        clk_prepare_enable(zynqmp_clks[i]);
+               }
        }

 

 

Afterwards, I noticed that clk_summary shows these clocks as enabled:

 

root@zynq:~# cat /sys/kernel/debug/clk/clk_summary
                                 enable  prepare  protect                                duty
   clock                          count    count    count        rate   accuracy phase  cycle
---------------------------------------------------------------------------------------------
...
                   timestamp_ref_mux       1        1        0  1499999985          0     0  50000
                      timestamp_ref_div1       1        1        0    99999999          0     0  50000
                         timestamp_ref       1        1        0    99999999          0     0  50000
...
                   dbg_lpd_mux        1        1        1  1499999985          0     0  50000
                      dbg_lpd_div1       1        1        1   249999998          0     0  50000
                         dbg_lpd       1        1        1   249999998          0     0  50000
                      dbg_tstmp_mux       1        1        0   499999995          0     0  50000
                         dbg_tstmp       1        1        0   249999998          0     0  50000
                      dbg_trace_mux       1        1        1   499999995          0     0  50000
                         dbg_trace_div1       1        1        1    13513514          0     0  50000
                            dbg_trace       1        1        1    13513514          0     0  50000
                      dbg_fpd_mux       1        1        1   499999995          0     0  50000
                         dbg_fpd_div1       1        1        1   249999998          0     0  50000
                            dbg_fpd       1        1        1   249999998          0     0  50000
...

Unfortunately, perf still shows timestamps of value 0x0.

 

I'd really appreciate any idea how to get ETM timestamping running. Many thanks!

0 Kudos
Visitor wzmuda
Visitor
303 Views
Registered: ‎01-29-2019

Re: CoreSight ETMv4 timestamp on Ultrascale+

Jump to solution

Thanks to the guys from the Linaro mailing list, here's how to enable timestamping in ETM:

Before booting Linux, break into U-Boot shell and do:

mw fe900000 1

This will enable the CNTCR_EN bit of the TSGEN register, enabling the timestamp generator block in the SoC. After that, boot to Linux and you can now get timestamps in perf:

        Idx:82685; ID:16;       I_TIMESTAMP : Timestamp.; Updated val = 0x143dba290                            
        Idx:82978; ID:16;       I_TIMESTAMP : Timestamp.; Updated val = 0x143dbdc28                            
        Idx:83713; ID:10;       I_TIMESTAMP : Timestamp.; Updated val = 0x14565a9ff                            
        Idx:87068; ID:10;       I_TIMESTAMP : Timestamp.; Updated val = 0x14568896e                            
        Idx:87828; ID:10;       I_TIMESTAMP : Timestamp.; Updated val = 0x146f25d9f                            
        Idx:91159; ID:10;       I_TIMESTAMP : Timestamp.; Updated val = 0x146f536ac

I used mainline kernel for that with the only change being my DTS with for CoreSight components. These clock driver hacks I tried in the previous post are not necessary for this.

Details are in this thread: https://lists.linaro.org/pipermail/coresight/2019-February/002214.html

View solution in original post

0 Kudos