root/drivers/mtd/nand/raw/nand_macronix.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. macronix_nand_setup_read_retry
  2. macronix_nand_onfi_init
  3. macronix_nand_fix_broken_get_timings
  4. macronix_nand_init

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   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 
   9 #include "internals.h"
  10 
  11 #define MACRONIX_READ_RETRY_BIT BIT(0)
  12 #define MACRONIX_NUM_READ_RETRY_MODES 6
  13 
  14 struct nand_onfi_vendor_macronix {
  15         u8 reserved;
  16         u8 reliability_func;
  17 } __packed;
  18 
  19 static int macronix_nand_setup_read_retry(struct nand_chip *chip, int mode)
  20 {
  21         u8 feature[ONFI_SUBFEATURE_PARAM_LEN];
  22 
  23         if (!chip->parameters.supports_set_get_features ||
  24             !test_bit(ONFI_FEATURE_ADDR_READ_RETRY,
  25                       chip->parameters.set_feature_list))
  26                 return -ENOTSUPP;
  27 
  28         feature[0] = mode;
  29         return nand_set_features(chip, ONFI_FEATURE_ADDR_READ_RETRY, feature);
  30 }
  31 
  32 static void macronix_nand_onfi_init(struct nand_chip *chip)
  33 {
  34         struct nand_parameters *p = &chip->parameters;
  35         struct nand_onfi_vendor_macronix *mxic;
  36 
  37         if (!p->onfi)
  38                 return;
  39 
  40         mxic = (struct nand_onfi_vendor_macronix *)p->onfi->vendor;
  41         if ((mxic->reliability_func & MACRONIX_READ_RETRY_BIT) == 0)
  42                 return;
  43 
  44         chip->read_retries = MACRONIX_NUM_READ_RETRY_MODES;
  45         chip->setup_read_retry = macronix_nand_setup_read_retry;
  46 
  47         if (p->supports_set_get_features) {
  48                 bitmap_set(p->set_feature_list,
  49                            ONFI_FEATURE_ADDR_READ_RETRY, 1);
  50                 bitmap_set(p->get_feature_list,
  51                            ONFI_FEATURE_ADDR_READ_RETRY, 1);
  52         }
  53 }
  54 
  55 /*
  56  * Macronix AC series does not support using SET/GET_FEATURES to change
  57  * the timings unlike what is declared in the parameter page. Unflag
  58  * this feature to avoid unnecessary downturns.
  59  */
  60 static void macronix_nand_fix_broken_get_timings(struct nand_chip *chip)
  61 {
  62         unsigned int i;
  63         static const char * const broken_get_timings[] = {
  64                 "MX30LF1G18AC",
  65                 "MX30LF1G28AC",
  66                 "MX30LF2G18AC",
  67                 "MX30LF2G28AC",
  68                 "MX30LF4G18AC",
  69                 "MX30LF4G28AC",
  70                 "MX60LF8G18AC",
  71                 "MX30UF1G18AC",
  72                 "MX30UF1G16AC",
  73                 "MX30UF2G18AC",
  74                 "MX30UF2G16AC",
  75                 "MX30UF4G18AC",
  76                 "MX30UF4G16AC",
  77                 "MX30UF4G28AC",
  78         };
  79 
  80         if (!chip->parameters.supports_set_get_features)
  81                 return;
  82 
  83         for (i = 0; i < ARRAY_SIZE(broken_get_timings); i++) {
  84                 if (!strcmp(broken_get_timings[i], chip->parameters.model))
  85                         break;
  86         }
  87 
  88         if (i == ARRAY_SIZE(broken_get_timings))
  89                 return;
  90 
  91         bitmap_clear(chip->parameters.get_feature_list,
  92                      ONFI_FEATURE_ADDR_TIMING_MODE, 1);
  93         bitmap_clear(chip->parameters.set_feature_list,
  94                      ONFI_FEATURE_ADDR_TIMING_MODE, 1);
  95 }
  96 
  97 static int macronix_nand_init(struct nand_chip *chip)
  98 {
  99         if (nand_is_slc(chip))
 100                 chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE;
 101 
 102         macronix_nand_fix_broken_get_timings(chip);
 103         macronix_nand_onfi_init(chip);
 104 
 105         return 0;
 106 }
 107 
 108 const struct nand_manufacturer_ops macronix_nand_manuf_ops = {
 109         .init = macronix_nand_init,
 110 };

/* [<][>][^][v][top][bottom][index][help] */