• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  *
4  * This program is free software; you can redistribute  it and/or modify it
5  * under  the terms of  the GNU General  Public License as published by the
6  * Free Software Foundation;  either version 2 of the  License, or (at your
7  * option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  *
17  */
18 
19 #include "ddr_interface.h"
20 #include "ddr_training_impl.h"
21 
22 #define CRG_REG_BASE 0x11010000U
23 #define PERI_CRG_DDRT 0x22A0U
24 #define PERI_CRG_DDRCKSEL 0x2280U
25 
26 /* sysctrl offset address */
27 #define DDRT_CTRL 0x4030 /* DDRT control register */
28 
29 /* register bit */
30 #define DDRTEST0_CKEN_BIT 4 /* DDRTEST0 clock gating configuration register */
31 #define DDRTEST0_SRST_REQ_BIT 0 /* soft reset request for DDRTEST0 */
32 #define DDRT0_MST_SEL_BIT 0 /* ddr p0 bus path selection control */
33 
34 /*
35  * Do some prepare before copy code from DDR to SRAM.
36  * Keep empty when nothing to do.
37  */
ddr_cmd_prepare_copy(void)38 void ddr_cmd_prepare_copy(void)
39 {
40 	return;
41 }
42 
43 /*
44  * Save site before DDR training command execute .
45  * Keep empty when nothing to do.
46  */
ddr_cmd_site_save(void)47 void ddr_cmd_site_save(void)
48 {
49 	return;
50 }
51 
52 /*
53  * Restore site after DDR training command execute.
54  * Keep empty when nothing to do.
55  */
ddr_cmd_site_restore(void)56 void ddr_cmd_site_restore(void)
57 {
58 	return;
59 }
60 
ddr_training_save_reg_custom(void * reg,unsigned int mask)61 void ddr_training_save_reg_custom(void *reg, unsigned int mask)
62 {
63 	return;
64 }
ddr_training_restore_reg_custom(void * reg)65 void ddr_training_restore_reg_custom(void *reg)
66 {
67 	return;
68 }
69 
70 /*
71  * Save site before DDR training:include boot and command execute.
72  * Keep empty when nothing to do.
73  */
ddr_boot_cmd_save(void * reg)74 void ddr_boot_cmd_save(void *reg)
75 {
76 	struct tr_relate_reg *relate_reg = (struct tr_relate_reg *)reg;
77 
78 	/* ddr bus path selection control */
79 	relate_reg->custom.ddr_ctrl = ddr_read(DDR_REG_BASE_SYSCTRL + DDRT_CTRL);
80 	ddr_write(relate_reg->custom.ddr_ctrl | (0x1 << DDRT0_MST_SEL_BIT), DDR_REG_BASE_SYSCTRL + DDRT_CTRL);
81 
82 	/* turn on ddrt clock */
83 	relate_reg->custom.ddrt_clk_reg = ddr_read(CRG_REG_BASE + PERI_CRG_DDRT);
84 	/* enable ddrt0 clock */
85 	ddr_write(relate_reg->custom.ddrt_clk_reg | (0x1 << DDRTEST0_CKEN_BIT), CRG_REG_BASE + PERI_CRG_DDRT);
86 	__asm__ __volatile__("nop");
87 	/* disable ddrt0 soft reset */
88 	ddr_write(ddr_read(CRG_REG_BASE + PERI_CRG_DDRT) & (~(0x1 << DDRTEST0_SRST_REQ_BIT)), CRG_REG_BASE + PERI_CRG_DDRT);
89 
90 	/* disable rdqs anti-aging */
91 	relate_reg->custom.phy0_age_compst_en = ddr_read(DDR_REG_BASE_PHY0 + DDR_PHY_PHYRSCTRL);
92 	ddr_write((relate_reg->custom.phy0_age_compst_en & (~(0x1 << PHY_CFG_RX_AGE_COMPST_EN_BIT))),
93 		DDR_REG_BASE_PHY0 + DDR_PHY_PHYRSCTRL);
94 #ifdef DDR_REG_BASE_PHY1
95 	relate_reg->custom.phy1_age_compst_en = ddr_read(DDR_REG_BASE_PHY1 + DDR_PHY_PHYRSCTRL);
96 	ddr_write((relate_reg->custom.phy1_age_compst_en & (~(0x1 << PHY_CFG_RX_AGE_COMPST_EN_BIT))),
97 		DDR_REG_BASE_PHY1 + DDR_PHY_PHYRSCTRL);
98 #endif
99 }
100 
101 /*
102  * Restore site after DDR training:include boot and command execute.
103  * Keep empty when nothing to do.
104  */
ddr_boot_cmd_restore(void * reg)105 void ddr_boot_cmd_restore(void *reg)
106 {
107 	struct tr_relate_reg *relate_reg = (struct tr_relate_reg *)reg;
108 
109 	/* restore ddr bus path selection */
110 	ddr_write(relate_reg->custom.ddr_ctrl, DDR_REG_BASE_SYSCTRL + DDRT_CTRL);
111 	/* restore ddrt clock */
112 	ddr_write(relate_reg->custom.ddrt_clk_reg, CRG_REG_BASE + PERI_CRG_DDRT);
113 
114 	/* restore rdqs anti-aging */
115 	ddr_write(relate_reg->custom.phy0_age_compst_en, DDR_REG_BASE_PHY0 + DDR_PHY_PHYRSCTRL);
116 #ifdef DDR_REG_BASE_PHY1
117 	ddr_write(relate_reg->custom.phy1_age_compst_en, DDR_REG_BASE_PHY1 + DDR_PHY_PHYRSCTRL);
118 #endif
119 }
120 
121 /*
122  * DDR clock select.
123  * For ddr osc training.
124  */
125 #ifdef DDR_PCODE_TRAINING_CONFIG
ddr_get_cksel(void)126 int ddr_get_cksel(void)
127 {
128 	int freq;
129 	unsigned int ddr_cksel;
130 	ddr_cksel = (ddr_read(CRG_REG_BASE + PERI_CRG_DDRCKSEL) >> 0x3) & 0x7;
131 	switch (ddr_cksel) {
132 	case 0x000:
133 		freq = 24; /* 24MHz */
134 		break;
135 	case 0x001:
136 		freq = 450; /* 450MHz */
137 		break;
138 	case 0x011:
139 		freq = 300; /* 300MHz */
140 		break;
141 	case 0x100:
142 		freq = 297; /* 297MHz */
143 		break;
144 	default:
145 		freq = 300; /* 300MHz */
146 		break;
147 	}
148 	return freq;
149 }
150 #endif
151