blob: b9946ae586168570f1ca84bb156834618098c50d [file] [log] [blame]
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001/*
2 * MTK NAND Flash controller driver.
3 * Copyright (C) 2016 MediaTek Inc.
4 * Authors: Xiaolei Li <xiaolei.li@mediatek.com>
5 * Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/platform_device.h>
18#include <linux/dma-mapping.h>
19#include <linux/interrupt.h>
20#include <linux/delay.h>
21#include <linux/clk.h>
Boris Brezillond4092d72017-08-04 17:29:10 +020022#include <linux/mtd/rawnand.h>
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -040023#include <linux/mtd/mtd.h>
24#include <linux/module.h>
25#include <linux/iopoll.h>
26#include <linux/of.h>
Xiaolei Li7ec4a372017-05-31 16:26:40 +080027#include <linux/of_device.h>
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -040028#include "mtk_ecc.h"
29
30/* NAND controller register definition */
31#define NFI_CNFG (0x00)
32#define CNFG_AHB BIT(0)
33#define CNFG_READ_EN BIT(1)
34#define CNFG_DMA_BURST_EN BIT(2)
35#define CNFG_BYTE_RW BIT(6)
36#define CNFG_HW_ECC_EN BIT(8)
37#define CNFG_AUTO_FMT_EN BIT(9)
38#define CNFG_OP_CUST (6 << 12)
39#define NFI_PAGEFMT (0x04)
40#define PAGEFMT_FDM_ECC_SHIFT (12)
41#define PAGEFMT_FDM_SHIFT (8)
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -040042#define PAGEFMT_SEC_SEL_512 BIT(2)
43#define PAGEFMT_512_2K (0)
44#define PAGEFMT_2K_4K (1)
45#define PAGEFMT_4K_8K (2)
46#define PAGEFMT_8K_16K (3)
47/* NFI control */
48#define NFI_CON (0x08)
49#define CON_FIFO_FLUSH BIT(0)
50#define CON_NFI_RST BIT(1)
51#define CON_BRD BIT(8) /* burst read */
52#define CON_BWR BIT(9) /* burst write */
53#define CON_SEC_SHIFT (12)
54/* Timming control register */
55#define NFI_ACCCON (0x0C)
56#define NFI_INTR_EN (0x10)
57#define INTR_AHB_DONE_EN BIT(6)
58#define NFI_INTR_STA (0x14)
59#define NFI_CMD (0x20)
60#define NFI_ADDRNOB (0x30)
61#define NFI_COLADDR (0x34)
62#define NFI_ROWADDR (0x38)
63#define NFI_STRDATA (0x40)
64#define STAR_EN (1)
65#define STAR_DE (0)
66#define NFI_CNRNB (0x44)
67#define NFI_DATAW (0x50)
68#define NFI_DATAR (0x54)
69#define NFI_PIO_DIRDY (0x58)
70#define PIO_DI_RDY (0x01)
71#define NFI_STA (0x60)
72#define STA_CMD BIT(0)
73#define STA_ADDR BIT(1)
74#define STA_BUSY BIT(8)
75#define STA_EMP_PAGE BIT(12)
76#define NFI_FSM_CUSTDATA (0xe << 16)
77#define NFI_FSM_MASK (0xf << 16)
78#define NFI_ADDRCNTR (0x70)
79#define CNTR_MASK GENMASK(16, 12)
RogerCC Lin559e58e2016-09-19 10:53:26 +080080#define ADDRCNTR_SEC_SHIFT (12)
81#define ADDRCNTR_SEC(val) \
82 (((val) & CNTR_MASK) >> ADDRCNTR_SEC_SHIFT)
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -040083#define NFI_STRADDR (0x80)
84#define NFI_BYTELEN (0x84)
85#define NFI_CSEL (0x90)
86#define NFI_FDML(x) (0xA0 + (x) * sizeof(u32) * 2)
87#define NFI_FDMM(x) (0xA4 + (x) * sizeof(u32) * 2)
88#define NFI_FDM_MAX_SIZE (8)
89#define NFI_FDM_MIN_SIZE (1)
90#define NFI_MASTER_STA (0x224)
91#define MASTER_STA_MASK (0x0FFF)
92#define NFI_EMPTY_THRESH (0x23C)
93
94#define MTK_NAME "mtk-nand"
95#define KB(x) ((x) * 1024UL)
96#define MB(x) (KB(x) * 1024UL)
97
98#define MTK_TIMEOUT (500000)
99#define MTK_RESET_TIMEOUT (1000000)
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -0400100#define MTK_NAND_MAX_NSELS (2)
Xiaolei Li7ec4a372017-05-31 16:26:40 +0800101#define MTK_NFC_MIN_SPARE (16)
Xiaolei Liedfee362017-06-23 15:12:28 +0800102#define ACCTIMING(tpoecs, tprecs, tc2r, tw2r, twh, twst, trlt) \
103 ((tpoecs) << 28 | (tprecs) << 22 | (tc2r) << 16 | \
104 (tw2r) << 12 | (twh) << 8 | (twst) << 4 | (trlt))
Xiaolei Li7ec4a372017-05-31 16:26:40 +0800105
106struct mtk_nfc_caps {
107 const u8 *spare_size;
108 u8 num_spare_size;
109 u8 pageformat_spare_shift;
Xiaolei Liedfee362017-06-23 15:12:28 +0800110 u8 nfi_clk_div;
RogerCC Linb45ee552017-11-30 22:10:44 +0800111 u8 max_sector;
112 u32 max_sector_size;
Xiaolei Li7ec4a372017-05-31 16:26:40 +0800113};
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -0400114
115struct mtk_nfc_bad_mark_ctl {
116 void (*bm_swap)(struct mtd_info *, u8 *buf, int raw);
117 u32 sec;
118 u32 pos;
119};
120
121/*
122 * FDM: region used to store free OOB data
123 */
124struct mtk_nfc_fdm {
125 u32 reg_size;
126 u32 ecc_size;
127};
128
129struct mtk_nfc_nand_chip {
130 struct list_head node;
131 struct nand_chip nand;
132
133 struct mtk_nfc_bad_mark_ctl bad_mark;
134 struct mtk_nfc_fdm fdm;
135 u32 spare_per_sector;
136
137 int nsels;
138 u8 sels[0];
139 /* nothing after this field */
140};
141
142struct mtk_nfc_clk {
143 struct clk *nfi_clk;
144 struct clk *pad_clk;
145};
146
147struct mtk_nfc {
148 struct nand_hw_control controller;
149 struct mtk_ecc_config ecc_cfg;
150 struct mtk_nfc_clk clk;
151 struct mtk_ecc *ecc;
152
153 struct device *dev;
Xiaolei Li7ec4a372017-05-31 16:26:40 +0800154 const struct mtk_nfc_caps *caps;
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -0400155 void __iomem *regs;
156
157 struct completion done;
158 struct list_head chips;
159
160 u8 *buffer;
161};
162
Xiaolei Li7ec4a372017-05-31 16:26:40 +0800163/*
164 * supported spare size of each IP.
165 * order should be the same with the spare size bitfiled defination of
166 * register NFI_PAGEFMT.
167 */
168static const u8 spare_size_mt2701[] = {
169 16, 26, 27, 28, 32, 36, 40, 44, 48, 49, 50, 51, 52, 62, 63, 64
170};
171
Xiaolei Li30ee8092017-05-31 16:26:41 +0800172static const u8 spare_size_mt2712[] = {
173 16, 26, 27, 28, 32, 36, 40, 44, 48, 49, 50, 51, 52, 62, 61, 63, 64, 67,
174 74
175};
176
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -0400177static inline struct mtk_nfc_nand_chip *to_mtk_nand(struct nand_chip *nand)
178{
179 return container_of(nand, struct mtk_nfc_nand_chip, nand);
180}
181
182static inline u8 *data_ptr(struct nand_chip *chip, const u8 *p, int i)
183{
184 return (u8 *)p + i * chip->ecc.size;
185}
186
187static inline u8 *oob_ptr(struct nand_chip *chip, int i)
188{
189 struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
190 u8 *poi;
191
192 /* map the sector's FDM data to free oob:
193 * the beginning of the oob area stores the FDM data of bad mark sectors
194 */
195
196 if (i < mtk_nand->bad_mark.sec)
197 poi = chip->oob_poi + (i + 1) * mtk_nand->fdm.reg_size;
198 else if (i == mtk_nand->bad_mark.sec)
199 poi = chip->oob_poi;
200 else
201 poi = chip->oob_poi + i * mtk_nand->fdm.reg_size;
202
203 return poi;
204}
205
206static inline int mtk_data_len(struct nand_chip *chip)
207{
208 struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
209
210 return chip->ecc.size + mtk_nand->spare_per_sector;
211}
212
213static inline u8 *mtk_data_ptr(struct nand_chip *chip, int i)
214{
215 struct mtk_nfc *nfc = nand_get_controller_data(chip);
216
217 return nfc->buffer + i * mtk_data_len(chip);
218}
219
220static inline u8 *mtk_oob_ptr(struct nand_chip *chip, int i)
221{
222 struct mtk_nfc *nfc = nand_get_controller_data(chip);
223
224 return nfc->buffer + i * mtk_data_len(chip) + chip->ecc.size;
225}
226
227static inline void nfi_writel(struct mtk_nfc *nfc, u32 val, u32 reg)
228{
229 writel(val, nfc->regs + reg);
230}
231
232static inline void nfi_writew(struct mtk_nfc *nfc, u16 val, u32 reg)
233{
234 writew(val, nfc->regs + reg);
235}
236
237static inline void nfi_writeb(struct mtk_nfc *nfc, u8 val, u32 reg)
238{
239 writeb(val, nfc->regs + reg);
240}
241
242static inline u32 nfi_readl(struct mtk_nfc *nfc, u32 reg)
243{
244 return readl_relaxed(nfc->regs + reg);
245}
246
247static inline u16 nfi_readw(struct mtk_nfc *nfc, u32 reg)
248{
249 return readw_relaxed(nfc->regs + reg);
250}
251
252static inline u8 nfi_readb(struct mtk_nfc *nfc, u32 reg)
253{
254 return readb_relaxed(nfc->regs + reg);
255}
256
257static void mtk_nfc_hw_reset(struct mtk_nfc *nfc)
258{
259 struct device *dev = nfc->dev;
260 u32 val;
261 int ret;
262
263 /* reset all registers and force the NFI master to terminate */
264 nfi_writel(nfc, CON_FIFO_FLUSH | CON_NFI_RST, NFI_CON);
265
266 /* wait for the master to finish the last transaction */
267 ret = readl_poll_timeout(nfc->regs + NFI_MASTER_STA, val,
268 !(val & MASTER_STA_MASK), 50,
269 MTK_RESET_TIMEOUT);
270 if (ret)
271 dev_warn(dev, "master active in reset [0x%x] = 0x%x\n",
272 NFI_MASTER_STA, val);
273
274 /* ensure any status register affected by the NFI master is reset */
275 nfi_writel(nfc, CON_FIFO_FLUSH | CON_NFI_RST, NFI_CON);
276 nfi_writew(nfc, STAR_DE, NFI_STRDATA);
277}
278
279static int mtk_nfc_send_command(struct mtk_nfc *nfc, u8 command)
280{
281 struct device *dev = nfc->dev;
282 u32 val;
283 int ret;
284
285 nfi_writel(nfc, command, NFI_CMD);
286
287 ret = readl_poll_timeout_atomic(nfc->regs + NFI_STA, val,
288 !(val & STA_CMD), 10, MTK_TIMEOUT);
289 if (ret) {
290 dev_warn(dev, "nfi core timed out entering command mode\n");
291 return -EIO;
292 }
293
294 return 0;
295}
296
297static int mtk_nfc_send_address(struct mtk_nfc *nfc, int addr)
298{
299 struct device *dev = nfc->dev;
300 u32 val;
301 int ret;
302
303 nfi_writel(nfc, addr, NFI_COLADDR);
304 nfi_writel(nfc, 0, NFI_ROWADDR);
305 nfi_writew(nfc, 1, NFI_ADDRNOB);
306
307 ret = readl_poll_timeout_atomic(nfc->regs + NFI_STA, val,
308 !(val & STA_ADDR), 10, MTK_TIMEOUT);
309 if (ret) {
310 dev_warn(dev, "nfi core timed out entering address mode\n");
311 return -EIO;
312 }
313
314 return 0;
315}
316
317static int mtk_nfc_hw_runtime_config(struct mtd_info *mtd)
318{
319 struct nand_chip *chip = mtd_to_nand(mtd);
320 struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
321 struct mtk_nfc *nfc = nand_get_controller_data(chip);
Xiaolei Li7ec4a372017-05-31 16:26:40 +0800322 u32 fmt, spare, i;
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -0400323
324 if (!mtd->writesize)
325 return 0;
326
327 spare = mtk_nand->spare_per_sector;
328
329 switch (mtd->writesize) {
330 case 512:
331 fmt = PAGEFMT_512_2K | PAGEFMT_SEC_SEL_512;
332 break;
333 case KB(2):
334 if (chip->ecc.size == 512)
335 fmt = PAGEFMT_2K_4K | PAGEFMT_SEC_SEL_512;
336 else
337 fmt = PAGEFMT_512_2K;
338 break;
339 case KB(4):
340 if (chip->ecc.size == 512)
341 fmt = PAGEFMT_4K_8K | PAGEFMT_SEC_SEL_512;
342 else
343 fmt = PAGEFMT_2K_4K;
344 break;
345 case KB(8):
346 if (chip->ecc.size == 512)
347 fmt = PAGEFMT_8K_16K | PAGEFMT_SEC_SEL_512;
348 else
349 fmt = PAGEFMT_4K_8K;
350 break;
351 case KB(16):
352 fmt = PAGEFMT_8K_16K;
353 break;
354 default:
355 dev_err(nfc->dev, "invalid page len: %d\n", mtd->writesize);
356 return -EINVAL;
357 }
358
359 /*
360 * the hardware will double the value for this eccsize, so we need to
361 * halve it
362 */
363 if (chip->ecc.size == 1024)
364 spare >>= 1;
365
Xiaolei Li7ec4a372017-05-31 16:26:40 +0800366 for (i = 0; i < nfc->caps->num_spare_size; i++) {
367 if (nfc->caps->spare_size[i] == spare)
368 break;
369 }
370
371 if (i == nfc->caps->num_spare_size) {
372 dev_err(nfc->dev, "invalid spare size %d\n", spare);
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -0400373 return -EINVAL;
374 }
375
Xiaolei Li7ec4a372017-05-31 16:26:40 +0800376 fmt |= i << nfc->caps->pageformat_spare_shift;
377
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -0400378 fmt |= mtk_nand->fdm.reg_size << PAGEFMT_FDM_SHIFT;
379 fmt |= mtk_nand->fdm.ecc_size << PAGEFMT_FDM_ECC_SHIFT;
Xiaolei Li582212c2017-05-31 16:26:39 +0800380 nfi_writel(nfc, fmt, NFI_PAGEFMT);
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -0400381
382 nfc->ecc_cfg.strength = chip->ecc.strength;
383 nfc->ecc_cfg.len = chip->ecc.size + mtk_nand->fdm.ecc_size;
384
385 return 0;
386}
387
388static void mtk_nfc_select_chip(struct mtd_info *mtd, int chip)
389{
390 struct nand_chip *nand = mtd_to_nand(mtd);
391 struct mtk_nfc *nfc = nand_get_controller_data(nand);
392 struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(nand);
393
394 if (chip < 0)
395 return;
396
397 mtk_nfc_hw_runtime_config(mtd);
398
399 nfi_writel(nfc, mtk_nand->sels[chip], NFI_CSEL);
400}
401
402static int mtk_nfc_dev_ready(struct mtd_info *mtd)
403{
404 struct mtk_nfc *nfc = nand_get_controller_data(mtd_to_nand(mtd));
405
406 if (nfi_readl(nfc, NFI_STA) & STA_BUSY)
407 return 0;
408
409 return 1;
410}
411
412static void mtk_nfc_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl)
413{
414 struct mtk_nfc *nfc = nand_get_controller_data(mtd_to_nand(mtd));
415
416 if (ctrl & NAND_ALE) {
417 mtk_nfc_send_address(nfc, dat);
418 } else if (ctrl & NAND_CLE) {
419 mtk_nfc_hw_reset(nfc);
420
421 nfi_writew(nfc, CNFG_OP_CUST, NFI_CNFG);
422 mtk_nfc_send_command(nfc, dat);
423 }
424}
425
426static inline void mtk_nfc_wait_ioready(struct mtk_nfc *nfc)
427{
428 int rc;
429 u8 val;
430
431 rc = readb_poll_timeout_atomic(nfc->regs + NFI_PIO_DIRDY, val,
432 val & PIO_DI_RDY, 10, MTK_TIMEOUT);
433 if (rc < 0)
434 dev_err(nfc->dev, "data not ready\n");
435}
436
437static inline u8 mtk_nfc_read_byte(struct mtd_info *mtd)
438{
439 struct nand_chip *chip = mtd_to_nand(mtd);
440 struct mtk_nfc *nfc = nand_get_controller_data(chip);
441 u32 reg;
442
443 /* after each byte read, the NFI_STA reg is reset by the hardware */
444 reg = nfi_readl(nfc, NFI_STA) & NFI_FSM_MASK;
445 if (reg != NFI_FSM_CUSTDATA) {
446 reg = nfi_readw(nfc, NFI_CNFG);
447 reg |= CNFG_BYTE_RW | CNFG_READ_EN;
448 nfi_writew(nfc, reg, NFI_CNFG);
449
450 /*
451 * set to max sector to allow the HW to continue reading over
452 * unaligned accesses
453 */
RogerCC Linb45ee552017-11-30 22:10:44 +0800454 reg = (nfc->caps->max_sector << CON_SEC_SHIFT) | CON_BRD;
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -0400455 nfi_writel(nfc, reg, NFI_CON);
456
457 /* trigger to fetch data */
458 nfi_writew(nfc, STAR_EN, NFI_STRDATA);
459 }
460
461 mtk_nfc_wait_ioready(nfc);
462
463 return nfi_readb(nfc, NFI_DATAR);
464}
465
466static void mtk_nfc_read_buf(struct mtd_info *mtd, u8 *buf, int len)
467{
468 int i;
469
470 for (i = 0; i < len; i++)
471 buf[i] = mtk_nfc_read_byte(mtd);
472}
473
474static void mtk_nfc_write_byte(struct mtd_info *mtd, u8 byte)
475{
476 struct mtk_nfc *nfc = nand_get_controller_data(mtd_to_nand(mtd));
477 u32 reg;
478
479 reg = nfi_readl(nfc, NFI_STA) & NFI_FSM_MASK;
480
481 if (reg != NFI_FSM_CUSTDATA) {
482 reg = nfi_readw(nfc, NFI_CNFG) | CNFG_BYTE_RW;
483 nfi_writew(nfc, reg, NFI_CNFG);
484
RogerCC Linb45ee552017-11-30 22:10:44 +0800485 reg = nfc->caps->max_sector << CON_SEC_SHIFT | CON_BWR;
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -0400486 nfi_writel(nfc, reg, NFI_CON);
487
488 nfi_writew(nfc, STAR_EN, NFI_STRDATA);
489 }
490
491 mtk_nfc_wait_ioready(nfc);
492 nfi_writeb(nfc, byte, NFI_DATAW);
493}
494
495static void mtk_nfc_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
496{
497 int i;
498
499 for (i = 0; i < len; i++)
500 mtk_nfc_write_byte(mtd, buf[i]);
501}
502
Xiaolei Liedfee362017-06-23 15:12:28 +0800503static int mtk_nfc_setup_data_interface(struct mtd_info *mtd, int csline,
504 const struct nand_data_interface *conf)
505{
506 struct mtk_nfc *nfc = nand_get_controller_data(mtd_to_nand(mtd));
507 const struct nand_sdr_timings *timings;
508 u32 rate, tpoecs, tprecs, tc2r, tw2r, twh, twst, trlt;
509
510 timings = nand_get_sdr_timings(conf);
511 if (IS_ERR(timings))
512 return -ENOTSUPP;
513
514 if (csline == NAND_DATA_IFACE_CHECK_ONLY)
515 return 0;
516
517 rate = clk_get_rate(nfc->clk.nfi_clk);
518 /* There is a frequency divider in some IPs */
519 rate /= nfc->caps->nfi_clk_div;
520
521 /* turn clock rate into KHZ */
522 rate /= 1000;
523
524 tpoecs = max(timings->tALH_min, timings->tCLH_min) / 1000;
525 tpoecs = DIV_ROUND_UP(tpoecs * rate, 1000000);
526 tpoecs &= 0xf;
527
528 tprecs = max(timings->tCLS_min, timings->tALS_min) / 1000;
529 tprecs = DIV_ROUND_UP(tprecs * rate, 1000000);
530 tprecs &= 0x3f;
531
532 /* sdr interface has no tCR which means CE# low to RE# low */
533 tc2r = 0;
534
535 tw2r = timings->tWHR_min / 1000;
536 tw2r = DIV_ROUND_UP(tw2r * rate, 1000000);
537 tw2r = DIV_ROUND_UP(tw2r - 1, 2);
538 tw2r &= 0xf;
539
540 twh = max(timings->tREH_min, timings->tWH_min) / 1000;
541 twh = DIV_ROUND_UP(twh * rate, 1000000) - 1;
542 twh &= 0xf;
543
544 twst = timings->tWP_min / 1000;
545 twst = DIV_ROUND_UP(twst * rate, 1000000) - 1;
546 twst &= 0xf;
547
548 trlt = max(timings->tREA_max, timings->tRP_min) / 1000;
549 trlt = DIV_ROUND_UP(trlt * rate, 1000000) - 1;
550 trlt &= 0xf;
551
552 /*
553 * ACCON: access timing control register
554 * -------------------------------------
555 * 31:28: tpoecs, minimum required time for CS post pulling down after
556 * accessing the device
557 * 27:22: tprecs, minimum required time for CS pre pulling down before
558 * accessing the device
559 * 21:16: tc2r, minimum required time from NCEB low to NREB low
560 * 15:12: tw2r, minimum required time from NWEB high to NREB low.
561 * 11:08: twh, write enable hold time
562 * 07:04: twst, write wait states
563 * 03:00: trlt, read wait states
564 */
565 trlt = ACCTIMING(tpoecs, tprecs, tc2r, tw2r, twh, twst, trlt);
566 nfi_writel(nfc, trlt, NFI_ACCCON);
567
568 return 0;
569}
570
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -0400571static int mtk_nfc_sector_encode(struct nand_chip *chip, u8 *data)
572{
573 struct mtk_nfc *nfc = nand_get_controller_data(chip);
574 struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
575 int size = chip->ecc.size + mtk_nand->fdm.reg_size;
576
577 nfc->ecc_cfg.mode = ECC_DMA_MODE;
578 nfc->ecc_cfg.op = ECC_ENCODE;
579
580 return mtk_ecc_encode(nfc->ecc, &nfc->ecc_cfg, data, size);
581}
582
583static void mtk_nfc_no_bad_mark_swap(struct mtd_info *a, u8 *b, int c)
584{
585 /* nop */
586}
587
588static void mtk_nfc_bad_mark_swap(struct mtd_info *mtd, u8 *buf, int raw)
589{
590 struct nand_chip *chip = mtd_to_nand(mtd);
591 struct mtk_nfc_nand_chip *nand = to_mtk_nand(chip);
592 u32 bad_pos = nand->bad_mark.pos;
593
594 if (raw)
595 bad_pos += nand->bad_mark.sec * mtk_data_len(chip);
596 else
597 bad_pos += nand->bad_mark.sec * chip->ecc.size;
598
599 swap(chip->oob_poi[0], buf[bad_pos]);
600}
601
602static int mtk_nfc_format_subpage(struct mtd_info *mtd, u32 offset,
603 u32 len, const u8 *buf)
604{
605 struct nand_chip *chip = mtd_to_nand(mtd);
606 struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
607 struct mtk_nfc *nfc = nand_get_controller_data(chip);
608 struct mtk_nfc_fdm *fdm = &mtk_nand->fdm;
609 u32 start, end;
610 int i, ret;
611
612 start = offset / chip->ecc.size;
613 end = DIV_ROUND_UP(offset + len, chip->ecc.size);
614
615 memset(nfc->buffer, 0xff, mtd->writesize + mtd->oobsize);
616 for (i = 0; i < chip->ecc.steps; i++) {
617 memcpy(mtk_data_ptr(chip, i), data_ptr(chip, buf, i),
618 chip->ecc.size);
619
620 if (start > i || i >= end)
621 continue;
622
623 if (i == mtk_nand->bad_mark.sec)
624 mtk_nand->bad_mark.bm_swap(mtd, nfc->buffer, 1);
625
626 memcpy(mtk_oob_ptr(chip, i), oob_ptr(chip, i), fdm->reg_size);
627
628 /* program the CRC back to the OOB */
629 ret = mtk_nfc_sector_encode(chip, mtk_data_ptr(chip, i));
630 if (ret < 0)
631 return ret;
632 }
633
634 return 0;
635}
636
637static void mtk_nfc_format_page(struct mtd_info *mtd, const u8 *buf)
638{
639 struct nand_chip *chip = mtd_to_nand(mtd);
640 struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
641 struct mtk_nfc *nfc = nand_get_controller_data(chip);
642 struct mtk_nfc_fdm *fdm = &mtk_nand->fdm;
643 u32 i;
644
645 memset(nfc->buffer, 0xff, mtd->writesize + mtd->oobsize);
646 for (i = 0; i < chip->ecc.steps; i++) {
647 if (buf)
648 memcpy(mtk_data_ptr(chip, i), data_ptr(chip, buf, i),
649 chip->ecc.size);
650
651 if (i == mtk_nand->bad_mark.sec)
652 mtk_nand->bad_mark.bm_swap(mtd, nfc->buffer, 1);
653
654 memcpy(mtk_oob_ptr(chip, i), oob_ptr(chip, i), fdm->reg_size);
655 }
656}
657
658static inline void mtk_nfc_read_fdm(struct nand_chip *chip, u32 start,
659 u32 sectors)
660{
661 struct mtk_nfc *nfc = nand_get_controller_data(chip);
662 struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
663 struct mtk_nfc_fdm *fdm = &mtk_nand->fdm;
664 u32 vall, valm;
665 u8 *oobptr;
666 int i, j;
667
668 for (i = 0; i < sectors; i++) {
669 oobptr = oob_ptr(chip, start + i);
670 vall = nfi_readl(nfc, NFI_FDML(i));
671 valm = nfi_readl(nfc, NFI_FDMM(i));
672
673 for (j = 0; j < fdm->reg_size; j++)
674 oobptr[j] = (j >= 4 ? valm : vall) >> ((j % 4) * 8);
675 }
676}
677
678static inline void mtk_nfc_write_fdm(struct nand_chip *chip)
679{
680 struct mtk_nfc *nfc = nand_get_controller_data(chip);
681 struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
682 struct mtk_nfc_fdm *fdm = &mtk_nand->fdm;
683 u32 vall, valm;
684 u8 *oobptr;
685 int i, j;
686
687 for (i = 0; i < chip->ecc.steps; i++) {
688 oobptr = oob_ptr(chip, i);
689 vall = 0;
690 valm = 0;
691 for (j = 0; j < 8; j++) {
692 if (j < 4)
693 vall |= (j < fdm->reg_size ? oobptr[j] : 0xff)
694 << (j * 8);
695 else
696 valm |= (j < fdm->reg_size ? oobptr[j] : 0xff)
697 << ((j - 4) * 8);
698 }
699 nfi_writel(nfc, vall, NFI_FDML(i));
700 nfi_writel(nfc, valm, NFI_FDMM(i));
701 }
702}
703
704static int mtk_nfc_do_write_page(struct mtd_info *mtd, struct nand_chip *chip,
705 const u8 *buf, int page, int len)
706{
707 struct mtk_nfc *nfc = nand_get_controller_data(chip);
708 struct device *dev = nfc->dev;
709 dma_addr_t addr;
710 u32 reg;
711 int ret;
712
713 addr = dma_map_single(dev, (void *)buf, len, DMA_TO_DEVICE);
714 ret = dma_mapping_error(nfc->dev, addr);
715 if (ret) {
716 dev_err(nfc->dev, "dma mapping error\n");
717 return -EINVAL;
718 }
719
720 reg = nfi_readw(nfc, NFI_CNFG) | CNFG_AHB | CNFG_DMA_BURST_EN;
721 nfi_writew(nfc, reg, NFI_CNFG);
722
723 nfi_writel(nfc, chip->ecc.steps << CON_SEC_SHIFT, NFI_CON);
724 nfi_writel(nfc, lower_32_bits(addr), NFI_STRADDR);
725 nfi_writew(nfc, INTR_AHB_DONE_EN, NFI_INTR_EN);
726
727 init_completion(&nfc->done);
728
729 reg = nfi_readl(nfc, NFI_CON) | CON_BWR;
730 nfi_writel(nfc, reg, NFI_CON);
731 nfi_writew(nfc, STAR_EN, NFI_STRDATA);
732
733 ret = wait_for_completion_timeout(&nfc->done, msecs_to_jiffies(500));
734 if (!ret) {
735 dev_err(dev, "program ahb done timeout\n");
736 nfi_writew(nfc, 0, NFI_INTR_EN);
737 ret = -ETIMEDOUT;
738 goto timeout;
739 }
740
741 ret = readl_poll_timeout_atomic(nfc->regs + NFI_ADDRCNTR, reg,
RogerCC Lin559e58e2016-09-19 10:53:26 +0800742 ADDRCNTR_SEC(reg) >= chip->ecc.steps,
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -0400743 10, MTK_TIMEOUT);
744 if (ret)
745 dev_err(dev, "hwecc write timeout\n");
746
747timeout:
748
749 dma_unmap_single(nfc->dev, addr, len, DMA_TO_DEVICE);
750 nfi_writel(nfc, 0, NFI_CON);
751
752 return ret;
753}
754
755static int mtk_nfc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
756 const u8 *buf, int page, int raw)
757{
758 struct mtk_nfc *nfc = nand_get_controller_data(chip);
759 struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
760 size_t len;
761 const u8 *bufpoi;
762 u32 reg;
763 int ret;
764
Boris Brezillon25f815f2017-11-30 18:01:30 +0100765 nand_prog_page_begin_op(chip, page, 0, NULL, 0);
766
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -0400767 if (!raw) {
768 /* OOB => FDM: from register, ECC: from HW */
769 reg = nfi_readw(nfc, NFI_CNFG) | CNFG_AUTO_FMT_EN;
770 nfi_writew(nfc, reg | CNFG_HW_ECC_EN, NFI_CNFG);
771
772 nfc->ecc_cfg.op = ECC_ENCODE;
773 nfc->ecc_cfg.mode = ECC_NFI_MODE;
774 ret = mtk_ecc_enable(nfc->ecc, &nfc->ecc_cfg);
775 if (ret) {
776 /* clear NFI config */
777 reg = nfi_readw(nfc, NFI_CNFG);
778 reg &= ~(CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN);
779 nfi_writew(nfc, reg, NFI_CNFG);
780
781 return ret;
782 }
783
784 memcpy(nfc->buffer, buf, mtd->writesize);
785 mtk_nand->bad_mark.bm_swap(mtd, nfc->buffer, raw);
786 bufpoi = nfc->buffer;
787
788 /* write OOB into the FDM registers (OOB area in MTK NAND) */
789 mtk_nfc_write_fdm(chip);
790 } else {
791 bufpoi = buf;
792 }
793
794 len = mtd->writesize + (raw ? mtd->oobsize : 0);
795 ret = mtk_nfc_do_write_page(mtd, chip, bufpoi, page, len);
796
797 if (!raw)
798 mtk_ecc_disable(nfc->ecc);
799
Boris Brezillon25f815f2017-11-30 18:01:30 +0100800 if (ret)
801 return ret;
802
803 return nand_prog_page_end_op(chip);
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -0400804}
805
806static int mtk_nfc_write_page_hwecc(struct mtd_info *mtd,
807 struct nand_chip *chip, const u8 *buf,
808 int oob_on, int page)
809{
810 return mtk_nfc_write_page(mtd, chip, buf, page, 0);
811}
812
813static int mtk_nfc_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
814 const u8 *buf, int oob_on, int pg)
815{
816 struct mtk_nfc *nfc = nand_get_controller_data(chip);
817
818 mtk_nfc_format_page(mtd, buf);
819 return mtk_nfc_write_page(mtd, chip, nfc->buffer, pg, 1);
820}
821
822static int mtk_nfc_write_subpage_hwecc(struct mtd_info *mtd,
823 struct nand_chip *chip, u32 offset,
824 u32 data_len, const u8 *buf,
825 int oob_on, int page)
826{
827 struct mtk_nfc *nfc = nand_get_controller_data(chip);
828 int ret;
829
830 ret = mtk_nfc_format_subpage(mtd, offset, data_len, buf);
831 if (ret < 0)
832 return ret;
833
834 /* use the data in the private buffer (now with FDM and CRC) */
835 return mtk_nfc_write_page(mtd, chip, nfc->buffer, page, 1);
836}
837
838static int mtk_nfc_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
839 int page)
840{
Boris Brezillon25f815f2017-11-30 18:01:30 +0100841 return mtk_nfc_write_page_raw(mtd, chip, NULL, 1, page);
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -0400842}
843
844static int mtk_nfc_update_ecc_stats(struct mtd_info *mtd, u8 *buf, u32 sectors)
845{
846 struct nand_chip *chip = mtd_to_nand(mtd);
847 struct mtk_nfc *nfc = nand_get_controller_data(chip);
848 struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
849 struct mtk_ecc_stats stats;
850 int rc, i;
851
852 rc = nfi_readl(nfc, NFI_STA) & STA_EMP_PAGE;
853 if (rc) {
854 memset(buf, 0xff, sectors * chip->ecc.size);
855 for (i = 0; i < sectors; i++)
856 memset(oob_ptr(chip, i), 0xff, mtk_nand->fdm.reg_size);
857 return 0;
858 }
859
860 mtk_ecc_get_stats(nfc->ecc, &stats, sectors);
861 mtd->ecc_stats.corrected += stats.corrected;
862 mtd->ecc_stats.failed += stats.failed;
863
864 return stats.bitflips;
865}
866
867static int mtk_nfc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
868 u32 data_offs, u32 readlen,
869 u8 *bufpoi, int page, int raw)
870{
871 struct mtk_nfc *nfc = nand_get_controller_data(chip);
872 struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
873 u32 spare = mtk_nand->spare_per_sector;
874 u32 column, sectors, start, end, reg;
875 dma_addr_t addr;
876 int bitflips;
877 size_t len;
878 u8 *buf;
879 int rc;
880
881 start = data_offs / chip->ecc.size;
882 end = DIV_ROUND_UP(data_offs + readlen, chip->ecc.size);
883
884 sectors = end - start;
885 column = start * (chip->ecc.size + spare);
886
887 len = sectors * chip->ecc.size + (raw ? sectors * spare : 0);
888 buf = bufpoi + start * chip->ecc.size;
889
Boris Brezillon25f815f2017-11-30 18:01:30 +0100890 nand_read_page_op(chip, page, column, NULL, 0);
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -0400891
892 addr = dma_map_single(nfc->dev, buf, len, DMA_FROM_DEVICE);
893 rc = dma_mapping_error(nfc->dev, addr);
894 if (rc) {
895 dev_err(nfc->dev, "dma mapping error\n");
896
897 return -EINVAL;
898 }
899
900 reg = nfi_readw(nfc, NFI_CNFG);
901 reg |= CNFG_READ_EN | CNFG_DMA_BURST_EN | CNFG_AHB;
902 if (!raw) {
903 reg |= CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN;
904 nfi_writew(nfc, reg, NFI_CNFG);
905
906 nfc->ecc_cfg.mode = ECC_NFI_MODE;
907 nfc->ecc_cfg.sectors = sectors;
908 nfc->ecc_cfg.op = ECC_DECODE;
909 rc = mtk_ecc_enable(nfc->ecc, &nfc->ecc_cfg);
910 if (rc) {
911 dev_err(nfc->dev, "ecc enable\n");
912 /* clear NFI_CNFG */
913 reg &= ~(CNFG_DMA_BURST_EN | CNFG_AHB | CNFG_READ_EN |
914 CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN);
915 nfi_writew(nfc, reg, NFI_CNFG);
916 dma_unmap_single(nfc->dev, addr, len, DMA_FROM_DEVICE);
917
918 return rc;
919 }
920 } else {
921 nfi_writew(nfc, reg, NFI_CNFG);
922 }
923
924 nfi_writel(nfc, sectors << CON_SEC_SHIFT, NFI_CON);
925 nfi_writew(nfc, INTR_AHB_DONE_EN, NFI_INTR_EN);
926 nfi_writel(nfc, lower_32_bits(addr), NFI_STRADDR);
927
928 init_completion(&nfc->done);
929 reg = nfi_readl(nfc, NFI_CON) | CON_BRD;
930 nfi_writel(nfc, reg, NFI_CON);
931 nfi_writew(nfc, STAR_EN, NFI_STRDATA);
932
933 rc = wait_for_completion_timeout(&nfc->done, msecs_to_jiffies(500));
934 if (!rc)
935 dev_warn(nfc->dev, "read ahb/dma done timeout\n");
936
937 rc = readl_poll_timeout_atomic(nfc->regs + NFI_BYTELEN, reg,
RogerCC Lin559e58e2016-09-19 10:53:26 +0800938 ADDRCNTR_SEC(reg) >= sectors, 10,
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -0400939 MTK_TIMEOUT);
940 if (rc < 0) {
941 dev_err(nfc->dev, "subpage done timeout\n");
942 bitflips = -EIO;
943 } else {
944 bitflips = 0;
945 if (!raw) {
946 rc = mtk_ecc_wait_done(nfc->ecc, ECC_DECODE);
947 bitflips = rc < 0 ? -ETIMEDOUT :
948 mtk_nfc_update_ecc_stats(mtd, buf, sectors);
949 mtk_nfc_read_fdm(chip, start, sectors);
950 }
951 }
952
953 dma_unmap_single(nfc->dev, addr, len, DMA_FROM_DEVICE);
954
955 if (raw)
956 goto done;
957
958 mtk_ecc_disable(nfc->ecc);
959
960 if (clamp(mtk_nand->bad_mark.sec, start, end) == mtk_nand->bad_mark.sec)
961 mtk_nand->bad_mark.bm_swap(mtd, bufpoi, raw);
962done:
963 nfi_writel(nfc, 0, NFI_CON);
964
965 return bitflips;
966}
967
968static int mtk_nfc_read_subpage_hwecc(struct mtd_info *mtd,
969 struct nand_chip *chip, u32 off,
970 u32 len, u8 *p, int pg)
971{
972 return mtk_nfc_read_subpage(mtd, chip, off, len, p, pg, 0);
973}
974
975static int mtk_nfc_read_page_hwecc(struct mtd_info *mtd,
976 struct nand_chip *chip, u8 *p,
977 int oob_on, int pg)
978{
979 return mtk_nfc_read_subpage(mtd, chip, 0, mtd->writesize, p, pg, 0);
980}
981
982static int mtk_nfc_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
983 u8 *buf, int oob_on, int page)
984{
985 struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
986 struct mtk_nfc *nfc = nand_get_controller_data(chip);
987 struct mtk_nfc_fdm *fdm = &mtk_nand->fdm;
988 int i, ret;
989
990 memset(nfc->buffer, 0xff, mtd->writesize + mtd->oobsize);
991 ret = mtk_nfc_read_subpage(mtd, chip, 0, mtd->writesize, nfc->buffer,
992 page, 1);
993 if (ret < 0)
994 return ret;
995
996 for (i = 0; i < chip->ecc.steps; i++) {
997 memcpy(oob_ptr(chip, i), mtk_oob_ptr(chip, i), fdm->reg_size);
998
999 if (i == mtk_nand->bad_mark.sec)
1000 mtk_nand->bad_mark.bm_swap(mtd, nfc->buffer, 1);
1001
1002 if (buf)
1003 memcpy(data_ptr(chip, buf, i), mtk_data_ptr(chip, i),
1004 chip->ecc.size);
1005 }
1006
1007 return ret;
1008}
1009
1010static int mtk_nfc_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
1011 int page)
1012{
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001013 return mtk_nfc_read_page_raw(mtd, chip, NULL, 1, page);
1014}
1015
1016static inline void mtk_nfc_hw_init(struct mtk_nfc *nfc)
1017{
1018 /*
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001019 * CNRNB: nand ready/busy register
1020 * -------------------------------
1021 * 7:4: timeout register for polling the NAND busy/ready signal
1022 * 0 : poll the status of the busy/ready signal after [7:4]*16 cycles.
1023 */
1024 nfi_writew(nfc, 0xf1, NFI_CNRNB);
Xiaolei Li582212c2017-05-31 16:26:39 +08001025 nfi_writel(nfc, PAGEFMT_8K_16K, NFI_PAGEFMT);
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001026
1027 mtk_nfc_hw_reset(nfc);
1028
1029 nfi_readl(nfc, NFI_INTR_STA);
1030 nfi_writel(nfc, 0, NFI_INTR_EN);
1031}
1032
1033static irqreturn_t mtk_nfc_irq(int irq, void *id)
1034{
1035 struct mtk_nfc *nfc = id;
1036 u16 sta, ien;
1037
1038 sta = nfi_readw(nfc, NFI_INTR_STA);
1039 ien = nfi_readw(nfc, NFI_INTR_EN);
1040
1041 if (!(sta & ien))
1042 return IRQ_NONE;
1043
1044 nfi_writew(nfc, ~sta & ien, NFI_INTR_EN);
1045 complete(&nfc->done);
1046
1047 return IRQ_HANDLED;
1048}
1049
1050static int mtk_nfc_enable_clk(struct device *dev, struct mtk_nfc_clk *clk)
1051{
1052 int ret;
1053
1054 ret = clk_prepare_enable(clk->nfi_clk);
1055 if (ret) {
1056 dev_err(dev, "failed to enable nfi clk\n");
1057 return ret;
1058 }
1059
1060 ret = clk_prepare_enable(clk->pad_clk);
1061 if (ret) {
1062 dev_err(dev, "failed to enable pad clk\n");
1063 clk_disable_unprepare(clk->nfi_clk);
1064 return ret;
1065 }
1066
1067 return 0;
1068}
1069
1070static void mtk_nfc_disable_clk(struct mtk_nfc_clk *clk)
1071{
1072 clk_disable_unprepare(clk->nfi_clk);
1073 clk_disable_unprepare(clk->pad_clk);
1074}
1075
1076static int mtk_nfc_ooblayout_free(struct mtd_info *mtd, int section,
1077 struct mtd_oob_region *oob_region)
1078{
1079 struct nand_chip *chip = mtd_to_nand(mtd);
1080 struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
1081 struct mtk_nfc_fdm *fdm = &mtk_nand->fdm;
1082 u32 eccsteps;
1083
1084 eccsteps = mtd->writesize / chip->ecc.size;
1085
1086 if (section >= eccsteps)
1087 return -ERANGE;
1088
1089 oob_region->length = fdm->reg_size - fdm->ecc_size;
1090 oob_region->offset = section * fdm->reg_size + fdm->ecc_size;
1091
1092 return 0;
1093}
1094
1095static int mtk_nfc_ooblayout_ecc(struct mtd_info *mtd, int section,
1096 struct mtd_oob_region *oob_region)
1097{
1098 struct nand_chip *chip = mtd_to_nand(mtd);
1099 struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
1100 u32 eccsteps;
1101
1102 if (section)
1103 return -ERANGE;
1104
1105 eccsteps = mtd->writesize / chip->ecc.size;
1106 oob_region->offset = mtk_nand->fdm.reg_size * eccsteps;
1107 oob_region->length = mtd->oobsize - oob_region->offset;
1108
1109 return 0;
1110}
1111
1112static const struct mtd_ooblayout_ops mtk_nfc_ooblayout_ops = {
1113 .free = mtk_nfc_ooblayout_free,
1114 .ecc = mtk_nfc_ooblayout_ecc,
1115};
1116
1117static void mtk_nfc_set_fdm(struct mtk_nfc_fdm *fdm, struct mtd_info *mtd)
1118{
1119 struct nand_chip *nand = mtd_to_nand(mtd);
1120 struct mtk_nfc_nand_chip *chip = to_mtk_nand(nand);
RogerCC Linb45ee552017-11-30 22:10:44 +08001121 struct mtk_nfc *nfc = nand_get_controller_data(nand);
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001122 u32 ecc_bytes;
1123
RogerCC Linb45ee552017-11-30 22:10:44 +08001124 ecc_bytes = DIV_ROUND_UP(nand->ecc.strength *
1125 mtk_ecc_get_parity_bits(nfc->ecc), 8);
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001126
1127 fdm->reg_size = chip->spare_per_sector - ecc_bytes;
1128 if (fdm->reg_size > NFI_FDM_MAX_SIZE)
1129 fdm->reg_size = NFI_FDM_MAX_SIZE;
1130
1131 /* bad block mark storage */
1132 fdm->ecc_size = 1;
1133}
1134
1135static void mtk_nfc_set_bad_mark_ctl(struct mtk_nfc_bad_mark_ctl *bm_ctl,
1136 struct mtd_info *mtd)
1137{
1138 struct nand_chip *nand = mtd_to_nand(mtd);
1139
1140 if (mtd->writesize == 512) {
1141 bm_ctl->bm_swap = mtk_nfc_no_bad_mark_swap;
1142 } else {
1143 bm_ctl->bm_swap = mtk_nfc_bad_mark_swap;
1144 bm_ctl->sec = mtd->writesize / mtk_data_len(nand);
1145 bm_ctl->pos = mtd->writesize % mtk_data_len(nand);
1146 }
1147}
1148
Xiaolei Li7ec4a372017-05-31 16:26:40 +08001149static int mtk_nfc_set_spare_per_sector(u32 *sps, struct mtd_info *mtd)
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001150{
1151 struct nand_chip *nand = mtd_to_nand(mtd);
Xiaolei Li7ec4a372017-05-31 16:26:40 +08001152 struct mtk_nfc *nfc = nand_get_controller_data(nand);
1153 const u8 *spare = nfc->caps->spare_size;
1154 u32 eccsteps, i, closest_spare = 0;
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001155
1156 eccsteps = mtd->writesize / nand->ecc.size;
1157 *sps = mtd->oobsize / eccsteps;
1158
1159 if (nand->ecc.size == 1024)
1160 *sps >>= 1;
1161
Xiaolei Li7ec4a372017-05-31 16:26:40 +08001162 if (*sps < MTK_NFC_MIN_SPARE)
1163 return -EINVAL;
1164
1165 for (i = 0; i < nfc->caps->num_spare_size; i++) {
1166 if (*sps >= spare[i] && spare[i] >= spare[closest_spare]) {
1167 closest_spare = i;
1168 if (*sps == spare[i])
1169 break;
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001170 }
1171 }
1172
Xiaolei Li7ec4a372017-05-31 16:26:40 +08001173 *sps = spare[closest_spare];
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001174
1175 if (nand->ecc.size == 1024)
1176 *sps <<= 1;
Xiaolei Li7ec4a372017-05-31 16:26:40 +08001177
1178 return 0;
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001179}
1180
1181static int mtk_nfc_ecc_init(struct device *dev, struct mtd_info *mtd)
1182{
1183 struct nand_chip *nand = mtd_to_nand(mtd);
Xiaolei Li7ec4a372017-05-31 16:26:40 +08001184 struct mtk_nfc *nfc = nand_get_controller_data(nand);
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001185 u32 spare;
Xiaolei Li7ec4a372017-05-31 16:26:40 +08001186 int free, ret;
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001187
1188 /* support only ecc hw mode */
1189 if (nand->ecc.mode != NAND_ECC_HW) {
1190 dev_err(dev, "ecc.mode not supported\n");
1191 return -EINVAL;
1192 }
1193
1194 /* if optional dt settings not present */
1195 if (!nand->ecc.size || !nand->ecc.strength) {
1196 /* use datasheet requirements */
1197 nand->ecc.strength = nand->ecc_strength_ds;
1198 nand->ecc.size = nand->ecc_step_ds;
1199
1200 /*
1201 * align eccstrength and eccsize
1202 * this controller only supports 512 and 1024 sizes
1203 */
1204 if (nand->ecc.size < 1024) {
RogerCC Linb45ee552017-11-30 22:10:44 +08001205 if (mtd->writesize > 512 &&
1206 nfc->caps->max_sector_size > 512) {
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001207 nand->ecc.size = 1024;
1208 nand->ecc.strength <<= 1;
1209 } else {
1210 nand->ecc.size = 512;
1211 }
1212 } else {
1213 nand->ecc.size = 1024;
1214 }
1215
Xiaolei Li7ec4a372017-05-31 16:26:40 +08001216 ret = mtk_nfc_set_spare_per_sector(&spare, mtd);
1217 if (ret)
1218 return ret;
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001219
1220 /* calculate oob bytes except ecc parity data */
RogerCC Linb45ee552017-11-30 22:10:44 +08001221 free = (nand->ecc.strength * mtk_ecc_get_parity_bits(nfc->ecc)
1222 + 7) >> 3;
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001223 free = spare - free;
1224
1225 /*
1226 * enhance ecc strength if oob left is bigger than max FDM size
1227 * or reduce ecc strength if oob size is not enough for ecc
1228 * parity data.
1229 */
1230 if (free > NFI_FDM_MAX_SIZE) {
1231 spare -= NFI_FDM_MAX_SIZE;
RogerCC Linb45ee552017-11-30 22:10:44 +08001232 nand->ecc.strength = (spare << 3) /
1233 mtk_ecc_get_parity_bits(nfc->ecc);
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001234 } else if (free < 0) {
1235 spare -= NFI_FDM_MIN_SIZE;
RogerCC Linb45ee552017-11-30 22:10:44 +08001236 nand->ecc.strength = (spare << 3) /
1237 mtk_ecc_get_parity_bits(nfc->ecc);
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001238 }
1239 }
1240
Xiaolei Li7ec4a372017-05-31 16:26:40 +08001241 mtk_ecc_adjust_strength(nfc->ecc, &nand->ecc.strength);
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001242
1243 dev_info(dev, "eccsize %d eccstrength %d\n",
1244 nand->ecc.size, nand->ecc.strength);
1245
1246 return 0;
1247}
1248
1249static int mtk_nfc_nand_chip_init(struct device *dev, struct mtk_nfc *nfc,
1250 struct device_node *np)
1251{
1252 struct mtk_nfc_nand_chip *chip;
1253 struct nand_chip *nand;
1254 struct mtd_info *mtd;
1255 int nsels, len;
1256 u32 tmp;
1257 int ret;
1258 int i;
1259
1260 if (!of_get_property(np, "reg", &nsels))
1261 return -ENODEV;
1262
1263 nsels /= sizeof(u32);
1264 if (!nsels || nsels > MTK_NAND_MAX_NSELS) {
1265 dev_err(dev, "invalid reg property size %d\n", nsels);
1266 return -EINVAL;
1267 }
1268
1269 chip = devm_kzalloc(dev, sizeof(*chip) + nsels * sizeof(u8),
1270 GFP_KERNEL);
1271 if (!chip)
1272 return -ENOMEM;
1273
1274 chip->nsels = nsels;
1275 for (i = 0; i < nsels; i++) {
1276 ret = of_property_read_u32_index(np, "reg", i, &tmp);
1277 if (ret) {
1278 dev_err(dev, "reg property failure : %d\n", ret);
1279 return ret;
1280 }
1281 chip->sels[i] = tmp;
1282 }
1283
1284 nand = &chip->nand;
1285 nand->controller = &nfc->controller;
1286
1287 nand_set_flash_node(nand, np);
1288 nand_set_controller_data(nand, nfc);
1289
1290 nand->options |= NAND_USE_BOUNCE_BUFFER | NAND_SUBPAGE_READ;
1291 nand->dev_ready = mtk_nfc_dev_ready;
1292 nand->select_chip = mtk_nfc_select_chip;
1293 nand->write_byte = mtk_nfc_write_byte;
1294 nand->write_buf = mtk_nfc_write_buf;
1295 nand->read_byte = mtk_nfc_read_byte;
1296 nand->read_buf = mtk_nfc_read_buf;
1297 nand->cmd_ctrl = mtk_nfc_cmd_ctrl;
Xiaolei Liedfee362017-06-23 15:12:28 +08001298 nand->setup_data_interface = mtk_nfc_setup_data_interface;
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001299
1300 /* set default mode in case dt entry is missing */
1301 nand->ecc.mode = NAND_ECC_HW;
1302
1303 nand->ecc.write_subpage = mtk_nfc_write_subpage_hwecc;
1304 nand->ecc.write_page_raw = mtk_nfc_write_page_raw;
1305 nand->ecc.write_page = mtk_nfc_write_page_hwecc;
1306 nand->ecc.write_oob_raw = mtk_nfc_write_oob_std;
1307 nand->ecc.write_oob = mtk_nfc_write_oob_std;
1308
1309 nand->ecc.read_subpage = mtk_nfc_read_subpage_hwecc;
1310 nand->ecc.read_page_raw = mtk_nfc_read_page_raw;
1311 nand->ecc.read_page = mtk_nfc_read_page_hwecc;
1312 nand->ecc.read_oob_raw = mtk_nfc_read_oob_std;
1313 nand->ecc.read_oob = mtk_nfc_read_oob_std;
1314
1315 mtd = nand_to_mtd(nand);
1316 mtd->owner = THIS_MODULE;
1317 mtd->dev.parent = dev;
1318 mtd->name = MTK_NAME;
1319 mtd_set_ooblayout(mtd, &mtk_nfc_ooblayout_ops);
1320
1321 mtk_nfc_hw_init(nfc);
1322
1323 ret = nand_scan_ident(mtd, nsels, NULL);
1324 if (ret)
Masahiro Yamadaf0dbe4a2016-11-04 19:43:02 +09001325 return ret;
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001326
1327 /* store bbt magic in page, cause OOB is not protected */
1328 if (nand->bbt_options & NAND_BBT_USE_FLASH)
1329 nand->bbt_options |= NAND_BBT_NO_OOB;
1330
1331 ret = mtk_nfc_ecc_init(dev, mtd);
1332 if (ret)
1333 return -EINVAL;
1334
1335 if (nand->options & NAND_BUSWIDTH_16) {
1336 dev_err(dev, "16bits buswidth not supported");
1337 return -EINVAL;
1338 }
1339
Xiaolei Li7ec4a372017-05-31 16:26:40 +08001340 ret = mtk_nfc_set_spare_per_sector(&chip->spare_per_sector, mtd);
1341 if (ret)
1342 return ret;
1343
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001344 mtk_nfc_set_fdm(&chip->fdm, mtd);
1345 mtk_nfc_set_bad_mark_ctl(&chip->bad_mark, mtd);
1346
1347 len = mtd->writesize + mtd->oobsize;
1348 nfc->buffer = devm_kzalloc(dev, len, GFP_KERNEL);
1349 if (!nfc->buffer)
1350 return -ENOMEM;
1351
1352 ret = nand_scan_tail(mtd);
1353 if (ret)
Masahiro Yamadaf0dbe4a2016-11-04 19:43:02 +09001354 return ret;
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001355
1356 ret = mtd_device_parse_register(mtd, NULL, NULL, NULL, 0);
1357 if (ret) {
1358 dev_err(dev, "mtd parse partition error\n");
1359 nand_release(mtd);
1360 return ret;
1361 }
1362
1363 list_add_tail(&chip->node, &nfc->chips);
1364
1365 return 0;
1366}
1367
1368static int mtk_nfc_nand_chips_init(struct device *dev, struct mtk_nfc *nfc)
1369{
1370 struct device_node *np = dev->of_node;
1371 struct device_node *nand_np;
1372 int ret;
1373
1374 for_each_child_of_node(np, nand_np) {
1375 ret = mtk_nfc_nand_chip_init(dev, nfc, nand_np);
1376 if (ret) {
1377 of_node_put(nand_np);
1378 return ret;
1379 }
1380 }
1381
1382 return 0;
1383}
1384
Xiaolei Li7ec4a372017-05-31 16:26:40 +08001385static const struct mtk_nfc_caps mtk_nfc_caps_mt2701 = {
1386 .spare_size = spare_size_mt2701,
1387 .num_spare_size = 16,
1388 .pageformat_spare_shift = 4,
Xiaolei Liedfee362017-06-23 15:12:28 +08001389 .nfi_clk_div = 1,
RogerCC Linb45ee552017-11-30 22:10:44 +08001390 .max_sector = 16,
1391 .max_sector_size = 1024,
Xiaolei Li7ec4a372017-05-31 16:26:40 +08001392};
1393
Xiaolei Li30ee8092017-05-31 16:26:41 +08001394static const struct mtk_nfc_caps mtk_nfc_caps_mt2712 = {
1395 .spare_size = spare_size_mt2712,
1396 .num_spare_size = 19,
1397 .pageformat_spare_shift = 16,
Xiaolei Liedfee362017-06-23 15:12:28 +08001398 .nfi_clk_div = 2,
RogerCC Linb45ee552017-11-30 22:10:44 +08001399 .max_sector = 16,
1400 .max_sector_size = 1024,
Xiaolei Li30ee8092017-05-31 16:26:41 +08001401};
1402
Xiaolei Li7ec4a372017-05-31 16:26:40 +08001403static const struct of_device_id mtk_nfc_id_table[] = {
1404 {
1405 .compatible = "mediatek,mt2701-nfc",
1406 .data = &mtk_nfc_caps_mt2701,
Xiaolei Li30ee8092017-05-31 16:26:41 +08001407 }, {
1408 .compatible = "mediatek,mt2712-nfc",
1409 .data = &mtk_nfc_caps_mt2712,
Xiaolei Li7ec4a372017-05-31 16:26:40 +08001410 },
1411 {}
1412};
1413MODULE_DEVICE_TABLE(of, mtk_nfc_id_table);
1414
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001415static int mtk_nfc_probe(struct platform_device *pdev)
1416{
1417 struct device *dev = &pdev->dev;
1418 struct device_node *np = dev->of_node;
1419 struct mtk_nfc *nfc;
1420 struct resource *res;
Xiaolei Li7ec4a372017-05-31 16:26:40 +08001421 const struct of_device_id *of_nfc_id = NULL;
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001422 int ret, irq;
1423
1424 nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
1425 if (!nfc)
1426 return -ENOMEM;
1427
1428 spin_lock_init(&nfc->controller.lock);
1429 init_waitqueue_head(&nfc->controller.wq);
1430 INIT_LIST_HEAD(&nfc->chips);
1431
1432 /* probe defer if not ready */
1433 nfc->ecc = of_mtk_ecc_get(np);
1434 if (IS_ERR(nfc->ecc))
1435 return PTR_ERR(nfc->ecc);
1436 else if (!nfc->ecc)
1437 return -ENODEV;
1438
1439 nfc->dev = dev;
1440
1441 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1442 nfc->regs = devm_ioremap_resource(dev, res);
1443 if (IS_ERR(nfc->regs)) {
1444 ret = PTR_ERR(nfc->regs);
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001445 goto release_ecc;
1446 }
1447
1448 nfc->clk.nfi_clk = devm_clk_get(dev, "nfi_clk");
1449 if (IS_ERR(nfc->clk.nfi_clk)) {
1450 dev_err(dev, "no clk\n");
1451 ret = PTR_ERR(nfc->clk.nfi_clk);
1452 goto release_ecc;
1453 }
1454
1455 nfc->clk.pad_clk = devm_clk_get(dev, "pad_clk");
1456 if (IS_ERR(nfc->clk.pad_clk)) {
1457 dev_err(dev, "no pad clk\n");
1458 ret = PTR_ERR(nfc->clk.pad_clk);
1459 goto release_ecc;
1460 }
1461
1462 ret = mtk_nfc_enable_clk(dev, &nfc->clk);
1463 if (ret)
1464 goto release_ecc;
1465
1466 irq = platform_get_irq(pdev, 0);
1467 if (irq < 0) {
1468 dev_err(dev, "no nfi irq resource\n");
1469 ret = -EINVAL;
1470 goto clk_disable;
1471 }
1472
1473 ret = devm_request_irq(dev, irq, mtk_nfc_irq, 0x0, "mtk-nand", nfc);
1474 if (ret) {
1475 dev_err(dev, "failed to request nfi irq\n");
1476 goto clk_disable;
1477 }
1478
1479 ret = dma_set_mask(dev, DMA_BIT_MASK(32));
1480 if (ret) {
1481 dev_err(dev, "failed to set dma mask\n");
1482 goto clk_disable;
1483 }
1484
Xiaolei Li7ec4a372017-05-31 16:26:40 +08001485 of_nfc_id = of_match_device(mtk_nfc_id_table, &pdev->dev);
1486 if (!of_nfc_id) {
1487 ret = -ENODEV;
1488 goto clk_disable;
1489 }
1490
1491 nfc->caps = of_nfc_id->data;
1492
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001493 platform_set_drvdata(pdev, nfc);
1494
1495 ret = mtk_nfc_nand_chips_init(dev, nfc);
1496 if (ret) {
1497 dev_err(dev, "failed to init nand chips\n");
1498 goto clk_disable;
1499 }
1500
1501 return 0;
1502
1503clk_disable:
1504 mtk_nfc_disable_clk(&nfc->clk);
1505
1506release_ecc:
1507 mtk_ecc_release(nfc->ecc);
1508
1509 return ret;
1510}
1511
1512static int mtk_nfc_remove(struct platform_device *pdev)
1513{
1514 struct mtk_nfc *nfc = platform_get_drvdata(pdev);
1515 struct mtk_nfc_nand_chip *chip;
1516
1517 while (!list_empty(&nfc->chips)) {
1518 chip = list_first_entry(&nfc->chips, struct mtk_nfc_nand_chip,
1519 node);
1520 nand_release(nand_to_mtd(&chip->nand));
1521 list_del(&chip->node);
1522 }
1523
1524 mtk_ecc_release(nfc->ecc);
1525 mtk_nfc_disable_clk(&nfc->clk);
1526
1527 return 0;
1528}
1529
1530#ifdef CONFIG_PM_SLEEP
1531static int mtk_nfc_suspend(struct device *dev)
1532{
1533 struct mtk_nfc *nfc = dev_get_drvdata(dev);
1534
1535 mtk_nfc_disable_clk(&nfc->clk);
1536
1537 return 0;
1538}
1539
1540static int mtk_nfc_resume(struct device *dev)
1541{
1542 struct mtk_nfc *nfc = dev_get_drvdata(dev);
1543 struct mtk_nfc_nand_chip *chip;
1544 struct nand_chip *nand;
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001545 int ret;
1546 u32 i;
1547
1548 udelay(200);
1549
1550 ret = mtk_nfc_enable_clk(dev, &nfc->clk);
1551 if (ret)
1552 return ret;
1553
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001554 /* reset NAND chip if VCC was powered off */
1555 list_for_each_entry(chip, &nfc->chips, node) {
1556 nand = &chip->nand;
Xiaolei Lif8831992017-11-02 10:05:07 +08001557 for (i = 0; i < chip->nsels; i++)
1558 nand_reset(nand, i);
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001559 }
1560
1561 return 0;
1562}
1563
1564static SIMPLE_DEV_PM_OPS(mtk_nfc_pm_ops, mtk_nfc_suspend, mtk_nfc_resume);
1565#endif
1566
Jorge Ramirez-Ortiz1d6b1e42016-06-14 11:50:51 -04001567static struct platform_driver mtk_nfc_driver = {
1568 .probe = mtk_nfc_probe,
1569 .remove = mtk_nfc_remove,
1570 .driver = {
1571 .name = MTK_NAME,
1572 .of_match_table = mtk_nfc_id_table,
1573#ifdef CONFIG_PM_SLEEP
1574 .pm = &mtk_nfc_pm_ops,
1575#endif
1576 },
1577};
1578
1579module_platform_driver(mtk_nfc_driver);
1580
1581MODULE_LICENSE("GPL");
1582MODULE_AUTHOR("Xiaolei Li <xiaolei.li@mediatek.com>");
1583MODULE_DESCRIPTION("MTK Nand Flash Controller Driver");