uboot-mediatek: update to U-Boot 2024.01 release
[openwrt/openwrt.git] / package / boot / uboot-mediatek / patches / 100-14-mtd-spi-nor-add-support-to-read-flash-unique-ID.patch
1 From c4172a95df8a57a66c70a8b9948b9600a01c4cb7 Mon Sep 17 00:00:00 2001
2 From: Weijie Gao <weijie.gao@mediatek.com>
3 Date: Mon, 25 Jul 2022 11:32:08 +0800
4 Subject: [PATCH 49/71] mtd: spi-nor: add support to read flash unique ID
5
6 This patch adds support to read unique ID from spi-nor flashes.
7
8 Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
9 ---
10 drivers/mtd/spi/spi-nor-core.c | 95 ++++++++++++++++++++++++++++++++++
11 include/linux/mtd/spi-nor.h | 2 +
12 2 files changed, 97 insertions(+)
13
14 --- a/drivers/mtd/spi/spi-nor-core.c
15 +++ b/drivers/mtd/spi/spi-nor-core.c
16 @@ -2854,6 +2854,100 @@ static int spi_nor_init_params(struct sp
17 return 0;
18 }
19
20 +static int spi_nor_read_uuid(struct spi_nor *nor)
21 +{
22 + u8 read_opcode, addr_width, read_dummy;
23 + loff_t addr;
24 + u8 *uuid;
25 + u8 uuid_len;
26 + int shift = 0;
27 + int ret;
28 + int i;
29 + struct spi_mem_op op;
30 +
31 + read_opcode = nor->read_opcode;
32 + addr_width = nor->addr_width;
33 + read_dummy = nor->read_dummy;
34 +
35 + switch (JEDEC_MFR(nor->info)) {
36 + case SNOR_MFR_WINBOND:
37 + uuid_len = 8;
38 + nor->read_opcode = 0x4b;
39 + nor->addr_width = 0;
40 + addr = 0x0;
41 + nor->read_dummy = 4;
42 + break;
43 + case SNOR_MFR_GIGADEVICE:
44 + uuid_len = 16;
45 + nor->read_opcode = 0x4b;
46 + nor->addr_width = 3;
47 + addr = 0x0;
48 + nor->read_dummy = 1;
49 + break;
50 + case CFI_MFR_ST:
51 + case SNOR_MFR_MICRON:
52 + uuid_len = 17;
53 + shift = 3;
54 + nor->read_opcode = 0x9f;
55 + nor->addr_width = 0;
56 + addr = 0x0;
57 + nor->read_dummy = 0;
58 + break;
59 + case SNOR_MFR_EON:
60 + uuid_len = 12;
61 + nor->read_opcode = 0x5a;
62 + nor->addr_width = 3;
63 + addr = 0x80;
64 + nor->read_dummy = 1;
65 + break;
66 + /* Automotive only in SPANSION's NOR devices */
67 + case SNOR_MFR_SPANSION:
68 + uuid_len = 11;
69 + shift = 386;
70 + nor->read_opcode = 0x9f;
71 + nor->addr_width = 0;
72 + addr = 0x0;
73 + nor->read_dummy = 0;
74 + break;
75 + default:
76 + printf("UUID not supported on this device.\n");
77 + return -ENOTSUPP;
78 + }
79 +
80 + uuid = kmalloc((uuid_len + shift) * sizeof(*uuid), GFP_KERNEL);
81 + if (!uuid) {
82 + ret = -ENOMEM;
83 + goto read_err;
84 + }
85 + memset(uuid, 0x0, (uuid_len + shift) * sizeof(*uuid));
86 +
87 + op = (struct spi_mem_op)SPI_MEM_OP(SPI_MEM_OP_CMD(nor->read_opcode, 0),
88 + SPI_MEM_OP_ADDR(nor->addr_width, addr, 0),
89 + SPI_MEM_OP_DUMMY(nor->read_dummy, 0),
90 + SPI_MEM_OP_DATA_IN(uuid_len+shift, NULL, 0));
91 +
92 + spi_nor_setup_op(nor, &op, nor->reg_proto);
93 +
94 + ret = spi_nor_read_write_reg(nor, &op, uuid);
95 + if (ret < 0) {
96 + dev_dbg(nor->dev, "error %d reading %x\n", ret, nor->read_opcode);
97 + goto read_err;
98 + }
99 +
100 + printf("UUID: 0x");
101 + for(i = 0; i<uuid_len; i++)
102 + printf("%02x", uuid[i+shift]);
103 + puts("\n");
104 +
105 +read_err:
106 + nor->read_opcode = read_opcode;
107 + nor->addr_width = addr_width;
108 + nor->read_dummy = read_dummy;
109 + kfree(uuid);
110 +
111 + return ret;
112 +}
113 +
114 static int spi_nor_hwcaps2cmd(u32 hwcaps, const int table[][2], size_t size)
115 {
116 size_t i;
117 @@ -4051,6 +4145,7 @@ int spi_nor_scan(struct spi_nor *nor)
118 nor->write = spi_nor_write_data;
119 nor->read_reg = spi_nor_read_reg;
120 nor->write_reg = spi_nor_write_reg;
121 + nor->read_uuid = spi_nor_read_uuid;
122
123 nor->setup = spi_nor_default_setup;
124
125 --- a/include/linux/mtd/spi-nor.h
126 +++ b/include/linux/mtd/spi-nor.h
127 @@ -29,6 +29,7 @@
128 #define SNOR_MFR_SPANSION CFI_MFR_AMD
129 #define SNOR_MFR_SST CFI_MFR_SST
130 #define SNOR_MFR_WINBOND 0xef /* Also used by some Spansion */
131 +#define SNOR_MFR_EON CFI_MFR_EON
132 #define SNOR_MFR_CYPRESS 0x34
133
134 /*
135 @@ -571,6 +572,7 @@ struct spi_nor {
136 void (*unprepare)(struct spi_nor *nor, enum spi_nor_ops ops);
137 int (*read_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len);
138 int (*write_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len);
139 + int (*read_uuid)(struct spi_nor *nor);
140
141 ssize_t (*read)(struct spi_nor *nor, loff_t from,
142 size_t len, u_char *read_buf);