mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-11-04 05:50:17 +00:00 
			
		
		
		
	commit 20c89a28548cdab11f88d2ec8936344af0686a1e upstream. WL phase correcion stage is failing while using bus_width of 16bit, not to be fix this stage is un-necessary when working with bus_width of 16 bit. Signed-off-by: Moti Buskila <motib@marvell.com> Reviewed-by: Kostya Porotchkin <kostap@marvell.com> Signed-off-by: Marek Behún <marek.behun@nic.cz> Tested-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
		
			
				
	
	
		
			875 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			875 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
// SPDX-License-Identifier: GPL-2.0
 | 
						|
/*
 | 
						|
 * Copyright (C) Marvell International Ltd. and its affiliates
 | 
						|
 */
 | 
						|
 | 
						|
#include "ddr_ml_wrapper.h"
 | 
						|
 | 
						|
#include "ddr3_training_ip_flow.h"
 | 
						|
#include "mv_ddr_topology.h"
 | 
						|
#include "mv_ddr_training_db.h"
 | 
						|
#include "ddr3_training_ip_db.h"
 | 
						|
 | 
						|
/* Device attributes structures */
 | 
						|
enum mv_ddr_dev_attribute ddr_dev_attributes[MV_ATTR_LAST];
 | 
						|
int ddr_dev_attr_init_done = 0;
 | 
						|
 | 
						|
static inline u32 pattern_table_get_killer_word16(u8 dqs, u8 index);
 | 
						|
static inline u32 pattern_table_get_sso_word(u8 sso, u8 index);
 | 
						|
static inline u32 pattern_table_get_vref_word(u8 index);
 | 
						|
static inline u32 pattern_table_get_vref_word16(u8 index);
 | 
						|
static inline u32 pattern_table_get_sso_full_xtalk_word(u8 bit, u8 index);
 | 
						|
static inline u32 pattern_table_get_sso_full_xtalk_word16(u8 bit, u8 index);
 | 
						|
static inline u32 pattern_table_get_sso_xtalk_free_word(u8 bit, u8 index);
 | 
						|
static inline u32 pattern_table_get_sso_xtalk_free_word16(u8 bit, u8 index);
 | 
						|
static inline u32 pattern_table_get_isi_word(u8 index);
 | 
						|
static inline u32 pattern_table_get_isi_word16(u8 index);
 | 
						|
 | 
						|
/* List of allowed frequency listed in order of enum mv_ddr_freq */
 | 
						|
static unsigned int freq_val[MV_DDR_FREQ_LAST] = {
 | 
						|
	0,			/*MV_DDR_FREQ_LOW_FREQ */
 | 
						|
	400,			/*MV_DDR_FREQ_400, */
 | 
						|
	533,			/*MV_DDR_FREQ_533, */
 | 
						|
	666,			/*MV_DDR_FREQ_667, */
 | 
						|
	800,			/*MV_DDR_FREQ_800, */
 | 
						|
	933,			/*MV_DDR_FREQ_933, */
 | 
						|
	1066,			/*MV_DDR_FREQ_1066, */
 | 
						|
	311,			/*MV_DDR_FREQ_311, */
 | 
						|
	333,			/*MV_DDR_FREQ_333, */
 | 
						|
	467,			/*MV_DDR_FREQ_467, */
 | 
						|
	850,			/*MV_DDR_FREQ_850, */
 | 
						|
	600,			/*MV_DDR_FREQ_600 */
 | 
						|
	300,			/*MV_DDR_FREQ_300 */
 | 
						|
	900,			/*MV_DDR_FREQ_900 */
 | 
						|
	360,			/*MV_DDR_FREQ_360 */
 | 
						|
	1000			/*MV_DDR_FREQ_1000 */
 | 
						|
};
 | 
						|
 | 
						|
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];
 | 
						|
}
 | 
						|
 | 
						|
/* cas latency values per frequency for each speed bin index */
 | 
						|
static struct mv_ddr_cl_val_per_freq cl_table[] = {
 | 
						|
	/*
 | 
						|
	 * 400M   667M     933M   311M     467M  600M    360
 | 
						|
	 * 100M    533M    800M    1066M   333M    850M      900
 | 
						|
	 * 1000 (the order is 100, 400, 533 etc.)
 | 
						|
	 */
 | 
						|
	/* DDR3-800D */
 | 
						|
	{ {6, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
 | 
						|
	/* DDR3-800E */
 | 
						|
	{ {6, 6, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 6, 0, 6, 0} },
 | 
						|
	/* DDR3-1066E */
 | 
						|
	{ {6, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 0, 5, 0, 5, 0} },
 | 
						|
	/* DDR3-1066F */
 | 
						|
	{ {6, 6, 7, 0, 0, 0, 0, 6, 6, 7, 0, 0, 6, 0, 6, 0} },
 | 
						|
	/* DDR3-1066G */
 | 
						|
	{ {6, 6, 8, 0, 0, 0, 0, 6, 6, 8, 0, 0, 6, 0, 6, 0} },
 | 
						|
	/* DDR3-1333F* */
 | 
						|
	{ {6, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 | 
						|
	/* DDR3-1333G */
 | 
						|
	{ {6, 5, 7, 8, 0, 0, 0, 5, 5, 7, 0, 8, 5, 0, 5, 0} },
 | 
						|
	/* DDR3-1333H */
 | 
						|
	{ {6, 6, 8, 9, 0, 0, 0, 6, 6, 8, 0, 9, 6, 0, 6, 0} },
 | 
						|
	/* DDR3-1333J* */
 | 
						|
	{ {6, 6, 8, 10, 0, 0, 0, 6, 6, 8, 0, 10, 6, 0, 6,  0}
 | 
						|
	 /* DDR3-1600G* */},
 | 
						|
	{ {6, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 | 
						|
	/* DDR3-1600H */
 | 
						|
	{ {6, 5, 6, 8, 9, 0, 0, 5, 5, 6, 0, 8, 5, 0, 5, 0} },
 | 
						|
	/* DDR3-1600J */
 | 
						|
	{ {6, 5, 7, 9, 10, 0, 0, 5, 5, 7, 0, 9, 5, 0, 5, 0} },
 | 
						|
	/* DDR3-1600K */
 | 
						|
	{ {6, 6, 8, 10, 11, 0, 0, 6, 6, 8, 0, 10, 6, 0, 6, 0 } },
 | 
						|
	/* DDR3-1866J* */
 | 
						|
	{ {6, 5, 6, 8, 9, 11, 0, 5, 5, 6, 11, 8, 5, 0, 5, 0} },
 | 
						|
	/* DDR3-1866K */
 | 
						|
	{ {6, 5, 7, 8, 10, 11, 0, 5, 5, 7, 11, 8, 5, 11, 5, 11} },
 | 
						|
	/* DDR3-1866L */
 | 
						|
	{ {6, 6, 7, 9, 11, 12, 0, 6, 6, 7, 12, 9, 6, 12, 6, 12} },
 | 
						|
	/* DDR3-1866M* */
 | 
						|
	{ {6, 6, 8, 10, 11, 13, 0, 6, 6, 8, 13, 10, 6, 13, 6, 13} },
 | 
						|
	/* DDR3-2133K* */
 | 
						|
	{ {6, 5, 6, 7, 9, 10, 11, 5, 5, 6, 10, 7, 5, 11, 5, 11} },
 | 
						|
	/* DDR3-2133L */
 | 
						|
	{ {6, 5, 6, 8, 9, 11, 12, 5, 5, 6, 11, 8, 5, 12, 5, 12} },
 | 
						|
	/* DDR3-2133M */
 | 
						|
	{ {6, 5, 7, 9, 10, 12, 13, 5, 5, 7, 12, 9, 5, 13, 5, 13} },
 | 
						|
	/* DDR3-2133N* */
 | 
						|
	{ {6, 6, 7, 9, 11, 13, 14, 6, 6, 7, 13, 9, 6, 14,  6, 14} },
 | 
						|
	/* DDR3-1333H-ext */
 | 
						|
	{ {6, 6, 7, 9, 0, 0, 0, 6, 6, 7, 0, 9, 6, 0, 6, 0} },
 | 
						|
	/* DDR3-1600K-ext */
 | 
						|
	{ {6, 6, 7, 9, 11, 0, 0, 6, 6, 7, 0, 9, 6, 0, 6, 0} },
 | 
						|
	/* DDR3-1866M-ext */
 | 
						|
	{ {6, 6, 7, 9, 11, 13, 0, 6, 6, 7, 13, 9, 6, 13, 6, 13} },
 | 
						|
};
 | 
						|
 | 
						|
u32 mv_ddr_cl_val_get(u32 index, u32 freq)
 | 
						|
{
 | 
						|
	return cl_table[index].cl_val[freq];
 | 
						|
}
 | 
						|
 | 
						|
/* cas write latency values per frequency for each speed bin index */
 | 
						|
static struct mv_ddr_cl_val_per_freq cwl_table[] = {
 | 
						|
	/*
 | 
						|
	 * 400M   667M     933M   311M     467M  600M    360
 | 
						|
	 * 100M    533M    800M    1066M   333M    850M      900
 | 
						|
	 * (the order is 100, 400, 533 etc.)
 | 
						|
	 */
 | 
						|
	/* DDR3-800D  */
 | 
						|
	{ {5, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
 | 
						|
	/* DDR3-800E  */
 | 
						|
	{ {5, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
 | 
						|
	/* DDR3-1066E  */
 | 
						|
	{ {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 | 
						|
	/* DDR3-1066F  */
 | 
						|
	{ {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 | 
						|
	/* DDR3-1066G  */
 | 
						|
	{ {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 | 
						|
	/* DDR3-1333F*  */
 | 
						|
	{ {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 | 
						|
	/* DDR3-1333G  */
 | 
						|
	{ {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 | 
						|
	/* DDR3-1333H  */
 | 
						|
	{ {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 | 
						|
	/* DDR3-1333J*  */
 | 
						|
	{ {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 | 
						|
	/* DDR3-1600G*  */
 | 
						|
	{ {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 | 
						|
	/* DDR3-1600H  */
 | 
						|
	{ {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 | 
						|
	/* DDR3-1600J  */
 | 
						|
	{ {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 | 
						|
	/* DDR3-1600K  */
 | 
						|
	{ {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 | 
						|
	/* DDR3-1866J*  */
 | 
						|
	{ {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 0, 5, 0} },
 | 
						|
	/* DDR3-1866K  */
 | 
						|
	{ {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 0, 5, 0} },
 | 
						|
	/* DDR3-1866L  */
 | 
						|
	{ {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
 | 
						|
	/* DDR3-1866M*   */
 | 
						|
	{ {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
 | 
						|
	/* DDR3-2133K*  */
 | 
						|
	{ {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
 | 
						|
	/* DDR3-2133L  */
 | 
						|
	{ {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
 | 
						|
	/* DDR3-2133M  */
 | 
						|
	{ {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
 | 
						|
	/* DDR3-2133N*  */
 | 
						|
	{ {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
 | 
						|
	/* DDR3-1333H-ext  */
 | 
						|
	{ {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 | 
						|
	/* DDR3-1600K-ext  */
 | 
						|
	{ {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 | 
						|
	/* DDR3-1866M-ext  */
 | 
						|
	{ {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
 | 
						|
};
 | 
						|
 | 
						|
u32 mv_ddr_cwl_val_get(u32 index, u32 freq)
 | 
						|
{
 | 
						|
	return cwl_table[index].cl_val[freq];
 | 
						|
}
 | 
						|
 | 
						|
u8 twr_mask_table[] = {
 | 
						|
	10,
 | 
						|
	10,
 | 
						|
	10,
 | 
						|
	10,
 | 
						|
	10,
 | 
						|
	1,			/* 5 */
 | 
						|
	2,			/* 6 */
 | 
						|
	3,			/* 7 */
 | 
						|
	4,			/* 8 */
 | 
						|
	10,
 | 
						|
	5,			/* 10 */
 | 
						|
	10,
 | 
						|
	6,			/* 12 */
 | 
						|
	10,
 | 
						|
	7,			/* 14 */
 | 
						|
	10,
 | 
						|
	0			/* 16 */
 | 
						|
};
 | 
						|
 | 
						|
u8 cl_mask_table[] = {
 | 
						|
	0,
 | 
						|
	0,
 | 
						|
	0,
 | 
						|
	0,
 | 
						|
	0,
 | 
						|
	0x2,
 | 
						|
	0x4,
 | 
						|
	0x6,
 | 
						|
	0x8,
 | 
						|
	0xa,
 | 
						|
	0xc,
 | 
						|
	0xe,
 | 
						|
	0x1,
 | 
						|
	0x3,
 | 
						|
	0x5,
 | 
						|
	0x5
 | 
						|
};
 | 
						|
 | 
						|
u8 cwl_mask_table[] = {
 | 
						|
	0,
 | 
						|
	0,
 | 
						|
	0,
 | 
						|
	0,
 | 
						|
	0,
 | 
						|
	0,
 | 
						|
	0x1,
 | 
						|
	0x2,
 | 
						|
	0x3,
 | 
						|
	0x4,
 | 
						|
	0x5,
 | 
						|
	0x6,
 | 
						|
	0x7,
 | 
						|
	0x8,
 | 
						|
	0x9,
 | 
						|
	0x9
 | 
						|
};
 | 
						|
 | 
						|
/* RFC values (in ns) */
 | 
						|
static unsigned int rfc_table[] = {
 | 
						|
	90,	/* 512M */
 | 
						|
	110,	/* 1G */
 | 
						|
	160,	/* 2G */
 | 
						|
	260,	/* 4G */
 | 
						|
	350,	/* 8G */
 | 
						|
	0,	/* TODO: placeholder for 16-Mbit dev width */
 | 
						|
	0,	/* TODO: placeholder for 32-Mbit dev width */
 | 
						|
	0,	/* TODO: placeholder for 12-Mbit dev width */
 | 
						|
	0	/* TODO: placeholder for 24-Mbit dev width */
 | 
						|
};
 | 
						|
 | 
						|
u32 mv_ddr_rfc_get(u32 mem)
 | 
						|
{
 | 
						|
	return rfc_table[mem];
 | 
						|
}
 | 
						|
 | 
						|
u32 speed_bin_table_t_rc[] = {
 | 
						|
	50000,
 | 
						|
	52500,
 | 
						|
	48750,
 | 
						|
	50625,
 | 
						|
	52500,
 | 
						|
	46500,
 | 
						|
	48000,
 | 
						|
	49500,
 | 
						|
	51000,
 | 
						|
	45000,
 | 
						|
	46250,
 | 
						|
	47500,
 | 
						|
	48750,
 | 
						|
	44700,
 | 
						|
	45770,
 | 
						|
	46840,
 | 
						|
	47910,
 | 
						|
	43285,
 | 
						|
	44220,
 | 
						|
	45155,
 | 
						|
	46090
 | 
						|
};
 | 
						|
 | 
						|
u32 speed_bin_table_t_rcd_t_rp[] = {
 | 
						|
	12500,
 | 
						|
	15000,
 | 
						|
	11250,
 | 
						|
	13125,
 | 
						|
	15000,
 | 
						|
	10500,
 | 
						|
	12000,
 | 
						|
	13500,
 | 
						|
	15000,
 | 
						|
	10000,
 | 
						|
	11250,
 | 
						|
	12500,
 | 
						|
	13750,
 | 
						|
	10700,
 | 
						|
	11770,
 | 
						|
	12840,
 | 
						|
	13910,
 | 
						|
	10285,
 | 
						|
	11220,
 | 
						|
	12155,
 | 
						|
	13090,
 | 
						|
};
 | 
						|
 | 
						|
enum {
 | 
						|
	PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR = 0,
 | 
						|
	PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM
 | 
						|
};
 | 
						|
 | 
						|
static u8 pattern_killer_pattern_table_map[KILLER_PATTERN_LENGTH * 2][2] = {
 | 
						|
	/*Aggressor / Victim */
 | 
						|
	{1, 0},
 | 
						|
	{0, 0},
 | 
						|
	{1, 0},
 | 
						|
	{1, 1},
 | 
						|
	{0, 1},
 | 
						|
	{0, 1},
 | 
						|
	{1, 0},
 | 
						|
	{0, 1},
 | 
						|
	{1, 0},
 | 
						|
	{0, 1},
 | 
						|
	{1, 0},
 | 
						|
	{1, 0},
 | 
						|
	{0, 1},
 | 
						|
	{1, 0},
 | 
						|
	{0, 1},
 | 
						|
	{0, 0},
 | 
						|
	{1, 1},
 | 
						|
	{0, 0},
 | 
						|
	{1, 1},
 | 
						|
	{0, 0},
 | 
						|
	{1, 1},
 | 
						|
	{0, 0},
 | 
						|
	{1, 1},
 | 
						|
	{1, 0},
 | 
						|
	{0, 0},
 | 
						|
	{1, 1},
 | 
						|
	{0, 0},
 | 
						|
	{1, 1},
 | 
						|
	{0, 0},
 | 
						|
	{0, 0},
 | 
						|
	{0, 0},
 | 
						|
	{0, 1},
 | 
						|
	{0, 1},
 | 
						|
	{1, 1},
 | 
						|
	{0, 0},
 | 
						|
	{0, 0},
 | 
						|
	{1, 1},
 | 
						|
	{1, 1},
 | 
						|
	{0, 0},
 | 
						|
	{1, 1},
 | 
						|
	{0, 0},
 | 
						|
	{1, 1},
 | 
						|
	{1, 1},
 | 
						|
	{0, 0},
 | 
						|
	{0, 0},
 | 
						|
	{1, 1},
 | 
						|
	{0, 0},
 | 
						|
	{1, 1},
 | 
						|
	{0, 1},
 | 
						|
	{0, 0},
 | 
						|
	{0, 1},
 | 
						|
	{0, 1},
 | 
						|
	{0, 0},
 | 
						|
	{1, 1},
 | 
						|
	{1, 1},
 | 
						|
	{1, 0},
 | 
						|
	{1, 0},
 | 
						|
	{1, 1},
 | 
						|
	{1, 1},
 | 
						|
	{1, 1},
 | 
						|
	{1, 1},
 | 
						|
	{1, 1},
 | 
						|
	{1, 1},
 | 
						|
	{1, 1}
 | 
						|
};
 | 
						|
 | 
						|
static u8 pattern_vref_pattern_table_map[] = {
 | 
						|
	/* 1 means 0xffffffff, 0 is 0x0 */
 | 
						|
	0xb8,
 | 
						|
	0x52,
 | 
						|
	0x55,
 | 
						|
	0x8a,
 | 
						|
	0x33,
 | 
						|
	0xa6,
 | 
						|
	0x6d,
 | 
						|
	0xfe
 | 
						|
};
 | 
						|
 | 
						|
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_2K, 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;
 | 
						|
}
 | 
						|
 | 
						|
/* Return speed Bin value for selected index and t* element */
 | 
						|
unsigned int mv_ddr_speed_bin_timing_get(enum mv_ddr_speed_bin index, enum mv_ddr_speed_bin_timing element)
 | 
						|
{
 | 
						|
	u32 result = 0;
 | 
						|
 | 
						|
	switch (element) {
 | 
						|
	case SPEED_BIN_TRCD:
 | 
						|
	case SPEED_BIN_TRP:
 | 
						|
		result = speed_bin_table_t_rcd_t_rp[index];
 | 
						|
		break;
 | 
						|
	case SPEED_BIN_TRAS:
 | 
						|
		if (index <= SPEED_BIN_DDR_1066G)
 | 
						|
			result = 37500;
 | 
						|
		else if (index <= SPEED_BIN_DDR_1333J)
 | 
						|
			result = 36000;
 | 
						|
		else if (index <= SPEED_BIN_DDR_1600K)
 | 
						|
			result = 35000;
 | 
						|
		else if (index <= SPEED_BIN_DDR_1866M)
 | 
						|
			result = 34000;
 | 
						|
		else
 | 
						|
			result = 33000;
 | 
						|
		break;
 | 
						|
	case SPEED_BIN_TRC:
 | 
						|
		result = speed_bin_table_t_rc[index];
 | 
						|
		break;
 | 
						|
	case SPEED_BIN_TRRD1K:
 | 
						|
		if (index <= SPEED_BIN_DDR_800E)
 | 
						|
			result = 10000;
 | 
						|
		else if (index <= SPEED_BIN_DDR_1066G)
 | 
						|
			result = 7500;
 | 
						|
		else if (index <= SPEED_BIN_DDR_1600K)
 | 
						|
			result = 6000;
 | 
						|
		else
 | 
						|
			result = 5000;
 | 
						|
		break;
 | 
						|
	case SPEED_BIN_TRRD2K:
 | 
						|
		if (index <= SPEED_BIN_DDR_1066G)
 | 
						|
			result = 10000;
 | 
						|
		else if (index <= SPEED_BIN_DDR_1600K)
 | 
						|
			result = 7500;
 | 
						|
		else
 | 
						|
			result = 6000;
 | 
						|
		break;
 | 
						|
	case SPEED_BIN_TPD:
 | 
						|
		if (index < SPEED_BIN_DDR_800E)
 | 
						|
			result = 7500;
 | 
						|
		else if (index < SPEED_BIN_DDR_1333J)
 | 
						|
			result = 5625;
 | 
						|
		else
 | 
						|
			result = 5000;
 | 
						|
		break;
 | 
						|
	case SPEED_BIN_TFAW1K:
 | 
						|
		if (index <= SPEED_BIN_DDR_800E)
 | 
						|
			result = 40000;
 | 
						|
		else if (index <= SPEED_BIN_DDR_1066G)
 | 
						|
			result = 37500;
 | 
						|
		else if (index <= SPEED_BIN_DDR_1600K)
 | 
						|
			result = 30000;
 | 
						|
		else if (index <= SPEED_BIN_DDR_1866M)
 | 
						|
			result = 27000;
 | 
						|
		else
 | 
						|
			result = 25000;
 | 
						|
		break;
 | 
						|
	case SPEED_BIN_TFAW2K:
 | 
						|
		if (index <= SPEED_BIN_DDR_1066G)
 | 
						|
			result = 50000;
 | 
						|
		else if (index <= SPEED_BIN_DDR_1333J)
 | 
						|
			result = 45000;
 | 
						|
		else if (index <= SPEED_BIN_DDR_1600K)
 | 
						|
			result = 40000;
 | 
						|
		else
 | 
						|
			result = 35000;
 | 
						|
		break;
 | 
						|
	case SPEED_BIN_TWTR:
 | 
						|
		result = 7500;
 | 
						|
		break;
 | 
						|
	case SPEED_BIN_TRTP:
 | 
						|
		result = 7500;
 | 
						|
		break;
 | 
						|
	case SPEED_BIN_TWR:
 | 
						|
		result = 15000;
 | 
						|
		break;
 | 
						|
	case SPEED_BIN_TMOD:
 | 
						|
		result = 15000;
 | 
						|
		break;
 | 
						|
	case SPEED_BIN_TXPDLL:
 | 
						|
		result = 24000;
 | 
						|
		break;
 | 
						|
	case SPEED_BIN_TXSDLL:
 | 
						|
		result = 512;
 | 
						|
		break;
 | 
						|
	default:
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	return result;
 | 
						|
}
 | 
						|
 | 
						|
static inline u32 pattern_table_get_killer_word(u8 dqs, u8 index)
 | 
						|
{
 | 
						|
	u8 i, byte = 0;
 | 
						|
	u8 role;
 | 
						|
 | 
						|
	for (i = 0; i < 8; i++) {
 | 
						|
		role = (i == dqs) ?
 | 
						|
			(PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR) :
 | 
						|
			(PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM);
 | 
						|
		byte |= pattern_killer_pattern_table_map[index][role] << i;
 | 
						|
	}
 | 
						|
 | 
						|
	return byte | (byte << 8) | (byte << 16) | (byte << 24);
 | 
						|
}
 | 
						|
 | 
						|
static inline u32 pattern_table_get_killer_word16(u8 dqs, u8 index)
 | 
						|
{
 | 
						|
	u8 i, byte0 = 0, byte1 = 0;
 | 
						|
	u8 role;
 | 
						|
 | 
						|
	for (i = 0; i < 8; i++) {
 | 
						|
		role = (i == dqs) ?
 | 
						|
			(PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR) :
 | 
						|
			(PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM);
 | 
						|
		byte0 |= pattern_killer_pattern_table_map[index * 2][role] << i;
 | 
						|
		byte1 |= pattern_killer_pattern_table_map[index * 2 + 1][role] << i;
 | 
						|
	}
 | 
						|
 | 
						|
	return byte0 | (byte0 << 8) | (byte1 << 16) | (byte1 << 24);
 | 
						|
}
 | 
						|
 | 
						|
static inline u32 pattern_table_get_sso_word(u8 sso, u8 index)
 | 
						|
{
 | 
						|
	u8 step = sso + 1;
 | 
						|
 | 
						|
	if (0 == ((index / step) & 1))
 | 
						|
		return 0x0;
 | 
						|
	else
 | 
						|
		return 0xffffffff;
 | 
						|
}
 | 
						|
 | 
						|
static inline u32 pattern_table_get_sso_full_xtalk_word(u8 bit, u8 index)
 | 
						|
{
 | 
						|
	u8 byte = (1 << bit);
 | 
						|
 | 
						|
	if ((index & 1) == 1)
 | 
						|
		byte = ~byte;
 | 
						|
 | 
						|
	return byte | (byte << 8) | (byte << 16) | (byte << 24);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
static inline u32 pattern_table_get_sso_xtalk_free_word(u8 bit, u8 index)
 | 
						|
{
 | 
						|
	u8 byte = (1 << bit);
 | 
						|
 | 
						|
	if ((index & 1) == 1)
 | 
						|
		byte = 0;
 | 
						|
 | 
						|
	return byte | (byte << 8) | (byte << 16) | (byte << 24);
 | 
						|
}
 | 
						|
 | 
						|
static inline u32 pattern_table_get_isi_word(u8 index)
 | 
						|
{
 | 
						|
	u8 i0 = index % 32;
 | 
						|
	u8 i1 = index % 8;
 | 
						|
	u32 word;
 | 
						|
 | 
						|
	if (i0 > 15)
 | 
						|
		word = ((i1 == 5) | (i1 == 7)) ? 0xffffffff : 0x0;
 | 
						|
	else
 | 
						|
		word = (i1 == 6) ? 0xffffffff : 0x0;
 | 
						|
 | 
						|
	word = ((i0 % 16) > 7) ? ~word : word;
 | 
						|
 | 
						|
	return word;
 | 
						|
}
 | 
						|
 | 
						|
static inline u32 pattern_table_get_sso_full_xtalk_word16(u8 bit, u8 index)
 | 
						|
{
 | 
						|
	u8 byte = (1 << bit);
 | 
						|
 | 
						|
	if ((index & 1) == 1)
 | 
						|
		byte = ~byte;
 | 
						|
 | 
						|
	return byte | (byte << 8) | ((~byte) << 16) | ((~byte) << 24);
 | 
						|
}
 | 
						|
 | 
						|
static inline u32 pattern_table_get_sso_xtalk_free_word16(u8 bit, u8 index)
 | 
						|
{
 | 
						|
	u8 byte = (1 << bit);
 | 
						|
 | 
						|
	if ((index & 1) == 0)
 | 
						|
		return (byte << 16) | (byte << 24);
 | 
						|
	else
 | 
						|
		return byte | (byte << 8);
 | 
						|
}
 | 
						|
 | 
						|
static inline u32 pattern_table_get_isi_word16(u8 index)
 | 
						|
{
 | 
						|
	u8 i0 = index % 16;
 | 
						|
	u8 i1 = index % 4;
 | 
						|
	u32 word;
 | 
						|
 | 
						|
	if (i0 > 7)
 | 
						|
		word = (i1 > 1) ? 0x0000ffff : 0x0;
 | 
						|
	else
 | 
						|
		word = (i1 == 3) ? 0xffff0000 : 0x0;
 | 
						|
 | 
						|
	word = ((i0 % 8) > 3) ? ~word : word;
 | 
						|
 | 
						|
	return word;
 | 
						|
}
 | 
						|
 | 
						|
static inline u32 pattern_table_get_vref_word(u8 index)
 | 
						|
{
 | 
						|
	if (0 == ((pattern_vref_pattern_table_map[index / 8] >>
 | 
						|
		   (index % 8)) & 1))
 | 
						|
		return 0x0;
 | 
						|
	else
 | 
						|
		return 0xffffffff;
 | 
						|
}
 | 
						|
 | 
						|
static inline u32 pattern_table_get_vref_word16(u8 index)
 | 
						|
{
 | 
						|
	if (0 == pattern_killer_pattern_table_map
 | 
						|
	    [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] &&
 | 
						|
	    0 == pattern_killer_pattern_table_map
 | 
						|
	    [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1])
 | 
						|
		return 0x00000000;
 | 
						|
	else if (1 == pattern_killer_pattern_table_map
 | 
						|
		 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] &&
 | 
						|
		 0 == pattern_killer_pattern_table_map
 | 
						|
		 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1])
 | 
						|
		return 0xffff0000;
 | 
						|
	else if (0 == pattern_killer_pattern_table_map
 | 
						|
		 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] &&
 | 
						|
		 1 == pattern_killer_pattern_table_map
 | 
						|
		 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1])
 | 
						|
		return 0x0000ffff;
 | 
						|
	else
 | 
						|
		return 0xffffffff;
 | 
						|
}
 | 
						|
 | 
						|
static inline u32 pattern_table_get_static_pbs_word(u8 index)
 | 
						|
{
 | 
						|
	u16 temp;
 | 
						|
 | 
						|
	temp = ((0x00ff << (index / 3)) & 0xff00) >> 8;
 | 
						|
 | 
						|
	return temp | (temp << 8) | (temp << 16) | (temp << 24);
 | 
						|
}
 | 
						|
 | 
						|
u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
 | 
						|
{
 | 
						|
	u32 pattern = 0;
 | 
						|
	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 | 
						|
 | 
						|
	if (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask) == 0) {
 | 
						|
		/* 32/64-bit patterns */
 | 
						|
		switch (type) {
 | 
						|
		case PATTERN_PBS1:
 | 
						|
		case PATTERN_PBS2:
 | 
						|
			if (index == 0 || index == 2 || index == 5 ||
 | 
						|
			    index == 7)
 | 
						|
				pattern = PATTERN_55;
 | 
						|
			else
 | 
						|
				pattern = PATTERN_AA;
 | 
						|
			break;
 | 
						|
		case PATTERN_PBS3:
 | 
						|
			if (0 == (index & 1))
 | 
						|
				pattern = PATTERN_55;
 | 
						|
			else
 | 
						|
				pattern = PATTERN_AA;
 | 
						|
			break;
 | 
						|
		case PATTERN_RL:
 | 
						|
			if (index < 6)
 | 
						|
				pattern = PATTERN_00;
 | 
						|
			else
 | 
						|
				pattern = PATTERN_80;
 | 
						|
			break;
 | 
						|
		case PATTERN_STATIC_PBS:
 | 
						|
			pattern = pattern_table_get_static_pbs_word(index);
 | 
						|
			break;
 | 
						|
		case PATTERN_KILLER_DQ0:
 | 
						|
		case PATTERN_KILLER_DQ1:
 | 
						|
		case PATTERN_KILLER_DQ2:
 | 
						|
		case PATTERN_KILLER_DQ3:
 | 
						|
		case PATTERN_KILLER_DQ4:
 | 
						|
		case PATTERN_KILLER_DQ5:
 | 
						|
		case PATTERN_KILLER_DQ6:
 | 
						|
		case PATTERN_KILLER_DQ7:
 | 
						|
			pattern = pattern_table_get_killer_word(
 | 
						|
				(u8)(type - PATTERN_KILLER_DQ0), index);
 | 
						|
			break;
 | 
						|
		case PATTERN_RL2:
 | 
						|
			if (index < 6)
 | 
						|
				pattern = PATTERN_00;
 | 
						|
			else
 | 
						|
				pattern = PATTERN_01;
 | 
						|
			break;
 | 
						|
		case PATTERN_TEST:
 | 
						|
			if (index > 1 && index < 6)
 | 
						|
				pattern = PATTERN_00;
 | 
						|
			else
 | 
						|
				pattern = PATTERN_FF;
 | 
						|
			break;
 | 
						|
		case PATTERN_FULL_SSO0:
 | 
						|
		case PATTERN_FULL_SSO1:
 | 
						|
		case PATTERN_FULL_SSO2:
 | 
						|
		case PATTERN_FULL_SSO3:
 | 
						|
			pattern = pattern_table_get_sso_word(
 | 
						|
				(u8)(type - PATTERN_FULL_SSO0), index);
 | 
						|
			break;
 | 
						|
		case PATTERN_VREF:
 | 
						|
			pattern = pattern_table_get_vref_word(index);
 | 
						|
			break;
 | 
						|
		case PATTERN_SSO_FULL_XTALK_DQ0:
 | 
						|
		case PATTERN_SSO_FULL_XTALK_DQ1:
 | 
						|
		case PATTERN_SSO_FULL_XTALK_DQ2:
 | 
						|
		case PATTERN_SSO_FULL_XTALK_DQ3:
 | 
						|
		case PATTERN_SSO_FULL_XTALK_DQ4:
 | 
						|
		case PATTERN_SSO_FULL_XTALK_DQ5:
 | 
						|
		case PATTERN_SSO_FULL_XTALK_DQ6:
 | 
						|
		case PATTERN_SSO_FULL_XTALK_DQ7:
 | 
						|
			pattern = pattern_table_get_sso_full_xtalk_word(
 | 
						|
				(u8)(type - PATTERN_SSO_FULL_XTALK_DQ0), index);
 | 
						|
			break;
 | 
						|
		case PATTERN_SSO_XTALK_FREE_DQ0:
 | 
						|
		case PATTERN_SSO_XTALK_FREE_DQ1:
 | 
						|
		case PATTERN_SSO_XTALK_FREE_DQ2:
 | 
						|
		case PATTERN_SSO_XTALK_FREE_DQ3:
 | 
						|
		case PATTERN_SSO_XTALK_FREE_DQ4:
 | 
						|
		case PATTERN_SSO_XTALK_FREE_DQ5:
 | 
						|
		case PATTERN_SSO_XTALK_FREE_DQ6:
 | 
						|
		case PATTERN_SSO_XTALK_FREE_DQ7:
 | 
						|
			pattern = pattern_table_get_sso_xtalk_free_word(
 | 
						|
				(u8)(type - PATTERN_SSO_XTALK_FREE_DQ0), index);
 | 
						|
			break;
 | 
						|
		case PATTERN_ISI_XTALK_FREE:
 | 
						|
			pattern = pattern_table_get_isi_word(index);
 | 
						|
			break;
 | 
						|
		default:
 | 
						|
			printf("error: %s: unsupported pattern type [%d] found\n",
 | 
						|
			       __func__, (int)type);
 | 
						|
			pattern = 0;
 | 
						|
			break;
 | 
						|
		}
 | 
						|
	} else {
 | 
						|
		/* 16bit patterns */
 | 
						|
		switch (type) {
 | 
						|
		case PATTERN_PBS1:
 | 
						|
		case PATTERN_PBS2:
 | 
						|
		case PATTERN_PBS3:
 | 
						|
			pattern = PATTERN_55AA;
 | 
						|
			break;
 | 
						|
		case PATTERN_RL:
 | 
						|
			if (index < 3)
 | 
						|
				pattern = PATTERN_00;
 | 
						|
			else
 | 
						|
				pattern = PATTERN_80;
 | 
						|
			break;
 | 
						|
		case PATTERN_STATIC_PBS:
 | 
						|
			pattern = PATTERN_00FF;
 | 
						|
			break;
 | 
						|
		case PATTERN_KILLER_DQ0:
 | 
						|
		case PATTERN_KILLER_DQ1:
 | 
						|
		case PATTERN_KILLER_DQ2:
 | 
						|
		case PATTERN_KILLER_DQ3:
 | 
						|
		case PATTERN_KILLER_DQ4:
 | 
						|
		case PATTERN_KILLER_DQ5:
 | 
						|
		case PATTERN_KILLER_DQ6:
 | 
						|
		case PATTERN_KILLER_DQ7:
 | 
						|
			pattern = pattern_table_get_killer_word16(
 | 
						|
				(u8)(type - PATTERN_KILLER_DQ0), index);
 | 
						|
			break;
 | 
						|
		case PATTERN_RL2:
 | 
						|
			if (index < 3)
 | 
						|
				pattern = PATTERN_00;
 | 
						|
			else
 | 
						|
				pattern = PATTERN_01;
 | 
						|
			break;
 | 
						|
		case PATTERN_TEST:
 | 
						|
			if ((index == 0) || (index == 3))
 | 
						|
				pattern = 0x00000000;
 | 
						|
			else
 | 
						|
				pattern = 0xFFFFFFFF;
 | 
						|
			break;
 | 
						|
		case PATTERN_FULL_SSO0:
 | 
						|
			pattern = 0x0000ffff;
 | 
						|
			break;
 | 
						|
		case PATTERN_FULL_SSO1:
 | 
						|
		case PATTERN_FULL_SSO2:
 | 
						|
		case PATTERN_FULL_SSO3:
 | 
						|
			pattern = pattern_table_get_sso_word(
 | 
						|
				(u8)(type - PATTERN_FULL_SSO1), index);
 | 
						|
			break;
 | 
						|
		case PATTERN_VREF:
 | 
						|
			pattern = pattern_table_get_vref_word16(index);
 | 
						|
			break;
 | 
						|
		case PATTERN_SSO_FULL_XTALK_DQ0:
 | 
						|
		case PATTERN_SSO_FULL_XTALK_DQ1:
 | 
						|
		case PATTERN_SSO_FULL_XTALK_DQ2:
 | 
						|
		case PATTERN_SSO_FULL_XTALK_DQ3:
 | 
						|
		case PATTERN_SSO_FULL_XTALK_DQ4:
 | 
						|
		case PATTERN_SSO_FULL_XTALK_DQ5:
 | 
						|
		case PATTERN_SSO_FULL_XTALK_DQ6:
 | 
						|
		case PATTERN_SSO_FULL_XTALK_DQ7:
 | 
						|
			pattern = pattern_table_get_sso_full_xtalk_word16(
 | 
						|
				(u8)(type - PATTERN_SSO_FULL_XTALK_DQ0), index);
 | 
						|
			break;
 | 
						|
		case PATTERN_SSO_XTALK_FREE_DQ0:
 | 
						|
		case PATTERN_SSO_XTALK_FREE_DQ1:
 | 
						|
		case PATTERN_SSO_XTALK_FREE_DQ2:
 | 
						|
		case PATTERN_SSO_XTALK_FREE_DQ3:
 | 
						|
		case PATTERN_SSO_XTALK_FREE_DQ4:
 | 
						|
		case PATTERN_SSO_XTALK_FREE_DQ5:
 | 
						|
		case PATTERN_SSO_XTALK_FREE_DQ6:
 | 
						|
		case PATTERN_SSO_XTALK_FREE_DQ7:
 | 
						|
			pattern = pattern_table_get_sso_xtalk_free_word16(
 | 
						|
				(u8)(type - PATTERN_SSO_XTALK_FREE_DQ0), index);
 | 
						|
			break;
 | 
						|
		case PATTERN_ISI_XTALK_FREE:
 | 
						|
			pattern = pattern_table_get_isi_word16(index);
 | 
						|
			break;
 | 
						|
		default:
 | 
						|
			if (((int)type == 29) || ((int)type == 30))
 | 
						|
				break;
 | 
						|
 | 
						|
			printf("error: %s: unsupported pattern type [%d] found\n",
 | 
						|
			       __func__, (int)type);
 | 
						|
			pattern = 0;
 | 
						|
			break;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return pattern;
 | 
						|
}
 | 
						|
 | 
						|
/* Device attribute functions */
 | 
						|
void ddr3_tip_dev_attr_init(u32 dev_num)
 | 
						|
{
 | 
						|
	u32 attr_id;
 | 
						|
 | 
						|
	for (attr_id = 0; attr_id < MV_ATTR_LAST; attr_id++)
 | 
						|
		ddr_dev_attributes[attr_id] = 0xFF;
 | 
						|
 | 
						|
	ddr_dev_attr_init_done = 1;
 | 
						|
}
 | 
						|
 | 
						|
u32 ddr3_tip_dev_attr_get(u32 dev_num, enum mv_ddr_dev_attribute attr_id)
 | 
						|
{
 | 
						|
	if (ddr_dev_attr_init_done == 0)
 | 
						|
		ddr3_tip_dev_attr_init(dev_num);
 | 
						|
 | 
						|
	return ddr_dev_attributes[attr_id];
 | 
						|
}
 | 
						|
 | 
						|
void ddr3_tip_dev_attr_set(u32 dev_num, enum mv_ddr_dev_attribute attr_id, u32 value)
 | 
						|
{
 | 
						|
	if (ddr_dev_attr_init_done == 0)
 | 
						|
		ddr3_tip_dev_attr_init(dev_num);
 | 
						|
 | 
						|
	ddr_dev_attributes[attr_id] = value;
 | 
						|
}
 |