123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655 |
- /*
- * Copyright (C) Marvell International Ltd. and its affiliates
- *
- * SPDX-License-Identifier: GPL-2.0
- */
- #include <common.h>
- #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*/
- 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) */
- 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;
- case SPEED_BIN_TXPDLL:
- result = 24000;
- 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;
- }
|