1/***********************license start***************
2 * Copyright (c) 2003-2010  Cavium Inc. (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 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
59extern "C" {
60#endif
61
62#define ENABLE_DEPRECATED   /* Set to enable the old 18/36 bit names */
63
64typedef 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 */
76typedef 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 */
90typedef 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 */
149static 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 */
163static 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 */
223static 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 */
256static 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 */
282static 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 */
310static 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*/
334typedef 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 */
357int 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 */
371int 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 */
385int 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