summaryrefslogtreecommitdiff
path: root/drivers/accel
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/accel')
-rw-r--r--drivers/accel/amdxdna/aie2_ctx.c26
-rw-r--r--drivers/accel/amdxdna/aie2_pci.c1
-rw-r--r--drivers/accel/amdxdna/aie2_pci.h7
-rw-r--r--drivers/accel/ethosu/ethosu_gem.c54
4 files changed, 56 insertions, 32 deletions
diff --git a/drivers/accel/amdxdna/aie2_ctx.c b/drivers/accel/amdxdna/aie2_ctx.c
index 101f324ee178..4b3a62aa8798 100644
--- a/drivers/accel/amdxdna/aie2_ctx.c
+++ b/drivers/accel/amdxdna/aie2_ctx.c
@@ -43,20 +43,22 @@ struct aie2_ctx_health {
static inline void aie2_tdr_signal(struct amdxdna_dev *xdna)
{
- WRITE_ONCE(xdna->dev_handle->tdr_status, AIE2_TDR_SIGNALED);
+ WRITE_ONCE(xdna->dev_handle->last_signal_ts, jiffies);
}
static bool aie2_tdr_detect(struct amdxdna_dev *xdna)
{
struct amdxdna_dev_hdl *ndev = xdna->dev_handle;
+ unsigned long last = READ_ONCE(ndev->last_signal_ts);
- if (READ_ONCE(ndev->tdr_status) == AIE2_TDR_WAIT) {
- XDNA_ERR(xdna, "TDR timeout detected");
- return true;
- }
+ if (!tdr_timeout_ms)
+ return false;
+
+ if (!time_after(jiffies, last + msecs_to_jiffies(tdr_timeout_ms)))
+ return false;
- WRITE_ONCE(ndev->tdr_status, AIE2_TDR_WAIT);
- return false;
+ XDNA_ERR(xdna, "TDR timeout detected");
+ return true;
}
static void aie2_cmd_release(struct kref *ref)
@@ -434,6 +436,12 @@ out:
mmput(job->mm);
fence = ERR_PTR(ret);
} else {
+ /*
+ * Command is successfully posted to hardware, update the
+ * tdr timestamp. The total pending commands are limited.
+ * So there will not be a case that driver keeps posting
+ * commands without getting any hardware respond.
+ */
aie2_tdr_signal(hwctx->client->xdna);
}
trace_xdna_job(sched_job, hwctx->name, "sent to device",
@@ -658,7 +666,9 @@ int aie2_hwctx_init(struct amdxdna_hwctx *hwctx)
const struct drm_sched_init_args args = {
.ops = &sched_ops,
.credit_limit = HWCTX_MAX_CMDS,
- .timeout = msecs_to_jiffies(tdr_timeout_ms),
+ .timeout = tdr_timeout_ms ?
+ msecs_to_jiffies(tdr_timeout_ms) :
+ MAX_SCHEDULE_TIMEOUT,
.name = "amdxdna_js",
.dev = xdna->ddev.dev,
};
diff --git a/drivers/accel/amdxdna/aie2_pci.c b/drivers/accel/amdxdna/aie2_pci.c
index 22f66c7f534d..daec1f6b4907 100644
--- a/drivers/accel/amdxdna/aie2_pci.c
+++ b/drivers/accel/amdxdna/aie2_pci.c
@@ -420,6 +420,7 @@ static int aie2_hw_start(struct amdxdna_dev *xdna)
goto stop_fw;
}
+ WRITE_ONCE(ndev->last_signal_ts, jiffies);
ndev->dev_status = AIE2_DEV_START;
return 0;
diff --git a/drivers/accel/amdxdna/aie2_pci.h b/drivers/accel/amdxdna/aie2_pci.h
index 77648cc548b6..ea1dac106400 100644
--- a/drivers/accel/amdxdna/aie2_pci.h
+++ b/drivers/accel/amdxdna/aie2_pci.h
@@ -143,11 +143,6 @@ struct aie2_exec_msg_ops {
u32 (*get_chain_msg_op)(u32 cmd_op);
};
-enum aie2_tdr_status {
- AIE2_TDR_WAIT,
- AIE2_TDR_SIGNALED,
-};
-
struct amdxdna_dev_hdl {
struct aie_device aie;
const struct amdxdna_dev_priv *priv;
@@ -179,7 +174,7 @@ struct amdxdna_dev_hdl {
u32 hwctx_num;
struct amdxdna_async_error last_async_err;
- enum aie2_tdr_status tdr_status;
+ unsigned long last_signal_ts;
};
struct aie2_hw_ops {
diff --git a/drivers/accel/ethosu/ethosu_gem.c b/drivers/accel/ethosu/ethosu_gem.c
index 3401883e207f..d50fed64d4d9 100644
--- a/drivers/accel/ethosu/ethosu_gem.c
+++ b/drivers/accel/ethosu/ethosu_gem.c
@@ -192,9 +192,17 @@ static u64 dma_length(struct ethosu_validated_cmdstream_info *info,
return len;
}
-static u64 feat_matrix_length(struct ethosu_validated_cmdstream_info *info,
+static bool feat_matrix_chained(struct ethosu_device *edev, struct feat_matrix *fm)
+{
+ u32 storage = fm->precision >> 14;
+
+ return !ethosu_is_u65(edev) && storage == 2;
+}
+
+static u64 feat_matrix_length(struct ethosu_device *edev,
+ struct ethosu_validated_cmdstream_info *info,
struct feat_matrix *fm,
- u32 x, u32 y, u32 c)
+ u32 x, u32 y, u32 c, bool ofm)
{
u32 element_size, storage = fm->precision >> 14;
int tile = 0;
@@ -203,6 +211,9 @@ static u64 feat_matrix_length(struct ethosu_validated_cmdstream_info *info,
if (fm->region < 0)
return U64_MAX;
+ if (feat_matrix_chained(edev, fm))
+ return 0;
+
switch (storage) {
case 0:
if (x >= fm->width0 + 1) {
@@ -223,6 +234,8 @@ static u64 feat_matrix_length(struct ethosu_validated_cmdstream_info *info,
tile = 1;
}
break;
+ default:
+ return U64_MAX;
}
if (fm->base[tile] == U64_MAX)
return U64_MAX;
@@ -231,10 +244,11 @@ static u64 feat_matrix_length(struct ethosu_validated_cmdstream_info *info,
switch ((fm->precision >> 6) & 0x3) { // format
case 0: //nhwc:
- addr += x * fm->stride_x + c;
+ element_size = BIT((fm->precision >> (ofm ? 1 : 2)) & 0x3);
+ addr += x * fm->stride_x + c * element_size;
break;
case 1: //nhcwb16:
- element_size = BIT((fm->precision >> 1) & 0x3);
+ element_size = BIT((fm->precision >> (ofm ? 1 : 2)) & 0x3);
addr += (c / 16) * fm->stride_c + (16 * x + (c & 0xf)) * element_size;
break;
@@ -250,6 +264,7 @@ static int calc_sizes(struct drm_device *ddev,
u16 op, struct cmd_state *st,
bool ifm, bool ifm2, bool weight, bool scale)
{
+ struct ethosu_device *edev = to_ethosu_device(ddev);
u64 len;
if (ifm) {
@@ -267,8 +282,8 @@ static int calc_sizes(struct drm_device *ddev,
if (ifm_height < 0 || ifm_width < 0)
return -EINVAL;
- len = feat_matrix_length(info, &st->ifm, ifm_width,
- ifm_height, st->ifm.depth);
+ len = feat_matrix_length(edev, info, &st->ifm, ifm_width,
+ ifm_height, st->ifm.depth, false);
dev_dbg(ddev->dev, "op %d: IFM:%d:0x%llx-0x%llx\n",
op, st->ifm.region, st->ifm.base[0], len);
if (len == U64_MAX)
@@ -276,8 +291,8 @@ static int calc_sizes(struct drm_device *ddev,
}
if (ifm2) {
- len = feat_matrix_length(info, &st->ifm2, st->ifm.depth,
- 0, st->ofm.depth);
+ len = feat_matrix_length(edev, info, &st->ifm2, st->ifm.depth,
+ 0, st->ofm.depth, false);
dev_dbg(ddev->dev, "op %d: IFM2:%d:0x%llx-0x%llx\n",
op, st->ifm2.region, st->ifm2.base[0], len);
if (len == U64_MAX)
@@ -308,13 +323,14 @@ static int calc_sizes(struct drm_device *ddev,
st->scale[0].base + st->scale[0].length);
}
- len = feat_matrix_length(info, &st->ofm, st->ofm.width,
- st->ofm.height[2], st->ofm.depth);
+ len = feat_matrix_length(edev, info, &st->ofm, st->ofm.width,
+ st->ofm.height[2], st->ofm.depth, true);
dev_dbg(ddev->dev, "op %d: OFM:%d:0x%llx-0x%llx\n",
op, st->ofm.region, st->ofm.base[0], len);
if (len == U64_MAX)
return -EINVAL;
- info->output_region[st->ofm.region] = true;
+ if (!feat_matrix_chained(edev, &st->ofm))
+ info->output_region[st->ofm.region] = true;
return 0;
}
@@ -324,6 +340,7 @@ static int calc_sizes_elemwise(struct drm_device *ddev,
u16 op, struct cmd_state *st,
bool ifm, bool ifm2)
{
+ struct ethosu_device *edev = to_ethosu_device(ddev);
u32 height, width, depth;
u64 len;
@@ -332,8 +349,8 @@ static int calc_sizes_elemwise(struct drm_device *ddev,
width = st->ifm.broadcast & 0x2 ? 0 : st->ofm.width;
depth = st->ifm.broadcast & 0x4 ? 0 : st->ofm.depth;
- len = feat_matrix_length(info, &st->ifm, width,
- height, depth);
+ len = feat_matrix_length(edev, info, &st->ifm, width,
+ height, depth, false);
dev_dbg(ddev->dev, "op %d: IFM:%d:0x%llx-0x%llx\n",
op, st->ifm.region, st->ifm.base[0], len);
if (len == U64_MAX)
@@ -345,21 +362,22 @@ static int calc_sizes_elemwise(struct drm_device *ddev,
width = st->ifm2.broadcast & 0x2 ? 0 : st->ofm.width;
depth = st->ifm2.broadcast & 0x4 ? 0 : st->ofm.depth;
- len = feat_matrix_length(info, &st->ifm2, width,
- height, depth);
+ len = feat_matrix_length(edev, info, &st->ifm2, width,
+ height, depth, false);
dev_dbg(ddev->dev, "op %d: IFM2:%d:0x%llx-0x%llx\n",
op, st->ifm2.region, st->ifm2.base[0], len);
if (len == U64_MAX)
return -EINVAL;
}
- len = feat_matrix_length(info, &st->ofm, st->ofm.width,
- st->ofm.height[2], st->ofm.depth);
+ len = feat_matrix_length(edev, info, &st->ofm, st->ofm.width,
+ st->ofm.height[2], st->ofm.depth, true);
dev_dbg(ddev->dev, "op %d: OFM:%d:0x%llx-0x%llx\n",
op, st->ofm.region, st->ofm.base[0], len);
if (len == U64_MAX)
return -EINVAL;
- info->output_region[st->ofm.region] = true;
+ if (!feat_matrix_chained(edev, &st->ofm))
+ info->output_region[st->ofm.region] = true;
return 0;
}