18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2018 Toradex AG 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Author: Marcel Ziswiler <marcel.ziswiler@toradex.com> 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/mtd/rawnand.h> 98c2ecf20Sopenharmony_ci#include "internals.h" 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_cistatic void esmt_nand_decode_id(struct nand_chip *chip) 128c2ecf20Sopenharmony_ci{ 138c2ecf20Sopenharmony_ci struct nand_device *base = &chip->base; 148c2ecf20Sopenharmony_ci struct nand_ecc_props requirements = {}; 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci nand_decode_ext_id(chip); 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci /* Extract ECC requirements from 5th id byte. */ 198c2ecf20Sopenharmony_ci if (chip->id.len >= 5 && nand_is_slc(chip)) { 208c2ecf20Sopenharmony_ci requirements.step_size = 512; 218c2ecf20Sopenharmony_ci switch (chip->id.data[4] & 0x3) { 228c2ecf20Sopenharmony_ci case 0x0: 238c2ecf20Sopenharmony_ci requirements.strength = 4; 248c2ecf20Sopenharmony_ci break; 258c2ecf20Sopenharmony_ci case 0x1: 268c2ecf20Sopenharmony_ci requirements.strength = 2; 278c2ecf20Sopenharmony_ci break; 288c2ecf20Sopenharmony_ci case 0x2: 298c2ecf20Sopenharmony_ci requirements.strength = 1; 308c2ecf20Sopenharmony_ci break; 318c2ecf20Sopenharmony_ci default: 328c2ecf20Sopenharmony_ci WARN(1, "Could not get ECC info"); 338c2ecf20Sopenharmony_ci requirements.step_size = 0; 348c2ecf20Sopenharmony_ci break; 358c2ecf20Sopenharmony_ci } 368c2ecf20Sopenharmony_ci } 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci nanddev_set_ecc_requirements(base, &requirements); 398c2ecf20Sopenharmony_ci} 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_cistatic int esmt_nand_init(struct nand_chip *chip) 428c2ecf20Sopenharmony_ci{ 438c2ecf20Sopenharmony_ci if (nand_is_slc(chip)) 448c2ecf20Sopenharmony_ci /* 458c2ecf20Sopenharmony_ci * It is known that some ESMT SLC NANDs have been shipped 468c2ecf20Sopenharmony_ci * with the factory bad block markers in the first or last page 478c2ecf20Sopenharmony_ci * of the block, instead of the first or second page. To be on 488c2ecf20Sopenharmony_ci * the safe side, let's check all three locations. 498c2ecf20Sopenharmony_ci */ 508c2ecf20Sopenharmony_ci chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE | 518c2ecf20Sopenharmony_ci NAND_BBM_LASTPAGE; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci return 0; 548c2ecf20Sopenharmony_ci} 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ciconst struct nand_manufacturer_ops esmt_nand_manuf_ops = { 578c2ecf20Sopenharmony_ci .detect = esmt_nand_decode_id, 588c2ecf20Sopenharmony_ci .init = esmt_nand_init, 598c2ecf20Sopenharmony_ci}; 60