merlin16_access.c (20264B)
1 /*********************************************************************************** 2 *********************************************************************************** 3 * File Name : merlin16_access.c * 4 * Created On : 03 Nov 2015 * 5 * Created By : Brent Roberts * 6 * Description : APIs for Serdes IPs * 7 * Revision : * 8 * * 9 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 10 * 11 * Copyright 2007-2019 Broadcom Inc. All rights reserved. * 12 * No portions of this material may be reproduced in any form without * 13 * the written permission of: * 14 * Broadcom Corporation * 15 * 5300 California Avenue * 16 * Irvine, CA 92617 * 17 * * 18 * All information contained in this document is Broadcom Corporation * 19 * company private proprietary, and trade secret. * 20 */ 21 22 /** @file merlin16_access.c 23 * Implementation of API uC access functions 24 */ 25 26 #include "merlin16_access.h" 27 #include "merlin16_common.h" 28 #include "merlin16_functions.h" 29 #include "merlin16_internal.h" 30 #include "merlin16_internal_error.h" 31 #include "merlin16_select_defns.h" 32 33 34 /******************************************************/ 35 /* Commands through Serdes FW DSC Command Interface */ 36 /******************************************************/ 37 38 err_code_t merlin16_pmd_uc_cmd_return_immediate(srds_access_t *sa__, enum srds_pmd_uc_cmd_enum cmd, uint8_t supp_info) { 39 err_code_t err_code; 40 uint16_t cmddata; 41 42 err_code = merlin16_INTERNAL_poll_uc_dsc_ready_for_cmd_equals_1(sa__, 1, cmd); /* Poll for uc_dsc_ready_for_cmd = 1 to indicate merlin16 ready for command */ 43 if (err_code) { 44 EFUN_PRINTF(("ERROR : DSC ready for command timed out (before cmd) cmd = %d, supp_info = x%02x err=%d !\n", cmd, supp_info, err_code)); 45 return (err_code); 46 } 47 /*EFUN(wr_uc_dsc_supp_info(supp_info)); */ /* Supplement info field */ 48 /*EFUN(wr_uc_dsc_error_found(0x0) ); */ /* Clear error found field */ 49 /*EFUN(wr_uc_dsc_gp_uc_req(cmd) ); */ /* Set command code */ 50 /*EFUN(wr_uc_dsc_ready_for_cmd(0x0) ); */ /* Issue command, by clearing "ready for command" field */ 51 cmddata = (((uint16_t)supp_info)<<8) | (uint16_t)cmd; /* Combine writes to single write instead of 4 RMW */ 52 53 EFUN(reg_wr_DSC_A_DSC_UC_CTRL(cmddata)); 54 55 return(ERR_CODE_NONE); 56 } 57 58 err_code_t merlin16_pmd_uc_cmd(srds_access_t *sa__, enum srds_pmd_uc_cmd_enum cmd, uint8_t supp_info, uint32_t timeout_ms) { 59 60 EFUN(merlin16_pmd_uc_cmd_return_immediate(sa__, cmd, supp_info)); /* Invoke merlin16_uc_cmd and return control immediately */ 61 62 EFUN(merlin16_INTERNAL_poll_uc_dsc_ready_for_cmd_equals_1(sa__, timeout_ms, cmd)); /* Poll for uc_dsc_ready_for_cmd = 1 to indicate merlin16 ready for command */ 63 64 return(ERR_CODE_NONE); 65 } 66 67 68 err_code_t merlin16_pmd_uc_cmd_with_data_return_immediate(srds_access_t *sa__, enum srds_pmd_uc_cmd_enum cmd, uint8_t supp_info, uint16_t data) { 69 uint16_t cmddata; 70 err_code_t err_code; 71 72 err_code = merlin16_INTERNAL_poll_uc_dsc_ready_for_cmd_equals_1(sa__, 1, cmd); /* Poll for uc_dsc_ready_for_cmd = 1 to indicate merlin16 ready for command */ 73 if (err_code) { 74 EFUN_PRINTF(("ERROR : DSC ready for command timed out (before cmd) cmd = %d, supp_info = x%02x, data = x%04x err=%d !\n", cmd, supp_info, data,err_code)); 75 return (err_code); 76 } 77 78 EFUN(wr_uc_dsc_data(data)); /* Write value written to uc_dsc_data field */ 79 /*EFUN(wr_uc_dsc_supp_info(supp_info)); */ /* Supplement info field */ 80 /*EFUN(wr_uc_dsc_error_found(0x0)); */ /* Clear error found field */ 81 /*EFUN(wr_uc_dsc_gp_uc_req(cmd)); */ /* Set command code */ 82 /*EFUN(wr_uc_dsc_ready_for_cmd(0x0)); */ /* Issue command, by clearing "ready for command" field */ 83 cmddata = (((uint16_t)supp_info)<<8) | (uint16_t)cmd; /* Combine writes to single write instead of 4 RMW */ 84 85 EFUN(reg_wr_DSC_A_DSC_UC_CTRL(cmddata)); 86 87 return(ERR_CODE_NONE); 88 } 89 90 91 err_code_t merlin16_pmd_uc_cmd_with_data(srds_access_t *sa__, enum srds_pmd_uc_cmd_enum cmd, uint8_t supp_info, uint16_t data, uint32_t timeout_ms) { 92 93 EFUN(merlin16_pmd_uc_cmd_with_data_return_immediate(sa__, cmd, supp_info, data)); /* Invoke merlin16_uc_cmd and return control immediately */ 94 95 EFUN(merlin16_INTERNAL_poll_uc_dsc_ready_for_cmd_equals_1(sa__, timeout_ms, cmd)); /* Poll for uc_dsc_ready_for_cmd = 1 to indicate merlin16 ready for command */ 96 return(ERR_CODE_NONE); 97 } 98 99 err_code_t merlin16_pmd_uc_control_return_immediate(srds_access_t *sa__, enum srds_pmd_uc_ctrl_cmd_enum control) { 100 return(merlin16_pmd_uc_cmd_return_immediate(sa__, CMD_UC_CTRL, (uint8_t) control)); 101 } 102 103 err_code_t merlin16_pmd_uc_control(srds_access_t *sa__, enum srds_pmd_uc_ctrl_cmd_enum control, uint32_t timeout_ms) { 104 return(merlin16_pmd_uc_cmd(sa__, CMD_UC_CTRL, (uint8_t) control, timeout_ms)); 105 } 106 107 err_code_t merlin16_pmd_uc_diag_cmd(srds_access_t *sa__, enum srds_pmd_uc_diag_cmd_enum control, uint32_t timeout_ms) { 108 return(merlin16_pmd_uc_cmd(sa__, CMD_DIAG_EN, (uint8_t) control, timeout_ms)); 109 } 110 111 /************************************************************/ 112 /* Serdes IP RAM access - Lane RAM Variables */ 113 /*----------------------------------------------------------*/ 114 /* - through Micro Register Interface for PMD IPs */ 115 /* - through Serdes FW DSC Command Interface for Gallardo */ 116 /************************************************************/ 117 118 /* This function returns the absolute address of lane RAM variables given the offset address and lane */ 119 uint16_t merlin16_INTERNAL_get_lane_addr(uint16_t addr, uint8_t lane) { 120 uint16_t lane_var_ram_base=0, lane_var_ram_size=0; 121 uint16_t lane_addr_offset = 0; 122 123 lane_var_ram_base = LANE_VAR_RAM_BASE; 124 lane_var_ram_size = LANE_VAR_RAM_SIZE; 125 lane_addr_offset = lane_var_ram_base+addr+(lane*lane_var_ram_size); 126 return(lane_addr_offset); 127 } 128 129 /* Micro RAM Lane Byte Read */ 130 uint8_t merlin16_rdbl_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) { 131 uint8_t rddata; 132 uint16_t lane_addr_offset = 0; 133 uint8_t lane; 134 135 if(!err_code_p) { 136 return(0); 137 } 138 139 { 140 lane = merlin16_get_physical_lane(sa__); 141 lane_addr_offset = merlin16_INTERNAL_get_lane_addr(addr,lane); 142 143 EPSTM(rddata = merlin16_rdb_uc_ram(sa__, err_code_p, lane_addr_offset)); /* Use Micro register interface for reading RAM */ 144 return (rddata); 145 } 146 } 147 148 /* Micro RAM Lane Byte Signed Read */ 149 int8_t merlin16_rdbls_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) { 150 return ((int8_t) merlin16_rdbl_uc_var(sa__, err_code_p, addr)); 151 } 152 153 /* Micro RAM Lane Word Read */ 154 uint16_t merlin16_rdwl_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) { 155 uint16_t rddata; 156 uint16_t lane_addr_offset = 0; 157 uint8_t lane; 158 159 if(!err_code_p) { 160 return(0); 161 } 162 if (addr%2 != 0) { /* Validate even address */ 163 *err_code_p = ERR_CODE_INVALID_RAM_ADDR; 164 return (0); 165 } 166 167 { 168 lane = merlin16_get_physical_lane(sa__); 169 lane_addr_offset = merlin16_INTERNAL_get_lane_addr(addr,lane); 170 171 EPSTM(rddata = merlin16_rdw_uc_ram(sa__, err_code_p, lane_addr_offset)); /* Use Micro register interface for reading RAM */ 172 return (rddata); 173 } 174 } 175 176 177 /* Micro RAM Lane Word Signed Read */ 178 int16_t merlin16_rdwls_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) { 179 return ((int16_t) merlin16_rdwl_uc_var(sa__, err_code_p, addr)); 180 } 181 182 /* Micro RAM Lane Byte Write */ 183 err_code_t merlin16_wrbl_uc_var(srds_access_t *sa__, uint16_t addr, uint8_t wr_val) { 184 uint16_t lane_addr_offset = 0; 185 uint8_t lane; 186 187 188 { 189 lane = merlin16_get_physical_lane(sa__); 190 lane_addr_offset = merlin16_INTERNAL_get_lane_addr(addr,lane); 191 192 return (merlin16_wrb_uc_ram(sa__, lane_addr_offset, wr_val)); /* Use Micro register interface for writing RAM */ 193 } 194 } 195 196 /* Micro RAM Lane Byte Signed Write */ 197 err_code_t merlin16_wrbls_uc_var(srds_access_t *sa__, uint16_t addr, int8_t wr_val) { 198 return (merlin16_wrbl_uc_var(sa__, addr, wr_val)); 199 } 200 201 /* Micro RAM Lane Word Write */ 202 err_code_t merlin16_wrwl_uc_var(srds_access_t *sa__, uint16_t addr, uint16_t wr_val) { 203 uint16_t lane_addr_offset = 0; 204 uint8_t lane; 205 206 if (addr%2 != 0) { /* Validate even address */ 207 return (_error(ERR_CODE_INVALID_RAM_ADDR)); 208 } 209 210 { 211 lane = merlin16_get_physical_lane(sa__); 212 lane_addr_offset = merlin16_INTERNAL_get_lane_addr(addr,lane); 213 214 return (merlin16_wrw_uc_ram(sa__, lane_addr_offset, wr_val)); /* Use Micro register interface for writing RAM */ 215 } 216 217 } 218 219 /* Micro RAM Lane Word Signed Write */ 220 err_code_t merlin16_wrwls_uc_var(srds_access_t *sa__, uint16_t addr, int16_t wr_val) { 221 return (merlin16_wrwl_uc_var(sa__, addr,wr_val)); 222 } 223 224 225 226 227 /************************************************************/ 228 /* Serdes IP RAM access - Core RAM Variables */ 229 /*----------------------------------------------------------*/ 230 /* - through Micro Register Interface for PMD IPs */ 231 /* - through Serdes FW DSC Command Interface for Gallardo */ 232 /************************************************************/ 233 234 /* This function returns the absolute address of core RAM variables given the offset address and lane */ 235 uint16_t merlin16_INTERNAL_get_core_address(uint16_t addr, uint8_t lane) { 236 uint16_t core_var_ram_base=0; 237 uint16_t core_addr_offset = 0; 238 239 core_var_ram_base = CORE_VAR_RAM_BASE; 240 core_addr_offset = core_var_ram_base + addr; 241 242 return(core_addr_offset); 243 } 244 245 /* Micro RAM Core Byte Read */ 246 uint8_t merlin16_rdbc_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint8_t addr) { 247 248 uint8_t rddata; 249 uint8_t lane; 250 uint16_t core_addr_offset; 251 if(!err_code_p) { 252 return(0); 253 } 254 255 { 256 lane = merlin16_get_physical_lane(sa__); 257 core_addr_offset = merlin16_INTERNAL_get_core_address(addr,lane); 258 EPSTM(rddata = merlin16_rdb_uc_ram(sa__, err_code_p, core_addr_offset)); /* Use Micro register interface for reading RAM */ 259 return (rddata); 260 } 261 } 262 263 /* Micro RAM Core Byte Signed Read */ 264 int8_t merlin16_rdbcs_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint8_t addr) { 265 return ((int8_t) merlin16_rdbc_uc_var(sa__, err_code_p, addr)); 266 } 267 268 /* Micro RAM Core Word Read */ 269 uint16_t merlin16_rdwc_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint8_t addr) { 270 uint16_t rddata; 271 uint8_t lane; 272 uint16_t core_addr_offset; 273 274 if(!err_code_p) { 275 return(0); 276 } 277 if (addr%2 != 0) { /* Validate even address */ 278 *err_code_p = ERR_CODE_INVALID_RAM_ADDR; 279 return (0); 280 } 281 282 { 283 lane = merlin16_get_physical_lane(sa__); 284 core_addr_offset = merlin16_INTERNAL_get_core_address(addr,lane); 285 286 EPSTM(rddata = merlin16_rdw_uc_ram(sa__, err_code_p, core_addr_offset)); /* Use Micro register interface for reading RAM */ 287 return (rddata); 288 } 289 } 290 291 /* Micro RAM Core Word Signed Read */ 292 int16_t merlin16_rdwcs_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint8_t addr) { 293 return ((int16_t) merlin16_rdwc_uc_var(sa__, err_code_p, addr)); 294 } 295 296 /* Micro RAM Core Byte Write */ 297 err_code_t merlin16_wrbc_uc_var(srds_access_t *sa__, uint8_t addr, uint8_t wr_val) { 298 uint8_t lane; 299 uint16_t core_addr_offset; 300 301 { 302 lane = merlin16_get_physical_lane(sa__); 303 core_addr_offset = merlin16_INTERNAL_get_core_address(addr,lane); 304 305 return (merlin16_wrb_uc_ram(sa__, core_addr_offset, wr_val)); /* Use Micro register interface for writing RAM */ 306 } 307 308 } 309 310 311 /* Micro RAM Core Byte Signed Write */ 312 err_code_t merlin16_wrbcs_uc_var(srds_access_t *sa__, uint8_t addr, int8_t wr_val) { 313 return (merlin16_wrbc_uc_var(sa__, addr, wr_val)); 314 } 315 316 /* Micro RAM Core Word Write */ 317 err_code_t merlin16_wrwc_uc_var(srds_access_t *sa__, uint8_t addr, uint16_t wr_val) { 318 uint8_t lane; 319 uint16_t core_addr_offset; 320 321 { 322 if (addr%2 != 0) { /* Validate even address */ 323 return (_error(ERR_CODE_INVALID_RAM_ADDR)); 324 } 325 326 lane = merlin16_get_physical_lane(sa__); 327 core_addr_offset = merlin16_INTERNAL_get_core_address(addr,lane); 328 return (merlin16_wrw_uc_ram(sa__, core_addr_offset, wr_val)); /* Use Micro register interface for writing RAM */ 329 } 330 } 331 332 /* Micro RAM Core Word Signed Write */ 333 err_code_t merlin16_wrwcs_uc_var(srds_access_t *sa__, uint8_t addr, int16_t wr_val) { 334 return(merlin16_wrwc_uc_var(sa__, addr,wr_val)); 335 } 336 337 /*********************************************************/ 338 /* Program RAM access through Micro Register Interface */ 339 /*********************************************************/ 340 341 /* Micro Program Ram Long Read */ 342 uint32_t merlin16_rd_long_uc_prog_ram(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) { 343 uint32_t rddata; 344 if(!err_code_p) { 345 return(0); 346 } 347 *err_code_p = ERR_CODE_NONE; 348 EPFUN(wrc_micro_autoinc_rdaddr_en(1)); 349 EPFUN(wrc_micro_ra_rddatasize(0x1)); /* Select 16bit read datasize */ 350 EPFUN(wrc_micro_ra_rdaddr_msw(0)); /* Upper 16bits of ROM address to be read */ 351 EPFUN(wrc_micro_ra_rdaddr_lsw(addr)); /* Lower 16bits of ROM address to be read */ 352 EPSTM(rddata = rdc_micro_ra_rddata_lsw()); /* 16bit read data */ 353 EPSTM(rddata |= (rdc_micro_ra_rddata_lsw() << 16)); /* 16bit read data */ 354 return (rddata); 355 } 356 357 /* Micro Program RAM Block Read */ 358 err_code_t merlin16_rdblk_uc_prog_ram(srds_access_t *sa__, uint8_t *mem, uint16_t addr, uint16_t cnt) { 359 merlin16_INTERNAL_rdblk_callback_arg_t arg; 360 361 if(!mem) { 362 return(_error(ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 363 } 364 365 arg.mem_ptr = mem; 366 return merlin16_INTERNAL_rdblk_uc_generic_ram(sa__, addr, cnt, 0, cnt, &arg, merlin16_INTERNAL_rdblk_callback); 367 } 368 369 /*************************************************/ 370 /* RAM access through Micro Register Interface */ 371 /*************************************************/ 372 373 /* Micro RAM Long Write */ 374 err_code_t merlin16_wr_long_uc_ram(srds_access_t *sa__, uint16_t offset, uint32_t value) { 375 EFUN(merlin16_wrw_uc_ram(sa__, offset+2, value >> 16)); 376 EFUN(merlin16_wrw_uc_ram(sa__, offset, value & 0xFFFF)); 377 return (ERR_CODE_NONE); 378 } 379 /* Micro RAM Word Write */ 380 err_code_t merlin16_wrw_uc_ram(srds_access_t *sa__, uint16_t addr, uint16_t wr_val) { 381 382 EFUN(wrc_micro_autoinc_wraddr_en(0)); 383 EFUN(wrc_micro_ra_wrdatasize(0x1)); /* Select 16bit write datasize */ 384 EFUN(wrc_micro_ra_wraddr_msw(0x2000)); /* Upper 16bits of RAM address to be written to */ 385 EFUN(wrc_micro_ra_wraddr_lsw(addr)); /* Lower 16bits of RAM address to be written to */ 386 EFUN(wrc_micro_ra_wrdata_lsw(wr_val)); /* uC RAM lower 16bits write data */ 387 return (ERR_CODE_NONE); 388 } 389 390 /* Micro RAM Byte Write */ 391 err_code_t merlin16_wrb_uc_ram(srds_access_t *sa__, uint16_t addr, uint8_t wr_val) { 392 EFUN(wrc_micro_autoinc_wraddr_en(0)); 393 EFUN(wrc_micro_ra_wrdatasize(0x0)); /* Select 8bit write datasize */ 394 EFUN(wrc_micro_ra_wraddr_msw(0x2000)); /* Upper 16bits of RAM address to be written to */ 395 EFUN(wrc_micro_ra_wraddr_lsw(addr)); /* Lower 16bits of RAM address to be written to */ 396 EFUN(wrc_micro_ra_wrdata_lsw(wr_val)); /* uC RAM lower 16bits write data */ 397 return (ERR_CODE_NONE); 398 } 399 400 /* Micro RAM Long Read */ 401 uint32_t merlin16_rd_long_uc_ram(srds_access_t *sa__, err_code_t *err, uint16_t offset) { 402 uint32_t result; 403 ESTM(result = merlin16_rdw_uc_ram(sa__, err, offset+2) << 16); 404 ESTM(result |= merlin16_rdw_uc_ram(sa__, err, offset) & 0xFFFF); 405 return result; 406 } 407 /* Micro RAM Word Read */ 408 uint16_t merlin16_rdw_uc_ram(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) { 409 uint16_t rddata; 410 if(!err_code_p) { 411 return(0); 412 } 413 *err_code_p = ERR_CODE_NONE; 414 EPFUN(wrc_micro_autoinc_rdaddr_en(0)); 415 EPFUN(wrc_micro_ra_rddatasize(0x1)); /* Select 16bit read datasize */ 416 EPFUN(wrc_micro_ra_rdaddr_msw(0x2000)); /* Upper 16bits of RAM address to be read */ 417 EPFUN(wrc_micro_ra_rdaddr_lsw(addr)); /* Lower 16bits of RAM address to be read */ 418 EPSTM(rddata = rdc_micro_ra_rddata_lsw()); /* 16bit read data */ 419 return (rddata); 420 } 421 422 /* Micro RAM Byte Read */ 423 uint8_t merlin16_rdb_uc_ram(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) { 424 uint8_t rddata; 425 if(!err_code_p) { 426 return(0); 427 } 428 *err_code_p = ERR_CODE_NONE; 429 EPFUN(wrc_micro_autoinc_rdaddr_en(0)); 430 EPFUN(wrc_micro_ra_rddatasize(0x0)); /* Select 8bit read datasize */ 431 EPFUN(wrc_micro_ra_rdaddr_msw(0x2000)); /* Upper 16bits of RAM address to be read */ 432 EPFUN(wrc_micro_ra_rdaddr_lsw(addr)); /* Lower 16bits of RAM address to be read */ 433 EPSTM(rddata = (uint8_t) rdc_micro_ra_rddata_lsw()); /* 16bit read data */ 434 return (rddata); 435 } 436 437 /* Micro RAM Word Signed Write */ 438 err_code_t merlin16_wrws_uc_ram(srds_access_t *sa__, uint16_t addr, int16_t wr_val) { 439 return (merlin16_wrw_uc_ram(sa__, addr, wr_val)); 440 } 441 442 /* Micro RAM Byte Signed Write */ 443 err_code_t merlin16_wrbs_uc_ram(srds_access_t *sa__, uint16_t addr, int8_t wr_val) { 444 return (merlin16_wrb_uc_ram(sa__, addr, wr_val)); 445 } 446 447 /* Micro RAM Word Signed Read */ 448 int16_t merlin16_rdws_uc_ram(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) { 449 return ((int16_t)merlin16_rdw_uc_ram(sa__, err_code_p, addr)); 450 } 451 452 /* Micro RAM Byte Signed Read */ 453 int8_t merlin16_rdbs_uc_ram(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) { 454 return ((int8_t)merlin16_rdb_uc_ram(sa__, err_code_p, addr)); 455 } 456 457 /* Micro RAM Block Read */ 458 err_code_t merlin16_rdblk_uc_ram(srds_access_t *sa__, uint8_t *mem, uint16_t addr, uint16_t cnt) { 459 merlin16_INTERNAL_rdblk_callback_arg_t arg; 460 461 if(!mem) { 462 return(_error(ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 463 } 464 465 arg.mem_ptr = mem; 466 return merlin16_INTERNAL_rdblk_uc_generic_ram(sa__, (uint32_t)addr | 0x20000000, cnt, 0, cnt, &arg, merlin16_INTERNAL_rdblk_callback); 467 } 468 469 /**************************/ 470 /* Temperature reading */ 471 /**************************/ 472 473 err_code_t merlin16_read_die_temperature (srds_access_t *sa__, int16_t *die_temp) { 474 475 uint16_t die_temp_sensor_reading; 476 477 ESTM(die_temp_sensor_reading=rdc_micro_pvt_tempdata_rmi()); 478 *die_temp = _bin_to_degC(die_temp_sensor_reading); 479 480 return(ERR_CODE_NONE); 481 } 482 483 484 err_code_t merlin16_read_die_temperature_double (srds_access_t *sa__, USR_DOUBLE *die_temp) { 485 #ifdef SERDES_API_FLOATING_POINT 486 uint16_t die_temp_sensor_reading; 487 488 ESTM(die_temp_sensor_reading=rdc_micro_pvt_tempdata_rmi()); 489 490 *die_temp = _bin_to_degC_double(die_temp_sensor_reading); 491 492 return(ERR_CODE_NONE); 493 #else 494 *die_temp = 0; 495 EFUN_PRINTF((" Function 'merlin16_read_die_temperature_double' needs SERDES_API_FLOATING_POINT defined to operate \n")); 496 return(_error(ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 497 #endif 498 } 499