blob: de221e91c8e34d3ec64e8cc94b88f36a6a2ec738 [file] [log] [blame]
Mauro Carvalho Chehabbaa293e2019-06-27 15:39:22 -03001.. SPDX-License-Identifier: GPL-2.0
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -03002
3===============
4NVMEM Subsystem
5===============
6
7 Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +01008
9This document explains the NVMEM Framework along with the APIs provided,
10and how to use it.
11
121. Introduction
13===============
14*NVMEM* is the abbreviation for Non Volatile Memory layer. It is used to
15retrieve configuration of SOC or Device specific data from non volatile
16memories like eeprom, efuses and so on.
17
18Before this framework existed, NVMEM drivers like eeprom were stored in
19drivers/misc, where they all had to duplicate pretty much the same code to
20register a sysfs file, allow in-kernel users to access the content of the
21devices they were driving, etc.
22
23This was also a problem as far as other in-kernel users were involved, since
24the solutions used were pretty much different from one driver to another, there
25was a rather big abstraction leak.
26
27This framework aims at solve these problems. It also introduces DT
28representation for consumer devices to go get the data they require (MAC
Sean Anderson673d2cc2022-02-20 15:15:24 +000029Addresses, SoC/Revision ID, part numbers, and so on) from the NVMEMs.
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +010030
31NVMEM Providers
32+++++++++++++++
33
34NVMEM provider refers to an entity that implements methods to initialize, read
35and write the non-volatile memory.
36
372. Registering/Unregistering the NVMEM provider
38===============================================
39
40A NVMEM provider can register with NVMEM core by supplying relevant
41nvmem configuration to nvmem_register(), on success core would return a valid
42nvmem_device pointer.
43
44nvmem_unregister(nvmem) is used to unregister a previously registered provider.
45
Sean Anderson671aa5a2022-02-20 15:15:25 +000046For example, a simple nvram case::
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +010047
Sean Anderson671aa5a2022-02-20 15:15:25 +000048 static int brcm_nvram_probe(struct platform_device *pdev)
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030049 {
Sean Anderson671aa5a2022-02-20 15:15:25 +000050 struct nvmem_config config = {
51 .name = "brcm-nvram",
52 .reg_read = brcm_nvram_read,
53 };
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +010054 ...
Sean Anderson671aa5a2022-02-20 15:15:25 +000055 config.dev = &pdev->dev;
56 config.priv = priv;
57 config.size = resource_size(res);
58
59 devm_nvmem_register(&config);
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030060 }
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +010061
Bartosz Golaszewski4903d192018-09-21 06:40:18 -070062Users of board files can define and register nvmem cells using the
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030063nvmem_cell_table struct::
Bartosz Golaszewski4903d192018-09-21 06:40:18 -070064
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030065 static struct nvmem_cell_info foo_nvmem_cells[] = {
Bartosz Golaszewski4903d192018-09-21 06:40:18 -070066 {
67 .name = "macaddr",
68 .offset = 0x7f00,
69 .bytes = ETH_ALEN,
70 }
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030071 };
Bartosz Golaszewski4903d192018-09-21 06:40:18 -070072
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030073 static struct nvmem_cell_table foo_nvmem_cell_table = {
Bartosz Golaszewski4903d192018-09-21 06:40:18 -070074 .nvmem_name = "i2c-eeprom",
75 .cells = foo_nvmem_cells,
76 .ncells = ARRAY_SIZE(foo_nvmem_cells),
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030077 };
Bartosz Golaszewski4903d192018-09-21 06:40:18 -070078
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030079 nvmem_add_cell_table(&foo_nvmem_cell_table);
Bartosz Golaszewski4903d192018-09-21 06:40:18 -070080
81Additionally it is possible to create nvmem cell lookup entries and register
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030082them with the nvmem framework from machine code as shown in the example below::
Bartosz Golaszewski4903d192018-09-21 06:40:18 -070083
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030084 static struct nvmem_cell_lookup foo_nvmem_lookup = {
Bartosz Golaszewski4903d192018-09-21 06:40:18 -070085 .nvmem_name = "i2c-eeprom",
86 .cell_name = "macaddr",
87 .dev_id = "foo_mac.0",
88 .con_id = "mac-address",
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030089 };
Bartosz Golaszewski4903d192018-09-21 06:40:18 -070090
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -030091 nvmem_add_cell_lookups(&foo_nvmem_lookup, 1);
Bartosz Golaszewski4903d192018-09-21 06:40:18 -070092
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +010093NVMEM Consumers
94+++++++++++++++
95
96NVMEM consumers are the entities which make use of the NVMEM provider to
97read from and to NVMEM.
98
993. NVMEM cell based consumer APIs
100=================================
101
102NVMEM cells are the data entries/fields in the NVMEM.
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300103The NVMEM framework provides 3 APIs to read/write NVMEM cells::
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100104
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300105 struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *name);
106 struct nvmem_cell *devm_nvmem_cell_get(struct device *dev, const char *name);
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100107
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300108 void nvmem_cell_put(struct nvmem_cell *cell);
109 void devm_nvmem_cell_put(struct device *dev, struct nvmem_cell *cell);
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100110
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300111 void *nvmem_cell_read(struct nvmem_cell *cell, ssize_t *len);
112 int nvmem_cell_write(struct nvmem_cell *cell, void *buf, ssize_t len);
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100113
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300114`*nvmem_cell_get()` apis will get a reference to nvmem cell for a given id,
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100115and nvmem_cell_read/write() can then read or write to the cell.
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300116Once the usage of the cell is finished the consumer should call
117`*nvmem_cell_put()` to free all the allocation memory for the cell.
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100118
1194. Direct NVMEM device based consumer APIs
120==========================================
121
122In some instances it is necessary to directly read/write the NVMEM.
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300123To facilitate such consumers NVMEM framework provides below apis::
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100124
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300125 struct nvmem_device *nvmem_device_get(struct device *dev, const char *name);
126 struct nvmem_device *devm_nvmem_device_get(struct device *dev,
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100127 const char *name);
Thomas Bogendoerfer8c2a2b82019-10-03 11:52:29 +0200128 struct nvmem_device *nvmem_device_find(void *data,
129 int (*match)(struct device *dev, const void *data));
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300130 void nvmem_device_put(struct nvmem_device *nvmem);
131 int nvmem_device_read(struct nvmem_device *nvmem, unsigned int offset,
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100132 size_t bytes, void *buf);
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300133 int nvmem_device_write(struct nvmem_device *nvmem, unsigned int offset,
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100134 size_t bytes, void *buf);
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300135 int nvmem_device_cell_read(struct nvmem_device *nvmem,
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100136 struct nvmem_cell_info *info, void *buf);
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300137 int nvmem_device_cell_write(struct nvmem_device *nvmem,
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100138 struct nvmem_cell_info *info, void *buf);
139
140Before the consumers can read/write NVMEM directly, it should get hold
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300141of nvmem_controller from one of the `*nvmem_device_get()` api.
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100142
143The difference between these apis and cell based apis is that these apis always
144take nvmem_device as parameter.
145
1465. Releasing a reference to the NVMEM
147=====================================
148
Narenbe629b42017-08-16 15:45:57 -0700149When a consumer no longer needs the NVMEM, it has to release the reference
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100150to the NVMEM it has obtained using the APIs mentioned in the above section.
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300151The NVMEM framework provides 2 APIs to release a reference to the NVMEM::
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100152
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300153 void nvmem_cell_put(struct nvmem_cell *cell);
154 void devm_nvmem_cell_put(struct device *dev, struct nvmem_cell *cell);
155 void nvmem_device_put(struct nvmem_device *nvmem);
156 void devm_nvmem_device_put(struct device *dev, struct nvmem_device *nvmem);
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100157
158Both these APIs are used to release a reference to the NVMEM and
159devm_nvmem_cell_put and devm_nvmem_device_put destroys the devres associated
160with this NVMEM.
161
162Userspace
163+++++++++
164
1656. Userspace binary interface
166==============================
167
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300168Userspace can read/write the raw NVMEM file located at::
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100169
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300170 /sys/bus/nvmem/devices/*/nvmem
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100171
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300172ex::
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100173
Mauro Carvalho Chehaba2782952019-04-15 19:25:27 -0300174 hexdump /sys/bus/nvmem/devices/qfprom0/nvmem
175
176 0000000 0000 0000 0000 0000 0000 0000 0000 0000
177 *
178 00000a0 db10 2240 0000 e000 0c00 0c00 0000 0c00
179 0000000 0000 0000 0000 0000 0000 0000 0000 0000
180 ...
181 *
182 0001000
Srinivas Kandagatla354ebb52015-07-27 12:14:14 +0100183
1847. DeviceTree Binding
185=====================
186
187See Documentation/devicetree/bindings/nvmem/nvmem.txt
Michael Walle266570f2023-04-04 18:21:21 +0100188
1898. NVMEM layouts
190================
191
192NVMEM layouts are yet another mechanism to create cells. With the device
193tree binding it is possible to specify simple cells by using an offset
194and a length. Sometimes, the cells doesn't have a static offset, but
195the content is still well defined, e.g. tag-length-values. In this case,
196the NVMEM device content has to be first parsed and the cells need to
197be added accordingly. Layouts let you read the content of the NVMEM device
198and let you add cells dynamically.
199
200Another use case for layouts is the post processing of cells. With layouts,
201it is possible to associate a custom post processing hook to a cell. It
202even possible to add this hook to cells not created by the layout itself.