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