1 /***********************license start***************
2 * Copyright (c) 2003-2010 Cavium Inc. (support@cavium.com). All rights
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
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
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
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**************************************/
47 * <hr>$Revision: 41586 $<hr>
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>
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>
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"
74 #include "cvmx-helper-errata.h"
77 #include "cvmx-helper.h"
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
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 */
102 uint64_t address : 24;
103 uint64_t hopcount : 8;
104 uint64_t reserved_32_33 : 2;
106 uint64_t reserved_36_39 : 4;
110 uint64_t reserved_49_61 : 13;
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 */
126 uint64_t address : 34;
128 uint64_t reserved_36_39 : 4;
132 uint64_t reserved_49_61 : 13;
136 } cvmx_sli_address_t;
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;
145 static CVMX_SHARED __cvmx_srio_state_t __cvmx_srio_state[4];
148 #ifndef CVMX_BUILD_FOR_LINUX_HOST
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.
157 * @param srio_port SRIO port device is on
158 * @param s2m SRIOX_S2M_TYPEX setup required
160 * @return Index of CSR, or negative on failure
162 static int __cvmx_srio_alloc_s2m(int srio_port, cvmx_sriox_s2m_typex_t s2m)
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++)
169 /* Increment ref count by 2 since we count read and write
170 independently. We might need a more complicated search in the
172 int ref_count = cvmx_atomic_fetch_and_add32(&__cvmx_srio_state[srio_port].s2m_ref_count[s2m_index], 2);
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));
183 /* In use, see if we can use it */
184 if (cvmx_read_csr(CVMX_SRIOX_S2M_TYPEX(s2m_index, srio_port)) == s2m.u64)
187 cvmx_atomic_add32(&__cvmx_srio_state[srio_port].s2m_ref_count[s2m_index], -2);
190 cvmx_dprintf("SRIO%d: Unable to find free SRIOX_S2M_TYPEX\n", srio_port);
197 * Free a handle allocated by __cvmx_srio_alloc_s2m
199 * @param srio_port SRIO port
200 * @param index Index to free
202 static void __cvmx_srio_free_s2m(int srio_port, int index)
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);
212 * Allocate a SLI SubID to map a region of memory. Reference
213 * counting is used to allow sharing of duplicate setups.
215 * @param subid SLI_MEM_ACCESS_SUBIDX we need an index for
217 * @return Index of CSR, or negative on failure
219 static int __cvmx_srio_alloc_subid(cvmx_sli_mem_access_subidx_t subid)
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
225 for (mem_index=27; mem_index>=12; mem_index--)
227 int ref_count = cvmx_atomic_fetch_and_add32(&__cvmx_srio_state[0].subidx_ref_count[mem_index-12], 1);
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));
238 /* In use, see if we can use it */
239 if (cvmx_read_csr(CVMX_PEXP_SLI_MEM_ACCESS_SUBIDX(mem_index)) == subid.u64)
242 cvmx_atomic_add32(&__cvmx_srio_state[0].subidx_ref_count[mem_index-12], -1);
245 cvmx_dprintf("SRIO: Unable to find free SLI_MEM_ACCESS_SUBIDX\n");
252 * Free a handle allocated by __cvmx_srio_alloc_subid
254 * @param index Index to free
256 static void __cvmx_srio_free_subid(int index)
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);
267 * Read 32bits from a local port
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.
273 * @return Zero on success, negative on failure.
275 static int __cvmx_srio_local_read32(int srio_port, uint32_t offset, uint32_t *result)
277 cvmx_sriox_maint_op_t maint_op;
278 cvmx_sriox_maint_rd_data_t maint_rd_data;
280 maint_op.s.op = 0; /* Read */
281 maint_op.s.addr = offset;
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))
286 cvmx_dprintf("SRIO%d: Pending bit stuck before config read\n", srio_port);
290 /* Issue the read to the hardware */
291 cvmx_write_csr(CVMX_SRIOX_MAINT_OP(srio_port), maint_op.u64);
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))
296 cvmx_dprintf("SRIO%d: Config read timeout\n", srio_port);
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));
304 cvmx_dprintf("SRIO%d: Config read addressing error (offset=0x%x)\n", srio_port, (unsigned int)offset);
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))
311 cvmx_dprintf("SRIO%d: Config read data timeout\n", srio_port);
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;
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.
329 * @return Zero on success, negative on failure.
331 static int __cvmx_srio_local_write32(int srio_port, uint32_t offset, uint32_t data)
333 cvmx_sriox_maint_op_t maint_op;
335 maint_op.s.wr_data = data;
336 maint_op.s.op = 1; /* Write */
337 maint_op.s.addr = offset;
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))
342 cvmx_dprintf("SRIO%d: Pending bit stuck before config write\n", srio_port);
346 /* Issue the write to the hardware */
347 cvmx_write_csr(CVMX_SRIOX_MAINT_OP(srio_port), maint_op.u64);
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))
352 cvmx_dprintf("SRIO%d: Config write timeout\n", srio_port);
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));
360 cvmx_dprintf("SRIO%d: Config write addressing error (offset=0x%x)\n", srio_port, (unsigned int)offset);
368 * Reset SRIO to link partner
370 * @param srio_port SRIO port to initialize
372 * @return Zero on success
374 int cvmx_srio_link_rst(int srio_port)
376 cvmx_sriomaintx_port_0_link_resp_t link_resp;
378 if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X))
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))
386 if (cvmx_srio_config_read32(srio_port, 0, -1, 0, 0,
387 CVMX_SRIOMAINTX_PORT_0_LINK_RESP(srio_port), &link_resp.u32))
390 /* Poll until link partner has received the reset. */
391 while (link_resp.s.valid == 0)
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))
399 /* Valid response, Asserting MAC reset */
400 cvmx_write_csr(CVMX_CIU_SOFT_PRST, 0x1);
404 /* De-asserting MAC Reset */
405 cvmx_write_csr(CVMX_CIU_SOFT_PRST, 0x0);
411 * Initialize a SRIO port for use.
413 * @param srio_port SRIO port to initialize
414 * @param flags Optional flags
416 * @return Zero on success
418 int cvmx_srio_initialize(int srio_port, cvmx_srio_initialize_flags_t flags)
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;
433 sriox_status_reg.u64 = cvmx_read_csr(CVMX_SRIOX_STATUS_REG(srio_port));
434 if (OCTEON_IS_MODEL(OCTEON_CN66XX))
436 /* All SRIO ports are connected to QLM0 */
437 int status = cvmx_qlm_get_status(0);
438 if (status < 4 || status > 6)
440 cvmx_dprintf("SRIO%d: Initialization called on a port not in SRIO mode\n", srio_port);
444 else if (!sriox_status_reg.s.srio)
446 cvmx_dprintf("SRIO%d: Initialization called on a port not in SRIO mode\n", srio_port);
450 __cvmx_srio_state[srio_port].flags = flags;
452 /* CN63XX Pass 1.0 errata G-14395 requires the QLM De-emphasis be
454 if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_0))
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);
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);
476 /* Don't receive or drive reset signals for the SRIO QLM */
477 if (OCTEON_IS_MODEL(OCTEON_CN66XX))
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))
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);
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));
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);
500 mio_rst_ctl.u64 = cvmx_read_csr(CVMX_MIO_RST_CTLX(srio_port));
503 cvmx_dprintf("SRIO%d: Port in %s mode\n", srio_port,
504 (mio_rst_ctl.s.prtmode) ? "host" : "endpoint");
506 /* Bring the port out of reset if necessary */
511 cvmx_ciu_soft_prst_t prst;
512 prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST);
513 if (prst.s.soft_prst)
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))
525 cvmx_ciu_soft_prst1_t prst;
526 prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
527 if (prst.s.soft_prst)
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))
539 cvmx_ciu_soft_prst2_t prst;
540 prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST2);
541 if (prst.s.soft_prst)
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))
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))
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))
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))
568 cvmx_mio_rst_boot_t mio_rst_boot;
569 cvmx_sriomaintx_lane_x_status_0_t lane_x_status;
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))
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)
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 */
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 */
593 cvmx_write_csr(CVMX_CIU_QLM1, ciu_qlm.u64);
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)
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 */
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 */
612 cvmx_write_csr(CVMX_CIU_QLM0, ciu_qlm.u64);
616 /* Errata SRIO-14485: Link speed is reported incorrectly in CN63XX
618 if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X))
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))
623 if (port_0_ctl2.s.enb_500g)
626 port_0_ctl2.s.enb_625g = 1;
628 else if (port_0_ctl2.s.enb_312g)
631 port_0_ctl2.s.enb_500g = 1;
633 else if (port_0_ctl2.s.enb_250g)
636 port_0_ctl2.s.enb_312g = 1;
638 else if (port_0_ctl2.s.enb_125g)
641 port_0_ctl2.s.enb_250g = 1;
646 port_0_ctl2.s.enb_125g = 1;
648 if (__cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_PORT_0_CTL2(srio_port), port_0_ctl2.u32))
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))
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))
659 mac_ctrl.s.type_mrg = 0;
660 if (__cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_MAC_CTRL(srio_port), mac_ctrl.u32))
664 /* Set the link layer timeout to 1ms. The default is too high and causes
666 if (__cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_PORT_LT_CTL(srio_port), &port_lt_ctl.u32))
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))
672 /* Set the logical layer timeout to 100ms. The default is too high and causes
674 if (__cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_PORT_RT_CTL(srio_port), &port_rt_ctl.u32))
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))
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))
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))
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))
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))
695 /* Set the MRRS and MPS for optimal SRIO performance */
696 prt_cfg.u64 = cvmx_read_csr(CVMX_DPI_SLI_PRTX_CFG(srio_port));
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
704 cvmx_write_csr(CVMX_DPI_SLI_PRTX_CFG(srio_port), prt_cfg.u64);
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);
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);
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);
724 /* Setup RX messaging thresholds for other virtual ports. */
725 if (OCTEON_IS_MODEL(OCTEON_CN66XX))
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);
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))
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);
745 /* Errata SLI-15954: SLI relaxed order issues */
746 if (OCTEON_IS_MODEL(OCTEON_CN66XX_PASS1_X))
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);
757 if (!OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X))
759 /* Clear the ACK state */
760 if (__cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_PORT_0_LOCAL_ACKID(srio_port), 0))
764 /* Bring the link down, then up, by writing to the SRIO port's
766 if (__cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_PORT_0_CTL2(srio_port), &port_0_ctl2.u32))
768 if (__cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_PORT_0_CTL2(srio_port), port_0_ctl2.u32))
771 /* Clear any pending interrupts */
772 cvmx_write_csr(CVMX_SRIOX_INT_REG(srio_port), cvmx_read_csr(CVMX_SRIOX_INT_REG(srio_port)));
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);
779 /* Finally enable the link */
780 if (__cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_PORT_0_CTL(srio_port), &port_0_ctl.u32))
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))
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);
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 */
801 /* Ask for a link and align our ACK state. CN63XXp1 didn't support this */
802 if (!OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X))
805 cvmx_sriomaintx_port_0_err_stat_t sriomaintx_port_0_err_stat;
807 /* Clear the SLI_CTL_PORTX[DIS_PORT[ bit to re-enable traffic-flow
809 cvmx_write_csr(CVMX_PEXP_SLI_CTL_PORTX(srio_port), cvmx_read_csr(CVMX_PEXP_SLI_CTL_PORTX(srio_port)));
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);
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))
818 } while (!sriomaintx_port_0_err_stat.s.pt_ok && (cvmx_clock_get_count(CVMX_CLOCK_CORE) < stop_cycle));
820 /* Send link request if link is up */
821 if (sriomaintx_port_0_err_stat.s.pt_ok)
823 cvmx_sriomaintx_port_0_link_req_t link_req;
824 cvmx_sriomaintx_port_0_link_resp_t link_resp;
828 /* Send the request */
829 if (__cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_PORT_0_LINK_REQ(srio_port), link_req.u32))
832 /* Wait for the response */
833 stop_cycle = cvmx_clock_get_rate(CVMX_CLOCK_CORE)/8 + cvmx_clock_get_count(CVMX_CLOCK_CORE);
836 if (__cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_PORT_0_LINK_RESP(srio_port), &link_resp.u32))
838 } while (!link_resp.s.valid && (cvmx_clock_get_count(CVMX_CLOCK_CORE) < stop_cycle));
840 /* Set our ACK state if we got a response */
841 if (link_resp.s.valid)
843 cvmx_sriomaintx_port_0_local_ackid_t local_ackid;
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))
862 * Read 32bits from a Device's config space
864 * @param srio_port SRIO port the device is on
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.
874 * @return Zero on success, negative on failure.
876 int cvmx_srio_config_read32(int srio_port, int srcid_index, int destid,
877 int is16bit, uint8_t hopcount, uint32_t offset,
882 int status = __cvmx_srio_local_read32(srio_port, offset, result);
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);
891 if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X))
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);
903 /* Read the proper source ID */
905 __cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_SEC_DEV_ID(srio_port), &sourceid);
907 __cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_PRI_DEV_ID(srio_port), &sourceid);
911 /* Use the 16bit source ID */
914 /* MAINT Reads are 11 bytes */
915 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_CTRL(srio_port), 11<<16);
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);
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);
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);
936 /* Use the 8bit source ID */
937 sourceid = (sourceid >> 16) & 0xff;
939 /* MAINT Reads are 9 bytes */
940 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_CTRL(srio_port), 9<<16);
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);
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);
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);
960 stop_cycle = cvmx_clock_get_rate(CVMX_CLOCK_CORE)/10 + cvmx_clock_get_count(CVMX_CLOCK_CORE);
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))
966 if (__cvmx_srio_state[srio_port].flags & CVMX_SRIO_INITIALIZE_DEBUG)
967 cvmx_dprintf("timeout\n");
970 } while (return_code == 0);
972 if (return_code == ((is16bit) ? 23 : 19))
977 *result = *(uint32_t*)(rx_buffer + 15);
979 *result = *(uint32_t*)(rx_buffer + 11);
984 *result = *(uint32_t*)(rx_buffer + 13);
986 *result = *(uint32_t*)(rx_buffer + 9);
988 if (__cvmx_srio_state[srio_port].flags & CVMX_SRIO_INITIALIZE_DEBUG)
989 cvmx_dprintf("0x%08x\n", (unsigned int)*result);
994 *result = 0xffffffff;
1002 #if !defined(CVMX_BUILD_FOR_LINUX_HOST)
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);
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);
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);
1018 if (__cvmx_srio_state[srio_port].flags & CVMX_SRIO_INITIALIZE_DEBUG)
1019 cvmx_dprintf("0x%08x\n", (unsigned int)*result);
1028 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
1029 EXPORT_SYMBOL(cvmx_srio_config_read32);
1034 * Write 32bits to a Device's config space
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.
1046 * @return Zero on success, negative on failure.
1048 int cvmx_srio_config_write32(int srio_port, int srcid_index, int destid,
1049 int is16bit, uint8_t hopcount, uint32_t offset,
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);
1057 return __cvmx_srio_local_write32(srio_port, offset, data);
1061 if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X))
1066 uint64_t stop_cycle;
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);
1073 /* Read the proper source ID */
1075 __cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_SEC_DEV_ID(srio_port), &sourceid);
1077 __cvmx_srio_local_read32(srio_port, CVMX_SRIOMAINTX_PRI_DEV_ID(srio_port), &sourceid);
1081 /* Use the 16bit source ID */
1084 /* MAINT Writes are 19 bytes */
1085 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_CTRL(srio_port), 19<<16);
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);
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);
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);
1107 pkt = 0xff & (data >> 24);
1108 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_DATA(srio_port), pkt);
1110 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_DATA(srio_port), pkt);
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);
1121 /* Use the 8bit source ID */
1122 sourceid = (sourceid >> 16) & 0xff;
1124 /* MAINT Writes are 17 bytes */
1125 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_CTRL(srio_port), 17<<16);
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);
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);
1141 pkt |= offset << 24; /* offset [31:27, wdptr[26], reserved[25:24] */
1144 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_DATA(srio_port), pkt);
1146 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_DATA(srio_port), pkt);
1148 __cvmx_srio_local_write32(srio_port, CVMX_SRIOMAINTX_IR_SP_TX_DATA(srio_port), pkt);
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);
1160 stop_cycle = cvmx_clock_get_rate(CVMX_CLOCK_CORE)/10 + cvmx_clock_get_count(CVMX_CLOCK_CORE);
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))
1166 if (__cvmx_srio_state[srio_port].flags & CVMX_SRIO_INITIALIZE_DEBUG)
1167 cvmx_dprintf("timeout\n");
1170 } while (return_code == 0);
1172 if (return_code == ((is16bit) ? 15 : 11))
1176 cvmx_dprintf("SRIO%d: Remote write failed\n", srio_port);
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);
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);
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);
1207 * Send a RapidIO doorbell to a remote device
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.
1218 * @return Zero on success, negative on failure.
1220 int cvmx_srio_send_doorbell(int srio_port, int srcid_index, int destid, int is16bit, int priority, uint16_t data)
1222 cvmx_sriox_tx_bell_t tx_bell;
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;
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))
1233 cvmx_dprintf("SRIO%d: Pending bit stuck before doorbell\n", srio_port);
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);
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);
1246 #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
1247 EXPORT_SYMBOL(cvmx_srio_send_doorbell);
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).
1255 * @param srio_port SRIO port to check doorbell on
1257 * @return Doorbell status
1259 cvmx_srio_doorbell_status_t cvmx_srio_send_doorbell_status(int srio_port)
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;
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;
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);
1278 /* Check for errors */
1279 if (int_reg.s.bell_err)
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;
1292 /* Check if we're done */
1293 if (int_reg.s.txbell)
1294 return CVMX_SRIO_DOORBELL_DONE;
1296 /* No doorbell found */
1297 return CVMX_SRIO_DOORBELL_NONE;
1302 * Read a received doorbell and report data about it.
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)
1315 * @return Doorbell status. Either DONE, NONE, or ERROR.
1317 cvmx_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)
1321 cvmx_sriox_rx_bell_seq_t rx_bell_seq;
1322 cvmx_sriox_rx_bell_t rx_bell;
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;
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;
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);
1342 return CVMX_SRIO_DOORBELL_DONE;
1347 * Receive a packet from the Soft Packet FIFO (SPF).
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.
1354 * @return Returns the length of the packet read. Negative on failure.
1355 * Zero if no packets are available.
1357 int cvmx_srio_receive_spf(int srio_port, void *buffer, int buffer_length)
1359 uint32_t *ptr = (uint32_t *)buffer;
1360 cvmx_sriomaintx_ir_sp_rx_stat_t sriomaintx_ir_sp_rx_stat;
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))
1366 /* Return zero if there isn't a packet available */
1367 if (sriomaintx_ir_sp_rx_stat.s.buffers < 1)
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);
1373 /* Return error if the packet is larger than our buffer */
1374 if (sriomaintx_ir_sp_rx_stat.s.octets > buffer_length)
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)
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);
1388 if (__cvmx_srio_state[srio_port].flags & CVMX_SRIO_INITIALIZE_DEBUG)
1391 /* Return the number of bytes in the buffer */
1392 return sriomaintx_ir_sp_rx_stat.s.octets;
1395 #ifndef CVMX_BUILD_FOR_LINUX_HOST
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.
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
1418 * @return Octeon 64bit physical address that accesses the remote device,
1419 * or zero on failure.
1421 uint64_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)
1425 cvmx_sriox_s2m_typex_t needed_s2m_type;
1426 cvmx_sli_mem_access_subidx_t needed_subid;
1429 cvmx_sli_address_t sli_address;
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))
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);
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;
1450 /* Build the needed SubID config */
1451 needed_subid.u64 = 0;
1452 needed_subid.s.port = srio_port;
1453 needed_subid.s.nmerge = 0;
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))
1461 needed_subid.cn63xx.ba = destid;
1462 needed_s2m_type.s.iaow_sel = 0;
1464 else if (base < (1ull<<42))
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;
1475 cvmx_dprintf("SRIO%d: Attempt to map 16bit device ID 0x%x using 66bit addressing\n", srio_port, destid);
1480 cvmx_dprintf("SRIO%d: Attempt to map address 0x%llx using 66bit addressing\n", srio_port, (ULL)base);
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;
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)
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);
1499 /* Allocate a SubID for use */
1500 subdid = __cvmx_srio_alloc_subid(needed_subid);
1503 /* Free the s2m_index as we aren't using it */
1504 __cvmx_srio_free_s2m(srio_port, s2m_index);
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;
1520 * Unmap a physical address window created by cvmx_srio_phys_map().
1522 * @param physical_address
1523 * Physical address returned by cvmx_srio_phys_map().
1524 * @param size Size used on original call.
1526 * @return Zero on success, negative on failure.
1528 int cvmx_srio_physical_unmap(uint64_t physical_address, uint64_t size)
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;
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);
1549 #ifdef CVMX_ENABLE_PKO_FUNCTIONS
1551 * fill out outbound message descriptor
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)
1561 * @return 0 on success; negative of failure.
1563 int cvmx_srio_omsg_desc (uint64_t port, cvmx_buf_ptr_t *buf_ptr,
1564 cvmx_srio_tx_message_header_t *desc_ptr)
1568 cvmx_helper_interface_mode_t imode;
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;
1574 if (buf_ptr == NULL)
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)
1583 /* app-generated outbound message. descriptor space pre-allocated */
1584 if (desc_ptr != NULL)
1586 desc_addr = (uint64_t *) cvmx_phys_to_ptr ((*buf_ptr).s.addr);
1587 *desc_addr = *(uint64_t *) desc_ptr;
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;
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);
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;
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 */