| /* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ |
| /* |
| * Copyright (c) 2019 Amlogic, Inc. All rights reserved. |
| */ |
| |
| #ifndef __AML_HWCTRL_H__ |
| #define __AML_HWCTRL_H__ |
| |
| #define NAND_TWB_TIME_CYCLE 10 |
| |
| /* |
| * CONFIG_SYS_NAND_RESET_CNT is used as a timeout mechanism when resetting |
| * a flash. NAND flash is initialized prior to interrupts so standard timers |
| * can't be used. CONFIG_SYS_NAND_RESET_CNT should be set to a value |
| * which is greater than (max NAND reset time / NAND status read time). |
| * A conservative default of 200000 (500 us / 25 ns) is used as a default. |
| */ |
| #define CONFIG_SYS_NAND_RESET_CNT 200000 |
| |
| #define CE_PAD_DEFAULT \ |
| ((AML_NAND_CE0) | \ |
| (AML_NAND_CE1 << 4) | \ |
| (AML_NAND_CE2 << 8) | \ |
| (AML_NAND_CE3 << 12)) |
| |
| #define RB_PAD_DEFAULT (AML_NAND_CE0) |
| #define MAX_CHIP_NUM 4 |
| |
| enum meson_chip_e { |
| MESON_CPU_MAJOR_ID_M8B = 0x1B, |
| MESON_CPU_MAJOR_ID_GXBB = 0x1F, |
| MESON_CPU_MAJOR_ID_GXTVBB = 0x20, |
| MESON_CPU_MAJOR_ID_GXL = 0x21, |
| MESON_CPU_MAJOR_ID_GXM = 0x22, |
| MESON_CPU_MAJOR_ID_TXL = 0x23, |
| MESON_CPU_MAJOR_ID_TXLX = 0x24, |
| MESON_CPU_MAJOR_ID_AXG = 0x25, |
| MESON_CPU_MAJOR_ID_GXLX = 0x26, |
| MESON_CPU_MAJOR_ID_TXHD = 0x27, |
| MESON_CPU_MAJOR_ID_G12A = 0x28, |
| MESON_CPU_MAJOR_ID_G12B = 0x29, |
| MESON_CPU_MAJOR_ID_GXLX2 = 0x2a, |
| MESON_CPU_MAJOR_ID_SM1 = 0x2B, |
| MESON_CPU_MAJOR_ID_TL1 = 0x2E, |
| MESON_CPU_MAJOR_ID_TM2, |
| MESON_CPU_MAJOR_ID_C1, |
| }; |
| |
| /*** HW controller configuration ***/ |
| struct hw_controller { |
| u32 chip_selected; |
| u32 rb_received; |
| u8 chip_num; |
| u32 ce_enable[MAX_CHIP_NUM]; |
| u32 rb_enable[MAX_CHIP_NUM]; |
| struct clk *clk; |
| enum meson_chip_e chip_type; |
| //u32 always_on; |
| |
| void __iomem *reg_base; |
| void __iomem *nand_clk_reg; |
| void __iomem *nand_ext_clk_ctrl_reg; |
| void __iomem *SYS_CLK_EN1; |
| void __iomem *PWRCTRL_PWR_OFF0; |
| u32 irq; |
| |
| struct pinctrl *nand_pinctrl; |
| struct pinctrl_state *nand_pinstate; |
| struct pinctrl_state *nand_rbstate; |
| struct pinctrl_state *nand_norbstate; |
| struct pinctrl_state *nand_idlestate; |
| struct device *device; |
| }; |
| |
| #include <linux/types.h> |
| |
| #define NF_REG_INDEX 0 |
| #define EXTCLK_REG_INDEX 1 |
| #define EXTPORT_REG_INDEX 2 |
| |
| #define RETURN_PAGE_ALL_0XFF 0x01 |
| #define RETURN_PAGE_NEED_READRETRY 0x02 |
| |
| #define A0_GP_CFG0 (0xc8100240) |
| #define A0_GP_CFG2 (0xc8100248) |
| #define SD_EMMC_BASE_C 0xFFE07000 |
| #define NAND_CLK_CNTL (SD_EMMC_BASE_C) |
| #define PINMUX_BASE (0xc8834400 + (0x2c << 2)) |
| #define P_NAND_BASE (SD_EMMC_BASE_C | BIT(11)) |
| #define NAND_BASE_APB (P_NAND_BASE) |
| |
| #define CLKTREE_SYS_CLK_EN1 ((0x0007 << 2) + 0xfe000800)//for C1 soc |
| |
| /* NAND Write Command And Read Status Register */ |
| #define P_NAND_CMD (0x00) |
| /* NAND Configuration Register */ |
| #define P_NAND_CFG (0x04) |
| /* NAND Data Address Register */ |
| #define P_NAND_DADR (0x08) |
| /* NAND Information Address Register */ |
| #define P_NAND_IADR (0x0c) |
| /* NAND Read Data Buffer Register */ |
| #define P_NAND_BUF (0x10) |
| /* NAND Information Register */ |
| #define P_NAND_INFO (0x14) |
| /* NAND DDR interface Register */ |
| #define P_NAND_DC (0x18) |
| /* NAND DDR Address Register */ |
| #define P_NAND_ADR (0x1c) |
| /* NAND DDR Low 32 bits Data Register */ |
| #define P_NAND_DL (0x20) |
| /* NAND DDR High 32 bits Data Register */ |
| #define P_NAND_DH (0x24) |
| /* NAND Command Queus Address Register */ |
| #define P_NAND_CADR (0x28) |
| /* NAND Status Address Register */ |
| #define P_NAND_SADR (0x2c) |
| /* NAND CS2: SDRAM/NAND pin sharing Register */ |
| #define P_NAND_PINS (0x30) |
| /* NAND Version number Register */ |
| #define P_NAND_VER (0x38) |
| |
| /*...other way to access cfg...*/ |
| union _nand_cfg { |
| /** raw register data */ |
| u32 d; |
| /** register bits */ |
| struct { |
| u32 bus_cyc:5; /* 0 */ |
| u32 bus_tim:5; /* 5 */ |
| u32 sync:2; /* 10 */ |
| u32 cmd_start:1; /* 12 */ |
| u32 cmd_auto:1; /* 13 */ |
| u32 apb_mode:1; /* 14 */ |
| u32 spare_only:1; /* 15 */ |
| u32 sync_adj:1; /* 16 */ |
| u32 secure_des:1; /* 17 */ |
| u32 reserved18:2; /* 18 */ |
| u32 sts_irq_en:1; /* 20 */ |
| u32 cmd_irq_en:1; /* 21 */ |
| u32 reserved22:4; /* 25 */ |
| u32 oob_on:1; /* 26 */ |
| u32 oob_mode:1; /* 27 */ |
| u32 dc_ugt:1; /* 28 */ |
| u32 nand_wpn:1; /* 29 */ |
| u32 dma_power:1; /* 30 */ |
| u32 bus_power:1; /* 31 */ |
| } b; |
| }; |
| |
| static inline u32 amlnf_read_reg32(u32 *_reg) |
| { |
| /*smp_rmb*/ |
| smp_rmb(); |
| return __raw_readl(_reg); |
| }; |
| |
| static inline void amlnf_write_reg32(u32 *_reg, |
| const u32 _value) |
| { |
| __raw_writel(_value, _reg); |
| |
| /*smp_mb*/ |
| smp_mb(); |
| }; |
| |
| static inline void amlnf_set_reg32_bits(u32 *_reg, |
| const u32 _value, |
| const u32 _start, |
| const u32 _len) |
| { |
| /*smp_rmb*/ |
| smp_rmb(); |
| |
| __raw_writel(((__raw_readl(_reg) & ~(((1L << (_len)) - 1) << (_start))) |
| | ((u32)((_value) & ((1L << (_len)) - 1)) << (_start))), _reg); |
| |
| /*smp_wmb*/ |
| smp_wmb(); |
| } |
| |
| static inline void amlnf_clrset_reg32_bits(u32 *_reg, |
| const u32 clr, |
| const u32 set) |
| { |
| /*smp_rmb*/ |
| smp_rmb(); |
| |
| __raw_writel((__raw_readl(_reg) & ~(clr)) | (set), _reg); |
| |
| /*smp_wmb*/ |
| smp_wmb(); |
| } |
| |
| static inline u32 amlnf_get_reg32_bits(u32 *_reg, |
| const u32 _start, |
| const u32 _len) |
| { |
| /*smp_rmb*/ |
| smp_rmb(); |
| return (__raw_readl(_reg) >> (_start)) & ((1L << (_len)) - 1); |
| } |
| |
| static inline void amlnf_set_reg32_mask(u32 *_reg, |
| const u32 _mask) |
| { |
| /*smp_rmb*/ |
| smp_rmb(); |
| __raw_writel((__raw_readl(_reg) | (_mask)), _reg); |
| |
| /*smp_wmb*/ |
| smp_wmb(); |
| } |
| |
| static inline void amlnf_clr_reg32_mask(u32 *_reg, |
| const u32 _mask) |
| { |
| /*smp_rmb*/ |
| smp_rmb(); |
| __raw_writel((__raw_readl(_reg) & (~(_mask))), _reg); |
| |
| /*smp_wmb*/ |
| smp_wmb(); |
| } |
| |
| #define AMLNF_WRITE_REG(reg, val) (amlnf_write_reg32(reg, (val))) |
| #define AMLNF_READ_REG(reg) (amlnf_read_reg32(reg)) |
| |
| #define AMLNF_WRITE_REG_BITS(reg, val, start, len) \ |
| (amlnf_set_reg32_bits(reg, val, start, len)) |
| |
| #define AMLNF_CLEAR_REG_MASK(reg, mask) (amlnf_clr_reg32_mask(reg, mask)) |
| #define AMLNF_SET_REG_MASK(reg, mask) (amlnf_set_reg32_mask(reg, mask)) |
| |
| #define NFC_SET_TIMING_ASYC(host, bus_tim, bus_cyc) \ |
| AMLNF_WRITE_REG_BITS((host)->reg_base + P_NAND_CFG, \ |
| (((bus_cyc) & 31) | (((bus_tim) & 31) << 5) | (0 << 10)), \ |
| 0, \ |
| 12) |
| |
| #define NFC_ENABLE_IO_IRQ(host) \ |
| AMLNF_SET_REG_MASK((host)->reg_base + P_NAND_CFG, BIT(21)) |
| #define NFC_DISABLE_IO_IRQ(host) \ |
| AMLNF_CLEAR_REG_MASK((host)->reg_base + P_NAND_CFG, BIT(21)) |
| |
| #define NFC_ENABLE_ENCRYPT(host) \ |
| AMLNF_SET_REG_MASK((host)->reg_base + P_NAND_CFG, BIT(17)) |
| #define NFC_DISABLE_ENCRYPT(host) \ |
| AMLNF_CLEAR_REG_MASK((host)->reg_base + P_NAND_CFG, BIT(17)) |
| |
| /* |
| *ADDR operations |
| */ |
| #define NFC_SET_DADDR(host, a) \ |
| (AMLNF_WRITE_REG((host)->reg_base + P_NAND_DADR, (u32)a)) |
| #define NFC_SET_IADDR(host, a) \ |
| (AMLNF_WRITE_REG((host)->reg_base + P_NAND_IADR, (u32)a)) |
| #define NFC_SET_SADDR(host, a) \ |
| (AMLNF_WRITE_REG((host)->reg_base + P_NAND_SADR, (u32)a)) |
| |
| #define NFC_INFO_GET(host) \ |
| (AMLNF_READ_REG((host)->reg_base + P_NAND_CMD)) |
| |
| #define NFC_GET_BUF(host) \ |
| AMLNF_READ_REG((host)->reg_base + P_NAND_BUF) |
| #define NFC_SET_CFG(host, val) \ |
| (AMLNF_WRITE_REG((host)->reg_base + P_NAND_CFG, (u32)val)) |
| #define NFC_GET_CFG(host) \ |
| (AMLNF_READ_REG((host)->reg_base + P_NAND_CFG)) |
| |
| /* |
| *Common Nand Read Flow |
| */ |
| #define CE0 (0xe << 10) |
| #define CE1 (0xd << 10) |
| #define CE2 (0xb << 10) |
| #define CE3 (0x7 << 10) |
| #define CE_NOT_SEL (0xf << 10) |
| #define IO4 ((0xe << 10) | BIT(18)) |
| #define IO5 ((0xd << 10) | BIT(18)) |
| #define IO6 ((0xb << 10) | BIT(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 STANDBY (0xf << 10) |
| |
| #define M2N ((0 << 17) | (2 << 20) | BIT(19)) |
| #define N2M ((1 << 17) | (2 << 20) | BIT(19)) |
| |
| #define M2N_NORAN 0x00200000 |
| #define N2M_NORAN 0x00220000 |
| |
| #define STS ((3 << 17) | (2 << 20)) |
| #define ADL ((0 << 16) | (3 << 20)) |
| #define ADH (BIT(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 SEED_OFFSET 0xc2 |
| |
| /** |
| * Nand Flash Controller (M1) |
| * Global Macros |
| */ |
| /** |
| * Config Group |
| */ |
| |
| /** |
| * CMD relative Macros |
| * Shortage word . NFCC |
| */ |
| #define NFC_CMD_IDLE(ce, time) ((ce) | IDLE | ((time) & 0x3ff)) |
| #define NFC_CMD_CLE(ce, cmd) ((ce) | CLE | ((cmd) & 0x0ff)) |
| #define NFC_CMD_ALE(ce, addr) ((ce) | ALE | ((addr) & 0x0ff)) |
| #define NFC_CMD_STANDBY(time) (STANDBY | ((time) & 0x3ff)) |
| #define NFC_CMD_ADL(addr) (ADL | ((addr) & 0xffff)) |
| #define NFC_CMD_ADH(addr) (ADH | (((addr) >> 16) & 0xffff)) |
| #define NFC_CMD_AIL(addr) (AIL | ((addr) & 0xffff)) |
| #define NFC_CMD_AIH(addr) (AIH | (((addr) >> 16) & 0xffff)) |
| #define NFC_CMD_DWR(ce, data) ((ce) | DWR | ((data) & 0xff)) |
| #define NFC_CMD_DRD(ce, size) ((ce) | DRD | (size)) |
| #define NFC_CMD_RB(ce, time) ((ce) | RB | ((time) & 0x1f)) |
| |
| #define NFC_CMD_RBIO(time, io) (RB | (io) | ((time) & 0x1f)) |
| #define NFC_CMD_RBIO_IRQ(time) (RB | IO6 | BIT(16) | ((time) & 0x1f)) |
| #define NFC_CMD_RBIO_INT(io, time) (RB | ((((io) >> 10) ^ 0x7) << 14) | \ |
| ((time) & 0x1f)) |
| #define NFC_CMD_SEED(seed) (SEED | (SEED_OFFSET + ((seed) & 0x7fff))) |
| #define NFC_CMD_STS(tim) (STS | ((tim) & 3)) |
| #define NFC_CMD_M2N(ran, ecc, sho, pgsz, pag) \ |
| (((ran) ? M2N : M2N_NORAN) | ((ecc) << 14) | ((sho) << 13) | \ |
| (((pgsz) & 0x7f) << 6) | ((pag) & 0x3f)) |
| #define NFC_CMD_N2M(ran, ecc, sho, pgsz, pag)\ |
| (((ran) ? N2M : N2M_NORAN) | ((ecc) << 14) | ((sho) << 13) | \ |
| (((pgsz) & 0x7f) << 6) | ((pag) & 0x3f)) |
| |
| #define NAND_ECC_NONE (0x0) |
| #define NAND_ECC_BCH8 (0x1) |
| #define NAND_ECC_BCH8_1K (0x2) |
| #define NAND_ECC_BCH24_1K (0x3) |
| #define NAND_ECC_BCH30_1K (0x4) |
| #define NAND_ECC_BCH40_1K (0x5) |
| #define NAND_ECC_BCH50_1K (0x6) |
| /*NAND_ECC_BCH50_1K only for mtd for general*/ |
| #define NAND_ECC_BCH60_1K (0x7) |
| #define NAND_ECC_BCH_SHORT (0x8) |
| |
| #define PER_INFO_BYTE 8 |
| |
| /* |
| *Register Operation and Controller Status |
| */ |
| #define NFC_SEND_CMD(host, cmd) \ |
| (AMLNF_WRITE_REG((host)->reg_base + P_NAND_CMD, cmd)) |
| #define NFC_READ_INFO(host) \ |
| (AMLNF_READ_REG((host)->reg_base + P_NAND_CMD)) |
| |
| /* |
| *Send command directly |
| */ |
| #define NFC_SEND_CMD_IDLE(host, time) \ |
| {\ |
| typeof(host)__host = (host); \ |
| while (NFC_CMDFIFO_SIZE(__host) > 0)\ |
| ; \ |
| NFC_SEND_CMD(__host, NFC_CMD_IDLE((__host)->chip_selected,\ |
| time)); \ |
| } |
| #define NFC_SEND_CMD_CLE(host, ce, cmd) \ |
| NFC_SEND_CMD(host, NFC_CMD_CLE(ce, cmd)) |
| #define NFC_SEND_CMD_ALE(host, ce, addr) \ |
| NFC_SEND_CMD(host, NFC_CMD_ALE(ce, addr)) |
| #define NFC_SEND_CMD_STANDBY(host, time) \ |
| NFC_SEND_CMD(host, NFC_CMD_STANDBY(time)) |
| #define NFC_SEND_CMD_ADL(host, addr) \ |
| NFC_SEND_CMD(host, NFC_CMD_ADL(addr)) |
| #define NFC_SEND_CMD_ADH(host, addr) \ |
| NFC_SEND_CMD(host, NFC_CMD_ADH(addr)) |
| #define NFC_SEND_CMD_AIL(host, addr) \ |
| NFC_SEND_CMD(host, NFC_CMD_AIL(addr)) |
| #define NFC_SEND_CMD_AIH(host, addr) \ |
| NFC_SEND_CMD(host, NFC_CMD_AIH(addr)) |
| #define NFC_SEND_CMD_DWR(host, ce, data) \ |
| NFC_SEND_CMD(host, NFC_CMD_DWR(ce, data)) |
| #define NFC_SEND_CMD_DRD(host, ce, size) \ |
| NFC_SEND_CMD(host, NFC_CMD_DRD(ce, size)) |
| #define NFC_SEND_CMD_RB(host, ce, time) \ |
| NFC_SEND_CMD(host, NFC_CMD_RB(ce, time)) |
| #define NFC_SEND_CMD_SEED(host, seed) \ |
| NFC_SEND_CMD(host, NFC_CMD_SEED(seed)) |
| #define NFC_SEND_CMD_M2N(host, ran, ecc, sho, pgsz, pag) \ |
| NFC_SEND_CMD(host, NFC_CMD_M2N(ran, ecc, sho, pgsz, pag)) |
| #define NFC_SEND_CMD_N2M(host, ran, ecc, sho, pgsz, pag) \ |
| NFC_SEND_CMD(host, NFC_CMD_N2M(ran, ecc, sho, pgsz, pag)) |
| |
| #define NFC_SEND_CMD_M2N_RAW(host, ran, len) \ |
| NFC_SEND_CMD(host, (ran ? M2N : M2N_NORAN) | ((len) & 0x3fff)) |
| #define NFC_SEND_CMD_N2M_RAW(host, ran, len) \ |
| NFC_SEND_CMD(host, (ran ? N2M : N2M_NORAN) | ((len) & 0x3fff)) |
| |
| #define NFC_SEND_CMD_STS(host, time, irq) \ |
| NFC_SEND_CMD(host, NFC_CMD_STS((time) | (irq))) |
| |
| #define NFC_SEND_CMD_RB_IRQ(host, time) \ |
| NFC_SEND_CMD(host, NFC_CMD_RBIO_IRQ(time)) |
| |
| /* |
| *Cmd Info Macros |
| */ |
| #define NFC_CMDFIFO_SIZE(host) ((NFC_INFO_GET(host) >> 22) & 0x1f) |
| #define NFC_CHECEK_RB_TIMEOUT(host) ((NFC_INFO_GET(host) >> 27) & 0x1) |
| #define NFC_FIFO_CUR_CMD(host) ((NFC_INFO_GET(host) >> 22) & 0x3FFFFF) |
| #define NFC_GET_RB_STATUS(host, ce) \ |
| (((NFC_INFO_GET(host) >> 28) & (~((ce) >> 10))) & 0xf) |
| |
| #define NAND_INFO_DONE(a) (((a) >> 31) & 1) |
| #define NAND_ECC_ENABLE(a) (((a) >> 30) & 1) |
| #define NAND_ECC_CNT(a) (((a) >> 24) & 0x3f) |
| #define NAND_ZERO_CNT(a) (((a) >> 16) & 0x3f) |
| #define NAND_INFO_DATA_2INFO(a) ((a) & 0xffff) |
| #define NAND_INFO_DATA_1INFO(a) ((a) & 0xff) |
| |
| #define POR_CONFIG READ_CBUS_REG(ASSIST_POR_CONFIG) |
| |
| #define POC_NAND_CFG BIT(2) |
| #define POC_NAND_NO_RB BIT(0) |
| #define POC_NAND_ASYNC BIT(7) |
| |
| /*nand relate define for hw controller*/ |
| /*ecc type define*/ |
| #define NAND_ECC_SOFT_MODE 0x00000000 |
| #define NAND_ECC_SHORT_MODE 0x00000001 |
| #define NAND_ECC_BCH9_MODE 0x00000002 |
| #define NAND_ECC_BCH8_MODE 0x00000003 |
| #define NAND_ECC_BCH12_MODE 0x00000004 |
| #define NAND_ECC_BCH16_MODE 0x00000005 |
| #define NAND_ECC_BCH8_1K_MODE 0x00000006 |
| #define NAND_ECC_BCH16_1K_MODE 0x00000007 |
| #define NAND_ECC_BCH24_1K_MODE 0x00000008 |
| #define NAND_ECC_BCH30_1K_MODE 0x00000009 |
| #define NAND_ECC_BCH40_1K_MODE 0x0000000a |
| #define NAND_ECC_BCH50_1K_MODE 0x0000000b |
| #define NAND_ECC_BCH60_1K_MODE 0x0000000c |
| |
| /*ecc page unit define*/ |
| #define NAND_ECC_UNIT_SIZE 512 |
| #define NAND_ECC_UNIT_1KSIZE 1024 |
| #define NAND_ECC_UNIT_SHORT 384 |
| |
| /*ecc type oob size(bytes) needed*/ |
| #define NAND_BCH9_ECC_SIZE 15 |
| #define NAND_BCH8_ECC_SIZE 14 |
| #define NAND_BCH12_ECC_SIZE 20 |
| #define NAND_BCH16_ECC_SIZE 26 |
| #define NAND_BCH8_1K_ECC_SIZE 14 |
| #define NAND_BCH16_1K_ECC_SIZE 28 |
| #define NAND_BCH24_1K_ECC_SIZE 42 |
| #define NAND_BCH30_1K_ECC_SIZE 54 |
| #define NAND_BCH40_1K_ECC_SIZE 70 |
| #define NAND_BCH50_1K_ECC_SIZE 88 |
| #define NAND_BCH60_1K_ECC_SIZE 106 |
| |
| #endif /* __HW_CTRL_H__ */ |