mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-22 12:54:37 +00:00

Import DDR training code from commit 1b69ce2fc0
("arm: mvebu:
ddr3_debug: remove self assignments") into
drivers/ddr/marvell/a38x/old/. The code is not used yet.
Explanation:
Since 2019, on some Turris Omnia boards we have been having problems
with newer versions of Marvell's DDR3 training code for Armada 38x,
which is ported from mv-ddr-marvell [1] to U-Boot into the
drivers/ddr/marvell/a38x/ directory:
- sometimes the DDR3 training fails on some older boards, sometime it
fails on some newer boards
- other times it succeeds, but some boards experience crashes of the
operating system after running for some time.
Using the stock version of Turris Omnia's U-Boot from solved these
issues, but this solution was not satisfactory, since we wanted
features from new U-Boot.
Back in 2020-2022 we have spent several months trying to debug the
issues, working with Marvell, on our own, and also with U-Boot
community, but these issues persist still.
One solution we used back in 2019 was a "hybrid U-Boot": the SPL part
(containing the DDR3 training code) was taken from the stock version,
while the proper part was current U-Boot at the time. This solution also
has its drawbacks, of which the main one is the need to glue binaries
from two separate builds.
Since then there have been some more changes to the DDR3 training code
in upstream mv-ddr-marvell that have been ported to U-Boot. We have
provided our users experimental builds of U-Boot in the TurrisOS so that
they could try upgrading the firmware and let us know if those problems
still exist. And they do.
We do not have the time nor manpower to debug this problem and fix it
properly. Marvell was also no able to provide a solution to this,
probably because they do not have the manpower as well.
I have therefore come up with this "not that pretty" solution: take the
DDR3 training code from an older version of U-Boot that is known to
work, put it into current U-Boot under old/ subdirectory within
drivers/ddr/marvell/a38x/, build into the SPL binary both the old and
new versions and make it possible to select the old version via an env
variable.
[1] https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell
Signed-off-by: Marek Behún <kabel@kernel.org>
651 lines
13 KiB
C
651 lines
13 KiB
C
/*
|
|
* Copyright (C) Marvell International Ltd. and its affiliates
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0
|
|
*/
|
|
|
|
#include <spl.h>
|
|
#include <asm/io.h>
|
|
#include <asm/arch/cpu.h>
|
|
#include <asm/arch/soc.h>
|
|
|
|
#include "ddr3_init.h"
|
|
|
|
/* List of allowed frequency listed in order of enum hws_ddr_freq */
|
|
u32 freq_val[DDR_FREQ_LIMIT] = {
|
|
0, /*DDR_FREQ_LOW_FREQ */
|
|
400, /*DDR_FREQ_400, */
|
|
533, /*DDR_FREQ_533, */
|
|
666, /*DDR_FREQ_667, */
|
|
800, /*DDR_FREQ_800, */
|
|
933, /*DDR_FREQ_933, */
|
|
1066, /*DDR_FREQ_1066, */
|
|
311, /*DDR_FREQ_311, */
|
|
333, /*DDR_FREQ_333, */
|
|
467, /*DDR_FREQ_467, */
|
|
850, /*DDR_FREQ_850, */
|
|
600, /*DDR_FREQ_600 */
|
|
300, /*DDR_FREQ_300 */
|
|
900, /*DDR_FREQ_900 */
|
|
360, /*DDR_FREQ_360 */
|
|
1000 /*DDR_FREQ_1000 */
|
|
};
|
|
|
|
/* Table for CL values per frequency for each speed bin index */
|
|
struct cl_val_per_freq cas_latency_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} },
|
|
};
|
|
|
|
/* Table for CWL values per speedbin index */
|
|
struct cl_val_per_freq cas_write_latency_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} },
|
|
};
|
|
|
|
u8 twr_mask_table[] = {
|
|
10,
|
|
10,
|
|
10,
|
|
10,
|
|
10,
|
|
1, /*5 */
|
|
2, /*6 */
|
|
3, /*7 */
|
|
10,
|
|
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) */
|
|
u16 rfc_table[] = {
|
|
90, /* 512M */
|
|
110, /* 1G */
|
|
160, /* 2G */
|
|
260, /* 4G */
|
|
350 /* 8G */
|
|
};
|
|
|
|
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,
|
|
46900
|
|
};
|
|
|
|
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,
|
|
11022,
|
|
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
|
|
};
|
|
|
|
/* Return speed Bin value for selected index and t* element */
|
|
u32 speed_bin_table(u8 index, enum speed_bin_table_elements 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 < 6)
|
|
result = 37500;
|
|
else if (index < 10)
|
|
result = 36000;
|
|
else if (index < 14)
|
|
result = 35000;
|
|
else if (index < 18)
|
|
result = 34000;
|
|
else
|
|
result = 33000;
|
|
break;
|
|
case SPEED_BIN_TRC:
|
|
result = speed_bin_table_t_rc[index];
|
|
break;
|
|
case SPEED_BIN_TRRD1K:
|
|
if (index < 3)
|
|
result = 10000;
|
|
else if (index < 6)
|
|
result = 7005;
|
|
else if (index < 14)
|
|
result = 6000;
|
|
else
|
|
result = 5000;
|
|
break;
|
|
case SPEED_BIN_TRRD2K:
|
|
if (index < 6)
|
|
result = 10000;
|
|
else if (index < 14)
|
|
result = 7005;
|
|
else
|
|
result = 6000;
|
|
break;
|
|
case SPEED_BIN_TPD:
|
|
if (index < 3)
|
|
result = 7500;
|
|
else if (index < 10)
|
|
result = 5625;
|
|
else
|
|
result = 5000;
|
|
break;
|
|
case SPEED_BIN_TFAW1K:
|
|
if (index < 3)
|
|
result = 40000;
|
|
else if (index < 6)
|
|
result = 37500;
|
|
else if (index < 14)
|
|
result = 30000;
|
|
else if (index < 18)
|
|
result = 27000;
|
|
else
|
|
result = 25000;
|
|
break;
|
|
case SPEED_BIN_TFAW2K:
|
|
if (index < 6)
|
|
result = 50000;
|
|
else if (index < 10)
|
|
result = 45000;
|
|
else if (index < 14)
|
|
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;
|
|
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;
|
|
}
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
role = (i == dqs) ?
|
|
(PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR) :
|
|
(PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM);
|
|
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_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);
|
|
}
|
|
|
|
inline u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
|
|
{
|
|
u32 pattern;
|
|
struct hws_topology_map *tm = ddr3_get_topology_map();
|
|
|
|
if (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask) == 0) {
|
|
/* 32bit 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_20;
|
|
else
|
|
pattern = PATTERN_00;
|
|
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;
|
|
default:
|
|
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:
|
|
pattern = PATTERN_0080;
|
|
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;
|
|
default:
|
|
pattern = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return pattern;
|
|
}
|