]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/contrib/octeon-sdk/cvmx-llm.h
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / contrib / octeon-sdk / cvmx-llm.h
1 /***********************license start***************
2  * Copyright (c) 2003-2010  Cavium Networks (support@cavium.com). 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 Networks 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  NETWORKS 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: 49448 $<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  */
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  */
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  */
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  */
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  */
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  */
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__ */