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/mtd/rawnand.h> 20 hynix_nand_decode_id(struct nand_chip * chip)21static void hynix_nand_decode_id(struct nand_chip *chip) 22 { 23 struct mtd_info *mtd = nand_to_mtd(chip); 24 25 /* Hynix MLC (6 byte ID): Hynix H27UBG8T2B (p.22) */ 26 if (chip->id.len == 6 && !nand_is_slc(chip)) { 27 u8 tmp, extid = chip->id.data[3]; 28 29 /* Extract pagesize */ 30 mtd->writesize = 2048 << (extid & 0x03); 31 extid >>= 2; 32 33 /* Extract oobsize */ 34 switch (((extid >> 2) & 0x4) | (extid & 0x3)) { 35 case 0: 36 mtd->oobsize = 128; 37 break; 38 case 1: 39 mtd->oobsize = 224; 40 break; 41 case 2: 42 mtd->oobsize = 448; 43 break; 44 case 3: 45 mtd->oobsize = 64; 46 break; 47 case 4: 48 mtd->oobsize = 32; 49 break; 50 case 5: 51 mtd->oobsize = 16; 52 break; 53 default: 54 mtd->oobsize = 640; 55 break; 56 } 57 58 /* Extract blocksize */ 59 extid >>= 2; 60 tmp = ((extid >> 1) & 0x04) | (extid & 0x03); 61 if (tmp < 0x03) 62 mtd->erasesize = (128 * 1024) << tmp; 63 else if (tmp == 0x03) 64 mtd->erasesize = 768 * 1024; 65 else 66 mtd->erasesize = (64 * 1024) << tmp; 67 } else { 68 nand_decode_ext_id(chip); 69 } 70 } 71 hynix_nand_init(struct nand_chip * chip)72static int hynix_nand_init(struct nand_chip *chip) 73 { 74 if (!nand_is_slc(chip)) 75 chip->bbt_options |= NAND_BBT_SCANLASTPAGE; 76 else 77 chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; 78 79 return 0; 80 } 81 82 const struct nand_manufacturer_ops hynix_nand_manuf_ops = { 83 .detect = hynix_nand_decode_id, 84 .init = hynix_nand_init, 85 }; 86