DDR

Attention

Please note that this driver is supported only on DM R5(WKUP R5) as part SBL examples. It is not supported on MCU-R5.

The DDR driver provides API to configure the DDR module.

Features Supported

  • Ability to enable/disable DDR support in your application

  • Ability to specify the DDR config generated using the “DDR SUBSYSTEM REGISTER CONFIGURATION” tool

  • Ability to enable/disable inline ECC (1b and 2b) in the application

  • Add regions for enabling inline ECC

SysConfig Features

Note

It is strongly recommend to use SysConfig where it is available instead of using direct SW API calls. This will help simplify the SW application and also catch common mistakes early in the development cycle.

  • Ability to specify the DDR config generated using the “DDR SUBSYSTEM REGISTER CONFIGURATION” tool

  • Enables DDR, EMIF module clock when DDR module is selected

  • Toggle inline ECC functionality

  • Add regions for which inline ECC needs to be enabled

  • Ability to set the SDRAM index based on the connected DDR size

Features not Supported

NA

Creating your own DDR config file

Step 1: Generate a DDR config file for your EVM

  • Goto https://dev.ti.com/sysconfig

  • Select “Software Product” as “DDR SUBSYSTEM REGISTER CONFIGURATION”

  • Select “Device” of interest, AM62DX in this case.

DDR SUBSYSTEM REGISTER CONFIGURATION Tool

DDR SUBSYSTEM REGISTER CONFIGURATION Tool

  • Configure the DDR parameters using the tool

  • Save the generated board_ddrReginit.h in your project workspace or work area

Configure and save the generated file

Configure and save the generated file

Step 2: Add the generated DDR config file to your project

Add DDR via SysConfig

Add DDR via SysConfig

  • Specify the path to the generated board_ddrReginit.h file including the filename in the sysconfig text box as shown above

    • Make sure to use forward slash “/” in the file path so that this will work with linux as well as windows build

    • Make sure that path to this is file set in your application include path, as needed.

  • Save the sysconfig project and build your application

Creating your own LPDDR config file

Step 1: Generate a LPDDR config file for your EVM

  • Goto https://dev.ti.com/sysconfig

  • Select “Software Product” as “DDR SUBSYSTEM REGISTER CONFIGURATION”

  • Select “Device” of interest, AM62DX in this case. The tool UI is the same as shown in Step 1: Generate a DDR config file for your EVM.

  • Configure the LPDDR parameters using the tool

  • Save the generated board_ddrReginit.h in your project workspace or work area. Rename the file as “board_lpddrReginit.h”.

Configure and save the generated file

Configure and save the generated file

Step 2: Add the generated LPDDR config file to your project

Add LPDDR via SysConfig

Add LPDDR via SysConfig

  • Specify the path to the generated board_lpddrReginit.h file including the filename in the sysconfig text box as shown above

    • Make sure to use forward slash “/” in the file path so that this will work with linux as well as windows build

    • Make sure that path to this is file set in your application include path, as needed.

  • Save the sysconfig project and build your application

Enabling DDR inline ECC

  • For SDRAM data integrity, the DDRSS bridge supports inline ECC on the data written to or read from the SDRAM. ECC is stored together with the data so that a dedicated SDRAM device for ECC is not required. The 8-bit single error correction double error detection (SECDED) ECC data is calculated over 64-bit data quanta.

  • For every 256-byte (AM62X) or 512-byte (AM62AX/AM62DX/AM62PX) data block, 32 or 64 bytes of ECC is stored inline respectively.

  • Thus 1/9th of the total SDRAM space is used for ECC storage and the rest 8/9th is available for system use. From system point of view that 8/9th of the SDRAM data space are seen as consecutive byte addresses. DDRSS supports up to 3 ECC protected non-overlapping memory ranges.

Attention

When inline ECC is enabled, the last 1/9th part of the DDR memory should not used. This rule applies irrespective of the size of the ECC regions.

Step 1: Enable inline ECC in the SBL sysconfig

Open the SBL SysConfig file and configure the inline ECC settings as described below.

  • Open SysConfig file (Using SDK with SysConfig) of your SBL

  • Calculate the SDRAM index based on your connected DDR size and update the field

    • Formula: SDRAM index = log2(connected DDR size) - 16

  • Enable inline ECC and add regions for which inline ECC needs to be enabled as shown.

Enable inline ECC via SysConfig

Enable inline ECC via SysConfig

  • Things to take care when adding ECC regions,

    • The address (ECC start and end) has to be specified as an offset from the DDR region start

    • The ECC region is inclusive of the start and end address.

    • The ECC region start address and the size should be aligned to 0x10000 bytes

    • The ECC region size has to be in the powers of two and greater than 0x10000 bytes

    • ECC region size = ECC region end address - ECC region start address + 1

    • When ECC is enabled, BIST engine primes only the 8/9th portion of the given size. So the actual ECC end address will be lesser than the given ECC address.

    • For the given ECC region, the actual end address will be calculated and displayed in the sysconfig

    • When ECC is enabled, last 1/9th of the total SDRAM space is used for ECC storage and the rest 8/9th is available for system use.

    • So 8/9th of the given ECC region should not fall under the last 1/9th part of the DDR memory.

  • Sysconfig files will get generated only if all the above conditions are met, otherwise it will throw an error.

Note

If you are using older release and migrating to 09_02 SDK, please make sure the above conditions are met in the added ECC regions.

  • Save the sysconfig project.

  • In the SBL, before using the DDR memory check if DDR init is done using the DDR_isInitDone function.

    while(!DDR_isInitDone())
    {
        ClockP_usleep(100);
    }
    
  • Build the SBL

Step 2: Generate linux appimage and u-boot.img

  • Rebuild a53 spl and u-boot.img with this change. Instructions to build A53 uboot can be found in the SDK Linux documentation at Foundational Components » U-Boot » User’s Guide » General Information » Build U-Boot

  • Generate the linux.appimage using the updated A53 SPL

  • Refer Linux Appimage Generator Tool for more details

  • Flash the linux.appimage and u-boot.img

  • For Falcon mode (fast bootmode):

  • Reduce the “DDR memory” to 8/9th of whole DDR size in linux device tree by modifying the device tree board file (arch/arm64/boot/dts/ti/k3-am62a7-sk.dts)

  • Rebuild the linux devicetree blob (dtb). For more information, refer the Linux SDK docs, section Foundational Components > Kernel > Users Guide

  • Generate the linux.appimage using the updated dtb file

  • Refer Linux Appimage Generator Tool for more details

  • Flash the linux.appimage

Important Usage Guidelines

Follow these guidelines when configuring and using the DDR driver.

  • Ideally DDR should be enabled in the bootloader application and the SDK bootloader by default enables DDR by default.

Usage Overview

Include the below file to access the APIs

#include <stdio.h>
#include <drivers/ddr.h>

/* DDR register config .h file as generated from DDR SUBSYSTEM REGISTER CONFIGURATION tool
 * Make sure path to this file is specified in your application project/makefile include path
 */
#include "drivers/ddr/v0/soc/am64x_am243x/board_ddrReginit.h"

static DDR_Params gDdrParams =
{
    /* below values are set using the globals defined in drivers/ddr/v0/soc/am64x_am243x/board_ddrReginit.h */
    .clk1Freq              = DDRSS_PLL_FREQUENCY_1,
    .clk2Freq              = DDRSS_PLL_FREQUENCY_2,
    .ddrssCtlReg           = DDRSS_ctlReg,
    .ddrssPhyIndepReg      = DDRSS_phyIndepReg,
    .ddrssPhyReg           = DDRSS_phyReg,
    .ddrssCtlRegNum        = DDRSS_ctlRegNum,
    .ddrssPhyIndepRegNum   = DDRSS_phyIndepRegNum,
    .ddrssPhyRegNum        = DDRSS_phyRegNum,
    .ddrssCtlRegCount      = DDRSS_CTL_REG_INIT_COUNT,
    .ddrssPhyIndepRegCount = DDRSS_PHY_INDEP_REG_INIT_COUNT,
    .ddrssPhyRegCount      = DDRSS_PHY_REG_INIT_COUNT,
    .fshcount              = DDRSS_PLL_FHS_CNT,
    .enableEccFlag = 0,
    .eccRegion = NULL,
};

Initialize DDR

    DDR_init(&gDdrParams);

Example Usage

NA

API Reference

This file contains DDR APIs.

DDR ECC error type

DDR_ECC_1B_ERROR
DDR_ECC_2B_ERROR
DDR_ECC_ERR_ALL

Functions

void DDR_Params_init(DDR_Params *prms)

Set default values to DDR_Params.

Parameters:

prms – [out] Pointer to DDR configuration.

int32_t DDR_init(DDR_Params *prms)

DDR4 Initialization function.

       Initializes the DDR timing parameters. Sets the DDR timing parameters
       based in the DDR PLL controller configuration.
       Any changes to DDR PLL requires change to DDR timing.
Parameters:

prms – [in] Pointer to DDR configuration.

Returns:

status SystemP_SUCCESS in case of success or appropriate error code

void DDR_enableInlineECC(uint8_t enableFlag)

Enable/Disable DDR inline ECC.

Parameters:

enableFlag – [in] Flag to enable or disable DDR Inline ECC

int32_t DDR_clearECCError(uint8_t errorType)

Clear ECC errors for DDR.

Parameters:

errorType – [in] DDR ECC error type (single bit/two bit ECC)

Returns:

status SystemP_SUCCESS in case of success or appropriate error code

int32_t DDR_getECCErrorInfo(DDR_ECCErrorInfo *ECCErrorInfo)

Get ECC error status.

Parameters:

ECCErrorInfo – [out] Get DDR ECC error bit status

Returns:

status SystemP_SUCCESS in case of success or appropriate error code

uint8_t DDR_isInitDone(void)

Check if DDR init is done.

Returns:

0 if DDR init is not completed else 1

struct DDR_EccRegion
#include <ddr.h>

DDR Inline ECC region The structure specifies the DDR inline ECC region start and End address.

Public Members

uint64_t ddrEccStart0

DDR inline ECC region-0 start address

uint64_t ddrEccEnd0

DDR inline ECC region-0 end address

uint64_t ddrEccPrimeEnd0

DDR inline ECC region-0 primed end address

uint64_t ddrEccStart1

DDR inline ECC region-1 start address

uint64_t ddrEccEnd1

DDR inline ECC region-1 end address

uint64_t ddrEccPrimeEnd1

DDR inline ECC region-1 primed end address

uint64_t ddrEccStart2

DDR inline ECC region-2 start address

uint64_t ddrEccEnd2

DDR inline ECC region-2 end address

uint64_t ddrEccPrimeEnd2

DDR inline ECC region-2 primed end address

struct DDR_Params
#include <ddr.h>

DDR config structure.

Below arrays and values are generated using the separate DDR config tool

  • ddrssCtlReg, ddrssPhyIndepReg, ddrssPhyReg

  • ddrssCtlRegNum, ddrssPhyIndepRegNum, ddrssPhyIndepRegNum

  • ddrssCtlRegCount, ddrssPhyIndepRegCount, ddrssPhyRegCount

Public Members

uint64_t clk1Freq

DDR Frequency of operation, in Hz

uint64_t clk2Freq

DDR Frequency of operation, in Hz

uint32_t *ddrssCtlReg

Array of register value to set

uint32_t *ddrssPhyIndepReg

Array of register value to set

uint32_t *ddrssPhyReg

Array of register value to set

uint16_t *ddrssCtlRegNum

Array of register numbers into which the values ddrssCtlReg will be set

uint16_t *ddrssPhyIndepRegNum

Array of register numbers into which the values ddrssPhyIndepReg will be set

uint16_t *ddrssPhyRegNum

Array of register numbers into which the values ddrssPhyReg will be set

uint16_t ddrssCtlRegCount

Number of elements in array ddrssCtlReg

uint16_t ddrssPhyIndepRegCount

Number of elements in array ddrssCtlReg

uint16_t ddrssPhyRegCount

Number of elements in array ddrssCtlReg

uint8_t fshcount

Frequency Handshake count

uint8_t sdramIdx

log2(connected SDRAM size) - 16

uint8_t enableEccFlag

Flag to enable Inline ECC

DDR_EccRegion *eccRegion

Inline ECC region address

struct DDR_ECCErrorInfo
#include <ddr.h>

Emif ECC Error Information structure.

This structure provides information about the ECC error

Public Members

uintptr_t singlebitErrorAddress

One Bit ECC error address

uintptr_t doublebitErrorAddress

Two Bit ECC error address

uint32_t singlebitErrorCount

One Bit ECC error count