120-11-v5.19-mtd-nand-make-mtk_ecc.c-a-separated-module.patch 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383
  1. From ebb9653d4a87c64fb679e4c339e867556dada719 Mon Sep 17 00:00:00 2001
  2. From: Chuanhong Guo <[email protected]>
  3. Date: Tue, 22 Mar 2022 18:44:21 +0800
  4. Subject: [PATCH 11/15] mtd: nand: make mtk_ecc.c a separated module
  5. this code will be used in mediatek snfi spi-mem controller with
  6. pipelined ECC engine.
  7. Signed-off-by: Chuanhong Guo <[email protected]>
  8. (cherry picked from commit 316f47cec4ce5b81aa8006de202d8769c117a52d)
  9. ---
  10. drivers/mtd/nand/Kconfig | 7 +++++++
  11. drivers/mtd/nand/Makefile | 1 +
  12. drivers/mtd/nand/{raw/mtk_ecc.c => ecc-mtk.c} | 3 +--
  13. drivers/mtd/nand/raw/Kconfig | 1 +
  14. drivers/mtd/nand/raw/Makefile | 2 +-
  15. drivers/mtd/nand/raw/mtk_nand.c | 2 +-
  16. .../nand/raw/mtk_ecc.h => include/linux/mtd/nand-ecc-mtk.h | 0
  17. 7 files changed, 12 insertions(+), 4 deletions(-)
  18. rename drivers/mtd/nand/{raw/mtk_ecc.c => ecc-mtk.c} (99%)
  19. rename drivers/mtd/nand/raw/mtk_ecc.h => include/linux/mtd/nand-ecc-mtk.h (100%)
  20. --- a/drivers/mtd/nand/Kconfig
  21. +++ b/drivers/mtd/nand/Kconfig
  22. @@ -50,6 +50,13 @@ config MTD_NAND_MTK_BMT
  23. bool "Support MediaTek NAND Bad-block Management Table"
  24. default n
  25. +config MTD_NAND_ECC_MEDIATEK
  26. + tristate "Mediatek hardware ECC engine"
  27. + depends on HAS_IOMEM
  28. + select MTD_NAND_ECC
  29. + help
  30. + This enables support for the hardware ECC engine from Mediatek.
  31. +
  32. endmenu
  33. endmenu
  34. --- a/drivers/mtd/nand/Makefile
  35. +++ b/drivers/mtd/nand/Makefile
  36. @@ -3,6 +3,7 @@
  37. nandcore-objs := core.o bbt.o
  38. obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o
  39. obj-$(CONFIG_MTD_NAND_MTK_BMT) += mtk_bmt.o mtk_bmt_v2.o mtk_bmt_bbt.o mtk_bmt_nmbm.o
  40. +obj-$(CONFIG_MTD_NAND_ECC_MEDIATEK) += ecc-mtk.o
  41. obj-y += onenand/
  42. obj-y += raw/
  43. --- a/drivers/mtd/nand/raw/mtk_ecc.c
  44. +++ /dev/null
  45. @@ -1,599 +0,0 @@
  46. -// SPDX-License-Identifier: GPL-2.0 OR MIT
  47. -/*
  48. - * MTK ECC controller driver.
  49. - * Copyright (C) 2016 MediaTek Inc.
  50. - * Authors: Xiaolei Li <[email protected]>
  51. - * Jorge Ramirez-Ortiz <[email protected]>
  52. - */
  53. -
  54. -#include <linux/platform_device.h>
  55. -#include <linux/dma-mapping.h>
  56. -#include <linux/interrupt.h>
  57. -#include <linux/clk.h>
  58. -#include <linux/module.h>
  59. -#include <linux/iopoll.h>
  60. -#include <linux/of.h>
  61. -#include <linux/of_platform.h>
  62. -#include <linux/mutex.h>
  63. -
  64. -#include "mtk_ecc.h"
  65. -
  66. -#define ECC_IDLE_MASK BIT(0)
  67. -#define ECC_IRQ_EN BIT(0)
  68. -#define ECC_PG_IRQ_SEL BIT(1)
  69. -#define ECC_OP_ENABLE (1)
  70. -#define ECC_OP_DISABLE (0)
  71. -
  72. -#define ECC_ENCCON (0x00)
  73. -#define ECC_ENCCNFG (0x04)
  74. -#define ECC_MS_SHIFT (16)
  75. -#define ECC_ENCDIADDR (0x08)
  76. -#define ECC_ENCIDLE (0x0C)
  77. -#define ECC_DECCON (0x100)
  78. -#define ECC_DECCNFG (0x104)
  79. -#define DEC_EMPTY_EN BIT(31)
  80. -#define DEC_CNFG_CORRECT (0x3 << 12)
  81. -#define ECC_DECIDLE (0x10C)
  82. -#define ECC_DECENUM0 (0x114)
  83. -
  84. -#define ECC_TIMEOUT (500000)
  85. -
  86. -#define ECC_IDLE_REG(op) ((op) == ECC_ENCODE ? ECC_ENCIDLE : ECC_DECIDLE)
  87. -#define ECC_CTL_REG(op) ((op) == ECC_ENCODE ? ECC_ENCCON : ECC_DECCON)
  88. -
  89. -struct mtk_ecc_caps {
  90. - u32 err_mask;
  91. - u32 err_shift;
  92. - const u8 *ecc_strength;
  93. - const u32 *ecc_regs;
  94. - u8 num_ecc_strength;
  95. - u8 ecc_mode_shift;
  96. - u32 parity_bits;
  97. - int pg_irq_sel;
  98. -};
  99. -
  100. -struct mtk_ecc {
  101. - struct device *dev;
  102. - const struct mtk_ecc_caps *caps;
  103. - void __iomem *regs;
  104. - struct clk *clk;
  105. -
  106. - struct completion done;
  107. - struct mutex lock;
  108. - u32 sectors;
  109. -
  110. - u8 *eccdata;
  111. -};
  112. -
  113. -/* ecc strength that each IP supports */
  114. -static const u8 ecc_strength_mt2701[] = {
  115. - 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36,
  116. - 40, 44, 48, 52, 56, 60
  117. -};
  118. -
  119. -static const u8 ecc_strength_mt2712[] = {
  120. - 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36,
  121. - 40, 44, 48, 52, 56, 60, 68, 72, 80
  122. -};
  123. -
  124. -static const u8 ecc_strength_mt7622[] = {
  125. - 4, 6, 8, 10, 12
  126. -};
  127. -
  128. -enum mtk_ecc_regs {
  129. - ECC_ENCPAR00,
  130. - ECC_ENCIRQ_EN,
  131. - ECC_ENCIRQ_STA,
  132. - ECC_DECDONE,
  133. - ECC_DECIRQ_EN,
  134. - ECC_DECIRQ_STA,
  135. -};
  136. -
  137. -static int mt2701_ecc_regs[] = {
  138. - [ECC_ENCPAR00] = 0x10,
  139. - [ECC_ENCIRQ_EN] = 0x80,
  140. - [ECC_ENCIRQ_STA] = 0x84,
  141. - [ECC_DECDONE] = 0x124,
  142. - [ECC_DECIRQ_EN] = 0x200,
  143. - [ECC_DECIRQ_STA] = 0x204,
  144. -};
  145. -
  146. -static int mt2712_ecc_regs[] = {
  147. - [ECC_ENCPAR00] = 0x300,
  148. - [ECC_ENCIRQ_EN] = 0x80,
  149. - [ECC_ENCIRQ_STA] = 0x84,
  150. - [ECC_DECDONE] = 0x124,
  151. - [ECC_DECIRQ_EN] = 0x200,
  152. - [ECC_DECIRQ_STA] = 0x204,
  153. -};
  154. -
  155. -static int mt7622_ecc_regs[] = {
  156. - [ECC_ENCPAR00] = 0x10,
  157. - [ECC_ENCIRQ_EN] = 0x30,
  158. - [ECC_ENCIRQ_STA] = 0x34,
  159. - [ECC_DECDONE] = 0x11c,
  160. - [ECC_DECIRQ_EN] = 0x140,
  161. - [ECC_DECIRQ_STA] = 0x144,
  162. -};
  163. -
  164. -static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc,
  165. - enum mtk_ecc_operation op)
  166. -{
  167. - struct device *dev = ecc->dev;
  168. - u32 val;
  169. - int ret;
  170. -
  171. - ret = readl_poll_timeout_atomic(ecc->regs + ECC_IDLE_REG(op), val,
  172. - val & ECC_IDLE_MASK,
  173. - 10, ECC_TIMEOUT);
  174. - if (ret)
  175. - dev_warn(dev, "%s NOT idle\n",
  176. - op == ECC_ENCODE ? "encoder" : "decoder");
  177. -}
  178. -
  179. -static irqreturn_t mtk_ecc_irq(int irq, void *id)
  180. -{
  181. - struct mtk_ecc *ecc = id;
  182. - u32 dec, enc;
  183. -
  184. - dec = readw(ecc->regs + ecc->caps->ecc_regs[ECC_DECIRQ_STA])
  185. - & ECC_IRQ_EN;
  186. - if (dec) {
  187. - dec = readw(ecc->regs + ecc->caps->ecc_regs[ECC_DECDONE]);
  188. - if (dec & ecc->sectors) {
  189. - /*
  190. - * Clear decode IRQ status once again to ensure that
  191. - * there will be no extra IRQ.
  192. - */
  193. - readw(ecc->regs + ecc->caps->ecc_regs[ECC_DECIRQ_STA]);
  194. - ecc->sectors = 0;
  195. - complete(&ecc->done);
  196. - } else {
  197. - return IRQ_HANDLED;
  198. - }
  199. - } else {
  200. - enc = readl(ecc->regs + ecc->caps->ecc_regs[ECC_ENCIRQ_STA])
  201. - & ECC_IRQ_EN;
  202. - if (enc)
  203. - complete(&ecc->done);
  204. - else
  205. - return IRQ_NONE;
  206. - }
  207. -
  208. - return IRQ_HANDLED;
  209. -}
  210. -
  211. -static int mtk_ecc_config(struct mtk_ecc *ecc, struct mtk_ecc_config *config)
  212. -{
  213. - u32 ecc_bit, dec_sz, enc_sz;
  214. - u32 reg, i;
  215. -
  216. - for (i = 0; i < ecc->caps->num_ecc_strength; i++) {
  217. - if (ecc->caps->ecc_strength[i] == config->strength)
  218. - break;
  219. - }
  220. -
  221. - if (i == ecc->caps->num_ecc_strength) {
  222. - dev_err(ecc->dev, "invalid ecc strength %d\n",
  223. - config->strength);
  224. - return -EINVAL;
  225. - }
  226. -
  227. - ecc_bit = i;
  228. -
  229. - if (config->op == ECC_ENCODE) {
  230. - /* configure ECC encoder (in bits) */
  231. - enc_sz = config->len << 3;
  232. -
  233. - reg = ecc_bit | (config->mode << ecc->caps->ecc_mode_shift);
  234. - reg |= (enc_sz << ECC_MS_SHIFT);
  235. - writel(reg, ecc->regs + ECC_ENCCNFG);
  236. -
  237. - if (config->mode != ECC_NFI_MODE)
  238. - writel(lower_32_bits(config->addr),
  239. - ecc->regs + ECC_ENCDIADDR);
  240. -
  241. - } else {
  242. - /* configure ECC decoder (in bits) */
  243. - dec_sz = (config->len << 3) +
  244. - config->strength * ecc->caps->parity_bits;
  245. -
  246. - reg = ecc_bit | (config->mode << ecc->caps->ecc_mode_shift);
  247. - reg |= (dec_sz << ECC_MS_SHIFT) | DEC_CNFG_CORRECT;
  248. - reg |= DEC_EMPTY_EN;
  249. - writel(reg, ecc->regs + ECC_DECCNFG);
  250. -
  251. - if (config->sectors)
  252. - ecc->sectors = 1 << (config->sectors - 1);
  253. - }
  254. -
  255. - return 0;
  256. -}
  257. -
  258. -void mtk_ecc_get_stats(struct mtk_ecc *ecc, struct mtk_ecc_stats *stats,
  259. - int sectors)
  260. -{
  261. - u32 offset, i, err;
  262. - u32 bitflips = 0;
  263. -
  264. - stats->corrected = 0;
  265. - stats->failed = 0;
  266. -
  267. - for (i = 0; i < sectors; i++) {
  268. - offset = (i >> 2) << 2;
  269. - err = readl(ecc->regs + ECC_DECENUM0 + offset);
  270. - err = err >> ((i % 4) * ecc->caps->err_shift);
  271. - err &= ecc->caps->err_mask;
  272. - if (err == ecc->caps->err_mask) {
  273. - /* uncorrectable errors */
  274. - stats->failed++;
  275. - continue;
  276. - }
  277. -
  278. - stats->corrected += err;
  279. - bitflips = max_t(u32, bitflips, err);
  280. - }
  281. -
  282. - stats->bitflips = bitflips;
  283. -}
  284. -EXPORT_SYMBOL(mtk_ecc_get_stats);
  285. -
  286. -void mtk_ecc_release(struct mtk_ecc *ecc)
  287. -{
  288. - clk_disable_unprepare(ecc->clk);
  289. - put_device(ecc->dev);
  290. -}
  291. -EXPORT_SYMBOL(mtk_ecc_release);
  292. -
  293. -static void mtk_ecc_hw_init(struct mtk_ecc *ecc)
  294. -{
  295. - mtk_ecc_wait_idle(ecc, ECC_ENCODE);
  296. - writew(ECC_OP_DISABLE, ecc->regs + ECC_ENCCON);
  297. -
  298. - mtk_ecc_wait_idle(ecc, ECC_DECODE);
  299. - writel(ECC_OP_DISABLE, ecc->regs + ECC_DECCON);
  300. -}
  301. -
  302. -static struct mtk_ecc *mtk_ecc_get(struct device_node *np)
  303. -{
  304. - struct platform_device *pdev;
  305. - struct mtk_ecc *ecc;
  306. -
  307. - pdev = of_find_device_by_node(np);
  308. - if (!pdev)
  309. - return ERR_PTR(-EPROBE_DEFER);
  310. -
  311. - ecc = platform_get_drvdata(pdev);
  312. - if (!ecc) {
  313. - put_device(&pdev->dev);
  314. - return ERR_PTR(-EPROBE_DEFER);
  315. - }
  316. -
  317. - clk_prepare_enable(ecc->clk);
  318. - mtk_ecc_hw_init(ecc);
  319. -
  320. - return ecc;
  321. -}
  322. -
  323. -struct mtk_ecc *of_mtk_ecc_get(struct device_node *of_node)
  324. -{
  325. - struct mtk_ecc *ecc = NULL;
  326. - struct device_node *np;
  327. -
  328. - np = of_parse_phandle(of_node, "ecc-engine", 0);
  329. - if (np) {
  330. - ecc = mtk_ecc_get(np);
  331. - of_node_put(np);
  332. - }
  333. -
  334. - return ecc;
  335. -}
  336. -EXPORT_SYMBOL(of_mtk_ecc_get);
  337. -
  338. -int mtk_ecc_enable(struct mtk_ecc *ecc, struct mtk_ecc_config *config)
  339. -{
  340. - enum mtk_ecc_operation op = config->op;
  341. - u16 reg_val;
  342. - int ret;
  343. -
  344. - ret = mutex_lock_interruptible(&ecc->lock);
  345. - if (ret) {
  346. - dev_err(ecc->dev, "interrupted when attempting to lock\n");
  347. - return ret;
  348. - }
  349. -
  350. - mtk_ecc_wait_idle(ecc, op);
  351. -
  352. - ret = mtk_ecc_config(ecc, config);
  353. - if (ret) {
  354. - mutex_unlock(&ecc->lock);
  355. - return ret;
  356. - }
  357. -
  358. - if (config->mode != ECC_NFI_MODE || op != ECC_ENCODE) {
  359. - init_completion(&ecc->done);
  360. - reg_val = ECC_IRQ_EN;
  361. - /*
  362. - * For ECC_NFI_MODE, if ecc->caps->pg_irq_sel is 1, then it
  363. - * means this chip can only generate one ecc irq during page
  364. - * read / write. If is 0, generate one ecc irq each ecc step.
  365. - */
  366. - if (ecc->caps->pg_irq_sel && config->mode == ECC_NFI_MODE)
  367. - reg_val |= ECC_PG_IRQ_SEL;
  368. - if (op == ECC_ENCODE)
  369. - writew(reg_val, ecc->regs +
  370. - ecc->caps->ecc_regs[ECC_ENCIRQ_EN]);
  371. - else
  372. - writew(reg_val, ecc->regs +
  373. - ecc->caps->ecc_regs[ECC_DECIRQ_EN]);
  374. - }
  375. -
  376. - writew(ECC_OP_ENABLE, ecc->regs + ECC_CTL_REG(op));
  377. -
  378. - return 0;
  379. -}
  380. -EXPORT_SYMBOL(mtk_ecc_enable);
  381. -
  382. -void mtk_ecc_disable(struct mtk_ecc *ecc)
  383. -{
  384. - enum mtk_ecc_operation op = ECC_ENCODE;
  385. -
  386. - /* find out the running operation */
  387. - if (readw(ecc->regs + ECC_CTL_REG(op)) != ECC_OP_ENABLE)
  388. - op = ECC_DECODE;
  389. -
  390. - /* disable it */
  391. - mtk_ecc_wait_idle(ecc, op);
  392. - if (op == ECC_DECODE) {
  393. - /*
  394. - * Clear decode IRQ status in case there is a timeout to wait
  395. - * decode IRQ.
  396. - */
  397. - readw(ecc->regs + ecc->caps->ecc_regs[ECC_DECDONE]);
  398. - writew(0, ecc->regs + ecc->caps->ecc_regs[ECC_DECIRQ_EN]);
  399. - } else {
  400. - writew(0, ecc->regs + ecc->caps->ecc_regs[ECC_ENCIRQ_EN]);
  401. - }
  402. -
  403. - writew(ECC_OP_DISABLE, ecc->regs + ECC_CTL_REG(op));
  404. -
  405. - mutex_unlock(&ecc->lock);
  406. -}
  407. -EXPORT_SYMBOL(mtk_ecc_disable);
  408. -
  409. -int mtk_ecc_wait_done(struct mtk_ecc *ecc, enum mtk_ecc_operation op)
  410. -{
  411. - int ret;
  412. -
  413. - ret = wait_for_completion_timeout(&ecc->done, msecs_to_jiffies(500));
  414. - if (!ret) {
  415. - dev_err(ecc->dev, "%s timeout - interrupt did not arrive)\n",
  416. - (op == ECC_ENCODE) ? "encoder" : "decoder");
  417. - return -ETIMEDOUT;
  418. - }
  419. -
  420. - return 0;
  421. -}
  422. -EXPORT_SYMBOL(mtk_ecc_wait_done);
  423. -
  424. -int mtk_ecc_encode(struct mtk_ecc *ecc, struct mtk_ecc_config *config,
  425. - u8 *data, u32 bytes)
  426. -{
  427. - dma_addr_t addr;
  428. - u32 len;
  429. - int ret;
  430. -
  431. - addr = dma_map_single(ecc->dev, data, bytes, DMA_TO_DEVICE);
  432. - ret = dma_mapping_error(ecc->dev, addr);
  433. - if (ret) {
  434. - dev_err(ecc->dev, "dma mapping error\n");
  435. - return -EINVAL;
  436. - }
  437. -
  438. - config->op = ECC_ENCODE;
  439. - config->addr = addr;
  440. - ret = mtk_ecc_enable(ecc, config);
  441. - if (ret) {
  442. - dma_unmap_single(ecc->dev, addr, bytes, DMA_TO_DEVICE);
  443. - return ret;
  444. - }
  445. -
  446. - ret = mtk_ecc_wait_done(ecc, ECC_ENCODE);
  447. - if (ret)
  448. - goto timeout;
  449. -
  450. - mtk_ecc_wait_idle(ecc, ECC_ENCODE);
  451. -
  452. - /* Program ECC bytes to OOB: per sector oob = FDM + ECC + SPARE */
  453. - len = (config->strength * ecc->caps->parity_bits + 7) >> 3;
  454. -
  455. - /* write the parity bytes generated by the ECC back to temp buffer */
  456. - __ioread32_copy(ecc->eccdata,
  457. - ecc->regs + ecc->caps->ecc_regs[ECC_ENCPAR00],
  458. - round_up(len, 4));
  459. -
  460. - /* copy into possibly unaligned OOB region with actual length */
  461. - memcpy(data + bytes, ecc->eccdata, len);
  462. -timeout:
  463. -
  464. - dma_unmap_single(ecc->dev, addr, bytes, DMA_TO_DEVICE);
  465. - mtk_ecc_disable(ecc);
  466. -
  467. - return ret;
  468. -}
  469. -EXPORT_SYMBOL(mtk_ecc_encode);
  470. -
  471. -void mtk_ecc_adjust_strength(struct mtk_ecc *ecc, u32 *p)
  472. -{
  473. - const u8 *ecc_strength = ecc->caps->ecc_strength;
  474. - int i;
  475. -
  476. - for (i = 0; i < ecc->caps->num_ecc_strength; i++) {
  477. - if (*p <= ecc_strength[i]) {
  478. - if (!i)
  479. - *p = ecc_strength[i];
  480. - else if (*p != ecc_strength[i])
  481. - *p = ecc_strength[i - 1];
  482. - return;
  483. - }
  484. - }
  485. -
  486. - *p = ecc_strength[ecc->caps->num_ecc_strength - 1];
  487. -}
  488. -EXPORT_SYMBOL(mtk_ecc_adjust_strength);
  489. -
  490. -unsigned int mtk_ecc_get_parity_bits(struct mtk_ecc *ecc)
  491. -{
  492. - return ecc->caps->parity_bits;
  493. -}
  494. -EXPORT_SYMBOL(mtk_ecc_get_parity_bits);
  495. -
  496. -static const struct mtk_ecc_caps mtk_ecc_caps_mt2701 = {
  497. - .err_mask = 0x3f,
  498. - .err_shift = 8,
  499. - .ecc_strength = ecc_strength_mt2701,
  500. - .ecc_regs = mt2701_ecc_regs,
  501. - .num_ecc_strength = 20,
  502. - .ecc_mode_shift = 5,
  503. - .parity_bits = 14,
  504. - .pg_irq_sel = 0,
  505. -};
  506. -
  507. -static const struct mtk_ecc_caps mtk_ecc_caps_mt2712 = {
  508. - .err_mask = 0x7f,
  509. - .err_shift = 8,
  510. - .ecc_strength = ecc_strength_mt2712,
  511. - .ecc_regs = mt2712_ecc_regs,
  512. - .num_ecc_strength = 23,
  513. - .ecc_mode_shift = 5,
  514. - .parity_bits = 14,
  515. - .pg_irq_sel = 1,
  516. -};
  517. -
  518. -static const struct mtk_ecc_caps mtk_ecc_caps_mt7622 = {
  519. - .err_mask = 0x1f,
  520. - .err_shift = 5,
  521. - .ecc_strength = ecc_strength_mt7622,
  522. - .ecc_regs = mt7622_ecc_regs,
  523. - .num_ecc_strength = 5,
  524. - .ecc_mode_shift = 4,
  525. - .parity_bits = 13,
  526. - .pg_irq_sel = 0,
  527. -};
  528. -
  529. -static const struct of_device_id mtk_ecc_dt_match[] = {
  530. - {
  531. - .compatible = "mediatek,mt2701-ecc",
  532. - .data = &mtk_ecc_caps_mt2701,
  533. - }, {
  534. - .compatible = "mediatek,mt2712-ecc",
  535. - .data = &mtk_ecc_caps_mt2712,
  536. - }, {
  537. - .compatible = "mediatek,mt7622-ecc",
  538. - .data = &mtk_ecc_caps_mt7622,
  539. - },
  540. - {},
  541. -};
  542. -
  543. -static int mtk_ecc_probe(struct platform_device *pdev)
  544. -{
  545. - struct device *dev = &pdev->dev;
  546. - struct mtk_ecc *ecc;
  547. - struct resource *res;
  548. - u32 max_eccdata_size;
  549. - int irq, ret;
  550. -
  551. - ecc = devm_kzalloc(dev, sizeof(*ecc), GFP_KERNEL);
  552. - if (!ecc)
  553. - return -ENOMEM;
  554. -
  555. - ecc->caps = of_device_get_match_data(dev);
  556. -
  557. - max_eccdata_size = ecc->caps->num_ecc_strength - 1;
  558. - max_eccdata_size = ecc->caps->ecc_strength[max_eccdata_size];
  559. - max_eccdata_size = (max_eccdata_size * ecc->caps->parity_bits + 7) >> 3;
  560. - max_eccdata_size = round_up(max_eccdata_size, 4);
  561. - ecc->eccdata = devm_kzalloc(dev, max_eccdata_size, GFP_KERNEL);
  562. - if (!ecc->eccdata)
  563. - return -ENOMEM;
  564. -
  565. - res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  566. - ecc->regs = devm_ioremap_resource(dev, res);
  567. - if (IS_ERR(ecc->regs))
  568. - return PTR_ERR(ecc->regs);
  569. -
  570. - ecc->clk = devm_clk_get(dev, NULL);
  571. - if (IS_ERR(ecc->clk)) {
  572. - dev_err(dev, "failed to get clock: %ld\n", PTR_ERR(ecc->clk));
  573. - return PTR_ERR(ecc->clk);
  574. - }
  575. -
  576. - irq = platform_get_irq(pdev, 0);
  577. - if (irq < 0)
  578. - return irq;
  579. -
  580. - ret = dma_set_mask(dev, DMA_BIT_MASK(32));
  581. - if (ret) {
  582. - dev_err(dev, "failed to set DMA mask\n");
  583. - return ret;
  584. - }
  585. -
  586. - ret = devm_request_irq(dev, irq, mtk_ecc_irq, 0x0, "mtk-ecc", ecc);
  587. - if (ret) {
  588. - dev_err(dev, "failed to request irq\n");
  589. - return -EINVAL;
  590. - }
  591. -
  592. - ecc->dev = dev;
  593. - mutex_init(&ecc->lock);
  594. - platform_set_drvdata(pdev, ecc);
  595. - dev_info(dev, "probed\n");
  596. -
  597. - return 0;
  598. -}
  599. -
  600. -#ifdef CONFIG_PM_SLEEP
  601. -static int mtk_ecc_suspend(struct device *dev)
  602. -{
  603. - struct mtk_ecc *ecc = dev_get_drvdata(dev);
  604. -
  605. - clk_disable_unprepare(ecc->clk);
  606. -
  607. - return 0;
  608. -}
  609. -
  610. -static int mtk_ecc_resume(struct device *dev)
  611. -{
  612. - struct mtk_ecc *ecc = dev_get_drvdata(dev);
  613. - int ret;
  614. -
  615. - ret = clk_prepare_enable(ecc->clk);
  616. - if (ret) {
  617. - dev_err(dev, "failed to enable clk\n");
  618. - return ret;
  619. - }
  620. -
  621. - return 0;
  622. -}
  623. -
  624. -static SIMPLE_DEV_PM_OPS(mtk_ecc_pm_ops, mtk_ecc_suspend, mtk_ecc_resume);
  625. -#endif
  626. -
  627. -MODULE_DEVICE_TABLE(of, mtk_ecc_dt_match);
  628. -
  629. -static struct platform_driver mtk_ecc_driver = {
  630. - .probe = mtk_ecc_probe,
  631. - .driver = {
  632. - .name = "mtk-ecc",
  633. - .of_match_table = of_match_ptr(mtk_ecc_dt_match),
  634. -#ifdef CONFIG_PM_SLEEP
  635. - .pm = &mtk_ecc_pm_ops,
  636. -#endif
  637. - },
  638. -};
  639. -
  640. -module_platform_driver(mtk_ecc_driver);
  641. -
  642. -MODULE_AUTHOR("Xiaolei Li <[email protected]>");
  643. -MODULE_DESCRIPTION("MTK Nand ECC Driver");
  644. -MODULE_LICENSE("Dual MIT/GPL");
  645. --- /dev/null
  646. +++ b/drivers/mtd/nand/ecc-mtk.c
  647. @@ -0,0 +1,598 @@
  648. +// SPDX-License-Identifier: GPL-2.0 OR MIT
  649. +/*
  650. + * MTK ECC controller driver.
  651. + * Copyright (C) 2016 MediaTek Inc.
  652. + * Authors: Xiaolei Li <[email protected]>
  653. + * Jorge Ramirez-Ortiz <[email protected]>
  654. + */
  655. +
  656. +#include <linux/platform_device.h>
  657. +#include <linux/dma-mapping.h>
  658. +#include <linux/interrupt.h>
  659. +#include <linux/clk.h>
  660. +#include <linux/module.h>
  661. +#include <linux/iopoll.h>
  662. +#include <linux/of.h>
  663. +#include <linux/of_platform.h>
  664. +#include <linux/mutex.h>
  665. +#include <linux/mtd/nand-ecc-mtk.h>
  666. +
  667. +#define ECC_IDLE_MASK BIT(0)
  668. +#define ECC_IRQ_EN BIT(0)
  669. +#define ECC_PG_IRQ_SEL BIT(1)
  670. +#define ECC_OP_ENABLE (1)
  671. +#define ECC_OP_DISABLE (0)
  672. +
  673. +#define ECC_ENCCON (0x00)
  674. +#define ECC_ENCCNFG (0x04)
  675. +#define ECC_MS_SHIFT (16)
  676. +#define ECC_ENCDIADDR (0x08)
  677. +#define ECC_ENCIDLE (0x0C)
  678. +#define ECC_DECCON (0x100)
  679. +#define ECC_DECCNFG (0x104)
  680. +#define DEC_EMPTY_EN BIT(31)
  681. +#define DEC_CNFG_CORRECT (0x3 << 12)
  682. +#define ECC_DECIDLE (0x10C)
  683. +#define ECC_DECENUM0 (0x114)
  684. +
  685. +#define ECC_TIMEOUT (500000)
  686. +
  687. +#define ECC_IDLE_REG(op) ((op) == ECC_ENCODE ? ECC_ENCIDLE : ECC_DECIDLE)
  688. +#define ECC_CTL_REG(op) ((op) == ECC_ENCODE ? ECC_ENCCON : ECC_DECCON)
  689. +
  690. +struct mtk_ecc_caps {
  691. + u32 err_mask;
  692. + u32 err_shift;
  693. + const u8 *ecc_strength;
  694. + const u32 *ecc_regs;
  695. + u8 num_ecc_strength;
  696. + u8 ecc_mode_shift;
  697. + u32 parity_bits;
  698. + int pg_irq_sel;
  699. +};
  700. +
  701. +struct mtk_ecc {
  702. + struct device *dev;
  703. + const struct mtk_ecc_caps *caps;
  704. + void __iomem *regs;
  705. + struct clk *clk;
  706. +
  707. + struct completion done;
  708. + struct mutex lock;
  709. + u32 sectors;
  710. +
  711. + u8 *eccdata;
  712. +};
  713. +
  714. +/* ecc strength that each IP supports */
  715. +static const u8 ecc_strength_mt2701[] = {
  716. + 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36,
  717. + 40, 44, 48, 52, 56, 60
  718. +};
  719. +
  720. +static const u8 ecc_strength_mt2712[] = {
  721. + 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36,
  722. + 40, 44, 48, 52, 56, 60, 68, 72, 80
  723. +};
  724. +
  725. +static const u8 ecc_strength_mt7622[] = {
  726. + 4, 6, 8, 10, 12
  727. +};
  728. +
  729. +enum mtk_ecc_regs {
  730. + ECC_ENCPAR00,
  731. + ECC_ENCIRQ_EN,
  732. + ECC_ENCIRQ_STA,
  733. + ECC_DECDONE,
  734. + ECC_DECIRQ_EN,
  735. + ECC_DECIRQ_STA,
  736. +};
  737. +
  738. +static int mt2701_ecc_regs[] = {
  739. + [ECC_ENCPAR00] = 0x10,
  740. + [ECC_ENCIRQ_EN] = 0x80,
  741. + [ECC_ENCIRQ_STA] = 0x84,
  742. + [ECC_DECDONE] = 0x124,
  743. + [ECC_DECIRQ_EN] = 0x200,
  744. + [ECC_DECIRQ_STA] = 0x204,
  745. +};
  746. +
  747. +static int mt2712_ecc_regs[] = {
  748. + [ECC_ENCPAR00] = 0x300,
  749. + [ECC_ENCIRQ_EN] = 0x80,
  750. + [ECC_ENCIRQ_STA] = 0x84,
  751. + [ECC_DECDONE] = 0x124,
  752. + [ECC_DECIRQ_EN] = 0x200,
  753. + [ECC_DECIRQ_STA] = 0x204,
  754. +};
  755. +
  756. +static int mt7622_ecc_regs[] = {
  757. + [ECC_ENCPAR00] = 0x10,
  758. + [ECC_ENCIRQ_EN] = 0x30,
  759. + [ECC_ENCIRQ_STA] = 0x34,
  760. + [ECC_DECDONE] = 0x11c,
  761. + [ECC_DECIRQ_EN] = 0x140,
  762. + [ECC_DECIRQ_STA] = 0x144,
  763. +};
  764. +
  765. +static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc,
  766. + enum mtk_ecc_operation op)
  767. +{
  768. + struct device *dev = ecc->dev;
  769. + u32 val;
  770. + int ret;
  771. +
  772. + ret = readl_poll_timeout_atomic(ecc->regs + ECC_IDLE_REG(op), val,
  773. + val & ECC_IDLE_MASK,
  774. + 10, ECC_TIMEOUT);
  775. + if (ret)
  776. + dev_warn(dev, "%s NOT idle\n",
  777. + op == ECC_ENCODE ? "encoder" : "decoder");
  778. +}
  779. +
  780. +static irqreturn_t mtk_ecc_irq(int irq, void *id)
  781. +{
  782. + struct mtk_ecc *ecc = id;
  783. + u32 dec, enc;
  784. +
  785. + dec = readw(ecc->regs + ecc->caps->ecc_regs[ECC_DECIRQ_STA])
  786. + & ECC_IRQ_EN;
  787. + if (dec) {
  788. + dec = readw(ecc->regs + ecc->caps->ecc_regs[ECC_DECDONE]);
  789. + if (dec & ecc->sectors) {
  790. + /*
  791. + * Clear decode IRQ status once again to ensure that
  792. + * there will be no extra IRQ.
  793. + */
  794. + readw(ecc->regs + ecc->caps->ecc_regs[ECC_DECIRQ_STA]);
  795. + ecc->sectors = 0;
  796. + complete(&ecc->done);
  797. + } else {
  798. + return IRQ_HANDLED;
  799. + }
  800. + } else {
  801. + enc = readl(ecc->regs + ecc->caps->ecc_regs[ECC_ENCIRQ_STA])
  802. + & ECC_IRQ_EN;
  803. + if (enc)
  804. + complete(&ecc->done);
  805. + else
  806. + return IRQ_NONE;
  807. + }
  808. +
  809. + return IRQ_HANDLED;
  810. +}
  811. +
  812. +static int mtk_ecc_config(struct mtk_ecc *ecc, struct mtk_ecc_config *config)
  813. +{
  814. + u32 ecc_bit, dec_sz, enc_sz;
  815. + u32 reg, i;
  816. +
  817. + for (i = 0; i < ecc->caps->num_ecc_strength; i++) {
  818. + if (ecc->caps->ecc_strength[i] == config->strength)
  819. + break;
  820. + }
  821. +
  822. + if (i == ecc->caps->num_ecc_strength) {
  823. + dev_err(ecc->dev, "invalid ecc strength %d\n",
  824. + config->strength);
  825. + return -EINVAL;
  826. + }
  827. +
  828. + ecc_bit = i;
  829. +
  830. + if (config->op == ECC_ENCODE) {
  831. + /* configure ECC encoder (in bits) */
  832. + enc_sz = config->len << 3;
  833. +
  834. + reg = ecc_bit | (config->mode << ecc->caps->ecc_mode_shift);
  835. + reg |= (enc_sz << ECC_MS_SHIFT);
  836. + writel(reg, ecc->regs + ECC_ENCCNFG);
  837. +
  838. + if (config->mode != ECC_NFI_MODE)
  839. + writel(lower_32_bits(config->addr),
  840. + ecc->regs + ECC_ENCDIADDR);
  841. +
  842. + } else {
  843. + /* configure ECC decoder (in bits) */
  844. + dec_sz = (config->len << 3) +
  845. + config->strength * ecc->caps->parity_bits;
  846. +
  847. + reg = ecc_bit | (config->mode << ecc->caps->ecc_mode_shift);
  848. + reg |= (dec_sz << ECC_MS_SHIFT) | DEC_CNFG_CORRECT;
  849. + reg |= DEC_EMPTY_EN;
  850. + writel(reg, ecc->regs + ECC_DECCNFG);
  851. +
  852. + if (config->sectors)
  853. + ecc->sectors = 1 << (config->sectors - 1);
  854. + }
  855. +
  856. + return 0;
  857. +}
  858. +
  859. +void mtk_ecc_get_stats(struct mtk_ecc *ecc, struct mtk_ecc_stats *stats,
  860. + int sectors)
  861. +{
  862. + u32 offset, i, err;
  863. + u32 bitflips = 0;
  864. +
  865. + stats->corrected = 0;
  866. + stats->failed = 0;
  867. +
  868. + for (i = 0; i < sectors; i++) {
  869. + offset = (i >> 2) << 2;
  870. + err = readl(ecc->regs + ECC_DECENUM0 + offset);
  871. + err = err >> ((i % 4) * ecc->caps->err_shift);
  872. + err &= ecc->caps->err_mask;
  873. + if (err == ecc->caps->err_mask) {
  874. + /* uncorrectable errors */
  875. + stats->failed++;
  876. + continue;
  877. + }
  878. +
  879. + stats->corrected += err;
  880. + bitflips = max_t(u32, bitflips, err);
  881. + }
  882. +
  883. + stats->bitflips = bitflips;
  884. +}
  885. +EXPORT_SYMBOL(mtk_ecc_get_stats);
  886. +
  887. +void mtk_ecc_release(struct mtk_ecc *ecc)
  888. +{
  889. + clk_disable_unprepare(ecc->clk);
  890. + put_device(ecc->dev);
  891. +}
  892. +EXPORT_SYMBOL(mtk_ecc_release);
  893. +
  894. +static void mtk_ecc_hw_init(struct mtk_ecc *ecc)
  895. +{
  896. + mtk_ecc_wait_idle(ecc, ECC_ENCODE);
  897. + writew(ECC_OP_DISABLE, ecc->regs + ECC_ENCCON);
  898. +
  899. + mtk_ecc_wait_idle(ecc, ECC_DECODE);
  900. + writel(ECC_OP_DISABLE, ecc->regs + ECC_DECCON);
  901. +}
  902. +
  903. +static struct mtk_ecc *mtk_ecc_get(struct device_node *np)
  904. +{
  905. + struct platform_device *pdev;
  906. + struct mtk_ecc *ecc;
  907. +
  908. + pdev = of_find_device_by_node(np);
  909. + if (!pdev)
  910. + return ERR_PTR(-EPROBE_DEFER);
  911. +
  912. + ecc = platform_get_drvdata(pdev);
  913. + if (!ecc) {
  914. + put_device(&pdev->dev);
  915. + return ERR_PTR(-EPROBE_DEFER);
  916. + }
  917. +
  918. + clk_prepare_enable(ecc->clk);
  919. + mtk_ecc_hw_init(ecc);
  920. +
  921. + return ecc;
  922. +}
  923. +
  924. +struct mtk_ecc *of_mtk_ecc_get(struct device_node *of_node)
  925. +{
  926. + struct mtk_ecc *ecc = NULL;
  927. + struct device_node *np;
  928. +
  929. + np = of_parse_phandle(of_node, "ecc-engine", 0);
  930. + if (np) {
  931. + ecc = mtk_ecc_get(np);
  932. + of_node_put(np);
  933. + }
  934. +
  935. + return ecc;
  936. +}
  937. +EXPORT_SYMBOL(of_mtk_ecc_get);
  938. +
  939. +int mtk_ecc_enable(struct mtk_ecc *ecc, struct mtk_ecc_config *config)
  940. +{
  941. + enum mtk_ecc_operation op = config->op;
  942. + u16 reg_val;
  943. + int ret;
  944. +
  945. + ret = mutex_lock_interruptible(&ecc->lock);
  946. + if (ret) {
  947. + dev_err(ecc->dev, "interrupted when attempting to lock\n");
  948. + return ret;
  949. + }
  950. +
  951. + mtk_ecc_wait_idle(ecc, op);
  952. +
  953. + ret = mtk_ecc_config(ecc, config);
  954. + if (ret) {
  955. + mutex_unlock(&ecc->lock);
  956. + return ret;
  957. + }
  958. +
  959. + if (config->mode != ECC_NFI_MODE || op != ECC_ENCODE) {
  960. + init_completion(&ecc->done);
  961. + reg_val = ECC_IRQ_EN;
  962. + /*
  963. + * For ECC_NFI_MODE, if ecc->caps->pg_irq_sel is 1, then it
  964. + * means this chip can only generate one ecc irq during page
  965. + * read / write. If is 0, generate one ecc irq each ecc step.
  966. + */
  967. + if (ecc->caps->pg_irq_sel && config->mode == ECC_NFI_MODE)
  968. + reg_val |= ECC_PG_IRQ_SEL;
  969. + if (op == ECC_ENCODE)
  970. + writew(reg_val, ecc->regs +
  971. + ecc->caps->ecc_regs[ECC_ENCIRQ_EN]);
  972. + else
  973. + writew(reg_val, ecc->regs +
  974. + ecc->caps->ecc_regs[ECC_DECIRQ_EN]);
  975. + }
  976. +
  977. + writew(ECC_OP_ENABLE, ecc->regs + ECC_CTL_REG(op));
  978. +
  979. + return 0;
  980. +}
  981. +EXPORT_SYMBOL(mtk_ecc_enable);
  982. +
  983. +void mtk_ecc_disable(struct mtk_ecc *ecc)
  984. +{
  985. + enum mtk_ecc_operation op = ECC_ENCODE;
  986. +
  987. + /* find out the running operation */
  988. + if (readw(ecc->regs + ECC_CTL_REG(op)) != ECC_OP_ENABLE)
  989. + op = ECC_DECODE;
  990. +
  991. + /* disable it */
  992. + mtk_ecc_wait_idle(ecc, op);
  993. + if (op == ECC_DECODE) {
  994. + /*
  995. + * Clear decode IRQ status in case there is a timeout to wait
  996. + * decode IRQ.
  997. + */
  998. + readw(ecc->regs + ecc->caps->ecc_regs[ECC_DECDONE]);
  999. + writew(0, ecc->regs + ecc->caps->ecc_regs[ECC_DECIRQ_EN]);
  1000. + } else {
  1001. + writew(0, ecc->regs + ecc->caps->ecc_regs[ECC_ENCIRQ_EN]);
  1002. + }
  1003. +
  1004. + writew(ECC_OP_DISABLE, ecc->regs + ECC_CTL_REG(op));
  1005. +
  1006. + mutex_unlock(&ecc->lock);
  1007. +}
  1008. +EXPORT_SYMBOL(mtk_ecc_disable);
  1009. +
  1010. +int mtk_ecc_wait_done(struct mtk_ecc *ecc, enum mtk_ecc_operation op)
  1011. +{
  1012. + int ret;
  1013. +
  1014. + ret = wait_for_completion_timeout(&ecc->done, msecs_to_jiffies(500));
  1015. + if (!ret) {
  1016. + dev_err(ecc->dev, "%s timeout - interrupt did not arrive)\n",
  1017. + (op == ECC_ENCODE) ? "encoder" : "decoder");
  1018. + return -ETIMEDOUT;
  1019. + }
  1020. +
  1021. + return 0;
  1022. +}
  1023. +EXPORT_SYMBOL(mtk_ecc_wait_done);
  1024. +
  1025. +int mtk_ecc_encode(struct mtk_ecc *ecc, struct mtk_ecc_config *config,
  1026. + u8 *data, u32 bytes)
  1027. +{
  1028. + dma_addr_t addr;
  1029. + u32 len;
  1030. + int ret;
  1031. +
  1032. + addr = dma_map_single(ecc->dev, data, bytes, DMA_TO_DEVICE);
  1033. + ret = dma_mapping_error(ecc->dev, addr);
  1034. + if (ret) {
  1035. + dev_err(ecc->dev, "dma mapping error\n");
  1036. + return -EINVAL;
  1037. + }
  1038. +
  1039. + config->op = ECC_ENCODE;
  1040. + config->addr = addr;
  1041. + ret = mtk_ecc_enable(ecc, config);
  1042. + if (ret) {
  1043. + dma_unmap_single(ecc->dev, addr, bytes, DMA_TO_DEVICE);
  1044. + return ret;
  1045. + }
  1046. +
  1047. + ret = mtk_ecc_wait_done(ecc, ECC_ENCODE);
  1048. + if (ret)
  1049. + goto timeout;
  1050. +
  1051. + mtk_ecc_wait_idle(ecc, ECC_ENCODE);
  1052. +
  1053. + /* Program ECC bytes to OOB: per sector oob = FDM + ECC + SPARE */
  1054. + len = (config->strength * ecc->caps->parity_bits + 7) >> 3;
  1055. +
  1056. + /* write the parity bytes generated by the ECC back to temp buffer */
  1057. + __ioread32_copy(ecc->eccdata,
  1058. + ecc->regs + ecc->caps->ecc_regs[ECC_ENCPAR00],
  1059. + round_up(len, 4));
  1060. +
  1061. + /* copy into possibly unaligned OOB region with actual length */
  1062. + memcpy(data + bytes, ecc->eccdata, len);
  1063. +timeout:
  1064. +
  1065. + dma_unmap_single(ecc->dev, addr, bytes, DMA_TO_DEVICE);
  1066. + mtk_ecc_disable(ecc);
  1067. +
  1068. + return ret;
  1069. +}
  1070. +EXPORT_SYMBOL(mtk_ecc_encode);
  1071. +
  1072. +void mtk_ecc_adjust_strength(struct mtk_ecc *ecc, u32 *p)
  1073. +{
  1074. + const u8 *ecc_strength = ecc->caps->ecc_strength;
  1075. + int i;
  1076. +
  1077. + for (i = 0; i < ecc->caps->num_ecc_strength; i++) {
  1078. + if (*p <= ecc_strength[i]) {
  1079. + if (!i)
  1080. + *p = ecc_strength[i];
  1081. + else if (*p != ecc_strength[i])
  1082. + *p = ecc_strength[i - 1];
  1083. + return;
  1084. + }
  1085. + }
  1086. +
  1087. + *p = ecc_strength[ecc->caps->num_ecc_strength - 1];
  1088. +}
  1089. +EXPORT_SYMBOL(mtk_ecc_adjust_strength);
  1090. +
  1091. +unsigned int mtk_ecc_get_parity_bits(struct mtk_ecc *ecc)
  1092. +{
  1093. + return ecc->caps->parity_bits;
  1094. +}
  1095. +EXPORT_SYMBOL(mtk_ecc_get_parity_bits);
  1096. +
  1097. +static const struct mtk_ecc_caps mtk_ecc_caps_mt2701 = {
  1098. + .err_mask = 0x3f,
  1099. + .err_shift = 8,
  1100. + .ecc_strength = ecc_strength_mt2701,
  1101. + .ecc_regs = mt2701_ecc_regs,
  1102. + .num_ecc_strength = 20,
  1103. + .ecc_mode_shift = 5,
  1104. + .parity_bits = 14,
  1105. + .pg_irq_sel = 0,
  1106. +};
  1107. +
  1108. +static const struct mtk_ecc_caps mtk_ecc_caps_mt2712 = {
  1109. + .err_mask = 0x7f,
  1110. + .err_shift = 8,
  1111. + .ecc_strength = ecc_strength_mt2712,
  1112. + .ecc_regs = mt2712_ecc_regs,
  1113. + .num_ecc_strength = 23,
  1114. + .ecc_mode_shift = 5,
  1115. + .parity_bits = 14,
  1116. + .pg_irq_sel = 1,
  1117. +};
  1118. +
  1119. +static const struct mtk_ecc_caps mtk_ecc_caps_mt7622 = {
  1120. + .err_mask = 0x1f,
  1121. + .err_shift = 5,
  1122. + .ecc_strength = ecc_strength_mt7622,
  1123. + .ecc_regs = mt7622_ecc_regs,
  1124. + .num_ecc_strength = 5,
  1125. + .ecc_mode_shift = 4,
  1126. + .parity_bits = 13,
  1127. + .pg_irq_sel = 0,
  1128. +};
  1129. +
  1130. +static const struct of_device_id mtk_ecc_dt_match[] = {
  1131. + {
  1132. + .compatible = "mediatek,mt2701-ecc",
  1133. + .data = &mtk_ecc_caps_mt2701,
  1134. + }, {
  1135. + .compatible = "mediatek,mt2712-ecc",
  1136. + .data = &mtk_ecc_caps_mt2712,
  1137. + }, {
  1138. + .compatible = "mediatek,mt7622-ecc",
  1139. + .data = &mtk_ecc_caps_mt7622,
  1140. + },
  1141. + {},
  1142. +};
  1143. +
  1144. +static int mtk_ecc_probe(struct platform_device *pdev)
  1145. +{
  1146. + struct device *dev = &pdev->dev;
  1147. + struct mtk_ecc *ecc;
  1148. + struct resource *res;
  1149. + u32 max_eccdata_size;
  1150. + int irq, ret;
  1151. +
  1152. + ecc = devm_kzalloc(dev, sizeof(*ecc), GFP_KERNEL);
  1153. + if (!ecc)
  1154. + return -ENOMEM;
  1155. +
  1156. + ecc->caps = of_device_get_match_data(dev);
  1157. +
  1158. + max_eccdata_size = ecc->caps->num_ecc_strength - 1;
  1159. + max_eccdata_size = ecc->caps->ecc_strength[max_eccdata_size];
  1160. + max_eccdata_size = (max_eccdata_size * ecc->caps->parity_bits + 7) >> 3;
  1161. + max_eccdata_size = round_up(max_eccdata_size, 4);
  1162. + ecc->eccdata = devm_kzalloc(dev, max_eccdata_size, GFP_KERNEL);
  1163. + if (!ecc->eccdata)
  1164. + return -ENOMEM;
  1165. +
  1166. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  1167. + ecc->regs = devm_ioremap_resource(dev, res);
  1168. + if (IS_ERR(ecc->regs))
  1169. + return PTR_ERR(ecc->regs);
  1170. +
  1171. + ecc->clk = devm_clk_get(dev, NULL);
  1172. + if (IS_ERR(ecc->clk)) {
  1173. + dev_err(dev, "failed to get clock: %ld\n", PTR_ERR(ecc->clk));
  1174. + return PTR_ERR(ecc->clk);
  1175. + }
  1176. +
  1177. + irq = platform_get_irq(pdev, 0);
  1178. + if (irq < 0)
  1179. + return irq;
  1180. +
  1181. + ret = dma_set_mask(dev, DMA_BIT_MASK(32));
  1182. + if (ret) {
  1183. + dev_err(dev, "failed to set DMA mask\n");
  1184. + return ret;
  1185. + }
  1186. +
  1187. + ret = devm_request_irq(dev, irq, mtk_ecc_irq, 0x0, "mtk-ecc", ecc);
  1188. + if (ret) {
  1189. + dev_err(dev, "failed to request irq\n");
  1190. + return -EINVAL;
  1191. + }
  1192. +
  1193. + ecc->dev = dev;
  1194. + mutex_init(&ecc->lock);
  1195. + platform_set_drvdata(pdev, ecc);
  1196. + dev_info(dev, "probed\n");
  1197. +
  1198. + return 0;
  1199. +}
  1200. +
  1201. +#ifdef CONFIG_PM_SLEEP
  1202. +static int mtk_ecc_suspend(struct device *dev)
  1203. +{
  1204. + struct mtk_ecc *ecc = dev_get_drvdata(dev);
  1205. +
  1206. + clk_disable_unprepare(ecc->clk);
  1207. +
  1208. + return 0;
  1209. +}
  1210. +
  1211. +static int mtk_ecc_resume(struct device *dev)
  1212. +{
  1213. + struct mtk_ecc *ecc = dev_get_drvdata(dev);
  1214. + int ret;
  1215. +
  1216. + ret = clk_prepare_enable(ecc->clk);
  1217. + if (ret) {
  1218. + dev_err(dev, "failed to enable clk\n");
  1219. + return ret;
  1220. + }
  1221. +
  1222. + return 0;
  1223. +}
  1224. +
  1225. +static SIMPLE_DEV_PM_OPS(mtk_ecc_pm_ops, mtk_ecc_suspend, mtk_ecc_resume);
  1226. +#endif
  1227. +
  1228. +MODULE_DEVICE_TABLE(of, mtk_ecc_dt_match);
  1229. +
  1230. +static struct platform_driver mtk_ecc_driver = {
  1231. + .probe = mtk_ecc_probe,
  1232. + .driver = {
  1233. + .name = "mtk-ecc",
  1234. + .of_match_table = of_match_ptr(mtk_ecc_dt_match),
  1235. +#ifdef CONFIG_PM_SLEEP
  1236. + .pm = &mtk_ecc_pm_ops,
  1237. +#endif
  1238. + },
  1239. +};
  1240. +
  1241. +module_platform_driver(mtk_ecc_driver);
  1242. +
  1243. +MODULE_AUTHOR("Xiaolei Li <[email protected]>");
  1244. +MODULE_DESCRIPTION("MTK Nand ECC Driver");
  1245. +MODULE_LICENSE("Dual MIT/GPL");
  1246. --- a/drivers/mtd/nand/raw/Kconfig
  1247. +++ b/drivers/mtd/nand/raw/Kconfig
  1248. @@ -360,6 +360,7 @@ config MTD_NAND_QCOM
  1249. config MTD_NAND_MTK
  1250. tristate "MTK NAND controller"
  1251. + depends on MTD_NAND_ECC_MEDIATEK
  1252. depends on ARCH_MEDIATEK || COMPILE_TEST
  1253. depends on HAS_IOMEM
  1254. help
  1255. --- a/drivers/mtd/nand/raw/Makefile
  1256. +++ b/drivers/mtd/nand/raw/Makefile
  1257. @@ -48,7 +48,7 @@ obj-$(CONFIG_MTD_NAND_SUNXI) += sunxi_n
  1258. obj-$(CONFIG_MTD_NAND_HISI504) += hisi504_nand.o
  1259. obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand/
  1260. obj-$(CONFIG_MTD_NAND_QCOM) += qcom_nandc.o
  1261. -obj-$(CONFIG_MTD_NAND_MTK) += mtk_ecc.o mtk_nand.o
  1262. +obj-$(CONFIG_MTD_NAND_MTK) += mtk_nand.o
  1263. obj-$(CONFIG_MTD_NAND_MXIC) += mxic_nand.o
  1264. obj-$(CONFIG_MTD_NAND_TEGRA) += tegra_nand.o
  1265. obj-$(CONFIG_MTD_NAND_STM32_FMC2) += stm32_fmc2_nand.o
  1266. --- a/drivers/mtd/nand/raw/mtk_nand.c
  1267. +++ b/drivers/mtd/nand/raw/mtk_nand.c
  1268. @@ -17,7 +17,7 @@
  1269. #include <linux/iopoll.h>
  1270. #include <linux/of.h>
  1271. #include <linux/of_device.h>
  1272. -#include "mtk_ecc.h"
  1273. +#include <linux/mtd/nand-ecc-mtk.h>
  1274. /* NAND controller register definition */
  1275. #define NFI_CNFG (0x00)
  1276. --- a/drivers/mtd/nand/raw/mtk_ecc.h
  1277. +++ /dev/null
  1278. @@ -1,47 +0,0 @@
  1279. -/* SPDX-License-Identifier: GPL-2.0 OR MIT */
  1280. -/*
  1281. - * MTK SDG1 ECC controller
  1282. - *
  1283. - * Copyright (c) 2016 Mediatek
  1284. - * Authors: Xiaolei Li <[email protected]>
  1285. - * Jorge Ramirez-Ortiz <[email protected]>
  1286. - */
  1287. -
  1288. -#ifndef __DRIVERS_MTD_NAND_MTK_ECC_H__
  1289. -#define __DRIVERS_MTD_NAND_MTK_ECC_H__
  1290. -
  1291. -#include <linux/types.h>
  1292. -
  1293. -enum mtk_ecc_mode {ECC_DMA_MODE = 0, ECC_NFI_MODE = 1};
  1294. -enum mtk_ecc_operation {ECC_ENCODE, ECC_DECODE};
  1295. -
  1296. -struct device_node;
  1297. -struct mtk_ecc;
  1298. -
  1299. -struct mtk_ecc_stats {
  1300. - u32 corrected;
  1301. - u32 bitflips;
  1302. - u32 failed;
  1303. -};
  1304. -
  1305. -struct mtk_ecc_config {
  1306. - enum mtk_ecc_operation op;
  1307. - enum mtk_ecc_mode mode;
  1308. - dma_addr_t addr;
  1309. - u32 strength;
  1310. - u32 sectors;
  1311. - u32 len;
  1312. -};
  1313. -
  1314. -int mtk_ecc_encode(struct mtk_ecc *, struct mtk_ecc_config *, u8 *, u32);
  1315. -void mtk_ecc_get_stats(struct mtk_ecc *, struct mtk_ecc_stats *, int);
  1316. -int mtk_ecc_wait_done(struct mtk_ecc *, enum mtk_ecc_operation);
  1317. -int mtk_ecc_enable(struct mtk_ecc *, struct mtk_ecc_config *);
  1318. -void mtk_ecc_disable(struct mtk_ecc *);
  1319. -void mtk_ecc_adjust_strength(struct mtk_ecc *ecc, u32 *p);
  1320. -unsigned int mtk_ecc_get_parity_bits(struct mtk_ecc *ecc);
  1321. -
  1322. -struct mtk_ecc *of_mtk_ecc_get(struct device_node *);
  1323. -void mtk_ecc_release(struct mtk_ecc *);
  1324. -
  1325. -#endif
  1326. --- /dev/null
  1327. +++ b/include/linux/mtd/nand-ecc-mtk.h
  1328. @@ -0,0 +1,47 @@
  1329. +/* SPDX-License-Identifier: GPL-2.0 OR MIT */
  1330. +/*
  1331. + * MTK SDG1 ECC controller
  1332. + *
  1333. + * Copyright (c) 2016 Mediatek
  1334. + * Authors: Xiaolei Li <[email protected]>
  1335. + * Jorge Ramirez-Ortiz <[email protected]>
  1336. + */
  1337. +
  1338. +#ifndef __DRIVERS_MTD_NAND_MTK_ECC_H__
  1339. +#define __DRIVERS_MTD_NAND_MTK_ECC_H__
  1340. +
  1341. +#include <linux/types.h>
  1342. +
  1343. +enum mtk_ecc_mode {ECC_DMA_MODE = 0, ECC_NFI_MODE = 1};
  1344. +enum mtk_ecc_operation {ECC_ENCODE, ECC_DECODE};
  1345. +
  1346. +struct device_node;
  1347. +struct mtk_ecc;
  1348. +
  1349. +struct mtk_ecc_stats {
  1350. + u32 corrected;
  1351. + u32 bitflips;
  1352. + u32 failed;
  1353. +};
  1354. +
  1355. +struct mtk_ecc_config {
  1356. + enum mtk_ecc_operation op;
  1357. + enum mtk_ecc_mode mode;
  1358. + dma_addr_t addr;
  1359. + u32 strength;
  1360. + u32 sectors;
  1361. + u32 len;
  1362. +};
  1363. +
  1364. +int mtk_ecc_encode(struct mtk_ecc *, struct mtk_ecc_config *, u8 *, u32);
  1365. +void mtk_ecc_get_stats(struct mtk_ecc *, struct mtk_ecc_stats *, int);
  1366. +int mtk_ecc_wait_done(struct mtk_ecc *, enum mtk_ecc_operation);
  1367. +int mtk_ecc_enable(struct mtk_ecc *, struct mtk_ecc_config *);
  1368. +void mtk_ecc_disable(struct mtk_ecc *);
  1369. +void mtk_ecc_adjust_strength(struct mtk_ecc *ecc, u32 *p);
  1370. +unsigned int mtk_ecc_get_parity_bits(struct mtk_ecc *ecc);
  1371. +
  1372. +struct mtk_ecc *of_mtk_ecc_get(struct device_node *);
  1373. +void mtk_ecc_release(struct mtk_ecc *);
  1374. +
  1375. +#endif