1 /*
2  * Copyright (c) 2021, Renesas Electronics Corporation. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <stdint.h>
8 
9 #include <common/debug.h>
10 #include <lib/mmio.h>
11 
12 #if RCAR_LSI == RCAR_AUTO
13 #include "G2E/qos_init_g2e_v10.h"
14 #include "G2H/qos_init_g2h_v30.h"
15 #include "G2M/qos_init_g2m_v10.h"
16 #include "G2M/qos_init_g2m_v11.h"
17 #include "G2M/qos_init_g2m_v30.h"
18 #include "G2N/qos_init_g2n_v10.h"
19 #endif /* RCAR_LSI == RCAR_AUTO */
20 #if (RCAR_LSI == RZ_G2M)
21 #include "G2M/qos_init_g2m_v10.h"
22 #include "G2M/qos_init_g2m_v11.h"
23 #include "G2M/qos_init_g2m_v30.h"
24 #endif /* RCAR_LSI == RZ_G2M */
25 #if RCAR_LSI == RZ_G2H
26 #include "G2H/qos_init_g2h_v30.h"
27 #endif /* RCAR_LSI == RZ_G2H */
28 #if RCAR_LSI == RZ_G2N
29 #include "G2N/qos_init_g2n_v10.h"
30 #endif /* RCAR_LSI == RZ_G2N */
31 #if RCAR_LSI == RZ_G2E
32 #include "G2E/qos_init_g2e_v10.h"
33 #endif /* RCAR_LSI == RZ_G2E */
34 #include "qos_common.h"
35 #include "qos_init.h"
36 #include "qos_reg.h"
37 #include "rcar_def.h"
38 
39 #if (RCAR_LSI != RZ_G2E)
40 #define DRAM_CH_CNT	0x04U
41 uint32_t qos_init_ddr_ch;
42 uint8_t qos_init_ddr_phyvalid;
43 #endif /* RCAR_LSI != RZ_G2E */
44 
45 #define PRR_PRODUCT_ERR(reg)				\
46 	{						\
47 		ERROR("LSI Product ID(PRR=0x%x) QoS "	\
48 		"initialize not supported.\n", reg);	\
49 		panic();				\
50 	}
51 
52 #define PRR_CUT_ERR(reg)				\
53 	{						\
54 		ERROR("LSI Cut ID(PRR=0x%x) QoS "	\
55 		"initialize not supported.\n", reg);	\
56 		panic();				\
57 	}
58 
rzg_qos_init(void)59 void rzg_qos_init(void)
60 {
61 	uint32_t reg;
62 #if (RCAR_LSI != RZ_G2E)
63 	uint32_t i;
64 
65 	qos_init_ddr_ch = 0U;
66 	qos_init_ddr_phyvalid = get_boardcnf_phyvalid();
67 	for (i = 0U; i < DRAM_CH_CNT; i++) {
68 		if ((qos_init_ddr_phyvalid & (1U << i))) {
69 			qos_init_ddr_ch++;
70 		}
71 	}
72 #endif /* RCAR_LSI != RZ_G2E */
73 
74 	reg = mmio_read_32(PRR);
75 #if (RCAR_LSI == RCAR_AUTO) || RCAR_LSI_CUT_COMPAT
76 	switch (reg & PRR_PRODUCT_MASK) {
77 	case PRR_PRODUCT_M3:
78 #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2M)
79 		switch (reg & PRR_CUT_MASK) {
80 		case PRR_PRODUCT_10:
81 			qos_init_g2m_v10();
82 			break;
83 		case PRR_PRODUCT_21: /* G2M Cut 13 */
84 			qos_init_g2m_v11();
85 			break;
86 		case PRR_PRODUCT_30: /* G2M Cut 30 */
87 		default:
88 			qos_init_g2m_v30();
89 			break;
90 		}
91 #else /* (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2M) */
92 		PRR_PRODUCT_ERR(reg);
93 #endif /* (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2M) */
94 		break;
95 	case PRR_PRODUCT_H3:
96 #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2H)
97 		switch (reg & PRR_CUT_MASK) {
98 		case PRR_PRODUCT_30:
99 		default:
100 			qos_init_g2h_v30();
101 			break;
102 		}
103 #else
104 		PRR_PRODUCT_ERR(reg);
105 #endif /* (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2H) */
106 		break;
107 	case PRR_PRODUCT_M3N:
108 #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2N)
109 		switch (reg & PRR_CUT_MASK) {
110 		case PRR_PRODUCT_10:
111 		default:
112 			qos_init_g2n_v10();
113 			break;
114 		}
115 #else
116 		PRR_PRODUCT_ERR(reg);
117 #endif /* (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2N) */
118 		break;
119 	case PRR_PRODUCT_E3:
120 #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2E)
121 		switch (reg & PRR_CUT_MASK) {
122 		case PRR_PRODUCT_10:
123 		default:
124 			qos_init_g2e_v10();
125 			break;
126 		}
127 #else
128 		PRR_PRODUCT_ERR(reg);
129 #endif /* (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2E) */
130 		break;
131 	default:
132 		PRR_PRODUCT_ERR(reg);
133 		break;
134 	}
135 #else /* RCAR_LSI == RCAR_AUTO || RCAR_LSI_CUT_COMPAT */
136 #if (RCAR_LSI == RZ_G2M)
137 #if RCAR_LSI_CUT == RCAR_CUT_10
138 	/* G2M Cut 10 */
139 	if ((PRR_PRODUCT_M3 | PRR_PRODUCT_10)
140 	    != (reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK))) {
141 		PRR_PRODUCT_ERR(reg);
142 	}
143 	qos_init_g2m_v10();
144 #elif RCAR_LSI_CUT == RCAR_CUT_11
145 	/* G2M Cut 11 */
146 	if ((PRR_PRODUCT_M3 | PRR_PRODUCT_20)
147 	    != (reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK))) {
148 		PRR_PRODUCT_ERR(reg);
149 	}
150 	qos_init_g2m_v11();
151 #elif RCAR_LSI_CUT == RCAR_CUT_13
152 	/* G2M Cut 13 */
153 	if ((PRR_PRODUCT_M3 | PRR_PRODUCT_21)
154 	    != (reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK))) {
155 		PRR_PRODUCT_ERR(reg);
156 	}
157 	qos_init_g2m_v11();
158 #else
159 	/* G2M Cut 30 or later */
160 	if ((PRR_PRODUCT_M3)
161 	    != (reg & (PRR_PRODUCT_MASK))) {
162 		PRR_PRODUCT_ERR(reg);
163 	}
164 	qos_init_g2m_v30();
165 #endif /* RCAR_LSI_CUT == RCAR_CUT_10 */
166 #elif (RCAR_LSI == RZ_G2H)
167 	/* G2H Cut 30 or later */
168 	if ((reg & PRR_PRODUCT_MASK) != PRR_PRODUCT_H3) {
169 		PRR_PRODUCT_ERR(reg);
170 	}
171 	qos_init_g2h_v30();
172 #elif (RCAR_LSI == RZ_G2N)
173 	/* G2N Cut 10 or later */
174 	if ((reg & (PRR_PRODUCT_MASK)) != PRR_PRODUCT_M3N) {
175 		PRR_PRODUCT_ERR(reg);
176 	}
177 	qos_init_g2n_v10();
178 #elif RCAR_LSI == RZ_G2E
179 	/* G2E Cut 10 or later */
180 	if ((reg & (PRR_PRODUCT_MASK)) != PRR_PRODUCT_E3) {
181 		PRR_PRODUCT_ERR(reg);
182 	}
183 	qos_init_g2e_v10();
184 #else /* (RCAR_LSI == RZ_G2M) */
185 #error "Don't have QoS initialize routine(Unknown chip)."
186 #endif /* (RCAR_LSI == RZ_G2M) */
187 #endif /* RCAR_LSI == RCAR_AUTO || RCAR_LSI_CUT_COMPAT */
188 }
189 
190 #if (RCAR_LSI != RZ_G2E)
get_refperiod(void)191 uint32_t get_refperiod(void)
192 {
193 	uint32_t refperiod = QOSWT_WTSET0_CYCLE;
194 
195 #if (RCAR_LSI == RCAR_AUTO) || RCAR_LSI_CUT_COMPAT
196 	uint32_t reg;
197 
198 	reg = mmio_read_32(PRR);
199 	switch (reg & PRR_PRODUCT_MASK) {
200 #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2M)
201 	case PRR_PRODUCT_M3:
202 		switch (reg & PRR_CUT_MASK) {
203 		case PRR_PRODUCT_10:
204 			break;
205 		case PRR_PRODUCT_20: /* G2M Cut 11 */
206 		case PRR_PRODUCT_21: /* G2M Cut 13 */
207 		case PRR_PRODUCT_30: /* G2M Cut 30 */
208 		default:
209 			refperiod = REFPERIOD_CYCLE;
210 			break;
211 		}
212 		break;
213 #endif /* (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2M) */
214 #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2H)
215 	case PRR_PRODUCT_H3:
216 		switch (reg & PRR_CUT_MASK) {
217 		case PRR_PRODUCT_30:
218 		default:
219 			refperiod = REFPERIOD_CYCLE;
220 			break;
221 		}
222 		break;
223 #endif /* (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2H) */
224 #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2N)
225 	case PRR_PRODUCT_M3N:
226 		refperiod = REFPERIOD_CYCLE;
227 		break;
228 #endif /* (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RZ_G2N) */
229 	default:
230 		break;
231 	}
232 #elif RCAR_LSI == RZ_G2M
233 #if RCAR_LSI_CUT == RCAR_CUT_10
234 	/* G2M Cut 10 */
235 #else /* RCAR_LSI_CUT == RCAR_CUT_10 */
236 	/* G2M Cut 11|13|30 or later */
237 	refperiod = REFPERIOD_CYCLE;
238 #endif /* RCAR_LSI_CUT == RCAR_CUT_10 */
239 #elif RCAR_LSI == RZ_G2N
240 	refperiod = REFPERIOD_CYCLE;
241 #elif RCAR_LSI == RZ_G2H
242 	/* G2H Cut 30 or later */
243 	refperiod = REFPERIOD_CYCLE;
244 #endif /* RCAR_LSI == RCAR_AUTO || RCAR_LSI_CUT_COMPAT */
245 	return refperiod;
246 }
247 #endif /* RCAR_LSI != RZ_G2E */
248 
rzg_qos_dbsc_setting(const struct rcar_gen3_dbsc_qos_settings * qos,unsigned int qos_size,bool dbsc_wren)249 void rzg_qos_dbsc_setting(const struct rcar_gen3_dbsc_qos_settings *qos,
250 			  unsigned int qos_size, bool dbsc_wren)
251 {
252 	unsigned int i;
253 
254 	/* Register write enable */
255 	if (dbsc_wren) {
256 		mmio_write_32(DBSC_DBSYSCNT0, 0x00001234U);
257 	}
258 
259 	for (i = 0; i < qos_size; i++) {
260 		mmio_write_32(qos[i].reg, qos[i].val);
261 	}
262 
263 	/* Register write protect */
264 	if (dbsc_wren) {
265 		mmio_write_32(DBSC_DBSYSCNT0, 0x00000000U);
266 	}
267 }
268