Skip to content

Commit 6762966

Browse files
committed
Merge tag 'spi-nor/for-6.8' into mtd/next
SPI NOR comes with die erase support for multi die flashes, with new octal protocols (1-1-8 and 1-8-8) parsed from SFDP and with an updated documentation about what the contributors shall consider when proposing flash additions or updates. Michael Walle stepped out from the reviewer role to maintainer.
2 parents 828f6df + 3c0e1df commit 6762966

File tree

14 files changed

+435
-184
lines changed

14 files changed

+435
-184
lines changed

Documentation/ABI/testing/sysfs-bus-spi-devices-spi-nor

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ KernelVersion: 5.14
2525
Contact: linux-mtd@lists.infradead.org
2626
Description: (RO) Part name of the SPI NOR flash.
2727

28+
The attribute is optional. User space should not rely on
29+
it to be present or even correct. Instead, user space
30+
should read the jedec_id attribute.
2831

2932
What: /sys/bus/spi/devices/.../spi-nor/sfdp
3033
Date: April 2021

Documentation/driver-api/mtd/spi-nor.rst

Lines changed: 201 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -2,64 +2,204 @@
22
SPI NOR framework
33
=================
44

5-
Part I - Why do we need this framework?
6-
---------------------------------------
7-
8-
SPI bus controllers (drivers/spi/) only deal with streams of bytes; the bus
9-
controller operates agnostic of the specific device attached. However, some
10-
controllers (such as Freescale's QuadSPI controller) cannot easily handle
11-
arbitrary streams of bytes, but rather are designed specifically for SPI NOR.
12-
13-
In particular, Freescale's QuadSPI controller must know the NOR commands to
14-
find the right LUT sequence. Unfortunately, the SPI subsystem has no notion of
15-
opcodes, addresses, or data payloads; a SPI controller simply knows to send or
16-
receive bytes (Tx and Rx). Therefore, we must define a new layering scheme under
17-
which the controller driver is aware of the opcodes, addressing, and other
18-
details of the SPI NOR protocol.
19-
20-
Part II - How does the framework work?
21-
--------------------------------------
22-
23-
This framework just adds a new layer between the MTD and the SPI bus driver.
24-
With this new layer, the SPI NOR controller driver does not depend on the
25-
m25p80 code anymore.
26-
27-
Before this framework, the layer is like::
28-
29-
MTD
30-
------------------------
31-
m25p80
32-
------------------------
33-
SPI bus driver
34-
------------------------
35-
SPI NOR chip
36-
37-
After this framework, the layer is like::
38-
39-
MTD
40-
------------------------
41-
SPI NOR framework
42-
------------------------
43-
m25p80
44-
------------------------
45-
SPI bus driver
46-
------------------------
47-
SPI NOR chip
48-
49-
With the SPI NOR controller driver (Freescale QuadSPI), it looks like::
50-
51-
MTD
52-
------------------------
53-
SPI NOR framework
54-
------------------------
55-
fsl-quadSPI
56-
------------------------
57-
SPI NOR chip
58-
59-
Part III - How can drivers use the framework?
60-
---------------------------------------------
61-
62-
The main API is spi_nor_scan(). Before you call the hook, a driver should
63-
initialize the necessary fields for spi_nor{}. Please see
64-
drivers/mtd/spi-nor/spi-nor.c for detail. Please also refer to spi-fsl-qspi.c
65-
when you want to write a new driver for a SPI NOR controller.
5+
How to propose a new flash addition
6+
-----------------------------------
7+
8+
Most SPI NOR flashes comply with the JEDEC JESD216
9+
Serial Flash Discoverable Parameter (SFDP) standard. SFDP describes
10+
the functional and feature capabilities of serial flash devices in a
11+
standard set of internal read-only parameter tables.
12+
13+
The SPI NOR driver queries the SFDP tables in order to determine the
14+
flash's parameters and settings. If the flash defines the SFDP tables
15+
it's likely that you won't need a flash entry at all, and instead
16+
rely on the generic flash driver which probes the flash solely based
17+
on its SFDP data. All one has to do is to specify the "jedec,spi-nor"
18+
compatible in the device tree.
19+
20+
There are cases however where you need to define an explicit flash
21+
entry. This typically happens when the flash has settings or support
22+
that is not covered by the SFDP tables (e.g. Block Protection), or
23+
when the flash contains mangled SFDP data. If the later, one needs
24+
to implement the ``spi_nor_fixups`` hooks in order to amend the SFDP
25+
parameters with the correct values.
26+
27+
Minimum testing requirements
28+
-----------------------------
29+
30+
Do all the tests from below and paste them in the commit's comments
31+
section, after the ``---`` marker.
32+
33+
1) Specify the controller that you used to test the flash and specify
34+
the frequency at which the flash was operated, e.g.::
35+
36+
This flash is populated on the X board and was tested at Y
37+
frequency using the Z (put compatible) SPI controller.
38+
39+
2) Dump the sysfs entries and print the md5/sha1/sha256 SFDP checksum::
40+
41+
root@1:~# cat /sys/bus/spi/devices/spi0.0/spi-nor/partname
42+
sst26vf064b
43+
root@1:~# cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
44+
bf2643
45+
root@1:~# cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
46+
sst
47+
root@1:~# xxd -p /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
48+
53464450060102ff00060110300000ff81000106000100ffbf0001180002
49+
0001fffffffffffffffffffffffffffffffffd20f1ffffffff0344eb086b
50+
083b80bbfeffffffffff00ffffff440b0c200dd80fd810d820914824806f
51+
1d81ed0f773830b030b0f7ffffff29c25cfff030c080ffffffffffffffff
52+
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
53+
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
54+
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
55+
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
56+
ffffffffffffffffffffffffffffffffff0004fff37f0000f57f0000f9ff
57+
7d00f57f0000f37f0000ffffffffffffffffffffffffffffffffffffffff
58+
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
59+
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
60+
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
61+
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
62+
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
63+
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
64+
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
65+
ffffbf2643ffb95ffdff30f260f332ff0a122346ff0f19320f1919ffffff
66+
ffffffff00669938ff05013506040232b03072428de89888a585c09faf5a
67+
ffff06ec060c0003080bffffffffff07ffff0202ff060300fdfd040700fc
68+
0300fefe0202070e
69+
root@1:~# sha256sum /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
70+
428f34d0461876f189ac97f93e68a05fa6428c6650b3b7baf736a921e5898ed1 /sys/bus/spi/devices/spi0.0/spi-nor/sfdp
71+
72+
Please dump the SFDP tables using ``xxd -p``. It enables us to do
73+
the reverse operation and convert the hexdump to binary with
74+
``xxd -rp``. Dumping the SFDP data with ``hexdump -Cv`` is accepted,
75+
but less desirable.
76+
77+
3) Dump debugfs data::
78+
79+
root@1:~# cat /sys/kernel/debug/spi-nor/spi0.0/capabilities
80+
Supported read modes by the flash
81+
1S-1S-1S
82+
opcode 0x03
83+
mode cycles 0
84+
dummy cycles 0
85+
1S-1S-1S (fast read)
86+
opcode 0x0b
87+
mode cycles 0
88+
dummy cycles 8
89+
1S-1S-2S
90+
opcode 0x3b
91+
mode cycles 0
92+
dummy cycles 8
93+
1S-2S-2S
94+
opcode 0xbb
95+
mode cycles 4
96+
dummy cycles 0
97+
1S-1S-4S
98+
opcode 0x6b
99+
mode cycles 0
100+
dummy cycles 8
101+
1S-4S-4S
102+
opcode 0xeb
103+
mode cycles 2
104+
dummy cycles 4
105+
4S-4S-4S
106+
opcode 0x0b
107+
mode cycles 2
108+
dummy cycles 4
109+
110+
Supported page program modes by the flash
111+
1S-1S-1S
112+
opcode 0x02
113+
114+
root@1:~# cat /sys/kernel/debug/spi-nor/spi0.0/params
115+
name sst26vf064b
116+
id bf 26 43 bf 26 43
117+
size 8.00 MiB
118+
write size 1
119+
page size 256
120+
address nbytes 3
121+
flags HAS_LOCK | HAS_16BIT_SR | SOFT_RESET | SWP_IS_VOLATILE
122+
123+
opcodes
124+
read 0xeb
125+
dummy cycles 6
126+
erase 0x20
127+
program 0x02
128+
8D extension none
129+
130+
protocols
131+
read 1S-4S-4S
132+
write 1S-1S-1S
133+
register 1S-1S-1S
134+
135+
erase commands
136+
20 (4.00 KiB) [0]
137+
d8 (8.00 KiB) [1]
138+
d8 (32.0 KiB) [2]
139+
d8 (64.0 KiB) [3]
140+
c7 (8.00 MiB)
141+
142+
sector map
143+
region (in hex) | erase mask | flags
144+
------------------+------------+----------
145+
00000000-00007fff | [01 ] |
146+
00008000-0000ffff | [0 2 ] |
147+
00010000-007effff | [0 3] |
148+
007f0000-007f7fff | [0 2 ] |
149+
007f8000-007fffff | [01 ] |
150+
151+
4) Use `mtd-utils <https://git.infradead.org/mtd-utils.git>`__
152+
and verify that erase, read and page program operations work fine::
153+
154+
root@1:~# dd if=/dev/urandom of=./spi_test bs=1M count=2
155+
2+0 records in
156+
2+0 records out
157+
2097152 bytes (2.1 MB, 2.0 MiB) copied, 0.848566 s, 2.5 MB/s
158+
159+
root@1:~# mtd_debug erase /dev/mtd0 0 2097152
160+
Erased 2097152 bytes from address 0x00000000 in flash
161+
162+
root@1:~# mtd_debug read /dev/mtd0 0 2097152 spi_read
163+
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
164+
165+
root@1:~# hexdump spi_read
166+
0000000 ffff ffff ffff ffff ffff ffff ffff ffff
167+
*
168+
0200000
169+
170+
root@1:~# sha256sum spi_read
171+
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
172+
173+
root@1:~# mtd_debug write /dev/mtd0 0 2097152 spi_test
174+
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
175+
176+
root@1:~# mtd_debug read /dev/mtd0 0 2097152 spi_read
177+
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
178+
179+
root@1:~# sha256sum spi*
180+
c444216a6ba2a4a66cccd60a0dd062bce4b865dd52b200ef5e21838c4b899ac8 spi_read
181+
c444216a6ba2a4a66cccd60a0dd062bce4b865dd52b200ef5e21838c4b899ac8 spi_test
182+
183+
If the flash comes erased by default and the previous erase was ignored,
184+
we won't catch it, thus test the erase again::
185+
186+
root@1:~# mtd_debug erase /dev/mtd0 0 2097152
187+
Erased 2097152 bytes from address 0x00000000 in flash
188+
189+
root@1:~# mtd_debug read /dev/mtd0 0 2097152 spi_read
190+
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
191+
192+
root@1:~# sha256sum spi*
193+
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
194+
c444216a6ba2a4a66cccd60a0dd062bce4b865dd52b200ef5e21838c4b899ac8 spi_test
195+
196+
Dump some other relevant data::
197+
198+
root@1:~# mtd_debug info /dev/mtd0
199+
mtd.type = MTD_NORFLASH
200+
mtd.flags = MTD_CAP_NORFLASH
201+
mtd.size = 8388608 (8M)
202+
mtd.erasesize = 4096 (4K)
203+
mtd.writesize = 1
204+
mtd.oobsize = 0
205+
regions = 0

MAINTAINERS

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9045,7 +9045,7 @@ F: drivers/gpio/gpio-mockup.c
90459045
F: tools/testing/selftests/gpio/
90469046

90479047
GPIO REGMAP
9048-
M: Michael Walle <michael@walle.cc>
9048+
M: Michael Walle <mwalle@kernel.org>
90499049
S: Maintained
90509050
F: drivers/gpio/gpio-regmap.c
90519051
F: include/linux/gpio/regmap.h
@@ -19901,7 +19901,7 @@ W: http://www.winischhofer.at/linuxsisusbvga.shtml
1990119901
F: drivers/usb/misc/sisusbvga/
1990219902

1990319903
SL28 CPLD MFD DRIVER
19904-
M: Michael Walle <michael@walle.cc>
19904+
M: Michael Walle <mwalle@kernel.org>
1990519905
S: Maintained
1990619906
F: Documentation/devicetree/bindings/gpio/kontron,sl28cpld-gpio.yaml
1990719907
F: Documentation/devicetree/bindings/hwmon/kontron,sl28cpld-hwmon.yaml
@@ -19916,7 +19916,7 @@ F: drivers/pwm/pwm-sl28cpld.c
1991619916
F: drivers/watchdog/sl28cpld_wdt.c
1991719917

1991819918
SL28 VPD NVMEM LAYOUT DRIVER
19919-
M: Michael Walle <michael@walle.cc>
19919+
M: Michael Walle <mwalle@kernel.org>
1992019920
S: Maintained
1992119921
F: Documentation/devicetree/bindings/nvmem/layouts/kontron,sl28-vpd.yaml
1992219922
F: drivers/nvmem/layouts/sl28vpd.c
@@ -20426,7 +20426,7 @@ F: drivers/pinctrl/spear/
2042620426
SPI NOR SUBSYSTEM
2042720427
M: Tudor Ambarus <tudor.ambarus@linaro.org>
2042820428
M: Pratyush Yadav <pratyush@kernel.org>
20429-
R: Michael Walle <michael@walle.cc>
20429+
M: Michael Walle <mwalle@kernel.org>
2043020430
L: linux-mtd@lists.infradead.org
2043120431
S: Maintained
2043220432
W: http://www.linux-mtd.infradead.org/

drivers/mtd/spi-nor/atmel.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616
* is to unlock the whole flash array on startup. Therefore, we have to support
1717
* exactly this operation.
1818
*/
19-
static int at25fs_nor_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
19+
static int at25fs_nor_lock(struct spi_nor *nor, loff_t ofs, u64 len)
2020
{
2121
return -EOPNOTSUPP;
2222
}
2323

24-
static int at25fs_nor_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
24+
static int at25fs_nor_unlock(struct spi_nor *nor, loff_t ofs, u64 len)
2525
{
2626
int ret;
2727

@@ -37,7 +37,7 @@ static int at25fs_nor_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
3737
return ret;
3838
}
3939

40-
static int at25fs_nor_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len)
40+
static int at25fs_nor_is_locked(struct spi_nor *nor, loff_t ofs, u64 len)
4141
{
4242
return -EOPNOTSUPP;
4343
}
@@ -69,7 +69,7 @@ static const struct spi_nor_fixups at25fs_nor_fixups = {
6969
* Return: 0 on success, -error otherwise.
7070
*/
7171
static int atmel_nor_set_global_protection(struct spi_nor *nor, loff_t ofs,
72-
uint64_t len, bool is_protect)
72+
u64 len, bool is_protect)
7373
{
7474
int ret;
7575
u8 sr;
@@ -118,20 +118,18 @@ static int atmel_nor_set_global_protection(struct spi_nor *nor, loff_t ofs,
118118
return spi_nor_write_sr(nor, nor->bouncebuf, 1);
119119
}
120120

121-
static int atmel_nor_global_protect(struct spi_nor *nor, loff_t ofs,
122-
uint64_t len)
121+
static int atmel_nor_global_protect(struct spi_nor *nor, loff_t ofs, u64 len)
123122
{
124123
return atmel_nor_set_global_protection(nor, ofs, len, true);
125124
}
126125

127-
static int atmel_nor_global_unprotect(struct spi_nor *nor, loff_t ofs,
128-
uint64_t len)
126+
static int atmel_nor_global_unprotect(struct spi_nor *nor, loff_t ofs, u64 len)
129127
{
130128
return atmel_nor_set_global_protection(nor, ofs, len, false);
131129
}
132130

133131
static int atmel_nor_is_global_protected(struct spi_nor *nor, loff_t ofs,
134-
uint64_t len)
132+
u64 len)
135133
{
136134
int ret;
137135

0 commit comments

Comments
 (0)