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