merlin16_pcieg3_dependencies.c (8213B)
1 /* 2 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 3 * 4 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 5 * 6 * This file implements Switch specific Bus access to the PCIE Gen3 PHY. 7 */ 8 #include <sal/compiler.h> 9 #include <sal/core/thread.h> 10 #include <shared/bsl.h> 11 #include "merlin16_pcieg3_internal.h" 12 #include "common/srds_api_err_code.h" 13 #include "common/srds_api_types.h" 14 #include "merlin16_pcieg3_common.h" 15 #include "merlin16_pcieg3_functions.h" 16 #include "merlin16_pcieg3_dependencies.h" 17 18 19 /** Read a register from the currently selected Serdes IP Lane. 20 * @param sa__ is an opaque state vector passed through to device access functions. 21 * @param address Address of register to be read 22 * @param *val value read out from the register 23 * @return Error code generated by read function (returns ERR_CODE_NONE if no errors) 24 */ 25 err_code_t merlin16_pcieg3_pmd_rdt_reg(srds_access_t *sa__, uint16_t address, uint16_t *val) 26 { 27 uint32_t phyaddr; 28 uint32_t lane = (uint32_t)(merlin16_pcieg3_get_lane(sa__)); 29 30 if (!SRDS_BUS_VALIDATE(sa__)) { 31 return ERR_CODE_BAD_PTR_OR_INVALID_INPUT; 32 } 33 34 phyaddr = address | 1 << 27; 35 phyaddr |= (lane & 0x1F) << 16; 36 SRDS_BUS_READ(sa__, phyaddr, val); 37 38 return ERR_CODE_NONE; 39 } 40 41 /** Write to a register from the currently selected Serdes IP Lane. 42 * @param sa__ is an opaque state vector passed through to device access functions. 43 * @param address Address of register to be written 44 * @param val Value to be written to the register 45 * @return Error code generated by write function (returns ERR_CODE_NONE if no errors) 46 */ 47 err_code_t merlin16_pcieg3_pmd_wr_reg(srds_access_t *sa__, uint16_t address, uint16_t val) 48 { 49 uint32_t phyaddr; 50 uint32_t lane = (uint32_t)(merlin16_pcieg3_get_lane(sa__)); 51 52 if (!SRDS_BUS_VALIDATE(sa__)) { 53 return ERR_CODE_BAD_PTR_OR_INVALID_INPUT; 54 } 55 56 phyaddr = address | 1 << 27; 57 phyaddr |= ((lane & 0x1F) << 16); 58 SRDS_BUS_WRITE(sa__, phyaddr, val); 59 60 return ERR_CODE_NONE; 61 } 62 63 /** Masked Register Write to the currently selected Serdes IP core/lane. 64 * If using Serdes MDIO controller to access the registers, implement this function using merlin16_pcieg3_pmd_mdio_mwr_reg(..) 65 * 66 * If NOT using a Serdes MDIO controller or the Serdes PMI Masked write feature, please use the following code to 67 * implement this function 68 * 69 * merlin16_pcieg3_pmd_wr_reg(addr, ((merlin16_pmd_rd_reg(addr) & ~mask) | (mask & (val << lsb)))); 70 * 71 * @param sa__ is an opaque state vector passed through to device access functions. 72 * @param addr Address of register to be written 73 * @param mask 16-bit mask indicating the position of the field with bits of 1s 74 * @param lsb LSB of the field 75 * @param val 16bit value to be written 76 * @return Error code generated by write function (returns ERR_CODE_NONE if no errors) 77 */ 78 err_code_t merlin16_pcieg3_pmd_mwr_reg(srds_access_t *sa__, uint16_t addr, uint16_t mask, uint8_t lsb, uint16_t val) 79 { 80 err_code_t error_code; 81 uint16_t data; 82 83 error_code = merlin16_pcieg3_pmd_rdt_reg(sa__, addr, &data); 84 if(error_code != ERR_CODE_NONE) 85 return error_code; 86 87 data = (data & ~mask) | (mask & (val << lsb)); 88 89 error_code = merlin16_pcieg3_pmd_wr_reg(sa__, addr, data); 90 91 return error_code; 92 } 93 94 /** Write to a PRAM location for the currently selected Serdes IP Core. 95 * The address is auto-incrementing, per the PRAM interface specification. 96 * @param sa__ is an opaque state vector passed through to device access functions. 97 * @param val Value to be written 98 * @return Error code generated by write function (returns ERR_CODE_NONE if no errors) 99 */ 100 err_code_t merlin16_pcieg3_pmd_wr_pram(srds_access_t *sa__, uint8_t val) 101 { 102 return ERR_CODE_NONE; 103 } 104 105 /** Write message to the logger with the designated verbose level. 106 * Output is sent to stdout and a logfile 107 * @param message_verbose_level Verbose level for the current message 108 * @param *format Format string as in printf 109 * @param ... Additional variables used as in printf 110 * @return Error code generated by function (returns ERR_CODE_NONE if no errors) 111 */ 112 #ifdef SRDS_API_ALL_FUNCTIONS_HAVE_ACCESS_STRUCT 113 int logger_write(srds_access_t *sa__, int message_verbose_level, const char *format, ...) 114 { 115 return ERR_CODE_NONE; 116 } 117 #endif 118 119 /** Delay the execution of the code for atleast specified amount of time in nanoseconds. 120 * This function is used ONLY for delays less than 1 microsecond, non-zero error code may be returned otherwise. 121 * The user can implement this as an empty function if their register access latency exceeds 1 microsecond. 122 * @param delay_ns Delay in nanoseconds 123 * @return Error code generated by delay function (returns ERR_CODE_NONE if no errors) 124 */ 125 #ifdef SRDS_API_ALL_FUNCTIONS_HAVE_ACCESS_STRUCT 126 err_code_t merlin16_pcieg3_delay_ns(srds_access_t *sa__, uint16_t delay_ns) 127 { 128 uint32_t delay; 129 delay = delay_ns / 1000; 130 if(!delay) { 131 delay = 1; 132 } 133 sal_udelay(delay); 134 return 0; 135 } 136 #else 137 err_code_t merlin16_pcieg3_delay_ns(uint16_t delay_ns) 138 { 139 uint32_t delay; 140 delay = delay_ns / 1000; 141 if(!delay) { 142 delay = 1; 143 } 144 sal_udelay(delay); 145 return 0; 146 } 147 #endif 148 149 /** Delay the execution of the code for atleast specified amount of time in microseconds. 150 * For longer delays, accuracy is required. When requested delay is > 100ms, the implemented delay is assumed 151 * to be < 10% bigger than requested. 152 * This function is used ONLY for delays greater than or equal to 1 microsecond. 153 * @param delay_us Delay in microseconds 154 * @return Error code generated by delay function (returns ERR_CODE_NONE if no errors) 155 */ 156 #ifdef SRDS_API_ALL_FUNCTIONS_HAVE_ACCESS_STRUCT 157 err_code_t merlin16_pcieg3_delay_us(srds_access_t *sa__, uint32_t delay_us) 158 { 159 sal_udelay(delay_us); 160 return 0; 161 } 162 #else 163 err_code_t merlin16_pcieg3_delay_us(uint32_t delay_us) 164 { 165 sal_udelay(delay_us); 166 return 0; 167 } 168 #endif 169 170 /** Delay the execution of the code for atleast specified amount of time in milliseconds. 171 * For longer delays, accuracy is required. When requested delay is > 100ms, the implemented delay is assumed 172 * to be < 10% bigger than requested. 173 * This function is used ONLY for delays greater than or equal to 1 millisecond. 174 * @param delay_ms Delay in milliseconds 175 * @return Error code generated by delay function (returns ERR_CODE_NONE if no errors) 176 */ 177 #ifdef SRDS_API_ALL_FUNCTIONS_HAVE_ACCESS_STRUCT 178 err_code_t merlin16_pcieg3_delay_ms(srds_access_t *sa__, uint32_t delay_ms) 179 { 180 sal_udelay(delay_ms * 1000); 181 return 0; 182 } 183 #else 184 err_code_t merlin16_pcieg3_delay_ms(uint32_t delay_ms) 185 { 186 sal_udelay(delay_ms * 1000); 187 return 0; 188 } 189 #endif 190 191 /** Return the address of current selected Serdes IP Core. 192 * @param sa__ is an opaque state vector passed through to device access functions. 193 * @return the IP level address of the current core. 194 */ 195 uint8_t merlin16_pcieg3_get_core(srds_access_t *sa__) 196 { 197 return 0; 198 } 199 200 /** Return the address of current selected Serdes IP lane. 201 * @param sa__ is an opaque state vector passed through to device access functions. 202 * @return the IP level address of the current lane. 0 to N-1, for an N lane IP 203 */ 204 uint8_t merlin16_pcieg3_get_lane(srds_access_t *sa__) 205 { 206 uint8_t lane_index; 207 208 if(sa__->lane_mask == 0x1) { 209 lane_index = 0; 210 } else if(sa__->lane_mask == 0x2) { 211 lane_index = 1; 212 } else if(sa__->lane_mask == 0x4) { 213 lane_index = 2; 214 } else if(sa__->lane_mask == 0x8) { 215 lane_index = 3; 216 } else { 217 lane_index = 0; 218 } 219 return (sa__->core + lane_index); 220 } 221 222 /** Set the address of current selected Serdes IP lane. Used in diagnostic 223 * and core-level management functions. 224 * @param sa__ is an opaque state vector passed through to device access functions. 225 * @param lane_index is the lane index 226 * @return Any error code generated during execution; ERR_CODE NONE otherwise. 227 */ 228 err_code_t merlin16_pcieg3_set_lane(srds_access_t *sa__, uint8_t lane_index) 229 { 230 231 sa__->core = (lane_index/4); /* Four lanes per core */ 232 sa__->lane_mask = (1 << (lane_index % 4)); 233 234 return ERR_CODE_NONE; 235 } 236 237