merlin16_pcieg3_access.c (20878B)
1 /*********************************************************************************** 2 *********************************************************************************** 3 * File Name : merlin16_pcieg3_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_pcieg3_access.c 23 * Implementation of API uC access functions 24 */ 25 26 #include "merlin16_pcieg3_access.h" 27 #include "merlin16_pcieg3_common.h" 28 #include "merlin16_pcieg3_functions.h" 29 #include "merlin16_pcieg3_internal.h" 30 #include "merlin16_pcieg3_internal_error.h" 31 #include "merlin16_pcieg3_select_defns.h" 32 33 34 /******************************************************/ 35 /* Commands through Serdes FW DSC Command Interface */ 36 /******************************************************/ 37 38 err_code_t merlin16_pcieg3_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_pcieg3_INTERNAL_poll_uc_dsc_ready_for_cmd_equals_1(sa__, 1, cmd); /* Poll for uc_dsc_ready_for_cmd = 1 to indicate merlin16_pcieg3 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_pcieg3_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_pcieg3_pmd_uc_cmd_return_immediate(sa__, cmd, supp_info)); /* Invoke merlin16_pcieg3_uc_cmd and return control immediately */ 61 62 EFUN(merlin16_pcieg3_INTERNAL_poll_uc_dsc_ready_for_cmd_equals_1(sa__, timeout_ms, cmd)); /* Poll for uc_dsc_ready_for_cmd = 1 to indicate merlin16_pcieg3 ready for command */ 63 64 return(ERR_CODE_NONE); 65 } 66 67 68 err_code_t merlin16_pcieg3_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_pcieg3_INTERNAL_poll_uc_dsc_ready_for_cmd_equals_1(sa__, 1, cmd); /* Poll for uc_dsc_ready_for_cmd = 1 to indicate merlin16_pcieg3 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_pcieg3_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_pcieg3_pmd_uc_cmd_with_data_return_immediate(sa__, cmd, supp_info, data)); /* Invoke merlin16_pcieg3_uc_cmd and return control immediately */ 94 95 EFUN(merlin16_pcieg3_INTERNAL_poll_uc_dsc_ready_for_cmd_equals_1(sa__, timeout_ms, cmd)); /* Poll for uc_dsc_ready_for_cmd = 1 to indicate merlin16_pcieg3 ready for command */ 96 return(ERR_CODE_NONE); 97 } 98 99 err_code_t merlin16_pcieg3_pmd_uc_control_return_immediate(srds_access_t *sa__, enum srds_pmd_uc_ctrl_cmd_enum control) { 100 return(merlin16_pcieg3_pmd_uc_cmd_return_immediate(sa__, CMD_UC_CTRL, (uint8_t) control)); 101 } 102 103 err_code_t merlin16_pcieg3_pmd_uc_control(srds_access_t *sa__, enum srds_pmd_uc_ctrl_cmd_enum control, uint32_t timeout_ms) { 104 return(merlin16_pcieg3_pmd_uc_cmd(sa__, CMD_UC_CTRL, (uint8_t) control, timeout_ms)); 105 } 106 107 err_code_t merlin16_pcieg3_pmd_uc_diag_cmd(srds_access_t *sa__, enum srds_pmd_uc_diag_cmd_enum control, uint32_t timeout_ms) { 108 return(merlin16_pcieg3_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_pcieg3_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_pcieg3_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_pcieg3_get_lane(sa__); 141 lane_addr_offset = merlin16_pcieg3_INTERNAL_get_lane_addr(addr,lane); 142 143 EPSTM(rddata = merlin16_pcieg3_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_pcieg3_rdbls_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) { 150 return ((int8_t) merlin16_pcieg3_rdbl_uc_var(sa__, err_code_p, addr)); 151 } 152 153 /* Micro RAM Lane Word Read */ 154 uint16_t merlin16_pcieg3_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_pcieg3_get_lane(sa__); 169 lane_addr_offset = merlin16_pcieg3_INTERNAL_get_lane_addr(addr,lane); 170 171 EPSTM(rddata = merlin16_pcieg3_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_pcieg3_rdwls_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) { 179 return ((int16_t) merlin16_pcieg3_rdwl_uc_var(sa__, err_code_p, addr)); 180 } 181 182 /* Micro RAM Lane Byte Write */ 183 err_code_t merlin16_pcieg3_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_pcieg3_get_lane(sa__); 190 lane_addr_offset = merlin16_pcieg3_INTERNAL_get_lane_addr(addr,lane); 191 192 return (merlin16_pcieg3_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_pcieg3_wrbls_uc_var(srds_access_t *sa__, uint16_t addr, int8_t wr_val) { 198 return (merlin16_pcieg3_wrbl_uc_var(sa__, addr, wr_val)); 199 } 200 201 /* Micro RAM Lane Word Write */ 202 err_code_t merlin16_pcieg3_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 lane = merlin16_pcieg3_get_lane(sa__); 211 lane_addr_offset = merlin16_pcieg3_INTERNAL_get_lane_addr(addr,lane); 212 213 return (merlin16_pcieg3_wrw_uc_ram(sa__, lane_addr_offset, wr_val)); /* Use Micro register interface for writing RAM */ 214 215 216 } 217 218 /* Micro RAM Lane Word Signed Write */ 219 err_code_t merlin16_pcieg3_wrwls_uc_var(srds_access_t *sa__, uint16_t addr, int16_t wr_val) { 220 return (merlin16_pcieg3_wrwl_uc_var(sa__, addr,wr_val)); 221 } 222 223 224 225 226 /************************************************************/ 227 /* Serdes IP RAM access - Core RAM Variables */ 228 /*----------------------------------------------------------*/ 229 /* - through Micro Register Interface for PMD IPs */ 230 /* - through Serdes FW DSC Command Interface for Gallardo */ 231 /************************************************************/ 232 233 /* This function returns the absolute address of core RAM variables given the offset address and lane */ 234 uint16_t merlin16_pcieg3_INTERNAL_get_core_address(uint16_t addr, uint8_t lane) { 235 uint16_t core_var_ram_base=0; 236 uint16_t core_addr_offset = 0; 237 238 core_var_ram_base = CORE_VAR_RAM_BASE; 239 core_addr_offset = core_var_ram_base + addr; 240 241 return(core_addr_offset); 242 } 243 244 /* Micro RAM Core Byte Read */ 245 uint8_t merlin16_pcieg3_rdbc_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint8_t addr) { 246 247 uint8_t rddata; 248 uint8_t lane; 249 uint16_t core_addr_offset; 250 if(!err_code_p) { 251 return(0); 252 } 253 254 lane = merlin16_pcieg3_get_lane(sa__); 255 core_addr_offset = merlin16_pcieg3_INTERNAL_get_core_address(addr,lane); 256 EPSTM(rddata = merlin16_pcieg3_rdb_uc_ram(sa__, err_code_p, core_addr_offset)); /* Use Micro register interface for reading RAM */ 257 return (rddata); 258 259 } 260 261 /* Micro RAM Core Byte Signed Read */ 262 int8_t merlin16_pcieg3_rdbcs_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint8_t addr) { 263 return ((int8_t) merlin16_pcieg3_rdbc_uc_var(sa__, err_code_p, addr)); 264 } 265 266 /* Micro RAM Core Word Read */ 267 uint16_t merlin16_pcieg3_rdwc_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint8_t addr) { 268 uint16_t rddata; 269 uint8_t lane; 270 uint16_t core_addr_offset; 271 272 if(!err_code_p) { 273 return(0); 274 } 275 if (addr%2 != 0) { /* Validate even address */ 276 *err_code_p = ERR_CODE_INVALID_RAM_ADDR; 277 return (0); 278 } 279 280 lane = merlin16_pcieg3_get_lane(sa__); 281 core_addr_offset = merlin16_pcieg3_INTERNAL_get_core_address(addr,lane); 282 283 EPSTM(rddata = merlin16_pcieg3_rdw_uc_ram(sa__, err_code_p, core_addr_offset)); /* Use Micro register interface for reading RAM */ 284 return (rddata); 285 286 } 287 288 /* Micro RAM Core Word Signed Read */ 289 int16_t merlin16_pcieg3_rdwcs_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint8_t addr) { 290 return ((int16_t) merlin16_pcieg3_rdwc_uc_var(sa__, err_code_p, addr)); 291 } 292 293 /* Micro RAM Core Byte Write */ 294 err_code_t merlin16_pcieg3_wrbc_uc_var(srds_access_t *sa__, uint8_t addr, uint8_t wr_val) { 295 uint8_t lane; 296 uint16_t core_addr_offset; 297 298 lane = merlin16_pcieg3_get_lane(sa__); 299 core_addr_offset = merlin16_pcieg3_INTERNAL_get_core_address(addr,lane); 300 301 return (merlin16_pcieg3_wrb_uc_ram(sa__, core_addr_offset, wr_val)); /* Use Micro register interface for writing RAM */ 302 303 304 } 305 306 307 /* Micro RAM Core Byte Signed Write */ 308 err_code_t merlin16_pcieg3_wrbcs_uc_var(srds_access_t *sa__, uint8_t addr, int8_t wr_val) { 309 return (merlin16_pcieg3_wrbc_uc_var(sa__, addr, wr_val)); 310 } 311 312 /* Micro RAM Core Word Write */ 313 err_code_t merlin16_pcieg3_wrwc_uc_var(srds_access_t *sa__, uint8_t addr, uint16_t wr_val) { 314 uint8_t lane; 315 uint16_t core_addr_offset; 316 317 318 if (addr%2 != 0) { /* Validate even address */ 319 return (_error(ERR_CODE_INVALID_RAM_ADDR)); 320 } 321 322 lane = merlin16_pcieg3_get_lane(sa__); 323 core_addr_offset = merlin16_pcieg3_INTERNAL_get_core_address(addr,lane); 324 return (merlin16_pcieg3_wrw_uc_ram(sa__, core_addr_offset, wr_val)); /* Use Micro register interface for writing RAM */ 325 326 } 327 328 /* Micro RAM Core Word Signed Write */ 329 err_code_t merlin16_pcieg3_wrwcs_uc_var(srds_access_t *sa__, uint8_t addr, int16_t wr_val) { 330 return(merlin16_pcieg3_wrwc_uc_var(sa__, addr,wr_val)); 331 } 332 333 /*********************************************************/ 334 /* Program RAM access through Micro Register Interface */ 335 /*********************************************************/ 336 337 /* Micro Program Ram Long Read */ 338 uint32_t merlin16_pcieg3_rd_long_uc_prog_ram(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) { 339 uint32_t rddata; 340 if(!err_code_p) { 341 return(0); 342 } 343 *err_code_p = ERR_CODE_NONE; 344 EPFUN(wrc_micro_autoinc_rdaddr_en(1)); 345 EPFUN(wrc_micro_ra_rddatasize(0x1)); /* Select 16bit read datasize */ 346 EPFUN(wrc_micro_ra_rdaddr_msw(0)); /* Upper 16bits of ROM address to be read */ 347 EPFUN(wrc_micro_ra_rdaddr_lsw(addr)); /* Lower 16bits of ROM address to be read */ 348 EPSTM(rddata = rdc_micro_ra_rddata_lsw()); /* 16bit read data */ 349 EPSTM(rddata |= (rdc_micro_ra_rddata_lsw() << 16)); /* 16bit read data */ 350 return (rddata); 351 } 352 353 /* Micro Program RAM Block Read */ 354 err_code_t merlin16_pcieg3_rdblk_uc_prog_ram(srds_access_t *sa__, uint8_t *mem, uint16_t addr, uint16_t cnt) { 355 merlin16_pcieg3_INTERNAL_rdblk_callback_arg_t arg; 356 357 if(!mem) { 358 return(_error(ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 359 } 360 361 arg.mem_ptr = mem; 362 return merlin16_pcieg3_INTERNAL_rdblk_uc_generic_ram(sa__, addr, cnt, 0, cnt, &arg, merlin16_pcieg3_INTERNAL_rdblk_callback); 363 } 364 365 /*************************************************/ 366 /* RAM access through Micro Register Interface */ 367 /*************************************************/ 368 369 /* Micro RAM Long Write */ 370 err_code_t merlin16_pcieg3_wr_long_uc_ram(srds_access_t *sa__, uint16_t offset, uint32_t value) { 371 EFUN(merlin16_pcieg3_wrw_uc_ram(sa__, offset+2, value >> 16)); 372 EFUN(merlin16_pcieg3_wrw_uc_ram(sa__, offset, value & 0xFFFF)); 373 return (ERR_CODE_NONE); 374 } 375 /* Micro RAM Word Write */ 376 err_code_t merlin16_pcieg3_wrw_uc_ram(srds_access_t *sa__, uint16_t addr, uint16_t wr_val) { 377 378 EFUN(wrc_micro_autoinc_wraddr_en(0)); 379 EFUN(wrc_micro_ra_wrdatasize(0x1)); /* Select 16bit write datasize */ 380 EFUN(wrc_micro_ra_wraddr_msw(0x2000)); /* Upper 16bits of RAM address to be written to */ 381 EFUN(wrc_micro_ra_wraddr_lsw(addr)); /* Lower 16bits of RAM address to be written to */ 382 EFUN(wrc_micro_ra_wrdata_lsw(wr_val)); /* uC RAM lower 16bits write data */ 383 return (ERR_CODE_NONE); 384 } 385 386 /* Micro RAM Byte Write */ 387 err_code_t merlin16_pcieg3_wrb_uc_ram(srds_access_t *sa__, uint16_t addr, uint8_t wr_val) { 388 EFUN(wrc_micro_autoinc_wraddr_en(0)); 389 EFUN(wrc_micro_ra_wrdatasize(0x0)); /* Select 8bit write datasize */ 390 EFUN(wrc_micro_ra_wraddr_msw(0x2000)); /* Upper 16bits of RAM address to be written to */ 391 EFUN(wrc_micro_ra_wraddr_lsw(addr)); /* Lower 16bits of RAM address to be written to */ 392 EFUN(wrc_micro_ra_wrdata_lsw(wr_val)); /* uC RAM lower 16bits write data */ 393 return (ERR_CODE_NONE); 394 } 395 396 /* Micro RAM Long Read */ 397 uint32_t merlin16_pcieg3_rd_long_uc_ram(srds_access_t *sa__, err_code_t *err, uint16_t offset) { 398 uint32_t result; 399 ESTM(result = merlin16_pcieg3_rdw_uc_ram(sa__, err, offset+2) << 16); 400 ESTM(result |= merlin16_pcieg3_rdw_uc_ram(sa__, err, offset) & 0xFFFF); 401 return result; 402 } 403 /* Micro RAM Word Read */ 404 uint16_t merlin16_pcieg3_rdw_uc_ram(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) { 405 uint16_t rddata; 406 if(!err_code_p) { 407 return(0); 408 } 409 *err_code_p = ERR_CODE_NONE; 410 EPFUN(wrc_micro_autoinc_rdaddr_en(0)); 411 EPFUN(wrc_micro_ra_rddatasize(0x1)); /* Select 16bit read datasize */ 412 EPFUN(wrc_micro_ra_rdaddr_msw(0x2000)); /* Upper 16bits of RAM address to be read */ 413 EPFUN(wrc_micro_ra_rdaddr_lsw(addr)); /* Lower 16bits of RAM address to be read */ 414 EPSTM(rddata = rdc_micro_ra_rddata_lsw()); /* 16bit read data */ 415 return (rddata); 416 } 417 418 /* Micro RAM Byte Read */ 419 uint8_t merlin16_pcieg3_rdb_uc_ram(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) { 420 uint8_t rddata; 421 if(!err_code_p) { 422 return(0); 423 } 424 *err_code_p = ERR_CODE_NONE; 425 EPFUN(wrc_micro_autoinc_rdaddr_en(0)); 426 EPFUN(wrc_micro_ra_rddatasize(0x0)); /* Select 8bit read datasize */ 427 EPFUN(wrc_micro_ra_rdaddr_msw(0x2000)); /* Upper 16bits of RAM address to be read */ 428 EPFUN(wrc_micro_ra_rdaddr_lsw(addr)); /* Lower 16bits of RAM address to be read */ 429 EPSTM(rddata = (uint8_t) rdc_micro_ra_rddata_lsw()); /* 16bit read data */ 430 return (rddata); 431 } 432 433 /* Micro RAM Word Signed Write */ 434 err_code_t merlin16_pcieg3_wrws_uc_ram(srds_access_t *sa__, uint16_t addr, int16_t wr_val) { 435 return (merlin16_pcieg3_wrw_uc_ram(sa__, addr, wr_val)); 436 } 437 438 /* Micro RAM Byte Signed Write */ 439 err_code_t merlin16_pcieg3_wrbs_uc_ram(srds_access_t *sa__, uint16_t addr, int8_t wr_val) { 440 return (merlin16_pcieg3_wrb_uc_ram(sa__, addr, wr_val)); 441 } 442 443 /* Micro RAM Word Signed Read */ 444 int16_t merlin16_pcieg3_rdws_uc_ram(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) { 445 return ((int16_t)merlin16_pcieg3_rdw_uc_ram(sa__, err_code_p, addr)); 446 } 447 448 /* Micro RAM Byte Signed Read */ 449 int8_t merlin16_pcieg3_rdbs_uc_ram(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) { 450 return ((int8_t)merlin16_pcieg3_rdb_uc_ram(sa__, err_code_p, addr)); 451 } 452 453 /* Micro RAM Block Read */ 454 err_code_t merlin16_pcieg3_rdblk_uc_ram(srds_access_t *sa__, uint8_t *mem, uint16_t addr, uint16_t cnt) { 455 merlin16_pcieg3_INTERNAL_rdblk_callback_arg_t arg; 456 457 if(!mem) { 458 return(_error(ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 459 } 460 461 arg.mem_ptr = mem; 462 return merlin16_pcieg3_INTERNAL_rdblk_uc_generic_ram(sa__, (uint32_t)addr | 0x20000000, cnt, 0, cnt, &arg, merlin16_pcieg3_INTERNAL_rdblk_callback); 463 } 464 465 /**************************/ 466 /* Temperature reading */ 467 /**************************/ 468 469 err_code_t merlin16_pcieg3_read_die_temperature (srds_access_t *sa__, int16_t *die_temp) { 470 471 uint16_t die_temp_sensor_reading; 472 473 ESTM(die_temp_sensor_reading=rdc_micro_pvt_tempdata_rmi()); 474 *die_temp = _bin_to_degC(die_temp_sensor_reading); 475 476 return(ERR_CODE_NONE); 477 } 478 479 480 err_code_t merlin16_pcieg3_read_die_temperature_double (srds_access_t *sa__, USR_DOUBLE *die_temp) { 481 #ifdef SERDES_API_FLOATING_POINT 482 uint16_t die_temp_sensor_reading; 483 484 ESTM(die_temp_sensor_reading=rdc_micro_pvt_tempdata_rmi()); 485 486 *die_temp = _bin_to_degC_double(die_temp_sensor_reading); 487 488 return(ERR_CODE_NONE); 489 #else 490 *die_temp = 0; 491 EFUN_PRINTF((" Function 'merlin16_pcieg3_read_die_temperature_double' needs SERDES_API_FLOATING_POINT defined to operate \n")); 492 return(_error(ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 493 #endif 494 } 495