My team and I are trying to boot a custom board embedding an Arria10 module. However, U-Boot fails during boot with the error "DDRCAL: Failure".
Here is an explanation of the startup problem of our Arria10-SoC card related to the PLL and the calibration of the DDR controller.
In the components to be retained on our Arria10 board, we have :
- a physical component that contains a PLL. This one must be initialized at each switch-on. The configuration is done by a FSM (Finite-state machine) which is integrated in the FPGA.
- In the HPS, there is a DDR controller which is clocked by a clock coming from this PLL component described above.
The startup sequence is as follows:
1. U-Boot is launched on the board.
2. Loading the bistream from U-Boot including the FSM to initialize the PLL.
3. The WFTU initializes the component that handles PLL.
4. The DDR controller initiates a calibration.
The problem is that points 3. and 4. are done at the same time. The DDR controller starts the calibration while the PLL has not finished its initialization, which puts the DDR controller in default and prevents the proper execution of U-Boot. The calibration of the DDR controller is done automatically as soon as the bitstream is loaded and we don't know any way to control this behavior.
In order to overcome this problem, we tried the following solution:
- Add a bit in the FSM which takes the value '1' when the PLL initialization is finished.
- In U-Boot, after loading the first bitstream, we wait for the bit to take the value '1', then we load a second bitstream (which does not initialize the PLL, to keep the previous configuration), in order to restart the calibration of the DDR controller. To load the second bitstream, we use the "cff_from_flash()" function, available in "arch/arm/cpu/armv7/socfpga_arria10/cff.c" file.
But without success, the calibration is not restarted.
An interesting note to this solution is that, although the loading of the 2nd bitstream via U-Boot doesn't work, the loading of this same bitstream via Quartus Programmer does.
If I restart, with Quartus Programmer, we have the following starting sequence: launching U-Boot, loading the 1st bitstream, waiting for the end of PLL initialization, loading the 2nd bitstream via Quartus Programmer. And then, the card starts up correctly.
Based on this behavior, we assume the following: loading a bitstream from U-Boot and from Quartus Programmer are not done the same way. It seems that loading via Quartus offers an extra reset level, since in this case, the DDR controller is reset when loading the 2nd bitstream.
After all these tests, we have two main questions:
1. Is it possible to tell the DDR controller to restart its calibration? Either via a signal made for that, or via a complete reset of the DDR controller.
2. How do the loading sequences of a bitstream in U-Boot and Quartus Programmer differ? Is it possible to have the same thing in U-Boot? If so, what are the extra steps?
Does anyone have any answer to these questions? Many thanks in advance.