blob: eec19bf8a9ab33e8f7789c40f0f89acff069bee6 [file] [log] [blame]
#include "../pwrcal-env.h"
#include "../pwrcal-rae.h"
#include "S5E8890-sfrbase.h"
#include "S5E8890-vclk-internal.h"
#ifdef PWRCAL_TARGET_LINUX
#include <soc/samsung/ect_parser.h>
#else
#include <mach/ect_parser.h>
#endif
#ifndef MHZ
#define MHZ ((unsigned long long)1000000)
#endif
#define __SMC_ALL (DMC_MISC_CCORE_BASE + 0x8000)
#define __PHY_ALL (DMC_MISC_CCORE_BASE + 0x4000)
#define __DMC_MISC_ALL (DMC_MISC_CCORE_BASE + 0x0000)
#define ModeRegAddr ((void *)(__SMC_ALL + 0x0000))
#define MprMrCtl ((void *)(__SMC_ALL + 0x0004))
#define ModeRegWrData ((void *)(__SMC_ALL + 0x0008))
#define DramTiming0_0 ((void *)(__SMC_ALL + 0x0058))
#define DramTiming1_0 ((void *)(__SMC_ALL + 0x005C))
#define DramTiming2_0 ((void *)(__SMC_ALL + 0x0060))
#define DramTiming3_0 ((void *)(__SMC_ALL + 0x0064))
#define DramTiming4_0 ((void *)(__SMC_ALL + 0x0068))
#define DramTiming5_0 ((void *)(__SMC_ALL + 0x006C))
#define DramTiming6_0 ((void *)(__SMC_ALL + 0x0070))
#define DramTiming7_0 ((void *)(__SMC_ALL + 0x0074))
#define DramTiming8_0 ((void *)(__SMC_ALL + 0x0078))
#define DramTiming9_0 ((void *)(__SMC_ALL + 0x007C))
#define DramDerateTiming0_0 ((void *)(__SMC_ALL + 0x0088))
#define DramDerateTiming1_0 ((void *)(__SMC_ALL + 0x008C))
#define Dimm0AutoRefTiming1_0 ((void *)(__SMC_ALL + 0x009C))
#define Dimm1AutoRefTiming1_0 ((void *)(__SMC_ALL + 0x00A4))
#define AutoRefTiming2_0 ((void *)(__SMC_ALL + 0x00A8))
#define PwrMgmtTiming0_0 ((void *)(__SMC_ALL + 0x00B8))
#define PwrMgmtTiming1_0 ((void *)(__SMC_ALL + 0x00BC))
#define PwrMgmtTiming2_0 ((void *)(__SMC_ALL + 0x00C0))
#define PwrMgmtTiming3_0 ((void *)(__SMC_ALL + 0x00C4))
#define TmrTrnInterval_0 ((void *)(__SMC_ALL + 0x00C8))
#define DvfsTrnCtl_0 ((void *)(__SMC_ALL + 0x00CC))
#define TrnTiming0_0 ((void *)(__SMC_ALL + 0x00D0))
#define TrnTiming1_0 ((void *)(__SMC_ALL + 0x00D4))
#define TrnTiming2_0 ((void *)(__SMC_ALL + 0x00D8))
#define DFIDelay1_0 ((void *)(__SMC_ALL + 0x00E0))
#define DFIDelay2_0 ((void *)(__SMC_ALL + 0x00E4))
#define DramTiming0_1 ((void *)(__SMC_ALL + 0x0108))
#define DramTiming1_1 ((void *)(__SMC_ALL + 0x010C))
#define DramTiming2_1 ((void *)(__SMC_ALL + 0x0110))
#define DramTiming3_1 ((void *)(__SMC_ALL + 0x0114))
#define DramTiming4_1 ((void *)(__SMC_ALL + 0x0118))
#define DramTiming5_1 ((void *)(__SMC_ALL + 0x011C))
#define DramTiming6_1 ((void *)(__SMC_ALL + 0x0120))
#define DramTiming7_1 ((void *)(__SMC_ALL + 0x0124))
#define DramTiming8_1 ((void *)(__SMC_ALL + 0x0128))
#define DramTiming9_1 ((void *)(__SMC_ALL + 0x012C))
#define DramDerateTiming0_1 ((void *)(__SMC_ALL + 0x0138))
#define DramDerateTiming1_1 ((void *)(__SMC_ALL + 0x013C))
#define Dimm0AutoRefTiming1_1 ((void *)(__SMC_ALL + 0x014C))
#define Dimm1AutoRefTiming1_1 ((void *)(__SMC_ALL + 0x0154))
#define AutoRefTiming2_1 ((void *)(__SMC_ALL + 0x0158))
#define PwrMgmtTiming0_1 ((void *)(__SMC_ALL + 0x0168))
#define PwrMgmtTiming1_1 ((void *)(__SMC_ALL + 0x016C))
#define PwrMgmtTiming2_1 ((void *)(__SMC_ALL + 0x0170))
#define PwrMgmtTiming3_1 ((void *)(__SMC_ALL + 0x0174))
#define TmrTrnInterval_1 ((void *)(__SMC_ALL + 0x0178))
#define DvfsTrnCtl_1 ((void *)(__SMC_ALL + 0x017C))
#define TrnTiming0_1 ((void *)(__SMC_ALL + 0x0180))
#define TrnTiming1_1 ((void *)(__SMC_ALL + 0x0184))
#define TrnTiming2_1 ((void *)(__SMC_ALL + 0x0188))
#define DFIDelay1_1 ((void *)(__SMC_ALL + 0x0190))
#define DFIDelay2_1 ((void *)(__SMC_ALL + 0x0194))
#define SMC_TmrTrnCtl ((void *)(__SMC_ALL + 0x01D0))
#define SMC_TmrTrnCtl_CH0 ((void *)(SMC0_BASE + 0x01D0))
#define SMC_TmrTrnCtl_CH1 ((void *)(SMC1_BASE + 0x01D0))
#define SMC_TmrTrnCtl_CH2 ((void *)(SMC2_BASE + 0x01D0))
#define SMC_TmrTrnCtl_CH3 ((void *)(SMC3_BASE + 0x01D0))
#define SMC_TrnStatus_CH0 ((void *)(SMC0_BASE + 0x01D8))
#define SMC_TrnStatus_CH1 ((void *)(SMC1_BASE + 0x01D8))
#define SMC_TrnStatus_CH2 ((void *)(SMC2_BASE + 0x01D8))
#define SMC_TrnStatus_CH3 ((void *)(SMC3_BASE + 0x01D8))
#define SMC_PwrMgmtMode_CH0 ((void *)(SMC0_BASE + 0x0238))
#define SMC_PwrMgmtMode_CH1 ((void *)(SMC1_BASE + 0x0238))
#define SMC_PwrMgmtMode_CH2 ((void *)(SMC2_BASE + 0x0238))
#define SMC_PwrMgmtMode_CH3 ((void *)(SMC3_BASE + 0x0238))
#define DMC_MISC_CON0 ((void *)(__DMC_MISC_ALL + 0x0014))
#define DMC_MISC_CON1 ((void *)(__DMC_MISC_ALL + 0x003C))
#define DMC_MISC_CON1_CH0 ((void *)(DMC_MISC0_BASE + 0x003C))
#define DMC_MISC_CON1_CH1 ((void *)(DMC_MISC1_BASE + 0x003C))
#define DMC_MISC_CON1_CH2 ((void *)(DMC_MISC2_BASE + 0x003C))
#define DMC_MISC_CON1_CH3 ((void *)(DMC_MISC3_BASE + 0x003C))
#define MRS_DATA1 ((void *)(__DMC_MISC_ALL + 0x0054))
#define MRS_DATA1_CH0 ((void *)(DMC_MISC0_BASE + 0x0054))
#define MRS_DATA1_CH1 ((void *)(DMC_MISC1_BASE + 0x0054))
#define MRS_DATA1_CH2 ((void *)(DMC_MISC2_BASE + 0x0054))
#define MRS_DATA1_CH3 ((void *)(DMC_MISC3_BASE + 0x0054))
#define CG_CTRL_VAL_DDRPHY0 ((void *)(CMU_MIF0_BASE + 0x0A08))
#define CG_CTRL_VAL_DDRPHY1 ((void *)(CMU_MIF1_BASE + 0x0A08))
#define CG_CTRL_VAL_DDRPHY2 ((void *)(CMU_MIF2_BASE + 0x0A08))
#define CG_CTRL_VAL_DDRPHY3 ((void *)(CMU_MIF3_BASE + 0x0A08))
#define CG_CTRL_MAN_DDRPHY0 ((void *)(CMU_MIF0_BASE + 0x1A08))
#define CG_CTRL_MAN_DDRPHY1 ((void *)(CMU_MIF1_BASE + 0x1A08))
#define CG_CTRL_MAN_DDRPHY2 ((void *)(CMU_MIF2_BASE + 0x1A08))
#define CG_CTRL_MAN_DDRPHY3 ((void *)(CMU_MIF3_BASE + 0x1A08))
#define PMU_DREX_CALIBRATION1 ((void *)(PMU_ALIVE_BASE + 0x09a4))
#define PMU_DREX_CALIBRATION2 ((void *)(PMU_ALIVE_BASE + 0x09a8))
#define PMU_DREX_CALIBRATION3 ((void *)(PMU_ALIVE_BASE + 0x09ac))
enum mif_timing_set_idx {
MIF_TIMING_SET_0,
MIF_TIMING_SET_1
};
enum smc_dram_mode_register {
DRAM_MR0,
DRAM_MR1,
DRAM_MR2,
DRAM_MR3,
DRAM_MR4,
DRAM_MR5,
DRAM_MR6,
DRAM_MR7,
DRAM_MR8,
DRAM_MR9,
DRAM_MR10,
DRAM_MR11,
DRAM_MR12,
DRAM_MR13,
DRAM_MR14,
DRAM_MR15,
DRAM_MR16,
DRAM_MR17,
DRAM_MR18,
DRAM_MR19,
DRAM_MR20,
DRAM_MR21,
DRAM_MR22,
DRAM_MR23,
DRAM_MR24,
DRAM_MR25,
DRAM_MR32 = 32,
DRAM_MR40 = 40,
};
enum timing_parameter_column {
DramTiming0,
DramTiming1,
DramTiming2,
DramTiming3,
DramTiming4,
DramTiming5,
DramTiming6,
DramTiming7,
DramTiming8,
DramTiming9,
DramDerateTiming0,
DramDerateTiming1,
Dimm0AutoRefTiming1,
Dimm1AutoRefTiming1,
AutoRefTiming2,
PwrMgmtTiming0,
PwrMgmtTiming1,
PwrMgmtTiming2,
PwrMgmtTiming3,
TmrTrnInterval,
DFIDelay1,
DFIDelay2,
DvfsTrnCtl,
TrnTiming0,
TrnTiming1,
TrnTiming2,
DVFSn_CON0,
DVFSn_CON1,
DVFSn_CON2,
DVFSn_CON3,
DVFSn_CON4,
DirectCmd_MR1,
DirectCmd_MR2,
DirectCmd_MR3,
DirectCmd_MR11,
DirectCmd_MR12,
DirectCmd_MR14,
DirectCmd_MR22,
num_of_g_smc_dfs_table_column = TrnTiming2 - DramTiming0 + 1,
num_of_g_phy_dfs_table_column = DVFSn_CON4 - DVFSn_CON0 + 1,
num_of_g_dram_dfs_table_column = DirectCmd_MR22 - DirectCmd_MR1 + 1,
num_of_dram_parameter = num_of_g_smc_dfs_table_column + num_of_g_phy_dfs_table_column + num_of_g_dram_dfs_table_column,
};
/******************************************************************************
*
*
*
*****************************************************************************/
typedef volatile unsigned int rw_bf_t;
typedef const unsigned int ro_bf_t;
typedef const unsigned int wo_bf_t;
typedef union {
volatile unsigned int data;
struct {
rw_bf_t rdlvl_periodic_incr_adj : (6 - 0 + 1);
rw_bf_t glvl_periodic_incr_adj : (13 - 7 + 1);
rw_bf_t glvl_start_adj : (15 - 14 + 1);
rw_bf_t rdlvl_pass_adj : (19 - 16 + 1);
rw_bf_t rdlvl_incr_adj : (26 - 20 + 1);
ro_bf_t reserved_27 : (27 - 27 + 1);
rw_bf_t rdlvl_start_adj : (31 - 28 + 1);
} bitfield;
} phy_cal_con1_t; //0x0008
typedef union {
volatile unsigned int data;
struct {
rw_bf_t dvfs0_readadj : (3 - 0 + 1);
rw_bf_t dvfs0_readduradj : (7 - 4 + 1);
rw_bf_t dvfs0_gateadj : (11 - 8 + 1);
rw_bf_t dvfs0_gateduradj : (15 - 12 + 1);
rw_bf_t dvfs0_shgate : (16 - 16 + 1);
rw_bf_t dvfs0_dgatelvl_en : (17 - 17 + 1);
ro_bf_t reserved_18_23 : (23 - 18 + 1);
rw_bf_t dvfs0_pulld_dqs : (25 - 24 + 1);
ro_bf_t reserved_26_28 : (28 - 26 + 1);
rw_bf_t dvfs0_rodt_disable : (29 - 29 + 1);
rw_bf_t dvfs0_dfdqs : (30 - 30 + 1);
rw_bf_t dvfs0_cmosrcv : (31 - 31 + 1);
} bitfield;
} phy_dvfs0_con2_t; //0x00CC
typedef union {
volatile unsigned int data;
struct {
rw_bf_t dvfs0_zq_ds0_pdds : (2 - 0 + 1);
rw_bf_t dvfs0_zq_ds0_dds : (5 - 3 + 1);
rw_bf_t dvfs0_zq_ds1_pdds : (8 - 6 + 1);
rw_bf_t dvfs0_zq_ds1_dds : (11 - 9 + 1);
rw_bf_t dvfs0_zq_mode_pdds : (14 - 12 + 1);
rw_bf_t dvfs0_zq_mode_dds : (17 - 15 + 1);
ro_bf_t reserved_18_19 : (19 - 18 + 1);
rw_bf_t dvfs0_ds0_vref : (25 - 20 + 1);
rw_bf_t dvfs0_ds1_vref : (31 - 26 + 1);
} bitfield;
} phy_dvfs0_con3_t;
typedef union {
volatile unsigned int data;
struct {
rw_bf_t dvfs0_phyupd_req_cycle : (5 - 0 + 1);
ro_bf_t reserved_6_7 : (7 - 6 + 1);
rw_bf_t dvfs0_mcupd_req_cycle : (13 - 8 + 1);
ro_bf_t reserved_14_15 : (15 - 14 + 1);
rw_bf_t dvfs0_zq_ds0_term : (18 - 16 + 1);
rw_bf_t dvfs0_zq_ds1_term : (21 - 19 + 1);
ro_bf_t reserved_22_31 : (31 - 22 + 1);
} bitfield;
} phy_dvfs0_con4_t;
typedef union {
volatile unsigned int data;
struct {
ro_bf_t reserved_0 : (0 - 0 + 1);
rw_bf_t zq_manual_str : (1 - 1 + 1);
rw_bf_t zq_manual_mode : (3 - 2 + 1);
rw_bf_t zq_udt_dly : (11 - 4 + 1);
rw_bf_t zq_force_impp : (14 - 12 + 1);
rw_bf_t zq_force_impn : (17 - 15 + 1);
rw_bf_t zq_clk_div_en : (18 - 18 + 1);
rw_bf_t zq_mode_noterm : (19 - 19 + 1);
rw_bf_t zq_rgddr3 : (20 - 20 + 1);
rw_bf_t zq_mode_term : (23 - 21 + 1);
rw_bf_t zq_mode_dds : (26 - 24 + 1);
rw_bf_t zq_clk_en : (27 - 27 + 1);
rw_bf_t zq_mode_pdds : (30 - 28 + 1);
rw_bf_t zq_mode_lp4 : (31 - 31 + 1);
} bitfield;
} phy_zq_con0_t;
typedef struct phy_dvfs0_con3_t DVFS_CON3;
typedef struct phy_dvfs0_con4_t DVFS_CON4;
typedef struct phy_zq_con0_t ZQ_CON0;
/******************************************************************************
*
* ECT related resource
*
*****************************************************************************/
struct smc_dfs_table {
unsigned int DramTiming0;
unsigned int DramTiming1;
unsigned int DramTiming2;
unsigned int DramTiming3;
unsigned int DramTiming4;
unsigned int DramTiming5;
unsigned int DramTiming6;
unsigned int DramTiming7;
unsigned int DramTiming8;
unsigned int DramTiming9;
unsigned int DramDerateTiming0;
unsigned int DramDerateTiming1;
unsigned int Dimm0AutoRefTiming1;
unsigned int Dimm1AutoRefTiming1;
unsigned int AutoRefTiming2;
unsigned int PwrMgmtTiming0;
unsigned int PwrMgmtTiming1;
unsigned int PwrMgmtTiming2;
unsigned int PwrMgmtTiming3;
unsigned int TmrTrnInterval;
unsigned int DFIDelay1;
unsigned int DFIDelay2;
unsigned int DvfsTrnCtl;
unsigned int TrnTiming0;
unsigned int TrnTiming1;
unsigned int TrnTiming2;
};
struct phy_dfs_table {
unsigned int DVFSn_CON0;
unsigned int DVFSn_CON1;
unsigned int DVFSn_CON2;
unsigned int DVFSn_CON3;
unsigned int DVFSn_CON4;
};
struct dram_dfs_table {
unsigned char DirectCmd_MR1;
unsigned char DirectCmd_MR2;
unsigned char DirectCmd_MR3;
unsigned char DirectCmd_MR11;
unsigned char DirectCmd_MR12;
unsigned char DirectCmd_MR14;
unsigned char DirectCmd_MR22;
};
/******************************************************************************
*
* SMC related resource
*
*****************************************************************************/
typedef enum {
SMC_BYTE_0,
SMC_BYTE_1,
SMC_BYTE_ALL,
} smc_byte_t;
typedef enum {
SMC_CH_0,
SMC_CH_1,
SMC_CH_2,
SMC_CH_3,
SMC_CH_ALL,
} smc_ch_t;
typedef enum {
SMC_RANK_0 = 0x1,
SMC_RANK_1 = 0x2,
SMC_RANK_ALL = 0x3,
} smc_rank_t;
struct smc_timing_params_t {
unsigned int DramTiming0;
unsigned int DramTiming1;
unsigned int DramTiming2;
unsigned int DramTiming3;
unsigned int DramTiming4;
unsigned int DramTiming5;
unsigned int DramTiming6;
unsigned int DramTiming7;
unsigned int DramTiming8;
unsigned int DramTiming9;
unsigned int DramDerateTiming0;
unsigned int DramDerateTiming1;
unsigned int Dimm0AutoRefTiming1;
unsigned int Dimm1AutoRefTiming1;
unsigned int AutoRefTiming2;
unsigned int PwrMgmtTiming0;
unsigned int PwrMgmtTiming1;
unsigned int PwrMgmtTiming2;
unsigned int PwrMgmtTiming3;
unsigned int TmrTrnInterval;
unsigned int DFIDelay1;
unsigned int DFIDelay2;
unsigned int DvfsTrnCtl;
unsigned int TrnTiming0;
unsigned int TrnTiming1;
unsigned int TrnTiming2;
};
struct smc_qos_params_t {
unsigned int Scheduler[5];
unsigned int ReadToken;
unsigned int WriteToken;
unsigned int HurryReadToken[3];
unsigned int HurryWriteToken[3];
};
struct smc_page_policy_params_t {
unsigned char autopchgdis;
unsigned char level3pchgtoadaptdis;
unsigned char level3pchgdis;
unsigned char level2pchgdis;
};
struct smc_pm_params_t {
unsigned char pd_idle_threshold;
unsigned char flush_wr_sre;
unsigned char hw_sre;
unsigned char pchg_pd;
unsigned char global_clk_gate;
unsigned char q_channel;
unsigned char phy_cg;
};
struct smc_dfi_params_t {
unsigned char freq_ratio;
unsigned char t_dram_clk_enable;
unsigned char t_dram_clk_disable;
};
struct smc_thermal_params_t {
unsigned char rate;
unsigned char poll;
unsigned char range;
unsigned char derate;
};
struct smc_aref_params_t {
unsigned char t_refi;
unsigned char pb_aref;
unsigned char payback_sref;
unsigned char staggered_aref;
};
struct smc_trn_lpi_t {
unsigned int enable;
unsigned char time;
};
struct smc_trn_periodic_t {
unsigned int enable;
unsigned char offset;
};
struct smc_trn_params_t {
struct smc_trn_lpi_t lpi;
struct smc_trn_periodic_t periodic;
};
struct smc_config_t {
unsigned int magic;
unsigned char LP4CaSwizzleEn;
unsigned char LP4DqSwizzleEn;
unsigned char cmd_cancel;
unsigned char TrrdRankToRankEn;
unsigned char DbiEn;
unsigned char DataMaskEn;
unsigned char t_zqcal;
struct smc_trn_params_t trn;
struct smc_aref_params_t aref;
struct smc_thermal_params_t thermal;
struct smc_dfi_params_t dfi;
struct smc_pm_params_t pm;
struct smc_page_policy_params_t page_policy;
struct smc_qos_params_t qos;
struct smc_timing_params_t timing;
};
/******************************************************************************
*
* PHY related resource
*
*****************************************************************************/
#define NUM_OF_TRN_OFFSET_INFO (2)
#define NUM_OF_TRN_DLL_INFO (1)
#define NUM_OF_TRN_GATE_INFO (4)
#define NUM_OF_TRN_RD_DESKEW_INFO (9)
#define NUM_OF_TRN_RD_DESKEWQ_INFO (2)
#define NUM_OF_TRN_WR_DESKEW_INFO (9)
#define PHY_OFFSET_CONFIG_MAGIC (0x74664f40) /* @Ofst */
#define PHY_CAL_CON1_OFFSET (0x0008)
#define PHY_OFFSETC_CON1_OFFSET (0x0040)
#define PHY_DVFS_CON ((void *)(__PHY_ALL + 0x00B8))
#define PHY_DVFS_CON_CH0 ((void *)(LPDDR4_PHY0_BASE + 0x00B8))
#define PHY_DVFS0_CON0_CH0 ((void *)(LPDDR4_PHY0_BASE + 0x00BC))
#define PHY_DVFS0_CON1_CH0 ((void *)(LPDDR4_PHY0_BASE + 0x00C4))
#define PHY_DVFS0_CON2_CH0 ((void *)(LPDDR4_PHY0_BASE + 0x00CC))
#define PHY_DVFS0_CON3_CH0 ((void *)(LPDDR4_PHY0_BASE + 0x00D4))
#define PHY_DVFS0_CON4_CH0 ((void *)(LPDDR4_PHY0_BASE + 0x00DC))
#define PHY_DVFS_CON_CH1 ((void *)(LPDDR4_PHY1_BASE + 0x00B8))
#define PHY_DVFS0_CON0_CH1 ((void *)(LPDDR4_PHY1_BASE + 0x00BC))
#define PHY_DVFS0_CON1_CH1 ((void *)(LPDDR4_PHY1_BASE + 0x00C4))
#define PHY_DVFS0_CON2_CH1 ((void *)(LPDDR4_PHY1_BASE + 0x00CC))
#define PHY_DVFS0_CON3_CH1 ((void *)(LPDDR4_PHY1_BASE + 0x00D4))
#define PHY_DVFS0_CON4_CH1 ((void *)(LPDDR4_PHY1_BASE + 0x00DC))
#define PHY_DVFS_CON_CH2 ((void *)(LPDDR4_PHY2_BASE + 0x00B8))
#define PHY_DVFS0_CON0_CH2 ((void *)(LPDDR4_PHY2_BASE + 0x00BC))
#define PHY_DVFS0_CON1_CH2 ((void *)(LPDDR4_PHY2_BASE + 0x00C4))
#define PHY_DVFS0_CON2_CH2 ((void *)(LPDDR4_PHY2_BASE + 0x00CC))
#define PHY_DVFS0_CON3_CH2 ((void *)(LPDDR4_PHY2_BASE + 0x00D4))
#define PHY_DVFS0_CON4_CH2 ((void *)(LPDDR4_PHY2_BASE + 0x00DC))
#define PHY_DVFS_CON_CH3 ((void *)(LPDDR4_PHY3_BASE + 0x00B8))
#define PHY_DVFS0_CON0_CH3 ((void *)(LPDDR4_PHY3_BASE + 0x00BC))
#define PHY_DVFS0_CON1_CH3 ((void *)(LPDDR4_PHY3_BASE + 0x00C4))
#define PHY_DVFS0_CON2_CH3 ((void *)(LPDDR4_PHY3_BASE + 0x00CC))
#define PHY_DVFS0_CON3_CH3 ((void *)(LPDDR4_PHY3_BASE + 0x00D4))
#define PHY_DVFS0_CON4_CH3 ((void *)(LPDDR4_PHY3_BASE + 0x00DC))
#define PHY_DVFS1_CON0_CH0 ((void *)(LPDDR4_PHY0_BASE + 0x00C0))
#define PHY_DVFS1_CON1_CH0 ((void *)(LPDDR4_PHY0_BASE + 0x00C8))
#define PHY_DVFS1_CON2_CH0 ((void *)(LPDDR4_PHY0_BASE + 0x00D0))
#define PHY_DVFS1_CON3_CH0 ((void *)(LPDDR4_PHY0_BASE + 0x00D8))
#define PHY_DVFS1_CON4_CH0 ((void *)(LPDDR4_PHY0_BASE + 0x00E0))
#define PHY_DVFS1_CON0_CH1 ((void *)(LPDDR4_PHY1_BASE + 0x00C0))
#define PHY_DVFS1_CON1_CH1 ((void *)(LPDDR4_PHY1_BASE + 0x00C8))
#define PHY_DVFS1_CON2_CH1 ((void *)(LPDDR4_PHY1_BASE + 0x00D0))
#define PHY_DVFS1_CON3_CH1 ((void *)(LPDDR4_PHY1_BASE + 0x00D8))
#define PHY_DVFS1_CON4_CH1 ((void *)(LPDDR4_PHY1_BASE + 0x00E0))
#define PHY_DVFS1_CON0_CH2 ((void *)(LPDDR4_PHY2_BASE + 0x00C0))
#define PHY_DVFS1_CON1_CH2 ((void *)(LPDDR4_PHY2_BASE + 0x00C8))
#define PHY_DVFS1_CON2_CH2 ((void *)(LPDDR4_PHY2_BASE + 0x00D0))
#define PHY_DVFS1_CON3_CH2 ((void *)(LPDDR4_PHY2_BASE + 0x00D8))
#define PHY_DVFS1_CON4_CH2 ((void *)(LPDDR4_PHY2_BASE + 0x00E0))
#define PHY_DVFS1_CON0_CH3 ((void *)(LPDDR4_PHY3_BASE + 0x00C0))
#define PHY_DVFS1_CON1_CH3 ((void *)(LPDDR4_PHY3_BASE + 0x00C8))
#define PHY_DVFS1_CON2_CH3 ((void *)(LPDDR4_PHY3_BASE + 0x00D0))
#define PHY_DVFS1_CON3_CH3 ((void *)(LPDDR4_PHY3_BASE + 0x00D8))
#define PHY_DVFS1_CON4_CH3 ((void *)(LPDDR4_PHY3_BASE + 0x00E0))
typedef enum {
PHY_BYTE_0,
PHY_BYTE_1,
PHY_BYTE_ALL,
} phy_byte_t;
typedef enum {
PHY_CH_0,
PHY_CH_1,
PHY_CH_2,
PHY_CH_3,
PHY_CH_ALL,
} phy_ch_t;
typedef enum {
PHY_RANK_0,
PHY_RANK_1,
PHY_RANK_ALL,
} phy_rank_t;
typedef unsigned short phy_trn_dll_size_t;
typedef unsigned char phy_trn_info_size_t;
struct phy_trn_gate_info_t {
phy_trn_info_size_t cycle[PHY_BYTE_ALL];
phy_trn_info_size_t center[PHY_BYTE_ALL];
};
struct phy_trn_read_dqs_info_t {
phy_trn_info_size_t left[PHY_BYTE_ALL];
phy_trn_info_size_t center[PHY_BYTE_ALL];
};
struct phy_trn_read_info_t {
phy_trn_info_size_t deskewc[NUM_OF_TRN_RD_DESKEW_INFO][PHY_BYTE_ALL];
phy_trn_info_size_t deskewl[NUM_OF_TRN_RD_DESKEW_INFO][PHY_BYTE_ALL];
struct phy_trn_read_dqs_info_t dqs;
};
struct phy_trn_write_info_t {
phy_trn_info_size_t deskewc[NUM_OF_TRN_WR_DESKEW_INFO][PHY_BYTE_ALL];
phy_trn_info_size_t deskewl[NUM_OF_TRN_WR_DESKEW_INFO][PHY_BYTE_ALL];
};
struct phy_trn_offset_info_t {
phy_trn_info_size_t read[PHY_BYTE_ALL];
phy_trn_info_size_t write[PHY_BYTE_ALL];
};
struct phy_trn_data_t {
phy_trn_dll_size_t dll;
struct phy_trn_offset_info_t offset;
struct phy_trn_gate_info_t gate[PHY_RANK_ALL];
struct phy_trn_read_info_t read;
struct phy_trn_write_info_t write[PHY_RANK_ALL];
};
struct phy_vwm_t {
signed char left;
signed char right;
};
struct phy_vwm_params_t {
struct phy_vwm_t read[PHY_CH_ALL][PHY_BYTE_ALL];
struct phy_vwm_t write[PHY_CH_ALL][PHY_BYTE_ALL];
struct phy_vwm_t command[PHY_CH_ALL];
};
struct phy_adjust_params_t {
unsigned char rdlvl_start_adj;
unsigned char rdlvl_incr_adj;
unsigned char rdlvl_periodic_incr_adj;
unsigned char rdlvl_pass_adj;
unsigned char glvl_start_adj;
unsigned char glvl_periodic_incr_adj;
unsigned char gateduradj;
unsigned char gateadj;
unsigned char readduradj;
unsigned char readadj;
unsigned char read_width;
};
struct phy_pd_params_t {
unsigned char command_io;
unsigned char data_io;
unsigned char data_clk;
unsigned char phy_logic_clk;
unsigned char mdll_clk;
unsigned char zq_vref[4][2];
};
struct phy_io_params_t {
unsigned char ca_pdds[PHY_CH_ALL];
unsigned char ca_dds[PHY_CH_ALL];
unsigned char dq_pdds[PHY_CH_ALL][PHY_BYTE_ALL];
unsigned char dq_dds[PHY_CH_ALL][PHY_BYTE_ALL];
unsigned char reset_dds;
unsigned char cke_dds[PHY_RANK_ALL];
unsigned char term[PHY_CH_ALL][PHY_BYTE_ALL];
unsigned char vref[PHY_CH_ALL][PHY_BYTE_ALL];
unsigned char offsetr[PHY_CH_ALL][PHY_BYTE_ALL];
unsigned char offsetw[PHY_CH_ALL][PHY_BYTE_ALL];
unsigned int ext_dds;
};
struct phy_dvfs_params_t {
unsigned int DVFSn_CON0;
unsigned int DVFSn_CON1;
unsigned int DVFSn_CON2;
unsigned int DVFSn_CON3;
unsigned int DVFSn_CON4;
};
struct phy_offset_config_t {
unsigned int magic;
unsigned short lock[PHY_CH_ALL];
signed char read[PHY_CH_ALL][PHY_BYTE_ALL];
signed char write[PHY_CH_ALL][PHY_BYTE_ALL];
unsigned char dq[PHY_CH_ALL];
signed char gate[PHY_CH_ALL][PHY_BYTE_ALL];
signed char command[PHY_CH_ALL];
signed char oen[PHY_CH_ALL][PHY_BYTE_ALL];
};
struct phy_config_t {
unsigned int magic;
unsigned short freq;
unsigned char training;
unsigned char update_mode;
unsigned char update_time;
unsigned char update_range;
unsigned char update_interval;
unsigned char write_postamble;
unsigned char otf;
unsigned char bl;
unsigned char rl;
unsigned char gate_read_check;
unsigned char dgate;
unsigned char freq_offset_calc;
unsigned char cal_vtc_en;
unsigned char ca_swap;
unsigned char phy_update_request_cycle;
unsigned char mc_update_request_cycle;
unsigned char dvfs_wait_cycle;
unsigned char update_ack_cycle;
unsigned char rank_en;
unsigned char clkm_cg_en_sw;
unsigned char fsbst;
unsigned char ctrl_ref;
struct phy_vwm_params_t vwm;
struct phy_pd_params_t pd;
struct phy_io_params_t io;
struct phy_adjust_params_t adjust;
struct phy_dvfs_params_t dvfs[2];
struct phy_trn_data_t trn_data[PHY_CH_ALL];
};
/******************************************************************************
*
* LPDDR4 related resource
*
*****************************************************************************/
typedef enum {
LPDDR4_CH_0,
LPDDR4_CH_1,
LPDDR4_CH_2,
LPDDR4_CH_3,
LPDDR4_CH_ALL,
} lpddr4_ch_t;
typedef enum {
LPDDR4_RANK_0,
LPDDR4_RANK_1,
LPDDR4_RANK_ALL,
} lpddr4_rank_t;
struct read_pattern_t {
unsigned char data[2];
unsigned char invert[2];
};
struct write_pattern_t {
unsigned char data[16];
unsigned char mask[16];
};
struct mr_params_t {
unsigned char reg1;
unsigned char reg2;
unsigned char reg3;
unsigned char reg11[LPDDR4_CH_ALL][LPDDR4_RANK_ALL];
unsigned char reg12[LPDDR4_CH_ALL][LPDDR4_RANK_ALL];
unsigned char reg14[LPDDR4_CH_ALL][LPDDR4_RANK_ALL];
unsigned char reg22[LPDDR4_CH_ALL][LPDDR4_RANK_ALL];
};
struct lpddr4_config_t {
unsigned int magic;
unsigned short freq;
unsigned char rro;
unsigned char dmd;
unsigned char training;
unsigned char manufacturer;
struct mr_params_t mode;
struct read_pattern_t read_pattern;
struct write_pattern_t write_pattern;
};
/******************************************************************************
*
* VREF related resource
*
*****************************************************************************/
#define MAX_NUM_DVFS_LEVEL (20)
struct vref_search_t {
unsigned short min_step :4;
unsigned short max_step :4;
unsigned short search_step :4;
unsigned short trial :4;
};
struct vref_info_t {
unsigned char vref;
unsigned char center;
struct vref_search_t search;
};
struct vref_config_t {
unsigned char num_of_level;
struct vref_info_t read;
unsigned char vref_read[PHY_CH_ALL][MAX_NUM_DVFS_LEVEL];
struct vref_info_t write;
unsigned char vref_write[PHY_CH_ALL][MAX_NUM_DVFS_LEVEL];
};
/******************************************************************************
*
*
*
*****************************************************************************/
struct drampara_config_t {
struct smc_config_t smc;
struct phy_config_t phy;
struct lpddr4_config_t lpddr4;
struct phy_offset_config_t phy_offset;
struct vref_config_t vref;
};
/******************************************************************************
*
*
*
*****************************************************************************/
void *PHY_CAL_CON1[] = {
(void *)(LPDDR4_PHY0_BASE + PHY_CAL_CON1_OFFSET),
(void *)(LPDDR4_PHY1_BASE + PHY_CAL_CON1_OFFSET),
(void *)(LPDDR4_PHY2_BASE + PHY_CAL_CON1_OFFSET),
(void *)(LPDDR4_PHY3_BASE + PHY_CAL_CON1_OFFSET),
};
void *PHY_OFFSETC_CON1[] = {
(void *)(LPDDR4_PHY0_BASE + PHY_OFFSETC_CON1_OFFSET),
(void *)(LPDDR4_PHY1_BASE + PHY_OFFSETC_CON1_OFFSET),
(void *)(LPDDR4_PHY2_BASE + PHY_OFFSETC_CON1_OFFSET),
(void *)(LPDDR4_PHY3_BASE + PHY_OFFSETC_CON1_OFFSET),
};
void *PHY_ZQ_CON0[] = {
((void *)(LPDDR4_PHY0_BASE + 0x03C8)),
((void *)(LPDDR4_PHY1_BASE + 0x03C8)),
((void *)(LPDDR4_PHY2_BASE + 0x03C8)),
((void *)(LPDDR4_PHY3_BASE + 0x03C8)),
};
void *PHY_DVFS0_CON0[] = {PHY_DVFS0_CON0_CH0, PHY_DVFS0_CON0_CH1, PHY_DVFS0_CON0_CH2, PHY_DVFS0_CON0_CH3};
void *PHY_DVFS0_CON1[] = {PHY_DVFS0_CON1_CH0, PHY_DVFS0_CON1_CH1, PHY_DVFS0_CON1_CH2, PHY_DVFS0_CON1_CH3};
void *PHY_DVFS0_CON2[] = {PHY_DVFS0_CON2_CH0, PHY_DVFS0_CON2_CH1, PHY_DVFS0_CON2_CH2, PHY_DVFS0_CON2_CH3};
void *PHY_DVFS0_CON3[] = {PHY_DVFS0_CON3_CH0, PHY_DVFS0_CON3_CH1, PHY_DVFS0_CON3_CH2, PHY_DVFS0_CON3_CH3};
void *PHY_DVFS0_CON4[] = {PHY_DVFS0_CON4_CH0, PHY_DVFS0_CON4_CH1, PHY_DVFS0_CON4_CH2, PHY_DVFS0_CON4_CH3};
void *PHY_DVFS1_CON0[] = {PHY_DVFS1_CON0_CH0, PHY_DVFS1_CON0_CH1, PHY_DVFS1_CON0_CH2, PHY_DVFS1_CON0_CH3};
void *PHY_DVFS1_CON1[] = {PHY_DVFS1_CON1_CH0, PHY_DVFS1_CON1_CH1, PHY_DVFS1_CON1_CH2, PHY_DVFS1_CON1_CH3};
void *PHY_DVFS1_CON2[] = {PHY_DVFS1_CON2_CH0, PHY_DVFS1_CON2_CH1, PHY_DVFS1_CON2_CH2, PHY_DVFS1_CON2_CH3};
void *PHY_DVFS1_CON3[] = {PHY_DVFS1_CON3_CH0, PHY_DVFS1_CON3_CH1, PHY_DVFS1_CON3_CH2, PHY_DVFS1_CON3_CH3};
void *PHY_DVFS1_CON4[] = {PHY_DVFS1_CON4_CH0, PHY_DVFS1_CON4_CH1, PHY_DVFS1_CON4_CH2, PHY_DVFS1_CON4_CH3};
static struct smc_dfs_table *g_smc_dfs_table;
static struct phy_dfs_table *g_phy_dfs_table;
static struct dram_dfs_table *g_dram_dfs_table;
static unsigned long long *mif_freq_to_level;
static int num_mif_freq_to_level;
static unsigned int query_key;
static const unsigned long long mif_freq_to_level_switch[] = {
936 * MHZ, /* BUS3_PLL SW 936 */
528 * MHZ, /* BUS0_PLL SW 528 */
};
static unsigned long config_base;
static struct drampara_config_t *drampara_config;
#ifndef PWRCAL_TARGET_LINUX
/******************************************************************************
*
* @fn get_smc_dfs_table
*
* @brief
*
* @param
*
* @return
*
*****************************************************************************/
void *get_smc_dfs_table(void)
{
return((void *)g_smc_dfs_table);
}
/******************************************************************************
*
* @fn get_phy_dfs_table
*
* @brief
*
* @param
*
* @return
*
*****************************************************************************/
void *get_phy_dfs_table(void)
{
return((void *)g_phy_dfs_table);
}
/******************************************************************************
*
* @fn get_dram_dfs_table
*
* @brief
*
* @param
*
* @return
*
*****************************************************************************/
void *get_dram_dfs_table(void)
{
return((void *)g_dram_dfs_table);
}
#endif
/******************************************************************************
*
* @fn pwrcal_get_dram_manufacturer
*
* @brief
*
* @param
*
* @return
*
*****************************************************************************/
unsigned int pwrcal_get_dram_manufacturer(void)
{
return (query_key);
}
/******************************************************************************
*
* @fn smc_set_qchannel
*
* @brief
*
* @param
*
* @return
*
*****************************************************************************/
void smc_set_qchannel(int enable)
{
if (enable == 0) {
pwrcal_setbit(CG_CTRL_VAL_DDRPHY0, 0, 0x1);
pwrcal_setbit(CG_CTRL_MAN_DDRPHY0, 0, 0x1);
pwrcal_setbit(CG_CTRL_VAL_DDRPHY1, 0, 0x1);
pwrcal_setbit(CG_CTRL_MAN_DDRPHY1, 0, 0x1);
pwrcal_setbit(CG_CTRL_VAL_DDRPHY2, 0, 0x1);
pwrcal_setbit(CG_CTRL_MAN_DDRPHY2, 0, 0x1);
pwrcal_setbit(CG_CTRL_VAL_DDRPHY3, 0, 0x1);
pwrcal_setbit(CG_CTRL_MAN_DDRPHY3, 0, 0x1);
} else {
pwrcal_setbit(CG_CTRL_MAN_DDRPHY3, 0, 0x0);
pwrcal_setbit(CG_CTRL_VAL_DDRPHY3, 0, 0x0);
pwrcal_setbit(CG_CTRL_MAN_DDRPHY2, 0, 0x0);
pwrcal_setbit(CG_CTRL_VAL_DDRPHY2, 0, 0x0);
pwrcal_setbit(CG_CTRL_MAN_DDRPHY1, 0, 0x0);
pwrcal_setbit(CG_CTRL_VAL_DDRPHY1, 0, 0x0);
pwrcal_setbit(CG_CTRL_MAN_DDRPHY0, 0, 0x0);
pwrcal_setbit(CG_CTRL_VAL_DDRPHY0, 0, 0x0);
}
}
/******************************************************************************
*
* @fn dmc_misc_direct_dmc_enable
*
* @brief
*
* @param
*
* @return
*
*****************************************************************************/
void dmc_misc_direct_dmc_enable(int enable)
{
pwrcal_writel(DMC_MISC_CON0, (enable << 24) | (0x2 << 20));
}
/******************************************************************************
*
* @fn smc_mode_register_write
*
* @brief
*
* @param
*
* @return
*
*****************************************************************************/
void smc_mode_register_write(int mr, int op)
{
pwrcal_writel(ModeRegAddr, ((0x3 << 28) | (mr << 20)));
pwrcal_writel(ModeRegWrData, op);
pwrcal_writel(MprMrCtl, 0x10);
}
/******************************************************************************
*
* @fn smc_mode_register_write_per_ch
*
* @brief
*
* @param
*
* @return
*
*****************************************************************************/
void smc_mode_register_write_per_ch(int ch, int mr, int rank, int op)
{
unsigned long modereg;
unsigned long moderegwrdata;
unsigned long mprmrctl;
unsigned long base;
switch (ch) {
case 0:
base = SMC0_BASE;
break;
case 1:
base = SMC1_BASE;
break;
case 2:
base = SMC2_BASE;
break;
case 3:
base = SMC3_BASE;
break;
}
modereg = base;
moderegwrdata = (base + 0x8);
mprmrctl = (base + 0x4);
pwrcal_writel((void *)modereg, (((rank & 0x3) << 28) | (mr << 20)));
pwrcal_writel((void *)moderegwrdata, op);
#ifdef PWRCAL_TARGET_LINUX
dsb(ishst);
pwrcal_writel((void *)mprmrctl, 0x10);
dsb(ishst);
#else
pwrcal_writel((void *)mprmrctl, 0x10);
#endif
}
/******************************************************************************
*
* @fn smc_mode_register_read_per_ch
*
* @brief
*
* @param
*
* @return
*
*****************************************************************************/
unsigned int smc_mode_register_read_per_ch(int ch, int mr, int rank)
{
unsigned long modereg;
unsigned long mprmrctl;
unsigned long moderegrddata0;
unsigned long base;
switch (ch) {
case 0:
base = SMC0_BASE;
break;
case 1:
base = SMC1_BASE;
break;
case 2:
base = SMC2_BASE;
break;
case 3:
base = SMC3_BASE;
break;
}
modereg = base;
mprmrctl = (base + 0x4);
moderegrddata0 = (base + 0xC);
pwrcal_writel((void *)modereg, (((rank & 0x3) << 28) | (mr << 20)));
#ifdef PWRCAL_TARGET_LINUX
dsb(ishst);
pwrcal_writel((void *)mprmrctl, 0x1);
dsb(ishst);
#else
pwrcal_writel((void *)mprmrctl, 0x1);
#endif
return pwrcal_readl((void *)moderegrddata0);
}
/******************************************************************************
*
* @fn convert_to_level
*
* @brief
*
* @param
*
* @return
*
*****************************************************************************/
static unsigned int convert_to_level(unsigned long long freq)
{
int idx;
int tablesize = num_mif_freq_to_level;
for (idx = tablesize - 1; idx >= 0; idx--)
if (freq <= mif_freq_to_level[idx])
return (unsigned int)idx;
return 0;
}
/******************************************************************************
*
* @fn convert_to_level_switch
*
* @brief
*
* @param
*
* @return
*
*****************************************************************************/
static unsigned int convert_to_level_switch(unsigned long long freq)
{
int idx;
int tablesize = sizeof(mif_freq_to_level_switch) / sizeof(mif_freq_to_level_switch[0]);
for (idx = tablesize - 1; idx >= 0; idx--)
if (freq <= mif_freq_to_level_switch[idx])
return (unsigned int)idx;
return 0;
}
/******************************************************************************
*
* @fn pwrcal_dmc_set_dvfs
*
* @brief
*
* @param
*
* @return
*
*****************************************************************************/
void pwrcal_dmc_set_dvfs(unsigned long long target_mif_freq, unsigned int timing_set_idx)
{
int n;
int rank;
int byte;
unsigned int uReg;
unsigned char target_mif_level_idx, target_mif_level_switch_idx;
unsigned char mr13;
unsigned char mr14;
int gate_offset_adjust = 0;
int new_gate_offset;
unsigned short offsetc;
phy_cal_con1_t cal_con1;
phy_dvfs0_con2_t *dvfs0_con2;
phy_dvfs0_con3_t DVFS_CON3_ECT, DVFS_CON3;
phy_dvfs0_con4_t DVFS_CON4_ECT, DVFS_CON4;
phy_zq_con0_t ZQ_CON0;
target_mif_level_idx = convert_to_level(target_mif_freq);
target_mif_level_switch_idx = convert_to_level_switch(target_mif_freq);
target_mif_level_switch_idx += num_mif_freq_to_level;
/* 1. Configure parameter */
if (timing_set_idx == MIF_TIMING_SET_0) {
//periodic training enable/disable as DVFS level
//1. Set TmrTrnInterval as zero to disable new periodic training.
pwrcal_writel(TmrTrnInterval_1, 0x0);
#ifndef PWRCAL_TARGET_LINUX
for (n = 0; n < PHY_CH_ALL; n++) {
//2. Wait until that TrnStatus.TrnSelStatus becomes 4'b0000 or 4'b1xxxx.
while (!((pwrcal_readl(SMC_TrnStatus_CH0 + n*0x100000) == 0x8) || (pwrcal_readl(SMC_TrnStatus_CH0 + n*0x100000) == 0x0)));
//3. Change TmrTrnInterval and TmrTrnCtl for new DVFS level.
if (g_smc_dfs_table[target_mif_level_idx].DvfsTrnCtl == 0)
pwrcal_writel(SMC_TmrTrnCtl_CH0 + n*0x100000, 0x0);
else
pwrcal_writel(SMC_TmrTrnCtl_CH0 + n*0x100000, (0x1<<31) | g_smc_dfs_table[target_mif_level_idx].DvfsTrnCtl);
}
#else
for (n = 0; n < PHY_CH_ALL; n++) {
//2. Wait until that TrnStatus.TrnSelStatus becomes 4'b0000 or 4'b1xxxx.
while (!((pwrcal_readl(SMC_TrnStatus_CH0 + n*0x10000) == 0x8) || (pwrcal_readl(SMC_TrnStatus_CH0 + n*0x10000) == 0x0)));
//3. Change TmrTrnInterval and TmrTrnCtl for new DVFS level.
if (g_smc_dfs_table[target_mif_level_idx].DvfsTrnCtl == 0)
pwrcal_writel(SMC_TmrTrnCtl_CH0 + n*0x10000, 0x0);
else
pwrcal_writel(SMC_TmrTrnCtl_CH0 + n*0x10000, (0x1<<31) | g_smc_dfs_table[target_mif_level_idx].DvfsTrnCtl);
}
#endif
pwrcal_writel(DMC_MISC_CON1_CH0, 0x0); //timing_set_sw_r=0x0
pwrcal_writel(DMC_MISC_CON1_CH1, 0x0); //timing_set_sw_r=0x0
pwrcal_writel(DMC_MISC_CON1_CH2, 0x0); //timing_set_sw_r=0x0
pwrcal_writel(DMC_MISC_CON1_CH3, 0x0); //timing_set_sw_r=0x0
pwrcal_writel(DramTiming0_0, g_smc_dfs_table[target_mif_level_idx].DramTiming0);
pwrcal_writel(DramTiming1_0, g_smc_dfs_table[target_mif_level_idx].DramTiming1);
pwrcal_writel(DramTiming2_0, g_smc_dfs_table[target_mif_level_idx].DramTiming2);
pwrcal_writel(DramTiming3_0, g_smc_dfs_table[target_mif_level_idx].DramTiming3);
pwrcal_writel(DramTiming4_0, g_smc_dfs_table[target_mif_level_idx].DramTiming4);
pwrcal_writel(DramTiming5_0, g_smc_dfs_table[target_mif_level_idx].DramTiming5);
pwrcal_writel(DramTiming6_0, g_smc_dfs_table[target_mif_level_idx].DramTiming6);
pwrcal_writel(DramTiming7_0, g_smc_dfs_table[target_mif_level_idx].DramTiming7);
pwrcal_writel(DramTiming8_0, g_smc_dfs_table[target_mif_level_idx].DramTiming8);
pwrcal_writel(DramTiming9_0, g_smc_dfs_table[target_mif_level_idx].DramTiming9);
pwrcal_writel(DramDerateTiming0_0, g_smc_dfs_table[target_mif_level_idx].DramDerateTiming0);
pwrcal_writel(DramDerateTiming1_0, g_smc_dfs_table[target_mif_level_idx].DramDerateTiming1);
pwrcal_writel(Dimm0AutoRefTiming1_0, g_smc_dfs_table[target_mif_level_idx].Dimm0AutoRefTiming1);
pwrcal_writel(Dimm1AutoRefTiming1_0, g_smc_dfs_table[target_mif_level_idx].Dimm1AutoRefTiming1);
pwrcal_writel(AutoRefTiming2_0, g_smc_dfs_table[target_mif_level_idx].AutoRefTiming2);
pwrcal_writel(PwrMgmtTiming0_0, g_smc_dfs_table[target_mif_level_idx].PwrMgmtTiming0);
pwrcal_writel(PwrMgmtTiming1_0, g_smc_dfs_table[target_mif_level_idx].PwrMgmtTiming1);
pwrcal_writel(PwrMgmtTiming2_0, g_smc_dfs_table[target_mif_level_idx].PwrMgmtTiming2);
pwrcal_writel(PwrMgmtTiming3_0, g_smc_dfs_table[target_mif_level_idx].PwrMgmtTiming3);
pwrcal_writel(TmrTrnInterval_0, g_smc_dfs_table[target_mif_level_idx].TmrTrnInterval);
pwrcal_writel(DFIDelay1_0, g_smc_dfs_table[target_mif_level_idx].DFIDelay1);
pwrcal_writel(DFIDelay2_0, g_smc_dfs_table[target_mif_level_idx].DFIDelay2);
pwrcal_writel(DvfsTrnCtl_0, g_smc_dfs_table[target_mif_level_idx].DvfsTrnCtl);
pwrcal_writel(TrnTiming0_0, g_smc_dfs_table[target_mif_level_idx].TrnTiming0);
pwrcal_writel(TrnTiming1_0, g_smc_dfs_table[target_mif_level_idx].TrnTiming1);
pwrcal_writel(TrnTiming2_0, g_smc_dfs_table[target_mif_level_idx].TrnTiming2);
uReg = pwrcal_readl((void *)PHY_DVFS_CON_CH0);
uReg &= ~(0x3 << 30);
uReg |= (0x1 << 30); //0x1 = DVFS 1 mode
pwrcal_writel(PHY_DVFS_CON, uReg);
for (n = 0; n < PHY_CH_ALL; n++) {
if (drampara_config != 0) {
/* get offsetc information */
if (drampara_config->phy_offset.magic == PHY_OFFSET_CONFIG_MAGIC) {
dvfs0_con2 = (phy_dvfs0_con2_t *)&g_phy_dfs_table[target_mif_level_idx].DVFSn_CON2;
if ((dvfs0_con2->bitfield.dvfs0_gateadj != 0) \
&& ((drampara_config->phy_offset.gate[n][0] != 0) \
|| (drampara_config->phy_offset.gate[n][1] != 0)))
gate_offset_adjust = 1;
}
offsetc = 0;
if (gate_offset_adjust == 1) {
cal_con1.data = pwrcal_readl(PHY_CAL_CON1[n]);
cal_con1.bitfield.rdlvl_pass_adj = 6;
cal_con1.bitfield.glvl_start_adj = 3;
pwrcal_writel(PHY_CAL_CON1[n], cal_con1.data);
for (byte = 0; byte < PHY_BYTE_ALL; byte++) {
new_gate_offset = (drampara_config->phy_offset.lock[n] >> 1) \
- drampara_config->phy_offset.gate[n][byte];
if (new_gate_offset < 0)
offsetc |= ((new_gate_offset & 0x7f) | 0x80) << (8 * byte);
else
offsetc |= (new_gate_offset & 0x7f) << (8 * byte);
}
} else {
cal_con1.data = pwrcal_readl(PHY_CAL_CON1[n]);
cal_con1.bitfield.rdlvl_pass_adj = drampara_config->phy.adjust.rdlvl_pass_adj;
cal_con1.bitfield.glvl_start_adj = drampara_config->phy.adjust.glvl_start_adj;
pwrcal_writel(PHY_CAL_CON1[n], cal_con1.data);
}
pwrcal_writel(PHY_OFFSETC_CON1[n], offsetc);
}
DVFS_CON3.data = DVFS_CON3_ECT.data = g_phy_dfs_table[target_mif_level_idx].DVFSn_CON3;
DVFS_CON4.data = DVFS_CON4_ECT.data = g_phy_dfs_table[target_mif_level_idx].DVFSn_CON4;
ZQ_CON0.data = pwrcal_readl(PHY_ZQ_CON0[n]);
/* WA: Ch1 and Ch2 wrong connection SFR and IO control pin */
if ((n == 1) || (n == 2)) {
/* ca register => byte1 pad */
DVFS_CON3.bitfield.dvfs0_zq_mode_dds = DVFS_CON3_ECT.bitfield.dvfs0_zq_ds1_dds;
DVFS_CON3.bitfield.dvfs0_zq_mode_pdds = DVFS_CON3_ECT.bitfield.dvfs0_zq_ds1_pdds;
ZQ_CON0.bitfield.zq_mode_term = DVFS_CON4_ECT.bitfield.dvfs0_zq_ds1_term;
/* ds0 register => ca pad */
DVFS_CON3.bitfield.dvfs0_zq_ds0_dds = DVFS_CON3_ECT.bitfield.dvfs0_zq_mode_dds;
DVFS_CON3.bitfield.dvfs0_zq_ds0_pdds = DVFS_CON3_ECT.bitfield.dvfs0_zq_mode_pdds;
DVFS_CON4.bitfield.dvfs0_zq_ds0_term = 0x0;
/* ds1 register => byte0 pad */
DVFS_CON3.bitfield.dvfs0_zq_ds1_dds = DVFS_CON3_ECT.bitfield.dvfs0_zq_ds0_dds;
DVFS_CON3.bitfield.dvfs0_zq_ds1_pdds = DVFS_CON3_ECT.bitfield.dvfs0_zq_ds0_pdds;
DVFS_CON4.bitfield.dvfs0_zq_ds1_term = DVFS_CON4_ECT.bitfield.dvfs0_zq_ds0_term;
} else {
DVFS_CON3.bitfield.dvfs0_zq_mode_dds = DVFS_CON3_ECT.bitfield.dvfs0_zq_mode_dds;
DVFS_CON3.bitfield.dvfs0_zq_mode_pdds = DVFS_CON3_ECT.bitfield.dvfs0_zq_mode_pdds;
ZQ_CON0.bitfield.zq_mode_term = 0x0;
DVFS_CON3.bitfield.dvfs0_zq_ds0_dds = DVFS_CON3_ECT.bitfield.dvfs0_zq_ds0_dds;
DVFS_CON3.bitfield.dvfs0_zq_ds0_pdds = DVFS_CON3_ECT.bitfield.dvfs0_zq_ds0_pdds;
DVFS_CON4.bitfield.dvfs0_zq_ds0_term = DVFS_CON4_ECT.bitfield.dvfs0_zq_ds0_term;
DVFS_CON3.bitfield.dvfs0_zq_ds1_dds = DVFS_CON3_ECT.bitfield.dvfs0_zq_ds1_dds;
DVFS_CON3.bitfield.dvfs0_zq_ds1_pdds = DVFS_CON3_ECT.bitfield.dvfs0_zq_ds1_pdds;
DVFS_CON4.bitfield.dvfs0_zq_ds1_term = DVFS_CON4_ECT.bitfield.dvfs0_zq_ds1_term;
}
/* tied to byte0 */
DVFS_CON3.bitfield.dvfs0_ds0_vref = DVFS_CON3_ECT.bitfield.dvfs0_ds0_vref;
DVFS_CON3.bitfield.dvfs0_ds1_vref = DVFS_CON3_ECT.bitfield.dvfs0_ds0_vref;
pwrcal_writel(PHY_DVFS0_CON0[n], g_phy_dfs_table[target_mif_level_idx].DVFSn_CON0);
pwrcal_writel(PHY_DVFS0_CON1[n], g_phy_dfs_table[target_mif_level_idx].DVFSn_CON1);
pwrcal_writel(PHY_DVFS0_CON2[n], g_phy_dfs_table[target_mif_level_idx].DVFSn_CON2);
pwrcal_writel(PHY_DVFS0_CON3[n], DVFS_CON3.data);
pwrcal_writel(PHY_DVFS0_CON4[n], DVFS_CON4.data);
pwrcal_writel(PHY_ZQ_CON0[n], ZQ_CON0.data);
}
mr13 = (0x1 << 7) | (0x0 << 6) | (0x0 << 5) | (0x1 << 3); //FSP-OP=0x1, FSP-WR=0x0, DMD=0x0, VRCG=0x1
smc_mode_register_write(DRAM_MR13, mr13);
smc_mode_register_write(DRAM_MR1, g_dram_dfs_table[target_mif_level_idx].DirectCmd_MR1);
smc_mode_register_write(DRAM_MR2, g_dram_dfs_table[target_mif_level_idx].DirectCmd_MR2);
smc_mode_register_write(DRAM_MR3, g_dram_dfs_table[target_mif_level_idx].DirectCmd_MR3);
smc_mode_register_write(DRAM_MR11, g_dram_dfs_table[target_mif_level_idx].DirectCmd_MR11);
smc_mode_register_write(DRAM_MR12, g_dram_dfs_table[target_mif_level_idx].DirectCmd_MR12);
if ((drampara_config->vref.num_of_level != 0) && (drampara_config->vref.write.vref == 1)) {
for (n = 0; n < PHY_CH_ALL; n++) {
mr14 = drampara_config->vref.vref_write[n][target_mif_level_idx];
for (rank = 1; rank < 0x4; rank <<= 1)
smc_mode_register_write_per_ch(n, DRAM_MR14, rank, mr14 & 0xff);
}
} else {
smc_mode_register_write(DRAM_MR22, g_dram_dfs_table[target_mif_level_idx].DirectCmd_MR14);
}
smc_mode_register_write(DRAM_MR22, g_dram_dfs_table[target_mif_level_idx].DirectCmd_MR22);
mr13 &= ~(0x1 << 7); // clear FSP-OP[7]
pwrcal_writel(MRS_DATA1_CH0, mr13);
pwrcal_writel(MRS_DATA1_CH1, mr13);
pwrcal_writel(MRS_DATA1_CH2, mr13);
pwrcal_writel(MRS_DATA1_CH3, mr13);
} else if (timing_set_idx == MIF_TIMING_SET_1) {
//periodic training enable/disable as DVFS level
//1. Set TmrTrnInterval as zero to disable new periodic training.
pwrcal_writel(TmrTrnInterval_0, 0x0);
#ifndef PWRCAL_TARGET_LINUX
for (n = 0; n < 4; n++) {
//2. Wait until that TrnStatus.TrnSelStatus becomes 4'b0000 or 4'b1xxxx.
while (!((pwrcal_readl(SMC_TrnStatus_CH0 + n*0x100000) == 0x8) || (pwrcal_readl(SMC_TrnStatus_CH0 + n*0x100000) == 0x0)));
//3. Change TmrTrnInterval and TmrTrnCtl for new DVFS level.
pwrcal_writel(SMC_TmrTrnCtl_CH0 + n*0x100000, 0x0); //switching PLL is always periodic training off
}
#else
for (n = 0; n < 4; n++) {
//2. Wait until that TrnStatus.TrnSelStatus becomes 4'b0000 or 4'b1xxxx.
while (!((pwrcal_readl(SMC_TrnStatus_CH0 + n*0x10000) == 0x8) || (pwrcal_readl(SMC_TrnStatus_CH0 + n*0x10000) == 0x0)));
//3. Change TmrTrnInterval and TmrTrnCtl for new DVFS level.
pwrcal_writel(SMC_TmrTrnCtl_CH0 + n*0x10000, 0x0); //switching PLL is always periodic training off
}
#endif
pwrcal_writel(DMC_MISC_CON1_CH0, 0x1); //timing_set_sw_r=0x1
pwrcal_writel(DMC_MISC_CON1_CH1, 0x1); //timing_set_sw_r=0x1
pwrcal_writel(DMC_MISC_CON1_CH2, 0x1); //timing_set_sw_r=0x1
pwrcal_writel(DMC_MISC_CON1_CH3, 0x1); //timing_set_sw_r=0x1
pwrcal_writel(DramTiming0_1, g_smc_dfs_table[target_mif_level_switch_idx].DramTiming0);
pwrcal_writel(DramTiming1_1, g_smc_dfs_table[target_mif_level_switch_idx].DramTiming1);
pwrcal_writel(DramTiming2_1, g_smc_dfs_table[target_mif_level_switch_idx].DramTiming2);
pwrcal_writel(DramTiming3_1, g_smc_dfs_table[target_mif_level_switch_idx].DramTiming3);
pwrcal_writel(DramTiming4_1, g_smc_dfs_table[target_mif_level_switch_idx].DramTiming4);
pwrcal_writel(DramTiming5_1, g_smc_dfs_table[target_mif_level_switch_idx].DramTiming5);
pwrcal_writel(DramTiming6_1, g_smc_dfs_table[target_mif_level_switch_idx].DramTiming6);
pwrcal_writel(DramTiming7_1, g_smc_dfs_table[target_mif_level_switch_idx].DramTiming7);
pwrcal_writel(DramTiming8_1, g_smc_dfs_table[target_mif_level_switch_idx].DramTiming8);
pwrcal_writel(DramTiming9_1, g_smc_dfs_table[target_mif_level_switch_idx].DramTiming9);
pwrcal_writel(DramDerateTiming0_1, g_smc_dfs_table[target_mif_level_switch_idx].DramDerateTiming0);
pwrcal_writel(DramDerateTiming1_1, g_smc_dfs_table[target_mif_level_switch_idx].DramDerateTiming1);
pwrcal_writel(Dimm0AutoRefTiming1_1, g_smc_dfs_table[target_mif_level_switch_idx].Dimm0AutoRefTiming1);
pwrcal_writel(Dimm1AutoRefTiming1_1, g_smc_dfs_table[target_mif_level_switch_idx].Dimm1AutoRefTiming1);
pwrcal_writel(AutoRefTiming2_1, g_smc_dfs_table[target_mif_level_switch_idx].AutoRefTiming2);
pwrcal_writel(PwrMgmtTiming0_1, g_smc_dfs_table[target_mif_level_switch_idx].PwrMgmtTiming0);
pwrcal_writel(PwrMgmtTiming1_1, g_smc_dfs_table[target_mif_level_switch_idx].PwrMgmtTiming1);
pwrcal_writel(PwrMgmtTiming2_1, g_smc_dfs_table[target_mif_level_switch_idx].PwrMgmtTiming2);
pwrcal_writel(PwrMgmtTiming3_1, g_smc_dfs_table[target_mif_level_switch_idx].PwrMgmtTiming3);
pwrcal_writel(TmrTrnInterval_1, g_smc_dfs_table[target_mif_level_switch_idx].TmrTrnInterval);
pwrcal_writel(DFIDelay1_1, g_smc_dfs_table[target_mif_level_switch_idx].DFIDelay1);
pwrcal_writel(DFIDelay2_1, g_smc_dfs_table[target_mif_level_switch_idx].DFIDelay2);
pwrcal_writel(DvfsTrnCtl_1, g_smc_dfs_table[target_mif_level_switch_idx].DvfsTrnCtl);
pwrcal_writel(TrnTiming0_1, g_smc_dfs_table[target_mif_level_switch_idx].TrnTiming0);
pwrcal_writel(TrnTiming1_1, g_smc_dfs_table[target_mif_level_switch_idx].TrnTiming1);
pwrcal_writel(TrnTiming2_1, g_smc_dfs_table[target_mif_level_switch_idx].TrnTiming2);
uReg = pwrcal_readl(PHY_DVFS_CON_CH0);
uReg &= ~(0x3 << 30);
uReg |= (0x2 << 30); //0x2 = DVFS 2 mode
pwrcal_writel(PHY_DVFS_CON, uReg);
for (n = 0; n < PHY_CH_ALL; n++) {
DVFS_CON3.data = DVFS_CON3_ECT.data = g_phy_dfs_table[target_mif_level_switch_idx].DVFSn_CON3;
DVFS_CON4.data = DVFS_CON4_ECT.data = g_phy_dfs_table[target_mif_level_switch_idx].DVFSn_CON4;
ZQ_CON0.data = pwrcal_readl(PHY_ZQ_CON0[n]);
/* WA: Ch1 and Ch2 wrong connection SFR and IO control pin */
if ((n == 1) || (n == 2)) {
/* ca register => byte1 pad */
DVFS_CON3.bitfield.dvfs0_zq_mode_dds = DVFS_CON3_ECT.bitfield.dvfs0_zq_ds1_dds;
DVFS_CON3.bitfield.dvfs0_zq_mode_pdds = DVFS_CON3_ECT.bitfield.dvfs0_zq_ds1_pdds;
ZQ_CON0.bitfield.zq_mode_term = DVFS_CON4_ECT.bitfield.dvfs0_zq_ds1_term;
/* ds0 register => ca pad */
DVFS_CON3.bitfield.dvfs0_zq_ds0_dds = DVFS_CON3_ECT.bitfield.dvfs0_zq_mode_dds;
DVFS_CON3.bitfield.dvfs0_zq_ds0_pdds = DVFS_CON3_ECT.bitfield.dvfs0_zq_mode_pdds;
DVFS_CON4.bitfield.dvfs0_zq_ds0_term = 0x0;
/* ds1 register => byte0 pad */
DVFS_CON3.bitfield.dvfs0_zq_ds1_dds = DVFS_CON3_ECT.bitfield.dvfs0_zq_ds0_dds;
DVFS_CON3.bitfield.dvfs0_zq_ds1_pdds = DVFS_CON3_ECT.bitfield.dvfs0_zq_ds0_pdds;
DVFS_CON4.bitfield.dvfs0_zq_ds1_term = DVFS_CON4_ECT.bitfield.dvfs0_zq_ds0_term;
} else {
DVFS_CON3.bitfield.dvfs0_zq_mode_dds = DVFS_CON3_ECT.bitfield.dvfs0_zq_mode_dds;
DVFS_CON3.bitfield.dvfs0_zq_mode_pdds = DVFS_CON3_ECT.bitfield.dvfs0_zq_mode_pdds;
ZQ_CON0.bitfield.zq_mode_term = 0x0;
DVFS_CON3.bitfield.dvfs0_zq_ds0_dds = DVFS_CON3_ECT.bitfield.dvfs0_zq_ds0_dds;
DVFS_CON3.bitfield.dvfs0_zq_ds0_pdds = DVFS_CON3_ECT.bitfield.dvfs0_zq_ds0_pdds;
DVFS_CON4.bitfield.dvfs0_zq_ds0_term = DVFS_CON4_ECT.bitfield.dvfs0_zq_ds0_term;
DVFS_CON3.bitfield.dvfs0_zq_ds1_dds = DVFS_CON3_ECT.bitfield.dvfs0_zq_ds1_dds;
DVFS_CON3.bitfield.dvfs0_zq_ds1_pdds = DVFS_CON3_ECT.bitfield.dvfs0_zq_ds1_pdds;
DVFS_CON4.bitfield.dvfs0_zq_ds1_term = DVFS_CON4_ECT.bitfield.dvfs0_zq_ds1_term;
}
/* tied to byte0 */
DVFS_CON3.bitfield.dvfs0_ds0_vref = DVFS_CON3_ECT.bitfield.dvfs0_ds0_vref;
DVFS_CON3.bitfield.dvfs0_ds1_vref = DVFS_CON3_ECT.bitfield.dvfs0_ds0_vref;
pwrcal_writel(PHY_DVFS1_CON0[n], g_phy_dfs_table[target_mif_level_switch_idx].DVFSn_CON0);
pwrcal_writel(PHY_DVFS1_CON1[n], g_phy_dfs_table[target_mif_level_switch_idx].DVFSn_CON1);
pwrcal_writel(PHY_DVFS1_CON2[n], g_phy_dfs_table[target_mif_level_switch_idx].DVFSn_CON2);
pwrcal_writel(PHY_DVFS1_CON3[n], DVFS_CON3.data);
pwrcal_writel(PHY_DVFS1_CON4[n], DVFS_CON4.data);
pwrcal_writel(PHY_ZQ_CON0[n], ZQ_CON0.data);
}
mr13 = (0x0 << 7) | (0x1 << 6) | (0x0 << 5) | (0x1 << 3); //FSP-OP=0x0, FSP-WR=0x1, DMD=0x0, VRCG=0x1
smc_mode_register_write(DRAM_MR13, mr13);
smc_mode_register_write(DRAM_MR1, g_dram_dfs_table[target_mif_level_switch_idx].DirectCmd_MR1);
smc_mode_register_write(DRAM_MR2, g_dram_dfs_table[target_mif_level_switch_idx].DirectCmd_MR2);
smc_mode_register_write(DRAM_MR3, g_dram_dfs_table[target_mif_level_switch_idx].DirectCmd_MR3);
smc_mode_register_write(DRAM_MR11, g_dram_dfs_table[target_mif_level_switch_idx].DirectCmd_MR11);
smc_mode_register_write(DRAM_MR12, g_dram_dfs_table[target_mif_level_switch_idx].DirectCmd_MR12);
if ((drampara_config->vref.num_of_level != 0) && (drampara_config->vref.write.vref == 1)) {
for (n = 0; n < PHY_CH_ALL; n++) {
mr14 = drampara_config->vref.vref_write[n][target_mif_level_switch_idx];
for (rank = 1; rank < 0x4; rank <<= 1)
smc_mode_register_write_per_ch(n, DRAM_MR14, rank, mr14 & 0xff);
}
} else {
smc_mode_register_write(DRAM_MR22, g_dram_dfs_table[target_mif_level_switch_idx].DirectCmd_MR14);
}
smc_mode_register_write(DRAM_MR22, g_dram_dfs_table[target_mif_level_switch_idx].DirectCmd_MR22);
mr13 &= ~(0x1 << 7); // clear FSP-OP[7]
mr13 |= (0x1 << 7); // set FSP-OP[7]=0x1
pwrcal_writel(MRS_DATA1_CH0, mr13);
pwrcal_writel(MRS_DATA1_CH1, mr13);
pwrcal_writel(MRS_DATA1_CH2, mr13);
pwrcal_writel(MRS_DATA1_CH3, mr13);
} else {
pr_err("wrong DMC timing set selection on DVFS\n");
return;
}
}
/******************************************************************************
*
* @fn dfs_dram_param_init
*
* @brief
*
* @param
*
* @return
*
*****************************************************************************/
void dfs_dram_param_init(void)
{
int i;
void *dram_block;
struct ect_timing_param_size *size;
dram_block = ect_get_block(BLOCK_TIMING_PARAM);
if (dram_block == NULL)
return;
query_key = pwrcal_readl(PMU_DREX_CALIBRATION3);
if (query_key != 0) {
size = ect_timing_param_get_key(dram_block, query_key | 0x1);
} else {
query_key = 3;
size = ect_timing_param_get_size(dram_block, query_key);
}
if (size == NULL)
return;
if (num_of_g_smc_dfs_table_column + num_of_g_phy_dfs_table_column + num_of_g_dram_dfs_table_column != size->num_of_timing_param)
return;
g_smc_dfs_table = kzalloc(sizeof(struct smc_dfs_table) * num_of_g_smc_dfs_table_column * size->num_of_level, GFP_KERNEL);
if (g_smc_dfs_table == NULL)
return;
g_phy_dfs_table = kzalloc(sizeof(struct phy_dfs_table) * num_of_g_phy_dfs_table_column * size->num_of_level, GFP_KERNEL);
if (g_phy_dfs_table == NULL)
return;
g_dram_dfs_table = kzalloc(sizeof(struct dram_dfs_table) * num_of_g_dram_dfs_table_column * size->num_of_level, GFP_KERNEL);
if (g_dram_dfs_table == NULL)
return;
for (i = 0; i < size->num_of_level; ++i) {
g_smc_dfs_table[i].DramTiming0 = size->timing_parameter[i * num_of_dram_parameter + DramTiming0];
g_smc_dfs_table[i].DramTiming1 = size->timing_parameter[i * num_of_dram_parameter + DramTiming1];
g_smc_dfs_table[i].DramTiming2 = size->timing_parameter[i * num_of_dram_parameter + DramTiming2];
g_smc_dfs_table[i].DramTiming3 = size->timing_parameter[i * num_of_dram_parameter + DramTiming3];
g_smc_dfs_table[i].DramTiming4 = size->timing_parameter[i * num_of_dram_parameter + DramTiming4];
g_smc_dfs_table[i].DramTiming5 = size->timing_parameter[i * num_of_dram_parameter + DramTiming5];
g_smc_dfs_table[i].DramTiming6 = size->timing_parameter[i * num_of_dram_parameter + DramTiming6];
g_smc_dfs_table[i].DramTiming7 = size->timing_parameter[i * num_of_dram_parameter + DramTiming7];
g_smc_dfs_table[i].DramTiming8 = size->timing_parameter[i * num_of_dram_parameter + DramTiming8];
g_smc_dfs_table[i].DramTiming9 = size->timing_parameter[i * num_of_dram_parameter + DramTiming9];
g_smc_dfs_table[i].DramDerateTiming0 = size->timing_parameter[i * num_of_dram_parameter + DramDerateTiming0];
g_smc_dfs_table[i].DramDerateTiming1 = size->timing_parameter[i * num_of_dram_parameter + DramDerateTiming1];
g_smc_dfs_table[i].Dimm0AutoRefTiming1 = size->timing_parameter[i * num_of_dram_parameter + Dimm0AutoRefTiming1];
g_smc_dfs_table[i].Dimm1AutoRefTiming1 = size->timing_parameter[i * num_of_dram_parameter + Dimm1AutoRefTiming1];
g_smc_dfs_table[i].AutoRefTiming2 = size->timing_parameter[i * num_of_dram_parameter + AutoRefTiming2];
g_smc_dfs_table[i].PwrMgmtTiming0 = size->timing_parameter[i * num_of_dram_parameter + PwrMgmtTiming0];
g_smc_dfs_table[i].PwrMgmtTiming1 = size->timing_parameter[i * num_of_dram_parameter + PwrMgmtTiming1];
g_smc_dfs_table[i].PwrMgmtTiming2 = size->timing_parameter[i * num_of_dram_parameter + PwrMgmtTiming2];
g_smc_dfs_table[i].PwrMgmtTiming3 = size->timing_parameter[i * num_of_dram_parameter + PwrMgmtTiming3];
g_smc_dfs_table[i].TmrTrnInterval = size->timing_parameter[i * num_of_dram_parameter + TmrTrnInterval];
g_smc_dfs_table[i].DFIDelay1 = size->timing_parameter[i * num_of_dram_parameter + DFIDelay1];
g_smc_dfs_table[i].DFIDelay2 = size->timing_parameter[i * num_of_dram_parameter + DFIDelay2];
g_smc_dfs_table[i].DvfsTrnCtl = size->timing_parameter[i * num_of_dram_parameter + DvfsTrnCtl];
g_smc_dfs_table[i].TrnTiming0 = size->timing_parameter[i * num_of_dram_parameter + TrnTiming0];
g_smc_dfs_table[i].TrnTiming1 = size->timing_parameter[i * num_of_dram_parameter + TrnTiming1];
g_smc_dfs_table[i].TrnTiming2 = size->timing_parameter[i * num_of_dram_parameter + TrnTiming2];
g_phy_dfs_table[i].DVFSn_CON0 = size->timing_parameter[i * num_of_dram_parameter + DVFSn_CON0];
g_phy_dfs_table[i].DVFSn_CON1 = size->timing_parameter[i * num_of_dram_parameter + DVFSn_CON1];
g_phy_dfs_table[i].DVFSn_CON2 = size->timing_parameter[i * num_of_dram_parameter + DVFSn_CON2];
g_phy_dfs_table[i].DVFSn_CON3 = size->timing_parameter[i * num_of_dram_parameter + DVFSn_CON3];
g_phy_dfs_table[i].DVFSn_CON4 = size->timing_parameter[i * num_of_dram_parameter + DVFSn_CON4];
g_dram_dfs_table[i].DirectCmd_MR1 = size->timing_parameter[i * num_of_dram_parameter + DirectCmd_MR1];
g_dram_dfs_table[i].DirectCmd_MR2 = size->timing_parameter[i * num_of_dram_parameter + DirectCmd_MR2];
g_dram_dfs_table[i].DirectCmd_MR3 = size->timing_parameter[i * num_of_dram_parameter + DirectCmd_MR3];
g_dram_dfs_table[i].DirectCmd_MR11 = size->timing_parameter[i * num_of_dram_parameter + DirectCmd_MR11];
g_dram_dfs_table[i].DirectCmd_MR12 = size->timing_parameter[i * num_of_dram_parameter + DirectCmd_MR12];
g_dram_dfs_table[i].DirectCmd_MR14 = size->timing_parameter[i * num_of_dram_parameter + DirectCmd_MR14];
g_dram_dfs_table[i].DirectCmd_MR22 = size->timing_parameter[i * num_of_dram_parameter + DirectCmd_MR22];
}
}
/******************************************************************************
*
* @fn dfs_mif_level_init
*
* @brief
*
* @param
*
* @return
*
*****************************************************************************/
void dfs_mif_level_init(void)
{
int i;
void *dvfs_block;
struct ect_dvfs_domain *domain;
dvfs_block = ect_get_block(BLOCK_DVFS);
if (dvfs_block == NULL)
return;
domain = ect_dvfs_get_domain(dvfs_block, vclk_dvfs_mif.vclk.name);
if (domain == NULL)
return;
mif_freq_to_level = kzalloc(sizeof(unsigned long long) * domain->num_of_level, GFP_KERNEL);
if (mif_freq_to_level == NULL)
return;
num_mif_freq_to_level = domain->num_of_level;
for (i = 0; i < domain->num_of_level; ++i)
mif_freq_to_level[i] = domain->list_level[i].level * KHZ;
}
/******************************************************************************
*
* @fn dfs_dram_init
*
* @brief
*
* @param
*
* @return
*
*****************************************************************************/
void dfs_dram_init(void)
{
int ch;
unsigned int trained_vref[4];
#ifndef PWRCAL_TARGET_LINUX
config_base = pwrcal_readl(PMU_DREX_CALIBRATION1);
#else
config_base = (unsigned long)ioremap(pwrcal_readl(PMU_DREX_CALIBRATION1), SZ_2K);
#endif
if (config_base != 0)
drampara_config = (struct drampara_config_t *)config_base;
else
pr_err("dram parameter is missing\n");
dfs_dram_param_init();
dfs_mif_level_init();
for (ch = 0; ch < PHY_CH_ALL; ch++)
trained_vref[ch] = smc_mode_register_read_per_ch(ch, DRAM_MR14, SMC_RANK_ALL);
pr_info("write vref training value = CH0:0x%x, CH1:0x%x, CH2:0x%x, CH3:0x%x\n", \
trained_vref[0], trained_vref[1], trained_vref[2], trained_vref[3]);
}