1*c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 23b5206f4SBoris Brezillon /* 33b5206f4SBoris Brezillon * Copyright (C) 2017 Free Electrons 43b5206f4SBoris Brezillon * Copyright (C) 2017 NextThing Co 53b5206f4SBoris Brezillon * 63b5206f4SBoris Brezillon * Author: Boris Brezillon <boris.brezillon@free-electrons.com> 73b5206f4SBoris Brezillon */ 83b5206f4SBoris Brezillon 9348d56a8SBoris Brezillon #include "internals.h" 103b5206f4SBoris Brezillon 1134c5c01eSMiquel Raynal /* 12fe3dd97dSMason Yang * Macronix AC series does not support using SET/GET_FEATURES to change 1334c5c01eSMiquel Raynal * the timings unlike what is declared in the parameter page. Unflag 1434c5c01eSMiquel Raynal * this feature to avoid unnecessary downturns. 1534c5c01eSMiquel Raynal */ 16fe3dd97dSMason Yang static void macronix_nand_fix_broken_get_timings(struct nand_chip *chip) 17fe3dd97dSMason Yang { 18fe3dd97dSMason Yang unsigned int i; 19fe3dd97dSMason Yang static const char * const broken_get_timings[] = { 20fe3dd97dSMason Yang "MX30LF1G18AC", 21fe3dd97dSMason Yang "MX30LF1G28AC", 22fe3dd97dSMason Yang "MX30LF2G18AC", 23fe3dd97dSMason Yang "MX30LF2G28AC", 24fe3dd97dSMason Yang "MX30LF4G18AC", 25fe3dd97dSMason Yang "MX30LF4G28AC", 26fe3dd97dSMason Yang "MX60LF8G18AC", 27acc9d62bSMason Yang "MX30UF1G18AC", 28acc9d62bSMason Yang "MX30UF1G16AC", 29acc9d62bSMason Yang "MX30UF2G18AC", 30acc9d62bSMason Yang "MX30UF2G16AC", 31acc9d62bSMason Yang "MX30UF4G18AC", 32acc9d62bSMason Yang "MX30UF4G16AC", 33acc9d62bSMason Yang "MX30UF4G28AC", 34fe3dd97dSMason Yang }; 35fe3dd97dSMason Yang 36fe3dd97dSMason Yang if (!chip->parameters.supports_set_get_features) 37fe3dd97dSMason Yang return; 38fe3dd97dSMason Yang 39fe3dd97dSMason Yang for (i = 0; i < ARRAY_SIZE(broken_get_timings); i++) { 40fe3dd97dSMason Yang if (!strcmp(broken_get_timings[i], chip->parameters.model)) 41fe3dd97dSMason Yang break; 42fe3dd97dSMason Yang } 43fe3dd97dSMason Yang 44fe3dd97dSMason Yang if (i == ARRAY_SIZE(broken_get_timings)) 45fe3dd97dSMason Yang return; 46fe3dd97dSMason Yang 4734c5c01eSMiquel Raynal bitmap_clear(chip->parameters.get_feature_list, 4834c5c01eSMiquel Raynal ONFI_FEATURE_ADDR_TIMING_MODE, 1); 4934c5c01eSMiquel Raynal bitmap_clear(chip->parameters.set_feature_list, 5034c5c01eSMiquel Raynal ONFI_FEATURE_ADDR_TIMING_MODE, 1); 5134c5c01eSMiquel Raynal } 5234c5c01eSMiquel Raynal 53fe3dd97dSMason Yang static int macronix_nand_init(struct nand_chip *chip) 54fe3dd97dSMason Yang { 55fe3dd97dSMason Yang if (nand_is_slc(chip)) 56bb592548SFrieder Schrempf chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE; 57fe3dd97dSMason Yang 58fe3dd97dSMason Yang macronix_nand_fix_broken_get_timings(chip); 59fe3dd97dSMason Yang 603b5206f4SBoris Brezillon return 0; 613b5206f4SBoris Brezillon } 623b5206f4SBoris Brezillon 633b5206f4SBoris Brezillon const struct nand_manufacturer_ops macronix_nand_manuf_ops = { 643b5206f4SBoris Brezillon .init = macronix_nand_init, 653b5206f4SBoris Brezillon }; 66