1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Copyright (C) 2018 Toradex AG 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Author: Marcel Ziswiler <marcel.ziswiler@toradex.com> 6*4882a593Smuzhiyun */ 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun #include <linux/mtd/rawnand.h> 9*4882a593Smuzhiyun #include "internals.h" 10*4882a593Smuzhiyun esmt_nand_decode_id(struct nand_chip * chip)11*4882a593Smuzhiyunstatic void esmt_nand_decode_id(struct nand_chip *chip) 12*4882a593Smuzhiyun { 13*4882a593Smuzhiyun struct nand_device *base = &chip->base; 14*4882a593Smuzhiyun struct nand_ecc_props requirements = {}; 15*4882a593Smuzhiyun 16*4882a593Smuzhiyun nand_decode_ext_id(chip); 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun /* Extract ECC requirements from 5th id byte. */ 19*4882a593Smuzhiyun if (chip->id.len >= 5 && nand_is_slc(chip)) { 20*4882a593Smuzhiyun requirements.step_size = 512; 21*4882a593Smuzhiyun switch (chip->id.data[4] & 0x3) { 22*4882a593Smuzhiyun case 0x0: 23*4882a593Smuzhiyun requirements.strength = 4; 24*4882a593Smuzhiyun break; 25*4882a593Smuzhiyun case 0x1: 26*4882a593Smuzhiyun requirements.strength = 2; 27*4882a593Smuzhiyun break; 28*4882a593Smuzhiyun case 0x2: 29*4882a593Smuzhiyun requirements.strength = 1; 30*4882a593Smuzhiyun break; 31*4882a593Smuzhiyun default: 32*4882a593Smuzhiyun WARN(1, "Could not get ECC info"); 33*4882a593Smuzhiyun requirements.step_size = 0; 34*4882a593Smuzhiyun break; 35*4882a593Smuzhiyun } 36*4882a593Smuzhiyun } 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun nanddev_set_ecc_requirements(base, &requirements); 39*4882a593Smuzhiyun } 40*4882a593Smuzhiyun esmt_nand_init(struct nand_chip * chip)41*4882a593Smuzhiyunstatic int esmt_nand_init(struct nand_chip *chip) 42*4882a593Smuzhiyun { 43*4882a593Smuzhiyun if (nand_is_slc(chip)) 44*4882a593Smuzhiyun /* 45*4882a593Smuzhiyun * It is known that some ESMT SLC NANDs have been shipped 46*4882a593Smuzhiyun * with the factory bad block markers in the first or last page 47*4882a593Smuzhiyun * of the block, instead of the first or second page. To be on 48*4882a593Smuzhiyun * the safe side, let's check all three locations. 49*4882a593Smuzhiyun */ 50*4882a593Smuzhiyun chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE | 51*4882a593Smuzhiyun NAND_BBM_LASTPAGE; 52*4882a593Smuzhiyun 53*4882a593Smuzhiyun return 0; 54*4882a593Smuzhiyun } 55*4882a593Smuzhiyun 56*4882a593Smuzhiyun const struct nand_manufacturer_ops esmt_nand_manuf_ops = { 57*4882a593Smuzhiyun .detect = esmt_nand_decode_id, 58*4882a593Smuzhiyun .init = esmt_nand_init, 59*4882a593Smuzhiyun }; 60