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