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