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