1 /***********************license start***************
2 * Copyright (c) 2003-2010 Cavium Inc. ([email protected]). All rights
3 * reserved.
4 *
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17
18 * * Neither the name of Cavium Inc. nor the names of
19 * its contributors may be used to endorse or promote products
20 * derived from this software without specific prior written
21 * permission.
22
23 * This Software, including technical data, may be subject to U.S. export control
24 * laws, including the U.S. Export Administration Act and its associated
25 * regulations, and may be subject to export or import regulations in other
26 * countries.
27
28 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
29 * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
30 * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
31 * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
32 * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
33 * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
34 * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
35 * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
36 * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR
37 * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
38 ***********************license end**************************************/
39
40
41
42
43
44
45
46 /**
47 * @file
48 *
49 * interface to the low latency DRAM
50 *
51 * <hr>$Revision: 70030 $<hr>
52 *
53 */
54
55 #ifndef __CVMX_LLM_H__
56 #define __CVMX_LLM_H__
57
58 #ifdef __cplusplus
59 extern "C" {
60 #endif
61
62 #define ENABLE_DEPRECATED /* Set to enable the old 18/36 bit names */
63
64 typedef enum
65 {
66 CVMX_LLM_REPLICATION_NONE = 0,
67 CVMX_LLM_REPLICATION_2X = 1, // on both interfaces, or 2x if only one interface
68 CVMX_LLM_REPLICATION_4X = 2, // both interfaces, 2x, or 4x if only one interface
69 CVMX_LLM_REPLICATION_8X = 3, // both interfaces, 4x, or 8x if only one interface
70 } cvmx_llm_replication_t;
71
72 /**
73 * This structure defines the address used to the low-latency memory.
74 * This address format is used for both loads and stores.
75 */
76 typedef union
77 {
78 uint64_t u64;
79 struct
80 {
81 uint64_t mbz :30;
82 cvmx_llm_replication_t repl : 2;
83 uint64_t address :32; // address<1:0> mbz, address<31:30> mbz
84 } s;
85 } cvmx_llm_address_t;
86
87 /**
88 * This structure defines the data format in the low-latency memory
89 */
90 typedef union
91 {
92 uint64_t u64;
93
94 /**
95 * this format defines the format returned on a load
96 * a load returns the 32/36-bits in memory, plus xxor = even_parity(dat<35:0>)
97 * typically, dat<35> = parity(dat<34:0>), so the xor bit directly indicates parity error
98 * Note that the data field size is 36 bits on the 36XX/38XX, and 32 bits on the 31XX
99 */
100 struct
101 {
102 uint64_t mbz1 :27;
103 uint64_t xxor : 1;
104 uint64_t mbz : 4;
105 uint64_t dat :32;
106 } cn31xx;
107
108 struct
109 {
110 uint64_t mbz :27;
111 uint64_t xxor : 1;
112 uint64_t dat :36;
113 } s;
114
115 /**
116 * This format defines what should be used if parity is desired. Hardware returns
117 * the XOR of all the bits in the 36/32 bit data word, so for parity software must use
118 * one of the data field bits as a parity bit.
119 */
120 struct cn31xx_par_struct
121 {
122 uint64_t mbz :32;
123 uint64_t par : 1;
124 uint64_t dat :31;
125 } cn31xx_par;
126 struct cn38xx_par_struct
127 {
128 uint64_t mbz :28;
129 uint64_t par : 1;
130 uint64_t dat :35;
131 } cn38xx_par;
132 #if !OCTEON_IS_COMMON_BINARY()
133 #if CVMX_COMPILED_FOR(OCTEON_CN31XX)
134 struct cn31xx_par_struct spar;
135 #else
136 struct cn38xx_par_struct spar;
137 #endif
138 #endif
139 } cvmx_llm_data_t;
140
141 #define CVMX_LLM_NARROW_DATA_WIDTH ((CVMX_COMPILED_FOR(OCTEON_CN31XX)) ? 32 : 36)
142
143 /**
144 * Calculate the parity value of a number
145 *
146 * @param value
147 * @return parity value
148 */
cvmx_llm_parity(uint64_t value)149 static inline uint64_t cvmx_llm_parity(uint64_t value)
150 {
151 uint64_t result;
152 CVMX_DPOP(result, value);
153 return result;
154 }
155
156
157 /**
158 * Calculate the ECC needed for 36b LLM mode
159 *
160 * @param value
161 * @return ECC value
162 */
cvmx_llm_ecc(uint64_t value)163 static inline int cvmx_llm_ecc(uint64_t value)
164 {
165 /* FIXME: This needs a re-write */
166 static const uint32_t ecc_code_29[7] = {
167 0x08962595,
168 0x112a4aaa,
169 0x024c934f,
170 0x04711c73,
171 0x0781e07c,
172 0x1801ff80,
173 0x1ffe0000};
174 uint64_t pop0, pop1, pop2, pop3, pop4, pop5, pop6;
175
176 pop0 = ecc_code_29[0];
177 pop1 = ecc_code_29[1];
178 pop2 = ecc_code_29[2];
179 pop0 &= value;
180 pop3 = ecc_code_29[3];
181 CVMX_DPOP(pop0, pop0);
182 pop4 = ecc_code_29[4];
183 pop1 &= value;
184 CVMX_DPOP(pop1, pop1);
185 pop2 &= value;
186 pop5 = ecc_code_29[5];
187 CVMX_DPOP(pop2, pop2);
188 pop6 = ecc_code_29[6];
189 pop3 &= value;
190 CVMX_DPOP(pop3, pop3);
191 pop4 &= value;
192 CVMX_DPOP(pop4, pop4);
193 pop5 &= value;
194 CVMX_DPOP(pop5, pop5);
195 pop6 &= value;
196 CVMX_DPOP(pop6, pop6);
197
198 return((pop6&1)<<6) | ((pop5&1)<<5) | ((pop4&1)<<4) | ((pop3&1)<<3) | ((pop2&1)<<2) | ((pop1&1)<<1) | (pop0&1);
199 }
200
201
202 #ifdef ENABLE_DEPRECATED
203 /* These macros are provided to provide compatibility with code that uses
204 ** the old names for the llm access functions. The names were changed
205 ** when support for the 31XX llm was added, as the widths differ between Octeon Models.
206 ** The wide/narrow names are preferred, and should be used in all new code */
207 #define cvmx_llm_write36 cvmx_llm_write_narrow
208 #define cvmx_llm_read36 cvmx_llm_read_narrow
209 #define cvmx_llm_write64 cvmx_llm_write_wide
210 #define cvmx_llm_read64 cvmx_llm_read_wide
211 #endif
212 /**
213 * Write to LLM memory - 36 bit
214 *
215 * @param address Address in LLM to write. Consecutive writes increment the
216 * address by 4. The replication mode is also encoded in this
217 * address.
218 * @param value Value to write to LLM. Only the low 36 bits will be used.
219 * @param set Which of the two coprocessor 2 register sets to use for the
220 * write. May be used to get two outstanding LLM access at once
221 * per core. Range: 0-1
222 */
cvmx_llm_write_narrow(cvmx_llm_address_t address,uint64_t value,int set)223 static inline void cvmx_llm_write_narrow(cvmx_llm_address_t address, uint64_t value, int set)
224 {
225 cvmx_llm_data_t data;
226 data.s.mbz = 0;
227
228 data.s.dat = value;
229
230 data.s.xxor = 0;
231
232 if (set)
233 {
234 CVMX_MT_LLM_DATA(1, data.u64);
235 CVMX_MT_LLM_WRITE_ADDR_INTERNAL(1, address.u64);
236 }
237 else
238 {
239 CVMX_MT_LLM_DATA(0, data.u64);
240 CVMX_MT_LLM_WRITE_ADDR_INTERNAL(0, address.u64);
241 }
242 }
243
244
245 /**
246 * Write to LLM memory - 64 bit
247 *
248 * @param address Address in LLM to write. Consecutive writes increment the
249 * address by 8. The replication mode is also encoded in this
250 * address.
251 * @param value Value to write to LLM.
252 * @param set Which of the two coprocessor 2 register sets to use for the
253 * write. May be used to get two outstanding LLM access at once
254 * per core. Range: 0-1
255 */
cvmx_llm_write_wide(cvmx_llm_address_t address,uint64_t value,int set)256 static inline void cvmx_llm_write_wide(cvmx_llm_address_t address, uint64_t value, int set)
257 {
258 if (set)
259 {
260 CVMX_MT_LLM_DATA(1, value);
261 CVMX_MT_LLM_WRITE64_ADDR_INTERNAL(1, address.u64);
262 }
263 else
264 {
265 CVMX_MT_LLM_DATA(0, value);
266 CVMX_MT_LLM_WRITE64_ADDR_INTERNAL(0, address.u64);
267 }
268 }
269
270
271 /**
272 * Read from LLM memory - 36 bit
273 *
274 * @param address Address in LLM to read. Consecutive reads increment the
275 * address by 4. The replication mode is also encoded in this
276 * address.
277 * @param set Which of the two coprocessor 2 register sets to use for the
278 * write. May be used to get two outstanding LLM access at once
279 * per core. Range: 0-1
280 * @return The lower 36 bits contain the result of the read
281 */
cvmx_llm_read_narrow(cvmx_llm_address_t address,int set)282 static inline cvmx_llm_data_t cvmx_llm_read_narrow(cvmx_llm_address_t address, int set)
283 {
284 cvmx_llm_data_t value;
285 if (set)
286 {
287 CVMX_MT_LLM_READ_ADDR(1, address.u64);
288 CVMX_MF_LLM_DATA(1, value.u64);
289 }
290 else
291 {
292 CVMX_MT_LLM_READ_ADDR(0, address.u64);
293 CVMX_MF_LLM_DATA(0, value.u64);
294 }
295 return value;
296 }
297
298
299 /**
300 * Read from LLM memory - 64 bit
301 *
302 * @param address Address in LLM to read. Consecutive reads increment the
303 * address by 8. The replication mode is also encoded in this
304 * address.
305 * @param set Which of the two coprocessor 2 register sets to use for the
306 * write. May be used to get two outstanding LLM access at once
307 * per core. Range: 0-1
308 * @return The result of the read
309 */
cvmx_llm_read_wide(cvmx_llm_address_t address,int set)310 static inline uint64_t cvmx_llm_read_wide(cvmx_llm_address_t address, int set)
311 {
312 uint64_t value;
313 if (set)
314 {
315 CVMX_MT_LLM_READ64_ADDR(1, address);
316 CVMX_MF_LLM_DATA(1, value);
317 }
318 else
319 {
320 CVMX_MT_LLM_READ64_ADDR(0, address);
321 CVMX_MF_LLM_DATA(0, value);
322 }
323 return value;
324 }
325
326
327 #define RLD_INIT_DELAY (1<<18)
328
329
330
331 /* This structure describes the RLDRAM configuration for a board. This structure
332 ** must be populated with the correct values and passed to the initialization function.
333 */
334 typedef struct
335 {
336 uint32_t cpu_hz; /* CPU frequency in Hz */
337 char addr_rld0_fb_str [100]; /* String describing RLDRAM connections on rld 0 front (0) bunk*/
338 char addr_rld0_bb_str [100]; /* String describing RLDRAM connections on rld 0 back (1) bunk*/
339 char addr_rld1_fb_str [100]; /* String describing RLDRAM connections on rld 1 front (0) bunk*/
340 char addr_rld1_bb_str [100]; /* String describing RLDRAM connections on rld 1 back (1) bunk*/
341 uint8_t rld0_bunks; /* Number of bunks on rld 0 (0 is disabled) */
342 uint8_t rld1_bunks; /* Number of bunks on rld 1 (0 is disabled) */
343 uint16_t rld0_mbytes; /* mbytes on rld 0 */
344 uint16_t rld1_mbytes; /* mbytes on rld 1 */
345 uint16_t max_rld_clock_mhz; /* Maximum RLD clock in MHz, only used for CN58XX */
346 } llm_descriptor_t;
347
348 /**
349 * Initialize LLM memory controller. This must be done
350 * before the low latency memory can be used.
351 * This is simply a wrapper around cvmx_llm_initialize_desc(),
352 * and is deprecated.
353 *
354 * @return -1 on error
355 * 0 on success
356 */
357 int cvmx_llm_initialize(void);
358
359
360 /**
361 * Initialize LLM memory controller. This must be done
362 * before the low latency memory can be used.
363 *
364 * @param llm_desc_ptr
365 * Pointer to descriptor structure. If NULL
366 * is passed, a default setting is used if available.
367 *
368 * @return -1 on error
369 * Size of llm in bytes on success
370 */
371 int cvmx_llm_initialize_desc(llm_descriptor_t *llm_desc_ptr);
372
373
374
375 /**
376 * Gets the default llm descriptor for the board code is being run on.
377 *
378 * @param llm_desc_ptr
379 * Pointer to descriptor structure to be filled in. Contents are only
380 * valid after successful completion. Must not be NULL.
381 *
382 * @return -1 on error
383 * 0 on success
384 */
385 int cvmx_llm_get_default_descriptor(llm_descriptor_t *llm_desc_ptr);
386
387 #ifdef __cplusplus
388 }
389 #endif
390
391 #endif /* __CVM_LLM_H__ */
392