linux/drivers/mtd/nand/raw/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
  15#include "internals.h"
  16
  17#define ONFI_DYN_TIMING_MAX U16_MAX
  18
  19static const struct nand_data_interface onfi_sdr_timings[] = {
  20        /* Mode 0 */
  21        {
  22                .type = NAND_SDR_IFACE,
  23                .timings.sdr = {
  24                        .tCCS_min = 500000,
  25                        .tR_max = 200000000,
  26                        .tADL_min = 400000,
  27                        .tALH_min = 20000,
  28                        .tALS_min = 50000,
  29                        .tAR_min = 25000,
  30                        .tCEA_max = 100000,
  31                        .tCEH_min = 20000,
  32                        .tCH_min = 20000,
  33                        .tCHZ_max = 100000,
  34                        .tCLH_min = 20000,
  35                        .tCLR_min = 20000,
  36                        .tCLS_min = 50000,
  37                        .tCOH_min = 0,
  38                        .tCS_min = 70000,
  39                        .tDH_min = 20000,
  40                        .tDS_min = 40000,
  41                        .tFEAT_max = 1000000,
  42                        .tIR_min = 10000,
  43                        .tITC_max = 1000000,
  44                        .tRC_min = 100000,
  45                        .tREA_max = 40000,
  46                        .tREH_min = 30000,
  47                        .tRHOH_min = 0,
  48                        .tRHW_min = 200000,
  49                        .tRHZ_max = 200000,
  50                        .tRLOH_min = 0,
  51                        .tRP_min = 50000,
  52                        .tRR_min = 40000,
  53                        .tRST_max = 250000000000ULL,
  54                        .tWB_max = 200000,
  55                        .tWC_min = 100000,
  56                        .tWH_min = 30000,
  57                        .tWHR_min = 120000,
  58                        .tWP_min = 50000,
  59                        .tWW_min = 100000,
  60                },
  61        },
  62        /* Mode 1 */
  63        {
  64                .type = NAND_SDR_IFACE,
  65                .timings.sdr = {
  66                        .tCCS_min = 500000,
  67                        .tR_max = 200000000,
  68                        .tADL_min = 400000,
  69                        .tALH_min = 10000,
  70                        .tALS_min = 25000,
  71                        .tAR_min = 10000,
  72                        .tCEA_max = 45000,
  73                        .tCEH_min = 20000,
  74                        .tCH_min = 10000,
  75                        .tCHZ_max = 50000,
  76                        .tCLH_min = 10000,
  77                        .tCLR_min = 10000,
  78                        .tCLS_min = 25000,
  79                        .tCOH_min = 15000,
  80                        .tCS_min = 35000,
  81                        .tDH_min = 10000,
  82                        .tDS_min = 20000,
  83                        .tFEAT_max = 1000000,
  84                        .tIR_min = 0,
  85                        .tITC_max = 1000000,
  86                        .tRC_min = 50000,
  87                        .tREA_max = 30000,
  88                        .tREH_min = 15000,
  89                        .tRHOH_min = 15000,
  90                        .tRHW_min = 100000,
  91                        .tRHZ_max = 100000,
  92                        .tRLOH_min = 0,
  93                        .tRP_min = 25000,
  94                        .tRR_min = 20000,
  95                        .tRST_max = 500000000,
  96                        .tWB_max = 100000,
  97                        .tWC_min = 45000,
  98                        .tWH_min = 15000,
  99                        .tWHR_min = 80000,
 100                        .tWP_min = 25000,
 101                        .tWW_min = 100000,
 102                },
 103        },
 104        /* Mode 2 */
 105        {
 106                .type = NAND_SDR_IFACE,
 107                .timings.sdr = {
 108                        .tCCS_min = 500000,
 109                        .tR_max = 200000000,
 110                        .tADL_min = 400000,
 111                        .tALH_min = 10000,
 112                        .tALS_min = 15000,
 113                        .tAR_min = 10000,
 114                        .tCEA_max = 30000,
 115                        .tCEH_min = 20000,
 116                        .tCH_min = 10000,
 117                        .tCHZ_max = 50000,
 118                        .tCLH_min = 10000,
 119                        .tCLR_min = 10000,
 120                        .tCLS_min = 15000,
 121                        .tCOH_min = 15000,
 122                        .tCS_min = 25000,
 123                        .tDH_min = 5000,
 124                        .tDS_min = 15000,
 125                        .tFEAT_max = 1000000,
 126                        .tIR_min = 0,
 127                        .tITC_max = 1000000,
 128                        .tRC_min = 35000,
 129                        .tREA_max = 25000,
 130                        .tREH_min = 15000,
 131                        .tRHOH_min = 15000,
 132                        .tRHW_min = 100000,
 133                        .tRHZ_max = 100000,
 134                        .tRLOH_min = 0,
 135                        .tRR_min = 20000,
 136                        .tRST_max = 500000000,
 137                        .tWB_max = 100000,
 138                        .tRP_min = 17000,
 139                        .tWC_min = 35000,
 140                        .tWH_min = 15000,
 141                        .tWHR_min = 80000,
 142                        .tWP_min = 17000,
 143                        .tWW_min = 100000,
 144                },
 145        },
 146        /* Mode 3 */
 147        {
 148                .type = NAND_SDR_IFACE,
 149                .timings.sdr = {
 150                        .tCCS_min = 500000,
 151                        .tR_max = 200000000,
 152                        .tADL_min = 400000,
 153                        .tALH_min = 5000,
 154                        .tALS_min = 10000,
 155                        .tAR_min = 10000,
 156                        .tCEA_max = 25000,
 157                        .tCEH_min = 20000,
 158                        .tCH_min = 5000,
 159                        .tCHZ_max = 50000,
 160                        .tCLH_min = 5000,
 161                        .tCLR_min = 10000,
 162                        .tCLS_min = 10000,
 163                        .tCOH_min = 15000,
 164                        .tCS_min = 25000,
 165                        .tDH_min = 5000,
 166                        .tDS_min = 10000,
 167                        .tFEAT_max = 1000000,
 168                        .tIR_min = 0,
 169                        .tITC_max = 1000000,
 170                        .tRC_min = 30000,
 171                        .tREA_max = 20000,
 172                        .tREH_min = 10000,
 173                        .tRHOH_min = 15000,
 174                        .tRHW_min = 100000,
 175                        .tRHZ_max = 100000,
 176                        .tRLOH_min = 0,
 177                        .tRP_min = 15000,
 178                        .tRR_min = 20000,
 179                        .tRST_max = 500000000,
 180                        .tWB_max = 100000,
 181                        .tWC_min = 30000,
 182                        .tWH_min = 10000,
 183                        .tWHR_min = 80000,
 184                        .tWP_min = 15000,
 185                        .tWW_min = 100000,
 186                },
 187        },
 188        /* Mode 4 */
 189        {
 190                .type = NAND_SDR_IFACE,
 191                .timings.sdr = {
 192                        .tCCS_min = 500000,
 193                        .tR_max = 200000000,
 194                        .tADL_min = 400000,
 195                        .tALH_min = 5000,
 196                        .tALS_min = 10000,
 197                        .tAR_min = 10000,
 198                        .tCEA_max = 25000,
 199                        .tCEH_min = 20000,
 200                        .tCH_min = 5000,
 201                        .tCHZ_max = 30000,
 202                        .tCLH_min = 5000,
 203                        .tCLR_min = 10000,
 204                        .tCLS_min = 10000,
 205                        .tCOH_min = 15000,
 206                        .tCS_min = 20000,
 207                        .tDH_min = 5000,
 208                        .tDS_min = 10000,
 209                        .tFEAT_max = 1000000,
 210                        .tIR_min = 0,
 211                        .tITC_max = 1000000,
 212                        .tRC_min = 25000,
 213                        .tREA_max = 20000,
 214                        .tREH_min = 10000,
 215                        .tRHOH_min = 15000,
 216                        .tRHW_min = 100000,
 217                        .tRHZ_max = 100000,
 218                        .tRLOH_min = 5000,
 219                        .tRP_min = 12000,
 220                        .tRR_min = 20000,
 221                        .tRST_max = 500000000,
 222                        .tWB_max = 100000,
 223                        .tWC_min = 25000,
 224                        .tWH_min = 10000,
 225                        .tWHR_min = 80000,
 226                        .tWP_min = 12000,
 227                        .tWW_min = 100000,
 228                },
 229        },
 230        /* Mode 5 */
 231        {
 232                .type = NAND_SDR_IFACE,
 233                .timings.sdr = {
 234                        .tCCS_min = 500000,
 235                        .tR_max = 200000000,
 236                        .tADL_min = 400000,
 237                        .tALH_min = 5000,
 238                        .tALS_min = 10000,
 239                        .tAR_min = 10000,
 240                        .tCEA_max = 25000,
 241                        .tCEH_min = 20000,
 242                        .tCH_min = 5000,
 243                        .tCHZ_max = 30000,
 244                        .tCLH_min = 5000,
 245                        .tCLR_min = 10000,
 246                        .tCLS_min = 10000,
 247                        .tCOH_min = 15000,
 248                        .tCS_min = 15000,
 249                        .tDH_min = 5000,
 250                        .tDS_min = 7000,
 251                        .tFEAT_max = 1000000,
 252                        .tIR_min = 0,
 253                        .tITC_max = 1000000,
 254                        .tRC_min = 20000,
 255                        .tREA_max = 16000,
 256                        .tREH_min = 7000,
 257                        .tRHOH_min = 15000,
 258                        .tRHW_min = 100000,
 259                        .tRHZ_max = 100000,
 260                        .tRLOH_min = 5000,
 261                        .tRP_min = 10000,
 262                        .tRR_min = 20000,
 263                        .tRST_max = 500000000,
 264                        .tWB_max = 100000,
 265                        .tWC_min = 20000,
 266                        .tWH_min = 7000,
 267                        .tWHR_min = 80000,
 268                        .tWP_min = 10000,
 269                        .tWW_min = 100000,
 270                },
 271        },
 272};
 273
 274/**
 275 * onfi_fill_data_interface - [NAND Interface] Initialize a data interface from
 276 * given ONFI mode
 277 * @mode: The ONFI timing mode
 278 */
 279int onfi_fill_data_interface(struct nand_chip *chip,
 280                             enum nand_data_interface_type type,
 281                             int timing_mode)
 282{
 283        struct nand_data_interface *iface = &chip->data_interface;
 284        struct onfi_params *onfi = chip->parameters.onfi;
 285
 286        if (type != NAND_SDR_IFACE)
 287                return -EINVAL;
 288
 289        if (timing_mode < 0 || timing_mode >= ARRAY_SIZE(onfi_sdr_timings))
 290                return -EINVAL;
 291
 292        *iface = onfi_sdr_timings[timing_mode];
 293
 294        /*
 295         * Initialize timings that cannot be deduced from timing mode:
 296         * tPROG, tBERS, tR and tCCS.
 297         * These information are part of the ONFI parameter page.
 298         */
 299        if (onfi) {
 300                struct nand_sdr_timings *timings = &iface->timings.sdr;
 301
 302                /* microseconds -> picoseconds */
 303                timings->tPROG_max = 1000000ULL * onfi->tPROG;
 304                timings->tBERS_max = 1000000ULL * onfi->tBERS;
 305                timings->tR_max = 1000000ULL * onfi->tR;
 306
 307                /* nanoseconds -> picoseconds */
 308                timings->tCCS_min = 1000UL * onfi->tCCS;
 309        } else {
 310                struct nand_sdr_timings *timings = &iface->timings.sdr;
 311                /*
 312                 * For non-ONFI chips we use the highest possible value for
 313                 * tPROG and tBERS. tR and tCCS will take the default values
 314                 * precised in the ONFI specification for timing mode 0,
 315                 * respectively 200us and 500ns.
 316                 */
 317
 318                /* microseconds -> picoseconds */
 319                timings->tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX;
 320                timings->tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX;
 321                timings->tR_max = 1000000ULL * 200000000ULL;
 322
 323                /* nanoseconds -> picoseconds */
 324                timings->tCCS_min = 1000UL * 500000;
 325        }
 326
 327        return 0;
 328}
 329