aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMasahiro Yamada <yamada.masahiro@socionext.com>2017-03-30 02:45:57 -0400
committerBoris Brezillon <boris.brezillon@free-electrons.com>2017-04-25 08:18:37 -0400
commite7beeeec854c40c28caa53bd84fdf26e9e459f06 (patch)
tree3e473fee320968bee3d762306697cf16e6f3b4b8
parent3f5c35819fc37d5f35680a55327c940b6e8fad41 (diff)
mtd: nand: denali: allow to override revision number
Commit 271707b1d817 ("mtd: nand: denali: max_banks calculation changed in revision 5.1") added a revision check to support the new max_banks encoding. Its git-log states "The encoding of max_banks changed in Denali revision 5.1". There are exceptional cases, for example, the revision register on some UniPhier SoCs says the IP is 5.0 but the max_banks is encoded in the new format. This IP updates the resister specification from time to time (often breaking the backward compatibility), but the revision number is not incremented correctly. The max_banks is not only the case that needs revision checking. Let's allow to override an incorrect revision number. Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com> Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
-rw-r--r--drivers/mtd/nand/denali.c23
-rw-r--r--drivers/mtd/nand/denali.h3
-rw-r--r--drivers/mtd/nand/denali_dt.c5
3 files changed, 18 insertions, 13 deletions
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 417a8950cf49..16634df2e39a 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -419,17 +419,12 @@ static void find_valid_banks(struct denali_nand_info *denali)
419static void detect_max_banks(struct denali_nand_info *denali) 419static void detect_max_banks(struct denali_nand_info *denali)
420{ 420{
421 uint32_t features = ioread32(denali->flash_reg + FEATURES); 421 uint32_t features = ioread32(denali->flash_reg + FEATURES);
422 /*
423 * Read the revision register, so we can calculate the max_banks
424 * properly: the encoding changed from rev 5.0 to 5.1
425 */
426 u32 revision = MAKE_COMPARABLE_REVISION(
427 ioread32(denali->flash_reg + REVISION));
428 422
429 if (revision < REVISION_5_1) 423 denali->max_banks = 1 << (features & FEATURES__N_BANKS);
430 denali->max_banks = 2 << (features & FEATURES__N_BANKS); 424
431 else 425 /* the encoding changed from rev 5.0 to 5.1 */
432 denali->max_banks = 1 << (features & FEATURES__N_BANKS); 426 if (denali->revision < 0x0501)
427 denali->max_banks <<= 1;
433} 428}
434 429
435static uint16_t denali_nand_timing_set(struct denali_nand_info *denali) 430static uint16_t denali_nand_timing_set(struct denali_nand_info *denali)
@@ -1320,6 +1315,14 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col,
1320static void denali_hw_init(struct denali_nand_info *denali) 1315static void denali_hw_init(struct denali_nand_info *denali)
1321{ 1316{
1322 /* 1317 /*
1318 * The REVISION register may not be reliable. Platforms are allowed to
1319 * override it.
1320 */
1321 if (!denali->revision)
1322 denali->revision =
1323 swab16(ioread32(denali->flash_reg + REVISION));
1324
1325 /*
1323 * tell driver how many bit controller will skip before 1326 * tell driver how many bit controller will skip before
1324 * writing ECC code in OOB, this register may be already 1327 * writing ECC code in OOB, this register may be already
1325 * set by firmware. So we read this value out. 1328 * set by firmware. So we read this value out.
diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h
index 1f413d05a010..ec004850652a 100644
--- a/drivers/mtd/nand/denali.h
+++ b/drivers/mtd/nand/denali.h
@@ -179,8 +179,6 @@
179 179
180#define REVISION 0x370 180#define REVISION 0x370
181#define REVISION__VALUE 0xffff 181#define REVISION__VALUE 0xffff
182#define MAKE_COMPARABLE_REVISION(x) swab16((x) & REVISION__VALUE)
183#define REVISION_5_1 0x00000501
184 182
185#define ONFI_DEVICE_FEATURES 0x380 183#define ONFI_DEVICE_FEATURES 0x380
186#define ONFI_DEVICE_FEATURES__VALUE 0x003f 184#define ONFI_DEVICE_FEATURES__VALUE 0x003f
@@ -343,6 +341,7 @@ struct denali_nand_info {
343 int devnum; /* represent how many nands connected */ 341 int devnum; /* represent how many nands connected */
344 int bbtskipbytes; 342 int bbtskipbytes;
345 int max_banks; 343 int max_banks;
344 unsigned int revision;
346 unsigned int caps; 345 unsigned int caps;
347}; 346};
348 347
diff --git a/drivers/mtd/nand/denali_dt.c b/drivers/mtd/nand/denali_dt.c
index ada38636122c..df9ef36cc2ce 100644
--- a/drivers/mtd/nand/denali_dt.c
+++ b/drivers/mtd/nand/denali_dt.c
@@ -30,6 +30,7 @@ struct denali_dt {
30}; 30};
31 31
32struct denali_dt_data { 32struct denali_dt_data {
33 unsigned int revision;
33 unsigned int caps; 34 unsigned int caps;
34}; 35};
35 36
@@ -60,8 +61,10 @@ static int denali_dt_probe(struct platform_device *pdev)
60 denali = &dt->denali; 61 denali = &dt->denali;
61 62
62 data = of_device_get_match_data(&pdev->dev); 63 data = of_device_get_match_data(&pdev->dev);
63 if (data) 64 if (data) {
65 denali->revision = data->revision;
64 denali->caps = data->caps; 66 denali->caps = data->caps;
67 }
65 68
66 denali->platform = DT; 69 denali->platform = DT;
67 denali->dev = &pdev->dev; 70 denali->dev = &pdev->dev;