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