Implement GigaDevice SPI Flash for u-boot support

手上的專案要把原本支援 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

/u-boot/blob/master/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/

Facebook Comments
Scottj Written by:

史考特 喜歡3C 愛拍照