cvmx-helper-srio.c revision 215976
1/***********************license start*************** 2 * Copyright (c) 2003-2010 Cavium Networks (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 Networks 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 NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR 30 * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO 31 * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR 32 * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM 33 * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE, 34 * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF 35 * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR 36 * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR 37 * PERFORMANCE OF THE SOFTWARE LIES WITH YOU. 38 ***********************license end**************************************/ 39 40 41 42 43 44 45 46/** 47 * @file 48 * 49 * Functions for SRIO initialization, configuration, 50 * and monitoring. 51 * 52 * <hr>$Revision: 41586 $<hr> 53 */ 54#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 55#include <asm/octeon/cvmx.h> 56#include <asm/octeon/cvmx-config.h> 57#include <asm/octeon/cvmx-clock.h> 58#include <asm/octeon/cvmx-helper.h> 59#include <asm/octeon/cvmx-srio.h> 60#include <asm/octeon/cvmx-pip-defs.h> 61#include <asm/octeon/cvmx-sriox-defs.h> 62#include <asm/octeon/cvmx-sriomaintx-defs.h> 63#include <asm/octeon/cvmx-dpi-defs.h> 64#else 65#include "executive-config.h" 66#include "cvmx-config.h" 67#ifdef CVMX_ENABLE_PKO_FUNCTIONS 68 69#include "cvmx.h" 70#include "cvmx-helper.h" 71#include "cvmx-srio.h" 72#endif 73#endif 74 75#ifdef CVMX_ENABLE_PKO_FUNCTIONS 76 77/** 78 * @INTERNAL 79 * Probe a SRIO interface and determine the number of ports 80 * connected to it. The SRIO interface should still be down 81 * after this call. 82 * 83 * @param interface Interface to probe 84 * 85 * @return Number of ports on the interface. Zero to disable. 86 */ 87int __cvmx_helper_srio_probe(int interface) 88{ 89 cvmx_sriox_status_reg_t srio0_status_reg; 90 cvmx_sriox_status_reg_t srio1_status_reg; 91 92 if (!OCTEON_IS_MODEL(OCTEON_CN63XX)) 93 return 0; 94 95 srio0_status_reg.u64 = cvmx_read_csr(CVMX_SRIOX_STATUS_REG(0)); 96 srio1_status_reg.u64 = cvmx_read_csr(CVMX_SRIOX_STATUS_REG(1)); 97 if (srio0_status_reg.s.srio || srio1_status_reg.s.srio) 98 return 2; 99 else 100 return 0; 101} 102 103 104/** 105 * @INTERNAL 106 * Bringup and enable SRIO interface. After this call packet 107 * I/O should be fully functional. This is called with IPD 108 * enabled but PKO disabled. 109 * 110 * @param interface Interface to bring up 111 * 112 * @return Zero on success, negative on failure 113 */ 114int __cvmx_helper_srio_enable(int interface) 115{ 116 int num_ports = cvmx_helper_ports_on_interface(interface); 117 int index; 118 cvmx_sriomaintx_core_enables_t sriomaintx_core_enables; 119 cvmx_sriox_imsg_ctrl_t sriox_imsg_ctrl; 120 cvmx_dpi_ctl_t dpi_ctl; 121 122 /* All SRIO ports have a cvmx_srio_rx_message_header_t header 123 on them that must be skipped by IPD */ 124 for (index=0; index<num_ports; index++) 125 { 126 cvmx_pip_prt_cfgx_t port_config; 127 cvmx_sriox_omsg_portx_t sriox_omsg_portx; 128 cvmx_sriox_omsg_sp_mrx_t sriox_omsg_sp_mrx; 129 cvmx_sriox_omsg_fmp_mrx_t sriox_omsg_fmp_mrx; 130 cvmx_sriox_omsg_nmp_mrx_t sriox_omsg_nmp_mrx; 131 int ipd_port = cvmx_helper_get_ipd_port(interface, index); 132 port_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port)); 133 /* Only change the skip if the user hasn't already set it */ 134 if (!port_config.s.skip) 135 { 136 port_config.s.skip = sizeof(cvmx_srio_rx_message_header_t); 137 cvmx_write_csr(CVMX_PIP_PRT_CFGX(ipd_port), port_config.u64); 138 } 139 140 /* Enable TX with PKO */ 141 sriox_omsg_portx.u64 = cvmx_read_csr(CVMX_SRIOX_OMSG_PORTX(index, interface - 4)); 142 sriox_omsg_portx.s.port = (interface - 4) * 2 + index; 143 sriox_omsg_portx.s.enable = 1; 144 cvmx_write_csr(CVMX_SRIOX_OMSG_PORTX(index, interface - 4), sriox_omsg_portx.u64); 145 146 /* Allow OMSG controller to send regardless of the state of any other 147 controller. Allow messages to different IDs and MBOXes to go in 148 parallel */ 149 sriox_omsg_sp_mrx.u64 = 0; 150 sriox_omsg_sp_mrx.s.xmbox_sp = 1; 151 sriox_omsg_sp_mrx.s.ctlr_sp = 1; 152 sriox_omsg_sp_mrx.s.ctlr_fmp = 1; 153 sriox_omsg_sp_mrx.s.ctlr_nmp = 1; 154 sriox_omsg_sp_mrx.s.id_sp = 1; 155 sriox_omsg_sp_mrx.s.id_fmp = 1; 156 sriox_omsg_sp_mrx.s.id_nmp = 1; 157 sriox_omsg_sp_mrx.s.mbox_sp = 1; 158 sriox_omsg_sp_mrx.s.mbox_fmp = 1; 159 sriox_omsg_sp_mrx.s.mbox_nmp = 1; 160 sriox_omsg_sp_mrx.s.all_psd = 1; 161 cvmx_write_csr(CVMX_SRIOX_OMSG_SP_MRX(index, interface-4), sriox_omsg_sp_mrx.u64); 162 163 /* Allow OMSG controller to send regardless of the state of any other 164 controller. Allow messages to different IDs and MBOXes to go in 165 parallel */ 166 sriox_omsg_fmp_mrx.u64 = 0; 167 sriox_omsg_fmp_mrx.s.ctlr_sp = 1; 168 sriox_omsg_fmp_mrx.s.ctlr_fmp = 1; 169 sriox_omsg_fmp_mrx.s.ctlr_nmp = 1; 170 sriox_omsg_fmp_mrx.s.id_sp = 1; 171 sriox_omsg_fmp_mrx.s.id_fmp = 1; 172 sriox_omsg_fmp_mrx.s.id_nmp = 1; 173 sriox_omsg_fmp_mrx.s.mbox_sp = 1; 174 sriox_omsg_fmp_mrx.s.mbox_fmp = 1; 175 sriox_omsg_fmp_mrx.s.mbox_nmp = 1; 176 sriox_omsg_fmp_mrx.s.all_psd = 1; 177 cvmx_write_csr(CVMX_SRIOX_OMSG_FMP_MRX(index, interface-4), sriox_omsg_fmp_mrx.u64); 178 179 /* Once the first part of a message is accepted, always acept the rest 180 of the message */ 181 sriox_omsg_nmp_mrx.u64 = 0; 182 sriox_omsg_nmp_mrx.s.all_sp = 1; 183 sriox_omsg_nmp_mrx.s.all_fmp = 1; 184 sriox_omsg_nmp_mrx.s.all_nmp = 1; 185 cvmx_write_csr(CVMX_SRIOX_OMSG_NMP_MRX(index, interface-4), sriox_omsg_nmp_mrx.u64); 186 187 } 188 189 /* Choose the receive controller based on the mailbox */ 190 sriox_imsg_ctrl.u64 = cvmx_read_csr(CVMX_SRIOX_IMSG_CTRL(interface - 4)); 191 sriox_imsg_ctrl.s.prt_sel = 0; 192 sriox_imsg_ctrl.s.mbox = 0xa; 193 cvmx_write_csr(CVMX_SRIOX_IMSG_CTRL(interface - 4), sriox_imsg_ctrl.u64); 194 195 /* DPI must be enabled for us to RX messages */ 196 dpi_ctl.u64 = cvmx_read_csr(CVMX_DPI_CTL); 197 dpi_ctl.s.clk = 1; 198 dpi_ctl.s.en = 1; 199 cvmx_write_csr(CVMX_DPI_CTL, dpi_ctl.u64); 200 201 /* Enable RX */ 202 if (!cvmx_srio_config_read32(interface - 4, 0, -1, 0, 0, 203 CVMX_SRIOMAINTX_CORE_ENABLES(interface-4), &sriomaintx_core_enables.u32)) 204 { 205 sriomaintx_core_enables.s.imsg0 = 1; 206 sriomaintx_core_enables.s.imsg1 = 1; 207 cvmx_srio_config_write32(interface - 4, 0, -1, 0, 0, 208 CVMX_SRIOMAINTX_CORE_ENABLES(interface-4), sriomaintx_core_enables.u32); 209 } 210 211 return 0; 212} 213 214/** 215 * @INTERNAL 216 * Return the link state of an IPD/PKO port as returned by SRIO link status. 217 * 218 * @param ipd_port IPD/PKO port to query 219 * 220 * @return Link state 221 */ 222cvmx_helper_link_info_t __cvmx_helper_srio_link_get(int ipd_port) 223{ 224 int interface = cvmx_helper_get_interface_num(ipd_port); 225 int srio_port = interface - 4; 226 cvmx_helper_link_info_t result; 227 cvmx_sriox_status_reg_t srio_status_reg; 228 cvmx_sriomaintx_port_0_err_stat_t sriomaintx_port_0_err_stat; 229 cvmx_sriomaintx_port_0_ctl_t sriomaintx_port_0_ctl; 230 cvmx_sriomaintx_port_0_ctl2_t sriomaintx_port_0_ctl2; 231 232 result.u64 = 0; 233 234 /* Make sure register access is allowed */ 235 srio_status_reg.u64 = cvmx_read_csr(CVMX_SRIOX_STATUS_REG(srio_port)); 236 if (!srio_status_reg.s.access) 237 return result; 238 239 /* Read the port link status */ 240 if (cvmx_srio_config_read32(srio_port, 0, -1, 0, 0, 241 CVMX_SRIOMAINTX_PORT_0_ERR_STAT(srio_port), 242 &sriomaintx_port_0_err_stat.u32)) 243 return result; 244 245 /* Return if link is down */ 246 if (!sriomaintx_port_0_err_stat.s.pt_ok) 247 return result; 248 249 /* Read the port link width and speed */ 250 if (cvmx_srio_config_read32(srio_port, 0, -1, 0, 0, 251 CVMX_SRIOMAINTX_PORT_0_CTL(srio_port), 252 &sriomaintx_port_0_ctl.u32)) 253 return result; 254 if (cvmx_srio_config_read32(srio_port, 0, -1, 0, 0, 255 CVMX_SRIOMAINTX_PORT_0_CTL2(srio_port), 256 &sriomaintx_port_0_ctl2.u32)) 257 return result; 258 259 /* Link is up */ 260 result.s.full_duplex = 1; 261 result.s.link_up = 1; 262 switch (sriomaintx_port_0_ctl2.s.sel_baud) 263 { 264 case 1: 265 result.s.speed = 1250; 266 break; 267 case 2: 268 result.s.speed = 2500; 269 break; 270 case 3: 271 result.s.speed = 3125; 272 break; 273 case 4: 274 result.s.speed = 5000; 275 break; 276 case 5: 277 result.s.speed = 6250; 278 break; 279 default: 280 result.s.speed = 0; 281 break; 282 } 283 switch (sriomaintx_port_0_ctl.s.it_width) 284 { 285 case 2: /* Four lanes */ 286 result.s.speed += 40000; 287 break; 288 case 3: /* Two lanes */ 289 result.s.speed += 20000; 290 break; 291 default: /* One lane */ 292 result.s.speed += 10000; 293 break; 294 } 295 return result; 296} 297 298/** 299 * @INTERNAL 300 * Configure an IPD/PKO port for the specified link state. This 301 * function does not influence auto negotiation at the PHY level. 302 * The passed link state must always match the link state returned 303 * by cvmx_helper_link_get(). It is normally best to use 304 * cvmx_helper_link_autoconf() instead. 305 * 306 * @param ipd_port IPD/PKO port to configure 307 * @param link_info The new link state 308 * 309 * @return Zero on success, negative on failure 310 */ 311int __cvmx_helper_srio_link_set(int ipd_port, cvmx_helper_link_info_t link_info) 312{ 313 return 0; 314} 315 316#endif /* CVMX_ENABLE_PKO_FUNCTIONS */ 317 318