• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 NXP
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include <errno.h>
9 #include <stdint.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 
13 #include <common/debug.h>
14 #include <ddr.h>
15 #include <immap.h>
16 #include <lib/mmio.h>
17 
18 #define UL_5POW12	244140625UL
19 #define ULL_2E12	2000000000000ULL
20 #define UL_2POW13	(1UL << 13)
21 #define ULL_8FS		0xFFFFFFFFULL
22 
23 #define do_div(n, base) ({				\
24 	unsigned int __base = (base);			\
25 	unsigned int __rem;				\
26 	__rem = ((unsigned long long)(n)) % __base;	\
27 	(n) = ((unsigned long long)(n)) / __base;	\
28 	__rem;						\
29 })
30 
31 #define CCN_HN_F_SAM_NODEID_MASK	0x7f
32 #ifdef NXP_HAS_CCN504
33 #define CCN_HN_F_SAM_NODEID_DDR0	0x4
34 #define CCN_HN_F_SAM_NODEID_DDR1	0xe
35 #elif defined(NXP_HAS_CCN508)
36 #define CCN_HN_F_SAM_NODEID_DDR0	0x8
37 #define CCN_HN_F_SAM_NODEID_DDR1	0x18
38 #endif
39 
get_ddr_freq(struct sysinfo * sys,int ctrl_num)40 unsigned long get_ddr_freq(struct sysinfo *sys, int ctrl_num)
41 {
42 	if (sys->freq_ddr_pll0 == 0) {
43 		get_clocks(sys);
44 	}
45 
46 	switch (ctrl_num) {
47 	case 0:
48 		return sys->freq_ddr_pll0;
49 	case 1:
50 		return sys->freq_ddr_pll0;
51 	case 2:
52 		return sys->freq_ddr_pll1;
53 	}
54 
55 	return 0;
56 }
57 
get_memory_clk_ps(const unsigned long data_rate)58 unsigned int get_memory_clk_ps(const unsigned long data_rate)
59 {
60 	unsigned int result;
61 	/* Round to nearest 10ps, being careful about 64-bit multiply/divide */
62 	unsigned long long rem, mclk_ps = ULL_2E12;
63 
64 	/* Now perform the big divide, the result fits in 32-bits */
65 	rem = do_div(mclk_ps, data_rate);
66 	result = (rem >= (data_rate >> 1)) ? mclk_ps + 1 : mclk_ps;
67 
68 	return result;
69 }
70 
picos_to_mclk(unsigned long data_rate,unsigned int picos)71 unsigned int picos_to_mclk(unsigned long data_rate, unsigned int picos)
72 {
73 	unsigned long long clks, clks_rem;
74 
75 	/* Short circuit for zero picos */
76 	if ((picos == 0U) || (data_rate == 0UL)) {
77 		return 0U;
78 	}
79 
80 	/* First multiply the time by the data rate (32x32 => 64) */
81 	clks = picos * (unsigned long long)data_rate;
82 	/*
83 	 * Now divide by 5^12 and track the 32-bit remainder, then divide
84 	 * by 2*(2^12) using shifts (and updating the remainder).
85 	 */
86 	clks_rem = do_div(clks, UL_5POW12);
87 	clks_rem += (clks & (UL_2POW13-1)) * UL_5POW12;
88 	clks >>= 13U;
89 
90 	/* If we had a remainder greater than the 1ps error, then round up */
91 	if (clks_rem > data_rate) {
92 		clks++;
93 	}
94 
95 	/* Clamp to the maximum representable value */
96 	if (clks > ULL_8FS) {
97 		clks = ULL_8FS;
98 	}
99 	return (unsigned int) clks;
100 }
101 
102 /* valid_spd_mask has been checked by parse_spd */
disable_unused_ddrc(struct ddr_info * priv,int valid_spd_mask,uintptr_t nxp_ccn_hn_f0_addr)103 int disable_unused_ddrc(struct ddr_info *priv,
104 			int valid_spd_mask, uintptr_t nxp_ccn_hn_f0_addr)
105 {
106 #if defined(NXP_HAS_CCN504) || defined(NXP_HAS_CCN508)
107 	void *hnf_sam_ctrl = (void *)(nxp_ccn_hn_f0_addr + CCN_HN_F_SAM_CTL);
108 	uint32_t val, nodeid;
109 #ifdef NXP_HAS_CCN504
110 	uint32_t num_hnf_nodes = 4U;
111 #else
112 	uint32_t num_hnf_nodes = 8U;
113 #endif
114 	int disable_ddrc = 0;
115 	int i;
116 
117 	if (priv->num_ctlrs < 2) {
118 		debug("%s: nothing to do.\n", __func__);
119 	}
120 
121 	switch (priv->dimm_on_ctlr) {
122 	case 1:
123 		disable_ddrc = ((valid_spd_mask &0x2) == 0) ? 2 : 0;
124 		disable_ddrc = ((valid_spd_mask &0x1) == 0) ? 1 : disable_ddrc;
125 		break;
126 	case 2:
127 		disable_ddrc = ((valid_spd_mask &0x4) == 0) ? 2 : 0;
128 		disable_ddrc = ((valid_spd_mask &0x1) == 0) ? 1 : disable_ddrc;
129 		break;
130 	default:
131 		ERROR("Invalid number of DIMMs %d\n", priv->dimm_on_ctlr);
132 		return -EINVAL;
133 	}
134 
135 	if (disable_ddrc != 0) {
136 		debug("valid_spd_mask = 0x%x\n", valid_spd_mask);
137 	}
138 
139 	switch (disable_ddrc) {
140 	case 1:
141 		priv->num_ctlrs = 1;
142 		priv->spd_addr = &priv->spd_addr[priv->dimm_on_ctlr];
143 		priv->ddr[0] = priv->ddr[1];
144 		priv->ddr[1] = NULL;
145 		priv->phy[0] = priv->phy[0];
146 		priv->phy[1] = NULL;
147 		debug("Disable first DDR controller\n");
148 		break;
149 	case 2:
150 		priv->num_ctlrs = 1;
151 		priv->ddr[1] = NULL;
152 		priv->phy[1] = NULL;
153 		debug("Disable second DDR controller\n");
154 		/* fallthrough */
155 	case 0:
156 		break;
157 	default:
158 		ERROR("Program error.\n");
159 		return -EINVAL;
160 	}
161 
162 	if (disable_ddrc == 0) {
163 		debug("Both controllers in use.\n");
164 		return 0;
165 	}
166 
167 	for (i = 0; i < num_hnf_nodes; i++) {
168 		val = mmio_read_64((uintptr_t)hnf_sam_ctrl);
169 		nodeid = disable_ddrc == 1 ? CCN_HN_F_SAM_NODEID_DDR1 :
170 			 (disable_ddrc == 2 ? CCN_HN_F_SAM_NODEID_DDR0 :
171 			  (i < 4 ? CCN_HN_F_SAM_NODEID_DDR0
172 				 : CCN_HN_F_SAM_NODEID_DDR1));
173 		if (nodeid != (val & CCN_HN_F_SAM_NODEID_MASK)) {
174 			debug("Setting HN-F node %d\n", i);
175 			debug("nodeid = 0x%x\n", nodeid);
176 			val &= ~CCN_HN_F_SAM_NODEID_MASK;
177 			val |= nodeid;
178 			mmio_write_64((uintptr_t)hnf_sam_ctrl, val);
179 		}
180 		hnf_sam_ctrl += CCN_HN_F_REGION_SIZE;
181 	}
182 #endif
183 	return 0;
184 }
185 
get_ddrc_version(const struct ccsr_ddr * ddr)186 unsigned int get_ddrc_version(const struct ccsr_ddr *ddr)
187 {
188 	unsigned int ver;
189 
190 	ver = (ddr_in32(&ddr->ip_rev1) & 0xFFFF) << 8U;
191 	ver |= (ddr_in32(&ddr->ip_rev2) & 0xFF00) >> 8U;
192 
193 	return ver;
194 }
195 
print_ddr_info(struct ccsr_ddr * ddr)196 void print_ddr_info(struct ccsr_ddr *ddr)
197 {
198 	unsigned int cs0_config = ddr_in32(&ddr->csn_cfg[0]);
199 	unsigned int sdram_cfg = ddr_in32(&ddr->sdram_cfg);
200 	int cas_lat;
201 
202 	if ((sdram_cfg & SDRAM_CFG_MEM_EN) == 0U) {
203 		printf(" (DDR not enabled)\n");
204 		return;
205 	}
206 
207 	printf("DDR");
208 	switch ((sdram_cfg & SDRAM_CFG_SDRAM_TYPE_MASK) >>
209 		SDRAM_CFG_SDRAM_TYPE_SHIFT) {
210 	case SDRAM_TYPE_DDR4:
211 		printf("4");
212 		break;
213 	default:
214 		printf("?");
215 		break;
216 	}
217 
218 	switch (sdram_cfg & SDRAM_CFG_DBW_MASK) {
219 	case SDRAM_CFG_32_BW:
220 		printf(", 32-bit");
221 		break;
222 	case SDRAM_CFG_16_BW:
223 		printf(", 16-bit");
224 		break;
225 	case SDRAM_CFG_8_BW:
226 		printf(", 8-bit");
227 		break;
228 	default:
229 		printf(", 64-bit");
230 		break;
231 	}
232 
233 	/* Calculate CAS latency based on timing cfg values */
234 	cas_lat = ((ddr_in32(&ddr->timing_cfg_1) >> 16) & 0xf);
235 	cas_lat += 2;	/* for DDRC newer than 4.4 */
236 	cas_lat += ((ddr_in32(&ddr->timing_cfg_3) >> 12) & 3) << 4;
237 	printf(", CL=%d", cas_lat >> 1);
238 	if ((cas_lat & 0x1) != 0) {
239 		printf(".5");
240 	}
241 
242 	if ((sdram_cfg & SDRAM_CFG_ECC_EN) != 0) {
243 		printf(", ECC on");
244 	} else {
245 		printf(", ECC off");
246 	}
247 
248 	if ((cs0_config & 0x20000000) != 0) {
249 		printf(", ");
250 		switch ((cs0_config >> 24) & 0xf) {
251 		case DDR_256B_INTLV:
252 			printf("256B");
253 			break;
254 		default:
255 			printf("invalid");
256 			break;
257 		}
258 	}
259 
260 	if (((sdram_cfg >> 8) & 0x7f) != 0) {
261 		printf(", ");
262 		switch (sdram_cfg >> 8 & 0x7f) {
263 		case DDR_BA_INTLV_CS0123:
264 			printf("CS0+CS1+CS2+CS3");
265 			break;
266 		case DDR_BA_INTLV_CS01:
267 			printf("CS0+CS1");
268 			break;
269 		default:
270 			printf("invalid");
271 			break;
272 		}
273 	}
274 	printf("\n");
275 }
276