1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) 2 * Copyright 2019-2021 NXP 3 */ 4 #include <fsl_mc_sys.h> 5 #include <fsl_mc_cmd.h> 6 #include <fsl_dprtc.h> 7 #include <fsl_dprtc_cmd.h> 8 9 /** @addtogroup dprtc 10 * @{ 11 */ 12 13 /** 14 * dprtc_open() - Open a control session for the specified object. 15 * @mc_io: Pointer to MC portal's I/O object 16 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 17 * @dprtc_id: DPRTC unique ID 18 * @token: Returned token; use in subsequent API calls 19 * 20 * This function can be used to open a control session for an 21 * already created object; an object may have been declared in 22 * the DPL or by calling the dprtc_create function. 23 * This function returns a unique authentication token, 24 * associated with the specific object ID and the specific MC 25 * portal; this token must be used in all subsequent commands for 26 * this specific object 27 * 28 * Return: '0' on Success; Error code otherwise. 29 */ 30 int dprtc_open(struct fsl_mc_io *mc_io, 31 uint32_t cmd_flags, 32 int dprtc_id, 33 uint16_t *token) 34 { 35 struct dprtc_cmd_open *cmd_params; 36 struct mc_command cmd = { 0 }; 37 int err; 38 39 /* prepare command */ 40 cmd.header = mc_encode_cmd_header(DPRTC_CMDID_OPEN, 41 cmd_flags, 42 0); 43 cmd_params = (struct dprtc_cmd_open *)cmd.params; 44 cmd_params->dprtc_id = cpu_to_le32(dprtc_id); 45 46 /* send command to mc*/ 47 err = mc_send_command(mc_io, &cmd); 48 if (err) 49 return err; 50 51 /* retrieve response parameters */ 52 *token = mc_cmd_hdr_read_token(&cmd); 53 54 return err; 55 } 56 57 /** 58 * dprtc_close() - Close the control session of the object 59 * @mc_io: Pointer to MC portal's I/O object 60 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 61 * @token: Token of DPRTC object 62 * 63 * After this function is called, no further operations are 64 * allowed on the object without opening a new control session. 65 * 66 * Return: '0' on Success; Error code otherwise. 67 */ 68 int dprtc_close(struct fsl_mc_io *mc_io, 69 uint32_t cmd_flags, 70 uint16_t token) 71 { 72 struct mc_command cmd = { 0 }; 73 74 /* prepare command */ 75 cmd.header = mc_encode_cmd_header(DPRTC_CMDID_CLOSE, cmd_flags, 76 token); 77 78 /* send command to mc*/ 79 return mc_send_command(mc_io, &cmd); 80 } 81 82 /** 83 * dprtc_create() - Create the DPRTC object. 84 * @mc_io: Pointer to MC portal's I/O object 85 * @dprc_token: Parent container token; '0' for default container 86 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 87 * @cfg: Configuration structure 88 * @obj_id: Returned object id 89 * 90 * Create the DPRTC object, allocate required resources and 91 * perform required initialization. 92 * 93 * The function accepts an authentication token of a parent 94 * container that this object should be assigned to. The token 95 * can be '0' so the object will be assigned to the default container. 96 * The newly created object can be opened with the returned 97 * object id and using the container's associated tokens and MC portals. 98 * 99 * Return: '0' on Success; Error code otherwise. 100 */ 101 int dprtc_create(struct fsl_mc_io *mc_io, 102 uint16_t dprc_token, 103 uint32_t cmd_flags, 104 const struct dprtc_cfg *cfg, 105 uint32_t *obj_id) 106 { 107 struct mc_command cmd = { 0 }; 108 int err; 109 110 (void)(cfg); /* unused */ 111 112 /* prepare command */ 113 cmd.header = mc_encode_cmd_header(DPRTC_CMDID_CREATE, 114 cmd_flags, 115 dprc_token); 116 117 /* send command to mc*/ 118 err = mc_send_command(mc_io, &cmd); 119 if (err) 120 return err; 121 122 /* retrieve response parameters */ 123 *obj_id = mc_cmd_read_object_id(&cmd); 124 125 return 0; 126 } 127 128 /** 129 * dprtc_destroy() - Destroy the DPRTC object and release all its resources. 130 * @mc_io: Pointer to MC portal's I/O object 131 * @dprc_token: Parent container token; '0' for default container 132 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 133 * @object_id: The object id; it must be a valid id within the container that 134 * created this object; 135 * 136 * The function accepts the authentication token of the parent container that 137 * created the object (not the one that currently owns the object). The object 138 * is searched within parent using the provided 'object_id'. 139 * All tokens to the object must be closed before calling destroy. 140 * 141 * Return: '0' on Success; error code otherwise. 142 */ 143 int dprtc_destroy(struct fsl_mc_io *mc_io, 144 uint16_t dprc_token, 145 uint32_t cmd_flags, 146 uint32_t object_id) 147 { 148 struct dprtc_cmd_destroy *cmd_params; 149 struct mc_command cmd = { 0 }; 150 151 /* prepare command */ 152 cmd.header = mc_encode_cmd_header(DPRTC_CMDID_DESTROY, 153 cmd_flags, 154 dprc_token); 155 cmd_params = (struct dprtc_cmd_destroy *)cmd.params; 156 cmd_params->object_id = cpu_to_le32(object_id); 157 158 /* send command to mc*/ 159 return mc_send_command(mc_io, &cmd); 160 } 161 162 /** 163 * dprtc_enable() - Enable the DPRTC. 164 * @mc_io: Pointer to MC portal's I/O object 165 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 166 * @token: Token of DPRTC object 167 * 168 * Return: '0' on Success; Error code otherwise. 169 */ 170 int dprtc_enable(struct fsl_mc_io *mc_io, 171 uint32_t cmd_flags, 172 uint16_t token) 173 { 174 struct mc_command cmd = { 0 }; 175 176 /* prepare command */ 177 cmd.header = mc_encode_cmd_header(DPRTC_CMDID_ENABLE, cmd_flags, 178 token); 179 180 /* send command to mc*/ 181 return mc_send_command(mc_io, &cmd); 182 } 183 184 /** 185 * dprtc_disable() - Disable the DPRTC. 186 * @mc_io: Pointer to MC portal's I/O object 187 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 188 * @token: Token of DPRTC object 189 * 190 * Return: '0' on Success; Error code otherwise. 191 */ 192 int dprtc_disable(struct fsl_mc_io *mc_io, 193 uint32_t cmd_flags, 194 uint16_t token) 195 { 196 struct mc_command cmd = { 0 }; 197 198 /* prepare command */ 199 cmd.header = mc_encode_cmd_header(DPRTC_CMDID_DISABLE, 200 cmd_flags, 201 token); 202 203 /* send command to mc*/ 204 return mc_send_command(mc_io, &cmd); 205 } 206 207 /** 208 * dprtc_is_enabled() - Check if the DPRTC is enabled. 209 * @mc_io: Pointer to MC portal's I/O object 210 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 211 * @token: Token of DPRTC object 212 * @en: Returns '1' if object is enabled; '0' otherwise 213 * 214 * Return: '0' on Success; Error code otherwise. 215 */ 216 int dprtc_is_enabled(struct fsl_mc_io *mc_io, 217 uint32_t cmd_flags, 218 uint16_t token, 219 int *en) 220 { 221 struct dprtc_rsp_is_enabled *rsp_params; 222 struct mc_command cmd = { 0 }; 223 int err; 224 225 /* prepare command */ 226 cmd.header = mc_encode_cmd_header(DPRTC_CMDID_IS_ENABLED, cmd_flags, 227 token); 228 229 /* send command to mc*/ 230 err = mc_send_command(mc_io, &cmd); 231 if (err) 232 return err; 233 234 /* retrieve response parameters */ 235 rsp_params = (struct dprtc_rsp_is_enabled *)cmd.params; 236 *en = dprtc_get_field(rsp_params->en, ENABLE); 237 238 return 0; 239 } 240 241 /** 242 * dprtc_reset() - Reset the DPRTC, returns the object to initial state. 243 * @mc_io: Pointer to MC portal's I/O object 244 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 245 * @token: Token of DPRTC object 246 * 247 * Return: '0' on Success; Error code otherwise. 248 */ 249 int dprtc_reset(struct fsl_mc_io *mc_io, 250 uint32_t cmd_flags, 251 uint16_t token) 252 { 253 struct mc_command cmd = { 0 }; 254 255 /* prepare command */ 256 cmd.header = mc_encode_cmd_header(DPRTC_CMDID_RESET, 257 cmd_flags, 258 token); 259 260 /* send command to mc*/ 261 return mc_send_command(mc_io, &cmd); 262 } 263 264 /** 265 * dprtc_get_attributes - Retrieve DPRTC attributes. 266 * 267 * @mc_io: Pointer to MC portal's I/O object 268 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 269 * @token: Token of DPRTC object 270 * @attr: Returned object's attributes 271 * 272 * Return: '0' on Success; Error code otherwise. 273 */ 274 int dprtc_get_attributes(struct fsl_mc_io *mc_io, 275 uint32_t cmd_flags, 276 uint16_t token, 277 struct dprtc_attr *attr) 278 { 279 struct dprtc_rsp_get_attributes *rsp_params; 280 struct mc_command cmd = { 0 }; 281 int err; 282 283 /* prepare command */ 284 cmd.header = mc_encode_cmd_header(DPRTC_CMDID_GET_ATTR, 285 cmd_flags, 286 token); 287 288 /* send command to mc*/ 289 err = mc_send_command(mc_io, &cmd); 290 if (err) 291 return err; 292 293 /* retrieve response parameters */ 294 rsp_params = (struct dprtc_rsp_get_attributes *)cmd.params; 295 attr->id = le32_to_cpu(rsp_params->id); 296 attr->paddr = le32_to_cpu(rsp_params->paddr); 297 attr->little_endian = 298 dprtc_get_field(rsp_params->little_endian, ENDIANNESS); 299 return 0; 300 } 301 302 /** 303 * dprtc_set_clock_offset() - Sets the clock's offset 304 * (usually relative to another clock). 305 * 306 * @mc_io: Pointer to MC portal's I/O object 307 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 308 * @token: Token of DPRTC object 309 * @offset: New clock offset (in nanoseconds). 310 * 311 * Return: '0' on Success; Error code otherwise. 312 */ 313 int dprtc_set_clock_offset(struct fsl_mc_io *mc_io, 314 uint32_t cmd_flags, 315 uint16_t token, 316 int64_t offset) 317 { 318 struct dprtc_cmd_set_clock_offset *cmd_params; 319 struct mc_command cmd = { 0 }; 320 321 /* prepare command */ 322 cmd.header = mc_encode_cmd_header(DPRTC_CMDID_SET_CLOCK_OFFSET, 323 cmd_flags, 324 token); 325 cmd_params = (struct dprtc_cmd_set_clock_offset *)cmd.params; 326 cmd_params->offset = cpu_to_le64(offset); 327 328 /* send command to mc*/ 329 return mc_send_command(mc_io, &cmd); 330 } 331 332 /** 333 * dprtc_set_freq_compensation() - Sets a new frequency compensation value. 334 * 335 * @mc_io: Pointer to MC portal's I/O object 336 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 337 * @token: Token of DPRTC object 338 * @freq_compensation: The new frequency compensation value to set. 339 * 340 * Return: '0' on Success; Error code otherwise. 341 */ 342 int dprtc_set_freq_compensation(struct fsl_mc_io *mc_io, 343 uint32_t cmd_flags, 344 uint16_t token, 345 uint32_t freq_compensation) 346 { 347 struct dprtc_get_freq_compensation *cmd_params; 348 struct mc_command cmd = { 0 }; 349 350 /* prepare command */ 351 cmd.header = mc_encode_cmd_header(DPRTC_CMDID_SET_FREQ_COMPENSATION, 352 cmd_flags, 353 token); 354 cmd_params = (struct dprtc_get_freq_compensation *)cmd.params; 355 cmd_params->freq_compensation = cpu_to_le32(freq_compensation); 356 357 /* send command to mc*/ 358 return mc_send_command(mc_io, &cmd); 359 } 360 361 /** 362 * dprtc_get_freq_compensation() - Retrieves the frequency compensation value 363 * 364 * @mc_io: Pointer to MC portal's I/O object 365 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 366 * @token: Token of DPRTC object 367 * @freq_compensation: Frequency compensation value 368 * 369 * Return: '0' on Success; Error code otherwise. 370 */ 371 int dprtc_get_freq_compensation(struct fsl_mc_io *mc_io, 372 uint32_t cmd_flags, 373 uint16_t token, 374 uint32_t *freq_compensation) 375 { 376 struct dprtc_get_freq_compensation *rsp_params; 377 struct mc_command cmd = { 0 }; 378 int err; 379 380 /* prepare command */ 381 cmd.header = mc_encode_cmd_header(DPRTC_CMDID_GET_FREQ_COMPENSATION, 382 cmd_flags, 383 token); 384 385 /* send command to mc*/ 386 err = mc_send_command(mc_io, &cmd); 387 if (err) 388 return err; 389 390 /* retrieve response parameters */ 391 rsp_params = (struct dprtc_get_freq_compensation *)cmd.params; 392 *freq_compensation = le32_to_cpu(rsp_params->freq_compensation); 393 394 return 0; 395 } 396 397 /** 398 * dprtc_get_time() - Returns the current RTC time. 399 * 400 * @mc_io: Pointer to MC portal's I/O object 401 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 402 * @token: Token of DPRTC object 403 * @time: Current RTC time. 404 * 405 * Return: '0' on Success; Error code otherwise. 406 */ 407 int dprtc_get_time(struct fsl_mc_io *mc_io, 408 uint32_t cmd_flags, 409 uint16_t token, 410 uint64_t *time) 411 { 412 struct dprtc_time *rsp_params; 413 struct mc_command cmd = { 0 }; 414 int err; 415 416 /* prepare command */ 417 cmd.header = mc_encode_cmd_header(DPRTC_CMDID_GET_TIME, 418 cmd_flags, 419 token); 420 421 /* send command to mc*/ 422 err = mc_send_command(mc_io, &cmd); 423 if (err) 424 return err; 425 426 /* retrieve response parameters */ 427 rsp_params = (struct dprtc_time *)cmd.params; 428 *time = le64_to_cpu(rsp_params->time); 429 430 return 0; 431 } 432 433 /** 434 * dprtc_set_time() - Updates current RTC time. 435 * 436 * @mc_io: Pointer to MC portal's I/O object 437 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 438 * @token: Token of DPRTC object 439 * @time: New RTC time. 440 * 441 * Return: '0' on Success; Error code otherwise. 442 */ 443 int dprtc_set_time(struct fsl_mc_io *mc_io, 444 uint32_t cmd_flags, 445 uint16_t token, 446 uint64_t time) 447 { 448 struct dprtc_time *cmd_params; 449 struct mc_command cmd = { 0 }; 450 451 /* prepare command */ 452 cmd.header = mc_encode_cmd_header(DPRTC_CMDID_SET_TIME, 453 cmd_flags, 454 token); 455 cmd_params = (struct dprtc_time *)cmd.params; 456 cmd_params->time = cpu_to_le64(time); 457 458 /* send command to mc*/ 459 return mc_send_command(mc_io, &cmd); 460 } 461 462 /** 463 * dprtc_set_alarm() - Defines and sets alarm. 464 * 465 * @mc_io: Pointer to MC portal's I/O object 466 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 467 * @token: Token of DPRTC object 468 * @time: In nanoseconds, the time when the alarm 469 * should go off - must be a multiple of 470 * 1 microsecond 471 * 472 * Return: '0' on Success; Error code otherwise. 473 */ 474 int dprtc_set_alarm(struct fsl_mc_io *mc_io, 475 uint32_t cmd_flags, 476 uint16_t token, uint64_t time) 477 { 478 struct dprtc_time *cmd_params; 479 struct mc_command cmd = { 0 }; 480 481 /* prepare command */ 482 cmd.header = mc_encode_cmd_header(DPRTC_CMDID_SET_ALARM, 483 cmd_flags, 484 token); 485 cmd_params = (struct dprtc_time *)cmd.params; 486 cmd_params->time = cpu_to_le64(time); 487 488 /* send command to mc*/ 489 return mc_send_command(mc_io, &cmd); 490 } 491 492 /** 493 * dprtc_get_api_version() - Get Data Path Real Time Counter API version 494 * @mc_io: Pointer to MC portal's I/O object 495 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 496 * @major_ver: Major version of data path real time counter API 497 * @minor_ver: Minor version of data path real time counter API 498 * 499 * Return: '0' on Success; Error code otherwise. 500 */ 501 int dprtc_get_api_version(struct fsl_mc_io *mc_io, 502 uint32_t cmd_flags, 503 uint16_t *major_ver, 504 uint16_t *minor_ver) 505 { 506 struct dprtc_rsp_get_api_version *rsp_params; 507 struct mc_command cmd = { 0 }; 508 int err; 509 510 cmd.header = mc_encode_cmd_header(DPRTC_CMDID_GET_API_VERSION, 511 cmd_flags, 512 0); 513 514 err = mc_send_command(mc_io, &cmd); 515 if (err) 516 return err; 517 518 rsp_params = (struct dprtc_rsp_get_api_version *)cmd.params; 519 *major_ver = le16_to_cpu(rsp_params->major); 520 *minor_ver = le16_to_cpu(rsp_params->minor); 521 522 return 0; 523 } 524 525 /** 526 * dprtc_get_ext_trigger_timestamp - Retrieve the Ext trigger timestamp status 527 * (timestamp + flag for unread timestamp in FIFO). 528 * 529 * @mc_io: Pointer to MC portal's I/O object 530 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 531 * @token: Token of DPRTC object 532 * @id: External trigger id. 533 * @status: Returned object's external trigger status 534 * 535 * Return: '0' on Success; Error code otherwise. 536 */ 537 int dprtc_get_ext_trigger_timestamp(struct fsl_mc_io *mc_io, 538 uint32_t cmd_flags, 539 uint16_t token, 540 uint8_t id, 541 struct dprtc_ext_trigger_status *status) 542 { 543 struct dprtc_rsp_ext_trigger_timestamp *rsp_params; 544 struct dprtc_cmd_ext_trigger_timestamp *cmd_params; 545 struct mc_command cmd = { 0 }; 546 int err; 547 548 /* prepare command */ 549 cmd.header = mc_encode_cmd_header(DPRTC_CMDID_GET_EXT_TRIGGER_TIMESTAMP, 550 cmd_flags, 551 token); 552 553 cmd_params = (struct dprtc_cmd_ext_trigger_timestamp *)cmd.params; 554 cmd_params->id = id; 555 /* send command to mc*/ 556 err = mc_send_command(mc_io, &cmd); 557 if (err) 558 return err; 559 560 /* retrieve response parameters */ 561 rsp_params = (struct dprtc_rsp_ext_trigger_timestamp *)cmd.params; 562 status->timestamp = le64_to_cpu(rsp_params->timestamp); 563 status->unread_valid_timestamp = rsp_params->unread_valid_timestamp; 564 565 return 0; 566 } 567 568 /** 569 * dprtc_set_fiper_loopback() - Set the fiper pulse as source of interrupt for 570 * External Trigger stamps 571 * @mc_io: Pointer to MC portal's I/O object 572 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 573 * @token: Token of DPRTC object 574 * @id: External trigger id. 575 * @fiper_as_input: Bit used to control interrupt signal source: 576 * 0 = Normal operation, interrupt external source 577 * 1 = Fiper pulse is looped back into Trigger input 578 * 579 * Return: '0' on Success; Error code otherwise. 580 */ 581 int dprtc_set_fiper_loopback(struct fsl_mc_io *mc_io, 582 uint32_t cmd_flags, 583 uint16_t token, 584 uint8_t id, 585 uint8_t fiper_as_input) 586 { 587 struct dprtc_ext_trigger_cfg *cmd_params; 588 struct mc_command cmd = { 0 }; 589 590 cmd.header = mc_encode_cmd_header(DPRTC_CMDID_SET_FIPER_LOOPBACK, 591 cmd_flags, 592 token); 593 594 cmd_params = (struct dprtc_ext_trigger_cfg *)cmd.params; 595 cmd_params->id = id; 596 cmd_params->fiper_as_input = fiper_as_input; 597 598 return mc_send_command(mc_io, &cmd); 599 } 600