pcie.c (11684B)
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 * BCM56xx I2C Device Driver for PCIE modules. 8 */ 9 #include <shared/bsl.h> 10 11 #include <sal/types.h> 12 #include <soc/drv.h> 13 #include <soc/error.h> 14 #include <soc/debug.h> 15 #include <soc/i2c.h> 16 17 #define PCIE_PAGE_SIZE 4 /* Bytes per page */ 18 #define PCIE_DEVICE_SIZE (256*PCIE_PAGE_SIZE) /* 256 bytes */ 19 #define PCIE_ACK_RETRY_COUNT 1000 /* Number of retry polls */ 20 21 /* 22 * Function: pcie_ack_poll 23 * 24 * Purpose: Poll the device to determine if it is ready for IO. 25 * When the chip writes data, it will become unresponsive 26 * for a period of Time Tw (Internal Write Delay). We could 27 * either wait the maximum amount of time for the device to 28 * finish it's write-cycle (10ms), or we can poll the device 29 * for a specified operation (r/w) until it responds with an 30 * ACK. This routine polls the device until it is responsive. 31 * 32 * Parameters: 33 * unit - StrataSwitch device number or I2C bus number 34 * bus_addr - chip IO (I2C) slave bus address byte(s) 35 * 36 * Returns: 37 * Number of Poll operations required to contact device, or 38 * PCIE_ACK_RETRY_COUNT if the device is not online or responding. 39 * 40 * 41 * Notes: 42 * See also: soc_i2c_ack_poll 43 */ 44 STATIC INLINE int 45 pcie_ack_poll(int unit, i2c_bus_addr_t bus_addr) 46 { 47 return soc_i2c_ack_poll(unit, bus_addr, PCIE_ACK_RETRY_COUNT); 48 } 49 50 /* 51 * Function: pcie_read 52 * 53 * Purpose: Read len bytes of data into buffer, update len with total 54 * amount read. 55 * 56 * Parameters: 57 * unit - StrataSwitch device number or I2C bus number 58 * devno - chip device id 59 * addr - PCIE memory address to read from 60 * data - address of data buffer to read into 61 * len - address containing number of bytes read into data buffer (updated 62 * with number of bytes read on completion). 63 * 64 * Returns: data bufffer filled in with data from address, number of 65 * bytes read is updated in len field. Status code: 66 * 67 * SOC_E_NONE -- no error encounter 68 * SOC_E_TIMEOUT - chip timeout or data error 69 * 70 * Notes: 71 * Currently uses random address byte read to initiate the read; if 72 * more than one byte of data is requested at the current address, a 73 * sequential read operation is performed. 74 */ 75 STATIC int 76 pcie_read(int unit, int devno, 77 uint16 addr, uint8* data, uint32 *len) 78 { 79 int rv = SOC_E_NONE; 80 uint8 saddr_r, saddr_w; 81 uint16 a0; 82 uint32 nbytes = 0; 83 84 /* Valid address, memory and size must be provided */ 85 if ( ! len || ! data ) 86 return SOC_E_PARAM; 87 88 I2C_LOCK(unit); 89 90 saddr_r = SOC_I2C_RX_ADDR(soc_i2c_addr(unit, devno)); 91 saddr_w = SOC_I2C_TX_ADDR(soc_i2c_addr(unit, devno)); 92 93 a0 = (uint16) (addr & 0xFFff); 94 95 LOG_INFO(BSL_LS_SOC_I2C, 96 (BSL_META_U(unit, 97 "pcie_read: addr=0x%x (a0=0x%x) len=%d\n"), 98 addr, a0, (int)*len)); 99 100 /* First, we put out the address which we would like to 101 * read at using the SOC_I2C_TX_ADDR (saddr_w) 102 */ 103 if ( (rv = soc_i2c_start(unit, saddr_w)) < 0) { 104 LOG_INFO(BSL_LS_SOC_I2C, 105 (BSL_META_U(unit, 106 "pcie_read(%d,%d,%x,%p,%d): " 107 "failed to generate start.\n"), 108 unit, devno, addr, (void *)data, *len)); 109 I2C_UNLOCK(unit); 110 return rv; 111 } 112 113 LOG_INFO(BSL_LS_SOC_I2C, 114 (BSL_META_U(unit, 115 "pcie_read(%d,%d,%x,%p,%d): " 116 "to send a0 byte.\n"), 117 unit, devno, addr, (void *)data, *len)); 118 if( (rv = soc_i2c_write_one_byte(unit, ((a0 >> 8) & 0xFF))) < 0) { 119 LOG_INFO(BSL_LS_SOC_I2C, 120 (BSL_META_U(unit, 121 "pcie_read(%d,%d,%x,%p,%d): " 122 "failed to send a0 byte.\n"), 123 unit, devno, addr, (void *)data, *len)); 124 125 goto error; 126 } 127 128 if( (rv = soc_i2c_write_one_byte(unit, a0 & 0xFF)) < 0) { 129 LOG_INFO(BSL_LS_SOC_I2C, 130 (BSL_META_U(unit, 131 "pcie_read(%d,%d,%04x,%x,%p,%d): " 132 "failed to send a0 byte.\n"), 133 unit, devno, addr, a0, (void *)data, *len)); 134 135 goto error; 136 } 137 /* Now, we have sent the first and second word addresses, 138 * we then issue a repeated start condition, followed by 139 * the device's read address (note: saddr_r) 140 */ 141 if( (rv = soc_i2c_rep_start(unit, saddr_r)) < 0) { 142 LOG_INFO(BSL_LS_SOC_I2C, 143 (BSL_META_U(unit, 144 "pcie_read(%d,%d,%x,%p,%d): " 145 "failed to generate rep start.\n"), 146 unit, devno, addr, (void *)data, *len)); 147 goto error; 148 } 149 nbytes = *len; 150 if ( (rv = soc_i2c_read_bytes(unit, data, (int *)&nbytes, 0) ) < 0 ) { 151 goto error; 152 } 153 *len = nbytes; 154 155 error: 156 157 soc_i2c_stop(unit); 158 159 I2C_UNLOCK(unit); 160 return rv ; 161 } 162 163 /* 164 * Function: pcie_write 165 * Purpose: Write len bytes of data, return the number of bytes written. 166 * Uses PAGE mode to write up to 32 bytes at a time between address 167 * stages for maximum performance. 168 * 169 * Parameters: 170 * unit - StrataSwitch device number or I2C bus number 171 * devno - chip device id 172 * addr - PCIE memory address to write to 173 * data - address of data buffer to write from 174 * len - number of bytes to write 175 * 176 * Returns: 177 * SOC_E_NONE -- no error encountered 178 * SOC_E_TIMEOUT - chip timeout or data error 179 * 180 * 181 * Notes: 182 * Uses page mode to write in 32-byte chunks, when an address 183 * which does not begin on a page boundary is provided, the write 184 * operation handles unaligned accesses by breaking up the write 185 * into one write which is not page aligned, and the remainder as 186 * page aligned accesses. 187 */ 188 STATIC int 189 pcie_write(int unit, int devno, 190 uint16 addr, uint8* data, uint32 len) 191 { 192 int rv = SOC_E_NONE; 193 uint8 *ptr; 194 uint16 a0; 195 uint32 b, numpages, cpage, nbytes, tbytes, caddr; 196 i2c_bus_addr_t bus_addr; 197 198 /* User must have data to write */ 199 if ( ! data || len <= 0 ) 200 return SOC_E_PARAM; 201 202 I2C_LOCK(unit); 203 204 /* Use PAGE mode */ 205 caddr = addr; 206 numpages = len / PCIE_PAGE_SIZE + (len % PCIE_PAGE_SIZE > 0); 207 ptr = data; 208 209 210 tbytes = soc_i2c_device(unit, devno)->tbyte++; 211 212 bus_addr = SOC_I2C_TX_ADDR(soc_i2c_addr(unit, devno)); 213 214 LOG_INFO(BSL_LS_SOC_I2C, 215 (BSL_META_U(unit, 216 "pcie_write: addr=0x%x data=%p len=%d npages=%d\n"), 217 caddr, (void *)data, (int)len, numpages)); 218 219 /* Loop over every page in buffer .. */ 220 for(cpage = 0; cpage < numpages; cpage++){ 221 /* Address not page aligned, D'Oh, can't write a full page. */ 222 if( (caddr % PCIE_PAGE_SIZE) != 0){ 223 nbytes = PCIE_PAGE_SIZE - (caddr % PCIE_PAGE_SIZE); 224 len -= nbytes; 225 } else { 226 /* Address is page aligned, calculate bytes to write */ 227 if ( len <= PCIE_PAGE_SIZE ) { 228 /* Less than a page to write */ 229 nbytes = len; 230 } else { 231 /* Wammo, full page write */ 232 nbytes = PCIE_PAGE_SIZE; 233 len -= nbytes; 234 } 235 } 236 237 /* Construct device address bytes */ 238 a0 = (uint16) (caddr & 0xFFff); 239 240 241 /* Generate Start, for Write address */ 242 if( (rv = soc_i2c_start(unit, bus_addr)) < 0){ 243 LOG_INFO(BSL_LS_SOC_I2C, 244 (BSL_META_U(unit, 245 "pcie_write(%d,%d,%x,%d,%d): " 246 "failed to gen start\n"), 247 unit, devno, caddr, *data, len)); 248 I2C_UNLOCK(unit); 249 return rv; 250 } 251 LOG_INFO(BSL_LS_SOC_I2C, 252 (BSL_META_U(unit, 253 "pcie_write: unit=%d cpage=%d START on page_addr=0x%x" 254 " nbytes=%d\n"), unit, cpage, ((a0 >> 8) & 0xFF) , nbytes)); 255 if( (rv = soc_i2c_write_one_byte(unit, ((a0 >> 8) & 0xFF))) < 0) { 256 LOG_INFO(BSL_LS_SOC_I2C, 257 (BSL_META_U(unit, 258 "pcie_write(%d,%d,%x,%p,%d): " 259 "failed to send a0 byte.\n"), 260 unit, devno, addr, (void *)data, len)); 261 262 goto error; 263 } 264 265 LOG_INFO(BSL_LS_SOC_I2C, 266 (BSL_META_U(unit, 267 "pcie_write: unit=%d cpage=%d START on page_addr=0x%x" 268 " nbytes=%d\n"), unit, cpage, ((a0) & 0xFF) , nbytes)); 269 if( (rv = soc_i2c_write_one_byte(unit, a0 & 0xFF)) < 0) { 270 LOG_INFO(BSL_LS_SOC_I2C, 271 (BSL_META_U(unit, 272 "pcie_write(%d,%d,%04x,%x,%p,%d): " 273 "failed to send a0 byte.\n"), 274 unit, devno, addr, a0, (void *)data, len)); 275 276 goto error; 277 } 278 /* Send up to PAGE_SIZE data bytes, wait for ACK */ 279 for ( b = 0; b < nbytes; b++, ptr++, caddr++ ) { 280 if ( (rv = soc_i2c_write_one_byte(unit, *ptr)) < 0){ 281 LOG_INFO(BSL_LS_SOC_I2C, 282 (BSL_META_U(unit, 283 "pcie_write(%d,%d,%d,%d,%d): " 284 "tx data byte error\n"), 285 unit, devno, caddr, (uint32)*ptr, b)); 286 goto error; 287 } 288 LOG_VERBOSE(BSL_LS_SOC_I2C, 289 (BSL_META_U(unit, 290 "pcie_write(u=%d,id=%d,page=%d " 291 "caddr=%d,data=0x%x,idx=%d)\n"), 292 unit, devno, cpage, caddr, (uint8)*ptr, b)); 293 294 soc_i2c_device(unit, devno)->tbyte++; 295 } 296 297 /* Send STOP, also what we do on an error to free bus.. */ 298 error: 299 300 soc_i2c_stop(unit); 301 302 /* Acknowledge polling: When the chip enters it's 303 * own internal write-cycle, it falls off the I2C bus 304 * and does not ACK a start/address phase; hence, we 305 * attempt addressing the chip until it responds, at 306 * which point the internal write cycle has finished. 307 */ 308 rv = pcie_ack_poll(unit, bus_addr); 309 LOG_INFO(BSL_LS_SOC_I2C, 310 (BSL_META_U(unit, 311 "pcie_ack_poll: " 312 "%d address cycles for wr latency.\n"), rv)); 313 rv = (rv > 0 ? SOC_E_NONE: SOC_E_TIMEOUT); 314 315 } 316 317 I2C_UNLOCK(unit); 318 319 return rv < 0 ? rv : soc_i2c_device(unit, devno)->tbyte - tbytes - 1 ; 320 } 321 322 323 /* 324 * Function: pcie_init 325 * 326 * Purpose: initialize the PCIE I2C interface. 327 * 328 * Parameters: 329 * unit - StrataSwitch device number or I2C bus number 330 * devno - chip device id 331 * data - address of test data 332 * len - size of test data 333 */ 334 STATIC int 335 pcie_init(int unit, int devno, void* data, int len) 336 { 337 soc_i2c_devdesc_set(unit, devno, "PCIE"); 338 339 return SOC_E_NONE; 340 } 341 342 /* 343 * Function: pcie_ioctl: does miscellaenous tasks. 344 * Purpose: Support miscellaneous chip options. 345 * 346 * Parameters: 347 * unit - StrataSwitch device number or I2C bus number 348 * devno - chip device id 349 * command - IO control operation 350 * data - address of user data 351 * len - size of test data 352 * 353 * Notes: 354 * Placeholder for write Protect, EEPROM Chip reset - NYI 355 */ 356 STATIC int 357 pcie_ioctl(int unit, int devno, 358 int command, void* data, int len) 359 { 360 switch ( command ) { 361 362 default: 363 break; 364 } 365 return SOC_E_NONE; 366 } 367 368 /* PCIE Driver callout */ 369 i2c_driver_t _soc_i2c_pcie_driver = { 370 0x0,0x0, /* System assigned bytes */ 371 PCIE_DEVICE_TYPE, 372 pcie_read, 373 pcie_write, 374 pcie_ioctl, 375 pcie_init, 376 NULL, 377 };