1 /* 2 * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0 5 */ 6 7 #include <common.h> 8 #include <linux/compat.h> 9 #include <linux/delay.h> 10 11 #include "flash.h" 12 #include "flash_com.h" 13 #include "nandc.h" 14 #include "rk_sftl.h" 15 16 #define CPU_DELAY_NS(n) ndelay(n) 17 18 #define NANDC_MASTER_EN 19 20 void __iomem *nandc_base; 21 static u8 g_nandc_ver; 22 23 static u32 g_nandc_ecc_bits; 24 #ifdef NANDC_MASTER_EN 25 static struct MASTER_INFO_T master; 26 static u32 *g_master_temp_buf; 27 #endif 28 29 void nandc_init(void __iomem *nandc_addr) 30 { 31 union FM_CTL_T ctl_reg; 32 33 nandc_base = nandc_addr; 34 35 ctl_reg.d32 = 0; 36 g_nandc_ver = 6; 37 if (nandc_readl(NANDC_V9_NANDC_VER) == RK3326_NANDC_VER) 38 g_nandc_ver = 9; 39 if (g_nandc_ver == 9) { 40 ctl_reg.V9.wp = 1; 41 ctl_reg.V9.sif_read_delay = 2; 42 nandc_writel(ctl_reg.d32, NANDC_V9_FMCTL); 43 nandc_writel(0, NANDC_V9_RANDMZ_CFG); 44 nandc_writel(0x1041, NANDC_V9_FMWAIT); 45 } else { 46 ctl_reg.V6.wp = 1; 47 nandc_writel(ctl_reg.d32, NANDC_FMCTL); 48 nandc_writel(0, NANDC_RANDMZ_CFG); 49 nandc_writel(0x1061, NANDC_FMWAIT); 50 } 51 nandc_time_cfg(40); 52 53 #ifdef NANDC_MASTER_EN 54 if (!g_master_temp_buf) 55 g_master_temp_buf = (u32 *)ftl_malloc(MAX_FLASH_PAGE_SIZE + 56 MAX_FLASH_PAGE_SIZE / 8); 57 master.page_buf = &g_master_temp_buf[0]; 58 master.spare_buf = &g_master_temp_buf[MAX_FLASH_PAGE_SIZE / 4]; 59 master.mapped = 0; 60 #endif 61 } 62 63 void nandc_flash_cs(u8 chip_sel) 64 { 65 union FM_CTL_T tmp; 66 67 tmp.d32 = nandc_readl(NANDC_FMCTL); 68 tmp.V6.cs = 0x01 << chip_sel; 69 nandc_writel(tmp.d32, NANDC_FMCTL); 70 } 71 72 void nandc_flash_de_cs(u8 chip_sel) 73 { 74 union FM_CTL_T tmp; 75 76 tmp.d32 = nandc_readl(NANDC_FMCTL); 77 tmp.V6.cs = 0; 78 tmp.V6.flash_abort_clear = 0; 79 nandc_writel(tmp.d32, NANDC_FMCTL); 80 } 81 82 u32 nandc_delayns(u32 count) 83 { 84 CPU_DELAY_NS(count); 85 return 0; 86 } 87 88 u32 nandc_wait_flash_ready(u8 chip_sel) 89 { 90 union FM_CTL_T tmp; 91 u32 status; 92 u32 i; 93 94 status = 0; 95 for (i = 0; i < 100000; i++) { 96 nandc_delayns(100); 97 tmp.d32 = nandc_readl(NANDC_FMCTL); 98 if (tmp.V6.rdy != 0) 99 break; 100 } 101 102 if (i >= 100000) 103 status = -1; 104 return status; 105 } 106 107 void nandc_randmz_sel(u8 chip_sel, u32 randmz_seed) 108 { 109 nandc_writel(randmz_seed, NANDC_RANDMZ_CFG); 110 } 111 112 void nandc_time_cfg(u32 ns) 113 { 114 if (g_nandc_ver == 9) { 115 if (ns < 36) 116 nandc_writel(0x1041, NANDC_V9_FMWAIT); 117 else if (ns >= 100) 118 nandc_writel(0x2082, NANDC_V9_FMWAIT); 119 else 120 nandc_writel(0x1061, NANDC_V9_FMWAIT); 121 } else { 122 if (ns < 36) 123 nandc_writel(0x1061, NANDC_FMWAIT); 124 else if (ns >= 100) 125 nandc_writel(0x2082, NANDC_FMWAIT); 126 else 127 nandc_writel(0x1081, NANDC_FMWAIT); 128 } 129 } 130 131 void nandc_bch_sel(u8 bits) 132 { 133 union BCH_CTL_T tmp; 134 union FL_CTL_T fl_reg; 135 u8 bch_config; 136 137 fl_reg.d32 = 0; 138 fl_reg.V6.rst = 1; 139 g_nandc_ecc_bits = bits; 140 if (g_nandc_ver == 9) { 141 nandc_writel(fl_reg.d32, NANDC_V9_FLCTL); 142 if (bits == 70) 143 bch_config = 0; 144 else if (bits == 60) 145 bch_config = 3; 146 else if (bits == 40) 147 bch_config = 2; 148 else 149 bch_config = 1; 150 tmp.d32 = 0; 151 tmp.V9.bchmode = bch_config; 152 tmp.V9.bchrst = 1; 153 nandc_writel(tmp.d32, NANDC_V9_BCHCTL); 154 } else { 155 nandc_writel(fl_reg.d32, NANDC_FLCTL); 156 tmp.d32 = 0; 157 tmp.V6.addr = 0x10; 158 tmp.V6.bch_mode1 = 0; 159 if (bits == 16) { 160 tmp.V6.bch_mode = 0; 161 } else if (bits == 24) { 162 tmp.V6.bch_mode = 1; 163 } else { 164 tmp.V6.bch_mode1 = 1; 165 tmp.V6.bch_mode = 1; 166 if (bits == 40) 167 tmp.V6.bch_mode = 0; 168 } 169 tmp.V6.rst = 1; 170 nandc_writel(tmp.d32, NANDC_BCHCTL); 171 } 172 } 173 174 /* 175 *Nandc xfer data transmission 176 *1. set bch register except nandc version equals 9 177 *2. set internal transfer control register 178 *3. set bus transfer 179 * a. target memory data address 180 * b. ahb setting 181 *4. configure register orderly and start transmission 182 */ 183 static void nandc_xfer_start(u8 dir, u8 n_sec, u32 *data, u32 *spare) 184 { 185 union BCH_CTL_T bch_reg; 186 union FL_CTL_T fl_reg; 187 u32 i; 188 union MTRANS_CFG_T master_reg; 189 u16 *p_spare_tmp = (u16 *)spare; 190 unsigned long vir_addr; 191 192 fl_reg.d32 = 0; 193 if (g_nandc_ver == 9) { 194 fl_reg.V9.flash_rdn = dir; 195 fl_reg.V9.bypass = 1; 196 fl_reg.V9.tr_count = 1; 197 fl_reg.V9.async_tog_mix = 1; 198 fl_reg.V9.cor_able = 1; 199 fl_reg.V9.st_addr = 0; 200 fl_reg.V9.page_num = (n_sec + 1) / 2; 201 /* dma start transfer data do care flash rdy */ 202 fl_reg.V9.flash_st_mod = 1; 203 204 if (dir != 0) { 205 for (i = 0; i < n_sec / 2; i++) { 206 if (spare) { 207 master.spare_buf[i] = 208 (p_spare_tmp[0]) | 209 ((u32)p_spare_tmp[1] << 16); 210 p_spare_tmp += 2; 211 } else { 212 master.spare_buf[i] = 0xffffffff; 213 } 214 } 215 } else { 216 master.spare_buf[0] = 1; 217 } 218 master.page_vir = (u32 *)((data == (u32 *)NULL) ? 219 master.page_buf : 220 (u32 *)data); 221 master.spare_vir = (u32 *)master.spare_buf; 222 223 master.page_phy = (u32)((unsigned long)master.page_vir); 224 master.spare_phy = (u32)((unsigned long)master.spare_vir); 225 vir_addr = ((unsigned long)master.page_phy); 226 flush_dcache_range(vir_addr & (~0x3FuL), 227 ((vir_addr + 63) & (~0x3FuL)) + 228 fl_reg.V6.page_num * 1024); 229 vir_addr = ((unsigned long)master.spare_phy); 230 flush_dcache_range(vir_addr & (~0x3FuL), 231 ((vir_addr + 63) & (~0x3FuL)) + 232 fl_reg.V6.page_num * 128); 233 master.mapped = 1; 234 nandc_writel(master.page_phy, NANDC_V9_MTRANS_SADDR0); 235 nandc_writel(master.spare_phy, NANDC_V9_MTRANS_SADDR1); 236 237 master_reg.d32 = nandc_readl(NANDC_V9_MTRANS_CFG); 238 master_reg.V9.incr_num = 16; 239 master_reg.V9.burst = 7; 240 master_reg.V9.hsize = 2; 241 master_reg.V9.bus_mode = 1; 242 master_reg.V9.ahb_wr = !dir; 243 master_reg.V9.ahb_wr_st = 1; 244 master_reg.V9.redundance_size = 0; 245 246 nandc_writel(master_reg.d32, NANDC_V9_MTRANS_CFG); 247 nandc_writel(fl_reg.d32, NANDC_V9_FLCTL); 248 fl_reg.V9.flash_st = 1; 249 nandc_writel(fl_reg.d32, NANDC_V9_FLCTL); 250 } else { 251 bch_reg.d32 = nandc_readl(NANDC_BCHCTL); 252 bch_reg.V6.addr = 0x10; 253 bch_reg.V6.power_down = 0; 254 bch_reg.V6.region = 0; 255 256 fl_reg.V6.rdn = dir; 257 fl_reg.V6.dma = 1; 258 fl_reg.V6.tr_count = 1; 259 fl_reg.V6.async_tog_mix = 1; 260 fl_reg.V6.cor_en = 1; 261 fl_reg.V6.st_addr = 0; 262 263 master_reg.d32 = nandc_readl(NANDC_MTRANS_CFG); 264 master_reg.V6.bus_mode = 0; 265 if (dir != 0) { 266 u32 spare_sz = 64; 267 268 for (i = 0; i < n_sec / 2; i++) { 269 if (spare) { 270 master.spare_buf[i * spare_sz / 4] = 271 (p_spare_tmp[0]) | 272 ((u32)p_spare_tmp[1] << 16); 273 p_spare_tmp += 2; 274 } else { 275 master.spare_buf[i * spare_sz / 4] = 276 0xffffffff; 277 } 278 } 279 } 280 fl_reg.V6.page_num = (n_sec + 1) / 2; 281 master.page_vir = (u32 *)((data == (u32 *)NULL) ? 282 master.page_buf : 283 (u32 *)data); 284 master.spare_vir = (u32 *)master.spare_buf; 285 286 master.page_phy = (u32)((unsigned long)master.page_vir); 287 master.spare_phy = (u32)((unsigned long)master.spare_vir); 288 vir_addr = ((unsigned long)master.page_phy); 289 flush_dcache_range(vir_addr & (~0x3FuL), 290 ((vir_addr + 63) & (~0x3FuL)) + 291 fl_reg.V6.page_num * 1024); 292 vir_addr = ((unsigned long)master.spare_phy); 293 flush_dcache_range(vir_addr & (~0x3FuL), 294 ((vir_addr + 63) & (~0x3FuL)) + 295 fl_reg.V6.page_num * 128); 296 master.mapped = 1; 297 nandc_writel(master.page_phy, NANDC_MTRANS_SADDR0); 298 nandc_writel(master.spare_phy, NANDC_MTRANS_SADDR1); 299 master_reg.d32 = 0; 300 master_reg.V6.incr_num = 16; 301 master_reg.V6.burst = 7; 302 master_reg.V6.hsize = 2; 303 master_reg.V6.bus_mode = 1; 304 master_reg.V6.ahb_wr = !dir; 305 master_reg.V6.ahb_wr_st = 1; 306 307 nandc_writel(master_reg.d32, NANDC_MTRANS_CFG); 308 nandc_writel(bch_reg.d32, NANDC_BCHCTL); 309 nandc_writel(fl_reg.d32, NANDC_FLCTL); 310 fl_reg.V6.start = 1; 311 nandc_writel(fl_reg.d32, NANDC_FLCTL); 312 } 313 } 314 315 /* 316 * Wait for the end of data transmission 317 */ 318 static void nandc_xfer_done(void) 319 { 320 union FL_CTL_T fl_reg; 321 union MTRANS_CFG_T master_reg; 322 323 if (g_nandc_ver == 9) { 324 union MTRANS_STAT_T stat_reg; 325 326 master_reg.d32 = nandc_readl(NANDC_V9_MTRANS_CFG); 327 if (master_reg.V9.ahb_wr != 0) { 328 do { 329 fl_reg.d32 = nandc_readl(NANDC_V9_FLCTL); 330 stat_reg.d32 = nandc_readl(NANDC_V9_MTRANS_STAT); 331 } while (stat_reg.V9.mtrans_cnt < fl_reg.V9.page_num || 332 fl_reg.V9.tr_rdy == 0); 333 } else { 334 do { 335 fl_reg.d32 = nandc_readl(NANDC_V9_FLCTL); 336 } while (fl_reg.V9.tr_rdy == 0); 337 } 338 } else { 339 master_reg.d32 = nandc_readl(NANDC_MTRANS_CFG); 340 if (master_reg.V6.bus_mode != 0) { 341 union MTRANS_STAT_T stat_reg; 342 343 if (master_reg.V6.ahb_wr != 0) { 344 do { 345 fl_reg.d32 = nandc_readl(NANDC_FLCTL); 346 stat_reg.d32 = nandc_readl(NANDC_MTRANS_STAT); 347 } while (stat_reg.V6.mtrans_cnt < fl_reg.V6.page_num || 348 fl_reg.V6.tr_rdy == 0); 349 } else { 350 do { 351 fl_reg.d32 = nandc_readl(NANDC_FLCTL); 352 } while (fl_reg.V6.tr_rdy == 0); 353 } 354 } else { 355 do { 356 fl_reg.d32 = nandc_readl(NANDC_FLCTL); 357 } while ((fl_reg.V6.tr_rdy == 0)); 358 } 359 } 360 } 361 362 u32 nandc_xfer_data(u8 chip_sel, u8 dir, u8 n_sec, 363 u32 *p_data, u32 *p_spare) 364 { 365 u32 status = NAND_STS_OK; 366 u32 i; 367 u32 spare[16]; 368 union BCH_ST_T bch_st_reg; 369 370 if (dir == NANDC_WRITE && !p_spare) { 371 p_spare = (u32 *)spare; 372 memset(spare, 0xFF, sizeof(spare)); 373 } 374 nandc_xfer_start(dir, n_sec, p_data, p_spare); 375 nandc_xfer_done(); 376 if (dir == NANDC_READ) { 377 if (g_nandc_ver == 9) { 378 for (i = 0; i < n_sec / 4; i++) { 379 bch_st_reg.d32 = nandc_readl(NANDC_V9_BCHST(i)); 380 if (n_sec > 2) { 381 if (bch_st_reg.V9.fail0 || bch_st_reg.V9.fail1) { 382 status = NAND_STS_ECC_ERR; 383 } else { 384 u32 tmp = max((u32)bch_st_reg.V9.err_bits0, 385 (u32)bch_st_reg.V9.err_bits1); 386 status = max(tmp, status); 387 } 388 } else { 389 if (bch_st_reg.V9.fail0) 390 status = NAND_STS_ECC_ERR; 391 else 392 status = bch_st_reg.V9.err_bits0; 393 } 394 } 395 if (p_spare) { 396 for (i = 0; i < n_sec / 2; i++) 397 p_spare[i] = master.spare_buf[i]; 398 } 399 } else { 400 for (i = 0; i < n_sec / 4 ; i++) { 401 bch_st_reg.d32 = nandc_readl(NANDC_BCHST(i)); 402 if (bch_st_reg.V6.fail0 || bch_st_reg.V6.fail1) { 403 status = NAND_STS_ECC_ERR; 404 } else { 405 u32 tmp = 0; 406 407 tmp = 408 max(bch_st_reg.V6.err_bits0 | 409 ((u32)bch_st_reg.V6.err_bits0_5 << 5), 410 bch_st_reg.V6.err_bits1 | 411 ((u32)bch_st_reg.V6.err_bits1_5 << 5)); 412 status = max(tmp, status); 413 } 414 } 415 if (p_spare) { 416 u32 spare_sz = 64; 417 u32 temp_data; 418 u8 *p_spare_temp = (u8 *)p_spare; 419 420 for (i = 0; i < n_sec / 2; i++) { 421 temp_data = master.spare_buf[i * spare_sz / 4]; 422 *p_spare_temp++ = (u8)temp_data; 423 *p_spare_temp++ = (u8)(temp_data >> 8); 424 *p_spare_temp++ = (u8)(temp_data >> 16); 425 *p_spare_temp++ = (u8)(temp_data >> 24); 426 } 427 } 428 nandc_writel(0, NANDC_MTRANS_CFG); 429 } 430 } 431 return status; 432 } 433 434 void nandc_clean_irq(void) 435 { 436 } 437