Lines Matching +full:dev +full:- +full:ctrl
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright © 2010-2015 Broadcom Corporation
17 #include <linux/dma-mapping.h>
215 struct device *dev; member
237 /* List of NAND hosts (one for each chip-select) */
240 /* EDU info, per-transaction */
261 /* in-memory cache of the FLASH_CACHE, used only for some commands */
267 const u8 *cs_offsets; /* within each chip-select */
278 /* for low-power standby/resume only */
298 /* use for low-power standby/resume only */
317 struct brcmnand_controller *ctrl; member
329 BRCMNAND_CS1_BASE, /* CS1 regs, if non-contiguous */
343 BRCMNAND_OOB_READ_10_BASE, /* offset 0x10, if non-contiguous */
345 BRCMNAND_OOB_WRITE_10_BASE, /* offset 0x10, if non-contiguous */
349 /* BRCMNAND v2.1-v2.2 */
379 /* BRCMNAND v3.3-v4.0 */
439 /* BRCMNAND v6.0 - v7.1 */
537 /* Per chip-select offsets for v7.1 */
546 /* Per chip-select offsets for pre v7.1, except CS0 on <= v5.0 */
555 /* Per chip-select offset for <= v5.0 on CS0 only */
565 * Bitfields for the CFG and CFG_EXT registers. Pre-v7.1 controllers only had
580 /* Only for pre-v7.1 (with no CFG_EXT register) */
630 static inline bool brcmnand_non_mmio_ops(struct brcmnand_controller *ctrl) in brcmnand_non_mmio_ops() argument
639 static inline u32 nand_readreg(struct brcmnand_controller *ctrl, u32 offs) in nand_readreg() argument
641 if (brcmnand_non_mmio_ops(ctrl)) in nand_readreg()
642 return brcmnand_soc_read(ctrl->soc, offs); in nand_readreg()
643 return brcmnand_readl(ctrl->nand_base + offs); in nand_readreg()
646 static inline void nand_writereg(struct brcmnand_controller *ctrl, u32 offs, in nand_writereg() argument
649 if (brcmnand_non_mmio_ops(ctrl)) in nand_writereg()
650 brcmnand_soc_write(ctrl->soc, val, offs); in nand_writereg()
652 brcmnand_writel(val, ctrl->nand_base + offs); in nand_writereg()
655 static int brcmnand_revision_init(struct brcmnand_controller *ctrl) in brcmnand_revision_init() argument
665 ctrl->nand_version = nand_readreg(ctrl, 0) & 0xffff; in brcmnand_revision_init()
668 if (ctrl->nand_version < 0x0201) { in brcmnand_revision_init()
669 dev_err(ctrl->dev, "version %#x not supported\n", in brcmnand_revision_init()
670 ctrl->nand_version); in brcmnand_revision_init()
671 return -ENODEV; in brcmnand_revision_init()
675 if (ctrl->nand_version >= 0x0702) in brcmnand_revision_init()
676 ctrl->reg_offsets = brcmnand_regs_v72; in brcmnand_revision_init()
677 else if (ctrl->nand_version == 0x0701) in brcmnand_revision_init()
678 ctrl->reg_offsets = brcmnand_regs_v71; in brcmnand_revision_init()
679 else if (ctrl->nand_version >= 0x0600) in brcmnand_revision_init()
680 ctrl->reg_offsets = brcmnand_regs_v60; in brcmnand_revision_init()
681 else if (ctrl->nand_version >= 0x0500) in brcmnand_revision_init()
682 ctrl->reg_offsets = brcmnand_regs_v50; in brcmnand_revision_init()
683 else if (ctrl->nand_version >= 0x0303) in brcmnand_revision_init()
684 ctrl->reg_offsets = brcmnand_regs_v33; in brcmnand_revision_init()
685 else if (ctrl->nand_version >= 0x0201) in brcmnand_revision_init()
686 ctrl->reg_offsets = brcmnand_regs_v21; in brcmnand_revision_init()
688 /* Chip-select stride */ in brcmnand_revision_init()
689 if (ctrl->nand_version >= 0x0701) in brcmnand_revision_init()
690 ctrl->reg_spacing = 0x14; in brcmnand_revision_init()
692 ctrl->reg_spacing = 0x10; in brcmnand_revision_init()
694 /* Per chip-select registers */ in brcmnand_revision_init()
695 if (ctrl->nand_version >= 0x0701) { in brcmnand_revision_init()
696 ctrl->cs_offsets = brcmnand_cs_offsets_v71; in brcmnand_revision_init()
698 ctrl->cs_offsets = brcmnand_cs_offsets; in brcmnand_revision_init()
700 /* v3.3-5.0 have a different CS0 offset layout */ in brcmnand_revision_init()
701 if (ctrl->nand_version >= 0x0303 && in brcmnand_revision_init()
702 ctrl->nand_version <= 0x0500) in brcmnand_revision_init()
703 ctrl->cs0_offsets = brcmnand_cs_offsets_cs0; in brcmnand_revision_init()
707 if (ctrl->nand_version >= 0x0701) { in brcmnand_revision_init()
708 /* >= v7.1 use nice power-of-2 values! */ in brcmnand_revision_init()
709 ctrl->max_page_size = 16 * 1024; in brcmnand_revision_init()
710 ctrl->max_block_size = 2 * 1024 * 1024; in brcmnand_revision_init()
712 if (ctrl->nand_version >= 0x0304) in brcmnand_revision_init()
713 ctrl->page_sizes = page_sizes_v3_4; in brcmnand_revision_init()
714 else if (ctrl->nand_version >= 0x0202) in brcmnand_revision_init()
715 ctrl->page_sizes = page_sizes_v2_2; in brcmnand_revision_init()
717 ctrl->page_sizes = page_sizes_v2_1; in brcmnand_revision_init()
719 if (ctrl->nand_version >= 0x0202) in brcmnand_revision_init()
720 ctrl->page_size_shift = CFG_PAGE_SIZE_SHIFT; in brcmnand_revision_init()
722 ctrl->page_size_shift = CFG_PAGE_SIZE_SHIFT_v2_1; in brcmnand_revision_init()
724 if (ctrl->nand_version >= 0x0600) in brcmnand_revision_init()
725 ctrl->block_sizes = block_sizes_v6; in brcmnand_revision_init()
726 else if (ctrl->nand_version >= 0x0400) in brcmnand_revision_init()
727 ctrl->block_sizes = block_sizes_v4; in brcmnand_revision_init()
728 else if (ctrl->nand_version >= 0x0202) in brcmnand_revision_init()
729 ctrl->block_sizes = block_sizes_v2_2; in brcmnand_revision_init()
731 ctrl->block_sizes = block_sizes_v2_1; in brcmnand_revision_init()
733 if (ctrl->nand_version < 0x0400) { in brcmnand_revision_init()
734 if (ctrl->nand_version < 0x0202) in brcmnand_revision_init()
735 ctrl->max_page_size = 2048; in brcmnand_revision_init()
737 ctrl->max_page_size = 4096; in brcmnand_revision_init()
738 ctrl->max_block_size = 512 * 1024; in brcmnand_revision_init()
743 if (ctrl->nand_version == 0x0702) in brcmnand_revision_init()
744 ctrl->max_oob = 128; in brcmnand_revision_init()
745 else if (ctrl->nand_version >= 0x0600) in brcmnand_revision_init()
746 ctrl->max_oob = 64; in brcmnand_revision_init()
747 else if (ctrl->nand_version >= 0x0500) in brcmnand_revision_init()
748 ctrl->max_oob = 32; in brcmnand_revision_init()
750 ctrl->max_oob = 16; in brcmnand_revision_init()
753 if (ctrl->nand_version >= 0x0600 && ctrl->nand_version != 0x0601) in brcmnand_revision_init()
754 ctrl->features |= BRCMNAND_HAS_PREFETCH; in brcmnand_revision_init()
760 if (ctrl->nand_version >= 0x0700) in brcmnand_revision_init()
761 ctrl->features |= BRCMNAND_HAS_CACHE_MODE; in brcmnand_revision_init()
763 if (ctrl->nand_version >= 0x0500) in brcmnand_revision_init()
764 ctrl->features |= BRCMNAND_HAS_1K_SECTORS; in brcmnand_revision_init()
766 if (ctrl->nand_version >= 0x0700) in brcmnand_revision_init()
767 ctrl->features |= BRCMNAND_HAS_WP; in brcmnand_revision_init()
768 else if (of_property_read_bool(ctrl->dev->of_node, "brcm,nand-has-wp")) in brcmnand_revision_init()
769 ctrl->features |= BRCMNAND_HAS_WP; in brcmnand_revision_init()
772 if (ctrl->nand_version == 0x0702) in brcmnand_revision_init()
773 ctrl->ecc_level_shift = ACC_CONTROL_ECC_EXT_SHIFT; in brcmnand_revision_init()
775 ctrl->ecc_level_shift = ACC_CONTROL_ECC_SHIFT; in brcmnand_revision_init()
780 static void brcmnand_flash_dma_revision_init(struct brcmnand_controller *ctrl) in brcmnand_flash_dma_revision_init() argument
783 if (ctrl->nand_version >= 0x0703) in brcmnand_flash_dma_revision_init()
784 ctrl->flash_dma_offsets = flash_dma_regs_v4; in brcmnand_flash_dma_revision_init()
785 else if (ctrl->nand_version == 0x0602) in brcmnand_flash_dma_revision_init()
786 ctrl->flash_dma_offsets = flash_dma_regs_v0; in brcmnand_flash_dma_revision_init()
788 ctrl->flash_dma_offsets = flash_dma_regs_v1; in brcmnand_flash_dma_revision_init()
791 static inline u32 brcmnand_read_reg(struct brcmnand_controller *ctrl, in brcmnand_read_reg() argument
794 u16 offs = ctrl->reg_offsets[reg]; in brcmnand_read_reg()
797 return nand_readreg(ctrl, offs); in brcmnand_read_reg()
802 static inline void brcmnand_write_reg(struct brcmnand_controller *ctrl, in brcmnand_write_reg() argument
805 u16 offs = ctrl->reg_offsets[reg]; in brcmnand_write_reg()
808 nand_writereg(ctrl, offs, val); in brcmnand_write_reg()
811 static inline void brcmnand_rmw_reg(struct brcmnand_controller *ctrl, in brcmnand_rmw_reg() argument
815 u32 tmp = brcmnand_read_reg(ctrl, reg); in brcmnand_rmw_reg()
819 brcmnand_write_reg(ctrl, reg, tmp); in brcmnand_rmw_reg()
822 static inline u32 brcmnand_read_fc(struct brcmnand_controller *ctrl, int word) in brcmnand_read_fc() argument
824 if (brcmnand_non_mmio_ops(ctrl)) in brcmnand_read_fc()
825 return brcmnand_soc_read(ctrl->soc, BRCMNAND_NON_MMIO_FC_ADDR); in brcmnand_read_fc()
826 return __raw_readl(ctrl->nand_fc + word * 4); in brcmnand_read_fc()
829 static inline void brcmnand_write_fc(struct brcmnand_controller *ctrl, in brcmnand_write_fc() argument
832 if (brcmnand_non_mmio_ops(ctrl)) in brcmnand_write_fc()
833 brcmnand_soc_write(ctrl->soc, val, BRCMNAND_NON_MMIO_FC_ADDR); in brcmnand_write_fc()
835 __raw_writel(val, ctrl->nand_fc + word * 4); in brcmnand_write_fc()
838 static inline void edu_writel(struct brcmnand_controller *ctrl, in edu_writel() argument
841 u16 offs = ctrl->edu_offsets[reg]; in edu_writel()
843 brcmnand_writel(val, ctrl->edu_base + offs); in edu_writel()
846 static inline u32 edu_readl(struct brcmnand_controller *ctrl, in edu_readl() argument
849 u16 offs = ctrl->edu_offsets[reg]; in edu_readl()
851 return brcmnand_readl(ctrl->edu_base + offs); in edu_readl()
854 static inline void brcmnand_read_data_bus(struct brcmnand_controller *ctrl, in brcmnand_read_data_bus() argument
857 struct brcmnand_soc *soc = ctrl->soc; in brcmnand_read_data_bus()
860 if (soc && soc->read_data_bus) { in brcmnand_read_data_bus()
861 soc->read_data_bus(soc, flash_cache, buffer, fc_words); in brcmnand_read_data_bus()
864 buffer[i] = brcmnand_read_fc(ctrl, i); in brcmnand_read_data_bus()
868 static void brcmnand_clear_ecc_addr(struct brcmnand_controller *ctrl) in brcmnand_clear_ecc_addr() argument
872 brcmnand_write_reg(ctrl, BRCMNAND_UNCORR_ADDR, 0); in brcmnand_clear_ecc_addr()
873 brcmnand_write_reg(ctrl, BRCMNAND_CORR_ADDR, 0); in brcmnand_clear_ecc_addr()
874 brcmnand_write_reg(ctrl, BRCMNAND_UNCORR_EXT_ADDR, 0); in brcmnand_clear_ecc_addr()
875 brcmnand_write_reg(ctrl, BRCMNAND_CORR_EXT_ADDR, 0); in brcmnand_clear_ecc_addr()
878 static u64 brcmnand_get_uncorrecc_addr(struct brcmnand_controller *ctrl) in brcmnand_get_uncorrecc_addr() argument
882 err_addr = brcmnand_read_reg(ctrl, BRCMNAND_UNCORR_ADDR); in brcmnand_get_uncorrecc_addr()
883 err_addr |= ((u64)(brcmnand_read_reg(ctrl, in brcmnand_get_uncorrecc_addr()
890 static u64 brcmnand_get_correcc_addr(struct brcmnand_controller *ctrl) in brcmnand_get_correcc_addr() argument
894 err_addr = brcmnand_read_reg(ctrl, BRCMNAND_CORR_ADDR); in brcmnand_get_correcc_addr()
895 err_addr |= ((u64)(brcmnand_read_reg(ctrl, in brcmnand_get_correcc_addr()
906 struct brcmnand_controller *ctrl = host->ctrl; in brcmnand_set_cmd_addr() local
908 brcmnand_write_reg(ctrl, BRCMNAND_CMD_EXT_ADDRESS, in brcmnand_set_cmd_addr()
909 (host->cs << 16) | ((addr >> 32) & 0xffff)); in brcmnand_set_cmd_addr()
910 (void)brcmnand_read_reg(ctrl, BRCMNAND_CMD_EXT_ADDRESS); in brcmnand_set_cmd_addr()
911 brcmnand_write_reg(ctrl, BRCMNAND_CMD_ADDRESS, in brcmnand_set_cmd_addr()
913 (void)brcmnand_read_reg(ctrl, BRCMNAND_CMD_ADDRESS); in brcmnand_set_cmd_addr()
916 static inline u16 brcmnand_cs_offset(struct brcmnand_controller *ctrl, int cs, in brcmnand_cs_offset() argument
919 u16 offs_cs0 = ctrl->reg_offsets[BRCMNAND_CS0_BASE]; in brcmnand_cs_offset()
920 u16 offs_cs1 = ctrl->reg_offsets[BRCMNAND_CS1_BASE]; in brcmnand_cs_offset()
923 if (cs == 0 && ctrl->cs0_offsets) in brcmnand_cs_offset()
924 cs_offs = ctrl->cs0_offsets[reg]; in brcmnand_cs_offset()
926 cs_offs = ctrl->cs_offsets[reg]; in brcmnand_cs_offset()
929 return offs_cs1 + (cs - 1) * ctrl->reg_spacing + cs_offs; in brcmnand_cs_offset()
931 return offs_cs0 + cs * ctrl->reg_spacing + cs_offs; in brcmnand_cs_offset()
934 static inline u32 brcmnand_count_corrected(struct brcmnand_controller *ctrl) in brcmnand_count_corrected() argument
936 if (ctrl->nand_version < 0x0600) in brcmnand_count_corrected()
938 return brcmnand_read_reg(ctrl, BRCMNAND_CORR_COUNT); in brcmnand_count_corrected()
943 struct brcmnand_controller *ctrl = host->ctrl; in brcmnand_wr_corr_thresh() local
946 int cs = host->cs; in brcmnand_wr_corr_thresh()
948 if (!ctrl->reg_offsets[reg]) in brcmnand_wr_corr_thresh()
951 if (ctrl->nand_version == 0x0702) in brcmnand_wr_corr_thresh()
953 else if (ctrl->nand_version >= 0x0600) in brcmnand_wr_corr_thresh()
955 else if (ctrl->nand_version >= 0x0500) in brcmnand_wr_corr_thresh()
960 if (ctrl->nand_version >= 0x0702) { in brcmnand_wr_corr_thresh()
964 } else if (ctrl->nand_version >= 0x0600) { in brcmnand_wr_corr_thresh()
969 brcmnand_rmw_reg(ctrl, reg, (bits - 1) << shift, shift, val); in brcmnand_wr_corr_thresh()
972 static inline int brcmnand_cmd_shift(struct brcmnand_controller *ctrl) in brcmnand_cmd_shift() argument
974 /* Kludge for the BCMA-based NAND controller which does not actually in brcmnand_cmd_shift()
977 if (ctrl->nand_version == 0x0304 && brcmnand_non_mmio_ops(ctrl)) in brcmnand_cmd_shift()
980 if (ctrl->nand_version < 0x0602) in brcmnand_cmd_shift()
985 static inline u32 brcmnand_spare_area_mask(struct brcmnand_controller *ctrl) in brcmnand_spare_area_mask() argument
987 if (ctrl->nand_version == 0x0702) in brcmnand_spare_area_mask()
989 else if (ctrl->nand_version >= 0x0600) in brcmnand_spare_area_mask()
991 else if (ctrl->nand_version >= 0x0303) in brcmnand_spare_area_mask()
997 static inline u32 brcmnand_ecc_level_mask(struct brcmnand_controller *ctrl) in brcmnand_ecc_level_mask() argument
999 u32 mask = (ctrl->nand_version >= 0x0600) ? 0x1f : 0x0f; in brcmnand_ecc_level_mask()
1004 if (ctrl->nand_version == 0x0702) in brcmnand_ecc_level_mask()
1012 struct brcmnand_controller *ctrl = host->ctrl; in brcmnand_set_ecc_enabled() local
1013 u16 offs = brcmnand_cs_offset(ctrl, host->cs, BRCMNAND_CS_ACC_CONTROL); in brcmnand_set_ecc_enabled()
1014 u32 acc_control = nand_readreg(ctrl, offs); in brcmnand_set_ecc_enabled()
1019 acc_control &= ~brcmnand_ecc_level_mask(ctrl); in brcmnand_set_ecc_enabled()
1020 acc_control |= host->hwcfg.ecc_level << ctrl->ecc_level_shift; in brcmnand_set_ecc_enabled()
1023 acc_control &= ~brcmnand_ecc_level_mask(ctrl); in brcmnand_set_ecc_enabled()
1026 nand_writereg(ctrl, offs, acc_control); in brcmnand_set_ecc_enabled()
1029 static inline int brcmnand_sector_1k_shift(struct brcmnand_controller *ctrl) in brcmnand_sector_1k_shift() argument
1031 if (ctrl->nand_version >= 0x0702) in brcmnand_sector_1k_shift()
1033 else if (ctrl->nand_version >= 0x0600) in brcmnand_sector_1k_shift()
1035 else if (ctrl->nand_version >= 0x0500) in brcmnand_sector_1k_shift()
1038 return -1; in brcmnand_sector_1k_shift()
1043 struct brcmnand_controller *ctrl = host->ctrl; in brcmnand_get_sector_size_1k() local
1044 int sector_size_bit = brcmnand_sector_1k_shift(ctrl); in brcmnand_get_sector_size_1k()
1045 u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs, in brcmnand_get_sector_size_1k()
1052 acc_control = nand_readreg(ctrl, acc_control_offs); in brcmnand_get_sector_size_1k()
1059 struct brcmnand_controller *ctrl = host->ctrl; in brcmnand_set_sector_size_1k() local
1060 int shift = brcmnand_sector_1k_shift(ctrl); in brcmnand_set_sector_size_1k()
1061 u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs, in brcmnand_set_sector_size_1k()
1068 tmp = nand_readreg(ctrl, acc_control_offs); in brcmnand_set_sector_size_1k()
1071 nand_writereg(ctrl, acc_control_offs, tmp); in brcmnand_set_sector_size_1k()
1076 struct brcmnand_controller *ctrl = host->ctrl; in brcmnand_get_spare_size() local
1077 u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs, in brcmnand_get_spare_size()
1079 u32 acc = nand_readreg(ctrl, acc_control_offs); in brcmnand_get_spare_size()
1081 return (acc & brcmnand_spare_area_mask(ctrl)); in brcmnand_get_spare_size()
1086 struct brcmnand_controller *ctrl = host->ctrl; in brcmnand_get_ecc_settings() local
1087 u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs, in brcmnand_get_ecc_settings()
1094 acc = nand_readreg(ctrl, acc_control_offs); in brcmnand_get_ecc_settings()
1095 ecc_level = (acc & brcmnand_ecc_level_mask(ctrl)) >> ctrl->ecc_level_shift; in brcmnand_get_ecc_settings()
1097 chip->ecc.strength = ecc_level * 2; in brcmnand_get_ecc_settings()
1099 chip->ecc.strength = 1; /* hamming */ in brcmnand_get_ecc_settings()
1101 chip->ecc.strength = ecc_level; in brcmnand_get_ecc_settings()
1103 if (chip->ecc.size == 0) { in brcmnand_get_ecc_settings()
1105 chip->ecc.size = 1024; in brcmnand_get_ecc_settings()
1107 chip->ecc.size = 512; in brcmnand_get_ecc_settings()
1124 struct brcmnand_controller *ctrl = host->ctrl; in bcmnand_ctrl_poll_status() local
1136 val = brcmnand_read_reg(ctrl, BRCMNAND_INTFC_STATUS); in bcmnand_ctrl_poll_status()
1150 val = brcmnand_read_reg(ctrl, BRCMNAND_INTFC_STATUS); in bcmnand_ctrl_poll_status()
1154 dev_err(ctrl->dev, "timeout on status poll (expected %x got %x)\n", in bcmnand_ctrl_poll_status()
1157 return -ETIMEDOUT; in bcmnand_ctrl_poll_status()
1160 static inline void brcmnand_set_wp(struct brcmnand_controller *ctrl, bool en) in brcmnand_set_wp() argument
1164 brcmnand_rmw_reg(ctrl, BRCMNAND_CS_SELECT, CS_SELECT_NAND_WP, 0, val); in brcmnand_set_wp()
1171 static inline bool has_flash_dma(struct brcmnand_controller *ctrl) in has_flash_dma() argument
1173 return ctrl->flash_dma_base; in has_flash_dma()
1176 static inline bool has_edu(struct brcmnand_controller *ctrl) in has_edu() argument
1178 return ctrl->edu_base; in has_edu()
1181 static inline bool use_dma(struct brcmnand_controller *ctrl) in use_dma() argument
1183 return has_flash_dma(ctrl) || has_edu(ctrl); in use_dma()
1186 static inline void disable_ctrl_irqs(struct brcmnand_controller *ctrl) in disable_ctrl_irqs() argument
1188 if (ctrl->pio_poll_mode) in disable_ctrl_irqs()
1191 if (has_flash_dma(ctrl)) { in disable_ctrl_irqs()
1192 ctrl->flash_dma_base = NULL; in disable_ctrl_irqs()
1193 disable_irq(ctrl->dma_irq); in disable_ctrl_irqs()
1196 disable_irq(ctrl->irq); in disable_ctrl_irqs()
1197 ctrl->pio_poll_mode = true; in disable_ctrl_irqs()
1206 static inline void flash_dma_writel(struct brcmnand_controller *ctrl, in flash_dma_writel() argument
1209 u16 offs = ctrl->flash_dma_offsets[dma_reg]; in flash_dma_writel()
1211 brcmnand_writel(val, ctrl->flash_dma_base + offs); in flash_dma_writel()
1214 static inline u32 flash_dma_readl(struct brcmnand_controller *ctrl, in flash_dma_readl() argument
1217 u16 offs = ctrl->flash_dma_offsets[dma_reg]; in flash_dma_readl()
1219 return brcmnand_readl(ctrl->flash_dma_base + offs); in flash_dma_readl()
1222 /* Low-level operation types: command, address, write, or read */
1234 static inline bool is_hamming_ecc(struct brcmnand_controller *ctrl, in is_hamming_ecc() argument
1237 if (ctrl->nand_version <= 0x0701) in is_hamming_ecc()
1238 return cfg->sector_size_1k == 0 && cfg->spare_area_size == 16 && in is_hamming_ecc()
1239 cfg->ecc_level == 15; in is_hamming_ecc()
1241 return cfg->sector_size_1k == 0 && ((cfg->spare_area_size == 16 && in is_hamming_ecc()
1242 cfg->ecc_level == 15) || in is_hamming_ecc()
1243 (cfg->spare_area_size == 28 && cfg->ecc_level == 16)); in is_hamming_ecc()
1247 * Set mtd->ooblayout to the appropriate mtd_ooblayout_ops given
1249 * Returns -ERRCODE on failure.
1256 struct brcmnand_cfg *cfg = &host->hwcfg; in brcmnand_hamming_ooblayout_ecc()
1257 int sas = cfg->spare_area_size << cfg->sector_size_1k; in brcmnand_hamming_ooblayout_ecc()
1258 int sectors = cfg->page_size / (512 << cfg->sector_size_1k); in brcmnand_hamming_ooblayout_ecc()
1261 return -ERANGE; in brcmnand_hamming_ooblayout_ecc()
1263 oobregion->offset = (section * sas) + 6; in brcmnand_hamming_ooblayout_ecc()
1264 oobregion->length = 3; in brcmnand_hamming_ooblayout_ecc()
1274 struct brcmnand_cfg *cfg = &host->hwcfg; in brcmnand_hamming_ooblayout_free()
1275 int sas = cfg->spare_area_size << cfg->sector_size_1k; in brcmnand_hamming_ooblayout_free()
1276 int sectors = cfg->page_size / (512 << cfg->sector_size_1k); in brcmnand_hamming_ooblayout_free()
1280 return -ERANGE; in brcmnand_hamming_ooblayout_free()
1287 oobregion->offset = ((section - 1) * sas) + 9; in brcmnand_hamming_ooblayout_free()
1289 if (cfg->page_size > 512) { in brcmnand_hamming_ooblayout_free()
1291 oobregion->offset = 2; in brcmnand_hamming_ooblayout_free()
1294 oobregion->offset = 0; in brcmnand_hamming_ooblayout_free()
1295 next--; in brcmnand_hamming_ooblayout_free()
1299 oobregion->length = next - oobregion->offset; in brcmnand_hamming_ooblayout_free()
1314 struct brcmnand_cfg *cfg = &host->hwcfg; in brcmnand_bch_ooblayout_ecc()
1315 int sas = cfg->spare_area_size << cfg->sector_size_1k; in brcmnand_bch_ooblayout_ecc()
1316 int sectors = cfg->page_size / (512 << cfg->sector_size_1k); in brcmnand_bch_ooblayout_ecc()
1319 return -ERANGE; in brcmnand_bch_ooblayout_ecc()
1321 oobregion->offset = ((section + 1) * sas) - chip->ecc.bytes; in brcmnand_bch_ooblayout_ecc()
1322 oobregion->length = chip->ecc.bytes; in brcmnand_bch_ooblayout_ecc()
1332 struct brcmnand_cfg *cfg = &host->hwcfg; in brcmnand_bch_ooblayout_free_lp()
1333 int sas = cfg->spare_area_size << cfg->sector_size_1k; in brcmnand_bch_ooblayout_free_lp()
1334 int sectors = cfg->page_size / (512 << cfg->sector_size_1k); in brcmnand_bch_ooblayout_free_lp()
1337 return -ERANGE; in brcmnand_bch_ooblayout_free_lp()
1339 if (sas <= chip->ecc.bytes) in brcmnand_bch_ooblayout_free_lp()
1342 oobregion->offset = section * sas; in brcmnand_bch_ooblayout_free_lp()
1343 oobregion->length = sas - chip->ecc.bytes; in brcmnand_bch_ooblayout_free_lp()
1346 oobregion->offset++; in brcmnand_bch_ooblayout_free_lp()
1347 oobregion->length--; in brcmnand_bch_ooblayout_free_lp()
1358 struct brcmnand_cfg *cfg = &host->hwcfg; in brcmnand_bch_ooblayout_free_sp()
1359 int sas = cfg->spare_area_size << cfg->sector_size_1k; in brcmnand_bch_ooblayout_free_sp()
1361 if (section > 1 || sas - chip->ecc.bytes < 6 || in brcmnand_bch_ooblayout_free_sp()
1362 (section && sas - chip->ecc.bytes == 6)) in brcmnand_bch_ooblayout_free_sp()
1363 return -ERANGE; in brcmnand_bch_ooblayout_free_sp()
1366 oobregion->offset = 0; in brcmnand_bch_ooblayout_free_sp()
1367 oobregion->length = 5; in brcmnand_bch_ooblayout_free_sp()
1369 oobregion->offset = 6; in brcmnand_bch_ooblayout_free_sp()
1370 oobregion->length = sas - chip->ecc.bytes - 6; in brcmnand_bch_ooblayout_free_sp()
1388 struct brcmnand_cfg *p = &host->hwcfg; in brcmstb_choose_ecc_layout()
1389 struct mtd_info *mtd = nand_to_mtd(&host->chip); in brcmstb_choose_ecc_layout()
1390 struct nand_ecc_ctrl *ecc = &host->chip.ecc; in brcmstb_choose_ecc_layout()
1391 unsigned int ecc_level = p->ecc_level; in brcmstb_choose_ecc_layout()
1392 int sas = p->spare_area_size << p->sector_size_1k; in brcmstb_choose_ecc_layout()
1393 int sectors = p->page_size / (512 << p->sector_size_1k); in brcmstb_choose_ecc_layout()
1395 if (p->sector_size_1k) in brcmstb_choose_ecc_layout()
1398 if (is_hamming_ecc(host->ctrl, p)) { in brcmstb_choose_ecc_layout()
1399 ecc->bytes = 3 * sectors; in brcmstb_choose_ecc_layout()
1410 ecc->bytes = DIV_ROUND_UP(ecc_level * 14, 8); in brcmstb_choose_ecc_layout()
1411 if (p->page_size == 512) in brcmstb_choose_ecc_layout()
1416 if (ecc->bytes >= sas) { in brcmstb_choose_ecc_layout()
1417 dev_err(&host->pdev->dev, in brcmstb_choose_ecc_layout()
1419 ecc->bytes, sas); in brcmstb_choose_ecc_layout()
1420 return -EINVAL; in brcmstb_choose_ecc_layout()
1430 struct brcmnand_controller *ctrl = host->ctrl; in brcmnand_wp() local
1432 if ((ctrl->features & BRCMNAND_HAS_WP) && wp_on == 1) { in brcmnand_wp()
1433 static int old_wp = -1; in brcmnand_wp()
1437 dev_dbg(ctrl->dev, "WP %s\n", wp ? "on" : "off"); in brcmnand_wp()
1442 * make sure ctrl/flash ready before and after in brcmnand_wp()
1452 brcmnand_set_wp(ctrl, wp); in brcmnand_wp()
1465 dev_err_ratelimited(&host->pdev->dev, in brcmnand_wp()
1472 static inline u8 oob_reg_read(struct brcmnand_controller *ctrl, u32 offs) in oob_reg_read() argument
1476 offset0 = ctrl->reg_offsets[BRCMNAND_OOB_READ_BASE]; in oob_reg_read()
1477 offset10 = ctrl->reg_offsets[BRCMNAND_OOB_READ_10_BASE]; in oob_reg_read()
1479 if (offs >= ctrl->max_oob) in oob_reg_read()
1483 reg_offs = offset10 + ((offs - 0x10) & ~0x03); in oob_reg_read()
1487 return nand_readreg(ctrl, reg_offs) >> (24 - ((offs & 0x03) << 3)); in oob_reg_read()
1490 static inline void oob_reg_write(struct brcmnand_controller *ctrl, u32 offs, in oob_reg_write() argument
1495 offset0 = ctrl->reg_offsets[BRCMNAND_OOB_WRITE_BASE]; in oob_reg_write()
1496 offset10 = ctrl->reg_offsets[BRCMNAND_OOB_WRITE_10_BASE]; in oob_reg_write()
1498 if (offs >= ctrl->max_oob) in oob_reg_write()
1502 reg_offs = offset10 + ((offs - 0x10) & ~0x03); in oob_reg_write()
1506 nand_writereg(ctrl, reg_offs, data); in oob_reg_write()
1510 * read_oob_from_regs - read data from OOB registers
1511 * @ctrl: NAND controller
1512 * @i: sub-page sector index
1517 static int read_oob_from_regs(struct brcmnand_controller *ctrl, int i, u8 *oob, in read_oob_from_regs() argument
1525 tbytes = max(0, tbytes - (int)ctrl->max_oob); in read_oob_from_regs()
1526 tbytes = min_t(int, tbytes, ctrl->max_oob); in read_oob_from_regs()
1529 oob[j] = oob_reg_read(ctrl, j); in read_oob_from_regs()
1534 * write_oob_to_regs - write data to OOB registers
1535 * @i: sub-page sector index
1540 static int write_oob_to_regs(struct brcmnand_controller *ctrl, int i, in write_oob_to_regs() argument
1550 tbytes = max(0, tbytes - (int)ctrl->max_oob); in write_oob_to_regs()
1551 tbytes = min_t(int, tbytes, ctrl->max_oob); in write_oob_to_regs()
1558 oob_reg_write(ctrl, j, in write_oob_to_regs()
1569 oob_reg_write(ctrl, (tbytes & ~0x3), (__force u32)cpu_to_be32(last)); in write_oob_to_regs()
1574 static void brcmnand_edu_init(struct brcmnand_controller *ctrl) in brcmnand_edu_init() argument
1577 edu_writel(ctrl, EDU_ERR_STATUS, 0); in brcmnand_edu_init()
1578 edu_readl(ctrl, EDU_ERR_STATUS); in brcmnand_edu_init()
1579 edu_writel(ctrl, EDU_DONE, 0); in brcmnand_edu_init()
1580 edu_writel(ctrl, EDU_DONE, 0); in brcmnand_edu_init()
1581 edu_writel(ctrl, EDU_DONE, 0); in brcmnand_edu_init()
1582 edu_writel(ctrl, EDU_DONE, 0); in brcmnand_edu_init()
1583 edu_readl(ctrl, EDU_DONE); in brcmnand_edu_init()
1589 struct brcmnand_controller *ctrl = data; in brcmnand_edu_irq() local
1591 if (ctrl->edu_count) { in brcmnand_edu_irq()
1592 ctrl->edu_count--; in brcmnand_edu_irq()
1593 while (!(edu_readl(ctrl, EDU_DONE) & EDU_DONE_MASK)) in brcmnand_edu_irq()
1595 edu_writel(ctrl, EDU_DONE, 0); in brcmnand_edu_irq()
1596 edu_readl(ctrl, EDU_DONE); in brcmnand_edu_irq()
1599 if (ctrl->edu_count) { in brcmnand_edu_irq()
1600 ctrl->edu_dram_addr += FC_BYTES; in brcmnand_edu_irq()
1601 ctrl->edu_ext_addr += FC_BYTES; in brcmnand_edu_irq()
1603 edu_writel(ctrl, EDU_DRAM_ADDR, (u32)ctrl->edu_dram_addr); in brcmnand_edu_irq()
1604 edu_readl(ctrl, EDU_DRAM_ADDR); in brcmnand_edu_irq()
1605 edu_writel(ctrl, EDU_EXT_ADDR, ctrl->edu_ext_addr); in brcmnand_edu_irq()
1606 edu_readl(ctrl, EDU_EXT_ADDR); in brcmnand_edu_irq()
1608 if (ctrl->oob) { in brcmnand_edu_irq()
1609 if (ctrl->edu_cmd == EDU_CMD_READ) { in brcmnand_edu_irq()
1610 ctrl->oob += read_oob_from_regs(ctrl, in brcmnand_edu_irq()
1611 ctrl->edu_count + 1, in brcmnand_edu_irq()
1612 ctrl->oob, ctrl->sas, in brcmnand_edu_irq()
1613 ctrl->sector_size_1k); in brcmnand_edu_irq()
1615 brcmnand_write_reg(ctrl, BRCMNAND_CMD_ADDRESS, in brcmnand_edu_irq()
1616 ctrl->edu_ext_addr); in brcmnand_edu_irq()
1617 brcmnand_read_reg(ctrl, BRCMNAND_CMD_ADDRESS); in brcmnand_edu_irq()
1618 ctrl->oob += write_oob_to_regs(ctrl, in brcmnand_edu_irq()
1619 ctrl->edu_count, in brcmnand_edu_irq()
1620 ctrl->oob, ctrl->sas, in brcmnand_edu_irq()
1621 ctrl->sector_size_1k); in brcmnand_edu_irq()
1626 edu_writel(ctrl, EDU_CMD, ctrl->edu_cmd); in brcmnand_edu_irq()
1627 edu_readl(ctrl, EDU_CMD); in brcmnand_edu_irq()
1632 complete(&ctrl->edu_done); in brcmnand_edu_irq()
1639 struct brcmnand_controller *ctrl = data; in brcmnand_ctlrdy_irq() local
1642 if (ctrl->dma_pending) in brcmnand_ctlrdy_irq()
1646 if (ctrl->edu_pending) { in brcmnand_ctlrdy_irq()
1647 if (irq == ctrl->irq && ((int)ctrl->edu_irq >= 0)) in brcmnand_ctlrdy_irq()
1655 complete(&ctrl->done); in brcmnand_ctlrdy_irq()
1659 /* Handle SoC-specific interrupt hardware */
1662 struct brcmnand_controller *ctrl = data; in brcmnand_irq() local
1664 if (ctrl->soc->ctlrdy_ack(ctrl->soc)) in brcmnand_irq()
1672 struct brcmnand_controller *ctrl = data; in brcmnand_dma_irq() local
1674 complete(&ctrl->dma_done); in brcmnand_dma_irq()
1681 struct brcmnand_controller *ctrl = host->ctrl; in brcmnand_send_cmd() local
1685 cmd_addr = brcmnand_read_reg(ctrl, BRCMNAND_CMD_ADDRESS); in brcmnand_send_cmd()
1687 dev_dbg(ctrl->dev, "send native cmd %d addr 0x%llx\n", cmd, cmd_addr); in brcmnand_send_cmd()
1695 if (ctrl->cmd_pending && in brcmnand_send_cmd()
1699 BUG_ON(ctrl->cmd_pending != 0); in brcmnand_send_cmd()
1700 ctrl->cmd_pending = cmd; in brcmnand_send_cmd()
1706 brcmnand_write_reg(ctrl, BRCMNAND_CMD_START, in brcmnand_send_cmd()
1707 cmd << brcmnand_cmd_shift(ctrl)); in brcmnand_send_cmd()
1713 struct brcmnand_controller *ctrl = host->ctrl; in brcmstb_nand_wait_for_completion() local
1718 if (mtd->oops_panic_write || ctrl->irq < 0) { in brcmstb_nand_wait_for_completion()
1720 disable_ctrl_irqs(ctrl); in brcmstb_nand_wait_for_completion()
1728 sts = wait_for_completion_timeout(&ctrl->done, timeo); in brcmstb_nand_wait_for_completion()
1738 struct brcmnand_controller *ctrl = host->ctrl; in brcmnand_waitfunc() local
1741 dev_dbg(ctrl->dev, "wait on native cmd %d\n", ctrl->cmd_pending); in brcmnand_waitfunc()
1742 if (ctrl->cmd_pending) in brcmnand_waitfunc()
1745 ctrl->cmd_pending = 0; in brcmnand_waitfunc()
1747 u32 cmd = brcmnand_read_reg(ctrl, BRCMNAND_CMD_START) in brcmnand_waitfunc()
1748 >> brcmnand_cmd_shift(ctrl); in brcmnand_waitfunc()
1750 dev_err_ratelimited(ctrl->dev, in brcmnand_waitfunc()
1752 dev_err_ratelimited(ctrl->dev, "intfc status %08x\n", in brcmnand_waitfunc()
1753 brcmnand_read_reg(ctrl, BRCMNAND_INTFC_STATUS)); in brcmnand_waitfunc()
1754 return -ETIMEDOUT; in brcmnand_waitfunc()
1756 return brcmnand_read_reg(ctrl, BRCMNAND_INTFC_STATUS) & in brcmnand_waitfunc()
1762 struct nand_chip *chip = &host->chip; in brcmnand_status()
1773 struct nand_chip *chip = &host->chip; in brcmnand_reset()
1794 struct nand_chip *chip = &host->chip; in brcmnand_low_level_op()
1795 struct brcmnand_controller *ctrl = host->ctrl; in brcmnand_low_level_op() local
1820 dev_dbg(ctrl->dev, "ll_op cmd %#x\n", tmp); in brcmnand_low_level_op()
1822 brcmnand_write_reg(ctrl, BRCMNAND_LL_OP, tmp); in brcmnand_low_level_op()
1823 (void)brcmnand_read_reg(ctrl, BRCMNAND_LL_OP); in brcmnand_low_level_op()
1835 struct brcmnand_controller *ctrl = host->ctrl; in brcmnand_edu_trans() local
1836 struct brcmnand_cfg *cfg = &host->hwcfg; in brcmnand_edu_trans()
1844 dev_dbg(ctrl->dev, "EDU %s %p:%p\n", ((edu_cmd == EDU_CMD_READ) ? in brcmnand_edu_trans()
1847 pa = dma_map_single(ctrl->dev, buf, len, dir); in brcmnand_edu_trans()
1848 if (dma_mapping_error(ctrl->dev, pa)) { in brcmnand_edu_trans()
1849 dev_err(ctrl->dev, "unable to map buffer for EDU DMA\n"); in brcmnand_edu_trans()
1850 return -ENOMEM; in brcmnand_edu_trans()
1853 ctrl->edu_pending = true; in brcmnand_edu_trans()
1854 ctrl->edu_dram_addr = pa; in brcmnand_edu_trans()
1855 ctrl->edu_ext_addr = addr; in brcmnand_edu_trans()
1856 ctrl->edu_cmd = edu_cmd; in brcmnand_edu_trans()
1857 ctrl->edu_count = trans; in brcmnand_edu_trans()
1858 ctrl->sas = cfg->spare_area_size; in brcmnand_edu_trans()
1859 ctrl->oob = oob; in brcmnand_edu_trans()
1861 edu_writel(ctrl, EDU_DRAM_ADDR, (u32)ctrl->edu_dram_addr); in brcmnand_edu_trans()
1862 edu_readl(ctrl, EDU_DRAM_ADDR); in brcmnand_edu_trans()
1863 edu_writel(ctrl, EDU_EXT_ADDR, ctrl->edu_ext_addr); in brcmnand_edu_trans()
1864 edu_readl(ctrl, EDU_EXT_ADDR); in brcmnand_edu_trans()
1865 edu_writel(ctrl, EDU_LENGTH, FC_BYTES); in brcmnand_edu_trans()
1866 edu_readl(ctrl, EDU_LENGTH); in brcmnand_edu_trans()
1868 if (ctrl->oob && (ctrl->edu_cmd == EDU_CMD_WRITE)) { in brcmnand_edu_trans()
1869 brcmnand_write_reg(ctrl, BRCMNAND_CMD_ADDRESS, in brcmnand_edu_trans()
1870 ctrl->edu_ext_addr); in brcmnand_edu_trans()
1871 brcmnand_read_reg(ctrl, BRCMNAND_CMD_ADDRESS); in brcmnand_edu_trans()
1872 ctrl->oob += write_oob_to_regs(ctrl, in brcmnand_edu_trans()
1874 ctrl->oob, ctrl->sas, in brcmnand_edu_trans()
1875 ctrl->sector_size_1k); in brcmnand_edu_trans()
1880 edu_writel(ctrl, EDU_CMD, ctrl->edu_cmd); in brcmnand_edu_trans()
1881 edu_readl(ctrl, EDU_CMD); in brcmnand_edu_trans()
1883 if (wait_for_completion_timeout(&ctrl->edu_done, timeo) <= 0) { in brcmnand_edu_trans()
1884 dev_err(ctrl->dev, in brcmnand_edu_trans()
1886 edu_readl(ctrl, EDU_STATUS), in brcmnand_edu_trans()
1887 edu_readl(ctrl, EDU_ERR_STATUS)); in brcmnand_edu_trans()
1890 dma_unmap_single(ctrl->dev, pa, len, dir); in brcmnand_edu_trans()
1893 if (ctrl->oob && (ctrl->edu_cmd == EDU_CMD_READ)) { in brcmnand_edu_trans()
1894 ctrl->oob += read_oob_from_regs(ctrl, in brcmnand_edu_trans()
1896 ctrl->oob, ctrl->sas, in brcmnand_edu_trans()
1897 ctrl->sector_size_1k); in brcmnand_edu_trans()
1901 if (((brcmnand_read_reg(ctrl, BRCMNAND_INTFC_STATUS) & in brcmnand_edu_trans()
1904 dev_info(ctrl->dev, "program failed at %llx\n", in brcmnand_edu_trans()
1906 ret = -EIO; in brcmnand_edu_trans()
1910 if (edu_readl(ctrl, EDU_STATUS) & EDU_STATUS_ACTIVE) in brcmnand_edu_trans()
1911 dev_warn(ctrl->dev, "EDU still active: %#x\n", in brcmnand_edu_trans()
1912 edu_readl(ctrl, EDU_STATUS)); in brcmnand_edu_trans()
1914 if (unlikely(edu_readl(ctrl, EDU_ERR_STATUS) & EDU_ERR_STATUS_ERRACK)) { in brcmnand_edu_trans()
1915 dev_warn(ctrl->dev, "EDU RBUS error at addr %llx\n", in brcmnand_edu_trans()
1917 ret = -EIO; in brcmnand_edu_trans()
1920 ctrl->edu_pending = false; in brcmnand_edu_trans()
1921 brcmnand_edu_init(ctrl); in brcmnand_edu_trans()
1922 edu_writel(ctrl, EDU_STOP, 0); /* force stop */ in brcmnand_edu_trans()
1923 edu_readl(ctrl, EDU_STOP); in brcmnand_edu_trans()
1932 err_addr = brcmnand_get_uncorrecc_addr(ctrl); in brcmnand_edu_trans()
1934 err_addr = brcmnand_get_correcc_addr(ctrl); in brcmnand_edu_trans()
1936 ret = -EUCLEAN; in brcmnand_edu_trans()
1938 ret = -EBADMSG; in brcmnand_edu_trans()
1947 * - Is this descriptor the beginning or end of a linked list?
1948 * - What is the (DMA) address of the next descriptor in the linked list?
1958 desc->next_desc = lower_32_bits(next_desc); in brcmnand_fill_dma_desc()
1959 desc->next_desc_ext = upper_32_bits(next_desc); in brcmnand_fill_dma_desc()
1960 desc->cmd_irq = (dma_cmd << 24) | in brcmnand_fill_dma_desc()
1964 desc->cmd_irq |= 0x01 << 12; in brcmnand_fill_dma_desc()
1966 desc->dram_addr = lower_32_bits(buf); in brcmnand_fill_dma_desc()
1967 desc->dram_addr_ext = upper_32_bits(buf); in brcmnand_fill_dma_desc()
1968 desc->tfr_len = len; in brcmnand_fill_dma_desc()
1969 desc->total_len = len; in brcmnand_fill_dma_desc()
1970 desc->flash_addr = lower_32_bits(addr); in brcmnand_fill_dma_desc()
1971 desc->flash_addr_ext = upper_32_bits(addr); in brcmnand_fill_dma_desc()
1972 desc->cs = host->cs; in brcmnand_fill_dma_desc()
1973 desc->status_valid = 0x01; in brcmnand_fill_dma_desc()
1982 struct brcmnand_controller *ctrl = host->ctrl; in brcmnand_dma_run() local
1985 flash_dma_writel(ctrl, FLASH_DMA_FIRST_DESC, lower_32_bits(desc)); in brcmnand_dma_run()
1986 (void)flash_dma_readl(ctrl, FLASH_DMA_FIRST_DESC); in brcmnand_dma_run()
1987 if (ctrl->nand_version > 0x0602) { in brcmnand_dma_run()
1988 flash_dma_writel(ctrl, FLASH_DMA_FIRST_DESC_EXT, in brcmnand_dma_run()
1990 (void)flash_dma_readl(ctrl, FLASH_DMA_FIRST_DESC_EXT); in brcmnand_dma_run()
1994 ctrl->dma_pending = true; in brcmnand_dma_run()
1996 flash_dma_writel(ctrl, FLASH_DMA_CTRL, 0x03); /* wake | run */ in brcmnand_dma_run()
1998 if (wait_for_completion_timeout(&ctrl->dma_done, timeo) <= 0) { in brcmnand_dma_run()
1999 dev_err(ctrl->dev, in brcmnand_dma_run()
2001 flash_dma_readl(ctrl, FLASH_DMA_STATUS), in brcmnand_dma_run()
2002 flash_dma_readl(ctrl, FLASH_DMA_ERROR_STATUS)); in brcmnand_dma_run()
2004 ctrl->dma_pending = false; in brcmnand_dma_run()
2005 flash_dma_writel(ctrl, FLASH_DMA_CTRL, 0); /* force stop */ in brcmnand_dma_run()
2011 struct brcmnand_controller *ctrl = host->ctrl; in brcmnand_dma_trans() local
2015 buf_pa = dma_map_single(ctrl->dev, buf, len, dir); in brcmnand_dma_trans()
2016 if (dma_mapping_error(ctrl->dev, buf_pa)) { in brcmnand_dma_trans()
2017 dev_err(ctrl->dev, "unable to map buffer for DMA\n"); in brcmnand_dma_trans()
2018 return -ENOMEM; in brcmnand_dma_trans()
2021 brcmnand_fill_dma_desc(host, ctrl->dma_desc, addr, buf_pa, len, in brcmnand_dma_trans()
2024 brcmnand_dma_run(host, ctrl->dma_pa); in brcmnand_dma_trans()
2026 dma_unmap_single(ctrl->dev, buf_pa, len, dir); in brcmnand_dma_trans()
2028 if (ctrl->dma_desc->status_valid & FLASH_DMA_ECC_ERROR) in brcmnand_dma_trans()
2029 return -EBADMSG; in brcmnand_dma_trans()
2030 else if (ctrl->dma_desc->status_valid & FLASH_DMA_CORR_ERROR) in brcmnand_dma_trans()
2031 return -EUCLEAN; in brcmnand_dma_trans()
2044 struct brcmnand_controller *ctrl = host->ctrl; in brcmnand_read_by_pio() local
2047 brcmnand_clear_ecc_addr(ctrl); in brcmnand_read_by_pio()
2056 brcmnand_soc_data_bus_prepare(ctrl->soc, false); in brcmnand_read_by_pio()
2058 brcmnand_read_data_bus(ctrl, ctrl->nand_fc, buf, FC_WORDS); in brcmnand_read_by_pio()
2061 brcmnand_soc_data_bus_unprepare(ctrl->soc, false); in brcmnand_read_by_pio()
2065 oob += read_oob_from_regs(ctrl, i, oob, in brcmnand_read_by_pio()
2066 mtd->oobsize / trans, in brcmnand_read_by_pio()
2067 host->hwcfg.sector_size_1k); in brcmnand_read_by_pio()
2069 if (ret != -EBADMSG) { in brcmnand_read_by_pio()
2070 *err_addr = brcmnand_get_uncorrecc_addr(ctrl); in brcmnand_read_by_pio()
2073 ret = -EBADMSG; in brcmnand_read_by_pio()
2077 *err_addr = brcmnand_get_correcc_addr(ctrl); in brcmnand_read_by_pio()
2080 ret = -EUCLEAN; in brcmnand_read_by_pio()
2095 * On a real error, return a negative error code (-EBADMSG for ECC error), and
2098 * bitflips-per-ECC-sector to the caller.
2107 int page = addr >> chip->page_shift; in brcmstb_nand_verify_erased_page()
2116 ret = chip->ecc.read_page_raw(chip, buf, true, page); in brcmstb_nand_verify_erased_page()
2120 for (i = 0; i < chip->ecc.steps; i++) { in brcmstb_nand_verify_erased_page()
2121 ecc_chunk = buf + chip->ecc.size * i; in brcmstb_nand_verify_erased_page()
2124 ecc_bytes = chip->oob_poi + ecc.offset; in brcmstb_nand_verify_erased_page()
2126 ret = nand_check_erased_ecc_chunk(ecc_chunk, chip->ecc.size, in brcmstb_nand_verify_erased_page()
2129 chip->ecc.strength); in brcmstb_nand_verify_erased_page()
2143 struct brcmnand_controller *ctrl = host->ctrl; in brcmnand_read() local
2149 dev_dbg(ctrl->dev, "read %llx -> %p\n", (unsigned long long)addr, buf); in brcmnand_read()
2152 brcmnand_clear_ecc_addr(ctrl); in brcmnand_read()
2154 if (ctrl->dma_trans && (has_edu(ctrl) || !oob) && in brcmnand_read()
2156 err = ctrl->dma_trans(host, addr, buf, oob, in brcmnand_read()
2164 return -EIO; in brcmnand_read()
2167 if (has_edu(ctrl) && err_addr) in brcmnand_read()
2172 memset(oob, 0x99, mtd->oobsize); in brcmnand_read()
2187 if ((ctrl->nand_version == 0x0700) || in brcmnand_read()
2188 (ctrl->nand_version == 0x0701)) { in brcmnand_read()
2199 if (ctrl->nand_version < 0x0702) { in brcmnand_read()
2207 dev_err(ctrl->dev, "uncorrectable error at 0x%llx\n", in brcmnand_read()
2209 mtd->ecc_stats.failed++; in brcmnand_read()
2215 unsigned int corrected = brcmnand_count_corrected(ctrl); in brcmnand_read()
2222 dev_dbg(ctrl->dev, "corrected error at 0x%llx\n", in brcmnand_read()
2224 mtd->ecc_stats.corrected += corrected; in brcmnand_read()
2225 /* Always exceed the software-imposed threshold */ in brcmnand_read()
2226 return max(mtd->bitflip_threshold, corrected); in brcmnand_read()
2237 u8 *oob = oob_required ? (u8 *)chip->oob_poi : NULL; in brcmnand_read_page()
2238 u64 addr = (u64)page << chip->page_shift; in brcmnand_read_page()
2240 host->last_addr = addr; in brcmnand_read_page()
2242 return brcmnand_read(mtd, chip, host->last_addr, in brcmnand_read_page()
2243 mtd->writesize >> FC_SHIFT, (u32 *)buf, oob); in brcmnand_read_page()
2251 u8 *oob = oob_required ? (u8 *)chip->oob_poi : NULL; in brcmnand_read_page_raw()
2253 u64 addr = (u64)page << chip->page_shift; in brcmnand_read_page_raw()
2255 host->last_addr = addr; in brcmnand_read_page_raw()
2258 ret = brcmnand_read(mtd, chip, host->last_addr, in brcmnand_read_page_raw()
2259 mtd->writesize >> FC_SHIFT, (u32 *)buf, oob); in brcmnand_read_page_raw()
2268 return brcmnand_read(mtd, chip, (u64)page << chip->page_shift, in brcmnand_read_oob()
2269 mtd->writesize >> FC_SHIFT, in brcmnand_read_oob()
2270 NULL, (u8 *)chip->oob_poi); in brcmnand_read_oob()
2279 brcmnand_read(mtd, chip, (u64)page << chip->page_shift, in brcmnand_read_oob_raw()
2280 mtd->writesize >> FC_SHIFT, in brcmnand_read_oob_raw()
2281 NULL, (u8 *)chip->oob_poi); in brcmnand_read_oob_raw()
2290 struct brcmnand_controller *ctrl = host->ctrl; in brcmnand_write() local
2291 unsigned int i, j, trans = mtd->writesize >> FC_SHIFT; in brcmnand_write()
2294 dev_dbg(ctrl->dev, "write %llx <- %p\n", (unsigned long long)addr, buf); in brcmnand_write()
2297 dev_warn(ctrl->dev, "unaligned buffer: %p\n", buf); in brcmnand_write()
2303 for (i = 0; i < ctrl->max_oob; i += 4) in brcmnand_write()
2304 oob_reg_write(ctrl, i, 0xffffffff); in brcmnand_write()
2306 if (mtd->oops_panic_write) in brcmnand_write()
2308 disable_ctrl_irqs(ctrl); in brcmnand_write()
2310 if (use_dma(ctrl) && (has_edu(ctrl) || !oob) && flash_dma_buf_ok(buf)) { in brcmnand_write()
2311 if (ctrl->dma_trans(host, addr, (u32 *)buf, oob, mtd->writesize, in brcmnand_write()
2314 ret = -EIO; in brcmnand_write()
2324 brcmnand_soc_data_bus_prepare(ctrl->soc, false); in brcmnand_write()
2327 brcmnand_write_fc(ctrl, j, *buf); in brcmnand_write()
2329 brcmnand_soc_data_bus_unprepare(ctrl->soc, false); in brcmnand_write()
2332 brcmnand_write_fc(ctrl, j, 0xffffffff); in brcmnand_write()
2336 oob += write_oob_to_regs(ctrl, i, oob, in brcmnand_write()
2337 mtd->oobsize / trans, in brcmnand_write()
2338 host->hwcfg.sector_size_1k); in brcmnand_write()
2351 dev_info(ctrl->dev, "program failed at %llx\n", in brcmnand_write()
2353 ret = -EIO; in brcmnand_write()
2367 void *oob = oob_required ? chip->oob_poi : NULL; in brcmnand_write_page()
2368 u64 addr = (u64)page << chip->page_shift; in brcmnand_write_page()
2370 host->last_addr = addr; in brcmnand_write_page()
2372 return brcmnand_write(mtd, chip, host->last_addr, (const u32 *)buf, oob); in brcmnand_write_page()
2380 void *oob = oob_required ? chip->oob_poi : NULL; in brcmnand_write_page_raw()
2381 u64 addr = (u64)page << chip->page_shift; in brcmnand_write_page_raw()
2384 host->last_addr = addr; in brcmnand_write_page_raw()
2386 ret = brcmnand_write(mtd, chip, host->last_addr, (const u32 *)buf, oob); in brcmnand_write_page_raw()
2395 (u64)page << chip->page_shift, NULL, in brcmnand_write_oob()
2396 chip->oob_poi); in brcmnand_write_oob()
2406 ret = brcmnand_write(mtd, chip, (u64)page << chip->page_shift, NULL, in brcmnand_write_oob_raw()
2407 (u8 *)chip->oob_poi); in brcmnand_write_oob_raw()
2416 const struct nand_op_instr *instr = &op->instrs[i]; in brcmnand_exec_instr()
2417 struct brcmnand_controller *ctrl = host->ctrl; in brcmnand_exec_instr() local
2427 last_op = ((i == (op->ninstrs - 1)) && (instr->type != NAND_OP_WAITRDY_INSTR)) || in brcmnand_exec_instr()
2428 ((i == (op->ninstrs - 2)) && (op->instrs[i + 1].type == NAND_OP_WAITRDY_INSTR)); in brcmnand_exec_instr()
2430 switch (instr->type) { in brcmnand_exec_instr()
2432 brcmnand_low_level_op(host, LL_OP_CMD, instr->ctx.cmd.opcode, last_op); in brcmnand_exec_instr()
2436 for (i = 0; i < instr->ctx.addr.naddrs; i++) in brcmnand_exec_instr()
2437 brcmnand_low_level_op(host, LL_OP_ADDR, instr->ctx.addr.addrs[i], in brcmnand_exec_instr()
2438 last_op && (i == (instr->ctx.addr.naddrs - 1))); in brcmnand_exec_instr()
2442 in = instr->ctx.data.buf.in; in brcmnand_exec_instr()
2443 for (i = 0; i < instr->ctx.data.len; i++) { in brcmnand_exec_instr()
2445 last_op && (i == (instr->ctx.data.len - 1))); in brcmnand_exec_instr()
2446 in[i] = brcmnand_read_reg(host->ctrl, BRCMNAND_LL_RDATA); in brcmnand_exec_instr()
2451 out = instr->ctx.data.buf.out; in brcmnand_exec_instr()
2452 for (i = 0; i < instr->ctx.data.len; i++) in brcmnand_exec_instr()
2454 last_op && (i == (instr->ctx.data.len - 1))); in brcmnand_exec_instr()
2462 dev_err(ctrl->dev, "unsupported instruction type: %d\n", in brcmnand_exec_instr()
2463 instr->type); in brcmnand_exec_instr()
2464 ret = -EINVAL; in brcmnand_exec_instr()
2473 if (op->ninstrs == 2 && in brcmnand_op_is_status()
2474 op->instrs[0].type == NAND_OP_CMD_INSTR && in brcmnand_op_is_status()
2475 op->instrs[0].ctx.cmd.opcode == NAND_CMD_STATUS && in brcmnand_op_is_status()
2476 op->instrs[1].type == NAND_OP_DATA_IN_INSTR) in brcmnand_op_is_status()
2484 if (op->ninstrs == 2 && in brcmnand_op_is_reset()
2485 op->instrs[0].type == NAND_OP_CMD_INSTR && in brcmnand_op_is_reset()
2486 op->instrs[0].ctx.cmd.opcode == NAND_CMD_RESET && in brcmnand_op_is_reset()
2487 op->instrs[1].type == NAND_OP_WAITRDY_INSTR) in brcmnand_op_is_reset()
2507 status = op->instrs[1].ctx.data.buf.in; in brcmnand_exec_op()
2525 if (op->deassert_wp) in brcmnand_exec_op()
2528 for (i = 0; i < op->ninstrs; i++) { in brcmnand_exec_op()
2534 if (op->deassert_wp) in brcmnand_exec_op()
2541 * Per-CS setup (1 NAND device)
2547 struct brcmnand_controller *ctrl = host->ctrl; in brcmnand_set_cfg() local
2548 struct nand_chip *chip = &host->chip; in brcmnand_set_cfg()
2549 u16 cfg_offs = brcmnand_cs_offset(ctrl, host->cs, BRCMNAND_CS_CFG); in brcmnand_set_cfg()
2550 u16 cfg_ext_offs = brcmnand_cs_offset(ctrl, host->cs, in brcmnand_set_cfg()
2552 u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs, in brcmnand_set_cfg()
2557 if (ctrl->block_sizes) { in brcmnand_set_cfg()
2560 for (i = 0, found = 0; ctrl->block_sizes[i]; i++) in brcmnand_set_cfg()
2561 if (ctrl->block_sizes[i] * 1024 == cfg->block_size) { in brcmnand_set_cfg()
2566 dev_warn(ctrl->dev, "invalid block size %u\n", in brcmnand_set_cfg()
2567 cfg->block_size); in brcmnand_set_cfg()
2568 return -EINVAL; in brcmnand_set_cfg()
2571 block_size = ffs(cfg->block_size) - ffs(BRCMNAND_MIN_BLOCKSIZE); in brcmnand_set_cfg()
2574 if (cfg->block_size < BRCMNAND_MIN_BLOCKSIZE || (ctrl->max_block_size && in brcmnand_set_cfg()
2575 cfg->block_size > ctrl->max_block_size)) { in brcmnand_set_cfg()
2576 dev_warn(ctrl->dev, "invalid block size %u\n", in brcmnand_set_cfg()
2577 cfg->block_size); in brcmnand_set_cfg()
2581 if (ctrl->page_sizes) { in brcmnand_set_cfg()
2584 for (i = 0, found = 0; ctrl->page_sizes[i]; i++) in brcmnand_set_cfg()
2585 if (ctrl->page_sizes[i] == cfg->page_size) { in brcmnand_set_cfg()
2590 dev_warn(ctrl->dev, "invalid page size %u\n", in brcmnand_set_cfg()
2591 cfg->page_size); in brcmnand_set_cfg()
2592 return -EINVAL; in brcmnand_set_cfg()
2595 page_size = ffs(cfg->page_size) - ffs(BRCMNAND_MIN_PAGESIZE); in brcmnand_set_cfg()
2598 if (cfg->page_size < BRCMNAND_MIN_PAGESIZE || (ctrl->max_page_size && in brcmnand_set_cfg()
2599 cfg->page_size > ctrl->max_page_size)) { in brcmnand_set_cfg()
2600 dev_warn(ctrl->dev, "invalid page size %u\n", cfg->page_size); in brcmnand_set_cfg()
2601 return -EINVAL; in brcmnand_set_cfg()
2604 if (fls64(cfg->device_size) < fls64(BRCMNAND_MIN_DEVSIZE)) { in brcmnand_set_cfg()
2605 dev_warn(ctrl->dev, "invalid device size 0x%llx\n", in brcmnand_set_cfg()
2606 (unsigned long long)cfg->device_size); in brcmnand_set_cfg()
2607 return -EINVAL; in brcmnand_set_cfg()
2609 device_size = fls64(cfg->device_size) - fls64(BRCMNAND_MIN_DEVSIZE); in brcmnand_set_cfg()
2611 tmp = (cfg->blk_adr_bytes << CFG_BLK_ADR_BYTES_SHIFT) | in brcmnand_set_cfg()
2612 (cfg->col_adr_bytes << CFG_COL_ADR_BYTES_SHIFT) | in brcmnand_set_cfg()
2613 (cfg->ful_adr_bytes << CFG_FUL_ADR_BYTES_SHIFT) | in brcmnand_set_cfg()
2614 (!!(cfg->device_width == 16) << CFG_BUS_WIDTH_SHIFT) | in brcmnand_set_cfg()
2617 tmp |= (page_size << ctrl->page_size_shift) | in brcmnand_set_cfg()
2619 nand_writereg(ctrl, cfg_offs, tmp); in brcmnand_set_cfg()
2621 nand_writereg(ctrl, cfg_offs, tmp); in brcmnand_set_cfg()
2624 nand_writereg(ctrl, cfg_ext_offs, tmp); in brcmnand_set_cfg()
2627 tmp = nand_readreg(ctrl, acc_control_offs); in brcmnand_set_cfg()
2628 tmp &= ~brcmnand_ecc_level_mask(ctrl); in brcmnand_set_cfg()
2629 tmp &= ~brcmnand_spare_area_mask(ctrl); in brcmnand_set_cfg()
2630 if (ctrl->nand_version >= 0x0302) { in brcmnand_set_cfg()
2631 tmp |= cfg->ecc_level << ctrl->ecc_level_shift; in brcmnand_set_cfg()
2632 tmp |= cfg->spare_area_size; in brcmnand_set_cfg()
2634 nand_writereg(ctrl, acc_control_offs, tmp); in brcmnand_set_cfg()
2636 brcmnand_set_sector_size_1k(host, cfg->sector_size_1k); in brcmnand_set_cfg()
2638 /* threshold = ceil(BCH-level * 0.75) */ in brcmnand_set_cfg()
2639 brcmnand_wr_corr_thresh(host, DIV_ROUND_UP(chip->ecc.strength * 3, 4)); in brcmnand_set_cfg()
2648 "%lluMiB total, %uKiB blocks, %u%s pages, %uB OOB, %u-bit", in brcmnand_print_cfg()
2649 (unsigned long long)cfg->device_size >> 20, in brcmnand_print_cfg()
2650 cfg->block_size >> 10, in brcmnand_print_cfg()
2651 cfg->page_size >= 1024 ? cfg->page_size >> 10 : cfg->page_size, in brcmnand_print_cfg()
2652 cfg->page_size >= 1024 ? "KiB" : "B", in brcmnand_print_cfg()
2653 cfg->spare_area_size, cfg->device_width); in brcmnand_print_cfg()
2656 if (is_hamming_ecc(host->ctrl, cfg)) in brcmnand_print_cfg()
2658 else if (cfg->sector_size_1k) in brcmnand_print_cfg()
2659 sprintf(buf, ", BCH-%u (1KiB sector)", cfg->ecc_level << 1); in brcmnand_print_cfg()
2661 sprintf(buf, ", BCH-%u", cfg->ecc_level); in brcmnand_print_cfg()
2666 * roundup(log2(size / page-size) / 8)
2668 * NB: the following does not "round up" for non-power-of-2 'size'; but this is
2673 return ALIGN(ilog2(size) - ilog2(writesize), 8) >> 3; in get_blk_adr_bytes()
2678 struct mtd_info *mtd = nand_to_mtd(&host->chip); in brcmnand_setup_dev()
2679 struct nand_chip *chip = &host->chip; in brcmnand_setup_dev()
2681 nanddev_get_ecc_requirements(&chip->base); in brcmnand_setup_dev()
2683 nanddev_get_memorg(&chip->base); in brcmnand_setup_dev()
2684 struct brcmnand_controller *ctrl = host->ctrl; in brcmnand_setup_dev() local
2685 struct brcmnand_cfg *cfg = &host->hwcfg; in brcmnand_setup_dev()
2693 use_strap = of_property_read_bool(np, "brcm,nand-ecc-use-strap"); in brcmnand_setup_dev()
2696 * Either nand-ecc-xxx or brcm,nand-ecc-use-strap can be set. Error out in brcmnand_setup_dev()
2699 if (chip->ecc.strength && use_strap) { in brcmnand_setup_dev()
2700 dev_err(ctrl->dev, in brcmnand_setup_dev()
2702 return -EINVAL; in brcmnand_setup_dev()
2708 ret = of_property_read_u32(np, "brcm,nand-oob-sector-size", in brcmnand_setup_dev()
2712 cfg->spare_area_size = brcmnand_get_spare_size(host); in brcmnand_setup_dev()
2715 cfg->spare_area_size = mtd->oobsize / in brcmnand_setup_dev()
2716 (mtd->writesize >> FC_SHIFT); in brcmnand_setup_dev()
2718 cfg->spare_area_size = oob_sector; in brcmnand_setup_dev()
2720 if (cfg->spare_area_size > ctrl->max_oob) in brcmnand_setup_dev()
2721 cfg->spare_area_size = ctrl->max_oob; in brcmnand_setup_dev()
2726 mtd->oobsize = cfg->spare_area_size * (mtd->writesize >> FC_SHIFT); in brcmnand_setup_dev()
2727 memorg->oobsize = mtd->oobsize; in brcmnand_setup_dev()
2729 cfg->device_size = mtd->size; in brcmnand_setup_dev()
2730 cfg->block_size = mtd->erasesize; in brcmnand_setup_dev()
2731 cfg->page_size = mtd->writesize; in brcmnand_setup_dev()
2732 cfg->device_width = (chip->options & NAND_BUSWIDTH_16) ? 16 : 8; in brcmnand_setup_dev()
2733 cfg->col_adr_bytes = 2; in brcmnand_setup_dev()
2734 cfg->blk_adr_bytes = get_blk_adr_bytes(mtd->size, mtd->writesize); in brcmnand_setup_dev()
2736 if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST) { in brcmnand_setup_dev()
2737 dev_err(ctrl->dev, "only HW ECC supported; selected: %d\n", in brcmnand_setup_dev()
2738 chip->ecc.engine_type); in brcmnand_setup_dev()
2739 return -EINVAL; in brcmnand_setup_dev()
2742 if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN) { in brcmnand_setup_dev()
2743 if (chip->ecc.strength == 1 && chip->ecc.size == 512) in brcmnand_setup_dev()
2744 /* Default to Hamming for 1-bit ECC, if unspecified */ in brcmnand_setup_dev()
2745 chip->ecc.algo = NAND_ECC_ALGO_HAMMING; in brcmnand_setup_dev()
2748 chip->ecc.algo = NAND_ECC_ALGO_BCH; in brcmnand_setup_dev()
2751 if (chip->ecc.algo == NAND_ECC_ALGO_HAMMING && in brcmnand_setup_dev()
2752 (chip->ecc.strength != 1 || chip->ecc.size != 512)) { in brcmnand_setup_dev()
2753 dev_err(ctrl->dev, "invalid Hamming params: %d bits per %d bytes\n", in brcmnand_setup_dev()
2754 chip->ecc.strength, chip->ecc.size); in brcmnand_setup_dev()
2755 return -EINVAL; in brcmnand_setup_dev()
2758 if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_NONE && in brcmnand_setup_dev()
2759 (!chip->ecc.size || !chip->ecc.strength)) { in brcmnand_setup_dev()
2760 if (requirements->step_size && requirements->strength) { in brcmnand_setup_dev()
2762 chip->ecc.size = requirements->step_size; in brcmnand_setup_dev()
2763 chip->ecc.strength = requirements->strength; in brcmnand_setup_dev()
2764 dev_info(ctrl->dev, "Using ECC step-size %d, strength %d\n", in brcmnand_setup_dev()
2765 chip->ecc.size, chip->ecc.strength); in brcmnand_setup_dev()
2769 switch (chip->ecc.size) { in brcmnand_setup_dev()
2771 if (chip->ecc.algo == NAND_ECC_ALGO_HAMMING) in brcmnand_setup_dev()
2772 cfg->ecc_level = 15; in brcmnand_setup_dev()
2774 cfg->ecc_level = chip->ecc.strength; in brcmnand_setup_dev()
2775 cfg->sector_size_1k = 0; in brcmnand_setup_dev()
2778 if (!(ctrl->features & BRCMNAND_HAS_1K_SECTORS)) { in brcmnand_setup_dev()
2779 dev_err(ctrl->dev, "1KB sectors not supported\n"); in brcmnand_setup_dev()
2780 return -EINVAL; in brcmnand_setup_dev()
2782 if (chip->ecc.strength & 0x1) { in brcmnand_setup_dev()
2783 dev_err(ctrl->dev, in brcmnand_setup_dev()
2785 return -EINVAL; in brcmnand_setup_dev()
2788 cfg->ecc_level = chip->ecc.strength >> 1; in brcmnand_setup_dev()
2789 cfg->sector_size_1k = 1; in brcmnand_setup_dev()
2792 dev_err(ctrl->dev, "unsupported ECC size: %d\n", in brcmnand_setup_dev()
2793 chip->ecc.size); in brcmnand_setup_dev()
2794 return -EINVAL; in brcmnand_setup_dev()
2797 cfg->ful_adr_bytes = cfg->blk_adr_bytes; in brcmnand_setup_dev()
2798 if (mtd->writesize > 512) in brcmnand_setup_dev()
2799 cfg->ful_adr_bytes += cfg->col_adr_bytes; in brcmnand_setup_dev()
2801 cfg->ful_adr_bytes += 1; in brcmnand_setup_dev()
2810 dev_info(ctrl->dev, "detected %s\n", msg); in brcmnand_setup_dev()
2813 offs = brcmnand_cs_offset(ctrl, host->cs, BRCMNAND_CS_ACC_CONTROL); in brcmnand_setup_dev()
2814 tmp = nand_readreg(ctrl, offs); in brcmnand_setup_dev()
2819 if (ctrl->nand_version >= 0x0702) in brcmnand_setup_dev()
2822 if (ctrl->features & BRCMNAND_HAS_PREFETCH) in brcmnand_setup_dev()
2825 nand_writereg(ctrl, offs, tmp); in brcmnand_setup_dev()
2836 chip->options |= NAND_NO_SUBPAGE_WRITE; in brcmnand_attach_chip()
2842 chip->options |= NAND_USES_DMA; in brcmnand_attach_chip()
2844 if (chip->bbt_options & NAND_BBT_USE_FLASH) in brcmnand_attach_chip()
2845 chip->bbt_options |= NAND_BBT_NO_OOB; in brcmnand_attach_chip()
2848 return -ENXIO; in brcmnand_attach_chip()
2850 chip->ecc.size = host->hwcfg.sector_size_1k ? 1024 : 512; in brcmnand_attach_chip()
2853 mtd->bitflip_threshold = 1; in brcmnand_attach_chip()
2858 if (is_hamming_ecc(host->ctrl, &host->hwcfg)) { in brcmnand_attach_chip()
2859 chip->ecc.write_oob = brcmnand_write_oob_raw; in brcmnand_attach_chip()
2860 chip->ecc.read_oob = brcmnand_read_oob_raw; in brcmnand_attach_chip()
2874 struct brcmnand_controller *ctrl = host->ctrl; in brcmnand_init_cs() local
2875 struct device *dev = ctrl->dev; in brcmnand_init_cs() local
2881 mtd = nand_to_mtd(&host->chip); in brcmnand_init_cs()
2882 chip = &host->chip; in brcmnand_init_cs()
2885 mtd->name = devm_kasprintf(dev, GFP_KERNEL, "brcmnand.%d", in brcmnand_init_cs()
2886 host->cs); in brcmnand_init_cs()
2887 if (!mtd->name) in brcmnand_init_cs()
2888 return -ENOMEM; in brcmnand_init_cs()
2890 mtd->owner = THIS_MODULE; in brcmnand_init_cs()
2891 mtd->dev.parent = dev; in brcmnand_init_cs()
2893 chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; in brcmnand_init_cs()
2894 chip->ecc.read_page = brcmnand_read_page; in brcmnand_init_cs()
2895 chip->ecc.write_page = brcmnand_write_page; in brcmnand_init_cs()
2896 chip->ecc.read_page_raw = brcmnand_read_page_raw; in brcmnand_init_cs()
2897 chip->ecc.write_page_raw = brcmnand_write_page_raw; in brcmnand_init_cs()
2898 chip->ecc.write_oob_raw = brcmnand_write_oob_raw; in brcmnand_init_cs()
2899 chip->ecc.read_oob_raw = brcmnand_read_oob_raw; in brcmnand_init_cs()
2900 chip->ecc.read_oob = brcmnand_read_oob; in brcmnand_init_cs()
2901 chip->ecc.write_oob = brcmnand_write_oob; in brcmnand_init_cs()
2903 chip->controller = &ctrl->controller; in brcmnand_init_cs()
2904 ctrl->controller.controller_wp = 1; in brcmnand_init_cs()
2911 cfg_offs = brcmnand_cs_offset(ctrl, host->cs, BRCMNAND_CS_CFG); in brcmnand_init_cs()
2912 nand_writereg(ctrl, cfg_offs, in brcmnand_init_cs()
2913 nand_readreg(ctrl, cfg_offs) & ~CFG_BUS_WIDTH); in brcmnand_init_cs()
2929 struct brcmnand_controller *ctrl = host->ctrl; in brcmnand_save_restore_cs_config() local
2930 u16 cfg_offs = brcmnand_cs_offset(ctrl, host->cs, BRCMNAND_CS_CFG); in brcmnand_save_restore_cs_config()
2931 u16 cfg_ext_offs = brcmnand_cs_offset(ctrl, host->cs, in brcmnand_save_restore_cs_config()
2933 u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs, in brcmnand_save_restore_cs_config()
2935 u16 t1_offs = brcmnand_cs_offset(ctrl, host->cs, BRCMNAND_CS_TIMING1); in brcmnand_save_restore_cs_config()
2936 u16 t2_offs = brcmnand_cs_offset(ctrl, host->cs, BRCMNAND_CS_TIMING2); in brcmnand_save_restore_cs_config()
2939 nand_writereg(ctrl, cfg_offs, host->hwcfg.config); in brcmnand_save_restore_cs_config()
2941 nand_writereg(ctrl, cfg_ext_offs, in brcmnand_save_restore_cs_config()
2942 host->hwcfg.config_ext); in brcmnand_save_restore_cs_config()
2943 nand_writereg(ctrl, acc_control_offs, host->hwcfg.acc_control); in brcmnand_save_restore_cs_config()
2944 nand_writereg(ctrl, t1_offs, host->hwcfg.timing_1); in brcmnand_save_restore_cs_config()
2945 nand_writereg(ctrl, t2_offs, host->hwcfg.timing_2); in brcmnand_save_restore_cs_config()
2947 host->hwcfg.config = nand_readreg(ctrl, cfg_offs); in brcmnand_save_restore_cs_config()
2949 host->hwcfg.config_ext = in brcmnand_save_restore_cs_config()
2950 nand_readreg(ctrl, cfg_ext_offs); in brcmnand_save_restore_cs_config()
2951 host->hwcfg.acc_control = nand_readreg(ctrl, acc_control_offs); in brcmnand_save_restore_cs_config()
2952 host->hwcfg.timing_1 = nand_readreg(ctrl, t1_offs); in brcmnand_save_restore_cs_config()
2953 host->hwcfg.timing_2 = nand_readreg(ctrl, t2_offs); in brcmnand_save_restore_cs_config()
2957 static int brcmnand_suspend(struct device *dev) in brcmnand_suspend() argument
2959 struct brcmnand_controller *ctrl = dev_get_drvdata(dev); in brcmnand_suspend() local
2962 list_for_each_entry(host, &ctrl->host_list, node) in brcmnand_suspend()
2965 ctrl->nand_cs_nand_select = brcmnand_read_reg(ctrl, BRCMNAND_CS_SELECT); in brcmnand_suspend()
2966 ctrl->nand_cs_nand_xor = brcmnand_read_reg(ctrl, BRCMNAND_CS_XOR); in brcmnand_suspend()
2967 ctrl->corr_stat_threshold = in brcmnand_suspend()
2968 brcmnand_read_reg(ctrl, BRCMNAND_CORR_THRESHOLD); in brcmnand_suspend()
2970 if (has_flash_dma(ctrl)) in brcmnand_suspend()
2971 ctrl->flash_dma_mode = flash_dma_readl(ctrl, FLASH_DMA_MODE); in brcmnand_suspend()
2972 else if (has_edu(ctrl)) in brcmnand_suspend()
2973 ctrl->edu_config = edu_readl(ctrl, EDU_CONFIG); in brcmnand_suspend()
2978 static int brcmnand_resume(struct device *dev) in brcmnand_resume() argument
2980 struct brcmnand_controller *ctrl = dev_get_drvdata(dev); in brcmnand_resume() local
2983 if (has_flash_dma(ctrl)) { in brcmnand_resume()
2984 flash_dma_writel(ctrl, FLASH_DMA_MODE, ctrl->flash_dma_mode); in brcmnand_resume()
2985 flash_dma_writel(ctrl, FLASH_DMA_ERROR_STATUS, 0); in brcmnand_resume()
2988 if (has_edu(ctrl)) { in brcmnand_resume()
2989 ctrl->edu_config = edu_readl(ctrl, EDU_CONFIG); in brcmnand_resume()
2990 edu_writel(ctrl, EDU_CONFIG, ctrl->edu_config); in brcmnand_resume()
2991 edu_readl(ctrl, EDU_CONFIG); in brcmnand_resume()
2992 brcmnand_edu_init(ctrl); in brcmnand_resume()
2995 brcmnand_write_reg(ctrl, BRCMNAND_CS_SELECT, ctrl->nand_cs_nand_select); in brcmnand_resume()
2996 brcmnand_write_reg(ctrl, BRCMNAND_CS_XOR, ctrl->nand_cs_nand_xor); in brcmnand_resume()
2997 brcmnand_write_reg(ctrl, BRCMNAND_CORR_THRESHOLD, in brcmnand_resume()
2998 ctrl->corr_stat_threshold); in brcmnand_resume()
2999 if (ctrl->soc) { in brcmnand_resume()
3000 /* Clear/re-enable interrupt */ in brcmnand_resume()
3001 ctrl->soc->ctlrdy_ack(ctrl->soc); in brcmnand_resume()
3002 ctrl->soc->ctlrdy_set_enabled(ctrl->soc, true); in brcmnand_resume()
3005 list_for_each_entry(host, &ctrl->host_list, node) { in brcmnand_resume()
3006 struct nand_chip *chip = &host->chip; in brcmnand_resume()
3010 /* Reset the chip, required by some chips after power-up */ in brcmnand_resume()
3024 { .compatible = "brcm,brcmnand-v2.1" },
3025 { .compatible = "brcm,brcmnand-v2.2" },
3026 { .compatible = "brcm,brcmnand-v4.0" },
3027 { .compatible = "brcm,brcmnand-v5.0" },
3028 { .compatible = "brcm,brcmnand-v6.0" },
3029 { .compatible = "brcm,brcmnand-v6.1" },
3030 { .compatible = "brcm,brcmnand-v6.2" },
3031 { .compatible = "brcm,brcmnand-v7.0" },
3032 { .compatible = "brcm,brcmnand-v7.1" },
3033 { .compatible = "brcm,brcmnand-v7.2" },
3034 { .compatible = "brcm,brcmnand-v7.3" },
3044 struct device *dev = &pdev->dev; in brcmnand_edu_setup() local
3045 struct brcmnand_controller *ctrl = dev_get_drvdata(&pdev->dev); in brcmnand_edu_setup() local
3049 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "flash-edu"); in brcmnand_edu_setup()
3051 ctrl->edu_base = devm_ioremap_resource(dev, res); in brcmnand_edu_setup()
3052 if (IS_ERR(ctrl->edu_base)) in brcmnand_edu_setup()
3053 return PTR_ERR(ctrl->edu_base); in brcmnand_edu_setup()
3055 ctrl->edu_offsets = edu_regs; in brcmnand_edu_setup()
3057 edu_writel(ctrl, EDU_CONFIG, EDU_CONFIG_MODE_NAND | in brcmnand_edu_setup()
3059 edu_readl(ctrl, EDU_CONFIG); in brcmnand_edu_setup()
3062 brcmnand_edu_init(ctrl); in brcmnand_edu_setup()
3064 ctrl->edu_irq = platform_get_irq_optional(pdev, 1); in brcmnand_edu_setup()
3065 if (ctrl->edu_irq < 0) { in brcmnand_edu_setup()
3066 dev_warn(dev, in brcmnand_edu_setup()
3069 ret = devm_request_irq(dev, ctrl->edu_irq, in brcmnand_edu_setup()
3071 "brcmnand-edu", ctrl); in brcmnand_edu_setup()
3073 dev_err(ctrl->dev, "can't allocate IRQ %d: error %d\n", in brcmnand_edu_setup()
3074 ctrl->edu_irq, ret); in brcmnand_edu_setup()
3078 dev_info(dev, "FLASH EDU enabled using irq %u\n", in brcmnand_edu_setup()
3079 ctrl->edu_irq); in brcmnand_edu_setup()
3088 struct brcmnand_platform_data *pd = dev_get_platdata(&pdev->dev); in brcmnand_probe()
3089 struct device *dev = &pdev->dev; in brcmnand_probe() local
3090 struct device_node *dn = dev->of_node, *child; in brcmnand_probe()
3091 struct brcmnand_controller *ctrl; in brcmnand_probe() local
3097 return -ENODEV; in brcmnand_probe()
3099 ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL); in brcmnand_probe()
3100 if (!ctrl) in brcmnand_probe()
3101 return -ENOMEM; in brcmnand_probe()
3103 dev_set_drvdata(dev, ctrl); in brcmnand_probe()
3104 ctrl->dev = dev; in brcmnand_probe()
3105 ctrl->soc = soc; in brcmnand_probe()
3108 * that a non-memory mapped IO access path must be used in brcmnand_probe()
3110 if (brcmnand_soc_has_ops(ctrl->soc)) in brcmnand_probe()
3113 init_completion(&ctrl->done); in brcmnand_probe()
3114 init_completion(&ctrl->dma_done); in brcmnand_probe()
3115 init_completion(&ctrl->edu_done); in brcmnand_probe()
3116 nand_controller_init(&ctrl->controller); in brcmnand_probe()
3117 ctrl->controller.ops = &brcmnand_controller_ops; in brcmnand_probe()
3118 INIT_LIST_HEAD(&ctrl->host_list); in brcmnand_probe()
3122 ctrl->nand_base = devm_ioremap_resource(dev, res); in brcmnand_probe()
3123 if (IS_ERR(ctrl->nand_base) && !brcmnand_soc_has_ops(soc)) in brcmnand_probe()
3124 return PTR_ERR(ctrl->nand_base); in brcmnand_probe()
3127 ctrl->clk = devm_clk_get(dev, "nand"); in brcmnand_probe()
3128 if (!IS_ERR(ctrl->clk)) { in brcmnand_probe()
3129 ret = clk_prepare_enable(ctrl->clk); in brcmnand_probe()
3133 ret = PTR_ERR(ctrl->clk); in brcmnand_probe()
3134 if (ret == -EPROBE_DEFER) in brcmnand_probe()
3137 ctrl->clk = NULL; in brcmnand_probe()
3141 ret = brcmnand_revision_init(ctrl); in brcmnand_probe()
3149 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand-cache"); in brcmnand_probe()
3151 ctrl->nand_fc = devm_ioremap_resource(dev, res); in brcmnand_probe()
3152 if (IS_ERR(ctrl->nand_fc)) { in brcmnand_probe()
3153 ret = PTR_ERR(ctrl->nand_fc); in brcmnand_probe()
3157 ctrl->nand_fc = ctrl->nand_base + in brcmnand_probe()
3158 ctrl->reg_offsets[BRCMNAND_FC_BASE]; in brcmnand_probe()
3162 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "flash-dma"); in brcmnand_probe()
3164 ctrl->flash_dma_base = devm_ioremap_resource(dev, res); in brcmnand_probe()
3165 if (IS_ERR(ctrl->flash_dma_base)) { in brcmnand_probe()
3166 ret = PTR_ERR(ctrl->flash_dma_base); in brcmnand_probe()
3171 brcmnand_flash_dma_revision_init(ctrl); in brcmnand_probe()
3173 ret = -EIO; in brcmnand_probe()
3174 if (ctrl->nand_version >= 0x0700) in brcmnand_probe()
3175 ret = dma_set_mask_and_coherent(&pdev->dev, in brcmnand_probe()
3178 ret = dma_set_mask_and_coherent(&pdev->dev, in brcmnand_probe()
3183 /* linked-list and stop on error */ in brcmnand_probe()
3184 flash_dma_writel(ctrl, FLASH_DMA_MODE, FLASH_DMA_MODE_MASK); in brcmnand_probe()
3185 flash_dma_writel(ctrl, FLASH_DMA_ERROR_STATUS, 0); in brcmnand_probe()
3188 ctrl->dma_desc = dmam_alloc_coherent(dev, in brcmnand_probe()
3189 sizeof(*ctrl->dma_desc), in brcmnand_probe()
3190 &ctrl->dma_pa, GFP_KERNEL); in brcmnand_probe()
3191 if (!ctrl->dma_desc) { in brcmnand_probe()
3192 ret = -ENOMEM; in brcmnand_probe()
3196 ctrl->dma_irq = platform_get_irq(pdev, 1); in brcmnand_probe()
3197 if ((int)ctrl->dma_irq < 0) { in brcmnand_probe()
3198 dev_err(dev, "missing FLASH_DMA IRQ\n"); in brcmnand_probe()
3199 ret = -ENODEV; in brcmnand_probe()
3203 ret = devm_request_irq(dev, ctrl->dma_irq, in brcmnand_probe()
3205 ctrl); in brcmnand_probe()
3207 dev_err(dev, "can't allocate IRQ %d: error %d\n", in brcmnand_probe()
3208 ctrl->dma_irq, ret); in brcmnand_probe()
3212 dev_info(dev, "enabling FLASH_DMA\n"); in brcmnand_probe()
3214 ctrl->dma_trans = brcmnand_dma_trans; in brcmnand_probe()
3220 if (has_edu(ctrl)) in brcmnand_probe()
3222 ctrl->dma_trans = brcmnand_edu_trans; in brcmnand_probe()
3226 brcmnand_rmw_reg(ctrl, BRCMNAND_CS_SELECT, in brcmnand_probe()
3229 brcmnand_rmw_reg(ctrl, BRCMNAND_CS_XOR, 0xff, 0, 0); in brcmnand_probe()
3232 if (of_property_read_bool(dn, "brcm,wp-not-connected")) in brcmnand_probe()
3235 if (ctrl->features & BRCMNAND_HAS_WP) { in brcmnand_probe()
3238 brcmnand_set_wp(ctrl, false); in brcmnand_probe()
3244 ctrl->irq = platform_get_irq_optional(pdev, 0); in brcmnand_probe()
3245 if (ctrl->irq > 0) { in brcmnand_probe()
3251 ret = devm_request_irq(dev, ctrl->irq, brcmnand_irq, 0, in brcmnand_probe()
3252 DRV_NAME, ctrl); in brcmnand_probe()
3255 ctrl->soc->ctlrdy_ack(ctrl->soc); in brcmnand_probe()
3256 ctrl->soc->ctlrdy_set_enabled(ctrl->soc, true); in brcmnand_probe()
3259 ret = devm_request_irq(dev, ctrl->irq, brcmnand_ctlrdy_irq, 0, in brcmnand_probe()
3260 DRV_NAME, ctrl); in brcmnand_probe()
3263 dev_err(dev, "can't allocate IRQ %d: error %d\n", in brcmnand_probe()
3264 ctrl->irq, ret); in brcmnand_probe()
3272 host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); in brcmnand_probe()
3275 ret = -ENOMEM; in brcmnand_probe()
3278 host->pdev = pdev; in brcmnand_probe()
3279 host->ctrl = ctrl; in brcmnand_probe()
3281 ret = of_property_read_u32(child, "reg", &host->cs); in brcmnand_probe()
3283 dev_err(dev, "can't get chip-select\n"); in brcmnand_probe()
3284 devm_kfree(dev, host); in brcmnand_probe()
3288 nand_set_flash_node(&host->chip, child); in brcmnand_probe()
3292 if (ret == -EPROBE_DEFER) { in brcmnand_probe()
3296 devm_kfree(dev, host); in brcmnand_probe()
3297 continue; /* Try all chip-selects */ in brcmnand_probe()
3300 list_add_tail(&host->node, &ctrl->host_list); in brcmnand_probe()
3304 if (!list_empty(&ctrl->host_list)) in brcmnand_probe()
3308 ret = -ENODEV; in brcmnand_probe()
3313 host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); in brcmnand_probe()
3315 ret = -ENOMEM; in brcmnand_probe()
3318 host->pdev = pdev; in brcmnand_probe()
3319 host->ctrl = ctrl; in brcmnand_probe()
3320 host->cs = pd->chip_select; in brcmnand_probe()
3321 host->chip.ecc.size = pd->ecc_stepsize; in brcmnand_probe()
3322 host->chip.ecc.strength = pd->ecc_strength; in brcmnand_probe()
3324 ret = brcmnand_init_cs(host, pd->part_probe_types); in brcmnand_probe()
3328 list_add_tail(&host->node, &ctrl->host_list); in brcmnand_probe()
3330 /* No chip-selects could initialize properly */ in brcmnand_probe()
3331 if (list_empty(&ctrl->host_list)) { in brcmnand_probe()
3332 ret = -ENODEV; in brcmnand_probe()
3339 clk_disable_unprepare(ctrl->clk); in brcmnand_probe()
3347 struct brcmnand_controller *ctrl = dev_get_drvdata(&pdev->dev); in brcmnand_remove() local
3352 list_for_each_entry(host, &ctrl->host_list, node) { in brcmnand_remove()
3353 chip = &host->chip; in brcmnand_remove()
3359 clk_disable_unprepare(ctrl->clk); in brcmnand_remove()
3361 dev_set_drvdata(&pdev->dev, NULL); in brcmnand_remove()