1
2
3
4
5
6
7
8
9
10
11#include <common.h>
12#include <dm.h>
13#include <errno.h>
14#include <malloc.h>
15#include <spi.h>
16#include <spi_flash.h>
17
18#include "sf_internal.h"
19
20
21
22
23
24
25
26static int spi_flash_probe_slave(struct spi_flash *flash)
27{
28 struct spi_slave *spi = flash->spi;
29 int ret;
30
31
32 if (!spi) {
33 printf("SF: Failed to set up slave\n");
34 return -ENODEV;
35 }
36
37
38 ret = spi_claim_bus(spi);
39 if (ret) {
40 debug("SF: Failed to claim SPI bus: %d\n", ret);
41 return ret;
42 }
43#if 0
44 if (spi->option == SF_DUAL_PARALLEL_FLASH)
45 spi->flags |= SPI_XFER_LOWER;
46
47 ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode));
48 if (ret) {
49 printf("SF: Failed to get idcodes\n");
50 goto err_read_id;
51 }
52
53#ifdef CONFIG_SPI_GENERIC
54 if (spi->option == SF_DUAL_PARALLEL_FLASH) {
55 spi->flags |= SPI_XFER_UPPER;
56 ret = spi_flash_cmd(spi, CMD_READ_ID, idcode_up,
57 sizeof(idcode_up));
58 if (ret) {
59 printf("SF: Failed to get idcodes\n");
60 goto err_read_id;
61 }
62 for (i = 0; i < sizeof(idcode); i++) {
63 if (idcode[i] != idcode_up[i]) {
64 printf("SF: Failed to get same idcodes\n");
65 goto err_read_id;
66 }
67 }
68 }
69#endif
70#ifdef DEBUG
71 printf("SF: Got idcodes\n");
72 print_buffer(0, idcode, 1, sizeof(idcode), 0);
73#endif
74
75 if (spi_flash_validate_params(spi, idcode, flash)) {
76
77#endif
78
79 ret = spi_flash_scan(flash);
80 if (ret)
81 goto err_read_id;
82
83#ifdef CONFIG_SPI_FLASH_MTD
84 ret = spi_flash_mtd_register(flash);
85#endif
86
87err_read_id:
88 spi_release_bus(spi);
89 return ret;
90}
91
92#ifndef CONFIG_DM_SPI_FLASH
93static struct spi_flash *spi_flash_probe_tail(struct spi_slave *bus)
94{
95 struct spi_flash *flash;
96
97
98 flash = calloc(1, sizeof(*flash));
99 if (!flash) {
100 debug("SF: Failed to allocate spi_flash\n");
101 return NULL;
102 }
103
104 flash->spi = bus;
105 if (spi_flash_probe_slave(flash)) {
106 spi_free_slave(bus);
107 free(flash);
108 return NULL;
109 }
110
111 return flash;
112}
113
114struct spi_flash *spi_flash_probe(unsigned int busnum, unsigned int cs,
115 unsigned int max_hz, unsigned int spi_mode)
116{
117 struct spi_slave *bus;
118
119 bus = spi_setup_slave(busnum, cs, max_hz, spi_mode);
120 if (!bus)
121 return NULL;
122 return spi_flash_probe_tail(bus);
123}
124
125#ifdef CONFIG_OF_SPI_FLASH
126struct spi_flash *spi_flash_probe_fdt(const void *blob, int slave_node,
127 int spi_node)
128{
129 struct spi_slave *bus;
130
131 bus = spi_setup_slave_fdt(blob, slave_node, spi_node);
132 if (!bus)
133 return NULL;
134 return spi_flash_probe_tail(bus);
135}
136#endif
137
138void spi_flash_free(struct spi_flash *flash)
139{
140#ifdef CONFIG_SPI_FLASH_MTD
141 spi_flash_mtd_unregister();
142#endif
143 spi_free_slave(flash->spi);
144 free(flash);
145}
146
147#else
148
149static int spi_flash_std_read(struct udevice *dev, u32 offset, size_t len,
150 void *buf)
151{
152 struct spi_flash *flash = dev_get_uclass_priv(dev);
153
154 return spi_flash_cmd_read_ops(flash, offset, len, buf);
155}
156
157static int spi_flash_std_write(struct udevice *dev, u32 offset, size_t len,
158 const void *buf)
159{
160 struct spi_flash *flash = dev_get_uclass_priv(dev);
161
162#if defined(CONFIG_SPI_FLASH_SST)
163 if (flash->flags & SNOR_F_SST_WR) {
164 if (flash->spi->mode & SPI_TX_BYTE)
165 return sst_write_bp(flash, offset, len, buf);
166 else
167 return sst_write_wp(flash, offset, len, buf);
168 }
169#endif
170
171 return spi_flash_cmd_write_ops(flash, offset, len, buf);
172}
173
174static int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len)
175{
176 struct spi_flash *flash = dev_get_uclass_priv(dev);
177
178 return spi_flash_cmd_erase_ops(flash, offset, len);
179}
180
181static int spi_flash_std_probe(struct udevice *dev)
182{
183 struct spi_slave *slave = dev_get_parent_priv(dev);
184 struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
185 struct spi_flash *flash;
186
187 flash = dev_get_uclass_priv(dev);
188 flash->dev = dev;
189 flash->spi = slave;
190 debug("%s: slave=%p, cs=%d\n", __func__, slave, plat->cs);
191 return spi_flash_probe_slave(flash);
192}
193
194static const struct dm_spi_flash_ops spi_flash_std_ops = {
195 .read = spi_flash_std_read,
196 .write = spi_flash_std_write,
197 .erase = spi_flash_std_erase,
198};
199
200static const struct udevice_id spi_flash_std_ids[] = {
201 { .compatible = "spi-flash" },
202 { }
203};
204
205U_BOOT_DRIVER(spi_flash_std) = {
206 .name = "spi_flash_std",
207 .id = UCLASS_SPI_FLASH,
208 .of_match = spi_flash_std_ids,
209 .probe = spi_flash_std_probe,
210 .priv_auto_alloc_size = sizeof(struct spi_flash),
211 .ops = &spi_flash_std_ops,
212};
213
214#endif
215