• 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 #define DDRT1_MST_SEL_BIT 1 /* ddr p1 bus path selection control */
34 
35 /**
36  * Do some prepare before copy code from DDR to SRAM.
37  * Keep empty when nothing to do.
38  */
ddr_cmd_prepare_copy(void)39 void ddr_cmd_prepare_copy(void)
40 {
41 	return;
42 }
43 
44 /**
45  * Save site before DDR training command execute .
46  * Keep empty when nothing to do.
47  */
ddr_cmd_site_save(void)48 void ddr_cmd_site_save(void)
49 {
50 	return;
51 }
52 
53 /**
54  * Restore site after DDR training command execute.
55  * Keep empty when nothing to do.
56  */
ddr_cmd_site_restore(void)57 void ddr_cmd_site_restore(void)
58 {
59 	return;
60 }
61 
ddr_training_save_reg_custom(void * reg,unsigned int mask)62 void ddr_training_save_reg_custom(void *reg, unsigned int mask)
63 {
64 	return;
65 }
ddr_training_restore_reg_custom(void * reg)66 void ddr_training_restore_reg_custom(void *reg)
67 {
68 	return;
69 }
70 
71 /**
72  * Save site before DDR training:include boot and command execute.
73  * Keep empty when nothing to do.
74  */
ddr_boot_cmd_save(void * reg)75 void ddr_boot_cmd_save(void *reg)
76 {
77 	struct tr_relate_reg *relate_reg = (struct tr_relate_reg *)reg;
78 
79 	/* ddr bus path selection control */
80 	relate_reg->custom.ddr_ctrl = ddr_read(DDR_REG_BASE_SYSCTRL + DDRT_CTRL);
81 	ddr_write(relate_reg->custom.ddr_ctrl | (0x1 << DDRT0_MST_SEL_BIT) |
82 		(0x1 << DDRT1_MST_SEL_BIT), DDR_REG_BASE_SYSCTRL + DDRT_CTRL);
83 
84 	/* turn on ddrt clock */
85 	relate_reg->custom.ddrt_clk_reg = ddr_read(CRG_REG_BASE + PERI_CRG_DDRT);
86 	/* enable ddrt0 clock */
87 	ddr_write(relate_reg->custom.ddrt_clk_reg | (0x1 << DDRTEST0_CKEN_BIT), CRG_REG_BASE + PERI_CRG_DDRT);
88 	__asm__ __volatile__("nop");
89 	/* disable ddrt0 soft reset */
90 	ddr_write(ddr_read(CRG_REG_BASE + PERI_CRG_DDRT) & (~(0x1 << DDRTEST0_SRST_REQ_BIT)), CRG_REG_BASE + PERI_CRG_DDRT);
91 
92 	/* disable rdqs anti-aging */
93 	relate_reg->custom.phy0_age_compst_en = ddr_read(DDR_REG_BASE_PHY0 + DDR_PHY_PHYRSCTRL);
94 	ddr_write((relate_reg->custom.phy0_age_compst_en & (~(0x1 << PHY_CFG_RX_AGE_COMPST_EN_BIT))),
95 		DDR_REG_BASE_PHY0 + DDR_PHY_PHYRSCTRL);
96 #ifdef DDR_REG_BASE_PHY1
97 	relate_reg->custom.phy1_age_compst_en = ddr_read(DDR_REG_BASE_PHY1 + DDR_PHY_PHYRSCTRL);
98 	ddr_write((relate_reg->custom.phy1_age_compst_en & (~(0x1 << PHY_CFG_RX_AGE_COMPST_EN_BIT))),
99 		DDR_REG_BASE_PHY1 + DDR_PHY_PHYRSCTRL);
100 #endif
101 }
102 
103 /**
104  * Restore site after DDR training:include boot and command execute.
105  * Keep empty when nothing to do.
106  */
ddr_boot_cmd_restore(void * reg)107 void ddr_boot_cmd_restore(void *reg)
108 {
109 	struct tr_relate_reg *relate_reg = (struct tr_relate_reg *)reg;
110 
111 	/* restore ddr bus path selection */
112 	ddr_write(relate_reg->custom.ddr_ctrl, DDR_REG_BASE_SYSCTRL + DDRT_CTRL);
113 	/* restore ddrt clock */
114 	ddr_write(relate_reg->custom.ddrt_clk_reg, CRG_REG_BASE + PERI_CRG_DDRT);
115 
116 	/* restore rdqs anti-aging */
117 	ddr_write(relate_reg->custom.phy0_age_compst_en, DDR_REG_BASE_PHY0 + DDR_PHY_PHYRSCTRL);
118 #ifdef DDR_REG_BASE_PHY1
119 	ddr_write(relate_reg->custom.phy1_age_compst_en, DDR_REG_BASE_PHY1 + DDR_PHY_PHYRSCTRL);
120 #endif
121 }
122 
123 /**
124  * DDR clock select.
125  * For ddr osc training.
126  */
127 #ifdef DDR_PCODE_TRAINING_CONFIG
ddr_get_cksel(void)128 int ddr_get_cksel(void)
129 {
130 	int freq;
131 	unsigned int ddr_cksel;
132 	ddr_cksel = (ddr_read(CRG_REG_BASE + PERI_CRG_DDRCKSEL) >> 0x3) & 0x7;
133 	switch (ddr_cksel) {
134 	case 0x000:
135 		freq = 24; /* 24MHz */
136 		break;
137 	case 0x001:
138 		freq = 450; /* 450MHz */
139 		break;
140 	case 0x011:
141 		freq = 300; /* 300MHz */
142 		break;
143 	case 0x100:
144 		freq = 297; /* 297MHz */
145 		break;
146 	default:
147 		freq = 300; /* 300MHz */
148 		break;
149 	}
150 	return freq;
151 }
152 #endif
153