xref: /openbmc/u-boot/drivers/mtd/pic32_flash.c (revision 85231c08)
1 /*
2  * Copyright (C) 2015
3  * Cristian Birsan <cristian.birsan@microchip.com>
4  * Purna Chandra Mandal <purna.mandal@microchip.com>
5  *
6  * SPDX-License-Identifier:	GPL-2.0+
7  */
8 
9 #include <common.h>
10 #include <dm.h>
11 #include <fdt_support.h>
12 #include <flash.h>
13 #include <mach/pic32.h>
14 #include <wait_bit.h>
15 
16 DECLARE_GLOBAL_DATA_PTR;
17 
18 /* NVM Controller registers */
19 struct pic32_reg_nvm {
20 	struct pic32_reg_atomic ctrl;
21 	struct pic32_reg_atomic key;
22 	struct pic32_reg_atomic addr;
23 	struct pic32_reg_atomic data;
24 };
25 
26 /* NVM operations */
27 #define NVMOP_NOP		0
28 #define NVMOP_WORD_WRITE	1
29 #define NVMOP_PAGE_ERASE	4
30 
31 /* NVM control bits */
32 #define NVM_WR			BIT(15)
33 #define NVM_WREN		BIT(14)
34 #define NVM_WRERR		BIT(13)
35 #define NVM_LVDERR		BIT(12)
36 
37 /* NVM programming unlock register */
38 #define LOCK_KEY		0x0
39 #define UNLOCK_KEY1		0xaa996655
40 #define UNLOCK_KEY2		0x556699aa
41 
42 /*
43  * PIC32 flash banks consist of number of pages, each page
44  * into number of rows and rows into number of words.
45  * Here we will maintain page information instead of sector.
46  */
47 flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
48 static struct pic32_reg_nvm *nvm_regs_p;
49 
50 static inline void flash_initiate_operation(u32 nvmop)
51 {
52 	/* set operation */
53 	writel(nvmop, &nvm_regs_p->ctrl.raw);
54 
55 	/* enable flash write */
56 	writel(NVM_WREN, &nvm_regs_p->ctrl.set);
57 
58 	/* unlock sequence */
59 	writel(LOCK_KEY, &nvm_regs_p->key.raw);
60 	writel(UNLOCK_KEY1, &nvm_regs_p->key.raw);
61 	writel(UNLOCK_KEY2, &nvm_regs_p->key.raw);
62 
63 	/* initiate operation */
64 	writel(NVM_WR, &nvm_regs_p->ctrl.set);
65 }
66 
67 static int flash_wait_till_busy(const char *func, ulong timeout)
68 {
69 	int ret = wait_for_bit_le32(&nvm_regs_p->ctrl.raw,
70 				    NVM_WR, false, timeout, false);
71 
72 	return ret ? ERR_TIMEOUT : ERR_OK;
73 }
74 
75 static inline int flash_complete_operation(void)
76 {
77 	u32 tmp;
78 
79 	tmp = readl(&nvm_regs_p->ctrl.raw);
80 	if (tmp & NVM_WRERR) {
81 		printf("Error in Block Erase - Lock Bit may be set!\n");
82 		flash_initiate_operation(NVMOP_NOP);
83 		return ERR_PROTECTED;
84 	}
85 
86 	if (tmp & NVM_LVDERR) {
87 		printf("Error in Block Erase - low-vol detected!\n");
88 		flash_initiate_operation(NVMOP_NOP);
89 		return ERR_NOT_ERASED;
90 	}
91 
92 	/* disable flash write or erase operation */
93 	writel(NVM_WREN, &nvm_regs_p->ctrl.clr);
94 
95 	return ERR_OK;
96 }
97 
98 /*
99  * Erase flash sectors, returns:
100  * ERR_OK - OK
101  * ERR_INVAL - invalid sector arguments
102  * ERR_TIMEOUT - write timeout
103  * ERR_NOT_ERASED - Flash not erased
104  * ERR_UNKNOWN_FLASH_VENDOR - incorrect flash
105  */
106 int flash_erase(flash_info_t *info, int s_first, int s_last)
107 {
108 	ulong sect_start, sect_end, flags;
109 	int prot, sect;
110 	int rc;
111 
112 	if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_MCHP) {
113 		printf("Can't erase unknown flash type %08lx - aborted\n",
114 		       info->flash_id);
115 		return ERR_UNKNOWN_FLASH_VENDOR;
116 	}
117 
118 	if ((s_first < 0) || (s_first > s_last)) {
119 		printf("- no sectors to erase\n");
120 		return ERR_INVAL;
121 	}
122 
123 	prot = 0;
124 	for (sect = s_first; sect <= s_last; ++sect) {
125 		if (info->protect[sect])
126 			prot++;
127 	}
128 
129 	if (prot)
130 		printf("- Warning: %d protected sectors will not be erased!\n",
131 		       prot);
132 	else
133 		printf("\n");
134 
135 	/* erase on unprotected sectors */
136 	for (sect = s_first; sect <= s_last; sect++) {
137 		if (info->protect[sect])
138 			continue;
139 
140 		/* disable interrupts */
141 		flags = disable_interrupts();
142 
143 		/* write destination page address (physical) */
144 		sect_start = CPHYSADDR(info->start[sect]);
145 		writel(sect_start, &nvm_regs_p->addr.raw);
146 
147 		/* page erase */
148 		flash_initiate_operation(NVMOP_PAGE_ERASE);
149 
150 		/* wait */
151 		rc = flash_wait_till_busy(__func__,
152 					  CONFIG_SYS_FLASH_ERASE_TOUT);
153 
154 		/* re-enable interrupts if necessary */
155 		if (flags)
156 			enable_interrupts();
157 
158 		if (rc != ERR_OK)
159 			return rc;
160 
161 		rc = flash_complete_operation();
162 		if (rc != ERR_OK)
163 			return rc;
164 
165 		/*
166 		 * flash content is updated but cache might contain stale
167 		 * data, so invalidate dcache.
168 		 */
169 		sect_end = info->start[sect] + info->size / info->sector_count;
170 		invalidate_dcache_range(info->start[sect], sect_end);
171 	}
172 
173 	printf(" done\n");
174 	return ERR_OK;
175 }
176 
177 int page_erase(flash_info_t *info, int sect)
178 {
179 	return 0;
180 }
181 
182 /* Write a word to flash */
183 static int write_word(flash_info_t *info, ulong dest, ulong word)
184 {
185 	ulong flags;
186 	int rc;
187 
188 	/* read flash to check if it is sufficiently erased */
189 	if ((readl((void __iomem *)dest) & word) != word) {
190 		printf("Error, Flash not erased!\n");
191 		return ERR_NOT_ERASED;
192 	}
193 
194 	/* disable interrupts */
195 	flags = disable_interrupts();
196 
197 	/* update destination page address (physical) */
198 	writel(CPHYSADDR(dest), &nvm_regs_p->addr.raw);
199 	writel(word, &nvm_regs_p->data.raw);
200 
201 	/* word write */
202 	flash_initiate_operation(NVMOP_WORD_WRITE);
203 
204 	/* wait for operation to complete */
205 	rc = flash_wait_till_busy(__func__, CONFIG_SYS_FLASH_WRITE_TOUT);
206 
207 	/* re-enable interrupts if necessary */
208 	if (flags)
209 		enable_interrupts();
210 
211 	if (rc != ERR_OK)
212 		return rc;
213 
214 	return flash_complete_operation();
215 }
216 
217 /*
218  * Copy memory to flash, returns:
219  * ERR_OK - OK
220  * ERR_TIMEOUT - write timeout
221  * ERR_NOT_ERASED - Flash not erased
222  */
223 int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
224 {
225 	ulong dst, tmp_le, len = cnt;
226 	int i, l, rc;
227 	uchar *cp;
228 
229 	/* get lower word aligned address */
230 	dst = (addr & ~3);
231 
232 	/* handle unaligned start bytes */
233 	l = addr - dst;
234 	if (l != 0) {
235 		tmp_le = 0;
236 		for (i = 0, cp = (uchar *)dst; i < l; ++i, ++cp)
237 			tmp_le |= *cp << (i * 8);
238 
239 		for (; (i < 4) && (cnt > 0); ++i, ++src, --cnt, ++cp)
240 			tmp_le |= *src << (i * 8);
241 
242 		for (; (cnt == 0) && (i < 4); ++i, ++cp)
243 			tmp_le |= *cp << (i * 8);
244 
245 		rc = write_word(info, dst, tmp_le);
246 		if (rc)
247 			goto out;
248 
249 		dst += 4;
250 	}
251 
252 	/* handle word aligned part */
253 	while (cnt >= 4) {
254 		tmp_le = src[0] | src[1] << 8 | src[2] << 16 | src[3] << 24;
255 		rc = write_word(info, dst, tmp_le);
256 		if (rc)
257 			goto out;
258 		src += 4;
259 		dst += 4;
260 		cnt -= 4;
261 	}
262 
263 	if (cnt == 0) {
264 		rc = ERR_OK;
265 		goto out;
266 	}
267 
268 	/* handle unaligned tail bytes */
269 	tmp_le = 0;
270 	for (i = 0, cp = (uchar *)dst; (i < 4) && (cnt > 0); ++i, ++cp) {
271 		tmp_le |= *src++ << (i * 8);
272 		--cnt;
273 	}
274 
275 	for (; i < 4; ++i, ++cp)
276 		tmp_le |= *cp << (i * 8);
277 
278 	rc = write_word(info, dst, tmp_le);
279 out:
280 	/*
281 	 * flash content updated by nvm controller but CPU cache might
282 	 * have stale data, so invalidate dcache.
283 	 */
284 	invalidate_dcache_range(addr, addr + len);
285 
286 	printf(" done\n");
287 	return rc;
288 }
289 
290 void flash_print_info(flash_info_t *info)
291 {
292 	int i;
293 
294 	if (info->flash_id == FLASH_UNKNOWN) {
295 		printf("missing or unknown FLASH type\n");
296 		return;
297 	}
298 
299 	switch (info->flash_id & FLASH_VENDMASK) {
300 	case FLASH_MAN_MCHP:
301 		printf("Microchip Technology ");
302 		break;
303 	default:
304 		printf("Unknown Vendor ");
305 		break;
306 	}
307 
308 	switch (info->flash_id & FLASH_TYPEMASK) {
309 	case FLASH_MCHP100T:
310 		printf("Internal (8 Mbit, 64 x 16k)\n");
311 		break;
312 	default:
313 		printf("Unknown Chip Type\n");
314 		break;
315 	}
316 
317 	printf("  Size: %ld MB in %d Sectors\n",
318 	       info->size >> 20, info->sector_count);
319 
320 	printf("  Sector Start Addresses:");
321 	for (i = 0; i < info->sector_count; ++i) {
322 		if ((i % 5) == 0)
323 			printf("\n   ");
324 
325 		printf(" %08lX%s", info->start[i],
326 		       info->protect[i] ? " (RO)" : "     ");
327 	}
328 	printf("\n");
329 }
330 
331 unsigned long flash_init(void)
332 {
333 	unsigned long size = 0;
334 	struct udevice *dev;
335 	int bank;
336 
337 	/* probe every MTD device */
338 	for (uclass_first_device(UCLASS_MTD, &dev); dev;
339 	     uclass_next_device(&dev)) {
340 		/* nop */
341 	}
342 
343 	/* calc total flash size */
344 	for (bank = 0; bank < CONFIG_SYS_MAX_FLASH_BANKS; ++bank)
345 		size += flash_info[bank].size;
346 
347 	return size;
348 }
349 
350 static void pic32_flash_bank_init(flash_info_t *info,
351 				  ulong base, ulong size)
352 {
353 	ulong sect_size;
354 	int sect;
355 
356 	/* device & manufacturer code */
357 	info->flash_id = FLASH_MAN_MCHP | FLASH_MCHP100T;
358 	info->sector_count = CONFIG_SYS_MAX_FLASH_SECT;
359 	info->size = size;
360 
361 	/* update sector (i.e page) info */
362 	sect_size = info->size / info->sector_count;
363 	for (sect = 0; sect < info->sector_count; sect++) {
364 		info->start[sect] = base;
365 		/* protect each sector by default */
366 		info->protect[sect] = 1;
367 		base += sect_size;
368 	}
369 }
370 
371 static int pic32_flash_probe(struct udevice *dev)
372 {
373 	void *blob = (void *)gd->fdt_blob;
374 	int node = dev_of_offset(dev);
375 	const char *list, *end;
376 	const fdt32_t *cell;
377 	unsigned long addr, size;
378 	int parent, addrc, sizec;
379 	flash_info_t *info;
380 	int len, idx;
381 
382 	/*
383 	 * decode regs. there are multiple reg tuples, and they need to
384 	 * match with reg-names.
385 	 */
386 	parent = fdt_parent_offset(blob, node);
387 	fdt_support_default_count_cells(blob, parent, &addrc, &sizec);
388 	list = fdt_getprop(blob, node, "reg-names", &len);
389 	if (!list)
390 		return -ENOENT;
391 
392 	end = list + len;
393 	cell = fdt_getprop(blob, node, "reg", &len);
394 	if (!cell)
395 		return -ENOENT;
396 
397 	for (idx = 0, info = &flash_info[0]; list < end;) {
398 		addr = fdt_translate_address((void *)blob, node, cell + idx);
399 		size = fdt_addr_to_cpu(cell[idx + addrc]);
400 		len = strlen(list);
401 		if (!strncmp(list, "nvm", len)) {
402 			/* NVM controller */
403 			nvm_regs_p = ioremap(addr, size);
404 		} else if (!strncmp(list, "bank", 4)) {
405 			/* Flash bank: use kseg0 cached address */
406 			pic32_flash_bank_init(info, CKSEG0ADDR(addr), size);
407 			info++;
408 		}
409 		idx += addrc + sizec;
410 		list += len + 1;
411 	}
412 
413 	/* disable flash write/erase operations */
414 	writel(NVM_WREN, &nvm_regs_p->ctrl.clr);
415 
416 #if (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
417 	/* monitor protection ON by default */
418 	flash_protect(FLAG_PROTECT_SET,
419 		      CONFIG_SYS_MONITOR_BASE,
420 		      CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
421 		      &flash_info[0]);
422 #endif
423 
424 #ifdef CONFIG_ENV_IS_IN_FLASH
425 	/* ENV protection ON by default */
426 	flash_protect(FLAG_PROTECT_SET,
427 		      CONFIG_ENV_ADDR,
428 		      CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1,
429 		      &flash_info[0]);
430 #endif
431 	return 0;
432 }
433 
434 static const struct udevice_id pic32_flash_ids[] = {
435 	{ .compatible = "microchip,pic32mzda-flash" },
436 	{}
437 };
438 
439 U_BOOT_DRIVER(pic32_flash) = {
440 	.name	= "pic32_flash",
441 	.id	= UCLASS_MTD,
442 	.of_match = pic32_flash_ids,
443 	.probe	= pic32_flash_probe,
444 };
445