1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun 3*4882a593Smuzhiyun /* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ 4*4882a593Smuzhiyun 5*4882a593Smuzhiyun #ifndef __NAND_H 6*4882a593Smuzhiyun #define __NAND_H 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun #include <linux/io.h> 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun #define nandc_writel(v, offs) writel((v), (offs) + nandc_base) 11*4882a593Smuzhiyun #define nandc_readl(offs) readl((offs) + nandc_base) 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun #define NANDC_READ 0 14*4882a593Smuzhiyun #define NANDC_WRITE 1 15*4882a593Smuzhiyun #define RK3326_NANDC_VER 0x56393030 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun /* INT ID */ 18*4882a593Smuzhiyun enum NANDC_IRQ_NUM_T { 19*4882a593Smuzhiyun NC_IRQ_DMA = 0, 20*4882a593Smuzhiyun NC_IRQ_FRDY, 21*4882a593Smuzhiyun NC_IRQ_BCHERR, 22*4882a593Smuzhiyun NC_IRQ_BCHFAIL, 23*4882a593Smuzhiyun NC_IRQ_LLP 24*4882a593Smuzhiyun }; 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun enum ENUM_NANDC_BCH_CFG { 27*4882a593Smuzhiyun NC_BCH_70 = 0, 28*4882a593Smuzhiyun NC_BCH_24, 29*4882a593Smuzhiyun NC_BCH_40, 30*4882a593Smuzhiyun NC_BCH_60, 31*4882a593Smuzhiyun }; 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun union FM_CTL_T { 34*4882a593Smuzhiyun u32 d32; 35*4882a593Smuzhiyun struct { 36*4882a593Smuzhiyun unsigned cs : 8; /* bits[0:7] */ 37*4882a593Smuzhiyun unsigned wp : 1; /* bits[8] */ 38*4882a593Smuzhiyun unsigned rdy : 1; /* bits[9] */ 39*4882a593Smuzhiyun unsigned fifo_empty : 1; /* bits[10] */ 40*4882a593Smuzhiyun unsigned reserved11 : 1; /* bits[11] */ 41*4882a593Smuzhiyun unsigned dwidth : 1; /* bits[12] */ 42*4882a593Smuzhiyun unsigned tm : 1; /* bits[13] */ 43*4882a593Smuzhiyun unsigned onficlk_en : 1; /* bits[14] */ 44*4882a593Smuzhiyun unsigned toggle_en : 1; /* bits[15] */ 45*4882a593Smuzhiyun unsigned flash_abort_en : 1; /* bits[16] */ 46*4882a593Smuzhiyun unsigned flash_abort_clear : 1; /* bits[17] */ 47*4882a593Smuzhiyun unsigned reserved18_23 : 6; /* bits[18:23] */ 48*4882a593Smuzhiyun unsigned read_delay : 3; /* bits[24:26] */ 49*4882a593Smuzhiyun unsigned reserved27_31 : 5; /* bits[27:31] */ 50*4882a593Smuzhiyun } V6; 51*4882a593Smuzhiyun struct { 52*4882a593Smuzhiyun unsigned cs : 8; 53*4882a593Smuzhiyun unsigned wp : 1; 54*4882a593Smuzhiyun unsigned frdy : 1; 55*4882a593Smuzhiyun unsigned fifo_empth_flash : 1; 56*4882a593Smuzhiyun unsigned reserved11_12 : 2; 57*4882a593Smuzhiyun unsigned tm : 1; 58*4882a593Smuzhiyun unsigned syn_clken : 1; 59*4882a593Smuzhiyun unsigned syn_mode : 1; 60*4882a593Smuzhiyun unsigned flash_abort_en : 1; 61*4882a593Smuzhiyun unsigned flash_abort_clear : 1; 62*4882a593Smuzhiyun unsigned sif_read_delay : 3; 63*4882a593Smuzhiyun unsigned io_mux : 3; 64*4882a593Smuzhiyun unsigned reserved24_31 : 8; 65*4882a593Smuzhiyun } V9; 66*4882a593Smuzhiyun }; 67*4882a593Smuzhiyun 68*4882a593Smuzhiyun union FM_WAIT_T { 69*4882a593Smuzhiyun u32 d32; 70*4882a593Smuzhiyun struct { 71*4882a593Smuzhiyun unsigned csrw : 5; 72*4882a593Smuzhiyun unsigned rwpw : 6; 73*4882a593Smuzhiyun unsigned rdy : 1; 74*4882a593Smuzhiyun unsigned rwcs : 6; 75*4882a593Smuzhiyun unsigned reserved18_23 : 6; 76*4882a593Smuzhiyun unsigned fmw_dly : 6; 77*4882a593Smuzhiyun unsigned fmw_dly_en : 1; 78*4882a593Smuzhiyun unsigned reserved31_31 : 1; 79*4882a593Smuzhiyun } V6; 80*4882a593Smuzhiyun struct { 81*4882a593Smuzhiyun unsigned rwcs : 5; 82*4882a593Smuzhiyun unsigned rwpw : 6; 83*4882a593Smuzhiyun unsigned hard_rdy : 1; 84*4882a593Smuzhiyun unsigned csrw : 6; 85*4882a593Smuzhiyun unsigned wait_frdy_dly : 5; 86*4882a593Smuzhiyun unsigned reserved23_23 : 1; 87*4882a593Smuzhiyun unsigned fmw_dly : 6; 88*4882a593Smuzhiyun unsigned fmw_dly_en : 1; 89*4882a593Smuzhiyun unsigned reserved31_31 : 1; 90*4882a593Smuzhiyun } V9; 91*4882a593Smuzhiyun }; 92*4882a593Smuzhiyun 93*4882a593Smuzhiyun union FL_CTL_T { 94*4882a593Smuzhiyun u32 d32; 95*4882a593Smuzhiyun struct { 96*4882a593Smuzhiyun unsigned rst : 1; 97*4882a593Smuzhiyun unsigned rdn : 1; 98*4882a593Smuzhiyun unsigned start : 1; 99*4882a593Smuzhiyun unsigned dma : 1; 100*4882a593Smuzhiyun unsigned st_addr : 1; 101*4882a593Smuzhiyun unsigned tr_count : 2; 102*4882a593Smuzhiyun unsigned rdy_ignore : 1; 103*4882a593Smuzhiyun /* unsigned int_clr : 1; */ 104*4882a593Smuzhiyun /* unsigned int_en : 1; */ 105*4882a593Smuzhiyun unsigned reserved8_9 : 2; 106*4882a593Smuzhiyun unsigned cor_en : 1; 107*4882a593Smuzhiyun unsigned lba_en : 1; 108*4882a593Smuzhiyun unsigned spare_size : 7; 109*4882a593Smuzhiyun unsigned reserved19 : 1; 110*4882a593Smuzhiyun unsigned tr_rdy : 1; 111*4882a593Smuzhiyun unsigned page_size : 1; 112*4882a593Smuzhiyun unsigned page_num : 6; 113*4882a593Smuzhiyun unsigned low_power : 1; 114*4882a593Smuzhiyun unsigned async_tog_mix : 1; 115*4882a593Smuzhiyun unsigned reserved30_31 : 2; 116*4882a593Smuzhiyun } V6; 117*4882a593Smuzhiyun struct { 118*4882a593Smuzhiyun unsigned flash_rst : 1; 119*4882a593Smuzhiyun unsigned flash_rdn : 1; 120*4882a593Smuzhiyun unsigned flash_st : 1; 121*4882a593Smuzhiyun unsigned bypass : 1; 122*4882a593Smuzhiyun unsigned st_addr : 1; 123*4882a593Smuzhiyun unsigned tr_count : 2; 124*4882a593Smuzhiyun unsigned flash_st_mod : 1; 125*4882a593Smuzhiyun unsigned not_tran_data : 1; 126*4882a593Smuzhiyun unsigned tran_seed : 1; 127*4882a593Smuzhiyun unsigned cor_able : 1; 128*4882a593Smuzhiyun unsigned lba_en : 1; 129*4882a593Smuzhiyun unsigned lba_spare_sel : 1; 130*4882a593Smuzhiyun unsigned reserved13_18 : 6; 131*4882a593Smuzhiyun unsigned bchst_trans : 1; 132*4882a593Smuzhiyun unsigned tr_rdy : 1; 133*4882a593Smuzhiyun unsigned page_size : 1; 134*4882a593Smuzhiyun unsigned page_num : 6; 135*4882a593Smuzhiyun unsigned low_power : 1; 136*4882a593Smuzhiyun unsigned async_tog_mix : 1; 137*4882a593Smuzhiyun unsigned bypass_fifo_mode : 1; 138*4882a593Smuzhiyun unsigned reserved31_31 : 1; 139*4882a593Smuzhiyun } V9; 140*4882a593Smuzhiyun }; 141*4882a593Smuzhiyun 142*4882a593Smuzhiyun union BCH_CTL_T { 143*4882a593Smuzhiyun u32 d32; 144*4882a593Smuzhiyun struct { 145*4882a593Smuzhiyun unsigned rst : 1; 146*4882a593Smuzhiyun unsigned reserved : 1; 147*4882a593Smuzhiyun unsigned addr_not_care : 1; 148*4882a593Smuzhiyun unsigned power_down : 1; 149*4882a593Smuzhiyun unsigned bch_mode : 1; /* 0-16bit/1KB, 1-24bit/1KB */ 150*4882a593Smuzhiyun unsigned region : 3; 151*4882a593Smuzhiyun unsigned addr : 8; 152*4882a593Smuzhiyun unsigned bchpage : 1; 153*4882a593Smuzhiyun unsigned reserved17 : 1; 154*4882a593Smuzhiyun unsigned bch_mode1 : 1; 155*4882a593Smuzhiyun unsigned thres : 8; 156*4882a593Smuzhiyun unsigned reserved27_31 : 5; 157*4882a593Smuzhiyun } V6; 158*4882a593Smuzhiyun struct { 159*4882a593Smuzhiyun unsigned bchrst : 1; 160*4882a593Smuzhiyun unsigned wcnt_clear : 1; 161*4882a593Smuzhiyun unsigned reserved2 : 1; 162*4882a593Smuzhiyun unsigned bchepd : 1; 163*4882a593Smuzhiyun unsigned reserved4_15 : 12; 164*4882a593Smuzhiyun unsigned bchpage : 1; 165*4882a593Smuzhiyun unsigned bchthre : 8; 166*4882a593Smuzhiyun unsigned bchmode : 3; 167*4882a593Smuzhiyun unsigned reserved28_31 : 4; 168*4882a593Smuzhiyun } V9; 169*4882a593Smuzhiyun }; 170*4882a593Smuzhiyun 171*4882a593Smuzhiyun union BCH_ST_T { 172*4882a593Smuzhiyun u32 d32; 173*4882a593Smuzhiyun struct { 174*4882a593Smuzhiyun unsigned errf0 : 1; 175*4882a593Smuzhiyun unsigned done0 : 1; 176*4882a593Smuzhiyun unsigned fail0 : 1; 177*4882a593Smuzhiyun unsigned err_bits0 : 5; 178*4882a593Smuzhiyun unsigned err_bits_low0 : 5; 179*4882a593Smuzhiyun unsigned errf1 : 1; 180*4882a593Smuzhiyun unsigned done1 : 1; 181*4882a593Smuzhiyun unsigned fail1 : 1; 182*4882a593Smuzhiyun unsigned err_bits1 : 5; 183*4882a593Smuzhiyun unsigned err_bits_low1 : 5; 184*4882a593Smuzhiyun unsigned rdy : 1; 185*4882a593Smuzhiyun /* unsigned cnt : 1; */ 186*4882a593Smuzhiyun unsigned err_bits0_5 : 1; 187*4882a593Smuzhiyun unsigned err_bits_low0_5 : 1; 188*4882a593Smuzhiyun unsigned err_bits1_5 : 1; 189*4882a593Smuzhiyun unsigned err_bits_low1_5 : 1; 190*4882a593Smuzhiyun unsigned reserved31_31 : 1; 191*4882a593Smuzhiyun } V6; 192*4882a593Smuzhiyun struct { 193*4882a593Smuzhiyun unsigned errf0 : 1; 194*4882a593Smuzhiyun unsigned done0 : 1; 195*4882a593Smuzhiyun unsigned fail0 : 1; 196*4882a593Smuzhiyun unsigned err_bits0 : 7; 197*4882a593Smuzhiyun unsigned all_f_flag0 : 1; 198*4882a593Smuzhiyun unsigned reserved11_15 : 5; 199*4882a593Smuzhiyun unsigned errf1 : 1; 200*4882a593Smuzhiyun unsigned done1 : 1; 201*4882a593Smuzhiyun unsigned fail1 : 1; 202*4882a593Smuzhiyun unsigned err_bits1 : 7; 203*4882a593Smuzhiyun unsigned all_f_flag1 : 1; 204*4882a593Smuzhiyun unsigned reserved27_30 : 4; 205*4882a593Smuzhiyun unsigned bch_ready_flag: 1; 206*4882a593Smuzhiyun } V9; 207*4882a593Smuzhiyun }; 208*4882a593Smuzhiyun 209*4882a593Smuzhiyun union MTRANS_CFG_T { 210*4882a593Smuzhiyun u32 d32; 211*4882a593Smuzhiyun struct { 212*4882a593Smuzhiyun unsigned ahb_wr_st : 1; 213*4882a593Smuzhiyun unsigned ahb_wr : 1; 214*4882a593Smuzhiyun unsigned bus_mode : 1; 215*4882a593Smuzhiyun unsigned hsize : 3; 216*4882a593Smuzhiyun unsigned burst : 3; 217*4882a593Smuzhiyun unsigned incr_num : 5; 218*4882a593Smuzhiyun unsigned fl_pwd : 1; 219*4882a593Smuzhiyun unsigned ahb_rst : 1; 220*4882a593Smuzhiyun unsigned reserved16_31 : 16; 221*4882a593Smuzhiyun } V6; 222*4882a593Smuzhiyun struct { 223*4882a593Smuzhiyun unsigned ahb_wr_st : 1; 224*4882a593Smuzhiyun unsigned ahb_wr : 1; 225*4882a593Smuzhiyun unsigned bus_mode : 1; 226*4882a593Smuzhiyun unsigned hsize : 3; 227*4882a593Smuzhiyun unsigned burst : 3; 228*4882a593Smuzhiyun unsigned incr_num : 5; 229*4882a593Smuzhiyun unsigned fl_pwd : 1; 230*4882a593Smuzhiyun unsigned ahb_rst : 1; 231*4882a593Smuzhiyun unsigned redundance_size : 11; 232*4882a593Smuzhiyun unsigned reserved27_31 : 5; 233*4882a593Smuzhiyun } V9; 234*4882a593Smuzhiyun }; 235*4882a593Smuzhiyun 236*4882a593Smuzhiyun union MTRANS_STAT_T { 237*4882a593Smuzhiyun u32 d32; 238*4882a593Smuzhiyun struct { 239*4882a593Smuzhiyun unsigned bus_err : 16; 240*4882a593Smuzhiyun unsigned mtrans_cnt : 5; 241*4882a593Smuzhiyun unsigned reserved21_31 : 11; 242*4882a593Smuzhiyun } V6; 243*4882a593Smuzhiyun struct { 244*4882a593Smuzhiyun unsigned bus_err : 16; 245*4882a593Smuzhiyun unsigned mtrans_cnt : 6; 246*4882a593Smuzhiyun unsigned reserved22_31 : 10; 247*4882a593Smuzhiyun } V9; 248*4882a593Smuzhiyun }; 249*4882a593Smuzhiyun 250*4882a593Smuzhiyun /* NANDC Registers */ 251*4882a593Smuzhiyun #define NANDC_FMCTL 0x0 252*4882a593Smuzhiyun #define NANDC_FMWAIT 0x4 253*4882a593Smuzhiyun #define NANDC_FLCTL 0x8 254*4882a593Smuzhiyun #define NANDC_BCHCTL 0xc 255*4882a593Smuzhiyun #define NANDC_MTRANS_CFG 0x10 256*4882a593Smuzhiyun #define NANDC_MTRANS_SADDR0 0x14 257*4882a593Smuzhiyun #define NANDC_MTRANS_SADDR1 0x18 258*4882a593Smuzhiyun #define NANDC_MTRANS_STAT 0x1c 259*4882a593Smuzhiyun #define NANDC_DLL_CTL_REG0 0x130 260*4882a593Smuzhiyun #define NANDC_DLL_CTL_REG1 0x134 261*4882a593Smuzhiyun #define NANDC_DLL_OBS_REG0 0x138 262*4882a593Smuzhiyun #define NANDC_RANDMZ_CFG 0x150 263*4882a593Smuzhiyun #define NANDC_EBI_EN 0x154 264*4882a593Smuzhiyun #define NANDC_FMWAIT_SYN 0x158 265*4882a593Smuzhiyun #define NANDC_MTRANS_STAT2 0x15c 266*4882a593Smuzhiyun #define NANDC_NANDC_VER 0x160 267*4882a593Smuzhiyun #define NANDC_LLP_CTL 0x164 268*4882a593Smuzhiyun #define NANDC_LLP_STAT 0x168 269*4882a593Smuzhiyun #define NANDC_INTEN 0x16c 270*4882a593Smuzhiyun #define NANDC_INTCLR 0x170 271*4882a593Smuzhiyun #define NANDC_INTST 0x174 272*4882a593Smuzhiyun #define NANDC_SPARE0 0x200 273*4882a593Smuzhiyun #define NANDC_SPARE1 0x230 274*4882a593Smuzhiyun 275*4882a593Smuzhiyun #define NANDC_BCHST(i) ({ \ 276*4882a593Smuzhiyun u32 x = (i); \ 277*4882a593Smuzhiyun 4 * x + x < 8 ? 0x20 : 0x520; }) 278*4882a593Smuzhiyun 279*4882a593Smuzhiyun #define NANDC_CHIP_DATA(id) (0x800 + (id) * 0x100) 280*4882a593Smuzhiyun #define NANDC_CHIP_ADDR(id) (0x800 + (id) * 0x100 + 0x4) 281*4882a593Smuzhiyun #define NANDC_CHIP_CMD(id) (0x800 + (id) * 0x100 + 0x8) 282*4882a593Smuzhiyun 283*4882a593Smuzhiyun #define NANDC_V9_FMCTL 0x0 284*4882a593Smuzhiyun #define NANDC_V9_FMWAIT 0x4 285*4882a593Smuzhiyun #define NANDC_V9_FLCTL 0x10 286*4882a593Smuzhiyun #define NANDC_V9_BCHCTL 0x20 287*4882a593Smuzhiyun #define NANDC_V9_MTRANS_CFG 0x30 288*4882a593Smuzhiyun #define NANDC_V9_MTRANS_SADDR0 0x34 289*4882a593Smuzhiyun #define NANDC_V9_MTRANS_SADDR1 0x38 290*4882a593Smuzhiyun #define NANDC_V9_MTRANS_STAT 0x40 291*4882a593Smuzhiyun #define NANDC_V9_MTRANS_STAT2 0x44 292*4882a593Smuzhiyun #define NANDC_V9_NANDC_VER 0x80 293*4882a593Smuzhiyun 294*4882a593Smuzhiyun #define NANDC_V9_INTEN 0x120 295*4882a593Smuzhiyun #define NANDC_V9_INTCLR 0x124 296*4882a593Smuzhiyun #define NANDC_V9_INTST 0x128 297*4882a593Smuzhiyun #define NANDC_V9_SPARE0 0x200 298*4882a593Smuzhiyun #define NANDC_V9_SPARE1 0x204 299*4882a593Smuzhiyun #define NANDC_V9_RANDMZ_CFG 0x208 300*4882a593Smuzhiyun #define NANDC_V9_BCHST(i) (0x150 + (i) * 4) 301*4882a593Smuzhiyun 302*4882a593Smuzhiyun #define NANDC_V9_CHIP_DATA(id) (0x800 + (id) * 0x100) 303*4882a593Smuzhiyun #define NANDC_V9_CHIP_ADDR(id) (0x800 + (id) * 0x100 + 0x4) 304*4882a593Smuzhiyun #define NANDC_V9_CHIP_CMD(id) (0x800 + (id) * 0x100 + 0x8) 305*4882a593Smuzhiyun 306*4882a593Smuzhiyun struct MASTER_INFO_T { 307*4882a593Smuzhiyun u32 *page_buf; /* [DATA_LEN]; */ 308*4882a593Smuzhiyun u32 *spare_buf; /* [DATA_LEN / (1024/128)]; */ 309*4882a593Smuzhiyun u32 *page_vir; /* page_buf_vir_addr */ 310*4882a593Smuzhiyun u32 *spare_vir; /* spare_buf_vir_addr */ 311*4882a593Smuzhiyun u32 page_phy; /* page_buf_phy_addr */ 312*4882a593Smuzhiyun u32 spare_phy; /* spare_buf_phy_addr*/ 313*4882a593Smuzhiyun u32 mapped; 314*4882a593Smuzhiyun u32 cnt; 315*4882a593Smuzhiyun }; 316*4882a593Smuzhiyun 317*4882a593Smuzhiyun struct CHIP_MAP_INFO_T { 318*4882a593Smuzhiyun u32 *nandc_addr; 319*4882a593Smuzhiyun u32 chip_num; 320*4882a593Smuzhiyun }; 321*4882a593Smuzhiyun 322*4882a593Smuzhiyun unsigned long rknandc_dma_map_single(unsigned long ptr, 323*4882a593Smuzhiyun int size, 324*4882a593Smuzhiyun int dir); 325*4882a593Smuzhiyun void rknandc_dma_unmap_single(unsigned long ptr, 326*4882a593Smuzhiyun int size, 327*4882a593Smuzhiyun int dir); 328*4882a593Smuzhiyun 329*4882a593Smuzhiyun void nandc_init(void __iomem *nandc_addr); 330*4882a593Smuzhiyun void nandc_flash_cs(u8 chip_sel); 331*4882a593Smuzhiyun void nandc_flash_de_cs(u8 chip_sel); 332*4882a593Smuzhiyun u32 nandc_wait_flash_ready(u8 chip_sel); 333*4882a593Smuzhiyun u32 nandc_delayns(u32 count); 334*4882a593Smuzhiyun u32 nandc_xfer_data(u8 chip_sel, 335*4882a593Smuzhiyun u8 dir, 336*4882a593Smuzhiyun u8 sector_count, 337*4882a593Smuzhiyun u32 *p_data, 338*4882a593Smuzhiyun u32 *p_spare); 339*4882a593Smuzhiyun void nandc_randmz_sel(u8 chip_sel, u32 randmz_seed); 340*4882a593Smuzhiyun void nandc_bch_sel(u8 bits); 341*4882a593Smuzhiyun void nandc_read_not_case_busy_en(u8 en); 342*4882a593Smuzhiyun void nandc_time_cfg(u32 ns); 343*4882a593Smuzhiyun void nandc_clean_irq(void); 344*4882a593Smuzhiyun u8 nandc_get_version(void); 345*4882a593Smuzhiyun 346*4882a593Smuzhiyun #endif 347