.. | .. |
---|
25 | 25 | #include <linux/of.h> |
---|
26 | 26 | #include <linux/of_platform.h> |
---|
27 | 27 | #include <linux/slab.h> |
---|
| 28 | +#include <linux/static_key.h> |
---|
28 | 29 | #include <linux/list.h> |
---|
29 | 30 | #include <linux/log2.h> |
---|
30 | 31 | |
---|
.. | .. |
---|
207 | 208 | |
---|
208 | 209 | struct brcmnand_host; |
---|
209 | 210 | |
---|
| 211 | +static DEFINE_STATIC_KEY_FALSE(brcmnand_soc_has_ops_key); |
---|
| 212 | + |
---|
210 | 213 | struct brcmnand_controller { |
---|
211 | 214 | struct device *dev; |
---|
212 | 215 | struct nand_controller controller; |
---|
.. | .. |
---|
265 | 268 | const unsigned int *page_sizes; |
---|
266 | 269 | unsigned int page_size_shift; |
---|
267 | 270 | unsigned int max_oob; |
---|
| 271 | + u32 ecc_level_shift; |
---|
268 | 272 | u32 features; |
---|
269 | 273 | |
---|
270 | 274 | /* for low-power standby/resume only */ |
---|
.. | .. |
---|
589 | 593 | INTFC_CTLR_READY = BIT(31), |
---|
590 | 594 | }; |
---|
591 | 595 | |
---|
| 596 | +/*********************************************************************** |
---|
| 597 | + * NAND ACC CONTROL bitfield |
---|
| 598 | + * |
---|
| 599 | + * Some bits have remained constant throughout hardware revision, while |
---|
| 600 | + * others have shifted around. |
---|
| 601 | + ***********************************************************************/ |
---|
| 602 | + |
---|
| 603 | +/* Constant for all versions (where supported) */ |
---|
| 604 | +enum { |
---|
| 605 | + /* See BRCMNAND_HAS_CACHE_MODE */ |
---|
| 606 | + ACC_CONTROL_CACHE_MODE = BIT(22), |
---|
| 607 | + |
---|
| 608 | + /* See BRCMNAND_HAS_PREFETCH */ |
---|
| 609 | + ACC_CONTROL_PREFETCH = BIT(23), |
---|
| 610 | + |
---|
| 611 | + ACC_CONTROL_PAGE_HIT = BIT(24), |
---|
| 612 | + ACC_CONTROL_WR_PREEMPT = BIT(25), |
---|
| 613 | + ACC_CONTROL_PARTIAL_PAGE = BIT(26), |
---|
| 614 | + ACC_CONTROL_RD_ERASED = BIT(27), |
---|
| 615 | + ACC_CONTROL_FAST_PGM_RDIN = BIT(28), |
---|
| 616 | + ACC_CONTROL_WR_ECC = BIT(30), |
---|
| 617 | + ACC_CONTROL_RD_ECC = BIT(31), |
---|
| 618 | +}; |
---|
| 619 | + |
---|
| 620 | +#define ACC_CONTROL_ECC_SHIFT 16 |
---|
| 621 | +/* Only for v7.2 */ |
---|
| 622 | +#define ACC_CONTROL_ECC_EXT_SHIFT 13 |
---|
| 623 | + |
---|
| 624 | +static inline bool brcmnand_non_mmio_ops(struct brcmnand_controller *ctrl) |
---|
| 625 | +{ |
---|
| 626 | + return static_branch_unlikely(&brcmnand_soc_has_ops_key); |
---|
| 627 | +} |
---|
| 628 | + |
---|
592 | 629 | static inline u32 nand_readreg(struct brcmnand_controller *ctrl, u32 offs) |
---|
593 | 630 | { |
---|
| 631 | + if (brcmnand_non_mmio_ops(ctrl)) |
---|
| 632 | + return brcmnand_soc_read(ctrl->soc, offs); |
---|
594 | 633 | return brcmnand_readl(ctrl->nand_base + offs); |
---|
595 | 634 | } |
---|
596 | 635 | |
---|
597 | 636 | static inline void nand_writereg(struct brcmnand_controller *ctrl, u32 offs, |
---|
598 | 637 | u32 val) |
---|
599 | 638 | { |
---|
600 | | - brcmnand_writel(val, ctrl->nand_base + offs); |
---|
| 639 | + if (brcmnand_non_mmio_ops(ctrl)) |
---|
| 640 | + brcmnand_soc_write(ctrl->soc, val, offs); |
---|
| 641 | + else |
---|
| 642 | + brcmnand_writel(val, ctrl->nand_base + offs); |
---|
601 | 643 | } |
---|
602 | 644 | |
---|
603 | 645 | static int brcmnand_revision_init(struct brcmnand_controller *ctrl) |
---|
.. | .. |
---|
716 | 758 | else if (of_property_read_bool(ctrl->dev->of_node, "brcm,nand-has-wp")) |
---|
717 | 759 | ctrl->features |= BRCMNAND_HAS_WP; |
---|
718 | 760 | |
---|
| 761 | + /* v7.2 has different ecc level shift in the acc register */ |
---|
| 762 | + if (ctrl->nand_version == 0x0702) |
---|
| 763 | + ctrl->ecc_level_shift = ACC_CONTROL_ECC_EXT_SHIFT; |
---|
| 764 | + else |
---|
| 765 | + ctrl->ecc_level_shift = ACC_CONTROL_ECC_SHIFT; |
---|
| 766 | + |
---|
719 | 767 | return 0; |
---|
720 | 768 | } |
---|
721 | 769 | |
---|
.. | .. |
---|
763 | 811 | |
---|
764 | 812 | static inline u32 brcmnand_read_fc(struct brcmnand_controller *ctrl, int word) |
---|
765 | 813 | { |
---|
| 814 | + if (brcmnand_non_mmio_ops(ctrl)) |
---|
| 815 | + return brcmnand_soc_read(ctrl->soc, BRCMNAND_NON_MMIO_FC_ADDR); |
---|
766 | 816 | return __raw_readl(ctrl->nand_fc + word * 4); |
---|
767 | 817 | } |
---|
768 | 818 | |
---|
769 | 819 | static inline void brcmnand_write_fc(struct brcmnand_controller *ctrl, |
---|
770 | 820 | int word, u32 val) |
---|
771 | 821 | { |
---|
772 | | - __raw_writel(val, ctrl->nand_fc + word * 4); |
---|
| 822 | + if (brcmnand_non_mmio_ops(ctrl)) |
---|
| 823 | + brcmnand_soc_write(ctrl->soc, val, BRCMNAND_NON_MMIO_FC_ADDR); |
---|
| 824 | + else |
---|
| 825 | + __raw_writel(val, ctrl->nand_fc + word * 4); |
---|
773 | 826 | } |
---|
774 | 827 | |
---|
775 | 828 | static inline void edu_writel(struct brcmnand_controller *ctrl, |
---|
.. | .. |
---|
899 | 952 | return 0; |
---|
900 | 953 | } |
---|
901 | 954 | |
---|
902 | | -/*********************************************************************** |
---|
903 | | - * NAND ACC CONTROL bitfield |
---|
904 | | - * |
---|
905 | | - * Some bits have remained constant throughout hardware revision, while |
---|
906 | | - * others have shifted around. |
---|
907 | | - ***********************************************************************/ |
---|
908 | | - |
---|
909 | | -/* Constant for all versions (where supported) */ |
---|
910 | | -enum { |
---|
911 | | - /* See BRCMNAND_HAS_CACHE_MODE */ |
---|
912 | | - ACC_CONTROL_CACHE_MODE = BIT(22), |
---|
913 | | - |
---|
914 | | - /* See BRCMNAND_HAS_PREFETCH */ |
---|
915 | | - ACC_CONTROL_PREFETCH = BIT(23), |
---|
916 | | - |
---|
917 | | - ACC_CONTROL_PAGE_HIT = BIT(24), |
---|
918 | | - ACC_CONTROL_WR_PREEMPT = BIT(25), |
---|
919 | | - ACC_CONTROL_PARTIAL_PAGE = BIT(26), |
---|
920 | | - ACC_CONTROL_RD_ERASED = BIT(27), |
---|
921 | | - ACC_CONTROL_FAST_PGM_RDIN = BIT(28), |
---|
922 | | - ACC_CONTROL_WR_ECC = BIT(30), |
---|
923 | | - ACC_CONTROL_RD_ECC = BIT(31), |
---|
924 | | -}; |
---|
925 | | - |
---|
926 | 955 | static inline u32 brcmnand_spare_area_mask(struct brcmnand_controller *ctrl) |
---|
927 | 956 | { |
---|
928 | 957 | if (ctrl->nand_version == 0x0702) |
---|
.. | .. |
---|
935 | 964 | return GENMASK(4, 0); |
---|
936 | 965 | } |
---|
937 | 966 | |
---|
938 | | -#define NAND_ACC_CONTROL_ECC_SHIFT 16 |
---|
939 | | -#define NAND_ACC_CONTROL_ECC_EXT_SHIFT 13 |
---|
940 | | - |
---|
941 | 967 | static inline u32 brcmnand_ecc_level_mask(struct brcmnand_controller *ctrl) |
---|
942 | 968 | { |
---|
943 | 969 | u32 mask = (ctrl->nand_version >= 0x0600) ? 0x1f : 0x0f; |
---|
944 | 970 | |
---|
945 | | - mask <<= NAND_ACC_CONTROL_ECC_SHIFT; |
---|
| 971 | + mask <<= ACC_CONTROL_ECC_SHIFT; |
---|
946 | 972 | |
---|
947 | 973 | /* v7.2 includes additional ECC levels */ |
---|
948 | | - if (ctrl->nand_version >= 0x0702) |
---|
949 | | - mask |= 0x7 << NAND_ACC_CONTROL_ECC_EXT_SHIFT; |
---|
| 974 | + if (ctrl->nand_version == 0x0702) |
---|
| 975 | + mask |= 0x7 << ACC_CONTROL_ECC_EXT_SHIFT; |
---|
950 | 976 | |
---|
951 | 977 | return mask; |
---|
952 | 978 | } |
---|
.. | .. |
---|
960 | 986 | |
---|
961 | 987 | if (en) { |
---|
962 | 988 | acc_control |= ecc_flags; /* enable RD/WR ECC */ |
---|
963 | | - acc_control |= host->hwcfg.ecc_level |
---|
964 | | - << NAND_ACC_CONTROL_ECC_SHIFT; |
---|
| 989 | + acc_control &= ~brcmnand_ecc_level_mask(ctrl); |
---|
| 990 | + acc_control |= host->hwcfg.ecc_level << ctrl->ecc_level_shift; |
---|
965 | 991 | } else { |
---|
966 | 992 | acc_control &= ~ecc_flags; /* disable RD/WR ECC */ |
---|
967 | 993 | acc_control &= ~brcmnand_ecc_level_mask(ctrl); |
---|
.. | .. |
---|
1039 | 1065 | |
---|
1040 | 1066 | cpu_relax(); |
---|
1041 | 1067 | } while (time_after(limit, jiffies)); |
---|
| 1068 | + |
---|
| 1069 | + /* |
---|
| 1070 | + * do a final check after time out in case the CPU was busy and the driver |
---|
| 1071 | + * did not get enough time to perform the polling to avoid false alarms |
---|
| 1072 | + */ |
---|
| 1073 | + val = brcmnand_read_reg(ctrl, BRCMNAND_INTFC_STATUS); |
---|
| 1074 | + if ((val & mask) == expected_val) |
---|
| 1075 | + return 0; |
---|
1042 | 1076 | |
---|
1043 | 1077 | dev_warn(ctrl->dev, "timeout on status poll (expected %x got %x)\n", |
---|
1044 | 1078 | expected_val, val & mask); |
---|
.. | .. |
---|
1429 | 1463 | const u8 *oob, int sas, int sector_1k) |
---|
1430 | 1464 | { |
---|
1431 | 1465 | int tbytes = sas << sector_1k; |
---|
1432 | | - int j; |
---|
| 1466 | + int j, k = 0; |
---|
| 1467 | + u32 last = 0xffffffff; |
---|
| 1468 | + u8 *plast = (u8 *)&last; |
---|
1433 | 1469 | |
---|
1434 | 1470 | /* Adjust OOB values for 1K sector size */ |
---|
1435 | 1471 | if (sector_1k && (i & 0x01)) |
---|
1436 | 1472 | tbytes = max(0, tbytes - (int)ctrl->max_oob); |
---|
1437 | 1473 | tbytes = min_t(int, tbytes, ctrl->max_oob); |
---|
1438 | 1474 | |
---|
1439 | | - for (j = 0; j < tbytes; j += 4) |
---|
| 1475 | + /* |
---|
| 1476 | + * tbytes may not be multiple of words. Make sure we don't read out of |
---|
| 1477 | + * the boundary and stop at last word. |
---|
| 1478 | + */ |
---|
| 1479 | + for (j = 0; (j + 3) < tbytes; j += 4) |
---|
1440 | 1480 | oob_reg_write(ctrl, j, |
---|
1441 | 1481 | (oob[j + 0] << 24) | |
---|
1442 | 1482 | (oob[j + 1] << 16) | |
---|
1443 | 1483 | (oob[j + 2] << 8) | |
---|
1444 | 1484 | (oob[j + 3] << 0)); |
---|
| 1485 | + |
---|
| 1486 | + /* handle the remaing bytes */ |
---|
| 1487 | + while (j < tbytes) |
---|
| 1488 | + plast[k++] = oob[j++]; |
---|
| 1489 | + |
---|
| 1490 | + if (tbytes & 0x3) |
---|
| 1491 | + oob_reg_write(ctrl, (tbytes & ~0x3), (__force u32)cpu_to_be32(last)); |
---|
| 1492 | + |
---|
1445 | 1493 | return tbytes; |
---|
1446 | 1494 | } |
---|
1447 | 1495 | |
---|
.. | .. |
---|
1543 | 1591 | |
---|
1544 | 1592 | dev_dbg(ctrl->dev, "send native cmd %d addr 0x%llx\n", cmd, cmd_addr); |
---|
1545 | 1593 | |
---|
1546 | | - BUG_ON(ctrl->cmd_pending != 0); |
---|
| 1594 | + /* |
---|
| 1595 | + * If we came here through _panic_write and there is a pending |
---|
| 1596 | + * command, try to wait for it. If it times out, rather than |
---|
| 1597 | + * hitting BUG_ON, just return so we don't crash while crashing. |
---|
| 1598 | + */ |
---|
| 1599 | + if (oops_in_progress) { |
---|
| 1600 | + if (ctrl->cmd_pending && |
---|
| 1601 | + bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY, NAND_CTRL_RDY, 0)) |
---|
| 1602 | + return; |
---|
| 1603 | + } else |
---|
| 1604 | + BUG_ON(ctrl->cmd_pending != 0); |
---|
1547 | 1605 | ctrl->cmd_pending = cmd; |
---|
1548 | 1606 | |
---|
1549 | 1607 | ret = bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY, NAND_CTRL_RDY, 0); |
---|
.. | .. |
---|
2483 | 2541 | tmp &= ~brcmnand_ecc_level_mask(ctrl); |
---|
2484 | 2542 | tmp &= ~brcmnand_spare_area_mask(ctrl); |
---|
2485 | 2543 | if (ctrl->nand_version >= 0x0302) { |
---|
2486 | | - tmp |= cfg->ecc_level << NAND_ACC_CONTROL_ECC_SHIFT; |
---|
| 2544 | + tmp |= cfg->ecc_level << ctrl->ecc_level_shift; |
---|
2487 | 2545 | tmp |= cfg->spare_area_size; |
---|
2488 | 2546 | } |
---|
2489 | 2547 | nand_writereg(ctrl, acc_control_offs, tmp); |
---|
.. | .. |
---|
2534 | 2592 | struct nand_chip *chip = &host->chip; |
---|
2535 | 2593 | const struct nand_ecc_props *requirements = |
---|
2536 | 2594 | nanddev_get_ecc_requirements(&chip->base); |
---|
| 2595 | + struct nand_memory_organization *memorg = |
---|
| 2596 | + nanddev_get_memorg(&chip->base); |
---|
2537 | 2597 | struct brcmnand_controller *ctrl = host->ctrl; |
---|
2538 | 2598 | struct brcmnand_cfg *cfg = &host->hwcfg; |
---|
2539 | 2599 | char msg[128]; |
---|
.. | .. |
---|
2555 | 2615 | if (cfg->spare_area_size > ctrl->max_oob) |
---|
2556 | 2616 | cfg->spare_area_size = ctrl->max_oob; |
---|
2557 | 2617 | /* |
---|
2558 | | - * Set oobsize to be consistent with controller's spare_area_size, as |
---|
2559 | | - * the rest is inaccessible. |
---|
| 2618 | + * Set mtd and memorg oobsize to be consistent with controller's |
---|
| 2619 | + * spare_area_size, as the rest is inaccessible. |
---|
2560 | 2620 | */ |
---|
2561 | 2621 | mtd->oobsize = cfg->spare_area_size * (mtd->writesize >> FC_SHIFT); |
---|
| 2622 | + memorg->oobsize = mtd->oobsize; |
---|
2562 | 2623 | |
---|
2563 | 2624 | cfg->device_size = mtd->size; |
---|
2564 | 2625 | cfg->block_size = mtd->erasesize; |
---|
.. | .. |
---|
2950 | 3011 | dev_set_drvdata(dev, ctrl); |
---|
2951 | 3012 | ctrl->dev = dev; |
---|
2952 | 3013 | |
---|
| 3014 | + /* Enable the static key if the soc provides I/O operations indicating |
---|
| 3015 | + * that a non-memory mapped IO access path must be used |
---|
| 3016 | + */ |
---|
| 3017 | + if (brcmnand_soc_has_ops(ctrl->soc)) |
---|
| 3018 | + static_branch_enable(&brcmnand_soc_has_ops_key); |
---|
| 3019 | + |
---|
2953 | 3020 | init_completion(&ctrl->done); |
---|
2954 | 3021 | init_completion(&ctrl->dma_done); |
---|
2955 | 3022 | init_completion(&ctrl->edu_done); |
---|