【Android驱动01】EMMC移植和兼容以及常见问题解决方案

一,增加 flash步骤

1) 根据硬件原理图和EMMC 和DDR厂家的芯片资料, 确定EMMC 和DDR 64+4,型号如下:
EMMC: SamsungKLMCG4JETD_B041
DDR: H9CKNNNDATMUPR_NUH

2) 检查MemoryDeviceList_MT6737M.xls里是否有该flash
vendor\mediatek\proprietary\bootable\bootloader\preloader\tools\emigen\MT6797\MemoryDeviceList_MT6797.xls
list里面要有custom_MemoryDevice.h里用到的emmc
如果MemoryDeviceList_MT6797.xls 中没有,则需要加入对应的器件

3)添加 flash
查看修改 DDR
vendor\mediatek\proprietary\bootable\bootloader\preloader\custom\6797_6m_n\inc\custom_MemoryDevice.h

/64+4/
#define BOARD_ID MT6797_EVB
#define CS_PART_NUMBER[0] H9CKNNNDATMUPR

4)out目录查看编译的flash型号,及DDR时序
编译时会调用emigen,emigen.pl脚本会解析MemoryDeviceList_MT6797.xls生成custom_emi.c
out\target\product\MT6797\obj\PRELOADER_OBJ\inc\custom_emi.h

 EMI_SETTINGS emi_settings[] =
          {      
              //08EMCP08_NL2DT227
              {
                  0x0,        /* sub_version */
                  0x0202,     /* TYPE */
                  9,      /* EMMC ID/FW ID checking length */
                  0,      /* FW length */
                  {0x70,0x01,0x00,0x45,0x48,0x38,0x45,0x42,0x38,0x0,0x0,0x0,0x0,0x0,0x0,0x0},     /* NAND_EMMC_ID */
                  {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},      /* FW_ID */
                  0x00025052,     /* EMI_CONA_VAL */
                  0xAA00AA00,     /* DRAMC_DRVCTL0_VAL */
                  0xAA00AA00,     /* DRAMC_DRVCTL1_VAL */
                  0x44584493,     /* DRAMC_ACTIM_VAL */
                  0x01000000,     /* DRAMC_GDDR3CTL1_VAL */
                  0xF0048483,     /* DRAMC_CONF1_VAL */
                  0xA00632D1,     /* DRAMC_DDR2CTL_VAL */
                  0xBF080401,     /* DRAMC_TEST2_3_VAL */

到这flash 就添加好了

5)MTK 平台查看eMMC和DDR的工作频率
eMMC:

adb shell cat /sys/kernel/debug/mmc0/clock

DDR:

 adb shell cat /sys/bus/platform/drivers/emi_clk_test/read_dram_data_rate

硬件信息:通过这个节点可以知道当前flash的id,上层根据id找到对应的flash名字。

cat /sys/block/mmcblk0/device/cid
\kernel-4.4\drivers\mmc\core\Mmc.c

MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1]

GDT42A32ED7_T2E 0x700100543532373332010585581e937d

二,支持兼容方式

  1. EMCP类: 只要emmc id不同,就可以兼容。

  2. discrete lp2 类: dram vendor ID不同,就可以兼容(也就是说不同晶圆厂家兼容,具体对应的是datasheet中的MR5值,对应到code中MemoryDeviceList_xxxx.xlsx 表格的MODE_REG5 列)

  3. discrete lp3 类: dram vendor ID不同,就可以兼容(也就是说不同晶圆厂家兼容,具体对应的是datasheet中的MR5值,对应到code中MemoryDeviceList_xxxx.xlsx 表格的MODE_REG5 列)

  4. PCDDR3类:不支持。

  5. 判断哪些ddr可以兼容,编译时会执行这个脚本
    vendor/mediatek/proprietary/bootable/bootloader/preloader/tools/emigen/MT8127/emigen.pl

①:Board ID不匹配,不支持

[Error]unsupported part number H9TKNNN8KDMP

所以xls表格里面配置的board id跟当前平台不一致的话,会报不支持。

②:兼容不了LPDDR2和LPDDR3同时选配

TotalCustemChips:2

[Error] LPDDR2 and LPDDR3 are not allowed to be mixed in the Combo Discrete DRAM list.

③:兼容不了多个PCDDR3同时选配

[Error] At most one discrete PCDDR3 DRAM is allowed in the Combo MCP list

④:兼容不了LPDDR3和PCDDR3同时选配

[Error] At most one discrete PCDDR3 DRAM is allowed in the Combo MCP list

  1. 开机检测ddr

Discrete lp3 (LPDDR3类) 或Discrete lp2 (LPDDR2类)
vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt8163/src/drivers/emi.c

对应log:
[EMI]MR5:3 ----------->读出来的值
emi_settings[i].MODE_REG_5:3,emi_settings[i].type:3
MODE_REG_5---------->时序表中MODE_REG5列配置的值

7.eMCP类
eMCP类的DDR是通过读emmc_id来实现兼容的。

所以:
可以兼容的情况:
1:兼容列表的ddr类型都是Discrete LPDDR2 (MODE_REG5不能有相同的)
2:兼容列表的ddr类型都是Discrete LPDDR3 (MODE_REG5不能有相同的)

不能兼容的情况:
1:兼容列表中不能同时包含LPDDR2,LPDDR3或PCDDR3类型
2:多个PCDDR3类型的ddr不能兼容

三,EMMC移植常见问题

1,无法下载
MTK平台会有以下几种情况:在下载过程中经常出现enable Dram fail的错错误,遇到这种情况第一反应先format 一下memory,然后再down,如果format不行过着还是没法dwon的话,那么再做如下分析;

一旦出现此问题,需做确认以下三点:
1,必须用最新版本的flash tool下载;
2,memory是不是经过MTK验证过;
3,板子必须跑过ett测试,preloader里面的MDL(memorydevicelist)里面配置Dram timing必须是ett log输出的对应的Dram timing;

去确认后还是无法下载那么就做如下分析:

a.软件原因(一般问题出在研发端):
a1.EMI没有配置手机硬件本身用的memory信息,此问题一般在研发端下载未知的软件版本时候发生,具体可以check 此文件:Custom_MemoryDevice.h是否配置了硬件本身用的memory的part number;

a2.修改了emigen.pl或者修改其他preloader的某些文件,导致tool解析不出build出的preloader.bin的EMI参数,此类一般是preloader客制化问题引起的,可以咨询一下MTK;

a3.DRAM 的时序timing有误,可以对比一下ETT测试输出的DRAM timing;

b.硬件原因;
b1.memory本身的问题,此时需要做交叉对比实验确定是memory问题,还是板子问题,若是memory问题,请找memoryvendor;

b2.板子硬件有问题,此类问题一般是由于Memory周边的器件有贴错或者虚焊导致;需要拿到硬件分析;

2,修改DDR时序
vendor/mediatek/proprietary/bootable/bootloader/preloader/tools/emigen/MT6735/MemoryDeviceList_MT6737M.xls
1. 其中 H9CCNNN8GTMLAR 为 2G DRAM(8192+8192),可配置为1G DRAM(8192 或 4096+4096),其余均不需动
2. 其中MODE_REG3由“0x00020003”修改为“0x00010003” -> 增强驱动能力
3. 其中CONA_VAL不对会导致编译报错
Samsung KMK7U000VM_B309 MCP(eMMC+LPDDR2) 4096+4096 MT6735_EVB 0x1501004B375530304D (4096+4096) 1GDRAM
KMK7U000VM_B309 Samsung 2048 2048 128 0 0 0 0 7634944 7460 (7460) 8GDROM

3,修改DDR频率 - 需要关闭DVFS
3.1. vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6735/src/drivers/pll2.c

void mt_pll_post_init(void)
        +    /*
                if (D2Plus == 1) {
                    mt_mempll_init(DDR1280, PLL_MODE_1);
                    memfreq_val = 1280000;
                } else {
                    mt_mempll_init(DDR1066, PLL_MODE_1);
                    memfreq_val = 1066000;
                }
        +    */
        +    mt_mempll_init(DDR1066, PLL_MODE_1);    // DDR800
        +    memfreq_val = 1066000;                    // 800000

3.2. 如果缺少所需频率,可以自己添加:
vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6735/src/drivers/pll2.c

void mt_mempll_init(int type, int pll_mode)
            else  if (type == DDR850) 
            {
                *((UINT32P)(DDRPHY_BASE + (0x0183 <<2))) = (*((UINT32P)(DDRPHY_BASE + (0x0183 <<2))) & (~mempll2_vco_div_sel)) | 0x00000000; //RG_MEMPLL2_VCO_DIV_SEL =0;
                *((UINT32P)(DDRPHY_BASE + (0x0185 <<2))) = (*((UINT32P)(DDRPHY_BASE + (0x0185 <<2))) & (~mempll3_vco_div_sel)) | 0x00000000; //RG_MEMPLL3_VCO_DIV_SEL =0;
                *((UINT32P)(DDRPHY_BASE + (0x0187 <<2))) = (*((UINT32P)(DDRPHY_BASE + (0x0187 <<2))) & (~mempll4_vco_div_sel)) | 0x00000000; //RG_MEMPLL4_VCO_DIV_SEL =0;
                *((UINT32P)(DDRPHY_BASE + (0x0189 <<2))) = (*((UINT32P)(DDRPHY_BASE + (0x0189 <<2))) & (~pllc1_dmss_pcw_ncpo_30_0)) | (0x338da215 << 1); //RG_DMSS_PCW_NCPO[30:0]
               
                if ((pll_mode == PLL_MODE_3) || (pll_mode == PLL_MODE_2))
                {
                    *((UINT32P)(DDRPHY_BASE + (0x0182 <<2))) = (*((UINT32P)(DDRPHY_BASE + (0x0182 <<2))) & (~mempll2_fbdiv_6_0)) | (0x0000000d << 2); //RG_MEMPLL2_FBDIV = 7'h0d;
                    *((UINT32P)(DDRPHY_BASE + (0x0184 <<2))) = (*((UINT32P)(DDRPHY_BASE + (0x0184 <<2))) & (~mempll3_fbdiv_6_0)) | (0x0000000d << 2); //RG_MEMPLL3_FBDIV = 7'h0d;
                    *((UINT32P)(DDRPHY_BASE + (0x0186 <<2))) = (*((UINT32P)(DDRPHY_BASE + (0x0186 <<2))) & (~mempll4_fbdiv_6_0)) | (0x0000000d << 2); //RG_MEMPLL4_FBDIV = 7'h0d;
                }
                else
                {
                    *((UINT32P)(DDRPHY_BASE + (0x0182 <<2))) = (*((UINT32P)(DDRPHY_BASE + (0x0182 <<2))) & (~mempll2_fbdiv_6_0)) | (0x00000034 << 2); //RG_MEMPLL2_FBDIV = 7'h34;
                    *((UINT32P)(DDRPHY_BASE + (0x0184 <<2))) = (*((UINT32P)(DDRPHY_BASE + (0x0184 <<2))) & (~mempll3_fbdiv_6_0)) | (0x00000034 << 2); //RG_MEMPLL3_FBDIV = 7'h34;
                    *((UINT32P)(DDRPHY_BASE + (0x0186 <<2))) = (*((UINT32P)(DDRPHY_BASE + (0x0186 <<2))) & (~mempll4_fbdiv_6_0)) | (0x00000034 << 2); //RG_MEMPLL4_FBDIV = 7'h34;
                }
            }

vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6735/src/drivers/inc/pll2.h

enum {
            DDR533   = 533,
        +    DDR850    = 850,
            DDR938   = 938,
            DDR1066  = 1066,
            DDR1280  = 1280,
            DDR1333  = 1333,
            DDR1466  = 1466,
        };

3.3 关闭DVFS(动态电压频率调节) - 不修改的话内核会动态调节,修改频率不会生效
3. alps\vendor\mediatek\proprietary\bootable\bootloader\preloader\platform\mt6735\src\drivers\inc\dramc2.h

 -    #define ENABLE_DFS
        +    //#define ENABLE_DFS
alps/kernel-3.18/drivers/misc/mediatek/base/power/mt6735/mt_vcore_dvfs_2.c
        -    static bool feature_en __nosavedata = 1;       /* if feature disable, then keep HPM */
        +    static bool feature_en __nosavedata = 0;       /* if feature disable, then keep HPM */

3.4 修改DDR电压
电压调节函数
pmic_Vcore_adjust();
pmic_Vmem_adjust();
pmic_Vmem_Cal_adjust();
方法一:

vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6735/src/drivers/emi.c 
        else if ((emi_set->type & 0xF) == TYPE_LPDDR3)
        {
            #ifdef REXTDN_ENABLE
                ett_rextdn_sw_calibration();
            #endif
        +    pmic_config_interface(MT6328_SLDO_ANA_CON0, 0, 0x3, 0);        // 1.24V 参数中第一位寄存器值,第二位就是我们要设的电压值,第三位读取位数
        +    pmic_config_interface(MT6328_SLDO_ANA_CON1, 0x0D, 0xF, 8);    // +0.6V

方法二:
1. 在preloader初始化的时候添加调整DDR电压的步骤
vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6735/src/drivers/platform.c

 void platform_pre_init(void)
            {
                mtk_timer_init();
                g_boot_time = get_timer(0);
                mtk_uart_init(UART_SRC_CLK_FRQ, CFG_LOG_BAUDRATE);
                mt_gpio_init();
                clk_buf_all_on();
                pwrap_init_preloader();

                i2c_hw_init();
                check_charger_boost_status();
            #if !CFG_FPGA_PLATFORM
                pmic_ret = pmic_init();
        +    #ifdef DRAM_HQA
        +        dram_HQA_adjust_voltage();
        +    #endif
                mt_pll_post_init();
            #endif
  1. 添加一些宏用做选择电压等级
    vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6735/src/drivers/inc/emi.h
		    +    #define DRAM_HQA 
            +    #define HVcore
            +    //#define NV
            +    //#define LVcore
            +    //#define HVcore_LVmem
            +    //#define LVcore_HVmem
  1. 实现调整电压的函数
    vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6735/src/drivers/emi.c
  -    #ifdef pmic_HQA_TCs        // 此宏没开
    +    #if 1
    +    void dram_HQA_adjust_voltage(void)
        {
            #ifdef HVcore  //HV (Vc=1.375V, Vm=1.3V
                pmic_Vcore_adjust(1); // 1.24V          
                pmic_Vmem_adjust(1);  // 1.39V
                pmic_Vmem_Cal_adjust(0);  // +0.10V (1.3V)                
                print("[DRAM HQA]========== HV ==========\r\n");    // LOG 显示走这里
            #endif

            #ifdef NV     //NV (Vc=1.15V, Vm=1.22V)
                pmic_Vcore_adjust(1); // 1.15V       
                pmic_Vmem_adjust(0);  // 1.20V
                pmic_Vmem_Cal_adjust(1);  // +0.02V (1.22V)            
                print("[DRAM HQA]========== NV ==========\r\n");
            #endif

            #ifdef LVcore //LV (Vc=1.09375V, Vm=1.16V
                pmic_Vcore_adjust(2); // 1.09375V
                pmic_Vmem_adjust(0);  // 1.20V
                pmic_Vmem_Cal_adjust(2);  // -0.04V(1.16V)        
                print("[DRAM HQA]========== LV ==========\r\n");
            #endif

            #ifdef HVcore_LVmem   //HVcore_LVmem (Vc=1.375V, Vm=1.16V)
                pmic_Vcore_adjust(0); // 1.375V          
                pmic_Vmem_adjust(0);  // 1.20V
                pmic_Vmem_Cal_adjust(2);  // -0.04V(1.16V)              
                print("[DRAM HQA]========== HVcLVm ==========\r\n");
            #endif

            #ifdef LVcore_HVmem   //LVcore_HVmem (Vc=1.09375V, Vm=1.3V)
                pmic_Vcore_adjust(2); // 1.09375V
                pmic_Vmem_adjust(0);  // 1.20V
                pmic_Vmem_Cal_adjust(0);  // +0.10V (1.3V)                      
                print("[DRAM HQA]========== LVcHVm ==========\r\n");
            #endif
    +    }

3.5 打开DDR重新校验 - 使每次回复出厂设置后DDR重新校验
适用于eng版
vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6735/src/drivers/inc/emi.h

        -    #define DDR_RESERVE_MODE
        +    //#define DDR_RESERVE_MODE

3.6 :开机重启 一般是emmc速度问题
kernel-3.18/arch/arm/boot/dts/hys6737m_35_m0.dts

				msdc-sys-suspend;
                mmc-ddr-1_8v;
                mmc-hs200-1_8v;
-               mmc-hs400-1_8v;
                non-removable;
                pinctl = <&mmc0_pins_default>;
                register_setting = <&mmc0_register_setting_default>;

eMMC 里 DDR52 HS200 HS400 这些名词指的是不同的速度

DDR52就是最高 52M clock,数据速率就是 52 x 2 = 104
HS200 就是最高 200M clock,单通道,数据速率也是 200
HS400 也是最高 200M clock,但是是双通道,所以数据速率是 200 x 2 = 400

HS200和HS400 是 5.0 协议才有的。

Modename Data Rate IO voltage Bus Width Frequency Max Data Transfer
MMC card Single 3/1.8/1.2V 1,4,8 0-26MH 26MB/s
HightSpeedSDR Single 3/1.8/1.2V 1,4,8 0-52MH 52MB/s
HightSpeedSDR Dual 3/1.8/1.2V 4,8 0-52MH 104MB/s
HS200 Single 1.8/1.2V 4,8 0-200MH 200MB/s
HS400 Dual 1.8/1.2V 8 0-200MH 400MB/s

  • 24
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孤舟簔笠翁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值