546 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			546 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
| // SPDX-License-Identifier: GPL-2.0
 | |
| /*
 | |
|  * Copyright (C) Marvell International Ltd. and its affiliates
 | |
|  */
 | |
| 
 | |
| #if defined(CONFIG_DDR4)
 | |
| 
 | |
| /* DDR4 Training Database */
 | |
| 
 | |
| #include "ddr_ml_wrapper.h"
 | |
| 
 | |
| #include "mv_ddr_topology.h"
 | |
| #include "mv_ddr_training_db.h"
 | |
| #include "ddr_topology_def.h"
 | |
| 
 | |
| /* list of allowed frequencies listed in order of enum mv_ddr_freq */
 | |
| static unsigned int freq_val[MV_DDR_FREQ_LAST] = {
 | |
| 	130,	/* MV_DDR_FREQ_LOW_FREQ */
 | |
| 	650,	/* MV_DDR_FREQ_650 */
 | |
| 	666,	/* MV_DDR_FREQ_667 */
 | |
| 	800,	/* MV_DDR_FREQ_800 */
 | |
| 	933,	/* MV_DDR_FREQ_933 */
 | |
| 	1066,	/* MV_DDR_FREQ_1066 */
 | |
| 	900,	/* MV_DDR_FREQ_900 */
 | |
| 	1000,	/* MV_DDR_FREQ_1000 */
 | |
| 	1050,	/* MV_DDR_FREQ_1050 */
 | |
| 	1200,	/* MV_DDR_FREQ_1200 */
 | |
| 	1333,	/* MV_DDR_FREQ_1333 */
 | |
| 	1466,	/* MV_DDR_FREQ_1466 */
 | |
| 	1600	/* MV_DDR_FREQ_1600 */
 | |
| };
 | |
| 
 | |
| unsigned int *mv_ddr_freq_tbl_get(void)
 | |
| {
 | |
| 	return &freq_val[0];
 | |
| }
 | |
| 
 | |
| u32 mv_ddr_freq_get(enum mv_ddr_freq freq)
 | |
| {
 | |
| 	return freq_val[freq];
 | |
| }
 | |
| 
 | |
| /* non-dbi mode - table for cl values per frequency for each speed bin index */
 | |
| static struct mv_ddr_cl_val_per_freq cl_table[] = {
 | |
| /*   130   650   667   800   933   1067   900   1000   1050   1200   1333   1466   1600 FREQ(MHz)*/
 | |
| /*   7.69  1.53  1.5   1.25  1.07  0.937  1.11	1	   0.95   0.83	 0.75	0.68   0.625 TCK(ns)*/
 | |
| 	{{10,  10,	 10,   0,	 0,    0,	  0,	0,	   0,	  0,	 0,	    0,	   0} },/* SPEED_BIN_DDR_1600J */
 | |
| 	{{10,  11,	 11,   0,	 0,    0,	  0,	0,	   0,	  0,	 0,	    0,     0} },/* SPEED_BIN_DDR_1600K */
 | |
| 	{{10,  12,	 12,   0,	 0,    0,	  0,	0,	   0,	  0,	 0,	    0,	   0} },/* SPEED_BIN_DDR_1600L */
 | |
| 	{{10,  12,	 12,   12,	 0,    0,	  0,	0,	   0,	  0,	 0,	    0,	   0} },/* SPEED_BIN_DDR_1866L */
 | |
| 	{{10,  12,	 12,   13,	 0,    0,	  0,	0,	   0,	  0,	 0,	    0,	   0} },/* SPEED_BIN_DDR_1866M */
 | |
| 	{{10,  12,	 12,   14,	 0,    0,	  0,	0,	   0,	  0,	 0,	    0,	   0} },/* SPEED_BIN_DDR_1866N */
 | |
| 	{{10,  10,	 10,   12,	 14,   14,	  14,	14,	   14,	  0,	 0,	    0,	   0} },/* SPEED_BIN_DDR_2133N */
 | |
| 	{{10,  9,	 9,    12,	 14,   15,	  14,	15,	   15,	  0,	 0,	    0,	   0} },/* SPEED_BIN_DDR_2133P */
 | |
| 	{{10,  10,	 10,   12,	 14,   16,	  14,	16,	   16,	  0,	 0,	    0,	   0} },/* SPEED_BIN_DDR_2133R */
 | |
| 	{{10,  10,	 10,   12,	 14,   16,	  14,	16,	   16,	  18,	 0,	    0,	   0} },/* SPEED_BIN_DDR_2400P */
 | |
| 	{{10,  9,	 9,    11,	 13,   15,	  13,	15,	   15,	  18,	 0,	    0,	   0} },/* SPEED_BIN_DDR_2400R */
 | |
| 	{{10,  9,	 9,    11,	 13,   15,	  13,	15,	   15,	  17,	 0,	    0,	   0} },/* SPEED_BIN_DDR_2400T */
 | |
| 	{{10,  10,	 10,   12,	 14,   16,	  14,	16,	   16,	  18,	 0,	    0,	   0} },/* SPEED_BIN_DDR_2400U */
 | |
| 	{{10,  10,   10,   11,   13,   15,    13,   15,    15,    16,    17,    0,     0} },/* SPEED_BIN_DDR_2666T */
 | |
| 	{{10,  9,    10,   11,   13,   15,    13,   15,    15,    17,    18,    0,     0} },/* SPEED_BIN_DDR_2666U */
 | |
| 	{{10,  9,    10,   12,   14,   16,    14,   16,    16,    18,    19,    0,     0} },/* SPEED_BIN_DDR_2666V */
 | |
| 	{{10,  10,   10,   12,   14,   16,    14,   16,    16,    18,    20,    0,     0} },/* SPEED_BIN_DDR_2666W */
 | |
| 	{{10,  10,   9,    11,   13,   15,    13,   15,    15,    16,    18,    19,    0} },/* SPEED_BIN_DDR_2933V */
 | |
| 	{{10,  9,    10,   11,   13,   15,    13,   15,    15,    17,    19,    20,    0} },/* SPEED_BIN_DDR_2933W */
 | |
| 	{{10,  9,    10,   12,   14,   16,    14,   16,    16,    18,    20,    21,    0} },/* SPEED_BIN_DDR_2933Y */
 | |
| 	{{10,  10,   10,   12,   14,   16,    14,   16,    16,    18,    20,    22,    0} },/* SPEED_BIN_DDR_2933AA*/
 | |
| 	{{10,  10,   9,    11,   13,   15,    13,   15,    15,    16,    18,    20,    20} },/* SPEED_BIN_DDR_3200W */
 | |
| 	{{10,  9,    0,    11,   13,   15,    13,   15,    15,    17,    19,    22,    22} },/* SPEED_BIN_DDR_3200AA*/
 | |
| 	{{10,  9,    10,   12,   14,   16,    14,   16,    16,    18,    20,    24,    24} } /* SPEED_BIN_DDR_3200AC*/
 | |
| 
 | |
| };
 | |
| 
 | |
| u32 mv_ddr_cl_val_get(u32 index, u32 freq)
 | |
| {
 | |
| 	return cl_table[index].cl_val[freq];
 | |
| }
 | |
| 
 | |
| /* dbi mode - table for cl values per frequency for each speed bin index */
 | |
| struct mv_ddr_cl_val_per_freq cas_latency_table_dbi[] = {
 | |
| /*	 130   650   667   800   933   1067   900   1000   1050   1200   1333   1466   1600 FREQ(MHz)*/
 | |
| /*	 7.69  1.53  1.5   1.25  1.07  0.937  1.11  1      0.95   0.83   0.75   0.68   0.625 TCK(ns)*/
 | |
| 	{{0,   12,	 12,   0,	 0,	   0,	  0,	0,	   0,	  0,	 0,	    0,     0} },/* SPEED_BIN_DDR_1600J */
 | |
| 	{{0,   13,	 13,   0,	 0,	   0,	  0,	0,	   0,	  0,	 0,	    0,     0} },/* SPEED_BIN_DDR_1600K */
 | |
| 	{{0,   14,	 14,   0,	 0,	   0,	  0,	0,	   0,	  0,	 0,	    0,     0} },/* SPEED_BIN_DDR_1600L */
 | |
| 	{{0,   14,	 14,   14,	 0,	   0,	  14,	0,	   0,	  0,	 0,	    0,     0} },/* SPEED_BIN_DDR_1866L */
 | |
| 	{{0,   14,	 14,   15,	 0,	   0,	  15,	0,	   0,	  0,	 0,	    0,     0} },/* SPEED_BIN_DDR_1866M */
 | |
| 	{{0,   14,	 14,   16,	 0,	   0,	  16,	0,	   0,	  0,	 0,	    0,     0} },/* SPEED_BIN_DDR_1866N */
 | |
| 	{{0,   12,	 12,   14,	 16,	  17,	  14,	17,	   0,	  0,	 0,	    0,     0} },/* SPEED_BIN_DDR_2133N */
 | |
| 	{{0,   11,	 11,   14,	 16,	  18,	  14,	18,	   0,	  0,	 0,	    0,     0} },/* SPEED_BIN_DDR_2133P */
 | |
| 	{{0,   12,	 12,   14,	 16,	  19,	  14,	19,	   0,	  0,	 0,	    0,     0} },/* SPEED_BIN_DDR_2133R */
 | |
| 	{{0,   12,	 12,   14,	 16,	  19,	  14,	19,	   0,	  0,	 0,	    0,     0} },/* SPEED_BIN_DDR_2400P */
 | |
| 	{{0,   11,	 11,   13,	 15,	  18,	  13,	18,	   0,	  0,	 0,	    0,     0} },/* SPEED_BIN_DDR_2400R */
 | |
| 	{{0,   11,	 11,   13,	 15,	  18,	  13,	18,	   0,	  0,	 0,	    0,     0} },/* SPEED_BIN_DDR_2400T */
 | |
| 	{{0,   12,	 12,   14,	 16,	  19,	  14,	19,	   0,	  0,	 0,	    0,     0} },/* SPEED_BIN_DDR_2400U */
 | |
| 	{{10,  10,   11,   13,   15,   18,    13,   18,    18,    19,    20,    0,     0} },/* SPEED_BIN_DDR_2666T */
 | |
| 	{{10,  9,    11,   13,   15,   18,    13,   18,    18,    20,    21,    0,     0} },/* SPEED_BIN_DDR_2666U */
 | |
| 	{{10,  9,    12,   14,   16,   19,    14,   19,    19,    21,    22,    0,     0} },/* SPEED_BIN_DDR_2666V */
 | |
| 	{{10,  10,   12,   14,   16,   19,    14,   19,    19,    21,    23,    0,     0} },/* SPEED_BIN_DDR_2666W */
 | |
| 	{{10,  10,   11,   13,   15,   18,    15,   18,    18,    19,    21,    23,    0} },/* SPEED_BIN_DDR_2933V */
 | |
| 	{{10,  9,    12,   13,   15,   18,    15,   18,    18,    20,    22,    24,    0} },/* SPEED_BIN_DDR_2933W */
 | |
| 	{{10,  9,    12,   14,   16,   19,    16,   19,    19,    21,    23,    26,    0} },/* SPEED_BIN_DDR_2933Y */
 | |
| 	{{10,  10,   12,   14,   16,   19,    16,   19,    19,    21,    23,    26,    0} },/* SPEED_BIN_DDR_2933AA*/
 | |
| 	{{10,  10,   11,   13,   15,   18,    15,   18,    18,    19,    21,    24,    24} },/* SPEED_BIN_DDR_3200W */
 | |
| 	{{10,  9,    0,    13,   15,   18,    15,   18,    18,    20,    22,    26,    26} },/* SPEED_BIN_DDR_3200AA*/
 | |
| 	{{10,  9,    12,   14,   16,   19,    16,   19,    19,    21,    23,    28,    28} } /* SPEED_BIN_DDR_3200AC*/
 | |
| };
 | |
| 
 | |
| /* table for cwl values per speed bin index */
 | |
| static struct mv_ddr_cl_val_per_freq cwl_table[] = {
 | |
| /*	 130   650   667   800   933   1067   900   1000   1050   1200   1333  1466   1600 FREQ(MHz)*/
 | |
| /*	7.69   1.53  1.5   1.25  1.07  0.937  1.11  1      0.95   0.83   0.75  0.68   0.625 TCK(ns)*/
 | |
| 	{{9,   9,	 9,	   0,	 0,    0,	  0,	0,	   0,	  0,	 0,	    0,     0} },/* SPEED_BIN_DDR_1600J */
 | |
| 	{{9,   9,	 9,	   0,	 0,    0,	  0,	0,	   0,	  0,	 0,	    0,     0} },/* SPEED_BIN_DDR_1600K */
 | |
| 	{{9,   9,	 9,	   0,	 0,    0,	  0,	0,	   0,	  0,	 0,	    0,     0} },/* SPEED_BIN_DDR_1600L */
 | |
| 	{{9,   9,	 9,	   10,	 0,    0,	  10,	0,	   0,	  0,	 0,	    0,     0} },/* SPEED_BIN_DDR_1866L */
 | |
| 	{{9,   9,	 9,	   10,	 0,    0,	  10,	0,	   0,	  0,	 0,	    0,     0} },/* SPEED_BIN_DDR_1866M */
 | |
| 	{{9,   9,	 9,	   10,	 0,    0,	  10,	0,	   0,	  0,	 0,	    0,     0} },/* SPEED_BIN_DDR_1866N */
 | |
| 	{{9,   9,	 9,	   9,	 10,   11,	  10,	11,	   10,	  11,	 0,	    0,     0} },/* SPEED_BIN_DDR_2133N */
 | |
| 	{{9,   9,	 9,	   9,	 10,   11,	  10,	11,	   10,	  11,	 0,	    0,     0} },/* SPEED_BIN_DDR_2133P */
 | |
| 	{{9,   9,	 9,	   10,	 10,   11,	  10,	11,	   10,	  11,	 0,	    0,     0} },/* SPEED_BIN_DDR_2133R */
 | |
| 	{{9,   9,	 9,	   9,	 10,   11,	  10,	11,	   10,	  12,	 0,	    0,     0} },/* SPEED_BIN_DDR_2400P */
 | |
| 	{{9,   9,	 9,	   9,	 10,   11,	  10,	11,	   10,	  12,	 0,	    0,     0} },/* SPEED_BIN_DDR_2400R */
 | |
| 	{{9,   9,	 9,	   9,	 10,   11,	  10,	11,	   10,	  12,	 0,	    0,     0} },/* SPEED_BIN_DDR_2400T */
 | |
| 	{{9,   9,	 9,	   9,	 10,   11,	  10,	11,	   10,	  12,	 0,	    0,     0} },/* SPEED_BIN_DDR_2400U */
 | |
| 	{{10,  10,   9,    9,    10,   11,    10,   11,    11,    12,    14,    0,     0} },/* SPEED_BIN_DDR_2666T */
 | |
| 	{{10,  9,    9,    9,    10,   11,    10,   11,    11,    12,    14,    0,     0} },/* SPEED_BIN_DDR_2666U */
 | |
| 	{{10,  9,    9,    9,    10,   11,    10,   11,    11,    12,    14,    0,     0} },/* SPEED_BIN_DDR_2666V */
 | |
| 	{{10,  10,   9,    9,    10,   11,    10,   11,    11,    12,    14,    0,     0} },/* SPEED_BIN_DDR_2666W */
 | |
| 	{{10,  10,   9,    9,    10,   11,    10,   11,    11,    12,    14,    16,    0} },/* SPEED_BIN_DDR_2933V */
 | |
| 	{{10,  9,    9,    9,    10,   11,    10,   11,    11,    12,    14,    16,    0} },/* SPEED_BIN_DDR_2933W */
 | |
| 	{{10,  9,    9,    9,    10,   11,    10,   11,    11,    12,    14,    16,    0} },/* SPEED_BIN_DDR_2933Y */
 | |
| 	{{10,  10,   9,    9,    10,   11,    10,   11,    11,    12,    14,    16,    0} },/* SPEED_BIN_DDR_2933AA*/
 | |
| 	{{10,  10,   9,    9,    10,   11,    10,   11,    11,    12,    14,    16,    16} },/* SPEED_BIN_DDR_3200W */
 | |
| 	{{10,  9,    9,    9,    10,   11,    10,   11,    11,    12,    14,    16,    16} },/* SPEED_BIN_DDR_3200AA*/
 | |
| 	{{10,  9,    9,    9,    10,   11,    10,   11,    11,    12,    14,    16,    16} } /* SPEED_BIN_DDR_3200AC*/
 | |
| };
 | |
| 
 | |
| u32 mv_ddr_cwl_val_get(u32 index, u32 freq)
 | |
| {
 | |
| 	return cwl_table[index].cl_val[freq];
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * rfc values, ns
 | |
|  * note: values per JEDEC speed bin 1866; TODO: check it
 | |
|  */
 | |
| static unsigned int rfc_table[] = {
 | |
| 	0,	/* placholder */
 | |
| 	0,	/* placholder */
 | |
| 	160,	/* 2G */
 | |
| 	260,	/* 4G */
 | |
| 	350,	/* 8G */
 | |
| 	0,	/* TODO: placeholder for 16-Mbit die capacity */
 | |
| 	0,	/* TODO: placeholder for 32-Mbit die capacity*/
 | |
| 	0,	/* TODO: placeholder for 12-Mbit die capacity */
 | |
| 	0	/* TODO: placeholder for 24-Mbit die capacity */
 | |
| };
 | |
| 
 | |
| u32 mv_ddr_rfc_get(u32 mem)
 | |
| {
 | |
| 	return rfc_table[mem];
 | |
| }
 | |
| 
 | |
| u16 rtt_table[] = {
 | |
| 	0xffff,
 | |
| 	60,
 | |
| 	120,
 | |
| 	40,
 | |
| 	240,
 | |
| 	48,
 | |
| 	80,
 | |
| 	34
 | |
| };
 | |
| 
 | |
| u8 twr_mask_table[] = {
 | |
| 	0xa,
 | |
| 	0xa,
 | |
| 	0xa,
 | |
| 	0xa,
 | |
| 	0xa,
 | |
| 	0xa,
 | |
| 	0xa,
 | |
| 	0xa,
 | |
| 	0xa,
 | |
| 	0xa,
 | |
| 	0x0,	/* 10 */
 | |
| 	0xa,
 | |
| 	0x1,	/* 12 */
 | |
| 	0xa,
 | |
| 	0x2,	/* 14 */
 | |
| 	0xa,
 | |
| 	0x3,	/* 16 */
 | |
| 	0xa,
 | |
| 	0x4,	/* 18 */
 | |
| 	0xa,
 | |
| 	0x5,	/* 20 */
 | |
| 	0xa,
 | |
| 	0xa,	/* 22 */
 | |
| 	0xa,
 | |
| 	0x6	/* 24 */
 | |
| };
 | |
| 
 | |
| u8 cl_mask_table[] = {
 | |
| 	0x0,
 | |
| 	0x0,
 | |
| 	0x0,
 | |
| 	0x0,
 | |
| 	0x0,
 | |
| 	0x0,
 | |
| 	0x0,
 | |
| 	0x0,
 | |
| 	0x0,
 | |
| 	0x0,
 | |
| 	0x1,	/* 10 */
 | |
| 	0x2,
 | |
| 	0x3,	/* 12 */
 | |
| 	0x4,
 | |
| 	0x5,	/* 14 */
 | |
| 	0x6,
 | |
| 	0x7,	/* 16 */
 | |
| 	0xd,
 | |
| 	0x8,	/* 18 */
 | |
| 	0x0,
 | |
| 	0x9,	/* 20 */
 | |
| 	0x0,
 | |
| 	0xa,	/* 22 */
 | |
| 	0x0,
 | |
| 	0xb	/* 24 */
 | |
| };
 | |
| 
 | |
| u8 cwl_mask_table[] = {
 | |
| 	0x0,
 | |
| 	0x0,
 | |
| 	0x0,
 | |
| 	0x0,
 | |
| 	0x0,
 | |
| 	0x0,
 | |
| 	0x0,
 | |
| 	0x0,
 | |
| 	0x0,
 | |
| 	0x0,
 | |
| 	0x1,	/* 10 */
 | |
| 	0x2,
 | |
| 	0x3,	/* 12 */
 | |
| 	0x0,
 | |
| 	0x4,	/* 14 */
 | |
| 	0x0,
 | |
| 	0x5,	/* 16 */
 | |
| 	0x0,
 | |
| 	0x6	/* 18 */
 | |
| };
 | |
| 
 | |
| u32 speed_bin_table_t_rcd_t_rp[] = {
 | |
| 	12500,
 | |
| 	13750,
 | |
| 	15000,
 | |
| 	12850,
 | |
| 	13920,
 | |
| 	15000,
 | |
| 	13130,
 | |
| 	14060,
 | |
| 	15000,
 | |
| 	12500,
 | |
| 	13320,
 | |
| 	14160,
 | |
| 	15000,
 | |
| 	12750,
 | |
| 	13500,
 | |
| 	14250,
 | |
| 	15000,
 | |
| 	12960,
 | |
| 	13640,
 | |
| 	14320,
 | |
| 	15000,
 | |
| 	12500,
 | |
| 	13750,
 | |
| 	15000
 | |
| };
 | |
| 
 | |
| u32 speed_bin_table_t_rc[] = {
 | |
| 	47500,
 | |
| 	48750,
 | |
| 	50000,
 | |
| 	46850,
 | |
| 	47920,
 | |
| 	49000,
 | |
| 	46130,
 | |
| 	47060,
 | |
| 	48000,
 | |
| 	44500,
 | |
| 	45320,
 | |
| 	46160,
 | |
| 	47000,
 | |
| 	44750,
 | |
| 	45500,
 | |
| 	46250,
 | |
| 	47000,
 | |
| 	44960,
 | |
| 	45640,
 | |
| 	46320,
 | |
| 	47000,
 | |
| 	44500,
 | |
| 	45750,
 | |
| 	47000
 | |
| };
 | |
| 
 | |
| static struct mv_ddr_page_element page_tbl[] = {
 | |
| 	/* 8-bit, 16-bit page size */
 | |
| 	{MV_DDR_PAGE_SIZE_1K, MV_DDR_PAGE_SIZE_2K}, /* 512M */
 | |
| 	{MV_DDR_PAGE_SIZE_1K, MV_DDR_PAGE_SIZE_2K}, /* 1G */
 | |
| 	{MV_DDR_PAGE_SIZE_1K, MV_DDR_PAGE_SIZE_2K}, /* 2G */
 | |
| 	{MV_DDR_PAGE_SIZE_1K, MV_DDR_PAGE_SIZE_2K}, /* 4G */
 | |
| 	{MV_DDR_PAGE_SIZE_1K, MV_DDR_PAGE_SIZE_2K}, /* 8G */
 | |
| 	{0, 0}, /* TODO: placeholder for 16-Mbit die capacity */
 | |
| 	{0, 0}, /* TODO: placeholder for 32-Mbit die capacity */
 | |
| 	{0, 0}, /* TODO: placeholder for 12-Mbit die capacity */
 | |
| 	{0, 0}  /* TODO: placeholder for 24-Mbit die capacity */
 | |
| };
 | |
| 
 | |
| u32 mv_ddr_page_size_get(enum mv_ddr_dev_width bus_width, enum mv_ddr_die_capacity mem_size)
 | |
| {
 | |
| 	if (bus_width == MV_DDR_DEV_WIDTH_8BIT)
 | |
| 		return page_tbl[mem_size].page_size_8bit;
 | |
| 	else
 | |
| 		return page_tbl[mem_size].page_size_16bit;
 | |
| }
 | |
| 
 | |
| /* DLL locking time, tDLLK */
 | |
| #define MV_DDR_TDLLK_DDR4_1600	597
 | |
| #define MV_DDR_TDLLK_DDR4_1866	597
 | |
| #define MV_DDR_TDLLK_DDR4_2133	768
 | |
| #define MV_DDR_TDLLK_DDR4_2400	768
 | |
| #define MV_DDR_TDLLK_DDR4_2666	854
 | |
| #define MV_DDR_TDLLK_DDR4_2933	940
 | |
| #define MV_DDR_TDLLK_DDR4_3200	1024
 | |
| static int mv_ddr_tdllk_get(unsigned int freq, unsigned int *tdllk)
 | |
| {
 | |
| 	if (freq >= 1600)
 | |
| 		*tdllk = MV_DDR_TDLLK_DDR4_3200;
 | |
| 	else if (freq >= 1466)
 | |
| 		*tdllk = MV_DDR_TDLLK_DDR4_2933;
 | |
| 	else if (freq >= 1333)
 | |
| 		*tdllk = MV_DDR_TDLLK_DDR4_2666;
 | |
| 	else if (freq >= 1200)
 | |
| 		*tdllk = MV_DDR_TDLLK_DDR4_2400;
 | |
| 	else if (freq >= 1066)
 | |
| 		*tdllk = MV_DDR_TDLLK_DDR4_2133;
 | |
| 	else if (freq >= 933)
 | |
| 		*tdllk = MV_DDR_TDLLK_DDR4_1866;
 | |
| 	else if (freq >= 800)
 | |
| 		*tdllk = MV_DDR_TDLLK_DDR4_1600;
 | |
| 	else {
 | |
| 		printf("error: %s: unsupported data rate found\n", __func__);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| /* return speed bin value for selected index and element */
 | |
| unsigned int mv_ddr_speed_bin_timing_get(enum mv_ddr_speed_bin index, enum mv_ddr_speed_bin_timing element)
 | |
| {
 | |
| 	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 | |
| 	unsigned int freq;
 | |
| 	u32 result = 0;
 | |
| 
 | |
| 	/* get frequency in MHz */
 | |
| 	freq = mv_ddr_freq_get(tm->interface_params[0].memory_freq);
 | |
| 
 | |
| 	switch (element) {
 | |
| 	case SPEED_BIN_TRCD:
 | |
| 	case SPEED_BIN_TRP:
 | |
| 		if (tm->cfg_src == MV_DDR_CFG_SPD)
 | |
| 			result = tm->timing_data[MV_DDR_TRCD_MIN];
 | |
| 		else
 | |
| 			result = speed_bin_table_t_rcd_t_rp[index];
 | |
| 		break;
 | |
| 	case SPEED_BIN_TRAS:
 | |
| 		if (tm->cfg_src == MV_DDR_CFG_SPD)
 | |
| 			result = tm->timing_data[MV_DDR_TRAS_MIN];
 | |
| 		else {
 | |
| 			if (index <= SPEED_BIN_DDR_1600L)
 | |
| 				result = 35000;
 | |
| 			else if (index <= SPEED_BIN_DDR_1866N)
 | |
| 				result = 34000;
 | |
| 			else if (index <= SPEED_BIN_DDR_2133R)
 | |
| 				result = 33000;
 | |
| 			else
 | |
| 				result = 32000;
 | |
| 		}
 | |
| 		break;
 | |
| 	case SPEED_BIN_TRC:
 | |
| 		if (tm->cfg_src == MV_DDR_CFG_SPD)
 | |
| 			result = tm->timing_data[MV_DDR_TRC_MIN];
 | |
| 		else
 | |
| 			result = speed_bin_table_t_rc[index];
 | |
| 		break;
 | |
| 	case SPEED_BIN_TRRD0_5K:
 | |
| 	case SPEED_BIN_TRRD1K:
 | |
| 		if (tm->cfg_src == MV_DDR_CFG_SPD)
 | |
| 			result = tm->timing_data[MV_DDR_TRRD_S_MIN];
 | |
| 		else {
 | |
| 			if (index <= SPEED_BIN_DDR_1600L)
 | |
| 				result = 5000;
 | |
| 			else if (index <= SPEED_BIN_DDR_1866N)
 | |
| 				result = 4200;
 | |
| 			else if (index <= SPEED_BIN_DDR_2133R)
 | |
| 				result = 3700;
 | |
| 			else if (index <= SPEED_BIN_DDR_2400U)
 | |
| 				result = 3500;
 | |
| 			else if (index <= SPEED_BIN_DDR_2666W)
 | |
| 				result = 3000;
 | |
| 			else if (index <= SPEED_BIN_DDR_2933AA)
 | |
| 				result = 2700;
 | |
| 			else
 | |
| 				result = 2500;
 | |
| 		}
 | |
| 	        break;
 | |
| 	case SPEED_BIN_TRRD2K:
 | |
| 		if (tm->cfg_src == MV_DDR_CFG_SPD)
 | |
| 			result = tm->timing_data[MV_DDR_TRRD_S_MIN];
 | |
| 		else {
 | |
| 			if (index <= SPEED_BIN_DDR_1600L)
 | |
| 				result = 6000;
 | |
| 			else
 | |
| 				result = 5300;
 | |
| 		}
 | |
| 
 | |
| 		break;
 | |
| 	case SPEED_BIN_TRRDL0_5K:
 | |
| 	case SPEED_BIN_TRRDL1K:
 | |
| 		if (tm->cfg_src == MV_DDR_CFG_SPD)
 | |
| 			result = tm->timing_data[MV_DDR_TRRD_L_MIN];
 | |
| 		else {
 | |
| 			if (index <= SPEED_BIN_DDR_1600L)
 | |
| 				result = 6000;
 | |
| 			else if (index <= SPEED_BIN_DDR_2133R)
 | |
| 				result = 5300;
 | |
| 			else
 | |
| 				result = 4900;
 | |
| 		}
 | |
| 		break;
 | |
| 	case SPEED_BIN_TRRDL2K:
 | |
| 		if (tm->cfg_src == MV_DDR_CFG_SPD)
 | |
| 			result = tm->timing_data[MV_DDR_TRRD_L_MIN];
 | |
| 		else {
 | |
| 			if (index <= SPEED_BIN_DDR_1600L)
 | |
| 				result = 7500;
 | |
| 			else
 | |
| 				result = 6400;
 | |
| 		}
 | |
| 	        break;
 | |
| 	case SPEED_BIN_TPD:
 | |
| 		result = 5000;
 | |
| 		break;
 | |
| 	case SPEED_BIN_TFAW0_5K:
 | |
| 		if (tm->cfg_src == MV_DDR_CFG_SPD)
 | |
| 			result = tm->timing_data[MV_DDR_TFAW_MIN];
 | |
| 		else {
 | |
| 			if (index <= SPEED_BIN_DDR_1600L)
 | |
| 				result = 20000;
 | |
| 			else if (index <= SPEED_BIN_DDR_1866N)
 | |
| 				result = 17000;
 | |
| 			else if (index <= SPEED_BIN_DDR_2133R)
 | |
| 				result = 15000;
 | |
| 			else if (index <= SPEED_BIN_DDR_2400U)
 | |
| 				result = 13000;
 | |
| 			else if (index <= SPEED_BIN_DDR_2666W)
 | |
| 				result = 12000;
 | |
| 			else if (index <= SPEED_BIN_DDR_2933AA)
 | |
| 				result = 10875;
 | |
| 			else
 | |
| 				result = 10000;
 | |
| 		}
 | |
| 	        break;
 | |
| 	case SPEED_BIN_TFAW1K:
 | |
| 		if (tm->cfg_src == MV_DDR_CFG_SPD)
 | |
| 			result = tm->timing_data[MV_DDR_TFAW_MIN];
 | |
| 		else {
 | |
| 			if (index <= SPEED_BIN_DDR_1600L)
 | |
| 				result = 25000;
 | |
| 			else if (index <= SPEED_BIN_DDR_1866N)
 | |
| 				result = 23000;
 | |
| 			else
 | |
| 				result = 21000;
 | |
| 		}
 | |
| 	        break;
 | |
| 	case SPEED_BIN_TFAW2K:
 | |
| 		if (tm->cfg_src == MV_DDR_CFG_SPD)
 | |
| 			result = tm->timing_data[MV_DDR_TFAW_MIN];
 | |
| 		else {
 | |
| 			if (index <= SPEED_BIN_DDR_1600L)
 | |
| 				result = 35000;
 | |
| 			else
 | |
| 				result = 30000;
 | |
| 		}
 | |
| 		break;
 | |
| 	case SPEED_BIN_TWTR:
 | |
| 		result = 2500;
 | |
| 		/* FIXME: wa: set twtr_s to a default value, if it's unset on spd */
 | |
| 		if (tm->cfg_src == MV_DDR_CFG_SPD && tm->timing_data[MV_DDR_TWTR_S_MIN])
 | |
| 			result = tm->timing_data[MV_DDR_TWTR_S_MIN];
 | |
| 		break;
 | |
| 	case SPEED_BIN_TWTRL:
 | |
| 	case SPEED_BIN_TRTP:
 | |
| 		result = 7500;
 | |
| 		/* FIXME: wa: set twtr_l to a default value, if it's unset on spd */
 | |
| 		if (tm->cfg_src == MV_DDR_CFG_SPD && tm->timing_data[MV_DDR_TWTR_L_MIN])
 | |
| 			result = tm->timing_data[MV_DDR_TWTR_L_MIN];
 | |
| 		break;
 | |
| 	case SPEED_BIN_TWR:
 | |
| 	case SPEED_BIN_TMOD:
 | |
| 		result = 15000;
 | |
| 		/* FIXME: wa: set twr to a default value, if it's unset on spd */
 | |
| 		if (tm->cfg_src == MV_DDR_CFG_SPD && tm->timing_data[MV_DDR_TWR_MIN])
 | |
| 			result = tm->timing_data[MV_DDR_TWR_MIN];
 | |
| 		break;
 | |
| 	case SPEED_BIN_TXPDLL:
 | |
| 		result = 24000;
 | |
| 		break;
 | |
| 	case SPEED_BIN_TXSDLL:
 | |
| 		if (mv_ddr_tdllk_get(freq, &result))
 | |
| 			result = 0;
 | |
| 		break;
 | |
| 	case SPEED_BIN_TCCDL:
 | |
| 		if (tm->cfg_src == MV_DDR_CFG_SPD)
 | |
| 			result = tm->timing_data[MV_DDR_TCCD_L_MIN];
 | |
| 		else {
 | |
| 			if (index <= SPEED_BIN_DDR_1600L)
 | |
| 				result = 6250;
 | |
| 			else if (index <= SPEED_BIN_DDR_2133R)
 | |
| 				result = 5355;
 | |
| 			else
 | |
| 				result = 5000;
 | |
| 		}
 | |
| 		break;
 | |
| 	default:
 | |
| 		printf("error: %s: invalid element [%d] found\n", __func__, (int)element);
 | |
| 		break;
 | |
| 	}
 | |
| 
 | |
| 	return result;
 | |
| }
 | |
| #endif /* CONFIG_DDR4 */
 |