高通平台DDR3初始化

news/2024/10/17 21:28:06/

        本文 以MSM8976平台为例,其他8K的平台都差不多类似。

        MSM8976支持两个DDR3接口(EBI0,EBI1)。每个EBI提供两个CS片选(CS0,CS1)。

       在SBL1的的代码实现中,一个EBI就是一个channel也就是一个INTERFACE。

       EBI0对应 SDRAM_INTERFACE_0;

       EBI1对应 SDRAM_INTERFACE_1;

       下面我们看一下SBL1中对ddr初始化的具体实现:

      入口函数是 sbl1_ddr_init:

void sbl1_ddr_init()
{ddr_info sbl1_ddr_info;/* Initialize DDR */boot_ddr_initialize_device(boot_clock_get_ddr_speed());--------------------(1)
}

(1)boot_clock_get_ddr_speed()获取ddr时钟,8976上是384MHZ


下面接着看ddr_initialize_device函数:

void ddr_initialize_device(uint32 clk_speed)
{struct ddr_device_params_common *ddr_param_interface_0, *ddr_param_interface_1;if(!ddr_init_done){    /* Pass the ddr parameters to HAL */ddr_init();  ---------------------------------------(1)          /* Update the ddr clock speed variable to the initialization clock */ddr_status.clk_speed = clk_speed;if(ddr_status.sdram0_cs0 != DDR_UNAVAILABLE) -----------------------(2)         {if(ddr_status.sdram0_cs1 != DDR_UNAVAILABLE) ----------------------(3){HAL_SDRAM_Init(SDRAM_INTERFACE_0, SDRAM_BOTH, clk_speed); ------------------(4)}else{HAL_SDRAM_Init(SDRAM_INTERFACE_0, SDRAM_CS0, clk_speed); ---------------------(5)}}if(ddr_status.sdram1_cs0 != DDR_UNAVAILABLE){if(ddr_status.sdram1_cs1 != DDR_UNAVAILABLE){HAL_SDRAM_Init(SDRAM_INTERFACE_1, SDRAM_BOTH, clk_speed);}else{HAL_SDRAM_Init(SDRAM_INTERFACE_1, SDRAM_CS0, clk_speed);}}/* Get DDR device parameters after detection during initialization */ddr_param_interface_0 = &(ddr_get_params(SDRAM_INTERFACE_0)->common);ddr_param_interface_1 = &(ddr_get_params(SDRAM_INTERFACE_1)->common);/* Update DDR status */ddr_status.sdram0_cs0 = (ddr_param_interface_0->num_rows_cs0 != 0) ?DDR_ACTIVE : DDR_UNAVAILABLE;ddr_status.sdram0_cs1 = (ddr_param_interface_0->num_rows_cs1 != 0) ?DDR_ACTIVE : DDR_UNAVAILABLE;ddr_status.sdram1_cs0 = (ddr_param_interface_1->num_rows_cs0 != 0) ?DDR_ACTIVE : DDR_UNAVAILABLE;ddr_status.sdram1_cs1 = (ddr_param_interface_1->num_rows_cs1 != 0) ?DDR_ACTIVE : DDR_UNAVAILABLE;/* Copy DDR device parameters to shared memory */ddr_params_set_shared_memory();ddr_init_done = TRUE;}/* Else, already initialized ddr, do nothing */
} /* ddr_initialize_device */
(1)ddr_init用已有的ddr参数初始化HAL层的一些数据结构,主要是ddr_status。

(2)(3)(4)(5)根据ddr_status状态判断SDRAM0的接口上的两个CS是否连了DDR,然后调用HAL_SDRAM_Init进行初始化。

后面几句是判断SDRAM1上是否连了DDR,并且相应的调用HAL_SDRAM_Init进行初始化。

ddr_init():

void ddr_init(void)
{struct ddr_device_params_common *ddr_param_interface_0, *ddr_param_interface_1;/* Initialize the ddr driver Mutex */DDR_SYNC_INIT();/* Get DDR parameters */ddr_param_interface_0 = &(ddr_get_params(SDRAM_INTERFACE_0)->common);ddr_param_interface_1 = &(ddr_get_params(SDRAM_INTERFACE_1)->common);/* First initialize all the ddr devices to be unavailable */ddr_status.sdram0_cs0 = DDR_UNAVAILABLE;ddr_status.sdram0_cs1 = DDR_UNAVAILABLE;ddr_status.sdram1_cs0 = DDR_UNAVAILABLE;ddr_status.sdram1_cs1 = DDR_UNAVAILABLE;/* based on ddr parameter selected, set the ddr status for active ddr */if(ddr_param_interface_0->num_rows_cs0 != 0){ddr_status.sdram0_cs0 = DDR_ACTIVE;}if(ddr_param_interface_0->num_rows_cs1 != 0){ddr_status.sdram0_cs1 = DDR_ACTIVE;}if(ddr_param_interface_1->num_rows_cs0 != 0){ddr_status.sdram1_cs0 = DDR_ACTIVE;}if(ddr_param_interface_1->num_rows_cs1 != 0){ddr_status.sdram1_cs1 = DDR_ACTIVE;}} /* ddr_init */
ddr_init()函数通过 ddr_get_params从IMEM中获取DDR参数,根据参数对ddr_status的两个SDRAM接口的CS进行设置。


我们下面来看

HAL_SDRAM_Init(SDRAM_INTERFACE interface, SDRAM_CHIPSELECT chip_select, uint32 clk_speed)函数:
这个函数完成DDR控制器,DDR 设备的初始化,DDR大小的检测等等基本的配置。
void HAL_SDRAM_Init(SDRAM_INTERFACE interface, SDRAM_CHIPSELECT chip_select, uint32 clk_speed)
{uint32 offset;struct ddr_device_params_common *ddr_params;/* Channel offset */offset = (interface == SDRAM_INTERFACE_0) ? SDRAM_0_OFFSET : SDRAM_1_OFFSET;/* Get DDR device parameters */ddr_params = &(ddr_get_params(interface)->common);ddr_set_config(offset, ddr_bimc_config_base, ddr_bimc_config_delta); --------------(1)/* Configure BIMC clock period */HAL_SDRAM_BIMC_Update_Clock_Period(clk_speed);/* Configure DPE timing */HAL_SDRAM_DPE_Update_AC_Parameters(interface, clk_speed);#ifndef BOOT_PRE_SILICON/* Initialize DDR PHY */HAL_SDRAM_PHY_Init(interface, clk_speed);
#endif/* Initialize DDR device */HAL_SDRAM_SHKE_Device_Init(interface, chip_select, clk_speed);#ifndef BOOT_PRE_SILICON/* Rank detection */chip_select = HAL_SDRAM_BIMC_Rank_Detection(interface); -----------------(2)/* Size detection */HAL_SDRAM_Ram_Size_Detection(interface); --------------------------------(3)/* Parameter detection */if (ddr_params_detection(interface)){/* Re-configure DPE timing */HAL_SDRAM_DPE_Update_AC_Parameters(interface, clk_speed);}
#endif/* Initialize BIMC DPE */HAL_SDRAM_DPE_Init(interface);/* Initialize BIMC SHKE */HAL_SDRAM_SHKE_Init(interface);/* Initialize BIMC SCMO */HAL_SDRAM_SCMO_Init(interface);}} /* HAL_SDRAM_Init */


 只列出了主要的函数流程。 

(1)ddr_set_config根据不同的平台对BMIC接口进行基本的配置。

(2)HAL_SDRAM_BIMC_Rank_Detection(interface)检测该interface上有几个rank,也就是说连了几个CS,返回值为SDRAM_CS0或者SDRAM_CS0|SDRAM_CS1即SDRAM_BOTH。

(3)HAL_SDRAM_Ram_Size_Detection(interface)计算该interface上连的DDR的容量,也就是计算有多少行,多少列,多少个bank,位宽是多少((num_rows_csx,num_cols_csx,num_banks_csx,interface_width)。有了这几个参数可以算出DDR的总的容量,对于DDR3来说,bank的数是8,因为有BA0-BA2。

          大家可以注意一下高通平台上DDR的几个概念:CHANNEL(INTERFACE),RANK,BANK,ROW,COL,INTERFACE_WIDTH。弄清楚了这几个概念对高通平台的DDR初始化也就弄清楚了一大半,剩下的就是时序等硬件参数的初始化。

        看到这里可能有些糊涂,因为我们都知道高通平台有一个CDT机制专门用来设置DDR参数的,为什么这里还需要重新检测设置,本文上面提到的获取IMEM中获取的DDR参数其实就是通过CDT机制得到的参数,因为在sbl1_ddr_init之前首先会调用boot_config_data_table_init函数,这个函数会会从CDT分区读取DDR相关参数,如果没有CDT分区则从编译生成的boot_cdt_array.c中提取DDR参数并保存中全局的bl_shared_data中,然后再用函数sbl1_ddr_set_params把DDR数据保存到SMEM中。

        高通平台的DDR的autodetection机制并不是所有平台都有,老的平台并不支持。





http://www.ppmy.cn/news/431948.html

相关文章

高通modem命名及对应芯片

高通modem命名及对应芯片: modemchipsetMPSS.HI.4.3SM4350MPSS.HI.2.0 , HimalayaSM8250SDX55MPSS.HI.1.0SM8250/SM7250MPSS.HE.1.5SM8150SDX50MPSS.HE.1.0SM8150MPSS.AT.4.4 , AtlasSM6250MPSS.AT.4.3SM6150/SM7150MPSS.AT.4.0.2SDM710/SDM670MPSS.AT.4.0SDM845MP…

高通设置LDO电压

高通平台如何设置LDO电压,以LDO17为例,默认给屏供电,设置为2.85V现在设置为3.3V。 修改的rpm和sbl部分代码,修改LDO17电压为3.3V 。 修改如下: (1)、 --- a/RPM.BF.2.2/rpm_proc/core/systemdri…

android 高通分区表,高通智能机分区表详细解析

很不错的帖子,以前很多firmware里不了解的二进制格式的系统镜像都能知道大概作用了 Label Purpose of this partition Modem Partition for modemFsc Cookie partition to store Modem File System’s cookies.Ssd Partition for ssd diag modul…

android 高通替换开机logo,高通平台 开机logo 替换

经过两天的奋战终于把开机logo给搞定了啊。 首先修改开机logo要从哪里入手呢?先分析一下源码看看. ---> 1 voiddisplay_image_on_screen()2 {3 struct fbimage default_fbimg, *fbimg;4 bool flag = true;5 6 fbcon_clear();7 fbimg =fetch_image_from_partition(); //从sp…

高通联机修改IMEI等参数的相关解析

目前来说。手机芯片被高通与mtk占领大多市场。系统版本越高对底层安全参数限制就越高。区别与早期高通芯片。直接就可以联机修改imei等相关数据。今天只对高通芯片imei等参数的修改做个简单的解析说明更改高通芯片imei等参数一般有以下几种方法1----联机软件修改串码2---修改基…

MSM8976平台概述

MSM8976是从8952平台继承下来的,包含两组(cluster)core: 四个A72cpu核,支持最高1.8G主频(MSM8976SG最高支持2G主频),有1MB大小的L2 CACHE 四个A53cpu核,支持最高1.4G主频…

高通8976pro手机下载端口变成900e解决办法

个人碰到两次了,给驱动的同事,都是无解,百度了很多相关的问题,什么切线,还有进入到fastboot模式,我的是adb设备都找不到的,无法进入fastboot模式,无法进入recovery模式。 第二次实在…

管理类联考——英语——趣味篇——阅读——考题的来源

Part One考研英语阅读——Part A 1.卫报 《卫报》( The Guardian)是英国的全国性综合内容日报。与《泰晤士报》、《每日电讯报》被合称为英国三大报。由约翰爱德华容泰勒创办于1821年5月5日。该报注重报道国际新闻,擅长发表评论和分析性专题文章。一般公众视《卫报…