fifodma.c (9416B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * Purpose: SOC FIFO DMA driver. 8 */ 9 10 #include <shared/bsl.h> 11 12 #include <sal/core/boot.h> 13 #include <sal/core/libc.h> 14 #include <shared/alloc.h> 15 16 #include <soc/drv.h> 17 #include <soc/debug.h> 18 #include <soc/cm.h> 19 #include <soc/fifodma_internal.h> 20 21 STATIC soc_fifodma_drv_t _fifodma_drv[SOC_MAX_NUM_DEVICES]; 22 23 /******************************************* 24 * @function soc_fifodma_stop 25 * purpose to stop fifo dma channel 26 * 27 * @param unit [in] unit # 28 * @param chan [in] channel number 29 * 30 * @returns SOC_E_BUSY 31 * @returns SOC_E_NONE 32 * 33 * @end 34 */ 35 extern int 36 soc_fifodma_stop(int unit, int chan) 37 { 38 int rv = SOC_E_UNAVAIL; 39 40 if (_fifodma_drv[unit].fifodma_stop != NULL) { 41 rv = _fifodma_drv[unit].fifodma_stop(unit, chan); 42 } 43 44 return rv; 45 } 46 47 /******************************************* 48 * @function soc_fifodma_start 49 * purpose to start fifo dma channel 50 * 51 * @param unit [in] unit # 52 * @param chan [in] channel number 53 * 54 * @returns SOC_E_BUSY 55 * @returns SOC_E_NONE 56 * 57 * @end 58 */ 59 extern int 60 soc_fifodma_start(int unit, int chan, int is_mem, 61 soc_mem_t mem, soc_reg_t reg, 62 int copyno, int force_entry_size, 63 int host_entries, void *host_buf) 64 { 65 int rv = SOC_E_UNAVAIL; 66 67 if (_fifodma_drv[unit].fifodma_start != NULL) { 68 rv = _fifodma_drv[unit].fifodma_start(unit, chan, 69 is_mem, mem, reg, 70 copyno, force_entry_size, 71 host_entries, host_buf); 72 } 73 74 return rv; 75 } 76 77 /******************************************* 78 * @function soc_fifodma_intr_enable 79 * purpose to enable interrupt 80 * 81 * @param unit [in] unit # 82 * @param ch [in] channel 83 * 84 * @returns SOC_E_BUSY 85 * @returns SOC_E_NONE 86 * 87 * @end 88 */ 89 extern int 90 soc_fifodma_intr_enable(int unit, int ch) 91 { 92 int rv = SOC_E_UNAVAIL; 93 94 if (_fifodma_drv[unit].fifodma_intr_enable != NULL) { 95 rv = _fifodma_drv[unit].fifodma_intr_enable(unit, ch); 96 } 97 98 return rv; 99 } 100 101 /******************************************* 102 * @function soc_fifodma_intr_disable 103 * purpose to disable interrupt 104 * 105 * @param unit [in] unit # 106 * @param ch [in] channel 107 * 108 * @returns SOC_E_BUSY 109 * @returns SOC_E_NONE 110 * 111 * @end 112 */ 113 extern int 114 soc_fifodma_intr_disable(int unit, int ch) 115 { 116 int rv = SOC_E_UNAVAIL; 117 118 if (_fifodma_drv[unit].fifodma_intr_disable != NULL) { 119 rv = _fifodma_drv[unit].fifodma_intr_disable(unit, ch); 120 } 121 122 return rv; 123 } 124 125 /******************************************* 126 * @function soc_fifodma_get_read_ptr 127 * purpose to get read ptr 128 * 129 * @param unit [in] unit # 130 * 131 * @returns SOC_E_BUSY 132 * @returns SOC_E_NONE 133 * 134 * @end 135 */ 136 extern int 137 soc_fifodma_get_read_ptr(int unit, int chan, void **host_ptr, int *count) 138 { 139 int rv = SOC_E_UNAVAIL; 140 141 if (_fifodma_drv[unit].fifodma_get_read_ptr != NULL) { 142 rv = _fifodma_drv[unit].fifodma_get_read_ptr(unit, chan, 143 host_ptr, count); 144 } 145 146 return rv; 147 } 148 149 /******************************************* 150 * @function soc_fifodma_advance_read_ptr 151 * purpose to advance read ptr 152 * 153 * @param unit [in] unit # 154 * 155 * @returns SOC_E_BUSY 156 * @returns SOC_E_NONE 157 * 158 * @end 159 */ 160 extern int 161 soc_fifodma_advance_read_ptr(int unit, int chan, int count) 162 { 163 int rv = SOC_E_UNAVAIL; 164 165 if (_fifodma_drv[unit].fifodma_advance_read_ptr != NULL) { 166 rv = _fifodma_drv[unit].fifodma_advance_read_ptr(unit, chan, 167 count); 168 } 169 170 return rv; 171 } 172 173 /******************************************* 174 * @function soc_fifodma_set_entries_read 175 * purpose to read set entries 176 * 177 * @param unit [in] unit # 178 * 179 * @returns SOC_E_BUSY 180 * @returns SOC_E_NONE 181 * 182 * @end 183 */ 184 extern int 185 soc_fifodma_set_entries_read(int unit, int chan, uint32 num) 186 { 187 int rv = SOC_E_UNAVAIL; 188 189 if (_fifodma_drv[unit].fifodma_set_entries_read != NULL) { 190 rv = _fifodma_drv[unit].fifodma_set_entries_read(unit, chan, num); 191 } 192 193 return rv; 194 } 195 196 /******************************************* 197 * @function soc_fifodma_num_entries_get 198 * purpose to get number of entries 199 * 200 * @param unit [in] unit # 201 * 202 * @returns SOC_E_BUSY 203 * @returns SOC_E_NONE 204 * 205 * @end 206 */ 207 extern int 208 soc_fifodma_num_entries_get(int unit, int chan, int *count) 209 { 210 int rv = SOC_E_UNAVAIL; 211 212 if (_fifodma_drv[unit].fifodma_num_entries_get != NULL) { 213 rv = _fifodma_drv[unit].fifodma_num_entries_get(unit, chan, count); 214 } 215 216 return rv; 217 } 218 219 /******************************************* 220 * @function soc_fifodma_status_clear 221 * purpose to clear fifo dma channel status 222 * 223 * @param unit [in] unit # 224 * @param chan [in] channel number 225 * 226 * @returns SOC_E_BUSY 227 * @returns SOC_E_NONE 228 * 229 * @end 230 */ 231 extern int 232 soc_fifodma_status_clear(int unit, int chan) 233 { 234 int rv = SOC_E_UNAVAIL; 235 236 if (_fifodma_drv[unit].fifodma_status_clear != NULL) { 237 rv = _fifodma_drv[unit].fifodma_status_clear(unit, chan); 238 } 239 240 return rv; 241 } 242 243 /******************************************* 244 * @function soc_fifodma_status_get 245 * purpose to obtain fifo dma channel status 246 * 247 * @param unit [in] unit # 248 * @param chan [in] channel number 249 * 250 * @returns SOC_E_BUSY 251 * @returns SOC_E_NONE 252 * 253 * @end 254 */ 255 extern int 256 soc_fifodma_status_get(int unit, int chan, uint32 *status) 257 { 258 int rv = SOC_E_UNAVAIL; 259 260 if (_fifodma_drv[unit].fifodma_status_get != NULL) { 261 rv = _fifodma_drv[unit].fifodma_status_get(unit, chan, status); 262 } 263 264 return rv; 265 } 266 267 /******************************************* 268 * @function soc_fifodma_ch_endian_set 269 * purpose to set fifo dma channel endianness 270 * 271 * @param unit [in] unit # 272 * @param chan [in] channel number 273 * @param ch [in] big_endian 274 * 275 * @returns SOC_E_BUSY 276 * @returns SOC_E_NONE 277 * 278 * @end 279 */ 280 int 281 soc_fifodma_ch_endian_set(int unit, int channel, int be) 282 { 283 #ifdef BCM_CMICX_SUPPORT 284 if (soc_feature(unit, soc_feature_cmicx)) { 285 return cmicx_fifodma_ch_endian_set(unit, channel, be); 286 } 287 #endif 288 return SOC_E_NONE; 289 } 290 /******************************************* 291 * @function soc_fifodma_masks_get 292 * purpose to obtain fifodma masks 293 * 294 * @param unit [in] unit # 295 * @param chan [in] channel number 296 * 297 * @returns SOC_E_BUSY 298 * @returns SOC_E_NONE 299 * 300 * @end 301 */ 302 extern int 303 soc_fifodma_masks_get(int unit, uint32 *hostmem_timeout, uint32 *hostmem_overflow, uint32 *error, uint32 *done) 304 { 305 int rv = SOC_E_UNAVAIL; 306 307 if (_fifodma_drv[unit].fifodma_masks_get != NULL) { 308 rv = _fifodma_drv[unit].fifodma_masks_get(unit, hostmem_timeout, hostmem_overflow, 309 error, done); 310 } 311 312 return rv; 313 } 314 315 /******************************************* 316 * @function soc_l2mod_sbus_fifo_field_set 317 * obtain l2 mod sbus field set 318 * 319 * @param unit [in] unit # 320 * @param field [in] field 321 * @param enable [in] enable 322 * 323 * @returns SOC_E_BUSY 324 * @returns SOC_E_NONE 325 * 326 * @end 327 */ 328 329 extern int 330 soc_l2mod_sbus_fifo_field_set(int unit, soc_field_t field, int enable) 331 { 332 int rv = SOC_E_UNAVAIL; 333 334 if (_fifodma_drv[unit].l2mod_sbus_fifo_field_set != NULL) { 335 rv = _fifodma_drv[unit].l2mod_sbus_fifo_field_set(unit, field, enable); 336 } 337 338 return rv; 339 } 340 341 /******************************************* 342 * @function soc_l2mod_sbus_fifo_field_get 343 * obtain l2 mod sbus field get 344 * 345 * @param unit [in] unit # 346 * @param field [in] field 347 * @param enable [in] enable 348 * 349 * @returns SOC_E_BUSY 350 * @returns SOC_E_NONE 351 * 352 * @end 353 */ 354 355 extern int 356 soc_l2mod_sbus_fifo_field_get(int unit, soc_field_t field, int *enable) 357 { 358 int rv = SOC_E_UNAVAIL; 359 360 if (_fifodma_drv[unit].l2mod_sbus_fifo_field_get != NULL) { 361 rv = _fifodma_drv[unit].l2mod_sbus_fifo_field_get(unit, field, enable); 362 } 363 364 return rv; 365 } 366 367 /******************************************* 368 * @function soc_fifodma_init 369 * purpose API to Initialize CCM DMA 370 * 371 * @param unit [in] unit 372 * 373 * @returns SOC_E_NONE 374 * @returns SOC_E_XXX 375 * 376 * @end 377 */ 378 int soc_fifodma_init(int unit) 379 { 380 LOG_VERBOSE(BSL_LS_SOC_FIFODMA, 381 (BSL_META_U(unit, 382 "fifo dma init\n"))); 383 #ifdef BCM_CMICM_SUPPORT 384 if (soc_feature(unit, soc_feature_cmicm)) { 385 SOC_IF_ERROR_RETURN(cmicm_fifodma_init(unit, 386 &_fifodma_drv[unit])); 387 } 388 #endif 389 #ifdef BCM_CMICX_SUPPORT 390 if (soc_feature(unit, soc_feature_cmicx)) { 391 SOC_IF_ERROR_RETURN(cmicx_fifodma_init(unit, 392 &_fifodma_drv[unit])); 393 } 394 #endif 395 return SOC_E_NONE; 396 } 397 398 /******************************************* 399 * @function soc_fifodma_deinit 400 * purpose API to Deinitialize CCM DMA 401 * 402 * @param unit [in] unit 403 * 404 * @returns SOC_E_NONE 405 * 406 * @end 407 */ 408 int soc_fifodma_deinit(int unit) 409 { 410 LOG_VERBOSE(BSL_LS_SOC_FIFODMA, 411 (BSL_META_U(unit, 412 "fifo dma deinit\n"))); 413 #ifdef BCM_CMICM_SUPPORT 414 if (soc_feature(unit, soc_feature_cmicm)) { 415 416 SOC_IF_ERROR_RETURN(cmicm_fifodma_deinit(unit, 417 &_fifodma_drv[unit])); 418 } 419 #endif 420 #ifdef BCM_CMICX_SUPPORT 421 if (soc_feature(unit, soc_feature_cmicx)) { 422 423 SOC_IF_ERROR_RETURN(cmicx_fifodma_deinit(unit, 424 &_fifodma_drv[unit])); 425 } 426 #endif 427 return SOC_E_NONE; 428 }