From: Philip Yang <[email protected]>

Extend the UALink manager with data structures for cross-GPU interrupt
and TLB shootdown: per-ring state, per-peer channel pairs, and the
top-level remote container.

Declare the public init, teardown, and reset APIs.

Define ring buffer capacity, firmware command and status codes, SMN
mailbox register addresses, and the metadata and writeback buffer layouts
shared between driver and MPNHT firmware.

Signed-off-by: Philip Yang <[email protected]>
Reviewed-by: Felix Kuehling <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.c | 140 +++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.h |  12 ++
 2 files changed, 152 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.c
index c0478087b95d4..d08f45d07fae9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.c
@@ -1240,3 +1240,143 @@ void amdgpu_ualink_manager_stop(struct amdgpu_device 
*adev)
        destroy_workqueue(adev->ualink.npa_wq);
        amdgpu_vm_fini(adev, &adev->ualink.npa_vm);
 }
+
+/*
+ * UALink remote interrupt and shootdown
+ */
+
+/* UALINK ring buffer size, same for both remote shootdown and interrupt ring 
*/
+#define AMDGPU_UALINK_RB_SIZE  4096
+
+#define AMDGPU_UALINK_METADATA_HEADER  0x4E485446
+
+/* UALINK F/W commands */
+#define AMDGPU_UALINK_FW_CMD_LOAD_METADATA     0x1
+#define AMDGPU_UALINK_FW_CMD_HALT_OPERATION    0x2
+
+/* UALINK F/W status */
+#define AMDGPU_UALINK_FW_STATUS_PREINIT        0xA0
+#define AMDGPU_UALINK_FW_STATUS_READY  0xA1
+#define AMDGPU_UALINK_FW_STATUS_HALT   0xA2
+#define AMDGPU_UALINK_FW_STATUS_ERROR  0xA3
+#define AMDGPU_UALINK_FW_STATUS_FATAL  0xF0
+
+/* UALINK mailbox registers via SMN, copy of MP1 */
+/* send command to nht f/w */
+#define mmMPNHT_SMN_C2PMSG_22_ALT_2    0xAE10958
+/* additional data */
+#define mmMPNHT_SMN_C2PMSG_23_ALT_2    0xAE1095C
+/* metadata address low */
+#define mmMPNHT_SMN_C2PMSG_24_ALT_2    0xAE10960
+/* metadata address high */
+#define mmMPNHT_SMN_C2PMSG_25_ALT_2    0xAE10964
+/* f/w status */
+#define mmMPNHT_SMN_C2PMSG_26_ALT_2    0xAE10968
+
+struct amdgpu_ualink_metadata {
+       u32 header;
+
+       /*
+        * "ring entries" as unit. So the ring-size-in-bytes could be calculated
+        * as entry-size * 2^RBsize. This would make the minimum size a single
+        * entry and the maximum size 32786 entries.
+        *
+        * u32 rb_size:4;
+        * u32 reserved0:4;
+        * u32 vmid:4;
+        * u32 reserved1:20;
+        */
+       u32 rb_size;
+
+       /* ring buffer base address for remote interrupt */
+       u64 ri_rb;
+
+       /* tlb invalidate ring buffer base address for remote shootdown */
+       u64 tlb_inv_rb;
+
+       /* remote interrupt Tail pointer, write pointer address */
+       u64 tailptr_ri;
+
+       /* TLB invalidate ring buffer's Tail pointer, write pointer address */
+       u64 tailptr_tlb_inv;
+};
+
+struct amdgpu_ualink_wb {
+       /* last finished command seq number */
+       u32 data;
+
+       /* command complete error code */
+       u32 status;
+
+       /* ring rptr updated by FW */
+       u64 rptr;
+};
+
+/*
+ * For remote interrupt and shootdown
+ */
+struct amdgpu_ualink_ring {
+       u32 rb_size;
+
+       /* writeback data */
+       u32 seq;
+
+       /* local copy */
+       u64 wptr, rptr;
+
+       /* NPA gart mapping for SDMA */
+       u64 rb_npa_gart;
+       u64 wptr_npa_gart;
+       u64 doorbell_npa_gart;
+
+       /* gart mapping node */
+       struct drm_mm_node mm_node_rb;
+       struct drm_mm_node mm_node_wptr;
+       struct drm_mm_node mm_node_doorbell;
+
+       /* true if fw write back address updated successfully */
+       bool ready;
+};
+
+struct amdgpu_ualink_peer {
+       /* remote interrupt and shootdown uses same SDMA entity */
+       struct mutex lock;
+
+       /* SDMA engine to send remote command via NPA */
+       struct drm_sched_entity entity;
+
+       /* to select different DXS ports, cycles through different values */
+       u32 dxs_port;
+
+       struct amdgpu_ualink_ring interrupt;
+       struct amdgpu_ualink_ring shootdown;
+};
+
+struct amdgpu_ualink_remote {
+       /* ualink metadata passed to MPNHT FW */
+       struct amdgpu_bo                *metadata_bo;
+       u64                             metadata_gpu_addr;
+       void                            *metadata_cpu_addr;
+
+       /* ualink ring, tlb ring buffer, wptr */
+       struct amdgpu_bo                *ring_bo;
+       u64                             rb_gpu_addr;
+       void                            *rb_cpu_addr;
+
+       /* ualink rptr, wb data, statuss for address alias mode */
+       struct amdgpu_bo                *rptr_bo;
+       u64                             rptr_gpu_addr;
+       void                            *rptr_cpu_addr;
+       u64                             rptr_npa;
+
+       /* address alias mode alloc npa address for shared wb */
+       struct drm_mm_node              rptr_mm_node;
+
+       /* active accelator id bitmap of the pod */
+       unsigned long                   *active_accel_bits;
+       u32                             num_accel;
+
+       /* remote GPUs ring buffer, read, write pointer local copy and gart 
mapping */
+       struct amdgpu_ualink_peer       peer[AMDGPU_UALINK_ACCEL_MAX];
+};
+
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.h
index c32b4fd3c3220..a75aac48604cb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.h
@@ -139,6 +139,8 @@ struct amdgpu_ualink_connection {
        enum amdgpu_ualink_conn_state state;
 };
 
+struct amdgpu_ualink_remote;
+
 struct amdgpu_ualink_mgr {
        u64 npa_size;
        u32 psp_if_ver;
@@ -147,6 +149,12 @@ struct amdgpu_ualink_mgr {
        struct amdgpu_ualink_vpod_config *config;
        struct amdgpu_ualink_station_config *stations;
 
+       /* For remote interrupt and shootdown */
+       struct amdgpu_ualink_remote *remote;
+
+       /* handle irq from ualink client of remote GPUs */
+       struct amdgpu_irq_src irq;
+
        /* Xarray to store info about exported BOs */
        struct xarray   exp_xa;
 
@@ -179,6 +187,10 @@ struct amdgpu_ualink_mgr {
        struct amdgpu_vm npa_vm;
 };
 
+int amdgpu_ualink_init_interrupt(struct amdgpu_device *adev);
+int amdgpu_ualink_sw_init(struct amdgpu_device *adev);
+void amdgpu_ualink_sw_fini(struct amdgpu_device *adev);
+
 int amdgpu_ualink_sysfs_init(struct amdgpu_device *adev);
 void amdgpu_ualink_sysfs_fini(struct amdgpu_device *adev);
 int amdgpu_ualink_init(struct amdgpu_device *adev);
-- 
2.55.0

Reply via email to