162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2018 Toradex AG 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Author: Marcel Ziswiler <marcel.ziswiler@toradex.com> 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/mtd/rawnand.h> 962306a36Sopenharmony_ci#include "internals.h" 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_cistatic void esmt_nand_decode_id(struct nand_chip *chip) 1262306a36Sopenharmony_ci{ 1362306a36Sopenharmony_ci struct nand_device *base = &chip->base; 1462306a36Sopenharmony_ci struct nand_ecc_props requirements = {}; 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci nand_decode_ext_id(chip); 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci /* Extract ECC requirements from 5th id byte. */ 1962306a36Sopenharmony_ci if (chip->id.len >= 5 && nand_is_slc(chip)) { 2062306a36Sopenharmony_ci requirements.step_size = 512; 2162306a36Sopenharmony_ci switch (chip->id.data[4] & 0x3) { 2262306a36Sopenharmony_ci case 0x0: 2362306a36Sopenharmony_ci requirements.strength = 4; 2462306a36Sopenharmony_ci break; 2562306a36Sopenharmony_ci case 0x1: 2662306a36Sopenharmony_ci requirements.strength = 2; 2762306a36Sopenharmony_ci break; 2862306a36Sopenharmony_ci case 0x2: 2962306a36Sopenharmony_ci requirements.strength = 1; 3062306a36Sopenharmony_ci break; 3162306a36Sopenharmony_ci default: 3262306a36Sopenharmony_ci WARN(1, "Could not get ECC info"); 3362306a36Sopenharmony_ci requirements.step_size = 0; 3462306a36Sopenharmony_ci break; 3562306a36Sopenharmony_ci } 3662306a36Sopenharmony_ci } 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci nanddev_set_ecc_requirements(base, &requirements); 3962306a36Sopenharmony_ci} 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_cistatic int esmt_nand_init(struct nand_chip *chip) 4262306a36Sopenharmony_ci{ 4362306a36Sopenharmony_ci if (nand_is_slc(chip)) 4462306a36Sopenharmony_ci /* 4562306a36Sopenharmony_ci * It is known that some ESMT SLC NANDs have been shipped 4662306a36Sopenharmony_ci * with the factory bad block markers in the first or last page 4762306a36Sopenharmony_ci * of the block, instead of the first or second page. To be on 4862306a36Sopenharmony_ci * the safe side, let's check all three locations. 4962306a36Sopenharmony_ci */ 5062306a36Sopenharmony_ci chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE | 5162306a36Sopenharmony_ci NAND_BBM_LASTPAGE; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci return 0; 5462306a36Sopenharmony_ci} 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ciconst struct nand_manufacturer_ops esmt_nand_manuf_ops = { 5762306a36Sopenharmony_ci .detect = esmt_nand_decode_id, 5862306a36Sopenharmony_ci .init = esmt_nand_init, 5962306a36Sopenharmony_ci}; 60