Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gpu: nova-core: Add bindings required by GSP sequencer

Add several firmware bindings required by GSP sequencer code.

Co-developed-by: Alistair Popple <apopple@nvidia.com>
Signed-off-by: Alistair Popple <apopple@nvidia.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Joel Fernandes <joelagnelf@nvidia.com>
[acourbot@nvidia.com: remove a couple stray lines/unwanted comment
changes.]
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Message-ID: <20251114195552.739371-7-joelagnelf@nvidia.com>

authored by

Joel Fernandes and committed by
Alexandre Courbot
eaf0989c f77be04d

+407
+323
drivers/gpu/nova-core/gsp/fw.rs
··· 312 312 } 313 313 } 314 314 315 + /// Sequencer buffer opcode for GSP sequencer commands. 316 + #[derive(Copy, Clone, Debug, PartialEq)] 317 + #[repr(u32)] 318 + pub(crate) enum SeqBufOpcode { 319 + // Core operation opcodes 320 + CoreReset = r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_RESET, 321 + CoreResume = r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_RESUME, 322 + CoreStart = r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_START, 323 + CoreWaitForHalt = r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_WAIT_FOR_HALT, 324 + 325 + // Delay opcode 326 + DelayUs = r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_DELAY_US, 327 + 328 + // Register operation opcodes 329 + RegModify = r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_MODIFY, 330 + RegPoll = r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_POLL, 331 + RegStore = r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_STORE, 332 + RegWrite = r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_WRITE, 333 + } 334 + 335 + impl fmt::Display for SeqBufOpcode { 336 + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 337 + match self { 338 + SeqBufOpcode::CoreReset => write!(f, "CORE_RESET"), 339 + SeqBufOpcode::CoreResume => write!(f, "CORE_RESUME"), 340 + SeqBufOpcode::CoreStart => write!(f, "CORE_START"), 341 + SeqBufOpcode::CoreWaitForHalt => write!(f, "CORE_WAIT_FOR_HALT"), 342 + SeqBufOpcode::DelayUs => write!(f, "DELAY_US"), 343 + SeqBufOpcode::RegModify => write!(f, "REG_MODIFY"), 344 + SeqBufOpcode::RegPoll => write!(f, "REG_POLL"), 345 + SeqBufOpcode::RegStore => write!(f, "REG_STORE"), 346 + SeqBufOpcode::RegWrite => write!(f, "REG_WRITE"), 347 + } 348 + } 349 + } 350 + 351 + impl TryFrom<u32> for SeqBufOpcode { 352 + type Error = kernel::error::Error; 353 + 354 + fn try_from(value: u32) -> Result<SeqBufOpcode> { 355 + match value { 356 + r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_RESET => { 357 + Ok(SeqBufOpcode::CoreReset) 358 + } 359 + r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_RESUME => { 360 + Ok(SeqBufOpcode::CoreResume) 361 + } 362 + r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_START => { 363 + Ok(SeqBufOpcode::CoreStart) 364 + } 365 + r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_WAIT_FOR_HALT => { 366 + Ok(SeqBufOpcode::CoreWaitForHalt) 367 + } 368 + r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_DELAY_US => Ok(SeqBufOpcode::DelayUs), 369 + r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_MODIFY => { 370 + Ok(SeqBufOpcode::RegModify) 371 + } 372 + r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_POLL => Ok(SeqBufOpcode::RegPoll), 373 + r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_STORE => Ok(SeqBufOpcode::RegStore), 374 + r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_WRITE => Ok(SeqBufOpcode::RegWrite), 375 + _ => Err(EINVAL), 376 + } 377 + } 378 + } 379 + 380 + impl From<SeqBufOpcode> for u32 { 381 + fn from(value: SeqBufOpcode) -> Self { 382 + // CAST: `SeqBufOpcode` is `repr(u32)` and can thus be cast losslessly. 383 + value as u32 384 + } 385 + } 386 + 387 + /// Wrapper for GSP sequencer register write payload. 388 + #[repr(transparent)] 389 + #[derive(Copy, Clone)] 390 + pub(crate) struct RegWritePayload(r570_144::GSP_SEQ_BUF_PAYLOAD_REG_WRITE); 391 + 392 + #[expect(unused)] 393 + impl RegWritePayload { 394 + /// Returns the register address. 395 + pub(crate) fn addr(&self) -> u32 { 396 + self.0.addr 397 + } 398 + 399 + /// Returns the value to write. 400 + pub(crate) fn val(&self) -> u32 { 401 + self.0.val 402 + } 403 + } 404 + 405 + // SAFETY: This struct only contains integer types for which all bit patterns are valid. 406 + unsafe impl FromBytes for RegWritePayload {} 407 + 408 + // SAFETY: Padding is explicit and will not contain uninitialized data. 409 + unsafe impl AsBytes for RegWritePayload {} 410 + 411 + /// Wrapper for GSP sequencer register modify payload. 412 + #[repr(transparent)] 413 + #[derive(Copy, Clone)] 414 + pub(crate) struct RegModifyPayload(r570_144::GSP_SEQ_BUF_PAYLOAD_REG_MODIFY); 415 + 416 + #[expect(unused)] 417 + impl RegModifyPayload { 418 + /// Returns the register address. 419 + pub(crate) fn addr(&self) -> u32 { 420 + self.0.addr 421 + } 422 + 423 + /// Returns the mask to apply. 424 + pub(crate) fn mask(&self) -> u32 { 425 + self.0.mask 426 + } 427 + 428 + /// Returns the value to write. 429 + pub(crate) fn val(&self) -> u32 { 430 + self.0.val 431 + } 432 + } 433 + 434 + // SAFETY: This struct only contains integer types for which all bit patterns are valid. 435 + unsafe impl FromBytes for RegModifyPayload {} 436 + 437 + // SAFETY: Padding is explicit and will not contain uninitialized data. 438 + unsafe impl AsBytes for RegModifyPayload {} 439 + 440 + /// Wrapper for GSP sequencer register poll payload. 441 + #[repr(transparent)] 442 + #[derive(Copy, Clone)] 443 + pub(crate) struct RegPollPayload(r570_144::GSP_SEQ_BUF_PAYLOAD_REG_POLL); 444 + 445 + #[expect(unused)] 446 + impl RegPollPayload { 447 + /// Returns the register address. 448 + pub(crate) fn addr(&self) -> u32 { 449 + self.0.addr 450 + } 451 + 452 + /// Returns the mask to apply. 453 + pub(crate) fn mask(&self) -> u32 { 454 + self.0.mask 455 + } 456 + 457 + /// Returns the expected value. 458 + pub(crate) fn val(&self) -> u32 { 459 + self.0.val 460 + } 461 + 462 + /// Returns the timeout in microseconds. 463 + pub(crate) fn timeout(&self) -> u32 { 464 + self.0.timeout 465 + } 466 + } 467 + 468 + // SAFETY: This struct only contains integer types for which all bit patterns are valid. 469 + unsafe impl FromBytes for RegPollPayload {} 470 + 471 + // SAFETY: Padding is explicit and will not contain uninitialized data. 472 + unsafe impl AsBytes for RegPollPayload {} 473 + 474 + /// Wrapper for GSP sequencer delay payload. 475 + #[repr(transparent)] 476 + #[derive(Copy, Clone)] 477 + pub(crate) struct DelayUsPayload(r570_144::GSP_SEQ_BUF_PAYLOAD_DELAY_US); 478 + 479 + #[expect(unused)] 480 + impl DelayUsPayload { 481 + /// Returns the delay value in microseconds. 482 + pub(crate) fn val(&self) -> u32 { 483 + self.0.val 484 + } 485 + } 486 + 487 + // SAFETY: This struct only contains integer types for which all bit patterns are valid. 488 + unsafe impl FromBytes for DelayUsPayload {} 489 + 490 + // SAFETY: Padding is explicit and will not contain uninitialized data. 491 + unsafe impl AsBytes for DelayUsPayload {} 492 + 493 + /// Wrapper for GSP sequencer register store payload. 494 + #[repr(transparent)] 495 + #[derive(Copy, Clone)] 496 + pub(crate) struct RegStorePayload(r570_144::GSP_SEQ_BUF_PAYLOAD_REG_STORE); 497 + 498 + #[expect(unused)] 499 + impl RegStorePayload { 500 + /// Returns the register address. 501 + pub(crate) fn addr(&self) -> u32 { 502 + self.0.addr 503 + } 504 + 505 + /// Returns the storage index. 506 + pub(crate) fn index(&self) -> u32 { 507 + self.0.index 508 + } 509 + } 510 + 511 + // SAFETY: This struct only contains integer types for which all bit patterns are valid. 512 + unsafe impl FromBytes for RegStorePayload {} 513 + 514 + // SAFETY: Padding is explicit and will not contain uninitialized data. 515 + unsafe impl AsBytes for RegStorePayload {} 516 + 517 + /// Wrapper for GSP sequencer buffer command. 518 + #[repr(transparent)] 519 + pub(crate) struct SequencerBufferCmd(r570_144::GSP_SEQUENCER_BUFFER_CMD); 520 + 521 + #[expect(unused)] 522 + impl SequencerBufferCmd { 523 + /// Returns the opcode as a `SeqBufOpcode` enum, or error if invalid. 524 + pub(crate) fn opcode(&self) -> Result<SeqBufOpcode> { 525 + self.0.opCode.try_into() 526 + } 527 + 528 + /// Returns the register write payload by value. 529 + /// 530 + /// Returns an error if the opcode is not `SeqBufOpcode::RegWrite`. 531 + pub(crate) fn reg_write_payload(&self) -> Result<RegWritePayload> { 532 + if self.opcode()? != SeqBufOpcode::RegWrite { 533 + return Err(EINVAL); 534 + } 535 + // SAFETY: Opcode is verified to be `RegWrite`, so union contains valid `RegWritePayload`. 536 + let payload_bytes = unsafe { 537 + core::slice::from_raw_parts( 538 + core::ptr::addr_of!(self.0.payload.regWrite).cast::<u8>(), 539 + core::mem::size_of::<RegWritePayload>(), 540 + ) 541 + }; 542 + Ok(*RegWritePayload::from_bytes(payload_bytes).ok_or(EINVAL)?) 543 + } 544 + 545 + /// Returns the register modify payload by value. 546 + /// 547 + /// Returns an error if the opcode is not `SeqBufOpcode::RegModify`. 548 + pub(crate) fn reg_modify_payload(&self) -> Result<RegModifyPayload> { 549 + if self.opcode()? != SeqBufOpcode::RegModify { 550 + return Err(EINVAL); 551 + } 552 + // SAFETY: Opcode is verified to be `RegModify`, so union contains valid `RegModifyPayload`. 553 + let payload_bytes = unsafe { 554 + core::slice::from_raw_parts( 555 + core::ptr::addr_of!(self.0.payload.regModify).cast::<u8>(), 556 + core::mem::size_of::<RegModifyPayload>(), 557 + ) 558 + }; 559 + Ok(*RegModifyPayload::from_bytes(payload_bytes).ok_or(EINVAL)?) 560 + } 561 + 562 + /// Returns the register poll payload by value. 563 + /// 564 + /// Returns an error if the opcode is not `SeqBufOpcode::RegPoll`. 565 + pub(crate) fn reg_poll_payload(&self) -> Result<RegPollPayload> { 566 + if self.opcode()? != SeqBufOpcode::RegPoll { 567 + return Err(EINVAL); 568 + } 569 + // SAFETY: Opcode is verified to be `RegPoll`, so union contains valid `RegPollPayload`. 570 + let payload_bytes = unsafe { 571 + core::slice::from_raw_parts( 572 + core::ptr::addr_of!(self.0.payload.regPoll).cast::<u8>(), 573 + core::mem::size_of::<RegPollPayload>(), 574 + ) 575 + }; 576 + Ok(*RegPollPayload::from_bytes(payload_bytes).ok_or(EINVAL)?) 577 + } 578 + 579 + /// Returns the delay payload by value. 580 + /// 581 + /// Returns an error if the opcode is not `SeqBufOpcode::DelayUs`. 582 + pub(crate) fn delay_us_payload(&self) -> Result<DelayUsPayload> { 583 + if self.opcode()? != SeqBufOpcode::DelayUs { 584 + return Err(EINVAL); 585 + } 586 + // SAFETY: Opcode is verified to be `DelayUs`, so union contains valid `DelayUsPayload`. 587 + let payload_bytes = unsafe { 588 + core::slice::from_raw_parts( 589 + core::ptr::addr_of!(self.0.payload.delayUs).cast::<u8>(), 590 + core::mem::size_of::<DelayUsPayload>(), 591 + ) 592 + }; 593 + Ok(*DelayUsPayload::from_bytes(payload_bytes).ok_or(EINVAL)?) 594 + } 595 + 596 + /// Returns the register store payload by value. 597 + /// 598 + /// Returns an error if the opcode is not `SeqBufOpcode::RegStore`. 599 + pub(crate) fn reg_store_payload(&self) -> Result<RegStorePayload> { 600 + if self.opcode()? != SeqBufOpcode::RegStore { 601 + return Err(EINVAL); 602 + } 603 + // SAFETY: Opcode is verified to be `RegStore`, so union contains valid `RegStorePayload`. 604 + let payload_bytes = unsafe { 605 + core::slice::from_raw_parts( 606 + core::ptr::addr_of!(self.0.payload.regStore).cast::<u8>(), 607 + core::mem::size_of::<RegStorePayload>(), 608 + ) 609 + }; 610 + Ok(*RegStorePayload::from_bytes(payload_bytes).ok_or(EINVAL)?) 611 + } 612 + } 613 + 614 + // SAFETY: This struct only contains integer types for which all bit patterns are valid. 615 + unsafe impl FromBytes for SequencerBufferCmd {} 616 + 617 + // SAFETY: Padding is explicit and will not contain uninitialized data. 618 + unsafe impl AsBytes for SequencerBufferCmd {} 619 + 620 + /// Wrapper for GSP run CPU sequencer RPC. 621 + #[repr(transparent)] 622 + pub(crate) struct RunCpuSequencer(r570_144::rpc_run_cpu_sequencer_v17_00); 623 + 624 + #[expect(unused)] 625 + impl RunCpuSequencer { 626 + /// Returns the command index. 627 + pub(crate) fn cmd_index(&self) -> u32 { 628 + self.0.cmdIndex 629 + } 630 + } 631 + 632 + // SAFETY: This struct only contains integer types for which all bit patterns are valid. 633 + unsafe impl FromBytes for RunCpuSequencer {} 634 + 635 + // SAFETY: Padding is explicit and will not contain uninitialized data. 636 + unsafe impl AsBytes for RunCpuSequencer {} 637 + 315 638 /// Struct containing the arguments required to pass a memory buffer to the GSP 316 639 /// for use during initialisation. 317 640 ///
+84
drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
··· 702 702 } 703 703 } 704 704 } 705 + #[repr(C)] 706 + #[derive(Debug, Default)] 707 + pub struct rpc_run_cpu_sequencer_v17_00 { 708 + pub bufferSizeDWord: u32_, 709 + pub cmdIndex: u32_, 710 + pub regSaveArea: [u32_; 8usize], 711 + pub commandBuffer: __IncompleteArrayField<u32_>, 712 + } 713 + pub const GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_WRITE: GSP_SEQ_BUF_OPCODE = 0; 714 + pub const GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_MODIFY: GSP_SEQ_BUF_OPCODE = 1; 715 + pub const GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_POLL: GSP_SEQ_BUF_OPCODE = 2; 716 + pub const GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_DELAY_US: GSP_SEQ_BUF_OPCODE = 3; 717 + pub const GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_STORE: GSP_SEQ_BUF_OPCODE = 4; 718 + pub const GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_RESET: GSP_SEQ_BUF_OPCODE = 5; 719 + pub const GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_START: GSP_SEQ_BUF_OPCODE = 6; 720 + pub const GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_WAIT_FOR_HALT: GSP_SEQ_BUF_OPCODE = 7; 721 + pub const GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_RESUME: GSP_SEQ_BUF_OPCODE = 8; 722 + pub type GSP_SEQ_BUF_OPCODE = ffi::c_uint; 723 + #[repr(C)] 724 + #[derive(Debug, Default, Copy, Clone)] 725 + pub struct GSP_SEQ_BUF_PAYLOAD_REG_WRITE { 726 + pub addr: u32_, 727 + pub val: u32_, 728 + } 729 + #[repr(C)] 730 + #[derive(Debug, Default, Copy, Clone)] 731 + pub struct GSP_SEQ_BUF_PAYLOAD_REG_MODIFY { 732 + pub addr: u32_, 733 + pub mask: u32_, 734 + pub val: u32_, 735 + } 736 + #[repr(C)] 737 + #[derive(Debug, Default, Copy, Clone)] 738 + pub struct GSP_SEQ_BUF_PAYLOAD_REG_POLL { 739 + pub addr: u32_, 740 + pub mask: u32_, 741 + pub val: u32_, 742 + pub timeout: u32_, 743 + pub error: u32_, 744 + } 745 + #[repr(C)] 746 + #[derive(Debug, Default, Copy, Clone)] 747 + pub struct GSP_SEQ_BUF_PAYLOAD_DELAY_US { 748 + pub val: u32_, 749 + } 750 + #[repr(C)] 751 + #[derive(Debug, Default, Copy, Clone)] 752 + pub struct GSP_SEQ_BUF_PAYLOAD_REG_STORE { 753 + pub addr: u32_, 754 + pub index: u32_, 755 + } 756 + #[repr(C)] 757 + #[derive(Copy, Clone)] 758 + pub struct GSP_SEQUENCER_BUFFER_CMD { 759 + pub opCode: GSP_SEQ_BUF_OPCODE, 760 + pub payload: GSP_SEQUENCER_BUFFER_CMD__bindgen_ty_1, 761 + } 762 + #[repr(C)] 763 + #[derive(Copy, Clone)] 764 + pub union GSP_SEQUENCER_BUFFER_CMD__bindgen_ty_1 { 765 + pub regWrite: GSP_SEQ_BUF_PAYLOAD_REG_WRITE, 766 + pub regModify: GSP_SEQ_BUF_PAYLOAD_REG_MODIFY, 767 + pub regPoll: GSP_SEQ_BUF_PAYLOAD_REG_POLL, 768 + pub delayUs: GSP_SEQ_BUF_PAYLOAD_DELAY_US, 769 + pub regStore: GSP_SEQ_BUF_PAYLOAD_REG_STORE, 770 + } 771 + impl Default for GSP_SEQUENCER_BUFFER_CMD__bindgen_ty_1 { 772 + fn default() -> Self { 773 + let mut s = ::core::mem::MaybeUninit::<Self>::uninit(); 774 + unsafe { 775 + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 776 + s.assume_init() 777 + } 778 + } 779 + } 780 + impl Default for GSP_SEQUENCER_BUFFER_CMD { 781 + fn default() -> Self { 782 + let mut s = ::core::mem::MaybeUninit::<Self>::uninit(); 783 + unsafe { 784 + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 785 + s.assume_init() 786 + } 787 + } 788 + }