^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0 OR MIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Rockchip NAND Flash controller driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2020 Rockchip Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Author: Yifeng Zhao <yifeng.zhao@rock-chips.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/dmaengine.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/iopoll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/mtd/mtd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/mtd/rawnand.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * NFC Page Data Layout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * 1024 bytes data + 4Bytes sys data + 28Bytes~124Bytes ECC data +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * 1024 bytes data + 4Bytes sys data + 28Bytes~124Bytes ECC data +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * ......
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * NAND Page Data Layout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * 1024 * n data + m Bytes oob
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * Original Bad Block Mask Location:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * First byte of oob(spare).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * nand_chip->oob_poi data layout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * 4Bytes sys data + .... + 4Bytes sys data + ECC data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* NAND controller register definition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define NFC_READ (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define NFC_WRITE (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define NFC_FMCTL (0x00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define FMCTL_CE_SEL_M 0xFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define FMCTL_CE_SEL(x) (1 << (x))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define FMCTL_WP BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define FMCTL_RDY BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define NFC_FMWAIT (0x04)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define FLCTL_RST BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define FLCTL_WR (1) /* 0: read, 1: write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define FLCTL_XFER_ST BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define FLCTL_XFER_EN BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define FLCTL_ACORRECT BIT(10) /* Auto correct error bits. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define FLCTL_XFER_READY BIT(20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define FLCTL_XFER_SECTOR (22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define FLCTL_TOG_FIX BIT(29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define BCHCTL_BANK_M (7 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define BCHCTL_BANK (5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define DMA_ST BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define DMA_WR (1) /* 0: write, 1: read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define DMA_EN BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define DMA_AHB_SIZE (3) /* 0: 1, 1: 2, 2: 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define DMA_BURST_SIZE (6) /* 0: 1, 3: 4, 5: 8, 7: 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define DMA_INC_NUM (9) /* 1 - 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define ECC_ERR_CNT(x, e) ((((x) >> (e).low) & (e).low_mask) |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) (((x) >> (e).high) & (e).high_mask) << (e).low_bn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define INT_DMA BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define NFC_BANK (0x800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define NFC_BANK_STEP (0x100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define BANK_DATA (0x00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define BANK_ADDR (0x04)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define BANK_CMD (0x08)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define NFC_SRAM0 (0x1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define NFC_SRAM1 (0x1400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define NFC_SRAM_SIZE (0x400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define NFC_TIMEOUT (500000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define NFC_MAX_OOB_PER_STEP 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define NFC_MIN_OOB_PER_STEP 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define MAX_DATA_SIZE 0xFFFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define MAX_ADDRESS_CYC 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define NFC_ECC_MAX_MODES 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define NFC_MAX_NSELS (8) /* Some Socs only have 1 or 2 CSs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define NFC_SYS_DATA_SIZE (4) /* 4 bytes sys data in oob pre 1024 data.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define RK_DEFAULT_CLOCK_RATE (150 * 1000 * 1000) /* 150 Mhz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define ACCTIMING(csrw, rwpw, rwcs) ((csrw) << 12 | (rwpw) << 5 | (rwcs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) enum nfc_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) NFC_V6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) NFC_V8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) NFC_V9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * struct rk_ecc_cnt_status: represent a ecc status data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * @err_flag_bit: error flag bit index at register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * @low: ECC count low bit index at register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * @low_mask: mask bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * @low_bn: ECC count low bit number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * @high: ECC count high bit index at register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * @high_mask: mask bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct ecc_cnt_status {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) u8 err_flag_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) u8 low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) u8 low_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) u8 low_bn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) u8 high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) u8 high_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * @type: NFC version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * @ecc_strengths: ECC strengths
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * @ecc_cfgs: ECC config values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * @flctl_off: FLCTL register offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * @bchctl_off: BCHCTL register offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * @dma_data_buf_off: DMA_DATA_BUF register offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * @dma_oob_buf_off: DMA_OOB_BUF register offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * @dma_cfg_off: DMA_CFG register offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * @dma_st_off: DMA_ST register offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * @bch_st_off: BCG_ST register offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * @randmz_off: RANDMZ register offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * @int_en_off: interrupt enable register offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * @int_clr_off: interrupt clean register offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * @int_st_off: interrupt status register offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * @oob0_off: oob0 register offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * @oob1_off: oob1 register offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * @ecc0: represent ECC0 status data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * @ecc1: represent ECC1 status data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct nfc_cfg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) enum nfc_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) u8 ecc_strengths[NFC_ECC_MAX_MODES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) u32 ecc_cfgs[NFC_ECC_MAX_MODES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) u32 flctl_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) u32 bchctl_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) u32 dma_cfg_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) u32 dma_data_buf_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) u32 dma_oob_buf_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) u32 dma_st_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) u32 bch_st_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) u32 randmz_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) u32 int_en_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) u32 int_clr_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) u32 int_st_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) u32 oob0_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) u32 oob1_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) struct ecc_cnt_status ecc0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct ecc_cnt_status ecc1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct rk_nfc_nand_chip {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) struct list_head node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct nand_chip chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) u16 boot_blks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) u16 metadata_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) u32 boot_ecc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) u32 timing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) u8 nsels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) u8 sels[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* Nothing after this field. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct rk_nfc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct nand_controller controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) const struct nfc_cfg *cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct clk *nfc_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct clk *ahb_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) void __iomem *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) u32 selected_bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) u32 band_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) u32 cur_ecc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) u32 cur_timing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct completion done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct list_head chips;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) u8 *page_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) u32 *oob_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) u32 page_buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) u32 oob_buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) unsigned long assigned_cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static inline struct rk_nfc_nand_chip *rk_nfc_to_rknand(struct nand_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return container_of(chip, struct rk_nfc_nand_chip, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) static inline u8 *rk_nfc_buf_to_data_ptr(struct nand_chip *chip, const u8 *p, int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return (u8 *)p + i * chip->ecc.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static inline u8 *rk_nfc_buf_to_oob_ptr(struct nand_chip *chip, int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) u8 *poi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) poi = chip->oob_poi + i * NFC_SYS_DATA_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return poi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static inline u8 *rk_nfc_buf_to_oob_ecc_ptr(struct nand_chip *chip, int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) u8 *poi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) poi = chip->oob_poi + rknand->metadata_size + chip->ecc.bytes * i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return poi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static inline int rk_nfc_data_len(struct nand_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return chip->ecc.size + chip->ecc.bytes + NFC_SYS_DATA_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static inline u8 *rk_nfc_data_ptr(struct nand_chip *chip, int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct rk_nfc *nfc = nand_get_controller_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return nfc->page_buf + i * rk_nfc_data_len(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static inline u8 *rk_nfc_oob_ptr(struct nand_chip *chip, int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) struct rk_nfc *nfc = nand_get_controller_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return nfc->page_buf + i * rk_nfc_data_len(chip) + chip->ecc.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static int rk_nfc_hw_ecc_setup(struct nand_chip *chip, u32 strength)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) struct rk_nfc *nfc = nand_get_controller_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) u32 reg, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) for (i = 0; i < NFC_ECC_MAX_MODES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (strength == nfc->cfg->ecc_strengths[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) reg = nfc->cfg->ecc_cfgs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (i >= NFC_ECC_MAX_MODES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) writel(reg, nfc->regs + nfc->cfg->bchctl_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /* Save chip ECC setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) nfc->cur_ecc = strength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) static void rk_nfc_select_chip(struct nand_chip *chip, int cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) struct rk_nfc *nfc = nand_get_controller_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct nand_ecc_ctrl *ecc = &chip->ecc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (cs < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) nfc->selected_bank = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /* Deselect the currently selected target. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) val = readl_relaxed(nfc->regs + NFC_FMCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) val &= ~FMCTL_CE_SEL_M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) writel(val, nfc->regs + NFC_FMCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) nfc->selected_bank = rknand->sels[cs];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) nfc->band_offset = NFC_BANK + nfc->selected_bank * NFC_BANK_STEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) val = readl_relaxed(nfc->regs + NFC_FMCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) val &= ~FMCTL_CE_SEL_M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) val |= FMCTL_CE_SEL(nfc->selected_bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) writel(val, nfc->regs + NFC_FMCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * Compare current chip timing with selected chip timing and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * change if needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (nfc->cur_timing != rknand->timing) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) writel(rknand->timing, nfc->regs + NFC_FMWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) nfc->cur_timing = rknand->timing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * Compare current chip ECC setting with selected chip ECC setting and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * change if needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (nfc->cur_ecc != ecc->strength)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) rk_nfc_hw_ecc_setup(chip, ecc->strength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) static inline int rk_nfc_wait_ioready(struct rk_nfc *nfc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) rc = readl_relaxed_poll_timeout(nfc->regs + NFC_FMCTL, val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) val & FMCTL_RDY, 10, NFC_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) static void rk_nfc_read_buf(struct rk_nfc *nfc, u8 *buf, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) for (i = 0; i < len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) buf[i] = readb_relaxed(nfc->regs + nfc->band_offset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) BANK_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static void rk_nfc_write_buf(struct rk_nfc *nfc, const u8 *buf, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) for (i = 0; i < len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) writeb(buf[i], nfc->regs + nfc->band_offset + BANK_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static int rk_nfc_cmd(struct nand_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) const struct nand_subop *subop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct rk_nfc *nfc = nand_get_controller_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) unsigned int i, j, remaining, start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) int reg_offset = nfc->band_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) u8 *inbuf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) const u8 *outbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) u32 cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) for (i = 0; i < subop->ninstrs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) const struct nand_op_instr *instr = &subop->instrs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) switch (instr->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) case NAND_OP_CMD_INSTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) writeb(instr->ctx.cmd.opcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) nfc->regs + reg_offset + BANK_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) case NAND_OP_ADDR_INSTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) remaining = nand_subop_get_num_addr_cyc(subop, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) start = nand_subop_get_addr_start_off(subop, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) for (j = 0; j < 8 && j + start < remaining; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) writeb(instr->ctx.addr.addrs[j + start],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) nfc->regs + reg_offset + BANK_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) case NAND_OP_DATA_IN_INSTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) case NAND_OP_DATA_OUT_INSTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) start = nand_subop_get_data_start_off(subop, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) cnt = nand_subop_get_data_len(subop, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (instr->type == NAND_OP_DATA_OUT_INSTR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) outbuf = instr->ctx.data.buf.out + start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) rk_nfc_write_buf(nfc, outbuf, cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) inbuf = instr->ctx.data.buf.in + start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) rk_nfc_read_buf(nfc, inbuf, cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) case NAND_OP_WAITRDY_INSTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (rk_nfc_wait_ioready(nfc) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) dev_err(nfc->dev, "IO not ready\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) static const struct nand_op_parser rk_nfc_op_parser = NAND_OP_PARSER(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) NAND_OP_PARSER_PATTERN(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) rk_nfc_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) NAND_OP_PARSER_PAT_CMD_ELEM(true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) NAND_OP_PARSER_PAT_ADDR_ELEM(true, MAX_ADDRESS_CYC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) NAND_OP_PARSER_PAT_CMD_ELEM(true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) NAND_OP_PARSER_PAT_WAITRDY_ELEM(true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) NAND_OP_PARSER_PAT_DATA_IN_ELEM(true, MAX_DATA_SIZE)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) NAND_OP_PARSER_PATTERN(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) rk_nfc_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) NAND_OP_PARSER_PAT_CMD_ELEM(true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) NAND_OP_PARSER_PAT_ADDR_ELEM(true, MAX_ADDRESS_CYC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) NAND_OP_PARSER_PAT_DATA_OUT_ELEM(true, MAX_DATA_SIZE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) NAND_OP_PARSER_PAT_CMD_ELEM(true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) NAND_OP_PARSER_PAT_WAITRDY_ELEM(true)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) static int rk_nfc_exec_op(struct nand_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) const struct nand_operation *op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) bool check_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (!check_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) rk_nfc_select_chip(chip, op->cs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return nand_op_parser_exec_op(chip, &rk_nfc_op_parser, op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) check_only);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) static int rk_nfc_setup_interface(struct nand_chip *chip, int target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) const struct nand_interface_config *conf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) struct rk_nfc *nfc = nand_get_controller_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) const struct nand_sdr_timings *timings;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) u32 rate, tc2rw, trwpw, trw2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) u32 temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (target < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) timings = nand_get_sdr_timings(conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (IS_ERR(timings))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (IS_ERR(nfc->nfc_clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) rate = clk_get_rate(nfc->ahb_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) rate = clk_get_rate(nfc->nfc_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) /* Turn clock rate into kHz. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) rate /= 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) tc2rw = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) trw2c = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) trwpw = max(timings->tWC_min, timings->tRC_min) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) trwpw = DIV_ROUND_UP(trwpw * rate, 1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) temp = timings->tREA_max / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) temp = DIV_ROUND_UP(temp * rate, 1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (trwpw < temp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) trwpw = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * ACCON: access timing control register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) * -------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) * 31:18: reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) * 17:12: csrw, clock cycles from the falling edge of CSn to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * falling edge of RDn or WRn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * 11:11: reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) * 10:05: rwpw, the width of RDn or WRn in processor clock cycles
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) * 04:00: rwcs, clock cycles from the rising edge of RDn or WRn to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) * rising edge of CSn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) /* Save chip timing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) rknand->timing = ACCTIMING(tc2rw, trwpw, trw2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) static void rk_nfc_xfer_start(struct rk_nfc *nfc, u8 rw, u8 n_KB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) dma_addr_t dma_data, dma_addr_t dma_oob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) u32 dma_reg, fl_reg, bch_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) dma_reg = DMA_ST | ((!rw) << DMA_WR) | DMA_EN | (2 << DMA_AHB_SIZE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) (7 << DMA_BURST_SIZE) | (16 << DMA_INC_NUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) fl_reg = (rw << FLCTL_WR) | FLCTL_XFER_EN | FLCTL_ACORRECT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) (n_KB << FLCTL_XFER_SECTOR) | FLCTL_TOG_FIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if (nfc->cfg->type == NFC_V6 || nfc->cfg->type == NFC_V8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) bch_reg = readl_relaxed(nfc->regs + nfc->cfg->bchctl_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) bch_reg = (bch_reg & (~BCHCTL_BANK_M)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) (nfc->selected_bank << BCHCTL_BANK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) writel(bch_reg, nfc->regs + nfc->cfg->bchctl_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) writel(dma_reg, nfc->regs + nfc->cfg->dma_cfg_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) writel((u32)dma_data, nfc->regs + nfc->cfg->dma_data_buf_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) writel((u32)dma_oob, nfc->regs + nfc->cfg->dma_oob_buf_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) writel(fl_reg, nfc->regs + nfc->cfg->flctl_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) fl_reg |= FLCTL_XFER_ST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) writel(fl_reg, nfc->regs + nfc->cfg->flctl_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) static int rk_nfc_wait_for_xfer_done(struct rk_nfc *nfc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) void __iomem *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) ptr = nfc->regs + nfc->cfg->flctl_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) return readl_relaxed_poll_timeout(ptr, reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) reg & FLCTL_XFER_READY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 10, NFC_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) static int rk_nfc_write_page_raw(struct nand_chip *chip, const u8 *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) int oob_on, int page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) struct rk_nfc *nfc = nand_get_controller_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) struct mtd_info *mtd = nand_to_mtd(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) struct nand_ecc_ctrl *ecc = &chip->ecc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) int i, pages_per_blk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) pages_per_blk = mtd->erasesize / mtd->writesize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if ((chip->options & NAND_IS_BOOT_MEDIUM) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) (page < (pages_per_blk * rknand->boot_blks)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) rknand->boot_ecc != ecc->strength) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) * There's currently no method to notify the MTD framework that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) * a different ECC strength is in use for the boot blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) memset(nfc->page_buf, 0xff, mtd->writesize + mtd->oobsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) for (i = 0; i < ecc->steps; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) /* Copy data to the NFC buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) memcpy(rk_nfc_data_ptr(chip, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) rk_nfc_buf_to_data_ptr(chip, buf, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) ecc->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * The first four bytes of OOB are reserved for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) * boot ROM. In some debugging cases, such as with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) * read, erase and write back test these 4 bytes stored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) * in OOB also need to be written back.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * The function nand_block_bad detects bad blocks like:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) * bad = chip->oob_poi[chip->badblockpos];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) * chip->badblockpos == 0 for a large page NAND Flash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) * so chip->oob_poi[0] is the bad block mask (BBM).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) * The OOB data layout on the NFC is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * PA0 PA1 PA2 PA3 | BBM OOB1 OOB2 OOB3 | ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) * or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) * 0xFF 0xFF 0xFF 0xFF | BBM OOB1 OOB2 OOB3 | ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) * The code here just swaps the first 4 bytes with the last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) * 4 bytes without losing any data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * The chip->oob_poi data layout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * BBM OOB1 OOB2 OOB3 |......| PA0 PA1 PA2 PA3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) * The rk_nfc_ooblayout_free() function already has reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * these 4 bytes with:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) * oob_region->offset = NFC_SYS_DATA_SIZE + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) if (!i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) memcpy(rk_nfc_oob_ptr(chip, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) rk_nfc_buf_to_oob_ptr(chip, ecc->steps - 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) NFC_SYS_DATA_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) memcpy(rk_nfc_oob_ptr(chip, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) rk_nfc_buf_to_oob_ptr(chip, i - 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) NFC_SYS_DATA_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) /* Copy ECC data to the NFC buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) memcpy(rk_nfc_oob_ptr(chip, i) + NFC_SYS_DATA_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) rk_nfc_buf_to_oob_ecc_ptr(chip, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) ecc->bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) nand_prog_page_begin_op(chip, page, 0, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) rk_nfc_write_buf(nfc, buf, mtd->writesize + mtd->oobsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) return nand_prog_page_end_op(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) static int rk_nfc_write_page_hwecc(struct nand_chip *chip, const u8 *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) int oob_on, int page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct mtd_info *mtd = nand_to_mtd(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) struct rk_nfc *nfc = nand_get_controller_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) struct nand_ecc_ctrl *ecc = &chip->ecc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) int oob_step = (ecc->bytes > 60) ? NFC_MAX_OOB_PER_STEP :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) NFC_MIN_OOB_PER_STEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) int pages_per_blk = mtd->erasesize / mtd->writesize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) int ret = 0, i, boot_rom_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) dma_addr_t dma_data, dma_oob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) u8 *oob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) nand_prog_page_begin_op(chip, page, 0, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) memcpy(nfc->page_buf, buf, mtd->writesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) memset(nfc->page_buf, 0xFF, mtd->writesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) * The first blocks (4, 8 or 16 depending on the device) are used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) * by the boot ROM and the first 32 bits of OOB need to link to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) * the next page address in the same block. We can't directly copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * OOB data from the MTD framework, because this page address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) * conflicts for example with the bad block marker (BBM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) * so we shift all OOB data including the BBM with 4 byte positions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * As a consequence the OOB size available to the MTD framework is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) * also reduced with 4 bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) * PA0 PA1 PA2 PA3 | BBM OOB1 OOB2 OOB3 | ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * If a NAND is not a boot medium or the page is not a boot block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) * the first 4 bytes are left untouched by writing 0xFF to them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) * 0xFF 0xFF 0xFF 0xFF | BBM OOB1 OOB2 OOB3 | ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) * Configure the ECC algorithm supported by the boot ROM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if ((page < (pages_per_blk * rknand->boot_blks)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) (chip->options & NAND_IS_BOOT_MEDIUM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) boot_rom_mode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (rknand->boot_ecc != ecc->strength)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) rk_nfc_hw_ecc_setup(chip, rknand->boot_ecc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) for (i = 0; i < ecc->steps; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (!i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) reg = 0xFFFFFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) oob = chip->oob_poi + (i - 1) * NFC_SYS_DATA_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) reg = oob[0] | oob[1] << 8 | oob[2] << 16 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) oob[3] << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (!i && boot_rom_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) reg = (page & (pages_per_blk - 1)) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (nfc->cfg->type == NFC_V9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) nfc->oob_buf[i] = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) nfc->oob_buf[i * (oob_step / 4)] = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) dma_data = dma_map_single(nfc->dev, (void *)nfc->page_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) mtd->writesize, DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) dma_oob = dma_map_single(nfc->dev, nfc->oob_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) ecc->steps * oob_step,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) reinit_completion(&nfc->done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) writel(INT_DMA, nfc->regs + nfc->cfg->int_en_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) rk_nfc_xfer_start(nfc, NFC_WRITE, ecc->steps, dma_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) dma_oob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) ret = wait_for_completion_timeout(&nfc->done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) msecs_to_jiffies(100));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) dev_warn(nfc->dev, "write: wait dma done timeout.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) * Whether the DMA transfer is completed or not. The driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) * needs to check the NFC`s status register to see if the data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) * transfer was completed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) ret = rk_nfc_wait_for_xfer_done(nfc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) dma_unmap_single(nfc->dev, dma_data, mtd->writesize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) dma_unmap_single(nfc->dev, dma_oob, ecc->steps * oob_step,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (boot_rom_mode && rknand->boot_ecc != ecc->strength)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) rk_nfc_hw_ecc_setup(chip, ecc->strength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) dev_err(nfc->dev, "write: wait transfer done timeout.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) return nand_prog_page_end_op(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) static int rk_nfc_write_oob(struct nand_chip *chip, int page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) return rk_nfc_write_page_hwecc(chip, NULL, 1, page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) static int rk_nfc_read_page_raw(struct nand_chip *chip, u8 *buf, int oob_on,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) int page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) struct rk_nfc *nfc = nand_get_controller_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) struct mtd_info *mtd = nand_to_mtd(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) struct nand_ecc_ctrl *ecc = &chip->ecc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) int i, pages_per_blk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) pages_per_blk = mtd->erasesize / mtd->writesize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if ((chip->options & NAND_IS_BOOT_MEDIUM) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) (page < (pages_per_blk * rknand->boot_blks)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) rknand->boot_ecc != ecc->strength) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) * There's currently no method to notify the MTD framework that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) * a different ECC strength is in use for the boot blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) nand_read_page_op(chip, page, 0, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) rk_nfc_read_buf(nfc, nfc->page_buf, mtd->writesize + mtd->oobsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) for (i = 0; i < ecc->steps; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) * The first four bytes of OOB are reserved for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) * boot ROM. In some debugging cases, such as with a read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) * erase and write back test, these 4 bytes also must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) * saved somewhere, otherwise this information will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) * lost during a write back.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (!i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) memcpy(rk_nfc_buf_to_oob_ptr(chip, ecc->steps - 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) rk_nfc_oob_ptr(chip, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) NFC_SYS_DATA_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) memcpy(rk_nfc_buf_to_oob_ptr(chip, i - 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) rk_nfc_oob_ptr(chip, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) NFC_SYS_DATA_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) /* Copy ECC data from the NFC buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) memcpy(rk_nfc_buf_to_oob_ecc_ptr(chip, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) rk_nfc_oob_ptr(chip, i) + NFC_SYS_DATA_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) ecc->bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) /* Copy data from the NFC buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) if (buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) memcpy(rk_nfc_buf_to_data_ptr(chip, buf, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) rk_nfc_data_ptr(chip, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) ecc->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) static int rk_nfc_read_page_hwecc(struct nand_chip *chip, u8 *buf, int oob_on,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) int page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) struct mtd_info *mtd = nand_to_mtd(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) struct rk_nfc *nfc = nand_get_controller_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) struct nand_ecc_ctrl *ecc = &chip->ecc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) int oob_step = (ecc->bytes > 60) ? NFC_MAX_OOB_PER_STEP :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) NFC_MIN_OOB_PER_STEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) int pages_per_blk = mtd->erasesize / mtd->writesize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) dma_addr_t dma_data, dma_oob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) int ret = 0, i, cnt, boot_rom_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) int max_bitflips = 0, bch_st, ecc_fail = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) u8 *oob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) nand_read_page_op(chip, page, 0, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) dma_data = dma_map_single(nfc->dev, nfc->page_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) mtd->writesize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) dma_oob = dma_map_single(nfc->dev, nfc->oob_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) ecc->steps * oob_step,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) * The first blocks (4, 8 or 16 depending on the device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) * are used by the boot ROM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) * Configure the ECC algorithm supported by the boot ROM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) if ((page < (pages_per_blk * rknand->boot_blks)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) (chip->options & NAND_IS_BOOT_MEDIUM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) boot_rom_mode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (rknand->boot_ecc != ecc->strength)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) rk_nfc_hw_ecc_setup(chip, rknand->boot_ecc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) reinit_completion(&nfc->done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) writel(INT_DMA, nfc->regs + nfc->cfg->int_en_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) rk_nfc_xfer_start(nfc, NFC_READ, ecc->steps, dma_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) dma_oob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) ret = wait_for_completion_timeout(&nfc->done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) msecs_to_jiffies(100));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) dev_warn(nfc->dev, "read: wait dma done timeout.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) * Whether the DMA transfer is completed or not. The driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) * needs to check the NFC`s status register to see if the data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) * transfer was completed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) ret = rk_nfc_wait_for_xfer_done(nfc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) dma_unmap_single(nfc->dev, dma_data, mtd->writesize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) dma_unmap_single(nfc->dev, dma_oob, ecc->steps * oob_step,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) dev_err(nfc->dev, "read: wait transfer done timeout.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) goto timeout_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) for (i = 1; i < ecc->steps; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) oob = chip->oob_poi + (i - 1) * NFC_SYS_DATA_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if (nfc->cfg->type == NFC_V9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) tmp = nfc->oob_buf[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) tmp = nfc->oob_buf[i * (oob_step / 4)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) *oob++ = (u8)tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) *oob++ = (u8)(tmp >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) *oob++ = (u8)(tmp >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) *oob++ = (u8)(tmp >> 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) for (i = 0; i < (ecc->steps / 2); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) bch_st = readl_relaxed(nfc->regs +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) nfc->cfg->bch_st_off + i * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) if (bch_st & BIT(nfc->cfg->ecc0.err_flag_bit) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) bch_st & BIT(nfc->cfg->ecc1.err_flag_bit)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) mtd->ecc_stats.failed++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) ecc_fail = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) cnt = ECC_ERR_CNT(bch_st, nfc->cfg->ecc0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) mtd->ecc_stats.corrected += cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) max_bitflips = max_t(u32, max_bitflips, cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) cnt = ECC_ERR_CNT(bch_st, nfc->cfg->ecc1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) mtd->ecc_stats.corrected += cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) max_bitflips = max_t(u32, max_bitflips, cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) memcpy(buf, nfc->page_buf, mtd->writesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) timeout_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (boot_rom_mode && rknand->boot_ecc != ecc->strength)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) rk_nfc_hw_ecc_setup(chip, ecc->strength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) if (ecc_fail) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) dev_err(nfc->dev, "read page: %x ecc error!\n", page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) return max_bitflips;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) static int rk_nfc_read_oob(struct nand_chip *chip, int page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return rk_nfc_read_page_hwecc(chip, NULL, 1, page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) static inline void rk_nfc_hw_init(struct rk_nfc *nfc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) /* Disable flash wp. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) writel(FMCTL_WP, nfc->regs + NFC_FMCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) /* Config default timing 40ns at 150 Mhz NFC clock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) writel(0x1081, nfc->regs + NFC_FMWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) nfc->cur_timing = 0x1081;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) /* Disable randomizer and DMA. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) writel(0, nfc->regs + nfc->cfg->randmz_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) writel(0, nfc->regs + nfc->cfg->dma_cfg_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) writel(FLCTL_RST, nfc->regs + nfc->cfg->flctl_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) static irqreturn_t rk_nfc_irq(int irq, void *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) struct rk_nfc *nfc = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) u32 sta, ien;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) sta = readl_relaxed(nfc->regs + nfc->cfg->int_st_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) ien = readl_relaxed(nfc->regs + nfc->cfg->int_en_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) if (!(sta & ien))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) writel(sta, nfc->regs + nfc->cfg->int_clr_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) writel(~sta & ien, nfc->regs + nfc->cfg->int_en_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) complete(&nfc->done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) static int rk_nfc_enable_clks(struct device *dev, struct rk_nfc *nfc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) if (!IS_ERR(nfc->nfc_clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) ret = clk_prepare_enable(nfc->nfc_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) dev_err(dev, "failed to enable NFC clk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) ret = clk_prepare_enable(nfc->ahb_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) dev_err(dev, "failed to enable ahb clk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) if (!IS_ERR(nfc->nfc_clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) clk_disable_unprepare(nfc->nfc_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) static void rk_nfc_disable_clks(struct rk_nfc *nfc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) if (!IS_ERR(nfc->nfc_clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) clk_disable_unprepare(nfc->nfc_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) clk_disable_unprepare(nfc->ahb_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) static int rk_nfc_ooblayout_free(struct mtd_info *mtd, int section,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) struct mtd_oob_region *oob_region)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) struct nand_chip *chip = mtd_to_nand(mtd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) if (section)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) * The beginning of the OOB area stores the reserved data for the NFC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) * the size of the reserved data is NFC_SYS_DATA_SIZE bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) oob_region->length = rknand->metadata_size - NFC_SYS_DATA_SIZE - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) oob_region->offset = NFC_SYS_DATA_SIZE + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) static int rk_nfc_ooblayout_ecc(struct mtd_info *mtd, int section,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) struct mtd_oob_region *oob_region)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) struct nand_chip *chip = mtd_to_nand(mtd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (section)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) oob_region->length = mtd->oobsize - rknand->metadata_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) oob_region->offset = rknand->metadata_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) static const struct mtd_ooblayout_ops rk_nfc_ooblayout_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) .free = rk_nfc_ooblayout_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) .ecc = rk_nfc_ooblayout_ecc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) static int rk_nfc_ecc_init(struct device *dev, struct mtd_info *mtd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) struct nand_chip *chip = mtd_to_nand(mtd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) struct rk_nfc *nfc = nand_get_controller_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) struct nand_ecc_ctrl *ecc = &chip->ecc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) const u8 *strengths = nfc->cfg->ecc_strengths;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) u8 max_strength, nfc_max_strength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) nfc_max_strength = nfc->cfg->ecc_strengths[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) /* If optional dt settings not present. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (!ecc->size || !ecc->strength ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) ecc->strength > nfc_max_strength) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) chip->ecc.size = 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) ecc->steps = mtd->writesize / ecc->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) * HW ECC always requests the number of ECC bytes per 1024 byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) * blocks. The first 4 OOB bytes are reserved for sys data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) max_strength = ((mtd->oobsize / ecc->steps) - 4) * 8 /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) fls(8 * 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) if (max_strength > nfc_max_strength)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) max_strength = nfc_max_strength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (max_strength >= strengths[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) if (i >= 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) dev_err(nfc->dev, "unsupported ECC strength\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) ecc->strength = strengths[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) ecc->steps = mtd->writesize / ecc->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) ecc->bytes = DIV_ROUND_UP(ecc->strength * fls(8 * chip->ecc.size), 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) static int rk_nfc_attach_chip(struct nand_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) struct mtd_info *mtd = nand_to_mtd(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) struct device *dev = mtd->dev.parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) struct rk_nfc *nfc = nand_get_controller_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) struct nand_ecc_ctrl *ecc = &chip->ecc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) int new_page_len, new_oob_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) void *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) if (chip->options & NAND_BUSWIDTH_16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) dev_err(dev, "16 bits bus width not supported");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) if (ecc->engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) ret = rk_nfc_ecc_init(dev, mtd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) rknand->metadata_size = NFC_SYS_DATA_SIZE * ecc->steps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (rknand->metadata_size < NFC_SYS_DATA_SIZE + 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) dev_err(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) "driver needs at least %d bytes of meta data\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) NFC_SYS_DATA_SIZE + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) /* Check buffer first, avoid duplicate alloc buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) new_page_len = mtd->writesize + mtd->oobsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) if (nfc->page_buf && new_page_len > nfc->page_buf_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) buf = krealloc(nfc->page_buf, new_page_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) GFP_KERNEL | GFP_DMA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) nfc->page_buf = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) nfc->page_buf_size = new_page_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) new_oob_len = ecc->steps * NFC_MAX_OOB_PER_STEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) if (nfc->oob_buf && new_oob_len > nfc->oob_buf_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) buf = krealloc(nfc->oob_buf, new_oob_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) GFP_KERNEL | GFP_DMA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) if (!buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) kfree(nfc->page_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) nfc->page_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) nfc->oob_buf = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) nfc->oob_buf_size = new_oob_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (!nfc->page_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) nfc->page_buf = kzalloc(new_page_len, GFP_KERNEL | GFP_DMA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) if (!nfc->page_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) nfc->page_buf_size = new_page_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) if (!nfc->oob_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) nfc->oob_buf = kzalloc(new_oob_len, GFP_KERNEL | GFP_DMA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) if (!nfc->oob_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) kfree(nfc->page_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) nfc->page_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) nfc->oob_buf_size = new_oob_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) chip->ecc.write_page_raw = rk_nfc_write_page_raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) chip->ecc.write_page = rk_nfc_write_page_hwecc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) chip->ecc.write_oob = rk_nfc_write_oob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) chip->ecc.read_page_raw = rk_nfc_read_page_raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) chip->ecc.read_page = rk_nfc_read_page_hwecc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) chip->ecc.read_oob = rk_nfc_read_oob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) static const struct nand_controller_ops rk_nfc_controller_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) .attach_chip = rk_nfc_attach_chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) .exec_op = rk_nfc_exec_op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) .setup_interface = rk_nfc_setup_interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) static int rk_nfc_nand_chip_init(struct device *dev, struct rk_nfc *nfc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) struct rk_nfc_nand_chip *rknand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) struct nand_chip *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) struct mtd_info *mtd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) int nsels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) if (!of_get_property(np, "reg", &nsels))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) nsels /= sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) if (!nsels || nsels > NFC_MAX_NSELS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) dev_err(dev, "invalid reg property size %d\n", nsels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) rknand = devm_kzalloc(dev, sizeof(*rknand) + nsels * sizeof(u8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) if (!rknand)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) rknand->nsels = nsels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) for (i = 0; i < nsels; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) ret = of_property_read_u32_index(np, "reg", i, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) dev_err(dev, "reg property failure : %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) if (tmp >= NFC_MAX_NSELS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) dev_err(dev, "invalid CS: %u\n", tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) if (test_and_set_bit(tmp, &nfc->assigned_cs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) dev_err(dev, "CS %u already assigned\n", tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) rknand->sels[i] = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) chip = &rknand->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) chip->controller = &nfc->controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) nand_set_flash_node(chip, np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) nand_set_controller_data(chip, nfc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) chip->options |= NAND_USES_DMA | NAND_NO_SUBPAGE_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) chip->bbt_options = NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) /* Set default mode in case dt entry is missing. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) mtd = nand_to_mtd(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) mtd->owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) mtd->dev.parent = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) if (!mtd->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) dev_err(nfc->dev, "NAND label property is mandatory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) mtd_set_ooblayout(mtd, &rk_nfc_ooblayout_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) rk_nfc_hw_init(nfc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) ret = nand_scan(chip, nsels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) if (chip->options & NAND_IS_BOOT_MEDIUM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) ret = of_property_read_u32(np, "rockchip,boot-blks", &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) rknand->boot_blks = ret ? 0 : tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) ret = of_property_read_u32(np, "rockchip,boot-ecc-strength",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) rknand->boot_ecc = ret ? chip->ecc.strength : tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) ret = mtd_device_register(mtd, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) dev_err(dev, "MTD parse partition error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) nand_cleanup(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) list_add_tail(&rknand->node, &nfc->chips);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) static void rk_nfc_chips_cleanup(struct rk_nfc *nfc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) struct rk_nfc_nand_chip *rknand, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) struct nand_chip *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) list_for_each_entry_safe(rknand, tmp, &nfc->chips, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) chip = &rknand->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) ret = mtd_device_unregister(nand_to_mtd(chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) WARN_ON(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) nand_cleanup(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) list_del(&rknand->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) static int rk_nfc_nand_chips_init(struct device *dev, struct rk_nfc *nfc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) struct device_node *np = dev->of_node, *nand_np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) int nchips = of_get_child_count(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) if (!nchips || nchips > NFC_MAX_NSELS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) dev_err(nfc->dev, "incorrect number of NAND chips (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) nchips);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) for_each_child_of_node(np, nand_np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) ret = rk_nfc_nand_chip_init(dev, nfc, nand_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) of_node_put(nand_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) rk_nfc_chips_cleanup(nfc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) static struct nfc_cfg nfc_v6_cfg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) .type = NFC_V6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) .ecc_strengths = {60, 40, 24, 16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) .ecc_cfgs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 0x00040011, 0x00040001, 0x00000011, 0x00000001,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) .flctl_off = 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) .bchctl_off = 0x0C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) .dma_cfg_off = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) .dma_data_buf_off = 0x14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) .dma_oob_buf_off = 0x18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) .dma_st_off = 0x1C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) .bch_st_off = 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) .randmz_off = 0x150,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) .int_en_off = 0x16C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) .int_clr_off = 0x170,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) .int_st_off = 0x174,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) .oob0_off = 0x200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) .oob1_off = 0x230,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) .ecc0 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) .err_flag_bit = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) .low = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) .low_mask = 0x1F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) .low_bn = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) .high = 27,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) .high_mask = 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) .ecc1 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) .err_flag_bit = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) .low = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) .low_mask = 0x1F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) .low_bn = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) .high = 29,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) .high_mask = 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) static struct nfc_cfg nfc_v8_cfg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) .type = NFC_V8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) .ecc_strengths = {16, 16, 16, 16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) .ecc_cfgs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 0x00000001, 0x00000001, 0x00000001, 0x00000001,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) .flctl_off = 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) .bchctl_off = 0x0C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) .dma_cfg_off = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) .dma_data_buf_off = 0x14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) .dma_oob_buf_off = 0x18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) .dma_st_off = 0x1C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) .bch_st_off = 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) .randmz_off = 0x150,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) .int_en_off = 0x16C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) .int_clr_off = 0x170,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) .int_st_off = 0x174,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) .oob0_off = 0x200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) .oob1_off = 0x230,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) .ecc0 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) .err_flag_bit = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) .low = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) .low_mask = 0x1F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) .low_bn = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) .high = 27,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) .high_mask = 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) .ecc1 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) .err_flag_bit = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) .low = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) .low_mask = 0x1F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) .low_bn = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) .high = 29,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) .high_mask = 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) static struct nfc_cfg nfc_v9_cfg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) .type = NFC_V9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) .ecc_strengths = {70, 60, 40, 16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) .ecc_cfgs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 0x00000001, 0x06000001, 0x04000001, 0x02000001,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) .flctl_off = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) .bchctl_off = 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) .dma_cfg_off = 0x30,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) .dma_data_buf_off = 0x34,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) .dma_oob_buf_off = 0x38,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) .dma_st_off = 0x3C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) .bch_st_off = 0x150,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) .randmz_off = 0x208,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) .int_en_off = 0x120,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) .int_clr_off = 0x124,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) .int_st_off = 0x128,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) .oob0_off = 0x200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) .oob1_off = 0x204,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) .ecc0 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) .err_flag_bit = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) .low = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) .low_mask = 0x7F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) .low_bn = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) .high = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) .high_mask = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) .ecc1 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) .err_flag_bit = 18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) .low = 19,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) .low_mask = 0x7F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) .low_bn = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) .high = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) .high_mask = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) static const struct of_device_id rk_nfc_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) .compatible = "rockchip,px30-nfc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) .data = &nfc_v9_cfg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) .compatible = "rockchip,rk2928-nfc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) .data = &nfc_v6_cfg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) .compatible = "rockchip,rv1108-nfc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) .data = &nfc_v8_cfg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) MODULE_DEVICE_TABLE(of, rk_nfc_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) static int rk_nfc_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) struct rk_nfc *nfc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) int ret, irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) if (!nfc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) nand_controller_init(&nfc->controller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) INIT_LIST_HEAD(&nfc->chips);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) nfc->controller.ops = &rk_nfc_controller_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) nfc->cfg = of_device_get_match_data(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) nfc->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) init_completion(&nfc->done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) nfc->regs = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) if (IS_ERR(nfc->regs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) ret = PTR_ERR(nfc->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) goto release_nfc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) nfc->nfc_clk = devm_clk_get(dev, "nfc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) if (IS_ERR(nfc->nfc_clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) dev_dbg(dev, "no NFC clk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) /* Some earlier models, such as rk3066, have no NFC clk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) nfc->ahb_clk = devm_clk_get(dev, "ahb");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) if (IS_ERR(nfc->ahb_clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) dev_err(dev, "no ahb clk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) ret = PTR_ERR(nfc->ahb_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) goto release_nfc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) ret = rk_nfc_enable_clks(dev, nfc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) goto release_nfc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) if (irq < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) dev_err(dev, "no NFC irq resource\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) goto clk_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) writel(0, nfc->regs + nfc->cfg->int_en_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) ret = devm_request_irq(dev, irq, rk_nfc_irq, 0x0, "rk-nand", nfc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) dev_err(dev, "failed to request NFC irq\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) goto clk_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) platform_set_drvdata(pdev, nfc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) ret = rk_nfc_nand_chips_init(dev, nfc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) dev_err(dev, "failed to init NAND chips\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) goto clk_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) clk_disable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) rk_nfc_disable_clks(nfc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) release_nfc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) static int rk_nfc_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) struct rk_nfc *nfc = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) kfree(nfc->page_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) kfree(nfc->oob_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) rk_nfc_chips_cleanup(nfc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) rk_nfc_disable_clks(nfc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) static int __maybe_unused rk_nfc_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) struct rk_nfc *nfc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) rk_nfc_disable_clks(nfc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) static int __maybe_unused rk_nfc_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) struct rk_nfc *nfc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) struct rk_nfc_nand_chip *rknand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) struct nand_chip *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) ret = rk_nfc_enable_clks(dev, nfc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) /* Reset NAND chip if VCC was powered off. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) list_for_each_entry(rknand, &nfc->chips, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) chip = &rknand->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) for (i = 0; i < rknand->nsels; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) nand_reset(chip, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) static const struct dev_pm_ops rk_nfc_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) SET_SYSTEM_SLEEP_PM_OPS(rk_nfc_suspend, rk_nfc_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) static struct platform_driver rk_nfc_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) .probe = rk_nfc_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) .remove = rk_nfc_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) .name = "rockchip-nfc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) .of_match_table = rk_nfc_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) .pm = &rk_nfc_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) module_platform_driver(rk_nfc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) MODULE_LICENSE("Dual MIT/GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) MODULE_AUTHOR("Yifeng Zhao <yifeng.zhao@rock-chips.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) MODULE_DESCRIPTION("Rockchip Nand Flash Controller Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) MODULE_ALIAS("platform:rockchip-nand-controller");