blob: c322cac3d63bfdfd74b4a71d0bdfb7e4d1805c45 [file]
/* 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__ */