1210284Sjmallett/***********************license start***************
2232812Sjmallett * Copyright (c) 2003-2010  Cavium Inc. (support@cavium.com). All rights
3215990Sjmallett * reserved.
4210284Sjmallett *
5210284Sjmallett *
6215990Sjmallett * Redistribution and use in source and binary forms, with or without
7215990Sjmallett * modification, are permitted provided that the following conditions are
8215990Sjmallett * met:
9210284Sjmallett *
10215990Sjmallett *   * Redistributions of source code must retain the above copyright
11215990Sjmallett *     notice, this list of conditions and the following disclaimer.
12210284Sjmallett *
13215990Sjmallett *   * Redistributions in binary form must reproduce the above
14215990Sjmallett *     copyright notice, this list of conditions and the following
15215990Sjmallett *     disclaimer in the documentation and/or other materials provided
16215990Sjmallett *     with the distribution.
17215990Sjmallett
18232812Sjmallett *   * Neither the name of Cavium Inc. nor the names of
19215990Sjmallett *     its contributors may be used to endorse or promote products
20215990Sjmallett *     derived from this software without specific prior written
21215990Sjmallett *     permission.
22215990Sjmallett
23215990Sjmallett * This Software, including technical data, may be subject to U.S. export  control
24215990Sjmallett * laws, including the U.S. Export Administration Act and its  associated
25215990Sjmallett * regulations, and may be subject to export or import  regulations in other
26215990Sjmallett * countries.
27215990Sjmallett
28215990Sjmallett * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
29232812Sjmallett * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
30215990Sjmallett * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
31215990Sjmallett * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
32215990Sjmallett * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
33215990Sjmallett * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
34215990Sjmallett * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
35215990Sjmallett * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
36215990Sjmallett * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE  RISK ARISING OUT OF USE OR
37215990Sjmallett * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
38210284Sjmallett ***********************license end**************************************/
39210284Sjmallett
40210284Sjmallett
41210284Sjmallett
42210284Sjmallett
43210284Sjmallett
44210284Sjmallett
45215990Sjmallett
46210284Sjmallett/**
47210284Sjmallett * @file
48210284Sjmallett *
49210284Sjmallett * interface to the low latency DRAM
50210284Sjmallett *
51232812Sjmallett * <hr>$Revision: 70030 $<hr>
52210284Sjmallett *
53210284Sjmallett */
54210284Sjmallett
55210284Sjmallett#ifndef __CVMX_LLM_H__
56210284Sjmallett#define __CVMX_LLM_H__
57210284Sjmallett
58210284Sjmallett#ifdef	__cplusplus
59210284Sjmallettextern "C" {
60210284Sjmallett#endif
61210284Sjmallett
62210284Sjmallett#define ENABLE_DEPRECATED   /* Set to enable the old 18/36 bit names */
63210284Sjmallett
64210284Sjmalletttypedef enum
65210284Sjmallett{
66210284Sjmallett    CVMX_LLM_REPLICATION_NONE = 0,
67210284Sjmallett    CVMX_LLM_REPLICATION_2X = 1, // on both interfaces, or 2x if only one interface
68210284Sjmallett    CVMX_LLM_REPLICATION_4X = 2, // both interfaces, 2x, or 4x if only one interface
69210284Sjmallett    CVMX_LLM_REPLICATION_8X = 3, // both interfaces, 4x,  or 8x if only one interface
70210284Sjmallett} cvmx_llm_replication_t;
71210284Sjmallett
72210284Sjmallett/**
73210284Sjmallett * This structure defines the address used to the low-latency memory.
74210284Sjmallett * This address format is used for both loads and stores.
75210284Sjmallett */
76210284Sjmalletttypedef union
77210284Sjmallett{
78210284Sjmallett    uint64_t u64;
79210284Sjmallett    struct
80210284Sjmallett    {
81210284Sjmallett        uint64_t                mbz     :30;
82210284Sjmallett        cvmx_llm_replication_t  repl    : 2;
83210284Sjmallett        uint64_t                address :32; // address<1:0> mbz, address<31:30> mbz
84210284Sjmallett    } s;
85210284Sjmallett} cvmx_llm_address_t;
86210284Sjmallett
87210284Sjmallett/**
88210284Sjmallett * This structure defines the data format in the low-latency memory
89210284Sjmallett */
90210284Sjmalletttypedef union
91210284Sjmallett{
92210284Sjmallett    uint64_t u64;
93210284Sjmallett
94210284Sjmallett    /**
95210284Sjmallett     * this format defines the format returned on a load
96210284Sjmallett     *   a load returns the 32/36-bits in memory, plus xxor = even_parity(dat<35:0>)
97210284Sjmallett     *   typically, dat<35> = parity(dat<34:0>), so the xor bit directly indicates parity error
98210284Sjmallett     *   Note that the data field size is 36 bits on the 36XX/38XX, and 32 bits on the 31XX
99210284Sjmallett     */
100210284Sjmallett    struct
101210284Sjmallett    {
102210284Sjmallett        uint64_t                       mbz1  :27;
103210284Sjmallett        uint64_t                       xxor  : 1;
104210284Sjmallett        uint64_t                       mbz   : 4;
105210284Sjmallett        uint64_t                       dat   :32;
106210284Sjmallett    } cn31xx;
107210284Sjmallett
108210284Sjmallett    struct
109210284Sjmallett    {
110210284Sjmallett        uint64_t                       mbz   :27;
111210284Sjmallett        uint64_t                       xxor  : 1;
112210284Sjmallett        uint64_t                       dat   :36;
113210284Sjmallett    } s;
114210284Sjmallett
115210284Sjmallett    /**
116210284Sjmallett     *  This format defines what should be used if parity is desired.  Hardware returns
117210284Sjmallett     *  the XOR of all the bits in the 36/32 bit data word, so for parity software must use
118210284Sjmallett     * one of the data field bits as a parity bit.
119210284Sjmallett     */
120210284Sjmallett    struct cn31xx_par_struct
121210284Sjmallett    {
122210284Sjmallett        uint64_t                       mbz   :32;
123210284Sjmallett        uint64_t                       par   : 1;
124210284Sjmallett        uint64_t                       dat   :31;
125210284Sjmallett    } cn31xx_par;
126210284Sjmallett    struct cn38xx_par_struct
127210284Sjmallett    {
128210284Sjmallett        uint64_t                       mbz   :28;
129210284Sjmallett        uint64_t                       par   : 1;
130210284Sjmallett        uint64_t                       dat   :35;
131210284Sjmallett    } cn38xx_par;
132210284Sjmallett#if !OCTEON_IS_COMMON_BINARY()
133210284Sjmallett#if CVMX_COMPILED_FOR(OCTEON_CN31XX)
134210284Sjmallett    struct cn31xx_par_struct spar;
135210284Sjmallett#else
136210284Sjmallett    struct cn38xx_par_struct spar;
137210284Sjmallett#endif
138210284Sjmallett#endif
139210284Sjmallett} cvmx_llm_data_t;
140210284Sjmallett
141210284Sjmallett#define CVMX_LLM_NARROW_DATA_WIDTH  ((CVMX_COMPILED_FOR(OCTEON_CN31XX)) ? 32 : 36)
142210284Sjmallett
143210284Sjmallett/**
144210284Sjmallett * Calculate the parity value of a number
145210284Sjmallett *
146210284Sjmallett * @param value
147210284Sjmallett * @return parity value
148210284Sjmallett */
149210284Sjmallettstatic inline uint64_t cvmx_llm_parity(uint64_t value)
150210284Sjmallett{
151210284Sjmallett    uint64_t result;
152210284Sjmallett    CVMX_DPOP(result, value);
153210284Sjmallett    return result;
154210284Sjmallett}
155210284Sjmallett
156210284Sjmallett
157210284Sjmallett/**
158210284Sjmallett * Calculate the ECC needed for 36b LLM mode
159210284Sjmallett *
160210284Sjmallett * @param value
161210284Sjmallett * @return  ECC value
162210284Sjmallett */
163210284Sjmallettstatic inline int cvmx_llm_ecc(uint64_t value)
164210284Sjmallett{
165210284Sjmallett    /* FIXME: This needs a re-write */
166210284Sjmallett    static const uint32_t ecc_code_29[7] = {
167210284Sjmallett        0x08962595,
168210284Sjmallett        0x112a4aaa,
169210284Sjmallett        0x024c934f,
170210284Sjmallett        0x04711c73,
171210284Sjmallett        0x0781e07c,
172210284Sjmallett        0x1801ff80,
173210284Sjmallett        0x1ffe0000};
174210284Sjmallett    uint64_t pop0, pop1, pop2, pop3, pop4, pop5, pop6;
175210284Sjmallett
176210284Sjmallett    pop0 = ecc_code_29[0];
177210284Sjmallett    pop1 = ecc_code_29[1];
178210284Sjmallett    pop2 = ecc_code_29[2];
179210284Sjmallett    pop0 &= value;
180210284Sjmallett    pop3 = ecc_code_29[3];
181210284Sjmallett    CVMX_DPOP(pop0, pop0);
182210284Sjmallett    pop4 = ecc_code_29[4];
183210284Sjmallett    pop1 &= value;
184210284Sjmallett    CVMX_DPOP(pop1, pop1);
185210284Sjmallett    pop2 &= value;
186210284Sjmallett    pop5 = ecc_code_29[5];
187210284Sjmallett    CVMX_DPOP(pop2, pop2);
188210284Sjmallett    pop6 = ecc_code_29[6];
189210284Sjmallett    pop3 &= value;
190210284Sjmallett    CVMX_DPOP(pop3, pop3);
191210284Sjmallett    pop4 &= value;
192210284Sjmallett    CVMX_DPOP(pop4, pop4);
193210284Sjmallett    pop5 &= value;
194210284Sjmallett    CVMX_DPOP(pop5, pop5);
195210284Sjmallett    pop6 &= value;
196210284Sjmallett    CVMX_DPOP(pop6, pop6);
197210284Sjmallett
198210284Sjmallett    return((pop6&1)<<6) | ((pop5&1)<<5) | ((pop4&1)<<4) | ((pop3&1)<<3) | ((pop2&1)<<2) | ((pop1&1)<<1) | (pop0&1);
199210284Sjmallett}
200210284Sjmallett
201210284Sjmallett
202210284Sjmallett#ifdef ENABLE_DEPRECATED
203210284Sjmallett/* These macros are provided to provide compatibility with code that uses
204210284Sjmallett** the old names for the llm access functions.  The names were changed
205210284Sjmallett** when support for the 31XX llm was added, as the widths differ between Octeon Models.
206210284Sjmallett** The wide/narrow names are preferred, and should be used in all new code */
207210284Sjmallett#define cvmx_llm_write36 cvmx_llm_write_narrow
208210284Sjmallett#define cvmx_llm_read36  cvmx_llm_read_narrow
209210284Sjmallett#define cvmx_llm_write64 cvmx_llm_write_wide
210210284Sjmallett#define cvmx_llm_read64  cvmx_llm_read_wide
211210284Sjmallett#endif
212210284Sjmallett/**
213210284Sjmallett * Write to LLM memory - 36 bit
214210284Sjmallett *
215210284Sjmallett * @param address Address in LLM to write. Consecutive writes increment the
216210284Sjmallett *                address by 4. The replication mode is also encoded in this
217210284Sjmallett *                address.
218210284Sjmallett * @param value   Value to write to LLM. Only the low 36 bits will be used.
219210284Sjmallett * @param set     Which of the two coprocessor 2 register sets to use for the
220210284Sjmallett *                write. May be used to get two outstanding LLM access at once
221210284Sjmallett *                per core. Range: 0-1
222210284Sjmallett */
223210284Sjmallettstatic inline void cvmx_llm_write_narrow(cvmx_llm_address_t address, uint64_t value, int set)
224210284Sjmallett{
225210284Sjmallett    cvmx_llm_data_t data;
226210284Sjmallett    data.s.mbz = 0;
227210284Sjmallett
228215990Sjmallett    data.s.dat = value;
229210284Sjmallett
230210284Sjmallett    data.s.xxor = 0;
231210284Sjmallett
232210284Sjmallett    if (set)
233210284Sjmallett    {
234210284Sjmallett        CVMX_MT_LLM_DATA(1, data.u64);
235210284Sjmallett        CVMX_MT_LLM_WRITE_ADDR_INTERNAL(1, address.u64);
236210284Sjmallett    }
237210284Sjmallett    else
238210284Sjmallett    {
239210284Sjmallett        CVMX_MT_LLM_DATA(0, data.u64);
240210284Sjmallett        CVMX_MT_LLM_WRITE_ADDR_INTERNAL(0, address.u64);
241210284Sjmallett    }
242210284Sjmallett}
243210284Sjmallett
244210284Sjmallett
245210284Sjmallett/**
246210284Sjmallett * Write to LLM memory - 64 bit
247210284Sjmallett *
248210284Sjmallett * @param address Address in LLM to write. Consecutive writes increment the
249210284Sjmallett *                address by 8. The replication mode is also encoded in this
250210284Sjmallett *                address.
251210284Sjmallett * @param value   Value to write to LLM.
252210284Sjmallett * @param set     Which of the two coprocessor 2 register sets to use for the
253210284Sjmallett *                write. May be used to get two outstanding LLM access at once
254210284Sjmallett *                per core. Range: 0-1
255210284Sjmallett */
256210284Sjmallettstatic inline void cvmx_llm_write_wide(cvmx_llm_address_t address, uint64_t value, int set)
257210284Sjmallett{
258215990Sjmallett    if (set)
259210284Sjmallett    {
260215990Sjmallett        CVMX_MT_LLM_DATA(1, value);
261215990Sjmallett        CVMX_MT_LLM_WRITE64_ADDR_INTERNAL(1, address.u64);
262210284Sjmallett    }
263210284Sjmallett    else
264210284Sjmallett    {
265215990Sjmallett        CVMX_MT_LLM_DATA(0, value);
266215990Sjmallett        CVMX_MT_LLM_WRITE64_ADDR_INTERNAL(0, address.u64);
267210284Sjmallett    }
268210284Sjmallett}
269210284Sjmallett
270210284Sjmallett
271210284Sjmallett/**
272210284Sjmallett * Read from LLM memory - 36 bit
273210284Sjmallett *
274210284Sjmallett * @param address Address in LLM to read. Consecutive reads increment the
275210284Sjmallett *                address by 4. The replication mode is also encoded in this
276210284Sjmallett *                address.
277210284Sjmallett * @param set     Which of the two coprocessor 2 register sets to use for the
278210284Sjmallett *                write. May be used to get two outstanding LLM access at once
279210284Sjmallett *                per core. Range: 0-1
280210284Sjmallett * @return The lower 36 bits contain the result of the read
281210284Sjmallett */
282210284Sjmallettstatic inline cvmx_llm_data_t cvmx_llm_read_narrow(cvmx_llm_address_t address, int set)
283210284Sjmallett{
284210284Sjmallett    cvmx_llm_data_t value;
285210284Sjmallett    if (set)
286210284Sjmallett    {
287210284Sjmallett        CVMX_MT_LLM_READ_ADDR(1, address.u64);
288210284Sjmallett        CVMX_MF_LLM_DATA(1, value.u64);
289210284Sjmallett    }
290210284Sjmallett    else
291210284Sjmallett    {
292210284Sjmallett        CVMX_MT_LLM_READ_ADDR(0, address.u64);
293210284Sjmallett        CVMX_MF_LLM_DATA(0, value.u64);
294210284Sjmallett    }
295210284Sjmallett    return value;
296210284Sjmallett}
297210284Sjmallett
298210284Sjmallett
299210284Sjmallett/**
300210284Sjmallett * Read from LLM memory - 64 bit
301210284Sjmallett *
302210284Sjmallett * @param address Address in LLM to read. Consecutive reads increment the
303210284Sjmallett *                address by 8. The replication mode is also encoded in this
304210284Sjmallett *                address.
305210284Sjmallett * @param set     Which of the two coprocessor 2 register sets to use for the
306210284Sjmallett *                write. May be used to get two outstanding LLM access at once
307210284Sjmallett *                per core. Range: 0-1
308210284Sjmallett * @return The result of the read
309210284Sjmallett */
310210284Sjmallettstatic inline uint64_t cvmx_llm_read_wide(cvmx_llm_address_t address, int set)
311210284Sjmallett{
312210284Sjmallett    uint64_t value;
313210284Sjmallett    if (set)
314210284Sjmallett    {
315210284Sjmallett        CVMX_MT_LLM_READ64_ADDR(1, address);
316210284Sjmallett        CVMX_MF_LLM_DATA(1, value);
317210284Sjmallett    }
318210284Sjmallett    else
319210284Sjmallett    {
320210284Sjmallett        CVMX_MT_LLM_READ64_ADDR(0, address);
321210284Sjmallett        CVMX_MF_LLM_DATA(0, value);
322210284Sjmallett    }
323210284Sjmallett    return value;
324210284Sjmallett}
325210284Sjmallett
326210284Sjmallett
327210284Sjmallett#define RLD_INIT_DELAY  (1<<18)
328210284Sjmallett
329210284Sjmallett
330210284Sjmallett
331210284Sjmallett/* This structure describes the RLDRAM configuration for a board.  This structure
332210284Sjmallett** must be populated with the correct values and passed to the initialization function.
333210284Sjmallett*/
334210284Sjmalletttypedef struct
335210284Sjmallett{
336210284Sjmallett    uint32_t cpu_hz;            /* CPU frequency in Hz */
337210284Sjmallett    char addr_rld0_fb_str [100];   /* String describing RLDRAM connections on rld 0 front (0) bunk*/
338210284Sjmallett    char addr_rld0_bb_str [100];   /* String describing RLDRAM connections on rld 0 back (1) bunk*/
339210284Sjmallett    char addr_rld1_fb_str [100];   /* String describing RLDRAM connections on rld 1 front (0) bunk*/
340210284Sjmallett    char addr_rld1_bb_str [100];   /* String describing RLDRAM connections on rld 1 back (1) bunk*/
341210284Sjmallett    uint8_t rld0_bunks;     /* Number of bunks on rld 0 (0 is disabled) */
342210284Sjmallett    uint8_t rld1_bunks;     /* Number of bunks on rld 1 (0 is disabled) */
343210284Sjmallett    uint16_t rld0_mbytes;   /* mbytes on rld 0 */
344210284Sjmallett    uint16_t rld1_mbytes;   /* mbytes on rld 1 */
345210284Sjmallett    uint16_t max_rld_clock_mhz;  /* Maximum RLD clock in MHz, only used for CN58XX */
346210284Sjmallett} llm_descriptor_t;
347210284Sjmallett
348210284Sjmallett/**
349210284Sjmallett * Initialize LLM memory controller.  This must be done
350210284Sjmallett * before the low latency memory can be used.
351210284Sjmallett * This is simply a wrapper around cvmx_llm_initialize_desc(),
352210284Sjmallett * and is deprecated.
353210284Sjmallett *
354210284Sjmallett * @return -1 on error
355210284Sjmallett *         0 on success
356210284Sjmallett */
357210284Sjmallettint cvmx_llm_initialize(void);
358210284Sjmallett
359210284Sjmallett
360210284Sjmallett/**
361210284Sjmallett * Initialize LLM memory controller.  This must be done
362210284Sjmallett * before the low latency memory can be used.
363210284Sjmallett *
364210284Sjmallett * @param llm_desc_ptr
365210284Sjmallett *              Pointer to descriptor structure. If NULL
366210284Sjmallett *              is passed, a default setting is used if available.
367210284Sjmallett *
368210284Sjmallett * @return -1 on error
369210284Sjmallett *         Size of llm in bytes on success
370210284Sjmallett */
371210284Sjmallettint cvmx_llm_initialize_desc(llm_descriptor_t *llm_desc_ptr);
372210284Sjmallett
373210284Sjmallett
374210284Sjmallett
375210284Sjmallett/**
376210284Sjmallett * Gets the default llm descriptor for the board code is being run on.
377210284Sjmallett *
378210284Sjmallett * @param llm_desc_ptr
379210284Sjmallett *               Pointer to descriptor structure to be filled in.  Contents are only
380210284Sjmallett *               valid after successful completion.  Must not be NULL.
381210284Sjmallett *
382210284Sjmallett * @return -1 on error
383210284Sjmallett *         0 on success
384210284Sjmallett */
385210284Sjmallettint cvmx_llm_get_default_descriptor(llm_descriptor_t *llm_desc_ptr);
386210284Sjmallett
387210284Sjmallett#ifdef	__cplusplus
388210284Sjmallett}
389210284Sjmallett#endif
390210284Sjmallett
391210284Sjmallett#endif /*  __CVM_LLM_H__ */
392