1. 获取 flash id:
硬件信息:通过这个节点可以知道当前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]
MT8163_MT8127
GDT42A32ED7_T2E 0x700100543532373332010585581e937d
MT8321 只支持如下方式兼容:
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类:不支持。
编译脚本
判断哪些ddr可以兼容,编译时会允许这个脚本
vendor/mediatek/proprietary/bootable/bootloader/preloader/tools/emigen/MT8127/emigen.pl
if ($scan_idx eq $PartNum) # scan column for Part Number
{
my $boardid ;
$boardid = &xls\_cell\_value($Sheet, $row, $COLUMN\_BOARD\_ID) ;
if ($CustBoard\_ID eq $boardid)
{
$rows\_part\_found\[$num\_part\_found\] = $row;
print "\\nPartNum($PartNum==$scan\_idx) found in row $row\\n" ;
$Total\_PART\_NUMBER\[$TotalCustemChips\] = $PartNum;
$num\_part\_found += ;
$TotalCustemChips += ;
}
}
if ($num_part_found == )
{
print "\n[Error]unsupported part number $PartNum\n" ;
die "\n[Error]unsupported part number $PartNum\n" ;
}
①: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
编译过后会生成
out/target/product/hiteq8127_ce/obj/PRELOADER_OBJ/inc/custom_emi.h
此文件包含兼容的所有ddr时序,就是将xls表格里的时序信息构建成数组。开机时会利用这个数组emi_settings[]找到指定的ddr。
EMI_SETTINGS emi_settings[] =
{
//K4E6E304EE\_EGCF
{
0x0, /\* sub\_version \*/
0x0003, /\* TYPE \*/
, /\* EMMC ID/FW ID checking length \*/
, /\* FW length \*/
{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}, /\* NAND\_EMMC\_ID \*/
{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}, /\* FW\_ID \*/
0x000250A2, /\* EMI\_CONA\_VAL \*/
0xAA00AA00, /\* DRAMC\_DRVCTL0\_VAL \*/
0xAA00AA00, /\* DRAMC\_DRVCTL1\_VAL \*/
0x66CB4619, /\* DRAMC\_ACTIM\_VAL \*/
0x01000000, /\* DRAMC\_GDDR3CTL1\_VAL \*/
0xF00487C3, /\* DRAMC\_CONF1\_VAL \*/
0xC00652D1, /\* DRAMC\_DDR2CTL\_VAL \*/
0xBF090401, /\* DRAMC\_TEST2\_3\_VAL \*/
0x01806C60, /\* DRAMC\_CONF2\_VAL \*/
0xD1643542, /\* DRAMC\_PD\_CTRL\_VAL \*/
0x00008888, /\* DRAMC\_PADCTL3\_VAL \*/
0x88888888, /\* DRAMC\_DQODLY\_VAL \*/
0x00000000, /\* DRAMC\_ADDR\_OUTPUT\_DLY \*/
0x00000000, /\* DRAMC\_CLK\_OUTPUT\_DLY \*/
0x11000D21, /\* DRAMC\_ACTIM1\_VAL\*/
0x17800000, /\* DRAMC\_MISCTL0\_VAL\*/
0x040004C1, /\* DRAMC\_ACTIM05T\_VAL\*/
{0x40000000,0x40000000,,}, /\* DRAM RANK SIZE \*/
{,,,,,,,,,}, /\* reserved 10 \*/
0x00C30001, /\* LPDDR3\_MODE\_REG1 \*/
0x000A0002, /\* LPDDR3\_MODE\_REG2 \*/
0x00020003, /\* LPDDR3\_MODE\_REG3 \*/
0x00000001, /\* LPDDR3\_MODE\_REG5 \*/
0x00FF000A, /\* LPDDR3\_MODE\_REG10 \*/
0x0000003F, /\* LPDDR3\_MODE\_REG63 \*/
} ,
};
vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt8127/src/drivers/inc/emi.h
这个结构体在emi.h中定义
typedef struct
{
int sub_version; // sub_version: 0x1 for new version
int type; /* 0x0000 : Invalid
0x0001 : Discrete DDR1
0x0002 : Discrete LPDDR2
0x0003 : Discrete LPDDR3
0x0004 : Discrete PCDDR3
0x0101 : MCP(NAND+DDR1)
0x0102 : MCP(NAND+LPDDR2)
0x0103 : MCP(NAND+LPDDR3)
0x0104 : MCP(NAND+PCDDR3)
0x0201 : MCP(eMMC+DDR1)
0x0202 : MCP(eMMC+LPDDR2)
0x0203 : MCP(eMMC+LPDDR3)
0x0204 : MCP(eMMC+PCDDR3)
*/
int id_length; // EMMC and NAND ID checking length
int fw_id_length; // FW ID checking length
char ID[];
char fw_id[]; // To save fw id
int EMI_CONA_VAL; //@0x3000
int DRAMC_DRVCTL0_VAL; //@0x40B8 -> customized TX I/O driving
int DRAMC_DRVCTL1_VAL; //@0x40BC -> customized TX I/O driving
int DRAMC_ACTIM_VAL; //@0x4000
int DRAMC_GDDR3CTL1_VAL; //@0x40F4
int DRAMC_CONF1_VAL; //@0x4004
int DRAMC_DDR2CTL_VAL; //@0x407C
int DRAMC_TEST2_3_VAL; //@0x4044
int DRAMC_CONF2_VAL; //@0x4008
int DRAMC_PD_CTRL_VAL; //@0x41DC
int DRAMC_PADCTL3_VAL; //@0x4014 -> customized TX DQS delay
int DRAMC_DQODLY_VAL; //@0x4200~0x420C -> customized TX DQ delay
int DRAMC_ADDR_OUTPUT_DLY; // for E1 DDR2 only
int DRAMC_CLK_OUTPUT_DLY; // for E1 DDR2 only
int DRAMC_ACTIM1_VAL; //@0x41E8
int DRAMC_MISCTL0_VAL; //@0x40FC
int DRAMC_ACTIM05T_VAL; //@0x41F8
int DRAM_RANK_SIZE[];
int reserved[];
union
{
struct
{
int LPDDR2\_MODE\_REG\_1;
int LPDDR2\_MODE\_REG\_2;
int LPDDR2\_MODE\_REG\_3;
int LPDDR2\_MODE\_REG\_5;
int LPDDR2\_MODE\_REG\_10;
int LPDDR2\_MODE\_REG\_63;
};
struct
{
int DDR1\_MODE\_REG;
int DDR1\_EXT\_MODE\_REG;
};
struct
{
int PCDDR3\_MODE\_REG0;
int PCDDR3\_MODE\_REG1;
int PCDDR3\_MODE\_REG2;
int PCDDR3\_MODE\_REG3;
int PCDDR3\_MODE\_REG4;
int PCDDR3\_MODE\_REG5;
};
struct
{
int LPDDR3\_MODE\_REG\_1;
int LPDDR3\_MODE\_REG\_2;
int LPDDR3\_MODE\_REG\_3;
int LPDDR3\_MODE\_REG\_5;
int LPDDR3\_MODE\_REG\_10;
int LPDDR3\_MODE\_REG\_63;
};
};
} EMI_SETTINGS;
三:开机检测ddr
Discrete lp3 (LPDDR3类) 或Discrete lp2 (LPDDR2类)
vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt8163/src/drivers/emi.c
static int mt_get_mdl_number (void)
//try to find discrete dram by DDR2_MODE_REG5(vendor ID)
for (i = ; i < num_of_emi_records; i++)
{
if (TYPE_LPDDR2 == dram_type)
mode_reg_5 = emi_settings[i].LPDDR2_MODE_REG_5;
else if (TYPE_LPDDR3 == dram_type)
mode_reg_5 = emi_settings[i].LPDDR3_MODE_REG_5;
printf("emi_settings[i].MODE_REG_5:%x,emi_settings[i].type:%x\n",mode_reg_5,emi_settings[i].type);
//only check discrete dram type
if (((emi_settings[i].type & 0x0F00) == 0x0000) || ((emi_settings[i].type & 0x0F00) == 0x0F00))
{
//support for compol discrete dram
if ((mode_reg_5 == manu_id) )
{
mdl_number = i;
found = ;
break;
}
}
}
对应log:
[EMI]MR5:3 ----------->读出来的值
emi_settings[i].MODE_REG_5:3,emi_settings[i].type:3
MODE_REG_5---------->时序表中MODE_REG5列配置的值
eMCP类
eMCP类的DDR是通过读emmc_id来实现兼容的。
/* 1.
* if there is MCP dram in the list, we try to find emi setting by emmc ID
* */
if (mcp_dram_num > )
{
result = platform_get_mcp_id (id, emmc_nand_id_len,&fw_id_len);
for (i = ; i < num\_of\_emi\_records; i++)
{
if (emi\_settings\[i\].type != )
{
if ((emi\_settings\[i\].type & 0x0F00) != 0x0000)
{
if (result == )
{ /\* valid ID \*/
if ((emi\_settings\[i\].type & 0x0F00) == 0x100)
{
/\* NAND \*/
if (memcmp(id, emi\_settings\[i\].ID, emi\_settings\[i\].id\_length) == ){
memset(id + emi\_settings\[i\].id\_length, , sizeof(id) - emi\_settings\[i\].id\_length);
mdl\_number = i;
found = ;
break; /\* found \*/
}
}
else
{
/\* eMMC \*/
if (memcmp(id, emi\_settings\[i\].ID, emi\_settings\[i\].id\_length) == )
{
#if 0
printf("fw id len:%d\n",emi_settings[i].fw_id_length);
if (emi_settings[i].fw_id_length > )
{
char fw_id[];
memset(fw_id, , sizeof(fw_id));
memcpy(fw_id,id+emmc_nand_id_len,fw_id_len);
for (j = ; j < fw_id_len;j ++){
printf("0x%x, 0x%x ",fw_id[j],emi_settings[i].fw_id[j]);
}
if(memcmp(fw_id,emi_settings[i].fw_id,fw_id_len) == )
{
mdl_number = i;
found = ;
break; /* found */
}
else
{
printf("[EMI] fw id match failed\n");
}
}
else
{
mdl_number = i;
found = ;
break; /* found */
}
#else
mdl_number = i;
found = ;
break; /* found */
#endif
}
else{
printf("[EMI] index(%d) emmc id match failed\n",i);
}
}
}
}
}
}
}
所以:
可以兼容的情况:
1:兼容列表的ddr类型都是Discrete LPDDR2 (MODE_REG5不能有相同的)
2:兼容列表的ddr类型都是Discrete LPDDR3 (MODE_REG5不能有相同的)
不能兼容的情况:
1:兼容列表中不能同时包含LPDDR2,LPDDR3或PCDDR3类型
2:多个PCDDR3类型的ddr不能兼容
手机扫一扫
移动阅读更方便
你可能感兴趣的文章