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 * @file 44 * 45 * Interface to SRIO 46 * 47 * <hr>$Revision: 41586 $<hr> 48 */ 49#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 50#include <asm/octeon/cvmx.h> 51#include <asm/octeon/cvmx-srio.h> 52#include <asm/octeon/cvmx-clock.h> 53#include <asm/octeon/cvmx-atomic.h> 54#ifdef CONFIG_CAVIUM_DECODE_RSL 55#include <asm/octeon/cvmx-error.h> 56#endif 57#include <asm/octeon/cvmx-sriox-defs.h> 58#include <asm/octeon/cvmx-sriomaintx-defs.h> 59#include <asm/octeon/cvmx-sli-defs.h> 60#include <asm/octeon/cvmx-dpi-defs.h> 61#include <asm/octeon/cvmx-pexp-defs.h> 62#include <asm/octeon/cvmx-helper.h> 63#include <asm/octeon/cvmx-qlm.h> 64#else 65#include "cvmx.h" 66#include "cvmx-srio.h" 67#include "cvmx-clock.h" 68#include "cvmx-helper.h" 69#ifndef CVMX_BUILD_FOR_LINUX_HOST 70#include "cvmx-atomic.h" 71#if !defined(CVMX_BUILD_FOR_FREEBSD_KERNEL) 72#include "cvmx-error.h" 73#endif 74#include "cvmx-helper-errata.h" 75#endif 76#include "cvmx-qlm.h" 77#include "cvmx-helper.h" 78#endif 79 80#define CVMX_SRIO_CONFIG_TIMEOUT 10000 /* 10ms */ 81#define CVMX_SRIO_DOORBELL_TIMEOUT 10000 /* 10ms */ 82#define CVMX_SRIO_CONFIG_PRIORITY 0 83#define ULL unsigned long long 84 85typedef union 86{ 87 uint64_t u64; 88 struct 89 { 90#ifdef __BIG_ENDIAN_BITFIELD 91 uint64_t upper : 2; /* Normally 2 for XKPHYS */ 92 uint64_t reserved_49_61 : 13; /* Must be zero */ 93 uint64_t io : 1; /* 1 for IO space access */ 94 uint64_t did : 5; /* DID = 3 */ 95 uint64_t subdid : 3; /* SubDID = 3-6 */ 96 uint64_t reserved_36_39 : 4; /* Must be zero */ 97 uint64_t se : 2; /* SubDID extender */ 98 uint64_t reserved_32_33 : 2; /* Must be zero */ 99 uint64_t hopcount : 8; /* Hopcount */ 100 uint64_t address : 24; /* Mem address */ 101#else 102 uint64_t address : 24; 103 uint64_t hopcount : 8; 104 uint64_t reserved_32_33 : 2; 105 uint64_t se : 2; 106 uint64_t reserved_36_39 : 4; 107 uint64_t subdid : 3; 108 uint64_t did : 5; 109 uint64_t io : 1; 110 uint64_t reserved_49_61 : 13; 111 uint64_t upper : 2; 112#endif 113 } config; 114 struct 115 { 116#ifdef __BIG_ENDIAN_BITFIELD 117 uint64_t upper : 2; /* Normally 2 for XKPHYS */ 118 uint64_t reserved_49_61 : 13; /* Must be zero */ 119 uint64_t io : 1; /* 1 for IO space access */ 120 uint64_t did : 5; /* DID = 3 */ 121 uint64_t subdid : 3; /* SubDID = 3-6 */ 122 uint64_t reserved_36_39 : 4; /* Must be zero */ 123 uint64_t se : 2; /* SubDID extender */ 124 uint64_t address : 34; /* Mem address */ 125#else 126 uint64_t address : 34; 127 uint64_t se : 2; 128 uint64_t reserved_36_39 : 4; 129 uint64_t subdid : 3; 130 uint64_t did : 5; 131 uint64_t io : 1; 132 uint64_t reserved_49_61 : 13; 133 uint64_t upper : 2; 134#endif 135 } mem; 136} cvmx_sli_address_t; 137 138typedef struct 139{ 140 cvmx_srio_initialize_flags_t flags; 141 int32_t subidx_ref_count[16]; /* Reference count for SLI_MEM_ACCESS_SUBID[12-27]. Index=X-12 */ 142 int32_t s2m_ref_count[16]; /* Reference count for SRIOX_S2M_TYPE[0-15]. */ 143} __cvmx_srio_state_t; 144 145static CVMX_SHARED __cvmx_srio_state_t __cvmx_srio_state[4]; 146 147 148#ifndef CVMX_BUILD_FOR_LINUX_HOST 149/** 150 * @INTERNAL 151 * Allocate a SRIOX_S2M_TYPEX register for mapping a remote SRIO 152 * device's address range into Octeons SLI address space. Reference 153 * counting is used to allow sharing of duplicate setups. The current 154 * implementation treats reads and writes as paired, but this could be 155 * changed if we have trouble running out of indexes. 156 * 157 * @param srio_port SRIO port device is on 158 * @param s2m SRIOX_S2M_TYPEX setup required 159 * 160 * @return Index of CSR, or negative on failure 161 */ 162static int __cvmx_srio_alloc_s2m(int srio_port, cvmx_sriox_s2m_typex_t s2m) 163{ 164 int s2m_index; 165 /* Search through the S2M_TYPE registers looking for an unsed one or one 166 setup the way we need it */ 167 for (s2m_index=0; s2m_index<16; s2m_index++) 168 { 169 /* Increment ref count by 2 since we count read and write 170 independently. We might need a more complicated search in the 171 future */ 172 int ref_count = cvmx_atomic_fetch_and_add32(&__cvmx_srio_state[srio_port].s2m_ref_count[s2m_index], 2); 173 if (ref_count == 0) 174 { 175 /* Unused location. Write our value */ 176 cvmx_write_csr(CVMX_SRIOX_S2M_TYPEX(s2m_index, srio_port), s2m.u64); 177 /* Read back to make sure the update is complete */ 178 cvmx_read_csr(CVMX_SRIOX_S2M_TYPEX(s2m_index, srio_port)); 179 return s2m_index; 180 } 181 else 182 { 183 /* In use, see if we can use it */ 184 if (cvmx_read_csr(CVMX_SRIOX_S2M_TYPEX(s2m_index, srio_port)) == s2m.u64) 185 return s2m_index; 186 else 187 cvmx_atomic_add32(&__cvmx_srio_state[srio_port].s2m_ref_count[s2m_index], -2); 188 } 189 } 190 cvmx_dprintf("SRIO%d: Unable to find free SRIOX_S2M_TYPEX\n", srio_port); 191 return -1; 192} 193 194 195/** 196 * @INTERNAL 197 * Free a handle allocated by __cvmx_srio_alloc_s2m 198 * 199 * @param srio_port SRIO port 200 * @param index Index to free 201 */ 202static void __cvmx_srio_free_s2m(int srio_port, int index) 203{ 204 /* Read to force pending transactions to complete */ 205 cvmx_read_csr(CVMX_SRIOX_S2M_TYPEX(index, srio_port)); 206 cvmx_atomic_add32(&__cvmx_srio_state[srio_port].s2m_ref_count[index], -2); 207} 208 209 210/** 211 * @INTERNAL 212 * Allocate a SLI SubID to map a region of memory. Reference 213 * counting is used to allow sharing of duplicate setups. 214 * 215 * @param subid SLI_MEM_ACCESS_SUBIDX we need an index for 216 * 217 * @return Index of CSR, or negative on failure 218 */ 219static int __cvmx_srio_alloc_subid(cvmx_sli_mem_access_subidx_t subid) 220{ 221 int mem_index; 222 /* Search through the mem access subid registers looking for an unsed one 223 or one setup the way we need it. PCIe uses the low indexes, so search 224 backwards */ 225 for (mem_index=27; mem_index>=12; mem_index--) 226 { 227 int ref_count = cvmx_atomic_fetch_and_add32(&__cvmx_srio_state[0].subidx_ref_count[mem_index-12], 1); 228 if (ref_count == 0) 229 { 230 /* Unused location. Write our value */ 231 cvmx_write_csr(CVMX_PEXP_SLI_MEM_ACCESS_SUBIDX(mem_index), subid.u64); 232 /* Read back the value to make sure the update is complete */ 233 cvmx_read_csr(CVMX_PEXP_SLI_MEM_ACCESS_SUBIDX(mem_index)); 234 return mem_index; 235 } 236 else 237 { 238 /* In use, see if we can use it */ 239 if (cvmx_read_csr(CVMX_PEXP_SLI_MEM_ACCESS_SUBIDX(mem_index)) == subid.u64) 240 return mem_index; 241 else 242 cvmx_atomic_add32(&__cvmx_srio_state[0].subidx_ref_count[mem_index-12], -1); 243 } 244 } 245 cvmx_dprintf("SRIO: Unable to find free SLI_MEM_ACCESS_SUBIDX\n"); 246 return -1; 247} 248 249 250/** 251 * @INTERNAL 252 * Free a handle allocated by __cvmx_srio_alloc_subid 253 * 254 * @param index Index to free 255 */ 256static void __cvmx_srio_free_subid(int index) 257{ 258 /* Read to force pending transactions to complete */ 259 cvmx_read_csr(CVMX_PEXP_SLI_MEM_ACCESS_SUBIDX(index)); 260 cvmx_atomic_add32(&__cvmx_srio_state[0].subidx_ref_count[index-12], -1); 261} 262#endif 263 264 265/** 266 * @INTERNAL 267 * Read 32bits from a local port 268 * 269 * @param srio_port SRIO port the device is on 270 * @param offset Offset in config space. This must be a multiple of 32 bits. 271 * @param result Result of the read. This will be unmodified on failure. 272 * 273 * @return Zero on success, negative on failure. 274 */ 275static int __cvmx_srio_local_read32(int srio_port, uint32_t offset, uint32_t *result) 276{ 277 cvmx_sriox_maint_op_t maint_op; 278 cvmx_sriox_maint_rd_data_t maint_rd_data; 279 maint_op.u64 = 0; 280 maint_op.s.op = 0; /* Read */ 281 maint_op.s.addr = offset; 282 283 /* Make sure SRIO isn't already busy */ 284 if (CVMX_WAIT_FOR_FIELD64(CVMX_SRIOX_MAINT_OP(srio_port), cvmx_sriox_maint_op_t, pending, ==, 0, CVMX_SRIO_CONFIG_TIMEOUT)) 285 { 286 cvmx_dprintf("SRIO%d: Pending bit stuck before config read\n", srio_port); 287 return -1; 288 } 289 290 /* Issue the read to the hardware */ 291 cvmx_write_csr(CVMX_SRIOX_MAINT_OP(srio_port), maint_op.u64); 292 293 /* Wait for the hardware to complete the operation */ 294 if (CVMX_WAIT_FOR_FIELD64(CVMX_SRIOX_MAINT_OP(srio_port), cvmx_sriox_maint_op_t, pending, ==, 0, CVMX_SRIO_CONFIG_TIMEOUT)) 295 { 296 cvmx_dprintf("SRIO%d: Config read timeout\n", srio_port); 297 return -1; 298 } 299 300 /* Display and error and return if the operation failed to issue */ 301 maint_op.u64 = cvmx_read_csr(CVMX_SRIOX_MAINT_OP(srio_port)); 302 if (maint_op.s.fail) 303 { 304 cvmx_dprintf("SRIO%d: Config read addressing error (offset=0x%x)\n", srio_port, (unsigned int)offset); 305 return -1; 306 } 307 308 /* Wait for the read data to become valid */ 309 if (CVMX_WAIT_FOR_FIELD64(CVMX_SRIOX_MAINT_RD_DATA(srio_port), cvmx_sriox_maint_rd_data_t, valid, ==, 1, CVMX_SRIO_CONFIG_TIMEOUT)) 310 { 311 cvmx_dprintf("SRIO%d: Config read data timeout\n", srio_port); 312 return -1; 313 } 314 315 /* Get the read data */ 316 maint_rd_data.u64 = cvmx_read_csr(CVMX_SRIOX_MAINT_RD_DATA(srio_port)); 317 *result = maint_rd_data.s.rd_data; 318 return 0; 319} 320 321 322/** 323 * @INTERNAL 324 * Write 32bits to a local port 325 * @param srio_port SRIO port the device is on 326 * @param offset Offset in config space. This must be a multiple of 32 bits. 327 * @param data Data to write. 328 * 329 * @return Zero on success, negative on failure. 330 */ 331static int __cvmx_srio_local_write32(int srio_port, uint32_t offset, uint32_t data) 332{ 333 cvmx_sriox_maint_op_t maint_op; 334 maint_op.u64 = 0; 335 maint_op.s.wr_data = data; 336 maint_op.s.op = 1; /* Write */ 337 maint_op.s.addr = offset; 338 339 /* Make sure SRIO isn't already busy */ 340 if (CVMX_WAIT_FOR_FIELD64(CVMX_SRIOX_MAINT_OP(srio_port), cvmx_sriox_maint_op_t, pending, ==, 0, CVMX_SRIO_CONFIG_TIMEOUT)) 341 { 342 cvmx_dprintf("SRIO%d: Pending bit stuck before config write\n", srio_port); 343 return -1; 344 } 345 346 /* Issue the write to the hardware */ 347 cvmx_write_csr(CVMX_SRIOX_MAINT_OP(srio_port), maint_op.u64); 348 349 /* Wait for the hardware to complete the operation */ 350 if (CVMX_WAIT_FOR_FIELD64(CVMX_SRIOX_MAINT_OP(srio_port), cvmx_sriox_maint_op_t, pending, ==, 0, CVMX_SRIO_CONFIG_TIMEOUT)) 351 { 352 cvmx_dprintf("SRIO%d: Config write timeout\n", srio_port); 353 return -1; 354 } 355 356 /* Display and error and return if the operation failed to issue */ 357 maint_op.u64 = cvmx_read_csr(CVMX_SRIOX_MAINT_OP(srio_port)); 358 if (maint_op.s.fail) 359 { 360 cvmx_dprintf("SRIO%d: Config write addressing error (offset=0x%x)\n", srio_port, (unsigned int)offset); 361 return -1; 362 } 363 return 0; 364} 365 366 367/** 368 * Reset SRIO to link partner 369 * 370 * @param srio_port SRIO port to initialize 371 * 372 * @return Zero on success 373 */ 374int cvmx_srio_link_rst(int srio_port) 375{ 376 cvmx_sriomaintx_port_0_link_resp_t link_resp; 377 378 if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X)) 379 return -1; 380 381 /* Generate a symbol reset to the link partner by writing 0x3. */ 382 if (cvmx_srio_config_write32(srio_port, 0, -1, 0, 0, 383 CVMX_SRIOMAINTX_PORT_0_LINK_REQ(srio_port), 3)) 384 return -1; 385 386 if (cvmx_srio_config_read32(srio_port, 0, -1, 0, 0, 387 CVMX_SRIOMAINTX_PORT_0_LINK_RESP(srio_port), &link_resp.u32)) 388 return -1; 389 390 /* Poll until link partner has received the reset. */ 391 while (link_resp.s.valid == 0) 392 { 393 //cvmx_dprintf("Waiting for Link Response\n"); 394 if (cvmx_srio_config_read32(srio_port, 0, -1, 0, 0, 395 CVMX_SRIOMAINTX_PORT_0_LINK_RESP(srio_port), &link_resp.u32)) 396 return -1; 397 } 398 399 /* Valid response, Asserting MAC reset */ 400 cvmx_write_csr(CVMX_CIU_SOFT_PRST, 0x1); 401 402 cvmx_wait(10); 403 404 /* De-asserting MAC Reset */ 405 cvmx_write_csr(CVMX_CIU_SOFT_PRST, 0x0); 406 407 return 0; 408} 409 410/** 411 * Initialize a SRIO port for use. 412 * 413 * @param srio_port SRIO port to initialize 414 * @param flags Optional flags 415 * 416 * @return Zero on success 417 */ 418int cvmx_srio_initialize(int srio_port, cvmx_srio_initialize_flags_t flags) 419{ 420 cvmx_sriomaintx_port_lt_ctl_t port_lt_ctl; 421 cvmx_sriomaintx_port_rt_ctl_t port_rt_ctl; 422 cvmx_sriomaintx_port_0_ctl_t port_0_ctl; 423 cvmx_sriomaintx_core_enables_t core_enables; 424 cvmx_sriomaintx_port_gen_ctl_t port_gen_ctl; 425 cvmx_sriox_status_reg_t sriox_status_reg; 426 cvmx_mio_rst_ctlx_t mio_rst_ctl; 427 cvmx_sriox_imsg_vport_thr_t sriox_imsg_vport_thr; 428 cvmx_dpi_sli_prtx_cfg_t prt_cfg; 429 cvmx_sli_s2m_portx_ctl_t sli_s2m_portx_ctl; 430 cvmx_sli_mem_access_ctl_t sli_mem_access_ctl; 431 cvmx_sriomaintx_port_0_ctl2_t port_0_ctl2; 432 433 sriox_status_reg.u64 = cvmx_read_csr(CVMX_SRIOX_STATUS_REG(srio_port)); 434 if (OCTEON_IS_MODEL(OCTEON_CN66XX)) 435 { 436 /* All SRIO ports are connected to QLM0 */ 437 int status = cvmx_qlm_get_status(0); 438 if (status < 4 || status > 6) 439 { 440 cvmx_dprintf("SRIO%d: Initialization called on a port not in SRIO mode\n", srio_port); 441 return -1; 442 } 443 } 444 else if (!sriox_status_reg.s.srio) 445 { 446 cvmx_dprintf("SRIO%d: Initialization called on a port not in SRIO mode\n", srio_port); 447 return -1; 448 } 449 450 __cvmx_srio_state[srio_port].flags = flags; 451 452 /* CN63XX Pass 1.0 errata G-14395 requires the QLM De-emphasis be 453 programmed */ 454 if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_0)) 455 { 456 if (srio_port) 457 { 458 cvmx_ciu_qlm1_t ciu_qlm; 459 ciu_qlm.u64 = cvmx_read_csr(CVMX_CIU_QLM1); 460 ciu_qlm.s.txbypass = 1; 461 ciu_qlm.s.txdeemph = 5; 462 ciu_qlm.s.txmargin = 0x17; 463 cvmx_write_csr(CVMX_CIU_QLM1, ciu_qlm.u64); 464 } 465 else 466 { 467 cvmx_ciu_qlm0_t ciu_qlm; 468 ciu_qlm.u64 = cvmx_read_csr(CVMX_CIU_QLM0); 469 ciu_qlm.s.txbypass = 1; 470 ciu_qlm.s.txdeemph = 5; 471 ciu_qlm.s.txmargin = 0x17; 472 cvmx_write_csr(CVMX_CIU_QLM0, ciu_qlm.u64); 473 } 474 } 475 476 /* Don't receive or drive reset signals for the SRIO QLM */ 477 if (OCTEON_IS_MODEL(OCTEON_CN66XX)) 478 { 479 /* The reset signals are available only for srio_port == 0. */ 480 if (srio_port == 0 || (OCTEON_IS_MODEL(OCTEON_CN66XX_PASS1_2) && srio_port == 1)) 481 { 482 cvmx_mio_rst_cntlx_t mio_rst_cntl; 483 mio_rst_cntl.u64 = cvmx_read_csr(CVMX_MIO_RST_CNTLX(srio_port)); 484 mio_rst_cntl.s.rst_drv = 0; 485 mio_rst_cntl.s.rst_rcv = 0; 486 mio_rst_cntl.s.rst_chip = 0; 487 cvmx_write_csr(CVMX_MIO_RST_CNTLX(srio_port), mio_rst_cntl.u64); 488 } 489 /* MIO_RST_CNTL2<prtmode> is initialized to 0 on cold reset */ 490 mio_rst_ctl.u64 = cvmx_read_csr(CVMX_MIO_RST_CNTLX(srio_port)); 491 } 492 else 493 { 494 mio_rst_ctl.u64 = cvmx_read_csr(CVMX_MIO_RST_CTLX(srio_port)); 495 mio_rst_ctl.s.rst_drv = 0; 496 mio_rst_ctl.s.rst_rcv = 0; 497 mio_rst_ctl.s.rst_chip = 0; 498 cvmx_write_csr(CVMX_MIO_RST_CTLX(srio_port), mio_rst_ctl.u64); 499 500 mio_rst_ctl.u64 = cvmx_read_csr(CVMX_MIO_RST_CTLX(srio_port)); 501 } 502 503 cvmx_dprintf("SRIO%d: Port in %s mode\n", srio_port, 504 (mio_rst_ctl.s.prtmode) ? "host" : "endpoint"); 505 506 /* Bring the port out of reset if necessary */ 507 switch (srio_port) 508 { 509 case 0: 510 { 511 cvmx_ciu_soft_prst_t prst; 512 prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST); 513 if (prst.s.soft_prst) 514 { 515 prst.s.soft_prst = 0; 516 cvmx_write_csr(CVMX_CIU_SOFT_PRST, prst.u64); 517 /* Wait up to 250ms for the port to come out of reset */ 518 if (CVMX_WAIT_FOR_FIELD64(CVMX_SRIOX_STATUS_REG(srio_port), cvmx_sriox_status_reg_t, access, ==, 1, 250000)) 519 return -1; 520 } 521 break; 522 } 523 case 1: 524 { 525 cvmx_ciu_soft_prst1_t prst; 526 prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1); 527 if (prst.s.soft_prst) 528 { 529 prst.s.soft_prst = 0; 530 cvmx_write_csr(CVMX_CIU_SOFT_PRST1, prst.u64); 531 /* Wait up to 250ms for the port to come out of reset */ 532 if (CVMX_WAIT_FOR_FIELD64(CVMX_SRIOX_STATUS_REG(srio_port), cvmx_sriox_status_reg_t, access, ==, 1, 250000)) 533 return -1; 534 } 535 break; 536 } 537 case 2: 538 { 539 cvmx_ciu_soft_prst2_t prst; 540 prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST2); 541 if (prst.s.soft_prst) 542 { 543 prst.s.soft_prst = 0; 544 cvmx_write_csr(CVMX_CIU_SOFT_PRST2, prst.u64); 545 /* Wait up to 250ms for the port to come out of reset */ 546 if (CVMX_WAIT_FOR_FIELD64(CVMX_SRIOX_STATUS_REG(srio_port), cvmx_sriox_status_reg_t, access, ==, 1, 250000)) 547 return -1; 548 } 549 break; 550 } 551 } 552 553 /* Disable the link while we make changes */ 554 if (__cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_PORT_0_CTL(srio_port), &port_0_ctl.u32)) 555 return -1; 556 port_0_ctl.s.o_enable = 0; 557 port_0_ctl.s.i_enable = 0; 558 port_0_ctl.s.prt_lock = 1; 559 port_0_ctl.s.disable = 0; 560 if (__cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_PORT_0_CTL(srio_port), port_0_ctl.u32)) 561 return -1; 562 563 /* CN63XX Pass 2.0 and 2.1 errata G-15273 requires the QLM De-emphasis be 564 programmed when using a 156.25Mhz ref clock */ 565 if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS2_0) || 566 OCTEON_IS_MODEL(OCTEON_CN63XX_PASS2_1)) 567 { 568 cvmx_mio_rst_boot_t mio_rst_boot; 569 cvmx_sriomaintx_lane_x_status_0_t lane_x_status; 570 571 /* Read the QLM config and speed pins */ 572 mio_rst_boot.u64 = cvmx_read_csr(CVMX_MIO_RST_BOOT); 573 if (__cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_LANE_X_STATUS_0(0, srio_port), &lane_x_status.u32)) 574 return -1; 575 576 if (srio_port) 577 { 578 cvmx_ciu_qlm1_t ciu_qlm; 579 ciu_qlm.u64 = cvmx_read_csr(CVMX_CIU_QLM1); 580 switch (mio_rst_boot.cn63xx.qlm1_spd) 581 { 582 case 0x4: /* 1.25 Gbaud, 156.25MHz */ 583 ciu_qlm.s.txbypass = 1; 584 ciu_qlm.s.txdeemph = 0x0; 585 ciu_qlm.s.txmargin = (lane_x_status.s.rx_type == 0) ? 0x11 : 0x1c; /* short or med/long */ 586 break; 587 case 0xb: /* 5.0 Gbaud, 156.25MHz */ 588 ciu_qlm.s.txbypass = 1; 589 ciu_qlm.s.txdeemph = (lane_x_status.s.rx_type == 0) ? 0xa : 0xf; /* short or med/long */ 590 ciu_qlm.s.txmargin = (lane_x_status.s.rx_type == 0) ? 0xf : 0x1a; /* short or med/long */ 591 break; 592 } 593 cvmx_write_csr(CVMX_CIU_QLM1, ciu_qlm.u64); 594 } 595 else 596 { 597 cvmx_ciu_qlm0_t ciu_qlm; 598 ciu_qlm.u64 = cvmx_read_csr(CVMX_CIU_QLM0); 599 switch (mio_rst_boot.cn63xx.qlm0_spd) 600 { 601 case 0x4: /* 1.25 Gbaud, 156.25MHz */ 602 ciu_qlm.s.txbypass = 1; 603 ciu_qlm.s.txdeemph = 0x0; 604 ciu_qlm.s.txmargin = (lane_x_status.s.rx_type == 0) ? 0x11 : 0x1c; /* short or med/long */ 605 break; 606 case 0xb: /* 5.0 Gbaud, 156.25MHz */ 607 ciu_qlm.s.txbypass = 1; 608 ciu_qlm.s.txdeemph = (lane_x_status.s.rx_type == 0) ? 0xa : 0xf; /* short or med/long */ 609 ciu_qlm.s.txmargin = (lane_x_status.s.rx_type == 0) ? 0xf : 0x1a; /* short or med/long */ 610 break; 611 } 612 cvmx_write_csr(CVMX_CIU_QLM0, ciu_qlm.u64); 613 } 614 } 615 616 /* Errata SRIO-14485: Link speed is reported incorrectly in CN63XX 617 pass 1.x */ 618 if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X)) 619 { 620 cvmx_sriomaintx_port_0_ctl2_t port_0_ctl2; 621 if (__cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_PORT_0_CTL2(srio_port), &port_0_ctl2.u32)) 622 return -1; 623 if (port_0_ctl2.s.enb_500g) 624 { 625 port_0_ctl2.u32 = 0; 626 port_0_ctl2.s.enb_625g = 1; 627 } 628 else if (port_0_ctl2.s.enb_312g) 629 { 630 port_0_ctl2.u32 = 0; 631 port_0_ctl2.s.enb_500g = 1; 632 } 633 else if (port_0_ctl2.s.enb_250g) 634 { 635 port_0_ctl2.u32 = 0; 636 port_0_ctl2.s.enb_312g = 1; 637 } 638 else if (port_0_ctl2.s.enb_125g) 639 { 640 port_0_ctl2.u32 = 0; 641 port_0_ctl2.s.enb_250g = 1; 642 } 643 else 644 { 645 port_0_ctl2.u32 = 0; 646 port_0_ctl2.s.enb_125g = 1; 647 } 648 if (__cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_PORT_0_CTL2(srio_port), port_0_ctl2.u32)) 649 return -1; 650 } 651 652 /* Errata SRIO-15351: Turn off SRIOMAINTX_MAC_CTRL[TYPE_MRG] as it may 653 cause packet ACCEPT to be lost */ 654 if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS2_0) || OCTEON_IS_MODEL(OCTEON_CN63XX_PASS2_1)) 655 { 656 cvmx_sriomaintx_mac_ctrl_t mac_ctrl; 657 if (__cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_MAC_CTRL(srio_port), &mac_ctrl.u32)) 658 return -1; 659 mac_ctrl.s.type_mrg = 0; 660 if (__cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_MAC_CTRL(srio_port), mac_ctrl.u32)) 661 return -1; 662 } 663 664 /* Set the link layer timeout to 1ms. The default is too high and causes 665 core bus errors */ 666 if (__cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_PORT_LT_CTL(srio_port), &port_lt_ctl.u32)) 667 return -1; 668 port_lt_ctl.s.timeout = 1000000 / 200; /* 1ms = 1000000ns / 200ns */ 669 if (__cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_PORT_LT_CTL(srio_port), port_lt_ctl.u32)) 670 return -1; 671 672 /* Set the logical layer timeout to 100ms. The default is too high and causes 673 core bus errors */ 674 if (__cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_PORT_RT_CTL(srio_port), &port_rt_ctl.u32)) 675 return -1; 676 port_rt_ctl.s.timeout = 100000000 / 200; /* 100ms = 100000000ns / 200ns */ 677 if (__cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_PORT_RT_CTL(srio_port), port_rt_ctl.u32)) 678 return -1; 679 680 /* Allow memory and doorbells. Messaging is enabled later */ 681 if (__cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_CORE_ENABLES(srio_port), &core_enables.u32)) 682 return -1; 683 core_enables.s.doorbell = 1; 684 core_enables.s.memory = 1; 685 if (__cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_CORE_ENABLES(srio_port), core_enables.u32)) 686 return -1; 687 688 /* Allow us to master transactions */ 689 if (__cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_PORT_GEN_CTL(srio_port), &port_gen_ctl.u32)) 690 return -1; 691 port_gen_ctl.s.menable = 1; 692 if (__cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_PORT_GEN_CTL(srio_port), port_gen_ctl.u32)) 693 return -1; 694 695 /* Set the MRRS and MPS for optimal SRIO performance */ 696 prt_cfg.u64 = cvmx_read_csr(CVMX_DPI_SLI_PRTX_CFG(srio_port)); 697 prt_cfg.s.mps = 1; 698 prt_cfg.s.mrrs = 1; 699 prt_cfg.s.molr = 32; 700 if (OCTEON_IS_MODEL(OCTEON_CN66XX)) 701 prt_cfg.s.molr = ((prt_cfg.s.qlm_cfg == 1 || prt_cfg.s.qlm_cfg == 3) ? 8 702 : (prt_cfg.s.qlm_cfg == 4 || prt_cfg.s.qlm_cfg == 6) ? 16 703 : 32); 704 cvmx_write_csr(CVMX_DPI_SLI_PRTX_CFG(srio_port), prt_cfg.u64); 705 706 sli_s2m_portx_ctl.u64 = cvmx_read_csr(CVMX_PEXP_SLI_S2M_PORTX_CTL(srio_port)); 707 sli_s2m_portx_ctl.s.mrrs = 1; 708 cvmx_write_csr(CVMX_PEXP_SLI_S2M_PORTX_CTL(srio_port), sli_s2m_portx_ctl.u64); 709 710 /* Setup RX messaging thresholds */ 711 sriox_imsg_vport_thr.u64 = cvmx_read_csr(CVMX_SRIOX_IMSG_VPORT_THR(srio_port)); 712 if (OCTEON_IS_MODEL(OCTEON_CN66XX)) 713 sriox_imsg_vport_thr.s.max_tot = ((prt_cfg.s.qlm_cfg == 1 || prt_cfg.s.qlm_cfg == 3) ? 44 : 46); 714 else 715 sriox_imsg_vport_thr.s.max_tot = 48; 716 sriox_imsg_vport_thr.s.max_s1 = 24; 717 sriox_imsg_vport_thr.s.max_s0 = 24; 718 sriox_imsg_vport_thr.s.sp_vport = 1; 719 sriox_imsg_vport_thr.s.buf_thr = 4; 720 sriox_imsg_vport_thr.s.max_p1 = 12; 721 sriox_imsg_vport_thr.s.max_p0 = 12; 722 cvmx_write_csr(CVMX_SRIOX_IMSG_VPORT_THR(srio_port), sriox_imsg_vport_thr.u64); 723 724 /* Setup RX messaging thresholds for other virtual ports. */ 725 if (OCTEON_IS_MODEL(OCTEON_CN66XX)) 726 { 727 cvmx_sriox_imsg_vport_thr2_t sriox_imsg_vport_thr2; 728 sriox_imsg_vport_thr2.u64 = cvmx_read_csr(CVMX_SRIOX_IMSG_VPORT_THR2(srio_port)); 729 sriox_imsg_vport_thr2.s.max_s2 = 24; 730 sriox_imsg_vport_thr2.s.max_s3 = 24; 731 cvmx_write_csr(CVMX_SRIOX_IMSG_VPORT_THR2(srio_port), sriox_imsg_vport_thr2.u64); 732 } 733 734 /* Errata SRIO-X: SRIO error behavior may not be optimal in CN63XX pass 1.x */ 735 if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X)) 736 { 737 cvmx_sriox_tx_ctrl_t sriox_tx_ctrl; 738 sriox_tx_ctrl.u64 = cvmx_read_csr(CVMX_SRIOX_TX_CTRL(srio_port)); 739 sriox_tx_ctrl.s.tag_th2 = 2; 740 sriox_tx_ctrl.s.tag_th1 = 3; 741 sriox_tx_ctrl.s.tag_th0 = 4; 742 cvmx_write_csr(CVMX_SRIOX_TX_CTRL(srio_port), sriox_tx_ctrl.u64); 743 } 744 745 /* Errata SLI-15954: SLI relaxed order issues */ 746 if (OCTEON_IS_MODEL(OCTEON_CN66XX_PASS1_X)) 747 { 748 cvmx_sli_ctl_portx_t sli_ctl_portx; 749 sli_ctl_portx.u64 = cvmx_read_csr(CVMX_PEXP_SLI_CTL_PORTX(srio_port)); 750 sli_ctl_portx.s.ptlp_ro = 1; /* Set to same value for all MACs. */ 751 sli_ctl_portx.s.ctlp_ro = 1; /* Set to same value for all MACs. */ 752 sli_ctl_portx.s.wait_com = 0; /* So that no inbound stores wait for a commit */ 753 sli_ctl_portx.s.waitl_com = 0; 754 cvmx_write_csr(CVMX_PEXP_SLI_CTL_PORTX(srio_port), sli_ctl_portx.u64); 755 } 756 757 if (!OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X)) 758 { 759 /* Clear the ACK state */ 760 if (__cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_PORT_0_LOCAL_ACKID(srio_port), 0)) 761 return -1; 762 } 763 764 /* Bring the link down, then up, by writing to the SRIO port's 765 PORT_0_CTL2 CSR. */ 766 if (__cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_PORT_0_CTL2(srio_port), &port_0_ctl2.u32)) 767 return -1; 768 if (__cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_PORT_0_CTL2(srio_port), port_0_ctl2.u32)) 769 return -1; 770 771 /* Clear any pending interrupts */ 772 cvmx_write_csr(CVMX_SRIOX_INT_REG(srio_port), cvmx_read_csr(CVMX_SRIOX_INT_REG(srio_port))); 773 774 /* Enable error reporting */ 775#if (!defined(CVMX_BUILD_FOR_LINUX_HOST) && !defined(CVMX_BUILD_FOR_LINUX_KERNEL) && !defined(CVMX_BUILD_FOR_FREEBSD_KERNEL)) || defined(CONFIG_CAVIUM_DECODE_RSL) 776 cvmx_error_enable_group(CVMX_ERROR_GROUP_SRIO, srio_port); 777#endif 778 779 /* Finally enable the link */ 780 if (__cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_PORT_0_CTL(srio_port), &port_0_ctl.u32)) 781 return -1; 782 port_0_ctl.s.o_enable = 1; 783 port_0_ctl.s.i_enable = 1; 784 port_0_ctl.s.disable = 0; 785 port_0_ctl.s.prt_lock = 0; 786 if (__cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_PORT_0_CTL(srio_port), port_0_ctl.u32)) 787 return -1; 788 789 /* Store merge control (SLI_MEM_ACCESS_CTL[TIMER,MAX_WORD]) */ 790 sli_mem_access_ctl.u64 = cvmx_read_csr(CVMX_PEXP_SLI_MEM_ACCESS_CTL); 791 sli_mem_access_ctl.s.max_word = 0; /* Allow 16 words to combine */ 792 sli_mem_access_ctl.s.timer = 127; /* Wait up to 127 cycles for more data */ 793 cvmx_write_csr(CVMX_PEXP_SLI_MEM_ACCESS_CTL, sli_mem_access_ctl.u64); 794 795 /* FIXME: Disable sending a link request when the SRIO link is 796 brought up. For unknown reasons this code causes issues with some SRIO 797 devices. As we currently don't support hotplug in software, this code 798 should never be needed. Without link down/up events, the ACKs should 799 start off and stay synchronized */ 800#if 0 801 /* Ask for a link and align our ACK state. CN63XXp1 didn't support this */ 802 if (!OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X)) 803 { 804 uint64_t stop_cycle; 805 cvmx_sriomaintx_port_0_err_stat_t sriomaintx_port_0_err_stat; 806 807 /* Clear the SLI_CTL_PORTX[DIS_PORT[ bit to re-enable traffic-flow 808 to the SRIO MACs. */ 809 cvmx_write_csr(CVMX_PEXP_SLI_CTL_PORTX(srio_port), cvmx_read_csr(CVMX_PEXP_SLI_CTL_PORTX(srio_port))); 810 811 /* Wait a little to see if the link comes up */ 812 stop_cycle = cvmx_clock_get_rate(CVMX_CLOCK_CORE)/4 + cvmx_clock_get_count(CVMX_CLOCK_CORE); 813 do 814 { 815 /* Read the port link status */ 816 if (__cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_PORT_0_ERR_STAT(srio_port), &sriomaintx_port_0_err_stat.u32)) 817 return -1; 818 } while (!sriomaintx_port_0_err_stat.s.pt_ok && (cvmx_clock_get_count(CVMX_CLOCK_CORE) < stop_cycle)); 819 820 /* Send link request if link is up */ 821 if (sriomaintx_port_0_err_stat.s.pt_ok) 822 { 823 cvmx_sriomaintx_port_0_link_req_t link_req; 824 cvmx_sriomaintx_port_0_link_resp_t link_resp; 825 link_req.u32 = 0; 826 link_req.s.cmd = 4; 827 828 /* Send the request */ 829 if (__cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_PORT_0_LINK_REQ(srio_port), link_req.u32)) 830 return -1; 831 832 /* Wait for the response */ 833 stop_cycle = cvmx_clock_get_rate(CVMX_CLOCK_CORE)/8 + cvmx_clock_get_count(CVMX_CLOCK_CORE); 834 do 835 { 836 if (__cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_PORT_0_LINK_RESP(srio_port), &link_resp.u32)) 837 return -1; 838 } while (!link_resp.s.valid && (cvmx_clock_get_count(CVMX_CLOCK_CORE) < stop_cycle)); 839 840 /* Set our ACK state if we got a response */ 841 if (link_resp.s.valid) 842 { 843 cvmx_sriomaintx_port_0_local_ackid_t local_ackid; 844 local_ackid.u32 = 0; 845 local_ackid.s.i_ackid = 0; 846 local_ackid.s.e_ackid = link_resp.s.ackid; 847 local_ackid.s.o_ackid = link_resp.s.ackid; 848 if (__cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_PORT_0_LOCAL_ACKID(srio_port), local_ackid.u32)) 849 return -1; 850 } 851 else 852 return -1; 853 } 854 } 855#endif 856 857 return 0; 858} 859 860 861/** 862 * Read 32bits from a Device's config space 863 * 864 * @param srio_port SRIO port the device is on 865 * @param srcid_index 866 * Which SRIO source ID to use. 0 = Primary, 1 = Secondary 867 * @param destid RapidIO device ID, or -1 for the local Octeon. 868 * @param is16bit Non zero if the transactions should use 16bit device IDs. Zero 869 * if transactions should use 8bit device IDs. 870 * @param hopcount Number of hops to the remote device. Use 0 for the local Octeon. 871 * @param offset Offset in config space. This must be a multiple of 32 bits. 872 * @param result Result of the read. This will be unmodified on failure. 873 * 874 * @return Zero on success, negative on failure. 875 */ 876int cvmx_srio_config_read32(int srio_port, int srcid_index, int destid, 877 int is16bit, uint8_t hopcount, uint32_t offset, 878 uint32_t *result) 879{ 880 if (destid == -1) 881 { 882 int status = __cvmx_srio_local_read32(srio_port, offset, result); 883 884 if ((status == 0) && (__cvmx_srio_state[srio_port].flags & CVMX_SRIO_INITIALIZE_DEBUG)) 885 cvmx_dprintf("SRIO%d: Local read [0x%06x] <= 0x%08x\n", srio_port, (unsigned int)offset, (unsigned int)*result); 886 887 return status; 888 } 889 else 890 { 891 if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X)) 892 { 893 int return_code; 894 uint32_t pkt = 0; 895 uint32_t sourceid; 896 uint64_t stop_cycle; 897 char rx_buffer[64]; 898 899 /* Tell the user */ 900 if (__cvmx_srio_state[srio_port].flags & CVMX_SRIO_INITIALIZE_DEBUG) 901 cvmx_dprintf("SRIO%d: Remote read [id=0x%04x hop=%3d offset=0x%06x] <= ", srio_port, destid, hopcount, (unsigned int)offset); 902 903 /* Read the proper source ID */ 904 if (srcid_index) 905 __cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_SEC_DEV_ID(srio_port), &sourceid); 906 else 907 __cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_PRI_DEV_ID(srio_port), &sourceid); 908 909 if (is16bit) 910 { 911 /* Use the 16bit source ID */ 912 sourceid &= 0xffff; 913 914 /* MAINT Reads are 11 bytes */ 915 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_CTRL(srio_port), 11<<16); 916 917 pkt |= CVMX_SRIO_CONFIG_PRIORITY << 30; /* priority [31:30] */ 918 pkt |= 1 << 28; /* tt [29:28] */ 919 pkt |= 0x8 << 24; /* ftype [27:24] */ 920 pkt |= destid << 8; /* destID [23:8] */ 921 pkt |= sourceid >> 8; /* sourceID [7:0] */ 922 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_DATA(srio_port), pkt); 923 pkt = 0; 924 pkt |= sourceid << 24; /* sourceID [31:24] */ 925 pkt |= 0 << 20; /* transaction [23:20] */ 926 pkt |= 8 << 16; /* rdsize [19:16] */ 927 pkt |= 0xc0 << 8; /* srcTID [15:8] */ 928 pkt |= hopcount; /* hopcount [7:0] */ 929 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_DATA(srio_port), pkt); 930 pkt = 0; 931 pkt |= offset << 8; /* offset [31:11, wdptr[10], reserved[9:8] */ 932 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_DATA(srio_port), pkt); 933 } 934 else 935 { 936 /* Use the 8bit source ID */ 937 sourceid = (sourceid >> 16) & 0xff; 938 939 /* MAINT Reads are 9 bytes */ 940 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_CTRL(srio_port), 9<<16); 941 942 pkt |= CVMX_SRIO_CONFIG_PRIORITY << 30; /* priority [31:30] */ 943 pkt |= 0 << 28; /* tt [29:28] */ 944 pkt |= 0x8 << 24; /* ftype [27:24] */ 945 pkt |= destid << 16; /* destID [23:16] */ 946 pkt |= sourceid << 8; /* sourceID [15:8] */ 947 pkt |= 0 << 4; /* transaction [7:4] */ 948 pkt |= 8 << 0; /* rdsize [3:0] */ 949 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_DATA(srio_port), pkt); 950 pkt = 0; 951 pkt |= 0xc0 << 24; /* srcTID [31:24] */ 952 pkt |= hopcount << 16; /* hopcount [23:16] */ 953 pkt |= offset >> 8; /* offset [15:0] */ 954 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_DATA(srio_port), pkt); 955 pkt = 0; 956 pkt |= offset << 24; /* offset [31:27, wdptr[26], reserved[25:24] */ 957 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_DATA(srio_port), pkt); 958 } 959 960 stop_cycle = cvmx_clock_get_rate(CVMX_CLOCK_CORE)/10 + cvmx_clock_get_count(CVMX_CLOCK_CORE); 961 do 962 { 963 return_code = cvmx_srio_receive_spf(srio_port, rx_buffer, sizeof(rx_buffer)); 964 if ((return_code == 0) && (cvmx_clock_get_count(CVMX_CLOCK_CORE) > stop_cycle)) 965 { 966 if (__cvmx_srio_state[srio_port].flags & CVMX_SRIO_INITIALIZE_DEBUG) 967 cvmx_dprintf("timeout\n"); 968 return_code = -1; 969 } 970 } while (return_code == 0); 971 972 if (return_code == ((is16bit) ? 23 : 19)) 973 { 974 if (is16bit) 975 { 976 if (offset & 4) 977 *result = *(uint32_t*)(rx_buffer + 15); 978 else 979 *result = *(uint32_t*)(rx_buffer + 11); 980 } 981 else 982 { 983 if (offset & 4) 984 *result = *(uint32_t*)(rx_buffer + 13); 985 else 986 *result = *(uint32_t*)(rx_buffer + 9); 987 } 988 if (__cvmx_srio_state[srio_port].flags & CVMX_SRIO_INITIALIZE_DEBUG) 989 cvmx_dprintf("0x%08x\n", (unsigned int)*result); 990 return_code = 0; 991 } 992 else 993 { 994 *result = 0xffffffff; 995 return_code = -1; 996 } 997 998 return return_code; 999 } 1000 else 1001 { 1002#if !defined(CVMX_BUILD_FOR_LINUX_HOST) 1003 uint64_t physical; 1004 physical = cvmx_srio_physical_map(srio_port, 1005 CVMX_SRIO_WRITE_MODE_MAINTENANCE, CVMX_SRIO_CONFIG_PRIORITY, 1006 CVMX_SRIO_READ_MODE_MAINTENANCE, CVMX_SRIO_CONFIG_PRIORITY, 1007 srcid_index, destid, is16bit, offset + (hopcount<<24), 4); 1008 if (!physical) 1009 return -1; 1010 1011 if (__cvmx_srio_state[srio_port].flags & CVMX_SRIO_INITIALIZE_DEBUG) 1012 cvmx_dprintf("SRIO%d: Remote read [id=0x%04x hop=%3d offset=0x%06x] <= ", srio_port, destid, hopcount, (unsigned int)offset); 1013 1014 /* Finally do the maintenance read to complete the config request */ 1015 *result = cvmx_read64_uint32(CVMX_ADD_IO_SEG(physical)); 1016 cvmx_srio_physical_unmap(physical, 4); 1017 1018 if (__cvmx_srio_state[srio_port].flags & CVMX_SRIO_INITIALIZE_DEBUG) 1019 cvmx_dprintf("0x%08x\n", (unsigned int)*result); 1020 1021 return 0; 1022#else 1023 return -1; 1024#endif 1025 } 1026 } 1027} 1028#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 1029EXPORT_SYMBOL(cvmx_srio_config_read32); 1030#endif 1031 1032 1033/** 1034 * Write 32bits to a Device's config space 1035 * 1036 * @param srio_port SRIO port the device is on 1037 * @param srcid_index 1038 * Which SRIO source ID to use. 0 = Primary, 1 = Secondary 1039 * @param destid RapidIO device ID, or -1 for the local Octeon. 1040 * @param is16bit Non zero if the transactions should use 16bit device IDs. Zero 1041 * if transactions should use 8bit device IDs. 1042 * @param hopcount Number of hops to the remote device. Use 0 for the local Octeon. 1043 * @param offset Offset in config space. This must be a multiple of 32 bits. 1044 * @param data Data to write. 1045 * 1046 * @return Zero on success, negative on failure. 1047 */ 1048int cvmx_srio_config_write32(int srio_port, int srcid_index, int destid, 1049 int is16bit, uint8_t hopcount, uint32_t offset, 1050 uint32_t data) 1051{ 1052 if (destid == -1) 1053 { 1054 if (__cvmx_srio_state[srio_port].flags & CVMX_SRIO_INITIALIZE_DEBUG) 1055 cvmx_dprintf("SRIO%d: Local write[0x%06x] => 0x%08x\n", srio_port, (unsigned int)offset, (unsigned int)data); 1056 1057 return __cvmx_srio_local_write32(srio_port, offset, data); 1058 } 1059 else 1060 { 1061 if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X)) 1062 { 1063 int return_code; 1064 uint32_t pkt = 0; 1065 uint32_t sourceid; 1066 uint64_t stop_cycle; 1067 char rx_buffer[64]; 1068 1069 /* Tell the user */ 1070 if (__cvmx_srio_state[srio_port].flags & CVMX_SRIO_INITIALIZE_DEBUG) 1071 cvmx_dprintf("SRIO%d: Remote write[id=0x%04x hop=%3d offset=0x%06x] => 0x%08x\n", srio_port, destid, hopcount, (unsigned int)offset, (unsigned int)data); 1072 1073 /* Read the proper source ID */ 1074 if (srcid_index) 1075 __cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_SEC_DEV_ID(srio_port), &sourceid); 1076 else 1077 __cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_PRI_DEV_ID(srio_port), &sourceid); 1078 1079 if (is16bit) 1080 { 1081 /* Use the 16bit source ID */ 1082 sourceid &= 0xffff; 1083 1084 /* MAINT Writes are 19 bytes */ 1085 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_CTRL(srio_port), 19<<16); 1086 1087 pkt |= CVMX_SRIO_CONFIG_PRIORITY << 30; /* priority [31:30] */ 1088 pkt |= 1 << 28; /* tt [29:28] */ 1089 pkt |= 0x8 << 24; /* ftype [27:24] */ 1090 pkt |= destid << 8; /* destID [23:8] */ 1091 pkt |= sourceid >> 8; /* sourceID [7:0] */ 1092 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_DATA(srio_port), pkt); 1093 pkt = 0; 1094 pkt |= sourceid << 24; /* sourceID [31:24] */ 1095 pkt |= 1 << 20; /* transaction [23:20] */ 1096 pkt |= 8 << 16; /* wrsize [19:16] */ 1097 pkt |= 0xc0 << 8; /* srcTID [15:8] */ 1098 pkt |= hopcount; /* hopcount [7:0] */ 1099 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_DATA(srio_port), pkt); 1100 pkt = 0; 1101 pkt |= offset << 8; /* offset [31:11, wdptr[10], reserved[9:8] */ 1102 if ((offset & 4) == 0) 1103 pkt |= 0xff & (data >> 24); /* data [7:0] */ 1104 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_DATA(srio_port), pkt); 1105 if (offset & 4) 1106 { 1107 pkt = 0xff & (data >> 24); 1108 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_DATA(srio_port), pkt); 1109 pkt = data << 8; 1110 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_DATA(srio_port), pkt); 1111 } 1112 else 1113 { 1114 pkt = data << 8; 1115 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_DATA(srio_port), pkt); 1116 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_DATA(srio_port), 0); 1117 } 1118 } 1119 else 1120 { 1121 /* Use the 8bit source ID */ 1122 sourceid = (sourceid >> 16) & 0xff; 1123 1124 /* MAINT Writes are 17 bytes */ 1125 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_CTRL(srio_port), 17<<16); 1126 1127 pkt |= CVMX_SRIO_CONFIG_PRIORITY << 30; /* priority [31:30] */ 1128 pkt |= 0 << 28; /* tt [29:28] */ 1129 pkt |= 0x8 << 24; /* ftype [27:24] */ 1130 pkt |= destid << 16; /* destID [23:16] */ 1131 pkt |= sourceid << 8; /* sourceID [15:8] */ 1132 pkt |= 1 << 4; /* transaction [7:4] */ 1133 pkt |= 8 << 0; /* wrsize [3:0] */ 1134 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_DATA(srio_port), pkt); 1135 pkt = 0; 1136 pkt |= 0xc0 << 24; /* srcTID [31:24] */ 1137 pkt |= hopcount << 16; /* hopcount [23:16] */ 1138 pkt |= offset >> 8; /* offset [15:0] */ 1139 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_DATA(srio_port), pkt); 1140 pkt = 0; 1141 pkt |= offset << 24; /* offset [31:27, wdptr[26], reserved[25:24] */ 1142 if (offset & 4) 1143 { 1144 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_DATA(srio_port), pkt); 1145 pkt = data >> 8; 1146 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_DATA(srio_port), pkt); 1147 pkt = data << 24; 1148 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_DATA(srio_port), pkt); 1149 } 1150 else 1151 { 1152 pkt |= data >> 8; /* data [23:0] */ 1153 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_DATA(srio_port), pkt); 1154 pkt = data << 24; /* data [31:24] */ 1155 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_DATA(srio_port), pkt); 1156 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_DATA(srio_port), 0); 1157 } 1158 } 1159 1160 stop_cycle = cvmx_clock_get_rate(CVMX_CLOCK_CORE)/10 + cvmx_clock_get_count(CVMX_CLOCK_CORE); 1161 do 1162 { 1163 return_code = cvmx_srio_receive_spf(srio_port, rx_buffer, sizeof(rx_buffer)); 1164 if ((return_code == 0) && (cvmx_clock_get_count(CVMX_CLOCK_CORE) > stop_cycle)) 1165 { 1166 if (__cvmx_srio_state[srio_port].flags & CVMX_SRIO_INITIALIZE_DEBUG) 1167 cvmx_dprintf("timeout\n"); 1168 return_code = -1; 1169 } 1170 } while (return_code == 0); 1171 1172 if (return_code == ((is16bit) ? 15 : 11)) 1173 return_code = 0; 1174 else 1175 { 1176 cvmx_dprintf("SRIO%d: Remote write failed\n", srio_port); 1177 return_code = -1; 1178 } 1179 1180 return return_code; 1181 } 1182 else 1183 { 1184#if !defined(CVMX_BUILD_FOR_LINUX_HOST) 1185 uint64_t physical = cvmx_srio_physical_map(srio_port, 1186 CVMX_SRIO_WRITE_MODE_MAINTENANCE, CVMX_SRIO_CONFIG_PRIORITY, 1187 CVMX_SRIO_READ_MODE_MAINTENANCE, CVMX_SRIO_CONFIG_PRIORITY, 1188 srcid_index, destid, is16bit, offset + (hopcount<<24), 4); 1189 if (!physical) 1190 return -1; 1191 1192 if (__cvmx_srio_state[srio_port].flags & CVMX_SRIO_INITIALIZE_DEBUG) 1193 cvmx_dprintf("SRIO%d: Remote write[id=0x%04x hop=%3d offset=0x%06x] => 0x%08x\n", srio_port, destid, hopcount, (unsigned int)offset, (unsigned int)data); 1194 1195 /* Finally do the maintenance write to complete the config request */ 1196 cvmx_write64_uint32(CVMX_ADD_IO_SEG(physical), data); 1197 return cvmx_srio_physical_unmap(physical, 4); 1198#else 1199 return -1; 1200#endif 1201 } 1202 } 1203} 1204 1205 1206/** 1207 * Send a RapidIO doorbell to a remote device 1208 * 1209 * @param srio_port SRIO port the device is on 1210 * @param srcid_index 1211 * Which SRIO source ID to use. 0 = Primary, 1 = Secondary 1212 * @param destid RapidIO device ID. 1213 * @param is16bit Non zero if the transactions should use 16bit device IDs. Zero 1214 * if transactions should use 8bit device IDs. 1215 * @param priority Doorbell priority (0-3) 1216 * @param data Data for doorbell. 1217 * 1218 * @return Zero on success, negative on failure. 1219 */ 1220int cvmx_srio_send_doorbell(int srio_port, int srcid_index, int destid, int is16bit, int priority, uint16_t data) 1221{ 1222 cvmx_sriox_tx_bell_t tx_bell; 1223 tx_bell.u64 = 0; 1224 tx_bell.s.data = data; 1225 tx_bell.s.dest_id = destid; 1226 tx_bell.s.src_id = srcid_index; 1227 tx_bell.s.id16 = !!is16bit; 1228 tx_bell.s.priority = priority; 1229 1230 /* Make sure the previous doorbell has completed */ 1231 if (CVMX_WAIT_FOR_FIELD64(CVMX_SRIOX_TX_BELL(srio_port), cvmx_sriox_tx_bell_t, pending, ==, 0, CVMX_SRIO_DOORBELL_TIMEOUT)) 1232 { 1233 cvmx_dprintf("SRIO%d: Pending bit stuck before doorbell\n", srio_port); 1234 return -1; 1235 } 1236 1237 if (__cvmx_srio_state[srio_port].flags & CVMX_SRIO_INITIALIZE_DEBUG) 1238 cvmx_dprintf("SRIO%d: Send doorbell destid=0x%x, priority=%d, data=0x%x\n", srio_port, destid, priority, 0xffff & data); 1239 1240 /* Send the doorbell. We don't wait for it to complete. The next doorbell 1241 may delay on the pending bit, but this gives the caller the ability to 1242 do other stuff while the doorbell processes */ 1243 cvmx_write_csr(CVMX_SRIOX_TX_BELL(srio_port), tx_bell.u64); 1244 return 0; 1245} 1246#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 1247EXPORT_SYMBOL(cvmx_srio_send_doorbell); 1248#endif 1249 1250/** 1251 * Get the status of the last doorbell sent. If the dooorbell 1252 * hardware is done, then the status is cleared to get ready for 1253 * the next doorbell (or retry). 1254 * 1255 * @param srio_port SRIO port to check doorbell on 1256 * 1257 * @return Doorbell status 1258 */ 1259cvmx_srio_doorbell_status_t cvmx_srio_send_doorbell_status(int srio_port) 1260{ 1261 cvmx_sriox_tx_bell_t tx_bell; 1262 cvmx_sriox_tx_bell_info_t tx_bell_info; 1263 cvmx_sriox_int_reg_t int_reg; 1264 cvmx_sriox_int_reg_t int_reg_clear; 1265 1266 /* Return busy if the doorbell is still processing */ 1267 tx_bell.u64 = cvmx_read_csr(CVMX_SRIOX_TX_BELL(srio_port)); 1268 if (tx_bell.s.pending) 1269 return CVMX_SRIO_DOORBELL_BUSY; 1270 1271 /* Read and clear the TX doorbell interrupts */ 1272 int_reg.u64 = cvmx_read_csr(CVMX_SRIOX_INT_REG(srio_port)); 1273 int_reg_clear.u64 = 0; 1274 int_reg_clear.s.bell_err = int_reg.s.bell_err; 1275 int_reg_clear.s.txbell = int_reg.s.txbell; 1276 cvmx_write_csr(CVMX_SRIOX_INT_REG(srio_port), int_reg_clear.u64); 1277 1278 /* Check for errors */ 1279 if (int_reg.s.bell_err) 1280 { 1281 if (__cvmx_srio_state[srio_port].flags & CVMX_SRIO_INITIALIZE_DEBUG) 1282 cvmx_dprintf("SRIO%d: Send doorbell failed\n", srio_port); 1283 tx_bell_info.u64 = cvmx_read_csr(CVMX_SRIOX_TX_BELL_INFO(srio_port)); 1284 if (tx_bell_info.s.timeout) 1285 return CVMX_SRIO_DOORBELL_TMOUT; 1286 if (tx_bell_info.s.error) 1287 return CVMX_SRIO_DOORBELL_ERROR; 1288 if (tx_bell_info.s.retry) 1289 return CVMX_SRIO_DOORBELL_RETRY; 1290 } 1291 1292 /* Check if we're done */ 1293 if (int_reg.s.txbell) 1294 return CVMX_SRIO_DOORBELL_DONE; 1295 1296 /* No doorbell found */ 1297 return CVMX_SRIO_DOORBELL_NONE; 1298} 1299 1300 1301/** 1302 * Read a received doorbell and report data about it. 1303 * 1304 * @param srio_port SRIO port to check for the received doorbell 1305 * @param destid_index 1306 * Which Octeon destination ID was the doorbell for 1307 * @param sequence_num 1308 * Sequence number of doorbell (32bits) 1309 * @param srcid RapidIO source ID of the doorbell sender 1310 * @param priority Priority of the doorbell (0-3) 1311 * @param is16bit Non zero if the transactions should use 16bit device IDs. Zero 1312 * if transactions should use 8bit device IDs. 1313 * @param data Data in the doorbell (16 bits) 1314 * 1315 * @return Doorbell status. Either DONE, NONE, or ERROR. 1316 */ 1317cvmx_srio_doorbell_status_t cvmx_srio_receive_doorbell(int srio_port, 1318 int *destid_index, uint32_t *sequence_num, int *srcid, int *priority, 1319 int *is16bit, uint16_t *data) 1320{ 1321 cvmx_sriox_rx_bell_seq_t rx_bell_seq; 1322 cvmx_sriox_rx_bell_t rx_bell; 1323 1324 /* Check if there are any pending doorbells */ 1325 rx_bell_seq.u64 = cvmx_read_csr(CVMX_SRIOX_RX_BELL_SEQ(srio_port)); 1326 if (!rx_bell_seq.s.count) 1327 return CVMX_SRIO_DOORBELL_NONE; 1328 1329 /* Read the doorbell and write our return parameters */ 1330 rx_bell.u64 = cvmx_read_csr(CVMX_SRIOX_RX_BELL(srio_port)); 1331 *sequence_num = rx_bell_seq.s.seq; 1332 *srcid = rx_bell.s.src_id; 1333 *priority = rx_bell.s.priority; 1334 *is16bit = rx_bell.s.id16; 1335 *data = rx_bell.s.data; 1336 *destid_index = rx_bell.s.dest_id; 1337 1338 if (__cvmx_srio_state[srio_port].flags & CVMX_SRIO_INITIALIZE_DEBUG) 1339 cvmx_dprintf("SRIO%d: Receive doorbell sequence=0x%x, srcid=0x%x, priority=%d, data=0x%x\n", 1340 srio_port, rx_bell_seq.s.seq, rx_bell.s.src_id, rx_bell.s.priority, rx_bell.s.data); 1341 1342 return CVMX_SRIO_DOORBELL_DONE; 1343} 1344 1345 1346/** 1347 * Receive a packet from the Soft Packet FIFO (SPF). 1348 * 1349 * @param srio_port SRIO port to read the packet from. 1350 * @param buffer Buffer to receive the packet. 1351 * @param buffer_length 1352 * Length of the buffer in bytes. 1353 * 1354 * @return Returns the length of the packet read. Negative on failure. 1355 * Zero if no packets are available. 1356 */ 1357int cvmx_srio_receive_spf(int srio_port, void *buffer, int buffer_length) 1358{ 1359 uint32_t *ptr = (uint32_t *)buffer; 1360 cvmx_sriomaintx_ir_sp_rx_stat_t sriomaintx_ir_sp_rx_stat; 1361 1362 /* Read the SFP status */ 1363 if (__cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_IR_SP_RX_STAT(srio_port), &sriomaintx_ir_sp_rx_stat.u32)) 1364 return -1; 1365 1366 /* Return zero if there isn't a packet available */ 1367 if (sriomaintx_ir_sp_rx_stat.s.buffers < 1) 1368 return 0; 1369 1370 if (__cvmx_srio_state[srio_port].flags & CVMX_SRIO_INITIALIZE_DEBUG) 1371 cvmx_dprintf("SRIO%d: Soft packet FIFO received %d bytes", srio_port, sriomaintx_ir_sp_rx_stat.s.octets); 1372 1373 /* Return error if the packet is larger than our buffer */ 1374 if (sriomaintx_ir_sp_rx_stat.s.octets > buffer_length) 1375 return -1; 1376 1377 /* Read out the packet four bytes at a time */ 1378 buffer_length = sriomaintx_ir_sp_rx_stat.s.octets; 1379 while (buffer_length > 0) 1380 { 1381 __cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_IR_SP_RX_DATA(srio_port), ptr); 1382 if (__cvmx_srio_state[srio_port].flags & CVMX_SRIO_INITIALIZE_DEBUG) 1383 cvmx_dprintf(" %08x", (unsigned int)*ptr); 1384 ptr++; 1385 buffer_length-=4; 1386 } 1387 1388 if (__cvmx_srio_state[srio_port].flags & CVMX_SRIO_INITIALIZE_DEBUG) 1389 cvmx_dprintf("\n"); 1390 1391 /* Return the number of bytes in the buffer */ 1392 return sriomaintx_ir_sp_rx_stat.s.octets; 1393} 1394 1395#ifndef CVMX_BUILD_FOR_LINUX_HOST 1396/** 1397 * Map a remote device's memory region into Octeon's physical 1398 * address area. The caller can then map this into a core using 1399 * the TLB or XKPHYS. 1400 * 1401 * @param srio_port SRIO port to map the device on 1402 * @param write_op Type of operation to perform on a write to the device. 1403 * Normally should be CVMX_SRIO_WRITE_MODE_AUTO. 1404 * @param write_priority 1405 * SRIO priority of writes (0-3) 1406 * @param read_op Type of operation to perform on reads to the device. 1407 * Normally should be CVMX_SRIO_READ_MODE_NORMAL. 1408 * @param read_priority 1409 * SRIO priority of reads (0-3) 1410 * @param srcid_index 1411 * Which SRIO source ID to use. 0 = Primary, 1 = Secondary 1412 * @param destid RapidIO device ID. 1413 * @param is16bit Non zero if the transactions should use 16bit device IDs. Zero 1414 * if transactions should use 8bit device IDs. 1415 * @param base Device base address to start the mapping 1416 * @param size Size of the mapping in bytes 1417 * 1418 * @return Octeon 64bit physical address that accesses the remote device, 1419 * or zero on failure. 1420 */ 1421uint64_t cvmx_srio_physical_map(int srio_port, cvmx_srio_write_mode_t write_op, 1422 int write_priority, cvmx_srio_read_mode_t read_op, int read_priority, 1423 int srcid_index, int destid, int is16bit, uint64_t base, uint64_t size) 1424{ 1425 cvmx_sriox_s2m_typex_t needed_s2m_type; 1426 cvmx_sli_mem_access_subidx_t needed_subid; 1427 int s2m_index; 1428 int subdid; 1429 cvmx_sli_address_t sli_address; 1430 1431 /* We currently don't support mapping regions that span a 34 bit boundary. 1432 Keeping track of multiple regions to span 34 bits is hard and not 1433 likely to be needed */ 1434 if (((base+size-1)>>34) != (base>>34)) 1435 { 1436 cvmx_dprintf("SRIO%d: Failed to map range 0x%llx-0x%llx spanning a 34bit boundary\n", 1437 srio_port, (ULL)base, (ULL)base+size-1); 1438 return 0; 1439 } 1440 1441 /* Build the S2M_TYPE we are going to need */ 1442 needed_s2m_type.u64 = 0; 1443 needed_s2m_type.s.wr_op = write_op; 1444 needed_s2m_type.s.rd_op = read_op; 1445 needed_s2m_type.s.wr_prior = write_priority; 1446 needed_s2m_type.s.rd_prior = read_priority; 1447 needed_s2m_type.s.src_id = srcid_index; 1448 needed_s2m_type.s.id16 = !!is16bit; 1449 1450 /* Build the needed SubID config */ 1451 needed_subid.u64 = 0; 1452 needed_subid.s.port = srio_port; 1453 needed_subid.s.nmerge = 0; 1454 1455 /* FIXME: We might want to use the device ID swapping modes so the device 1456 ID is part of the lower address bits. This would allow many more 1457 devices to share S2M_TYPE indexes. This would require "base+size-1" 1458 to fit in bits [17:0] or bits[25:0] for 8 bits of device ID */ 1459 if (base < (1ull<<34)) 1460 { 1461 needed_subid.cn63xx.ba = destid; 1462 needed_s2m_type.s.iaow_sel = 0; 1463 } 1464 else if (base < (1ull<<42)) 1465 { 1466 needed_subid.cn63xx.ba = (base>>34) & 0xff; 1467 needed_subid.cn63xx.ba |= ((uint64_t)destid & 0xff) << (42-34); 1468 needed_subid.cn63xx.ba |= (((uint64_t)destid>>8) & 0xff) << (51-34); 1469 needed_s2m_type.s.iaow_sel = 1; 1470 } 1471 else 1472 { 1473 if (destid>>8) 1474 { 1475 cvmx_dprintf("SRIO%d: Attempt to map 16bit device ID 0x%x using 66bit addressing\n", srio_port, destid); 1476 return 0; 1477 } 1478 if (base>>50) 1479 { 1480 cvmx_dprintf("SRIO%d: Attempt to map address 0x%llx using 66bit addressing\n", srio_port, (ULL)base); 1481 return 0; 1482 } 1483 needed_subid.cn63xx.ba = (base>>34) & 0xffff; 1484 needed_subid.cn63xx.ba |= ((uint64_t)destid & 0xff) << (51-34); 1485 needed_s2m_type.s.iaow_sel = 2; 1486 } 1487 1488 /* Find a S2M_TYPE index to use. If this fails return 0 */ 1489 s2m_index = __cvmx_srio_alloc_s2m(srio_port, needed_s2m_type); 1490 if (s2m_index == -1) 1491 return 0; 1492 1493 /* Attach the SubID to the S2M_TYPE index */ 1494 needed_subid.s.rtype = s2m_index & 3; 1495 needed_subid.s.wtype = s2m_index & 3; 1496 needed_subid.cn63xx.ba |= (((uint64_t)s2m_index >> 2) & 1) << (50-34); 1497 needed_subid.cn63xx.ba |= (((uint64_t)s2m_index >> 3) & 1) << (59-34); 1498 1499 /* Allocate a SubID for use */ 1500 subdid = __cvmx_srio_alloc_subid(needed_subid); 1501 if (subdid == -1) 1502 { 1503 /* Free the s2m_index as we aren't using it */ 1504 __cvmx_srio_free_s2m(srio_port, s2m_index); 1505 return 0; 1506 } 1507 1508 /* Build the final core physical address */ 1509 sli_address.u64 = 0; 1510 sli_address.mem.io = 1; 1511 sli_address.mem.did = 3; 1512 sli_address.mem.subdid = subdid>>2; 1513 sli_address.mem.se = subdid & 3; 1514 sli_address.mem.address = base; /* Bits[33:0] of full address */ 1515 return sli_address.u64; 1516} 1517 1518 1519/** 1520 * Unmap a physical address window created by cvmx_srio_phys_map(). 1521 * 1522 * @param physical_address 1523 * Physical address returned by cvmx_srio_phys_map(). 1524 * @param size Size used on original call. 1525 * 1526 * @return Zero on success, negative on failure. 1527 */ 1528int cvmx_srio_physical_unmap(uint64_t physical_address, uint64_t size) 1529{ 1530 cvmx_sli_mem_access_subidx_t subid; 1531 int subdid = (physical_address >> 40) & 7; 1532 int extender = (physical_address >> 34) & 3; 1533 int mem_index = subdid * 4 + extender; 1534 int read_s2m_type; 1535 1536 /* Get the subid setup so we can figure out where this mapping was for */ 1537 subid.u64 = cvmx_read_csr(CVMX_PEXP_SLI_MEM_ACCESS_SUBIDX(mem_index)); 1538 /* Type[0] is mapped to the Relaxed Ordering 1539 Type[1] is mapped to the No Snoop 1540 Type[2] is mapped directly to bit 50 of the SLI address 1541 Type[3] is mapped directly to bit 59 of the SLI address */ 1542 read_s2m_type = ((subid.cn63xx.ba>>(50-34))&1<<2) | ((subid.cn63xx.ba>>(59-34))&1<<3); 1543 read_s2m_type |= subid.s.rtype; 1544 __cvmx_srio_free_subid(mem_index); 1545 __cvmx_srio_free_s2m(subid.s.port, read_s2m_type); 1546 return 0; 1547} 1548 1549#ifdef CVMX_ENABLE_PKO_FUNCTIONS 1550/** 1551 * fill out outbound message descriptor 1552 * 1553 * @param port pip/ipd port number 1554 * @param buf_ptr pointer to a buffer pointer. the buffer pointer points 1555 * to a chain of buffers that hold an outbound srio packet. 1556 * the packet can take the format of (1) a pip/ipd inbound 1557 * message or (2) an application-generated outbound message 1558 * @param desc_ptr pointer to an outbound message descriptor. should be null 1559 * if *buf_ptr is in the format (1) 1560 * 1561 * @return 0 on success; negative of failure. 1562 */ 1563int cvmx_srio_omsg_desc (uint64_t port, cvmx_buf_ptr_t *buf_ptr, 1564 cvmx_srio_tx_message_header_t *desc_ptr) 1565{ 1566 int ret_val = -1; 1567 int intf_num; 1568 cvmx_helper_interface_mode_t imode; 1569 1570 uint64_t *desc_addr, *hdr_addr; 1571 cvmx_srio_rx_message_header_t rx_msg_hdr; 1572 cvmx_srio_tx_message_header_t *tx_msg_hdr_ptr; 1573 1574 if (buf_ptr == NULL) 1575 return ret_val; 1576 1577 /* check if port is an srio port */ 1578 intf_num = cvmx_helper_get_interface_num (port); 1579 imode = cvmx_helper_interface_get_mode (intf_num); 1580 if (imode != CVMX_HELPER_INTERFACE_MODE_SRIO) 1581 return ret_val; 1582 1583 /* app-generated outbound message. descriptor space pre-allocated */ 1584 if (desc_ptr != NULL) 1585 { 1586 desc_addr = (uint64_t *) cvmx_phys_to_ptr ((*buf_ptr).s.addr); 1587 *desc_addr = *(uint64_t *) desc_ptr; 1588 ret_val = 0; 1589 return ret_val; 1590 } 1591 1592 /* pip/ipd inbound message. 16-byte srio message header is present */ 1593 hdr_addr = (uint64_t *) cvmx_phys_to_ptr ((*buf_ptr).s.addr); 1594 rx_msg_hdr.word0.u64 = *hdr_addr; 1595 1596 /* adjust buffer pointer to get rid of srio message header word 0 */ 1597 (*buf_ptr).s.addr += 8; 1598 (*buf_ptr).s.size -= 8; /* last buffer or not */ 1599 if ((*buf_ptr).s.addr >> 7 > ((*buf_ptr).s.addr - 8) >> 7) 1600 (*buf_ptr).s.back++; 1601 tx_msg_hdr_ptr = (cvmx_srio_tx_message_header_t *) 1602 cvmx_phys_to_ptr ((*buf_ptr).s.addr); 1603 1604 /* transfer values from rx to tx */ 1605 tx_msg_hdr_ptr->s.prio = rx_msg_hdr.word0.s.prio; 1606 tx_msg_hdr_ptr->s.tt = rx_msg_hdr.word0.s.tt; /* called id in hrm */ 1607 tx_msg_hdr_ptr->s.sis = rx_msg_hdr.word0.s.dis; 1608 tx_msg_hdr_ptr->s.ssize = rx_msg_hdr.word0.s.ssize; 1609 tx_msg_hdr_ptr->s.did = rx_msg_hdr.word0.s.sid; 1610 tx_msg_hdr_ptr->s.mbox = rx_msg_hdr.word0.s.mbox; 1611 1612 /* other values we have to decide */ 1613 tx_msg_hdr_ptr->s.xmbox = 0; /* multi-segement in general */ 1614 tx_msg_hdr_ptr->s.letter = 0; /* fake like traffic gen */ 1615 tx_msg_hdr_ptr->s.lns = 0; /* not use sriox_omsg_ctrly[] */ 1616 tx_msg_hdr_ptr->s.intr = 1; /* get status */ 1617 1618 ret_val = 0; 1619 return ret_val; 1620} 1621#endif 1622#endif 1623