Merge tag 'thermal-v5.11-2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / drivers / mtd / devices / bcm47xxsflash.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 #include <linux/kernel.h>
3 #include <linux/module.h>
4 #include <linux/slab.h>
5 #include <linux/delay.h>
6 #include <linux/ioport.h>
7 #include <linux/mtd/mtd.h>
8 #include <linux/platform_device.h>
9 #include <linux/bcma/bcma.h>
10
11 #include "bcm47xxsflash.h"
12
13 MODULE_LICENSE("GPL");
14 MODULE_DESCRIPTION("Serial flash driver for BCMA bus");
15
16 static const char * const probes[] = { "bcm47xxpart", NULL };
17
18 /**************************************************
19  * Various helpers
20  **************************************************/
21
22 static void bcm47xxsflash_cmd(struct bcm47xxsflash *b47s, u32 opcode)
23 {
24         int i;
25
26         b47s->cc_write(b47s, BCMA_CC_FLASHCTL, BCMA_CC_FLASHCTL_START | opcode);
27         for (i = 0; i < 1000; i++) {
28                 if (!(b47s->cc_read(b47s, BCMA_CC_FLASHCTL) &
29                       BCMA_CC_FLASHCTL_BUSY))
30                         return;
31                 cpu_relax();
32         }
33         pr_err("Control command failed (timeout)!\n");
34 }
35
36 static int bcm47xxsflash_poll(struct bcm47xxsflash *b47s, int timeout)
37 {
38         unsigned long deadline = jiffies + timeout;
39
40         do {
41                 switch (b47s->type) {
42                 case BCM47XXSFLASH_TYPE_ST:
43                         bcm47xxsflash_cmd(b47s, OPCODE_ST_RDSR);
44                         if (!(b47s->cc_read(b47s, BCMA_CC_FLASHDATA) &
45                               SR_ST_WIP))
46                                 return 0;
47                         break;
48                 case BCM47XXSFLASH_TYPE_ATMEL:
49                         bcm47xxsflash_cmd(b47s, OPCODE_AT_STATUS);
50                         if (b47s->cc_read(b47s, BCMA_CC_FLASHDATA) &
51                             SR_AT_READY)
52                                 return 0;
53                         break;
54                 }
55
56                 cpu_relax();
57                 udelay(1);
58         } while (!time_after_eq(jiffies, deadline));
59
60         pr_err("Timeout waiting for flash to be ready!\n");
61
62         return -EBUSY;
63 }
64
65 /**************************************************
66  * MTD ops
67  **************************************************/
68
69 static int bcm47xxsflash_erase(struct mtd_info *mtd, struct erase_info *erase)
70 {
71         struct bcm47xxsflash *b47s = mtd->priv;
72
73         switch (b47s->type) {
74         case BCM47XXSFLASH_TYPE_ST:
75                 bcm47xxsflash_cmd(b47s, OPCODE_ST_WREN);
76                 b47s->cc_write(b47s, BCMA_CC_FLASHADDR, erase->addr);
77                 /* Newer flashes have "sub-sectors" which can be erased
78                  * independently with a new command: ST_SSE. The ST_SE command
79                  * erases 64KB just as before.
80                  */
81                 if (b47s->blocksize < (64 * 1024))
82                         bcm47xxsflash_cmd(b47s, OPCODE_ST_SSE);
83                 else
84                         bcm47xxsflash_cmd(b47s, OPCODE_ST_SE);
85                 break;
86         case BCM47XXSFLASH_TYPE_ATMEL:
87                 b47s->cc_write(b47s, BCMA_CC_FLASHADDR, erase->addr << 1);
88                 bcm47xxsflash_cmd(b47s, OPCODE_AT_PAGE_ERASE);
89                 break;
90         }
91
92         return bcm47xxsflash_poll(b47s, HZ);
93 }
94
95 static int bcm47xxsflash_read(struct mtd_info *mtd, loff_t from, size_t len,
96                               size_t *retlen, u_char *buf)
97 {
98         struct bcm47xxsflash *b47s = mtd->priv;
99         size_t orig_len = len;
100
101         /* Check address range */
102         if ((from + len) > mtd->size)
103                 return -EINVAL;
104
105         /* Read as much as possible using fast MMIO window */
106         if (from < BCM47XXSFLASH_WINDOW_SZ) {
107                 size_t memcpy_len;
108
109                 memcpy_len = min(len, (size_t)(BCM47XXSFLASH_WINDOW_SZ - from));
110                 memcpy_fromio(buf, b47s->window + from, memcpy_len);
111                 from += memcpy_len;
112                 len -= memcpy_len;
113                 buf += memcpy_len;
114         }
115
116         /* Use indirect access for content out of the window */
117         for (; len; len--) {
118                 b47s->cc_write(b47s, BCMA_CC_FLASHADDR, from++);
119                 bcm47xxsflash_cmd(b47s, OPCODE_ST_READ4B);
120                 *buf++ = b47s->cc_read(b47s, BCMA_CC_FLASHDATA);
121         }
122
123         *retlen = orig_len;
124
125         return orig_len;
126 }
127
128 static int bcm47xxsflash_write_st(struct mtd_info *mtd, u32 offset, size_t len,
129                                   const u_char *buf)
130 {
131         struct bcm47xxsflash *b47s = mtd->priv;
132         int written = 0;
133
134         /* Enable writes */
135         bcm47xxsflash_cmd(b47s, OPCODE_ST_WREN);
136
137         /* Write first byte */
138         b47s->cc_write(b47s, BCMA_CC_FLASHADDR, offset);
139         b47s->cc_write(b47s, BCMA_CC_FLASHDATA, *buf++);
140
141         /* Program page */
142         if (b47s->bcma_cc->core->id.rev < 20) {
143                 bcm47xxsflash_cmd(b47s, OPCODE_ST_PP);
144                 return 1; /* 1B written */
145         }
146
147         /* Program page and set CSA (on newer chips we can continue writing) */
148         bcm47xxsflash_cmd(b47s, OPCODE_ST_CSA | OPCODE_ST_PP);
149         offset++;
150         len--;
151         written++;
152
153         while (len > 0) {
154                 /* Page boundary, another function call is needed */
155                 if ((offset & 0xFF) == 0)
156                         break;
157
158                 bcm47xxsflash_cmd(b47s, OPCODE_ST_CSA | *buf++);
159                 offset++;
160                 len--;
161                 written++;
162         }
163
164         /* All done, drop CSA & poll */
165         b47s->cc_write(b47s, BCMA_CC_FLASHCTL, 0);
166         udelay(1);
167         if (bcm47xxsflash_poll(b47s, HZ / 10))
168                 pr_err("Flash rejected dropping CSA\n");
169
170         return written;
171 }
172
173 static int bcm47xxsflash_write_at(struct mtd_info *mtd, u32 offset, size_t len,
174                                   const u_char *buf)
175 {
176         struct bcm47xxsflash *b47s = mtd->priv;
177         u32 mask = b47s->blocksize - 1;
178         u32 page = (offset & ~mask) << 1;
179         u32 byte = offset & mask;
180         int written = 0;
181
182         /* If we don't overwrite whole page, read it to the buffer first */
183         if (byte || (len < b47s->blocksize)) {
184                 int err;
185
186                 b47s->cc_write(b47s, BCMA_CC_FLASHADDR, page);
187                 bcm47xxsflash_cmd(b47s, OPCODE_AT_BUF1_LOAD);
188                 /* 250 us for AT45DB321B */
189                 err = bcm47xxsflash_poll(b47s, HZ / 1000);
190                 if (err) {
191                         pr_err("Timeout reading page 0x%X info buffer\n", page);
192                         return err;
193                 }
194         }
195
196         /* Change buffer content with our data */
197         while (len > 0) {
198                 /* Page boundary, another function call is needed */
199                 if (byte == b47s->blocksize)
200                         break;
201
202                 b47s->cc_write(b47s, BCMA_CC_FLASHADDR, byte++);
203                 b47s->cc_write(b47s, BCMA_CC_FLASHDATA, *buf++);
204                 bcm47xxsflash_cmd(b47s, OPCODE_AT_BUF1_WRITE);
205                 len--;
206                 written++;
207         }
208
209         /* Program page with the buffer content */
210         b47s->cc_write(b47s, BCMA_CC_FLASHADDR, page);
211         bcm47xxsflash_cmd(b47s, OPCODE_AT_BUF1_PROGRAM);
212
213         return written;
214 }
215
216 static int bcm47xxsflash_write(struct mtd_info *mtd, loff_t to, size_t len,
217                                size_t *retlen, const u_char *buf)
218 {
219         struct bcm47xxsflash *b47s = mtd->priv;
220         int written;
221
222         /* Writing functions can return without writing all passed data, for
223          * example when the hardware is too old or when we git page boundary.
224          */
225         while (len > 0) {
226                 switch (b47s->type) {
227                 case BCM47XXSFLASH_TYPE_ST:
228                         written = bcm47xxsflash_write_st(mtd, to, len, buf);
229                         break;
230                 case BCM47XXSFLASH_TYPE_ATMEL:
231                         written = bcm47xxsflash_write_at(mtd, to, len, buf);
232                         break;
233                 default:
234                         BUG_ON(1);
235                 }
236                 if (written < 0) {
237                         pr_err("Error writing at offset 0x%llX\n", to);
238                         return written;
239                 }
240                 to += (loff_t)written;
241                 len -= written;
242                 *retlen += written;
243                 buf += written;
244         }
245
246         return 0;
247 }
248
249 static void bcm47xxsflash_fill_mtd(struct bcm47xxsflash *b47s,
250                                    struct device *dev)
251 {
252         struct mtd_info *mtd = &b47s->mtd;
253
254         mtd->priv = b47s;
255         mtd->dev.parent = dev;
256         mtd->name = "bcm47xxsflash";
257
258         mtd->type = MTD_NORFLASH;
259         mtd->flags = MTD_CAP_NORFLASH;
260         mtd->size = b47s->size;
261         mtd->erasesize = b47s->blocksize;
262         mtd->writesize = 1;
263         mtd->writebufsize = 1;
264
265         mtd->_erase = bcm47xxsflash_erase;
266         mtd->_read = bcm47xxsflash_read;
267         mtd->_write = bcm47xxsflash_write;
268 }
269
270 /**************************************************
271  * BCMA
272  **************************************************/
273
274 static int bcm47xxsflash_bcma_cc_read(struct bcm47xxsflash *b47s, u16 offset)
275 {
276         return bcma_cc_read32(b47s->bcma_cc, offset);
277 }
278
279 static void bcm47xxsflash_bcma_cc_write(struct bcm47xxsflash *b47s, u16 offset,
280                                         u32 value)
281 {
282         bcma_cc_write32(b47s->bcma_cc, offset, value);
283 }
284
285 static int bcm47xxsflash_bcma_probe(struct platform_device *pdev)
286 {
287         struct device *dev = &pdev->dev;
288         struct bcma_sflash *sflash = dev_get_platdata(dev);
289         struct bcm47xxsflash *b47s;
290         struct resource *res;
291         int err;
292
293         b47s = devm_kzalloc(dev, sizeof(*b47s), GFP_KERNEL);
294         if (!b47s)
295                 return -ENOMEM;
296
297         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
298         if (!res) {
299                 dev_err(dev, "invalid resource\n");
300                 return -EINVAL;
301         }
302         if (!devm_request_mem_region(dev, res->start, resource_size(res),
303                                      res->name)) {
304                 dev_err(dev, "can't request region for resource %pR\n", res);
305                 return -EBUSY;
306         }
307
308         b47s->bcma_cc = container_of(sflash, struct bcma_drv_cc, sflash);
309         b47s->cc_read = bcm47xxsflash_bcma_cc_read;
310         b47s->cc_write = bcm47xxsflash_bcma_cc_write;
311
312         /*
313          * On old MIPS devices cache was magically invalidated when needed,
314          * allowing us to use cached access and gain some performance. Trying
315          * the same on ARM based BCM53573 results in flash corruptions, we need
316          * to use uncached access for it.
317          *
318          * It may be arch specific, but right now there is only 1 ARM SoC using
319          * this driver, so let's follow Broadcom's reference code and check
320          * ChipCommon revision.
321          */
322         if (b47s->bcma_cc->core->id.rev == 54)
323                 b47s->window = ioremap(res->start, resource_size(res));
324         else
325                 b47s->window = ioremap_cache(res->start, resource_size(res));
326         if (!b47s->window) {
327                 dev_err(dev, "ioremap failed for resource %pR\n", res);
328                 return -ENOMEM;
329         }
330
331         switch (b47s->bcma_cc->capabilities & BCMA_CC_CAP_FLASHT) {
332         case BCMA_CC_FLASHT_STSER:
333                 b47s->type = BCM47XXSFLASH_TYPE_ST;
334                 break;
335         case BCMA_CC_FLASHT_ATSER:
336                 b47s->type = BCM47XXSFLASH_TYPE_ATMEL;
337                 break;
338         }
339
340         b47s->blocksize = sflash->blocksize;
341         b47s->numblocks = sflash->numblocks;
342         b47s->size = sflash->size;
343         bcm47xxsflash_fill_mtd(b47s, &pdev->dev);
344
345         platform_set_drvdata(pdev, b47s);
346
347         err = mtd_device_parse_register(&b47s->mtd, probes, NULL, NULL, 0);
348         if (err) {
349                 pr_err("Failed to register MTD device: %d\n", err);
350                 iounmap(b47s->window);
351                 return err;
352         }
353
354         if (bcm47xxsflash_poll(b47s, HZ / 10))
355                 pr_warn("Serial flash busy\n");
356
357         return 0;
358 }
359
360 static int bcm47xxsflash_bcma_remove(struct platform_device *pdev)
361 {
362         struct bcm47xxsflash *b47s = platform_get_drvdata(pdev);
363
364         mtd_device_unregister(&b47s->mtd);
365         iounmap(b47s->window);
366
367         return 0;
368 }
369
370 static struct platform_driver bcma_sflash_driver = {
371         .probe  = bcm47xxsflash_bcma_probe,
372         .remove = bcm47xxsflash_bcma_remove,
373         .driver = {
374                 .name = "bcma_sflash",
375         },
376 };
377
378 /**************************************************
379  * Init
380  **************************************************/
381
382 module_platform_driver(bcma_sflash_driver);