Showing results for 
Show  only  | Search instead for 
Did you mean: 
Registered: ‎06-16-2016

Clock frequency mismatch causing linux boot problems - possible incorrectly generated devicetree

Good Day,


I'm working with a Zedboard.


I have been trying to figure out why I am having problems booting Linux as a secondary OS, with OP-TEE as primary. I think I've resolved some of my earlier issues, but now have a problem when initializing the clocks...specifically the first one that gets initialized, the ARM PLL.


In an effort to debug this, I went into Vivado and checked to see what my clock frequencies were set to. My CPU (ARM  PLL) is set to 666.666667. However, when I take a look at the generated device tree source, I see the following node:


&clkc {





I also put a debug message into the clock init code and can confirm that this is the reported clock speed at init time - so it seems as though Linux is reading things correctly based on the device tree.


This seems wrong to me. Shouldn't the frequency be <66666666> or <0x4426aaab> (float rep of the same value), or am I missing something.


Help would be greatly appreciated.






0 Kudos
5 Replies
Community Manager
Community Manager
Registered: ‎07-23-2012

Zynq has three PLLs- ARM PLL, IO PLL & DDR PLL. The source clock for these PLLs is PS_CLK (processor clock).

The frequency you see in dts is of PS_CLK. There are parameters (can be found from UG585) to choose a divider value to generate the expected clock frequency. These registers are configured by either ps7_init or FSBL.
Please mark the post as "Accept as solution" if the information provided answers your query/resolves your issue.

Give Kudos to a post which you think is helpful.
0 Kudos
Registered: ‎06-16-2016 I understood that. I guess what I'm not clear on is exactly what part of this is represented by the <33333333> in the clock node I referenced. In other words, is this supposed to match any particular value that I configured on the PS in Vivado, or is this just a base value that the dividers are applied to?


That said...I went back and used the pre-built images with a few Linux patches that have nothing to do with board config applied. This boots fine as the solo OS, but fails when Linux is booted as secondary, after OP-TEE. Is it not safe to conclude that the problem isn't with misconfiguration of the clocks, if it will boot solo? 


Boot fails when we call clk_register_zynq_pll() against the ARM PLL - i.e. armpll_int / ps_clk as parameterized in clkc.c. This is the first PLL to be initialized. For some reason, when booted as secondary OS. It crashes right after the call to spin_lock_irqsave(). It's either on the clk_readl() or subsequent clk_writel(). I need to track down exactly which one.


Any ideas? Why would the behavior be any different after booting OP-TEE first?



0 Kudos
Registered: ‎06-16-2016

So, I went back and traced to where the exact failure is. Here's the code snipped from pll.c as well as the associated asm code. I have highlighted the location where the kernel panic occurs:

spin_lock_irqsave(pll->lock, flags);

pr_warn("after: spin_lock_irqsave()\n");

reg = clk_readl(pll->pll_ctrl);
clk_writel(reg, pll->pll_ctrl);


BL _raw_spin_lock_irqsave
MOV R7, R0
LDR R0, =unk_C07854D9
BL printk
LDR R3, [R4,#0xC]
LDR R5, [R3]
BIC R5, R5, #8
LDR R8, [R4,#0xC]


0 Kudos
Registered: ‎04-17-2011

Let me share some details here. The Zynq clocks have a node under SLCR as clkc. It appears as below:

clkc: clkc@100 {
 #clock-cells = <1>;
 compatible = "xlnx,ps7-clkc";
 fclk-enable = <0xf>;
 clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x",
  "cpu_3or2x", "cpu_2x", "cpu_1x", "ddr2x", "ddr3x",
  "dci", "lqspi", "smc", "pcap", "gem0", "gem1",
  "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1",
  "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1",
  "dma", "usb0_aper", "usb1_aper", "gem0_aper",
  "gem1_aper", "sdio0_aper", "sdio1_aper",
  "spi0_aper", "spi1_aper", "can0_aper", "can1_aper",
  "i2c0_aper", "i2c1_aper", "uart0_aper", "uart1_aper",
  "gpio_aper", "lqspi_aper", "smc_aper", "swdt",
  "dbg_trc", "dbg_apb";
 reg = <0x100 0x100>;

Other nodes in the Device Tree refer to this master node as &clkc. In your case ps_clk is 33.3333 MHz and is set in the GUI as below:




If you are interested to see the clock status at runtime, then you can set a Kernel Hack as Kernel hacking -> Compile-time checks and compiler options -> Debug Filesystem (CONFIG_DEBUG_FS)


Once booted, the clocks of the system can be viewed in the filesystem at /sys/kernel/debug/clk with clk_summary showing all the clocks. You can refer to that to see if the device tree has the clocks properly generated at runtime.


This may provide some information for you to see why it hangs when trying to read the clock source. 

Kindly note- Please mark the Answer as "Accept as solution" if information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented.
0 Kudos
Registered: ‎06-16-2016 I am looking at the right things. In fact, my clock config in Vivado is exactly like the one you display...and my device tree node is almost the same. There are only two differences I see when compared to the Zed board config that shipped with the pre-built part of the ZedBoard BSP (avnet-digilent-zedboard-2016.4.


I have two additional values in the node:





However, the fact that things boot fine when it is Linux alone leads me to believe that nothing is wrong with this. I'm still stumped as to why it fails when Linux is boot as secondary after OP-TEE. I'm going to turn on more of the kernel hacking settings...though that will only provide info for the case when things actually boot...i.e. Linux alone.





0 Kudos