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