drm/xe: Let's return last value read on xe_mmio_wait32.
authorRodrigo Vivi <rodrigo.vivi@intel.com>
Fri, 31 Mar 2023 18:21:34 +0000 (14:21 -0400)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Tue, 12 Dec 2023 19:05:59 +0000 (14:05 -0500)
This is already useful because it avoids some extra reads
where registers might have changed after the timeout decision.

But also, it will be important to end the kill of i915's wait_for.

Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
drivers/gpu/drm/xe/xe_force_wake.c
drivers/gpu/drm/xe/xe_gt.c
drivers/gpu/drm/xe/xe_guc.c
drivers/gpu/drm/xe/xe_huc.c
drivers/gpu/drm/xe/xe_mmio.h
drivers/gpu/drm/xe/xe_uc_fw.c

index 31a33ee9ccb6c6a4d9823a213738c8825ecd7806..a203eabba4e29877e9e5e9fa7e218ebfd807841a 100644 (file)
@@ -129,7 +129,7 @@ static int domain_wake_wait(struct xe_gt *gt,
                            struct xe_force_wake_domain *domain)
 {
        return xe_mmio_wait32(gt, domain->reg_ack, domain->val, domain->val,
-                             XE_FORCE_WAKE_ACK_TIMEOUT_MS);
+                             XE_FORCE_WAKE_ACK_TIMEOUT_MS, NULL);
 }
 
 static void domain_sleep(struct xe_gt *gt, struct xe_force_wake_domain *domain)
@@ -141,7 +141,7 @@ static int domain_sleep_wait(struct xe_gt *gt,
                             struct xe_force_wake_domain *domain)
 {
        return xe_mmio_wait32(gt, domain->reg_ack, 0, domain->val,
-                             XE_FORCE_WAKE_ACK_TIMEOUT_MS);
+                             XE_FORCE_WAKE_ACK_TIMEOUT_MS, NULL);
 }
 
 #define for_each_fw_domain_masked(domain__, mask__, fw__, tmp__) \
index 5f8fa9d98d5af2db07e79e8e13f9250bc5fc5bcc..6a84d2a1c7f34d6718782c47eada43491f0415de 100644 (file)
@@ -599,7 +599,7 @@ int do_gt_reset(struct xe_gt *gt)
        int err;
 
        xe_mmio_write32(gt, GEN6_GDRST.reg, GEN11_GRDOM_FULL);
-       err = xe_mmio_wait32(gt, GEN6_GDRST.reg, 0, GEN11_GRDOM_FULL, 5);
+       err = xe_mmio_wait32(gt, GEN6_GDRST.reg, 0, GEN11_GRDOM_FULL, 5, NULL);
        if (err)
                drm_err(&xe->drm,
                        "GT reset failed to clear GEN11_GRDOM_FULL\n");
index 9234da06d205cb9ed640e8dcaaba8b9ba242d4f1..52f42bd5cad7a2d29b817912a7769369f9cb165d 100644 (file)
@@ -324,17 +324,17 @@ int xe_guc_reset(struct xe_guc *guc)
 {
        struct xe_device *xe = guc_to_xe(guc);
        struct xe_gt *gt = guc_to_gt(guc);
-       u32 guc_status;
+       u32 guc_status, gdrst;
        int ret;
 
        xe_force_wake_assert_held(gt_to_fw(gt), XE_FW_GT);
 
        xe_mmio_write32(gt, GEN6_GDRST.reg, GEN11_GRDOM_GUC);
 
-       ret = xe_mmio_wait32(gt, GEN6_GDRST.reg, 0, GEN11_GRDOM_GUC, 5);
+       ret = xe_mmio_wait32(gt, GEN6_GDRST.reg, 0, GEN11_GRDOM_GUC, 5, &gdrst);
        if (ret) {
                drm_err(&xe->drm, "GuC reset timed out, GEN6_GDRST=0x%8x\n",
-                       xe_mmio_read32(gt, GEN6_GDRST.reg));
+                       gdrst);
                goto err_out;
        }
 
@@ -654,7 +654,7 @@ int xe_guc_send_mmio(struct xe_guc *guc, const u32 *request, u32 len)
 {
        struct xe_device *xe = guc_to_xe(guc);
        struct xe_gt *gt = guc_to_gt(guc);
-       u32 header;
+       u32 header, reply;
        u32 reply_reg = xe_gt_is_media_type(gt) ?
                MEDIA_SOFT_SCRATCH(0).reg : GEN11_SOFT_SCRATCH(0).reg;
        int ret;
@@ -691,12 +691,11 @@ retry:
        ret = xe_mmio_wait32(gt, reply_reg,
                             FIELD_PREP(GUC_HXG_MSG_0_ORIGIN,
                                        GUC_HXG_ORIGIN_GUC),
-                            GUC_HXG_MSG_0_ORIGIN,
-                            50);
+                            GUC_HXG_MSG_0_ORIGIN, 50, &reply);
        if (ret) {
 timeout:
                drm_err(&xe->drm, "mmio request 0x%08x: no reply 0x%08x\n",
-                       request[0], xe_mmio_read32(gt, reply_reg));
+                       request[0], reply);
                return ret;
        }
 
index 93b22fac6e149597a9c79838bbe516956d8310d9..c8c93bdf4760fcebed2fe750be2a25877cbf09bb 100644 (file)
@@ -85,7 +85,7 @@ int xe_huc_auth(struct xe_huc *huc)
 
        ret = xe_mmio_wait32(gt, GEN11_HUC_KERNEL_LOAD_INFO.reg,
                             HUC_LOAD_SUCCESSFUL,
-                            HUC_LOAD_SUCCESSFUL, 100);
+                            HUC_LOAD_SUCCESSFUL, 100, NULL);
        if (ret) {
                drm_err(&xe->drm, "HuC: Firmware not verified %d\n", ret);
                goto fail;
index 7352b622ca87a34f70df93dc8d72f6c97d2f2a3b..ccd97a4a89c16160cc1d27048a61e22cbd671f71 100644 (file)
@@ -82,21 +82,28 @@ static inline int xe_mmio_write32_and_verify(struct xe_gt *gt,
        return (reg_val & mask) != eval ? -EINVAL : 0;
 }
 
-static inline int xe_mmio_wait32(struct xe_gt *gt,
-                                u32 reg, u32 val,
-                                u32 mask, u32 timeout_ms)
+static inline int xe_mmio_wait32(struct xe_gt *gt, u32 reg, u32 val,
+                                u32 mask, u32 timeout_ms, u32 *out_val)
 {
        ktime_t cur = ktime_get_raw();
        const ktime_t end = ktime_add_ms(cur, timeout_ms);
+       int ret = -ETIMEDOUT;
        s64 wait = 10;
+       u32 read;
 
        for (;;) {
                if ((xe_mmio_read32(gt, reg) & mask) == val)
                        return 0;
 
+               read = xe_mmio_read32(gt, reg);
+               if ((read & mask) == val) {
+                       ret = 0;
+                       break;
+               }
+
                cur = ktime_get_raw();
                if (!ktime_before(cur, end))
-                       return -ETIMEDOUT;
+                       break;
 
                if (ktime_after(ktime_add_us(cur, wait), end))
                        wait = ktime_us_delta(end, cur);
@@ -105,7 +112,10 @@ static inline int xe_mmio_wait32(struct xe_gt *gt,
                wait <<= 1;
        }
 
-       return -ETIMEDOUT;
+       if (out_val)
+               *out_val = read;
+
+       return ret;
 }
 
 int xe_mmio_ioctl(struct drm_device *dev, void *data,
index 86c47b7f09017ea7f703f3e577d2ffeeb9396f4e..edd6a5d2db34e91ba318e4cf37d446b357d049d7 100644 (file)
@@ -326,7 +326,7 @@ static int uc_fw_xfer(struct xe_uc_fw *uc_fw, u32 offset, u32 dma_flags)
 {
        struct xe_device *xe = uc_fw_to_xe(uc_fw);
        struct xe_gt *gt = uc_fw_to_gt(uc_fw);
-       u32 src_offset;
+       u32 src_offset, dma_ctrl;
        int ret;
 
        xe_force_wake_assert_held(gt_to_fw(gt), XE_FW_GT);
@@ -352,11 +352,10 @@ static int uc_fw_xfer(struct xe_uc_fw *uc_fw, u32 offset, u32 dma_flags)
                        _MASKED_BIT_ENABLE(dma_flags | START_DMA));
 
        /* Wait for DMA to finish */
-       ret = xe_mmio_wait32(gt, DMA_CTRL.reg, 0, START_DMA, 100);
+       ret = xe_mmio_wait32(gt, DMA_CTRL.reg, 0, START_DMA, 100, &dma_ctrl);
        if (ret)
                drm_err(&xe->drm, "DMA for %s fw failed, DMA_CTRL=%u\n",
-                       xe_uc_fw_type_repr(uc_fw->type),
-                       xe_mmio_read32(gt, DMA_CTRL.reg));
+                       xe_uc_fw_type_repr(uc_fw->type), dma_ctrl);
 
        /* Disable the bits once DMA is over */
        xe_mmio_write32(gt, DMA_CTRL.reg, _MASKED_BIT_DISABLE(dma_flags));