手上的專案要把原本支援 Spansion 的 flash 換成 Giga Device 的 GD25Q64B, 因為這顆 SPI 的 Flash 並不在原本提供的 SDK 內,所以要自己來實作,好在先拜過谷哥大神後的確有前輩走過了,但卻並不盡然可以完全照抄.
找到這個範例僅有辨識出該顆 Flash ,並 return flash 的 sector 與 size number. 少了讀取(Read),寫入(Write)與清除(Erase)等這些對 flash 存取的動作(可能再他原本的用意裡面只需要去辨識他後續交由 Kernel 處理或者是當ROM來使用).於是再參考了這個 SDK 原本已支援 SPI Flash 的作法補上去(不少是原本該 SDK 本身 SPI Flash 的 API )並留下個紀錄.
PATH: u-boot/drivers/mtd/spi/gigadevice.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | /* * Gigadevice SPI flash driver * Copyright 2013, Samsung Electronics Co., Ltd. * Author: Banajit Goswami <banajit.g@samsung.com> * * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> #include <malloc.h> #include <spi_flash.h> #include "spi_flash_internal.h" +//GigaDevice specific commands+#define CMD_GD25X_BE 0xD8 /* Block Erase */ struct gigadevice_spi_flash_params { - uint16_t id; + u16 id;- uint16_t nr_blocks; + u16 nr_blocks;- const char *name; + u16 *name;}; +static int gigadevice_erase(struct spi_flash *flash, u32 offset, size_t len)+{+ return spi_flash_cmd_erase(flash, CMD_GD25X_BE, offset, len);+} static const struct gigadevice_spi_flash_params gigadevice_spi_flash_table[] = { { - .id = 0x6016, + .id = 0x6016,- .nr_blocks = 64, + .nr_blocks = 64,- .name = "GD25LQ", + .name = "GD25LQ", }, { - .id = 0x4017, + .id = 0x4017,- .nr_blocks = 128, + .nr_blocks = 128,- .name = "GD25Q64B", + .name = "GD25Q64B", }, }; struct spi_flash *spi_flash_probe_gigadevice(struct spi_slave *spi, u8 *idcode) { const struct gigadevice_spi_flash_params *params; struct spi_flash *flash; unsigned int i; for (i = 0; i < ARRAY_SIZE(gigadevice_spi_flash_table); i++) { params = &gigadevice_spi_flash_table[i]; if (params->id == ((idcode[1] << 8) | idcode[2])) break; } if (i == ARRAY_SIZE(gigadevice_spi_flash_table)) { debug("SF: Unsupported Gigadevice ID %02x%02x\n", idcode[1], idcode[2]); return NULL; } - flash = spi_flash_alloc_base(spi, params->name); + flash = malloc(sizeof(*flash)); if (!flash) { debug("SF: Failed to allocate memory\n"); return NULL; } + //Add For SPI flash access cmd+ flash->spi = spi;+ flash->name = params->name;+ flash->write = spi_flash_cmd_write_multi;+ flash->read = spi_flash_cmd_read_fast;+ flash->erase = gigadevice_erase; /* page_size */ flash->page_size = 256; /* sector_size = page_size * pages_per_sector */ flash->sector_size = flash->page_size * 16; /* size = sector_size * sector_per_block * number of blocks */ flash->size = flash->sector_size * 16 * params->nr_blocks; return flash; } |
實際上還需要對 u-boot/drivers/mtd/spi/Makefile, u-boot/drivers/mtd/spi/spi_flash.c, u-boot/drivers/mtd/spi/spi_flash_internal.h 等,這些file置入性的小修正,下方refer中則提供了patch file的參考,當然位置的號碼一定不會和這些free-open的一致,可以參考上下行的敘述來進行修補.
另外補一個笨點是我完成上面這些步驟後發現Build出來的 uboot image file size 卻沒有變動,更不用說放進板子當然沒有效果啦,追到後來是 /include/configs/* 裡面針對我手上的 target board 還是要把 option 打開拉~!
refer:
https://github.com/martinezjavier/u-boot/blob/master/drivers/mtd/spi/gigadevice.c
https://patchwork.ozlabs.org/patch/214801/