| .. | .. |
|---|
| 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); |
|---|