| /* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ |
| /* |
| * Copyright (c) 2019 Amlogic, Inc. All rights reserved. |
| */ |
| |
| #ifndef __AMLMTD_NAND_H_ |
| #define __AMLMTD_NAND_H_ |
| |
| #include <linux/mtd/rawnand.h> |
| #include <linux/clk-provider.h> |
| #include <linux/amlogic/aml_storage.h> |
| |
| #define NAND_TIMING_MODE0 0x0 |
| #define NAND_TIMING_MODE1 0x1 |
| #define NAND_TIMING_MODE2 0x2 |
| #define NAND_TIMING_MODE3 0x3 |
| #define NAND_TIMING_MODE4 0x4 |
| #define NAND_TIMING_MODE5 0x5 |
| |
| #define NFC_REG_CMD 0x00 |
| #define NFC_CMD_IDLE (0xc << 14) |
| #define NFC_CMD_CLE (0x5 << 14) |
| #define NFC_CMD_ALE (0x6 << 14) |
| #define NFC_CMD_ADL ((0 << 16) | (3 << 20)) |
| #define NFC_CMD_ADH ((1 << 16) | (3 << 20)) |
| #define NFC_CMD_AIL ((2 << 16) | (3 << 20)) |
| #define NFC_CMD_AIH ((3 << 16) | (3 << 20)) |
| #define NFC_CMD_SEED ((8 << 16) | (3 << 20)) |
| #define NFC_CMD_M2N ((0 << 17) | (2 << 20)) |
| #define NFC_CMD_N2M ((1 << 17) | (2 << 20)) |
| #define NFC_CMD_DRD (0x8 << 14) |
| #define NFC_CMD_RB BIT(20) |
| #define NFC_CMD_SCRAMBLER_ENABLE 1 //BIT(19) |
| #define NFC_CMD_SCRAMBLER_DISABLE 0 |
| #define NFC_CMD_SHORTMODE_DISABLE 0 |
| #define NFC_CMD_SHORTMODE_ENABLE 1 |
| #define NFC_CMD_RB_INT BIT(14) |
| |
| #define NFC_CMD_GET_SIZE(x) (((x) >> 22) & GENMASK(4, 0)) |
| |
| #define NFC_REG_CFG 0x04 |
| #define NFC_REG_DADR 0x08 |
| #define NFC_REG_IADR 0x0c |
| #define NFC_REG_BUF 0x10 |
| #define NFC_REG_INFO 0x14 |
| #define NFC_REG_DC 0x18 |
| #define NFC_REG_ADR 0x1c |
| #define NFC_REG_DL 0x20 |
| #define NFC_REG_DH 0x24 |
| #define NFC_REG_CADR 0x28 |
| #define NFC_REG_SADR 0x2c |
| #define NFC_REG_PINS 0x30 |
| #define NFC_REG_VER 0x38 |
| |
| #define NFC_RB_IRQ_EN BIT(21) |
| |
| #define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages) \ |
| ( \ |
| (cmd_dir) | \ |
| ((ran) << 19) | \ |
| ((bch) << 14) | \ |
| ((short_mode) << 13) | \ |
| (((page_size) & 0x7f) << 6) | \ |
| ((pages) & 0x3f) \ |
| ) |
| |
| #define GENCMDDADDRL(adl, addr) ((adl) | ((addr) & 0xffff)) |
| #define GENCMDDADDRH(adh, addr) ((adh) | (((addr) >> 16) & 0xffff)) |
| #define GENCMDIADDRL(ail, addr) ((ail) | ((addr) & 0xffff)) |
| #define GENCMDIADDRH(aih, addr) ((aih) | (((addr) >> 16) & 0xffff)) |
| |
| #define DMA_DIR(dir) ((dir) ? NFC_CMD_N2M : NFC_CMD_M2N) |
| |
| #define ECC_CHECK_RETURN_FF (-1) |
| |
| #define NAND_CE0 (0xe << 10) |
| #define NAND_CE1 (0xd << 10) |
| |
| #define DMA_BUSY_TIMEOUT 0x100000 |
| #define CMD_FIFO_EMPTY_TIMEOUT 1000 |
| |
| #define MAX_CE_NUM 2 |
| #define NAND_MAX_DEVICE 4 |
| |
| /* eMMC clock register, misc control */ |
| #define CLK_SELECT_NAND BIT(31) |
| |
| #define NFC_CLK_CYCLE 6 |
| |
| /* nand flash controller delay 3 ns */ |
| #define NFC_DEFAULT_DELAY 3000 |
| |
| #define ROW_ADDER(page, index) (((page) >> (8 * (index))) & 0xff) |
| #define MAX_CYCLE_ADDRS 5 |
| #define DIRREAD 1 |
| #define DIRWRITE 0 |
| |
| #define ECC_PARITY_BCH8_512B 14 |
| #define ECC_COMPLETE BIT(31) |
| #define ECC_ERR_CNT(x) (((x) >> 24) & GENMASK(5, 0)) |
| #define ECC_ZERO_CNT(x) (((x) >> 16) & GENMASK(5, 0)) |
| #define ECC_UNCORRECTABLE 0x3f |
| |
| #define PER_INFO_BYTE 8 |
| |
| #define NAND_BLOCK_GOOD 0 |
| #define NAND_BLOCK_BAD 1 |
| #define NAND_FACTORY_BAD 2 |
| |
| /* Max total is 1024 as romboot says so... */ |
| #define BOOT_TOTAL_PAGES (1024) |
| #define NAND_FIPMODE_DISCRETE (1) |
| struct meson_nfc_nand_chip { |
| struct list_head node; |
| struct nand_chip nand; |
| unsigned long clk_rate; |
| unsigned long level1_divider; |
| u32 bus_timing; |
| u32 twb; |
| u32 tadl; |
| u32 tbers_max; |
| u32 bch_info; |
| u32 bch_mode; |
| u8 *data_buf; |
| __le64 *info_buf; |
| u32 nsels; |
| u8 sels[0]; |
| }; |
| |
| struct meson_nand_ecc { |
| u32 bch; |
| u32 strength; |
| u32 step_size; |
| }; |
| |
| struct meson_nfc_data { |
| const struct nand_ecc_caps *ecc_caps; |
| int bl2ex_mode; |
| }; |
| |
| struct meson_nfc_param { |
| u32 chip_select; |
| u32 rb_select; |
| }; |
| |
| struct nand_rw_cmd { |
| u32 cmd0; |
| u32 addrs[MAX_CYCLE_ADDRS]; |
| u32 cmd1; |
| }; |
| |
| struct nand_timing { |
| u32 twb; |
| u32 tadl; |
| u32 tbers_max; |
| }; |
| |
| struct meson_nfc { |
| struct nand_controller controller; |
| struct clk *clk_gate; |
| struct clk *fix_div2_pll; |
| struct clk_divider nand_divider; |
| struct clk *nand_div_clk; |
| unsigned long clk_rate; |
| u32 bus_timing; |
| |
| struct device *dev; |
| void __iomem *reg_base; |
| void __iomem *nand_clk_reg; |
| |
| struct completion completion; |
| struct list_head chips; |
| const struct meson_nfc_data *data; |
| struct meson_nfc_param param; |
| struct nand_timing timing; |
| struct meson_rsv_handler_t *rsv; |
| union { |
| int cmd[32]; |
| struct nand_rw_cmd rw; |
| } cmdfifo; |
| |
| dma_addr_t daddr; |
| dma_addr_t iaddr; |
| |
| unsigned long assigned_cs; |
| s8 *block_status; |
| |
| struct para_form_dts { |
| u32 clk_ctrl_base; |
| u32 bl_mode; |
| u32 fip_copies; |
| u32 fip_size; |
| u32 skip_bad_block; |
| u32 disa_irq_hand; |
| } param_from_dts; |
| |
| struct pinctrl *nand_pinctrl; |
| struct pinctrl_state *nand_norbstate; |
| struct pinctrl_state *nand_idlestate; |
| }; |
| |
| /**for info page0 information**/ |
| union sc2_cmdinfo { |
| u32 d32; |
| struct { |
| unsigned cmd:22; |
| unsigned page_list:1; |
| unsigned new_type:8; |
| unsigned reserved:1; |
| } b; |
| }; |
| |
| struct _nand_setup_sc2 { |
| union sc2_cmdinfo cfg; |
| u16 id; |
| u16 max; |
| }; |
| |
| union cmdinfo { |
| u32 d32; |
| struct { |
| unsigned cmd:22; |
| unsigned large_page:1; |
| unsigned no_rb:1; |
| unsigned a2:1; |
| unsigned reserved25:1; |
| unsigned page_list:1; |
| unsigned sync_mode:2; |
| unsigned size:2; |
| unsigned active:1; |
| } b; |
| }; |
| |
| struct _nand_setup { |
| union cmdinfo cfg; |
| u16 id; |
| u16 max; |
| }; |
| |
| struct _nand_cmd { |
| unsigned char type; |
| unsigned char val; |
| }; |
| |
| struct _ext_info { |
| u32 read_info; |
| u32 new_type; |
| u32 pages_per_blk; |
| u32 xlc; |
| u32 ce_mask; |
| u32 boot_num; |
| u32 each_boot_pages; |
| u32 bbt_occupy_pages; |
| u32 bbt_start_block; |
| }; |
| |
| struct _fip_info { |
| u16 version; |
| u16 mode; /*compact or discrete*/ |
| u32 fip_start; /*fip_start, pages*/ |
| }; |
| |
| #define NAND_PAGELIST_CNT 16 |
| #define NAND_ECC_UNIT_SHORT 384 |
| /*max size 384 bytes*/ |
| struct _nand_page0 { |
| struct _nand_setup nand_setup; |
| unsigned char page_list[NAND_PAGELIST_CNT]; |
| struct _nand_cmd retry_usr[32]; |
| struct _ext_info ext_info; |
| struct _fip_info fip_info; |
| u32 ddrp_start_page; |
| }; |
| |
| struct _nand_page0_sc2 { |
| struct _nand_setup_sc2 nand_setup; |
| unsigned char page_list[32]; |
| struct _nand_cmd retry_usr[32]; |
| struct _ext_info ext_info; |
| struct _fip_info fip_info; |
| u32 ddrp_start_page; |
| }; |
| |
| /**end info page0 information**/ |
| extern struct mtd_part_parser ofpart_meson_parser; |
| extern struct nand_flash_dev aml_nand_flash_ids[]; |
| |
| #endif /* __AMLMTD_NAND_H_ */ |