blob: bad3b8ad5e0a16f8331c5118bff9174873529716 [file] [log] [blame]
Masahiro Yamadaf1bf52e2018-08-20 12:26:36 +09001// SPDX-License-Identifier: GPL-2.0
Jason Robertsce082592010-05-13 15:57:33 +01002/*
3 * NAND Flash Controller Device Driver
4 * Copyright © 2009-2010, Intel Corporation and its suppliers.
5 *
Masahiro Yamadaf1bf52e2018-08-20 12:26:36 +09006 * Copyright (c) 2017 Socionext Inc.
7 * Reworked by Masahiro Yamada <yamada.masahiro@socionext.com>
Jason Robertsce082592010-05-13 15:57:33 +01008 */
Masahiro Yamadada4734b2017-09-22 12:46:40 +09009
Masahiro Yamadae0d53b32017-09-22 12:46:43 +090010#include <linux/bitfield.h>
Masahiro Yamadada4734b2017-09-22 12:46:40 +090011#include <linux/completion.h>
Jamie Iles84457942011-05-06 15:28:55 +010012#include <linux/dma-mapping.h>
Masahiro Yamadada4734b2017-09-22 12:46:40 +090013#include <linux/interrupt.h>
14#include <linux/io.h>
Jason Robertsce082592010-05-13 15:57:33 +010015#include <linux/module.h>
Masahiro Yamadada4734b2017-09-22 12:46:40 +090016#include <linux/mtd/mtd.h>
17#include <linux/mtd/rawnand.h>
Masahiro Yamada7d370b22017-06-13 22:45:48 +090018#include <linux/slab.h>
Masahiro Yamadada4734b2017-09-22 12:46:40 +090019#include <linux/spinlock.h>
Jason Robertsce082592010-05-13 15:57:33 +010020
21#include "denali.h"
22
Jason Robertsce082592010-05-13 15:57:33 +010023#define DENALI_NAND_NAME "denali-nand"
Masahiro Yamada0d55c662018-09-28 13:16:01 +090024#define DENALI_DEFAULT_OOB_SKIP_BYTES 8
Jason Robertsce082592010-05-13 15:57:33 +010025
Masahiro Yamada29c4dd92017-09-22 12:46:48 +090026/* for Indexed Addressing */
27#define DENALI_INDEXED_CTRL 0x00
28#define DENALI_INDEXED_DATA 0x10
Jason Robertsce082592010-05-13 15:57:33 +010029
Masahiro Yamada0d3a9662017-06-16 14:36:39 +090030#define DENALI_MAP00 (0 << 26) /* direct access to buffer */
31#define DENALI_MAP01 (1 << 26) /* read/write pages in PIO */
32#define DENALI_MAP10 (2 << 26) /* high-level control plane */
33#define DENALI_MAP11 (3 << 26) /* direct controller access */
34
35/* MAP11 access cycle type */
36#define DENALI_MAP11_CMD ((DENALI_MAP11) | 0) /* command cycle */
37#define DENALI_MAP11_ADDR ((DENALI_MAP11) | 1) /* address cycle */
38#define DENALI_MAP11_DATA ((DENALI_MAP11) | 2) /* data cycle */
39
40/* MAP10 commands */
41#define DENALI_ERASE 0x01
42
43#define DENALI_BANK(denali) ((denali)->active_bank << 24)
44
45#define DENALI_INVALID_BANK -1
Masahiro Yamadac19e31d2017-06-13 22:45:38 +090046#define DENALI_NR_BANKS 4
47
Boris BREZILLON442f201b2015-12-11 15:06:00 +010048static inline struct denali_nand_info *mtd_to_denali(struct mtd_info *mtd)
49{
50 return container_of(mtd_to_nand(mtd), struct denali_nand_info, nand);
51}
Jason Robertsce082592010-05-13 15:57:33 +010052
Masahiro Yamada29c4dd92017-09-22 12:46:48 +090053/*
54 * Direct Addressing - the slave address forms the control information (command
55 * type, bank, block, and page address). The slave data is the actual data to
56 * be transferred. This mode requires 28 bits of address region allocated.
57 */
58static u32 denali_direct_read(struct denali_nand_info *denali, u32 addr)
Jason Robertsce082592010-05-13 15:57:33 +010059{
Masahiro Yamada29c4dd92017-09-22 12:46:48 +090060 return ioread32(denali->host + addr);
61}
62
63static void denali_direct_write(struct denali_nand_info *denali, u32 addr,
64 u32 data)
65{
66 iowrite32(data, denali->host + addr);
67}
68
69/*
70 * Indexed Addressing - address translation module intervenes in passing the
71 * control information. This mode reduces the required address range. The
72 * control information and transferred data are latched by the registers in
73 * the translation module.
74 */
75static u32 denali_indexed_read(struct denali_nand_info *denali, u32 addr)
76{
77 iowrite32(addr, denali->host + DENALI_INDEXED_CTRL);
78 return ioread32(denali->host + DENALI_INDEXED_DATA);
79}
80
81static void denali_indexed_write(struct denali_nand_info *denali, u32 addr,
82 u32 data)
83{
84 iowrite32(addr, denali->host + DENALI_INDEXED_CTRL);
85 iowrite32(data, denali->host + DENALI_INDEXED_DATA);
Jason Robertsce082592010-05-13 15:57:33 +010086}
87
Masahiro Yamada43914a22014-09-09 11:01:51 +090088/*
Jamie Ilesc89eeda2011-05-06 15:28:57 +010089 * Use the configuration feature register to determine the maximum number of
90 * banks that the hardware supports.
91 */
Masahiro Yamada3ac6c712017-09-22 12:46:39 +090092static void denali_detect_max_banks(struct denali_nand_info *denali)
Jamie Ilesc89eeda2011-05-06 15:28:57 +010093{
Masahiro Yamada0d3a9662017-06-16 14:36:39 +090094 uint32_t features = ioread32(denali->reg + FEATURES);
Jamie Ilesc89eeda2011-05-06 15:28:57 +010095
Masahiro Yamada8e4cbf72017-09-22 12:46:44 +090096 denali->max_banks = 1 << FIELD_GET(FEATURES__N_BANKS, features);
Masahiro Yamadae7beeee2017-03-30 15:45:57 +090097
98 /* the encoding changed from rev 5.0 to 5.1 */
99 if (denali->revision < 0x0501)
100 denali->max_banks <<= 1;
Jamie Ilesc89eeda2011-05-06 15:28:57 +0100101}
102
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900103static void denali_enable_irq(struct denali_nand_info *denali)
Jason Robertsce082592010-05-13 15:57:33 +0100104{
Jamie Iles9589bf52011-05-06 15:28:56 +0100105 int i;
106
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900107 for (i = 0; i < DENALI_NR_BANKS; i++)
Masahiro Yamada0d3a9662017-06-16 14:36:39 +0900108 iowrite32(U32_MAX, denali->reg + INTR_EN(i));
109 iowrite32(GLOBAL_INT_EN_FLAG, denali->reg + GLOBAL_INT_ENABLE);
Jason Robertsce082592010-05-13 15:57:33 +0100110}
111
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900112static void denali_disable_irq(struct denali_nand_info *denali)
Jason Robertsce082592010-05-13 15:57:33 +0100113{
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900114 int i;
115
116 for (i = 0; i < DENALI_NR_BANKS; i++)
Masahiro Yamada0d3a9662017-06-16 14:36:39 +0900117 iowrite32(0, denali->reg + INTR_EN(i));
118 iowrite32(0, denali->reg + GLOBAL_INT_ENABLE);
Jason Robertsce082592010-05-13 15:57:33 +0100119}
120
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900121static void denali_clear_irq(struct denali_nand_info *denali,
122 int bank, uint32_t irq_status)
Jason Robertsce082592010-05-13 15:57:33 +0100123{
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900124 /* write one to clear bits */
Masahiro Yamada0d3a9662017-06-16 14:36:39 +0900125 iowrite32(irq_status, denali->reg + INTR_STATUS(bank));
Jason Robertsce082592010-05-13 15:57:33 +0100126}
127
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900128static void denali_clear_irq_all(struct denali_nand_info *denali)
Jason Robertsce082592010-05-13 15:57:33 +0100129{
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900130 int i;
Masahiro Yamada5637b692014-09-09 11:01:52 +0900131
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900132 for (i = 0; i < DENALI_NR_BANKS; i++)
133 denali_clear_irq(denali, i, U32_MAX);
Jason Robertsce082592010-05-13 15:57:33 +0100134}
135
Jason Robertsce082592010-05-13 15:57:33 +0100136static irqreturn_t denali_isr(int irq, void *dev_id)
137{
138 struct denali_nand_info *denali = dev_id;
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900139 irqreturn_t ret = IRQ_NONE;
Masahiro Yamada5637b692014-09-09 11:01:52 +0900140 uint32_t irq_status;
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900141 int i;
Jason Robertsce082592010-05-13 15:57:33 +0100142
143 spin_lock(&denali->irq_lock);
144
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900145 for (i = 0; i < DENALI_NR_BANKS; i++) {
Masahiro Yamada0d3a9662017-06-16 14:36:39 +0900146 irq_status = ioread32(denali->reg + INTR_STATUS(i));
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900147 if (irq_status)
148 ret = IRQ_HANDLED;
149
150 denali_clear_irq(denali, i, irq_status);
151
Masahiro Yamada0d3a9662017-06-16 14:36:39 +0900152 if (i != denali->active_bank)
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900153 continue;
154
155 denali->irq_status |= irq_status;
156
157 if (denali->irq_status & denali->irq_mask)
Jason Robertsce082592010-05-13 15:57:33 +0100158 complete(&denali->complete);
Jason Robertsce082592010-05-13 15:57:33 +0100159 }
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900160
Jason Robertsce082592010-05-13 15:57:33 +0100161 spin_unlock(&denali->irq_lock);
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900162
163 return ret;
Jason Robertsce082592010-05-13 15:57:33 +0100164}
Jason Robertsce082592010-05-13 15:57:33 +0100165
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900166static void denali_reset_irq(struct denali_nand_info *denali)
Jason Robertsce082592010-05-13 15:57:33 +0100167{
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900168 unsigned long flags;
Jason Robertsce082592010-05-13 15:57:33 +0100169
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900170 spin_lock_irqsave(&denali->irq_lock, flags);
171 denali->irq_status = 0;
172 denali->irq_mask = 0;
173 spin_unlock_irqrestore(&denali->irq_lock, flags);
174}
Jason Robertsce082592010-05-13 15:57:33 +0100175
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900176static uint32_t denali_wait_for_irq(struct denali_nand_info *denali,
177 uint32_t irq_mask)
178{
179 unsigned long time_left, flags;
180 uint32_t irq_status;
Masahiro Yamada81254502014-09-16 20:04:25 +0900181
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900182 spin_lock_irqsave(&denali->irq_lock, flags);
Jason Robertsce082592010-05-13 15:57:33 +0100183
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900184 irq_status = denali->irq_status;
Jason Robertsce082592010-05-13 15:57:33 +0100185
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900186 if (irq_mask & irq_status) {
187 /* return immediately if the IRQ has already happened. */
188 spin_unlock_irqrestore(&denali->irq_lock, flags);
189 return irq_status;
Jason Robertsce082592010-05-13 15:57:33 +0100190 }
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900191
192 denali->irq_mask = irq_mask;
193 reinit_completion(&denali->complete);
194 spin_unlock_irqrestore(&denali->irq_lock, flags);
195
196 time_left = wait_for_completion_timeout(&denali->complete,
197 msecs_to_jiffies(1000));
198 if (!time_left) {
199 dev_err(denali->dev, "timeout while waiting for irq 0x%x\n",
Masahiro Yamadafdd4d082017-09-22 12:46:42 +0900200 irq_mask);
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900201 return 0;
202 }
203
204 return denali->irq_status;
205}
206
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900207static uint32_t denali_check_irq(struct denali_nand_info *denali)
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900208{
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900209 unsigned long flags;
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900210 uint32_t irq_status;
211
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900212 spin_lock_irqsave(&denali->irq_lock, flags);
213 irq_status = denali->irq_status;
214 spin_unlock_irqrestore(&denali->irq_lock, flags);
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900215
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900216 return irq_status;
Jason Robertsce082592010-05-13 15:57:33 +0100217}
218
Boris Brezillon7e534322018-09-06 14:05:22 +0200219static void denali_read_buf(struct nand_chip *chip, uint8_t *buf, int len)
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900220{
Boris Brezillon7e534322018-09-06 14:05:22 +0200221 struct mtd_info *mtd = nand_to_mtd(chip);
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900222 struct denali_nand_info *denali = mtd_to_denali(mtd);
Masahiro Yamada29c4dd92017-09-22 12:46:48 +0900223 u32 addr = DENALI_MAP11_DATA | DENALI_BANK(denali);
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900224 int i;
225
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900226 for (i = 0; i < len; i++)
Masahiro Yamada29c4dd92017-09-22 12:46:48 +0900227 buf[i] = denali->host_read(denali, addr);
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900228}
229
Boris Brezillonc0739d82018-09-06 14:05:23 +0200230static void denali_write_buf(struct nand_chip *chip, const uint8_t *buf,
231 int len)
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900232{
Boris Brezillonc0739d82018-09-06 14:05:23 +0200233 struct denali_nand_info *denali = mtd_to_denali(nand_to_mtd(chip));
Masahiro Yamada29c4dd92017-09-22 12:46:48 +0900234 u32 addr = DENALI_MAP11_DATA | DENALI_BANK(denali);
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900235 int i;
236
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900237 for (i = 0; i < len; i++)
Masahiro Yamada29c4dd92017-09-22 12:46:48 +0900238 denali->host_write(denali, addr, buf[i]);
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900239}
240
Boris Brezillon7e534322018-09-06 14:05:22 +0200241static void denali_read_buf16(struct nand_chip *chip, uint8_t *buf, int len)
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900242{
Boris Brezillon7e534322018-09-06 14:05:22 +0200243 struct denali_nand_info *denali = mtd_to_denali(nand_to_mtd(chip));
Masahiro Yamada29c4dd92017-09-22 12:46:48 +0900244 u32 addr = DENALI_MAP11_DATA | DENALI_BANK(denali);
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900245 uint16_t *buf16 = (uint16_t *)buf;
246 int i;
247
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900248 for (i = 0; i < len / 2; i++)
Masahiro Yamada29c4dd92017-09-22 12:46:48 +0900249 buf16[i] = denali->host_read(denali, addr);
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900250}
251
Boris Brezillonc0739d82018-09-06 14:05:23 +0200252static void denali_write_buf16(struct nand_chip *chip, const uint8_t *buf,
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900253 int len)
254{
Boris Brezillonc0739d82018-09-06 14:05:23 +0200255 struct denali_nand_info *denali = mtd_to_denali(nand_to_mtd(chip));
Masahiro Yamada29c4dd92017-09-22 12:46:48 +0900256 u32 addr = DENALI_MAP11_DATA | DENALI_BANK(denali);
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900257 const uint16_t *buf16 = (const uint16_t *)buf;
258 int i;
259
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900260 for (i = 0; i < len / 2; i++)
Masahiro Yamada29c4dd92017-09-22 12:46:48 +0900261 denali->host_write(denali, addr, buf16[i]);
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900262}
263
Boris Brezillon7e534322018-09-06 14:05:22 +0200264static uint8_t denali_read_byte(struct nand_chip *chip)
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900265{
266 uint8_t byte;
267
Boris Brezillon7e534322018-09-06 14:05:22 +0200268 denali_read_buf(chip, &byte, 1);
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900269
270 return byte;
271}
272
Boris Brezillonc0739d82018-09-06 14:05:23 +0200273static void denali_write_byte(struct nand_chip *chip, uint8_t byte)
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900274{
Boris Brezillonc0739d82018-09-06 14:05:23 +0200275 denali_write_buf(chip, &byte, 1);
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900276}
277
Boris Brezillon0f808c12018-09-06 14:05:26 +0200278static void denali_cmd_ctrl(struct nand_chip *chip, int dat, unsigned int ctrl)
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900279{
Boris Brezillon0f808c12018-09-06 14:05:26 +0200280 struct denali_nand_info *denali = mtd_to_denali(nand_to_mtd(chip));
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900281 uint32_t type;
282
283 if (ctrl & NAND_CLE)
Masahiro Yamada0d3a9662017-06-16 14:36:39 +0900284 type = DENALI_MAP11_CMD;
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900285 else if (ctrl & NAND_ALE)
Masahiro Yamada0d3a9662017-06-16 14:36:39 +0900286 type = DENALI_MAP11_ADDR;
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900287 else
288 return;
289
290 /*
Boris Brezillon8395b752018-09-07 00:38:37 +0200291 * Some commands are followed by chip->legacy.dev_ready or
292 * chip->legacy.waitfunc.
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900293 * irq_status must be cleared here to catch the R/B# interrupt later.
294 */
295 if (ctrl & NAND_CTRL_CHANGE)
296 denali_reset_irq(denali);
297
Masahiro Yamada29c4dd92017-09-22 12:46:48 +0900298 denali->host_write(denali, DENALI_BANK(denali) | type, dat);
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900299}
300
Boris Brezillon50a487e2018-09-06 14:05:27 +0200301static int denali_dev_ready(struct nand_chip *chip)
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900302{
Boris Brezillon50a487e2018-09-06 14:05:27 +0200303 struct denali_nand_info *denali = mtd_to_denali(nand_to_mtd(chip));
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900304
305 return !!(denali_check_irq(denali) & INTR__INT_ACT);
306}
307
Masahiro Yamadad29109b2017-03-30 15:45:51 +0900308static int denali_check_erased_page(struct mtd_info *mtd,
309 struct nand_chip *chip, uint8_t *buf,
310 unsigned long uncor_ecc_flags,
311 unsigned int max_bitflips)
Jason Robertsce082592010-05-13 15:57:33 +0100312{
Boris Brezillon8c677542017-12-05 12:09:28 +0100313 struct denali_nand_info *denali = mtd_to_denali(mtd);
314 uint8_t *ecc_code = chip->oob_poi + denali->oob_skip_bytes;
Masahiro Yamadad29109b2017-03-30 15:45:51 +0900315 int ecc_steps = chip->ecc.steps;
316 int ecc_size = chip->ecc.size;
317 int ecc_bytes = chip->ecc.bytes;
Boris Brezillon8c677542017-12-05 12:09:28 +0100318 int i, stat;
Masahiro Yamadad29109b2017-03-30 15:45:51 +0900319
320 for (i = 0; i < ecc_steps; i++) {
321 if (!(uncor_ecc_flags & BIT(i)))
322 continue;
323
324 stat = nand_check_erased_ecc_chunk(buf, ecc_size,
325 ecc_code, ecc_bytes,
326 NULL, 0,
327 chip->ecc.strength);
328 if (stat < 0) {
329 mtd->ecc_stats.failed++;
330 } else {
331 mtd->ecc_stats.corrected += stat;
332 max_bitflips = max_t(unsigned int, max_bitflips, stat);
333 }
334
335 buf += ecc_size;
336 ecc_code += ecc_bytes;
337 }
338
339 return max_bitflips;
Jason Robertsce082592010-05-13 15:57:33 +0100340}
Masahiro Yamadad29109b2017-03-30 15:45:51 +0900341
Masahiro Yamada24715c72017-03-30 15:45:52 +0900342static int denali_hw_ecc_fixup(struct mtd_info *mtd,
343 struct denali_nand_info *denali,
344 unsigned long *uncor_ecc_flags)
345{
346 struct nand_chip *chip = mtd_to_nand(mtd);
Masahiro Yamada0d3a9662017-06-16 14:36:39 +0900347 int bank = denali->active_bank;
Masahiro Yamada24715c72017-03-30 15:45:52 +0900348 uint32_t ecc_cor;
349 unsigned int max_bitflips;
350
Masahiro Yamada0d3a9662017-06-16 14:36:39 +0900351 ecc_cor = ioread32(denali->reg + ECC_COR_INFO(bank));
Masahiro Yamada24715c72017-03-30 15:45:52 +0900352 ecc_cor >>= ECC_COR_INFO__SHIFT(bank);
353
354 if (ecc_cor & ECC_COR_INFO__UNCOR_ERR) {
355 /*
356 * This flag is set when uncorrectable error occurs at least in
357 * one ECC sector. We can not know "how many sectors", or
358 * "which sector(s)". We need erase-page check for all sectors.
359 */
360 *uncor_ecc_flags = GENMASK(chip->ecc.steps - 1, 0);
361 return 0;
362 }
363
Masahiro Yamada8e4cbf72017-09-22 12:46:44 +0900364 max_bitflips = FIELD_GET(ECC_COR_INFO__MAX_ERRORS, ecc_cor);
Masahiro Yamada24715c72017-03-30 15:45:52 +0900365
366 /*
367 * The register holds the maximum of per-sector corrected bitflips.
368 * This is suitable for the return value of the ->read_page() callback.
369 * Unfortunately, we can not know the total number of corrected bits in
370 * the page. Increase the stats by max_bitflips. (compromised solution)
371 */
372 mtd->ecc_stats.corrected += max_bitflips;
373
374 return max_bitflips;
375}
376
Masahiro Yamada24715c72017-03-30 15:45:52 +0900377static int denali_sw_ecc_fixup(struct mtd_info *mtd,
378 struct denali_nand_info *denali,
379 unsigned long *uncor_ecc_flags, uint8_t *buf)
Jason Robertsce082592010-05-13 15:57:33 +0100380{
Masahiro Yamada7de117f2017-06-07 20:52:12 +0900381 unsigned int ecc_size = denali->nand.ecc.size;
Mike Dunn3f91e942012-04-25 12:06:09 -0700382 unsigned int bitflips = 0;
Masahiro Yamada20d48592017-03-30 15:45:50 +0900383 unsigned int max_bitflips = 0;
384 uint32_t err_addr, err_cor_info;
385 unsigned int err_byte, err_sector, err_device;
386 uint8_t err_cor_value;
387 unsigned int prev_sector = 0;
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900388 uint32_t irq_status;
Jason Robertsce082592010-05-13 15:57:33 +0100389
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900390 denali_reset_irq(denali);
Jason Robertsce082592010-05-13 15:57:33 +0100391
Masahiro Yamada20d48592017-03-30 15:45:50 +0900392 do {
Masahiro Yamada0d3a9662017-06-16 14:36:39 +0900393 err_addr = ioread32(denali->reg + ECC_ERROR_ADDRESS);
Masahiro Yamadae0d53b32017-09-22 12:46:43 +0900394 err_sector = FIELD_GET(ECC_ERROR_ADDRESS__SECTOR, err_addr);
395 err_byte = FIELD_GET(ECC_ERROR_ADDRESS__OFFSET, err_addr);
Jason Robertsce082592010-05-13 15:57:33 +0100396
Masahiro Yamada0d3a9662017-06-16 14:36:39 +0900397 err_cor_info = ioread32(denali->reg + ERR_CORRECTION_INFO);
Masahiro Yamadae0d53b32017-09-22 12:46:43 +0900398 err_cor_value = FIELD_GET(ERR_CORRECTION_INFO__BYTE,
399 err_cor_info);
400 err_device = FIELD_GET(ERR_CORRECTION_INFO__DEVICE,
401 err_cor_info);
Jason Robertsce082592010-05-13 15:57:33 +0100402
Masahiro Yamada20d48592017-03-30 15:45:50 +0900403 /* reset the bitflip counter when crossing ECC sector */
404 if (err_sector != prev_sector)
405 bitflips = 0;
Masahiro Yamada81254502014-09-16 20:04:25 +0900406
Masahiro Yamadae0d53b32017-09-22 12:46:43 +0900407 if (err_cor_info & ERR_CORRECTION_INFO__UNCOR) {
Masahiro Yamada20d48592017-03-30 15:45:50 +0900408 /*
Masahiro Yamadad29109b2017-03-30 15:45:51 +0900409 * Check later if this is a real ECC error, or
410 * an erased sector.
Masahiro Yamada20d48592017-03-30 15:45:50 +0900411 */
Masahiro Yamadad29109b2017-03-30 15:45:51 +0900412 *uncor_ecc_flags |= BIT(err_sector);
Masahiro Yamada7de117f2017-06-07 20:52:12 +0900413 } else if (err_byte < ecc_size) {
Masahiro Yamada20d48592017-03-30 15:45:50 +0900414 /*
Masahiro Yamada7de117f2017-06-07 20:52:12 +0900415 * If err_byte is larger than ecc_size, means error
Masahiro Yamada20d48592017-03-30 15:45:50 +0900416 * happened in OOB, so we ignore it. It's no need for
417 * us to correct it err_device is represented the NAND
418 * error bits are happened in if there are more than
419 * one NAND connected.
420 */
421 int offset;
422 unsigned int flips_in_byte;
423
Masahiro Yamada7de117f2017-06-07 20:52:12 +0900424 offset = (err_sector * ecc_size + err_byte) *
Masahiro Yamada0d3a9662017-06-16 14:36:39 +0900425 denali->devs_per_cs + err_device;
Masahiro Yamada20d48592017-03-30 15:45:50 +0900426
427 /* correct the ECC error */
428 flips_in_byte = hweight8(buf[offset] ^ err_cor_value);
429 buf[offset] ^= err_cor_value;
430 mtd->ecc_stats.corrected += flips_in_byte;
431 bitflips += flips_in_byte;
432
433 max_bitflips = max(max_bitflips, bitflips);
434 }
435
436 prev_sector = err_sector;
Masahiro Yamadae0d53b32017-09-22 12:46:43 +0900437 } while (!(err_cor_info & ERR_CORRECTION_INFO__LAST_ERR));
Masahiro Yamada20d48592017-03-30 15:45:50 +0900438
439 /*
Masahiro Yamada8582a032017-09-22 12:46:45 +0900440 * Once handle all ECC errors, controller will trigger an
441 * ECC_TRANSACTION_DONE interrupt.
Masahiro Yamada20d48592017-03-30 15:45:50 +0900442 */
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900443 irq_status = denali_wait_for_irq(denali, INTR__ECC_TRANSACTION_DONE);
444 if (!(irq_status & INTR__ECC_TRANSACTION_DONE))
445 return -EIO;
Masahiro Yamada20d48592017-03-30 15:45:50 +0900446
447 return max_bitflips;
Jason Robertsce082592010-05-13 15:57:33 +0100448}
449
Masahiro Yamada2291cb82017-06-13 22:45:42 +0900450static void denali_setup_dma64(struct denali_nand_info *denali,
Masahiro Yamada96a376b2017-06-13 22:45:44 +0900451 dma_addr_t dma_addr, int page, int write)
Masahiro Yamada210a2c82017-03-30 15:45:54 +0900452{
453 uint32_t mode;
454 const int page_count = 1;
Masahiro Yamada210a2c82017-03-30 15:45:54 +0900455
Masahiro Yamada0d3a9662017-06-16 14:36:39 +0900456 mode = DENALI_MAP10 | DENALI_BANK(denali) | page;
Masahiro Yamada210a2c82017-03-30 15:45:54 +0900457
458 /* DMA is a three step process */
459
460 /*
461 * 1. setup transfer type, interrupt when complete,
462 * burst len = 64 bytes, the number of pages
463 */
Masahiro Yamada29c4dd92017-09-22 12:46:48 +0900464 denali->host_write(denali, mode,
465 0x01002000 | (64 << 16) | (write << 8) | page_count);
Masahiro Yamada210a2c82017-03-30 15:45:54 +0900466
467 /* 2. set memory low address */
Masahiro Yamada29c4dd92017-09-22 12:46:48 +0900468 denali->host_write(denali, mode, lower_32_bits(dma_addr));
Masahiro Yamada210a2c82017-03-30 15:45:54 +0900469
470 /* 3. set memory high address */
Masahiro Yamada29c4dd92017-09-22 12:46:48 +0900471 denali->host_write(denali, mode, upper_32_bits(dma_addr));
Masahiro Yamada210a2c82017-03-30 15:45:54 +0900472}
473
Masahiro Yamada2291cb82017-06-13 22:45:42 +0900474static void denali_setup_dma32(struct denali_nand_info *denali,
Masahiro Yamada96a376b2017-06-13 22:45:44 +0900475 dma_addr_t dma_addr, int page, int write)
Jason Robertsce082592010-05-13 15:57:33 +0100476{
Masahiro Yamada5637b692014-09-09 11:01:52 +0900477 uint32_t mode;
Jason Robertsce082592010-05-13 15:57:33 +0100478 const int page_count = 1;
Jason Robertsce082592010-05-13 15:57:33 +0100479
Masahiro Yamada0d3a9662017-06-16 14:36:39 +0900480 mode = DENALI_MAP10 | DENALI_BANK(denali);
Jason Robertsce082592010-05-13 15:57:33 +0100481
482 /* DMA is a four step process */
483
484 /* 1. setup transfer type and # of pages */
Masahiro Yamada29c4dd92017-09-22 12:46:48 +0900485 denali->host_write(denali, mode | page,
486 0x2000 | (write << 8) | page_count);
Jason Robertsce082592010-05-13 15:57:33 +0100487
488 /* 2. set memory high address bits 23:8 */
Masahiro Yamada29c4dd92017-09-22 12:46:48 +0900489 denali->host_write(denali, mode | ((dma_addr >> 16) << 8), 0x2200);
Jason Robertsce082592010-05-13 15:57:33 +0100490
491 /* 3. set memory low address bits 23:8 */
Masahiro Yamada29c4dd92017-09-22 12:46:48 +0900492 denali->host_write(denali, mode | ((dma_addr & 0xffff) << 8), 0x2300);
Jason Robertsce082592010-05-13 15:57:33 +0100493
Masahiro Yamada43914a22014-09-09 11:01:51 +0900494 /* 4. interrupt when complete, burst len = 64 bytes */
Masahiro Yamada29c4dd92017-09-22 12:46:48 +0900495 denali->host_write(denali, mode | 0x14000, 0x2400);
Jason Robertsce082592010-05-13 15:57:33 +0100496}
497
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900498static int denali_pio_read(struct denali_nand_info *denali, void *buf,
499 size_t size, int page, int raw)
Jason Robertsce082592010-05-13 15:57:33 +0100500{
Masahiro Yamada29c4dd92017-09-22 12:46:48 +0900501 u32 addr = DENALI_MAP01 | DENALI_BANK(denali) | page;
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900502 uint32_t *buf32 = (uint32_t *)buf;
503 uint32_t irq_status, ecc_err_mask;
504 int i;
Masahiro Yamadab21ff822017-06-13 22:45:35 +0900505
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900506 if (denali->caps & DENALI_CAP_HW_ECC_FIXUP)
507 ecc_err_mask = INTR__ECC_UNCOR_ERR;
508 else
509 ecc_err_mask = INTR__ECC_ERR;
Jason Robertsce082592010-05-13 15:57:33 +0100510
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900511 denali_reset_irq(denali);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900512
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900513 for (i = 0; i < size / 4; i++)
Masahiro Yamada29c4dd92017-09-22 12:46:48 +0900514 *buf32++ = denali->host_read(denali, addr);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900515
516 irq_status = denali_wait_for_irq(denali, INTR__PAGE_XFER_INC);
517 if (!(irq_status & INTR__PAGE_XFER_INC))
518 return -EIO;
519
Masahiro Yamada57a4d8b2017-06-13 22:45:46 +0900520 if (irq_status & INTR__ERASED_PAGE)
521 memset(buf, 0xff, size);
522
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900523 return irq_status & ecc_err_mask ? -EBADMSG : 0;
524}
525
526static int denali_pio_write(struct denali_nand_info *denali,
527 const void *buf, size_t size, int page, int raw)
528{
Masahiro Yamada29c4dd92017-09-22 12:46:48 +0900529 u32 addr = DENALI_MAP01 | DENALI_BANK(denali) | page;
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900530 const uint32_t *buf32 = (uint32_t *)buf;
531 uint32_t irq_status;
532 int i;
533
534 denali_reset_irq(denali);
535
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900536 for (i = 0; i < size / 4; i++)
Masahiro Yamada29c4dd92017-09-22 12:46:48 +0900537 denali->host_write(denali, addr, *buf32++);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900538
539 irq_status = denali_wait_for_irq(denali,
540 INTR__PROGRAM_COMP | INTR__PROGRAM_FAIL);
541 if (!(irq_status & INTR__PROGRAM_COMP))
542 return -EIO;
543
544 return 0;
545}
546
547static int denali_pio_xfer(struct denali_nand_info *denali, void *buf,
548 size_t size, int page, int raw, int write)
549{
550 if (write)
551 return denali_pio_write(denali, buf, size, page, raw);
552 else
553 return denali_pio_read(denali, buf, size, page, raw);
554}
555
556static int denali_dma_xfer(struct denali_nand_info *denali, void *buf,
557 size_t size, int page, int raw, int write)
558{
Masahiro Yamada997cde22017-06-13 22:45:47 +0900559 dma_addr_t dma_addr;
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900560 uint32_t irq_mask, irq_status, ecc_err_mask;
561 enum dma_data_direction dir = write ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
562 int ret = 0;
563
Masahiro Yamada997cde22017-06-13 22:45:47 +0900564 dma_addr = dma_map_single(denali->dev, buf, size, dir);
565 if (dma_mapping_error(denali->dev, dma_addr)) {
566 dev_dbg(denali->dev, "Failed to DMA-map buffer. Trying PIO.\n");
567 return denali_pio_xfer(denali, buf, size, page, raw, write);
568 }
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900569
570 if (write) {
571 /*
572 * INTR__PROGRAM_COMP is never asserted for the DMA transfer.
573 * We can use INTR__DMA_CMD_COMP instead. This flag is asserted
574 * when the page program is completed.
575 */
576 irq_mask = INTR__DMA_CMD_COMP | INTR__PROGRAM_FAIL;
577 ecc_err_mask = 0;
578 } else if (denali->caps & DENALI_CAP_HW_ECC_FIXUP) {
579 irq_mask = INTR__DMA_CMD_COMP;
580 ecc_err_mask = INTR__ECC_UNCOR_ERR;
581 } else {
582 irq_mask = INTR__DMA_CMD_COMP;
583 ecc_err_mask = INTR__ECC_ERR;
584 }
585
Masahiro Yamada586a2c52017-09-22 12:46:41 +0900586 iowrite32(DMA_ENABLE__FLAG, denali->reg + DMA_ENABLE);
Masahiro Yamadacf51e4b2018-09-13 14:58:49 +0900587 /*
588 * The ->setup_dma() hook kicks DMA by using the data/command
589 * interface, which belongs to a different AXI port from the
590 * register interface. Read back the register to avoid a race.
591 */
592 ioread32(denali->reg + DMA_ENABLE);
Jason Robertsce082592010-05-13 15:57:33 +0100593
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900594 denali_reset_irq(denali);
Masahiro Yamada89dcb272017-09-22 12:46:49 +0900595 denali->setup_dma(denali, dma_addr, page, write);
Jason Robertsce082592010-05-13 15:57:33 +0100596
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900597 irq_status = denali_wait_for_irq(denali, irq_mask);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900598 if (!(irq_status & INTR__DMA_CMD_COMP))
Masahiro Yamadab21ff822017-06-13 22:45:35 +0900599 ret = -EIO;
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900600 else if (irq_status & ecc_err_mask)
601 ret = -EBADMSG;
Jason Robertsce082592010-05-13 15:57:33 +0100602
Masahiro Yamada586a2c52017-09-22 12:46:41 +0900603 iowrite32(0, denali->reg + DMA_ENABLE);
604
Masahiro Yamada997cde22017-06-13 22:45:47 +0900605 dma_unmap_single(denali->dev, dma_addr, size, dir);
Josh Wufdbad98d2012-06-25 18:07:45 +0800606
Masahiro Yamada57a4d8b2017-06-13 22:45:46 +0900607 if (irq_status & INTR__ERASED_PAGE)
608 memset(buf, 0xff, size);
609
Masahiro Yamadab21ff822017-06-13 22:45:35 +0900610 return ret;
Jason Robertsce082592010-05-13 15:57:33 +0100611}
612
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900613static int denali_data_xfer(struct denali_nand_info *denali, void *buf,
614 size_t size, int page, int raw, int write)
Jason Robertsce082592010-05-13 15:57:33 +0100615{
Masahiro Yamadaee0ae6a2017-09-22 12:46:38 +0900616 iowrite32(raw ? 0 : ECC_ENABLE__FLAG, denali->reg + ECC_ENABLE);
617 iowrite32(raw ? TRANSFER_SPARE_REG__FLAG : 0,
618 denali->reg + TRANSFER_SPARE_REG);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900619
620 if (denali->dma_avail)
621 return denali_dma_xfer(denali, buf, size, page, raw, write);
622 else
623 return denali_pio_xfer(denali, buf, size, page, raw, write);
Jason Robertsce082592010-05-13 15:57:33 +0100624}
625
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900626static void denali_oob_xfer(struct mtd_info *mtd, struct nand_chip *chip,
627 int page, int write)
Jason Robertsce082592010-05-13 15:57:33 +0100628{
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900629 struct denali_nand_info *denali = mtd_to_denali(mtd);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900630 int writesize = mtd->writesize;
631 int oobsize = mtd->oobsize;
632 uint8_t *bufpoi = chip->oob_poi;
633 int ecc_steps = chip->ecc.steps;
634 int ecc_size = chip->ecc.size;
635 int ecc_bytes = chip->ecc.bytes;
Masahiro Yamada0d3a9662017-06-16 14:36:39 +0900636 int oob_skip = denali->oob_skip_bytes;
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900637 size_t size = writesize + oobsize;
638 int i, pos, len;
639
640 /* BBM at the beginning of the OOB area */
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900641 if (write)
Boris Brezillon97d90da2017-11-30 18:01:29 +0100642 nand_prog_page_begin_op(chip, page, writesize, bufpoi,
643 oob_skip);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900644 else
Boris Brezillon97d90da2017-11-30 18:01:29 +0100645 nand_read_page_op(chip, page, writesize, bufpoi, oob_skip);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900646 bufpoi += oob_skip;
647
648 /* OOB ECC */
649 for (i = 0; i < ecc_steps; i++) {
650 pos = ecc_size + i * (ecc_size + ecc_bytes);
651 len = ecc_bytes;
652
653 if (pos >= writesize)
654 pos += oob_skip;
655 else if (pos + len > writesize)
656 len = writesize - pos;
657
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900658 if (write)
Boris Brezillon97d90da2017-11-30 18:01:29 +0100659 nand_change_write_column_op(chip, pos, bufpoi, len,
660 false);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900661 else
Boris Brezillon97d90da2017-11-30 18:01:29 +0100662 nand_change_read_column_op(chip, pos, bufpoi, len,
663 false);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900664 bufpoi += len;
665 if (len < ecc_bytes) {
666 len = ecc_bytes - len;
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900667 if (write)
Boris Brezillon97d90da2017-11-30 18:01:29 +0100668 nand_change_write_column_op(chip, writesize +
669 oob_skip, bufpoi,
670 len, false);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900671 else
Boris Brezillon97d90da2017-11-30 18:01:29 +0100672 nand_change_read_column_op(chip, writesize +
673 oob_skip, bufpoi,
674 len, false);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900675 bufpoi += len;
676 }
677 }
678
679 /* OOB free */
680 len = oobsize - (bufpoi - chip->oob_poi);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900681 if (write)
Boris Brezillon97d90da2017-11-30 18:01:29 +0100682 nand_change_write_column_op(chip, size - len, bufpoi, len,
683 false);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900684 else
Boris Brezillon97d90da2017-11-30 18:01:29 +0100685 nand_change_read_column_op(chip, size - len, bufpoi, len,
686 false);
Jason Robertsce082592010-05-13 15:57:33 +0100687}
688
Boris Brezillonb9761682018-09-06 14:05:20 +0200689static int denali_read_page_raw(struct nand_chip *chip, uint8_t *buf,
690 int oob_required, int page)
Jason Robertsce082592010-05-13 15:57:33 +0100691{
Boris Brezillonb9761682018-09-06 14:05:20 +0200692 struct mtd_info *mtd = nand_to_mtd(chip);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900693 struct denali_nand_info *denali = mtd_to_denali(mtd);
694 int writesize = mtd->writesize;
695 int oobsize = mtd->oobsize;
696 int ecc_steps = chip->ecc.steps;
697 int ecc_size = chip->ecc.size;
698 int ecc_bytes = chip->ecc.bytes;
Masahiro Yamada8a8c8ba2017-11-23 22:32:28 +0900699 void *tmp_buf = denali->buf;
Masahiro Yamada0d3a9662017-06-16 14:36:39 +0900700 int oob_skip = denali->oob_skip_bytes;
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900701 size_t size = writesize + oobsize;
702 int ret, i, pos, len;
703
Masahiro Yamada8a8c8ba2017-11-23 22:32:28 +0900704 ret = denali_data_xfer(denali, tmp_buf, size, page, 1, 0);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900705 if (ret)
706 return ret;
707
708 /* Arrange the buffer for syndrome payload/ecc layout */
709 if (buf) {
710 for (i = 0; i < ecc_steps; i++) {
711 pos = i * (ecc_size + ecc_bytes);
712 len = ecc_size;
713
714 if (pos >= writesize)
715 pos += oob_skip;
716 else if (pos + len > writesize)
717 len = writesize - pos;
718
Masahiro Yamada8a8c8ba2017-11-23 22:32:28 +0900719 memcpy(buf, tmp_buf + pos, len);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900720 buf += len;
721 if (len < ecc_size) {
722 len = ecc_size - len;
Masahiro Yamada8a8c8ba2017-11-23 22:32:28 +0900723 memcpy(buf, tmp_buf + writesize + oob_skip,
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900724 len);
725 buf += len;
726 }
727 }
728 }
729
730 if (oob_required) {
731 uint8_t *oob = chip->oob_poi;
732
733 /* BBM at the beginning of the OOB area */
Masahiro Yamada8a8c8ba2017-11-23 22:32:28 +0900734 memcpy(oob, tmp_buf + writesize, oob_skip);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900735 oob += oob_skip;
736
737 /* OOB ECC */
738 for (i = 0; i < ecc_steps; i++) {
739 pos = ecc_size + i * (ecc_size + ecc_bytes);
740 len = ecc_bytes;
741
742 if (pos >= writesize)
743 pos += oob_skip;
744 else if (pos + len > writesize)
745 len = writesize - pos;
746
Masahiro Yamada8a8c8ba2017-11-23 22:32:28 +0900747 memcpy(oob, tmp_buf + pos, len);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900748 oob += len;
749 if (len < ecc_bytes) {
750 len = ecc_bytes - len;
Masahiro Yamada8a8c8ba2017-11-23 22:32:28 +0900751 memcpy(oob, tmp_buf + writesize + oob_skip,
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900752 len);
753 oob += len;
754 }
755 }
756
757 /* OOB free */
758 len = oobsize - (oob - chip->oob_poi);
Masahiro Yamada8a8c8ba2017-11-23 22:32:28 +0900759 memcpy(oob, tmp_buf + size - len, len);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900760 }
761
762 return 0;
Jason Robertsce082592010-05-13 15:57:33 +0100763}
764
Boris Brezillonb9761682018-09-06 14:05:20 +0200765static int denali_read_oob(struct nand_chip *chip, int page)
Jason Robertsce082592010-05-13 15:57:33 +0100766{
Boris Brezillonb9761682018-09-06 14:05:20 +0200767 struct mtd_info *mtd = nand_to_mtd(chip);
768
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900769 denali_oob_xfer(mtd, chip, page, 0);
Jason Robertsce082592010-05-13 15:57:33 +0100770
Shmulik Ladkani5c2ffb12012-05-09 13:06:35 +0300771 return 0;
Jason Robertsce082592010-05-13 15:57:33 +0100772}
773
Boris Brezillon767eb6f2018-09-06 14:05:21 +0200774static int denali_write_oob(struct nand_chip *chip, int page)
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900775{
Boris Brezillon767eb6f2018-09-06 14:05:21 +0200776 struct mtd_info *mtd = nand_to_mtd(chip);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900777 struct denali_nand_info *denali = mtd_to_denali(mtd);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900778
779 denali_reset_irq(denali);
780
781 denali_oob_xfer(mtd, chip, page, 1);
782
Boris Brezillon97d90da2017-11-30 18:01:29 +0100783 return nand_prog_page_end_op(chip);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900784}
785
Boris Brezillonb9761682018-09-06 14:05:20 +0200786static int denali_read_page(struct nand_chip *chip, uint8_t *buf,
787 int oob_required, int page)
Jason Robertsce082592010-05-13 15:57:33 +0100788{
Boris Brezillonb9761682018-09-06 14:05:20 +0200789 struct mtd_info *mtd = nand_to_mtd(chip);
Jason Robertsce082592010-05-13 15:57:33 +0100790 struct denali_nand_info *denali = mtd_to_denali(mtd);
Masahiro Yamadad29109b2017-03-30 15:45:51 +0900791 unsigned long uncor_ecc_flags = 0;
792 int stat = 0;
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900793 int ret;
Jason Robertsce082592010-05-13 15:57:33 +0100794
Masahiro Yamada997cde22017-06-13 22:45:47 +0900795 ret = denali_data_xfer(denali, buf, mtd->writesize, page, 0, 0);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900796 if (ret && ret != -EBADMSG)
797 return ret;
Jason Robertsce082592010-05-13 15:57:33 +0100798
Masahiro Yamada24715c72017-03-30 15:45:52 +0900799 if (denali->caps & DENALI_CAP_HW_ECC_FIXUP)
800 stat = denali_hw_ecc_fixup(mtd, denali, &uncor_ecc_flags);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900801 else if (ret == -EBADMSG)
Masahiro Yamada24715c72017-03-30 15:45:52 +0900802 stat = denali_sw_ecc_fixup(mtd, denali, &uncor_ecc_flags, buf);
Jason Robertsce082592010-05-13 15:57:33 +0100803
Masahiro Yamadad29109b2017-03-30 15:45:51 +0900804 if (stat < 0)
805 return stat;
806
807 if (uncor_ecc_flags) {
Boris Brezillonb9761682018-09-06 14:05:20 +0200808 ret = denali_read_oob(chip, page);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900809 if (ret)
810 return ret;
Jason Robertsce082592010-05-13 15:57:33 +0100811
Masahiro Yamadad29109b2017-03-30 15:45:51 +0900812 stat = denali_check_erased_page(mtd, chip, buf,
813 uncor_ecc_flags, stat);
Jason Robertsce082592010-05-13 15:57:33 +0100814 }
Masahiro Yamadad29109b2017-03-30 15:45:51 +0900815
816 return stat;
Jason Robertsce082592010-05-13 15:57:33 +0100817}
818
Boris Brezillon767eb6f2018-09-06 14:05:21 +0200819static int denali_write_page_raw(struct nand_chip *chip, const uint8_t *buf,
820 int oob_required, int page)
Jason Robertsce082592010-05-13 15:57:33 +0100821{
Boris Brezillon767eb6f2018-09-06 14:05:21 +0200822 struct mtd_info *mtd = nand_to_mtd(chip);
Jason Robertsce082592010-05-13 15:57:33 +0100823 struct denali_nand_info *denali = mtd_to_denali(mtd);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900824 int writesize = mtd->writesize;
825 int oobsize = mtd->oobsize;
826 int ecc_steps = chip->ecc.steps;
827 int ecc_size = chip->ecc.size;
828 int ecc_bytes = chip->ecc.bytes;
Masahiro Yamada8a8c8ba2017-11-23 22:32:28 +0900829 void *tmp_buf = denali->buf;
Masahiro Yamada0d3a9662017-06-16 14:36:39 +0900830 int oob_skip = denali->oob_skip_bytes;
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900831 size_t size = writesize + oobsize;
832 int i, pos, len;
Chuanxiao5bac3acf2010-08-05 23:06:04 +0800833
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900834 /*
835 * Fill the buffer with 0xff first except the full page transfer.
836 * This simplifies the logic.
837 */
838 if (!buf || !oob_required)
Masahiro Yamada8a8c8ba2017-11-23 22:32:28 +0900839 memset(tmp_buf, 0xff, size);
Jason Robertsce082592010-05-13 15:57:33 +0100840
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900841 /* Arrange the buffer for syndrome payload/ecc layout */
842 if (buf) {
843 for (i = 0; i < ecc_steps; i++) {
844 pos = i * (ecc_size + ecc_bytes);
845 len = ecc_size;
Jason Robertsce082592010-05-13 15:57:33 +0100846
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900847 if (pos >= writesize)
848 pos += oob_skip;
849 else if (pos + len > writesize)
850 len = writesize - pos;
Jason Robertsce082592010-05-13 15:57:33 +0100851
Masahiro Yamada8a8c8ba2017-11-23 22:32:28 +0900852 memcpy(tmp_buf + pos, buf, len);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900853 buf += len;
854 if (len < ecc_size) {
855 len = ecc_size - len;
Masahiro Yamada8a8c8ba2017-11-23 22:32:28 +0900856 memcpy(tmp_buf + writesize + oob_skip, buf,
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900857 len);
858 buf += len;
859 }
860 }
861 }
Jason Robertsce082592010-05-13 15:57:33 +0100862
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900863 if (oob_required) {
864 const uint8_t *oob = chip->oob_poi;
Jason Robertsce082592010-05-13 15:57:33 +0100865
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900866 /* BBM at the beginning of the OOB area */
Masahiro Yamada8a8c8ba2017-11-23 22:32:28 +0900867 memcpy(tmp_buf + writesize, oob, oob_skip);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900868 oob += oob_skip;
Jason Robertsce082592010-05-13 15:57:33 +0100869
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900870 /* OOB ECC */
871 for (i = 0; i < ecc_steps; i++) {
872 pos = ecc_size + i * (ecc_size + ecc_bytes);
873 len = ecc_bytes;
Jason Robertsce082592010-05-13 15:57:33 +0100874
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900875 if (pos >= writesize)
876 pos += oob_skip;
877 else if (pos + len > writesize)
878 len = writesize - pos;
879
Masahiro Yamada8a8c8ba2017-11-23 22:32:28 +0900880 memcpy(tmp_buf + pos, oob, len);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900881 oob += len;
882 if (len < ecc_bytes) {
883 len = ecc_bytes - len;
Masahiro Yamada8a8c8ba2017-11-23 22:32:28 +0900884 memcpy(tmp_buf + writesize + oob_skip, oob,
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900885 len);
886 oob += len;
887 }
888 }
889
890 /* OOB free */
891 len = oobsize - (oob - chip->oob_poi);
Masahiro Yamada8a8c8ba2017-11-23 22:32:28 +0900892 memcpy(tmp_buf + size - len, oob, len);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900893 }
894
Masahiro Yamada8a8c8ba2017-11-23 22:32:28 +0900895 return denali_data_xfer(denali, tmp_buf, size, page, 1, 1);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900896}
897
Boris Brezillon767eb6f2018-09-06 14:05:21 +0200898static int denali_write_page(struct nand_chip *chip, const uint8_t *buf,
899 int oob_required, int page)
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900900{
Boris Brezillon767eb6f2018-09-06 14:05:21 +0200901 struct mtd_info *mtd = nand_to_mtd(chip);
Masahiro Yamada26d266e2017-06-13 22:45:45 +0900902 struct denali_nand_info *denali = mtd_to_denali(mtd);
903
Masahiro Yamada997cde22017-06-13 22:45:47 +0900904 return denali_data_xfer(denali, (void *)buf, mtd->writesize,
905 page, 0, 1);
Jason Robertsce082592010-05-13 15:57:33 +0100906}
907
Boris Brezillon758b56f2018-09-06 14:05:24 +0200908static void denali_select_chip(struct nand_chip *chip, int cs)
Jason Robertsce082592010-05-13 15:57:33 +0100909{
Boris Brezillon758b56f2018-09-06 14:05:24 +0200910 struct denali_nand_info *denali = mtd_to_denali(nand_to_mtd(chip));
Chuanxiao Dong7cfffac2010-08-10 00:16:51 +0800911
Boris Brezillon758b56f2018-09-06 14:05:24 +0200912 denali->active_bank = cs;
Jason Robertsce082592010-05-13 15:57:33 +0100913}
914
Boris Brezillonf1d46942018-09-06 14:05:29 +0200915static int denali_waitfunc(struct nand_chip *chip)
Jason Robertsce082592010-05-13 15:57:33 +0100916{
Boris Brezillonf1d46942018-09-06 14:05:29 +0200917 struct denali_nand_info *denali = mtd_to_denali(nand_to_mtd(chip));
Masahiro Yamadafa6134e2017-06-13 22:45:39 +0900918 uint32_t irq_status;
919
920 /* R/B# pin transitioned from low to high? */
921 irq_status = denali_wait_for_irq(denali, INTR__INT_ACT);
922
923 return irq_status & INTR__INT_ACT ? 0 : NAND_STATUS_FAIL;
Jason Robertsce082592010-05-13 15:57:33 +0100924}
925
Boris Brezillona2098a92018-09-06 14:05:30 +0200926static int denali_erase(struct nand_chip *chip, int page)
Jason Robertsce082592010-05-13 15:57:33 +0100927{
Boris Brezillona2098a92018-09-06 14:05:30 +0200928 struct denali_nand_info *denali = mtd_to_denali(nand_to_mtd(chip));
Masahiro Yamada0d3a9662017-06-16 14:36:39 +0900929 uint32_t irq_status;
Jason Robertsce082592010-05-13 15:57:33 +0100930
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900931 denali_reset_irq(denali);
Jason Robertsce082592010-05-13 15:57:33 +0100932
Masahiro Yamada29c4dd92017-09-22 12:46:48 +0900933 denali->host_write(denali, DENALI_MAP10 | DENALI_BANK(denali) | page,
934 DENALI_ERASE);
Jason Robertsce082592010-05-13 15:57:33 +0100935
936 /* wait for erase to complete or failure to occur */
Masahiro Yamadac19e31d2017-06-13 22:45:38 +0900937 irq_status = denali_wait_for_irq(denali,
938 INTR__ERASE_COMP | INTR__ERASE_FAIL);
Jason Robertsce082592010-05-13 15:57:33 +0100939
Miquel Raynaleb945552017-11-30 18:01:28 +0100940 return irq_status & INTR__ERASE_COMP ? 0 : -EIO;
Jason Robertsce082592010-05-13 15:57:33 +0100941}
942
Boris Brezillon858838b2018-09-06 14:05:33 +0200943static int denali_setup_data_interface(struct nand_chip *chip, int chipnr,
Masahiro Yamada1bb88662017-06-13 22:45:37 +0900944 const struct nand_data_interface *conf)
945{
Boris Brezillon858838b2018-09-06 14:05:33 +0200946 struct denali_nand_info *denali = mtd_to_denali(nand_to_mtd(chip));
Masahiro Yamada1bb88662017-06-13 22:45:37 +0900947 const struct nand_sdr_timings *timings;
Masahiro Yamada1dfac312018-06-23 01:06:38 +0900948 unsigned long t_x, mult_x;
Masahiro Yamada1bb88662017-06-13 22:45:37 +0900949 int acc_clks, re_2_we, re_2_re, we_2_re, addr_2_data;
950 int rdwr_en_lo, rdwr_en_hi, rdwr_en_lo_hi, cs_setup;
951 int addr_2_data_mask;
952 uint32_t tmp;
953
954 timings = nand_get_sdr_timings(conf);
955 if (IS_ERR(timings))
956 return PTR_ERR(timings);
957
958 /* clk_x period in picoseconds */
Masahiro Yamada1dfac312018-06-23 01:06:38 +0900959 t_x = DIV_ROUND_DOWN_ULL(1000000000000ULL, denali->clk_x_rate);
960 if (!t_x)
961 return -EINVAL;
962
963 /*
964 * The bus interface clock, clk_x, is phase aligned with the core clock.
965 * The clk_x is an integral multiple N of the core clk. The value N is
966 * configured at IP delivery time, and its available value is 4, 5, 6.
967 */
968 mult_x = DIV_ROUND_CLOSEST_ULL(denali->clk_x_rate, denali->clk_rate);
969 if (mult_x < 4 || mult_x > 6)
Masahiro Yamada1bb88662017-06-13 22:45:37 +0900970 return -EINVAL;
971
972 if (chipnr == NAND_DATA_IFACE_CHECK_ONLY)
973 return 0;
974
975 /* tREA -> ACC_CLKS */
Masahiro Yamada1dfac312018-06-23 01:06:38 +0900976 acc_clks = DIV_ROUND_UP(timings->tREA_max, t_x);
Masahiro Yamada1bb88662017-06-13 22:45:37 +0900977 acc_clks = min_t(int, acc_clks, ACC_CLKS__VALUE);
978
Masahiro Yamada0d3a9662017-06-16 14:36:39 +0900979 tmp = ioread32(denali->reg + ACC_CLKS);
Masahiro Yamada1bb88662017-06-13 22:45:37 +0900980 tmp &= ~ACC_CLKS__VALUE;
Masahiro Yamada8e4cbf72017-09-22 12:46:44 +0900981 tmp |= FIELD_PREP(ACC_CLKS__VALUE, acc_clks);
Masahiro Yamada0d3a9662017-06-16 14:36:39 +0900982 iowrite32(tmp, denali->reg + ACC_CLKS);
Masahiro Yamada1bb88662017-06-13 22:45:37 +0900983
984 /* tRWH -> RE_2_WE */
Masahiro Yamada1dfac312018-06-23 01:06:38 +0900985 re_2_we = DIV_ROUND_UP(timings->tRHW_min, t_x);
Masahiro Yamada1bb88662017-06-13 22:45:37 +0900986 re_2_we = min_t(int, re_2_we, RE_2_WE__VALUE);
987
Masahiro Yamada0d3a9662017-06-16 14:36:39 +0900988 tmp = ioread32(denali->reg + RE_2_WE);
Masahiro Yamada1bb88662017-06-13 22:45:37 +0900989 tmp &= ~RE_2_WE__VALUE;
Masahiro Yamada8e4cbf72017-09-22 12:46:44 +0900990 tmp |= FIELD_PREP(RE_2_WE__VALUE, re_2_we);
Masahiro Yamada0d3a9662017-06-16 14:36:39 +0900991 iowrite32(tmp, denali->reg + RE_2_WE);
Masahiro Yamada1bb88662017-06-13 22:45:37 +0900992
993 /* tRHZ -> RE_2_RE */
Masahiro Yamada1dfac312018-06-23 01:06:38 +0900994 re_2_re = DIV_ROUND_UP(timings->tRHZ_max, t_x);
Masahiro Yamada1bb88662017-06-13 22:45:37 +0900995 re_2_re = min_t(int, re_2_re, RE_2_RE__VALUE);
996
Masahiro Yamada0d3a9662017-06-16 14:36:39 +0900997 tmp = ioread32(denali->reg + RE_2_RE);
Masahiro Yamada1bb88662017-06-13 22:45:37 +0900998 tmp &= ~RE_2_RE__VALUE;
Masahiro Yamada8e4cbf72017-09-22 12:46:44 +0900999 tmp |= FIELD_PREP(RE_2_RE__VALUE, re_2_re);
Masahiro Yamada0d3a9662017-06-16 14:36:39 +09001000 iowrite32(tmp, denali->reg + RE_2_RE);
Masahiro Yamada1bb88662017-06-13 22:45:37 +09001001
Masahiro Yamada7963f582017-09-29 23:12:57 +09001002 /*
1003 * tCCS, tWHR -> WE_2_RE
1004 *
1005 * With WE_2_RE properly set, the Denali controller automatically takes
1006 * care of the delay; the driver need not set NAND_WAIT_TCCS.
1007 */
Masahiro Yamada1dfac312018-06-23 01:06:38 +09001008 we_2_re = DIV_ROUND_UP(max(timings->tCCS_min, timings->tWHR_min), t_x);
Masahiro Yamada1bb88662017-06-13 22:45:37 +09001009 we_2_re = min_t(int, we_2_re, TWHR2_AND_WE_2_RE__WE_2_RE);
1010
Masahiro Yamada0d3a9662017-06-16 14:36:39 +09001011 tmp = ioread32(denali->reg + TWHR2_AND_WE_2_RE);
Masahiro Yamada1bb88662017-06-13 22:45:37 +09001012 tmp &= ~TWHR2_AND_WE_2_RE__WE_2_RE;
Masahiro Yamada8e4cbf72017-09-22 12:46:44 +09001013 tmp |= FIELD_PREP(TWHR2_AND_WE_2_RE__WE_2_RE, we_2_re);
Masahiro Yamada0d3a9662017-06-16 14:36:39 +09001014 iowrite32(tmp, denali->reg + TWHR2_AND_WE_2_RE);
Masahiro Yamada1bb88662017-06-13 22:45:37 +09001015
1016 /* tADL -> ADDR_2_DATA */
1017
1018 /* for older versions, ADDR_2_DATA is only 6 bit wide */
1019 addr_2_data_mask = TCWAW_AND_ADDR_2_DATA__ADDR_2_DATA;
1020 if (denali->revision < 0x0501)
1021 addr_2_data_mask >>= 1;
1022
Masahiro Yamada1dfac312018-06-23 01:06:38 +09001023 addr_2_data = DIV_ROUND_UP(timings->tADL_min, t_x);
Masahiro Yamada1bb88662017-06-13 22:45:37 +09001024 addr_2_data = min_t(int, addr_2_data, addr_2_data_mask);
1025
Masahiro Yamada0d3a9662017-06-16 14:36:39 +09001026 tmp = ioread32(denali->reg + TCWAW_AND_ADDR_2_DATA);
Masahiro Yamada8e4cbf72017-09-22 12:46:44 +09001027 tmp &= ~TCWAW_AND_ADDR_2_DATA__ADDR_2_DATA;
1028 tmp |= FIELD_PREP(TCWAW_AND_ADDR_2_DATA__ADDR_2_DATA, addr_2_data);
Masahiro Yamada0d3a9662017-06-16 14:36:39 +09001029 iowrite32(tmp, denali->reg + TCWAW_AND_ADDR_2_DATA);
Masahiro Yamada1bb88662017-06-13 22:45:37 +09001030
1031 /* tREH, tWH -> RDWR_EN_HI_CNT */
1032 rdwr_en_hi = DIV_ROUND_UP(max(timings->tREH_min, timings->tWH_min),
Masahiro Yamada1dfac312018-06-23 01:06:38 +09001033 t_x);
Masahiro Yamada1bb88662017-06-13 22:45:37 +09001034 rdwr_en_hi = min_t(int, rdwr_en_hi, RDWR_EN_HI_CNT__VALUE);
1035
Masahiro Yamada0d3a9662017-06-16 14:36:39 +09001036 tmp = ioread32(denali->reg + RDWR_EN_HI_CNT);
Masahiro Yamada1bb88662017-06-13 22:45:37 +09001037 tmp &= ~RDWR_EN_HI_CNT__VALUE;
Masahiro Yamada8e4cbf72017-09-22 12:46:44 +09001038 tmp |= FIELD_PREP(RDWR_EN_HI_CNT__VALUE, rdwr_en_hi);
Masahiro Yamada0d3a9662017-06-16 14:36:39 +09001039 iowrite32(tmp, denali->reg + RDWR_EN_HI_CNT);
Masahiro Yamada1bb88662017-06-13 22:45:37 +09001040
1041 /* tRP, tWP -> RDWR_EN_LO_CNT */
Masahiro Yamada1dfac312018-06-23 01:06:38 +09001042 rdwr_en_lo = DIV_ROUND_UP(max(timings->tRP_min, timings->tWP_min), t_x);
Masahiro Yamada1bb88662017-06-13 22:45:37 +09001043 rdwr_en_lo_hi = DIV_ROUND_UP(max(timings->tRC_min, timings->tWC_min),
Masahiro Yamada1dfac312018-06-23 01:06:38 +09001044 t_x);
1045 rdwr_en_lo_hi = max_t(int, rdwr_en_lo_hi, mult_x);
Masahiro Yamada1bb88662017-06-13 22:45:37 +09001046 rdwr_en_lo = max(rdwr_en_lo, rdwr_en_lo_hi - rdwr_en_hi);
1047 rdwr_en_lo = min_t(int, rdwr_en_lo, RDWR_EN_LO_CNT__VALUE);
1048
Masahiro Yamada0d3a9662017-06-16 14:36:39 +09001049 tmp = ioread32(denali->reg + RDWR_EN_LO_CNT);
Masahiro Yamada1bb88662017-06-13 22:45:37 +09001050 tmp &= ~RDWR_EN_LO_CNT__VALUE;
Masahiro Yamada8e4cbf72017-09-22 12:46:44 +09001051 tmp |= FIELD_PREP(RDWR_EN_LO_CNT__VALUE, rdwr_en_lo);
Masahiro Yamada0d3a9662017-06-16 14:36:39 +09001052 iowrite32(tmp, denali->reg + RDWR_EN_LO_CNT);
Masahiro Yamada1bb88662017-06-13 22:45:37 +09001053
1054 /* tCS, tCEA -> CS_SETUP_CNT */
Masahiro Yamada1dfac312018-06-23 01:06:38 +09001055 cs_setup = max3((int)DIV_ROUND_UP(timings->tCS_min, t_x) - rdwr_en_lo,
1056 (int)DIV_ROUND_UP(timings->tCEA_max, t_x) - acc_clks,
Masahiro Yamada1bb88662017-06-13 22:45:37 +09001057 0);
1058 cs_setup = min_t(int, cs_setup, CS_SETUP_CNT__VALUE);
1059
Masahiro Yamada0d3a9662017-06-16 14:36:39 +09001060 tmp = ioread32(denali->reg + CS_SETUP_CNT);
Masahiro Yamada1bb88662017-06-13 22:45:37 +09001061 tmp &= ~CS_SETUP_CNT__VALUE;
Masahiro Yamada8e4cbf72017-09-22 12:46:44 +09001062 tmp |= FIELD_PREP(CS_SETUP_CNT__VALUE, cs_setup);
Masahiro Yamada0d3a9662017-06-16 14:36:39 +09001063 iowrite32(tmp, denali->reg + CS_SETUP_CNT);
Masahiro Yamada1bb88662017-06-13 22:45:37 +09001064
1065 return 0;
1066}
Jason Robertsce082592010-05-13 15:57:33 +01001067
Masahiro Yamadaf4862872017-06-13 22:45:40 +09001068static void denali_reset_banks(struct denali_nand_info *denali)
1069{
Masahiro Yamadad49f5792017-06-13 22:45:41 +09001070 u32 irq_status;
Masahiro Yamadaf4862872017-06-13 22:45:40 +09001071 int i;
1072
Masahiro Yamadaf4862872017-06-13 22:45:40 +09001073 for (i = 0; i < denali->max_banks; i++) {
Masahiro Yamada0d3a9662017-06-16 14:36:39 +09001074 denali->active_bank = i;
Masahiro Yamadad49f5792017-06-13 22:45:41 +09001075
1076 denali_reset_irq(denali);
1077
1078 iowrite32(DEVICE_RESET__BANK(i),
Masahiro Yamada0d3a9662017-06-16 14:36:39 +09001079 denali->reg + DEVICE_RESET);
Masahiro Yamadad49f5792017-06-13 22:45:41 +09001080
1081 irq_status = denali_wait_for_irq(denali,
1082 INTR__RST_COMP | INTR__INT_ACT | INTR__TIME_OUT);
1083 if (!(irq_status & INTR__INT_ACT))
Masahiro Yamadaf4862872017-06-13 22:45:40 +09001084 break;
1085 }
1086
1087 dev_dbg(denali->dev, "%d chips connected\n", i);
1088 denali->max_banks = i;
Masahiro Yamadaf4862872017-06-13 22:45:40 +09001089}
1090
Jason Robertsce082592010-05-13 15:57:33 +01001091static void denali_hw_init(struct denali_nand_info *denali)
1092{
Masahiro Yamada43914a22014-09-09 11:01:51 +09001093 /*
Masahiro Yamadae7beeee2017-03-30 15:45:57 +09001094 * The REVISION register may not be reliable. Platforms are allowed to
1095 * override it.
1096 */
1097 if (!denali->revision)
Masahiro Yamada0d3a9662017-06-16 14:36:39 +09001098 denali->revision = swab16(ioread32(denali->reg + REVISION));
Masahiro Yamadae7beeee2017-03-30 15:45:57 +09001099
1100 /*
Masahiro Yamada0d55c662018-09-28 13:16:01 +09001101 * Set how many bytes should be skipped before writing data in OOB.
1102 * If a non-zero value has already been set (by firmware or something),
1103 * just use it. Otherwise, set the driver default.
Masahiro Yamada43914a22014-09-09 11:01:51 +09001104 */
Masahiro Yamada0d3a9662017-06-16 14:36:39 +09001105 denali->oob_skip_bytes = ioread32(denali->reg + SPARE_AREA_SKIP_BYTES);
Masahiro Yamada0d55c662018-09-28 13:16:01 +09001106 if (!denali->oob_skip_bytes) {
1107 denali->oob_skip_bytes = DENALI_DEFAULT_OOB_SKIP_BYTES;
1108 iowrite32(denali->oob_skip_bytes,
1109 denali->reg + SPARE_AREA_SKIP_BYTES);
1110 }
1111
Masahiro Yamada3ac6c712017-09-22 12:46:39 +09001112 denali_detect_max_banks(denali);
Masahiro Yamada0d3a9662017-06-16 14:36:39 +09001113 iowrite32(0x0F, denali->reg + RB_PIN_ENABLED);
1114 iowrite32(CHIP_EN_DONT_CARE__FLAG, denali->reg + CHIP_ENABLE_DONT_CARE);
Jason Robertsce082592010-05-13 15:57:33 +01001115
Masahiro Yamada0d3a9662017-06-16 14:36:39 +09001116 iowrite32(0xffff, denali->reg + SPARE_AREA_MARKER);
Jason Robertsce082592010-05-13 15:57:33 +01001117}
1118
Masahiro Yamada7de117f2017-06-07 20:52:12 +09001119int denali_calc_ecc_bytes(int step_size, int strength)
1120{
1121 /* BCH code. Denali requires ecc.bytes to be multiple of 2 */
1122 return DIV_ROUND_UP(strength * fls(step_size * 8), 16) * 2;
1123}
1124EXPORT_SYMBOL(denali_calc_ecc_bytes);
1125
Boris Brezillon14fad622016-02-03 20:00:11 +01001126static int denali_ooblayout_ecc(struct mtd_info *mtd, int section,
1127 struct mtd_oob_region *oobregion)
1128{
1129 struct denali_nand_info *denali = mtd_to_denali(mtd);
1130 struct nand_chip *chip = mtd_to_nand(mtd);
1131
1132 if (section)
1133 return -ERANGE;
1134
Masahiro Yamada0d3a9662017-06-16 14:36:39 +09001135 oobregion->offset = denali->oob_skip_bytes;
Boris Brezillon14fad622016-02-03 20:00:11 +01001136 oobregion->length = chip->ecc.total;
1137
1138 return 0;
1139}
1140
1141static int denali_ooblayout_free(struct mtd_info *mtd, int section,
1142 struct mtd_oob_region *oobregion)
1143{
1144 struct denali_nand_info *denali = mtd_to_denali(mtd);
1145 struct nand_chip *chip = mtd_to_nand(mtd);
1146
1147 if (section)
1148 return -ERANGE;
1149
Masahiro Yamada0d3a9662017-06-16 14:36:39 +09001150 oobregion->offset = chip->ecc.total + denali->oob_skip_bytes;
Boris Brezillon14fad622016-02-03 20:00:11 +01001151 oobregion->length = mtd->oobsize - oobregion->offset;
1152
1153 return 0;
1154}
1155
1156static const struct mtd_ooblayout_ops denali_ooblayout_ops = {
1157 .ecc = denali_ooblayout_ecc,
1158 .free = denali_ooblayout_free,
Jason Robertsce082592010-05-13 15:57:33 +01001159};
1160
Masahiro Yamadae93c1642017-03-23 05:07:21 +09001161static int denali_multidev_fixup(struct denali_nand_info *denali)
Masahiro Yamada6da27b42017-03-23 05:07:20 +09001162{
1163 struct nand_chip *chip = &denali->nand;
1164 struct mtd_info *mtd = nand_to_mtd(chip);
1165
1166 /*
1167 * Support for multi device:
1168 * When the IP configuration is x16 capable and two x8 chips are
1169 * connected in parallel, DEVICES_CONNECTED should be set to 2.
1170 * In this case, the core framework knows nothing about this fact,
1171 * so we should tell it the _logical_ pagesize and anything necessary.
1172 */
Masahiro Yamada0d3a9662017-06-16 14:36:39 +09001173 denali->devs_per_cs = ioread32(denali->reg + DEVICES_CONNECTED);
Masahiro Yamada6da27b42017-03-23 05:07:20 +09001174
Masahiro Yamadacc5d8032017-03-23 05:07:22 +09001175 /*
1176 * On some SoCs, DEVICES_CONNECTED is not auto-detected.
1177 * For those, DEVICES_CONNECTED is left to 0. Set 1 if it is the case.
1178 */
Masahiro Yamada0d3a9662017-06-16 14:36:39 +09001179 if (denali->devs_per_cs == 0) {
1180 denali->devs_per_cs = 1;
1181 iowrite32(1, denali->reg + DEVICES_CONNECTED);
Masahiro Yamadacc5d8032017-03-23 05:07:22 +09001182 }
1183
Masahiro Yamada0d3a9662017-06-16 14:36:39 +09001184 if (denali->devs_per_cs == 1)
Masahiro Yamadae93c1642017-03-23 05:07:21 +09001185 return 0;
1186
Masahiro Yamada0d3a9662017-06-16 14:36:39 +09001187 if (denali->devs_per_cs != 2) {
Masahiro Yamadae93c1642017-03-23 05:07:21 +09001188 dev_err(denali->dev, "unsupported number of devices %d\n",
Masahiro Yamada0d3a9662017-06-16 14:36:39 +09001189 denali->devs_per_cs);
Masahiro Yamadae93c1642017-03-23 05:07:21 +09001190 return -EINVAL;
1191 }
1192
1193 /* 2 chips in parallel */
1194 mtd->size <<= 1;
1195 mtd->erasesize <<= 1;
1196 mtd->writesize <<= 1;
1197 mtd->oobsize <<= 1;
1198 chip->chipsize <<= 1;
1199 chip->page_shift += 1;
1200 chip->phys_erase_shift += 1;
1201 chip->bbt_erase_shift += 1;
1202 chip->chip_shift += 1;
1203 chip->pagemask <<= 1;
1204 chip->ecc.size <<= 1;
1205 chip->ecc.bytes <<= 1;
1206 chip->ecc.strength <<= 1;
Masahiro Yamada0d3a9662017-06-16 14:36:39 +09001207 denali->oob_skip_bytes <<= 1;
Masahiro Yamadae93c1642017-03-23 05:07:21 +09001208
1209 return 0;
Masahiro Yamada6da27b42017-03-23 05:07:20 +09001210}
1211
Miquel Raynald03af162018-07-20 17:14:56 +02001212static int denali_attach_chip(struct nand_chip *chip)
1213{
1214 struct mtd_info *mtd = nand_to_mtd(chip);
1215 struct denali_nand_info *denali = mtd_to_denali(mtd);
1216 int ret;
1217
1218 if (ioread32(denali->reg + FEATURES) & FEATURES__DMA)
1219 denali->dma_avail = 1;
1220
1221 if (denali->dma_avail) {
1222 int dma_bit = denali->caps & DENALI_CAP_DMA_64BIT ? 64 : 32;
1223
1224 ret = dma_set_mask(denali->dev, DMA_BIT_MASK(dma_bit));
1225 if (ret) {
1226 dev_info(denali->dev,
1227 "Failed to set DMA mask. Disabling DMA.\n");
1228 denali->dma_avail = 0;
1229 }
1230 }
1231
1232 if (denali->dma_avail) {
1233 chip->options |= NAND_USE_BOUNCE_BUFFER;
1234 chip->buf_align = 16;
1235 if (denali->caps & DENALI_CAP_DMA_64BIT)
1236 denali->setup_dma = denali_setup_dma64;
1237 else
1238 denali->setup_dma = denali_setup_dma32;
1239 }
1240
1241 chip->bbt_options |= NAND_BBT_USE_FLASH;
1242 chip->bbt_options |= NAND_BBT_NO_OOB;
1243 chip->ecc.mode = NAND_ECC_HW_SYNDROME;
1244 chip->options |= NAND_NO_SUBPAGE_WRITE;
1245
1246 ret = nand_ecc_choose_conf(chip, denali->ecc_caps,
1247 mtd->oobsize - denali->oob_skip_bytes);
1248 if (ret) {
1249 dev_err(denali->dev, "Failed to setup ECC settings.\n");
1250 return ret;
1251 }
1252
1253 dev_dbg(denali->dev,
1254 "chosen ECC settings: step=%d, strength=%d, bytes=%d\n",
1255 chip->ecc.size, chip->ecc.strength, chip->ecc.bytes);
1256
1257 iowrite32(FIELD_PREP(ECC_CORRECTION__ERASE_THRESHOLD, 1) |
1258 FIELD_PREP(ECC_CORRECTION__VALUE, chip->ecc.strength),
1259 denali->reg + ECC_CORRECTION);
1260 iowrite32(mtd->erasesize / mtd->writesize,
1261 denali->reg + PAGES_PER_BLOCK);
1262 iowrite32(chip->options & NAND_BUSWIDTH_16 ? 1 : 0,
1263 denali->reg + DEVICE_WIDTH);
1264 iowrite32(chip->options & NAND_ROW_ADDR_3 ? 0 : TWO_ROW_ADDR_CYCLES__FLAG,
1265 denali->reg + TWO_ROW_ADDR_CYCLES);
1266 iowrite32(mtd->writesize, denali->reg + DEVICE_MAIN_AREA_SIZE);
1267 iowrite32(mtd->oobsize, denali->reg + DEVICE_SPARE_AREA_SIZE);
1268
1269 iowrite32(chip->ecc.size, denali->reg + CFG_DATA_BLOCK_SIZE);
1270 iowrite32(chip->ecc.size, denali->reg + CFG_LAST_DATA_BLOCK_SIZE);
1271 /* chip->ecc.steps is set by nand_scan_tail(); not available here */
1272 iowrite32(mtd->writesize / chip->ecc.size,
1273 denali->reg + CFG_NUM_DATA_BLOCKS);
1274
1275 mtd_set_ooblayout(mtd, &denali_ooblayout_ops);
1276
1277 if (chip->options & NAND_BUSWIDTH_16) {
Boris Brezillon716bbba2018-09-07 00:38:35 +02001278 chip->legacy.read_buf = denali_read_buf16;
1279 chip->legacy.write_buf = denali_write_buf16;
Miquel Raynald03af162018-07-20 17:14:56 +02001280 } else {
Boris Brezillon716bbba2018-09-07 00:38:35 +02001281 chip->legacy.read_buf = denali_read_buf;
1282 chip->legacy.write_buf = denali_write_buf;
Miquel Raynald03af162018-07-20 17:14:56 +02001283 }
1284 chip->ecc.read_page = denali_read_page;
1285 chip->ecc.read_page_raw = denali_read_page_raw;
1286 chip->ecc.write_page = denali_write_page;
1287 chip->ecc.write_page_raw = denali_write_page_raw;
1288 chip->ecc.read_oob = denali_read_oob;
1289 chip->ecc.write_oob = denali_write_oob;
Boris Brezillonf9ebd1b2018-09-07 00:38:39 +02001290 chip->legacy.erase = denali_erase;
Miquel Raynald03af162018-07-20 17:14:56 +02001291
1292 ret = denali_multidev_fixup(denali);
1293 if (ret)
1294 return ret;
1295
1296 /*
1297 * This buffer is DMA-mapped by denali_{read,write}_page_raw. Do not
1298 * use devm_kmalloc() because the memory allocated by devm_ does not
1299 * guarantee DMA-safe alignment.
1300 */
1301 denali->buf = kmalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL);
1302 if (!denali->buf)
1303 return -ENOMEM;
1304
1305 return 0;
1306}
1307
1308static void denali_detach_chip(struct nand_chip *chip)
1309{
1310 struct mtd_info *mtd = nand_to_mtd(chip);
1311 struct denali_nand_info *denali = mtd_to_denali(mtd);
1312
1313 kfree(denali->buf);
1314}
1315
1316static const struct nand_controller_ops denali_controller_ops = {
1317 .attach_chip = denali_attach_chip,
1318 .detach_chip = denali_detach_chip,
Boris Brezillon7a08dba2018-11-11 08:55:24 +01001319 .setup_data_interface = denali_setup_data_interface,
Miquel Raynald03af162018-07-20 17:14:56 +02001320};
1321
Dinh Nguyen2a0a2882012-09-27 10:58:05 -06001322int denali_init(struct denali_nand_info *denali)
Jason Robertsce082592010-05-13 15:57:33 +01001323{
Masahiro Yamada1394a722017-03-23 05:07:17 +09001324 struct nand_chip *chip = &denali->nand;
1325 struct mtd_info *mtd = nand_to_mtd(chip);
Masahiro Yamada29c4dd92017-09-22 12:46:48 +09001326 u32 features = ioread32(denali->reg + FEATURES);
Dinh Nguyen2a0a2882012-09-27 10:58:05 -06001327 int ret;
Jason Robertsce082592010-05-13 15:57:33 +01001328
Boris BREZILLON442f201b2015-12-11 15:06:00 +01001329 mtd->dev.parent = denali->dev;
Jason Robertsce082592010-05-13 15:57:33 +01001330 denali_hw_init(denali);
Masahiro Yamada8582a032017-09-22 12:46:45 +09001331
1332 init_completion(&denali->complete);
1333 spin_lock_init(&denali->irq_lock);
Jason Robertsce082592010-05-13 15:57:33 +01001334
Masahiro Yamadac19e31d2017-06-13 22:45:38 +09001335 denali_clear_irq_all(denali);
1336
Masahiro Yamada7ebb8d02016-11-09 13:35:27 +09001337 ret = devm_request_irq(denali->dev, denali->irq, denali_isr,
1338 IRQF_SHARED, DENALI_NAND_NAME, denali);
1339 if (ret) {
Masahiro Yamada789ccf12016-11-09 13:35:24 +09001340 dev_err(denali->dev, "Unable to request IRQ\n");
Masahiro Yamada7ebb8d02016-11-09 13:35:27 +09001341 return ret;
Jason Robertsce082592010-05-13 15:57:33 +01001342 }
1343
Masahiro Yamadac19e31d2017-06-13 22:45:38 +09001344 denali_enable_irq(denali);
Masahiro Yamadad49f5792017-06-13 22:45:41 +09001345 denali_reset_banks(denali);
Masahiro Yamada336d1392018-08-27 16:01:41 +09001346 if (!denali->max_banks) {
1347 /* Error out earlier if no chip is found for some reasons. */
1348 ret = -ENODEV;
1349 goto disable_irq;
1350 }
Masahiro Yamadad49f5792017-06-13 22:45:41 +09001351
Masahiro Yamada0d3a9662017-06-16 14:36:39 +09001352 denali->active_bank = DENALI_INVALID_BANK;
Masahiro Yamadac19e31d2017-06-13 22:45:38 +09001353
Masahiro Yamada63757d42017-03-23 05:07:18 +09001354 nand_set_flash_node(chip, denali->dev->of_node);
Masahiro Yamada8aabdf32017-03-30 15:45:48 +09001355 /* Fallback to the default name if DT did not give "label" property */
1356 if (!mtd->name)
1357 mtd->name = "denali-nand";
Jason Robertsce082592010-05-13 15:57:33 +01001358
Boris Brezillon7d6c37e2018-11-11 08:55:22 +01001359 chip->legacy.select_chip = denali_select_chip;
Boris Brezillon716bbba2018-09-07 00:38:35 +02001360 chip->legacy.read_byte = denali_read_byte;
1361 chip->legacy.write_byte = denali_write_byte;
Boris Brezillonbf6065c2018-09-07 00:38:36 +02001362 chip->legacy.cmd_ctrl = denali_cmd_ctrl;
Boris Brezillon8395b752018-09-07 00:38:37 +02001363 chip->legacy.dev_ready = denali_dev_ready;
1364 chip->legacy.waitfunc = denali_waitfunc;
Jason Robertsce082592010-05-13 15:57:33 +01001365
Masahiro Yamada29c4dd92017-09-22 12:46:48 +09001366 if (features & FEATURES__INDEX_ADDR) {
1367 denali->host_read = denali_indexed_read;
1368 denali->host_write = denali_indexed_write;
1369 } else {
1370 denali->host_read = denali_direct_read;
1371 denali->host_write = denali_direct_write;
1372 }
1373
Masahiro Yamada1bb88662017-06-13 22:45:37 +09001374 /* clk rate info is needed for setup_data_interface */
Masahiro Yamada1dfac312018-06-23 01:06:38 +09001375 if (denali->clk_rate && denali->clk_x_rate)
Boris Brezillon7a08dba2018-11-11 08:55:24 +01001376 chip->options |= NAND_KEEP_TIMINGS;
Masahiro Yamada1bb88662017-06-13 22:45:37 +09001377
Miquel Raynald03af162018-07-20 17:14:56 +02001378 chip->dummy_controller.ops = &denali_controller_ops;
Boris Brezillon00ad3782018-09-06 14:05:14 +02001379 ret = nand_scan(chip, denali->max_banks);
Masahiro Yamadaa227d4e2016-11-09 13:35:28 +09001380 if (ret)
Masahiro Yamadac19e31d2017-06-13 22:45:38 +09001381 goto disable_irq;
Chuanxiao5bac3acf2010-08-05 23:06:04 +08001382
Boris BREZILLON442f201b2015-12-11 15:06:00 +01001383 ret = mtd_device_register(mtd, NULL, 0);
Jason Robertsce082592010-05-13 15:57:33 +01001384 if (ret) {
Masahiro Yamada789ccf12016-11-09 13:35:24 +09001385 dev_err(denali->dev, "Failed to register MTD: %d\n", ret);
Miquel Raynal4e5d1d92018-03-21 14:01:45 +01001386 goto cleanup_nand;
Jason Robertsce082592010-05-13 15:57:33 +01001387 }
Miquel Raynald03af162018-07-20 17:14:56 +02001388
Jason Robertsce082592010-05-13 15:57:33 +01001389 return 0;
1390
Miquel Raynal4e5d1d92018-03-21 14:01:45 +01001391cleanup_nand:
1392 nand_cleanup(chip);
Masahiro Yamadac19e31d2017-06-13 22:45:38 +09001393disable_irq:
1394 denali_disable_irq(denali);
Dinh Nguyen2a0a2882012-09-27 10:58:05 -06001395
Jason Robertsce082592010-05-13 15:57:33 +01001396 return ret;
1397}
Dinh Nguyen2a0a2882012-09-27 10:58:05 -06001398EXPORT_SYMBOL(denali_init);
Jason Robertsce082592010-05-13 15:57:33 +01001399
Dinh Nguyen2a0a2882012-09-27 10:58:05 -06001400void denali_remove(struct denali_nand_info *denali)
Jason Robertsce082592010-05-13 15:57:33 +01001401{
Boris Brezillon59ac2762018-09-06 14:05:15 +02001402 nand_release(&denali->nand);
Masahiro Yamadac19e31d2017-06-13 22:45:38 +09001403 denali_disable_irq(denali);
Jason Robertsce082592010-05-13 15:57:33 +01001404}
Dinh Nguyen2a0a2882012-09-27 10:58:05 -06001405EXPORT_SYMBOL(denali_remove);
Masahiro Yamadaf1bf52e2018-08-20 12:26:36 +09001406
1407MODULE_DESCRIPTION("Driver core for Denali NAND controller");
1408MODULE_AUTHOR("Intel Corporation and its suppliers");
1409MODULE_LICENSE("GPL v2");