cvmx-llm.h revision 232812
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