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