]> git.ipfire.org Git - thirdparty/u-boot.git/blame - drivers/mtd/nand/raw/arasan_nfc.c
Revert "Merge patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet""
[thirdparty/u-boot.git] / drivers / mtd / nand / raw / arasan_nfc.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
e4b40e92
SDPP
2/*
3 * Arasan NAND Flash Controller Driver
4 *
5 * Copyright (C) 2014 - 2015 Xilinx, Inc.
e4b40e92
SDPP
6 */
7
d678a59d 8#include <common.h>
e4b40e92
SDPP
9#include <malloc.h>
10#include <asm/io.h>
c05ed00a 11#include <linux/delay.h>
1221ce45 12#include <linux/errno.h>
e4b40e92 13#include <linux/mtd/mtd.h>
6ae3900a 14#include <linux/mtd/rawnand.h>
e4b40e92
SDPP
15#include <linux/mtd/partitions.h>
16#include <linux/mtd/nand_ecc.h>
17#include <asm/arch/hardware.h>
18#include <asm/arch/sys_proto.h>
b014b833 19#include <dm.h>
e4b40e92 20#include <nand.h>
1e94b46f 21#include <linux/printk.h>
e4b40e92 22
b014b833 23struct nand_config {
e4b40e92 24 u32 page;
cacb8a02 25 bool on_die_ecc_enabled;
e4b40e92
SDPP
26};
27
3dd0f8cc
ARS
28struct nand_drv {
29 struct nand_regs *reg;
30 struct nand_config config;
31};
32
b014b833
ARS
33struct arasan_nand_info {
34 struct udevice *dev;
3dd0f8cc 35 struct nand_drv nand_ctrl;
b014b833
ARS
36 struct nand_chip nand_chip;
37};
38
e4b40e92
SDPP
39struct nand_regs {
40 u32 pkt_reg;
41 u32 memadr_reg1;
42 u32 memadr_reg2;
43 u32 cmd_reg;
44 u32 pgm_reg;
45 u32 intsts_enr;
46 u32 intsig_enr;
47 u32 intsts_reg;
48 u32 rdy_busy;
49 u32 cms_sysadr_reg;
50 u32 flash_sts_reg;
51 u32 tmg_reg;
52 u32 buf_dataport;
53 u32 ecc_reg;
54 u32 ecc_errcnt_reg;
55 u32 ecc_sprcmd_reg;
56 u32 errcnt_1bitreg;
57 u32 errcnt_2bitreg;
58 u32 errcnt_3bitreg;
59 u32 errcnt_4bitreg;
60 u32 dma_sysadr0_reg;
61 u32 dma_bufbdry_reg;
62 u32 cpu_rls_reg;
63 u32 errcnt_5bitreg;
64 u32 errcnt_6bitreg;
65 u32 errcnt_7bitreg;
66 u32 errcnt_8bitreg;
67 u32 data_if_reg;
68};
69
e4b40e92
SDPP
70struct arasan_nand_command_format {
71 u8 cmd1;
72 u8 cmd2;
73 u8 addr_cycles;
74 u32 pgm;
75};
76
77#define ONDIE_ECC_FEATURE_ADDR 0x90
cacb8a02 78#define ENABLE_ONDIE_ECC 0x08
e4b40e92
SDPP
79
80#define ARASAN_PROG_RD_MASK 0x00000001
81#define ARASAN_PROG_BLK_ERS_MASK 0x00000004
82#define ARASAN_PROG_RD_ID_MASK 0x00000040
83#define ARASAN_PROG_RD_STS_MASK 0x00000008
84#define ARASAN_PROG_PG_PROG_MASK 0x00000010
85#define ARASAN_PROG_RD_PARAM_PG_MASK 0x00000080
86#define ARASAN_PROG_RST_MASK 0x00000100
87#define ARASAN_PROG_GET_FTRS_MASK 0x00000200
88#define ARASAN_PROG_SET_FTRS_MASK 0x00000400
89#define ARASAN_PROG_CHNG_ROWADR_END_MASK 0x00400000
90
91#define ARASAN_NAND_CMD_ECC_ON_MASK 0x80000000
92#define ARASAN_NAND_CMD_CMD12_MASK 0xFFFF
93#define ARASAN_NAND_CMD_PG_SIZE_MASK 0x3800000
94#define ARASAN_NAND_CMD_PG_SIZE_SHIFT 23
95#define ARASAN_NAND_CMD_CMD2_SHIFT 8
96#define ARASAN_NAND_CMD_ADDR_CYCL_MASK 0x70000000
97#define ARASAN_NAND_CMD_ADDR_CYCL_SHIFT 28
98
6fbbe2d8 99#define ARASAN_NAND_MEM_ADDR1_PAGE_MASK 0xFFFF0000
e4b40e92
SDPP
100#define ARASAN_NAND_MEM_ADDR1_COL_MASK 0xFFFF
101#define ARASAN_NAND_MEM_ADDR1_PAGE_SHIFT 16
102#define ARASAN_NAND_MEM_ADDR2_PAGE_MASK 0xFF
103#define ARASAN_NAND_MEM_ADDR2_CS_MASK 0xC0000000
97fca6a1
KR
104#define ARASAN_NAND_MEM_ADDR2_CS0_MASK (0x3 << 30)
105#define ARASAN_NAND_MEM_ADDR2_CS1_MASK (0x1 << 30)
e4b40e92
SDPP
106#define ARASAN_NAND_MEM_ADDR2_BCH_MASK 0xE000000
107#define ARASAN_NAND_MEM_ADDR2_BCH_SHIFT 25
108
109#define ARASAN_NAND_INT_STS_ERR_EN_MASK 0x10
110#define ARASAN_NAND_INT_STS_MUL_BIT_ERR_MASK 0x08
111#define ARASAN_NAND_INT_STS_BUF_RD_RDY_MASK 0x02
112#define ARASAN_NAND_INT_STS_BUF_WR_RDY_MASK 0x01
113#define ARASAN_NAND_INT_STS_XFR_CMPLT_MASK 0x04
114
115#define ARASAN_NAND_PKT_REG_PKT_CNT_MASK 0xFFF000
116#define ARASAN_NAND_PKT_REG_PKT_SIZE_MASK 0x7FF
117#define ARASAN_NAND_PKT_REG_PKT_CNT_SHFT 12
118
119#define ARASAN_NAND_ROW_ADDR_CYCL_MASK 0x0F
120#define ARASAN_NAND_COL_ADDR_CYCL_MASK 0xF0
121#define ARASAN_NAND_COL_ADDR_CYCL_SHIFT 4
122
123#define ARASAN_NAND_ECC_SIZE_SHIFT 16
124#define ARASAN_NAND_ECC_BCH_SHIFT 27
125
126#define ARASAN_NAND_PKTSIZE_1K 1024
127#define ARASAN_NAND_PKTSIZE_512 512
128
129#define ARASAN_NAND_POLL_TIMEOUT 1000000
130#define ARASAN_NAND_INVALID_ADDR_CYCL 0xFF
131
132#define ERR_ADDR_CYCLE -1
133#define READ_BUFF_SIZE 0x4000
134
135static struct arasan_nand_command_format *curr_cmd;
136
137enum addr_cycles {
138 NAND_ADDR_CYCL_NONE,
139 NAND_ADDR_CYCL_ONE,
140 NAND_ADDR_CYCL_ROW,
141 NAND_ADDR_CYCL_COL,
142 NAND_ADDR_CYCL_BOTH,
143};
144
145static struct arasan_nand_command_format arasan_nand_commands[] = {
146 {NAND_CMD_READ0, NAND_CMD_READSTART, NAND_ADDR_CYCL_BOTH,
147 ARASAN_PROG_RD_MASK},
148 {NAND_CMD_RNDOUT, NAND_CMD_RNDOUTSTART, NAND_ADDR_CYCL_COL,
149 ARASAN_PROG_RD_MASK},
150 {NAND_CMD_READID, NAND_CMD_NONE, NAND_ADDR_CYCL_ONE,
151 ARASAN_PROG_RD_ID_MASK},
152 {NAND_CMD_STATUS, NAND_CMD_NONE, NAND_ADDR_CYCL_NONE,
153 ARASAN_PROG_RD_STS_MASK},
154 {NAND_CMD_SEQIN, NAND_CMD_PAGEPROG, NAND_ADDR_CYCL_BOTH,
155 ARASAN_PROG_PG_PROG_MASK},
156 {NAND_CMD_RNDIN, NAND_CMD_NONE, NAND_ADDR_CYCL_COL,
157 ARASAN_PROG_CHNG_ROWADR_END_MASK},
158 {NAND_CMD_ERASE1, NAND_CMD_ERASE2, NAND_ADDR_CYCL_ROW,
159 ARASAN_PROG_BLK_ERS_MASK},
160 {NAND_CMD_RESET, NAND_CMD_NONE, NAND_ADDR_CYCL_NONE,
161 ARASAN_PROG_RST_MASK},
162 {NAND_CMD_PARAM, NAND_CMD_NONE, NAND_ADDR_CYCL_ONE,
163 ARASAN_PROG_RD_PARAM_PG_MASK},
164 {NAND_CMD_GET_FEATURES, NAND_CMD_NONE, NAND_ADDR_CYCL_ONE,
165 ARASAN_PROG_GET_FTRS_MASK},
166 {NAND_CMD_SET_FEATURES, NAND_CMD_NONE, NAND_ADDR_CYCL_ONE,
167 ARASAN_PROG_SET_FTRS_MASK},
168 {NAND_CMD_NONE, NAND_CMD_NONE, NAND_ADDR_CYCL_NONE, 0},
169};
170
171struct arasan_ecc_matrix {
172 u32 pagesize;
173 u32 ecc_codeword_size;
174 u8 eccbits;
175 u8 bch;
176 u8 bchval;
177 u16 eccaddr;
178 u16 eccsize;
179};
180
181static const struct arasan_ecc_matrix ecc_matrix[] = {
182 {512, 512, 1, 0, 0, 0x20D, 0x3},
183 {512, 512, 4, 1, 3, 0x209, 0x7},
184 {512, 512, 8, 1, 2, 0x203, 0xD},
185 /*
186 * 2K byte page
187 */
188 {2048, 512, 1, 0, 0, 0x834, 0xC},
189 {2048, 512, 4, 1, 3, 0x826, 0x1A},
190 {2048, 512, 8, 1, 2, 0x80c, 0x34},
191 {2048, 512, 12, 1, 1, 0x822, 0x4E},
192 {2048, 512, 16, 1, 0, 0x808, 0x68},
193 {2048, 1024, 24, 1, 4, 0x81c, 0x54},
194 /*
195 * 4K byte page
196 */
197 {4096, 512, 1, 0, 0, 0x1068, 0x18},
198 {4096, 512, 4, 1, 3, 0x104c, 0x34},
199 {4096, 512, 8, 1, 2, 0x1018, 0x68},
200 {4096, 512, 12, 1, 1, 0x1044, 0x9C},
201 {4096, 512, 16, 1, 0, 0x1010, 0xD0},
202 {4096, 1024, 24, 1, 4, 0x1038, 0xA8},
203 /*
204 * 8K byte page
205 */
206 {8192, 512, 1, 0, 0, 0x20d0, 0x30},
207 {8192, 512, 4, 1, 3, 0x2098, 0x68},
208 {8192, 512, 8, 1, 2, 0x2030, 0xD0},
209 {8192, 512, 12, 1, 1, 0x2088, 0x138},
210 {8192, 512, 16, 1, 0, 0x2020, 0x1A0},
211 {8192, 1024, 24, 1, 4, 0x2070, 0x150},
212 /*
213 * 16K byte page
214 */
215 {16384, 512, 1, 0, 0, 0x4460, 0x60},
216 {16384, 512, 4, 1, 3, 0x43f0, 0xD0},
217 {16384, 512, 8, 1, 2, 0x4320, 0x1A0},
218 {16384, 512, 12, 1, 1, 0x4250, 0x270},
219 {16384, 512, 16, 1, 0, 0x4180, 0x340},
220 {16384, 1024, 24, 1, 4, 0x4220, 0x2A0}
221};
222
cacb8a02
SDPP
223static struct nand_ecclayout ondie_nand_oob_64 = {
224 .eccbytes = 32,
225
226 .eccpos = {
227 8, 9, 10, 11, 12, 13, 14, 15,
228 24, 25, 26, 27, 28, 29, 30, 31,
229 40, 41, 42, 43, 44, 45, 46, 47,
230 56, 57, 58, 59, 60, 61, 62, 63
231 },
232
233 .oobfree = {
234 { .offset = 4, .length = 4 },
235 { .offset = 20, .length = 4 },
236 { .offset = 36, .length = 4 },
237 { .offset = 52, .length = 4 }
238 }
239};
240
241/*
242 * bbt decriptors for chips with on-die ECC and
243 * chips with 64-byte OOB
244 */
245static u8 bbt_pattern[] = {'B', 'b', 't', '0' };
246static u8 mirror_pattern[] = {'1', 't', 'b', 'B' };
247
248static struct nand_bbt_descr bbt_main_descr = {
249 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
250 NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
251 .offs = 4,
252 .len = 4,
253 .veroffs = 20,
254 .maxblocks = 4,
255 .pattern = bbt_pattern
256};
257
258static struct nand_bbt_descr bbt_mirror_descr = {
259 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
260 NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
261 .offs = 4,
262 .len = 4,
263 .veroffs = 20,
264 .maxblocks = 4,
265 .pattern = mirror_pattern
266};
267
e4b40e92
SDPP
268static u8 buf_data[READ_BUFF_SIZE];
269static u32 buf_index;
270
271static struct nand_ecclayout nand_oob;
272
e4b40e92
SDPP
273static void arasan_nand_select_chip(struct mtd_info *mtd, int chip)
274{
3dd0f8cc
ARS
275 struct nand_chip *nand_chip = mtd_to_nand(mtd);
276 struct nand_drv *info = nand_get_controller_data(nand_chip);
97fca6a1
KR
277 u32 reg_val;
278
3dd0f8cc 279 reg_val = readl(&info->reg->memadr_reg2);
97fca6a1
KR
280 if (chip == 0) {
281 reg_val &= ~ARASAN_NAND_MEM_ADDR2_CS0_MASK;
3dd0f8cc 282 writel(reg_val, &info->reg->memadr_reg2);
97fca6a1
KR
283 } else if (chip == 1) {
284 reg_val |= ARASAN_NAND_MEM_ADDR2_CS1_MASK;
3dd0f8cc 285 writel(reg_val, &info->reg->memadr_reg2);
97fca6a1 286 }
e4b40e92
SDPP
287}
288
3dd0f8cc 289static void arasan_nand_enable_ecc(struct mtd_info *mtd)
e4b40e92 290{
3dd0f8cc
ARS
291 struct nand_chip *chip = mtd_to_nand(mtd);
292 struct nand_drv *info = nand_get_controller_data(chip);
e4b40e92
SDPP
293 u32 reg_val;
294
3dd0f8cc 295 reg_val = readl(&info->reg->cmd_reg);
e4b40e92
SDPP
296 reg_val |= ARASAN_NAND_CMD_ECC_ON_MASK;
297
3dd0f8cc 298 writel(reg_val, &info->reg->cmd_reg);
e4b40e92
SDPP
299}
300
301static u8 arasan_nand_get_addrcycle(struct mtd_info *mtd)
302{
303 u8 addrcycles;
17cb4b8f 304 struct nand_chip *chip = mtd_to_nand(mtd);
e4b40e92
SDPP
305
306 switch (curr_cmd->addr_cycles) {
307 case NAND_ADDR_CYCL_NONE:
308 addrcycles = 0;
309 break;
310 case NAND_ADDR_CYCL_ONE:
311 addrcycles = 1;
312 break;
313 case NAND_ADDR_CYCL_ROW:
314 addrcycles = chip->onfi_params.addr_cycles &
315 ARASAN_NAND_ROW_ADDR_CYCL_MASK;
316 break;
317 case NAND_ADDR_CYCL_COL:
318 addrcycles = (chip->onfi_params.addr_cycles &
319 ARASAN_NAND_COL_ADDR_CYCL_MASK) >>
320 ARASAN_NAND_COL_ADDR_CYCL_SHIFT;
321 break;
322 case NAND_ADDR_CYCL_BOTH:
323 addrcycles = chip->onfi_params.addr_cycles &
324 ARASAN_NAND_ROW_ADDR_CYCL_MASK;
325 addrcycles += (chip->onfi_params.addr_cycles &
326 ARASAN_NAND_COL_ADDR_CYCL_MASK) >>
327 ARASAN_NAND_COL_ADDR_CYCL_SHIFT;
328 break;
329 default:
330 addrcycles = ARASAN_NAND_INVALID_ADDR_CYCL;
331 break;
332 }
333 return addrcycles;
334}
335
336static int arasan_nand_read_page(struct mtd_info *mtd, u8 *buf, u32 size)
337{
17cb4b8f 338 struct nand_chip *chip = mtd_to_nand(mtd);
3dd0f8cc
ARS
339 struct nand_drv *info = nand_get_controller_data(chip);
340 struct nand_config *nand = &info->config;
e4b40e92
SDPP
341 u32 reg_val, i, pktsize, pktnum;
342 u32 *bufptr = (u32 *)buf;
343 u32 timeout;
344 u32 rdcount = 0;
345 u8 addr_cycles;
346
347 if (chip->ecc_step_ds >= ARASAN_NAND_PKTSIZE_1K)
348 pktsize = ARASAN_NAND_PKTSIZE_1K;
349 else
350 pktsize = ARASAN_NAND_PKTSIZE_512;
351
352 if (size % pktsize)
353 pktnum = size/pktsize + 1;
354 else
355 pktnum = size/pktsize;
356
3dd0f8cc 357 reg_val = readl(&info->reg->intsts_enr);
e4b40e92
SDPP
358 reg_val |= ARASAN_NAND_INT_STS_ERR_EN_MASK |
359 ARASAN_NAND_INT_STS_MUL_BIT_ERR_MASK;
3dd0f8cc 360 writel(reg_val, &info->reg->intsts_enr);
e4b40e92 361
3dd0f8cc 362 reg_val = readl(&info->reg->pkt_reg);
e4b40e92
SDPP
363 reg_val &= ~(ARASAN_NAND_PKT_REG_PKT_CNT_MASK |
364 ARASAN_NAND_PKT_REG_PKT_SIZE_MASK);
365 reg_val |= (pktnum << ARASAN_NAND_PKT_REG_PKT_CNT_SHFT) |
366 pktsize;
3dd0f8cc 367 writel(reg_val, &info->reg->pkt_reg);
e4b40e92 368
cacb8a02 369 if (!nand->on_die_ecc_enabled) {
3dd0f8cc 370 arasan_nand_enable_ecc(mtd);
cacb8a02
SDPP
371 addr_cycles = arasan_nand_get_addrcycle(mtd);
372 if (addr_cycles == ARASAN_NAND_INVALID_ADDR_CYCL)
373 return ERR_ADDR_CYCLE;
e4b40e92 374
cacb8a02
SDPP
375 writel((NAND_CMD_RNDOUTSTART << ARASAN_NAND_CMD_CMD2_SHIFT) |
376 NAND_CMD_RNDOUT | (addr_cycles <<
377 ARASAN_NAND_CMD_ADDR_CYCL_SHIFT),
3dd0f8cc 378 &info->reg->ecc_sprcmd_reg);
cacb8a02 379 }
3dd0f8cc 380 writel(curr_cmd->pgm, &info->reg->pgm_reg);
e4b40e92
SDPP
381
382 while (rdcount < pktnum) {
383 timeout = ARASAN_NAND_POLL_TIMEOUT;
3dd0f8cc 384 while (!(readl(&info->reg->intsts_reg) &
e4b40e92
SDPP
385 ARASAN_NAND_INT_STS_BUF_RD_RDY_MASK) && timeout) {
386 udelay(1);
387 timeout--;
388 }
389 if (!timeout) {
390 puts("arasan_read_page: timedout:Buff RDY\n");
391 return -ETIMEDOUT;
392 }
393
394 rdcount++;
395
396 if (pktnum == rdcount) {
3dd0f8cc 397 reg_val = readl(&info->reg->intsts_enr);
e4b40e92 398 reg_val |= ARASAN_NAND_INT_STS_XFR_CMPLT_MASK;
3dd0f8cc 399 writel(reg_val, &info->reg->intsts_enr);
e4b40e92 400 } else {
3dd0f8cc 401 reg_val = readl(&info->reg->intsts_enr);
e4b40e92 402 writel(reg_val | ARASAN_NAND_INT_STS_BUF_RD_RDY_MASK,
3dd0f8cc 403 &info->reg->intsts_enr);
e4b40e92 404 }
3dd0f8cc 405 reg_val = readl(&info->reg->intsts_reg);
e4b40e92 406 writel(reg_val | ARASAN_NAND_INT_STS_BUF_RD_RDY_MASK,
3dd0f8cc 407 &info->reg->intsts_reg);
e4b40e92
SDPP
408
409 for (i = 0; i < pktsize/4; i++)
3dd0f8cc 410 bufptr[i] = readl(&info->reg->buf_dataport);
e4b40e92
SDPP
411
412
413 bufptr += pktsize/4;
414
415 if (rdcount >= pktnum)
416 break;
417
418 writel(ARASAN_NAND_INT_STS_BUF_RD_RDY_MASK,
3dd0f8cc 419 &info->reg->intsts_enr);
e4b40e92
SDPP
420 }
421
422 timeout = ARASAN_NAND_POLL_TIMEOUT;
423
3dd0f8cc 424 while (!(readl(&info->reg->intsts_reg) &
e4b40e92
SDPP
425 ARASAN_NAND_INT_STS_XFR_CMPLT_MASK) && timeout) {
426 udelay(1);
427 timeout--;
428 }
429 if (!timeout) {
430 puts("arasan rd_page timedout:Xfer CMPLT\n");
431 return -ETIMEDOUT;
432 }
433
3dd0f8cc 434 reg_val = readl(&info->reg->intsts_enr);
e4b40e92 435 writel(reg_val | ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
3dd0f8cc
ARS
436 &info->reg->intsts_enr);
437 reg_val = readl(&info->reg->intsts_reg);
e4b40e92 438 writel(reg_val | ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
3dd0f8cc 439 &info->reg->intsts_reg);
e4b40e92 440
cacb8a02 441 if (!nand->on_die_ecc_enabled) {
3dd0f8cc 442 if (readl(&info->reg->intsts_reg) &
cacb8a02
SDPP
443 ARASAN_NAND_INT_STS_MUL_BIT_ERR_MASK) {
444 printf("arasan rd_page:sbiterror\n");
445 return -1;
446 }
e4b40e92 447
3dd0f8cc 448 if (readl(&info->reg->intsts_reg) &
cacb8a02
SDPP
449 ARASAN_NAND_INT_STS_ERR_EN_MASK) {
450 mtd->ecc_stats.failed++;
451 printf("arasan rd_page:multibiterror\n");
452 return -1;
453 }
e4b40e92
SDPP
454 }
455
456 return 0;
457}
458
459static int arasan_nand_read_page_hwecc(struct mtd_info *mtd,
460 struct nand_chip *chip, u8 *buf, int oob_required, int page)
461{
462 int status;
463
464 status = arasan_nand_read_page(mtd, buf, (mtd->writesize));
465
466 if (oob_required)
467 chip->ecc.read_oob(mtd, chip, page);
468
469 return status;
470}
471
3dd0f8cc 472static void arasan_nand_fill_tx(struct mtd_info *mtd, const u8 *buf, int len)
e4b40e92 473{
3dd0f8cc
ARS
474 struct nand_chip *chip = mtd_to_nand(mtd);
475 struct nand_drv *info = nand_get_controller_data(chip);
476 u32 __iomem *nand = &info->reg->buf_dataport;
e4b40e92
SDPP
477
478 if (((unsigned long)buf & 0x3) != 0) {
479 if (((unsigned long)buf & 0x1) != 0) {
480 if (len) {
481 writeb(*buf, nand);
482 buf += 1;
483 len--;
484 }
485 }
486
487 if (((unsigned long)buf & 0x3) != 0) {
488 if (len >= 2) {
489 writew(*(u16 *)buf, nand);
490 buf += 2;
491 len -= 2;
492 }
493 }
494 }
495
496 while (len >= 4) {
497 writel(*(u32 *)buf, nand);
498 buf += 4;
499 len -= 4;
500 }
501
502 if (len) {
503 if (len >= 2) {
504 writew(*(u16 *)buf, nand);
505 buf += 2;
506 len -= 2;
507 }
508
509 if (len)
510 writeb(*buf, nand);
511 }
512}
513
514static int arasan_nand_write_page_hwecc(struct mtd_info *mtd,
81c77252
SW
515 struct nand_chip *chip, const u8 *buf, int oob_required,
516 int page)
e4b40e92 517{
3dd0f8cc
ARS
518 struct nand_drv *info = nand_get_controller_data(chip);
519 struct nand_config *nand = &info->config;
e4b40e92
SDPP
520 u32 reg_val, i, pktsize, pktnum;
521 const u32 *bufptr = (const u32 *)buf;
522 u32 timeout = ARASAN_NAND_POLL_TIMEOUT;
523 u32 size = mtd->writesize;
524 u32 rdcount = 0;
525 u8 column_addr_cycles;
e4b40e92
SDPP
526
527 if (chip->ecc_step_ds >= ARASAN_NAND_PKTSIZE_1K)
528 pktsize = ARASAN_NAND_PKTSIZE_1K;
529 else
530 pktsize = ARASAN_NAND_PKTSIZE_512;
531
532 if (size % pktsize)
533 pktnum = size/pktsize + 1;
534 else
535 pktnum = size/pktsize;
536
3dd0f8cc 537 reg_val = readl(&info->reg->pkt_reg);
e4b40e92
SDPP
538 reg_val &= ~(ARASAN_NAND_PKT_REG_PKT_CNT_MASK |
539 ARASAN_NAND_PKT_REG_PKT_SIZE_MASK);
540 reg_val |= (pktnum << ARASAN_NAND_PKT_REG_PKT_CNT_SHFT) | pktsize;
3dd0f8cc 541 writel(reg_val, &info->reg->pkt_reg);
e4b40e92 542
cacb8a02 543 if (!nand->on_die_ecc_enabled) {
3dd0f8cc 544 arasan_nand_enable_ecc(mtd);
cacb8a02
SDPP
545 column_addr_cycles = (chip->onfi_params.addr_cycles &
546 ARASAN_NAND_COL_ADDR_CYCL_MASK) >>
547 ARASAN_NAND_COL_ADDR_CYCL_SHIFT;
548 writel((NAND_CMD_RNDIN | (column_addr_cycles << 28)),
3dd0f8cc 549 &info->reg->ecc_sprcmd_reg);
cacb8a02 550 }
3dd0f8cc 551 writel(curr_cmd->pgm, &info->reg->pgm_reg);
e4b40e92
SDPP
552
553 while (rdcount < pktnum) {
554 timeout = ARASAN_NAND_POLL_TIMEOUT;
3dd0f8cc 555 while (!(readl(&info->reg->intsts_reg) &
e4b40e92
SDPP
556 ARASAN_NAND_INT_STS_BUF_WR_RDY_MASK) && timeout) {
557 udelay(1);
558 timeout--;
559 }
560
561 if (!timeout) {
562 puts("arasan_write_page: timedout:Buff RDY\n");
563 return -ETIMEDOUT;
564 }
565
566 rdcount++;
567
568 if (pktnum == rdcount) {
3dd0f8cc 569 reg_val = readl(&info->reg->intsts_enr);
e4b40e92 570 reg_val |= ARASAN_NAND_INT_STS_XFR_CMPLT_MASK;
3dd0f8cc 571 writel(reg_val, &info->reg->intsts_enr);
e4b40e92 572 } else {
3dd0f8cc 573 reg_val = readl(&info->reg->intsts_enr);
e4b40e92 574 writel(reg_val | ARASAN_NAND_INT_STS_BUF_WR_RDY_MASK,
3dd0f8cc 575 &info->reg->intsts_enr);
e4b40e92
SDPP
576 }
577
3dd0f8cc 578 reg_val = readl(&info->reg->intsts_reg);
e4b40e92 579 writel(reg_val | ARASAN_NAND_INT_STS_BUF_WR_RDY_MASK,
3dd0f8cc 580 &info->reg->intsts_reg);
e4b40e92
SDPP
581
582 for (i = 0; i < pktsize/4; i++)
3dd0f8cc 583 writel(bufptr[i], &info->reg->buf_dataport);
e4b40e92
SDPP
584
585 bufptr += pktsize/4;
586
587 if (rdcount >= pktnum)
588 break;
589
590 writel(ARASAN_NAND_INT_STS_BUF_WR_RDY_MASK,
3dd0f8cc 591 &info->reg->intsts_enr);
e4b40e92
SDPP
592 }
593
594 timeout = ARASAN_NAND_POLL_TIMEOUT;
595
3dd0f8cc 596 while (!(readl(&info->reg->intsts_reg) &
e4b40e92
SDPP
597 ARASAN_NAND_INT_STS_XFR_CMPLT_MASK) && timeout) {
598 udelay(1);
599 timeout--;
600 }
601 if (!timeout) {
602 puts("arasan write_page timedout:Xfer CMPLT\n");
603 return -ETIMEDOUT;
604 }
605
3dd0f8cc 606 reg_val = readl(&info->reg->intsts_enr);
e4b40e92 607 writel(reg_val | ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
3dd0f8cc
ARS
608 &info->reg->intsts_enr);
609 reg_val = readl(&info->reg->intsts_reg);
e4b40e92 610 writel(reg_val | ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
3dd0f8cc 611 &info->reg->intsts_reg);
e4b40e92
SDPP
612
613 if (oob_required)
614 chip->ecc.write_oob(mtd, chip, nand->page);
615
616 return 0;
617}
618
619static int arasan_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
620 int page)
621{
622 chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
623 chip->read_buf(mtd, chip->oob_poi, (mtd->oobsize));
624
625 return 0;
626}
627
628static int arasan_nand_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
629 int page)
630{
631 int status = 0;
632 const u8 *buf = chip->oob_poi;
633
634 chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page);
635 chip->write_buf(mtd, buf, mtd->oobsize);
636
637 return status;
638}
639
3dd0f8cc
ARS
640static int arasan_nand_reset(struct mtd_info *mtd,
641 struct arasan_nand_command_format *curr_cmd)
e4b40e92 642{
3dd0f8cc
ARS
643 struct nand_chip *chip = mtd_to_nand(mtd);
644 struct nand_drv *info = nand_get_controller_data(chip);
e4b40e92
SDPP
645 u32 timeout = ARASAN_NAND_POLL_TIMEOUT;
646 u32 cmd_reg = 0;
647
648 writel(ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
3dd0f8cc
ARS
649 &info->reg->intsts_enr);
650 cmd_reg = readl(&info->reg->cmd_reg);
e4b40e92
SDPP
651 cmd_reg &= ~ARASAN_NAND_CMD_CMD12_MASK;
652
653 cmd_reg |= curr_cmd->cmd1 |
654 (curr_cmd->cmd2 << ARASAN_NAND_CMD_CMD2_SHIFT);
3dd0f8cc
ARS
655 writel(cmd_reg, &info->reg->cmd_reg);
656 writel(curr_cmd->pgm, &info->reg->pgm_reg);
e4b40e92 657
3dd0f8cc 658 while (!(readl(&info->reg->intsts_reg) &
e4b40e92
SDPP
659 ARASAN_NAND_INT_STS_XFR_CMPLT_MASK) && timeout) {
660 udelay(1);
661 timeout--;
662 }
663 if (!timeout) {
664 printf("ERROR:%s timedout\n", __func__);
665 return -ETIMEDOUT;
666 }
667
668 writel(ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
3dd0f8cc 669 &info->reg->intsts_enr);
e4b40e92
SDPP
670
671 writel(ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
3dd0f8cc 672 &info->reg->intsts_reg);
e4b40e92
SDPP
673
674 return 0;
675}
676
677static u8 arasan_nand_page(struct mtd_info *mtd)
678{
679 u8 page_val = 0;
680
681 switch (mtd->writesize) {
682 case 512:
683 page_val = 0;
684 break;
685 case 2048:
686 page_val = 1;
687 break;
688 case 4096:
689 page_val = 2;
690 break;
691 case 8192:
692 page_val = 3;
693 break;
694 case 16384:
695 page_val = 4;
696 break;
697 case 1024:
698 page_val = 5;
699 break;
700 default:
701 printf("%s:Pagesize>16K\n", __func__);
702 break;
703 }
704
705 return page_val;
706}
707
708static int arasan_nand_send_wrcmd(struct arasan_nand_command_format *curr_cmd,
709 int column, int page_addr, struct mtd_info *mtd)
710{
3dd0f8cc
ARS
711 struct nand_chip *chip = mtd_to_nand(mtd);
712 struct nand_drv *info = nand_get_controller_data(chip);
e4b40e92
SDPP
713 u32 reg_val, page;
714 u8 page_val, addr_cycles;
715
716 writel(ARASAN_NAND_INT_STS_BUF_WR_RDY_MASK,
3dd0f8cc
ARS
717 &info->reg->intsts_enr);
718 reg_val = readl(&info->reg->cmd_reg);
e4b40e92
SDPP
719 reg_val &= ~ARASAN_NAND_CMD_CMD12_MASK;
720 reg_val |= curr_cmd->cmd1 |
721 (curr_cmd->cmd2 << ARASAN_NAND_CMD_CMD2_SHIFT);
722 if (curr_cmd->cmd1 == NAND_CMD_SEQIN) {
723 reg_val &= ~ARASAN_NAND_CMD_PG_SIZE_MASK;
724 page_val = arasan_nand_page(mtd);
725 reg_val |= (page_val << ARASAN_NAND_CMD_PG_SIZE_SHIFT);
726 }
727
728 reg_val &= ~ARASAN_NAND_CMD_ADDR_CYCL_MASK;
729 addr_cycles = arasan_nand_get_addrcycle(mtd);
730
731 if (addr_cycles == ARASAN_NAND_INVALID_ADDR_CYCL)
732 return ERR_ADDR_CYCLE;
733
734 reg_val |= (addr_cycles <<
735 ARASAN_NAND_CMD_ADDR_CYCL_SHIFT);
3dd0f8cc 736 writel(reg_val, &info->reg->cmd_reg);
e4b40e92
SDPP
737
738 if (page_addr == -1)
739 page_addr = 0;
740
741 page = (page_addr << ARASAN_NAND_MEM_ADDR1_PAGE_SHIFT) &
742 ARASAN_NAND_MEM_ADDR1_PAGE_MASK;
743 column &= ARASAN_NAND_MEM_ADDR1_COL_MASK;
3dd0f8cc 744 writel(page | column, &info->reg->memadr_reg1);
e4b40e92 745
3dd0f8cc 746 reg_val = readl(&info->reg->memadr_reg2);
e4b40e92
SDPP
747 reg_val &= ~ARASAN_NAND_MEM_ADDR2_PAGE_MASK;
748 reg_val |= (page_addr >> ARASAN_NAND_MEM_ADDR1_PAGE_SHIFT);
3dd0f8cc 749 writel(reg_val, &info->reg->memadr_reg2);
e4b40e92
SDPP
750
751 return 0;
752}
753
754static void arasan_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
755{
3dd0f8cc
ARS
756 struct nand_chip *chip = mtd_to_nand(mtd);
757 struct nand_drv *info = nand_get_controller_data(chip);
e4b40e92
SDPP
758 u32 reg_val;
759 u32 timeout = ARASAN_NAND_POLL_TIMEOUT;
760
3dd0f8cc 761 reg_val = readl(&info->reg->pkt_reg);
e4b40e92
SDPP
762 reg_val &= ~(ARASAN_NAND_PKT_REG_PKT_CNT_MASK |
763 ARASAN_NAND_PKT_REG_PKT_SIZE_MASK);
764
765 reg_val |= (1 << ARASAN_NAND_PKT_REG_PKT_CNT_SHFT) | len;
3dd0f8cc
ARS
766 writel(reg_val, &info->reg->pkt_reg);
767 writel(curr_cmd->pgm, &info->reg->pgm_reg);
e4b40e92 768
3dd0f8cc 769 while (!(readl(&info->reg->intsts_reg) &
e4b40e92
SDPP
770 ARASAN_NAND_INT_STS_BUF_WR_RDY_MASK) && timeout) {
771 udelay(1);
772 timeout--;
773 }
774
775 if (!timeout)
776 puts("ERROR:arasan_nand_write_buf timedout:Buff RDY\n");
777
3dd0f8cc 778 reg_val = readl(&info->reg->intsts_enr);
e4b40e92 779 reg_val |= ARASAN_NAND_INT_STS_XFR_CMPLT_MASK;
3dd0f8cc 780 writel(reg_val, &info->reg->intsts_enr);
e4b40e92 781 writel(reg_val | ARASAN_NAND_INT_STS_BUF_WR_RDY_MASK,
3dd0f8cc
ARS
782 &info->reg->intsts_enr);
783 reg_val = readl(&info->reg->intsts_reg);
e4b40e92 784 writel(reg_val | ARASAN_NAND_INT_STS_BUF_WR_RDY_MASK,
3dd0f8cc 785 &info->reg->intsts_reg);
e4b40e92 786
3dd0f8cc 787 arasan_nand_fill_tx(mtd, buf, len);
e4b40e92
SDPP
788
789 timeout = ARASAN_NAND_POLL_TIMEOUT;
3dd0f8cc 790 while (!(readl(&info->reg->intsts_reg) &
e4b40e92
SDPP
791 ARASAN_NAND_INT_STS_XFR_CMPLT_MASK) && timeout) {
792 udelay(1);
793 timeout--;
794 }
795 if (!timeout)
796 puts("ERROR:arasan_nand_write_buf timedout:Xfer CMPLT\n");
797
3dd0f8cc 798 writel(readl(&info->reg->intsts_enr) |
e4b40e92 799 ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
3dd0f8cc
ARS
800 &info->reg->intsts_enr);
801 writel(readl(&info->reg->intsts_reg) |
e4b40e92 802 ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
3dd0f8cc 803 &info->reg->intsts_reg);
e4b40e92
SDPP
804}
805
806static int arasan_nand_erase(struct arasan_nand_command_format *curr_cmd,
807 int column, int page_addr, struct mtd_info *mtd)
808{
3dd0f8cc
ARS
809 struct nand_chip *chip = mtd_to_nand(mtd);
810 struct nand_drv *info = nand_get_controller_data(chip);
e4b40e92
SDPP
811 u32 reg_val, page;
812 u32 timeout = ARASAN_NAND_POLL_TIMEOUT;
813 u8 row_addr_cycles;
814
815 writel(ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
3dd0f8cc
ARS
816 &info->reg->intsts_enr);
817 reg_val = readl(&info->reg->cmd_reg);
e4b40e92
SDPP
818 reg_val &= ~ARASAN_NAND_CMD_CMD12_MASK;
819 reg_val |= curr_cmd->cmd1 |
820 (curr_cmd->cmd2 << ARASAN_NAND_CMD_CMD2_SHIFT);
821 row_addr_cycles = arasan_nand_get_addrcycle(mtd);
822
823 if (row_addr_cycles == ARASAN_NAND_INVALID_ADDR_CYCL)
824 return ERR_ADDR_CYCLE;
825
826 reg_val &= ~ARASAN_NAND_CMD_ADDR_CYCL_MASK;
827 reg_val |= (row_addr_cycles <<
828 ARASAN_NAND_CMD_ADDR_CYCL_SHIFT);
829
3dd0f8cc 830 writel(reg_val, &info->reg->cmd_reg);
e4b40e92 831
2453c695 832 page = (page_addr >> ARASAN_NAND_MEM_ADDR1_PAGE_SHIFT) &
6fbbe2d8 833 ARASAN_NAND_MEM_ADDR1_COL_MASK;
e4b40e92 834 column = page_addr & ARASAN_NAND_MEM_ADDR1_COL_MASK;
2453c695 835 writel(column | (page << ARASAN_NAND_MEM_ADDR1_PAGE_SHIFT),
3dd0f8cc 836 &info->reg->memadr_reg1);
e4b40e92 837
3dd0f8cc 838 reg_val = readl(&info->reg->memadr_reg2);
e4b40e92
SDPP
839 reg_val &= ~ARASAN_NAND_MEM_ADDR2_PAGE_MASK;
840 reg_val |= (page_addr >> ARASAN_NAND_MEM_ADDR1_PAGE_SHIFT);
3dd0f8cc
ARS
841 writel(reg_val, &info->reg->memadr_reg2);
842 writel(curr_cmd->pgm, &info->reg->pgm_reg);
e4b40e92 843
3dd0f8cc 844 while (!(readl(&info->reg->intsts_reg) &
e4b40e92
SDPP
845 ARASAN_NAND_INT_STS_XFR_CMPLT_MASK) && timeout) {
846 udelay(1);
847 timeout--;
848 }
849 if (!timeout) {
850 printf("ERROR:%s timedout:Xfer CMPLT\n", __func__);
851 return -ETIMEDOUT;
852 }
853
3dd0f8cc 854 reg_val = readl(&info->reg->intsts_enr);
e4b40e92 855 writel(reg_val | ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
3dd0f8cc
ARS
856 &info->reg->intsts_enr);
857 reg_val = readl(&info->reg->intsts_reg);
e4b40e92 858 writel(reg_val | ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
3dd0f8cc 859 &info->reg->intsts_reg);
e4b40e92
SDPP
860
861 return 0;
862}
863
864static int arasan_nand_read_status(struct arasan_nand_command_format *curr_cmd,
865 int column, int page_addr, struct mtd_info *mtd)
866{
3dd0f8cc
ARS
867 struct nand_chip *chip = mtd_to_nand(mtd);
868 struct nand_drv *info = nand_get_controller_data(chip);
e4b40e92
SDPP
869 u32 reg_val;
870 u32 timeout = ARASAN_NAND_POLL_TIMEOUT;
871 u8 addr_cycles;
872
873 writel(ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
3dd0f8cc
ARS
874 &info->reg->intsts_enr);
875 reg_val = readl(&info->reg->cmd_reg);
e4b40e92
SDPP
876 reg_val &= ~ARASAN_NAND_CMD_CMD12_MASK;
877 reg_val |= curr_cmd->cmd1 |
878 (curr_cmd->cmd2 << ARASAN_NAND_CMD_CMD2_SHIFT);
879 addr_cycles = arasan_nand_get_addrcycle(mtd);
880
881 if (addr_cycles == ARASAN_NAND_INVALID_ADDR_CYCL)
882 return ERR_ADDR_CYCLE;
883
884 reg_val &= ~ARASAN_NAND_CMD_ADDR_CYCL_MASK;
885 reg_val |= (addr_cycles <<
886 ARASAN_NAND_CMD_ADDR_CYCL_SHIFT);
887
3dd0f8cc 888 writel(reg_val, &info->reg->cmd_reg);
e4b40e92 889
3dd0f8cc 890 reg_val = readl(&info->reg->pkt_reg);
e4b40e92
SDPP
891 reg_val &= ~(ARASAN_NAND_PKT_REG_PKT_CNT_MASK |
892 ARASAN_NAND_PKT_REG_PKT_SIZE_MASK);
893 reg_val |= (1 << ARASAN_NAND_PKT_REG_PKT_CNT_SHFT) | 1;
3dd0f8cc 894 writel(reg_val, &info->reg->pkt_reg);
e4b40e92 895
3dd0f8cc
ARS
896 writel(curr_cmd->pgm, &info->reg->pgm_reg);
897 while (!(readl(&info->reg->intsts_reg) &
e4b40e92
SDPP
898 ARASAN_NAND_INT_STS_XFR_CMPLT_MASK) && timeout) {
899 udelay(1);
900 timeout--;
901 }
902
903 if (!timeout) {
904 printf("ERROR:%s: timedout:Xfer CMPLT\n", __func__);
905 return -ETIMEDOUT;
906 }
907
3dd0f8cc 908 reg_val = readl(&info->reg->intsts_enr);
e4b40e92 909 writel(reg_val | ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
3dd0f8cc
ARS
910 &info->reg->intsts_enr);
911 reg_val = readl(&info->reg->intsts_reg);
e4b40e92 912 writel(reg_val | ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
3dd0f8cc 913 &info->reg->intsts_reg);
e4b40e92
SDPP
914
915 return 0;
916}
917
918static int arasan_nand_send_rdcmd(struct arasan_nand_command_format *curr_cmd,
919 int column, int page_addr, struct mtd_info *mtd)
920{
3dd0f8cc
ARS
921 struct nand_chip *chip = mtd_to_nand(mtd);
922 struct nand_drv *info = nand_get_controller_data(chip);
e4b40e92
SDPP
923 u32 reg_val, addr_cycles, page;
924 u8 page_val;
925
3dd0f8cc 926 reg_val = readl(&info->reg->intsts_enr);
e4b40e92 927 writel(reg_val | ARASAN_NAND_INT_STS_BUF_RD_RDY_MASK,
3dd0f8cc 928 &info->reg->intsts_enr);
e4b40e92 929
3dd0f8cc 930 reg_val = readl(&info->reg->cmd_reg);
e4b40e92
SDPP
931 reg_val &= ~ARASAN_NAND_CMD_CMD12_MASK;
932 reg_val |= curr_cmd->cmd1 |
933 (curr_cmd->cmd2 << ARASAN_NAND_CMD_CMD2_SHIFT);
934
935 if (curr_cmd->cmd1 == NAND_CMD_RNDOUT ||
936 curr_cmd->cmd1 == NAND_CMD_READ0) {
937 reg_val &= ~ARASAN_NAND_CMD_PG_SIZE_MASK;
938 page_val = arasan_nand_page(mtd);
939 reg_val |= (page_val << ARASAN_NAND_CMD_PG_SIZE_SHIFT);
940 }
941
02bcff2c
SDPP
942 reg_val &= ~ARASAN_NAND_CMD_ECC_ON_MASK;
943
e4b40e92
SDPP
944 reg_val &= ~ARASAN_NAND_CMD_ADDR_CYCL_MASK;
945
946 addr_cycles = arasan_nand_get_addrcycle(mtd);
947
948 if (addr_cycles == ARASAN_NAND_INVALID_ADDR_CYCL)
949 return ERR_ADDR_CYCLE;
950
951 reg_val |= (addr_cycles << 28);
3dd0f8cc 952 writel(reg_val, &info->reg->cmd_reg);
e4b40e92
SDPP
953
954 if (page_addr == -1)
955 page_addr = 0;
956
957 page = (page_addr << ARASAN_NAND_MEM_ADDR1_PAGE_SHIFT) &
958 ARASAN_NAND_MEM_ADDR1_PAGE_MASK;
959 column &= ARASAN_NAND_MEM_ADDR1_COL_MASK;
3dd0f8cc 960 writel(page | column, &info->reg->memadr_reg1);
e4b40e92 961
3dd0f8cc 962 reg_val = readl(&info->reg->memadr_reg2);
e4b40e92
SDPP
963 reg_val &= ~ARASAN_NAND_MEM_ADDR2_PAGE_MASK;
964 reg_val |= (page_addr >> ARASAN_NAND_MEM_ADDR1_PAGE_SHIFT);
3dd0f8cc 965 writel(reg_val, &info->reg->memadr_reg2);
e4b40e92 966
e4b40e92
SDPP
967 buf_index = 0;
968
969 return 0;
970}
971
972static void arasan_nand_read_buf(struct mtd_info *mtd, u8 *buf, int size)
973{
3dd0f8cc
ARS
974 struct nand_chip *chip = mtd_to_nand(mtd);
975 struct nand_drv *info = nand_get_controller_data(chip);
e4b40e92
SDPP
976 u32 reg_val, i;
977 u32 *bufptr = (u32 *)buf;
978 u32 timeout = ARASAN_NAND_POLL_TIMEOUT;
979
3dd0f8cc 980 reg_val = readl(&info->reg->pkt_reg);
e4b40e92
SDPP
981 reg_val &= ~(ARASAN_NAND_PKT_REG_PKT_CNT_MASK |
982 ARASAN_NAND_PKT_REG_PKT_SIZE_MASK);
983 reg_val |= (1 << ARASAN_NAND_PKT_REG_PKT_CNT_SHFT) | size;
3dd0f8cc 984 writel(reg_val, &info->reg->pkt_reg);
e4b40e92 985
3dd0f8cc 986 writel(curr_cmd->pgm, &info->reg->pgm_reg);
e4b40e92 987
3dd0f8cc 988 while (!(readl(&info->reg->intsts_reg) &
e4b40e92
SDPP
989 ARASAN_NAND_INT_STS_BUF_RD_RDY_MASK) && timeout) {
990 udelay(1);
991 timeout--;
992 }
993
994 if (!timeout)
995 puts("ERROR:arasan_nand_read_buf timedout:Buff RDY\n");
996
3dd0f8cc 997 reg_val = readl(&info->reg->intsts_enr);
e4b40e92 998 reg_val |= ARASAN_NAND_INT_STS_XFR_CMPLT_MASK;
3dd0f8cc 999 writel(reg_val, &info->reg->intsts_enr);
e4b40e92
SDPP
1000
1001 writel(reg_val | ARASAN_NAND_INT_STS_BUF_RD_RDY_MASK,
3dd0f8cc
ARS
1002 &info->reg->intsts_enr);
1003 reg_val = readl(&info->reg->intsts_reg);
e4b40e92 1004 writel(reg_val | ARASAN_NAND_INT_STS_BUF_RD_RDY_MASK,
3dd0f8cc 1005 &info->reg->intsts_reg);
e4b40e92
SDPP
1006
1007 buf_index = 0;
1008 for (i = 0; i < size / 4; i++)
3dd0f8cc 1009 bufptr[i] = readl(&info->reg->buf_dataport);
e4b40e92
SDPP
1010
1011 if (size & 0x03)
3dd0f8cc 1012 bufptr[i] = readl(&info->reg->buf_dataport);
e4b40e92
SDPP
1013
1014 timeout = ARASAN_NAND_POLL_TIMEOUT;
1015
3dd0f8cc 1016 while (!(readl(&info->reg->intsts_reg) &
e4b40e92
SDPP
1017 ARASAN_NAND_INT_STS_XFR_CMPLT_MASK) && timeout) {
1018 udelay(1);
1019 timeout--;
1020 }
1021
1022 if (!timeout)
1023 puts("ERROR:arasan_nand_read_buf timedout:Xfer CMPLT\n");
1024
3dd0f8cc 1025 reg_val = readl(&info->reg->intsts_enr);
e4b40e92 1026 writel(reg_val | ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
3dd0f8cc
ARS
1027 &info->reg->intsts_enr);
1028 reg_val = readl(&info->reg->intsts_reg);
e4b40e92 1029 writel(reg_val | ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
3dd0f8cc 1030 &info->reg->intsts_reg);
e4b40e92
SDPP
1031}
1032
1033static u8 arasan_nand_read_byte(struct mtd_info *mtd)
1034{
17cb4b8f 1035 struct nand_chip *chip = mtd_to_nand(mtd);
3dd0f8cc 1036 struct nand_drv *info = nand_get_controller_data(chip);
e4b40e92
SDPP
1037 u32 size;
1038 u8 val;
1039 struct nand_onfi_params *p;
1040
1041 if (buf_index == 0) {
1042 p = &chip->onfi_params;
1043 if (curr_cmd->cmd1 == NAND_CMD_READID)
1044 size = 4;
1045 else if (curr_cmd->cmd1 == NAND_CMD_PARAM)
1046 size = sizeof(struct nand_onfi_params);
1047 else if (curr_cmd->cmd1 == NAND_CMD_RNDOUT)
1048 size = le16_to_cpu(p->ext_param_page_length) * 16;
1049 else if (curr_cmd->cmd1 == NAND_CMD_GET_FEATURES)
1050 size = 4;
1051 else if (curr_cmd->cmd1 == NAND_CMD_STATUS)
3dd0f8cc 1052 return readb(&info->reg->flash_sts_reg);
e4b40e92
SDPP
1053 else
1054 size = 8;
1055 chip->read_buf(mtd, &buf_data[0], size);
1056 }
1057
1058 val = *(&buf_data[0] + buf_index);
1059 buf_index++;
1060
1061 return val;
1062}
1063
1064static void arasan_nand_cmd_function(struct mtd_info *mtd, unsigned int command,
1065 int column, int page_addr)
1066{
17cb4b8f 1067 struct nand_chip *chip = mtd_to_nand(mtd);
3dd0f8cc
ARS
1068 struct nand_drv *info = nand_get_controller_data(chip);
1069 struct nand_config *nand = &info->config;
1070 u32 i, ret = 0;
e4b40e92
SDPP
1071
1072 curr_cmd = NULL;
1073 writel(ARASAN_NAND_INT_STS_XFR_CMPLT_MASK,
3dd0f8cc 1074 &info->reg->intsts_enr);
e4b40e92
SDPP
1075
1076 if ((command == NAND_CMD_READOOB) &&
1077 (mtd->writesize > 512)) {
1078 column += mtd->writesize;
1079 command = NAND_CMD_READ0;
1080 }
1081
1082 /* Get the command format */
1083 for (i = 0; (arasan_nand_commands[i].cmd1 != NAND_CMD_NONE ||
1084 arasan_nand_commands[i].cmd2 != NAND_CMD_NONE); i++) {
1085 if (command == arasan_nand_commands[i].cmd1) {
1086 curr_cmd = &arasan_nand_commands[i];
1087 break;
1088 }
1089 }
1090
1091 if (curr_cmd == NULL) {
1092 printf("Unsupported Command; 0x%x\n", command);
1093 return;
1094 }
1095
1096 if (curr_cmd->cmd1 == NAND_CMD_RESET)
3dd0f8cc 1097 ret = arasan_nand_reset(mtd, curr_cmd);
e4b40e92
SDPP
1098
1099 if ((curr_cmd->cmd1 == NAND_CMD_READID) ||
1100 (curr_cmd->cmd1 == NAND_CMD_PARAM) ||
1101 (curr_cmd->cmd1 == NAND_CMD_RNDOUT) ||
1102 (curr_cmd->cmd1 == NAND_CMD_GET_FEATURES) ||
1103 (curr_cmd->cmd1 == NAND_CMD_READ0))
1104 ret = arasan_nand_send_rdcmd(curr_cmd, column, page_addr, mtd);
1105
1106 if ((curr_cmd->cmd1 == NAND_CMD_SET_FEATURES) ||
1107 (curr_cmd->cmd1 == NAND_CMD_SEQIN)) {
1108 nand->page = page_addr;
1109 ret = arasan_nand_send_wrcmd(curr_cmd, column, page_addr, mtd);
1110 }
1111
1112 if (curr_cmd->cmd1 == NAND_CMD_ERASE1)
1113 ret = arasan_nand_erase(curr_cmd, column, page_addr, mtd);
1114
1115 if (curr_cmd->cmd1 == NAND_CMD_STATUS)
1116 ret = arasan_nand_read_status(curr_cmd, column, page_addr, mtd);
1117
1118 if (ret != 0)
1119 printf("ERROR:%s:command:0x%x\n", __func__, curr_cmd->cmd1);
1120}
1121
cacb8a02
SDPP
1122static void arasan_check_ondie(struct mtd_info *mtd)
1123{
1124 struct nand_chip *nand_chip = mtd_to_nand(mtd);
4c2c28a4
KR
1125 struct nand_drv *info = nand_get_controller_data(nand_chip);
1126 struct nand_config *nand = &info->config;
cacb8a02
SDPP
1127 u8 maf_id, dev_id;
1128 u8 get_feature[4];
1129 u8 set_feature[4] = {ENABLE_ONDIE_ECC, 0x00, 0x00, 0x00};
1130 u32 i;
1131
4c2c28a4
KR
1132 nand_chip->select_chip(mtd, 0);
1133
cacb8a02
SDPP
1134 /* Send the command for reading device ID */
1135 nand_chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
1136 nand_chip->cmdfunc(mtd, NAND_CMD_READID, 0, -1);
1137
1138 /* Read manufacturer and device IDs */
1139 maf_id = nand_chip->read_byte(mtd);
1140 dev_id = nand_chip->read_byte(mtd);
1141
1142 if ((maf_id == NAND_MFR_MICRON) &&
1143 ((dev_id == 0xf1) || (dev_id == 0xa1) || (dev_id == 0xb1) ||
1144 (dev_id == 0xaa) || (dev_id == 0xba) || (dev_id == 0xda) ||
1145 (dev_id == 0xca) || (dev_id == 0xac) || (dev_id == 0xbc) ||
1146 (dev_id == 0xdc) || (dev_id == 0xcc) || (dev_id == 0xa3) ||
1147 (dev_id == 0xb3) || (dev_id == 0xd3) || (dev_id == 0xc3))) {
1148 nand_chip->cmdfunc(mtd, NAND_CMD_SET_FEATURES,
1149 ONDIE_ECC_FEATURE_ADDR, -1);
1150
1151 nand_chip->write_buf(mtd, &set_feature[0], 4);
1152 nand_chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES,
1153 ONDIE_ECC_FEATURE_ADDR, -1);
1154
1155 for (i = 0; i < 4; i++)
1156 get_feature[i] = nand_chip->read_byte(mtd);
1157
4c2c28a4 1158 if (get_feature[0] & ENABLE_ONDIE_ECC) {
cacb8a02 1159 nand->on_die_ecc_enabled = true;
4c2c28a4
KR
1160 printf("On-DIE ECC Enabled\n");
1161 } else {
cacb8a02 1162 printf("%s: Unable to enable OnDie ECC\n", __func__);
4c2c28a4 1163 }
cacb8a02
SDPP
1164
1165 /* Use the BBT pattern descriptors */
1166 nand_chip->bbt_td = &bbt_main_descr;
1167 nand_chip->bbt_md = &bbt_mirror_descr;
1168 }
1169}
1170
e4b40e92
SDPP
1171static int arasan_nand_ecc_init(struct mtd_info *mtd)
1172{
3dd0f8cc
ARS
1173 struct nand_chip *nand_chip = mtd_to_nand(mtd);
1174 struct nand_drv *info = nand_get_controller_data(nand_chip);
e4b40e92 1175 int found = -1;
f25ac66c 1176 u32 regval, eccpos_start, i, eccaddr;
e4b40e92 1177
e4b40e92
SDPP
1178 for (i = 0; i < ARRAY_SIZE(ecc_matrix); i++) {
1179 if ((ecc_matrix[i].pagesize == mtd->writesize) &&
1180 (ecc_matrix[i].ecc_codeword_size >=
1181 nand_chip->ecc_step_ds)) {
1182 if (ecc_matrix[i].eccbits >=
1183 nand_chip->ecc_strength_ds) {
1184 found = i;
1185 break;
1186 }
1187 found = i;
1188 }
1189 }
1190
1191 if (found < 0)
1192 return 1;
1193
f25ac66c
SDPP
1194 eccaddr = mtd->writesize + mtd->oobsize -
1195 ecc_matrix[found].eccsize;
1196
1197 regval = eccaddr |
a39d1440
SDPP
1198 (ecc_matrix[found].eccsize << ARASAN_NAND_ECC_SIZE_SHIFT) |
1199 (ecc_matrix[found].bch << ARASAN_NAND_ECC_BCH_SHIFT);
3dd0f8cc 1200 writel(regval, &info->reg->ecc_reg);
e4b40e92 1201
a39d1440 1202 if (ecc_matrix[found].bch) {
3dd0f8cc 1203 regval = readl(&info->reg->memadr_reg2);
e4b40e92 1204 regval &= ~ARASAN_NAND_MEM_ADDR2_BCH_MASK;
a39d1440 1205 regval |= (ecc_matrix[found].bchval <<
e4b40e92 1206 ARASAN_NAND_MEM_ADDR2_BCH_SHIFT);
3dd0f8cc 1207 writel(regval, &info->reg->memadr_reg2);
e4b40e92
SDPP
1208 }
1209
a39d1440 1210 nand_oob.eccbytes = ecc_matrix[found].eccsize;
e4b40e92
SDPP
1211 eccpos_start = mtd->oobsize - nand_oob.eccbytes;
1212
1213 for (i = 0; i < nand_oob.eccbytes; i++)
1214 nand_oob.eccpos[i] = eccpos_start + i;
1215
1216 nand_oob.oobfree[0].offset = 2;
1217 nand_oob.oobfree[0].length = eccpos_start - 2;
1218
a39d1440
SDPP
1219 nand_chip->ecc.size = ecc_matrix[found].ecc_codeword_size;
1220 nand_chip->ecc.strength = ecc_matrix[found].eccbits;
1221 nand_chip->ecc.bytes = ecc_matrix[found].eccsize;
e4b40e92
SDPP
1222 nand_chip->ecc.layout = &nand_oob;
1223
1224 return 0;
1225}
1226
b014b833 1227static int arasan_probe(struct udevice *dev)
e4b40e92 1228{
b014b833
ARS
1229 struct arasan_nand_info *arasan = dev_get_priv(dev);
1230 struct nand_chip *nand_chip = &arasan->nand_chip;
3dd0f8cc
ARS
1231 struct nand_drv *info = &arasan->nand_ctrl;
1232 struct nand_config *nand = &info->config;
e4b40e92 1233 struct mtd_info *mtd;
1e01769a 1234 ofnode child;
0508653e 1235 int ret;
602b879e 1236 const char *str;
e4b40e92 1237
a12a73b6 1238 info->reg = dev_read_addr_ptr(dev);
17cb4b8f 1239 mtd = nand_to_mtd(nand_chip);
3dd0f8cc 1240 nand_set_controller_data(nand_chip, &arasan->nand_ctrl);
e4b40e92 1241
1e01769a
ARS
1242 ofnode_for_each_subnode(child, dev_ofnode(dev))
1243 nand_set_flash_node(nand_chip, child);
1244
1cefca71
ML
1245#ifdef CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
1246 nand_chip->options |= NAND_NO_SUBPAGE_WRITE;
1247#endif
1248
e4b40e92
SDPP
1249 /* Set the driver entry points for MTD */
1250 nand_chip->cmdfunc = arasan_nand_cmd_function;
1251 nand_chip->select_chip = arasan_nand_select_chip;
1252 nand_chip->read_byte = arasan_nand_read_byte;
1253
1254 /* Buffer read/write routines */
1255 nand_chip->read_buf = arasan_nand_read_buf;
1256 nand_chip->write_buf = arasan_nand_write_buf;
e4b40e92 1257
3dd0f8cc
ARS
1258 writel(0x0, &info->reg->cmd_reg);
1259 writel(0x0, &info->reg->pgm_reg);
e4b40e92
SDPP
1260
1261 /* first scan to find the device and get the page size */
0508653e
VYA
1262 ret = nand_scan_ident(mtd, CONFIG_SYS_NAND_MAX_CHIPS, NULL);
1263 if (ret) {
e4b40e92 1264 printf("%s: nand_scan_ident failed\n", __func__);
0508653e 1265 return ret;
e4b40e92
SDPP
1266 }
1267
602b879e
VYA
1268 str = ofnode_read_string(nand_chip->flash_node, "nand-ecc-mode");
1269 if (!str || strcmp(str, "hw") != 0) {
1270 printf("%s ecc mode is not supported\n", str);
1271 return -EINVAL;
1272 }
1273
b08fc34f
SDPP
1274 nand_chip->ecc.mode = NAND_ECC_HW;
1275 nand_chip->ecc.hwctl = NULL;
1276 nand_chip->ecc.read_page = arasan_nand_read_page_hwecc;
1277 nand_chip->ecc.write_page = arasan_nand_write_page_hwecc;
1278 nand_chip->ecc.read_oob = arasan_nand_read_oob;
1279 nand_chip->ecc.write_oob = arasan_nand_write_oob;
1280
cacb8a02
SDPP
1281 arasan_check_ondie(mtd);
1282
1283 /*
1284 * If on die supported, then give priority to on-die ecc and use
1285 * it instead of controller ecc.
1286 */
1287 if (nand->on_die_ecc_enabled) {
1288 nand_chip->ecc.strength = 1;
1289 nand_chip->ecc.size = mtd->writesize;
1290 nand_chip->ecc.bytes = 0;
1291 nand_chip->ecc.layout = &ondie_nand_oob_64;
1292 } else {
0508653e
VYA
1293 ret = arasan_nand_ecc_init(mtd);
1294 if (ret) {
cacb8a02 1295 printf("%s: nand_ecc_init failed\n", __func__);
0508653e 1296 return ret;
cacb8a02 1297 }
e4b40e92
SDPP
1298 }
1299
0508653e
VYA
1300 ret = nand_scan_tail(mtd);
1301 if (ret) {
e4b40e92 1302 printf("%s: nand_scan_tail failed\n", __func__);
0508653e 1303 return ret;
e4b40e92
SDPP
1304 }
1305
0508653e
VYA
1306 ret = nand_register(0, mtd);
1307 if (ret) {
e4b40e92 1308 printf("Nand Register Fail\n");
0508653e 1309 return ret;
e4b40e92
SDPP
1310 }
1311
0508653e 1312 return ret;
e4b40e92
SDPP
1313}
1314
b014b833
ARS
1315static const struct udevice_id arasan_nand_dt_ids[] = {
1316 {.compatible = "arasan,nfc-v3p10",},
1317 { /* sentinel */ }
1318};
1319
1320U_BOOT_DRIVER(arasan_nand) = {
6c0e59fc 1321 .name = "arasan_nand",
b014b833
ARS
1322 .id = UCLASS_MTD,
1323 .of_match = arasan_nand_dt_ids,
1324 .probe = arasan_probe,
41575d8e 1325 .priv_auto = sizeof(struct arasan_nand_info),
b014b833
ARS
1326};
1327
e4b40e92
SDPP
1328void board_nand_init(void)
1329{
b014b833
ARS
1330 struct udevice *dev;
1331 int ret;
e4b40e92 1332
b014b833 1333 ret = uclass_get_device_by_driver(UCLASS_MTD,
65e25bea 1334 DM_DRIVER_GET(arasan_nand), &dev);
b014b833
ARS
1335 if (ret && ret != -ENODEV)
1336 pr_err("Failed to initialize %s. (error %d)\n", dev->name, ret);
e4b40e92 1337}