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