Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

spi: aspeed: Improve clock, timing and address

Merge series from Chin-Ting Kuo <chin-ting_kuo@aspeedtech.com>:

This patch series introduces several improvements to the
ASPEED SPI driver, targeting better stability, compatibility
and, flexibility across multiple ASPEED platforms.

Key changes include:

* Clock selection strategy update
Improves fallback logic when timing calibration is skipped or
fails, ensuring reliable boot behavior.

* Timing calibration enhancement for AST2600
Replaces the previous "first-pass" strategy with a more robust
algorithm that selects the optimal timing point.

* Default address decoding assignment
Ensures each chip select (CS) has a valid decoding range during
probe, avoiding detection failures due to missing or incorrect
bootloader setup.

* Centralized address decoding management
Refactors the decoding logic to centrally assign address windows,
preventing improper trimming and improving layout flexibility.

* Per-platform decoding adjustment
Introduces platform-specific `adjust_window` callbacks to handle
platform specific hardware constraints for address decoding range.

* Selective memory mapping
Optimizes memory usage by mapping only the required address window
per CS to avoid exhaustion.

+493 -159
+493 -159
drivers/spi/spi-aspeed-smc.c
··· 7 7 */ 8 8 9 9 #include <linux/clk.h> 10 + #include <linux/io.h> 10 11 #include <linux/module.h> 11 12 #include <linux/of.h> 12 13 #include <linux/of_platform.h> ··· 68 67 u32 ahb_window_size; 69 68 u32 ctl_val[ASPEED_SPI_MAX]; 70 69 u32 clk_freq; 70 + bool force_user_mode; 71 71 }; 72 72 73 73 struct aspeed_spi_data { ··· 80 78 u32 timing; 81 79 u32 hclk_mask; 82 80 u32 hdiv_max; 81 + u32 min_window_size; 83 82 84 83 u32 (*segment_start)(struct aspeed_spi *aspi, u32 reg); 85 84 u32 (*segment_end)(struct aspeed_spi *aspi, u32 reg); 86 85 u32 (*segment_reg)(struct aspeed_spi *aspi, u32 start, u32 end); 86 + int (*adjust_window)(struct aspeed_spi *aspi); 87 + u32 (*get_clk_div)(struct aspeed_spi_chip *chip, u32 hz); 87 88 int (*calibrate)(struct aspeed_spi_chip *chip, u32 hdiv, 88 89 const u8 *golden_buf, u8 *test_buf); 89 90 }; ··· 97 92 const struct aspeed_spi_data *data; 98 93 99 94 void __iomem *regs; 100 - void __iomem *ahb_base; 101 95 u32 ahb_base_phy; 102 96 u32 ahb_window_size; 97 + u32 num_cs; 103 98 struct device *dev; 104 99 105 100 struct clk *clk; ··· 381 376 spi_get_chipselect(mem->spi, 0)); 382 377 } 383 378 384 - struct aspeed_spi_window { 385 - u32 cs; 386 - u32 offset; 387 - u32 size; 388 - }; 389 - 390 - static void aspeed_spi_get_windows(struct aspeed_spi *aspi, 391 - struct aspeed_spi_window windows[ASPEED_SPI_MAX_NUM_CS]) 379 + static int aspeed_spi_set_window(struct aspeed_spi *aspi) 392 380 { 393 - const struct aspeed_spi_data *data = aspi->data; 394 - u32 reg_val; 381 + struct device *dev = aspi->dev; 382 + off_t offset = 0; 383 + phys_addr_t start; 384 + phys_addr_t end; 385 + void __iomem *seg_reg_base = aspi->regs + CE0_SEGMENT_ADDR_REG; 386 + void __iomem *seg_reg; 387 + u32 seg_val_backup; 388 + u32 seg_val; 395 389 u32 cs; 390 + size_t window_size; 396 391 397 392 for (cs = 0; cs < aspi->data->max_cs; cs++) { 398 - reg_val = readl(aspi->regs + CE0_SEGMENT_ADDR_REG + cs * 4); 399 - windows[cs].cs = cs; 400 - windows[cs].size = data->segment_end(aspi, reg_val) - 401 - data->segment_start(aspi, reg_val); 402 - windows[cs].offset = data->segment_start(aspi, reg_val) - aspi->ahb_base_phy; 403 - dev_vdbg(aspi->dev, "CE%d offset=0x%.8x size=0x%x\n", cs, 404 - windows[cs].offset, windows[cs].size); 393 + if (aspi->chips[cs].ahb_base) { 394 + iounmap(aspi->chips[cs].ahb_base); 395 + aspi->chips[cs].ahb_base = NULL; 396 + } 405 397 } 398 + 399 + for (cs = 0; cs < aspi->data->max_cs; cs++) { 400 + seg_reg = seg_reg_base + cs * 4; 401 + seg_val_backup = readl(seg_reg); 402 + 403 + start = aspi->ahb_base_phy + offset; 404 + window_size = aspi->chips[cs].ahb_window_size; 405 + end = start + window_size; 406 + 407 + seg_val = aspi->data->segment_reg(aspi, start, end); 408 + writel(seg_val, seg_reg); 409 + 410 + /* 411 + * Restore initial value if something goes wrong or the segment 412 + * register is written protected. 413 + */ 414 + if (seg_val != readl(seg_reg)) { 415 + dev_warn(dev, "CE%d expected window [ 0x%.9llx - 0x%.9llx ] %zdMB\n", 416 + cs, (u64)start, (u64)end - 1, window_size >> 20); 417 + writel(seg_val_backup, seg_reg); 418 + window_size = aspi->data->segment_end(aspi, seg_val_backup) - 419 + aspi->data->segment_start(aspi, seg_val_backup); 420 + aspi->chips[cs].ahb_window_size = window_size; 421 + end = start + window_size; 422 + } 423 + 424 + if (window_size != 0) 425 + dev_dbg(dev, "CE%d window [ 0x%.9llx - 0x%.9llx ] %zdMB\n", 426 + cs, (u64)start, (u64)end - 1, window_size >> 20); 427 + else 428 + dev_dbg(dev, "CE%d window closed\n", cs); 429 + 430 + offset += window_size; 431 + if (offset > aspi->ahb_window_size) { 432 + dev_err(dev, "CE%d offset value 0x%llx is too large.\n", 433 + cs, (u64)offset); 434 + return -ENOSPC; 435 + } 436 + 437 + /* 438 + * No need to map the address deocding range when 439 + * - window size is 0. 440 + * - the CS is unused. 441 + */ 442 + if (window_size == 0 || cs >= aspi->num_cs) 443 + continue; 444 + 445 + aspi->chips[cs].ahb_base = 446 + devm_ioremap(aspi->dev, start, window_size); 447 + if (!aspi->chips[cs].ahb_base) { 448 + dev_err(aspi->dev, 449 + "Fail to remap window [0x%.9llx - 0x%.9llx]\n", 450 + (u64)start, (u64)end - 1); 451 + return -ENOMEM; 452 + } 453 + } 454 + 455 + return 0; 406 456 } 407 457 408 - /* 409 - * On the AST2600, some CE windows are closed by default at reset but 410 - * U-Boot should open all. 411 - */ 412 - static int aspeed_spi_chip_set_default_window(struct aspeed_spi_chip *chip) 458 + static const struct aspeed_spi_data ast2500_spi_data; 459 + static const struct aspeed_spi_data ast2600_spi_data; 460 + static const struct aspeed_spi_data ast2600_fmc_data; 461 + 462 + static int aspeed_spi_chip_set_default_window(struct aspeed_spi *aspi) 413 463 { 414 - struct aspeed_spi *aspi = chip->aspi; 415 - struct aspeed_spi_window windows[ASPEED_SPI_MAX_NUM_CS] = { 0 }; 416 - struct aspeed_spi_window *win = &windows[chip->cs]; 464 + u32 cs; 417 465 418 466 /* No segment registers for the AST2400 SPI controller */ 419 467 if (aspi->data == &ast2400_spi_data) { 420 - win->offset = 0; 421 - win->size = aspi->ahb_window_size; 422 - } else { 423 - aspeed_spi_get_windows(aspi, windows); 468 + aspi->chips[0].ahb_base = devm_ioremap(aspi->dev, 469 + aspi->ahb_base_phy, 470 + aspi->ahb_window_size); 471 + aspi->chips[0].ahb_window_size = aspi->ahb_window_size; 472 + return 0; 424 473 } 425 474 426 - chip->ahb_base = aspi->ahb_base + win->offset; 427 - chip->ahb_window_size = win->size; 475 + /* Assign the minimum window size to each CS */ 476 + for (cs = 0; cs < aspi->num_cs; cs++) { 477 + aspi->chips[cs].ahb_window_size = aspi->data->min_window_size; 478 + dev_dbg(aspi->dev, "CE%d default window [ 0x%.8x - 0x%.8x ]", 479 + cs, aspi->ahb_base_phy + aspi->data->min_window_size * cs, 480 + aspi->ahb_base_phy + aspi->data->min_window_size * cs - 1); 481 + } 428 482 429 - dev_dbg(aspi->dev, "CE%d default window [ 0x%.8x - 0x%.8x ] %dMB", 430 - chip->cs, aspi->ahb_base_phy + win->offset, 431 - aspi->ahb_base_phy + win->offset + win->size - 1, 432 - win->size >> 20); 483 + /* Close unused CS */ 484 + for (cs = aspi->num_cs; cs < aspi->data->max_cs; cs++) 485 + aspi->chips[cs].ahb_window_size = 0; 433 486 434 - return chip->ahb_window_size ? 0 : -1; 487 + if (aspi->data->adjust_window) 488 + aspi->data->adjust_window(aspi); 489 + 490 + return aspeed_spi_set_window(aspi); 435 491 } 436 492 437 - static int aspeed_spi_set_window(struct aspeed_spi *aspi, 438 - const struct aspeed_spi_window *win) 493 + /* 494 + * As the flash size grows up, we need to trim some decoding 495 + * size if needed for the sake of conforming the maximum 496 + * decoding size. We trim the decoding size from the rear CS 497 + * to avoid affecting the default boot up sequence, usually, 498 + * from CS0. Notice, if a CS decoding size is trimmed, 499 + * command mode may not work perfectly on that CS, but it only 500 + * affect performance and the debug function. 501 + */ 502 + static int aspeed_spi_trim_window_size(struct aspeed_spi *aspi) 439 503 { 440 - u32 start = aspi->ahb_base_phy + win->offset; 441 - u32 end = start + win->size; 442 - void __iomem *seg_reg = aspi->regs + CE0_SEGMENT_ADDR_REG + win->cs * 4; 443 - u32 seg_val_backup = readl(seg_reg); 444 - u32 seg_val = aspi->data->segment_reg(aspi, start, end); 504 + struct aspeed_spi_chip *chips = aspi->chips; 505 + size_t total_sz; 506 + int cs = aspi->data->max_cs - 1; 507 + u32 i; 508 + bool trimmed = false; 445 509 446 - if (seg_val == seg_val_backup) 447 - return 0; 510 + do { 511 + total_sz = 0; 512 + for (i = 0; i < aspi->data->max_cs; i++) 513 + total_sz += chips[i].ahb_window_size; 448 514 449 - writel(seg_val, seg_reg); 515 + if (cs < 0) 516 + return -ENOMEM; 450 517 451 - /* 452 - * Restore initial value if something goes wrong else we could 453 - * loose access to the chip. 454 - */ 455 - if (seg_val != readl(seg_reg)) { 456 - dev_err(aspi->dev, "CE%d invalid window [ 0x%.8x - 0x%.8x ] %dMB", 457 - win->cs, start, end - 1, win->size >> 20); 458 - writel(seg_val_backup, seg_reg); 459 - return -EIO; 518 + if (chips[cs].ahb_window_size <= aspi->data->min_window_size) { 519 + cs--; 520 + continue; 521 + } 522 + 523 + if (total_sz > aspi->ahb_window_size) { 524 + chips[cs].ahb_window_size -= 525 + aspi->data->min_window_size; 526 + total_sz -= aspi->data->min_window_size; 527 + /* 528 + * If the ahb window size is ever trimmed, only user 529 + * mode can be adopted to access the whole flash. 530 + */ 531 + chips[cs].force_user_mode = true; 532 + trimmed = true; 533 + } 534 + } while (total_sz > aspi->ahb_window_size); 535 + 536 + if (trimmed) { 537 + dev_warn(aspi->dev, "Window size after triming:\n"); 538 + for (cs = 0; cs < aspi->data->max_cs; cs++) { 539 + dev_warn(aspi->dev, "CE%d: 0x%08x\n", 540 + cs, chips[cs].ahb_window_size); 541 + } 460 542 } 461 543 462 - if (win->size) 463 - dev_dbg(aspi->dev, "CE%d new window [ 0x%.8x - 0x%.8x ] %dMB", 464 - win->cs, start, end - 1, win->size >> 20); 465 - else 466 - dev_dbg(aspi->dev, "CE%d window closed", win->cs); 544 + return 0; 545 + } 546 + 547 + static int aspeed_adjust_window_ast2400(struct aspeed_spi *aspi) 548 + { 549 + int ret; 550 + int cs; 551 + struct aspeed_spi_chip *chips = aspi->chips; 552 + 553 + /* Close unused CS. */ 554 + for (cs = aspi->num_cs; cs < aspi->data->max_cs; cs++) 555 + chips[cs].ahb_window_size = 0; 556 + 557 + ret = aspeed_spi_trim_window_size(aspi); 558 + if (ret != 0) 559 + return ret; 560 + 561 + return 0; 562 + } 563 + 564 + /* 565 + * For AST2500, the minimum address decoding size for each CS 566 + * is 8MB. This address decoding size is mandatory for each 567 + * CS no matter whether it will be used. This is a HW limitation. 568 + */ 569 + static int aspeed_adjust_window_ast2500(struct aspeed_spi *aspi) 570 + { 571 + int ret; 572 + int cs, i; 573 + u32 cum_size, rem_size; 574 + struct aspeed_spi_chip *chips = aspi->chips; 575 + 576 + /* Assign min_window_sz to unused CS. */ 577 + for (cs = aspi->num_cs; cs < aspi->data->max_cs; cs++) { 578 + if (chips[cs].ahb_window_size < aspi->data->min_window_size) 579 + chips[cs].ahb_window_size = 580 + aspi->data->min_window_size; 581 + } 582 + 583 + /* 584 + * If command mode or normal mode is used by dirmap read, the start 585 + * address of a window should be multiple of its related flash size. 586 + * Namely, the total windows size from flash 0 to flash N should 587 + * be multiple of the size of flash (N + 1). 588 + */ 589 + for (cs = aspi->num_cs - 1; cs >= 0; cs--) { 590 + cum_size = 0; 591 + for (i = 0; i < cs; i++) 592 + cum_size += chips[i].ahb_window_size; 593 + 594 + rem_size = cum_size % chips[cs].ahb_window_size; 595 + if (chips[cs].ahb_window_size != 0 && rem_size != 0) 596 + chips[0].ahb_window_size += 597 + chips[cs].ahb_window_size - rem_size; 598 + } 599 + 600 + ret = aspeed_spi_trim_window_size(aspi); 601 + if (ret != 0) 602 + return ret; 603 + 604 + /* The total window size of AST2500 SPI1 CS0 and CS1 must be 128MB */ 605 + if (aspi->data == &ast2500_spi_data) 606 + chips[1].ahb_window_size = 607 + 0x08000000 - chips[0].ahb_window_size; 608 + 609 + return 0; 610 + } 611 + 612 + static int aspeed_adjust_window_ast2600(struct aspeed_spi *aspi) 613 + { 614 + int ret; 615 + int cs, i; 616 + u32 cum_size, rem_size; 617 + struct aspeed_spi_chip *chips = aspi->chips; 618 + 619 + /* Close unused CS. */ 620 + for (cs = aspi->num_cs; cs < aspi->data->max_cs; cs++) 621 + chips[cs].ahb_window_size = 0; 622 + 623 + /* 624 + * If command mode or normal mode is used by dirmap read, the start 625 + * address of a window should be multiple of its related flash size. 626 + * Namely, the total windows size from flash 0 to flash N should 627 + * be multiple of the size of flash (N + 1). 628 + */ 629 + for (cs = aspi->num_cs - 1; cs >= 0; cs--) { 630 + cum_size = 0; 631 + for (i = 0; i < cs; i++) 632 + cum_size += chips[i].ahb_window_size; 633 + 634 + rem_size = cum_size % chips[cs].ahb_window_size; 635 + if (chips[cs].ahb_window_size != 0 && rem_size != 0) 636 + chips[0].ahb_window_size += 637 + chips[cs].ahb_window_size - rem_size; 638 + } 639 + 640 + ret = aspeed_spi_trim_window_size(aspi); 641 + if (ret != 0) 642 + return ret; 467 643 468 644 return 0; 469 645 } ··· 655 469 * - ioremap each window, not strictly necessary since the overall window 656 470 * is correct. 657 471 */ 658 - static const struct aspeed_spi_data ast2500_spi_data; 659 - static const struct aspeed_spi_data ast2600_spi_data; 660 - static const struct aspeed_spi_data ast2600_fmc_data; 661 - 662 472 static int aspeed_spi_chip_adjust_window(struct aspeed_spi_chip *chip, 663 473 u32 local_offset, u32 size) 664 474 { 665 475 struct aspeed_spi *aspi = chip->aspi; 666 - struct aspeed_spi_window windows[ASPEED_SPI_MAX_NUM_CS] = { 0 }; 667 - struct aspeed_spi_window *win = &windows[chip->cs]; 668 476 int ret; 669 477 670 478 /* No segment registers for the AST2400 SPI controller */ 671 479 if (aspi->data == &ast2400_spi_data) 672 480 return 0; 673 481 674 - /* 675 - * Due to an HW issue on the AST2500 SPI controller, the CE0 676 - * window size should be smaller than the maximum 128MB. 677 - */ 678 - if (aspi->data == &ast2500_spi_data && chip->cs == 0 && size == SZ_128M) { 679 - size = 120 << 20; 680 - dev_info(aspi->dev, "CE%d window resized to %dMB (AST2500 HW quirk)", 681 - chip->cs, size >> 20); 682 - } 683 - 684 - /* 685 - * The decoding size of AST2600 SPI controller should set at 686 - * least 2MB. 687 - */ 688 - if ((aspi->data == &ast2600_spi_data || aspi->data == &ast2600_fmc_data) && 689 - size < SZ_2M) { 690 - size = SZ_2M; 691 - dev_info(aspi->dev, "CE%d window resized to %dMB (AST2600 Decoding)", 692 - chip->cs, size >> 20); 693 - } 694 - 695 - aspeed_spi_get_windows(aspi, windows); 696 - 697 482 /* Adjust this chip window */ 698 - win->offset += local_offset; 699 - win->size = size; 483 + aspi->chips[chip->cs].ahb_window_size = size; 700 484 701 - if (win->offset + win->size > aspi->ahb_window_size) { 702 - win->size = aspi->ahb_window_size - win->offset; 703 - dev_warn(aspi->dev, "CE%d window resized to %dMB", chip->cs, win->size >> 20); 704 - } 485 + /* Adjust the overall windows size regarding each platform */ 486 + if (aspi->data->adjust_window) 487 + aspi->data->adjust_window(aspi); 705 488 706 - ret = aspeed_spi_set_window(aspi, win); 489 + ret = aspeed_spi_set_window(aspi); 707 490 if (ret) 708 491 return ret; 709 492 710 - /* Update chip mapping info */ 711 - chip->ahb_base = aspi->ahb_base + win->offset; 712 - chip->ahb_window_size = win->size; 713 - 714 - /* 715 - * Also adjust next chip window to make sure that it does not 716 - * overlap with the current window. 717 - */ 718 - if (chip->cs < aspi->data->max_cs - 1) { 719 - struct aspeed_spi_window *next = &windows[chip->cs + 1]; 720 - 721 - /* Change offset and size to keep the same end address */ 722 - if ((next->offset + next->size) > (win->offset + win->size)) 723 - next->size = (next->offset + next->size) - (win->offset + win->size); 724 - else 725 - next->size = 0; 726 - next->offset = win->offset + win->size; 727 - 728 - aspeed_spi_set_window(aspi, next); 729 - } 730 493 return 0; 731 494 } 732 495 ··· 754 619 struct aspeed_spi_chip *chip = &aspi->chips[spi_get_chipselect(desc->mem->spi, 0)]; 755 620 756 621 /* Switch to USER command mode if mapping window is too small */ 757 - if (chip->ahb_window_size < offset + len) { 622 + if (chip->ahb_window_size < offset + len || chip->force_user_mode) { 758 623 int ret; 759 624 760 625 ret = aspeed_spi_read_user(chip, &desc->info.op_tmpl, offset, len, buf); ··· 812 677 if (data->hastype) 813 678 aspeed_spi_chip_set_type(aspi, cs, CONFIG_TYPE_SPI); 814 679 815 - if (aspeed_spi_chip_set_default_window(chip) < 0) { 816 - dev_warn(aspi->dev, "CE%d window invalid", cs); 817 - return -EINVAL; 818 - } 819 - 820 680 aspeed_spi_chip_enable(aspi, cs, true); 821 681 822 682 chip->ctl_val[ASPEED_SPI_BASE] = CTRL_CE_STOP_ACTIVE | CTRL_IO_MODE_USER; ··· 864 734 if (IS_ERR(aspi->regs)) 865 735 return PTR_ERR(aspi->regs); 866 736 867 - aspi->ahb_base = devm_platform_get_and_ioremap_resource(pdev, 1, &res); 868 - if (IS_ERR(aspi->ahb_base)) { 869 - dev_err(dev, "missing AHB mapping window\n"); 870 - return PTR_ERR(aspi->ahb_base); 737 + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 738 + if (IS_ERR(res)) { 739 + dev_err(dev, "missing AHB memory\n"); 740 + return PTR_ERR(res); 871 741 } 872 742 873 743 aspi->ahb_window_size = resource_size(res); ··· 892 762 ctlr->mem_ops = &aspeed_spi_mem_ops; 893 763 ctlr->setup = aspeed_spi_setup; 894 764 ctlr->cleanup = aspeed_spi_cleanup; 895 - ctlr->num_chipselect = data->max_cs; 765 + ctlr->num_chipselect = of_get_available_child_count(dev->of_node); 896 766 ctlr->dev.of_node = dev->of_node; 767 + 768 + aspi->num_cs = ctlr->num_chipselect; 769 + 770 + ret = aspeed_spi_chip_set_default_window(aspi); 771 + if (ret) { 772 + dev_err(&pdev->dev, "fail to set default window\n"); 773 + return ret; 774 + } 897 775 898 776 ret = devm_spi_register_controller(dev, ctlr); 899 777 if (ret) ··· 1080 942 } 1081 943 1082 944 static const u32 aspeed_spi_hclk_divs[] = { 1083 - 0xf, /* HCLK */ 1084 - 0x7, /* HCLK/2 */ 1085 - 0xe, /* HCLK/3 */ 1086 - 0x6, /* HCLK/4 */ 1087 - 0xd, /* HCLK/5 */ 945 + /* HCLK, HCLK/2, HCLK/3, HCLK/4, HCLK/5, ..., HCLK/16 */ 946 + 0xf, 0x7, 0xe, 0x6, 0xd, 947 + 0x5, 0xc, 0x4, 0xb, 0x3, 948 + 0xa, 0x2, 0x9, 0x1, 0x8, 949 + 0x0 1088 950 }; 1089 951 1090 952 #define ASPEED_SPI_HCLK_DIV(i) \ 1091 953 (aspeed_spi_hclk_divs[(i) - 1] << CTRL_FREQ_SEL_SHIFT) 954 + 955 + /* Transfer maximum clock frequency to register setting */ 956 + static u32 aspeed_get_clk_div_ast2400(struct aspeed_spi_chip *chip, 957 + u32 max_hz) 958 + { 959 + struct device *dev = chip->aspi->dev; 960 + u32 hclk_clk = chip->aspi->clk_freq; 961 + u32 div_ctl = 0; 962 + u32 i; 963 + bool found = false; 964 + 965 + /* FMC/SPIR10[11:8] */ 966 + for (i = 1; i <= ARRAY_SIZE(aspeed_spi_hclk_divs); i++) { 967 + if (hclk_clk / i <= max_hz) { 968 + found = true; 969 + break; 970 + } 971 + } 972 + 973 + if (found) { 974 + div_ctl = ASPEED_SPI_HCLK_DIV(i); 975 + chip->clk_freq = hclk_clk / i; 976 + } 977 + 978 + dev_dbg(dev, "found: %s, hclk: %d, max_clk: %d\n", 979 + found ? "yes" : "no", hclk_clk, max_hz); 980 + 981 + if (found) { 982 + dev_dbg(dev, "h_div: 0x%08x, speed: %d\n", 983 + div_ctl, chip->clk_freq); 984 + } 985 + 986 + return div_ctl; 987 + } 988 + 989 + static u32 aspeed_get_clk_div_ast2500(struct aspeed_spi_chip *chip, 990 + u32 max_hz) 991 + { 992 + struct device *dev = chip->aspi->dev; 993 + u32 hclk_clk = chip->aspi->clk_freq; 994 + u32 div_ctl = 0; 995 + u32 i; 996 + bool found = false; 997 + 998 + /* FMC/SPIR10[11:8] */ 999 + for (i = 1; i <= ARRAY_SIZE(aspeed_spi_hclk_divs); i++) { 1000 + if (hclk_clk / i <= max_hz) { 1001 + found = true; 1002 + chip->clk_freq = hclk_clk / i; 1003 + break; 1004 + } 1005 + } 1006 + 1007 + if (found) { 1008 + div_ctl = ASPEED_SPI_HCLK_DIV(i); 1009 + goto end; 1010 + } 1011 + 1012 + for (i = 1; i <= ARRAY_SIZE(aspeed_spi_hclk_divs); i++) { 1013 + if (hclk_clk / (i * 4) <= max_hz) { 1014 + found = true; 1015 + chip->clk_freq = hclk_clk / (i * 4); 1016 + break; 1017 + } 1018 + } 1019 + 1020 + if (found) 1021 + div_ctl = BIT(13) | ASPEED_SPI_HCLK_DIV(i); 1022 + 1023 + end: 1024 + dev_dbg(dev, "found: %s, hclk: %d, max_clk: %d\n", 1025 + found ? "yes" : "no", hclk_clk, max_hz); 1026 + 1027 + if (found) { 1028 + dev_dbg(dev, "h_div: 0x%08x, speed: %d\n", 1029 + div_ctl, chip->clk_freq); 1030 + } 1031 + 1032 + return div_ctl; 1033 + } 1034 + 1035 + static u32 aspeed_get_clk_div_ast2600(struct aspeed_spi_chip *chip, 1036 + u32 max_hz) 1037 + { 1038 + struct device *dev = chip->aspi->dev; 1039 + u32 hclk_clk = chip->aspi->clk_freq; 1040 + u32 div_ctl = 0; 1041 + u32 i, j; 1042 + bool found = false; 1043 + 1044 + /* FMC/SPIR10[27:24] */ 1045 + for (j = 0; j < 16; j++) { 1046 + /* FMC/SPIR10[11:8] */ 1047 + for (i = 1; i <= ARRAY_SIZE(aspeed_spi_hclk_divs); i++) { 1048 + if (j == 0 && i == 1) 1049 + continue; 1050 + 1051 + if (hclk_clk / (j * 16 + i) <= max_hz) { 1052 + found = true; 1053 + break; 1054 + } 1055 + } 1056 + 1057 + if (found) { 1058 + div_ctl = ((j << 24) | ASPEED_SPI_HCLK_DIV(i)); 1059 + chip->clk_freq = hclk_clk / (j * 16 + i); 1060 + break; 1061 + } 1062 + } 1063 + 1064 + dev_dbg(dev, "found: %s, hclk: %d, max_clk: %d\n", 1065 + found ? "yes" : "no", hclk_clk, max_hz); 1066 + 1067 + if (found) { 1068 + dev_dbg(dev, "h_div: 0x%08x, speed: %d\n", 1069 + div_ctl, chip->clk_freq); 1070 + } 1071 + 1072 + return div_ctl; 1073 + } 1092 1074 1093 1075 static int aspeed_spi_do_calibration(struct aspeed_spi_chip *chip) 1094 1076 { ··· 1216 958 const struct aspeed_spi_data *data = aspi->data; 1217 959 u32 ahb_freq = aspi->clk_freq; 1218 960 u32 max_freq = chip->clk_freq; 961 + bool exec_calib = false; 962 + u32 best_freq = 0; 1219 963 u32 ctl_val; 1220 964 u8 *golden_buf = NULL; 1221 965 u8 *test_buf = NULL; 1222 - int i, rc, best_div = -1; 966 + int i, rc; 967 + u32 div_ctl; 1223 968 1224 969 dev_dbg(aspi->dev, "calculate timing compensation - AHB freq: %d MHz", 1225 970 ahb_freq / 1000000); ··· 1243 982 memcpy_fromio(golden_buf, chip->ahb_base, CALIBRATE_BUF_SIZE); 1244 983 if (!aspeed_spi_check_calib_data(golden_buf, CALIBRATE_BUF_SIZE)) { 1245 984 dev_info(aspi->dev, "Calibration area too uniform, using low speed"); 1246 - goto no_calib; 985 + goto end_calib; 1247 986 } 1248 987 1249 988 #if defined(VERBOSE_DEBUG) ··· 1252 991 #endif 1253 992 1254 993 /* Now we iterate the HCLK dividers until we find our breaking point */ 1255 - for (i = ARRAY_SIZE(aspeed_spi_hclk_divs); i > data->hdiv_max - 1; i--) { 994 + for (i = 5; i > data->hdiv_max - 1; i--) { 1256 995 u32 tv, freq; 1257 996 1258 997 freq = ahb_freq / i; ··· 1265 1004 dev_dbg(aspi->dev, "Trying HCLK/%d [%08x] ...", i, tv); 1266 1005 rc = data->calibrate(chip, i, golden_buf, test_buf); 1267 1006 if (rc == 0) 1268 - best_div = i; 1007 + best_freq = freq; 1008 + 1009 + exec_calib = true; 1269 1010 } 1270 1011 1271 - /* Nothing found ? */ 1272 - if (best_div < 0) { 1273 - dev_warn(aspi->dev, "No good frequency, using dumb slow"); 1012 + end_calib: 1013 + if (!exec_calib) { 1014 + /* calibration process is not executed */ 1015 + dev_warn(aspi->dev, "Force to dts configuration %dkHz.\n", 1016 + max_freq / 1000); 1017 + div_ctl = data->get_clk_div(chip, max_freq); 1018 + } else if (best_freq == 0) { 1019 + /* calibration process is executed, but no good frequency */ 1020 + dev_warn(aspi->dev, "No good frequency, using dumb slow\n"); 1021 + div_ctl = 0; 1274 1022 } else { 1275 - dev_dbg(aspi->dev, "Found good read timings at HCLK/%d", best_div); 1276 - 1277 - /* Record the freq */ 1278 - for (i = 0; i < ASPEED_SPI_MAX; i++) 1279 - chip->ctl_val[i] = (chip->ctl_val[i] & data->hclk_mask) | 1280 - ASPEED_SPI_HCLK_DIV(best_div); 1023 + dev_dbg(aspi->dev, "Found good read timings at %dMHz.\n", 1024 + best_freq / 1000000); 1025 + div_ctl = data->get_clk_div(chip, best_freq); 1281 1026 } 1282 1027 1283 - no_calib: 1028 + /* Record the freq */ 1029 + for (i = 0; i < ASPEED_SPI_MAX; i++) { 1030 + chip->ctl_val[i] = (chip->ctl_val[i] & data->hclk_mask) | 1031 + div_ctl; 1032 + } 1033 + 1284 1034 writel(chip->ctl_val[ASPEED_SPI_READ], chip->ctl); 1285 1035 kfree(test_buf); 1286 1036 return 0; ··· 1299 1027 1300 1028 #define TIMING_DELAY_DI BIT(3) 1301 1029 #define TIMING_DELAY_HCYCLE_MAX 5 1030 + #define TIMING_DELAY_INPUT_MAX 16 1302 1031 #define TIMING_REG_AST2600(chip) \ 1303 1032 ((chip)->aspi->regs + (chip)->aspi->data->timing + \ 1304 1033 (chip)->cs * 4) 1034 + 1035 + /* 1036 + * This function returns the center point of the longest 1037 + * continuous "pass" interval within the buffer. The interval 1038 + * must contains the highest number of consecutive "pass" 1039 + * results and not span across multiple rows. 1040 + */ 1041 + static u32 aspeed_spi_ast2600_optimized_timing(u32 rows, u32 cols, 1042 + u8 buf[rows][cols]) 1043 + { 1044 + int r = 0, c = 0; 1045 + int max = 0; 1046 + int i, j; 1047 + 1048 + for (i = 0; i < rows; i++) { 1049 + for (j = 0; j < cols;) { 1050 + int k = j; 1051 + 1052 + while (k < cols && buf[i][k]) 1053 + k++; 1054 + 1055 + if (k - j > max) { 1056 + max = k - j; 1057 + r = i; 1058 + c = j + (k - j) / 2; 1059 + } 1060 + 1061 + j = k + 1; 1062 + } 1063 + } 1064 + 1065 + return max > 4 ? r * cols + c : 0; 1066 + } 1305 1067 1306 1068 static int aspeed_spi_ast2600_calibrate(struct aspeed_spi_chip *chip, u32 hdiv, 1307 1069 const u8 *golden_buf, u8 *test_buf) 1308 1070 { 1309 1071 struct aspeed_spi *aspi = chip->aspi; 1310 1072 int hcycle; 1073 + int delay_ns; 1311 1074 u32 shift = (hdiv - 2) << 3; 1312 - u32 mask = ~(0xfu << shift); 1075 + u32 mask = ~(0xffu << shift); 1313 1076 u32 fread_timing_val = 0; 1077 + u8 calib_res[6][17] = {0}; 1078 + u32 calib_point; 1314 1079 1315 1080 for (hcycle = 0; hcycle <= TIMING_DELAY_HCYCLE_MAX; hcycle++) { 1316 - int delay_ns; 1317 1081 bool pass = false; 1318 1082 1319 1083 fread_timing_val &= mask; ··· 1362 1054 " * [%08x] %d HCLK delay, DI delay none : %s", 1363 1055 fread_timing_val, hcycle, pass ? "PASS" : "FAIL"); 1364 1056 if (pass) 1365 - return 0; 1057 + calib_res[hcycle][0] = 1; 1366 1058 1367 1059 /* Add DI input delays */ 1368 1060 fread_timing_val &= mask; 1369 1061 fread_timing_val |= (TIMING_DELAY_DI | hcycle) << shift; 1370 1062 1371 - for (delay_ns = 0; delay_ns < 0x10; delay_ns++) { 1372 - fread_timing_val &= ~(0xf << (4 + shift)); 1063 + for (delay_ns = 0; delay_ns < TIMING_DELAY_INPUT_MAX; delay_ns++) { 1064 + fread_timing_val &= ~(0xfu << (4 + shift)); 1373 1065 fread_timing_val |= delay_ns << (4 + shift); 1374 1066 1375 1067 writel(fread_timing_val, TIMING_REG_AST2600(chip)); ··· 1378 1070 " * [%08x] %d HCLK delay, DI delay %d.%dns : %s", 1379 1071 fread_timing_val, hcycle, (delay_ns + 1) / 2, 1380 1072 (delay_ns + 1) & 1 ? 5 : 5, pass ? "PASS" : "FAIL"); 1381 - /* 1382 - * TODO: This is optimistic. We should look 1383 - * for a working interval and save the middle 1384 - * value in the read timing register. 1385 - */ 1073 + 1386 1074 if (pass) 1387 - return 0; 1075 + calib_res[hcycle][delay_ns + 1] = 1; 1388 1076 } 1389 1077 } 1390 1078 1079 + calib_point = aspeed_spi_ast2600_optimized_timing(6, 17, calib_res); 1391 1080 /* No good setting for this frequency */ 1392 - return -1; 1081 + if (calib_point == 0) 1082 + return -1; 1083 + 1084 + hcycle = calib_point / 17; 1085 + delay_ns = calib_point % 17; 1086 + 1087 + fread_timing_val = (TIMING_DELAY_DI | hcycle | (delay_ns << 4)) << shift; 1088 + 1089 + dev_dbg(aspi->dev, "timing val: %08x, final hcycle: %d, delay_ns: %d\n", 1090 + fread_timing_val, hcycle, delay_ns); 1091 + 1092 + writel(fread_timing_val, TIMING_REG_AST2600(chip)); 1093 + 1094 + return 0; 1393 1095 } 1394 1096 1395 1097 /* ··· 1413 1095 .timing = CE0_TIMING_COMPENSATION_REG, 1414 1096 .hclk_mask = 0xfffff0ff, 1415 1097 .hdiv_max = 1, 1098 + .min_window_size = 0x800000, 1416 1099 .calibrate = aspeed_spi_calibrate, 1100 + .get_clk_div = aspeed_get_clk_div_ast2400, 1417 1101 .segment_start = aspeed_spi_segment_start, 1418 1102 .segment_end = aspeed_spi_segment_end, 1419 1103 .segment_reg = aspeed_spi_segment_reg, 1104 + .adjust_window = aspeed_adjust_window_ast2400, 1420 1105 }; 1421 1106 1422 1107 static const struct aspeed_spi_data ast2400_spi_data = { ··· 1430 1109 .timing = 0x14, 1431 1110 .hclk_mask = 0xfffff0ff, 1432 1111 .hdiv_max = 1, 1112 + .get_clk_div = aspeed_get_clk_div_ast2400, 1433 1113 .calibrate = aspeed_spi_calibrate, 1434 1114 /* No segment registers */ 1435 1115 }; ··· 1443 1121 .timing = CE0_TIMING_COMPENSATION_REG, 1444 1122 .hclk_mask = 0xffffd0ff, 1445 1123 .hdiv_max = 1, 1124 + .min_window_size = 0x800000, 1125 + .get_clk_div = aspeed_get_clk_div_ast2500, 1446 1126 .calibrate = aspeed_spi_calibrate, 1447 1127 .segment_start = aspeed_spi_segment_start, 1448 1128 .segment_end = aspeed_spi_segment_end, 1449 1129 .segment_reg = aspeed_spi_segment_reg, 1130 + .adjust_window = aspeed_adjust_window_ast2500, 1450 1131 }; 1451 1132 1452 1133 static const struct aspeed_spi_data ast2500_spi_data = { ··· 1460 1135 .timing = CE0_TIMING_COMPENSATION_REG, 1461 1136 .hclk_mask = 0xffffd0ff, 1462 1137 .hdiv_max = 1, 1138 + .min_window_size = 0x800000, 1139 + .get_clk_div = aspeed_get_clk_div_ast2500, 1463 1140 .calibrate = aspeed_spi_calibrate, 1464 1141 .segment_start = aspeed_spi_segment_start, 1465 1142 .segment_end = aspeed_spi_segment_end, 1466 1143 .segment_reg = aspeed_spi_segment_reg, 1144 + .adjust_window = aspeed_adjust_window_ast2500, 1467 1145 }; 1468 1146 1469 1147 static const struct aspeed_spi_data ast2600_fmc_data = { ··· 1478 1150 .timing = CE0_TIMING_COMPENSATION_REG, 1479 1151 .hclk_mask = 0xf0fff0ff, 1480 1152 .hdiv_max = 2, 1153 + .min_window_size = 0x200000, 1154 + .get_clk_div = aspeed_get_clk_div_ast2600, 1481 1155 .calibrate = aspeed_spi_ast2600_calibrate, 1482 1156 .segment_start = aspeed_spi_segment_ast2600_start, 1483 1157 .segment_end = aspeed_spi_segment_ast2600_end, 1484 1158 .segment_reg = aspeed_spi_segment_ast2600_reg, 1159 + .adjust_window = aspeed_adjust_window_ast2600, 1485 1160 }; 1486 1161 1487 1162 static const struct aspeed_spi_data ast2600_spi_data = { ··· 1496 1165 .timing = CE0_TIMING_COMPENSATION_REG, 1497 1166 .hclk_mask = 0xf0fff0ff, 1498 1167 .hdiv_max = 2, 1168 + .min_window_size = 0x200000, 1169 + .get_clk_div = aspeed_get_clk_div_ast2600, 1499 1170 .calibrate = aspeed_spi_ast2600_calibrate, 1500 1171 .segment_start = aspeed_spi_segment_ast2600_start, 1501 1172 .segment_end = aspeed_spi_segment_ast2600_end, 1502 1173 .segment_reg = aspeed_spi_segment_ast2600_reg, 1174 + .adjust_window = aspeed_adjust_window_ast2600, 1503 1175 }; 1504 1176 1505 1177 static const struct of_device_id aspeed_spi_matches[] = {