blob: d33ad77839b10f823d8cdfb2a842726a94b3b484 [file] [log] [blame]
Pankaj Guptac518de42020-12-09 14:02:39 +05301/*
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
40unsigned 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
58unsigned 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
71unsigned 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 */
103int 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
186unsigned 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
196void 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}