19b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney/************************************************************************ 29b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney * 39b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney * Copyright (c) 2013-2015 Intel Corporation. 49b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney * 59b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney* This program and the accompanying materials 69b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney* are licensed and made available under the terms and conditions of the BSD License 79b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney* which accompanies this distribution. The full text of the license may be found at 89b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney* http://opensource.org/licenses/bsd-license.php 99b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney* 109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney * 139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ***************************************************************************/ 149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#include "mrc.h" 169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#include "memory_options.h" 179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#include "meminit_utils.h" 199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#include "hte.h" 209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#include "io.h" 219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid select_hte( 239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney MRCParams_t *mrc_params); 249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneystatic uint8_t first_run = 0; 269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyconst uint8_t vref_codes[64] = 289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ // lowest to highest 299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, // 00 - 15 309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 0x2F, 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, // 16 - 31 319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, // 32 - 47 329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F // 48 - 63 339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney}; 349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#ifdef EMU 369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// Track current post code for debugging purpose 379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyuint32_t PostCode; 389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#endif 399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// set_rcvn: 419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This function will program the RCVEN delays. 439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// (currently doesn't comprehend rank) 449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid set_rcvn( 459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t channel, 469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t rank, 479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t byte_lane, 489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t pi_count) 499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t reg; 519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t msk; 529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t tempD; 539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ENTERFN(); 559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_TRN, "Rcvn ch%d rnk%d ln%d : pi=%03X\n", channel, rank, byte_lane, pi_count); 569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // RDPTR (1/2 MCLK, 64 PIs) 589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL0 -> B01PTRCTL0[11:08] (0x0-0xF) 599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL1 -> B01PTRCTL0[23:20] (0x0-0xF) 609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = B01PTRCTL0 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET); 619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk = (byte_lane & BIT0) ? (BIT23 | BIT22 | BIT21 | BIT20) : (BIT11 | BIT10 | BIT9 | BIT8); 629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = (byte_lane & BIT0) ? ((pi_count / HALF_CLK) << 20) : ((pi_count / HALF_CLK) << 8); 639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, reg, tempD, msk); 649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Adjust PI_COUNT 669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney pi_count -= ((pi_count / HALF_CLK) & 0xF) * HALF_CLK; 679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // PI (1/64 MCLK, 1 PIs) 699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL0 -> B0DLLPICODER0[29:24] (0x00-0x3F) 709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL1 -> B1DLLPICODER0[29:24] (0x00-0x3F) 719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = (byte_lane & BIT0) ? (B1DLLPICODER0) : (B0DLLPICODER0); 729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg += (((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET)); 739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk = (BIT29 | BIT28 | BIT27 | BIT26 | BIT25 | BIT24); 749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = pi_count << 24; 759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, reg, tempD, msk); 769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // DEADBAND 789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL0/1 -> B01DBCTL1[08/11] (+1 select) 799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL0/1 -> B01DBCTL1[02/05] (enable) 809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = B01DBCTL1 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET); 819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk = 0x00; 829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = 0x00; 839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // enable 849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk |= (byte_lane & BIT0) ? (BIT5) : (BIT2); 859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if ((pi_count < EARLY_DB) || (pi_count > LATE_DB)) 869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD |= msk; 889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // select 909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk |= (byte_lane & BIT0) ? (BIT11) : (BIT8); 919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (pi_count < EARLY_DB) 929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD |= msk; 949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, reg, tempD, msk); 969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // error check 989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (pi_count > 0x3F) 999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 1009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney training_message(channel, rank, byte_lane); 1019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney post_code(0xEE, 0xE0); 1029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 1039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney LEAVEFN(); 1059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 1069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 1079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// get_rcvn: 1099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 1109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This function will return the current RCVEN delay on the given channel, rank, byte_lane as an absolute PI count. 1119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// (currently doesn't comprehend rank) 1129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyuint32_t get_rcvn( 1139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t channel, 1149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t rank, 1159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t byte_lane) 1169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 1179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t reg; 1189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t tempD; 1199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t pi_count; 1209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ENTERFN(); 1229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // RDPTR (1/2 MCLK, 64 PIs) 1249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL0 -> B01PTRCTL0[11:08] (0x0-0xF) 1259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL1 -> B01PTRCTL0[23:20] (0x0-0xF) 1269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = B01PTRCTL0 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET); 1279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = isbR32m(DDRPHY, reg); 1289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD >>= (byte_lane & BIT0) ? (20) : (8); 1299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD &= 0xF; 1309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Adjust PI_COUNT 1329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney pi_count = tempD * HALF_CLK; 1339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // PI (1/64 MCLK, 1 PIs) 1359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL0 -> B0DLLPICODER0[29:24] (0x00-0x3F) 1369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL1 -> B1DLLPICODER0[29:24] (0x00-0x3F) 1379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = (byte_lane & BIT0) ? (B1DLLPICODER0) : (B0DLLPICODER0); 1389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg += (((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET)); 1399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = isbR32m(DDRPHY, reg); 1409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD >>= 24; 1419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD &= 0x3F; 1429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Adjust PI_COUNT 1449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney pi_count += tempD; 1459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney LEAVEFN(); 1479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return pi_count; 1489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 1499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// set_rdqs: 1519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 1529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This function will program the RDQS delays based on an absolute amount of PIs. 1539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// (currently doesn't comprehend rank) 1549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid set_rdqs( 1559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t channel, 1569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t rank, 1579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t byte_lane, 1589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t pi_count) 1599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 1609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t reg; 1619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t msk; 1629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t tempD; 1639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ENTERFN(); 1659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_TRN, "Rdqs ch%d rnk%d ln%d : pi=%03X\n", channel, rank, byte_lane, pi_count); 1669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // PI (1/128 MCLK) 1689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL0 -> B0RXDQSPICODE[06:00] (0x00-0x47) 1699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL1 -> B1RXDQSPICODE[06:00] (0x00-0x47) 1709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = (byte_lane & BIT0) ? (B1RXDQSPICODE) : (B0RXDQSPICODE); 1719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg += (((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET)); 1729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk = (BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0); 1739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = pi_count << 0; 1749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, reg, tempD, msk); 1759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // error check (shouldn't go above 0x3F) 1779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (pi_count > 0x47) 1789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 1799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney training_message(channel, rank, byte_lane); 1809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney post_code(0xEE, 0xE1); 1819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 1829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney LEAVEFN(); 1849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 1859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 1869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// get_rdqs: 1889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 1899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This function will return the current RDQS delay on the given channel, rank, byte_lane as an absolute PI count. 1909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// (currently doesn't comprehend rank) 1919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyuint32_t get_rdqs( 1929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t channel, 1939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t rank, 1949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t byte_lane) 1959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 1969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t reg; 1979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t tempD; 1989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t pi_count; 1999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ENTERFN(); 2019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // PI (1/128 MCLK) 2039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL0 -> B0RXDQSPICODE[06:00] (0x00-0x47) 2049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL1 -> B1RXDQSPICODE[06:00] (0x00-0x47) 2059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = (byte_lane & BIT0) ? (B1RXDQSPICODE) : (B0RXDQSPICODE); 2069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg += (((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET)); 2079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = isbR32m(DDRPHY, reg); 2089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Adjust PI_COUNT 2109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney pi_count = tempD & 0x7F; 2119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney LEAVEFN(); 2139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return pi_count; 2149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 2159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// set_wdqs: 2179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 2189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This function will program the WDQS delays based on an absolute amount of PIs. 2199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// (currently doesn't comprehend rank) 2209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid set_wdqs( 2219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t channel, 2229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t rank, 2239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t byte_lane, 2249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t pi_count) 2259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 2269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t reg; 2279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t msk; 2289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t tempD; 2299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ENTERFN(); 2319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_TRN, "Wdqs ch%d rnk%d ln%d : pi=%03X\n", channel, rank, byte_lane, pi_count); 2329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // RDPTR (1/2 MCLK, 64 PIs) 2349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL0 -> B01PTRCTL0[07:04] (0x0-0xF) 2359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL1 -> B01PTRCTL0[19:16] (0x0-0xF) 2369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = B01PTRCTL0 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET); 2379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk = (byte_lane & BIT0) ? (BIT19 | BIT18 | BIT17 | BIT16) : (BIT7 | BIT6 | BIT5 | BIT4); 2389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = pi_count / HALF_CLK; 2399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD <<= (byte_lane & BIT0) ? (16) : (4); 2409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, reg, tempD, msk); 2419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Adjust PI_COUNT 2439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney pi_count -= ((pi_count / HALF_CLK) & 0xF) * HALF_CLK; 2449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // PI (1/64 MCLK, 1 PIs) 2469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL0 -> B0DLLPICODER0[21:16] (0x00-0x3F) 2479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL1 -> B1DLLPICODER0[21:16] (0x00-0x3F) 2489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = (byte_lane & BIT0) ? (B1DLLPICODER0) : (B0DLLPICODER0); 2499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg += (((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET)); 2509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk = (BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | BIT16); 2519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = pi_count << 16; 2529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, reg, tempD, msk); 2539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // DEADBAND 2559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL0/1 -> B01DBCTL1[07/10] (+1 select) 2569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL0/1 -> B01DBCTL1[01/04] (enable) 2579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = B01DBCTL1 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET); 2589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk = 0x00; 2599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = 0x00; 2609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // enable 2619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk |= (byte_lane & BIT0) ? (BIT4) : (BIT1); 2629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if ((pi_count < EARLY_DB) || (pi_count > LATE_DB)) 2639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 2649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD |= msk; 2659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 2669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // select 2679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk |= (byte_lane & BIT0) ? (BIT10) : (BIT7); 2689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (pi_count < EARLY_DB) 2699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 2709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD |= msk; 2719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 2729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, reg, tempD, msk); 2739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // error check 2759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (pi_count > 0x3F) 2769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 2779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney training_message(channel, rank, byte_lane); 2789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney post_code(0xEE, 0xE2); 2799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 2809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney LEAVEFN(); 2829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 2839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 2849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// get_wdqs: 2869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 2879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This function will return the amount of WDQS delay on the given channel, rank, byte_lane as an absolute PI count. 2889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// (currently doesn't comprehend rank) 2899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyuint32_t get_wdqs( 2909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t channel, 2919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t rank, 2929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t byte_lane) 2939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 2949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t reg; 2959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t tempD; 2969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t pi_count; 2979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 2989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ENTERFN(); 2999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // RDPTR (1/2 MCLK, 64 PIs) 3019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL0 -> B01PTRCTL0[07:04] (0x0-0xF) 3029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL1 -> B01PTRCTL0[19:16] (0x0-0xF) 3039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = B01PTRCTL0 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET); 3049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = isbR32m(DDRPHY, reg); 3059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD >>= (byte_lane & BIT0) ? (16) : (4); 3069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD &= 0xF; 3079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Adjust PI_COUNT 3099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney pi_count = (tempD * HALF_CLK); 3109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // PI (1/64 MCLK, 1 PIs) 3129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL0 -> B0DLLPICODER0[21:16] (0x00-0x3F) 3139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL1 -> B1DLLPICODER0[21:16] (0x00-0x3F) 3149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = (byte_lane & BIT0) ? (B1DLLPICODER0) : (B0DLLPICODER0); 3159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg += (((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET)); 3169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = isbR32m(DDRPHY, reg); 3179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD >>= 16; 3189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD &= 0x3F; 3199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Adjust PI_COUNT 3219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney pi_count += tempD; 3229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney LEAVEFN(); 3249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return pi_count; 3259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 3269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// set_wdq: 3289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 3299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This function will program the WDQ delays based on an absolute number of PIs. 3309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// (currently doesn't comprehend rank) 3319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid set_wdq( 3329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t channel, 3339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t rank, 3349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t byte_lane, 3359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t pi_count) 3369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 3379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t reg; 3389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t msk; 3399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t tempD; 3409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ENTERFN(); 3429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_TRN, "Wdq ch%d rnk%d ln%d : pi=%03X\n", channel, rank, byte_lane, pi_count); 3439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // RDPTR (1/2 MCLK, 64 PIs) 3459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL0 -> B01PTRCTL0[03:00] (0x0-0xF) 3469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL1 -> B01PTRCTL0[15:12] (0x0-0xF) 3479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = B01PTRCTL0 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET); 3489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk = (byte_lane & BIT0) ? (BIT15 | BIT14 | BIT13 | BIT12) : (BIT3 | BIT2 | BIT1 | BIT0); 3499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = pi_count / HALF_CLK; 3509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD <<= (byte_lane & BIT0) ? (12) : (0); 3519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, reg, tempD, msk); 3529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Adjust PI_COUNT 3549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney pi_count -= ((pi_count / HALF_CLK) & 0xF) * HALF_CLK; 3559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // PI (1/64 MCLK, 1 PIs) 3579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL0 -> B0DLLPICODER0[13:08] (0x00-0x3F) 3589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL1 -> B1DLLPICODER0[13:08] (0x00-0x3F) 3599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = (byte_lane & BIT0) ? (B1DLLPICODER0) : (B0DLLPICODER0); 3609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg += (((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET)); 3619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk = (BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8); 3629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = pi_count << 8; 3639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, reg, tempD, msk); 3649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // DEADBAND 3669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL0/1 -> B01DBCTL1[06/09] (+1 select) 3679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL0/1 -> B01DBCTL1[00/03] (enable) 3689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = B01DBCTL1 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET); 3699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk = 0x00; 3709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = 0x00; 3719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // enable 3729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk |= (byte_lane & BIT0) ? (BIT3) : (BIT0); 3739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if ((pi_count < EARLY_DB) || (pi_count > LATE_DB)) 3749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 3759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD |= msk; 3769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 3779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // select 3789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk |= (byte_lane & BIT0) ? (BIT9) : (BIT6); 3799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (pi_count < EARLY_DB) 3809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 3819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD |= msk; 3829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 3839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, reg, tempD, msk); 3849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // error check 3869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (pi_count > 0x3F) 3879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 3889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney training_message(channel, rank, byte_lane); 3899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney post_code(0xEE, 0xE3); 3909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 3919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney LEAVEFN(); 3939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 3949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 3959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 3969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// get_wdq: 3979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 3989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This function will return the amount of WDQ delay on the given channel, rank, byte_lane as an absolute PI count. 3999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// (currently doesn't comprehend rank) 4009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyuint32_t get_wdq( 4019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t channel, 4029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t rank, 4039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t byte_lane) 4049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 4059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t reg; 4069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t tempD; 4079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t pi_count; 4089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ENTERFN(); 4109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // RDPTR (1/2 MCLK, 64 PIs) 4129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL0 -> B01PTRCTL0[03:00] (0x0-0xF) 4139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL1 -> B01PTRCTL0[15:12] (0x0-0xF) 4149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = B01PTRCTL0 + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET); 4159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = isbR32m(DDRPHY, reg); 4169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD >>= (byte_lane & BIT0) ? (12) : (0); 4179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD &= 0xF; 4189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Adjust PI_COUNT 4209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney pi_count = (tempD * HALF_CLK); 4219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // PI (1/64 MCLK, 1 PIs) 4239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL0 -> B0DLLPICODER0[13:08] (0x00-0x3F) 4249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // BL1 -> B1DLLPICODER0[13:08] (0x00-0x3F) 4259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = (byte_lane & BIT0) ? (B1DLLPICODER0) : (B0DLLPICODER0); 4269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg += (((byte_lane >> 1) * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET)); 4279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = isbR32m(DDRPHY, reg); 4289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD >>= 8; 4299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD &= 0x3F; 4309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Adjust PI_COUNT 4329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney pi_count += tempD; 4339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney LEAVEFN(); 4359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return pi_count; 4369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 4379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// set_wcmd: 4399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 4409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This function will program the WCMD delays based on an absolute number of PIs. 4419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid set_wcmd( 4429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t channel, 4439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t pi_count) 4449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 4459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t reg; 4469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t msk; 4479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t tempD; 4489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ENTERFN(); 4509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // RDPTR (1/2 MCLK, 64 PIs) 4519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CMDPTRREG[11:08] (0x0-0xF) 4529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = CMDPTRREG + (channel * DDRIOCCC_CH_OFFSET); 4539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk = (BIT11 | BIT10 | BIT9 | BIT8); 4549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = pi_count / HALF_CLK; 4559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD <<= 8; 4569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, reg, tempD, msk); 4579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Adjust PI_COUNT 4599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney pi_count -= ((pi_count / HALF_CLK) & 0xF) * HALF_CLK; 4609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // PI (1/64 MCLK, 1 PIs) 4629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CMDDLLPICODER0[29:24] -> CMDSLICE R3 (unused) 4639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CMDDLLPICODER0[21:16] -> CMDSLICE L3 (unused) 4649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CMDDLLPICODER0[13:08] -> CMDSLICE R2 (unused) 4659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CMDDLLPICODER0[05:00] -> CMDSLICE L2 (unused) 4669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CMDDLLPICODER1[29:24] -> CMDSLICE R1 (unused) 4679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CMDDLLPICODER1[21:16] -> CMDSLICE L1 (0x00-0x3F) 4689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CMDDLLPICODER1[13:08] -> CMDSLICE R0 (unused) 4699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CMDDLLPICODER1[05:00] -> CMDSLICE L0 (unused) 4709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = CMDDLLPICODER1 + (channel * DDRIOCCC_CH_OFFSET); 4719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk = (BIT29 | BIT28 | BIT27 | BIT26 | BIT25 | BIT24) | (BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | BIT16) 4739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney | (BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8) | (BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0); 4749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = (pi_count << 24) | (pi_count << 16) | (pi_count << 8) | (pi_count << 0); 4769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, reg, tempD, msk); 4789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = CMDDLLPICODER0 + (channel * DDRIOCCC_CH_OFFSET); // PO 4799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, reg, tempD, msk); 4809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 4819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // DEADBAND 4829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CMDCFGREG0[17] (+1 select) 4839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CMDCFGREG0[16] (enable) 4849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = CMDCFGREG0 + (channel * DDRIOCCC_CH_OFFSET); 4859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk = 0x00; 4869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = 0x00; 4879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // enable 4889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk |= BIT16; 4899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if ((pi_count < EARLY_DB) || (pi_count > LATE_DB)) 4909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 4919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD |= msk; 4929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 4939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // select 4949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk |= BIT17; 4959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (pi_count < EARLY_DB) 4969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 4979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD |= msk; 4989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 4999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, reg, tempD, msk); 5009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // error check 5029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (pi_count > 0x3F) 5039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 5049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney post_code(0xEE, 0xE4); 5059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 5069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney LEAVEFN(); 5089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 5099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 5109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// get_wcmd: 5129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 5139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This function will return the amount of WCMD delay on the given channel as an absolute PI count. 5149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyuint32_t get_wcmd( 5159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t channel) 5169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 5179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t reg; 5189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t tempD; 5199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t pi_count; 5209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ENTERFN(); 5229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // RDPTR (1/2 MCLK, 64 PIs) 5239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CMDPTRREG[11:08] (0x0-0xF) 5249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = CMDPTRREG + (channel * DDRIOCCC_CH_OFFSET); 5259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = isbR32m(DDRPHY, reg); 5269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD >>= 8; 5279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD &= 0xF; 5289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Adjust PI_COUNT 5309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney pi_count = tempD * HALF_CLK; 5319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // PI (1/64 MCLK, 1 PIs) 5339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CMDDLLPICODER0[29:24] -> CMDSLICE R3 (unused) 5349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CMDDLLPICODER0[21:16] -> CMDSLICE L3 (unused) 5359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CMDDLLPICODER0[13:08] -> CMDSLICE R2 (unused) 5369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CMDDLLPICODER0[05:00] -> CMDSLICE L2 (unused) 5379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CMDDLLPICODER1[29:24] -> CMDSLICE R1 (unused) 5389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CMDDLLPICODER1[21:16] -> CMDSLICE L1 (0x00-0x3F) 5399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CMDDLLPICODER1[13:08] -> CMDSLICE R0 (unused) 5409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CMDDLLPICODER1[05:00] -> CMDSLICE L0 (unused) 5419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = CMDDLLPICODER1 + (channel * DDRIOCCC_CH_OFFSET); 5429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = isbR32m(DDRPHY, reg); 5439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD >>= 16; 5449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD &= 0x3F; 5459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Adjust PI_COUNT 5479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney pi_count += tempD; 5489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney LEAVEFN(); 5509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return pi_count; 5519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 5529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// set_wclk: 5549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 5559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This function will program the WCLK delays based on an absolute number of PIs. 5569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid set_wclk( 5579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t channel, 5589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t rank, 5599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t pi_count) 5609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 5619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t reg; 5629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t msk; 5639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t tempD; 5649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ENTERFN(); 5669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // RDPTR (1/2 MCLK, 64 PIs) 5679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CCPTRREG[15:12] -> CLK1 (0x0-0xF) 5689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CCPTRREG[11:08] -> CLK0 (0x0-0xF) 5699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = CCPTRREG + (channel * DDRIOCCC_CH_OFFSET); 5709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk = (BIT15 | BIT14 | BIT13 | BIT12) | (BIT11 | BIT10 | BIT9 | BIT8); 5719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = ((pi_count / HALF_CLK) << 12) | ((pi_count / HALF_CLK) << 8); 5729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, reg, tempD, msk); 5739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Adjust PI_COUNT 5759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney pi_count -= ((pi_count / HALF_CLK) & 0xF) * HALF_CLK; 5769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // PI (1/64 MCLK, 1 PIs) 5789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // ECCB1DLLPICODER0[13:08] -> CLK0 (0x00-0x3F) 5799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // ECCB1DLLPICODER0[21:16] -> CLK1 (0x00-0x3F) 5809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = (rank) ? (ECCB1DLLPICODER0) : (ECCB1DLLPICODER0); 5819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg += (channel * DDRIOCCC_CH_OFFSET); 5829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk = (BIT21 | BIT20 | BIT19 | BIT18 | BIT17 | BIT16) | (BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8); 5839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = (pi_count << 16) | (pi_count << 8); 5849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, reg, tempD, msk); 5859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = (rank) ? (ECCB1DLLPICODER1) : (ECCB1DLLPICODER1); 5869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg += (channel * DDRIOCCC_CH_OFFSET); 5879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, reg, tempD, msk); 5889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = (rank) ? (ECCB1DLLPICODER2) : (ECCB1DLLPICODER2); 5899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg += (channel * DDRIOCCC_CH_OFFSET); 5909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, reg, tempD, msk); 5919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = (rank) ? (ECCB1DLLPICODER3) : (ECCB1DLLPICODER3); 5929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg += (channel * DDRIOCCC_CH_OFFSET); 5939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, reg, tempD, msk); 5949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 5959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // DEADBAND 5969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CCCFGREG1[11:08] (+1 select) 5979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CCCFGREG1[03:00] (enable) 5989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = CCCFGREG1 + (channel * DDRIOCCC_CH_OFFSET); 5999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk = 0x00; 6009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = 0x00; 6019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // enable 6029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk |= (BIT3 | BIT2 | BIT1 | BIT0); // only ??? matters 6039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if ((pi_count < EARLY_DB) || (pi_count > LATE_DB)) 6049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 6059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD |= msk; 6069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 6079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // select 6089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk |= (BIT11 | BIT10 | BIT9 | BIT8); // only ??? matters 6099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (pi_count < EARLY_DB) 6109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 6119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD |= msk; 6129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 6139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, reg, tempD, msk); 6149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // error check 6169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (pi_count > 0x3F) 6179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 6189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney post_code(0xEE, 0xE5); 6199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 6209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney LEAVEFN(); 6229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 6239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 6249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// get_wclk: 6269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 6279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This function will return the amout of WCLK delay on the given channel, rank as an absolute PI count. 6289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyuint32_t get_wclk( 6299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t channel, 6309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t rank) 6319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 6329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t reg; 6339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t tempD; 6349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t pi_count; 6359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ENTERFN(); 6379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // RDPTR (1/2 MCLK, 64 PIs) 6389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CCPTRREG[15:12] -> CLK1 (0x0-0xF) 6399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CCPTRREG[11:08] -> CLK0 (0x0-0xF) 6409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = CCPTRREG + (channel * DDRIOCCC_CH_OFFSET); 6419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = isbR32m(DDRPHY, reg); 6429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD >>= (rank) ? (12) : (8); 6439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD &= 0xF; 6449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Adjust PI_COUNT 6469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney pi_count = tempD * HALF_CLK; 6479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // PI (1/64 MCLK, 1 PIs) 6499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // ECCB1DLLPICODER0[13:08] -> CLK0 (0x00-0x3F) 6509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // ECCB1DLLPICODER0[21:16] -> CLK1 (0x00-0x3F) 6519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = (rank) ? (ECCB1DLLPICODER0) : (ECCB1DLLPICODER0); 6529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg += (channel * DDRIOCCC_CH_OFFSET); 6539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = isbR32m(DDRPHY, reg); 6549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD >>= (rank) ? (16) : (8); 6559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD &= 0x3F; 6569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney pi_count += tempD; 6589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney LEAVEFN(); 6609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return pi_count; 6619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 6629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// set_wctl: 6649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 6659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This function will program the WCTL delays based on an absolute number of PIs. 6669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// (currently doesn't comprehend rank) 6679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid set_wctl( 6689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t channel, 6699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t rank, 6709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t pi_count) 6719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 6729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t reg; 6739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t msk; 6749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t tempD; 6759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ENTERFN(); 6779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // RDPTR (1/2 MCLK, 64 PIs) 6799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CCPTRREG[31:28] (0x0-0xF) 6809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CCPTRREG[27:24] (0x0-0xF) 6819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = CCPTRREG + (channel * DDRIOCCC_CH_OFFSET); 6829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk = (BIT31 | BIT30 | BIT29 | BIT28) | (BIT27 | BIT26 | BIT25 | BIT24); 6839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = ((pi_count / HALF_CLK) << 28) | ((pi_count / HALF_CLK) << 24); 6849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, reg, tempD, msk); 6859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Adjust PI_COUNT 6879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney pi_count -= ((pi_count / HALF_CLK) & 0xF) * HALF_CLK; 6889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 6899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // PI (1/64 MCLK, 1 PIs) 6909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // ECCB1DLLPICODER?[29:24] (0x00-0x3F) 6919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // ECCB1DLLPICODER?[29:24] (0x00-0x3F) 6929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = ECCB1DLLPICODER0 + (channel * DDRIOCCC_CH_OFFSET); 6939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk = (BIT29 | BIT28 | BIT27 | BIT26 | BIT25 | BIT24); 6949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = (pi_count << 24); 6959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, reg, tempD, msk); 6969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = ECCB1DLLPICODER1 + (channel * DDRIOCCC_CH_OFFSET); 6979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, reg, tempD, msk); 6989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = ECCB1DLLPICODER2 + (channel * DDRIOCCC_CH_OFFSET); 6999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, reg, tempD, msk); 7009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = ECCB1DLLPICODER3 + (channel * DDRIOCCC_CH_OFFSET); 7019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, reg, tempD, msk); 7029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // DEADBAND 7049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CCCFGREG1[13:12] (+1 select) 7059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CCCFGREG1[05:04] (enable) 7069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = CCCFGREG1 + (channel * DDRIOCCC_CH_OFFSET); 7079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk = 0x00; 7089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = 0x00; 7099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // enable 7109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk |= (BIT5 | BIT4); // only ??? matters 7119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if ((pi_count < EARLY_DB) || (pi_count > LATE_DB)) 7129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 7139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD |= msk; 7149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 7159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // select 7169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk |= (BIT13 | BIT12); // only ??? matters 7179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (pi_count < EARLY_DB) 7189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 7199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD |= msk; 7209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 7219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, reg, tempD, msk); 7229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // error check 7249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (pi_count > 0x3F) 7259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 7269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney post_code(0xEE, 0xE6); 7279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 7289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney LEAVEFN(); 7309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 7319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 7329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// get_wctl: 7349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 7359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This function will return the amount of WCTL delay on the given channel, rank as an absolute PI count. 7369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// (currently doesn't comprehend rank) 7379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyuint32_t get_wctl( 7389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t channel, 7399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t rank) 7409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 7419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t reg; 7429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t tempD; 7439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t pi_count; 7449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ENTERFN(); 7469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // RDPTR (1/2 MCLK, 64 PIs) 7489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CCPTRREG[31:28] (0x0-0xF) 7499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // CCPTRREG[27:24] (0x0-0xF) 7509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = CCPTRREG + (channel * DDRIOCCC_CH_OFFSET); 7519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = isbR32m(DDRPHY, reg); 7529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD >>= 24; 7539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD &= 0xF; 7549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Adjust PI_COUNT 7569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney pi_count = tempD * HALF_CLK; 7579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // PI (1/64 MCLK, 1 PIs) 7599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // ECCB1DLLPICODER?[29:24] (0x00-0x3F) 7609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // ECCB1DLLPICODER?[29:24] (0x00-0x3F) 7619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney reg = ECCB1DLLPICODER0 + (channel * DDRIOCCC_CH_OFFSET); 7629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = isbR32m(DDRPHY, reg); 7639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD >>= 24; 7649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD &= 0x3F; 7659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Adjust PI_COUNT 7679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney pi_count += tempD; 7689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney LEAVEFN(); 7709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return pi_count; 7719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 7729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// set_vref: 7749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 7759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This function will program the internal Vref setting in a given byte lane in a given channel. 7769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid set_vref( 7779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t channel, 7789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t byte_lane, 7799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t setting) 7809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 7819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t reg = (byte_lane & 0x1) ? (B1VREFCTL) : (B0VREFCTL); 7829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ENTERFN(); 7849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_TRN, "Vref ch%d ln%d : val=%03X\n", channel, byte_lane, setting); 7859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, (reg + (channel * DDRIODQ_CH_OFFSET) + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET)), 7879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney (vref_codes[setting] << 2), (BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2)); 7889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney //isbM32m(DDRPHY, (reg + (channel * DDRIODQ_CH_OFFSET) + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET)), (setting<<2), (BIT7|BIT6|BIT5|BIT4|BIT3|BIT2)); 7899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // need to wait ~300ns for Vref to settle (check that this is necessary) 7909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney delay_n(300); 7919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // ??? may need to clear pointers ??? 7929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney LEAVEFN(); 7939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 7949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 7959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 7969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// get_vref: 7979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 7989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This function will return the internal Vref setting for the given channel, byte_lane; 7999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyuint32_t get_vref( 8009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t channel, 8019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t byte_lane) 8029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 8039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t j; 8049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t ret_val = sizeof(vref_codes) / 2; 8059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t reg = (byte_lane & 0x1) ? (B1VREFCTL) : (B0VREFCTL); 8069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t tempD; 8089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ENTERFN(); 8109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = isbR32m(DDRPHY, (reg + (channel * DDRIODQ_CH_OFFSET) + ((byte_lane >> 1) * DDRIODQ_BL_OFFSET))); 8119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD >>= 2; 8129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD &= 0x3F; 8139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (j = 0; j < sizeof(vref_codes); j++) 8149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 8159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (vref_codes[j] == tempD) 8169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 8179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ret_val = j; 8189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 8199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 8209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 8219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney LEAVEFN(); 8229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return ret_val; 8239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 8249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// clear_pointers: 8269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 8279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This function will be used to clear the pointers in a given byte lane in a given channel. 8289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid clear_pointers( 8299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney void) 8309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 8319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t channel_i; 8329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t bl_i; 8339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ENTERFN(); 8359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (channel_i = 0; channel_i < NUM_CHANNELS; channel_i++) 8369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 8379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (bl_i = 0; bl_i < NUM_BYTE_LANES; bl_i++) 8389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 8399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, (B01PTRCTL1 + (channel_i * DDRIODQ_CH_OFFSET) + ((bl_i >> 1) * DDRIODQ_BL_OFFSET)), ~(BIT8), 8409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney (BIT8)); 8419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney //delay_m(1); // DEBUG 8429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbM32m(DDRPHY, (B01PTRCTL1 + (channel_i * DDRIODQ_CH_OFFSET) + ((bl_i >> 1) * DDRIODQ_BL_OFFSET)), (BIT8), 8439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney (BIT8)); 8449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 8459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 8469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney LEAVEFN(); 8479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 8489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 8499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// void enable_cache: 8519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid enable_cache( 8529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney void) 8539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 8549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Cache control not used in Quark MRC 8559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 8569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 8579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// void disable_cache: 8599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid disable_cache( 8609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney void) 8619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 8629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Cache control not used in Quark MRC 8639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 8649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 8659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// Send DRAM command, data should be formated 8679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// using DCMD_Xxxx macro or emrsXCommand structure. 8689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneystatic void dram_init_command( 8699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t data) 8709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 8719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney Wr32(DCMD, 0, data); 8729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 8739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// find_rising_edge: 8759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 8769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This function will find the rising edge transition on RCVN or WDQS. 8779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid find_rising_edge( 8789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney MRCParams_t *mrc_params, 8799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t delay[], 8809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t channel, 8819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t rank, 8829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney bool rcvn) 8839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 8849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#define SAMPLE_CNT 3 // number of sample points 8869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#define SAMPLE_DLY 26 // number of PIs to increment per sample 8879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#define FORWARD true // indicates to increase delays when looking for edge 8889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#define BACKWARD false // indicates to decrease delays when looking for edge 8899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney bool all_edges_found; // determines stop condition 8919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney bool direction[NUM_BYTE_LANES]; // direction indicator 8929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t sample_i; // sample counter 8939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t bl_i; // byte lane counter 8949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t bl_divisor = (mrc_params->channel_width == x16) ? 2 : 1; // byte lane divisor 8959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t sample_result[SAMPLE_CNT]; // results of "sample_dqs()" 8969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t tempD; // temporary DWORD 8979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t transition_pattern; 8989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 8999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ENTERFN(); 9009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // select hte and request initial configuration 9029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney select_hte(mrc_params); 9039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney first_run = 1; 9049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Take 3 sample points (T1,T2,T3) to obtain a transition pattern. 9069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (sample_i = 0; sample_i < SAMPLE_CNT; sample_i++) 9079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 9089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // program the desired delays for sample 9099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i++) 9109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 9119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // increase sample delay by 26 PI (0.2 CLK) 9129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (rcvn) 9139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 9149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney set_rcvn(channel, rank, bl_i, delay[bl_i] + (sample_i * SAMPLE_DLY)); 9159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 9169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney else 9179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 9189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney set_wdqs(channel, rank, bl_i, delay[bl_i] + (sample_i * SAMPLE_DLY)); 9199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 9209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } // bl_i loop 9219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // take samples (Tsample_i) 9229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney sample_result[sample_i] = sample_dqs(mrc_params, channel, rank, rcvn); 9239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_TRN, "Find rising edge %s ch%d rnk%d: #%d dly=%d dqs=%02X\n", 9259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney (rcvn ? "RCVN" : "WDQS"), channel, rank, 9269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney sample_i, sample_i * SAMPLE_DLY, sample_result[sample_i]); 9279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } // sample_i loop 9299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // This pattern will help determine where we landed and ultimately how to place RCVEN/WDQS. 9319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i++) 9329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 9339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // build "transition_pattern" (MSB is 1st sample) 9349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney transition_pattern = 0x00; 9359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (sample_i = 0; sample_i < SAMPLE_CNT; sample_i++) 9369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 9379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney transition_pattern |= ((sample_result[sample_i] & (1 << bl_i)) >> bl_i) << (SAMPLE_CNT - 1 - sample_i); 9389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } // sample_i loop 9399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_TRN, "=== transition pattern %d\n", transition_pattern); 9419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // set up to look for rising edge based on "transition_pattern" 9439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney switch (transition_pattern) 9449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 9459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney case 0x00: // sampled 0->0->0 9469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // move forward from T3 looking for 0->1 9479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney delay[bl_i] += 2 * SAMPLE_DLY; 9489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney direction[bl_i] = FORWARD; 9499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 9509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney case 0x01: // sampled 0->0->1 9519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney case 0x05: // sampled 1->0->1 (bad duty cycle) *HSD#237503* 9529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // move forward from T2 looking for 0->1 9539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney delay[bl_i] += 1 * SAMPLE_DLY; 9549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney direction[bl_i] = FORWARD; 9559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 9569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// HSD#237503 9579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// case 0x02: // sampled 0->1->0 (bad duty cycle) 9589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// training_message(channel, rank, bl_i); 9599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// post_code(0xEE, 0xE8); 9609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// break; 9619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney case 0x02: // sampled 0->1->0 (bad duty cycle) *HSD#237503* 9629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney case 0x03: // sampled 0->1->1 9639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // move forward from T1 looking for 0->1 9649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney delay[bl_i] += 0 * SAMPLE_DLY; 9659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney direction[bl_i] = FORWARD; 9669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 9679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney case 0x04: // sampled 1->0->0 (assumes BL8, HSD#234975) 9689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // move forward from T3 looking for 0->1 9699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney delay[bl_i] += 2 * SAMPLE_DLY; 9709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney direction[bl_i] = FORWARD; 9719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 9729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// HSD#237503 9739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// case 0x05: // sampled 1->0->1 (bad duty cycle) 9749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// training_message(channel, rank, bl_i); 9759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// post_code(0xEE, 0xE9); 9769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// break; 9779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney case 0x06: // sampled 1->1->0 9789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney case 0x07: // sampled 1->1->1 9799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // move backward from T1 looking for 1->0 9809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney delay[bl_i] += 0 * SAMPLE_DLY; 9819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney direction[bl_i] = BACKWARD; 9829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 9839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney default: 9849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney post_code(0xEE, 0xEE); 9859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 9869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } // transition_pattern switch 9879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // program delays 9889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (rcvn) 9899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 9909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney set_rcvn(channel, rank, bl_i, delay[bl_i]); 9919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 9929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney else 9939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 9949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney set_wdqs(channel, rank, bl_i, delay[bl_i]); 9959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 9969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } // bl_i loop 9979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 9989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Based on the observed transition pattern on the byte lane, 9999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // begin looking for a rising edge with single PI granularity. 10009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney do 10019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 10029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney all_edges_found = true; // assume all byte lanes passed 10039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tempD = sample_dqs(mrc_params, channel, rank, rcvn); // take a sample 10049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // check all each byte lane for proper edge 10059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i++) 10069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 10079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (tempD & (1 << bl_i)) 10089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 10099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // sampled "1" 10109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (direction[bl_i] == BACKWARD) 10119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 10129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // keep looking for edge on this byte lane 10139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney all_edges_found = false; 10149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney delay[bl_i] -= 1; 10159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (rcvn) 10169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 10179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney set_rcvn(channel, rank, bl_i, delay[bl_i]); 10189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 10199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney else 10209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 10219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney set_wdqs(channel, rank, bl_i, delay[bl_i]); 10229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 10239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 10249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 10259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney else 10269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 10279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // sampled "0" 10289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (direction[bl_i] == FORWARD) 10299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 10309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // keep looking for edge on this byte lane 10319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney all_edges_found = false; 10329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney delay[bl_i] += 1; 10339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (rcvn) 10349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 10359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney set_rcvn(channel, rank, bl_i, delay[bl_i]); 10369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 10379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney else 10389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 10399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney set_wdqs(channel, rank, bl_i, delay[bl_i]); 10409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 10419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 10429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 10439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } // bl_i loop 10449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } while (!all_edges_found); 10459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 10469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // restore DDR idle state 10479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney dram_init_command(DCMD_PREA(rank)); 10489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 10499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_TRN, "Delay %03X %03X %03X %03X\n", 10509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney delay[0], delay[1], delay[2], delay[3]); 10519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 10529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney LEAVEFN(); 10539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 10549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 10559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 10569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// sample_dqs: 10579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 10589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This function will sample the DQTRAINSTS registers in the given channel/rank SAMPLE_SIZE times looking for a valid '0' or '1'. 10599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// It will return an encoded DWORD in which each bit corresponds to the sampled value on the byte lane. 10609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyuint32_t sample_dqs( 10619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney MRCParams_t *mrc_params, 10629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t channel, 10639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t rank, 10649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney bool rcvn) 10659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 10669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t j; // just a counter 10679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t bl_i; // which BL in the module (always 2 per module) 10689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t bl_grp; // which BL module 10699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t bl_divisor = (mrc_params->channel_width == x16) ? 2 : 1; // byte lane divisor 10709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t msk[2]; // BLx in module 10719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t sampled_val[SAMPLE_SIZE]; // DQTRAINSTS register contents for each sample 10729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t num_0s; // tracks the number of '0' samples 10739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t num_1s; // tracks the number of '1' samples 10749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t ret_val = 0x00; // assume all '0' samples 10759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t address = get_addr(mrc_params, channel, rank); 10769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 10779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // initialise "msk[]" 10789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk[0] = (rcvn) ? (BIT1) : (BIT9); // BL0 10799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney msk[1] = (rcvn) ? (BIT0) : (BIT8); // BL1 10809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 10819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 10829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // cycle through each byte lane group 10839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (bl_grp = 0; bl_grp < (NUM_BYTE_LANES / bl_divisor) / 2; bl_grp++) 10849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 10859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // take SAMPLE_SIZE samples 10869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (j = 0; j < SAMPLE_SIZE; j++) 10879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 10889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney HteMemOp(address, first_run, rcvn?0:1); 10899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney first_run = 0; 10909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 10919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // record the contents of the proper DQTRAINSTS register 10929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney sampled_val[j] = isbR32m(DDRPHY, (DQTRAINSTS + (bl_grp * DDRIODQ_BL_OFFSET) + (channel * DDRIODQ_CH_OFFSET))); 10939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 10949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // look for a majority value ( (SAMPLE_SIZE/2)+1 ) on the byte lane 10959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // and set that value in the corresponding "ret_val" bit 10969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (bl_i = 0; bl_i < 2; bl_i++) 10979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 10989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney num_0s = 0x00; // reset '0' tracker for byte lane 10999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney num_1s = 0x00; // reset '1' tracker for byte lane 11009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (j = 0; j < SAMPLE_SIZE; j++) 11019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 11029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (sampled_val[j] & msk[bl_i]) 11039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 11049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney num_1s++; 11059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 11069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney else 11079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 11089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney num_0s++; 11099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 11109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 11119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (num_1s > num_0s) 11129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 11139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ret_val |= (1 << (bl_i + (bl_grp * 2))); 11149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 11159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 11169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 11179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 11189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // "ret_val.0" contains the status of BL0 11199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // "ret_val.1" contains the status of BL1 11209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // "ret_val.2" contains the status of BL2 11219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // etc. 11229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return ret_val; 11239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 11249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 11259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// get_addr: 11269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 11279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This function will return a 32 bit address in the desired channel and rank. 11289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyuint32_t get_addr( 11299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney MRCParams_t *mrc_params, 11309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t channel, 11319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t rank) 11329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 11339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t offset = 0x02000000; // 32MB 11349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 11359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Begin product specific code 11369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (channel > 0) 11379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 11389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_ERROR, "ILLEGAL CHANNEL\n"); 11399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DEAD_LOOP(); 11409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 11419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 11429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (rank > 1) 11439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 11449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_ERROR, "ILLEGAL RANK\n"); 11459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DEAD_LOOP(); 11469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 11479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 11489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // use 256MB lowest density as per DRP == 0x0003 11499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney offset += rank * (256 * 1024 * 1024); 11509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 11519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return offset; 11529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 11539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 11549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// byte_lane_mask: 11559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 11569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This function will return a 32 bit mask that will be used to check for byte lane failures. 11579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyuint32_t byte_lane_mask( 11589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney MRCParams_t *mrc_params) 11599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 11609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t j; 11619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t ret_val = 0x00; 11629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 11639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // set "ret_val" based on NUM_BYTE_LANES such that you will check only BL0 in "result" 11649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // (each bit in "result" represents a byte lane) 11659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (j = 0; j < MAX_BYTE_LANES; j += NUM_BYTE_LANES) 11669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 11679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ret_val |= (1 << ((j / NUM_BYTE_LANES) * NUM_BYTE_LANES)); 11689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 11699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 11709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // HSD#235037 11719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // need to adjust the mask for 16-bit mode 11729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (mrc_params->channel_width == x16) 11739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 11749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ret_val |= (ret_val << 2); 11759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 11769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 11779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return ret_val; 11789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 11799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 11809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 11819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// read_tsc: 11829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 11839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This function will do some assembly to return TSC register contents as a uint64_t. 11849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyuint64_t read_tsc( 11859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney void) 11869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 11879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney volatile uint64_t tsc; // EDX:EAX 11889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 11899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#if defined (SIM) || defined (GCC) 11909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney volatile uint32_t tscH; // EDX 11919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney volatile uint32_t tscL;// EAX 11929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 11939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney asm("rdtsc":"=a"(tscL),"=d"(tscH)); 11949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tsc = tscH; 11959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tsc = (tsc<<32)|tscL; 11969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#else 11979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney tsc = __rdtsc(); 11989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#endif 11999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 12009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return tsc; 12019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 12029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 12039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// get_tsc_freq: 12049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 12059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This function returns the TSC frequency in MHz 12069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyuint32_t get_tsc_freq( 12079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney void) 12089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 12099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney static uint32_t freq[] = 12109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 533, 400, 200, 100 }; 12119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t fuse; 12129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#if 0 12139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney fuse = (isbR32m(FUSE, 0) >> 12) & (BIT1|BIT0); 12149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#else 12159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // todo!!! Fixed 533MHz for emulation or debugging 12169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney fuse = 0; 12179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#endif 12189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return freq[fuse]; 12199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 12209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 12219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#ifndef SIM 12229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// delay_n: 12239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 12249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This is a simple delay function. 12259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// It takes "nanoseconds" as a parameter. 12269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid delay_n( 12279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t nanoseconds) 12289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 12299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 1000 MHz clock has 1ns period --> no conversion required 12309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint64_t final_tsc = read_tsc(); 12319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney final_tsc += ((get_tsc_freq() * (nanoseconds)) / 1000); 12329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 12339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney while (read_tsc() < final_tsc) 12349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ; 12359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 12369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 12379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#endif 12389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 12399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// delay_u: 12409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 12419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This is a simple delay function. 12429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// It takes "microseconds as a parameter. 12439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid delay_u( 12449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t microseconds) 12459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 12469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 64 bit math is not an option, just use loops 12479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney while (microseconds--) 12489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 12499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney delay_n(1000); 12509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 12519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 12529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 12539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 12549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// delay_m: 12559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 12569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This is a simple delay function. 12579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// It takes "milliseconds" as a parameter. 12589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid delay_m( 12599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t milliseconds) 12609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 12619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 64 bit math is not an option, just use loops 12629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney while (milliseconds--) 12639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 12649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney delay_u(1000); 12659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 12669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 12679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 12689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 12699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// delay_s: 12709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 12719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This is a simple delay function. 12729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// It takes "seconds" as a parameter. 12739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid delay_s( 12749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t seconds) 12759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 12769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 64 bit math is not an option, just use loops 12779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney while (seconds--) 12789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 12799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney delay_m(1000); 12809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 12819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 12829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 12839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 12849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// post_code: 12859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 12869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This function will output the POST CODE to the four 7-Segment LED displays. 12879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid post_code( 12889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t major, 12899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t minor) 12909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 12919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#ifdef EMU 12929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // Update global variable for execution tracking in debug env 12939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney PostCode = ((major << 8) | minor); 12949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#endif 12959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 12969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // send message to UART 12979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_INFO, "POST: 0x%01X%02X\n", major, minor); 12989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 12999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // error check: 13009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (major == 0xEE) 13019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 13029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // todo!!! Consider updating error status and exit MRC 13039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#ifdef SIM 13049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // enable Ctrl-C handling 13059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for(;;) delay_n(100); 13069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#else 13079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DEAD_LOOP(); 13089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney#endif 13099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 13109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 13119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 13129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid training_message( 13139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t channel, 13149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t rank, 13159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t byte_lane) 13169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 13179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // send message to UART 13189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_INFO, "CH%01X RK%01X BL%01X\n", channel, rank, byte_lane); 13199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 13209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 13219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 13229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid print_timings( 13239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney MRCParams_t *mrc_params) 13249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 13259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t algo_i; 13269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t channel_i; 13279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t rank_i; 13289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t bl_i; 13299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t bl_divisor = (mrc_params->channel_width == x16) ? 2 : 1; 13309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 13319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_INFO, "\n---------------------------"); 13329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_INFO, "\nALGO[CH:RK] BL0 BL1 BL2 BL3"); 13339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_INFO, "\n==========================="); 13349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (algo_i = 0; algo_i < eMAX_ALGOS; algo_i++) 13359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 13369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (channel_i = 0; channel_i < NUM_CHANNELS; channel_i++) 13379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 13389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (mrc_params->channel_enables & (1 << channel_i)) 13399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 13409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (rank_i = 0; rank_i < NUM_RANKS; rank_i++) 13419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 13429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (mrc_params->rank_enables & (1 << rank_i)) 13439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 13449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney switch (algo_i) 13459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 13469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney case eRCVN: 13479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_INFO, "\nRCVN[%02d:%02d]", channel_i, rank_i); 13489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 13499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney case eWDQS: 13509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_INFO, "\nWDQS[%02d:%02d]", channel_i, rank_i); 13519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 13529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney case eWDQx: 13539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_INFO, "\nWDQx[%02d:%02d]", channel_i, rank_i); 13549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 13559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney case eRDQS: 13569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_INFO, "\nRDQS[%02d:%02d]", channel_i, rank_i); 13579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 13589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney case eVREF: 13599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_INFO, "\nVREF[%02d:%02d]", channel_i, rank_i); 13609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 13619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney case eWCMD: 13629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_INFO, "\nWCMD[%02d:%02d]", channel_i, rank_i); 13639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 13649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney case eWCTL: 13659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_INFO, "\nWCTL[%02d:%02d]", channel_i, rank_i); 13669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 13679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney case eWCLK: 13689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_INFO, "\nWCLK[%02d:%02d]", channel_i, rank_i); 13699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 13709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney default: 13719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 13729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } // algo_i switch 13739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (bl_i = 0; bl_i < (NUM_BYTE_LANES / bl_divisor); bl_i++) 13749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 13759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney switch (algo_i) 13769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 13779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney case eRCVN: 13789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_INFO, " %03d", get_rcvn(channel_i, rank_i, bl_i)); 13799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 13809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney case eWDQS: 13819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_INFO, " %03d", get_wdqs(channel_i, rank_i, bl_i)); 13829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 13839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney case eWDQx: 13849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_INFO, " %03d", get_wdq(channel_i, rank_i, bl_i)); 13859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 13869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney case eRDQS: 13879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_INFO, " %03d", get_rdqs(channel_i, rank_i, bl_i)); 13889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 13899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney case eVREF: 13909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_INFO, " %03d", get_vref(channel_i, bl_i)); 13919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 13929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney case eWCMD: 13939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_INFO, " %03d", get_wcmd(channel_i)); 13949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 13959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney case eWCTL: 13969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_INFO, " %03d", get_wctl(channel_i, rank_i)); 13979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 13989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney case eWCLK: 13999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_INFO, " %03d", get_wclk(channel_i, rank_i)); 14009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 14019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney default: 14029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney break; 14039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } // algo_i switch 14049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } // bl_i loop 14059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } // if rank_i enabled 14069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } // rank_i loop 14079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } // if channel_i enabled 14089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } // channel_i loop 14099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } // algo_i loop 14109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_INFO, "\n---------------------------"); 14119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney DPF(D_INFO, "\n"); 14129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 14139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 14149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 14159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// 32 bit LFSR with characteristic polynomial: X^32 + X^22 +X^2 + X^1 14169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// The function takes pointer to previous 32 bit value and modifies it to next value. 14179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid lfsr32( 14189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t *lfsr_ptr) 14199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 14209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t bit; 14219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t lfsr; 14229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t i; 14239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 14249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney lfsr = *lfsr_ptr; 14259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 14269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (i = 0; i < 32; i++) 14279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 14289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney bit = 1 ^ (lfsr & BIT0); 14299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney bit = bit ^ ((lfsr & BIT1) >> 1); 14309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney bit = bit ^ ((lfsr & BIT2) >> 2); 14319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney bit = bit ^ ((lfsr & BIT22) >> 22); 14329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 14339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney lfsr = ((lfsr >> 1) | (bit << 31)); 14349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 14359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 14369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney *lfsr_ptr = lfsr; 14379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 14389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 14399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 14409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// The purpose of this function is to ensure the SEC comes out of reset 14419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// and IA initiates the SEC enabling Memory Scrambling. 14429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid enable_scrambling( 14439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney MRCParams_t *mrc_params) 14449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 14459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint32_t lfsr = 0; 14469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t i; 14479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 14489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (mrc_params->scrambling_enables == 0) 14499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 14509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 14519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney ENTERFN(); 14529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 14539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // 32 bit seed is always stored in BIOS NVM. 14549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney lfsr = mrc_params->timings.scrambler_seed; 14559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 14569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (mrc_params->boot_mode == bmCold) 14579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 14589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // factory value is 0 and in first boot, a clock based seed is loaded. 14599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (lfsr == 0) 14609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 14619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney lfsr = read_tsc() & 0x0FFFFFFF; // get seed from system clock and make sure it is not all 1's 14629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 14639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // need to replace scrambler 14649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // get next 32bit LFSR 16 times which is the last part of the previous scrambler vector. 14659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney else 14669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 14679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (i = 0; i < 16; i++) 14689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 14699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney lfsr32(&lfsr); 14709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 14719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 14729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney mrc_params->timings.scrambler_seed = lfsr; // save new seed. 14739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } // if (cold_boot) 14749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 14759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // In warm boot or S3 exit, we have the previous seed. 14769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // In cold boot, we have the last 32bit LFSR which is the new seed. 14779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney lfsr32(&lfsr); // shift to next value 14789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbW32m(MCU, SCRMSEED, (lfsr & 0x0003FFFF)); 14799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (i = 0; i < 2; i++) 14809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 14819b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney isbW32m(MCU, SCRMLO + i, (lfsr & 0xAAAAAAAA)); 14829b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 14839b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 14849b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney LEAVEFN(); 14859b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 14869b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 14879b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 14889b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This function will store relevant timing data 14899b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This data will be used on subsequent boots to speed up boot times 14909b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// and is required for Suspend To RAM capabilities. 14919b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid store_timings( 14929b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney MRCParams_t *mrc_params) 14939b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 14949b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t ch, rk, bl; 14959b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney MrcTimings_t *mt = &mrc_params->timings; 14969b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 14979b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (ch = 0; ch < NUM_CHANNELS; ch++) 14989b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 14999b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (rk = 0; rk < NUM_RANKS; rk++) 15009b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 15019b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (bl = 0; bl < NUM_BYTE_LANES; bl++) 15029b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 15039b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney mt->rcvn[ch][rk][bl] = get_rcvn(ch, rk, bl); // RCVN 15049b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney mt->rdqs[ch][rk][bl] = get_rdqs(ch, rk, bl); // RDQS 15059b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney mt->wdqs[ch][rk][bl] = get_wdqs(ch, rk, bl); // WDQS 15069b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney mt->wdq[ch][rk][bl] = get_wdq(ch, rk, bl); // WDQ 15079b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (rk == 0) 15089b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 15099b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney mt->vref[ch][bl] = get_vref(ch, bl); // VREF (RANK0 only) 15109b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 15119b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 15129b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney mt->wctl[ch][rk] = get_wctl(ch, rk); // WCTL 15139b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 15149b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney mt->wcmd[ch] = get_wcmd(ch); // WCMD 15159b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 15169b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 15179b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney // need to save for a case of changing frequency after warm reset 15189b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney mt->ddr_speed = mrc_params->ddr_speed; 15199b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 15209b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 15219b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 15229b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 15239b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This function will retrieve relevant timing data 15249b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// This data will be used on subsequent boots to speed up boot times 15259b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// and is required for Suspend To RAM capabilities. 15269b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid restore_timings( 15279b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney MRCParams_t *mrc_params) 15289b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 15299b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t ch, rk, bl; 15309b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney const MrcTimings_t *mt = &mrc_params->timings; 15319b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 15329b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (ch = 0; ch < NUM_CHANNELS; ch++) 15339b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 15349b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (rk = 0; rk < NUM_RANKS; rk++) 15359b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 15369b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (bl = 0; bl < NUM_BYTE_LANES; bl++) 15379b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 15389b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney set_rcvn(ch, rk, bl, mt->rcvn[ch][rk][bl]); // RCVN 15399b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney set_rdqs(ch, rk, bl, mt->rdqs[ch][rk][bl]); // RDQS 15409b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney set_wdqs(ch, rk, bl, mt->wdqs[ch][rk][bl]); // WDQS 15419b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney set_wdq(ch, rk, bl, mt->wdq[ch][rk][bl]); // WDQ 15429b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (rk == 0) 15439b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 15449b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney set_vref(ch, bl, mt->vref[ch][bl]); // VREF (RANK0 only) 15459b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 15469b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 15479b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney set_wctl(ch, rk, mt->wctl[ch][rk]); // WCTL 15489b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 15499b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney set_wcmd(ch, mt->wcmd[ch]); // WCMD 15509b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 15519b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 15529b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 15539b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 15549b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 15559b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// Configure default settings normally set as part of read training 15569b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// Some defaults have to be set earlier as they may affect earlier 15579b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney// training steps. 15589b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinneyvoid default_timings( 15599b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney MRCParams_t *mrc_params) 15609b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney{ 15619b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney uint8_t ch, rk, bl; 15629b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 15639b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (ch = 0; ch < NUM_CHANNELS; ch++) 15649b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 15659b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (rk = 0; rk < NUM_RANKS; rk++) 15669b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 15679b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney for (bl = 0; bl < NUM_BYTE_LANES; bl++) 15689b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 15699b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney set_rdqs(ch, rk, bl, 24); // RDQS 15709b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney if (rk == 0) 15719b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney { 15729b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney set_vref(ch, bl, 32); // VREF (RANK0 only) 15739b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 15749b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 15759b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 15769b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney } 15779b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 15789b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney return; 15799b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney} 15809b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164Michael Kinney 1581