blob: a4fdeecace158b591cd03c2601e5db63afce6f7e [file] [log] [blame]
Angel Ponse67ab182020-04-04 18:51:11 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Peter Kaoda1e02a2015-07-31 17:11:14 +08002
Kyösti Mälkki13f66502019-03-03 08:01:05 +02003#include <device/mmio.h>
Peter Kaoda1e02a2015-07-31 17:11:14 +08004#include <console/console.h>
Peter Kaoda1e02a2015-07-31 17:11:14 +08005#include <soc/addressmap.h>
6#include <soc/dramc_common.h>
7#include <soc/dramc_register.h>
8#include <soc/dramc_pi_api.h>
Xi Chena3b19442021-03-03 18:04:28 +08009#include <soc/dramc_soc.h>
Peter Kaoda1e02a2015-07-31 17:11:14 +080010#include <soc/mt6391.h>
Tristan Shiehab1b83d2018-11-01 18:01:50 +080011#include <soc/pmic_wrap.h>
Peter Kaoda1e02a2015-07-31 17:11:14 +080012#include <soc/pll.h>
PH Hsu3693d0f2015-12-16 13:48:10 +080013#include <soc/infracfg.h>
14#include <soc/pericfg.h>
Peter Kaoda1e02a2015-07-31 17:11:14 +080015
16struct emi_regs *emi_regs = (void *)EMI_BASE;
17
18static void dram_vcore_adjust(void)
19{
20 /* options: Vcore_HV_LPPDR3/Vcore_NV_LPPDR3/Vcore_LV_LPPDR3 */
Tristan Shiehab1b83d2018-11-01 18:01:50 +080021 pwrap_write_field(PMIC_RG_VCORE_CON9, Vcore_NV_LPPDR3, 0x7F, 0);
22 pwrap_write_field(PMIC_RG_VCORE_CON10, Vcore_NV_LPPDR3, 0x7F, 0);
Peter Kaoda1e02a2015-07-31 17:11:14 +080023}
24
25static void dram_vmem_adjust(void)
26{
27 /* options: Vmem_HV_LPPDR3/Vmem_NV_LPPDR3/Vmem_LV_LPPDR3 */
Tristan Shiehab1b83d2018-11-01 18:01:50 +080028 pwrap_write_field(PMIC_RG_VDRM_CON9, Vmem_NV_LPDDR3, 0x7F, 0);
29 pwrap_write_field(PMIC_RG_VDRM_CON10, Vmem_NV_LPDDR3, 0x7F, 0);
Peter Kaoda1e02a2015-07-31 17:11:14 +080030}
31
32static void emi_init(const struct mt8173_sdram_params *sdram_params)
33{
34 /* EMI setting initialization */
35 write32(&emi_regs->emi_conf, sdram_params->emi_set.conf);
36 write32(&emi_regs->emi_conm, sdram_params->emi_set.conm_1);
37 write32(&emi_regs->emi_arbi, sdram_params->emi_set.arbi);
38 write32(&emi_regs->emi_arba, sdram_params->emi_set.arba);
39 write32(&emi_regs->emi_arbc, sdram_params->emi_set.arbc);
40 write32(&emi_regs->emi_arbd, sdram_params->emi_set.arbd);
41 write32(&emi_regs->emi_arbe, sdram_params->emi_set.arbe);
42 write32(&emi_regs->emi_arbf, sdram_params->emi_set.arbf);
43 write32(&emi_regs->emi_arbg, sdram_params->emi_set.arbg);
44 write32(&emi_regs->emi_arbj, sdram_params->emi_set.arbj);
45 write32(&emi_regs->emi_cona, sdram_params->emi_set.cona);
46 write32(&emi_regs->emi_testd, sdram_params->emi_set.testd);
47 write32(&emi_regs->emi_bmen, sdram_params->emi_set.bmen);
48 write32(&emi_regs->emi_conb, sdram_params->emi_set.conb);
49 write32(&emi_regs->emi_conc, sdram_params->emi_set.conc);
50 write32(&emi_regs->emi_cond, sdram_params->emi_set.cond);
51 write32(&emi_regs->emi_cone, sdram_params->emi_set.cone);
52 write32(&emi_regs->emi_cong, sdram_params->emi_set.cong);
53 write32(&emi_regs->emi_conh, sdram_params->emi_set.conh);
54 write32(&emi_regs->emi_slct, sdram_params->emi_set.slct_1);
55 write32(&emi_regs->emi_mdct, sdram_params->emi_set.mdct_1);
56 write32(&emi_regs->emi_arbk, sdram_params->emi_set.arbk);
57 write32(&emi_regs->emi_testc, sdram_params->emi_set.testc);
58 write32(&emi_regs->emi_mdct, sdram_params->emi_set.mdct_2);
59 write32(&emi_regs->emi_testb, sdram_params->emi_set.testb);
60 write32(&emi_regs->emi_slct, sdram_params->emi_set.slct_2);
61 write32(&emi_regs->emi_conm, sdram_params->emi_set.conm_2);
62 write32(&emi_regs->emi_test0, sdram_params->emi_set.test0);
63 write32(&emi_regs->emi_test1, sdram_params->emi_set.test1);
64}
65
66static void do_calib(const struct mt8173_sdram_params *sdram_params)
67{
68 u32 channel;
69
70 sw_impedance_cal(CHANNEL_A, sdram_params);
71 sw_impedance_cal(CHANNEL_B, sdram_params);
72
73 /* SPM_CONTROL_AFTERK */
74 transfer_to_reg_control();
75
76 /* do dram calibration for channel A and B */
Elyes HAOUAS4a83f1c2016-08-25 21:07:59 +020077 for (channel = 0; channel < CHANNEL_NUM; channel++) {
Peter Kaoda1e02a2015-07-31 17:11:14 +080078 ca_training(channel, sdram_params);
79 write_leveling(channel, sdram_params);
80
81 /* rx gating and datlat for single or dual rank */
82 if (is_dual_rank(channel, sdram_params)) {
83 dual_rank_rx_dqs_gating_cal(channel, sdram_params);
84 dual_rank_rx_datlat_cal(channel, sdram_params);
85 } else {
86 rx_dqs_gating_cal(channel, 0, sdram_params);
87 rx_datlat_cal(channel, 0, sdram_params);
88 }
89
90 clk_duty_cal(channel);
91 /* rx window perbit calibration */
92 perbit_window_cal(channel, RX_WIN);
93 /* tx window perbit calibration */
94 perbit_window_cal(channel, TX_WIN);
95
96 dramc_rankinctl_config(channel, sdram_params);
97 dramc_runtime_config(channel, sdram_params);
98 }
99
100 /* SPM_CONTROL_AFTERK */
101 transfer_to_spm_control();
102}
103
104static void init_dram(const struct mt8173_sdram_params *sdram_params)
105{
106 emi_init(sdram_params);
107
108 dramc_pre_init(CHANNEL_A, sdram_params);
109 dramc_pre_init(CHANNEL_B, sdram_params);
110
111 div2_phase_sync();
112
113 dramc_init(CHANNEL_A, sdram_params);
114 dramc_init(CHANNEL_B, sdram_params);
115}
116
Yidi Linc6d7dcc2016-02-04 17:26:48 +0800117size_t sdram_size(void)
118{
119 u32 value = read32(&emi_regs->emi_cona);
120 u32 bit_counter = 0;
121
122 /* check if dual channel */
123 if (value & CONA_DUAL_CH_EN)
124 bit_counter++;
125
Elyes HAOUASa342f392018-10-17 10:56:26 +0200126 /* check if 32bit, 32 = 2^5*/
Yidi Linc6d7dcc2016-02-04 17:26:48 +0800127 if (value & CONA_32BIT_EN)
128 bit_counter += 5;
129 else
130 bit_counter += 4;
131
132 /* check column address */
Elyes HAOUASa342f392018-10-17 10:56:26 +0200133 /* 00 is 9 bits, 01 is 10 bits, 10 is 11 bits */
Yidi Linc6d7dcc2016-02-04 17:26:48 +0800134 bit_counter += ((value & COL_ADDR_BITS_MASK) >> COL_ADDR_BITS_SHIFT) +
135 9;
136
137 /* check if row address */
Elyes HAOUAS1f220a92020-02-20 14:17:55 +0100138 /* 00 is 13 bits, 01 is 14 bits, 10 is 15bits, 11 is 16 bits */
Yidi Linc6d7dcc2016-02-04 17:26:48 +0800139 bit_counter += ((value & ROW_ADDR_BITS_MASK) >> ROW_ADDR_BITS_SHIFT) +
140 13;
141
142 /* check if dual rank */
143 if (value & CONA_DUAL_RANK_EN)
144 bit_counter++;
145
146 /* add bank address bit, LPDDR3 is 8 banks =2^3 */
147 bit_counter += 3;
148
Elyes HAOUAS1f220a92020-02-20 14:17:55 +0100149 /* transform bits to bytes */
Yidi Linc6d7dcc2016-02-04 17:26:48 +0800150 return ((size_t)1 << (bit_counter - 3));
151}
152
PH Hsu3693d0f2015-12-16 13:48:10 +0800153static void init_4GB_mode(void)
154{
155 if (sdram_size() == (size_t)4 * GiB) {
Julius Werner55009af2019-12-02 22:03:27 -0800156 setbits32(&mt8173_pericfg->axi_bus_ctl3, PERISYS_4G_SUPPORT);
157 setbits32(&mt8173_infracfg->infra_misc, DDR_4GB_SUPPORT_EN);
PH Hsu3693d0f2015-12-16 13:48:10 +0800158 } else {
Julius Werner55009af2019-12-02 22:03:27 -0800159 clrbits32(&mt8173_pericfg->axi_bus_ctl3, PERISYS_4G_SUPPORT);
160 clrbits32(&mt8173_infracfg->infra_misc, DDR_4GB_SUPPORT_EN);
PH Hsu3693d0f2015-12-16 13:48:10 +0800161 }
162}
163
Peter Kaoda1e02a2015-07-31 17:11:14 +0800164void mt_set_emi(const struct mt8173_sdram_params *sdram_params)
165{
166 /* voltage info */
167 dram_vcore_adjust();
168 dram_vmem_adjust();
169
170 if (sdram_params->type != TYPE_LPDDR3) {
171 die("The DRAM type is not supported");
172 }
173
174 init_dram(sdram_params);
175 do_calib(sdram_params);
PH Hsu3693d0f2015-12-16 13:48:10 +0800176 init_4GB_mode();
Peter Kaoda1e02a2015-07-31 17:11:14 +0800177}