Automatically scans and configures the SDRAM topology.
This function determines the SDRAM topology by performing a series of scans. First, it scans and establishes the number of ranks and the DQ width. Then, it scans the SDRAM address lines to determine the size of each rank. After the scan, it updates the dram_tpr13 register to reflect that the SDRAM topology has been successfully detected. The updated value of dram_tpr13 ensures that the auto-scan is not repeated upon a re-initialization.
The function follows these steps:
- If the
dram_tpr13 register does not indicate that the number of ranks and DQ width have been determined (bit 14 not set), it calls auto_scan_dram_rank_width() to perform the scan. If the scan fails, it logs an error message and returns 0.
- If the
dram_tpr13 register does not indicate that the size of each rank is known (bit 0 not set), it calls auto_scan_dram_size() to determine the size of each rank. If the scan fails, it logs an error message and returns 0.
- If bit 15 of
dram_tpr13 is not set, it sets the appropriate bits in dram_tpr13 to indicate that the SDRAM topology is now known.
- Parameters
-
| para | Pointer to the dram_para_t structure that holds the SDRAM parameters. |
- Returns
- int Returns
1 if the SDRAM configuration was successfully determined, or 0 if an error occurred during the scan.
- Note
- The function assumes that
auto_scan_dram_rank_width() and auto_scan_dram_size() are properly implemented and return 0 on failure and non-zero on success.
- Warning
- The function logs errors if the rank, width, or size detection fails, and it ensures that re-initialization will not repeat the auto-scan if the SDRAM topology is already known.
Scans and sizes a DRAM device by cycling through address lines to determine the configuration.
This function performs an auto-scan of the DRAM to determine its size by cycling through various address lines and checking if they correspond to real memory addresses or mirrored addresses. The process involves adjusting and testing column, row, and bank bit allocations, and determining the number of address lines for each part. The results are then stored in the dram_para1 and dram_para2 parameters.
The procedure follows these steps:
- Initializes the DRAM controller using
mctl_core_init().
- Sets the rank count based on the DRAM configuration.
- For each rank, it:
- Configures and tests the row address lines.
- Tests the bank address lines.
- Configures and tests the column address lines.
- Finally, checks if the configuration for rank 1 differs from rank 0 for dual rank configurations.
The results for row size, bank size, and page size are stored in the dram_para1 structure, while the dual rank configuration is updated in dram_para2.
- Parameters
-
| para | Pointer to a dram_para_t structure that holds the configuration and result of the DRAM scan. |
- Returns
- int Returns 1 on success, indicating the DRAM size scan was successful.
- Return values
-
| 0 | If the DRAM initialization failed. |
- Note
- The function assumes that the DRAM is mapped starting at
CONFIG_SYS_SDRAM_BASE. It uses hardware-specific register operations to configure and test the DRAM controller.
| static unsigned int calculate_rank_size |
( |
uint32_t |
regval | ) |
|
|
static |
Calculates the size of a memory rank based on the provided register value.
This function computes the size of a memory rank using the information embedded in the given register value. The register value is interpreted as follows:
- Bits 8-11 (page size): Represents the page size offset.
- Bits 4-7 (row width): Represents the row width offset.
- Bits 2-3 (bank count): Represents the bank count offset. The function combines these values to calculate the rank size in terms of memory blocks.
The calculation subtracts 14 (representing 1MB = 20 bits, minus an additional 6 bits), and then returns the size of the memory rank as a power of 2.
- Parameters
-
| regval | The register value containing memory configuration information. The value is assumed to be formatted with page size, row width, and bank count information located in specific bit ranges:
- Bits 8-11 (page size)
- Bits 4-7 (row width)
- Bits 2-3 (bank count)
|
- Returns
- The calculated size of the memory rank in bytes as a power of 2 (i.e., 2^bits).
- Note
- The function assumes that the provided register value corresponds to valid memory configuration data (i.e., it is already correctly formatted according to the memory controller specifications).
| static int ccu_set_pll_ddr_clk |
( |
int |
index, |
|
|
dram_para_t * |
para |
|
) |
| |
|
static |
Set the DDR PLL clock based on the given DRAM parameters.
This function configures the PLL clock for the DDR memory controller based on the DRAM parameters passed in the dram_para_t structure. It calculates the PLL parameters (such as the PLL multiplier and divider) and writes them to the appropriate registers to enable the PLL and ensure it locks to the desired frequency. It also configures the DRAM clock source to use the PLL.
The PLL is configured using the following parameters:
- PLL N (PLL multiplier)
- PLL M0, M1 (input/output dividers)
- PLL enable and lock control
- Gate control for the PLL output
The function uses hardware registers to configure the PLL and waits for the PLL to lock before enabling the output gate and selecting the PLL as the clock source for the DRAM controller.
- Parameters
-
| index | The index used to determine which PLL clock configuration to use. This is typically used to select different PLL configurations based on the input parameters. |
| para | A pointer to a structure containing the DRAM parameters, including:
- dram_clk: The DRAM clock frequency in MHz.
- dram_tpr13: Contains information for selecting PLL configurations.
- dram_tpr9: Used for PLL clock calculation.
- dram_tpr10: Contains high-speed oscillator frequency for PLL calculation.
|
- Returns
- The resulting DDR PLL frequency in Hz, calculated as: [ \text{hosc_freq} \times n / p0 / m0 / m1 ] Where:
- (\text{hosc_freq}) is the high-speed oscillator frequency.
- (n) is the PLL multiplier.
- (p0, m0, m1) are divider values for the PLL.
- Note
- The PLL frequency calculation takes into account the DRAM clock, dividers, and the high-speed oscillator frequency (
hosc_freq). The function assumes that dram_tpr13, dram_tpr9, and dram_tpr10 contain the necessary information for PLL configuration.
-
This function performs low-level hardware register writes to configure the PLL and DRAM clock. It directly interacts with the hardware, so it's intended for use in a low-level driver or platform-specific initialization code.
-
The function waits for the PLL to lock, which involves polling a lock status bit in the PLL control register. It then enables the output gate to allow the PLL to drive the DRAM clock.
-
Ensure that the values in the
dram_para_t structure are valid and appropriate for your system configuration before calling this function.
Detects the DQS gate state and updates DRAM parameters based on the detected configuration.
This function performs a series of hardware register reads to detect the state of the DQS (Data Strobe) gate in a DRAM system. It checks the configuration of the DRAM system and modifies the dram_para2 field of the dram_para_t structure to reflect the detected DRAM parameters, such as rank and DQ (Data Queue) configuration. Based on the detection, the function will set the appropriate flags for dual rank, single rank, full DQ, or half DQ memory configurations.
The function reads values from specific registers:
The detected configuration is then used to update para->dram_para2, and appropriate debug messages are logged.
- Parameters
-
| para | Pointer to the dram_para_t structure which holds DRAM configuration parameters. |
- Returns
- 1 if the DRAM configuration was successfully detected and updated, 0 if no valid configuration was detected.
- Note
- This function assumes that the register addresses (
MCTL_PHY_BASE, MCTL_PHY_PGSR0, etc.) are correctly mapped and accessible in the memory space. It also relies on the presence of specific debug logging mechanisms (printk_debug).
| static int dramc_simple_wr_test |
( |
unsigned int |
mem_mb, |
|
|
int |
len |
|
) |
| |
|
static |
Performs a simple write-read test on the DRAM to verify its functionality.
This function writes two distinct patterns to different memory regions in the DRAM and then reads back the written values to check for consistency. The test is performed on half of the specified memory size, with pattern patt1 written to the first half and pattern patt2 written to the second half. The function verifies that the read values match the expected patterns at the corresponding addresses. If any mismatch is found, the function logs an error and returns a failure code.
The function works as follows:
- It calculates the offset as half of the total memory size (
mem_mb), and uses this offset to write to the second half of the memory.
- It writes
patt1 and patt2 to the first and second halves of the memory, respectively.
- It reads the values from both halves of the memory and compares them to the expected patterns (
patt1 and patt2).
- If any read value does not match the expected value, an error is logged and the function returns
1 indicating failure.
- If all values match, the function prints a success message and returns
0 indicating success.
- Parameters
-
| mem_mb | Total size of the DRAM in megabytes. |
| len | Number of memory locations (in words) to test. |
- Returns
- 0 if the test passes (all values match the expected patterns), 1 if any mismatch is found.
- Note
- The function assumes that the base address of the DRAM is specified by
CONFIG_SYS_SDRAM_BASE and that the system supports 32-bit word writes and reads. The function also assumes that the memory is properly initialized.
| static void eye_delay_compensation |
( |
dram_para_t * |
para | ) |
|
|
static |
Perform eye delay compensation for DRAM timings.
This function configures various delay parameters for DRAM by manipulating specific PHY (Physical Layer) control registers. The compensation ensures that the timing of various signal transitions (e.g., DQS, RAS, CAS) is optimized for the DRAM device, based on the provided timing parameters. The adjustments are based on values extracted from the dram_para_t structure. The function configures the appropriate delay settings for data signals, command signals, and other necessary PHY control registers.
- Parameters
-
| para | Pointer to a structure containing the DRAM timing parameters. These parameters are used to configure delays for various signal lines in the DRAM controller. |
| static unsigned int get_dram_size |
( |
void |
| ) |
|
|
static |
Retrieves the total size of the DRAM.
This function calculates the total size of the DRAM by reading memory configuration values from two registers (MCTL_COM_WORK_MODE0 and MCTL_COM_WORK_MODE1) and interpreting the memory rank configurations. It determines whether the system has a single rank, two identical ranks, or two distinct ranks based on the values read from the registers.
- If the system has a single rank, the size of that rank is returned.
- If the system has two identical ranks, the size of one rank is multiplied by two.
- If the system has two distinct ranks, the sizes of both ranks are added together.
The function uses the calculate_rank_size() helper function to determine the size of individual ranks.
- Returns
- The total size of the DRAM in bytes.
- Note
- The function assumes the DRAM configuration is valid and the base addresses (
MCTL_COM_BASE + MCTL_COM_WORK_MODE0, MCTL_COM_BASE + MCTL_COM_WORK_MODE1) are correctly mapped and accessible in the memory space.
Initializes the DRAM controller and configures memory parameters.
This function initializes the DRAM controller and configures various settings based on the provided dram_para_t structure. It configures the DRAM clock, type, ZQ calibration, SDRAM size, hardware auto-refresh, ODT (On Die Termination) settings, and more. The function also ensures that the DRAM controller is properly initialized for the specified memory type (DDR2, DDR3, LPDDR2, LPDDR3, etc.).
The following steps are performed:
- Prints out the DRAM boot info, clock speed, and type.
- Checks and configures the ZQ calibration based on the DRAM parameters.
- If the DRAM auto-scan is not already performed, it invokes
auto_scan_dram_config to scan and configure the DRAM topology.
- Initializes the core controller using
mctl_core_init.
- Retrieves and sets the DRAM size. The size can be forced by the
dram_para2 parameter.
- Configures hardware auto-refresh settings if specified.
- Adjusts settings based on the DRAM type (e.g., LPDDR3 ODT delay, HDR/DDR dynamic).
- Disables ZQ calibration and sets the appropriate configurations for VTF and PAD hold.
- Enables all DRAM masters and performs simple write tests if necessary.
- Parameters
-
| type | The type of DRAM to initialize (not used in the function body, but typically used to specify DDR2, DDR3, LPDDR2, etc.). |
| para | Pointer to a dram_para_t structure containing DRAM configuration parameters, such as clock, type, ODT settings, and other controller parameters. |
- Returns
- int The size of the initialized DRAM in megabytes (MB) if successful, or 0 if initialization fails.
- Note
- This function assumes that all registers are mapped to their correct memory locations. The ZQ calibration and other settings might depend on the specific hardware configuration and DRAM type.
- Warning
- The function assumes that the proper base addresses and control registers for the DRAM controller are defined and accessible in the system.
| static unsigned int mctl_channel_init |
( |
unsigned int |
ch_index, |
|
|
dram_para_t * |
para |
|
) |
| |
|
static |
Initializes the memory controller channel with the provided DRAM parameters.
This function configures the memory controller channel based on the provided DRAM parameters. It sets the DDR clock, adjusts PHY registers for DQS gating mode, enables/disable ODT (On-Die Termination), configures PLL and SSCG, applies timing and voltage parameters, and performs necessary DRAM controller initialization and calibration steps. The function also handles power gating and waits for the status signals to complete.
- Parameters
-
| ch_index | The index of the memory channel to initialize (not used in this implementation). |
| para | Pointer to a structure containing the DRAM configuration parameters. This structure includes:
- dram_clk: DRAM clock frequency
- dram_odt_en: ODT enable flag
- dram_type: DRAM type (e.g., DDR3, LPDDR2, LPDDR3)
- dram_tpr13: Timing parameter for DQS gating
- dram_zq: ZQ calibration parameter
- dram_para2: Additional parameters, including rank configuration
- dram_tpr4: Additional timing parameter
- dram_tpr13: Timing parameter for DQS gating mode
|
- Returns
- 1 if initialization was successful, 0 if there was a ZQ calibration error.
- Note
- The function waits for several internal signals and completes multiple calibration steps. It assumes the DRAM controller's base address (MCTL_PHY_BASE, MCTL_COM_BASE) and the relevant register offsets are correctly defined elsewhere in the system.
- Warning
- This function relies on hardware-specific timing parameters and assumes correct memory controller configuration for the target platform. Modifications to the registers or incorrect parameter values may result in improper initialization or system instability.
Initializes the memory controller with the specified parameters.
This function configures the memory controller by setting various parameters such as SDRAM type, word width, rank, bank, row, and address mapping. It also configures additional settings like the controller wait time, ODTMAP, and specific register values for different DRAM configurations.
- Parameters
-
| para | Pointer to a structure containing the DRAM parameters. The structure should contain values such as DRAM type, size, ranks, timing parameters, and other relevant settings. |
- Note
- This function assumes that the base addresses for the memory controller (MCTL_COM_BASE, MCTL_PHY_BASE) and the relevant register offsets are correctly defined elsewhere in the code. The specific register settings depend on the DRAM type and configuration (e.g., LPDDR2, LPDDR3).
- Returns
- void
| static void mctl_set_timing_params |
( |
dram_para_t * |
para | ) |
|
|
static |
Set the DRAM timing parameters for the specified DRAM type.
This function configures various timing parameters for the DRAM controller based on the DRAM type and clock speed specified in the dram_para_t structure. It sets the timing values for the DRAM and writes them to the appropriate registers. The function supports multiple DRAM types, including DDR2, DDR3, LPDDR2, and LPDDR3.
The following parameters are configured:
- DRAM timing values (e.g., tCCD, tFAW, tRCD, tRP, tCAS latency, etc.)
- Mode register values (mr0, mr1, mr2, mr3)
- Initialization timing (e.g., tdinit0, tdinit1, tdinit2, tdinit3)
- Parameters
-
| para | Pointer to a structure that contains the DRAM parameters, including:
- dram_type: The type of DRAM (e.g., DDR2, DDR3, LPDDR2, LPDDR3).
- dram_clk: The DRAM clock frequency in MHz.
- dram_mr1: Value to be written to the MR1 register.
- Other parameters related to the DRAM configuration.
|
- Note
- The function uses the
ns_to_t helper function to convert nanosecond values to clock cycles based on the DRAM clock frequency. The DRAM type and clock speed influence the specific values of the timing parameters.
- Returns
- None
Initializes the MCTL (Memory Controller) system by configuring the DRAM and MBUS clocks and resets.
This function initializes the Memory Controller by performing a sequence of hardware register writes to assert and deassert resets, configure clock gating, and enable the necessary clock sources for DRAM operation. It configures the DRAM clock PLL and updates the clock settings based on the system's oscillator frequency (HOSC). Additionally, it enables the MCTL clock and prepares the system for further memory operations.
The steps performed by this function include:
- Asserting and deasserting the MBUS and DRAM resets.
- Configuring the MBUS and DRAM clock gating.
- Setting the DRAM clock PLL frequency and enabling the clock for DRAM operations.
- Enabling the MCTL clock for PHY access.
This function directly manipulates hardware registers for clock configuration, reset control, and memory initialization. It's intended for low-level hardware initialization and should be executed early in the system's startup sequence.
- Parameters
-
| para | A pointer to a structure of type dram_para_t which contains the DRAM configuration parameters, including the DRAM clock frequency and PLL settings. |
- Note
- This function assumes that the hardware addresses for the clock and reset control registers are correct and the system is ready for memory controller configuration.
-
The function uses
udelay to introduce delays, which might not be precise on all platforms. Ensure that the delays are sufficient for your platform's clock configuration to take effect.
-
The
dram_tpr10 register in para is modified to configure the HOSC frequency based on whether the system is using a 40 MHz or a different oscillator frequency.
-
The
ccu_set_pll_ddr_clk function is called to configure the PLL for DRAM based on the passed parameters. It returns the actual DRAM frequency, which is stored in para->dram_clk.
-
This function performs critical operations on the system's memory and clocking hardware and should be executed with care, particularly when the system is in the early stages of booting.
Initializes the Vref mode for the memory controller.
This function configures the voltage reference (Vref) settings for the memory controller by modifying the appropriate registers. It uses the dram_para_t structure to determine the settings based on the provided configuration parameters.
The function performs the following steps:
- Checks if a certain bit in
dram_tpr13 is set (bit 17). If it is, the function returns early and does nothing.
- Modifies the
MCTL_PHY_IOVCR0 register to set the appropriate I/O voltage reference values based on the dram_tpr5 configuration. Only the lower 32 bits of dram_tpr5 are used for this purpose.
- If bit 16 in
dram_tpr13 is not set, it modifies the MCTL_PHY_IOVCR1 register to adjust another set of voltage reference settings based on the lower 7 bits of dram_tpr6.
The function utilizes the clrsetbits_le32 helper to modify specific bits of the I/O voltage reference control registers without affecting the other bits.
- Parameters
-
| para | Pointer to the dram_para_t structure containing the configuration parameters. |
- Note
- The function assumes that the memory controller base address (
MCTL_PHY_BASE) and the corresponding register offsets (MCTL_PHY_IOVCR0 and MCTL_PHY_IOVCR1) are defined elsewhere in the code. Additionally, the function assumes that the dram_para_t structure contains valid values for the voltage reference configuration.