brintos

brintos / linux-shallow public Read only

0
0
Text · 18.5 KiB · 7b41afc Raw
738 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 *  Copyright (C) 2014 Free Electrons4 *5 *  Author: Boris BREZILLON <boris.brezillon@free-electrons.com>6 */7#include <linux/kernel.h>8#include <linux/err.h>9#include <linux/export.h>10 11#include "internals.h"12 13#define ONFI_DYN_TIMING_MAX U16_MAX14 15/*16 * For non-ONFI chips we use the highest possible value for tPROG and tBERS.17 * tR and tCCS will take the default values precised in the ONFI specification18 * for timing mode 0, respectively 200us and 500ns.19 *20 * These four values are tweaked to be more accurate in the case of ONFI chips.21 */22static const struct nand_interface_config onfi_sdr_timings[] = {23	/* Mode 0 */24	{25		.type = NAND_SDR_IFACE,26		.timings.mode = 0,27		.timings.sdr = {28			.tCCS_min = 500000,29			.tR_max = 200000000,30			.tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,31			.tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,32			.tADL_min = 400000,33			.tALH_min = 20000,34			.tALS_min = 50000,35			.tAR_min = 25000,36			.tCEA_max = 100000,37			.tCEH_min = 20000,38			.tCH_min = 20000,39			.tCHZ_max = 100000,40			.tCLH_min = 20000,41			.tCLR_min = 20000,42			.tCLS_min = 50000,43			.tCOH_min = 0,44			.tCS_min = 70000,45			.tDH_min = 20000,46			.tDS_min = 40000,47			.tFEAT_max = 1000000,48			.tIR_min = 10000,49			.tITC_max = 1000000,50			.tRC_min = 100000,51			.tREA_max = 40000,52			.tREH_min = 30000,53			.tRHOH_min = 0,54			.tRHW_min = 200000,55			.tRHZ_max = 200000,56			.tRLOH_min = 0,57			.tRP_min = 50000,58			.tRR_min = 40000,59			.tRST_max = 250000000000ULL,60			.tWB_max = 200000,61			.tWC_min = 100000,62			.tWH_min = 30000,63			.tWHR_min = 120000,64			.tWP_min = 50000,65			.tWW_min = 100000,66		},67	},68	/* Mode 1 */69	{70		.type = NAND_SDR_IFACE,71		.timings.mode = 1,72		.timings.sdr = {73			.tCCS_min = 500000,74			.tR_max = 200000000,75			.tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,76			.tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,77			.tADL_min = 400000,78			.tALH_min = 10000,79			.tALS_min = 25000,80			.tAR_min = 10000,81			.tCEA_max = 45000,82			.tCEH_min = 20000,83			.tCH_min = 10000,84			.tCHZ_max = 50000,85			.tCLH_min = 10000,86			.tCLR_min = 10000,87			.tCLS_min = 25000,88			.tCOH_min = 15000,89			.tCS_min = 35000,90			.tDH_min = 10000,91			.tDS_min = 20000,92			.tFEAT_max = 1000000,93			.tIR_min = 0,94			.tITC_max = 1000000,95			.tRC_min = 50000,96			.tREA_max = 30000,97			.tREH_min = 15000,98			.tRHOH_min = 15000,99			.tRHW_min = 100000,100			.tRHZ_max = 100000,101			.tRLOH_min = 0,102			.tRP_min = 25000,103			.tRR_min = 20000,104			.tRST_max = 500000000,105			.tWB_max = 100000,106			.tWC_min = 45000,107			.tWH_min = 15000,108			.tWHR_min = 80000,109			.tWP_min = 25000,110			.tWW_min = 100000,111		},112	},113	/* Mode 2 */114	{115		.type = NAND_SDR_IFACE,116		.timings.mode = 2,117		.timings.sdr = {118			.tCCS_min = 500000,119			.tR_max = 200000000,120			.tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,121			.tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,122			.tADL_min = 400000,123			.tALH_min = 10000,124			.tALS_min = 15000,125			.tAR_min = 10000,126			.tCEA_max = 30000,127			.tCEH_min = 20000,128			.tCH_min = 10000,129			.tCHZ_max = 50000,130			.tCLH_min = 10000,131			.tCLR_min = 10000,132			.tCLS_min = 15000,133			.tCOH_min = 15000,134			.tCS_min = 25000,135			.tDH_min = 5000,136			.tDS_min = 15000,137			.tFEAT_max = 1000000,138			.tIR_min = 0,139			.tITC_max = 1000000,140			.tRC_min = 35000,141			.tREA_max = 25000,142			.tREH_min = 15000,143			.tRHOH_min = 15000,144			.tRHW_min = 100000,145			.tRHZ_max = 100000,146			.tRLOH_min = 0,147			.tRR_min = 20000,148			.tRST_max = 500000000,149			.tWB_max = 100000,150			.tRP_min = 17000,151			.tWC_min = 35000,152			.tWH_min = 15000,153			.tWHR_min = 80000,154			.tWP_min = 17000,155			.tWW_min = 100000,156		},157	},158	/* Mode 3 */159	{160		.type = NAND_SDR_IFACE,161		.timings.mode = 3,162		.timings.sdr = {163			.tCCS_min = 500000,164			.tR_max = 200000000,165			.tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,166			.tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,167			.tADL_min = 400000,168			.tALH_min = 5000,169			.tALS_min = 10000,170			.tAR_min = 10000,171			.tCEA_max = 25000,172			.tCEH_min = 20000,173			.tCH_min = 5000,174			.tCHZ_max = 50000,175			.tCLH_min = 5000,176			.tCLR_min = 10000,177			.tCLS_min = 10000,178			.tCOH_min = 15000,179			.tCS_min = 25000,180			.tDH_min = 5000,181			.tDS_min = 10000,182			.tFEAT_max = 1000000,183			.tIR_min = 0,184			.tITC_max = 1000000,185			.tRC_min = 30000,186			.tREA_max = 20000,187			.tREH_min = 10000,188			.tRHOH_min = 15000,189			.tRHW_min = 100000,190			.tRHZ_max = 100000,191			.tRLOH_min = 0,192			.tRP_min = 15000,193			.tRR_min = 20000,194			.tRST_max = 500000000,195			.tWB_max = 100000,196			.tWC_min = 30000,197			.tWH_min = 10000,198			.tWHR_min = 80000,199			.tWP_min = 15000,200			.tWW_min = 100000,201		},202	},203	/* Mode 4 */204	{205		.type = NAND_SDR_IFACE,206		.timings.mode = 4,207		.timings.sdr = {208			.tCCS_min = 500000,209			.tR_max = 200000000,210			.tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,211			.tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,212			.tADL_min = 400000,213			.tALH_min = 5000,214			.tALS_min = 10000,215			.tAR_min = 10000,216			.tCEA_max = 25000,217			.tCEH_min = 20000,218			.tCH_min = 5000,219			.tCHZ_max = 30000,220			.tCLH_min = 5000,221			.tCLR_min = 10000,222			.tCLS_min = 10000,223			.tCOH_min = 15000,224			.tCS_min = 20000,225			.tDH_min = 5000,226			.tDS_min = 10000,227			.tFEAT_max = 1000000,228			.tIR_min = 0,229			.tITC_max = 1000000,230			.tRC_min = 25000,231			.tREA_max = 20000,232			.tREH_min = 10000,233			.tRHOH_min = 15000,234			.tRHW_min = 100000,235			.tRHZ_max = 100000,236			.tRLOH_min = 5000,237			.tRP_min = 12000,238			.tRR_min = 20000,239			.tRST_max = 500000000,240			.tWB_max = 100000,241			.tWC_min = 25000,242			.tWH_min = 10000,243			.tWHR_min = 80000,244			.tWP_min = 12000,245			.tWW_min = 100000,246		},247	},248	/* Mode 5 */249	{250		.type = NAND_SDR_IFACE,251		.timings.mode = 5,252		.timings.sdr = {253			.tCCS_min = 500000,254			.tR_max = 200000000,255			.tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,256			.tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,257			.tADL_min = 400000,258			.tALH_min = 5000,259			.tALS_min = 10000,260			.tAR_min = 10000,261			.tCEA_max = 25000,262			.tCEH_min = 20000,263			.tCH_min = 5000,264			.tCHZ_max = 30000,265			.tCLH_min = 5000,266			.tCLR_min = 10000,267			.tCLS_min = 10000,268			.tCOH_min = 15000,269			.tCS_min = 15000,270			.tDH_min = 5000,271			.tDS_min = 7000,272			.tFEAT_max = 1000000,273			.tIR_min = 0,274			.tITC_max = 1000000,275			.tRC_min = 20000,276			.tREA_max = 16000,277			.tREH_min = 7000,278			.tRHOH_min = 15000,279			.tRHW_min = 100000,280			.tRHZ_max = 100000,281			.tRLOH_min = 5000,282			.tRP_min = 10000,283			.tRR_min = 20000,284			.tRST_max = 500000000,285			.tWB_max = 100000,286			.tWC_min = 20000,287			.tWH_min = 7000,288			.tWHR_min = 80000,289			.tWP_min = 10000,290			.tWW_min = 100000,291		},292	},293};294 295static const struct nand_interface_config onfi_nvddr_timings[] = {296	/* Mode 0 */297	{298		.type = NAND_NVDDR_IFACE,299		.timings.mode = 0,300		.timings.nvddr = {301			.tCCS_min = 500000,302			.tR_max = 200000000,303			.tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,304			.tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,305			.tAC_min = 3000,306			.tAC_max = 25000,307			.tADL_min = 400000,308			.tCAD_min = 45000,309			.tCAH_min = 10000,310			.tCALH_min = 10000,311			.tCALS_min = 10000,312			.tCAS_min = 10000,313			.tCEH_min = 20000,314			.tCH_min = 10000,315			.tCK_min = 50000,316			.tCS_min = 35000,317			.tDH_min = 5000,318			.tDQSCK_min = 3000,319			.tDQSCK_max = 25000,320			.tDQSD_min = 0,321			.tDQSD_max = 18000,322			.tDQSHZ_max = 20000,323			.tDQSQ_max = 5000,324			.tDS_min = 5000,325			.tDSC_min = 50000,326			.tFEAT_max = 1000000,327			.tITC_max = 1000000,328			.tQHS_max = 6000,329			.tRHW_min = 100000,330			.tRR_min = 20000,331			.tRST_max = 500000000,332			.tWB_max = 100000,333			.tWHR_min = 80000,334			.tWRCK_min = 20000,335			.tWW_min = 100000,336		},337	},338	/* Mode 1 */339	{340		.type = NAND_NVDDR_IFACE,341		.timings.mode = 1,342		.timings.nvddr = {343			.tCCS_min = 500000,344			.tR_max = 200000000,345			.tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,346			.tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,347			.tAC_min = 3000,348			.tAC_max = 25000,349			.tADL_min = 400000,350			.tCAD_min = 45000,351			.tCAH_min = 5000,352			.tCALH_min = 5000,353			.tCALS_min = 5000,354			.tCAS_min = 5000,355			.tCEH_min = 20000,356			.tCH_min = 5000,357			.tCK_min = 30000,358			.tCS_min = 25000,359			.tDH_min = 2500,360			.tDQSCK_min = 3000,361			.tDQSCK_max = 25000,362			.tDQSD_min = 0,363			.tDQSD_max = 18000,364			.tDQSHZ_max = 20000,365			.tDQSQ_max = 2500,366			.tDS_min = 3000,367			.tDSC_min = 30000,368			.tFEAT_max = 1000000,369			.tITC_max = 1000000,370			.tQHS_max = 3000,371			.tRHW_min = 100000,372			.tRR_min = 20000,373			.tRST_max = 500000000,374			.tWB_max = 100000,375			.tWHR_min = 80000,376			.tWRCK_min = 20000,377			.tWW_min = 100000,378		},379	},380	/* Mode 2 */381	{382		.type = NAND_NVDDR_IFACE,383		.timings.mode = 2,384		.timings.nvddr = {385			.tCCS_min = 500000,386			.tR_max = 200000000,387			.tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,388			.tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,389			.tAC_min = 3000,390			.tAC_max = 25000,391			.tADL_min = 400000,392			.tCAD_min = 45000,393			.tCAH_min = 4000,394			.tCALH_min = 4000,395			.tCALS_min = 4000,396			.tCAS_min = 4000,397			.tCEH_min = 20000,398			.tCH_min = 4000,399			.tCK_min = 20000,400			.tCS_min = 15000,401			.tDH_min = 1700,402			.tDQSCK_min = 3000,403			.tDQSCK_max = 25000,404			.tDQSD_min = 0,405			.tDQSD_max = 18000,406			.tDQSHZ_max = 20000,407			.tDQSQ_max = 1700,408			.tDS_min = 2000,409			.tDSC_min = 20000,410			.tFEAT_max = 1000000,411			.tITC_max = 1000000,412			.tQHS_max = 2000,413			.tRHW_min = 100000,414			.tRR_min = 20000,415			.tRST_max = 500000000,416			.tWB_max = 100000,417			.tWHR_min = 80000,418			.tWRCK_min = 20000,419			.tWW_min = 100000,420		},421	},422	/* Mode 3 */423	{424		.type = NAND_NVDDR_IFACE,425		.timings.mode = 3,426		.timings.nvddr = {427			.tCCS_min = 500000,428			.tR_max = 200000000,429			.tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,430			.tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,431			.tAC_min = 3000,432			.tAC_max = 25000,433			.tADL_min = 400000,434			.tCAD_min = 45000,435			.tCAH_min = 3000,436			.tCALH_min = 3000,437			.tCALS_min = 3000,438			.tCAS_min = 3000,439			.tCEH_min = 20000,440			.tCH_min = 3000,441			.tCK_min = 15000,442			.tCS_min = 15000,443			.tDH_min = 1300,444			.tDQSCK_min = 3000,445			.tDQSCK_max = 25000,446			.tDQSD_min = 0,447			.tDQSD_max = 18000,448			.tDQSHZ_max = 20000,449			.tDQSQ_max = 1300,450			.tDS_min = 1500,451			.tDSC_min = 15000,452			.tFEAT_max = 1000000,453			.tITC_max = 1000000,454			.tQHS_max = 1500,455			.tRHW_min = 100000,456			.tRR_min = 20000,457			.tRST_max = 500000000,458			.tWB_max = 100000,459			.tWHR_min = 80000,460			.tWRCK_min = 20000,461			.tWW_min = 100000,462		},463	},464	/* Mode 4 */465	{466		.type = NAND_NVDDR_IFACE,467		.timings.mode = 4,468		.timings.nvddr = {469			.tCCS_min = 500000,470			.tR_max = 200000000,471			.tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,472			.tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,473			.tAC_min = 3000,474			.tAC_max = 25000,475			.tADL_min = 400000,476			.tCAD_min = 45000,477			.tCAH_min = 2500,478			.tCALH_min = 2500,479			.tCALS_min = 2500,480			.tCAS_min = 2500,481			.tCEH_min = 20000,482			.tCH_min = 2500,483			.tCK_min = 12000,484			.tCS_min = 15000,485			.tDH_min = 1100,486			.tDQSCK_min = 3000,487			.tDQSCK_max = 25000,488			.tDQSD_min = 0,489			.tDQSD_max = 18000,490			.tDQSHZ_max = 20000,491			.tDQSQ_max = 1000,492			.tDS_min = 1100,493			.tDSC_min = 12000,494			.tFEAT_max = 1000000,495			.tITC_max = 1000000,496			.tQHS_max = 1200,497			.tRHW_min = 100000,498			.tRR_min = 20000,499			.tRST_max = 500000000,500			.tWB_max = 100000,501			.tWHR_min = 80000,502			.tWRCK_min = 20000,503			.tWW_min = 100000,504		},505	},506	/* Mode 5 */507	{508		.type = NAND_NVDDR_IFACE,509		.timings.mode = 5,510		.timings.nvddr = {511			.tCCS_min = 500000,512			.tR_max = 200000000,513			.tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX,514			.tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX,515			.tAC_min = 3000,516			.tAC_max = 25000,517			.tADL_min = 400000,518			.tCAD_min = 45000,519			.tCAH_min = 2000,520			.tCALH_min = 2000,521			.tCALS_min = 2000,522			.tCAS_min = 2000,523			.tCEH_min = 20000,524			.tCH_min = 2000,525			.tCK_min = 10000,526			.tCS_min = 15000,527			.tDH_min = 900,528			.tDQSCK_min = 3000,529			.tDQSCK_max = 25000,530			.tDQSD_min = 0,531			.tDQSD_max = 18000,532			.tDQSHZ_max = 20000,533			.tDQSQ_max = 850,534			.tDS_min = 900,535			.tDSC_min = 10000,536			.tFEAT_max = 1000000,537			.tITC_max = 1000000,538			.tQHS_max = 1000,539			.tRHW_min = 100000,540			.tRR_min = 20000,541			.tRST_max = 500000000,542			.tWB_max = 100000,543			.tWHR_min = 80000,544			.tWRCK_min = 20000,545			.tWW_min = 100000,546		},547	},548};549 550/* All NAND chips share the same reset data interface: SDR mode 0 */551const struct nand_interface_config *nand_get_reset_interface_config(void)552{553	return &onfi_sdr_timings[0];554}555 556/**557 * onfi_find_closest_sdr_mode - Derive the closest ONFI SDR timing mode given a558 *                              set of timings559 * @spec_timings: the timings to challenge560 */561unsigned int562onfi_find_closest_sdr_mode(const struct nand_sdr_timings *spec_timings)563{564	const struct nand_sdr_timings *onfi_timings;565	int mode;566 567	for (mode = ARRAY_SIZE(onfi_sdr_timings) - 1; mode > 0; mode--) {568		onfi_timings = &onfi_sdr_timings[mode].timings.sdr;569 570		if (spec_timings->tCCS_min <= onfi_timings->tCCS_min &&571		    spec_timings->tADL_min <= onfi_timings->tADL_min &&572		    spec_timings->tALH_min <= onfi_timings->tALH_min &&573		    spec_timings->tALS_min <= onfi_timings->tALS_min &&574		    spec_timings->tAR_min <= onfi_timings->tAR_min &&575		    spec_timings->tCEH_min <= onfi_timings->tCEH_min &&576		    spec_timings->tCH_min <= onfi_timings->tCH_min &&577		    spec_timings->tCLH_min <= onfi_timings->tCLH_min &&578		    spec_timings->tCLR_min <= onfi_timings->tCLR_min &&579		    spec_timings->tCLS_min <= onfi_timings->tCLS_min &&580		    spec_timings->tCOH_min <= onfi_timings->tCOH_min &&581		    spec_timings->tCS_min <= onfi_timings->tCS_min &&582		    spec_timings->tDH_min <= onfi_timings->tDH_min &&583		    spec_timings->tDS_min <= onfi_timings->tDS_min &&584		    spec_timings->tIR_min <= onfi_timings->tIR_min &&585		    spec_timings->tRC_min <= onfi_timings->tRC_min &&586		    spec_timings->tREH_min <= onfi_timings->tREH_min &&587		    spec_timings->tRHOH_min <= onfi_timings->tRHOH_min &&588		    spec_timings->tRHW_min <= onfi_timings->tRHW_min &&589		    spec_timings->tRLOH_min <= onfi_timings->tRLOH_min &&590		    spec_timings->tRP_min <= onfi_timings->tRP_min &&591		    spec_timings->tRR_min <= onfi_timings->tRR_min &&592		    spec_timings->tWC_min <= onfi_timings->tWC_min &&593		    spec_timings->tWH_min <= onfi_timings->tWH_min &&594		    spec_timings->tWHR_min <= onfi_timings->tWHR_min &&595		    spec_timings->tWP_min <= onfi_timings->tWP_min &&596		    spec_timings->tWW_min <= onfi_timings->tWW_min)597			return mode;598	}599 600	return 0;601}602 603/**604 * onfi_find_closest_nvddr_mode - Derive the closest ONFI NVDDR timing mode605 *                                given a set of timings606 * @spec_timings: the timings to challenge607 */608unsigned int609onfi_find_closest_nvddr_mode(const struct nand_nvddr_timings *spec_timings)610{611	const struct nand_nvddr_timings *onfi_timings;612	int mode;613 614	for (mode = ARRAY_SIZE(onfi_nvddr_timings) - 1; mode > 0; mode--) {615		onfi_timings = &onfi_nvddr_timings[mode].timings.nvddr;616 617		if (spec_timings->tCCS_min <= onfi_timings->tCCS_min &&618		    spec_timings->tAC_min <= onfi_timings->tAC_min &&619		    spec_timings->tADL_min <= onfi_timings->tADL_min &&620		    spec_timings->tCAD_min <= onfi_timings->tCAD_min &&621		    spec_timings->tCAH_min <= onfi_timings->tCAH_min &&622		    spec_timings->tCALH_min <= onfi_timings->tCALH_min &&623		    spec_timings->tCALS_min <= onfi_timings->tCALS_min &&624		    spec_timings->tCAS_min <= onfi_timings->tCAS_min &&625		    spec_timings->tCEH_min <= onfi_timings->tCEH_min &&626		    spec_timings->tCH_min <= onfi_timings->tCH_min &&627		    spec_timings->tCK_min <= onfi_timings->tCK_min &&628		    spec_timings->tCS_min <= onfi_timings->tCS_min &&629		    spec_timings->tDH_min <= onfi_timings->tDH_min &&630		    spec_timings->tDQSCK_min <= onfi_timings->tDQSCK_min &&631		    spec_timings->tDQSD_min <= onfi_timings->tDQSD_min &&632		    spec_timings->tDS_min <= onfi_timings->tDS_min &&633		    spec_timings->tDSC_min <= onfi_timings->tDSC_min &&634		    spec_timings->tRHW_min <= onfi_timings->tRHW_min &&635		    spec_timings->tRR_min <= onfi_timings->tRR_min &&636		    spec_timings->tWHR_min <= onfi_timings->tWHR_min &&637		    spec_timings->tWRCK_min <= onfi_timings->tWRCK_min &&638		    spec_timings->tWW_min <= onfi_timings->tWW_min)639			return mode;640	}641 642	return 0;643}644 645/*646 * onfi_fill_sdr_interface_config - Initialize a SDR interface config from a647 *                                  given ONFI mode648 * @chip: The NAND chip649 * @iface: The interface configuration to fill650 * @timing_mode: The ONFI timing mode651 */652static void onfi_fill_sdr_interface_config(struct nand_chip *chip,653					   struct nand_interface_config *iface,654					   unsigned int timing_mode)655{656	struct onfi_params *onfi = chip->parameters.onfi;657 658	if (WARN_ON(timing_mode >= ARRAY_SIZE(onfi_sdr_timings)))659		return;660 661	*iface = onfi_sdr_timings[timing_mode];662 663	/*664	 * Initialize timings that cannot be deduced from timing mode:665	 * tPROG, tBERS, tR and tCCS.666	 * These information are part of the ONFI parameter page.667	 */668	if (onfi) {669		struct nand_sdr_timings *timings = &iface->timings.sdr;670 671		/* microseconds -> picoseconds */672		timings->tPROG_max = 1000000ULL * onfi->tPROG;673		timings->tBERS_max = 1000000ULL * onfi->tBERS;674		timings->tR_max = 1000000ULL * onfi->tR;675 676		/* nanoseconds -> picoseconds */677		timings->tCCS_min = 1000UL * onfi->tCCS;678	}679}680 681/**682 * onfi_fill_nvddr_interface_config - Initialize a NVDDR interface config from a683 *                                    given ONFI mode684 * @chip: The NAND chip685 * @iface: The interface configuration to fill686 * @timing_mode: The ONFI timing mode687 */688static void onfi_fill_nvddr_interface_config(struct nand_chip *chip,689					     struct nand_interface_config *iface,690					     unsigned int timing_mode)691{692	struct onfi_params *onfi = chip->parameters.onfi;693 694	if (WARN_ON(timing_mode >= ARRAY_SIZE(onfi_nvddr_timings)))695		return;696 697	*iface = onfi_nvddr_timings[timing_mode];698 699	/*700	 * Initialize timings that cannot be deduced from timing mode:701	 * tPROG, tBERS, tR, tCCS and tCAD.702	 * These information are part of the ONFI parameter page.703	 */704	if (onfi) {705		struct nand_nvddr_timings *timings = &iface->timings.nvddr;706 707		/* microseconds -> picoseconds */708		timings->tPROG_max = 1000000ULL * onfi->tPROG;709		timings->tBERS_max = 1000000ULL * onfi->tBERS;710		timings->tR_max = 1000000ULL * onfi->tR;711 712		/* nanoseconds -> picoseconds */713		timings->tCCS_min = 1000UL * onfi->tCCS;714 715		if (onfi->fast_tCAD)716			timings->tCAD_min = 25000;717	}718}719 720/**721 * onfi_fill_interface_config - Initialize an interface config from a given722 *                              ONFI mode723 * @chip: The NAND chip724 * @iface: The interface configuration to fill725 * @type: The interface type726 * @timing_mode: The ONFI timing mode727 */728void onfi_fill_interface_config(struct nand_chip *chip,729				struct nand_interface_config *iface,730				enum nand_interface_type type,731				unsigned int timing_mode)732{733	if (type == NAND_SDR_IFACE)734		return onfi_fill_sdr_interface_config(chip, iface, timing_mode);735	else736		return onfi_fill_nvddr_interface_config(chip, iface, timing_mode);737}738