first and last commit
This commit is contained in:
commit
1bf4efd552
2612 files changed
+636500
No files matched your search
@@ -0,0 +1,921 @@
|
||||
/*
|
||||
* Copyright (C) 2013-2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This document is the property of Apple Inc.
|
||||
* It is considered confidential and proprietary.
|
||||
*
|
||||
* This document may not be reproduced or transmitted in any form,
|
||||
* in whole or in part, without the express written permission of
|
||||
* Apple Inc.
|
||||
*/
|
||||
#include <debug.h>
|
||||
#include <drivers/dcs/dcs.h>
|
||||
#include <drivers/dcs/dcs_regs.h>
|
||||
#include <drivers/dcs/dcs_init_lib.h>
|
||||
#include <drivers/dram.h>
|
||||
#include <drivers/miu.h>
|
||||
#include <drivers/reconfig.h>
|
||||
#include <sys.h>
|
||||
#include <platform/soc/hwclocks.h>
|
||||
|
||||
int mcu_initialize_dram (bool resume)
|
||||
{
|
||||
dcs_boottype_t boot_type;
|
||||
|
||||
// Don't perform DRAM initializion if the memory controller is already
|
||||
// initialized (e.g., for SecureROM validation testing).
|
||||
#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003
|
||||
if (resume || DCS_REG_READ_CH(0, rDCS_MCU_AMCCTRL) == 0) {
|
||||
#endif
|
||||
clock_gate(CLK_DCS0, true);
|
||||
clock_gate(CLK_DCS1, true);
|
||||
clock_gate(CLK_DCS2, true);
|
||||
clock_gate(CLK_DCS3, true);
|
||||
#if SUB_PLATFORM_S8001 && DCS_NUM_CHANNELS > 4
|
||||
clock_gate(CLK_DCS4, true);
|
||||
clock_gate(CLK_DCS5, true);
|
||||
clock_gate(CLK_DCS6, true);
|
||||
clock_gate(CLK_DCS7, true);
|
||||
#endif
|
||||
clock_gate(CLK_MCC, true);
|
||||
|
||||
boot_type = (resume)? DCS_BOOT_RESUME:DCS_BOOT_COLDBOOT;
|
||||
// NOTE: Boot types AOP_DDR or AOP_AWAKE do not use this Code
|
||||
// For those cases, the Init sequence is executed by the AOP
|
||||
|
||||
// Perform the LPDDR4 Init for this type of Boot
|
||||
dcs_init(boot_type);
|
||||
|
||||
// <rdar://problem/18602531> Maui A1: Samsung 25nm LP4 RBM failures - WA
|
||||
// Can't do this as part of dcs_dram_workarounds because reg value gets overwritten later in the sequence
|
||||
const struct dcs_memory_device_info *dev_info = dcs_get_memory_device_info();
|
||||
if(dev_info->vendor_id == JEDEC_LPDDR4_MANUF_ID_SAMSUNG)
|
||||
if(dev_info->rev_id == 0x3 && dev_info->rev_id2 == 0x0)
|
||||
for(uint32_t channel = 0; channel < DCS_NUM_CHANNELS; channel++)
|
||||
DCS_REG_ACCESS(rDCS_MCU_AREFEN_FREQ(0) + (channel * DCS_SPACING)) = 0x1010013f;
|
||||
#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dcs_lock_down_mcc(void)
|
||||
{
|
||||
// Don't allow MCC as RAM
|
||||
rAMCC_MCCGEN &= ~AMCC_MCCGEN_MCC_RAM_EN;
|
||||
rAMCC_MCCGEN |= AMCC_MCCGEN_MCC_RAM_EN_LOCK;
|
||||
// Don't allow tag RAM reads
|
||||
rAMCC_MCCCFG_TAG_RD_DIS |= 1;
|
||||
#if NUM_AMCCS > 1
|
||||
rAMCC1_MCCGEN &= ~AMCC_MCCGEN_MCC_RAM_EN;
|
||||
rAMCC1_MCCGEN |= AMCC_MCCGEN_MCC_RAM_EN_LOCK;
|
||||
rAMCC1_MCCCFG_TAG_RD_DIS |= 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void mcu_bypass_prep (int step)
|
||||
{
|
||||
}
|
||||
|
||||
uint64_t mcu_get_memory_size (void)
|
||||
{
|
||||
return dcs_get_memory_size();
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
void dcs_enable_slow_boot (bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
// switch to slow clock
|
||||
clocks_set_performance(kPerformanceMemoryLow);
|
||||
spin(1);
|
||||
}
|
||||
else {
|
||||
#if !SUPPORT_FPGA
|
||||
// switch back to full-speed
|
||||
clocks_set_performance(kPerformanceMemoryFull);
|
||||
spin(1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// https://seg-docs.ecs.apple.com/projects/malta//release/UserManual/Hx_LPDDR4_RevID_Workaround.pdf
|
||||
void dcs_dram_workarounds(dcs_boottype_t boot_type)
|
||||
{
|
||||
#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003
|
||||
uint32_t autoref_freq1;
|
||||
#endif
|
||||
#if SUB_PLATFORM_S8000
|
||||
uint32_t dqvref_freq1;
|
||||
#endif
|
||||
|
||||
if(boot_type == DCS_BOOT_COLDBOOT) {
|
||||
|
||||
const struct dcs_memory_device_info *dev_info = dcs_get_memory_device_info();
|
||||
|
||||
switch (dev_info->vendor_id) {
|
||||
case JEDEC_LPDDR4_MANUF_ID_SAMSUNG:
|
||||
#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003
|
||||
if(dev_info->rev_id == 5 && dev_info->rev_id2 == 1) {
|
||||
// <rdar://problem/21042636> tRFCpbCyc_freq1 = 0x1c for Samsung
|
||||
autoref_freq1 = DCS_REG_READ_CH(0, rDCS_MCU_AUTOREF_FREQ(1));
|
||||
autoref_freq1 &= 0x00ffffff;
|
||||
autoref_freq1 |= (0x1c << 24);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_FREQ(1), autoref_freq1);
|
||||
}
|
||||
#endif
|
||||
#if SUB_PLATFORM_S8000
|
||||
if(dev_info->rev_id == 5) {
|
||||
dqvref_freq1 = 0x00ec00ec; // Maui
|
||||
dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ0, 1), dqvref_freq1);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ1, 1), dqvref_freq1);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case JEDEC_LPDDR4_MANUF_ID_HYNIX:
|
||||
#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003
|
||||
if(dev_info->rev_id == 3 && dev_info->rev_id2 == 2) {
|
||||
// <rdar://problem/21042636> tRFCpbCyc_freq1 = 0x1c for Hynix
|
||||
autoref_freq1 = DCS_REG_READ_CH(0, rDCS_MCU_AUTOREF_FREQ(1));
|
||||
autoref_freq1 &= 0x00ffffff;
|
||||
autoref_freq1 |= (0x1c << 24);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_FREQ(1), autoref_freq1);
|
||||
}
|
||||
#endif
|
||||
#if SUB_PLATFORM_S8000
|
||||
if(dev_info->rev_id == 3) {
|
||||
dqvref_freq1 = 0x00df00df; // Maui
|
||||
dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ0, 1), dqvref_freq1);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ1, 1), dqvref_freq1);
|
||||
}
|
||||
#endif
|
||||
|
||||
// <rdar://problem/18183851> Workarounds: Pull Up/Down shift for Maui Hynix 25nm
|
||||
if(dev_info->rev_id == 0x3) {
|
||||
// Test MRS Exit
|
||||
dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x0);
|
||||
|
||||
// Test MRS Entry
|
||||
dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0xb0);
|
||||
dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0xe0);
|
||||
dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x90);
|
||||
|
||||
if(dev_info->rev_id2 == 0x0) {
|
||||
// Rising Slew-rate up
|
||||
dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x87);
|
||||
|
||||
// Self-refresh OSC Min
|
||||
dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0xd0);
|
||||
dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x90);
|
||||
dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x86);
|
||||
dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x81);
|
||||
}
|
||||
|
||||
// For all SoCs that use this particular DRAM
|
||||
if(dev_info->rev_id2 <= 0x1) {
|
||||
// Pull Up RON shift
|
||||
dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0xc4);
|
||||
dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x90);
|
||||
dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x8e);
|
||||
dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x81);
|
||||
|
||||
// Pull Down RON shift
|
||||
dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0xc4);
|
||||
dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x94);
|
||||
dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x92);
|
||||
dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x81);
|
||||
|
||||
// ZQ calibration START MPC cmd
|
||||
dcs_mrcmd(MR_MPC, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x0, 0x4f);
|
||||
// wait 1us for tZQCAL
|
||||
dcs_spin(1, "Workarounds -- tZQCAL");
|
||||
|
||||
// ZQ calibration LATCH MPC cmd
|
||||
dcs_mrcmd(MR_MPC, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x0, 0x51);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case JEDEC_LPDDR4_MANUF_ID_MICRON:
|
||||
#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003
|
||||
if(dev_info->rev_id == 1 && dev_info->rev_id2 == 2) {
|
||||
// <rdar://problem/21042636> tRFCpbCyc_freq1 = 0x20 for Micron
|
||||
autoref_freq1 = DCS_REG_READ_CH(0, rDCS_MCU_AUTOREF_FREQ(1));
|
||||
autoref_freq1 &= 0x00ffffff;
|
||||
autoref_freq1 |= (0x20 << 24);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_FREQ(1), autoref_freq1);
|
||||
}
|
||||
#endif
|
||||
#if SUB_PLATFORM_S8000
|
||||
if(dev_info->rev_id == 1) {
|
||||
dqvref_freq1 = 0x00ea00ea; // Maui
|
||||
dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ0, 1), dqvref_freq1);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ1, 1), dqvref_freq1);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(dev_info->rev_id == 0x1) {
|
||||
// Test MRS Exit
|
||||
dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x0);
|
||||
|
||||
// <rdar://problem/20303861> Test MRS: Disable VREFDQ TAP code local latch
|
||||
dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0xf1);
|
||||
dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x9, 0x40);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003
|
||||
void dcs_dram_workarounds_step12 ( void )
|
||||
{
|
||||
|
||||
const struct dcs_memory_device_info *dev_info = dcs_get_memory_device_info();
|
||||
|
||||
if ( (dev_info->vendor_id == JEDEC_LPDDR4_MANUF_ID_SAMSUNG) && (dev_info->rev_id == 5) && (dev_info->rev_id2 == 1) )
|
||||
{
|
||||
|
||||
if((dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_C0) || (dcs_cfg.chipID == 0x8003 && dcs_cfg.chipRev >= CHIP_REVISION_A1) ||
|
||||
(dcs_cfg.chipID == 0x8001 && dcs_cfg.chipRev >= CHIP_REVISION_B0) )
|
||||
{
|
||||
dcs_mrcmd(MR_WRITE, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x0b, 0x34);
|
||||
dcs_mrcmd(MR_MPC, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x00, 0x4F);
|
||||
dcs_spin(1, "Workaround-Samsung--step-12-tzQCAL");
|
||||
dcs_mrcmd(MR_MPC, DCS_NUM_CHANNELS, DCS_NUM_RANKS, 0x00, 0x51);
|
||||
dcs_spin(1, "Workaround-Samsung--step-12-tZQLAT");
|
||||
dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL_FREQ(2, 0), 0xb303340b);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
//================================================================================
|
||||
// Grab (Platform Specific) Tables with Definitions of Values for DCS Init & DCS Tunables
|
||||
#include <platform/dcsconfig.h>
|
||||
|
||||
#if DCS_FIXUP_PARAMS
|
||||
// Grab (Target Specific) Definition of Required Fixups to the Values for DCS Init
|
||||
#include <target/dcsfixup.h>
|
||||
#endif
|
||||
|
||||
// use_dcs_params is already the same as dcs_params, unless we want to override with older chip-rev or target specific values
|
||||
void dcs_init_config_params(dcs_config_params_t *use_dcs_params, dcs_target_t targtype)
|
||||
{
|
||||
#if SUB_PLATFORM_S8000
|
||||
// Maui B0 DCS param table
|
||||
if(platform_get_chip_revision() < CHIP_REVISION_C0)
|
||||
memcpy(use_dcs_params, &dcs_params_b0, sizeof(dcs_config_params_t));
|
||||
#endif
|
||||
|
||||
#if DCS_FIXUP_PARAMS
|
||||
// This gives the particular target a chance to make target-specific changes
|
||||
dcs_init_config_fixup_params(use_dcs_params, targtype);
|
||||
#endif
|
||||
}
|
||||
|
||||
const dcs_tunable_t *dcs_init_tunable_table(uint32_t *table_len)
|
||||
{
|
||||
const dcs_tunable_t *tunables = dcs_tunables;
|
||||
uint32_t tunables_size = sizeof(dcs_tunables);
|
||||
|
||||
#if SUB_PLATFORM_S8000
|
||||
// Maui B0 DCS tunables
|
||||
if(platform_get_chip_revision() < CHIP_REVISION_C0) {
|
||||
tunables = dcs_tunables_b0;
|
||||
tunables_size = sizeof(dcs_tunables_b0);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (table_len)
|
||||
*table_len = tunables_size / sizeof(tunables[0]);
|
||||
|
||||
return tunables;
|
||||
}
|
||||
|
||||
void dcs_aop_ddr_to_awake_post_tunables_insert(void)
|
||||
{
|
||||
uint32_t i, num_tunables = 0;
|
||||
const dcs_tunable_t *tunables = NULL;
|
||||
uintptr_t curr_reg = 0;
|
||||
uint32_t reg_val = 0;
|
||||
|
||||
tunables = dcs_init_tunable_table(&num_tunables);
|
||||
|
||||
// At the time this function is called, tunables values are already expected to be programmed into the registers.
|
||||
// Expected format of the dcs_tunables table: Each field that has a tunable value is 1 entry in the tunables table
|
||||
for(i = 0; i < num_tunables; i++, tunables++) {
|
||||
|
||||
// end of table
|
||||
if(tunables->reg == 0)
|
||||
break;
|
||||
|
||||
// skip over subsequent tunables values for different fields in the same register, since we read out the entire register the first time
|
||||
if(tunables->reg == curr_reg)
|
||||
continue;
|
||||
|
||||
curr_reg = tunables->reg;
|
||||
|
||||
if(dcs_reg_is_outside_dcs_block(curr_reg)) {
|
||||
reg_val = DCS_REG_ACCESS(curr_reg);
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, curr_reg, reg_val, false);
|
||||
} else {
|
||||
// if reg is within DCS hw block, the reg is duplicated for each instance of the hw block, just read out 1st instance
|
||||
// and write that value for all instances
|
||||
reg_val = DCS_REG_READ_CH(0, curr_reg);
|
||||
|
||||
for(uint32_t channel = 0; channel < DCS_NUM_CHANNELS; channel++)
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, (curr_reg + (channel * DCS_SPACING)), reg_val, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003
|
||||
//================================================================================
|
||||
// Save off calibration results to AOP_SRAM region (later to be stitched into mcu_aop_awake_reconfig_restore sequence)
|
||||
// Order of registers to be saved matches the order in the reconfig sequence
|
||||
volatile uint32_t *dcs_save_calibration_results(volatile uint32_t *save_region, uint32_t freq)
|
||||
{
|
||||
uint32_t ch, n;
|
||||
|
||||
// Registers to be saved off after calibration in freq 1 has completed
|
||||
if (freq == DCS_FREQ(1)) {
|
||||
// CASDLLCTRL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
*save_region++ = DCS_REG_ACCESS(rAMP_CASDLLCTRL(ch));
|
||||
|
||||
// CSSDLLCTRL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
*save_region++ = DCS_REG_ACCESS(rAMP_CSSDLLCTRL(ch));
|
||||
|
||||
// CKSDLLCTRL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
*save_region++ = DCS_REG_ACCESS(rAMP_CKSDLLCTRL(ch));
|
||||
|
||||
// AMPCAWRLVLSDLLCODE
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
*save_region++ = DCS_REG_ACCESS(rAMP_CAWRLVLSDLLCODE(ch));
|
||||
|
||||
// CA_DESKEW_CTRL
|
||||
for(n = 0; n < CA_NUM_BITS; n++)
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
*save_region++ = DCS_REG_ACCESS(rAMP_CADESKEW_CTRL(ch, n));
|
||||
|
||||
// CS_DESKEW_CTRL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
*save_region++ = DCS_REG_ACCESS(rAMP_CSDESKEW_CTRL(ch));
|
||||
|
||||
// CK_DESKEW_CTRL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
*save_region++ = DCS_REG_ACCESS(rAMP_CKDESKEW_CTRL(ch));
|
||||
|
||||
// AMPWRLVLSDLLCODE0
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
*save_region++ = DCS_REG_ACCESS(rAMP_DQWRLVLSDLLCODE(0, ch));
|
||||
*save_region++ = DCS_REG_ACCESS(rAMP_DQWRLVLSDLLCODE(1, ch));
|
||||
}
|
||||
|
||||
// VREF_Fx
|
||||
for(n = 0; n < DCS_FREQUENCY_SLOTS; n++) {
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_VREF_F(AMP_DQ0, n));
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_VREF_F(AMP_DQ1, n));
|
||||
}
|
||||
}
|
||||
|
||||
// AUTOREF_FREQ1
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_MCU_AUTOREF_FREQ(1));
|
||||
|
||||
// CAMDLLVTSCALEREFCONTROL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_CAMDLL_VTSCALE_REFCNTL(AMP_DQ0));
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_CAMDLL_VTSCALE_REFCNTL(AMP_DQ1));
|
||||
}
|
||||
|
||||
// RDMDLLVTSCALEREFCONTROL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_RDMDLL_VTSCALE_REFCNTL(AMP_DQ0));
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_RDMDLL_VTSCALE_REFCNTL(AMP_DQ1));
|
||||
}
|
||||
|
||||
// WRMDLLVTSCALEREFCONTROL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_WRMDLL_VTSCALE_REFCNTL(AMP_DQ0));
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_WRMDLL_VTSCALE_REFCNTL(AMP_DQ1));
|
||||
}
|
||||
|
||||
// FREQCHNGCTL1_FREQ1
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_MCU_FREQCHNGCTL_FREQ(1, 1));
|
||||
|
||||
} else if (freq == DCS_FREQ(0)) {
|
||||
// Registers to be saved off after calibration in freq 0 has completed
|
||||
|
||||
// VREF_F0
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_VREF_F(AMP_DQ0, 0));
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_VREF_F(AMP_DQ1, 0));
|
||||
}
|
||||
|
||||
// FREQCHNGCTL1_FREQ0
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_MCU_FREQCHNGCTL_FREQ(1, 0));
|
||||
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_MCU_FREQCHNGCTL_FREQ(2, 0));
|
||||
} else if (freq == 0) {
|
||||
// <rdar://problem/23355941> Maui/Malta: Samsung DRAM workaround: disable hw zqcal
|
||||
// rGLBTIMER_ZQCTIMER
|
||||
*save_region++ = DCS_REG_ACCESS(rGLBTIMER_ZQCTIMER);
|
||||
}
|
||||
|
||||
return save_region;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Stitch the saved calibration results into the reconfig sequence
|
||||
// To be called immediately after stitching mcu_aop_awake_reconfig_pre_restore
|
||||
// Uses mcu_aop_awake_reconfig_restore as reference for register order and fields
|
||||
void dcs_restore_calibration_results(volatile uint32_t *save_region)
|
||||
{
|
||||
uint32_t ch, n, f;
|
||||
uint32_t reg_val;
|
||||
|
||||
// CASDLLCTRL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
reg_val = ((*save_region) & SDLLOVRVAL_MASK) | RUNSDLLUPDWRRESULT;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CASDLLCTRL(ch), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
|
||||
// CSSDLLCTRL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
reg_val = ((*save_region) & SDLLOVRVAL_MASK) | RUNSDLLUPDWRRESULT;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CSSDLLCTRL(ch), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
|
||||
// CKSDLLCTRL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
reg_val = ((*save_region) & SDLLOVRVAL_MASK) | RUNSDLLUPDWRRESULT;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CKSDLLCTRL(ch), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
|
||||
// AMPCAWRLVLSDLLCODE
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
reg_val = ((*save_region) & WRLVLSDLLCODE_MASK) | WRLVLRUNUPDWRRESULT;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CAWRLVLSDLLCODE(ch), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
|
||||
// Poll for AMPCAWRLVLSDLLCODE.WRLVLRUNUPDWRRESULT to clear
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
reconfig_command_read(AOP_DDR_AWAKE_POST, rAMP_CAWRLVLSDLLCODE(ch), 0, WRLVLRUNUPDWRRESULT, 0, false);
|
||||
|
||||
// CA_DESKEW_CTRL
|
||||
for(n = 0; n < CA_NUM_BITS; n++) {
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
reg_val = ((*save_region) & DESKEWCODE_MASK) | RUNDESKEWUPD;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CADESKEW_CTRL(ch, n), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
}
|
||||
|
||||
// CS_DESKEW_CTRL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
reg_val = ((*save_region) & DESKEWCODE_MASK) | RUNDESKEWUPD;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CSDESKEW_CTRL(ch), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
|
||||
// CK_DESKEW_CTRL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
reg_val = ((*save_region) & DESKEWCODE_MASK) | RUNDESKEWUPD;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CKDESKEW_CTRL(ch), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
|
||||
// AMPWRLVLSDLLCODE0
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
// for DQ0 and DQ1
|
||||
for(n = 0; n < 2; n++) {
|
||||
reg_val = ((*save_region) & WRLVLSDLLCODE_MASK) | WRLVLRUNUPDWRRESULT;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_DQWRLVLSDLLCODE(n, ch), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
}
|
||||
|
||||
// VREF_Fx
|
||||
for(f = 0; f < DCS_FREQUENCY_SLOTS; f++) {
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
// for DQ0 and DQ1
|
||||
for(n = AMP_DQ0; n < DCS_AMP_NUM_PHYS; n++) {
|
||||
reg_val = (*save_region) & (VREFSEL_MASK | DQSVREFSEL_MASK);
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMP_VREF_F(n, f) + (ch * DCS_SPACING), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AUTOREF_FREQ1
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
reg_val = *save_region;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_MCU_AUTOREF_FREQ(1) + (ch * DCS_SPACING), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
|
||||
// CAMDLLVTSCALEREFCONTROL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
// for DQ0 and DQ1: shift the status field value into the override field
|
||||
for(n = AMP_DQ0; n < DCS_AMP_NUM_PHYS; n++) {
|
||||
reg_val = (((*save_region) & VTSCALEREFSTATUS_MASK) << VTSCALEREFOVERRIDEVAL_SHIFT) | VTSCALEREFUPDATE;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMP_CAMDLL_VTSCALE_REFCNTL(n) + (ch * DCS_SPACING), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
}
|
||||
|
||||
// RDMDLLVTSCALEREFCONTROL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
// for DQ0 and DQ1: shift the status field value into the override field
|
||||
for(n = AMP_DQ0; n < DCS_AMP_NUM_PHYS; n++) {
|
||||
reg_val = (((*save_region) & VTSCALEREFSTATUS_MASK) << VTSCALEREFOVERRIDEVAL_SHIFT) | VTSCALEREFUPDATE;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMP_RDMDLL_VTSCALE_REFCNTL(n) + (ch * DCS_SPACING), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
}
|
||||
|
||||
// WRMDLLVTSCALEREFCONTROL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
// for DQ0 and DQ1: shift the status field value into the override field
|
||||
for(n = AMP_DQ0; n < DCS_AMP_NUM_PHYS; n++) {
|
||||
reg_val = (((*save_region) & VTSCALEREFSTATUS_MASK) << VTSCALEREFOVERRIDEVAL_SHIFT) | VTSCALEREFUPDATE;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMP_WRMDLL_VTSCALE_REFCNTL(n) + (ch * DCS_SPACING), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
}
|
||||
|
||||
// FREQCHNGCTL1_FREQ1
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
reg_val = *save_region;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_MCU_FREQCHNGCTL_FREQ(1, 1) + (ch * DCS_SPACING), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
|
||||
// The next set of registers were saved off after freq0 calibration completed
|
||||
|
||||
// VREF_F0
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
reg_val = *save_region;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMP_VREF_F(AMP_DQ0, 0) + (ch * DCS_SPACING), reg_val, false);
|
||||
save_region++;
|
||||
|
||||
reg_val = *save_region;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMP_VREF_F(AMP_DQ1, 0) + (ch * DCS_SPACING), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
|
||||
// FREQCHNGCTL1_FREQ0
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
reg_val = *save_region;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_MCU_FREQCHNGCTL_FREQ(1, 0) + (ch * DCS_SPACING), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
|
||||
// FREQCHNGCTL2_FREQ0
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
reg_val = *save_region;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_MCU_FREQCHNGCTL_FREQ(2, 0) + (ch * DCS_SPACING), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
|
||||
// <rdar://problem/23355941> Maui/Malta: Samsung DRAM workaround: disable hw zqcal
|
||||
// rGLBTIMER_ZQCTIMER
|
||||
reg_val = *save_region;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rGLBTIMER_ZQCTIMER, reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
#endif // #if SUB_PLATFORM_S8000 || SUB_PLATFORM_S8003
|
||||
|
||||
#if SUB_PLATFORM_S8001
|
||||
//================================================================================
|
||||
// Save off calibration results to AOP_SRAM region (later to be stitched into mcu_aop_awake_reconfig_restore sequence)
|
||||
// Order of registers to be saved matches the order in the reconfig sequence
|
||||
volatile uint32_t *dcs_save_calibration_results(volatile uint32_t *save_region, uint32_t freq)
|
||||
{
|
||||
uint32_t ch, n;
|
||||
|
||||
if(freq == DCS_FREQ(0)) {
|
||||
// CASDLLCTRL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
*save_region++ = DCS_REG_ACCESS(rAMP_CASDLLCTRL(ch));
|
||||
|
||||
// CSSDLLCTRL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
*save_region++ = DCS_REG_ACCESS(rAMP_CSSDLLCTRL(ch));
|
||||
|
||||
// CKSDLLCTRL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
*save_region++ = DCS_REG_ACCESS(rAMP_CKSDLLCTRL(ch));
|
||||
|
||||
// AMPCAWRLVLSDLLCODE
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
*save_region++ = DCS_REG_ACCESS(rAMP_CAWRLVLSDLLCODE(ch));
|
||||
|
||||
// CA_DESKEW_CTRL
|
||||
for(n = 0; n < CA_NUM_BITS; n++)
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
*save_region++ = DCS_REG_ACCESS(rAMP_CADESKEW_CTRL(ch, n));
|
||||
|
||||
// CS_DESKEW_CTRL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
*save_region++ = DCS_REG_ACCESS(rAMP_CSDESKEW_CTRL(ch));
|
||||
|
||||
// CK_DESKEW_CTRL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
*save_region++ = DCS_REG_ACCESS(rAMP_CKDESKEW_CTRL(ch));
|
||||
|
||||
// AMPWRLVLSDLLCODE0
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
*save_region++ = DCS_REG_ACCESS(rAMP_DQWRLVLSDLLCODE(0, ch));
|
||||
*save_region++ = DCS_REG_ACCESS(rAMP_DQWRLVLSDLLCODE(1, ch));
|
||||
}
|
||||
|
||||
// VREF_Fx
|
||||
for(n = 0; n < DCS_FREQUENCY_SLOTS; n++) {
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_VREF_F(AMP_DQ0, n));
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_VREF_F(AMP_DQ1, n));
|
||||
}
|
||||
}
|
||||
|
||||
// WRDQCALVREFCODESTATUS
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_WRDQCALVREFCODESTATUS);
|
||||
|
||||
// RDDQCALVREFCODESTATUS
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_RDDQCALVREFCODESTATUS);
|
||||
|
||||
// CAMDLLVTSCALEREFCONTROL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_CAMDLL_VTSCALE_REFCNTL(AMP_DQ0));
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_CAMDLL_VTSCALE_REFCNTL(AMP_DQ1));
|
||||
}
|
||||
|
||||
// RDMDLLVTSCALEREFCONTROL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_RDMDLL_VTSCALE_REFCNTL(AMP_DQ0));
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_RDMDLL_VTSCALE_REFCNTL(AMP_DQ1));
|
||||
}
|
||||
|
||||
// WRMDLLVTSCALEREFCONTROL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_WRMDLL_VTSCALE_REFCNTL(AMP_DQ0));
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_AMP_WRMDLL_VTSCALE_REFCNTL(AMP_DQ1));
|
||||
}
|
||||
|
||||
// FREQCHNGCTL1_FREQ0
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_MCU_FREQCHNGCTL_FREQ(1, 0));
|
||||
|
||||
// FREQCHNGCTL2_FREQ0
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_MCU_FREQCHNGCTL_FREQ(2, 0));
|
||||
|
||||
// FREQCHNGCTL2_FREQ3
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_MCU_FREQCHNGCTL_FREQ(2, 3));
|
||||
|
||||
// FREQCHNGCTL4_FREQ0
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
*save_region++ = DCS_REG_READ_CH(ch, rDCS_MCU_FREQCHNGCTL_FREQ(4, 0));
|
||||
|
||||
// CB_IMPCTL
|
||||
*save_region++ = DCS_REG_READ_CH(0, rDCS_AMPH_CB_IMPCTL);
|
||||
|
||||
// B0_ODT
|
||||
*save_region++ = DCS_REG_READ_CH(0, rDCS_AMPH_B0_ODT);
|
||||
|
||||
// B1_ODT
|
||||
*save_region++ = DCS_REG_READ_CH(0, rDCS_AMPH_B1_ODT);
|
||||
|
||||
// DQS0_ODT
|
||||
*save_region++ = DCS_REG_READ_CH(0, rDCS_AMPH_DQS0_ODT);
|
||||
|
||||
// DQS1_ODT
|
||||
*save_region++ = DCS_REG_READ_CH(0, rDCS_AMPH_DQS1_ODT);
|
||||
} else if(freq == 0) {
|
||||
// <rdar://problem/23244578> Elba: Samsung DRAM workaround: disable hw zqcal
|
||||
// rGLBTIMER_ZQCTIMER
|
||||
*save_region++ = DCS_REG_ACCESS(rGLBTIMER_ZQCTIMER);
|
||||
}
|
||||
|
||||
return save_region;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Stitch the saved calibration results into the reconfig sequence
|
||||
// To be called immediately after stitching mcu_aop_awake_reconfig_pre_restore
|
||||
// Uses mcu_aop_awake_reconfig_restore as reference for register order and fields
|
||||
void dcs_restore_calibration_results(volatile uint32_t *save_region)
|
||||
{
|
||||
uint32_t ch, n, f;
|
||||
uint32_t reg_val;
|
||||
|
||||
// CASDLLCTRL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
reg_val = ((*save_region) & SDLLOVRVAL_MASK) | RUNSDLLUPDWRRESULT;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CASDLLCTRL(ch), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
|
||||
// CSSDLLCTRL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
reg_val = ((*save_region) & SDLLOVRVAL_MASK) | RUNSDLLUPDWRRESULT;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CSSDLLCTRL(ch), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
|
||||
// CKSDLLCTRL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
reg_val = ((*save_region) & SDLLOVRVAL_MASK) | RUNSDLLUPDWRRESULT;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CKSDLLCTRL(ch), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
|
||||
// AMPCAWRLVLSDLLCODE
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
reg_val = ((*save_region) & WRLVLSDLLCODE_MASK) | WRLVLRUNUPDWRRESULT;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CAWRLVLSDLLCODE(ch), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
|
||||
// Poll for AMPCAWRLVLSDLLCODE.WRLVLRUNUPDWRRESULT to clear
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
reconfig_command_read(AOP_DDR_AWAKE_POST, rAMP_CAWRLVLSDLLCODE(ch), 0, WRLVLRUNUPDWRRESULT, 0, false);
|
||||
|
||||
// CA_DESKEW_CTRL
|
||||
for(n = 0; n < CA_NUM_BITS; n++) {
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
reg_val = ((*save_region) & DESKEWCODE_MASK) | RUNDESKEWUPD;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CADESKEW_CTRL(ch, n), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
}
|
||||
|
||||
// CS_DESKEW_CTRL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
reg_val = ((*save_region) & DESKEWCODE_MASK) | RUNDESKEWUPD;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CSDESKEW_CTRL(ch), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
|
||||
// CK_DESKEW_CTRL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
reg_val = ((*save_region) & DESKEWCODE_MASK) | RUNDESKEWUPD;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_CKDESKEW_CTRL(ch), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
|
||||
// AMPWRLVLSDLLCODE0
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
// for DQ0 and DQ1
|
||||
for(n = 0; n < 2; n++) {
|
||||
reg_val = ((*save_region) & WRLVLSDLLCODE_MASK) | WRLVLRUNUPDWRRESULT;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rAMP_DQWRLVLSDLLCODE(n, ch), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
}
|
||||
|
||||
// VREF_Fx
|
||||
for(f = 0; f < DCS_FREQUENCY_SLOTS; f++) {
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
// for DQ0 and DQ1
|
||||
for(n = AMP_DQ0; n < DCS_AMP_NUM_PHYS; n++) {
|
||||
reg_val = (*save_region) & (VREFSEL_MASK | DQSVREFSEL_MASK);
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMP_VREF_F(n, f) + (ch * DCS_SPACING), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WRDQCALVREFCODECONTROL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
reg_val = (*save_region);
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMP_WRDQCALVREFCODECONTROL + (ch * DCS_SPACING), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
|
||||
// RDDQCALVREFCODECONTROL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
reg_val = (*save_region);
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMP_RDDQCALVREFCODECONTROL + (ch * DCS_SPACING), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
|
||||
// CAMDLLVTSCALEREFCONTROL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
// for DQ0 and DQ1: shift the status field value into the override field
|
||||
for(n = AMP_DQ0; n < DCS_AMP_NUM_PHYS; n++) {
|
||||
reg_val = (((*save_region) & VTSCALEREFSTATUS_MASK) << VTSCALEREFOVERRIDEVAL_SHIFT) | VTSCALEREFUPDATE;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMP_CAMDLL_VTSCALE_REFCNTL(n) + (ch * DCS_SPACING), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
}
|
||||
|
||||
// RDMDLLVTSCALEREFCONTROL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
// for DQ0 and DQ1: shift the status field value into the override field
|
||||
for(n = AMP_DQ0; n < DCS_AMP_NUM_PHYS; n++) {
|
||||
reg_val = (((*save_region) & VTSCALEREFSTATUS_MASK) << VTSCALEREFOVERRIDEVAL_SHIFT) | VTSCALEREFUPDATE;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMP_RDMDLL_VTSCALE_REFCNTL(n) + (ch * DCS_SPACING), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
}
|
||||
|
||||
// WRMDLLVTSCALEREFCONTROL
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
// for DQ0 and DQ1: shift the status field value into the override field
|
||||
for(n = AMP_DQ0; n < DCS_AMP_NUM_PHYS; n++) {
|
||||
reg_val = (((*save_region) & VTSCALEREFSTATUS_MASK) << VTSCALEREFOVERRIDEVAL_SHIFT) | VTSCALEREFUPDATE;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMP_WRMDLL_VTSCALE_REFCNTL(n) + (ch * DCS_SPACING), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
}
|
||||
|
||||
// FREQCHNGCTL1_FREQ0
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
reg_val = *save_region;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_MCU_FREQCHNGCTL_FREQ(1, 0) + (ch * DCS_SPACING), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
|
||||
// FREQCHNGCTL2_FREQ0
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
reg_val = *save_region;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_MCU_FREQCHNGCTL_FREQ(2, 0) + (ch * DCS_SPACING), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
|
||||
// FREQCHNGCTL2_FREQ3
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
reg_val = *save_region;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_MCU_FREQCHNGCTL_FREQ(2, 3) + (ch * DCS_SPACING), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
|
||||
// <rdar://problem/23244578> Elba: Samsung DRAM workaround: disable hw zqcal
|
||||
// FREQCHNGCTL4_FREQ0
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++) {
|
||||
reg_val = *save_region;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_MCU_FREQCHNGCTL_FREQ(4, 0) + (ch * DCS_SPACING), reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
|
||||
// CB_IMPCTL
|
||||
reg_val = *save_region;
|
||||
save_region++;
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMPH_CB_IMPCTL + (ch * DCS_SPACING), reg_val, false);
|
||||
|
||||
// B0_ODT
|
||||
reg_val = *save_region;
|
||||
save_region++;
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMPH_B0_ODT + (ch * DCS_SPACING), reg_val, false);
|
||||
|
||||
// B1_ODT
|
||||
reg_val = *save_region;
|
||||
save_region++;
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMPH_B1_ODT + (ch * DCS_SPACING), reg_val, false);
|
||||
|
||||
// DQS0_ODT
|
||||
reg_val = *save_region;
|
||||
save_region++;
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMPH_DQS0_ODT + (ch * DCS_SPACING), reg_val, false);
|
||||
|
||||
// DQS1_ODT
|
||||
reg_val = *save_region;
|
||||
save_region++;
|
||||
for(ch = 0; ch < DCS_NUM_CHANNELS; ch++)
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rDCS_AMPH_DQS1_ODT + (ch * DCS_SPACING), reg_val, false);
|
||||
|
||||
// rGLBTIMER_ZQCTIMER
|
||||
reg_val = *save_region;
|
||||
reconfig_command_write(AOP_DDR_AWAKE_POST, rGLBTIMER_ZQCTIMER, reg_val, false);
|
||||
save_region++;
|
||||
}
|
||||
#endif // #if SUB_PLATFORM_S8001
|
||||
|
||||
@@ -0,0 +1,849 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This document is the property of Apple Inc.
|
||||
* It is considered confidential and proprietary.
|
||||
*
|
||||
* This document may not be reproduced or transmitted in any form,
|
||||
* in whole or in part, without the express written permission of
|
||||
* Apple Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Init Sequence Library for use in:
|
||||
* Driver for the LPDDR4 compatible DRAM Control Subsystem (DCS) block
|
||||
*/
|
||||
|
||||
/*
|
||||
Summary of Steps from the Spec (Spreadsheet)
|
||||
|
||||
+ (Aa) Steps 0,1,2,3a [need to identify parameterization]
|
||||
+ (Ab) Step 3b [PMGR: set Freq to 50MHz & delay-wait]
|
||||
+ (Ac) Steps 3c,4,5 [need to identify parameterization]
|
||||
+ (B) Step 6 [Change Clk Speed]
|
||||
+ (C) Step 7 [include delay-wait from early Step 8]
|
||||
+ (D) Step 8a [Cal: CA 800MHz Vmin]
|
||||
+ (E) Step 8b [Write Regs]
|
||||
+ (F) Step 8c [Cal: CA 800MHz Vmin] (...again? should it be CS?)
|
||||
+ (G) Step 8d [Write Regs]
|
||||
+ (H) Step 9 [Write Regs]
|
||||
+ (I) Step 10 [Cal: WrLvl, RdDq, WrDq 800MHz Vmin]
|
||||
+ (J) Step 11 [Write Regs]
|
||||
+ (K) Step 12 [Cal: CA 1200MHz Vnom]
|
||||
+ (L) Step 13 [Write Regs]
|
||||
+ (M) Step 14 [Cal: WrLvl, RdDq, WrDq 1200MHz Vmin]
|
||||
+ (N) Steps 15,16,17,18,19,20 [need to identify parameterization]
|
||||
|
||||
Between these steps there is possibly a need/desire for:
|
||||
- Frequency Changes (PMGR)
|
||||
- PMU save/restore
|
||||
- debug messages
|
||||
- register dumps (DV, SiVal)
|
||||
- anything else!
|
||||
|
||||
CONFIG Table:
|
||||
Compile-Time Known:
|
||||
Type of Execution Environment CoreOS, DV, SiVal
|
||||
Type of Target SoC, FPGA, Palladium
|
||||
ChipID 0x8000, 0x8001, etc.
|
||||
Revision A0, B0, B1, etc.
|
||||
Num DCS 4, 8, etc. (Derived...!)
|
||||
Variant Flags Work-arounds, RADAR Ref., et al.
|
||||
|
||||
(Config Info know at Compile time can be subject to #if)
|
||||
|
||||
Run-Time Known:
|
||||
Type of Init ColdBoot, AOP_DDR, AOP_AWAKE
|
||||
Debug Flags Low-Level, Milestone, et al.
|
||||
|
||||
RegValue Table
|
||||
Much like today's: various values for various registers
|
||||
Sensitive to ChipID (also Target type?)
|
||||
(Internal static alloc (Complete Table Fill-in within Init function):
|
||||
Fill in Values (per ChipID/Rev & Target-type)
|
||||
return pointer to caller
|
||||
(Allows customization by caller before use)
|
||||
|
||||
TODO:
|
||||
- Convert to using SPDS for register names, et al
|
||||
|
||||
*/
|
||||
|
||||
//================================================================================
|
||||
// API Definitions
|
||||
#include <drivers/dcs/dcs_init_lib.h>
|
||||
extern dcs_config_t dcs_cfg;
|
||||
extern dcs_config_params_t dcs_params;
|
||||
|
||||
#if izIBOOT
|
||||
extern int debug_level_dcs;
|
||||
#endif
|
||||
|
||||
void dcs_enable_autorefresh(void)
|
||||
{
|
||||
uint32_t arefen_freq0 = 0x1111013f;
|
||||
uint32_t arefen_freq1 = 0x11110000;
|
||||
uint32_t arefen_freq2 = 0x11000000;
|
||||
uint32_t arefen_freq3 = 0x11100000;
|
||||
|
||||
if(dcs_cfg.chipRev < CHIP_REVISION_C0) {
|
||||
arefen_freq0 = 0x1011013f;
|
||||
arefen_freq1 = 0x10110000;
|
||||
arefen_freq2 = 0x10000000;
|
||||
arefen_freq3 = 0x10100000;
|
||||
}
|
||||
|
||||
// Configure auto-refresh. Freq0 has the auto-refresh enable, so do it last.
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(3), arefen_freq3);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(2), arefen_freq2);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(1), arefen_freq1);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(0), arefen_freq0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//================================================================================
|
||||
// Implementing the Various Steps of the DCS Init, per Specification
|
||||
// Based on AMC Init Spec (Spreadsheet)
|
||||
// - Supporting Maui: Spec (v??)
|
||||
//================================================================================
|
||||
// Step 0: AMC Prolog
|
||||
//================================================================================
|
||||
void dcs_init_Prolog(void)
|
||||
{
|
||||
// NOTE: between the Compiler and the Optimization, this should vanish for non-FPGA builds
|
||||
if (izFPGA && izColdBoot) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DRAM_RESETN(AMP_CA), 1);
|
||||
delay_for_us(200);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DRAM_RESETN(AMP_CA), 0);
|
||||
delay_for_us(200);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DRAM_RESETN(AMP_CA), 1);
|
||||
delay_for_us(200);
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 1: AMC Initial Configuration
|
||||
//================================================================================
|
||||
void dcs_init_AMC_Initial_Config(void)
|
||||
{
|
||||
uint32_t i,n;
|
||||
|
||||
// rdar://problem/19137387: this applies to Maui A1 and B0, as well as other SoCs before Cayman
|
||||
|
||||
dcs_reg_write(rAMCC_MCCCHNLDEC_ADDR, dcs_params.chnldec);
|
||||
dcs_reg_write_all_chan(rDCS_SPLLCTRL_CHARGEPUMP, 0x00000068);
|
||||
dcs_reg_write_all_chan(rDCS_SPLLCTRL_VCO, dcs_params.spllctrl_vco_1);
|
||||
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_SPLLCTRL_VCO, dcs_params.spllctrl_vco_2);
|
||||
dcs_reg_write_all_chan(rDCS_SPLLCTRL_LDO, 0x00000004);
|
||||
|
||||
// This register write to be skipped for Maui A0/A1, but written to for B0 & later, and all other SoCs
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0))
|
||||
dcs_reg_write_all_chan(rDCS_SPLLCTRL_SPLLPWRDNCFG, 0x00000011);
|
||||
|
||||
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) {
|
||||
for (n = 0; n < dcs_params.num_freqchngctl_regs; n++)
|
||||
dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL_FREQ(n, i), dcs_params.freq[i].freqchngctl[n]);
|
||||
|
||||
// This register write to be skipped for Maui A0/A1, but written to for B0 & later, and all other SoCs
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0))
|
||||
dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGTIM_FREQ(i), dcs_params.freq[i].freqchngtim);
|
||||
}
|
||||
|
||||
if (dcs_cfg.chipRev < CHIP_REVISION_C0)
|
||||
dcs_reg_write_all_chan(rDCS_MCU_RWCFG, dcs_params.rwcfg);
|
||||
|
||||
for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTCTRL(i), dcs_params.dllupdtctrl);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_MCU_LAT_FREQ(0), dcs_params.freq[0].lat);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_LAT_FREQ(1), dcs_params.freq[1].lat);
|
||||
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_MCU_PHYRDWRTIM_FREQ(i), dcs_params.freq[i].phyrdwrtim);
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) {
|
||||
dcs_reg_write_all_chan(rDCS_MCU_CASPCH_FREQ(i), dcs_params.freq[i].caspch);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_ACT_FREQ(i), dcs_params.freq[i].act);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_FREQ(i), dcs_params.freq[i].autoref);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_SELFREF_FREQ(i), dcs_params.freq[i].selfref);
|
||||
|
||||
if (i == 0) dcs_reg_write_all_chan(rDCS_MCU_MODEREG, dcs_params.modereg);
|
||||
|
||||
}
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_PARAMS, dcs_params.autoref_params);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_PDN, dcs_params.pdn);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_DERATE_FREQ(0), dcs_params.freq[0].derate);
|
||||
|
||||
// These register writes to be skipped for Maui A0/A1, but written to for B0 & later, and all other SoCs
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0))
|
||||
for(i = 1; i < DCS_FREQUENCY_SLOTS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_MCU_DERATE_FREQ(i), dcs_params.freq[i].derate);
|
||||
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_MCU_LAT_FREQ(i), dcs_params.freq[i].lat2);
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_MCU_TAT_FREQ(i), dcs_params.freq[i].tat);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_RNKCFG, dcs_params.rnkcfg);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_MIFQMAXCTRL_FREQ(0), dcs_params.freq[0].mifqmaxctrl);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_MIFQMAXCTRL_FREQ(3), dcs_params.freq[3].mifqmaxctrl);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTEN, 0);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, 0x00002000);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AMCCTRL, 0x00000002);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_MCPHYUPDTPARAM, 0x15030000);
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 2: AMP Initial Configuration
|
||||
//================================================================================
|
||||
void dcs_init_AMP_Initial_Config(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_AMPEN(i), 0x00000001);
|
||||
|
||||
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_NONDQDSPD_F(i), dcs_params.freq[i].nondqdspd);
|
||||
|
||||
for(i = 1; i < DCS_FREQUENCY_SLOTS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_NONDQDS_F(i), dcs_params.freq[i].nondqds);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_CACKCSWKDS, dcs_params.cackcswkds);
|
||||
|
||||
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_CA, i), dcs_params.freq[i].cavref);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_ODTENABLE_F(0), dcs_params.freq[0].odt_enable);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_ODTENABLE_F(1), dcs_params.freq[1].odt_enable);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_ODTENABLE_F(3), dcs_params.freq[3].odt_enable);
|
||||
|
||||
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) {
|
||||
// These register writes to be skipped for Maui A0/A1
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQDS_F(AMP_DQ0,i), dcs_params.freq[i].dqds);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQDS_F(AMP_DQ1,i), dcs_params.freq[i].dqds);
|
||||
}
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQDQSDS_F(AMP_DQ0,i), dcs_params.freq[i].dqdqsds);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQDQSDS_F(AMP_DQ1,i), dcs_params.freq[i].dqdqsds);
|
||||
}
|
||||
|
||||
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ0, i), dcs_params.freq[i].dqvref);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ1, i), dcs_params.freq[i].dqvref);
|
||||
}
|
||||
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQSPDRES(AMP_DQ0), dcs_params.dqspdres);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQSPDRES(AMP_DQ1), dcs_params.dqspdres);
|
||||
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_CNTL(AMP_CA), dcs_params.casdllupdatectrl);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_CNTL(AMP_DQ0), dcs_params.dqsdllupdatectrl);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_CNTL(AMP_DQ1), dcs_params.dqsdllupdatectrl);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DIFFMODE_FREQ(AMP_DQ0, 3), 0x1);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DIFFMODE_FREQ(AMP_DQ1, 3), 0x1);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step2);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step2);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step2 & 0x7, 0x0);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step2 & 0x7, 0x0);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ0), dcs_params.wrdqdqssdllctrl_step2);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ1), dcs_params.wrdqdqssdllctrl_step2);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ0), dcs_params.wrdqdqssdllctrl_step2 & 0x7, 0x0);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ1), dcs_params.wrdqdqssdllctrl_step2 & 0x7, 0x0);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, dcs_params.cawrlvlsdllcode);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, dcs_params.cawrlvlsdllcode & 0x300, 0x000);
|
||||
|
||||
if (!izFPGA)
|
||||
for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DLLLOCKTIM(i), dcs_params.dlllocktim);
|
||||
|
||||
if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQSPDENALWYSON(AMP_DQ0), 0x00000001);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQSPDENALWYSON(AMP_DQ1), 0x00000001);
|
||||
}
|
||||
|
||||
if((dcs_params.supported_freqs & DCS_FREQ(1)) != 0)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DFICALTIMING, dcs_params.dficaltiming);
|
||||
|
||||
|
||||
// These register writes to be skipped for Maui A0/A1
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) {
|
||||
for(i = 1; i < DCS_FREQUENCY_SLOTS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMPCA_DFICALTIMING_F(i), dcs_params.freq[i].cadficaltiming);
|
||||
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) {
|
||||
dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ0, i), dcs_params.freq[i].dqdficaltiming);
|
||||
dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ1, i), dcs_params.freq[i].dqdficaltiming);
|
||||
}
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_MDLLCODE_CAP_CNTL(AMP_DQ0), 0x00000002);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_MDLLCODE_CAP_CNTL(AMP_DQ1), 0x00000002);
|
||||
|
||||
}
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALTIMING_F(0), dcs_params.rdwrdqcaltiming_f0);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALSEGLEN_F(0), dcs_params.rdwrdqcalseglen_f0);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALTIMING_F(1), dcs_params.rdwrdqcaltiming_f1);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALSEGLEN_F(1), dcs_params.rdwrdqcalseglen_f1);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALTIMINGCTRL(1), dcs_params.rdwrdqcaltimingctrl1);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALTIMINGCTRL(2), dcs_params.rdwrdqcaltimingctrl2);
|
||||
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWRDDQCALPATPRBS4I, dcs_params.rddqcalpatprbs4i);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATPRBS4I, dcs_params.wrdqcalpatprbs4i);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDDQCALWINDOW_F(0), dcs_params.freq[0].rddqcalwindow);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_WRDQCALWINDOW_F(0), dcs_params.freq[0].wrdqcalwindow);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDDQCALWINDOW_F(1), dcs_params.freq[1].rddqcalwindow);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_WRDQCALWINDOW_F(1), dcs_params.freq[1].wrdqcalwindow);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_MAXWRDQS_SDLL_MULFACTOR, dcs_params.maxwrdqssdllmulfactor);
|
||||
|
||||
// These register writes to be skipped for Maui A0/A1
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) {
|
||||
dcs_reg_write_all_chan(rDCS_AMPDQ_RDDQSMULFACTOR(AMP_DQ0), 0x20181000);
|
||||
dcs_reg_write_all_chan(rDCS_AMPDQ_RDDQSMULFACTOR(AMP_DQ1), 0x20181000);
|
||||
}
|
||||
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_CAOUTDLLSCL_FREQ(i), dcs_params.freq[i].caoutdllscl);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQSINDLLSCL_FREQ(AMP_DQ0, i), dcs_params.freq[i].dqsindllscl);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQSINDLLSCL_FREQ(AMP_DQ1, i), dcs_params.freq[i].dqsindllscl);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDCAPCFG_FREQ(AMP_DQ0, i), dcs_params.freq[i].rdcapcfg);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDCAPCFG_FREQ(AMP_DQ1, i), dcs_params.freq[i].rdcapcfg);
|
||||
}
|
||||
|
||||
if (!izFPGA) {
|
||||
for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTCTRL(i), dcs_params.dllupdtctrl1);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_IMPAUTOCAL, 0x00010000);
|
||||
}
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTINTVL(AMP_CA), dcs_params.dllupdtintvl);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTINTVL(AMP_DQ0), dcs_params.dllupdtintvl);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTINTVL(AMP_DQ1), dcs_params.dllupdtintvl);
|
||||
|
||||
|
||||
for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DLLEN(i), 0x00000100);
|
||||
|
||||
if(!izFPGA)
|
||||
{
|
||||
dcs_reg_write_all_chan(rDCS_AMP_IMPCALCMD, 0x00000000);
|
||||
}
|
||||
|
||||
|
||||
// Workaround for Maui B0
|
||||
if((dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0))
|
||||
dcs_reg_write_all_chan(rDCS_AMP_BISTRXMODE, 0x0000001c);
|
||||
// AMPH configuration
|
||||
|
||||
if(dcs_cfg.chipRev >= CHIP_REVISION_B0)
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_SLC_REG(0), 0x0000003f);
|
||||
|
||||
for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_AMPINIT(i), 0x00000001);
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 3: Self-Refresh Exit
|
||||
//================================================================================
|
||||
void dcs_init_Self_Refresh_Exit_a(void)
|
||||
{
|
||||
// Wait 5 us after Impedence Calibration to avoid McPhyPending
|
||||
// preventing the SRFSM from exiting SR.
|
||||
dcs_spin(5, "after Imp. Cal.");
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AREFPARAM, dcs_params.arefparam);
|
||||
|
||||
for(int i = 0; i < DCS_FREQUENCY_SLOTS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_FREQ(i), dcs_params.freq[i].autoref2);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_PARAMS, dcs_params.autoref_params2);
|
||||
|
||||
if(izFPGA)
|
||||
if(dcs_cfg.chipRev < CHIP_REVISION_B0)
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_PARAMS, dcs_params.autoref_params);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_LONGSR, dcs_params.longsr);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_MCPHYUPDTPARAM, 0x15030007);
|
||||
|
||||
}
|
||||
|
||||
//========================================
|
||||
// Caller Code should:
|
||||
// - Change Frequency to 50MHz
|
||||
//========================================
|
||||
|
||||
void dcs_init_Self_Refresh_Exit_b(void)
|
||||
{
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AMCCTRL, 0x00000003);
|
||||
|
||||
if (!izFPGA) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_IMPCALCMD, 0x00000001);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_IMPCALCMD, 0x01, 0x00);
|
||||
}
|
||||
|
||||
if (izResume)
|
||||
dcs_enable_autorefresh();
|
||||
|
||||
dcs_spin(2200, "After Enable Auto-Refresh");
|
||||
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) {
|
||||
dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, dcs_params.freqchngctl_step3);
|
||||
dcs_reg_poll_all_chan(rDCS_MCU_FREQCHNGCTL, 0x10000, 0x00000);
|
||||
dcs_spin(2, "After SoC Update");
|
||||
}
|
||||
|
||||
// Resume-Boot and Cold-Boot use different Exit commands for Self-Refresh
|
||||
// Issue self-refresh exit cmd for resume boot with MPC
|
||||
int n = (izColdBoot)? 0x00000000:0x00004000;
|
||||
// Issue self-refresh exit cmd for resume boot with MPC
|
||||
dcs_reg_write_all_chan(rDCS_MCU_MRINITCMD_0, n);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_MRINITCMD_0, n | 0x1);
|
||||
dcs_reg_poll_all_chan(rDCS_MCU_MRINITCMD_0, 0x01, 0x00);
|
||||
|
||||
dcs_spin(2, NULL);
|
||||
|
||||
dcs_reg_write(rGLBTIMER_CHEN, (1 << dcs_cfg.num_dcs) - 1);
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 4: DRAM Reset, ZQ Calibration & Configuration (cold boot only)
|
||||
//================================================================================
|
||||
void dcs_init_ZQ_Cal_Cfg(void)
|
||||
{
|
||||
// ZQ calibration START MPC cmd
|
||||
dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0, 0x4f);
|
||||
// wait 1us for tZQCAL
|
||||
dcs_spin(1, "tZQCAL");
|
||||
|
||||
// ZQ calibration LATCH MPC cmd
|
||||
dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0, 0x51);
|
||||
// wait 10ns for tZQLAT
|
||||
dcs_spin(1, "tZQLAT");
|
||||
|
||||
if (izColdBoot) {
|
||||
// MR2 register (read/write latency)
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x2, 0x0);
|
||||
// MR1 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x1, 0x8e);
|
||||
// MR3 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x3, dcs_params.mr3cmd);
|
||||
// MR22 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x16, 0x0);
|
||||
// MR11 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xb, 0x0);
|
||||
// MR13 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xd, dcs_params.mr13cmd);
|
||||
// MR12 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xc, 0x59);
|
||||
// MR14 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xe, 0x59);
|
||||
|
||||
// MR23 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x17, 0x80);
|
||||
|
||||
uint32_t patinvertmask = (DCS_REG_READ_CH(0, rDCS_AMP_HWRDDQCALPATPRBS4I) >> 16) & 0xffff;
|
||||
uint32_t prbs = DCS_REG_READ_CH(0, rDCS_AMP_HWWRDQCALPATPRBS4I);
|
||||
|
||||
// MR15 register
|
||||
dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xf, patinvertmask & 0xff);
|
||||
// MR20 register
|
||||
dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x14, (patinvertmask >> 8) & 0xff);
|
||||
// MR32 register
|
||||
dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x20, prbs & 0xff);
|
||||
// MR40 register
|
||||
dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x28, (prbs >> 8) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 5a: AddrConfig Configuration
|
||||
//================================================================================
|
||||
void dcs_init_AddrCfg_Cfg(void)
|
||||
{
|
||||
dcs_reg_write(rAMCC_ADDRCFG_ADDR, dcs_params.addrcfg);
|
||||
}
|
||||
|
||||
//========================================
|
||||
// Caller Code should:
|
||||
// - Use MR Cmds to Query the Device
|
||||
//========================================
|
||||
|
||||
//================================================================================
|
||||
// Step 5b: Total Mem Size Config
|
||||
//================================================================================
|
||||
void dcs_init_TotalSize_Cfg(uint32_t total_size_Mbytes)
|
||||
{
|
||||
dbgprintf(DCS_DBG_ASSESS_CONFIG, "Memory_size: %llu bytes\n",
|
||||
(((uint64_t)total_size_Mbytes) * MEG * NUM_AMCCS));
|
||||
// (Units of 128 MBs in the register)
|
||||
dcs_reg_write(rAMCC_DRAMACCCTRL_ADDR, ((total_size_Mbytes / NUM_AMCCS) / DCS_NUM_MEG_IN_DRAM_BLK) - 1);
|
||||
dcs_reg_write(rAMCC_MCCCHNLDEC_ADDR, dcs_params.chnldec);
|
||||
|
||||
dbgprintf(DCS_DBG_ASSESS_CONFIG, "rAMCC_DRAMACCCTRL: 0x%08x\n", rAMCC_DRAMACCCTRL);
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 6: Switch from boot-clock speed to normal operation speed
|
||||
//================================================================================
|
||||
void dcs_init_Reenable_AMC_Scheduler(void)
|
||||
{
|
||||
// Wait 5 us before freq change to make sure all refreshes have been flushed
|
||||
dcs_spin(5, "After Refresh");
|
||||
|
||||
// Enable (again) the AMC Scheduler
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AMCCTRL, 0x00000003);
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 7: Setup registers for CA calibration for bucket 1
|
||||
//================================================================================
|
||||
void dcs_init_CA_Cal_Setup_Freq1(void)
|
||||
{
|
||||
// MR13 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xd, dcs_params.mr13cmd_step7);
|
||||
|
||||
if (izColdBoot) {
|
||||
if (izFPGA) {
|
||||
// MR11 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xb, 0x00);
|
||||
} else {
|
||||
// MR2 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x2, 0x52);
|
||||
// MR1 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x1, 0xae);
|
||||
// MR3 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x3, dcs_params.mr3cmd_step7);
|
||||
// MR22 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x16, dcs_params.mr22cmd);
|
||||
// MR11 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xb, dcs_params.mr11cmd);
|
||||
// MR12 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xc, 0x11);
|
||||
// MR14 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xe, 0x11);
|
||||
}
|
||||
dcs_reg_write_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x00000200);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x0200, 0x0000);
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 8: AMP Dynamic CA Vref Timing Calibration at Vmin 800MHz
|
||||
//================================================================================
|
||||
void dcs_init_CA_Cal_Freq1(void)
|
||||
{
|
||||
// Nothing to be done at this step for cold boot
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 9: Setup registers for DQ calibration for bucket 1
|
||||
//================================================================================
|
||||
void dcs_init_DQ_Cal_Setup_Freq1_a(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (izColdBoot) {
|
||||
// MR13 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xd, dcs_params.mr13cmd_step9);
|
||||
}
|
||||
|
||||
dcs_spin(1, NULL);
|
||||
|
||||
if(izResume) {
|
||||
dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTEN, 0x00000002);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, 0x01008888);
|
||||
|
||||
for(i = AMP_DQ0 ; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(i), 0xFF00000C);
|
||||
for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_DEFER_EN(i), 0x00000000);
|
||||
for(i = AMP_DQ0; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_MDLLOVRRD(i), 0x00000000);
|
||||
}
|
||||
}
|
||||
|
||||
// Caller code should change frequency to bucket 1
|
||||
void dcs_init_DQ_Cal_Setup_Freq1_b(void)
|
||||
{
|
||||
if (izColdBoot) {
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) {
|
||||
dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, dcs_params.freqchngctl_step9);
|
||||
dcs_reg_poll_all_chan(rDCS_MCU_FREQCHNGCTL, 0x10000, 0x00000);
|
||||
|
||||
// Wait 2us for the soc update to finish
|
||||
dcs_spin(2, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 10: PHY write DQ calibration
|
||||
//================================================================================
|
||||
void dcs_init_wrdq_skew(void)
|
||||
{
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQSDQ_SKEWCTL(AMP_DQ0), 0x06000000);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQSDQ_SKEWCTL(AMP_DQ1), 0x06000000);
|
||||
}
|
||||
|
||||
void dcs_init_post_wrlvl(void)
|
||||
{
|
||||
if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ0), 0x00000010);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ1), 0x00000010);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 11: Setup registers for CA calibration for bucket 0
|
||||
//================================================================================
|
||||
void dcs_init_CA_Cal_Setup_Freq0(void)
|
||||
{
|
||||
if (izColdBoot) {
|
||||
|
||||
if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ0), 0x00000000);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ1), 0x00000000);
|
||||
}
|
||||
|
||||
// MR13 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, dcs_params.mr13cmd_step11);
|
||||
if (!izFPGA) {
|
||||
// MR2 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x02, dcs_params.mr2cmd_step11);
|
||||
// MR1 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x01, dcs_params.mr1cmd_step11);
|
||||
// MR3 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x03, dcs_params.mr3cmd_step11);
|
||||
}
|
||||
|
||||
// MR22 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x16, dcs_params.mr22cmd_step11);
|
||||
// MR11 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0b, (izFPGA) ? 0x00 : dcs_params.mr11cmd_step11);
|
||||
// MR12 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0c, dcs_params.mr12cmd_step11);
|
||||
// MR14 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0e, dcs_params.mr14cmd_step11);
|
||||
|
||||
if((dcs_params.supported_freqs & DCS_FREQ(1)) == 0) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x00000200);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x200, 0x000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 12: AMP Dynamic CA Timing Calibration
|
||||
//================================================================================
|
||||
|
||||
//================================================================================
|
||||
// Step 13: Setup registers for DQ calibration for bucket 0
|
||||
//================================================================================
|
||||
void dcs_init_DQ_Cal_Setup_Freq0_a(void)
|
||||
{
|
||||
if (izColdBoot) {
|
||||
// MR13 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, dcs_params.mr13cmd_step13);
|
||||
|
||||
// Wait 1 us
|
||||
dcs_spin(1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void dcs_init_DQ_Cal_Setup_Freq0_b(void)
|
||||
{
|
||||
if (izColdBoot) {
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) {
|
||||
dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, 0x00010000);
|
||||
dcs_reg_poll_all_chan(rDCS_MCU_FREQCHNGCTL, 0x10000, 0x00000);
|
||||
|
||||
// Wait 2us for the soc update to finish
|
||||
dcs_spin(2, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 14: AMP Dynamic DQ Calibration
|
||||
//================================================================================
|
||||
|
||||
//================================================================================
|
||||
// Step 15: Setup Registers for Boot
|
||||
//================================================================================
|
||||
void dcs_init_Reg_for_Boot(void)
|
||||
{
|
||||
|
||||
if((dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0))
|
||||
dcs_reg_write_all_chan(rDCS_AMP_BISTRXMODE, 0x00000000);
|
||||
|
||||
if(dcs_cfg.chipRev >= CHIP_REVISION_C0)
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_SLC_REG(0), 0x0000013f);
|
||||
|
||||
#ifndef DCS_RUN_AT_50MHZ
|
||||
if (izColdBoot) {
|
||||
// MR13 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, dcs_params.mr13cmd_step15);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(izFPGA && !(dcs_params.supported_freqs & DCS_FREQ(1)))
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, 0x50);
|
||||
|
||||
// Wait 1 us
|
||||
dcs_spin(1, NULL);
|
||||
|
||||
if (izColdBoot) {
|
||||
dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, dcs_params.freqchngctl_step15);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ0), 0xff000008);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ1), 0xff000008);
|
||||
|
||||
#if !DCS_DO_CALIBRATION
|
||||
// skip these for all silicon targets, where calibration is performed, also skip for any Maui A1 target
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step15);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step15);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step15 & 0x7, 0x0);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step15 & 0x7, 0x0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALFULLSCANEN, 0x00000000);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALFULLSCANEN, 0x00000003);
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 16: Enable Other Features
|
||||
//================================================================================
|
||||
void dcs_init_MoreFeatures(void)
|
||||
{
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AREFPARAM, dcs_params.arefparam);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc2);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_QBREN, dcs_params.qbren_step16);
|
||||
|
||||
if (izColdBoot)
|
||||
dcs_enable_autorefresh();
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 17: Enable Fast Critical Word Forwarding Feature
|
||||
//================================================================================
|
||||
void dcs_init_Fast_Critical_Word_Forwarding(void)
|
||||
{
|
||||
dcs_reg_write_all_chan(rDCS_MCU_QBRPARAM, dcs_params.qbrparam);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_QBREN, dcs_params.qbren);
|
||||
|
||||
dcs_reg_poll(rAMCC_MCCPWRONWAYCNTSTATUS_ADDR, 0x7fff7fff, 0x42104210);
|
||||
dcs_reg_write(rAMCC_MCC0QPROPCTRL_ADDR, 0x300011a2);
|
||||
dcs_reg_write(rAMCC_MCC1QPROPCTRL_ADDR, 0x300011a2);
|
||||
dcs_reg_write(rAMCC_MCCGEN_ADDR, dcs_params.mccgen);
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 18: Enable Power- and Clock-Gating Features; Config MCC and Global Timers
|
||||
//================================================================================
|
||||
void dcs_init_Gating_Global_Timers(void)
|
||||
{
|
||||
const struct dcs_memory_device_info *dev_info = dcs_get_memory_device_info();
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_AMPCLK(AMP_CA), dcs_params.caampclk);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_AMPCLK(AMP_DQ0), dcs_params.dqampclk);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_AMPCLK(AMP_DQ1), dcs_params.dqampclk);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTEN, dcs_params.pwrmngten);
|
||||
|
||||
if(!izFPGA) {
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTPARAM_FREQ(0), 0x01800000);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_PSQWQCTL1, 0x01640120);
|
||||
}
|
||||
|
||||
// Global Timer Setup
|
||||
|
||||
if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev < CHIP_REVISION_B0) {
|
||||
dcs_reg_write(rGLBTIMER_PMGRWAKEUPCFG, 0x0000ff);
|
||||
dcs_reg_write(rGLBTIMER_MDLLTIMER, 0x000bb8); // 3000
|
||||
dcs_reg_write(rGLBTIMER_MDLLVOLTRAMPTIMER, 0x00004b); // 75
|
||||
dcs_reg_write(rGLBTIMER_CTRLUPDMASKTIMER, 0x00000f); // 15
|
||||
dcs_reg_write(rGLBTIMER_RDCALTIMER, 0x2dc6c0); // 3000000
|
||||
dcs_reg_write(rGLBTIMER_WRCALTIMER, 0x2dc6c0); // 3000000
|
||||
dcs_reg_write(rGLBTIMER_ZQCTIMER, 0x3d0900); // 4000000
|
||||
dcs_reg_write(rGLBTIMER_PERCAL_FREQCHNGTIMER, 0x000001); // 300000
|
||||
dcs_reg_write(rGLBTIMER_VOLTRAMPTIMER, 0x000001); // 300000
|
||||
dcs_reg_write(rGLBTIMER_IMPCALTIMER, 0x002ee0); // 12000
|
||||
} else {
|
||||
dcs_reg_write(rGLBTIMER_PMGRWAKEUPCFG, 0x0000ff);
|
||||
dcs_reg_write(rGLBTIMER_PREFREQ2ALLBANKDLY(0), 0x01500150);
|
||||
dcs_reg_write(rGLBTIMER_PREFREQ2ALLBANKDLY(1), 0x01500150);
|
||||
dcs_reg_write(rGLBTIMER_PREFREQCHNG2FREQCHNGDLY(0), 0x02a002a0);
|
||||
dcs_reg_write(rGLBTIMER_PREFREQCHNG2FREQCHNGDLY(1), 0x02a002a0);
|
||||
|
||||
dcs_reg_write(rGLBTIMER_CAL2PREFREQCHNGDLY(0), 0x00900090);
|
||||
dcs_reg_write(rGLBTIMER_CAL2PREFREQCHNGDLY(1), 0x00900090);
|
||||
dcs_reg_write(rGLBTIMER_FREQCHNG2PSTCALDLY(0), 0x01200120);
|
||||
dcs_reg_write(rGLBTIMER_FREQCHNG2PSTCALDLY(1), 0x01200120);
|
||||
|
||||
dcs_reg_write(rGLBTIMER_MDLLTIMER, 0x000bb8); // 3000
|
||||
dcs_reg_write(rGLBTIMER_MDLLVOLTRAMPTIMER, 0x00004b); // 75
|
||||
dcs_reg_write(rGLBTIMER_CTRLUPDMASKTIMER, 0x00000f); // 15
|
||||
// skip IDTTIMER setup per spec
|
||||
//dcs_reg_write(rGLBTIMER_IDTTIMER, 0x007530); // 30000
|
||||
dcs_reg_write(rGLBTIMER_RDCALTIMER, 0x2dc6c0); // 3000000
|
||||
dcs_reg_write(rGLBTIMER_WRCALTIMER, 0x2dc6c0); // 3000000
|
||||
|
||||
// <rdar://problem/23355941> Maui/Malta: Samsung DRAM workaround: disable hw zqcal
|
||||
if(! ((dev_info->vendor_id == JEDEC_LPDDR4_MANUF_ID_SAMSUNG) && (dev_info->rev_id == 5) && (dev_info->rev_id2 <= 1)) )
|
||||
dcs_reg_write(rGLBTIMER_ZQCTIMER, 0x3d0900); // 4000000
|
||||
|
||||
dcs_reg_write(rGLBTIMER_PERCAL_FREQCHNGTIMER, 0x0493e0); //
|
||||
dcs_reg_write(rGLBTIMER_VOLTRAMPTIMER, 0x0493e0); //
|
||||
dcs_reg_write(rGLBTIMER_IMPCALTIMER, 0x002ee0); // 12000
|
||||
|
||||
dcs_reg_write(rGLBTIMER_VOLTRAMP2ALLBANKDLY(0), 0x00d800d8);
|
||||
dcs_reg_write(rGLBTIMER_VOLTRAMP2ALLBANKDLY(1), 0x00d800d8);
|
||||
dcs_reg_write(rGLBTIMER_ALLBANK2PMGRACKDLY(0), 0x00900090);
|
||||
dcs_reg_write(rGLBTIMER_ALLBANK2PMGRACKDLY(1), 0x00900090);
|
||||
}
|
||||
|
||||
// Dynamic Clk & Power Gating
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AMCCLKPWRGATE, 0x050a0000);
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 19: ODTS read & set interval for periodic MR4 on-die Temp sensor reading
|
||||
//================================================================================
|
||||
void dcs_init_ODTS(void)
|
||||
{
|
||||
uint8_t temp[16*8]; // Far more Channels/Ranks than we are likely ever to have/need
|
||||
// INSTEAD OF: uint8_t temp[dcs_cfg.num_dcs * dcs_cfg.num_rank];
|
||||
|
||||
// MR4 read to bring memory out of self-refresh
|
||||
dcs_mrcmd(MR_READ, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x4, (uintptr_t)temp);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc3);
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
@@ -0,0 +1,963 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This document is the property of Apple Inc.
|
||||
* It is considered confidential and proprietary.
|
||||
*
|
||||
* This document may not be reproduced or transmitted in any form,
|
||||
* in whole or in part, without the express written permission of
|
||||
* Apple Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Init Sequence Library for use in:
|
||||
* Driver for the LPDDR4 compatible DRAM Control Subsystem (DCS) block
|
||||
*/
|
||||
|
||||
/*
|
||||
Summary of Steps from the Spec (Spreadsheet)
|
||||
|
||||
+ (Aa) Steps 0,1,2,3a [need to identify parameterization]
|
||||
+ (Ab) Step 3b [PMGR: set Freq to 50MHz & delay-wait]
|
||||
+ (Ac) Steps 3c,4,5 [need to identify parameterization]
|
||||
+ (B) Step 6 [Change Clk Speed]
|
||||
+ (C) Step 7 [include delay-wait from early Step 8]
|
||||
+ (D) Step 8a [Cal: CA 800MHz Vmin]
|
||||
+ (E) Step 8b [Write Regs]
|
||||
+ (F) Step 8c [Cal: CA 800MHz Vmin] (...again? should it be CS?)
|
||||
+ (G) Step 8d [Write Regs]
|
||||
+ (H) Step 9 [Write Regs]
|
||||
+ (I) Step 10 [Cal: WrLvl, RdDq, WrDq 800MHz Vmin]
|
||||
+ (J) Step 11 [Write Regs]
|
||||
+ (K) Step 12 [Cal: CA 1200MHz Vnom]
|
||||
+ (L) Step 13 [Write Regs]
|
||||
+ (M) Step 14 [Cal: WrLvl, RdDq, WrDq 1200MHz Vmin]
|
||||
+ (N) Steps 15,16,17,18,19,20 [need to identify parameterization]
|
||||
|
||||
Between these steps there is possibly a need/desire for:
|
||||
- Frequency Changes (PMGR)
|
||||
- PMU save/restore
|
||||
- debug messages
|
||||
- register dumps (DV, SiVal)
|
||||
- anything else!
|
||||
|
||||
CONFIG Table:
|
||||
Compile-Time Known:
|
||||
Type of Execution Environment CoreOS, DV, SiVal
|
||||
Type of Target SoC, FPGA, Palladium
|
||||
ChipID 0x8000, 0x8001, etc.
|
||||
Revision A0, B0, B1, etc.
|
||||
Num DCS 4, 8, etc. (Derived...!)
|
||||
Variant Flags Work-arounds, RADAR Ref., et al.
|
||||
|
||||
(Config Info know at Compile time can be subject to #if)
|
||||
|
||||
Run-Time Known:
|
||||
Type of Init ColdBoot, AOP_DDR, AOP_AWAKE
|
||||
Debug Flags Low-Level, Milestone, et al.
|
||||
|
||||
RegValue Table
|
||||
Much like today's: various values for various registers
|
||||
Sensitive to ChipID (also Target type?)
|
||||
(Internal static alloc (Complete Table Fill-in within Init function):
|
||||
Fill in Values (per ChipID/Rev & Target-type)
|
||||
return pointer to caller
|
||||
(Allows customization by caller before use)
|
||||
|
||||
TODO:
|
||||
- Convert to using SPDS for register names, et al
|
||||
|
||||
*/
|
||||
|
||||
//================================================================================
|
||||
// API Definitions
|
||||
#include <drivers/dcs/dcs_init_lib.h>
|
||||
|
||||
extern dcs_config_t dcs_cfg;
|
||||
extern dcs_config_params_t dcs_params;
|
||||
|
||||
#if izIBOOT
|
||||
extern int debug_level_dcs;
|
||||
#endif
|
||||
|
||||
// <rdar://problem/23244578>: To track throughout the sequence whether we should apply the Samsung DRAM workarounds
|
||||
static bool apply_samsung_workaround = false;
|
||||
|
||||
void dcs_enable_autorefresh(void)
|
||||
{
|
||||
uint32_t arefen_freq0 = 0x1011013f;
|
||||
uint32_t arefen_freq1 = 0x10010000;
|
||||
|
||||
// Configure auto-refresh. Freq0 has the auto-refresh enable, so do it last.
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(3), 0x10100000);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(2), 0x10000000);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(1), arefen_freq1);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(0), arefen_freq0);
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Implementing the Various Steps of the DCS Init, per Specification
|
||||
// Based on AMC Init Spec (Spreadsheet)
|
||||
// - Supporting Maui: Spec (v??)
|
||||
//================================================================================
|
||||
// Step 0: AMC Prolog
|
||||
//================================================================================
|
||||
void dcs_init_Prolog(void)
|
||||
{
|
||||
// NOTE: between the Compiler and the Optimization, this should vanish for non-FPGA builds
|
||||
if (izFPGA && izColdBoot) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DRAM_RESETN(AMP_CA), 1);
|
||||
delay_for_us(200);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DRAM_RESETN(AMP_CA), 0);
|
||||
delay_for_us(200);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DRAM_RESETN(AMP_CA), 1);
|
||||
delay_for_us(200);
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 1: AMC Initial Configuration
|
||||
//================================================================================
|
||||
void dcs_init_AMC_Initial_Config(void)
|
||||
{
|
||||
uint32_t i,n;
|
||||
|
||||
// rdar://problem/19137387: this applies to Maui A1 and B0, as well as other SoCs before Cayman
|
||||
|
||||
dcs_reg_write(rAMCC_MCCCHNLDEC_ADDR, dcs_params.chnldec);
|
||||
#if NUM_AMCCS == 2
|
||||
dcs_reg_write(rAMCC1_MCCCHNLDEC_ADDR, dcs_params.chnldec);
|
||||
#endif
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_SPLLCTRL_CHARGEPUMP, 0x00000068);
|
||||
dcs_reg_write_all_chan(rDCS_SPLLCTRL_MODEREG, 0x1);
|
||||
dcs_reg_write_all_chan(rDCS_SPLLCTRL_VCO, dcs_params.spllctrl_vco_1);
|
||||
dcs_reg_write_all_chan(rDCS_SPLLCTRL_VCO, dcs_params.spllctrl_vco_2);
|
||||
dcs_reg_write_all_chan(rDCS_SPLLCTRL_LDO, 0x00000004);
|
||||
|
||||
// This register write to be skipped for Maui A0/A1, but written to for B0 & later, and all other SoCs
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0))
|
||||
dcs_reg_write_all_chan(rDCS_SPLLCTRL_SPLLPWRDNCFG, 0x00000011);
|
||||
|
||||
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) {
|
||||
for (n = 0; n < dcs_params.num_freqchngctl_regs; n++)
|
||||
dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL_FREQ(n, i), dcs_params.freq[i].freqchngctl[n]);
|
||||
|
||||
// This register write to be skipped for Maui A0/A1, but written to for B0 & later, and all other SoCs
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0))
|
||||
dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGTIM_FREQ(i), dcs_params.freq[i].freqchngtim);
|
||||
}
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_WRDQCALVREFCODECONTROL, dcs_params.wrdqcalvrefcodecontrol);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDDQCALVREFCODECONTROL, dcs_params.rddqcalvrefcodecontrol);
|
||||
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWRDDQCALVREFCONTROL, 0x01d0b060);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWRDDQCALVREFOFFSETCONTROL(1), 0x06040200);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWRDDQCALVREFOFFSETCONTROL(2), 0x00fafcfe);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALVREFCONTROL, 0x02200060);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALVREFOFFSETCONTROL(1), 0x06040200);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALVREFOFFSETCONTROL(2), 0x00fafcfe);
|
||||
dcs_reg_write(rGLBTIMER_PERVREFCALCFG, 0x00000003);
|
||||
dcs_reg_write(rGLBTIMER_VREFCNTRL, 0x00060006);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_MODEREG, 0x120c90b8);
|
||||
|
||||
if (dcs_cfg.chipRev < CHIP_REVISION_B0)
|
||||
{
|
||||
dcs_reg_write_all_chan(rDCS_MCU_RWCFG, dcs_params.rwcfg);
|
||||
}
|
||||
|
||||
for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTCTRL(i), dcs_params.dllupdtctrl);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_MCU_LAT_FREQ(0), dcs_params.freq[0].lat);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_LAT_FREQ(1), dcs_params.freq[1].lat);
|
||||
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_MCU_PHYRDWRTIM_FREQ(i), dcs_params.freq[i].phyrdwrtim);
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) {
|
||||
dcs_reg_write_all_chan(rDCS_MCU_CASPCH_FREQ(i), dcs_params.freq[i].caspch);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_ACT_FREQ(i), dcs_params.freq[i].act);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_FREQ(i), dcs_params.freq[i].autoref);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_SELFREF_FREQ(i), dcs_params.freq[i].selfref);
|
||||
|
||||
if (i == 0) dcs_reg_write_all_chan(rDCS_MCU_MODEREG, dcs_params.modereg);
|
||||
|
||||
}
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_PARAMS, dcs_params.autoref_params);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_PDN, dcs_params.pdn);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_DERATE_FREQ(0), dcs_params.freq[0].derate);
|
||||
|
||||
// These register writes to be skipped for Maui A0/A1, but written to for B0 & later, and all other SoCs
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0))
|
||||
for(i = 1; i < DCS_FREQUENCY_SLOTS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_MCU_DERATE_FREQ(i), dcs_params.freq[i].derate);
|
||||
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_MCU_LAT_FREQ(i), dcs_params.freq[i].lat2);
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_MCU_TAT_FREQ(i), dcs_params.freq[i].tat);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_RNKCFG, dcs_params.rnkcfg);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_MIFQMAXCTRL_FREQ(0), dcs_params.freq[0].mifqmaxctrl);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_MIFQMAXCTRL_FREQ(3), dcs_params.freq[3].mifqmaxctrl);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTEN, 0);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, 0x00002000);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AMCCTRL, 0x00000002);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_MCPHYUPDTPARAM, 0x15030000);
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 2: AMP Initial Configuration
|
||||
//================================================================================
|
||||
void dcs_init_AMP_Initial_Config(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (dcs_cfg.chipRev < CHIP_REVISION_B0)
|
||||
{
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPCK, 0x00003f3f);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPCS, 0x00003f3f);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPB0, 0x00003f3f);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPDQS0, 0x00003f3f);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPB1, 0x00003f3f);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPDQS1, 0x00003f3f);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPCA, 0x00003f3f);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPCK, 0x00013f3f);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPCS, 0x00013f3f);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPB0, 0x00013f3f);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPDQS0, 0x00013f3f);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPB1, 0x00013f3f);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPDQS1, 0x00013f3f);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DCC_BYPCA, 0x00013f3f);
|
||||
}
|
||||
|
||||
for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_AMPEN(i), 0x00000001);
|
||||
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_CA, i), dcs_params.freq[i].cavref);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_ODTENABLE_F(0), dcs_params.freq[0].odt_enable);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_ODTENABLE_F(1), dcs_params.freq[1].odt_enable);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_ODTENABLE_F(3), dcs_params.freq[3].odt_enable);
|
||||
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ0, i), dcs_params.freq[i].dqvref);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ1, i), dcs_params.freq[i].dqvref);
|
||||
}
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_CNTL(AMP_CA), dcs_params.casdllupdatectrl);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_CNTL(AMP_DQ0), dcs_params.dqsdllupdatectrl);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_CNTL(AMP_DQ1), dcs_params.dqsdllupdatectrl);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step2);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step2);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step2 & 0x7, 0x0);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step2 & 0x7, 0x0);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ0), dcs_params.wrdqdqssdllctrl_step2);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ1), dcs_params.wrdqdqssdllctrl_step2);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ0), dcs_params.wrdqdqssdllctrl_step2 & 0x7, 0x0);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ1), dcs_params.wrdqdqssdllctrl_step2 & 0x7, 0x0);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, dcs_params.cawrlvlsdllcode);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, dcs_params.cawrlvlsdllcode & 0x300, 0x000);
|
||||
|
||||
if (!izFPGA)
|
||||
for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DLLLOCKTIM(i), dcs_params.dlllocktim);
|
||||
|
||||
if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQSPDENALWYSON(AMP_DQ0), 0x00000001);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQSPDENALWYSON(AMP_DQ1), 0x00000001);
|
||||
}
|
||||
|
||||
if((dcs_params.supported_freqs & DCS_FREQ(1)) != 0)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DFICALTIMING, dcs_params.dficaltiming);
|
||||
|
||||
|
||||
if (dcs_cfg.chipRev < CHIP_REVISION_B0)
|
||||
{
|
||||
for(i = 1; i < DCS_FREQUENCY_SLOTS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMPCA_DFICALTIMING_F(i), dcs_params.freq[i].cadficaltiming);
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) {
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ0, i), dcs_params.freq[i].dqdficaltiming);
|
||||
dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ1, i), dcs_params.freq[i].dqdficaltiming);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dcs_reg_write_all_chan(rDCS_AMPCA_DFICALTIMING_F(1), 0x04000710);
|
||||
dcs_reg_write_all_chan(rDCS_AMPCA_DFICALTIMING_F(2), 0x04000710);
|
||||
dcs_reg_write_all_chan(rDCS_AMPCA_DFICALTIMING_F(3), 0x04000510);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ0, 0), 0x06020704);
|
||||
dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ0, 1), 0x04020702);
|
||||
dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ0, 2), 0x04020702);
|
||||
dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ0, 3), 0x04020504);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ1, 0), 0x06020704);
|
||||
dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ1, 1), 0x04020702);
|
||||
dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ1, 2), 0x04020702);
|
||||
dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ1, 3), 0x04020504);
|
||||
dcs_reg_write_all_chan(rDCS_AMPCA_DFICALTIMING_RDDQCAL2, 0x00000019);
|
||||
}
|
||||
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_MDLLCODE_CAP_CNTL(AMP_DQ0), 0x00000002);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_MDLLCODE_CAP_CNTL(AMP_DQ1), 0x00000002);
|
||||
|
||||
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALTIMING_F(0), dcs_params.rdwrdqcaltiming_f0);
|
||||
|
||||
if (dcs_cfg.chipRev < CHIP_REVISION_B0)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALSEGLEN_F(0), dcs_params.rdwrdqcalseglen_f0);
|
||||
else
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALSEGLEN_F(0), 0x00040008);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALTIMING_F(1), dcs_params.rdwrdqcaltiming_f1);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALSEGLEN_F(1), dcs_params.rdwrdqcalseglen_f1);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALTIMING_F(3), dcs_params.rdwrdqcaltiming_f3);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALTIMINGCTRL(1), dcs_params.rdwrdqcaltimingctrl1);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALTIMINGCTRL(2), dcs_params.rdwrdqcaltimingctrl2);
|
||||
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWRDDQCALPATPRBS4I, dcs_params.rddqcalpatprbs4i);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATPRBS4I, dcs_params.wrdqcalpatprbs4i);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATPRBS7(0), 0x87654321);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATPRBS7(1), 0xcdedcba9);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATPRBS7(2), 0x456789ab);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATPRBS7(3), 0x5fa63123);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATINVERTMASK, 0x55550000);
|
||||
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDDQCALWINDOW_F(0), dcs_params.freq[0].rddqcalwindow);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_WRDQCALWINDOW_F(0), dcs_params.freq[0].wrdqcalwindow);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDDQCALWINDOW_F(1), dcs_params.freq[1].rddqcalwindow);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_WRDQCALWINDOW_F(1), dcs_params.freq[1].wrdqcalwindow);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_MAXRDDQS_SDLL_MULFACTOR, dcs_params.maxrddqssdllmulfactor);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_MAXWRDQS_SDLL_MULFACTOR, dcs_params.maxwrdqssdllmulfactor);
|
||||
|
||||
// These register writes to be skipped for Maui A0/A1
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) {
|
||||
dcs_reg_write_all_chan(rDCS_AMPDQ_RDDQSMULFACTOR(AMP_DQ0), 0x20181000);
|
||||
dcs_reg_write_all_chan(rDCS_AMPDQ_RDDQSMULFACTOR(AMP_DQ1), 0x20181000);
|
||||
}
|
||||
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDCAPCFG_FREQ(AMP_DQ0, i), dcs_params.freq[i].rdcapcfg);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDCAPCFG_FREQ(AMP_DQ1, i), dcs_params.freq[i].rdcapcfg);
|
||||
}
|
||||
|
||||
if (!izFPGA) {
|
||||
for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTCTRL(i), dcs_params.dllupdtctrl1);
|
||||
}
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTINTVL(AMP_CA), dcs_params.dllupdtintvl);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTINTVL(AMP_DQ0), dcs_params.dllupdtintvl);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTINTVL(AMP_DQ1), dcs_params.dllupdtintvl);
|
||||
|
||||
for(i = AMP_DQ0 ; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DLLEN(i), 0x00000100);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DCCCONTROL, dcs_params.dcccontrol);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DCCTIMER, 0x00000190);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALDYNHALFCLKDLYCTRL, 0x00000001);
|
||||
|
||||
|
||||
// AMPH configuration
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_CB_WKPUPD, 0);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_CB_DRIVESTR, dcs_params.cbdrivestr);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_CB_IOCTL, dcs_params.cbioctl);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_CK_WKPUPD, 0);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_CK_ZDETBIASEN, 0);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_CK_DRIVESTR, dcs_params.ckdrivestr);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_CK_IOCTL, dcs_params.ckioctl);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B0_DRIVESTR, dcs_params.b0drivestr);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B0_WKPUPD, 0);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B0_IOCTL, dcs_params.b0ioctl);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B0_ODT, dcs_params.b0odt);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B0_ODTCTRL, dcs_params.b0odtctrl);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B1_DRIVESTR, dcs_params.b1drivestr);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B1_ODTCTRL, dcs_params.b1odtctrl);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B1_WKPUPD, 0);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B1_IOCTL, dcs_params.b1ioctl);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B1_ODT, dcs_params.b1odt);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS0_WKPUPD, 0x00000782);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS0_DRIVESTR, dcs_params.dqs0drivestr);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS0_IOCTL, dcs_params.dqs0ioctl);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS0_ODT, dcs_params.dqs0odt);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS0_ZDETBIASEN, dcs_params.dqs0zdetbiasen);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS0_ODTCTRL, dcs_params.dqs0odtctrl);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS1_WKPUPD, 0x00000782);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS1_DRIVESTR, dcs_params.dqs1drivestr);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS1_IOCTL, dcs_params.dqs1ioctl);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS1_ODT, dcs_params.dqs1odt);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS1_ZDETBIASEN, dcs_params.dqs1zdetbiasen);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS1_ODTCTRL, dcs_params.dqs1odtctrl);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DBG_REG0, 0x00000000);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_ZCAL_FSM(1), dcs_params.zcalfsm1);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_ZCAL_FSM(0), dcs_params.zcalfsm0);
|
||||
|
||||
if (dcs_cfg.chipRev < CHIP_REVISION_B0)
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_SPARE(0), dcs_params.spare0);
|
||||
else
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_SPARE(0), 0x00000816);
|
||||
|
||||
for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_AMPINIT(i), 0x00000001);
|
||||
|
||||
if (dcs_cfg.chipRev < CHIP_REVISION_B0)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DFICALTIMING, dcs_params.dficaltiming);
|
||||
else
|
||||
{
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DFICALTIMING, 0x06001604);
|
||||
dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ0, 0), 0x06021604);
|
||||
dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ1, 0), 0x06021604);
|
||||
}
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWRDDQCALTVREF, dcs_params.hwrddqcaltvref);
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 3: Self-Refresh Exit
|
||||
//================================================================================
|
||||
void dcs_init_Self_Refresh_Exit_a(void)
|
||||
{
|
||||
// Wait 5 us after Impedence Calibration to avoid McPhyPending
|
||||
// preventing the SRFSM from exiting SR.
|
||||
dcs_spin(5, "after Imp. Cal.");
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AREFPARAM, dcs_params.arefparam);
|
||||
|
||||
for(int i = 0; i < DCS_FREQUENCY_SLOTS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_FREQ(i), dcs_params.freq[i].autoref2);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_PARAMS, dcs_params.autoref_params2);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc);
|
||||
// M8 Bug radar #20346417, two writes to ensure propogation
|
||||
dcs_reg_write_all_chan(rDCS_MCU_LONGSR, dcs_params.longsr);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_LONGSR, dcs_params.longsr);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_MCPHYUPDTPARAM, 0x15030004);
|
||||
|
||||
}
|
||||
|
||||
//========================================
|
||||
// Caller Code should:
|
||||
// - Change Frequency to 50MHz
|
||||
//========================================
|
||||
|
||||
void dcs_init_Self_Refresh_Exit_b(void)
|
||||
{
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AMCCTRL, 0x00000003);
|
||||
|
||||
|
||||
if (!izFPGA) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_IMPCALCMD, 0x00000001);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_IMPCALCMD, 0x01, 0x00);
|
||||
}
|
||||
|
||||
if (izResume)
|
||||
dcs_enable_autorefresh();
|
||||
|
||||
dcs_spin(2200, "After Enable Auto-Refresh");
|
||||
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) {
|
||||
dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, dcs_params.freqchngctl_step3);
|
||||
dcs_reg_poll_all_chan(rDCS_MCU_FREQCHNGCTL, 0x10000, 0x00000);
|
||||
dcs_spin(2, "After SoC Update");
|
||||
}
|
||||
|
||||
// Resume-Boot and Cold-Boot use different Exit commands for Self-Refresh
|
||||
// Issue self-refresh exit cmd for resume boot with MPC
|
||||
int n = (izColdBoot)? 0x00000000:0x00004000;
|
||||
// Issue self-refresh exit cmd for resume boot with MPC
|
||||
dcs_reg_write_all_chan(rDCS_MCU_MRINITCMD_0, n);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_MRINITCMD_0, n | 0x1);
|
||||
dcs_reg_poll_all_chan(rDCS_MCU_MRINITCMD_0, 0x01, 0x00);
|
||||
|
||||
dcs_spin(2, NULL);
|
||||
|
||||
dcs_reg_write(rGLBTIMER_CHEN, (1 << dcs_cfg.num_dcs) - 1);
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 4: DRAM Reset, ZQ Calibration & Configuration (cold boot only)
|
||||
//================================================================================
|
||||
void dcs_init_ZQ_Cal_Cfg(void)
|
||||
{
|
||||
// ZQ calibration START MPC cmd
|
||||
dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0, 0x4f);
|
||||
// wait 1us for tZQCAL
|
||||
dcs_spin(1, "tZQCAL");
|
||||
|
||||
// ZQ calibration LATCH MPC cmd
|
||||
dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0, 0x51);
|
||||
// wait 10ns for tZQLAT
|
||||
dcs_spin(1, "tZQLAT");
|
||||
|
||||
if (izColdBoot) {
|
||||
// MR2 register (read/write latency)
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x2, 0x0);
|
||||
// MR1 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x1, 0x8e);
|
||||
// MR3 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x3, dcs_params.mr3cmd);
|
||||
// MR22 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x16, 0x0);
|
||||
// MR11 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xb, 0x0);
|
||||
// MR13 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xd, dcs_params.mr13cmd);
|
||||
// MR12 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xc, 0x59);
|
||||
// MR14 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xe, 0x59);
|
||||
|
||||
// MR23 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x17, 0x80);
|
||||
|
||||
uint32_t patinvertmask = (DCS_REG_READ_CH(0, rDCS_AMP_HWRDDQCALPATPRBS4I) >> 16) & 0xffff;
|
||||
uint32_t prbs = DCS_REG_READ_CH(0, rDCS_AMP_HWWRDQCALPATPRBS4I);
|
||||
|
||||
// MR15 register
|
||||
dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xf, patinvertmask & 0xff);
|
||||
// MR20 register
|
||||
dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x14, (patinvertmask >> 8) & 0xff);
|
||||
// MR32 register
|
||||
dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x20, prbs & 0xff);
|
||||
// MR40 register
|
||||
dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x28, (prbs >> 8) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 5a: AddrConfig Configuration
|
||||
//================================================================================
|
||||
void dcs_init_AddrCfg_Cfg(void)
|
||||
{
|
||||
|
||||
dcs_reg_write(rAMCC_ADDRCFG_ADDR, dcs_params.addrcfg);
|
||||
#if NUM_AMCCS == 2
|
||||
dcs_reg_write(rAMCC1_ADDRCFG_ADDR, dcs_params.addrcfg);
|
||||
#endif
|
||||
}
|
||||
|
||||
//========================================
|
||||
// Caller Code should:
|
||||
// - Use MR Cmds to Query the Device
|
||||
//========================================
|
||||
|
||||
//================================================================================
|
||||
// Step 5b: Total Mem Size Config
|
||||
//================================================================================
|
||||
void dcs_init_TotalSize_Cfg(uint32_t total_size_Mbytes)
|
||||
{
|
||||
dbgprintf(DCS_DBG_ASSESS_CONFIG, "Memory_size: %llu bytes\n",
|
||||
(((uint64_t)total_size_Mbytes) * MEG * NUM_AMCCS));
|
||||
// (Units of 128 MBs in the register)
|
||||
dcs_reg_write(rAMCC_DRAMACCCTRL_ADDR, ((total_size_Mbytes / NUM_AMCCS) / DCS_NUM_MEG_IN_DRAM_BLK) - 1);
|
||||
dcs_reg_write(rAMCC_MCCCHNLDEC_ADDR, dcs_params.chnldec);
|
||||
|
||||
#if NUM_AMCCS == 2
|
||||
dcs_reg_write(rAMCC1_DRAMACCCTRL_ADDR, ((total_size_Mbytes / NUM_AMCCS) / DCS_NUM_MEG_IN_DRAM_BLK) - 1);
|
||||
dcs_reg_write(rAMCC1_MCCCHNLDEC_ADDR, dcs_params.chnldec);
|
||||
#endif
|
||||
|
||||
dbgprintf(DCS_DBG_ASSESS_CONFIG, "rAMCC_DRAMACCCTRL: 0x%08x\n", rAMCC_DRAMACCCTRL);
|
||||
|
||||
const struct dcs_memory_device_info *dev_info = dcs_get_memory_device_info();
|
||||
if((dev_info->vendor_id == JEDEC_LPDDR4_MANUF_ID_SAMSUNG) && (dev_info->rev_id == 5) && (dev_info->rev_id2 <= 1))
|
||||
apply_samsung_workaround = true;
|
||||
|
||||
if(apply_samsung_workaround) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ0, 0), 0x00d800d8);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ1, 0), 0x00d800d8);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ0, 1), 0x00d800d8);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ1, 1), 0x00d800d8);
|
||||
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x3, 0xf2);
|
||||
dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0, 0x4f);
|
||||
|
||||
dcs_spin(1, " For tZQCAL");
|
||||
dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0, 0x51);
|
||||
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL_FREQ(2, 0), 0xb203330b);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL_FREQ(4, 0), 0x00000316);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL_FREQ(2, 3), 0xf203000b);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_CB_IMPCTL, 0x01001c2b);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B0_ODT, 0x01c00339);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B1_ODT, 0x01c00339);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS0_ODT, 0x01c00339);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS1_ODT, 0x01c00339);
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 6: Switch from boot-clock speed to normal operation speed
|
||||
//================================================================================
|
||||
void dcs_init_Reenable_AMC_Scheduler(void)
|
||||
{
|
||||
// Wait 5 us before freq change to make sure all refreshes have been flushed
|
||||
dcs_spin(5, "After Refresh");
|
||||
|
||||
// Enable (again) the AMC Scheduler
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AMCCTRL, 0x00000003);
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 7: Setup registers for CA calibration for bucket 1
|
||||
//================================================================================
|
||||
void dcs_init_CA_Cal_Setup_Freq1(void)
|
||||
{
|
||||
// MR13 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xd, dcs_params.mr13cmd_step7);
|
||||
|
||||
if (izColdBoot) {
|
||||
if (izFPGA) {
|
||||
// MR11 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xb, 0x00);
|
||||
} else {
|
||||
// MR2 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x2, 0x52);
|
||||
// MR1 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x1, 0xae);
|
||||
// MR3 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x3, dcs_params.mr3cmd_step7);
|
||||
// MR22 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x16, dcs_params.mr22cmd);
|
||||
// MR11 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xb, dcs_params.mr11cmd);
|
||||
// MR12 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xc, 0x11);
|
||||
// MR14 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xe, 0x11);
|
||||
}
|
||||
dcs_reg_write_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x00000200);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x0200, 0x0000);
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 8: AMP Dynamic CA Vref Timing Calibration at Vmin 800MHz
|
||||
//================================================================================
|
||||
void dcs_init_CA_Cal_Freq1(void)
|
||||
{
|
||||
// Nothing to be done at this step for cold boot
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 9: Setup registers for DQ calibration for bucket 1
|
||||
//================================================================================
|
||||
void dcs_init_DQ_Cal_Setup_Freq1_a(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (izColdBoot) {
|
||||
// MR13 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xd, dcs_params.mr13cmd_step9);
|
||||
}
|
||||
|
||||
dcs_spin(1, NULL);
|
||||
|
||||
if(izResume) {
|
||||
dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTEN, 0x00000002);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, 0x01008888);
|
||||
|
||||
for(i = AMP_DQ0 ; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(i), 0xFF00000C);
|
||||
for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_DEFER_EN(i), 0x00000000);
|
||||
for(i = AMP_DQ0; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_MDLLOVRRD(i), 0x00000000);
|
||||
}
|
||||
}
|
||||
|
||||
// Caller code should change frequency to bucket 1
|
||||
void dcs_init_DQ_Cal_Setup_Freq1_b(void)
|
||||
{
|
||||
if (izColdBoot) {
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) {
|
||||
dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, dcs_params.freqchngctl_step9);
|
||||
dcs_reg_poll_all_chan(rDCS_MCU_FREQCHNGCTL, 0x10000, 0x00000);
|
||||
|
||||
// Wait 2us for the soc update to finish
|
||||
dcs_spin(2, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 10: PHY write DQ calibration
|
||||
//================================================================================
|
||||
void dcs_init_wrdq_skew(void)
|
||||
{
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQSDQ_SKEWCTL(AMP_DQ0), 0x06000000);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQSDQ_SKEWCTL(AMP_DQ1), 0x06000000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//================================================================================
|
||||
// Step 11: Setup registers for CA calibration for bucket 0
|
||||
//================================================================================
|
||||
void dcs_init_CA_Cal_Setup_Freq0(void)
|
||||
{
|
||||
if (izColdBoot) {
|
||||
|
||||
if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ0), 0x00000000);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ1), 0x00000000);
|
||||
}
|
||||
|
||||
// MR13 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, dcs_params.mr13cmd_step11);
|
||||
if (!izFPGA) {
|
||||
// MR2 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x02, dcs_params.mr2cmd_step11);
|
||||
// MR1 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x01, dcs_params.mr1cmd_step11);
|
||||
// MR3 register
|
||||
if(apply_samsung_workaround)
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x03, 0xb2);
|
||||
else
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x03, dcs_params.mr3cmd_step11);
|
||||
}
|
||||
|
||||
if(apply_samsung_workaround) {
|
||||
// MR22 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x16, 0x03);
|
||||
// MR11 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0b, 0x33);
|
||||
} else {
|
||||
// MR22 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x16, dcs_params.mr22cmd_step11);
|
||||
// MR11 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0b, (izFPGA) ? 0x00 : dcs_params.mr11cmd_step11);
|
||||
}
|
||||
|
||||
// MR12 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0c, dcs_params.mr12cmd_step11);
|
||||
// MR14 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0e, dcs_params.mr14cmd_step11);
|
||||
|
||||
if((dcs_params.supported_freqs & DCS_FREQ(1)) == 0) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x00000200);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x200, 0x000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 12: AMP Dynamic CA Timing Calibration
|
||||
//================================================================================
|
||||
|
||||
//================================================================================
|
||||
// Step 13: Setup registers for DQ calibration for bucket 0
|
||||
//================================================================================
|
||||
void dcs_init_DQ_Cal_Setup_Freq0_a(void)
|
||||
{
|
||||
if (izColdBoot) {
|
||||
// MR13 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, dcs_params.mr13cmd_step13);
|
||||
|
||||
// Wait 1 us
|
||||
dcs_spin(1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void dcs_init_DQ_Cal_Setup_Freq0_b(void)
|
||||
{
|
||||
if (izColdBoot) {
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) {
|
||||
dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, 0x00010000);
|
||||
dcs_reg_poll_all_chan(rDCS_MCU_FREQCHNGCTL, 0x10000, 0x00000);
|
||||
|
||||
// Wait 2us for the soc update to finish
|
||||
dcs_spin(2, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 14: AMP Dynamic DQ Calibration
|
||||
//================================================================================
|
||||
void dcs_init_post_wrlvl(void)
|
||||
{
|
||||
if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ0), 0x00000010);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ1), 0x00000010);
|
||||
}
|
||||
if (!izFPGA)
|
||||
{
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS0_WKPUPD, dcs_params.dqs0wkpupd);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS1_WKPUPD, dcs_params.dqs1wkpupd);
|
||||
}
|
||||
}
|
||||
//================================================================================
|
||||
// Step 15: Setup Registers for Boot
|
||||
//================================================================================
|
||||
void dcs_init_Reg_for_Boot(void)
|
||||
{
|
||||
if (dcs_cfg.chipRev >= CHIP_REVISION_B0)
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_SPARE(0), 0xc16);
|
||||
|
||||
#ifndef DCS_RUN_AT_50MHZ
|
||||
if (izColdBoot) {
|
||||
// MR13 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, dcs_params.mr13cmd_step15);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(izFPGA && !(dcs_params.supported_freqs & DCS_FREQ(1)))
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, 0x50);
|
||||
|
||||
// Wait 1 us
|
||||
dcs_spin(1, NULL);
|
||||
|
||||
if (izColdBoot) {
|
||||
dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, dcs_params.freqchngctl_step15);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ0), 0xff000008);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ1), 0xff000008);
|
||||
|
||||
|
||||
#if !DCS_DO_CALIBRATION
|
||||
// skip these for all silicon targets, where calibration is performed, also skip for any Maui A1 target
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) {
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDDQSDLL_DLYSEL(AMP_DQ0), 0x00000000);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDDQSDLL_DLYSEL(AMP_DQ1), 0x00000000);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step15);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step15);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step15 & 0x7, 0x0);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step15 & 0x7, 0x0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
if(!izFPGA)
|
||||
{
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALFULLSCANEN, 0x00000000);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALFULLSCANEN, 0x00000003);
|
||||
}
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWRDDQCALVREFCONTROL, 0x01D0B061);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALVREFCONTROL, 0x02200061);
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 16: Enable Other Features
|
||||
//================================================================================
|
||||
void dcs_init_MoreFeatures(void)
|
||||
{
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AREFPARAM, dcs_params.arefparam);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc2);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_QBREN, dcs_params.qbren_step16);
|
||||
if (izColdBoot)
|
||||
dcs_enable_autorefresh();
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B0_DYN_ISEL_ASRTIME, dcs_params.b0dyniselasrtime);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B0_DYN_ISEL, dcs_params.b0dynisel);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B1_DYN_ISEL, dcs_params.b1dynisel);
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 17: Enable Fast Critical Word Forwarding Feature
|
||||
//================================================================================
|
||||
void dcs_init_Fast_Critical_Word_Forwarding(void)
|
||||
{
|
||||
dcs_reg_write_all_chan(rDCS_MCU_QBRPARAM, dcs_params.qbrparam);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_QBREN, dcs_params.qbren);
|
||||
dcs_reg_write(rAMCC_MCCGEN_ADDR, dcs_params.mccgen);
|
||||
dcs_reg_write(rAMCC_MCC0QPROPCTRL_ADDR, 0x300011a2);
|
||||
dcs_reg_write(rAMCC_MCC1QPROPCTRL_ADDR, 0x300011a2);
|
||||
|
||||
#if NUM_AMCCS == 2
|
||||
dcs_reg_write(rAMCC1_MCCGEN_ADDR, dcs_params.mccgen);
|
||||
dcs_reg_write(rAMCC1_MCC0QPROPCTRL_ADDR, 0x300011a2);
|
||||
dcs_reg_write(rAMCC1_MCC1QPROPCTRL_ADDR, 0x300011a2);
|
||||
#endif // #if NUM_AMCCS == 2
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 18: Enable Power- and Clock-Gating Features; Config MCC and Global Timers
|
||||
//================================================================================
|
||||
void dcs_init_Gating_Global_Timers(void)
|
||||
{
|
||||
dcs_reg_write_all_chan(rDCS_AMP_AMPCLK(AMP_CA), dcs_params.caampclk);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_AMPCLK(AMP_DQ0), dcs_params.dqampclk);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_AMPCLK(AMP_DQ1), dcs_params.dqampclk);
|
||||
dcs_reg_write_all_chan(rDCS_SPLLCTRL_MDLLPWRDNCFG(0), 0x00000001);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTEN, dcs_params.pwrmngten);
|
||||
|
||||
// Global Timer Setup
|
||||
|
||||
dcs_reg_write(rGLBTIMER_PMGRWAKEUPCFG, 0x0001ff);
|
||||
dcs_reg_write(rGLBTIMER_PREFREQ2ALLBANKDLY(0), 0x00f000f0);
|
||||
dcs_reg_write(rGLBTIMER_PREFREQ2ALLBANKDLY(1), 0x00f000f0);
|
||||
dcs_reg_write(rGLBTIMER_PREFREQCHNG2FREQCHNGDLY(0), 0x02400240);
|
||||
dcs_reg_write(rGLBTIMER_PREFREQCHNG2FREQCHNGDLY(1), 0x02400240);
|
||||
|
||||
dcs_reg_write(rGLBTIMER_CALSEG2ALLBANK(0), 0x00fa0120);
|
||||
dcs_reg_write(rGLBTIMER_ALLBANK2CALSEG(0), 0x00fa0120);
|
||||
|
||||
dcs_reg_write(rGLBTIMER_MDLLTIMER, 0x000bb8);
|
||||
dcs_reg_write(rGLBTIMER_DCCTIMER, 0x000bb8);
|
||||
dcs_reg_write(rGLBTIMER_MDLLVOLTRAMPTIMER, 0x00004b);
|
||||
dcs_reg_write(rGLBTIMER_CTRLUPDMASKTIMER, 0x00000f);
|
||||
// <rdar://problem/19573098> Elba A0: Samsung 20nm Rev0 LPDDR4 work-around(disable IDT cal)
|
||||
//dcs_reg_write(rGLBTIMER_IDTTIMER, 0x007530); // 30000
|
||||
dcs_reg_write(rGLBTIMER_RDCALTIMER, 0x002dc6bb);
|
||||
dcs_reg_write(rGLBTIMER_WRCALTIMER, 0x002dc6c0);
|
||||
|
||||
// <rdar://problem/23244578> Elba: Samsung DRAM workaround: disable hw zqcal
|
||||
if(!apply_samsung_workaround)
|
||||
dcs_reg_write(rGLBTIMER_ZQCTIMER, 0x3d0900);
|
||||
|
||||
dcs_reg_write(rGLBTIMER_PERCAL_FREQCHNGTIMER, 0x000001);
|
||||
dcs_reg_write(rGLBTIMER_IMPCALTIMER, 0x002ee0);
|
||||
|
||||
// Dynamic Clk & Power Gating
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AMCCLKPWRGATE, 0x050a0000);
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 19: ODTS read & set interval for periodic MR4 on-die Temp sensor reading
|
||||
//================================================================================
|
||||
void dcs_init_ODTS(void)
|
||||
{
|
||||
uint8_t temp[16*8]; // Far more Channels/Ranks than we are likely ever to have/need
|
||||
// INSTEAD OF: uint8_t temp[dcs_cfg.num_dcs * dcs_cfg.num_rank];
|
||||
|
||||
// MR4 read to bring memory out of self-refresh
|
||||
dcs_mrcmd(MR_READ, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x4, (uintptr_t)temp);
|
||||
// M8 Bug radar #20346417, two writes to ensure propogation
|
||||
dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc3);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc3);
|
||||
|
||||
}
|
||||
|
||||
// <rdar://problem/23244578>: This function used in calibration code for Elba
|
||||
bool shim_apply_samsung_workaround(void)
|
||||
{
|
||||
return apply_samsung_workaround;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
@@ -0,0 +1,889 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This document is the property of Apple Inc.
|
||||
* It is considered confidential and proprietary.
|
||||
*
|
||||
* This document may not be reproduced or transmitted in any form,
|
||||
* in whole or in part, without the express written permission of
|
||||
* Apple Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Init Sequence Library for use in:
|
||||
* Driver for the LPDDR4 compatible DRAM Control Subsystem (DCS) block
|
||||
*/
|
||||
|
||||
/*
|
||||
Summary of Steps from the Spec (Spreadsheet)
|
||||
|
||||
+ (Aa) Steps 0,1,2,3a [need to identify parameterization]
|
||||
+ (Ab) Step 3b [PMGR: set Freq to 50MHz & delay-wait]
|
||||
+ (Ac) Steps 3c,4,5 [need to identify parameterization]
|
||||
+ (B) Step 6 [Change Clk Speed]
|
||||
+ (C) Step 7 [include delay-wait from early Step 8]
|
||||
+ (D) Step 8a [Cal: CA 800MHz Vmin]
|
||||
+ (E) Step 8b [Write Regs]
|
||||
+ (F) Step 8c [Cal: CA 800MHz Vmin] (...again? should it be CS?)
|
||||
+ (G) Step 8d [Write Regs]
|
||||
+ (H) Step 9 [Write Regs]
|
||||
+ (I) Step 10 [Cal: WrLvl, RdDq, WrDq 800MHz Vmin]
|
||||
+ (J) Step 11 [Write Regs]
|
||||
+ (K) Step 12 [Cal: CA 1200MHz Vnom]
|
||||
+ (L) Step 13 [Write Regs]
|
||||
+ (M) Step 14 [Cal: WrLvl, RdDq, WrDq 1200MHz Vmin]
|
||||
+ (N) Steps 15,16,17,18,19,20 [need to identify parameterization]
|
||||
|
||||
Between these steps there is possibly a need/desire for:
|
||||
- Frequency Changes (PMGR)
|
||||
- PMU save/restore
|
||||
- debug messages
|
||||
- register dumps (DV, SiVal)
|
||||
- anything else!
|
||||
|
||||
CONFIG Table:
|
||||
Compile-Time Known:
|
||||
Type of Execution Environment CoreOS, DV, SiVal
|
||||
Type of Target SoC, FPGA, Palladium
|
||||
ChipID 0x8000, 0x8001, etc.
|
||||
Revision A0, B0, B1, etc.
|
||||
Num DCS 4, 8, etc. (Derived...!)
|
||||
Variant Flags Work-arounds, RADAR Ref., et al.
|
||||
|
||||
(Config Info know at Compile time can be subject to #if)
|
||||
|
||||
Run-Time Known:
|
||||
Type of Init ColdBoot, AOP_DDR, AOP_AWAKE
|
||||
Debug Flags Low-Level, Milestone, et al.
|
||||
|
||||
RegValue Table
|
||||
Much like today's: various values for various registers
|
||||
Sensitive to ChipID (also Target type?)
|
||||
(Internal static alloc (Complete Table Fill-in within Init function):
|
||||
Fill in Values (per ChipID/Rev & Target-type)
|
||||
return pointer to caller
|
||||
(Allows customization by caller before use)
|
||||
|
||||
TODO:
|
||||
- Convert to using SPDS for register names, et al
|
||||
|
||||
*/
|
||||
|
||||
//================================================================================
|
||||
// API Definitions
|
||||
#include <drivers/dcs/dcs_init_lib.h>
|
||||
|
||||
extern dcs_config_t dcs_cfg;
|
||||
extern dcs_config_params_t dcs_params;
|
||||
|
||||
#if izIBOOT
|
||||
extern int debug_level_dcs;
|
||||
#endif
|
||||
|
||||
void dcs_enable_autorefresh(void)
|
||||
{
|
||||
// Configure auto-refresh. Freq0 has the auto-refresh enable, so do it last.
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(3), 0x11100000);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(2), 0x11000000);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(1), 0x11110000);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AREFEN_FREQ(0), 0x1111013f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//================================================================================
|
||||
// Implementing the Various Steps of the DCS Init, per Specification
|
||||
// Based on AMC Init Spec (Spreadsheet)
|
||||
// - Supporting Maui: Spec (v??)
|
||||
//================================================================================
|
||||
// Step 0: AMC Prolog
|
||||
//================================================================================
|
||||
void dcs_init_Prolog(void)
|
||||
{
|
||||
// NOTE: between the Compiler and the Optimization, this should vanish for non-FPGA builds
|
||||
if (izFPGA && izColdBoot) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DRAM_RESETN(AMP_CA), 1);
|
||||
delay_for_us(200);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DRAM_RESETN(AMP_CA), 0);
|
||||
delay_for_us(200);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DRAM_RESETN(AMP_CA), 1);
|
||||
delay_for_us(200);
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 1: AMC Initial Configuration
|
||||
//================================================================================
|
||||
void dcs_init_AMC_Initial_Config(void)
|
||||
{
|
||||
uint32_t i,n;
|
||||
|
||||
// rdar://problem/19137387: this applies to Maui A1 and B0, as well as other SoCs before Cayman
|
||||
|
||||
dcs_reg_write(rAMCC_MCCCHNLDEC_ADDR, dcs_params.chnldec);
|
||||
dcs_reg_write_all_chan(rDCS_SPLLCTRL_CHARGEPUMP, 0x00000068);
|
||||
dcs_reg_write_all_chan(rDCS_SPLLCTRL_VCO, dcs_params.spllctrl_vco_1);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_SPLLCTRL_VCO, dcs_params.spllctrl_vco_2);
|
||||
dcs_reg_write_all_chan(rDCS_SPLLCTRL_LDO, 0x00000004);
|
||||
|
||||
// This register write to be skipped for Maui A0/A1, but written to for B0 & later, and all other SoCs
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0))
|
||||
dcs_reg_write_all_chan(rDCS_SPLLCTRL_SPLLPWRDNCFG, 0x00000011);
|
||||
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) {
|
||||
for (n = 0; n < dcs_params.num_freqchngctl_regs; n++)
|
||||
dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL_FREQ(n, i), dcs_params.freq[i].freqchngctl[n]);
|
||||
|
||||
// This register write to be skipped for Maui A0/A1, but written to for B0 & later, and all other SoCs
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0))
|
||||
dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGTIM_FREQ(i), dcs_params.freq[i].freqchngtim);
|
||||
}
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_MCU_RWCFG, dcs_params.rwcfg);
|
||||
|
||||
for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTCTRL(i), dcs_params.dllupdtctrl);
|
||||
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_MCU_LAT_FREQ(0), dcs_params.freq[0].lat);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_LAT_FREQ(1), dcs_params.freq[1].lat);
|
||||
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_MCU_PHYRDWRTIM_FREQ(i), dcs_params.freq[i].phyrdwrtim);
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) {
|
||||
dcs_reg_write_all_chan(rDCS_MCU_CASPCH_FREQ(i), dcs_params.freq[i].caspch);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_ACT_FREQ(i), dcs_params.freq[i].act);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_FREQ(i), dcs_params.freq[i].autoref);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_SELFREF_FREQ(i), dcs_params.freq[i].selfref);
|
||||
|
||||
if (i == 0) dcs_reg_write_all_chan(rDCS_MCU_MODEREG, dcs_params.modereg);
|
||||
|
||||
}
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_PARAMS, dcs_params.autoref_params);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_PDN, dcs_params.pdn);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_DERATE_FREQ(0), dcs_params.freq[0].derate);
|
||||
|
||||
// These register writes to be skipped for Maui A0/A1, but written to for B0 & later, and all other SoCs
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0))
|
||||
for(i = 1; i < DCS_FREQUENCY_SLOTS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_MCU_DERATE_FREQ(i), dcs_params.freq[i].derate);
|
||||
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_MCU_LAT_FREQ(i), dcs_params.freq[i].lat2);
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_MCU_TAT_FREQ(i), dcs_params.freq[i].tat);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_RNKCFG, dcs_params.rnkcfg);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_MIFQMAXCTRL_FREQ(0), dcs_params.freq[0].mifqmaxctrl);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_MIFQMAXCTRL_FREQ(3), dcs_params.freq[3].mifqmaxctrl);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTEN, 0);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, 0x00002000);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AMCCTRL, 0x00000002);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_MCPHYUPDTPARAM, 0x15030000);
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 2: AMP Initial Configuration
|
||||
//================================================================================
|
||||
void dcs_init_AMP_Initial_Config(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_AMPEN(i), 0x00000001);
|
||||
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_NONDQDSPD_F(i), dcs_params.freq[i].nondqdspd);
|
||||
|
||||
for(i = 1; i < DCS_FREQUENCY_SLOTS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_NONDQDS_F(i), dcs_params.freq[i].nondqds);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_CACKCSWKDS, dcs_params.cackcswkds);
|
||||
|
||||
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_CA, i), dcs_params.freq[i].cavref);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_ODTENABLE_F(0), dcs_params.freq[0].odt_enable);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_ODTENABLE_F(1), dcs_params.freq[1].odt_enable);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_ODTENABLE_F(3), dcs_params.freq[3].odt_enable);
|
||||
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) {
|
||||
// These register writes to be skipped for Maui A0/A1
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQDS_F(AMP_DQ0,i), dcs_params.freq[i].dqds);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQDS_F(AMP_DQ1,i), dcs_params.freq[i].dqds);
|
||||
}
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQDQSDS_F(AMP_DQ0,i), dcs_params.freq[i].dqdqsds);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQDQSDS_F(AMP_DQ1,i), dcs_params.freq[i].dqdqsds);
|
||||
}
|
||||
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ0, i), dcs_params.freq[i].dqvref);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_VREF_F(AMP_DQ1, i), dcs_params.freq[i].dqvref);
|
||||
}
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQSPDRES(AMP_DQ0), dcs_params.dqspdres);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQSPDRES(AMP_DQ1), dcs_params.dqspdres);
|
||||
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_CNTL(AMP_CA), dcs_params.casdllupdatectrl);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_CNTL(AMP_DQ0), dcs_params.dqsdllupdatectrl);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_CNTL(AMP_DQ1), dcs_params.dqsdllupdatectrl);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step2);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step2);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step2 & 0x7, 0x0);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step2 & 0x7, 0x0);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ0), dcs_params.wrdqdqssdllctrl_step2);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ1), dcs_params.wrdqdqssdllctrl_step2);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ0), dcs_params.wrdqdqssdllctrl_step2 & 0x7, 0x0);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ1), dcs_params.wrdqdqssdllctrl_step2 & 0x7, 0x0);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, dcs_params.cawrlvlsdllcode);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, dcs_params.cawrlvlsdllcode & 0x300, 0x000);
|
||||
|
||||
if (!izFPGA)
|
||||
for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DLLLOCKTIM(i), dcs_params.dlllocktim);
|
||||
|
||||
if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQSPDENALWYSON(AMP_DQ0), 0x00000001);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQSPDENALWYSON(AMP_DQ1), 0x00000001);
|
||||
}
|
||||
|
||||
if((dcs_params.supported_freqs & DCS_FREQ(1)) != 0)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DFICALTIMING, dcs_params.dficaltiming);
|
||||
|
||||
// These register writes to be skipped for Maui A0/A1
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) {
|
||||
for(i = 1; i < DCS_FREQUENCY_SLOTS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMPCA_DFICALTIMING_F(i), dcs_params.freq[i].cadficaltiming);
|
||||
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) {
|
||||
dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ0, i), dcs_params.freq[i].dqdficaltiming);
|
||||
dcs_reg_write_all_chan(rDCS_AMPDQ_DFICALTIMING_F(AMP_DQ1, i), dcs_params.freq[i].dqdficaltiming);
|
||||
}
|
||||
dcs_reg_write_all_chan(rDCS_AMP_MDLLCODE_CAP_CNTL(AMP_DQ0), 0x00000002);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_MDLLCODE_CAP_CNTL(AMP_DQ1), 0x00000002);
|
||||
|
||||
}
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALTIMING_F(0), dcs_params.rdwrdqcaltiming_f0);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALSEGLEN_F(0), dcs_params.rdwrdqcalseglen_f0);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALTIMING_F(1), dcs_params.rdwrdqcaltiming_f1);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDWRDQCALSEGLEN_F(1), dcs_params.rdwrdqcalseglen_f1);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALTIMINGCTRL(1), dcs_params.rdwrdqcaltimingctrl1);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALTIMINGCTRL(2), dcs_params.rdwrdqcaltimingctrl2);
|
||||
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWRDDQCALPATPRBS4I, dcs_params.rddqcalpatprbs4i);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWWRDQCALPATPRBS4I, dcs_params.wrdqcalpatprbs4i);
|
||||
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDDQCALWINDOW_F(0), dcs_params.freq[0].rddqcalwindow);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_WRDQCALWINDOW_F(0), dcs_params.freq[0].wrdqcalwindow);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDDQCALWINDOW_F(1), dcs_params.freq[1].rddqcalwindow);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_WRDQCALWINDOW_F(1), dcs_params.freq[1].wrdqcalwindow);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_MAXRDDQS_SDLL_MULFACTOR, dcs_params.maxrddqssdllmulfactor);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_MAXWRDQ_SDLL_MULFACTOR, 0x00a00a0f);
|
||||
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_MAXWRDQS_SDLL_MULFACTOR, dcs_params.maxwrdqssdllmulfactor);
|
||||
|
||||
// These register writes to be skipped for Maui A0/A1
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) {
|
||||
dcs_reg_write_all_chan(rDCS_AMPDQ_RDDQSMULFACTOR(AMP_DQ0), 0x20181000);
|
||||
dcs_reg_write_all_chan(rDCS_AMPDQ_RDDQSMULFACTOR(AMP_DQ1), 0x20181000);
|
||||
}
|
||||
|
||||
for(i = 0; i < DCS_FREQUENCY_SLOTS; i++) {
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_CAOUTDLLSCL_FREQ(i), dcs_params.freq[i].caoutdllscl);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQSINDLLSCL_FREQ(AMP_DQ0, i), dcs_params.freq[i].dqsindllscl);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQSINDLLSCL_FREQ(AMP_DQ1, i), dcs_params.freq[i].dqsindllscl);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDCAPCFG_FREQ(AMP_DQ0, i), dcs_params.freq[i].rdcapcfg);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDCAPCFG_FREQ(AMP_DQ1, i), dcs_params.freq[i].rdcapcfg);
|
||||
}
|
||||
|
||||
if (!izFPGA) {
|
||||
for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTCTRL(i), dcs_params.dllupdtctrl1);
|
||||
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_IMPAUTOCAL, 0x00010000);
|
||||
|
||||
}
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTINTVL(AMP_CA), dcs_params.dllupdtintvl);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTINTVL(AMP_DQ0), dcs_params.dllupdtintvl);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DLLUPDTINTVL(AMP_DQ1), dcs_params.dllupdtintvl);
|
||||
|
||||
for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DLLEN(i), 0x00000100);
|
||||
|
||||
if(!izFPGA) {
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_IMPCALCMD, 0x00000000);
|
||||
}
|
||||
|
||||
// Workaround for Maui B0
|
||||
if((dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0))
|
||||
dcs_reg_write_all_chan(rDCS_AMP_BISTRXMODE, 0x0000001c);
|
||||
|
||||
|
||||
|
||||
// AMPH configuration
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_CB_WKPUPD, 0);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_CB_DRIVESTR, dcs_params.cbdrivestr);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_CB_IOCTL, dcs_params.cbioctl);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_CK_WKPUPD, 0);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_CK_ZDETBIASEN, 0);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_CK_DRIVESTR, dcs_params.ckdrivestr);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_CK_IOCTL, dcs_params.ckioctl);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B0_DRIVESTR, dcs_params.b0drivestr);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B0_IMPCTL, 0x00201c2b);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B0_WKPUPD, 0);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B0_IOCTL, dcs_params.b0ioctl);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B0_ODT, dcs_params.b0odt);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B0_ODTCTRL, dcs_params.b0odtctrl);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B1_DRIVESTR, dcs_params.b1drivestr);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B1_ODTCTRL, dcs_params.b1odtctrl);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B1_IMPCTL, 0x00201c2b);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B1_WKPUPD, 0);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B1_IOCTL, dcs_params.b1ioctl);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B1_ODT, dcs_params.b1odt);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS0_WKPUPD, 0x00000788);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS0_DRIVESTR, dcs_params.dqs0drivestr);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS0_IMPCTL, 0x00201c2b);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS0_IOCTL, dcs_params.dqs0ioctl);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS0_ODT, dcs_params.dqs0odt);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS0_ZDETBIASEN, dcs_params.dqs0zdetbiasen);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS0_ODTCTRL, dcs_params.dqs0odtctrl);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS1_WKPUPD, 0x00000788);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS1_DRIVESTR, dcs_params.dqs1drivestr);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS1_IMPCTL, 0x00201c2b);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS1_IOCTL, dcs_params.dqs1ioctl);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS1_ODT, dcs_params.dqs1odt);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS1_ZDETBIASEN, dcs_params.dqs1zdetbiasen);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS1_ODTCTRL, dcs_params.dqs1odtctrl);
|
||||
|
||||
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DBG_REG0, 0x00000000);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_ZCAL_FSM(1), dcs_params.zcalfsm1);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_ZCAL_FSM(0), dcs_params.zcalfsm0);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_SPARE(0), dcs_params.spare0);
|
||||
|
||||
for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_AMPINIT(i), 0x00000001);
|
||||
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 3: Self-Refresh Exit
|
||||
//================================================================================
|
||||
void dcs_init_Self_Refresh_Exit_a(void)
|
||||
{
|
||||
// Wait 5 us after Impedence Calibration to avoid McPhyPending
|
||||
// preventing the SRFSM from exiting SR.
|
||||
dcs_spin(5, "after Imp. Cal.");
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AREFPARAM, dcs_params.arefparam);
|
||||
|
||||
for(int i = 0; i < DCS_FREQUENCY_SLOTS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_FREQ(i), dcs_params.freq[i].autoref2);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AUTOREF_PARAMS, dcs_params.autoref_params2);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_LONGSR, dcs_params.longsr);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_MCPHYUPDTPARAM, 0x15030007);
|
||||
|
||||
|
||||
}
|
||||
|
||||
//========================================
|
||||
// Caller Code should:
|
||||
// - Change Frequency to 50MHz
|
||||
//========================================
|
||||
|
||||
void dcs_init_Self_Refresh_Exit_b(void)
|
||||
{
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AMCCTRL, 0x00000003);
|
||||
|
||||
|
||||
if (!izFPGA) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_IMPCALCMD, 0x00000001);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_IMPCALCMD, 0x01, 0x00);
|
||||
}
|
||||
|
||||
if (izResume)
|
||||
dcs_enable_autorefresh();
|
||||
|
||||
dcs_spin(2200, "After Enable Auto-Refresh");
|
||||
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) {
|
||||
dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, dcs_params.freqchngctl_step3);
|
||||
dcs_reg_poll_all_chan(rDCS_MCU_FREQCHNGCTL, 0x10000, 0x00000);
|
||||
dcs_spin(2, "After SoC Update");
|
||||
}
|
||||
|
||||
// Resume-Boot and Cold-Boot use different Exit commands for Self-Refresh
|
||||
// Issue self-refresh exit cmd for resume boot with MPC
|
||||
int n = (izColdBoot)? 0x00000000:0x00004000;
|
||||
// Issue self-refresh exit cmd for resume boot with MPC
|
||||
dcs_reg_write_all_chan(rDCS_MCU_MRINITCMD_0, n);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_MRINITCMD_0, n | 0x1);
|
||||
dcs_reg_poll_all_chan(rDCS_MCU_MRINITCMD_0, 0x01, 0x00);
|
||||
|
||||
dcs_spin(2, NULL);
|
||||
|
||||
dcs_reg_write(rGLBTIMER_CHEN, (1 << dcs_cfg.num_dcs) - 1);
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 4: DRAM Reset, ZQ Calibration & Configuration (cold boot only)
|
||||
//================================================================================
|
||||
void dcs_init_ZQ_Cal_Cfg(void)
|
||||
{
|
||||
// ZQ calibration START MPC cmd
|
||||
dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0, 0x4f);
|
||||
// wait 1us for tZQCAL
|
||||
dcs_spin(1, "tZQCAL");
|
||||
|
||||
// ZQ calibration LATCH MPC cmd
|
||||
dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0, 0x51);
|
||||
// wait 10ns for tZQLAT
|
||||
dcs_spin(1, "tZQLAT");
|
||||
|
||||
if (izColdBoot) {
|
||||
// MR2 register (read/write latency)
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x2, 0x0);
|
||||
// MR1 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x1, 0x8e);
|
||||
// MR3 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x3, dcs_params.mr3cmd);
|
||||
// MR22 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x16, 0x0);
|
||||
// MR11 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xb, 0x0);
|
||||
// MR13 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xd, dcs_params.mr13cmd);
|
||||
// MR12 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xc, 0x59);
|
||||
// MR14 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xe, 0x59);
|
||||
|
||||
// MR23 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x17, 0x80);
|
||||
|
||||
uint32_t patinvertmask = (DCS_REG_READ_CH(0, rDCS_AMP_HWRDDQCALPATPRBS4I) >> 16) & 0xffff;
|
||||
uint32_t prbs = DCS_REG_READ_CH(0, rDCS_AMP_HWWRDQCALPATPRBS4I);
|
||||
|
||||
// MR15 register
|
||||
dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xf, patinvertmask & 0xff);
|
||||
// MR20 register
|
||||
dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x14, (patinvertmask >> 8) & 0xff);
|
||||
// MR32 register
|
||||
dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x20, prbs & 0xff);
|
||||
// MR40 register
|
||||
dcs_mrcmd(MR_MPC, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x28, (prbs >> 8) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 5a: AddrConfig Configuration
|
||||
//================================================================================
|
||||
void dcs_init_AddrCfg_Cfg(void)
|
||||
{
|
||||
|
||||
dcs_reg_write(rAMCC_ADDRCFG_ADDR, dcs_params.addrcfg);
|
||||
}
|
||||
|
||||
//========================================
|
||||
// Caller Code should:
|
||||
// - Use MR Cmds to Query the Device
|
||||
//========================================
|
||||
|
||||
//================================================================================
|
||||
// Step 5b: Total Mem Size Config
|
||||
//================================================================================
|
||||
void dcs_init_TotalSize_Cfg(uint32_t total_size_Mbytes)
|
||||
{
|
||||
|
||||
dbgprintf(DCS_DBG_ASSESS_CONFIG, "Memory_size: %llu bytes\n",
|
||||
(((uint64_t)total_size_Mbytes) * MEG * NUM_AMCCS));
|
||||
|
||||
// (Units of 128 MBs in the register)
|
||||
dcs_reg_write(rAMCC_DRAMACCCTRL_ADDR, ((total_size_Mbytes / NUM_AMCCS) / DCS_NUM_MEG_IN_DRAM_BLK) - 1);
|
||||
dcs_reg_write(rAMCC_MCCCHNLDEC_ADDR, dcs_params.chnldec);
|
||||
|
||||
dbgprintf(DCS_DBG_ASSESS_CONFIG, "rAMCC_DRAMACCCTRL: 0x%08x\n", rAMCC_DRAMACCCTRL);
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 6: Switch from boot-clock speed to normal operation speed
|
||||
//================================================================================
|
||||
void dcs_init_Reenable_AMC_Scheduler(void)
|
||||
{
|
||||
// Wait 5 us before freq change to make sure all refreshes have been flushed
|
||||
dcs_spin(5, "After Refresh");
|
||||
|
||||
// Enable (again) the AMC Scheduler
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AMCCTRL, 0x00000003);
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 7: Setup registers for CA calibration for bucket 1
|
||||
//================================================================================
|
||||
void dcs_init_CA_Cal_Setup_Freq1(void)
|
||||
{
|
||||
// MR13 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xd, dcs_params.mr13cmd_step7);
|
||||
|
||||
if (izColdBoot) {
|
||||
if (izFPGA) {
|
||||
// MR11 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xb, 0x00);
|
||||
} else {
|
||||
// MR2 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x2, 0x52);
|
||||
// MR1 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x1, 0xae);
|
||||
// MR3 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x3, dcs_params.mr3cmd_step7);
|
||||
// MR22 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x16, dcs_params.mr22cmd);
|
||||
// MR11 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xb, dcs_params.mr11cmd);
|
||||
// MR12 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xc, 0x11);
|
||||
// MR14 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xe, 0x11);
|
||||
}
|
||||
dcs_reg_write_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x00000200);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x0200, 0x0000);
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 8: AMP Dynamic CA Vref Timing Calibration at Vmin 800MHz
|
||||
//================================================================================
|
||||
void dcs_init_CA_Cal_Freq1(void)
|
||||
{
|
||||
// Nothing to be done at this step for cold boot
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 9: Setup registers for DQ calibration for bucket 1
|
||||
//================================================================================
|
||||
void dcs_init_DQ_Cal_Setup_Freq1_a(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (izColdBoot) {
|
||||
// MR13 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0xd, dcs_params.mr13cmd_step9);
|
||||
}
|
||||
|
||||
dcs_spin(1, NULL);
|
||||
|
||||
if(izResume) {
|
||||
dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTEN, 0x00000002);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, 0x01008888);
|
||||
|
||||
for(i = AMP_DQ0 ; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(i), 0xFF00000C);
|
||||
for(i = AMP_CA ; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_SDLL_UPDATE_DEFER_EN(i), 0x00000000);
|
||||
for(i = AMP_DQ0; i < DCS_AMP_NUM_PHYS; i++)
|
||||
dcs_reg_write_all_chan(rDCS_AMP_MDLLOVRRD(i), 0x00000000);
|
||||
}
|
||||
}
|
||||
|
||||
// Caller code should change frequency to bucket 1
|
||||
void dcs_init_DQ_Cal_Setup_Freq1_b(void)
|
||||
{
|
||||
if (izColdBoot) {
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) {
|
||||
dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, dcs_params.freqchngctl_step9);
|
||||
dcs_reg_poll_all_chan(rDCS_MCU_FREQCHNGCTL, 0x10000, 0x00000);
|
||||
|
||||
// Wait 2us for the soc update to finish
|
||||
dcs_spin(2, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 10: PHY write DQ calibration
|
||||
//================================================================================
|
||||
void dcs_init_wrdq_skew(void)
|
||||
{
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQSDQ_SKEWCTL(AMP_DQ0), 0x06000000);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQSDQ_SKEWCTL(AMP_DQ1), 0x06000000);
|
||||
}
|
||||
|
||||
void dcs_init_post_wrlvl(void)
|
||||
{
|
||||
if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ0), 0x00000010);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ1), 0x00000010);
|
||||
}
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS0_WKPUPD, dcs_params.dqs0wkpupd);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS1_WKPUPD, dcs_params.dqs1wkpupd);
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 11: Setup registers for CA calibration for bucket 0
|
||||
//================================================================================
|
||||
void dcs_init_CA_Cal_Setup_Freq0(void)
|
||||
{
|
||||
if (izColdBoot) {
|
||||
|
||||
if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ0), 0x00000000);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_DQFLTCTRL(AMP_DQ1), 0x00000000);
|
||||
}
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS0_WKPUPD, 0x00000788);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS1_WKPUPD, 0x00000788);
|
||||
|
||||
// MR13 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, dcs_params.mr13cmd_step11);
|
||||
if (!izFPGA) {
|
||||
// MR2 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x02, dcs_params.mr2cmd_step11);
|
||||
// MR1 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x01, dcs_params.mr1cmd_step11);
|
||||
// MR3 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x03, dcs_params.mr3cmd_step11);
|
||||
}
|
||||
|
||||
// MR22 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x16, dcs_params.mr22cmd_step11);
|
||||
// MR11 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0b, (izFPGA) ? 0x00 : dcs_params.mr11cmd_step11);
|
||||
// MR12 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0c, dcs_params.mr12cmd_step11);
|
||||
// MR14 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0e, dcs_params.mr14cmd_step11);
|
||||
|
||||
if((dcs_params.supported_freqs & DCS_FREQ(1)) == 0) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x00000200);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_CAWRLVLSDLLCODE, 0x200, 0x000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 12: AMP Dynamic CA Timing Calibration
|
||||
//================================================================================
|
||||
|
||||
//================================================================================
|
||||
// Step 13: Setup registers for DQ calibration for bucket 0
|
||||
//================================================================================
|
||||
void dcs_init_DQ_Cal_Setup_Freq0_a(void)
|
||||
{
|
||||
if (izColdBoot) {
|
||||
// MR13 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, dcs_params.mr13cmd_step13);
|
||||
|
||||
// Wait 1 us
|
||||
dcs_spin(1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void dcs_init_DQ_Cal_Setup_Freq0_b(void)
|
||||
{
|
||||
if (izColdBoot) {
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) {
|
||||
dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, 0x00010000);
|
||||
dcs_reg_poll_all_chan(rDCS_MCU_FREQCHNGCTL, 0x10000, 0x00000);
|
||||
|
||||
// Wait 2us for the soc update to finish
|
||||
dcs_spin(2, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 14: AMP Dynamic DQ Calibration
|
||||
//================================================================================
|
||||
|
||||
//================================================================================
|
||||
// Step 15: Setup Registers for Boot
|
||||
//================================================================================
|
||||
void dcs_init_Reg_for_Boot(void)
|
||||
{
|
||||
if (dcs_cfg.chipRev > CHIP_REVISION_A0)
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_SPARE(0), 0x0000040e);
|
||||
|
||||
#ifndef DCS_RUN_AT_50MHZ
|
||||
if (izColdBoot) {
|
||||
// MR13 register
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, dcs_params.mr13cmd_step15);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(izFPGA && !(dcs_params.supported_freqs & DCS_FREQ(1)))
|
||||
dcs_mrcmd(MR_WRITE, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x0d, 0x50);
|
||||
|
||||
// Wait 1 us
|
||||
dcs_spin(1, NULL);
|
||||
|
||||
if (izColdBoot) {
|
||||
dcs_reg_write_all_chan(rDCS_MCU_FREQCHNGCTL, dcs_params.freqchngctl_step15);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ0), 0xff000008);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_WRDQDQSSDLLCTRL(AMP_DQ1), 0xff000008);
|
||||
|
||||
|
||||
#if !DCS_DO_CALIBRATION
|
||||
// skip these for all silicon targets, where calibration is performed, also skip for any Maui A1 target
|
||||
if((dcs_cfg.chipID != 0x8000) || (dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev >= CHIP_REVISION_B0)) {
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step15);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step15);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ0), dcs_params.rdsdllctrl_step15 & 0x7, 0x0);
|
||||
dcs_reg_poll_all_chan(rDCS_AMP_RDSDLLCTRL(AMP_DQ1), dcs_params.rdsdllctrl_step15 & 0x7, 0x0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALFULLSCANEN, 0x00000000);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_HWRDWRDQCALFULLSCANEN, 0x00000003);
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 16: Enable Other Features
|
||||
//================================================================================
|
||||
void dcs_init_MoreFeatures(void)
|
||||
{
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AREFPARAM, dcs_params.arefparam);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc2);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_QBREN, dcs_params.qbren_step16);
|
||||
|
||||
if (izColdBoot)
|
||||
dcs_enable_autorefresh();
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B0_DYN_ISEL_ASRTIME, dcs_params.b0dyniselasrtime);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B0_DYN_ISEL, dcs_params.b0dynisel);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_B1_DYN_ISEL, dcs_params.b1dynisel);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS0_DCD_IOCTL, 0x00030000);
|
||||
dcs_reg_write_all_chan(rDCS_AMPH_DQS1_DCD_IOCTL, 0x00030000);
|
||||
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 17: Enable Fast Critical Word Forwarding Feature
|
||||
//================================================================================
|
||||
void dcs_init_Fast_Critical_Word_Forwarding(void)
|
||||
{
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_MCU_QBRPARAM, dcs_params.qbrparam);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_QBREN, dcs_params.qbren);
|
||||
|
||||
dcs_reg_poll(rAMCC_MCCPWRONWAYCNTSTATUS_ADDR, 0x7fff7fff, 0x42104210);
|
||||
dcs_reg_write(rAMCC_MCC0QPROPCTRL_ADDR, 0x300011a2);
|
||||
dcs_reg_write(rAMCC_MCC1QPROPCTRL_ADDR, 0x300011a2);
|
||||
dcs_reg_write(rAMCC_MCCGEN_ADDR, dcs_params.mccgen);
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 18: Enable Power- and Clock-Gating Features; Config MCC and Global Timers
|
||||
//================================================================================
|
||||
void dcs_init_Gating_Global_Timers(void)
|
||||
{
|
||||
const struct dcs_memory_device_info *dev_info = dcs_get_memory_device_info();
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_AMP_AMPCLK(AMP_CA), dcs_params.caampclk);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_AMPCLK(AMP_DQ0), dcs_params.dqampclk);
|
||||
dcs_reg_write_all_chan(rDCS_AMP_AMPCLK(AMP_DQ1), dcs_params.dqampclk);
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTEN, dcs_params.pwrmngten);
|
||||
|
||||
|
||||
if(!izFPGA) {
|
||||
|
||||
dcs_reg_write_all_chan(rDCS_MCU_PWRMNGTPARAM_FREQ(0), 0x01800000);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_PSQWQCTL1, 0x01640120);
|
||||
}
|
||||
|
||||
// Global Timer Setup
|
||||
|
||||
if(dcs_cfg.chipID == 0x8000 && dcs_cfg.chipRev < CHIP_REVISION_B0) {
|
||||
dcs_reg_write(rGLBTIMER_PMGRWAKEUPCFG, 0x0000ff);
|
||||
dcs_reg_write(rGLBTIMER_MDLLTIMER, 0x000bb8); // 3000
|
||||
dcs_reg_write(rGLBTIMER_MDLLVOLTRAMPTIMER, 0x00004b); // 75
|
||||
dcs_reg_write(rGLBTIMER_CTRLUPDMASKTIMER, 0x00000f); // 15
|
||||
dcs_reg_write(rGLBTIMER_RDCALTIMER, 0x2dc6c0); // 3000000
|
||||
dcs_reg_write(rGLBTIMER_WRCALTIMER, 0x2dc6c0); // 3000000
|
||||
dcs_reg_write(rGLBTIMER_ZQCTIMER, 0x3d0900); // 4000000
|
||||
dcs_reg_write(rGLBTIMER_PERCAL_FREQCHNGTIMER, 0x000001); // 300000
|
||||
dcs_reg_write(rGLBTIMER_VOLTRAMPTIMER, 0x000001); // 300000
|
||||
dcs_reg_write(rGLBTIMER_IMPCALTIMER, 0x002ee0); // 12000
|
||||
} else {
|
||||
dcs_reg_write(rGLBTIMER_PMGRWAKEUPCFG, 0x0000ff);
|
||||
dcs_reg_write(rGLBTIMER_PREFREQ2ALLBANKDLY(0), 0x01500150);
|
||||
dcs_reg_write(rGLBTIMER_PREFREQ2ALLBANKDLY(1), 0x01500150);
|
||||
dcs_reg_write(rGLBTIMER_PREFREQCHNG2FREQCHNGDLY(0), 0x02a002a0);
|
||||
dcs_reg_write(rGLBTIMER_PREFREQCHNG2FREQCHNGDLY(1), 0x02a002a0);
|
||||
|
||||
dcs_reg_write(rGLBTIMER_CAL2PREFREQCHNGDLY(0), 0x00900090);
|
||||
dcs_reg_write(rGLBTIMER_CAL2PREFREQCHNGDLY(1), 0x00900090);
|
||||
dcs_reg_write(rGLBTIMER_FREQCHNG2PSTCALDLY(0), 0x01200120);
|
||||
dcs_reg_write(rGLBTIMER_FREQCHNG2PSTCALDLY(1), 0x01200120);
|
||||
|
||||
dcs_reg_write(rGLBTIMER_MDLLTIMER, 0x000bb8); // 3000
|
||||
dcs_reg_write(rGLBTIMER_MDLLVOLTRAMPTIMER, 0x00004b); // 75
|
||||
dcs_reg_write(rGLBTIMER_CTRLUPDMASKTIMER, 0x00000f); // 15
|
||||
// skip IDTTIMER setup per spec
|
||||
//dcs_reg_write(rGLBTIMER_IDTTIMER, 0x007530); // 30000
|
||||
dcs_reg_write(rGLBTIMER_RDCALTIMER, 0x2dc6c0); // 3000000
|
||||
dcs_reg_write(rGLBTIMER_WRCALTIMER, 0x2dc6c0); // 3000000
|
||||
|
||||
// <rdar://problem/23355941> Maui/Malta: Samsung DRAM workaround: disable hw zqcal
|
||||
if(! ((dev_info->vendor_id == JEDEC_LPDDR4_MANUF_ID_SAMSUNG) && (dev_info->rev_id == 5) && (dev_info->rev_id2 <= 1)) )
|
||||
dcs_reg_write(rGLBTIMER_ZQCTIMER, 0x3d0900); // 4000000
|
||||
|
||||
dcs_reg_write(rGLBTIMER_PERCAL_FREQCHNGTIMER, 0x0493e0); //
|
||||
dcs_reg_write(rGLBTIMER_VOLTRAMPTIMER, 0x0493e0); //
|
||||
dcs_reg_write(rGLBTIMER_IMPCALTIMER, 0x002ee0); // 12000
|
||||
|
||||
dcs_reg_write(rGLBTIMER_VOLTRAMP2ALLBANKDLY(0), 0x00d800d8);
|
||||
dcs_reg_write(rGLBTIMER_VOLTRAMP2ALLBANKDLY(1), 0x00d800d8);
|
||||
dcs_reg_write(rGLBTIMER_ALLBANK2PMGRACKDLY(0), 0x00900090);
|
||||
dcs_reg_write(rGLBTIMER_ALLBANK2PMGRACKDLY(1), 0x00900090);
|
||||
}
|
||||
// Dynamic Clk & Power Gating
|
||||
dcs_reg_write_all_chan(rDCS_MCU_AMCCLKPWRGATE, 0x050a0000);
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// Step 19: ODTS read & set interval for periodic MR4 on-die Temp sensor reading
|
||||
//================================================================================
|
||||
void dcs_init_ODTS(void)
|
||||
{
|
||||
uint8_t temp[16*8]; // Far more Channels/Ranks than we are likely ever to have/need
|
||||
// INSTEAD OF: uint8_t temp[dcs_cfg.num_dcs * dcs_cfg.num_rank];
|
||||
|
||||
// MR4 read to bring memory out of self-refresh
|
||||
dcs_mrcmd(MR_READ, dcs_cfg.num_dcs, dcs_cfg.num_rank, 0x4, (uintptr_t)temp);
|
||||
dcs_reg_write_all_chan(rDCS_MCU_ODTSZQC, dcs_params.odtszqc3);
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
@@ -0,0 +1,26 @@
|
||||
# Copyright (C) 2013 Apple Inc. All rights reserved.
|
||||
#
|
||||
# This document is the property of Apple Inc.
|
||||
# It is considered confidential and proprietary.
|
||||
#
|
||||
# This document may not be reproduced or transmitted in any form,
|
||||
# in whole or in part, without the express written permission of
|
||||
# Apple Inc.
|
||||
#
|
||||
LOCAL_DIR := $(GET_LOCAL_DIR)
|
||||
|
||||
OPTIONS += \
|
||||
WITH_HW_DCS=1
|
||||
|
||||
ALL_OBJS += \
|
||||
$(LOCAL_DIR)/dcs.o
|
||||
|
||||
ifeq ($(SUB_PLATFORM),s8000)
|
||||
ALL_OBJS += $(LOCAL_DIR)/dcs_init_lib_s8000.o
|
||||
else ifeq ($(SUB_PLATFORM),s8001)
|
||||
ALL_OBJS += $(LOCAL_DIR)/dcs_init_lib_s8001.o
|
||||
else ifeq ($(SUB_PLATFORM),s8003)
|
||||
ALL_OBJS += $(LOCAL_DIR)/dcs_init_lib_s8003.o
|
||||
else
|
||||
$(error "Unrecognized SUB_PLATFORM \"$(SUB_PLATFORM)\"")
|
||||
endif
|
||||
Reference in new issue
Block a user