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