/***********************license start*************** * Copyright (c) 2003-2010 Cavium Inc. (support@cavium.com). All rights * reserved. * * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of Cavium Inc. nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * This Software, including technical data, may be subject to U.S. export control * laws, including the U.S. Export Administration Act and its associated * regulations, and may be subject to export or import regulations in other * countries. * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE, * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR * PERFORMANCE OF THE SOFTWARE LIES WITH YOU. ***********************license end**************************************/ /** * @file * * interface to the low latency DRAM * *
$Revision: 70030 $
* */ #ifndef __CVMX_LLM_H__ #define __CVMX_LLM_H__ #ifdef __cplusplus extern "C" { #endif #define ENABLE_DEPRECATED /* Set to enable the old 18/36 bit names */ typedef enum { CVMX_LLM_REPLICATION_NONE = 0, CVMX_LLM_REPLICATION_2X = 1, // on both interfaces, or 2x if only one interface CVMX_LLM_REPLICATION_4X = 2, // both interfaces, 2x, or 4x if only one interface CVMX_LLM_REPLICATION_8X = 3, // both interfaces, 4x, or 8x if only one interface } cvmx_llm_replication_t; /** * This structure defines the address used to the low-latency memory. * This address format is used for both loads and stores. */ typedef union { uint64_t u64; struct { uint64_t mbz :30; cvmx_llm_replication_t repl : 2; uint64_t address :32; // address<1:0> mbz, address<31:30> mbz } s; } cvmx_llm_address_t; /** * This structure defines the data format in the low-latency memory */ typedef union { uint64_t u64; /** * this format defines the format returned on a load * a load returns the 32/36-bits in memory, plus xxor = even_parity(dat<35:0>) * typically, dat<35> = parity(dat<34:0>), so the xor bit directly indicates parity error * Note that the data field size is 36 bits on the 36XX/38XX, and 32 bits on the 31XX */ struct { uint64_t mbz1 :27; uint64_t xxor : 1; uint64_t mbz : 4; uint64_t dat :32; } cn31xx; struct { uint64_t mbz :27; uint64_t xxor : 1; uint64_t dat :36; } s; /** * This format defines what should be used if parity is desired. Hardware returns * the XOR of all the bits in the 36/32 bit data word, so for parity software must use * one of the data field bits as a parity bit. */ struct cn31xx_par_struct { uint64_t mbz :32; uint64_t par : 1; uint64_t dat :31; } cn31xx_par; struct cn38xx_par_struct { uint64_t mbz :28; uint64_t par : 1; uint64_t dat :35; } cn38xx_par; #if !OCTEON_IS_COMMON_BINARY() #if CVMX_COMPILED_FOR(OCTEON_CN31XX) struct cn31xx_par_struct spar; #else struct cn38xx_par_struct spar; #endif #endif } cvmx_llm_data_t; #define CVMX_LLM_NARROW_DATA_WIDTH ((CVMX_COMPILED_FOR(OCTEON_CN31XX)) ? 32 : 36) /** * Calculate the parity value of a number * * @param value * @return parity value */ static inline uint64_t cvmx_llm_parity(uint64_t value) { uint64_t result; CVMX_DPOP(result, value); return result; } /** * Calculate the ECC needed for 36b LLM mode * * @param value * @return ECC value */ static inline int cvmx_llm_ecc(uint64_t value) { /* FIXME: This needs a re-write */ static const uint32_t ecc_code_29[7] = { 0x08962595, 0x112a4aaa, 0x024c934f, 0x04711c73, 0x0781e07c, 0x1801ff80, 0x1ffe0000}; uint64_t pop0, pop1, pop2, pop3, pop4, pop5, pop6; pop0 = ecc_code_29[0]; pop1 = ecc_code_29[1]; pop2 = ecc_code_29[2]; pop0 &= value; pop3 = ecc_code_29[3]; CVMX_DPOP(pop0, pop0); pop4 = ecc_code_29[4]; pop1 &= value; CVMX_DPOP(pop1, pop1); pop2 &= value; pop5 = ecc_code_29[5]; CVMX_DPOP(pop2, pop2); pop6 = ecc_code_29[6]; pop3 &= value; CVMX_DPOP(pop3, pop3); pop4 &= value; CVMX_DPOP(pop4, pop4); pop5 &= value; CVMX_DPOP(pop5, pop5); pop6 &= value; CVMX_DPOP(pop6, pop6); return((pop6&1)<<6) | ((pop5&1)<<5) | ((pop4&1)<<4) | ((pop3&1)<<3) | ((pop2&1)<<2) | ((pop1&1)<<1) | (pop0&1); } #ifdef ENABLE_DEPRECATED /* These macros are provided to provide compatibility with code that uses ** the old names for the llm access functions. The names were changed ** when support for the 31XX llm was added, as the widths differ between Octeon Models. ** The wide/narrow names are preferred, and should be used in all new code */ #define cvmx_llm_write36 cvmx_llm_write_narrow #define cvmx_llm_read36 cvmx_llm_read_narrow #define cvmx_llm_write64 cvmx_llm_write_wide #define cvmx_llm_read64 cvmx_llm_read_wide #endif /** * Write to LLM memory - 36 bit * * @param address Address in LLM to write. Consecutive writes increment the * address by 4. The replication mode is also encoded in this * address. * @param value Value to write to LLM. Only the low 36 bits will be used. * @param set Which of the two coprocessor 2 register sets to use for the * write. May be used to get two outstanding LLM access at once * per core. Range: 0-1 */ static inline void cvmx_llm_write_narrow(cvmx_llm_address_t address, uint64_t value, int set) { cvmx_llm_data_t data; data.s.mbz = 0; data.s.dat = value; data.s.xxor = 0; if (set) { CVMX_MT_LLM_DATA(1, data.u64); CVMX_MT_LLM_WRITE_ADDR_INTERNAL(1, address.u64); } else { CVMX_MT_LLM_DATA(0, data.u64); CVMX_MT_LLM_WRITE_ADDR_INTERNAL(0, address.u64); } } /** * Write to LLM memory - 64 bit * * @param address Address in LLM to write. Consecutive writes increment the * address by 8. The replication mode is also encoded in this * address. * @param value Value to write to LLM. * @param set Which of the two coprocessor 2 register sets to use for the * write. May be used to get two outstanding LLM access at once * per core. Range: 0-1 */ static inline void cvmx_llm_write_wide(cvmx_llm_address_t address, uint64_t value, int set) { if (set) { CVMX_MT_LLM_DATA(1, value); CVMX_MT_LLM_WRITE64_ADDR_INTERNAL(1, address.u64); } else { CVMX_MT_LLM_DATA(0, value); CVMX_MT_LLM_WRITE64_ADDR_INTERNAL(0, address.u64); } } /** * Read from LLM memory - 36 bit * * @param address Address in LLM to read. Consecutive reads increment the * address by 4. The replication mode is also encoded in this * address. * @param set Which of the two coprocessor 2 register sets to use for the * write. May be used to get two outstanding LLM access at once * per core. Range: 0-1 * @return The lower 36 bits contain the result of the read */ static inline cvmx_llm_data_t cvmx_llm_read_narrow(cvmx_llm_address_t address, int set) { cvmx_llm_data_t value; if (set) { CVMX_MT_LLM_READ_ADDR(1, address.u64); CVMX_MF_LLM_DATA(1, value.u64); } else { CVMX_MT_LLM_READ_ADDR(0, address.u64); CVMX_MF_LLM_DATA(0, value.u64); } return value; } /** * Read from LLM memory - 64 bit * * @param address Address in LLM to read. Consecutive reads increment the * address by 8. The replication mode is also encoded in this * address. * @param set Which of the two coprocessor 2 register sets to use for the * write. May be used to get two outstanding LLM access at once * per core. Range: 0-1 * @return The result of the read */ static inline uint64_t cvmx_llm_read_wide(cvmx_llm_address_t address, int set) { uint64_t value; if (set) { CVMX_MT_LLM_READ64_ADDR(1, address); CVMX_MF_LLM_DATA(1, value); } else { CVMX_MT_LLM_READ64_ADDR(0, address); CVMX_MF_LLM_DATA(0, value); } return value; } #define RLD_INIT_DELAY (1<<18) /* This structure describes the RLDRAM configuration for a board. This structure ** must be populated with the correct values and passed to the initialization function. */ typedef struct { uint32_t cpu_hz; /* CPU frequency in Hz */ char addr_rld0_fb_str [100]; /* String describing RLDRAM connections on rld 0 front (0) bunk*/ char addr_rld0_bb_str [100]; /* String describing RLDRAM connections on rld 0 back (1) bunk*/ char addr_rld1_fb_str [100]; /* String describing RLDRAM connections on rld 1 front (0) bunk*/ char addr_rld1_bb_str [100]; /* String describing RLDRAM connections on rld 1 back (1) bunk*/ uint8_t rld0_bunks; /* Number of bunks on rld 0 (0 is disabled) */ uint8_t rld1_bunks; /* Number of bunks on rld 1 (0 is disabled) */ uint16_t rld0_mbytes; /* mbytes on rld 0 */ uint16_t rld1_mbytes; /* mbytes on rld 1 */ uint16_t max_rld_clock_mhz; /* Maximum RLD clock in MHz, only used for CN58XX */ } llm_descriptor_t; /** * Initialize LLM memory controller. This must be done * before the low latency memory can be used. * This is simply a wrapper around cvmx_llm_initialize_desc(), * and is deprecated. * * @return -1 on error * 0 on success */ int cvmx_llm_initialize(void); /** * Initialize LLM memory controller. This must be done * before the low latency memory can be used. * * @param llm_desc_ptr * Pointer to descriptor structure. If NULL * is passed, a default setting is used if available. * * @return -1 on error * Size of llm in bytes on success */ int cvmx_llm_initialize_desc(llm_descriptor_t *llm_desc_ptr); /** * Gets the default llm descriptor for the board code is being run on. * * @param llm_desc_ptr * Pointer to descriptor structure to be filled in. Contents are only * valid after successful completion. Must not be NULL. * * @return -1 on error * 0 on success */ int cvmx_llm_get_default_descriptor(llm_descriptor_t *llm_desc_ptr); #ifdef __cplusplus } #endif #endif /* __CVM_LLM_H__ */