cvmx-llm.h revision 210284
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 57extern "C" { 58#endif 59 60#define ENABLE_DEPRECATED /* Set to enable the old 18/36 bit names */ 61 62typedef 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 */ 74typedef 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 */ 88typedef 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 */ 147static 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 */ 161static 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 */ 221static 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 */ 257static 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 */ 292static 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 */ 320static 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*/ 344typedef 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 */ 367int 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 */ 381int 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 */ 395int cvmx_llm_get_default_descriptor(llm_descriptor_t *llm_desc_ptr); 396 397#ifdef __cplusplus 398} 399#endif 400 401#endif /* __CVM_LLM_H__ */ 402