2 /******************************************************************************
\r
4 * alt_bridge_manager.c - API for the Altera SoC FPGA bridge manager.
\r
6 ******************************************************************************/
\r
8 /******************************************************************************
\r
10 * Copyright 2013 Altera Corporation. All Rights Reserved.
\r
12 * Redistribution and use in source and binary forms, with or without
\r
13 * modification, are permitted provided that the following conditions are met:
\r
15 * 1. Redistributions of source code must retain the above copyright notice,
\r
16 * this list of conditions and the following disclaimer.
\r
18 * 2. Redistributions in binary form must reproduce the above copyright notice,
\r
19 * this list of conditions and the following disclaimer in the documentation
\r
20 * and/or other materials provided with the distribution.
\r
22 * 3. The name of the author may not be used to endorse or promote products
\r
23 * derived from this software without specific prior written permission.
\r
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR
\r
26 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
\r
27 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO
\r
28 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
\r
29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
\r
30 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
\r
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
\r
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
\r
33 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
\r
36 ******************************************************************************/
\r
39 #include "alt_bridge_manager.h"
\r
40 #include "alt_clock_manager.h"
\r
41 #include "alt_fpga_manager.h"
\r
42 #include "socal/hps.h"
\r
43 #include "socal/socal.h"
\r
44 #include "socal/alt_rstmgr.h"
\r
47 /******************************************************************************/
\r
48 ALT_STATUS_CODE alt_bridge_init(ALT_BRIDGE_t bridge,
\r
49 alt_bridge_fpga_is_ready_t fpga_is_ready,
\r
52 uint32_t bridge_reset_mask = 0;
\r
54 // Validate the bridge parameter and set the appropriate bridge reset mask.
\r
55 if (bridge == ALT_BRIDGE_LWH2F)
\r
57 bridge_reset_mask = ALT_RSTMGR_BRGMODRST_LWH2F_SET_MSK;
\r
59 else if (bridge == ALT_BRIDGE_H2F)
\r
61 bridge_reset_mask = ALT_RSTMGR_BRGMODRST_H2F_SET_MSK;
\r
63 else if (bridge == ALT_BRIDGE_F2H)
\r
65 bridge_reset_mask = ALT_RSTMGR_BRGMODRST_F2H_SET_MSK;
\r
69 // Invalid bridge argument specified.
\r
70 return ALT_E_BAD_ARG;
\r
73 // Place and hold the specified bridge in reset.
\r
74 alt_setbits_word(ALT_RSTMGR_BRGMODRST_ADDR, bridge_reset_mask);
\r
76 // Validate that bridge clock(s) are configured and stable. Perform the
\r
77 // clock checks prior other validations that might depend on clocks being
\r
78 // checked (e.g. FPGA manager dependency on ALT_CLK_L4_MP).
\r
80 // l4_mp_clk is required for all bridges.
\r
81 if (alt_clk_is_enabled(ALT_CLK_L4_MP) != ALT_E_TRUE)
\r
83 return ALT_E_BAD_CLK;
\r
86 // Although a stable l3_main_clk is required for H2F and F2H bridges, the
\r
87 // l3_main_clk is not gated and it runs directly from the Main PLL C1 output
\r
88 // so if this code is executing it effectively means that this clock is stable
\r
89 // and hence there are no meaningful validation checks that software can perform
\r
90 // on the ALT_CLK_L3_MAIN.
\r
92 // lws2f_axi_clk is required for LWH2F bridge and clocks all LWH2F AXI transactions.
\r
93 // s2f_axi_clk is required for H2F bridge and clocks all H2F AXI transactions.
\r
94 // f2s_axi_clk is required for F2H bridge and clocks all F2H AXI transactions.
\r
96 // NOTE: All of these clocks are sourced from the FPGA and provided to the HPS.
\r
97 // The FPGA must be configured to drive these clocks. Beyond checking that
\r
98 // the FPGA is configured, there are no HPS control and status mechanisms
\r
99 // available to check the operational status of these clocks.
\r
101 // Check that FPGA is powered on.
\r
102 ALT_FPGA_STATE_t fpga_state = alt_fpga_state_get();
\r
103 if (fpga_state == ALT_FPGA_STATE_POWER_OFF)
\r
105 return ALT_E_FPGA_PWR_OFF;
\r
108 // Check that FPGA has been configured and is in USER mode.
\r
109 if (fpga_state != ALT_FPGA_STATE_USER_MODE)
\r
111 return ALT_E_FPGA_NOT_USER_MODE;
\r
114 // If specified, invoke user defined callback function to determine whether the
\r
115 // FPGA is ready to commence bridge interface transactions. If no user defined
\r
116 // callback function is specified then proceed on the assumption that the FPGA
\r
117 // is ready to commence bridge transactions.
\r
118 if (fpga_is_ready != NULL)
\r
120 ALT_STATUS_CODE fpga_ready_status = fpga_is_ready(user_arg);
\r
121 if (fpga_ready_status != ALT_E_SUCCESS)
\r
123 // Return the value of the non successful status code as returned from
\r
124 // the user defined callback function.
\r
125 return fpga_ready_status;
\r
129 // Release the bridge from reset.
\r
130 alt_clrbits_word(ALT_RSTMGR_BRGMODRST_ADDR, bridge_reset_mask);
\r
132 return ALT_E_SUCCESS;
\r
135 /******************************************************************************/
\r
136 ALT_STATUS_CODE alt_bridge_uninit(ALT_BRIDGE_t bridge,
\r
137 alt_bridge_teardown_handshake_t handshake,
\r
140 uint32_t bridge_reset_mask = 0;
\r
142 // Validate the bridge parameter and set the appropriate bridge reset mask.
\r
143 if (bridge == ALT_BRIDGE_LWH2F)
\r
145 bridge_reset_mask = ALT_RSTMGR_BRGMODRST_LWH2F_SET_MSK;
\r
147 else if (bridge == ALT_BRIDGE_H2F)
\r
149 bridge_reset_mask = ALT_RSTMGR_BRGMODRST_H2F_SET_MSK;
\r
151 else if (bridge == ALT_BRIDGE_F2H)
\r
153 bridge_reset_mask = ALT_RSTMGR_BRGMODRST_F2H_SET_MSK;
\r
157 // Invalid bridge argument specified.
\r
158 return ALT_E_BAD_ARG;
\r
161 if ((alt_read_word(ALT_RSTMGR_BRGMODRST_ADDR) & bridge_reset_mask) == bridge_reset_mask)
\r
163 // The bridge is already in reset and therefore considered uninitialized.
\r
164 return ALT_E_SUCCESS;
\r
167 // If specified, invoke user defined callback function to perform the tear-down
\r
168 // handshake notification protocol with the FPGA. If no user defined callback
\r
169 // function is specified then proceed without performing any tear-down handshake
\r
170 // notification protocol with the FPGA.
\r
171 if (handshake != NULL)
\r
173 ALT_STATUS_CODE handshake_status = handshake(user_arg);
\r
174 if (handshake_status != ALT_E_SUCCESS)
\r
176 // Return the value of the non successful status code as returned from
\r
177 // the user defined callback function.
\r
178 return handshake_status;
\r
182 // Place and hold the bridge in reset.
\r
183 alt_setbits_word(ALT_RSTMGR_BRGMODRST_ADDR, bridge_reset_mask);
\r
185 return ALT_E_SUCCESS;
\r
188 /******************************************************************************/
\r