PLLE Spectrum Spread

Hi everyone,

I am currently working with the Tegra K1 and I have a few questions related to the PLLE configuration, more specifically the Spectrum Spread of the clock.

I would like to disable it for the PCIe. However the only location where I could find a Linux driver that is changing the PLLE control register is in the SATA driver (CLK_RST_CONTROLLER_PLLE_SS_CNTL_0 register changed in kernel/drivers/ata/ahci-tegra.c).

So my questions are:

-if you disable the Spectrum Spread in the SATA driver, does it affect the other devices using PLLE as clock source (USB3, PCIe, SATA) ?

-can you do the above during the “make menuconfig” of the kernel ? As of now, I could not find the option

-if menuconfig doesn’t work, is writting manually in the driver the only solution ?

Thanks in advance for your enlightenments.

Best regards,

Marc

Hi Marc_S,

You can disable SSC of PLLE by set bit<12> of CLK_RST_CONTROLLER_PLLE_SS_CNTL_0 to ‘1’, but it will surely affect other devices, especially USB3.0, which need SSC for jitter requirements.

Hi Trumany,

That’s what I expected and I did the change in the ahci-tegra.c source file for the ata driver. It didn’t change anything even though the register is changed (I read it and use a printk to see it). I also found in UBoot that the board was initialized with SSC enabled, I disabled it as well. Here the visible effect is the SSC is disabled as long as you are in UBoot (which is good !). But as soon as the kernel starts, it sets it back on.

I don’t know which driver configures the PLLE at last. I found in the clock driver (/kernel/drivers/clk/tegra) a source file called clk-pll.c which should disabled SSC by default in the function clk_plle_enable but a printk there won’t show up and after some digging I think that this function is used only with Tegra20 and/or Tegra30 SoC.

So to summarize, where do I change this bit in order to permanently disable the SSC PLLE ?

Hi everyone,

I still haven’t found a solution, however I am pretty confident that the very early kernel launch sequences are responsible for this behaviour. I can’t pinpoint exactly where in the code.

So if anyone has an idea on what happens to the TK1 registers during the kernel launch, I would gladly hear it.

Best regards,

Marc

EDIT: I found someone else having the same issue. Unfortunately without a solution yet:
https://devtalk.nvidia.com/default/topic/819646/?comment=4488504

I finally made it.

For those who are interested in a solution (no THE solution), I will try to describe the things I’ve done. Bear in mind that this is not optimized. What I mean is that the modifications are redundant and could certainly be shortened.

  • Modified UBoot: u-boot/arch/arm/cpu/tegra123-common/clock.c --> In this file I modified the SSC register to disable SSC (PLLE_SS_CNTL_SSCBYP to 1 instead of 0). This makes the PCIe to work without SSC in Uboot before kernel boot (mainly a check before kernel boot of your PCIe).

-Modified /kernel/arch/arm/mach-tegra/tegra12_clock.c --> Inside the function tegra12_plle_clk_enable I reset the SSC to disable SSC, do a complete init of PLLE just like UBoot before any check (but only at the 1st execution of this function, this is a nuke method and it might be useless).

-Modified in /kernel/arch/arm/mach-tegra/clock.h --> USE_PLLE_SWCTL set 1 (instead of 0) and USE_PLLE_SS set to 0 (instead of 1). This changes the configuration made by the function tegra12_clock.c, especially the SS init and the control of the software instead of hardware on certain registers bits of PLLE.

-Modified in /kernel/drivers/ata/ahci-tegra.c --> the driver sets the SSC to enable through the SSC control register, I changed that.

After all these modifications I have a what it seems to be a fully functional PCIe from the Tegra K1 without the SSC (at least I can see all my PCIe domain with all devices recognized so I guess it works).

Another thing that I discovered later but didn’t try:

The tegra12 function is called 3 times, 1 early in the boot and twice before PCI enumeration. Maybe adding the “pci=firmware” kernel command (extlinux.conf) could resolve the issue by ignoring the two last calls.

Anyway, I hope it could help someone.

Best regards,

Marc

Is it possible to disable the SSC on the NVIDIA TX1 as well utilizing the same procedure???

Thanks

I have not tested this, but maybe USE_PLLE_SS could be defined as 0 instead of 1 here:

drivers/platform/tegra/tegra21_clocks.c
include/linux/platform/tegra/clock.h

I do not know if u-boot also requires change. There may be other places I don’t know about also requiring change, e.g., a register for SS.