123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299 |
- // SPDX-License-Identifier: GPL-2.0
- /*
- * Copyright (C) Marvell International Ltd. and its affiliates
- */
- #include <common.h>
- #include <i2c.h>
- #include <spl.h>
- #include <asm/io.h>
- #include <asm/arch/cpu.h>
- #include <asm/arch/soc.h>
- #include "ddr3_init.h"
- #if defined(MV88F78X60)
- #include "ddr3_axp_config.h"
- #elif defined(MV88F67XX)
- #include "ddr3_a370_config.h"
- #endif
- #if defined(MV88F672X)
- #include "ddr3_a375_config.h"
- #endif
- #ifdef DUNIT_SPD
- /* DIMM SPD offsets */
- #define SPD_DEV_TYPE_BYTE 2
- #define SPD_MODULE_TYPE_BYTE 3
- #define SPD_MODULE_MASK 0xf
- #define SPD_MODULE_TYPE_RDIMM 1
- #define SPD_MODULE_TYPE_UDIMM 2
- #define SPD_DEV_DENSITY_BYTE 4
- #define SPD_DEV_DENSITY_MASK 0xf
- #define SPD_ROW_NUM_BYTE 5
- #define SPD_ROW_NUM_MIN 12
- #define SPD_ROW_NUM_OFF 3
- #define SPD_ROW_NUM_MASK (7 << SPD_ROW_NUM_OFF)
- #define SPD_COL_NUM_BYTE 5
- #define SPD_COL_NUM_MIN 9
- #define SPD_COL_NUM_OFF 0
- #define SPD_COL_NUM_MASK (7 << SPD_COL_NUM_OFF)
- #define SPD_MODULE_ORG_BYTE 7
- #define SPD_MODULE_SDRAM_DEV_WIDTH_OFF 0
- #define SPD_MODULE_SDRAM_DEV_WIDTH_MASK (7 << SPD_MODULE_SDRAM_DEV_WIDTH_OFF)
- #define SPD_MODULE_BANK_NUM_MIN 1
- #define SPD_MODULE_BANK_NUM_OFF 3
- #define SPD_MODULE_BANK_NUM_MASK (7 << SPD_MODULE_BANK_NUM_OFF)
- #define SPD_BUS_WIDTH_BYTE 8
- #define SPD_BUS_WIDTH_OFF 0
- #define SPD_BUS_WIDTH_MASK (7 << SPD_BUS_WIDTH_OFF)
- #define SPD_BUS_ECC_OFF 3
- #define SPD_BUS_ECC_MASK (3 << SPD_BUS_ECC_OFF)
- #define SPD_MTB_DIVIDEND_BYTE 10
- #define SPD_MTB_DIVISOR_BYTE 11
- #define SPD_TCK_BYTE 12
- #define SPD_SUP_CAS_LAT_LSB_BYTE 14
- #define SPD_SUP_CAS_LAT_MSB_BYTE 15
- #define SPD_TAA_BYTE 16
- #define SPD_TWR_BYTE 17
- #define SPD_TRCD_BYTE 18
- #define SPD_TRRD_BYTE 19
- #define SPD_TRP_BYTE 20
- #define SPD_TRAS_MSB_BYTE 21
- #define SPD_TRAS_MSB_MASK 0xf
- #define SPD_TRC_MSB_BYTE 21
- #define SPD_TRC_MSB_MASK 0xf0
- #define SPD_TRAS_LSB_BYTE 22
- #define SPD_TRC_LSB_BYTE 23
- #define SPD_TRFC_LSB_BYTE 24
- #define SPD_TRFC_MSB_BYTE 25
- #define SPD_TWTR_BYTE 26
- #define SPD_TRTP_BYTE 27
- #define SPD_TFAW_MSB_BYTE 28
- #define SPD_TFAW_MSB_MASK 0xf
- #define SPD_TFAW_LSB_BYTE 29
- #define SPD_OPT_FEATURES_BYTE 30
- #define SPD_THERMAL_REFRESH_OPT_BYTE 31
- #define SPD_ADDR_MAP_BYTE 63
- #define SPD_ADDR_MAP_MIRROR_OFFS 0
- #define SPD_RDIMM_RC_BYTE 69
- #define SPD_RDIMM_RC_NIBBLE_MASK 0xF
- #define SPD_RDIMM_RC_NUM 16
- /* Dimm Memory Type values */
- #define SPD_MEM_TYPE_SDRAM 0x4
- #define SPD_MEM_TYPE_DDR1 0x7
- #define SPD_MEM_TYPE_DDR2 0x8
- #define SPD_MEM_TYPE_DDR3 0xB
- #define DIMM_MODULE_MANU_OFFS 64
- #define DIMM_MODULE_MANU_SIZE 8
- #define DIMM_MODULE_VEN_OFFS 73
- #define DIMM_MODULE_VEN_SIZE 25
- #define DIMM_MODULE_ID_OFFS 99
- #define DIMM_MODULE_ID_SIZE 18
- /* enumeration for voltage levels. */
- enum dimm_volt_if {
- TTL_5V_TOLERANT,
- LVTTL,
- HSTL_1_5V,
- SSTL_3_3V,
- SSTL_2_5V,
- VOLTAGE_UNKNOWN,
- };
- /* enumaration for SDRAM CAS Latencies. */
- enum dimm_sdram_cas {
- SD_CL_1 = 1,
- SD_CL_2,
- SD_CL_3,
- SD_CL_4,
- SD_CL_5,
- SD_CL_6,
- SD_CL_7,
- SD_FAULT
- };
- /* enumeration for memory types */
- enum memory_type {
- MEM_TYPE_SDRAM,
- MEM_TYPE_DDR1,
- MEM_TYPE_DDR2,
- MEM_TYPE_DDR3
- };
- /* DIMM information structure */
- typedef struct dimm_info {
- /* DIMM dimensions */
- u32 num_of_module_ranks;
- u32 data_width;
- u32 rank_capacity;
- u32 num_of_devices;
- u32 sdram_width;
- u32 num_of_banks_on_each_device;
- u32 sdram_capacity;
- u32 num_of_row_addr;
- u32 num_of_col_addr;
- u32 addr_mirroring;
- u32 err_check_type; /* ECC , PARITY.. */
- u32 type_info; /* DDR2 only */
- /* DIMM timing parameters */
- u32 supported_cas_latencies;
- u32 refresh_interval;
- u32 min_cycle_time;
- u32 min_row_precharge_time;
- u32 min_row_active_to_row_active;
- u32 min_ras_to_cas_delay;
- u32 min_write_recovery_time; /* DDR3/2 only */
- u32 min_write_to_read_cmd_delay; /* DDR3/2 only */
- u32 min_read_to_prech_cmd_delay; /* DDR3/2 only */
- u32 min_active_to_precharge;
- u32 min_refresh_recovery; /* DDR3/2 only */
- u32 min_cas_lat_time;
- u32 min_four_active_win_delay;
- u8 dimm_rc[SPD_RDIMM_RC_NUM];
- /* DIMM vendor ID */
- u32 vendor;
- } MV_DIMM_INFO;
- static int ddr3_spd_sum_init(MV_DIMM_INFO *info, MV_DIMM_INFO *sum_info,
- u32 dimm);
- static u32 ddr3_get_max_val(u32 spd_val, u32 dimm_num, u32 static_val);
- static u32 ddr3_get_min_val(u32 spd_val, u32 dimm_num, u32 static_val);
- static int ddr3_spd_init(MV_DIMM_INFO *info, u32 dimm_addr, u32 dimm_width);
- static u32 ddr3_div(u32 val, u32 divider, u32 sub);
- extern u8 spd_data[SPD_SIZE];
- extern u32 odt_config[ODT_OPT];
- extern u16 odt_static[ODT_OPT][MAX_CS];
- extern u16 odt_dynamic[ODT_OPT][MAX_CS];
- #if !(defined(DB_88F6710) || defined(DB_88F6710_PCAC) || defined(RD_88F6710))
- /*
- * Name: ddr3_get_dimm_num - Find number of dimms and their addresses
- * Desc:
- * Args: dimm_addr - array of dimm addresses
- * Notes:
- * Returns: None.
- */
- static u32 ddr3_get_dimm_num(u32 *dimm_addr)
- {
- u32 dimm_cur_addr;
- u8 data[3];
- u32 dimm_num = 0;
- int ret;
- /* Read the dimm eeprom */
- for (dimm_cur_addr = MAX_DIMM_ADDR; dimm_cur_addr > MIN_DIMM_ADDR;
- dimm_cur_addr--) {
- data[SPD_DEV_TYPE_BYTE] = 0;
- /* Far-End DIMM must be connected */
- if ((dimm_num == 0) && (dimm_cur_addr < FAR_END_DIMM_ADDR))
- return 0;
- ret = i2c_read(dimm_cur_addr, 0, 1, (uchar *)data, 3);
- if (!ret) {
- if (data[SPD_DEV_TYPE_BYTE] == SPD_MEM_TYPE_DDR3) {
- dimm_addr[dimm_num] = dimm_cur_addr;
- dimm_num++;
- }
- }
- }
- return dimm_num;
- }
- #endif
- /*
- * Name: dimmSpdInit - Get the SPD parameters.
- * Desc: Read the DIMM SPD parameters into given struct parameter.
- * Args: dimmNum - DIMM number. See MV_BOARD_DIMM_NUM enumerator.
- * info - DIMM information structure.
- * Notes:
- * Returns: MV_OK if function could read DIMM parameters, 0 otherwise.
- */
- int ddr3_spd_init(MV_DIMM_INFO *info, u32 dimm_addr, u32 dimm_width)
- {
- u32 tmp;
- u32 time_base;
- int ret;
- __maybe_unused u32 rc;
- __maybe_unused u8 vendor_high, vendor_low;
- if (dimm_addr != 0) {
- memset(spd_data, 0, SPD_SIZE * sizeof(u8));
- ret = i2c_read(dimm_addr, 0, 1, (uchar *)spd_data, SPD_SIZE);
- if (ret)
- return MV_DDR3_TRAINING_ERR_TWSI_FAIL;
- }
- /* Check if DDR3 */
- if (spd_data[SPD_DEV_TYPE_BYTE] != SPD_MEM_TYPE_DDR3)
- return MV_DDR3_TRAINING_ERR_TWSI_BAD_TYPE;
- /* Error Check Type */
- /* No byte for error check in DDR3 SPD, use DDR2 convention */
- info->err_check_type = 0;
- /* Check if ECC */
- if ((spd_data[SPD_BUS_WIDTH_BYTE] & 0x18) >> 3)
- info->err_check_type = 1;
- DEBUG_INIT_FULL_C("DRAM err_check_type ", info->err_check_type, 1);
- switch (spd_data[SPD_MODULE_TYPE_BYTE]) {
- case 1:
- /* support RDIMM */
- info->type_info = SPD_MODULE_TYPE_RDIMM;
- break;
- case 2:
- /* support UDIMM */
- info->type_info = SPD_MODULE_TYPE_UDIMM;
- break;
- case 11: /* LRDIMM current not supported */
- default:
- info->type_info = (spd_data[SPD_MODULE_TYPE_BYTE]);
- break;
- }
- /* Size Calculations: */
- /* Number Of Row Addresses - 12/13/14/15/16 */
- info->num_of_row_addr =
- (spd_data[SPD_ROW_NUM_BYTE] & SPD_ROW_NUM_MASK) >>
- SPD_ROW_NUM_OFF;
- info->num_of_row_addr += SPD_ROW_NUM_MIN;
- DEBUG_INIT_FULL_C("DRAM num_of_row_addr ", info->num_of_row_addr, 2);
- /* Number Of Column Addresses - 9/10/11/12 */
- info->num_of_col_addr =
- (spd_data[SPD_COL_NUM_BYTE] & SPD_COL_NUM_MASK) >>
- SPD_COL_NUM_OFF;
- info->num_of_col_addr += SPD_COL_NUM_MIN;
- DEBUG_INIT_FULL_C("DRAM num_of_col_addr ", info->num_of_col_addr, 1);
- /* Number Of Ranks = number of CS on Dimm - 1/2/3/4 Ranks */
- info->num_of_module_ranks =
- (spd_data[SPD_MODULE_ORG_BYTE] & SPD_MODULE_BANK_NUM_MASK) >>
- SPD_MODULE_BANK_NUM_OFF;
- info->num_of_module_ranks += SPD_MODULE_BANK_NUM_MIN;
- DEBUG_INIT_FULL_C("DRAM numOfModuleBanks ", info->num_of_module_ranks,
- 1);
- /* Data Width - 8/16/32/64 bits */
- info->data_width =
- 1 << (3 + (spd_data[SPD_BUS_WIDTH_BYTE] & SPD_BUS_WIDTH_MASK));
- DEBUG_INIT_FULL_C("DRAM data_width ", info->data_width, 1);
- /* Number Of Banks On Each Device - 8/16/32/64 banks */
- info->num_of_banks_on_each_device =
- 1 << (3 + ((spd_data[SPD_DEV_DENSITY_BYTE] >> 4) & 0x7));
- DEBUG_INIT_FULL_C("DRAM num_of_banks_on_each_device ",
- info->num_of_banks_on_each_device, 1);
- /* Total SDRAM capacity - 256Mb/512Mb/1Gb/2Gb/4Gb/8Gb/16Gb - MegaBits */
- info->sdram_capacity =
- spd_data[SPD_DEV_DENSITY_BYTE] & SPD_DEV_DENSITY_MASK;
- /* Sdram Width - 4/8/16/32 bits */
- info->sdram_width = 1 << (2 + (spd_data[SPD_MODULE_ORG_BYTE] &
- SPD_MODULE_SDRAM_DEV_WIDTH_MASK));
- DEBUG_INIT_FULL_C("DRAM sdram_width ", info->sdram_width, 1);
- /* CS (Rank) Capacity - MB */
- /*
- * DDR3 device uiDensity val are: (device capacity/8) *
- * (Module_width/Device_width)
- */
- /* Jedec SPD DDR3 - page 7, Save spd_data in Mb - 2048=2GB */
- if (dimm_width == 32) {
- info->rank_capacity =
- ((1 << info->sdram_capacity) * 256 *
- (info->data_width / info->sdram_width)) << 16;
- /* CS size = CS size / 2 */
- } else {
- info->rank_capacity =
- ((1 << info->sdram_capacity) * 256 *
- (info->data_width / info->sdram_width) * 0x2) << 16;
- /* 0x2 => 0x100000-1Mbit / 8-bit->byte / 0x10000 */
- }
- DEBUG_INIT_FULL_C("DRAM rank_capacity[31] ", info->rank_capacity, 1);
- /* Number of devices includeing Error correction */
- info->num_of_devices =
- ((info->data_width / info->sdram_width) *
- info->num_of_module_ranks) + info->err_check_type;
- DEBUG_INIT_FULL_C("DRAM num_of_devices ", info->num_of_devices, 1);
- /* Address Mapping from Edge connector to DRAM - mirroring option */
- info->addr_mirroring =
- spd_data[SPD_ADDR_MAP_BYTE] & (1 << SPD_ADDR_MAP_MIRROR_OFFS);
- /* Timings - All in ps */
- time_base = (1000 * spd_data[SPD_MTB_DIVIDEND_BYTE]) /
- spd_data[SPD_MTB_DIVISOR_BYTE];
- /* Minimum Cycle Time At Max CasLatancy */
- info->min_cycle_time = spd_data[SPD_TCK_BYTE] * time_base;
- DEBUG_INIT_FULL_C("DRAM tCKmin ", info->min_cycle_time, 1);
- /* Refresh Interval */
- /* No byte for refresh interval in DDR3 SPD, use DDR2 convention */
- /*
- * JEDEC param are 0 <= Tcase <= 85: 7.8uSec, 85 <= Tcase
- * <= 95: 3.9uSec
- */
- info->refresh_interval = 7800000; /* Set to 7.8uSec */
- DEBUG_INIT_FULL_C("DRAM refresh_interval ", info->refresh_interval, 1);
- /* Suported Cas Latencies - DDR 3: */
- /*
- * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
- *******-******-******-******-******-******-******-*******-*******
- CAS = 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 *
- *********************************************************-*******
- *******-******-******-******-******-******-******-*******-*******
- * bit15 |bit14 |bit13 |bit12 |bit11 |bit10 | bit9 | bit8 *
- *******-******-******-******-******-******-******-*******-*******
- CAS = TBD | 18 | 17 | 16 | 15 | 14 | 13 | 12 *
- */
- /* DDR3 include 2 byte of CAS support */
- info->supported_cas_latencies =
- (spd_data[SPD_SUP_CAS_LAT_MSB_BYTE] << 8) |
- spd_data[SPD_SUP_CAS_LAT_LSB_BYTE];
- DEBUG_INIT_FULL_C("DRAM supported_cas_latencies ",
- info->supported_cas_latencies, 1);
- /* Minimum Cycle Time At Max CasLatancy */
- info->min_cas_lat_time = (spd_data[SPD_TAA_BYTE] * time_base);
- /*
- * This field divided by the cycleTime will give us the CAS latency
- * to config
- */
- /*
- * For DDR3 and DDR2 includes Write Recovery Time field.
- * Other SDRAM ignore
- */
- info->min_write_recovery_time = spd_data[SPD_TWR_BYTE] * time_base;
- DEBUG_INIT_FULL_C("DRAM min_write_recovery_time ",
- info->min_write_recovery_time, 1);
- /* Mininmum Ras to Cas Delay */
- info->min_ras_to_cas_delay = spd_data[SPD_TRCD_BYTE] * time_base;
- DEBUG_INIT_FULL_C("DRAM min_ras_to_cas_delay ",
- info->min_ras_to_cas_delay, 1);
- /* Minimum Row Active to Row Active Time */
- info->min_row_active_to_row_active =
- spd_data[SPD_TRRD_BYTE] * time_base;
- DEBUG_INIT_FULL_C("DRAM min_row_active_to_row_active ",
- info->min_row_active_to_row_active, 1);
- /* Minimum Row Precharge Delay Time */
- info->min_row_precharge_time = spd_data[SPD_TRP_BYTE] * time_base;
- DEBUG_INIT_FULL_C("DRAM min_row_precharge_time ",
- info->min_row_precharge_time, 1);
- /* Minimum Active to Precharge Delay Time - tRAS ps */
- info->min_active_to_precharge =
- (spd_data[SPD_TRAS_MSB_BYTE] & SPD_TRAS_MSB_MASK) << 8;
- info->min_active_to_precharge |= spd_data[SPD_TRAS_LSB_BYTE];
- info->min_active_to_precharge *= time_base;
- DEBUG_INIT_FULL_C("DRAM min_active_to_precharge ",
- info->min_active_to_precharge, 1);
- /* Minimum Refresh Recovery Delay Time - tRFC ps */
- info->min_refresh_recovery = spd_data[SPD_TRFC_MSB_BYTE] << 8;
- info->min_refresh_recovery |= spd_data[SPD_TRFC_LSB_BYTE];
- info->min_refresh_recovery *= time_base;
- DEBUG_INIT_FULL_C("DRAM min_refresh_recovery ",
- info->min_refresh_recovery, 1);
- /*
- * For DDR3 and DDR2 includes Internal Write To Read Command Delay
- * field.
- */
- info->min_write_to_read_cmd_delay = spd_data[SPD_TWTR_BYTE] * time_base;
- DEBUG_INIT_FULL_C("DRAM min_write_to_read_cmd_delay ",
- info->min_write_to_read_cmd_delay, 1);
- /*
- * For DDR3 and DDR2 includes Internal Read To Precharge Command Delay
- * field.
- */
- info->min_read_to_prech_cmd_delay = spd_data[SPD_TRTP_BYTE] * time_base;
- DEBUG_INIT_FULL_C("DRAM min_read_to_prech_cmd_delay ",
- info->min_read_to_prech_cmd_delay, 1);
- /*
- * For DDR3 includes Minimum Activate to Activate/Refresh Command
- * field
- */
- tmp = ((spd_data[SPD_TFAW_MSB_BYTE] & SPD_TFAW_MSB_MASK) << 8) |
- spd_data[SPD_TFAW_LSB_BYTE];
- info->min_four_active_win_delay = tmp * time_base;
- DEBUG_INIT_FULL_C("DRAM min_four_active_win_delay ",
- info->min_four_active_win_delay, 1);
- #if defined(MV88F78X60) || defined(MV88F672X)
- /* Registered DIMM support */
- if (info->type_info == SPD_MODULE_TYPE_RDIMM) {
- for (rc = 2; rc < 6; rc += 2) {
- tmp = spd_data[SPD_RDIMM_RC_BYTE + rc / 2];
- info->dimm_rc[rc] =
- spd_data[SPD_RDIMM_RC_BYTE + rc / 2] &
- SPD_RDIMM_RC_NIBBLE_MASK;
- info->dimm_rc[rc + 1] =
- (spd_data[SPD_RDIMM_RC_BYTE + rc / 2] >> 4) &
- SPD_RDIMM_RC_NIBBLE_MASK;
- }
- vendor_low = spd_data[66];
- vendor_high = spd_data[65];
- info->vendor = (vendor_high << 8) + vendor_low;
- DEBUG_INIT_C("DDR3 Training Sequence - Registered DIMM vendor ID 0x",
- info->vendor, 4);
- info->dimm_rc[0] = RDIMM_RC0;
- info->dimm_rc[1] = RDIMM_RC1;
- info->dimm_rc[2] = RDIMM_RC2;
- info->dimm_rc[8] = RDIMM_RC8;
- info->dimm_rc[9] = RDIMM_RC9;
- info->dimm_rc[10] = RDIMM_RC10;
- info->dimm_rc[11] = RDIMM_RC11;
- }
- #endif
- return MV_OK;
- }
- /*
- * Name: ddr3_spd_sum_init - Get the SPD parameters.
- * Desc: Read the DIMM SPD parameters into given struct parameter.
- * Args: dimmNum - DIMM number. See MV_BOARD_DIMM_NUM enumerator.
- * info - DIMM information structure.
- * Notes:
- * Returns: MV_OK if function could read DIMM parameters, 0 otherwise.
- */
- int ddr3_spd_sum_init(MV_DIMM_INFO *info, MV_DIMM_INFO *sum_info, u32 dimm)
- {
- if (dimm == 0) {
- memcpy(sum_info, info, sizeof(MV_DIMM_INFO));
- return MV_OK;
- }
- if (sum_info->type_info != info->type_info) {
- DEBUG_INIT_S("DDR3 Dimm Compare - DIMM type does not match - FAIL\n");
- return MV_DDR3_TRAINING_ERR_DIMM_TYPE_NO_MATCH;
- }
- if (sum_info->err_check_type > info->err_check_type) {
- sum_info->err_check_type = info->err_check_type;
- DEBUG_INIT_S("DDR3 Dimm Compare - ECC does not match. ECC is disabled\n");
- }
- if (sum_info->data_width != info->data_width) {
- DEBUG_INIT_S("DDR3 Dimm Compare - DRAM bus width does not match - FAIL\n");
- return MV_DDR3_TRAINING_ERR_BUS_WIDTH_NOT_MATCH;
- }
- if (sum_info->min_cycle_time < info->min_cycle_time)
- sum_info->min_cycle_time = info->min_cycle_time;
- if (sum_info->refresh_interval < info->refresh_interval)
- sum_info->refresh_interval = info->refresh_interval;
- sum_info->supported_cas_latencies &= info->supported_cas_latencies;
- if (sum_info->min_cas_lat_time < info->min_cas_lat_time)
- sum_info->min_cas_lat_time = info->min_cas_lat_time;
- if (sum_info->min_write_recovery_time < info->min_write_recovery_time)
- sum_info->min_write_recovery_time =
- info->min_write_recovery_time;
- if (sum_info->min_ras_to_cas_delay < info->min_ras_to_cas_delay)
- sum_info->min_ras_to_cas_delay = info->min_ras_to_cas_delay;
- if (sum_info->min_row_active_to_row_active <
- info->min_row_active_to_row_active)
- sum_info->min_row_active_to_row_active =
- info->min_row_active_to_row_active;
- if (sum_info->min_row_precharge_time < info->min_row_precharge_time)
- sum_info->min_row_precharge_time = info->min_row_precharge_time;
- if (sum_info->min_active_to_precharge < info->min_active_to_precharge)
- sum_info->min_active_to_precharge =
- info->min_active_to_precharge;
- if (sum_info->min_refresh_recovery < info->min_refresh_recovery)
- sum_info->min_refresh_recovery = info->min_refresh_recovery;
- if (sum_info->min_write_to_read_cmd_delay <
- info->min_write_to_read_cmd_delay)
- sum_info->min_write_to_read_cmd_delay =
- info->min_write_to_read_cmd_delay;
- if (sum_info->min_read_to_prech_cmd_delay <
- info->min_read_to_prech_cmd_delay)
- sum_info->min_read_to_prech_cmd_delay =
- info->min_read_to_prech_cmd_delay;
- if (sum_info->min_four_active_win_delay <
- info->min_four_active_win_delay)
- sum_info->min_four_active_win_delay =
- info->min_four_active_win_delay;
- if (sum_info->min_write_to_read_cmd_delay <
- info->min_write_to_read_cmd_delay)
- sum_info->min_write_to_read_cmd_delay =
- info->min_write_to_read_cmd_delay;
- return MV_OK;
- }
- /*
- * Name: ddr3_dunit_setup
- * Desc: Set the controller with the timing values.
- * Args: ecc_ena - User ECC setup
- * Notes:
- * Returns:
- */
- int ddr3_dunit_setup(u32 ecc_ena, u32 hclk_time, u32 *ddr_width)
- {
- u32 reg, tmp, cwl;
- u32 ddr_clk_time;
- MV_DIMM_INFO dimm_info[2];
- MV_DIMM_INFO sum_info;
- u32 stat_val, spd_val;
- u32 cs, cl, cs_num, cs_ena;
- u32 dimm_num = 0;
- int status;
- u32 rc;
- __maybe_unused u32 dimm_cnt, cs_count, dimm;
- __maybe_unused u32 dimm_addr[2] = { 0, 0 };
- #if defined(DB_88F6710) || defined(DB_88F6710_PCAC) || defined(RD_88F6710)
- /* Armada 370 - SPD is not available on DIMM */
- /*
- * Set MC registers according to Static SPD values Values -
- * must be set manually
- */
- /*
- * We only have one optional DIMM for the DB and we already got the
- * SPD matching values
- */
- status = ddr3_spd_init(&dimm_info[0], 0, *ddr_width);
- if (MV_OK != status)
- return status;
- dimm_num = 1;
- /* Use JP8 to enable multiCS support for Armada 370 DB */
- if (!ddr3_check_config(EEPROM_MODULE_ADDR, CONFIG_MULTI_CS))
- dimm_info[0].num_of_module_ranks = 1;
- status = ddr3_spd_sum_init(&dimm_info[0], &sum_info, 0);
- if (MV_OK != status)
- return status;
- #else
- /* Dynamic D-Unit Setup - Read SPD values */
- #ifdef DUNIT_SPD
- dimm_num = ddr3_get_dimm_num(dimm_addr);
- if (dimm_num == 0) {
- #ifdef MIXED_DIMM_STATIC
- DEBUG_INIT_S("DDR3 Training Sequence - No DIMMs detected\n");
- #else
- DEBUG_INIT_S("DDR3 Training Sequence - FAILED (Wrong DIMMs Setup)\n");
- return MV_DDR3_TRAINING_ERR_BAD_DIMM_SETUP;
- #endif
- } else {
- DEBUG_INIT_C("DDR3 Training Sequence - Number of DIMMs detected: ",
- dimm_num, 1);
- }
- for (dimm = 0; dimm < dimm_num; dimm++) {
- status = ddr3_spd_init(&dimm_info[dimm], dimm_addr[dimm],
- *ddr_width);
- if (MV_OK != status)
- return status;
- status = ddr3_spd_sum_init(&dimm_info[dimm], &sum_info, dimm);
- if (MV_OK != status)
- return status;
- }
- #endif
- #endif
- /* Set number of enabled CS */
- cs_num = 0;
- #ifdef DUNIT_STATIC
- cs_num = ddr3_get_cs_num_from_reg();
- #endif
- #ifdef DUNIT_SPD
- for (dimm = 0; dimm < dimm_num; dimm++)
- cs_num += dimm_info[dimm].num_of_module_ranks;
- #endif
- if (cs_num > MAX_CS) {
- DEBUG_INIT_C("DDR3 Training Sequence - Number of CS exceed limit - ",
- MAX_CS, 1);
- return MV_DDR3_TRAINING_ERR_MAX_CS_LIMIT;
- }
- /* Set bitmap of enabled CS */
- cs_ena = 0;
- #ifdef DUNIT_STATIC
- cs_ena = ddr3_get_cs_ena_from_reg();
- #endif
- #ifdef DUNIT_SPD
- dimm = 0;
- if (dimm_num) {
- for (cs = 0; cs < MAX_CS; cs += 2) {
- if (((1 << cs) & DIMM_CS_BITMAP) &&
- !(cs_ena & (1 << cs))) {
- if (dimm_info[dimm].num_of_module_ranks == 1)
- cs_ena |= (0x1 << cs);
- else if (dimm_info[dimm].num_of_module_ranks == 2)
- cs_ena |= (0x3 << cs);
- else if (dimm_info[dimm].num_of_module_ranks == 3)
- cs_ena |= (0x7 << cs);
- else if (dimm_info[dimm].num_of_module_ranks == 4)
- cs_ena |= (0xF << cs);
- dimm++;
- if (dimm == dimm_num)
- break;
- }
- }
- }
- #endif
- if (cs_ena > 0xF) {
- DEBUG_INIT_C("DDR3 Training Sequence - Number of enabled CS exceed limit - ",
- MAX_CS, 1);
- return MV_DDR3_TRAINING_ERR_MAX_ENA_CS_LIMIT;
- }
- DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - Number of CS = ", cs_num, 1);
- /* Check Ratio - '1' - 2:1, '0' - 1:1 */
- if (reg_read(REG_DDR_IO_ADDR) & (1 << REG_DDR_IO_CLK_RATIO_OFFS))
- ddr_clk_time = hclk_time / 2;
- else
- ddr_clk_time = hclk_time;
- #ifdef DUNIT_STATIC
- /* Get target CL value from set register */
- reg = (reg_read(REG_DDR3_MR0_ADDR) >> 2);
- reg = ((((reg >> 1) & 0xE)) | (reg & 0x1)) & 0xF;
- cl = ddr3_get_max_val(ddr3_div(sum_info.min_cas_lat_time,
- ddr_clk_time, 0),
- dimm_num, ddr3_valid_cl_to_cl(reg));
- #else
- cl = ddr3_div(sum_info.min_cas_lat_time, ddr_clk_time, 0);
- #endif
- if (cl < 5)
- cl = 5;
- DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - Cas Latency = ", cl, 1);
- /* {0x00001400} - DDR SDRAM Configuration Register */
- reg = 0x73004000;
- stat_val = ddr3_get_static_mc_value(
- REG_SDRAM_CONFIG_ADDR, REG_SDRAM_CONFIG_ECC_OFFS, 0x1, 0, 0);
- if (ecc_ena && ddr3_get_min_val(sum_info.err_check_type, dimm_num,
- stat_val)) {
- reg |= (1 << REG_SDRAM_CONFIG_ECC_OFFS);
- reg |= (1 << REG_SDRAM_CONFIG_IERR_OFFS);
- DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - ECC Enabled\n");
- } else {
- DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - ECC Disabled\n");
- }
- if (sum_info.type_info == SPD_MODULE_TYPE_RDIMM) {
- #ifdef DUNIT_STATIC
- DEBUG_INIT_S("DDR3 Training Sequence - FAIL - Illegal R-DIMM setup\n");
- return MV_DDR3_TRAINING_ERR_BAD_R_DIMM_SETUP;
- #endif
- reg |= (1 << REG_SDRAM_CONFIG_REGDIMM_OFFS);
- DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - R-DIMM\n");
- } else {
- DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - U-DIMM\n");
- }
- #ifndef MV88F67XX
- #ifdef DUNIT_STATIC
- if (ddr3_get_min_val(sum_info.data_width, dimm_num, BUS_WIDTH) == 64) {
- #else
- if (*ddr_width == 64) {
- #endif
- reg |= (1 << REG_SDRAM_CONFIG_WIDTH_OFFS);
- DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - Datawidth - 64Bits\n");
- } else {
- DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - Datawidth - 32Bits\n");
- }
- #else
- DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - Datawidth - 16Bits\n");
- #endif
- #if defined(MV88F672X)
- if (*ddr_width == 32) {
- reg |= (1 << REG_SDRAM_CONFIG_WIDTH_OFFS);
- DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - Datawidth - 32Bits\n");
- } else {
- DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - Datawidth - 16Bits\n");
- }
- #endif
- stat_val = ddr3_get_static_mc_value(REG_SDRAM_CONFIG_ADDR, 0,
- REG_SDRAM_CONFIG_RFRS_MASK, 0, 0);
- tmp = ddr3_get_min_val(sum_info.refresh_interval / hclk_time,
- dimm_num, stat_val);
- #ifdef TREFI_USER_EN
- tmp = min(TREFI_USER / hclk_time, tmp);
- #endif
- DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - RefreshInterval/Hclk = ", tmp, 4);
- reg |= tmp;
- if (cl != 3)
- reg |= (1 << 16); /* If 2:1 need to set P2DWr */
- #if defined(MV88F672X)
- reg |= (1 << 27); /* PhyRfRST = Disable */
- #endif
- reg_write(REG_SDRAM_CONFIG_ADDR, reg);
- /*{0x00001404} - DDR SDRAM Configuration Register */
- reg = 0x3630B800;
- #ifdef DUNIT_SPD
- reg |= (DRAM_2T << REG_DUNIT_CTRL_LOW_2T_OFFS);
- #endif
- reg_write(REG_DUNIT_CTRL_LOW_ADDR, reg);
- /* {0x00001408} - DDR SDRAM Timing (Low) Register */
- reg = 0x0;
- /* tRAS - (0:3,20) */
- spd_val = ddr3_div(sum_info.min_active_to_precharge,
- ddr_clk_time, 1);
- stat_val = ddr3_get_static_mc_value(REG_SDRAM_TIMING_LOW_ADDR,
- 0, 0xF, 16, 0x10);
- tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val);
- DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tRAS-1 = ", tmp, 1);
- reg |= (tmp & 0xF);
- reg |= ((tmp & 0x10) << 16); /* to bit 20 */
- /* tRCD - (4:7) */
- spd_val = ddr3_div(sum_info.min_ras_to_cas_delay, ddr_clk_time, 1);
- stat_val = ddr3_get_static_mc_value(REG_SDRAM_TIMING_LOW_ADDR,
- 4, 0xF, 0, 0);
- tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val);
- DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tRCD-1 = ", tmp, 1);
- reg |= ((tmp & 0xF) << 4);
- /* tRP - (8:11) */
- spd_val = ddr3_div(sum_info.min_row_precharge_time, ddr_clk_time, 1);
- stat_val = ddr3_get_static_mc_value(REG_SDRAM_TIMING_LOW_ADDR,
- 8, 0xF, 0, 0);
- tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val);
- DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tRP-1 = ", tmp, 1);
- reg |= ((tmp & 0xF) << 8);
- /* tWR - (12:15) */
- spd_val = ddr3_div(sum_info.min_write_recovery_time, ddr_clk_time, 1);
- stat_val = ddr3_get_static_mc_value(REG_SDRAM_TIMING_LOW_ADDR,
- 12, 0xF, 0, 0);
- tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val);
- DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tWR-1 = ", tmp, 1);
- reg |= ((tmp & 0xF) << 12);
- /* tWTR - (16:19) */
- spd_val = ddr3_div(sum_info.min_write_to_read_cmd_delay, ddr_clk_time, 1);
- stat_val = ddr3_get_static_mc_value(REG_SDRAM_TIMING_LOW_ADDR,
- 16, 0xF, 0, 0);
- tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val);
- DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tWTR-1 = ", tmp, 1);
- reg |= ((tmp & 0xF) << 16);
- /* tRRD - (24:27) */
- spd_val = ddr3_div(sum_info.min_row_active_to_row_active, ddr_clk_time, 1);
- stat_val = ddr3_get_static_mc_value(REG_SDRAM_TIMING_LOW_ADDR,
- 24, 0xF, 0, 0);
- tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val);
- DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tRRD-1 = ", tmp, 1);
- reg |= ((tmp & 0xF) << 24);
- /* tRTP - (28:31) */
- spd_val = ddr3_div(sum_info.min_read_to_prech_cmd_delay, ddr_clk_time, 1);
- stat_val = ddr3_get_static_mc_value(REG_SDRAM_TIMING_LOW_ADDR,
- 28, 0xF, 0, 0);
- tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val);
- DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tRTP-1 = ", tmp, 1);
- reg |= ((tmp & 0xF) << 28);
- if (cl < 7)
- reg = 0x33137663;
- reg_write(REG_SDRAM_TIMING_LOW_ADDR, reg);
- /*{0x0000140C} - DDR SDRAM Timing (High) Register */
- /* Add cycles to R2R W2W */
- reg = 0x39F8FF80;
- /* tRFC - (0:6,16:18) */
- spd_val = ddr3_div(sum_info.min_refresh_recovery, ddr_clk_time, 1);
- stat_val = ddr3_get_static_mc_value(REG_SDRAM_TIMING_HIGH_ADDR,
- 0, 0x7F, 9, 0x380);
- tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val);
- DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tRFC-1 = ", tmp, 1);
- reg |= (tmp & 0x7F);
- reg |= ((tmp & 0x380) << 9); /* to bit 16 */
- reg_write(REG_SDRAM_TIMING_HIGH_ADDR, reg);
- /*{0x00001410} - DDR SDRAM Address Control Register */
- reg = 0x000F0000;
- /* tFAW - (24:28) */
- #if (defined(MV88F78X60) || defined(MV88F672X))
- tmp = sum_info.min_four_active_win_delay;
- spd_val = ddr3_div(tmp, ddr_clk_time, 0);
- stat_val = ddr3_get_static_mc_value(REG_SDRAM_ADDRESS_CTRL_ADDR,
- 24, 0x3F, 0, 0);
- tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val);
- DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tFAW = ", tmp, 1);
- reg |= ((tmp & 0x3F) << 24);
- #else
- tmp = sum_info.min_four_active_win_delay -
- 4 * (sum_info.min_row_active_to_row_active);
- spd_val = ddr3_div(tmp, ddr_clk_time, 0);
- stat_val = ddr3_get_static_mc_value(REG_SDRAM_ADDRESS_CTRL_ADDR,
- 24, 0x1F, 0, 0);
- tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val);
- DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tFAW-4*tRRD = ", tmp, 1);
- reg |= ((tmp & 0x1F) << 24);
- #endif
- /* SDRAM device capacity */
- #ifdef DUNIT_STATIC
- reg |= (reg_read(REG_SDRAM_ADDRESS_CTRL_ADDR) & 0xF0FFFF);
- #endif
- #ifdef DUNIT_SPD
- cs_count = 0;
- dimm_cnt = 0;
- for (cs = 0; cs < MAX_CS; cs++) {
- if (cs_ena & (1 << cs) & DIMM_CS_BITMAP) {
- if (dimm_info[dimm_cnt].num_of_module_ranks == cs_count) {
- dimm_cnt++;
- cs_count = 0;
- }
- cs_count++;
- if (dimm_info[dimm_cnt].sdram_capacity < 0x3) {
- reg |= ((dimm_info[dimm_cnt].sdram_capacity + 1) <<
- (REG_SDRAM_ADDRESS_SIZE_OFFS +
- (REG_SDRAM_ADDRESS_CTRL_STRUCT_OFFS * cs)));
- } else if (dimm_info[dimm_cnt].sdram_capacity > 0x3) {
- reg |= ((dimm_info[dimm_cnt].sdram_capacity & 0x3) <<
- (REG_SDRAM_ADDRESS_SIZE_OFFS +
- (REG_SDRAM_ADDRESS_CTRL_STRUCT_OFFS * cs)));
- reg |= ((dimm_info[dimm_cnt].sdram_capacity & 0x4) <<
- (REG_SDRAM_ADDRESS_SIZE_HIGH_OFFS + cs));
- }
- }
- }
- /* SDRAM device structure */
- cs_count = 0;
- dimm_cnt = 0;
- for (cs = 0; cs < MAX_CS; cs++) {
- if (cs_ena & (1 << cs) & DIMM_CS_BITMAP) {
- if (dimm_info[dimm_cnt].num_of_module_ranks == cs_count) {
- dimm_cnt++;
- cs_count = 0;
- }
- cs_count++;
- if (dimm_info[dimm_cnt].sdram_width == 16)
- reg |= (1 << (REG_SDRAM_ADDRESS_CTRL_STRUCT_OFFS * cs));
- }
- }
- #endif
- reg_write(REG_SDRAM_ADDRESS_CTRL_ADDR, reg);
- /*{0x00001418} - DDR SDRAM Operation Register */
- reg = 0xF00;
- for (cs = 0; cs < MAX_CS; cs++) {
- if (cs_ena & (1 << cs))
- reg &= ~(1 << (cs + REG_SDRAM_OPERATION_CS_OFFS));
- }
- reg_write(REG_SDRAM_OPERATION_ADDR, reg);
- /*{0x00001420} - DDR SDRAM Extended Mode Register */
- reg = 0x00000004;
- reg_write(REG_SDRAM_EXT_MODE_ADDR, reg);
- /*{0x00001424} - DDR Controller Control (High) Register */
- #if (defined(MV88F78X60) || defined(MV88F672X))
- reg = 0x0000D3FF;
- #else
- reg = 0x0100D1FF;
- #endif
- reg_write(REG_DDR_CONT_HIGH_ADDR, reg);
- /*{0x0000142C} - DDR3 Timing Register */
- reg = 0x014C2F38;
- #if defined(MV88F78X60) || defined(MV88F672X)
- reg = 0x1FEC2F38;
- #endif
- reg_write(0x142C, reg);
- /*{0x00001484} - MBus CPU Block Register */
- #ifdef MV88F67XX
- if (reg_read(REG_DDR_IO_ADDR) & (1 << REG_DDR_IO_CLK_RATIO_OFFS))
- reg_write(REG_MBUS_CPU_BLOCK_ADDR, 0x0000E907);
- #endif
- /*
- * In case of mixed dimm and on-board devices setup paramters will
- * be taken statically
- */
- /*{0x00001494} - DDR SDRAM ODT Control (Low) Register */
- reg = odt_config[cs_ena];
- reg_write(REG_SDRAM_ODT_CTRL_LOW_ADDR, reg);
- /*{0x00001498} - DDR SDRAM ODT Control (High) Register */
- reg = 0x00000000;
- reg_write(REG_SDRAM_ODT_CTRL_HIGH_ADDR, reg);
- /*{0x0000149C} - DDR Dunit ODT Control Register */
- reg = cs_ena;
- reg_write(REG_DUNIT_ODT_CTRL_ADDR, reg);
- /*{0x000014A0} - DDR Dunit ODT Control Register */
- #if defined(MV88F672X)
- reg = 0x000006A9;
- reg_write(REG_DRAM_FIFO_CTRL_ADDR, reg);
- #endif
- /*{0x000014C0} - DRAM address and Control Driving Strenght */
- reg_write(REG_DRAM_ADDR_CTRL_DRIVE_STRENGTH_ADDR, 0x192435e9);
- /*{0x000014C4} - DRAM Data and DQS Driving Strenght */
- reg_write(REG_DRAM_DATA_DQS_DRIVE_STRENGTH_ADDR, 0xB2C35E9);
- #if (defined(MV88F78X60) || defined(MV88F672X))
- /*{0x000014CC} - DRAM Main Pads Calibration Machine Control Register */
- reg = reg_read(REG_DRAM_MAIN_PADS_CAL_ADDR);
- reg_write(REG_DRAM_MAIN_PADS_CAL_ADDR, reg | (1 << 0));
- #endif
- #if defined(MV88F672X)
- /* DRAM Main Pads Calibration Machine Control Register */
- /* 0x14CC[4:3] - CalUpdateControl = IntOnly */
- reg = reg_read(REG_DRAM_MAIN_PADS_CAL_ADDR);
- reg &= 0xFFFFFFE7;
- reg |= (1 << 3);
- reg_write(REG_DRAM_MAIN_PADS_CAL_ADDR, reg);
- #endif
- #ifdef DUNIT_SPD
- cs_count = 0;
- dimm_cnt = 0;
- for (cs = 0; cs < MAX_CS; cs++) {
- if ((1 << cs) & DIMM_CS_BITMAP) {
- if ((1 << cs) & cs_ena) {
- if (dimm_info[dimm_cnt].num_of_module_ranks ==
- cs_count) {
- dimm_cnt++;
- cs_count = 0;
- }
- cs_count++;
- reg_write(REG_CS_SIZE_SCRATCH_ADDR + (cs * 0x8),
- dimm_info[dimm_cnt].rank_capacity - 1);
- } else {
- reg_write(REG_CS_SIZE_SCRATCH_ADDR + (cs * 0x8), 0);
- }
- }
- }
- #endif
- /*{0x00020184} - Close FastPath - 2G */
- reg_write(REG_FASTPATH_WIN_0_CTRL_ADDR, 0);
- /*{0x00001538} - Read Data Sample Delays Register */
- reg = 0;
- for (cs = 0; cs < MAX_CS; cs++) {
- if (cs_ena & (1 << cs))
- reg |= (cl << (REG_READ_DATA_SAMPLE_DELAYS_OFFS * cs));
- }
- reg_write(REG_READ_DATA_SAMPLE_DELAYS_ADDR, reg);
- DEBUG_INIT_FULL_C("DDR3 - SPD-SET - Read Data Sample Delays = ", reg,
- 1);
- /*{0x0000153C} - Read Data Ready Delay Register */
- reg = 0;
- for (cs = 0; cs < MAX_CS; cs++) {
- if (cs_ena & (1 << cs)) {
- reg |= ((cl + 2) <<
- (REG_READ_DATA_READY_DELAYS_OFFS * cs));
- }
- }
- reg_write(REG_READ_DATA_READY_DELAYS_ADDR, reg);
- DEBUG_INIT_FULL_C("DDR3 - SPD-SET - Read Data Ready Delays = ", reg, 1);
- /* Set MR registers */
- /* MR0 */
- reg = 0x00000600;
- tmp = ddr3_cl_to_valid_cl(cl);
- reg |= ((tmp & 0x1) << 2);
- reg |= ((tmp & 0xE) << 3); /* to bit 4 */
- for (cs = 0; cs < MAX_CS; cs++) {
- if (cs_ena & (1 << cs)) {
- reg_write(REG_DDR3_MR0_CS_ADDR +
- (cs << MR_CS_ADDR_OFFS), reg);
- }
- }
- /* MR1 */
- reg = 0x00000044 & REG_DDR3_MR1_ODT_MASK;
- if (cs_num > 1)
- reg = 0x00000046 & REG_DDR3_MR1_ODT_MASK;
- for (cs = 0; cs < MAX_CS; cs++) {
- if (cs_ena & (1 << cs)) {
- reg |= odt_static[cs_ena][cs];
- reg_write(REG_DDR3_MR1_CS_ADDR +
- (cs << MR_CS_ADDR_OFFS), reg);
- }
- }
- /* MR2 */
- if (reg_read(REG_DDR_IO_ADDR) & (1 << REG_DDR_IO_CLK_RATIO_OFFS))
- tmp = hclk_time / 2;
- else
- tmp = hclk_time;
- if (tmp >= 2500)
- cwl = 5; /* CWL = 5 */
- else if (tmp >= 1875 && tmp < 2500)
- cwl = 6; /* CWL = 6 */
- else if (tmp >= 1500 && tmp < 1875)
- cwl = 7; /* CWL = 7 */
- else if (tmp >= 1250 && tmp < 1500)
- cwl = 8; /* CWL = 8 */
- else if (tmp >= 1070 && tmp < 1250)
- cwl = 9; /* CWL = 9 */
- else if (tmp >= 935 && tmp < 1070)
- cwl = 10; /* CWL = 10 */
- else if (tmp >= 833 && tmp < 935)
- cwl = 11; /* CWL = 11 */
- else if (tmp >= 750 && tmp < 833)
- cwl = 12; /* CWL = 12 */
- else {
- cwl = 12; /* CWL = 12 */
- printf("Unsupported hclk %d MHz\n", tmp);
- }
- reg = ((cwl - 5) << REG_DDR3_MR2_CWL_OFFS);
- for (cs = 0; cs < MAX_CS; cs++) {
- if (cs_ena & (1 << cs)) {
- reg &= REG_DDR3_MR2_ODT_MASK;
- reg |= odt_dynamic[cs_ena][cs];
- reg_write(REG_DDR3_MR2_CS_ADDR +
- (cs << MR_CS_ADDR_OFFS), reg);
- }
- }
- /* MR3 */
- reg = 0x00000000;
- for (cs = 0; cs < MAX_CS; cs++) {
- if (cs_ena & (1 << cs)) {
- reg_write(REG_DDR3_MR3_CS_ADDR +
- (cs << MR_CS_ADDR_OFFS), reg);
- }
- }
- /* {0x00001428} - DDR ODT Timing (Low) Register */
- reg = 0;
- reg |= (((cl - cwl + 1) & 0xF) << 4);
- reg |= (((cl - cwl + 6) & 0xF) << 8);
- reg |= ((((cl - cwl + 6) >> 4) & 0x1) << 21);
- reg |= (((cl - 1) & 0xF) << 12);
- reg |= (((cl + 6) & 0x1F) << 16);
- reg_write(REG_ODT_TIME_LOW_ADDR, reg);
- /* {0x0000147C} - DDR ODT Timing (High) Register */
- reg = 0x00000071;
- reg |= ((cwl - 1) << 8);
- reg |= ((cwl + 5) << 12);
- reg_write(REG_ODT_TIME_HIGH_ADDR, reg);
- #ifdef DUNIT_SPD
- /*{0x000015E0} - DDR3 Rank Control Register */
- reg = cs_ena;
- cs_count = 0;
- dimm_cnt = 0;
- for (cs = 0; cs < MAX_CS; cs++) {
- if (cs_ena & (1 << cs) & DIMM_CS_BITMAP) {
- if (dimm_info[dimm_cnt].num_of_module_ranks == cs_count) {
- dimm_cnt++;
- cs_count = 0;
- }
- cs_count++;
- if (dimm_info[dimm_cnt].addr_mirroring &&
- (cs == 1 || cs == 3) &&
- (sum_info.type_info != SPD_MODULE_TYPE_RDIMM)) {
- reg |= (1 << (REG_DDR3_RANK_CTRL_MIRROR_OFFS + cs));
- DEBUG_INIT_FULL_C("DDR3 - SPD-SET - Setting Address Mirroring for CS = ",
- cs, 1);
- }
- }
- }
- reg_write(REG_DDR3_RANK_CTRL_ADDR, reg);
- #endif
- /*{0xD00015E4} - ZQDS Configuration Register */
- reg = 0x00203c18;
- reg_write(REG_ZQC_CONF_ADDR, reg);
- /* {0x00015EC} - DDR PHY */
- #if defined(MV88F78X60)
- reg = 0xF800AAA5;
- if (mv_ctrl_rev_get() == MV_78XX0_B0_REV)
- reg = 0xF800A225;
- #else
- reg = 0xDE000025;
- #if defined(MV88F672X)
- reg = 0xF800A225;
- #endif
- #endif
- reg_write(REG_DRAM_PHY_CONFIG_ADDR, reg);
- #if (defined(MV88F78X60) || defined(MV88F672X))
- /* Registered DIMM support - supported only in AXP A0 devices */
- /* Currently supported for SPD detection only */
- /*
- * Flow is according to the Registered DIMM chapter in the
- * Functional Spec
- */
- if (sum_info.type_info == SPD_MODULE_TYPE_RDIMM) {
- DEBUG_INIT_S("DDR3 Training Sequence - Registered DIMM detected\n");
- /* Set commands parity completion */
- reg = reg_read(REG_REGISTERED_DRAM_CTRL_ADDR);
- reg &= ~REG_REGISTERED_DRAM_CTRL_PARITY_MASK;
- reg |= 0x8;
- reg_write(REG_REGISTERED_DRAM_CTRL_ADDR, reg);
- /* De-assert M_RESETn and assert M_CKE */
- reg_write(REG_SDRAM_INIT_CTRL_ADDR,
- 1 << REG_SDRAM_INIT_CKE_ASSERT_OFFS);
- do {
- reg = (reg_read(REG_SDRAM_INIT_CTRL_ADDR)) &
- (1 << REG_SDRAM_INIT_CKE_ASSERT_OFFS);
- } while (reg);
- for (rc = 0; rc < SPD_RDIMM_RC_NUM; rc++) {
- if (rc != 6 && rc != 7) {
- /* Set CWA Command */
- reg = (REG_SDRAM_OPERATION_CMD_CWA &
- ~(0xF << REG_SDRAM_OPERATION_CS_OFFS));
- reg |= ((dimm_info[0].dimm_rc[rc] &
- REG_SDRAM_OPERATION_CWA_DATA_MASK) <<
- REG_SDRAM_OPERATION_CWA_DATA_OFFS);
- reg |= rc << REG_SDRAM_OPERATION_CWA_RC_OFFS;
- /* Configure - Set Delay - tSTAB/tMRD */
- if (rc == 2 || rc == 10)
- reg |= (0x1 << REG_SDRAM_OPERATION_CWA_DELAY_SEL_OFFS);
- /* 0x1418 - SDRAM Operation Register */
- reg_write(REG_SDRAM_OPERATION_ADDR, reg);
- /*
- * Poll the "cmd" field in the SDRAM OP
- * register for 0x0
- */
- do {
- reg = reg_read(REG_SDRAM_OPERATION_ADDR) &
- (REG_SDRAM_OPERATION_CMD_MASK);
- } while (reg);
- }
- }
- }
- #endif
- return MV_OK;
- }
- /*
- * Name: ddr3_div - this function divides integers
- * Desc:
- * Args: val - the value
- * divider - the divider
- * sub - substruction value
- * Notes:
- * Returns: required value
- */
- u32 ddr3_div(u32 val, u32 divider, u32 sub)
- {
- return val / divider + (val % divider > 0 ? 1 : 0) - sub;
- }
- /*
- * Name: ddr3_get_max_val
- * Desc:
- * Args:
- * Notes:
- * Returns:
- */
- u32 ddr3_get_max_val(u32 spd_val, u32 dimm_num, u32 static_val)
- {
- #ifdef DUNIT_STATIC
- if (dimm_num > 0) {
- if (spd_val >= static_val)
- return spd_val;
- else
- return static_val;
- } else {
- return static_val;
- }
- #else
- return spd_val;
- #endif
- }
- /*
- * Name: ddr3_get_min_val
- * Desc:
- * Args:
- * Notes:
- * Returns:
- */
- u32 ddr3_get_min_val(u32 spd_val, u32 dimm_num, u32 static_val)
- {
- #ifdef DUNIT_STATIC
- if (dimm_num > 0) {
- if (spd_val <= static_val)
- return spd_val;
- else
- return static_val;
- } else
- return static_val;
- #else
- return spd_val;
- #endif
- }
- #endif
|