xref: /rk3399_rockchip-uboot/drivers/mtd/st_smi.c (revision ae3e0cc924579bcea0906a6888a7bc01a19157e4)
1 /*
2  * (C) Copyright 2009
3  * Vipin Kumar, ST Microelectronics, vipin.kumar@st.com.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23 
24 #include <common.h>
25 #include <flash.h>
26 #include <linux/err.h>
27 #include <linux/mtd/st_smi.h>
28 
29 #include <asm/io.h>
30 #include <asm/arch/hardware.h>
31 
32 #if !defined(CONFIG_SYS_NO_FLASH)
33 
34 static struct smi_regs *const smicntl =
35     (struct smi_regs * const)CONFIG_SYS_SMI_BASE;
36 static ulong bank_base[CONFIG_SYS_MAX_FLASH_BANKS] =
37     CONFIG_SYS_FLASH_ADDR_BASE;
38 flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
39 
40 static struct flash_dev flash_ids[] = {
41 	{0x10, 0x10000, 2},	/* 64K Byte */
42 	{0x11, 0x20000, 4},	/* 128K Byte */
43 	{0x12, 0x40000, 4},	/* 256K Byte */
44 	{0x13, 0x80000, 8},	/* 512K Byte */
45 	{0x14, 0x100000, 16},	/* 1M Byte */
46 	{0x15, 0x200000, 32},	/* 2M Byte */
47 	{0x16, 0x400000, 64},	/* 4M Byte */
48 	{0x17, 0x800000, 128},	/* 8M Byte */
49 	{0x18, 0x1000000, 64},	/* 16M Byte */
50 	{0x00,}
51 };
52 
53 /*
54  * smi_wait_xfer_finish - Wait until TFF is set in status register
55  * @timeout:	 timeout in milliseconds
56  *
57  * Wait until TFF is set in status register
58  */
59 static int smi_wait_xfer_finish(int timeout)
60 {
61 	do {
62 		if (readl(&smicntl->smi_sr) & TFF)
63 			return 0;
64 		udelay(1000);
65 	} while (timeout--);
66 
67 	return -1;
68 }
69 
70 /*
71  * smi_read_id - Read flash id
72  * @info:	 flash_info structure pointer
73  * @banknum:	 bank number
74  *
75  * Read the flash id present at bank #banknum
76  */
77 static unsigned int smi_read_id(flash_info_t *info, int banknum)
78 {
79 	unsigned int value;
80 
81 	writel(readl(&smicntl->smi_cr1) | SW_MODE, &smicntl->smi_cr1);
82 	writel(READ_ID, &smicntl->smi_tr);
83 	writel((banknum << BANKSEL_SHIFT) | SEND | TX_LEN_1 | RX_LEN_3,
84 	       &smicntl->smi_cr2);
85 
86 	if (smi_wait_xfer_finish(XFER_FINISH_TOUT))
87 		return -EIO;
88 
89 	value = (readl(&smicntl->smi_rr) & 0x00FFFFFF);
90 
91 	writel(readl(&smicntl->smi_sr) & ~TFF, &smicntl->smi_sr);
92 	writel(readl(&smicntl->smi_cr1) & ~SW_MODE, &smicntl->smi_cr1);
93 
94 	return value;
95 }
96 
97 /*
98  * flash_get_size - Detect the SMI flash by reading the ID.
99  * @base:	 Base address of the flash area bank #banknum
100  * @banknum:	 Bank number
101  *
102  * Detect the SMI flash by reading the ID. Initializes the flash_info structure
103  * with size, sector count etc.
104  */
105 static ulong flash_get_size(ulong base, int banknum)
106 {
107 	flash_info_t *info = &flash_info[banknum];
108 	struct flash_dev *dev;
109 	int value;
110 	unsigned int density;
111 	int i;
112 
113 	value = smi_read_id(info, banknum);
114 
115 	if (value < 0) {
116 		printf("Flash id could not be read\n");
117 		return 0;
118 	}
119 
120 	density = (value >> 16) & 0xff;
121 
122 	for (i = 0, dev = &flash_ids[0]; dev->density != 0x0;
123 	     i++, dev = &flash_ids[i]) {
124 		if (dev->density == density) {
125 			info->size = dev->size;
126 			info->sector_count = dev->sector_count;
127 			break;
128 		}
129 	}
130 
131 	if (dev->density == 0x0)
132 		return 0;
133 
134 	info->flash_id = value & 0xffff;
135 	info->start[0] = base;
136 
137 	return info->size;
138 }
139 
140 /*
141  * smi_read_sr - Read status register of SMI
142  * @bank:	 bank number
143  *
144  * This routine will get the status register of the flash chip present at the
145  * given bank
146  */
147 static int smi_read_sr(int bank)
148 {
149 	u32 ctrlreg1, val;
150 
151 	/* store the CTRL REG1 state */
152 	ctrlreg1 = readl(&smicntl->smi_cr1);
153 
154 	/* Program SMI in HW Mode */
155 	writel(readl(&smicntl->smi_cr1) & ~(SW_MODE | WB_MODE),
156 	       &smicntl->smi_cr1);
157 
158 	/* Performing a RSR instruction in HW mode */
159 	writel((bank << BANKSEL_SHIFT) | RD_STATUS_REG, &smicntl->smi_cr2);
160 
161 	if (smi_wait_xfer_finish(XFER_FINISH_TOUT))
162 		return -1;
163 
164 	val = readl(&smicntl->smi_sr);
165 
166 	/* Restore the CTRL REG1 state */
167 	writel(ctrlreg1, &smicntl->smi_cr1);
168 
169 	return val;
170 }
171 
172 /*
173  * smi_wait_till_ready - Wait till last operation is over.
174  * @bank:	 bank number shifted.
175  * @timeout:	 timeout in milliseconds.
176  *
177  * This routine checks for WIP(write in progress)bit in Status register(SMSR-b0)
178  * The routine checks for #timeout loops, each at interval of 1 milli-second.
179  * If successful the routine returns 0.
180  */
181 static int smi_wait_till_ready(int bank, int timeout)
182 {
183 	int sr;
184 
185 	/* One chip guarantees max 5 msec wait here after page writes,
186 	   but potentially three seconds (!) after page erase. */
187 	do {
188 		sr = smi_read_sr(bank);
189 		if ((sr >= 0) && (!(sr & WIP_BIT)))
190 			return 0;
191 
192 		/* Try again after 1m-sec */
193 		udelay(1000);
194 	} while (timeout--);
195 
196 	printf("SMI controller is still in wait, timeout=%d\n", timeout);
197 	return -EIO;
198 }
199 
200 /*
201  * smi_write_enable - Enable the flash to do write operation
202  * @bank:	 bank number
203  *
204  * Set write enable latch with Write Enable command.
205  * Returns negative if error occurred.
206  */
207 static int smi_write_enable(int bank)
208 {
209 	u32 ctrlreg1;
210 	int timeout = WMODE_TOUT;
211 	int sr;
212 
213 	/* Store the CTRL REG1 state */
214 	ctrlreg1 = readl(&smicntl->smi_cr1);
215 
216 	/* Program SMI in H/W Mode */
217 	writel(readl(&smicntl->smi_cr1) & ~SW_MODE, &smicntl->smi_cr1);
218 
219 	/* Give the Flash, Write Enable command */
220 	writel((bank << BANKSEL_SHIFT) | WE, &smicntl->smi_cr2);
221 
222 	if (smi_wait_xfer_finish(XFER_FINISH_TOUT))
223 		return -1;
224 
225 	/* Restore the CTRL REG1 state */
226 	writel(ctrlreg1, &smicntl->smi_cr1);
227 
228 	do {
229 		sr = smi_read_sr(bank);
230 		if ((sr >= 0) && (sr & (1 << (bank + WM_SHIFT))))
231 			return 0;
232 
233 		/* Try again after 1m-sec */
234 		udelay(1000);
235 	} while (timeout--);
236 
237 	return -1;
238 }
239 
240 /*
241  * smi_init - SMI initialization routine
242  *
243  * SMI initialization routine. Sets SMI control register1.
244  */
245 void smi_init(void)
246 {
247 	/* Setting the fast mode values. SMI working at 166/4 = 41.5 MHz */
248 	writel(HOLD1 | FAST_MODE | BANK_EN | DSEL_TIME | PRESCAL4,
249 	       &smicntl->smi_cr1);
250 }
251 
252 /*
253  * smi_sector_erase - Erase flash sector
254  * @info:	 flash_info structure pointer
255  * @sector:	 sector number
256  *
257  * Set write enable latch with Write Enable command.
258  * Returns negative if error occurred.
259  */
260 static int smi_sector_erase(flash_info_t *info, unsigned int sector)
261 {
262 	int bank;
263 	unsigned int sect_add;
264 	unsigned int instruction;
265 
266 	switch (info->start[0]) {
267 	case SMIBANK0_BASE:
268 		bank = BANK0;
269 		break;
270 	case SMIBANK1_BASE:
271 		bank = BANK1;
272 		break;
273 	case SMIBANK2_BASE:
274 		bank = BANK2;
275 		break;
276 	case SMIBANK3_BASE:
277 		bank = BANK3;
278 		break;
279 	default:
280 		return -1;
281 	}
282 
283 	sect_add = sector * (info->size / info->sector_count);
284 	instruction = ((sect_add >> 8) & 0x0000FF00) | SECTOR_ERASE;
285 
286 	writel(readl(&smicntl->smi_sr) & ~(ERF1 | ERF2), &smicntl->smi_sr);
287 
288 	/* Wait until finished previous write command. */
289 	if (smi_wait_till_ready(bank, CONFIG_SYS_FLASH_ERASE_TOUT))
290 		return -EBUSY;
291 
292 	/* Send write enable, before erase commands. */
293 	if (smi_write_enable(bank))
294 		return -EIO;
295 
296 	/* Put SMI in SW mode */
297 	writel(readl(&smicntl->smi_cr1) | SW_MODE, &smicntl->smi_cr1);
298 
299 	/* Send Sector Erase command in SW Mode */
300 	writel(instruction, &smicntl->smi_tr);
301 	writel((bank << BANKSEL_SHIFT) | SEND | TX_LEN_4,
302 		       &smicntl->smi_cr2);
303 	if (smi_wait_xfer_finish(XFER_FINISH_TOUT))
304 		return -EIO;
305 
306 	if (smi_wait_till_ready(bank, CONFIG_SYS_FLASH_ERASE_TOUT))
307 		return -EBUSY;
308 
309 	/* Put SMI in HW mode */
310 	writel(readl(&smicntl->smi_cr1) & ~SW_MODE,
311 		       &smicntl->smi_cr1);
312 
313 	return 0;
314 }
315 
316 /*
317  * smi_write - Write to SMI flash
318  * @src_addr:	 source buffer
319  * @dst_addr:	 destination buffer
320  * @length:	 length to write in words
321  * @bank:	 bank base address
322  *
323  * Write to SMI flash
324  */
325 static int smi_write(unsigned int *src_addr, unsigned int *dst_addr,
326 		     unsigned int length, ulong bank_addr)
327 {
328 	int banknum;
329 
330 	switch (bank_addr) {
331 	case SMIBANK0_BASE:
332 		banknum = BANK0;
333 		break;
334 	case SMIBANK1_BASE:
335 		banknum = BANK1;
336 		break;
337 	case SMIBANK2_BASE:
338 		banknum = BANK2;
339 		break;
340 	case SMIBANK3_BASE:
341 		banknum = BANK3;
342 		break;
343 	default:
344 		return -1;
345 	}
346 
347 	if (smi_wait_till_ready(banknum, CONFIG_SYS_FLASH_WRITE_TOUT))
348 		return -EBUSY;
349 
350 	/* Set SMI in Hardware Mode */
351 	writel(readl(&smicntl->smi_cr1) & ~SW_MODE, &smicntl->smi_cr1);
352 
353 	if (smi_write_enable(banknum))
354 		return -EIO;
355 
356 	/* Perform the write command */
357 	while (length--) {
358 		if (((ulong) (dst_addr) % SFLASH_PAGE_SIZE) == 0) {
359 			if (smi_wait_till_ready(banknum,
360 						CONFIG_SYS_FLASH_WRITE_TOUT))
361 				return -EBUSY;
362 
363 			if (smi_write_enable(banknum))
364 				return -EIO;
365 		}
366 
367 		*dst_addr++ = *src_addr++;
368 
369 		if ((readl(&smicntl->smi_sr) & (ERF1 | ERF2)))
370 			return -EIO;
371 	}
372 
373 	if (smi_wait_till_ready(banknum, CONFIG_SYS_FLASH_WRITE_TOUT))
374 		return -EBUSY;
375 
376 	writel(readl(&smicntl->smi_sr) & ~(WCF), &smicntl->smi_sr);
377 
378 	return 0;
379 }
380 
381 /*
382  * write_buff - Write to SMI flash
383  * @info:	 flash info structure
384  * @src:	 source buffer
385  * @dest_addr:	 destination buffer
386  * @length:	 length to write in words
387  *
388  * Write to SMI flash
389  */
390 int write_buff(flash_info_t *info, uchar *src, ulong dest_addr, ulong length)
391 {
392 	return smi_write((unsigned int *)src, (unsigned int *)dest_addr,
393 		  (length + 3) / 4, info->start[0]);
394 }
395 
396 /*
397  * flash_init - SMI flash initialization
398  *
399  * SMI flash initialization
400  */
401 unsigned long flash_init(void)
402 {
403 	unsigned long size = 0;
404 	int i, j;
405 
406 	smi_init();
407 
408 	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
409 		flash_info[i].flash_id = FLASH_UNKNOWN;
410 		size += flash_info[i].size = flash_get_size(bank_base[i], i);
411 	}
412 
413 	for (j = 0; j < CONFIG_SYS_MAX_FLASH_BANKS; j++) {
414 		for (i = 1; i < flash_info[j].sector_count; i++)
415 			flash_info[j].start[i] =
416 			    flash_info[j].start[i - 1] +
417 			    flash_info->size / flash_info->sector_count;
418 
419 	}
420 
421 	return size;
422 }
423 
424 /*
425  * flash_print_info - Print SMI flash information
426  *
427  * Print SMI flash information
428  */
429 void flash_print_info(flash_info_t *info)
430 {
431 	int i;
432 	if (info->flash_id == FLASH_UNKNOWN) {
433 		puts("missing or unknown FLASH type\n");
434 		return;
435 	}
436 	printf("  Size: %ld MB in %d Sectors\n",
437 	       info->size >> 20, info->sector_count);
438 
439 	puts("  Sector Start Addresses:");
440 	for (i = 0; i < info->sector_count; ++i) {
441 #ifdef CONFIG_SYS_FLASH_EMPTY_INFO
442 		int size;
443 		int erased;
444 		u32 *flash;
445 
446 		/*
447 		 * Check if whole sector is erased
448 		 */
449 		size = (info->size) / (info->sector_count);
450 		flash = (u32 *) info->start[i];
451 		size = size / sizeof(int);
452 
453 		while ((size--) && (*flash++ == ~0))
454 			;
455 
456 		size++;
457 		if (size)
458 			erased = 0;
459 		else
460 			erased = 1;
461 
462 		if ((i % 5) == 0)
463 			printf("\n");
464 
465 		printf(" %08lX%s%s",
466 		       info->start[i],
467 		       erased ? " E" : "  ", info->protect[i] ? "RO " : "   ");
468 #else
469 		if ((i % 5) == 0)
470 			printf("\n   ");
471 		printf(" %08lX%s",
472 		       info->start[i], info->protect[i] ? " (RO)  " : "     ");
473 #endif
474 	}
475 	putc('\n');
476 	return;
477 }
478 
479 /*
480  * flash_erase - Erase SMI flash
481  *
482  * Erase SMI flash
483  */
484 int flash_erase(flash_info_t *info, int s_first, int s_last)
485 {
486 	int rcode = 0;
487 	int prot = 0;
488 	flash_sect_t sect;
489 
490 	if ((s_first < 0) || (s_first > s_last)) {
491 		puts("- no sectors to erase\n");
492 		return 1;
493 	}
494 
495 	for (sect = s_first; sect <= s_last; ++sect) {
496 		if (info->protect[sect])
497 			prot++;
498 	}
499 	if (prot) {
500 		printf("- Warning: %d protected sectors will not be erased!\n",
501 		       prot);
502 	} else {
503 		putc('\n');
504 	}
505 
506 	for (sect = s_first; sect <= s_last; sect++) {
507 		if (info->protect[sect] == 0) {
508 			if (smi_sector_erase(info, sect))
509 				rcode = 1;
510 			else
511 				putc('.');
512 		}
513 	}
514 	puts(" done\n");
515 	return rcode;
516 }
517 #endif
518