cvmx-helper-spi.c revision 210284
1/***********************license start*************** 2 * Copyright (c) 2003-2008 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 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" 24 * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS 25 * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH 26 * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY 27 * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT 28 * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES 29 * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR 30 * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET 31 * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT 32 * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. 33 * 34 * 35 * For any questions regarding licensing please contact marketing@caviumnetworks.com 36 * 37 ***********************license end**************************************/ 38 39 40 41 42 43 44/** 45 * @file 46 * 47 * Functions for SPI initialization, configuration, 48 * and monitoring. 49 * 50 * <hr>$Revision: 42417 $<hr> 51 */ 52#include "executive-config.h" 53#include "cvmx-config.h" 54#ifdef CVMX_ENABLE_PKO_FUNCTIONS 55 56#include "cvmx.h" 57#include "cvmx-spi.h" 58#include "cvmx-sysinfo.h" 59#include "cvmx-helper.h" 60 61/* CVMX_HELPER_SPI_TIMEOUT is used to determine how long the SPI initialization 62 routines wait for SPI training. You can override the value using 63 executive-config.h if necessary */ 64#ifndef CVMX_HELPER_SPI_TIMEOUT 65#define CVMX_HELPER_SPI_TIMEOUT 10 66#endif 67 68 69/** 70 * @INTERNAL 71 * Probe a SPI interface and determine the number of ports 72 * connected to it. The SPI interface should still be down after 73 * this call. 74 * 75 * @param interface Interface to probe 76 * 77 * @return Number of ports on the interface. Zero to disable. 78 */ 79int __cvmx_helper_spi_probe(int interface) 80{ 81 int num_ports = 0; 82 83 if ((cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) && 84 cvmx_spi4000_is_present(interface)) 85 { 86 num_ports = 10; 87 } 88 else 89 { 90 cvmx_pko_reg_crc_enable_t enable; 91 num_ports = 16; 92 /* Unlike the SPI4000, most SPI devices don't automatically 93 put on the L2 CRC. For everything except for the SPI4000 94 have PKO append the L2 CRC to the packet */ 95 enable.u64 = cvmx_read_csr(CVMX_PKO_REG_CRC_ENABLE); 96 enable.s.enable |= 0xffff << (interface*16); 97 cvmx_write_csr(CVMX_PKO_REG_CRC_ENABLE, enable.u64); 98 } 99 __cvmx_helper_setup_gmx(interface, num_ports); 100 return num_ports; 101} 102 103 104/** 105 * @INTERNAL 106 * Bringup and enable a SPI interface. After this call packet I/O 107 * should be fully functional. This is called with IPD enabled but 108 * PKO disabled. 109 * 110 * @param interface Interface to bring up 111 * 112 * @return Zero on success, negative on failure 113 */ 114int __cvmx_helper_spi_enable(int interface) 115{ 116 /* Normally the ethernet L2 CRC is checked and stripped in the GMX block. 117 When you are using SPI, this isn' the case and IPD needs to check 118 the L2 CRC */ 119 int num_ports = cvmx_helper_ports_on_interface(interface); 120 int ipd_port; 121 for (ipd_port=interface*16; ipd_port<interface*16+num_ports; ipd_port++) 122 { 123 cvmx_pip_port_cfg_t port_config; 124 port_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port)); 125 port_config.s.crc_en = 1; 126 cvmx_write_csr(CVMX_PIP_PRT_CFGX(ipd_port), port_config.u64); 127 } 128 129 if (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) 130 { 131 cvmx_spi_start_interface(interface, CVMX_SPI_MODE_DUPLEX, CVMX_HELPER_SPI_TIMEOUT, num_ports); 132 if (cvmx_spi4000_is_present(interface)) 133 cvmx_spi4000_initialize(interface); 134 } 135 return 0; 136} 137 138/** 139 * @INTERNAL 140 * Return the link state of an IPD/PKO port as returned by 141 * auto negotiation. The result of this function may not match 142 * Octeon's link config if auto negotiation has changed since 143 * the last call to cvmx_helper_link_set(). 144 * 145 * @param ipd_port IPD/PKO port to query 146 * 147 * @return Link state 148 */ 149cvmx_helper_link_info_t __cvmx_helper_spi_link_get(int ipd_port) 150{ 151 cvmx_helper_link_info_t result; 152 int interface = cvmx_helper_get_interface_num(ipd_port); 153 int index = cvmx_helper_get_interface_index_num(ipd_port); 154 result.u64 = 0; 155 156 if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM) 157 { 158 /* The simulator gives you a simulated full duplex link */ 159 result.s.link_up = 1; 160 result.s.full_duplex = 1; 161 result.s.speed = 10000; 162 } 163 else if (cvmx_spi4000_is_present(interface)) 164 { 165 cvmx_gmxx_rxx_rx_inbnd_t inband = cvmx_spi4000_check_speed(interface, index); 166 result.s.link_up = inband.s.status; 167 result.s.full_duplex = inband.s.duplex; 168 switch (inband.s.speed) 169 { 170 case 0: /* 10 Mbps */ 171 result.s.speed = 10; 172 break; 173 case 1: /* 100 Mbps */ 174 result.s.speed = 100; 175 break; 176 case 2: /* 1 Gbps */ 177 result.s.speed = 1000; 178 break; 179 case 3: /* Illegal */ 180 result.s.speed = 0; 181 result.s.link_up = 0; 182 break; 183 } 184 } 185 else 186 { 187 /* For generic SPI we can't determine the link, just return some 188 sane results */ 189 result.s.link_up = 1; 190 result.s.full_duplex = 1; 191 result.s.speed = 10000; 192 } 193 return result; 194} 195 196 197/** 198 * @INTERNAL 199 * Configure an IPD/PKO port for the specified link state. This 200 * function does not influence auto negotiation at the PHY level. 201 * The passed link state must always match the link state returned 202 * by cvmx_helper_link_get(). It is normally best to use 203 * cvmx_helper_link_autoconf() instead. 204 * 205 * @param ipd_port IPD/PKO port to configure 206 * @param link_info The new link state 207 * 208 * @return Zero on success, negative on failure 209 */ 210int __cvmx_helper_spi_link_set(int ipd_port, cvmx_helper_link_info_t link_info) 211{ 212 /* Nothing to do. If we have a SPI4000 then the setup was already performed 213 by cvmx_spi4000_check_speed(). If not then there isn't any link 214 info */ 215 return 0; 216} 217 218#endif /* CVMX_ENABLE_PKO_FUNCTIONS */ 219 220