linux/drivers/mtd/nand/nand_timings.c
<<
>>
Prefs
   1/*
   2 *  Copyright (C) 2014 Free Electrons
   3 *
   4 *  Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 *
  10 */
  11#include <linux/kernel.h>
  12#include <linux/err.h>
  13#include <linux/export.h>
  14#include <linux/mtd/nand.h>
  15
  16static const struct nand_data_interface onfi_sdr_timings[] = {
  17        /* Mode 0 */
  18        {
  19                .type = NAND_SDR_IFACE,
  20                .timings.sdr = {
  21                        .tADL_min = 400000,
  22                        .tALH_min = 20000,
  23                        .tALS_min = 50000,
  24                        .tAR_min = 25000,
  25                        .tCEA_max = 100000,
  26                        .tCEH_min = 20000,
  27                        .tCH_min = 20000,
  28                        .tCHZ_max = 100000,
  29                        .tCLH_min = 20000,
  30                        .tCLR_min = 20000,
  31                        .tCLS_min = 50000,
  32                        .tCOH_min = 0,
  33                        .tCS_min = 70000,
  34                        .tDH_min = 20000,
  35                        .tDS_min = 40000,
  36                        .tFEAT_max = 1000000,
  37                        .tIR_min = 10000,
  38                        .tITC_max = 1000000,
  39                        .tRC_min = 100000,
  40                        .tREA_max = 40000,
  41                        .tREH_min = 30000,
  42                        .tRHOH_min = 0,
  43                        .tRHW_min = 200000,
  44                        .tRHZ_max = 200000,
  45                        .tRLOH_min = 0,
  46                        .tRP_min = 50000,
  47                        .tRR_min = 40000,
  48                        .tRST_max = 250000000000ULL,
  49                        .tWB_max = 200000,
  50                        .tWC_min = 100000,
  51                        .tWH_min = 30000,
  52                        .tWHR_min = 120000,
  53                        .tWP_min = 50000,
  54                        .tWW_min = 100000,
  55                },
  56        },
  57        /* Mode 1 */
  58        {
  59                .type = NAND_SDR_IFACE,
  60                .timings.sdr = {
  61                        .tADL_min = 400000,
  62                        .tALH_min = 10000,
  63                        .tALS_min = 25000,
  64                        .tAR_min = 10000,
  65                        .tCEA_max = 45000,
  66                        .tCEH_min = 20000,
  67                        .tCH_min = 10000,
  68                        .tCHZ_max = 50000,
  69                        .tCLH_min = 10000,
  70                        .tCLR_min = 10000,
  71                        .tCLS_min = 25000,
  72                        .tCOH_min = 15000,
  73                        .tCS_min = 35000,
  74                        .tDH_min = 10000,
  75                        .tDS_min = 20000,
  76                        .tFEAT_max = 1000000,
  77                        .tIR_min = 0,
  78                        .tITC_max = 1000000,
  79                        .tRC_min = 50000,
  80                        .tREA_max = 30000,
  81                        .tREH_min = 15000,
  82                        .tRHOH_min = 15000,
  83                        .tRHW_min = 100000,
  84                        .tRHZ_max = 100000,
  85                        .tRLOH_min = 0,
  86                        .tRP_min = 25000,
  87                        .tRR_min = 20000,
  88                        .tRST_max = 500000000,
  89                        .tWB_max = 100000,
  90                        .tWC_min = 45000,
  91                        .tWH_min = 15000,
  92                        .tWHR_min = 80000,
  93                        .tWP_min = 25000,
  94                        .tWW_min = 100000,
  95                },
  96        },
  97        /* Mode 2 */
  98        {
  99                .type = NAND_SDR_IFACE,
 100                .timings.sdr = {
 101                        .tADL_min = 400000,
 102                        .tALH_min = 10000,
 103                        .tALS_min = 15000,
 104                        .tAR_min = 10000,
 105                        .tCEA_max = 30000,
 106                        .tCEH_min = 20000,
 107                        .tCH_min = 10000,
 108                        .tCHZ_max = 50000,
 109                        .tCLH_min = 10000,
 110                        .tCLR_min = 10000,
 111                        .tCLS_min = 15000,
 112                        .tCOH_min = 15000,
 113                        .tCS_min = 25000,
 114                        .tDH_min = 5000,
 115                        .tDS_min = 15000,
 116                        .tFEAT_max = 1000000,
 117                        .tIR_min = 0,
 118                        .tITC_max = 1000000,
 119                        .tRC_min = 35000,
 120                        .tREA_max = 25000,
 121                        .tREH_min = 15000,
 122                        .tRHOH_min = 15000,
 123                        .tRHW_min = 100000,
 124                        .tRHZ_max = 100000,
 125                        .tRLOH_min = 0,
 126                        .tRR_min = 20000,
 127                        .tRST_max = 500000000,
 128                        .tWB_max = 100000,
 129                        .tRP_min = 17000,
 130                        .tWC_min = 35000,
 131                        .tWH_min = 15000,
 132                        .tWHR_min = 80000,
 133                        .tWP_min = 17000,
 134                        .tWW_min = 100000,
 135                },
 136        },
 137        /* Mode 3 */
 138        {
 139                .type = NAND_SDR_IFACE,
 140                .timings.sdr = {
 141                        .tADL_min = 400000,
 142                        .tALH_min = 5000,
 143                        .tALS_min = 10000,
 144                        .tAR_min = 10000,
 145                        .tCEA_max = 25000,
 146                        .tCEH_min = 20000,
 147                        .tCH_min = 5000,
 148                        .tCHZ_max = 50000,
 149                        .tCLH_min = 5000,
 150                        .tCLR_min = 10000,
 151                        .tCLS_min = 10000,
 152                        .tCOH_min = 15000,
 153                        .tCS_min = 25000,
 154                        .tDH_min = 5000,
 155                        .tDS_min = 10000,
 156                        .tFEAT_max = 1000000,
 157                        .tIR_min = 0,
 158                        .tITC_max = 1000000,
 159                        .tRC_min = 30000,
 160                        .tREA_max = 20000,
 161                        .tREH_min = 10000,
 162                        .tRHOH_min = 15000,
 163                        .tRHW_min = 100000,
 164                        .tRHZ_max = 100000,
 165                        .tRLOH_min = 0,
 166                        .tRP_min = 15000,
 167                        .tRR_min = 20000,
 168                        .tRST_max = 500000000,
 169                        .tWB_max = 100000,
 170                        .tWC_min = 30000,
 171                        .tWH_min = 10000,
 172                        .tWHR_min = 80000,
 173                        .tWP_min = 15000,
 174                        .tWW_min = 100000,
 175                },
 176        },
 177        /* Mode 4 */
 178        {
 179                .type = NAND_SDR_IFACE,
 180                .timings.sdr = {
 181                        .tADL_min = 400000,
 182                        .tALH_min = 5000,
 183                        .tALS_min = 10000,
 184                        .tAR_min = 10000,
 185                        .tCEA_max = 25000,
 186                        .tCEH_min = 20000,
 187                        .tCH_min = 5000,
 188                        .tCHZ_max = 30000,
 189                        .tCLH_min = 5000,
 190                        .tCLR_min = 10000,
 191                        .tCLS_min = 10000,
 192                        .tCOH_min = 15000,
 193                        .tCS_min = 20000,
 194                        .tDH_min = 5000,
 195                        .tDS_min = 10000,
 196                        .tFEAT_max = 1000000,
 197                        .tIR_min = 0,
 198                        .tITC_max = 1000000,
 199                        .tRC_min = 25000,
 200                        .tREA_max = 20000,
 201                        .tREH_min = 10000,
 202                        .tRHOH_min = 15000,
 203                        .tRHW_min = 100000,
 204                        .tRHZ_max = 100000,
 205                        .tRLOH_min = 5000,
 206                        .tRP_min = 12000,
 207                        .tRR_min = 20000,
 208                        .tRST_max = 500000000,
 209                        .tWB_max = 100000,
 210                        .tWC_min = 25000,
 211                        .tWH_min = 10000,
 212                        .tWHR_min = 80000,
 213                        .tWP_min = 12000,
 214                        .tWW_min = 100000,
 215                },
 216        },
 217        /* Mode 5 */
 218        {
 219                .type = NAND_SDR_IFACE,
 220                .timings.sdr = {
 221                        .tADL_min = 400000,
 222                        .tALH_min = 5000,
 223                        .tALS_min = 10000,
 224                        .tAR_min = 10000,
 225                        .tCEA_max = 25000,
 226                        .tCEH_min = 20000,
 227                        .tCH_min = 5000,
 228                        .tCHZ_max = 30000,
 229                        .tCLH_min = 5000,
 230                        .tCLR_min = 10000,
 231                        .tCLS_min = 10000,
 232                        .tCOH_min = 15000,
 233                        .tCS_min = 15000,
 234                        .tDH_min = 5000,
 235                        .tDS_min = 7000,
 236                        .tFEAT_max = 1000000,
 237                        .tIR_min = 0,
 238                        .tITC_max = 1000000,
 239                        .tRC_min = 20000,
 240                        .tREA_max = 16000,
 241                        .tREH_min = 7000,
 242                        .tRHOH_min = 15000,
 243                        .tRHW_min = 100000,
 244                        .tRHZ_max = 100000,
 245                        .tRLOH_min = 5000,
 246                        .tRP_min = 10000,
 247                        .tRR_min = 20000,
 248                        .tRST_max = 500000000,
 249                        .tWB_max = 100000,
 250                        .tWC_min = 20000,
 251                        .tWH_min = 7000,
 252                        .tWHR_min = 80000,
 253                        .tWP_min = 10000,
 254                        .tWW_min = 100000,
 255                },
 256        },
 257};
 258
 259/**
 260 * onfi_async_timing_mode_to_sdr_timings - [NAND Interface] Retrieve NAND
 261 * timings according to the given ONFI timing mode
 262 * @mode: ONFI timing mode
 263 */
 264const struct nand_sdr_timings *onfi_async_timing_mode_to_sdr_timings(int mode)
 265{
 266        if (mode < 0 || mode >= ARRAY_SIZE(onfi_sdr_timings))
 267                return ERR_PTR(-EINVAL);
 268
 269        return &onfi_sdr_timings[mode].timings.sdr;
 270}
 271EXPORT_SYMBOL(onfi_async_timing_mode_to_sdr_timings);
 272
 273/**
 274 * onfi_init_data_interface - [NAND Interface] Initialize a data interface from
 275 * given ONFI mode
 276 * @iface: The data interface to be initialized
 277 * @mode: The ONFI timing mode
 278 */
 279int onfi_init_data_interface(struct nand_chip *chip,
 280                             struct nand_data_interface *iface,
 281                             enum nand_data_interface_type type,
 282                             int timing_mode)
 283{
 284        if (type != NAND_SDR_IFACE)
 285                return -EINVAL;
 286
 287        if (timing_mode < 0 || timing_mode >= ARRAY_SIZE(onfi_sdr_timings))
 288                return -EINVAL;
 289
 290        *iface = onfi_sdr_timings[timing_mode];
 291
 292        /*
 293         * TODO: initialize timings that cannot be deduced from timing mode:
 294         * tR, tPROG, tCCS, ...
 295         * These information are part of the ONFI parameter page.
 296         */
 297
 298        return 0;
 299}
 300EXPORT_SYMBOL(onfi_init_data_interface);
 301
 302/**
 303 * nand_get_default_data_interface - [NAND Interface] Retrieve NAND
 304 * data interface for mode 0. This is used as default timing after
 305 * reset.
 306 */
 307const struct nand_data_interface *nand_get_default_data_interface(void)
 308{
 309        return &onfi_sdr_timings[0];
 310}
 311EXPORT_SYMBOL(nand_get_default_data_interface);
 312