1. 程式人生 > >在全誌V3/V3s和索智S3/S3L上調試32MB NorFlash

在全誌V3/V3s和索智S3/S3L上調試32MB NorFlash

memcpy card 型號 min printk 工作 firmware des 對象

選取MX25L25635F作為調試對象,其他型號的NorFlash開發調試原理基本一致。為了使V3/V3s/S3/S3L識別32MB NorFlash並正常工作,主要針對以下三個部分進行開發和調試。下文將針對這三個部分的開發進行說明。

  1. U-Boot
  2. Linux Kernel
  3. System Configuration

第一部分,U-boot

原始的SDK包支持3線模式,但沒有支持4線模式,因此,必須在引導過程中加入4線模式。簡單解釋一下,3線模式是指NorFlash支持3x8位地址線,可以訪問的地址空間是16MB(2^24/1024/1024),4線模式支持4x8位地址線,可以訪問比16MB大的地址空間。找到源碼文件drivers/spinor/sunxi_spinor.c,增加4線模式的使能函數。

static void spinor_enter_4bytes_addr(int enable)
{
    int command = 0;
    if(spinor_4bytes_addr_mode == 1 && enable == 1)
        command = 0xB7;
    else if(spinor_4bytes_addr_mode == 1 && enable == 0)
        command = 0xE9;
else return ;
#ifdef CONFIG_ARCH_SUN8IW8P1 spic_config_dual_mode(
0, 0, 0, 1); #endif spic_rw(1, (void*)&command, 0, 0); return; }

需要註意的是,0xB7和0xE9不代碼所有32MB NorFlash的4線模式進入/退出命令,應從datasheet中獲取相應的命令值。接下來,找到spinor_init函數,回復flash size大於16MB的處理。

if(spi_size > 16*1024*1024/512)
{
    spinor_4bytes_addr_mode = 1;
    spinor_enter_4bytes_addr(ENABLE_4BYTES);
}

找到NorFlash讀寫函數__spinor_pp和__spinor_sector_normal_read,增加4線模式的數據讀寫代碼片段。

------------if(spinor_4bytes_addr_mode == 0)
{
    txnum = len+4;
    sdata[0]  =  SPINOR_PP;
    sdata[1]  = (page_addr >> 16) & 0xff;
    sdata[2]  = (page_addr >> 8 ) & 0xff;
    sdata[3]  =  page_addr        & 0xff;
    memcpy((void *)(sdata+4), buf, len);
}
else if(spinor_4bytes_addr_mode == 1)
{
    txnum = len+5;
    sdata[0]  =  SPINOR_PP;
    sdata[1]  = (page_addr >> 24) & 0xff;
    sdata[2]  = (page_addr >> 16) & 0xff;
    sdata[3]  = (page_addr >> 8 ) & 0xff;
    sdata[4]  =  page_addr        & 0xff;
    memcpy((void *)(sdata+5), buf, len);
}
------------if(spinor_4bytes_addr_mode == 0)
{
    txnum = 4;
    sdata[0]  =  SPINOR_READ;
    sdata[1]  = (page_addr >> 16) & 0xff;
    sdata[2]  = (page_addr >> 8 ) & 0xff;
    sdata[3]  =  page_addr        & 0xff;
}
else if(spinor_4bytes_addr_mode == 1)
{
    txnum = 5;
    sdata[0]  =  SPINOR_READ;
    sdata[1]  = (page_addr >> 24) & 0xff;
    sdata[2]  = (page_addr >> 16) & 0xff;
    sdata[3]  = (page_addr >> 8 ) & 0xff;
    sdata[4]  =  page_addr        & 0xff;
}

最後需要在spinor_datafinish_card函數最後退出4線模式,這樣做,刷機結束後,系統啟動時才可以正確得到boot0,否則會重復刷機。

第二部分,Linux Kernel

內核部分的修改比較簡單,在NorFlash設備驅動drivers/mtd/devices/m25p80.c中加入針對MX25L25635F這款32MB NorFlash的支持,如下:

--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -724,7 +724,7 @@ static const struct spi_device_id m25p_ids[] = {
        { "mx25l1606e",  INFO(0xc22015, 0, 64 * 1024,  32, SECT_4K) },
        { "mx25l3205d",  INFO(0xc22016, 0, 64 * 1024,  64, 0) },
        { "mx25l6405d",  INFO(0xc22017, 0, 64 * 1024, 128, 0) },
-       { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
+       { "mx25l12805f", INFO(0xc22018, 0, 64 * 1024, 512, 0) },
        { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
        { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
        { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
@@ -1136,6 +1136,22 @@ static int __devexit m25p_remove(struct spi_device *spi)
 }
 
 
+static int  m25p_shutdown(struct spi_device *spi)
+{
+       struct m25p     *flash = dev_get_drvdata(&spi->dev);
+       const struct spi_device_id      *id = spi_get_device_id(spi);
+       struct flash_info               *info;
+    printk("m25p: spinor shutdown\n");
+
+       if(flash->addr_width == 4)
+       {
+               info = (void *)id->driver_data;
+               set_4byte(flash, info->jedec_id, 0);
+       }
+       return 0;
+}
+
+
 static struct spi_driver m25p80_driver = {
        .driver = {
                .name   = "m25p80",
@@ -1144,6 +1160,7 @@ static struct spi_driver m25p80_driver = {
        .id_table       = m25p_ids,
        .probe  = m25p_probe,
        .remove = __devexit_p(m25p_remove),
+       .shutdown = m25p_shutdown,
 
        /* REVISIT: many of these chips have deep power-down modes, which
         * should clearly be entered on suspend() to minimize power use.

第三部分,System Configuration

V3/V3s/S3/S3L這4個平臺的SDK裏面,U-Boot和Kernel都會調用sys_config.fex的Nor配置,需要將Nor Flash的大小修改成32,意思是32MB。

@@ -301,7 +298,8 @@ max_speed_hz  = 50000000
 bus_num       = 0
 chip_select   = 0
 mode          = 0
-sflash_size             = 16
+sflash_size   = 32

完成上述三個環節的修改以後,依次編譯U-Boot,Linux Kernel,最後打包Firmware,燒錄到設備。

在全誌V3/V3s和索智S3/S3L上調試32MB NorFlash