1 /*******************************************************************************
2 * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 * MPFS HAL Embedded Software
7 *
8 */
9 /*******************************************************************************
10 * @file mss_axiswitch.c
11 * @author Microchip-FPGA Embedded Systems Solutions
12 * @brief PolarFire SoC MSS AXI switch configuration
13 *
14 */
15
16 #include <stddef.h>
17 #include <stdint.h>
18 #include "mpfs_hal/mss_hal.h"
19
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23
24 /*Returns the value of AXI_HW_CFG_REG register*/
MSS_AXISW_get_hwcfg(void)25 uint32_t MSS_AXISW_get_hwcfg(void)
26 {
27 return (AXISW->HWCFG);
28 }
29
30 /*Returns the value of AXI_VERSION_ID_REG register*/
MSS_AXISW_get_vid(void)31 uint32_t MSS_AXISW_get_vid(void)
32 {
33 return (AXISW->VID);
34 }
35
36 /*Performs write operation on the AXI SWITCH APB interface,
37 * Parameters:
38 * master_port_num = AXI Master Port number. See Enum mss_axisw_mport_t above.
39
40
41 Note: QoS values are programmable through registers only for AXI3 configurations.
42 We have AXI4 so the QoS value programming should not be attempted.
43 IF you try to write/read QoS value you will get return value =1 (AXI_ERR_BIT)
44
45 Burstiness peak rate and transaction rate can be configured using other APIs.
46
47 data: QoS value to be programmed
48 return value: As received form AXI_ERR_BIT in CMD register.
49
50 * */
MSS_AXISW_write_qos_val(mss_axisw_mport_t master_port_num,uint32_t data)51 uint32_t MSS_AXISW_write_qos_val(mss_axisw_mport_t master_port_num,
52 uint32_t data)
53 {
54 while(AXISW->CMD & AXISW_CMD_EN_MASK); /*make sure previous command completed*/
55
56 AXISW->DATA = data & AXISW_DATA_QOSVAL_MASK; /*only valid values of bits[3:0]*/
57
58 AXISW->CMD = (AXISW_CMD_RW_MASK |
59 (master_port_num << AXISW_CMD_RWCHAN) |
60 MSS_AXISW_QOS_VAL |
61 AXISW_CMD_EN_MASK);
62
63 while(AXISW->CMD & AXISW_CMD_EN_MASK); /*Wait for command to complete*/
64
65 return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
66 }
67
68 /*Performs read operation on the AXI SWITCH APB interface,
69 * Parameters:
70 * master_port_num = AXI Master Port number. See Enum mss_axisw_mport_t above.
71 *
72 * Note: QoS values are programmable through registers only for AXI3 configurations.
73 We have AXI4 so the QoS value programming should not be attempted.
74 IF you try to write/read QoS value you will get return value =1 (AXI_ERR_BIT)
75 *
76 * returns the data returned by AXI SWITCH read operation for QoS command
77 *
78 * return value: As received form AXI_ERR_BIT in CMD register.
79 */
MSS_AXISW_read_qos_val(mss_axisw_mport_t master_port_num,uint32_t * rd_data)80 uint32_t MSS_AXISW_read_qos_val(mss_axisw_mport_t master_port_num,
81 uint32_t* rd_data)
82 {
83
84 while(AXISW->CMD & AXISW_CMD_EN_MASK);
85
86 AXISW->CMD &= ~(AXISW_CMD_RW_MASK); /*Clear read/write bit*/
87
88 AXISW->CMD = ((master_port_num << AXISW_CMD_RWCHAN) | (MSS_AXISW_QOS_VAL) | AXISW_CMD_EN_MASK);
89
90 while(AXISW->CMD & AXISW_CMD_EN_MASK);
91
92 *rd_data = AXISW->DATA & AXISW_DATA_QOSVAL_MASK;
93
94 return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
95 }
96
97 /* Programs the peak rate and transaction rate value for the given master port
98 read/write address channel
99
100 NOTE: Peak rate and transaction rate are programmed simultaneously in one command.
101 So we must make sure that both desired valid values must be provided.
102
103 * return value: As received form AXI_ERR_BIT in CMD register.
104
105 */
MSS_AXISW_write_rate(mss_axisw_mport_t master_port_num,mss_axisw_rate_t peak_rate,mss_axisw_rate_t xct_rate)106 uint32_t MSS_AXISW_write_rate(mss_axisw_mport_t master_port_num,
107 mss_axisw_rate_t peak_rate,
108 mss_axisw_rate_t xct_rate)
109 {
110 while(AXISW->CMD & AXISW_CMD_EN_MASK); /*make sure previous command completed*/
111 AXISW->DATA = ((peak_rate) << AXISW_DATA_PEAKRT) | ((xct_rate) << AXISW_DATA_XCTRT) ;
112
113 AXISW->CMD = (AXISW_CMD_RW_MASK |
114 (master_port_num << AXISW_CMD_RWCHAN) |
115 (MSS_AXISW_PEAKRT_XCTRT) |
116 AXISW_CMD_EN_MASK);
117
118 while(AXISW->CMD & AXISW_CMD_EN_MASK); /*Wait for command to complete*/
119
120 return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
121 }
122
123 /* Reads the peak rate and transaction rate value for the given master port
124 read/write address channel
125 peak_rate: returns the value of peak rate
126 xct_rate: returns the value of transaction rate
127 return value: As received form AXI_ERR_BIT in CMD register.
128
129 */
MSS_AXISW_read_rate(mss_axisw_mport_t master_port_num,mss_axisw_rate_t * peak_rate,mss_axisw_rate_t * xct_rate)130 uint32_t MSS_AXISW_read_rate(mss_axisw_mport_t master_port_num,
131 mss_axisw_rate_t* peak_rate,
132 mss_axisw_rate_t* xct_rate)
133 {
134 uint32_t temp = 0u;
135 while(AXISW->CMD & AXISW_CMD_EN_MASK);
136
137 AXISW->CMD &= ~(AXISW_CMD_RW_MASK); /*Clear read/write and command EN bit*/
138
139 AXISW->CMD = ((master_port_num << AXISW_CMD_RWCHAN) |
140 (MSS_AXISW_PEAKRT_XCTRT) |
141 AXISW_CMD_EN_MASK);
142
143 while(AXISW->CMD & AXISW_CMD_EN_MASK);
144
145 temp = AXISW->DATA;
146
147 *peak_rate = (temp & AXISW_DATA_PEAKRT_MASK) >> AXISW_DATA_PEAKRT;
148 *xct_rate = (temp & AXISW_DATA_XCTRT_MASK) >> AXISW_DATA_XCTRT;
149
150 return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
151 }
152
153 /* Programs the burstiness value for the given master port read/write address channel
154
155 burstiness_val: burstiness value to be programmed
156 NOTE: Burstiness value formula as mentioned in AXISW document is Burstiness = DataReg[23:16] + 1
157
158 regulator_en: QoS regulator Enable 1= enable, 0 = disable
159
160 * return value: As received form AXI_ERR_BIT in CMD register.
161 */
MSS_AXISW_write_burstiness(mss_axisw_mport_t master_port_num,uint32_t burstiness_val,uint32_t regulator_en)162 int32_t MSS_AXISW_write_burstiness(mss_axisw_mport_t master_port_num,
163 uint32_t burstiness_val,
164 uint32_t regulator_en)
165 {
166
167 while(AXISW->CMD & AXISW_CMD_EN_MASK); /*make sure previous command completed*/
168
169 /*Write burstiness value and enable burstiness regulator.
170 * Burstiness_val=0 is not valid.
171 Burstiness value formula as mentioned in AXISW document is Burstiness = DataReg[23:16] + 1*/
172
173 if(burstiness_val == 0)
174 {
175 return -1;
176 }
177 else
178 {
179 AXISW->DATA = ((burstiness_val - 1u) << AXISW_DATA_BURSTI) | (regulator_en & 0x01);
180 }
181
182 AXISW->CMD = (AXISW_CMD_RW_MASK |
183 (master_port_num << AXISW_CMD_RWCHAN) |
184 (MSS_AXISW_BURSTINESS_EN) |
185 AXISW_CMD_EN_MASK);
186
187 while(AXISW->CMD & AXISW_CMD_EN_MASK); /*Wait for command to complete*/
188
189 return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
190 }
191
192 /* Reads the burstiness value for the given master port read/write address channel
193
194 burstiness_val: Return parameter bit 23:16 shows the burstiness value.
195 NOTE: Burstiness value formula as mentioned in AXISW document is Burstiness = DataReg[23:16] + 1
196
197 * return value: As received form AXI_ERR_BIT in CMD register.
198 */
MSS_AXISW_read_burstiness(mss_axisw_mport_t master_port_num,uint32_t * burstiness_val)199 uint32_t MSS_AXISW_read_burstiness(mss_axisw_mport_t master_port_num,
200 uint32_t* burstiness_val)
201 {
202 while(AXISW->CMD & AXISW_CMD_EN_MASK);
203
204 AXISW->CMD &= ~(AXISW_CMD_RW_MASK); /*Clear read/write and command EN bit*/
205
206 AXISW->CMD = ((master_port_num << AXISW_CMD_RWCHAN) |
207 (MSS_AXISW_BURSTINESS_EN) |
208 AXISW_CMD_EN_MASK);
209
210 while(AXISW->CMD & AXISW_CMD_EN_MASK);
211
212 *burstiness_val = ((AXISW->DATA & AXISW_DATA_BURSTI_MASK) >> AXISW_DATA_BURSTI) + 1u;
213
214 return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
215 }
216
MSS_AXISW_write_slave_ready(mss_axisw_mport_t master_port_num,uint8_t slave_ready_en)217 uint32_t MSS_AXISW_write_slave_ready(mss_axisw_mport_t master_port_num,
218 uint8_t slave_ready_en)
219 {
220 while(AXISW->CMD & AXISW_CMD_EN_MASK); /*make sure previous command completed*/
221
222 AXISW->DATA = slave_ready_en & 0x01; /*only valid value of bit0*/
223
224 AXISW->CMD = (AXISW_CMD_RW_MASK |
225 (master_port_num << AXISW_CMD_RWCHAN) |
226 MSS_AXISW_SLV_RDY |
227 AXISW_CMD_EN_MASK);
228
229 while(AXISW->CMD & AXISW_CMD_EN_MASK); /*Wait for command to complete*/
230
231 return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
232 }
233
234 /*Performs read operation on the AXI SWITCH APB interface,
235 * Parameters:
236 * master_port_num = AXI Master Port number. See Enum mss_axisw_mport_t above.
237 *
238 *
239 * slave_ready_en: returns the data returned by AXI SWITCH read operation for slave ready command
240 * return value: As received form AXI_ERR_BIT in CMD register.
241 *
242 */
MSS_AXISW_read_slave_ready(mss_axisw_mport_t master_port_num,uint8_t * slave_ready_en)243 uint32_t MSS_AXISW_read_slave_ready(mss_axisw_mport_t master_port_num,
244 uint8_t* slave_ready_en)
245 {
246
247 while(AXISW->CMD & AXISW_CMD_EN_MASK);
248
249 AXISW->CMD &= ~(AXISW_CMD_RW_MASK); /*Clear read/write bit*/
250
251 AXISW->CMD = ((master_port_num << AXISW_CMD_RWCHAN) |
252 (MSS_AXISW_SLV_RDY) |
253 AXISW_CMD_EN_MASK);
254
255 while(AXISW->CMD & AXISW_CMD_EN_MASK);
256
257 *slave_ready_en = AXISW->DATA & 0x01;
258
259 return ((AXISW->CMD & AXISW_CMD_ERR_MASK) >> AXISW_CMD_ERR); /*return error bit value*/
260 }
261
262 #ifdef __cplusplus
263 }
264 #endif
265
266
267