| 323 | | #define RTC_DENOMINATOR 100 |
|---|
| 324 | | #define RTC_PERIOD 110000000 / RTC_DENOMINATOR |
|---|
| 325 | | |
|---|
| 326 | | #define MACRO_START do { |
|---|
| 327 | | #define MACRO_END } while (0) |
|---|
| 328 | | static unsigned int cyg_hal_clock_period; |
|---|
| 329 | | |
|---|
| 330 | | #define HAL_CLOCK_INITIALIZE( _period_ ) \ |
|---|
| 331 | | MACRO_START \ |
|---|
| 332 | | asm volatile ( \ |
|---|
| 333 | | "mtc0 $0,$9\n" \ |
|---|
| 334 | | "nop; nop; nop\n" \ |
|---|
| 335 | | "mtc0 %0,$11\n" \ |
|---|
| 336 | | "nop; nop; nop\n" \ |
|---|
| 337 | | : \ |
|---|
| 338 | | : "r"(_period_) \ |
|---|
| 339 | | ); \ |
|---|
| 340 | | cyg_hal_clock_period = _period_; \ |
|---|
| 341 | | MACRO_END |
|---|
| 342 | | |
|---|
| 343 | | #define HAL_CLOCK_RESET( _vector_, _period_ ) \ |
|---|
| 344 | | MACRO_START \ |
|---|
| 345 | | asm volatile ( \ |
|---|
| 346 | | "mtc0 $0,$9\n" \ |
|---|
| 347 | | "nop; nop; nop\n" \ |
|---|
| 348 | | "mtc0 %0,$11\n" \ |
|---|
| 349 | | "nop; nop; nop\n" \ |
|---|
| 350 | | : \ |
|---|
| 351 | | : "r"(_period_) \ |
|---|
| 352 | | ); \ |
|---|
| 353 | | MACRO_END |
|---|
| 354 | | |
|---|
| 355 | | #define HAL_CLOCK_READ( _pvalue_ ) \ |
|---|
| 356 | | MACRO_START \ |
|---|
| 357 | | register unsigned int result; \ |
|---|
| 358 | | asm volatile ( \ |
|---|
| 359 | | "mfc0 %0,$9\n" \ |
|---|
| 360 | | : "=r"(result) \ |
|---|
| 361 | | ); \ |
|---|
| 362 | | *(_pvalue_) = result; \ |
|---|
| 363 | | MACRO_END |
|---|
| 364 | | |
|---|
| 365 | | /* |
|---|
| 366 | | * udelay implementation based on cpu cycle counter |
|---|
| 367 | | */ |
|---|
| 368 | | static void udelay(int us) |
|---|
| 369 | | { |
|---|
| 370 | | unsigned int val1, val2; |
|---|
| 371 | | int diff; |
|---|
| 372 | | long usticks; |
|---|
| 373 | | long ticks; |
|---|
| 374 | | |
|---|
| 375 | | // Calculate the number of counter register ticks per microsecond. |
|---|
| 376 | | |
|---|
| 377 | | usticks = (RTC_PERIOD * RTC_DENOMINATOR) / 1000000; |
|---|
| 378 | | |
|---|
| 379 | | // Make sure that the value is not zero. This will only happen if the |
|---|
| 380 | | // CPU is running at < 2MHz. |
|---|
| 381 | | if (usticks == 0) |
|---|
| 382 | | usticks = 1; |
|---|
| 383 | | |
|---|
| 384 | | while (us > 0) { |
|---|
| 385 | | int us1 = us; |
|---|
| 386 | | |
|---|
| 387 | | // Wait in bursts of less than 10000us to avoid any overflow |
|---|
| 388 | | // problems in the multiply. |
|---|
| 389 | | if (us1 > 10000) |
|---|
| 390 | | us1 = 10000; |
|---|
| 391 | | |
|---|
| 392 | | us -= us1; |
|---|
| 393 | | |
|---|
| 394 | | ticks = us1 * usticks; |
|---|
| 395 | | |
|---|
| 396 | | HAL_CLOCK_READ(&val1); |
|---|
| 397 | | while (ticks > 0) { |
|---|
| 398 | | do { |
|---|
| 399 | | HAL_CLOCK_READ(&val2); |
|---|
| 400 | | } |
|---|
| 401 | | while (val1 == val2); |
|---|
| 402 | | diff = val2 - val1; |
|---|
| 403 | | if (diff < 0) |
|---|
| 404 | | diff += RTC_PERIOD; |
|---|
| 405 | | ticks -= diff; |
|---|
| 406 | | val1 = val2; |
|---|
| 407 | | } |
|---|
| 408 | | } |
|---|
| 409 | | } |
|---|
| 410 | | |
|---|
| 411 | | #ifndef STANDALONE_DEBUG |
|---|
| 412 | | |
|---|
| 413 | | typedef unsigned int AR531X_REG; |
|---|
| 414 | | |
|---|
| 415 | | #undef sysRegRead |
|---|
| 416 | | #undef sysRegWrite |
|---|
| 417 | | #define sysRegRead(phys) \ |
|---|
| 418 | | (*(volatile AR531X_REG *)(KSEG1|phys)) |
|---|
| 419 | | |
|---|
| 420 | | #define sysRegWrite(phys, val) \ |
|---|
| 421 | | ((*(volatile AR531X_REG *)(KSEG1|phys)) = (val)) |
|---|
| 422 | | |
|---|
| 423 | | #ifndef AR5312 |
|---|
| 424 | | |
|---|
| 425 | | #define RESET_WARM_WLAN0_MAC 0x00000001 /* warm reset WLAN0 MAC */ |
|---|
| 426 | | #define RESET_WARM_WLAN0_BB 0x00000002 /* warm reset WLAN0 BaseBand */ |
|---|
| 427 | | #define RESET_MPEGTS_RSVD 0x00000004 /* warm reset MPEG-TS */ |
|---|
| 428 | | #define RESET_PCIDMA 0x00000008 /* warm reset PCI ahb/dma */ |
|---|
| 429 | | #define RESET_MEMCTL 0x00000010 /* warm reset memory controller */ |
|---|
| 430 | | #define RESET_LOCAL 0x00000020 /* warm reset local bus */ |
|---|
| 431 | | #define RESET_I2C_RSVD 0x00000040 /* warm reset I2C bus */ |
|---|
| 432 | | #define RESET_SPI 0x00000080 /* warm reset SPI interface */ |
|---|
| 433 | | #define RESET_UART0 0x00000100 /* warm reset UART0 */ |
|---|
| 434 | | #define RESET_IR_RSVD 0x00000200 /* warm reset IR interface */ |
|---|
| 435 | | #define RESET_EPHY0 0x00000400 /* cold reset ENET0 phy */ |
|---|
| 436 | | #define RESET_ENET0 0x00000800 /* cold reset ENET0 mac */ |
|---|
| 437 | | |
|---|
| 438 | | #define IF_TS_LOCAL 2 |
|---|
| 439 | | #define AR2316_DSLBASE 0xB1000000 /* RESET CONTROL MMR */ |
|---|
| 440 | | #define AR2316_RESET (AR2316_DSLBASE + 0x0004) |
|---|
| 441 | | #define AR2316_IF_CTL (AR2316_DSLBASE + 0x0018) |
|---|
| 442 | | #define AR2316_ENDIAN_CTL (AR2316_DSLBASE + 0x000c) |
|---|
| 443 | | |
|---|
| 444 | | #define CONFIG_ETHERNET 0x00000040 /* Ethernet byteswap */ |
|---|
| 445 | | |
|---|
| 446 | | #define AR2316_AHB_ARB_CTL (AR2316_DSLBASE + 0x0008) |
|---|
| 447 | | #define ARB_CPU 0x00000001 /* CPU, default */ |
|---|
| 448 | | #define ARB_WLAN 0x00000002 /* WLAN */ |
|---|
| 449 | | #define ARB_MPEGTS_RSVD 0x00000004 /* MPEG-TS */ |
|---|
| 450 | | #define ARB_LOCAL 0x00000008 /* LOCAL */ |
|---|
| 451 | | #define ARB_PCI 0x00000010 /* PCI */ |
|---|
| 452 | | #define ARB_ETHERNET 0x00000020 /* Ethernet */ |
|---|
| 453 | | #define ARB_RETRY 0x00000100 /* retry policy, debug only */ |
|---|
| 454 | | |
|---|
| 455 | | #define AR531XPLUS_SPI 0xB1300000 /* SPI FLASH MMR */ |
|---|
| 456 | | |
|---|
| 457 | | #define FLASH_1MB 1 |
|---|
| 458 | | #define FLASH_2MB 2 |
|---|
| 459 | | #define FLASH_4MB 3 |
|---|
| 460 | | #define FLASH_8MB 4 |
|---|
| 461 | | #define FLASH_16MB 5 |
|---|
| 462 | | #define MAX_FLASH 6 |
|---|
| 463 | | |
|---|
| 464 | | #define STM_PAGE_SIZE 256 |
|---|
| 465 | | |
|---|
| 466 | | #define SFI_WRITE_BUFFER_SIZE 4 |
|---|
| 467 | | #define SFI_FLASH_ADDR_MASK 0x00ffffff |
|---|
| 468 | | |
|---|
| 469 | | #define STM_8MBIT_SIGNATURE 0x13 |
|---|
| 470 | | #define STM_M25P80_BYTE_COUNT 1048576 |
|---|
| 471 | | #define STM_M25P80_SECTOR_COUNT 16 |
|---|
| 472 | | #define STM_M25P80_SECTOR_SIZE 0x10000 |
|---|
| 473 | | |
|---|
| 474 | | #define STM_16MBIT_SIGNATURE 0x14 |
|---|
| 475 | | #define STM_M25P16_BYTE_COUNT 2097152 |
|---|
| 476 | | #define STM_M25P16_SECTOR_COUNT 32 |
|---|
| 477 | | #define STM_M25P16_SECTOR_SIZE 0x10000 |
|---|
| 478 | | |
|---|
| 479 | | #define STM_32MBIT_SIGNATURE 0x15 |
|---|
| 480 | | #define STM_M25P32_BYTE_COUNT 4194304 |
|---|
| 481 | | #define STM_M25P32_SECTOR_COUNT 64 |
|---|
| 482 | | #define STM_M25P32_SECTOR_SIZE 0x10000 |
|---|
| 483 | | |
|---|
| 484 | | #define STM_64MBIT_SIGNATURE 0x16 |
|---|
| 485 | | #define STM_M25P64_BYTE_COUNT 8388608 |
|---|
| 486 | | #define STM_M25P64_SECTOR_COUNT 128 |
|---|
| 487 | | #define STM_M25P64_SECTOR_SIZE 0x10000 |
|---|
| 488 | | |
|---|
| 489 | | #define STM_128MBIT_SIGNATURE 0x17 |
|---|
| 490 | | #define STM_M25P128_BYTE_COUNT 16777216 |
|---|
| 491 | | #define STM_M25P128_SECTOR_COUNT 256 |
|---|
| 492 | | #define STM_M25P128_SECTOR_SIZE 0x10000 |
|---|
| 493 | | |
|---|
| 494 | | #define STM_1MB_BYTE_COUNT STM_M25P80_BYTE_COUNT |
|---|
| 495 | | #define STM_1MB_SECTOR_COUNT STM_M25P80_SECTOR_COUNT |
|---|
| 496 | | #define STM_1MB_SECTOR_SIZE STM_M25P80_SECTOR_SIZE |
|---|
| 497 | | #define STM_2MB_BYTE_COUNT STM_M25P16_BYTE_COUNT |
|---|
| 498 | | #define STM_2MB_SECTOR_COUNT STM_M25P16_SECTOR_COUNT |
|---|
| 499 | | #define STM_2MB_SECTOR_SIZE STM_M25P16_SECTOR_SIZE |
|---|
| 500 | | #define STM_4MB_BYTE_COUNT STM_M25P32_BYTE_COUNT |
|---|
| 501 | | #define STM_4MB_SECTOR_COUNT STM_M25P32_SECTOR_COUNT |
|---|
| 502 | | #define STM_4MB_SECTOR_SIZE STM_M25P32_SECTOR_SIZE |
|---|
| 503 | | #define STM_8MB_BYTE_COUNT STM_M25P64_BYTE_COUNT |
|---|
| 504 | | #define STM_8MB_SECTOR_COUNT STM_M25P64_SECTOR_COUNT |
|---|
| 505 | | #define STM_8MB_SECTOR_SIZE STM_M25P64_SECTOR_SIZE |
|---|
| 506 | | #define STM_16MB_BYTE_COUNT STM_M25P128_BYTE_COUNT |
|---|
| 507 | | #define STM_16MB_SECTOR_COUNT STM_M25P128_SECTOR_COUNT |
|---|
| 508 | | #define STM_16MB_SECTOR_SIZE STM_M25P128_SECTOR_SIZE |
|---|
| 509 | | |
|---|
| 510 | | #define SPI_FLASH_MMR AR531XPLUS_SPI_MMR |
|---|
| 511 | | |
|---|
| 512 | | #define SPI_WRITE_ENABLE 0 |
|---|
| 513 | | #define SPI_WRITE_DISABLE 1 |
|---|
| 514 | | #define SPI_RD_STATUS 2 |
|---|
| 515 | | #define SPI_WR_STATUS 3 |
|---|
| 516 | | #define SPI_RD_DATA 4 |
|---|
| 517 | | #define SPI_FAST_RD_DATA 5 |
|---|
| 518 | | #define SPI_PAGE_PROGRAM 6 |
|---|
| 519 | | #define SPI_SECTOR_ERASE 7 |
|---|
| 520 | | #define SPI_BULK_ERASE 8 |
|---|
| 521 | | #define SPI_DEEP_PWRDOWN 9 |
|---|
| 522 | | #define SPI_RD_SIG 10 |
|---|
| 523 | | #define SPI_MAX_OPCODES 11 |
|---|
| 524 | | |
|---|
| 525 | | struct flashconfig { |
|---|
| 526 | | __u32 byte_cnt; |
|---|
| 527 | | __u32 sector_cnt; |
|---|
| 528 | | __u32 sector_size; |
|---|
| 529 | | __u32 cs_addrmask; |
|---|
| 530 | | } static flashconfig_tbl[MAX_FLASH] = { |
|---|
| 531 | | {0, 0, 0, 0}, // |
|---|
| 532 | | {STM_1MB_BYTE_COUNT, STM_1MB_SECTOR_COUNT, STM_1MB_SECTOR_SIZE, 0x0}, // |
|---|
| 533 | | {STM_2MB_BYTE_COUNT, STM_2MB_SECTOR_COUNT, STM_2MB_SECTOR_SIZE, 0x0}, // |
|---|
| 534 | | {STM_4MB_BYTE_COUNT, STM_4MB_SECTOR_COUNT, STM_4MB_SECTOR_SIZE, 0x0}, // |
|---|
| 535 | | {STM_8MB_BYTE_COUNT, STM_8MB_SECTOR_COUNT, STM_8MB_SECTOR_SIZE, 0x0}, // |
|---|
| 536 | | {STM_16MB_BYTE_COUNT, STM_16MB_SECTOR_COUNT, STM_16MB_SECTOR_SIZE, 0x0} // |
|---|
| 537 | | }; |
|---|
| 538 | | |
|---|
| 539 | | struct opcodes { |
|---|
| 540 | | __u16 code; |
|---|
| 541 | | __s8 tx_cnt; |
|---|
| 542 | | __s8 rx_cnt; |
|---|
| 543 | | } static stm_opcodes[] = { |
|---|
| 544 | | {STM_OP_WR_ENABLE, 1, 0}, // |
|---|
| 545 | | {STM_OP_WR_DISABLE, 1, 0}, // |
|---|
| 546 | | {STM_OP_RD_STATUS, 1, 1}, // |
|---|
| 547 | | {STM_OP_WR_STATUS, 1, 0}, // |
|---|
| 548 | | {STM_OP_RD_DATA, 4, 4}, // |
|---|
| 549 | | {STM_OP_FAST_RD_DATA, 5, 0}, // |
|---|
| 550 | | {STM_OP_PAGE_PGRM, 8, 0}, // |
|---|
| 551 | | {STM_OP_SECTOR_ERASE, 4, 0}, // |
|---|
| 552 | | {STM_OP_BULK_ERASE, 1, 0}, // |
|---|
| 553 | | {STM_OP_DEEP_PWRDOWN, 1, 0}, // |
|---|
| 554 | | {STM_OP_RD_SIG, 4, 1}, // |
|---|
| 555 | | }; |
|---|
| 556 | | |
|---|
| 557 | | static __u32 spiflash_regread32(int reg) |
|---|
| 558 | | { |
|---|
| 559 | | volatile __u32 *data = (__u32 *)(AR531XPLUS_SPI + reg); |
|---|
| 560 | | |
|---|
| 561 | | return (*data); |
|---|
| 562 | | } |
|---|
| 563 | | |
|---|
| 564 | | static void spiflash_regwrite32(int reg, __u32 data) |
|---|
| 565 | | { |
|---|
| 566 | | volatile __u32 *addr = (__u32 *)(AR531XPLUS_SPI + reg); |
|---|
| 567 | | |
|---|
| 568 | | *addr = data; |
|---|
| 569 | | return; |
|---|
| 570 | | } |
|---|
| 571 | | |
|---|
| 572 | | #define busy_wait(condition, wait) \ |
|---|
| 573 | | do { \ |
|---|
| 574 | | while (condition) { \ |
|---|
| 575 | | if (!wait) \ |
|---|
| 576 | | udelay(1); \ |
|---|
| 577 | | else \ |
|---|
| 578 | | udelay(wait*1000); \ |
|---|
| 579 | | } \ |
|---|
| 580 | | } while (0) |
|---|
| 581 | | |
|---|
| 582 | | static __u32 spiflash_sendcmd(int op, u32 addr) |
|---|
| 583 | | { |
|---|
| 584 | | u32 reg; |
|---|
| 585 | | u32 mask; |
|---|
| 586 | | struct opcodes *ptr_opcode; |
|---|
| 587 | | |
|---|
| 588 | | ptr_opcode = &stm_opcodes[op]; |
|---|
| 589 | | busy_wait((reg = spiflash_regread32(SPI_FLASH_CTL)) & SPI_CTL_BUSY, 0); |
|---|
| 590 | | |
|---|
| 591 | | spiflash_regwrite32(SPI_FLASH_OPCODE, |
|---|
| 592 | | ((u32)ptr_opcode->code) | (addr << 8)); |
|---|
| 593 | | |
|---|
| 594 | | reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | ptr_opcode->tx_cnt | |
|---|
| 595 | | (ptr_opcode->rx_cnt << 4) | SPI_CTL_START; |
|---|
| 596 | | |
|---|
| 597 | | spiflash_regwrite32(SPI_FLASH_CTL, reg); |
|---|
| 598 | | |
|---|
| 599 | | busy_wait(spiflash_regread32(SPI_FLASH_CTL) & SPI_CTL_BUSY, 0); |
|---|
| 600 | | |
|---|
| 601 | | if (!ptr_opcode->rx_cnt) |
|---|
| 602 | | return 0; |
|---|
| 603 | | |
|---|
| 604 | | reg = (__u32)spiflash_regread32(SPI_FLASH_DATA); |
|---|
| 605 | | |
|---|
| 606 | | switch (ptr_opcode->rx_cnt) { |
|---|
| 607 | | case 1: |
|---|
| 608 | | mask = 0x000000ff; |
|---|
| 609 | | break; |
|---|
| 610 | | case 2: |
|---|
| 611 | | mask = 0x0000ffff; |
|---|
| 612 | | break; |
|---|
| 613 | | case 3: |
|---|
| 614 | | mask = 0x00ffffff; |
|---|
| 615 | | break; |
|---|
| 616 | | default: |
|---|
| 617 | | mask = 0xffffffff; |
|---|
| 618 | | break; |
|---|
| 619 | | } |
|---|
| 620 | | reg &= mask; |
|---|
| 621 | | |
|---|
| 622 | | return reg; |
|---|
| 623 | | } |
|---|
| 624 | | |
|---|
| 625 | | static int spiflash_probe_chip(void) |
|---|
| 626 | | { |
|---|
| 627 | | unsigned int sig; |
|---|
| 628 | | int flash_size; |
|---|
| 629 | | |
|---|
| 630 | | sig = spiflash_sendcmd(SPI_RD_SIG, 0); |
|---|
| 631 | | |
|---|
| 632 | | switch (sig) { |
|---|
| 633 | | case STM_8MBIT_SIGNATURE: |
|---|
| 634 | | flash_size = FLASH_1MB; |
|---|
| 635 | | break; |
|---|
| 636 | | case STM_16MBIT_SIGNATURE: |
|---|
| 637 | | flash_size = FLASH_2MB; |
|---|
| 638 | | break; |
|---|
| 639 | | case STM_32MBIT_SIGNATURE: |
|---|
| 640 | | flash_size = FLASH_4MB; |
|---|
| 641 | | break; |
|---|
| 642 | | case STM_64MBIT_SIGNATURE: |
|---|
| 643 | | flash_size = FLASH_8MB; |
|---|
| 644 | | break; |
|---|
| 645 | | case STM_128MBIT_SIGNATURE: |
|---|
| 646 | | flash_size = FLASH_16MB; |
|---|
| 647 | | break; |
|---|
| 648 | | default: |
|---|
| 649 | | puts("Read of flash device signature failed!\n"); |
|---|
| 650 | | return (0); |
|---|
| 651 | | } |
|---|
| 652 | | |
|---|
| 653 | | return (flash_size); |
|---|
| 654 | | } |
|---|
| 655 | | |
|---|
| 656 | | static int flash_erase_nvram(unsigned int flashsize, unsigned int blocksize) |
|---|
| 657 | | { |
|---|
| 658 | | unsigned int res; |
|---|
| 659 | | unsigned int offset = nvramdetect; |
|---|
| 660 | | struct opcodes *ptr_opcode; |
|---|
| 661 | | __u32 temp, reg; |
|---|
| 662 | | if (!nvramdetect) { |
|---|
| 663 | | puts("nvram can and will not erased, since nvram was not detected on this device (maybe dd-wrt isnt installed)!\n"); |
|---|
| 664 | | return; |
|---|
| 665 | | } |
|---|
| 666 | | printf("erasing nvram at [0x%08X]\n", nvramdetect); |
|---|
| 667 | | |
|---|
| 668 | | ptr_opcode = &stm_opcodes[SPI_SECTOR_ERASE]; |
|---|
| 669 | | |
|---|
| 670 | | temp = ((__u32)offset << 8) | (__u32)(ptr_opcode->code); |
|---|
| 671 | | spiflash_sendcmd(SPI_WRITE_ENABLE, 0); |
|---|
| 672 | | busy_wait((reg = spiflash_regread32(SPI_FLASH_CTL)) & SPI_CTL_BUSY, 0); |
|---|
| 673 | | |
|---|
| 674 | | spiflash_regwrite32(SPI_FLASH_OPCODE, temp); |
|---|
| 675 | | |
|---|
| 676 | | reg = |
|---|
| 677 | | (reg & ~SPI_CTL_TX_RX_CNT_MASK) | ptr_opcode->tx_cnt | |
|---|
| 678 | | SPI_CTL_START; |
|---|
| 679 | | spiflash_regwrite32(SPI_FLASH_CTL, reg); |
|---|
| 680 | | |
|---|
| 681 | | busy_wait(spiflash_sendcmd(SPI_RD_STATUS, 0) & SPI_STATUS_WIP, 20); |
|---|
| 682 | | |
|---|
| 683 | | puts("done\n"); |
|---|
| 684 | | return 0; |
|---|
| 685 | | } |
|---|
| 686 | | |
|---|
| 687 | | static int flashdetected = 0; |
|---|
| 688 | | static int flashdetect(void) |
|---|
| 689 | | { |
|---|
| 690 | | if (flashdetected) |
|---|
| 691 | | return 0; |
|---|
| 692 | | flashsize = 8 * 1024 * 1024; |
|---|
| 693 | | flashbase = 0xa8000000; |
|---|
| 694 | | int index = 0; |
|---|
| 695 | | if (!(index = spiflash_probe_chip())) { |
|---|
| 696 | | puts("Found no serial flash device, cannot reset to factory defaults\n"); |
|---|
| 697 | | return -1; |
|---|
| 698 | | } else { |
|---|
| 699 | | flashsize = flashconfig_tbl[index].byte_cnt; |
|---|
| 700 | | sectorsize = flashconfig_tbl[index].sector_size; |
|---|
| 701 | | if (flashsize == 8 * 1024 * 1024) |
|---|
| 702 | | flashbase = 0xa8000000; |
|---|
| 703 | | else |
|---|
| 704 | | flashbase = 0xbfc00000; |
|---|
| 705 | | printf |
|---|
| 706 | | ("Found Flash device SIZE=0x%08X SECTORSIZE=0x%08X FLASHBASE=0x%08X\n", |
|---|
| 707 | | flashsize, sectorsize, flashbase); |
|---|
| 708 | | } |
|---|
| 709 | | flashdetected = 1; |
|---|
| 710 | | return 0; |
|---|
| 711 | | |
|---|
| 712 | | } |
|---|
| 713 | | #else |
|---|
| 714 | | |
|---|
| 715 | | typedef unsigned char FLASH_DATA_T; |
|---|
| 716 | | #define FLASH_P2V( _a_ ) ((volatile FLASH_DATA_T *)((unsigned int)((_a_)))) |
|---|
| 717 | | #define FLASH_BLANKVALUE (FLASH_DATA_T)(0xff) |
|---|
| 718 | | #define FLASHWORD(x) ((FLASH_DATA_T)(x)) |
|---|
| 719 | | #define FLASH_POLLING_TIMEOUT (3000000) |
|---|
| 720 | | #define FLASH_READ_ID FLASHWORD( 0x90 ) |
|---|
| 721 | | #define FLASH_WP_STATE FLASHWORD( 0x90 ) |
|---|
| 722 | | #define FLASH_RESET FLASHWORD( 0xF0 ) |
|---|
| 723 | | #define FLASH_PROGRAM FLASHWORD( 0xA0 ) |
|---|
| 724 | | #define FLASH_BLOCK_ERASE FLASHWORD( 0x30 ) |
|---|
| 725 | | #define FLASH_Query FLASHWORD( 0x98 ) // Add by Jason for CFI support |
|---|
| 726 | | |
|---|
| 727 | | #define FLASH_DATA FLASHWORD( 0x80 ) // Data complement |
|---|
| 728 | | #define FLASH_BUSY FLASHWORD( 0x40 ) // "Toggle" bit |
|---|
| 729 | | #define FLASH_ERR FLASHWORD( 0x20 ) |
|---|
| 730 | | #define FLASH_SECTOR_ERASE_TIMER FLASHWORD( 0x08 ) |
|---|
| 731 | | |
|---|
| 732 | | #define FLASH_UNLOCKED FLASHWORD( 0x00 ) |
|---|
| 733 | | #define FLASH_WP_ADDR (4) |
|---|
| 734 | | |
|---|
| 735 | | #define FLASH_SETUP_ADDR1 (0xAAA) |
|---|
| 736 | | #define FLASH_SETUP_ADDR2 (0x555) |
|---|
| 737 | | #define FLASH_VENDORID_ADDR (0x0) |
|---|
| 738 | | #define FLASH_DEVICEID_ADDR (0x2) |
|---|
| 739 | | #define FLASH_DEVICEID_ADDR2 (0x1c) |
|---|
| 740 | | #define FLASH_DEVICEID_ADDR3 (0x1e) |
|---|
| 741 | | //#define FLASH_WP_ADDR (0x12) |
|---|
| 742 | | #define FLASH_SETUP_CODE1 FLASHWORD( 0xAA ) |
|---|
| 743 | | #define FLASH_SETUP_CODE2 FLASHWORD( 0x55 ) |
|---|
| 744 | | #define FLASH_SETUP_ERASE FLASHWORD( 0x80 ) |
|---|
| 745 | | #define FLASH_ERR_OK 0x0 |
|---|
| 746 | | #define FLASH_ERR_DRV_TIMEOUT -1 |
|---|
| 747 | | |
|---|
| 748 | | /*static void |
|---|
| 749 | | flash_query(void* data) |
|---|
| 750 | | { |
|---|
| 751 | | volatile FLASH_DATA_T *ROM; |
|---|
| 752 | | volatile FLASH_DATA_T *f_s1, *f_s2; |
|---|
| 753 | | FLASH_DATA_T* id = (FLASH_DATA_T*) data; |
|---|
| 754 | | FLASH_DATA_T w; |
|---|
| 755 | | long timeout = 50000; |
|---|
| 756 | | |
|---|
| 757 | | ROM = (volatile FLASH_DATA_T*) ((unsigned int)nvramdetect & ~(0x800000-1)); |
|---|
| 758 | | *(FLASH_P2V(ROM)) = FLASH_RESET; |
|---|
| 759 | | |
|---|
| 760 | | f_s1 = FLASH_P2V(ROM+FLASH_SETUP_ADDR1); |
|---|
| 761 | | f_s2 = FLASH_P2V(ROM+FLASH_SETUP_ADDR2); |
|---|
| 762 | | |
|---|
| 763 | | *f_s1 = FLASH_RESET; |
|---|
| 764 | | w = *(FLASH_P2V(ROM)); |
|---|
| 765 | | |
|---|
| 766 | | *f_s1 = FLASH_SETUP_CODE1; |
|---|
| 767 | | *f_s2 = FLASH_SETUP_CODE2; |
|---|
| 768 | | *f_s1 = FLASH_READ_ID; |
|---|
| 769 | | |
|---|
| 770 | | id[0] = -1; |
|---|
| 771 | | id[1] = -1; |
|---|
| 772 | | |
|---|
| 773 | | // Manufacturers' code |
|---|
| 774 | | id[0] = *(FLASH_P2V(ROM+FLASH_VENDORID_ADDR)); |
|---|
| 775 | | // Part number |
|---|
| 776 | | id[1] = *(FLASH_P2V(ROM+FLASH_DEVICEID_ADDR)); |
|---|
| 777 | | id[2] = *(FLASH_P2V(ROM+FLASH_DEVICEID_ADDR2)); |
|---|
| 778 | | id[3] = *(FLASH_P2V(ROM+FLASH_DEVICEID_ADDR3)); |
|---|
| 779 | | |
|---|
| 780 | | *(FLASH_P2V(ROM)) = FLASH_RESET; |
|---|
| 781 | | |
|---|
| 782 | | // Stall, waiting for flash to return to read mode. |
|---|
| 783 | | while ((--timeout != 0) && (w != *(FLASH_P2V(ROM)))) ; |
|---|
| 784 | | } |
|---|
| 785 | | */ |
|---|
| 786 | | |
|---|
| 787 | | #define AR531X_FLASHCTL 0xb8400000 |
|---|
| 788 | | #define AR531X_FLASHCTL0 (AR531X_FLASHCTL + 0x00) |
|---|
| 789 | | #define AR531X_FLASHCTL1 (AR531X_FLASHCTL + 0x04) |
|---|
| 790 | | #define AR531X_FLASHCTL2 (AR531X_FLASHCTL + 0x08) |
|---|
| 791 | | #define FLASHCTL_IDCY 0x0000000f /* Idle cycle turn around time */ |
|---|
| 792 | | #define FLASHCTL_IDCY_S 0 |
|---|
| 793 | | #define FLASHCTL_WST1 0x000003e0 /* Wait state 1 */ |
|---|
| 794 | | #define FLASHCTL_WST1_S 5 |
|---|
| 795 | | #define FLASHCTL_RBLE 0x00000400 /* Read byte lane enable */ |
|---|
| 796 | | #define FLASHCTL_WST2 0x0000f800 /* Wait state 2 */ |
|---|
| 797 | | #define FLASHCTL_WST2_S 11 |
|---|
| 798 | | #define FLASHCTL_AC 0x00070000 /* Flash address check (added) */ |
|---|
| 799 | | #define FLASHCTL_AC_S 16 |
|---|
| 800 | | #define FLASHCTL_AC_128K 0x00000000 |
|---|
| 801 | | #define FLASHCTL_AC_256K 0x00010000 |
|---|
| 802 | | #define FLASHCTL_AC_512K 0x00020000 |
|---|
| 803 | | #define FLASHCTL_AC_1M 0x00030000 |
|---|
| 804 | | #define FLASHCTL_AC_2M 0x00040000 |
|---|
| 805 | | #define FLASHCTL_AC_4M 0x00050000 |
|---|
| 806 | | #define FLASHCTL_AC_8M 0x00060000 |
|---|
| 807 | | #define FLASHCTL_AC_RES 0x00070000 /* 16MB is not supported */ |
|---|
| 808 | | #define FLASHCTL_E 0x00080000 /* Flash bank enable (added) */ |
|---|
| 809 | | #define FLASHCTL_BUSERR 0x01000000 /* Bus transfer error status flag */ |
|---|
| 810 | | #define FLASHCTL_WPERR 0x02000000 /* Write protect error status flag */ |
|---|
| 811 | | #define FLASHCTL_WP 0x04000000 /* Write protect */ |
|---|
| 812 | | #define FLASHCTL_BM 0x08000000 /* Burst mode */ |
|---|
| 813 | | #define FLASHCTL_MW 0x30000000 /* Memory width */ |
|---|
| 814 | | #define FLASHCTL_MWx8 0x00000000 /* Memory width x8 */ |
|---|
| 815 | | #define FLASHCTL_MWx16 0x10000000 /* Memory width x16 */ |
|---|
| 816 | | #define FLASHCTL_MWx32 0x20000000 /* Memory width x32 (not supported) */ |
|---|
| 817 | | #define FLASHCTL_ATNR 0x00000000 /* Access type == no retry */ |
|---|
| 818 | | #define FLASHCTL_ATR 0x80000000 /* Access type == retry every */ |
|---|
| 819 | | #define FLASHCTL_ATR4 0xc0000000 /* Access type == retry every 4 */ |
|---|
| 820 | | |
|---|
| 821 | | static int flash_erase_nvram(unsigned int flashsize, unsigned int blocksize) |
|---|
| 822 | | { |
|---|
| 823 | | int i, ticks; |
|---|
| 824 | | unsigned short val; |
|---|
| 825 | | if (!nvramdetect) { |
|---|
| 826 | | puts("nvram can and will not erased, since nvram was not detected on this device (maybe dd-wrt isnt installed)!\n"); |
|---|
| 827 | | return; |
|---|
| 828 | | } |
|---|
| 829 | | unsigned int flash_ctl = sysRegRead(AR531X_FLASHCTL0); |
|---|
| 830 | | |
|---|
| 831 | | FLASH_DATA_T id[4]; |
|---|
| 832 | | // puts("read id\n"); |
|---|
| 833 | | // flash_query(id); |
|---|
| 834 | | // printf("FLASH MANID: %X DEVID: %X DEVID2: %X DEVID3: %X\n",id[0],id[1],id[2],id[3]); |
|---|
| 835 | | |
|---|
| 836 | | printf("erasing nvram at [0x%08X]\n", nvramdetect); |
|---|
| 837 | | |
|---|
| 838 | | volatile FLASH_DATA_T *ROM, *BANK; |
|---|
| 839 | | volatile FLASH_DATA_T *b_p = (FLASH_DATA_T *) (nvramdetect); |
|---|
| 840 | | volatile FLASH_DATA_T *b_v; |
|---|
| 841 | | volatile FLASH_DATA_T *f_s0, *f_s1, *f_s2; |
|---|
| 842 | | int timeout = 50000; |
|---|
| 843 | | FLASH_DATA_T state; |
|---|
| 844 | | int len; |
|---|
| 845 | | BANK = ROM = |
|---|
| 846 | | (volatile FLASH_DATA_T *)((unsigned long)nvramdetect & |
|---|
| 847 | | ~(0x800000 - 1)); |
|---|
| 848 | | f_s0 = FLASH_P2V(BANK); |
|---|
| 849 | | f_s1 = FLASH_P2V(BANK + FLASH_SETUP_ADDR1); |
|---|
| 850 | | f_s2 = FLASH_P2V(BANK + FLASH_SETUP_ADDR2); |
|---|
| 851 | | len = blocksize; |
|---|
| 852 | | int res = FLASH_ERR_OK; |
|---|
| 853 | | |
|---|
| 854 | | *f_s1 = FLASH_SETUP_CODE1; |
|---|
| 855 | | *f_s2 = FLASH_SETUP_CODE2; |
|---|
| 856 | | *f_s1 = FLASH_WP_STATE; |
|---|
| 857 | | state = *FLASH_P2V(b_p + FLASH_WP_ADDR); |
|---|
| 858 | | *f_s0 = FLASH_RESET; |
|---|
| 859 | | |
|---|
| 860 | | if (FLASH_UNLOCKED != state) { |
|---|
| 861 | | *FLASH_P2V(ROM) = FLASH_RESET; |
|---|
| 862 | | } |
|---|
| 863 | | |
|---|
| 864 | | b_v = FLASH_P2V(b_p); |
|---|
| 865 | | |
|---|
| 866 | | *f_s1 = FLASH_SETUP_CODE1; |
|---|
| 867 | | *f_s2 = FLASH_SETUP_CODE2; |
|---|
| 868 | | *f_s1 = FLASH_SETUP_ERASE; |
|---|
| 869 | | *f_s1 = FLASH_SETUP_CODE1; |
|---|
| 870 | | *f_s2 = FLASH_SETUP_CODE2; |
|---|
| 871 | | *b_v = FLASH_BLOCK_ERASE; |
|---|
| 872 | | timeout = FLASH_POLLING_TIMEOUT; |
|---|
| 873 | | while (1) { |
|---|
| 874 | | state = *b_v; |
|---|
| 875 | | if ((state & FLASH_SECTOR_ERASE_TIMER) |
|---|
| 876 | | == FLASH_SECTOR_ERASE_TIMER) |
|---|
| 877 | | break; |
|---|
| 878 | | udelay(1); |
|---|
| 879 | | if (--timeout == 0) { |
|---|
| 880 | | puts("flash erase timeout\n"); |
|---|
| 881 | | res = FLASH_ERR_DRV_TIMEOUT; |
|---|
| 882 | | break; |
|---|
| 883 | | } |
|---|
| 884 | | } |
|---|
| 885 | | if (FLASH_ERR_OK == res) { |
|---|
| 886 | | timeout = FLASH_POLLING_TIMEOUT; |
|---|
| 887 | | while (1) { |
|---|
| 888 | | state = *b_v; |
|---|
| 889 | | if (FLASH_BLANKVALUE == state) { |
|---|
| 890 | | break; |
|---|
| 891 | | } |
|---|
| 892 | | udelay(1); |
|---|
| 893 | | if (--timeout == 0) { |
|---|
| 894 | | puts("flash erase timeout while waiting for erase complete\n"); |
|---|
| 895 | | res = FLASH_ERR_DRV_TIMEOUT; |
|---|
| 896 | | break; |
|---|
| 897 | | } |
|---|
| 898 | | } |
|---|
| 899 | | } |
|---|
| 900 | | |
|---|
| 901 | | if (FLASH_ERR_OK != res) |
|---|
| 902 | | *FLASH_P2V(ROM) = FLASH_RESET; |
|---|
| 903 | | |
|---|
| 904 | | b_v = FLASH_P2V(b_p++); |
|---|
| 905 | | if (*b_v != FLASH_BLANKVALUE) { |
|---|
| 906 | | if (FLASH_ERR_OK == res) { |
|---|
| 907 | | puts("erase verify failed\n"); |
|---|
| 908 | | } else { |
|---|
| 909 | | puts("nvram erase done\n"); |
|---|
| 910 | | } |
|---|
| 911 | | return 0; |
|---|
| 912 | | } |
|---|
| 913 | | |
|---|
| 914 | | } |
|---|
| 915 | | |
|---|
| 916 | | #endif |
|---|