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
22static void toshiba_nand_decode_id(struct nand_chip *chip)
23{
24	struct mtd_info *mtd = nand_to_mtd(chip);
25
26	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	if (chip->id.len >= 6 && nand_is_slc(chip) &&
37	    (chip->id.data[5] & 0x7) == 0x6 /* 24nm */ &&
38	    !(chip->id.data[4] & 0x80) /* !BENAND */)
39		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	if (chip->id.len >= 6 && nand_is_slc(chip)) {
49		chip->ecc_step_ds = 512;
50		switch (chip->id.data[5] & 0x7) {
51		case 0x4:
52			chip->ecc_strength_ds = 1;
53			break;
54		case 0x5:
55			chip->ecc_strength_ds = 4;
56			break;
57		case 0x6:
58			chip->ecc_strength_ds = 8;
59			break;
60		default:
61			WARN(1, "Could not get ECC info");
62			chip->ecc_step_ds = 0;
63			break;
64		}
65	}
66}
67
68static int toshiba_nand_init(struct nand_chip *chip)
69{
70	if (nand_is_slc(chip))
71		chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
72
73	return 0;
74}
75
76const struct nand_manufacturer_ops toshiba_nand_manuf_ops = {
77	.detect = toshiba_nand_decode_id,
78	.init = toshiba_nand_init,
79};
80