]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/contrib/octeon-sdk/cvmx-helper-spi.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / contrib / octeon-sdk / cvmx-helper-spi.c
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  */
100 int __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  */
150 int __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  */
185 cvmx_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  */
246 int __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