cvmx-helper-spi.c revision 225736
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 * @file 46 * 47 * Functions for SPI initialization, configuration, 48 * and monitoring. 49 * 50 * <hr>$Revision: 49448 $<hr> 51 */ 52#ifdef CVMX_BUILD_FOR_LINUX_KERNEL 53#include <asm/octeon/cvmx.h> 54#include <asm/octeon/cvmx-config.h> 55#ifdef CVMX_ENABLE_PKO_FUNCTIONS 56#include <asm/octeon/cvmx-spi.h> 57#include <asm/octeon/cvmx-helper.h> 58#endif 59#include <asm/octeon/cvmx-pko-defs.h> 60#include <asm/octeon/cvmx-pip-defs.h> 61#else 62#if !defined(__FreeBSD__) || !defined(_KERNEL) 63#include "executive-config.h" 64#include "cvmx-config.h" 65#ifdef CVMX_ENABLE_PKO_FUNCTIONS 66 67#include "cvmx.h" 68#include "cvmx-spi.h" 69#include "cvmx-sysinfo.h" 70#include "cvmx-helper.h" 71#endif 72#else 73#include "cvmx.h" 74#include "cvmx-spi.h" 75#include "cvmx-sysinfo.h" 76#include "cvmx-helper.h" 77#endif 78#endif 79 80#ifdef CVMX_ENABLE_PKO_FUNCTIONS 81 82/* CVMX_HELPER_SPI_TIMEOUT is used to determine how long the SPI initialization 83 routines wait for SPI training. You can override the value using 84 executive-config.h if necessary */ 85#ifndef CVMX_HELPER_SPI_TIMEOUT 86#define CVMX_HELPER_SPI_TIMEOUT 10 87#endif 88 89 90/** 91 * @INTERNAL 92 * Probe a SPI interface and determine the number of ports 93 * connected to it. The SPI interface should still be down after 94 * this call. 95 * 96 * @param interface Interface to probe 97 * 98 * @return Number of ports on the interface. Zero to disable. 99 */ 100int __cvmx_helper_spi_probe(int interface) 101{ 102 int num_ports = 0; 103 104 if ((cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) && 105 cvmx_spi4000_is_present(interface)) 106 { 107 num_ports = 10; 108 } 109#if defined(OCTEON_VENDOR_LANNER) 110 else if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CUST_LANNER_MR955) 111 { 112 cvmx_pko_reg_crc_enable_t enable; 113 if (interface == 1) { 114 num_ports = 12; 115 } else { 116 /* XXX This is not entirely true. */ 117 num_ports = 0; 118 } 119 enable.u64 = cvmx_read_csr(CVMX_PKO_REG_CRC_ENABLE); 120 enable.s.enable &= 0xffff << (16 - (interface*16)); 121 cvmx_write_csr(CVMX_PKO_REG_CRC_ENABLE, enable.u64); 122 } 123#endif 124 else 125 { 126 cvmx_pko_reg_crc_enable_t enable; 127 num_ports = 16; 128 /* Unlike the SPI4000, most SPI devices don't automatically 129 put on the L2 CRC. For everything except for the SPI4000 130 have PKO append the L2 CRC to the packet */ 131 enable.u64 = cvmx_read_csr(CVMX_PKO_REG_CRC_ENABLE); 132 enable.s.enable |= 0xffff << (interface*16); 133 cvmx_write_csr(CVMX_PKO_REG_CRC_ENABLE, enable.u64); 134 } 135 __cvmx_helper_setup_gmx(interface, num_ports); 136 return num_ports; 137} 138 139 140/** 141 * @INTERNAL 142 * Bringup and enable a SPI interface. After this call packet I/O 143 * should be fully functional. This is called with IPD enabled but 144 * PKO disabled. 145 * 146 * @param interface Interface to bring up 147 * 148 * @return Zero on success, negative on failure 149 */ 150int __cvmx_helper_spi_enable(int interface) 151{ 152 /* Normally the ethernet L2 CRC is checked and stripped in the GMX block. 153 When you are using SPI, this isn' the case and IPD needs to check 154 the L2 CRC */ 155 int num_ports = cvmx_helper_ports_on_interface(interface); 156 int ipd_port; 157 for (ipd_port=interface*16; ipd_port<interface*16+num_ports; ipd_port++) 158 { 159 cvmx_pip_prt_cfgx_t port_config; 160 port_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port)); 161 port_config.s.crc_en = 1; 162 cvmx_write_csr(CVMX_PIP_PRT_CFGX(ipd_port), port_config.u64); 163 } 164 165 if (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) 166 { 167 cvmx_spi_start_interface(interface, CVMX_SPI_MODE_DUPLEX, CVMX_HELPER_SPI_TIMEOUT, num_ports); 168 if (cvmx_spi4000_is_present(interface)) 169 cvmx_spi4000_initialize(interface); 170 } 171 return 0; 172} 173 174/** 175 * @INTERNAL 176 * Return the link state of an IPD/PKO port as returned by 177 * auto negotiation. The result of this function may not match 178 * Octeon's link config if auto negotiation has changed since 179 * the last call to cvmx_helper_link_set(). 180 * 181 * @param ipd_port IPD/PKO port to query 182 * 183 * @return Link state 184 */ 185cvmx_helper_link_info_t __cvmx_helper_spi_link_get(int ipd_port) 186{ 187 cvmx_helper_link_info_t result; 188 int interface = cvmx_helper_get_interface_num(ipd_port); 189 int index = cvmx_helper_get_interface_index_num(ipd_port); 190 result.u64 = 0; 191 192 if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM) 193 { 194 /* The simulator gives you a simulated full duplex link */ 195 result.s.link_up = 1; 196 result.s.full_duplex = 1; 197 result.s.speed = 10000; 198 } 199 else if (cvmx_spi4000_is_present(interface)) 200 { 201 cvmx_gmxx_rxx_rx_inbnd_t inband = cvmx_spi4000_check_speed(interface, index); 202 result.s.link_up = inband.s.status; 203 result.s.full_duplex = inband.s.duplex; 204 switch (inband.s.speed) 205 { 206 case 0: /* 10 Mbps */ 207 result.s.speed = 10; 208 break; 209 case 1: /* 100 Mbps */ 210 result.s.speed = 100; 211 break; 212 case 2: /* 1 Gbps */ 213 result.s.speed = 1000; 214 break; 215 case 3: /* Illegal */ 216 result.s.speed = 0; 217 result.s.link_up = 0; 218 break; 219 } 220 } 221 else 222 { 223 /* For generic SPI we can't determine the link, just return some 224 sane results */ 225 result.s.link_up = 1; 226 result.s.full_duplex = 1; 227 result.s.speed = 10000; 228 } 229 return result; 230} 231 232 233/** 234 * @INTERNAL 235 * Configure an IPD/PKO port for the specified link state. This 236 * function does not influence auto negotiation at the PHY level. 237 * The passed link state must always match the link state returned 238 * by cvmx_helper_link_get(). It is normally best to use 239 * cvmx_helper_link_autoconf() instead. 240 * 241 * @param ipd_port IPD/PKO port to configure 242 * @param link_info The new link state 243 * 244 * @return Zero on success, negative on failure 245 */ 246int __cvmx_helper_spi_link_set(int ipd_port, cvmx_helper_link_info_t link_info) 247{ 248 /* Nothing to do. If we have a SPI4000 then the setup was already performed 249 by cvmx_spi4000_check_speed(). If not then there isn't any link 250 info */ 251 return 0; 252} 253 254#endif /* CVMX_ENABLE_PKO_FUNCTIONS */ 255 256