| /* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ |
| /* |
| * Copyright (c) 2019 Amlogic, Inc. All rights reserved. |
| */ |
| |
| #ifndef _NFC_H_ |
| #define _NFC_H_ |
| |
| #include <asm/cache.h> |
| #include <asm/io.h> |
| |
| #define SD_EMMC_DLY1 (0x04) |
| #define SD_EMMC_DLY2 (0x08) |
| |
| #define PADCTRL_MISC_CTRL0 ((0x002a << 2) + 0xfe004000) |
| #define PADCTRL_GPIOB_PULL_EN ((0x0093 << 2) + 0xfe004000) |
| #define PADCTRL_GPIOB_PULL_UP ((0x0094 << 2) + 0xfe004000) |
| #define CLKCTRL_SYS_CLK_EN0_REG0 ((0x0011 << 2) + 0xfe000000) |
| #define CLKCTRL_NAND_CLK_CTRL ((0x005a << 2) + 0xfe000000) |
| #define PADCTRL_PIN_MUX_REG0 ((0x0000 << 2) + 0xfe004000) |
| #define PADCTRL_PIN_MUX_REG1 ((0x0001 << 2) + 0xfe004000) |
| |
| #define NAND_CMD (0x00) |
| #define NAND_CFG (0x04) |
| #define NAND_DADR (0x08) |
| #define NAND_IADR (0x0c) |
| #define NAND_BUF (0x10) |
| #define NAND_INFO (0x14) |
| #define NAND_DC (0x18) |
| #define NAND_ADR (0x1c) |
| #define NAND_DL (0x20) |
| #define NAND_DH (0x24) |
| #define NAND_CADR (0x28) |
| #define NAND_SADR (0x2c) |
| |
| #define SPI_RX_IDX (0x34) |
| #define SPI_RX_DAT (0x38) |
| #define SPI_CFG (0x40) |
| |
| #define CEF (0xf << 10) |
| #define CE0 (0xe << 10) |
| #define CE1 (0xd << 10) |
| #define CE2 (0xb << 10) |
| #define CE3 (0x7 << 10) |
| |
| #define IO4 ((0xe << 10) | (1 << 18)) |
| #define IO5 ((0xd << 10) | (1 << 18)) |
| #define IO6 ((0xb << 10) | (1 << 18)) |
| |
| #define CLE (0x5 << 14) |
| #define ALE (0x6 << 14) |
| #define DWR (0x4 << 14) |
| #define DRD (0x8 << 14) |
| #define IDLE (0xc << 14) |
| #define RB BIT(20) |
| |
| #define M2N ((0 << 17) | (2 << 20) | (1 << 19)) |
| #define N2M ((1 << 17) | (2 << 20) | (1 << 19)) |
| #define STS ((3 << 17) | (2 << 20)) |
| #define ADL ((0 << 16) | (3 << 20)) |
| #define ADH ((1 << 16) | (3 << 20)) |
| #define AIL ((2 << 16) | (3 << 20)) |
| #define AIH ((3 << 16) | (3 << 20)) |
| #define ASL ((4 << 16) | (3 << 20)) |
| #define ASH ((5 << 16) | (3 << 20)) |
| #define SEED ((8 << 16) | (3 << 20)) |
| #define DUMMY (0xB << 14) |
| |
| #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 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 ECC_COMPLETE BIT(31) |
| #define ECC_UNCORRECTABLE 0x3f |
| #define ECC_ERR_CNT(x) (((x) >> 24) & 0x3f) |
| #define ECC_ZERO_CNT(x) (((x) >> 16) & 0x3f) |
| |
| #define CLK_ALWAYS_ON BIT(28) |
| #define CLK_SELECT_NAND BIT(31) |
| #define CLK_DEF_CORE_PHASE (2 << 8) |
| |
| #define CTRL_NAND_CLK_GATE_ON_BIT BIT(26) |
| #define CTRL_SDEMMC_CLK_CTRL_ON_BIT BIT(7) |
| |
| #define GET_BCH_MODE(x) (((x) >> 14) & 0x7) |
| |
| #define ERROR_MODE(mod, num) ((u32)((((mod) << 8) | (num)))) |
| #define ERR_NFC_WRONG_PARAM ERROR_MODE(3, 5) |
| #define ERR_NFC_TIMEOUT ERROR_MODE(3, 6) |
| #define ERR_DMA_TIMEOUT ERROR_MODE(3, 7) |
| #define ERROR_BLANK_PAGE ERROR_MODE(3, 8) |
| #define ERROR_ECC ERROR_MODE(3, 9) |
| |
| extern u64 *info_buf; |
| |
| #define ARRAY_SIZE_UL(array) (sizeof(array) / sizeof(unsigned long)) |
| |
| #define NFC_STATUS_ON 1 |
| #define NFC_STATUS_OFF 0 |
| |
| #define SPI_MODE 1 |
| #define NFC_MODE 0 |
| |
| #define NFC_RAW_CHUNK_SHIFT 14 |
| |
| enum CMD_TYPE { /* bit shift */ |
| TYPE_NONE = 0, |
| TYPE_CMD = 1, |
| TYPE_ADDR = 2, |
| TYPE_DATA_DRD = 4, |
| TYPE_DATA_DWR = 8, |
| }; |
| |
| #define CMD_ADDR (TYPE_CMD | TYPE_ADDR) |
| #define CMD_ADDR_DATA_RD (TYPE_CMD | TYPE_ADDR | TYPE_DATA_DRD) |
| #define CMD_ADDR_DATA_WR (TYPE_CMD | TYPE_ADDR | TYPE_DATA_DWR) |
| |
| #define NFC_SEND_CMD(cmd) \ |
| nfc_send_cmd_addr_and_wait(TYPE_CMD, (cmd), \ |
| NULL, 0, NULL, 0, 0) |
| #define NFC_SEND_ADDR(addr, addr_len) \ |
| nfc_send_cmd_addr_and_wait(TYPE_ADDR, 0, \ |
| (addr), (addr_len), NULL, 0, 0) |
| #define NFC_SEND_DATA_IN(data, data_len) \ |
| nfc_send_cmd_addr_and_wait(TYPE_DATA_DRD, 0, \ |
| NULL, 0, (data), (data_len), 0) |
| #define NFC_SEND_DATA_OUT(data, data_len) \ |
| nfc_send_cmd_addr_and_wait(TYPE_DATA_DWR, 0, \ |
| NULL, 0, (data), (data_len), 0) |
| #define NFC_SEND_CMD_CTRL(cmd, ctrl) \ |
| nfc_send_cmd_addr_and_wait(TYPE_CMD, (cmd), \ |
| NULL, 0, NULL, 0, (ctrl)) |
| #define NFC_SEND_CMD_ADDR(cmd, addr, addr_len) \ |
| nfc_send_cmd_addr_and_wait(CMD_ADDR, (cmd), \ |
| (addr), (addr_len), \ |
| NULL, 0, 0) |
| #define NFC_SEND_CMD_ADDR_CTRL(cmd, addr, addr_len, ctrl) \ |
| nfc_send_cmd_addr_and_wait(CMD_ADDR, (cmd), \ |
| (addr), (addr_len), \ |
| NULL, 0, (ctrl)) |
| #define NFC_SEND_CMD_ADDR_DATA_RD(cmd, addr, addr_len, data, data_len) \ |
| nfc_send_cmd_addr_and_wait(CMD_ADDR_DATA_RD, \ |
| (cmd), (addr), (addr_len), \ |
| (data), (data_len), 0) |
| #define NFC_SEND_CMD_ADDR_DATA_WR(cmd, addr, addr_len, data, data_len) \ |
| nfc_send_cmd_addr_and_wait(CMD_ADDR_DATA_WR, \ |
| (cmd), (addr), (addr_len), \ |
| (data), (data_len), 0) |
| #define NFC_SEND_CMD_ADDR_DATA_WR_CTRL(cmd, addr, addr_len, data, data_len, ctrl) \ |
| nfc_send_cmd_addr_and_wait(CMD_ADDR_DATA_WR, \ |
| (cmd), (addr), (addr_len), \ |
| (data), (data_len), (ctrl)) |
| |
| enum STATE_AND_DUMMY_CTL { |
| DUMMY_BEFORE_ADDRESS = 0x01, |
| DUMMY_AFTER_ADDRESS = 0x02, |
| DONT_SEND_CEF = 0x04, |
| }; |
| |
| #define STATE_AND_DUMMY_CTL_BIT_SHIFT 8 |
| |
| /* timeout in unit us */ |
| /* 10ms */ |
| #define NFC_COMMAND_FIFO_TIMEOUT (10000) |
| /* when transferring data, considering the worse case: |
| * 1bit and 6Mhz, all the 202KiB data would cost about |
| * 6MByts/s / 8 = 0.75MBytes/s, then the 202KiB would |
| * cost about 202/1024*0.75*1000 = 147.9ms. |
| * Considering more redundancy, 1s would be a good |
| * choice. |
| */ |
| #define NFC_DATA_FIFO_TIMEOUT (1000000) |
| |
| enum NFC_CLK_RATE { |
| CLK_6MHZ = 0, |
| CLK_12MHZ, |
| CLK_20MHZ, |
| CLK_41MHZ, |
| CLK_83MHZ, |
| CLK_100MHZ_400, |
| CLK_100MHZ_500, |
| CLK_125MHZ, |
| CLK_133MHZ, |
| CLK_166MHZ_333, |
| CLK_166MHZ_666, |
| CLK_200MHZ_400, |
| CLK_200MHZ_800, |
| }; |
| |
| enum NFC_CLK_SRC_TYPE { |
| OSC_CLK_24MHZ = 0, |
| FIX_PLL_DIV2, |
| FIX_PLL_DIV3, |
| HIFI_PLL, |
| FIX_PLL_DIV2P5, |
| }; |
| |
| struct nfc_clk_provider { |
| enum NFC_CLK_SRC_TYPE clk_src_type; |
| enum NFC_CLK_RATE clk_rate; |
| unsigned char div1; |
| unsigned char div2; |
| unsigned char adj; |
| unsigned char cs_deselect_time; |
| }; |
| |
| enum NFC_STORAGE_TYPE { |
| SPINAND_FLASH = 0, |
| SPINOR_FLASH = 1, |
| SLCNAND_FLASH = 2, |
| }; |
| |
| #define N2M_RAW (0x00220000) |
| #define M2N_RAW (0x00200000) |
| |
| #define CMD_BITMAP_TEST_AND_GET_BIT_VALUE(x, i) \ |
| (__extension__ ({int tmp = 1 << (i); (((x) & tmp) ? tmp : 0); })) |
| #define CMD_BITMAP_CLEAR_BIT(x, i) ((x) &= ~(1 << (i))) |
| |
| #define NFC_IDX 0 |
| #define EMMC_IDX 1 |
| |
| #define CLK_DIV_SHIFT 0 |
| #define CLK_DIV_WIDTH 6 |
| |
| enum TRANSFER_STATE { |
| TRANSFER_STATE_NONE, |
| TRANSFER_STATE_CMD, |
| TRANSFER_STATE_ADDR, |
| TRANSFER_STATE_DUMMY, |
| TRANSFER_STATE_DATAOUT, |
| TRANSFER_STATE_DATAIN, |
| }; |
| |
| void nfc_pinmux_init(enum NFC_STORAGE_TYPE storage_type); |
| void nfc_send_idle(u32 cycle); |
| void nfc_select_mode(int spi_mode); |
| void nfc_deselect_chip(u32 cycle); |
| void nfc_raw_size_ext_convert(u32 size); |
| u32 nfc_send_cmd_addr_and_wait(unsigned char cmd_bitmap, u8 cmd, |
| u8 *addr, u8 addr_len, |
| u8 *data, u8 data_len, |
| unsigned short state_dummy_ctl); |
| void nfc_set_clock_and_timing(unsigned long *clk_rate); |
| void nfc_set_dma_mem_and_info(u32 mem, unsigned long info); |
| int nfc_start_dma_and_wait_done(u32 n2m_cmd); |
| int nfc_wait_data_and_ecc_engine_done(struct device *dev, dma_addr_t iaddr, |
| u64 *info_buf, unsigned char nsteps, int raw); |
| void nfc_send_repeat_rb_command(void); |
| void nfc_set_dma_random_seed(u32 page, u32 n2m_cmd); |
| unsigned int nfc_recalculate_n2m_command(u32 size, int no_cal); |
| int nfc_wait_command_fifo_done(u32 timeout, int repeat_rb); |
| |
| void nfc_get_user_byte(u8 *oob_buf, u64 *info_buf, int ecc_steps); |
| void nfc_set_user_byte(u8 *oob_buf, u64 *info_buf, int ecc_steps); |
| void nfc_set_data_bus_width(int bus_width); |
| |
| extern struct regmap *nfc_regmap[2]; |
| |
| #endif |