pcie_interface.h 13 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
/*******************************************************************************
    OpenAirInterface 
    Copyright(c) 1999 - 2014 Eurecom

    OpenAirInterface is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.


    OpenAirInterface is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with OpenAirInterface.The full GNU General Public License is 
    included in this distribution in the file called "COPYING". If not, 
    see <http://www.gnu.org/licenses/>.

   Contact Information
   OpenAirInterface Admin: openair_admin@eurecom.fr
   OpenAirInterface Tech : openair_tech@eurecom.fr
   OpenAirInterface Dev  : openair4g-devel@eurecom.fr
  
   Address      : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.

 *******************************************************************************/
 
 /** pcie_interface.h
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68

    Interface definitions to handle communication between PC (kernel driver & SDR application) and Leon3

    - commands from PC->Leon and Leon->PC passed through CONTROL1 register (or new: FIFOs)
    - structure for passing initial (shared PC memory) buffer pointers
    - #defines for buffer sizes
    
    This is now the CENTRAL header file for all structs and defines that are
    requires on both LEON and Kernel and PC Application
            
    Changelog:
    01.12.2012: Fix: RXEN and TXEN were swapped
                New rf_mode flag: use DMAMODE_RX and DMAMODE_TX to selectively enable DMA transfers (only used on ExpressMIMO2)
                                  use RXOUTSW to close Lime baseband RXout switch between RFFE and ADC
    09.01.2013: Renamed exmimo_rf_t.mbox --> .p_mbox to indicate this is a pointer to the mbox and not the mbox itself
    15.01.2013: added command (EXMIMO_GET_SYSTEMID) and structure (exmimo_system_id_t)
                to get system ID and bitstream and software versions on PC
    22.01.2013: Moved structures into pcie/pcie_interface.h to have all these spread-out definitions in a single place

    Author: Matthias Ihmig <matthias.ihmig@mytum.de>, 2012
            Raymond Knopp <raymond.knopp@eurecom.fr>
            Riadh Ghaddab <riadh.ghaddab@eurecom.fr>
 */

#ifndef PCIE_INTERFACE_H
#define PCIE_INTERFACE_H

#ifndef __KERNEL__
#include <stdint.h>
#endif

// ------------------------------
// Buffer sizes
// ------------------------------
#define MAX_ANTENNAS                       4
#define MAX_FIRMWARE_BLOCK_SIZE_B     262144
#define MAX_PRINTK_BUFFER_B             1024

69
// #define FRAME_LENGTH_COMPLEX_SAMPLES   76800
70
// Buffer size per channel: FRAME_LENGTH_COMPLEX_SAMPLES+2048 smp/frame: LTE frame+tail, *4 (7.68*4 MsmpPS), *4 Bytes/smp
71
#define ADAC_BUFFERSZ_PERCHAN_B  ((76800+2048)*4*4)
72

73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
#define BIGSHM_SIZE_PAGES ((( MAX_FIRMWARE_BLOCK_SIZE_B + \
                              MAX_PRINTK_BUFFER_B + \
                              sizeof(exmimo_pci_interface_bot_t) +   \
                              sizeof(exmimo_config_t) + \
                              sizeof(exmimo_id_t) + \
                              2*MAX_ANTENNAS*sizeof(uint32_t)*4  + \
                              16*256 /* alignment overhead */  ) >> PAGE_SHIFT ) +1 )

/*
 * Commands exchanged between PC <--> LEON
 * 
 * Idle/Ready: EXMIMO_NOP
 */
#define EXMIMO_NOP                  0x9999

// Commands from PC --> LEON, passed through ahbpcie_control1 register (must be smaller than 0x1000 !

#define EXMIMO_PCIE_INIT            0x0000
#define EXMIMO_FW_INIT              0x0001
#define EXMIMO_FW_CLEAR_BSS         0x0002
#define EXMIMO_FW_START_EXEC        0x0003
#define EXMIMO_REBOOT               0x0004
#define EXMIMO_CONFIG               0x0005
#define EXMIMO_GET_FRAME            0x0006
#define EXMIMO_START_RT_ACQUISITION 0x0007
#define EXMIMO_STOP                 0x0008
ghaddab's avatar
 
ghaddab committed
99
#define EXMIMO_STOP_WITHOUT_RESET   0x0009
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336

#define IS_EXMIMOCMD_FROM_PC(x)  ( (x)<0x1000 ? 1 : 0)

// Commands from LEON --> PC, passed through ahbpcie_control2 register

#define PCI_PRINTK        0x2222
#define GET_FRAME_DONE    0x3333

#define EXMIMO_CONTROL2_COOKIE      0x43545232

// Default MODEM configuration in TV whitespace(400.850MHz), using RX/TX switch
#define TVWS_TDD          0xF7E04002

// 850MHz .. 865MHz
#define  DD_FDD      0xFAE40041
#define  DD_TDD      0xF7E04000
#define  B19G_TDD      0xCBC20084
#define  B24G_TDD      0xCBA20084
#define  B26G_TDD      0xCB820084
#define  B26G_FDD      0xDEE60108
#define  B35G_TDD      0xE9F01810
#define  B50G_TDD      0xC079A020


// used for DPD and dirty RF validation, TX fed back to RX through attenuators
#define  TVWS_TDD_DPD  0xF5E04000
#define  DD_TDD_DPD    0xF5E04000
#define  B19G_TDD_DPD    0xCDC20080
#define  B24G_TDD_DPD    0xCDA20080
#define  B26G_TDD_DPD    0xCD820080
#define  B35G_TDD_DPD    0xEDF01880


// -----------------------------------------------------------
// structures for communication between ExMIMO and kernel
// -----------------------------------------------------------

/* 
 * struct exmimo_system_id_t:
 *   Contains information on the bitstream, filled by Leon,
 *   based on data stored in an APB block on FPGA (TODO)
 * 
 * struct exmimo_id_t:
 *   Compound structure, also includes information
 *   from PCI configuration space (board_)
 */
typedef struct
{
    uint32_t bitstream_id;
    uint32_t bitstream_build_date;
    uint32_t software_id;
    uint32_t software_build_date;
    uint32_t dsp_bitstream_id;
    uint32_t dsp_bitstream_build_date;
} exmimo_system_id_t;

typedef struct
{
    exmimo_system_id_t system_id;
    uint32_t board_vendor;
    uint32_t board_exmimoversion;
    uint32_t board_hwrev;
    uint32_t board_swrev;
} exmimo_id_t;


/****************************************************
 * Structure and flags for configuring RF and LIME
 * (struct exmimo_rf_t)
 */
//
// register values and masks for rf_mode
//
#define RXEN 1
#define TXEN 2

#define TXLPFENMASK 4
#define TXLPFEN 4

#define TXLPFMASK     (15<<3)
#define TXLPF14        0
#define TXLPF10       (1<<3)
#define TXLPF7        (2<<3)
#define TXLPF6        (3<<3)
#define TXLPF5        (4<<3)
#define TXLPF4375     (5<<3)
#define TXLPF35       (6<<3)
#define TXLPF3        (7<<3)
#define TXLPF275      (8<<3)
#define TXLPF25       (9<<3)
#define TXLPF192      (10<<3)
#define TXLPF15       (11<<3)
#define TXLPF1375     (12<<3)
#define TXLPF125      (13<<3)
#define TXLPF0875     (14<<3)
#define TXLPF075      (15<<3)


#define RXLPFENMASK (1<<7)
#define RXLPFEN      128

#define RXLPFMASK   (15<<8)
#define RXLPF14      0
#define RXLPF10     (1<<8)
#define RXLPF7      (2<<8)
#define RXLPF6      (3<<8)
#define RXLPF5      (4<<8)
#define RXLPF4375   (5<<8)
#define RXLPF35     (6<<8)
#define RXLPF3      (7<<8)
#define RXLPF275    (8<<8)
#define RXLPF25     (9<<8)
#define RXLPF192    (10<<8)
#define RXLPF15     (11<<8)
#define RXLPF1375   (12<<8)
#define RXLPF125    (13<<8)
#define RXLPF0875   (14<<8)
#define RXLPF075    (15<<8)

#define LNAMASK     (3<<12)
#define LNADIS       0
#define LNA1ON      (1<<12)
#define LNA2ON      (2<<12) 
#define LNA3ON      (3<<12)

#define LNAGAINMASK (3<<14)
#define LNAByp      (1<<14)
#define LNAMed      (2<<14)
#define LNAMax      (3<<14)

// RFBBMASK: enable different loopback modes for calibration and testing. Use RFBBNORM for normal operation
#define RFBBMASK   (7<<16)
#define RFBBNORM    0
#define RFBBRXLPF  (1<<16)
#define RFBBRXVGA  (2<<16)
#define RFBBOUTPUT (3<<16)
#define RFBBLNA1   (4<<16)
#define RFBBLNA2   (5<<16)
#define RFBBLNA3   (6<<16)

#define RXLPFMODEMASK   (3<<19)
#define RXLPFNORM        0
#define RXLPFBYP        (1<<19)
#define RXLPFBPY2       (3<<19)

#define TXLPFMODEMASK   (1<<21)
#define TXLPFNORM        0
#define TXLPFBYP        (1<<21)

#define RXOUTSW         (1<<22)

#define DMAMODE_TRXMASK (3<<23)
#define DMAMODE_RX      (1<<23)
#define DMAMODE_TX      (2<<23)


// register values and masks for rf_local
#define TXLOIMASK   63
#define TXLOQMASK  (63<<6)
#define RXLOIMASK  (63<<12)
#define RXLOQMASK  (63<<18)

typedef struct
{
  uint32_t do_autocal[MAX_ANTENNAS];
  uint32_t rf_freq_rx[MAX_ANTENNAS];
  uint32_t rf_freq_tx[MAX_ANTENNAS];
  
  // TX Gain [Chain0..3][0=LIME Gain, 1=currently ignored]
  uint32_t tx_gain[MAX_ANTENNAS][2];
  
  // RX Gain [Chain0..3][0=LIME Gain, 1=currently ignored]
  uint32_t rx_gain[MAX_ANTENNAS][2];
  
  //LIME RF modes
  // 21    | 20:19 | 18:16 |15:14  | 13:12|11:8 |  7    |6:3  |2      |1   |0   |
  // TXBYP | RXBYP | RF/BB |LNAMode| LNA  |RXLPF|RXLPFen|TXLPF|TXLPFen|TXen|RXen|
  uint32_t rf_mode[MAX_ANTENNAS];
  
  // LIME LO Calibration Constants
  // | RXLOQ | RXLOI | TXLOQ | TXLOI |
  // | 23:18 | 17:12 | 11:6  | 5:0   |
  uint32_t rf_local[MAX_ANTENNAS];
  
  // LIME RX DC OFFSET
  // | RXDCQ | RXDCI |
  // | 15:8  | 7:0   |
  uint32_t rf_rxdc[MAX_ANTENNAS];
  
  // LIME VCO Calibration Constants
  // | RXVCOCAP | TXVCOCAP |
  // | 11:6     | 5:0      |
  uint32_t rf_vcocal[MAX_ANTENNAS];
  
  // External RF Frontend, as used on ExpressMIMO-2
  uint32_t rffe_gain_txlow[MAX_ANTENNAS];
  uint32_t rffe_gain_txhigh[MAX_ANTENNAS];
  uint32_t rffe_gain_rxfinal[MAX_ANTENNAS];
  uint32_t rffe_gain_rxlow[MAX_ANTENNAS];
  uint32_t rffe_band_mode[MAX_ANTENNAS];
  
} exmimo_rf_t;


/*********************************************************
 * Structure and flags for configuring Framing and Sync
 * (struct exmimo_framing_t)
 */
//
// ** multicard synchronization mode (framing.multicard_syncmode)
//
//    slave: take sync_newframe & sync_getframe from IO_SYNC header pin
//    master: enable IO_SYNC header OUTPUT (do this only on a single card!) for sync_newframe & sync_getframe
#define SYNCMODE_FREE       0
#define SYNCMODE_MASTER     1
#define SYNCMODE_SLAVE      2

//
// ** register values and masks for tdd_config
//
//    In TDD mode, there are two ways to control the RX/TX switch:
//    1. using the LSB from the TX data (TXRXSWITCH_LSB)
//    2. using FPGA logic, based on switch_offset[0..3]
#define DUPLEXMODE_MASK   (1<<0)
#define DUPLEXMODE_FDD     0
#define DUPLEXMODE_TDD    (1<<0)
#define TXRXSWITCH_MASK   (3<<1)
#define TXRXSWITCH_LSB     0
#define TXRXSWITCH_FPGA   (1<<1)
#define TXRXSWITCH_TESTRX (2<<1)
#define TXRXSWITCH_TESTTX (3<<1)
#define SWITCHSTATE_MASK  (1<<3)
#define SWITCHSTATE_0      0
#define SWITCHSTATE_1     (1<<3)
#define TEST_ADACLOOP_MASK  (1<<4)
#define TEST_ADACLOOP_EN    (1<<4)

337 338 339 340 341 342
typedef enum {
  BW5,
  BW10,
  BW20
} exmimo_bw_t;

343 344 345 346 347 348 349 350 351 352 353 354 355 356
typedef struct
{
  uint32_t multicard_syncmode;
  
  uint32_t eNB_flag;
  
  uint32_t tdd_config;
  
  uint32_t frame_length;          // e.g. 76800
  uint32_t frame_start;           // e.g. 18
  uint32_t adac_buffer_period;    // e.g. 2048
  uint32_t adac_intr_period;      // e.g. 1024
  
  uint32_t switch_offset[4];      // sample offsets (relative to start of frame) used to control the RX/TX switch in TDD mode
ghaddab's avatar
 
ghaddab committed
357
  uint32_t resampling_factor[4];     // 0=>1, 1=>2, 2=>4, applied equally to each chain and TX/RX
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414
} exmimo_framing_t;


typedef struct
{
    exmimo_rf_t rf;
    exmimo_framing_t framing;
} exmimo_config_t;



/*****************************************
 * Structures to pass pointers
 * between Leon, Kernel and Userspace
 */

/* 
 * struct exmimo_pci_interface_bot_t:
 *   Main structure to exchange physical(DMA) pointers between kernel and Leon
 */
typedef struct
{
    uint32_t firmware_block_ptr;
    uint32_t printk_buffer_ptr;

    uint32_t exmimo_config_ptr;
    uint32_t exmimo_id_ptr;

    // rxcnt / txcnt: stores the current ring buffer position indicators (formerly mbox)
    // - increment by one for every 512 samples (512 DW)
    // - currently wraps at 150 (0..149) to cover 1 LTE frame in the buffer
    // - in current sdr LEON code: only rxcnt_ptr[0] is used
    uint32_t rxcnt_ptr[MAX_ANTENNAS];    // points to uint32_t RX ring buffer position for each antenna
    uint32_t txcnt_ptr[MAX_ANTENNAS];    // points to uint32_t TX ring buffer position for each antenna
    uint32_t adc_head[MAX_ANTENNAS];     // address of start of ADC (RX) buffer in PC memory
    uint32_t dac_head[MAX_ANTENNAS];     // address of start of DAC (TX) buffer in PC memory

#ifdef NOINIT
    uint32_t dummy[13];      // used only in simulation for Modelsim memcopy tests
#endif
} exmimo_pci_interface_bot_t;
/*
 * Equivalent structure to exmimo_pci_interface_bot, which keeps type-specific virtual pointers
 */
typedef struct
{
    char *firmware_block_ptr;
    char *printk_buffer_ptr;
    exmimo_config_t *exmimo_config_ptr;
    exmimo_id_t *exmimo_id_ptr;
    uint32_t *rxcnt_ptr[MAX_ANTENNAS];    // points to uint32_t RX ring buffer position for each antenna
    uint32_t *txcnt_ptr[MAX_ANTENNAS];    // points to uint32_t TX ring buffer position for each antenna
    uint32_t *adc_head[MAX_ANTENNAS];     // address of start of ADC (RX) buffer in PC memory
    uint32_t *dac_head[MAX_ANTENNAS];     // address of start of DAC (TX) buffer in PC memory
} exmimo_pci_interface_bot_virtual_t;

#endif