Changeset 9242
- Timestamp:
- 03/06/08 00:34:24 (5 years ago)
- Location:
- src/linux/ar531x/linux-2.6.23/drivers/mtd/devices
- Files:
-
- 2 edited
-
spiflash.c (modified) (8 diffs)
-
spiflash_selfmap.c (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/linux/ar531x/linux-2.6.23/drivers/mtd/devices/spiflash.c
r9156 r9242 204 204 #define SET_SPI_ACTIVITY() \ 205 205 { \ 206 /*printk("SET_SPI @ %s, line %d\n",__FUNCTION__,__LINE__);*/ \207 while (atomic_read(&spiflash_cs)) \208 { \209 printk("Woops, shit happens @ %s, line %d !!!\n",__FUNCTION__,__LINE__); \210 udelay(1); \211 } \212 atomic_set(&spiflash_cs, 1); \213 206 } 214 207 215 208 #define CLEAR_SPI_ACTIVITY() \ 216 209 { \ 217 /*printk("CLEAR_SPI @ %s, line %d\n",__FUNCTION__,__LINE__);*/ \218 210 chip_select(1); \ 219 atomic_set(&spiflash_cs, 0); \220 211 } 221 212 … … 368 359 { 369 360 struct opcodes *ptr_opcode; 370 u32 temp, reg; 361 __u32 temp, reg; 362 int finished = 0; 363 unsigned int addr = instr->addr; 364 365 #ifdef SPIFLASH_DEBUG 366 printk (KERN_DEBUG "%s(addr = 0x%.8x, len = %d)\n",__FUNCTION__,instr->addr,instr->len); 367 #endif 371 368 372 369 /* sanity checks */ 373 370 if (instr->addr + instr->len > mtd->size) return (-EINVAL); 374 375 371 if (!spiflash_wait_ready(FL_ERASING)) 376 372 return -EINTR; 377 378 spiflash_sendcmd(SPI_WRITE_ENABLE, 0); 373 for (addr=instr->addr;addr<instr->addr+instr->len;addr+=mtd->erasesize) 374 { 375 376 ptr_opcode = &stm_opcodes[SPI_SECTOR_ERASE]; 377 378 temp = ((__u32)addr << 8) | (__u32)(ptr_opcode->code); 379 spiflash_sendcmd(SPI_WRITE_ENABLE,0); 379 380 busy_wait((reg = spiflash_regread32(SPI_FLASH_CTL)) & SPI_CTL_BUSY, 0); 380 reg = spiflash_regread32(SPI_FLASH_CTL); 381 382 ptr_opcode = &stm_opcodes[SPI_SECTOR_ERASE]; 383 temp = ((__u32)instr->addr << 8) | (__u32)(ptr_opcode->code); 381 384 382 spiflash_regwrite32(SPI_FLASH_OPCODE, temp); 385 383 … … 387 385 spiflash_regwrite32(SPI_FLASH_CTL, reg); 388 386 389 390 387 busy_wait(spiflash_sendcmd(SPI_RD_STATUS, 0) & SPI_STATUS_WIP, 20); 388 } 391 389 spiflash_done(); 392 390 393 391 instr->state = MTD_ERASE_DONE; 394 392 if (instr->callback) instr->callback (instr); 395 396 return 0; 393 #ifdef SPIFLASH_DEBUG 394 printk (KERN_DEBUG "%s return\n",__FUNCTION__); 395 #endif 396 return (0); 397 397 } 398 398 … … 518 518 519 519 /* wait and mark our activity */ 520 if (!spiflash_wait_ready(FL_WRITING)) 521 return -EINTR; 520 522 SET_SPI_ACTIVITY(); 521 523 chip_select(0); … … 565 567 /* clean our activity */ 566 568 CLEAR_SPI_ACTIVITY(); 567 568 for (;;) 569 { 570 udelay(1); 571 reg = spiflash_sendcmd(SPI_RD_STATUS, 0); 572 if (!(reg & SPI_STATUS_WIP)) 573 { 574 break; 575 } 576 } 577 569 570 571 busy_wait(spiflash_sendcmd(SPI_RD_STATUS, 0) & SPI_STATUS_WIP, 20); 572 spiflash_done(); 578 573 return; 579 574 } … … 597 592 for (i=0; i<256; i++) buffer[i] = (unsigned char)i; 598 593 page_write(block, buffer); 594 if (!spiflash_wait_ready(FL_WRITING)) 595 return -EINTR; 599 596 600 597 /* wait and mark our activity */ … … 642 639 udelay(10); 643 640 644 for (;;) 645 { 646 udelay(1); 647 reg = spiflash_sendcmd(SPI_RD_STATUS, 0); 648 if (!(reg & SPI_STATUS_WIP)) break; 649 } 650 641 busy_wait(spiflash_sendcmd(SPI_RD_STATUS, 0) & SPI_STATUS_WIP, 20); 642 spiflash_done(); 651 643 printk("SPI flash write test done (%d)!, page programming is %s!\n", i, i<8 ? "disabled":"enabled"); 652 644 return (i<8 ? 1:0); … … 654 646 655 647 static int pp_mode = -1; 656 static int pp_enable = 0;648 static int pp_enable = 1; 657 649 658 650 /* implementation for spiflash page programing. */ -
src/linux/ar531x/linux-2.6.23/drivers/mtd/devices/spiflash_selfmap.c
r9159 r9242 45 45 #include <linux/squashfs_fs.h> 46 46 #include <linux/delay.h> 47 #include <linux/proc_fs.h> 47 48 #include <asm/delay.h> 48 49 #include <asm/io.h> … … 147 148 FL_READING, 148 149 FL_ERASING, 149 FL_WRITING 150 FL_WRITING, 151 FL_SPI 150 152 }; 151 153 … … 155 157 { name: "rootfs", offset: 0x0, size: 0x2b0000,}, //must be detected 156 158 { name: "nvram", offset: 0x3d0000, size: 0x10000, }, 157 { name: "FIS directory", offset: 0x3e0000, size: 0x10000, },159 { name: "FIS Directory", offset: 0x3e0000, size: 0x10000, }, 158 160 { name: "board_config", offset: 0x3f0000, size: 0x10000, }, 159 161 { name: "fullflash", offset: 0x3f0000, size: 0x10000, }, … … 166 168 167 169 extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts); 170 171 #ifdef CONFIG_MTD_SPIFLASH_PP 172 /* 173 * With AR2317, WRG-G19, we add the external circuit to implement page 174 * programming. The GPIO 0 is used to control the chip select of the SPI 175 * interface. The chip select is low active. 176 * 177 * david_hsieh@alphanetworks.com 178 */ 179 180 /* The following part is cut from arch/mips/ar531x/ar531x.h */ 181 182 #include <asm/addrspace.h> 183 184 #define AR5315_DSLBASE 0xB1000000 /* RESET CONTROL MMR */ 185 186 /* GPIO */ 187 #define AR5315_GPIO_DI (AR5315_DSLBASE + 0x0088) 188 #define AR5315_GPIO_DO (AR5315_DSLBASE + 0x0090) 189 #define AR5315_GPIO_CR (AR5315_DSLBASE + 0x0098) 190 #define AR5315_GPIO_INT (AR5315_DSLBASE + 0x00a0) 191 192 /* Chip Select GPIO for Page Programming */ 193 #ifndef CONFIG_MTD_SPIFLASH_PP_GPIO 194 #define CONFIG_MTD_SPIFLASH_PP_GPIO 0 195 #endif 196 #define SPI_CS_BIT_MASK (1 << CONFIG_MTD_SPIFLASH_PP_GPIO) 197 198 typedef unsigned int AR531X_REG; 199 #define sysRegRead(phys) (*(volatile AR531X_REG *)KSEG1ADDR(phys)) 200 #define sysRegWrite(phys, val) ((*(volatile AR531X_REG *)KSEG1ADDR(phys)) = (val)) 201 202 static atomic_t spiflash_cs = ATOMIC_INIT(0); 203 204 static inline void chip_select(int value) 205 { 206 __u32 reg; 207 208 /* Set GPIO 0 as output. */ 209 reg = sysRegRead(AR5315_GPIO_CR); 210 reg |= SPI_CS_BIT_MASK; 211 sysRegWrite(AR5315_GPIO_CR, reg); 212 213 /* Set GPIO 0 data. */ 214 reg = sysRegRead(AR5315_GPIO_DO); 215 if (value) reg |= SPI_CS_BIT_MASK; 216 else reg &= ~SPI_CS_BIT_MASK; 217 sysRegWrite(AR5315_GPIO_DO, reg); 218 } 219 220 #define SET_SPI_ACTIVITY() \ 221 { \ 222 } 223 224 #define CLEAR_SPI_ACTIVITY() \ 225 { \ 226 chip_select(1); \ 227 } 228 229 #else 230 231 #define SET_SPI_ACTIVITY() 232 #define CLEAR_SPI_ACTIVITY() 233 234 #endif 235 236 168 237 169 238 /***************************************************************************************************/ … … 287 356 return 0; 288 357 358 289 359 goto retry; 290 360 } … … 307 377 __u32 temp, reg; 308 378 int finished = 0; 379 unsigned int addr = instr->addr; 309 380 310 381 #ifdef SPIFLASH_DEBUG … … 314 385 /* sanity checks */ 315 386 if (instr->addr + instr->len > mtd->size) return (-EINVAL); 387 if (!spiflash_wait_ready(FL_ERASING)) 388 return -EINTR; 389 for (addr=instr->addr;addr<instr->addr+instr->len;addr+=mtd->erasesize) 390 { 316 391 317 392 ptr_opcode = &stm_opcodes[SPI_SECTOR_ERASE]; 318 393 319 temp = ((__u32) instr->addr << 8) | (__u32)(ptr_opcode->code);394 temp = ((__u32)addr << 8) | (__u32)(ptr_opcode->code); 320 395 spiflash_sendcmd(SPI_WRITE_ENABLE,0); 321 do { 322 reg = spiflash_regread32(SPI_FLASH_CTL); 323 } while (reg & SPI_CTL_BUSY); 396 busy_wait((reg = spiflash_regread32(SPI_FLASH_CTL)) & SPI_CTL_BUSY, 0); 324 397 325 398 spiflash_regwrite32(SPI_FLASH_OPCODE, temp); … … 328 401 spiflash_regwrite32(SPI_FLASH_CTL, reg); 329 402 330 do { 331 reg = spiflash_sendcmd(SPI_RD_STATUS,0); 332 if (!(reg & SPI_STATUS_WIP)) { 333 finished = 1; 334 } 335 } while (!finished); 403 busy_wait(spiflash_sendcmd(SPI_RD_STATUS, 0) & SPI_STATUS_WIP, 20); 404 } 405 spiflash_done(); 336 406 337 407 instr->state = MTD_ERASE_DONE; 338 408 if (instr->callback) instr->callback (instr); 339 340 409 #ifdef SPIFLASH_DEBUG 341 410 printk (KERN_DEBUG "%s return\n",__FUNCTION__); … … 445 514 } 446 515 516 #ifdef CONFIG_MTD_SPIFLASH_PP 517 518 static void page_write(loff_t to, const u_char * buf) 519 { 520 __u32 reg, spi_data, opcode; 521 int i; 522 523 524 /* We are going to write flash now, do write enable first. */ 525 spiflash_sendcmd(SPI_WRITE_ENABLE, 0); 526 527 /* we are not really waiting for CPU spiflash activity, just need the value of the register. */ 528 busy_wait((reg = spiflash_regread32(SPI_FLASH_CTL)) & SPI_CTL_BUSY, 0); 529 530 /* Prepare SPI opcode, data and control register values. */ 531 opcode = (stm_opcodes[SPI_PAGE_PROGRAM].code & SPI_OPCODE_MASK) | ((__u32)to << 8); 532 spi_data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; buf += 4; 533 reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | 0x8 | SPI_CTL_START; 534 535 /* wait and mark our activity */ 536 if (!spiflash_wait_ready(FL_WRITING)) 537 return -EINTR; 538 SET_SPI_ACTIVITY(); 539 chip_select(0); 540 541 /* Send out the the first 4 bytes. */ 542 spiflash_regwrite32(SPI_FLASH_DATA, spi_data); 543 spiflash_regwrite32(SPI_FLASH_OPCODE, opcode); 544 spiflash_regwrite32(SPI_FLASH_CTL, reg); 545 546 /* 31 loops, each loop send 8 bytes */ 547 for (i=0; i<31; i++) 548 { 549 busy_wait((reg = spiflash_regread32(SPI_FLASH_CTL)) & SPI_CTL_BUSY, 0); 550 551 /* 552 * The sample code from the application node is: 553 * 554 * spi_data = (UINT32)*((UINT32 *)buf); 555 * spi_data = cpi2le32(spi_data); 556 * spi_data_swapped = 557 * (((spi_data>>8) & 0xff) << 24) | 558 * (((spi_data>>24)& 0xff) << 8) | 559 * (spi_data & 0x00ff00ff); 560 */ 561 opcode = (buf[3] << 8) | (buf[2] << 16) | (buf[1] << 24) | buf[0]; buf += 4; 562 spi_data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; buf += 4; 563 reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | 0x8 | SPI_CTL_START; 564 565 spiflash_regwrite32(SPI_FLASH_DATA, spi_data); 566 spiflash_regwrite32(SPI_FLASH_OPCODE, opcode); 567 spiflash_regwrite32(SPI_FLASH_CTL, reg); 568 } 569 570 /* send out the last 4 bytes */ 571 busy_wait((reg = spiflash_regread32(SPI_FLASH_CTL)) & SPI_CTL_BUSY, 0); 572 573 opcode = (buf[3] << 8) | (buf[2] << 16) | (buf[1] << 24) | buf[0]; buf += 4; 574 reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | 0x4 | SPI_CTL_START; 575 576 spiflash_regwrite32(SPI_FLASH_OPCODE, opcode); 577 spiflash_regwrite32(SPI_FLASH_CTL, reg); 578 579 busy_wait((reg = spiflash_regread32(SPI_FLASH_CTL)) & SPI_CTL_BUSY, 0); 580 581 /* Deactive chip select */ 582 chip_select(1); 583 /* clean our activity */ 584 CLEAR_SPI_ACTIVITY(); 585 586 587 busy_wait(spiflash_sendcmd(SPI_RD_STATUS, 0) & SPI_STATUS_WIP, 20); 588 spiflash_done(); 589 return; 590 } 591 592 /* 593 * Do page programming test. 594 * The 'block' should be erase already. 595 * We try to use page programming mode to write flash, 596 * and erase this block again before return. 597 */ 598 static int test_page_programming(struct mtd_info * mtd, loff_t block) 599 { 600 unsigned char buffer[256]; 601 unsigned char * flash; 602 struct opcodes *ptr_opcode; 603 __u32 opcode, reg; 604 int i; 605 606 607 /* write the flash with known pattern */ 608 for (i=0; i<256; i++) buffer[i] = (unsigned char)i; 609 page_write(block, buffer); 610 if (!spiflash_wait_ready(FL_WRITING)) 611 return -EINTR; 612 613 /* wait and mark our activity */ 614 SET_SPI_ACTIVITY(); 615 616 /* read it back and check pattern */ 617 flash = (unsigned char *)(spidata->readaddr + block); 618 printk(KERN_EMERG "%s(): checking @ 0x%.8x ...\n",__FUNCTION__,(__u32)flash); 619 for (i = 0; i < 8; i++) 620 { 621 if (flash[i*4] != (unsigned char)(i*4)) 622 { 623 printk(KERN_EMERG "unexpected value @ %d: 0x%02x !!\n", i*4, flash[i*4]); 624 break; 625 } 626 } 627 628 /* clean our activity */ 629 CLEAR_SPI_ACTIVITY(); 630 udelay(10); 631 632 /* erase this block before return */ 633 printk(KERN_EMERG "%s(): erasing block 0x%.8x ...\n",__FUNCTION__,(__u32)block); 634 635 /* we are going to erase sector, do write enable first */ 636 spiflash_sendcmd(SPI_WRITE_ENABLE, 0); 637 638 /* wait and mark our activity */ 639 SET_SPI_ACTIVITY(); 640 641 /* we are not really waiting for CPU spiflash activity, just need the value of the register. */ 642 busy_wait((reg = spiflash_regread32(SPI_FLASH_CTL)) & SPI_CTL_BUSY, 0); 643 644 /* send sector erase op. */ 645 ptr_opcode = &stm_opcodes[SPI_SECTOR_ERASE]; 646 opcode = ((__u32)ptr_opcode->code) | ((__u32)block << 8); 647 spiflash_regwrite32(SPI_FLASH_OPCODE, opcode); 648 reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | ptr_opcode->tx_cnt | SPI_CTL_START; 649 spiflash_regwrite32(SPI_FLASH_CTL, reg); 650 651 /* wait for CPU spiflash activity */ 652 busy_wait((reg = spiflash_regread32(SPI_FLASH_CTL)) & SPI_CTL_BUSY, 0); 653 /* clean our activity */ 654 CLEAR_SPI_ACTIVITY(); 655 udelay(10); 656 657 busy_wait(spiflash_sendcmd(SPI_RD_STATUS, 0) & SPI_STATUS_WIP, 20); 658 spiflash_done(); 659 printk("SPI flash write test done (%d)!, page programming is %s!\n", i, i<8 ? "disabled":"enabled"); 660 return (i<8 ? 1:0); 661 } 662 663 static int pp_mode = -1; 664 static int pp_enable = 1; 665 666 /* implementation for spiflash page programing. */ 667 static int spiflash_page_write(struct mtd_info * mtd, 668 loff_t to, size_t len, size_t * retlen, const u_char * buf) 669 { 670 size_t bytes_left = len; 671 size_t xact_len; 672 size_t written; 673 size_t offset; 674 675 676 /* If we already test page programming and failed, 677 * fall back to spiflash_write() directly. */ 678 if (pp_mode > 0) return spiflash_write(mtd, to, len, retlen, buf); 679 680 *retlen = 0; 681 if (to + len > mtd->size) return (-EINVAL); 682 683 while (bytes_left > 0) 684 { 685 offset = to % STM_PAGE_SIZE; 686 xact_len = MIN(bytes_left, STM_PAGE_SIZE - offset); 687 if (offset > 0 || xact_len < STM_PAGE_SIZE) 688 { 689 spiflash_write(mtd, to, xact_len, &written, buf); 690 } 691 else 692 { 693 /* test page program mode, if we did not test it before. */ 694 if (pp_mode < 0) pp_mode = test_page_programming(mtd, to); 695 696 if (pp_enable && (pp_mode == 0)) page_write(to, buf); 697 else spiflash_write(mtd, to, xact_len, &written, buf); 698 } 699 to += xact_len; 700 bytes_left -= xact_len; 701 buf += xact_len; 702 *retlen += xact_len; 703 } 704 705 return 0; 706 } 707 708 static int __my_atoi(const char * buf) 709 { 710 int ret = 0; 711 while (*buf) 712 { 713 if (*buf >= '0' && *buf <= '9') ret += (int)(*buf - '0'); 714 buf++; 715 } 716 return ret; 717 } 718 719 static int proc_read_pp_enable(char * buf, char ** start, off_t offset, 720 int len, int * eof, void * data) 721 { 722 char * p = buf; 723 p += sprintf(p, "%d\n", pp_enable); 724 *eof = 1; 725 return p - buf; 726 } 727 728 static int proc_write_pp_enable(struct file * file, const char * buf, 729 unsigned long count, void * data) 730 { 731 pp_enable = __my_atoi(buf); 732 printk("spiflash: %s page programming!\n", pp_enable ? "enable" : "disable"); 733 if (pp_mode >= 0) printk("spiflash: H/W is %scapable of doing page programming!\n", pp_mode ? "not " : ""); 734 return count; 735 } 736 737 static struct proc_dir_entry * root = NULL; 738 static struct proc_dir_entry * pp_enable_entry = NULL; 739 740 static int register_spi_proc(void) 741 { 742 root = proc_mkdir("spiflash", NULL); 743 if (root == NULL) 744 { 745 printk("spiflash: fail to create /proc/spiflash !!\n"); 746 return -1; 747 } 748 pp_enable_entry = create_proc_entry("pp_enable", 0644, root); 749 if (pp_enable_entry == NULL) 750 { 751 printk("spiflash: fail to create /proc/spiflash/pp_enable !!\n"); 752 remove_proc_entry("spiflash", root); 753 root = NULL; 754 return -1; 755 } 756 pp_enable_entry->data = 0; 757 pp_enable_entry->read_proc = proc_read_pp_enable; 758 pp_enable_entry->write_proc = proc_write_pp_enable; 759 pp_enable_entry->owner = THIS_MODULE; 760 printk("spiflash: /proc/spiflash/pp_enable created !!\n"); 761 return 0; 762 } 763 764 static void remove_spi_proc(void) 765 { 766 if (pp_enable_entry) remove_proc_entry("pp_enable", root); 767 if (root) remove_proc_entry("spiflash", root); 768 pp_enable_entry = NULL; 769 root = NULL; 770 } 771 772 #endif 447 773 448 774 #ifdef CONFIG_MTD_PARTITIONS … … 510 836 mtd->erase = spiflash_erase; 511 837 mtd->read = spiflash_read; 512 mtd->write = spiflash_write; 838 #ifdef CONFIG_MTD_SPIFLASH_PP 839 mtd->write = spiflash_page_write; 840 #else 841 mtd->write = spiflash_write; 842 #endif 513 843 mtd->owner = THIS_MODULE; 514 844 printk(KERN_EMERG "scanning for root partition\n"); … … 562 892 def:; 563 893 result = add_mtd_partitions(mtd, dir_parts, 7); 894 #ifdef CONFIG_MTD_SPIFLASH_PP 895 register_spi_proc(); 896 #endif 564 897 spidata->mtd = mtd; 565 898 … … 602 935 { 603 936 kfree(spidata); 937 #ifdef CONFIG_MTD_SPIFLASH_PP 938 remove_spi_proc(); 939 #endif 604 940 } 605 941
Note: See TracChangeset
for help on using the changeset viewer.
