.. | .. |
---|
454 | 454 | NAND_OP_PARSER_PAT_DATA_IN_ELEM(true, 4)), |
---|
455 | 455 | ); |
---|
456 | 456 | |
---|
| 457 | +static void tegra_nand_select_target(struct nand_chip *chip, |
---|
| 458 | + unsigned int die_nr) |
---|
| 459 | +{ |
---|
| 460 | + struct tegra_nand_chip *nand = to_tegra_chip(chip); |
---|
| 461 | + struct tegra_nand_controller *ctrl = to_tegra_ctrl(chip->controller); |
---|
| 462 | + |
---|
| 463 | + ctrl->cur_cs = nand->cs[die_nr]; |
---|
| 464 | +} |
---|
| 465 | + |
---|
457 | 466 | static int tegra_nand_exec_op(struct nand_chip *chip, |
---|
458 | 467 | const struct nand_operation *op, |
---|
459 | 468 | bool check_only) |
---|
460 | 469 | { |
---|
| 470 | + if (!check_only) |
---|
| 471 | + tegra_nand_select_target(chip, op->cs); |
---|
| 472 | + |
---|
461 | 473 | return nand_op_parser_exec_op(chip, &tegra_nand_op_parser, op, |
---|
462 | 474 | check_only); |
---|
463 | | -} |
---|
464 | | - |
---|
465 | | -static void tegra_nand_select_chip(struct mtd_info *mtd, int die_nr) |
---|
466 | | -{ |
---|
467 | | - struct nand_chip *chip = mtd_to_nand(mtd); |
---|
468 | | - struct tegra_nand_chip *nand = to_tegra_chip(chip); |
---|
469 | | - struct tegra_nand_controller *ctrl = to_tegra_ctrl(chip->controller); |
---|
470 | | - |
---|
471 | | - WARN_ON(die_nr >= (int)ARRAY_SIZE(nand->cs)); |
---|
472 | | - |
---|
473 | | - if (die_nr < 0 || die_nr > 0) { |
---|
474 | | - ctrl->cur_cs = -1; |
---|
475 | | - return; |
---|
476 | | - } |
---|
477 | | - |
---|
478 | | - ctrl->cur_cs = nand->cs[die_nr]; |
---|
479 | 475 | } |
---|
480 | 476 | |
---|
481 | 477 | static void tegra_nand_hw_ecc(struct tegra_nand_controller *ctrl, |
---|
.. | .. |
---|
483 | 479 | { |
---|
484 | 480 | struct tegra_nand_chip *nand = to_tegra_chip(chip); |
---|
485 | 481 | |
---|
486 | | - if (chip->ecc.algo == NAND_ECC_BCH && enable) |
---|
| 482 | + if (chip->ecc.algo == NAND_ECC_ALGO_BCH && enable) |
---|
487 | 483 | writel_relaxed(nand->bch_config, ctrl->regs + BCH_CONFIG); |
---|
488 | 484 | else |
---|
489 | 485 | writel_relaxed(0, ctrl->regs + BCH_CONFIG); |
---|
.. | .. |
---|
503 | 499 | dma_addr_t dma_addr = 0, dma_addr_oob = 0; |
---|
504 | 500 | u32 addr1, cmd, dma_ctrl; |
---|
505 | 501 | int ret; |
---|
| 502 | + |
---|
| 503 | + tegra_nand_select_target(chip, chip->cur_cs); |
---|
506 | 504 | |
---|
507 | 505 | if (read) { |
---|
508 | 506 | writel_relaxed(NAND_CMD_READ0, ctrl->regs + CMD_REG1); |
---|
.. | .. |
---|
615 | 613 | return ret; |
---|
616 | 614 | } |
---|
617 | 615 | |
---|
618 | | -static int tegra_nand_read_page_raw(struct mtd_info *mtd, |
---|
619 | | - struct nand_chip *chip, u8 *buf, |
---|
| 616 | +static int tegra_nand_read_page_raw(struct nand_chip *chip, u8 *buf, |
---|
620 | 617 | int oob_required, int page) |
---|
621 | 618 | { |
---|
| 619 | + struct mtd_info *mtd = nand_to_mtd(chip); |
---|
622 | 620 | void *oob_buf = oob_required ? chip->oob_poi : NULL; |
---|
623 | 621 | |
---|
624 | 622 | return tegra_nand_page_xfer(mtd, chip, buf, oob_buf, |
---|
625 | 623 | mtd->oobsize, page, true); |
---|
626 | 624 | } |
---|
627 | 625 | |
---|
628 | | -static int tegra_nand_write_page_raw(struct mtd_info *mtd, |
---|
629 | | - struct nand_chip *chip, const u8 *buf, |
---|
| 626 | +static int tegra_nand_write_page_raw(struct nand_chip *chip, const u8 *buf, |
---|
630 | 627 | int oob_required, int page) |
---|
631 | 628 | { |
---|
| 629 | + struct mtd_info *mtd = nand_to_mtd(chip); |
---|
632 | 630 | void *oob_buf = oob_required ? chip->oob_poi : NULL; |
---|
633 | 631 | |
---|
634 | 632 | return tegra_nand_page_xfer(mtd, chip, (void *)buf, oob_buf, |
---|
635 | 633 | mtd->oobsize, page, false); |
---|
636 | 634 | } |
---|
637 | 635 | |
---|
638 | | -static int tegra_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip, |
---|
639 | | - int page) |
---|
| 636 | +static int tegra_nand_read_oob(struct nand_chip *chip, int page) |
---|
640 | 637 | { |
---|
| 638 | + struct mtd_info *mtd = nand_to_mtd(chip); |
---|
| 639 | + |
---|
641 | 640 | return tegra_nand_page_xfer(mtd, chip, NULL, chip->oob_poi, |
---|
642 | 641 | mtd->oobsize, page, true); |
---|
643 | 642 | } |
---|
644 | 643 | |
---|
645 | | -static int tegra_nand_write_oob(struct mtd_info *mtd, struct nand_chip *chip, |
---|
646 | | - int page) |
---|
| 644 | +static int tegra_nand_write_oob(struct nand_chip *chip, int page) |
---|
647 | 645 | { |
---|
| 646 | + struct mtd_info *mtd = nand_to_mtd(chip); |
---|
| 647 | + |
---|
648 | 648 | return tegra_nand_page_xfer(mtd, chip, NULL, chip->oob_poi, |
---|
649 | 649 | mtd->oobsize, page, false); |
---|
650 | 650 | } |
---|
651 | 651 | |
---|
652 | | -static int tegra_nand_read_page_hwecc(struct mtd_info *mtd, |
---|
653 | | - struct nand_chip *chip, u8 *buf, |
---|
| 652 | +static int tegra_nand_read_page_hwecc(struct nand_chip *chip, u8 *buf, |
---|
654 | 653 | int oob_required, int page) |
---|
655 | 654 | { |
---|
| 655 | + struct mtd_info *mtd = nand_to_mtd(chip); |
---|
656 | 656 | struct tegra_nand_controller *ctrl = to_tegra_ctrl(chip->controller); |
---|
657 | 657 | struct tegra_nand_chip *nand = to_tegra_chip(chip); |
---|
658 | 658 | void *oob_buf = oob_required ? chip->oob_poi : NULL; |
---|
.. | .. |
---|
716 | 716 | * erased or if error correction just failed for all sub- |
---|
717 | 717 | * pages. |
---|
718 | 718 | */ |
---|
719 | | - ret = tegra_nand_read_oob(mtd, chip, page); |
---|
| 719 | + ret = tegra_nand_read_oob(chip, page); |
---|
720 | 720 | if (ret < 0) |
---|
721 | 721 | return ret; |
---|
722 | 722 | |
---|
.. | .. |
---|
759 | 759 | } |
---|
760 | 760 | } |
---|
761 | 761 | |
---|
762 | | -static int tegra_nand_write_page_hwecc(struct mtd_info *mtd, |
---|
763 | | - struct nand_chip *chip, const u8 *buf, |
---|
| 762 | +static int tegra_nand_write_page_hwecc(struct nand_chip *chip, const u8 *buf, |
---|
764 | 763 | int oob_required, int page) |
---|
765 | 764 | { |
---|
| 765 | + struct mtd_info *mtd = nand_to_mtd(chip); |
---|
766 | 766 | struct tegra_nand_controller *ctrl = to_tegra_ctrl(chip->controller); |
---|
767 | 767 | void *oob_buf = oob_required ? chip->oob_poi : NULL; |
---|
768 | 768 | int ret; |
---|
.. | .. |
---|
813 | 813 | writel_relaxed(reg, ctrl->regs + TIMING_2); |
---|
814 | 814 | } |
---|
815 | 815 | |
---|
816 | | -static int tegra_nand_setup_data_interface(struct mtd_info *mtd, int csline, |
---|
817 | | - const struct nand_data_interface *conf) |
---|
| 816 | +static int tegra_nand_setup_interface(struct nand_chip *chip, int csline, |
---|
| 817 | + const struct nand_interface_config *conf) |
---|
818 | 818 | { |
---|
819 | | - struct nand_chip *chip = mtd_to_nand(mtd); |
---|
820 | 819 | struct tegra_nand_controller *ctrl = to_tegra_ctrl(chip->controller); |
---|
821 | 820 | const struct nand_sdr_timings *timings; |
---|
822 | 821 | |
---|
.. | .. |
---|
841 | 840 | int strength_len, int bits_per_step, |
---|
842 | 841 | int oobsize) |
---|
843 | 842 | { |
---|
844 | | - bool maximize = chip->ecc.options & NAND_ECC_MAXIMIZE; |
---|
| 843 | + struct nand_device *base = mtd_to_nanddev(nand_to_mtd(chip)); |
---|
| 844 | + const struct nand_ecc_props *requirements = |
---|
| 845 | + nanddev_get_ecc_requirements(base); |
---|
| 846 | + bool maximize = base->ecc.user_conf.flags & NAND_ECC_MAXIMIZE_STRENGTH; |
---|
845 | 847 | int i; |
---|
846 | 848 | |
---|
847 | 849 | /* |
---|
.. | .. |
---|
856 | 858 | } else { |
---|
857 | 859 | strength_sel = strength[i]; |
---|
858 | 860 | |
---|
859 | | - if (strength_sel < chip->ecc_strength_ds) |
---|
| 861 | + if (strength_sel < requirements->strength) |
---|
860 | 862 | continue; |
---|
861 | 863 | } |
---|
862 | 864 | |
---|
.. | .. |
---|
878 | 880 | int strength_len, bits_per_step; |
---|
879 | 881 | |
---|
880 | 882 | switch (chip->ecc.algo) { |
---|
881 | | - case NAND_ECC_RS: |
---|
| 883 | + case NAND_ECC_ALGO_RS: |
---|
882 | 884 | bits_per_step = BITS_PER_STEP_RS; |
---|
883 | 885 | if (chip->options & NAND_IS_BOOT_MEDIUM) { |
---|
884 | 886 | strength = rs_strength_bootable; |
---|
.. | .. |
---|
888 | 890 | strength_len = ARRAY_SIZE(rs_strength); |
---|
889 | 891 | } |
---|
890 | 892 | break; |
---|
891 | | - case NAND_ECC_BCH: |
---|
| 893 | + case NAND_ECC_ALGO_BCH: |
---|
892 | 894 | bits_per_step = BITS_PER_STEP_BCH; |
---|
893 | 895 | if (chip->options & NAND_IS_BOOT_MEDIUM) { |
---|
894 | 896 | strength = bch_strength_bootable; |
---|
.. | .. |
---|
909 | 911 | static int tegra_nand_attach_chip(struct nand_chip *chip) |
---|
910 | 912 | { |
---|
911 | 913 | struct tegra_nand_controller *ctrl = to_tegra_ctrl(chip->controller); |
---|
| 914 | + const struct nand_ecc_props *requirements = |
---|
| 915 | + nanddev_get_ecc_requirements(&chip->base); |
---|
912 | 916 | struct tegra_nand_chip *nand = to_tegra_chip(chip); |
---|
913 | 917 | struct mtd_info *mtd = nand_to_mtd(chip); |
---|
914 | 918 | int bits_per_step; |
---|
.. | .. |
---|
917 | 921 | if (chip->bbt_options & NAND_BBT_USE_FLASH) |
---|
918 | 922 | chip->bbt_options |= NAND_BBT_NO_OOB; |
---|
919 | 923 | |
---|
920 | | - chip->ecc.mode = NAND_ECC_HW; |
---|
| 924 | + chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; |
---|
921 | 925 | chip->ecc.size = 512; |
---|
922 | 926 | chip->ecc.steps = mtd->writesize / chip->ecc.size; |
---|
923 | | - if (chip->ecc_step_ds != 512) { |
---|
| 927 | + if (requirements->step_size != 512) { |
---|
924 | 928 | dev_err(ctrl->dev, "Unsupported step size %d\n", |
---|
925 | | - chip->ecc_step_ds); |
---|
| 929 | + requirements->step_size); |
---|
926 | 930 | return -EINVAL; |
---|
927 | 931 | } |
---|
928 | 932 | |
---|
.. | .. |
---|
936 | 940 | if (chip->options & NAND_BUSWIDTH_16) |
---|
937 | 941 | nand->config |= CONFIG_BUS_WIDTH_16; |
---|
938 | 942 | |
---|
939 | | - if (chip->ecc.algo == NAND_ECC_UNKNOWN) { |
---|
| 943 | + if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN) { |
---|
940 | 944 | if (mtd->writesize < 2048) |
---|
941 | | - chip->ecc.algo = NAND_ECC_RS; |
---|
| 945 | + chip->ecc.algo = NAND_ECC_ALGO_RS; |
---|
942 | 946 | else |
---|
943 | | - chip->ecc.algo = NAND_ECC_BCH; |
---|
| 947 | + chip->ecc.algo = NAND_ECC_ALGO_BCH; |
---|
944 | 948 | } |
---|
945 | 949 | |
---|
946 | | - if (chip->ecc.algo == NAND_ECC_BCH && mtd->writesize < 2048) { |
---|
| 950 | + if (chip->ecc.algo == NAND_ECC_ALGO_BCH && mtd->writesize < 2048) { |
---|
947 | 951 | dev_err(ctrl->dev, "BCH supports 2K or 4K page size only\n"); |
---|
948 | 952 | return -EINVAL; |
---|
949 | 953 | } |
---|
.. | .. |
---|
953 | 957 | if (ret < 0) { |
---|
954 | 958 | dev_err(ctrl->dev, |
---|
955 | 959 | "No valid strength found, minimum %d\n", |
---|
956 | | - chip->ecc_strength_ds); |
---|
| 960 | + requirements->strength); |
---|
957 | 961 | return ret; |
---|
958 | 962 | } |
---|
959 | 963 | |
---|
.. | .. |
---|
964 | 968 | CONFIG_SKIP_SPARE_SIZE_4; |
---|
965 | 969 | |
---|
966 | 970 | switch (chip->ecc.algo) { |
---|
967 | | - case NAND_ECC_RS: |
---|
| 971 | + case NAND_ECC_ALGO_RS: |
---|
968 | 972 | bits_per_step = BITS_PER_STEP_RS * chip->ecc.strength; |
---|
969 | 973 | mtd_set_ooblayout(mtd, &tegra_nand_oob_rs_ops); |
---|
970 | 974 | nand->config_ecc |= CONFIG_HW_ECC | CONFIG_ECC_SEL | |
---|
.. | .. |
---|
985 | 989 | return -EINVAL; |
---|
986 | 990 | } |
---|
987 | 991 | break; |
---|
988 | | - case NAND_ECC_BCH: |
---|
| 992 | + case NAND_ECC_ALGO_BCH: |
---|
989 | 993 | bits_per_step = BITS_PER_STEP_BCH * chip->ecc.strength; |
---|
990 | 994 | mtd_set_ooblayout(mtd, &tegra_nand_oob_bch_ops); |
---|
991 | 995 | nand->bch_config = BCH_ENABLE; |
---|
.. | .. |
---|
1014 | 1018 | } |
---|
1015 | 1019 | |
---|
1016 | 1020 | dev_info(ctrl->dev, "Using %s with strength %d per 512 byte step\n", |
---|
1017 | | - chip->ecc.algo == NAND_ECC_BCH ? "BCH" : "RS", |
---|
| 1021 | + chip->ecc.algo == NAND_ECC_ALGO_BCH ? "BCH" : "RS", |
---|
1018 | 1022 | chip->ecc.strength); |
---|
1019 | 1023 | |
---|
1020 | 1024 | chip->ecc.bytes = DIV_ROUND_UP(bits_per_step, BITS_PER_BYTE); |
---|
.. | .. |
---|
1053 | 1057 | |
---|
1054 | 1058 | static const struct nand_controller_ops tegra_nand_controller_ops = { |
---|
1055 | 1059 | .attach_chip = &tegra_nand_attach_chip, |
---|
| 1060 | + .exec_op = tegra_nand_exec_op, |
---|
| 1061 | + .setup_interface = tegra_nand_setup_interface, |
---|
1056 | 1062 | }; |
---|
1057 | 1063 | |
---|
1058 | 1064 | static int tegra_nand_chips_init(struct device *dev, |
---|
.. | .. |
---|
1114 | 1120 | if (!mtd->name) |
---|
1115 | 1121 | mtd->name = "tegra_nand"; |
---|
1116 | 1122 | |
---|
1117 | | - chip->options = NAND_NO_SUBPAGE_WRITE | NAND_USE_BOUNCE_BUFFER; |
---|
1118 | | - chip->exec_op = tegra_nand_exec_op; |
---|
1119 | | - chip->select_chip = tegra_nand_select_chip; |
---|
1120 | | - chip->setup_data_interface = tegra_nand_setup_data_interface; |
---|
| 1123 | + chip->options = NAND_NO_SUBPAGE_WRITE | NAND_USES_DMA; |
---|
1121 | 1124 | |
---|
1122 | 1125 | ret = nand_scan(chip, 1); |
---|
1123 | 1126 | if (ret) |
---|