1 |
From fb32abcf0ebc895d1f479bef345e32923bf16eef Mon Sep 17 00:00:00 2001 |
2 |
From: Masahiro Yamada <yamada.masahiro@socionext.com> |
3 |
Date: Fri, 28 Sep 2018 13:16:01 +0900 |
4 |
Subject: [PATCH 026/145] mtd: rawnand: denali: set SPARE_AREA_SKIP_BYTES |
5 |
register to 8 if unset |
6 |
|
7 |
[ Upstream commit 0d55c668b218a1db68b5044bce4de74e1bd0f0c8 ] |
8 |
|
9 |
NAND devices need additional data area (OOB) for error correction, |
10 |
but it is also used for Bad Block Marker (BBM). In many cases, the |
11 |
first byte in OOB is used for BBM, but the location actually depends |
12 |
on chip vendors. The NAND controller should preserve the precious |
13 |
BBM to keep track of bad blocks. |
14 |
|
15 |
In Denali IP, the SPARE_AREA_SKIP_BYTES register is used to specify |
16 |
the number of bytes to skip from the start of OOB. The ECC engine |
17 |
will automatically skip the specified number of bytes when it gets |
18 |
access to OOB area. |
19 |
|
20 |
The same value for SPARE_AREA_SKIP_BYTES should be used between |
21 |
firmware and the operating system if you intend to use the NAND |
22 |
device across the control hand-off. |
23 |
|
24 |
In fact, the current denali.c code expects firmware to have already |
25 |
set the SPARE_AREA_SKIP_BYTES register, then reads the value out. |
26 |
|
27 |
If no firmware (or bootloader) has initialized the controller, the |
28 |
register value is zero, which is the default after power-on-reset. |
29 |
In other words, the Linux driver cannot initialize the controller |
30 |
by itself. |
31 |
|
32 |
Some possible solutions are: |
33 |
|
34 |
[1] Add a DT property to specify the skipped bytes in OOB |
35 |
[2] Associate the preferred value with compatible |
36 |
[3] Hard-code the default value in the driver |
37 |
|
38 |
My first attempt was [1], but in the review process, [3] was suggested |
39 |
as a counter-implementation. |
40 |
(https://lore.kernel.org/patchwork/patch/983055/) |
41 |
|
42 |
The default value 8 was chosen to match to the boot ROM of the UniPhier |
43 |
platform. The preferred value may vary by platform. If so, please |
44 |
trade up to a different solution. |
45 |
|
46 |
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com> |
47 |
Reviewed-by: Boris Brezillon <boris.brezillon@bootlin.com> |
48 |
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> |
49 |
Signed-off-by: Sasha Levin <sashal@kernel.org> |
50 |
--- |
51 |
drivers/mtd/nand/raw/denali.c | 14 ++++++++++---- |
52 |
1 file changed, 10 insertions(+), 4 deletions(-) |
53 |
|
54 |
diff --git a/drivers/mtd/nand/raw/denali.c b/drivers/mtd/nand/raw/denali.c |
55 |
index b864b93dd289..2242e999a76b 100644 |
56 |
--- a/drivers/mtd/nand/raw/denali.c |
57 |
+++ b/drivers/mtd/nand/raw/denali.c |
58 |
@@ -28,6 +28,7 @@ |
59 |
MODULE_LICENSE("GPL"); |
60 |
|
61 |
#define DENALI_NAND_NAME "denali-nand" |
62 |
+#define DENALI_DEFAULT_OOB_SKIP_BYTES 8 |
63 |
|
64 |
/* for Indexed Addressing */ |
65 |
#define DENALI_INDEXED_CTRL 0x00 |
66 |
@@ -1105,12 +1106,17 @@ static void denali_hw_init(struct denali_nand_info *denali) |
67 |
denali->revision = swab16(ioread32(denali->reg + REVISION)); |
68 |
|
69 |
/* |
70 |
- * tell driver how many bit controller will skip before |
71 |
- * writing ECC code in OOB, this register may be already |
72 |
- * set by firmware. So we read this value out. |
73 |
- * if this value is 0, just let it be. |
74 |
+ * Set how many bytes should be skipped before writing data in OOB. |
75 |
+ * If a non-zero value has already been set (by firmware or something), |
76 |
+ * just use it. Otherwise, set the driver default. |
77 |
*/ |
78 |
denali->oob_skip_bytes = ioread32(denali->reg + SPARE_AREA_SKIP_BYTES); |
79 |
+ if (!denali->oob_skip_bytes) { |
80 |
+ denali->oob_skip_bytes = DENALI_DEFAULT_OOB_SKIP_BYTES; |
81 |
+ iowrite32(denali->oob_skip_bytes, |
82 |
+ denali->reg + SPARE_AREA_SKIP_BYTES); |
83 |
+ } |
84 |
+ |
85 |
denali_detect_max_banks(denali); |
86 |
iowrite32(0x0F, denali->reg + RB_PIN_ENABLED); |
87 |
iowrite32(CHIP_EN_DONT_CARE__FLAG, denali->reg + CHIP_ENABLE_DONT_CARE); |
88 |
-- |
89 |
2.19.1 |
90 |
|