/src/u-boot/drivers/mtd/nand/raw/nand_toshiba.c
Line | Count | Source |
1 | | // SPDX-License-Identifier: GPL-2.0+ |
2 | | /* |
3 | | * Copyright (C) 2017 Free Electrons |
4 | | * Copyright (C) 2017 NextThing Co |
5 | | * |
6 | | * Author: Boris Brezillon <boris.brezillon@free-electrons.com> |
7 | | * |
8 | | * This program is free software; you can redistribute it and/or modify |
9 | | * it under the terms of the GNU General Public License as published by |
10 | | * the Free Software Foundation; either version 2 of the License, or |
11 | | * (at your option) any later version. |
12 | | * |
13 | | * This program is distributed in the hope that it will be useful, |
14 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | | * GNU General Public License for more details. |
17 | | */ |
18 | | |
19 | | #include <linux/bug.h> |
20 | | #include <linux/mtd/rawnand.h> |
21 | | |
22 | | static void toshiba_nand_decode_id(struct nand_chip *chip) |
23 | 0 | { |
24 | 0 | struct mtd_info *mtd = nand_to_mtd(chip); |
25 | |
|
26 | 0 | nand_decode_ext_id(chip); |
27 | | |
28 | | /* |
29 | | * Toshiba 24nm raw SLC (i.e., not BENAND) have 32B OOB per |
30 | | * 512B page. For Toshiba SLC, we decode the 5th/6th byte as |
31 | | * follows: |
32 | | * - ID byte 6, bits[2:0]: 100b -> 43nm, 101b -> 32nm, |
33 | | * 110b -> 24nm |
34 | | * - ID byte 5, bit[7]: 1 -> BENAND, 0 -> raw SLC |
35 | | */ |
36 | 0 | if (chip->id.len >= 6 && nand_is_slc(chip) && |
37 | 0 | (chip->id.data[5] & 0x7) == 0x6 /* 24nm */ && |
38 | 0 | !(chip->id.data[4] & 0x80) /* !BENAND */) |
39 | 0 | mtd->oobsize = 32 * mtd->writesize >> 9; |
40 | | |
41 | | /* |
42 | | * Extract ECC requirements from 6th id byte. |
43 | | * For Toshiba SLC, ecc requrements are as follows: |
44 | | * - 43nm: 1 bit ECC for each 512Byte is required. |
45 | | * - 32nm: 4 bit ECC for each 512Byte is required. |
46 | | * - 24nm: 8 bit ECC for each 512Byte is required. |
47 | | */ |
48 | 0 | if (chip->id.len >= 6 && nand_is_slc(chip)) { |
49 | 0 | chip->ecc_step_ds = 512; |
50 | 0 | switch (chip->id.data[5] & 0x7) { |
51 | 0 | case 0x4: |
52 | 0 | chip->ecc_strength_ds = 1; |
53 | 0 | break; |
54 | 0 | case 0x5: |
55 | 0 | chip->ecc_strength_ds = 4; |
56 | 0 | break; |
57 | 0 | case 0x6: |
58 | 0 | chip->ecc_strength_ds = 8; |
59 | 0 | break; |
60 | 0 | default: |
61 | 0 | WARN(1, "Could not get ECC info"); |
62 | 0 | chip->ecc_step_ds = 0; |
63 | 0 | break; |
64 | 0 | } |
65 | 0 | } |
66 | 0 | } |
67 | | |
68 | | static int toshiba_nand_init(struct nand_chip *chip) |
69 | 0 | { |
70 | 0 | if (nand_is_slc(chip)) |
71 | 0 | chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; |
72 | |
|
73 | 0 | return 0; |
74 | 0 | } |
75 | | |
76 | | const struct nand_manufacturer_ops toshiba_nand_manuf_ops = { |
77 | | .detect = toshiba_nand_decode_id, |
78 | | .init = toshiba_nand_init, |
79 | | }; |