MTK MCP FLASH 兼容设计思路

来源:互联网 发布:pptv网络电视机 编辑:程序博客网 时间:2024/05/01 15:32

 

 

MTK MCP FLASH 兼容设计思路
系列:
最近将MTK平台MT6225的兼容设计完成了,实现了 AMD &INTEL系列的局部兼容,所谓局部兼容,即兼容的那么几个MCP可同时兼容。大致实现思路如下,仅供参考

Flash启动流程:
使用NOR FLASH 架构时,当按下POWER key,硬件就从0×00000000地址开始运行代码,此地址在没有REMAPPING时,正好为CS0片选地址,即 nor Flash0地址。做一些基本配置,如 colck ,EMI golden timming等。
要实现 FLASH兼容,必须在配置时序之前,获取FLASH的具体型号,并查表得出具体时序及Regions配置信息。

获取ID:
那么,我没应该在调用BL  INT_Config之前,将我们获取FLASH ID的代码复制到INTRAM运行,并将ID保存在CPU的寄存器中,比如DMA的src addr 和dstaddr寄存器,都是32位寄存器。获取ID后,应该返回继续初始化。

获取ID后,在函数 custom_setEMI 中设置 FLASH 的时序,那么,应该在这里建立一个 timing table,索引为FLASH ID,搜索到ID后,即可配置timing了。

配置好timing 后,应该需要再配置Regions信息,在Initialize_FDD_tables 中,还需要识别不同的FLASH driver,是AMD还是INTEL,这些都需要通过指针来选择,动态选择。

可能,还会遇到一些比较复杂的MCP,比如SIBLEY系列,操作不同的部分,都需要使用指针来区别。MTK实现中,宏很多,我们需要仔细的替换成指针实现。

实现后,运行了一段时间,没有问题的。欢迎广大MTK同仁交流。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/kuanghanli/archive/2009/08/13/4443742.aspx

 

================================================================================
如何获取Nor FlashID
Nor Flash 目前主要有两个系列,一个是 AMD 另外一个就是 INTEL,其他系列的,我没有接触到,再此不讨论。

这两个系列的各自的命令集,差不多,至少,获取ID的命令集应该是一样的。针对一些厂商的Flash,可能驱动需要特别优化,延时需要特别修改等,由于获取ID , 对时序要求并不高,一般都能读取到ID的。

下面我把AMD 及 INTEL 获取 Flash ID 的命令放出,希望对大家有帮助,其实,这里写的,在 MCP的Datasheet 上都能查得。

AMD 系列
以下按照 word 来操作,byte操作方式,将偏移乘2即可
flash_base[0x0] = 0xF0; //reset Flash
flash_base[0x555] = 0xaa;
flash_base[0x2aa] = 0x55;
flash_base[0x555] = 0x90;
以上发送完成后,可以读取如下位置,获得相应的ID
AMD_MANUFACTURE_CODE = flash_base[0x0];
AMD_DEV_CODE = flash_base[0x1];
AMD_EXTDEV1_CODE = flash_base[0xe];
AMD_EXTDEV2_CODE = flash_base[0xf];

INTEL 系列
flash_base[0x0] = 0xFF;
flash_base[0x0] = 0x50;
flash_base[0x0] = 0x90;
以上发送完成后,可以读取如下位置,获得相应的ID
INTEL_MANUFACTURE_CODE = flash_base[0x0];
INTEL_DEV_CODE = flash_base[0x1];

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/kuanghanli/archive/2009/08/13/4443702.aspx

 

================================================================================
不同厂家的flash,大小一样,封装一样,可以兼容。目前支持nor-flash
我说说思路;
1、首先要把mtk里面memory自动配置的命令关掉,就是把emigen这个命令关闭
2、把要兼容的flash的id,分区,页大小等相关信息搜集到,然后放在一个结构里面。
3、在init.c中Application_Initialize进行读id操作
const kal_uint32 MANUFACTURE_ID_ADDR = 0x80030100; // flash id issave in DMA registers
const kal_uint32 DEV_ID_ADDR = 0x80030200;
const kal_uint32 EXT_DEV1_ID_ADDR = 0x80030104;
const kal_uint32 EXT_DEV2_ID_ADDR = 0x80030204;

gManufacture_code = *(volatile kal_uint16*)MANUFACTURE_ID_ADDR;
gDev_code = *(volatile kal_uint16 *)DEV_ID_ADDR;
gExt_dev_code1 = *(volatile kal_uint16 *)EXT_DEV1_ID_ADDR;
gExt_dev_code2 = *(volatile kal_uint16 *)EXT_DEV2_ID_ADDR;

4、在custom_emi.c中custom_setEMI和Initialize_FDD_tables中进行判断,然后把相应的flash参数赋给相关的变量。
--------------------------------------------------------------------------
几点疑问:
1 在Application_Initialize进行读id操作是不是晚了?是不是应该在INT_Config里setemi之前?
2 把flash id is save in DMA registers 是做何考虑?直接保存到不会被清零的internalram中可以吧

3 flash操作函数也需要根据不同的flash动态加载的


-------------------------------------------------------------------------- 
我的意思是把所有兼容的flash相关信息保存在一个静态数据结构里面,等读到板子上真正贴的flash的id后,和这个数据结构里面的id进行比较,如果相同,就把这个结构里面相应的flash的访问方式,分区等赋给相应的变量

在Application_Initialize进行读id操作不晚,


 

================================================================================
mtk平台,做一个动态识别flash的bin档

mtk平台下,打算做一个能自动识别flash并配置emi的bin档,就是说更换flash时不再需要每次emiclean,emigen来生成那几个配置文件,一个bin档支持几种flash。现在已能识别不同型号的flash,下一步要做的:各种flash需要的不同emi配置可以直接用exel表格的东西,即把custom_emi.h定义的宏改成全局变量等,在这些全局变量被用到之前根据flash的不同来动态调整他们,而原来代码里在c运行环境建立之前就被用到了的宏可以可以定义为几组只读常量来解决,也可以做到动态。可是做到现在发现一个问题,cusom_setemi这个函数是初始化bb的emi模块的,只有这步骤做完了才可能去操作emi上的器件,就是说flashid就只能在这个函数正常执行完才能读出来,可是动态的目的恰恰就是要根据flash的不同来配置emi模块,似乎这是个逻辑上的因果矛盾,这个问题无解了吗?

mikal Post at 2007-11-5 10:44:58
这个想法很好,如果做好了,完全可以取消emiclean这个动作!欢迎高手一起来解决这个问题!
--------------------------------------------------------------------------------
mikal Post at 2007-11-5 11:01:57
我个人的建议:

完全取消emiclean这个动作,我们可以在现有的emi文件中做修改;添加如下功能函数:

1、读取flash ID的函数接口;
2、根据ID来配置flash的指令集,bank及读写速度等参数的配置;

采用以上的想法后,我们可以取消custom_MemoryDevice.h文件中cs0和cs1的类型定义了;另外,Flash_opt.h中的定义要调整,同时调用Flash_opt.h中宏的flash驱动文件也要调整;

这样设计,以后手机硬件换不同类型的flash,只要bin能支持,就不用重新烧入bin了,直接换就ok:)

--------------------------------------------------------------------------------
Jane110 Post at 2007-11-5 15:36:06
哦,就是作flash兼容吧,读id判断的同时,是不是,flash driver也要改
--------------------------------------------------------------------------------
jinggu2001 Post at 2007-11-5 16:45:38
大家好像都没有解决楼主的问题:
1,楼主想读flash ID,但是读flashID 需要flash 的时序配置正确,或者至少可以正确访问;
2,楼主必须默认配置一组默认值,而这组默认值支持你要做兼容的几种flash;
3,flash id读取成功后,可以根据不同的ID采取优化后的参数;
4,至于driver操作的兼容,相信楼主没有问题

--------------------------------------------------------------------------------
fla888 Post at 2007-11-5 18:48:41
楼上的兄弟深得我意,基本上这个方案可以到此为止,可能性不大,关键问题是这组同时适合多种flash的emi默认值不好找,就算能找到也是兼容的型号非常有限。

我做了一个返回flashid的函数,利用是否正确读到id来做判断,如果id正确则可继续往下走,否则会强制出错。结果将这个处理过程放到init.c文件的custom_setemi函数之前,系统不能启动。而放到该函数之后,系统正常启动。说明确实一定要先配置好BB的emi模块硬件才谈得上读flashid。

当然不排除有强人能有别的解决办法,如果有请一定赐教在下。

--------------------------------------------------------------------------------
fla888 Post at 2007-11-5 23:19:04
想到了一个临时解决办法,做几组emi参数供custom_setemi调用,该函数后读flashid,将返回值在一个预先定义的id组里查找,如果没找到就返回去传入另一组参数调用custom_setemi,直到返回值在此id组里找到,此时emi即为正确设置。
--------------------------------------------------------------------------------
oldkitty Post at 2007-11-6 8:19:05
读FLASHd的ID并不需要先初始化时序,比如FlashTool等的DownloadAgent之类的。但是可能(记不清楚了,也可能不需要)有一个要求就是这段代码需要在非FLASH上运行,比如内部SRAM或者外部的PSRAM等。你可以考虑把读取FLASHID的代码放在系统引导过程中并拷贝到RAM中运行,最好是内部SRAM。
--------------------------------------------------------------------------------
oldkitty Post at 2007-11-6 8:21:20
不过这种做法并不一定有多大的好处。更换FLASH是一个很重要的事情,通常需要进行批量试产来帮助验证,而且即使同一型号的FLASH批次不同都有可能时序上有差异,所以需要严格控制FLASH的型号。
--------------------------------------------------------------------------------
longago Post at 2007-11-6 10:21:02
如果是MTK的话可以看下bootarm.s,引导程序会把flash里的代码拷贝到ram里运行,在拷贝之前也会对emi进行配置时序的操作,这是在custom_setemi之前

--------------------------------------------------------------------------------
mikal Post at 2007-11-6 10:57:50
今天来看,还没有人来解决啊!看来只有我出马了:)

1、flash ID的读写没有任何限制,任何flash都能提供 flash id的读,但是我们现在感觉好像读
    不出 flashID,其真正的原因是因为我们要把读flash ID 的函数link到mtk的内部ram
   中,具体原因,大家自己考虑吧;

2、自己做张flash的配置表,里面根据flash ID来索引。至于有同仁说时序问题,我想这个问题
    和做这个自动的表没有任何冲突,你可以先调好。


以上两步好后,自动适应flash的bin大部分工作就完成。lz可以去试试。

--------------------------------------------------------------------------------
fla888 Post at 2007-11-6 17:44:15
读flashid真的不需要设emi,不要配时序?那版主请你解释一下为什么将读id的函数放到custom_setemi之前不能读取,而放到后面就可以了?这个过程读id函数始终位于flash,并未拷贝到sram。

 就算将该函数link到内部sram,也是不可能执行的,除非使用仿真器将其下载到sram还差不多,因为在mtk的codebase里,先是执行int_config-->custom_setemi,后才是进行数据和代码的拷贝:INT_InitRegions,请大伙确认了再发言。

--------------------------------------------------------------------------------
fla888 Post at 2007-11-6 20:22:39
将读id函数link到sram,在custom_setemi之前调用它,指向的只是该函数将来会装载的地址,此时该地址只是一堆未知数据。
--------------------------------------------------------------------------------
mikal Post at 2007-11-7 11:22:44
再发表点个人的建议,后面就不讨论了。

1、我是站在flash角度上来看flash ID读操作的,至于有说,为什么在前面不可以,在后面可
   以,那得去分析下mtk的程序的运行流程了;但这个本身和flash ID读操作没有什么相冲
  之处,我提出为什么要把这个函数link到cpu的内部sram中呢?其考虑在于:
  如果我们的程序已经运行在flash上了,然后再对flash去做命令操作,担心有些flash不支持这
  样的操作,所以采用程序运行区和操作区分开的方法,至于如果说放到一起,也可以啊,
  是的,也许是可以,但是你试过所有的flash了吗?为了稳定可靠,程序运行和度操作区分
   开是最好的方法

2、说到link到sram中不能运行问题,这个应该是思路问题吧,您现在是考虑改他的框架,
    应该说是涉及到他的一些架构问题了,难道这个时候还必须走它的流程?

3、再说下emi的问题,其实任何cpu在上电reset后,如果能配置emi,系统缺省配置最慢
    速度的。如果认为非要配置emi才能操作flash,那么请问,程序刚开始怎么跑到flash上
    的?

4、再补充下,lz的问题其实和mtk bb本身可能没有太多关系,关键还是涉及到cpu,
    flash的操作和运行机制,这种操作基本都是标准得。

--------------------------------------------------------------------------------
fla888 Post at 2007-11-7 11:48:10
谢谢楼上的讨论。
--------------------------------------------------------------------------------
2410linux Post at 2007-11-7 22:16:03
在bootloader中读出flashID应该就可以了吧。
--------------------------------------------------------------------------------
wzl1188 Post at 2008-12-19 21:50:56
这种有意义的贴子讨论的朋友总是这么多,好热的
--------------------------------------------------------------------------------
hgd_dingjun Post at 2009-9-26 23:23:18
请问大侠如何实现的?
--------------------------------------------------------------------------------
study_mtk Post at 2009-9-27 15:39:13
各位同仁讨论的很热烈,不知LZ现在是否已经将FLASH兼容在一起呢!能否给大家讲解一下是怎么做兼容的。
--------------------------------------------------------------------------------
balu_dark Post at 2009-9-30 16:48:10
need ID list [em03]
--------------------------------------------------------------------------------
ffhh Post at 2009-10-6 20:16:35
可不可以先把所有的默认值都配置一遍,然后再读取ID,将读取出的ID 和你做的兼容的 ID list作对比,如果能对应上,则说明配置OK

本文来自:我爱研发网(52RD.com) - R&D大本营
详细出处:http://www.52rd.com/bbs/Archive_Thread.asp?SID=101434&TID=2

 


================================================================================
不同厂家的flash,大小一样,封装一样,可以兼容。目前支持nor-flash
我说说思路;
1、首先要把mtk里面memory自动配置的命令关掉,就是把emigen这个命令关闭
2、把要兼容的flash的id,分区,页大小等相关信息搜集到,然后放在一个结构里面。
3、在init.c中Application_Initialize进行读id操作
const kal_uint32 MANUFACTURE_ID_ADDR = 0x80030100; // flash id issave in DMA registers
const kal_uint32 DEV_ID_ADDR = 0x80030200;
const kal_uint32 EXT_DEV1_ID_ADDR = 0x80030104;
const kal_uint32 EXT_DEV2_ID_ADDR = 0x80030204;

gManufacture_code = *(volatile kal_uint16*)MANUFACTURE_ID_ADDR;
 gDev_code = *(volatile kal_uint16*)DEV_ID_ADDR;
 gExt_dev_code1 = *(volatile kal_uint16*)EXT_DEV1_ID_ADDR;
 gExt_dev_code2 = *(volatile kal_uint16*)EXT_DEV2_ID_ADDR;

4、在custom_emi.c中custom_setEMI和Initialize_FDD_tables中进行判断,然后把相应的flash参数赋给相关的变量。

--------------------------------------------------------------------------------
tommygreen Post at 2009-4-22 19:37:28
一般来讲,区分不同的Flash MCP,有如下几个方法:
1. 产品ID号
2. RAM的容量大小
3. 上述两个都无法区分,还可以通过分析不同MCP的NOR控制器中的寄存器,即CFI接口数据进行区分
--------------------------------------------------------------------------------
dalvin Post at 2009-4-23 11:38:44
To:yxj5421
几点疑问:
1 在Application_Initialize进行读id操作是不是晚了?是不是应该在INT_Config里setemi之前?
2 把flash id is save in DMA registers 是做何考虑?直接保存到不会被清零的internalram中可以吧

3 flash操作函数也需要根据不同的flash动态加载的

--------------------------------------------------------------------------------
yxj5421 Post at 2009-4-23 14:04:21
我的意思是把所有兼容的flash相关信息保存在一个静态数据结构里面,等读到板子上真正贴的flash的id后,和这个数据结构里面的id进行比较,如果相同,就把这个结构里面相应的flash的访问方式,分区等赋给相应的变量

在Application_Initialize进行读id操作不晚,

--------------------------------------------------------------------------------
hdhscuahong Post at 2009-4-26 23:42:11
是不是还要修改BOOTARM。S中的汇编代码?
--------------------------------------------------------------------------------
gogogoing Post at 2009-4-27 14:06:38
我们已经做了,目前常用的几种都ok
--------------------------------------------------------------------------------
paradise0207 Post at 2009-4-27 19:43:22
TO:gogogoing&&yxj5421,谢谢两位的指点,我尝试了修改代码,但还是没有兼容成功,两位能否提供相关的实例代码,鄙人不胜感激。
--------------------------------------------------------------------------------
BrightHan Post at 2009-6-18 23:48:16
最好不要做Flash的兼容,出现问题后,很难调试,会出现校准数据丢失等现象(造成无法进行呼叫等)。
--------------------------------------------------------------------------------
xiaohaoxiao1 Post at 2009-6-22 11:39:31
事实上,只要两个FLASH 的ID不一样,应该都可以做兼容。知识根据两个FLASH的BLOCK划分不一样(小BLOCK),可能会造成一些空间浪费。


 

================================================================================

MTK 08A 之前支持FDM5.0 手机U盘 功能,如何实现?
EMI timing 按照之前的情况,不需要更改。欲支持FDM5.0 则需要在文件
/custom/system/AOXUN25_GEMINI_BB/custom_MemoryDevice.h 中去掉 #define__NOR_FDM5__ 前的注释;修改 PARTITION_SECTORS 为手机U盘空间大小,注意,此值为10进制,单位为512Bytes 。
实现FDM5.0 需要再修改如下文件
/custom/system/AOXUN25_GEMINI_BB/custom_nor_large_disk.c
按照MTK注释部分修改

//FAT开始地址
#define FLASH_BASE_ADDRESS 0x01000000


//FAT 大小 单位Bytes
#define ALLOCATED_FAT_SPACE 0x00FE0000


//block大小 有小端block大小的话,最好不要选择
#define NOR_BLOCK_SIZE 0x20000


//bank的布局情况
static NORBankInfo BankInfo[] =
{
{0x200000,7},
{0x1E0000,1},
EndBankInfo
};


//这个值计算方法是:假设此值为A ,如果FAT大小(B)<=32M ,B=2^N (512Bytes), 那么
//A=2^[N/2] [] 表示取上限
// 如果FAT大小(B)> 32M 那么 A=2^(N-8)
#define NOR_TOTAL_LSMT 256


// 这是分配给系统使用的FAT,NVRAM就保存在此区域
#define NOR_SYSDRV_SECTORS 4096

到此,已经完成MTK 规定的步骤,应该没有问题了。但是,编译会报错的,我们还需要修改如下
/custom/system/AOXUN25_GEMINI_BB/custom_EMI.h
#define FLASH_BASE_ADDRESS 0x01000000
#define ALLOCATED_FAT_SPACE 0x00FE0000
此两个值修改成正确的配置,由于 EMI timing 没有修改, emigen生成的这两个值是不支持FDM5.0的,在此修改,使之编译通过,实际代码中,并没有使用此处的2个值。

原创粉丝点击