Skip to content

Commit

Permalink
misc: xilinx-ai-engine: Add sysfs event binary attribute
Browse files Browse the repository at this point in the history
Add sysfs event binary attribute to exports all active events in
a given tile to a tile level sysfs node.

Signed-off-by: Nishad Saraf <[email protected]>
Acked-by: Wendy Liang <[email protected]>
  • Loading branch information
NishadSaraf authored and Michal Simek committed Apr 15, 2021
1 parent 098a50b commit a93b6d8
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 3 deletions.
1 change: 1 addition & 0 deletions drivers/misc/xilinx-ai-engine/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ xilinx-aie-$(CONFIG_XILINX_AIE) := ai-engine-aie.o \
ai-engine-sysfs-core.o \
ai-engine-sysfs-dma.o \
ai-engine-sysfs-error.o \
ai-engine-sysfs-event.o \
ai-engine-sysfs-lock.o
3 changes: 3 additions & 0 deletions drivers/misc/xilinx-ai-engine/ai-engine-aie.c
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,9 @@ static const struct aie_dev_attr aie_tile_dev_attr[] = {
AIE_TILE_DEV_ATTR_RO(error, AIE_TILE_TYPE_MASK_TILE |
AIE_TILE_TYPE_MASK_SHIMNOC |
AIE_TILE_TYPE_MASK_SHIMPL),
AIE_TILE_DEV_ATTR_RO(event, AIE_TILE_TYPE_MASK_TILE |
AIE_TILE_TYPE_MASK_SHIMNOC |
AIE_TILE_TYPE_MASK_SHIMPL),
AIE_TILE_DEV_ATTR_RO(lock, AIE_TILE_TYPE_MASK_TILE |
AIE_TILE_TYPE_MASK_SHIMNOC),
};
Expand Down
6 changes: 6 additions & 0 deletions drivers/misc/xilinx-ai-engine/ai-engine-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ enum aie_tile_type {
#define AIE_SYSFS_ERROR_SIZE 300U
#define AIE_SYSFS_ERROR_CATEGORY_SIZE 500U
#define AIE_SYSFS_LOCK_STS_SIZE 400U
#define AIE_SYSFS_EVENT_STS_SIZE 550U

/* Helper macros to dynamically create sysfs device attribute */
#define AIE_PART_DEV_ATTR_RO(_name) { \
Expand Down Expand Up @@ -1079,5 +1080,10 @@ ssize_t aie_part_show_error_stat(struct device *dev,
struct device_attribute *attr, char *buffer);
ssize_t aie_part_read_cb_error(struct kobject *kobj, char *buffer,
ssize_t size);
ssize_t aie_tile_show_event(struct device *dev, struct device_attribute *attr,
char *buffer);
void aie_read_event_status(struct aie_partition *apart,
struct aie_location *loc,
enum aie_module_type module, u32 *reg);

#endif /* AIE_INTERNAL_H */
6 changes: 3 additions & 3 deletions drivers/misc/xilinx-ai-engine/ai-engine-interrupt.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ static u8 aie_get_broadcast_event(struct aie_partition *apart,
* @module: module type.
* @reg: array to store event status register values.
*/
static void aie_read_event_status(struct aie_partition *apart,
struct aie_location *loc,
enum aie_module_type module, u32 *reg)
void aie_read_event_status(struct aie_partition *apart,
struct aie_location *loc,
enum aie_module_type module, u32 *reg)
{
const struct aie_event_attr *event_mod;
u8 offset;
Expand Down
125 changes: 125 additions & 0 deletions drivers/misc/xilinx-ai-engine/ai-engine-sysfs-event.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Xilinx AI Engine device driver.
*
* Copyright (C) 2021 Xilinx, Inc.
*/
#include "ai-engine-internal.h"

/**
* aie_tile_print_event() - formats events strings from each module into a
* single buffer.
* @atile: AI engine tile.
* @buffer: export buffer.
* @core: core module event string
* @mem: memory module event string
* @pl: pl module event string
* @return: length of string copied to buffer.
*/
static ssize_t aie_tile_print_event(struct aie_tile *atile, char *buffer,
char *core, char *mem, char *pl)
{
ssize_t len = 0, size = PAGE_SIZE;
u32 ttype;

ttype = atile->apart->adev->ops->get_tile_type(&atile->loc);
if (ttype == AIE_TILE_TYPE_TILE) {
len += scnprintf(&buffer[len], max(0L, size - len),
"core: %s\n", core);
len += scnprintf(&buffer[len], max(0L, size - len),
"memory: %s\n", mem);
} else {
len += scnprintf(&buffer[len], max(0L, size - len), "pl: %s\n",
pl);
}
return len;
}

/**
* aie_tile_show_event() - exports all active events in a given tile to a
* tile level sysfs node.
* @dev: AI engine tile device.
* @attr: sysfs device attribute.
* @buffer: export buffer.
* @return: length of string copied to buffer.
*/
ssize_t aie_tile_show_event(struct device *dev, struct device_attribute *attr,
char *buffer)
{
struct aie_tile *atile = container_of(dev, struct aie_tile, dev);
struct aie_partition *apart = atile->apart;
ssize_t l = 0;
unsigned long cs[4] = {0}, ms[4] = {0}, ps[4] = {0};
u32 ttype, n;
char core_buf[AIE_SYSFS_EVENT_STS_SIZE],
mem_buf[AIE_SYSFS_EVENT_STS_SIZE],
pl_buf[AIE_SYSFS_EVENT_STS_SIZE];
bool is_delimit_req = false;

if (mutex_lock_interruptible(&apart->mlock)) {
dev_err(&apart->dev,
"Failed to acquire lock. Process was interrupted by fatal signals\n");
return 0;
}

ttype = apart->adev->ops->get_tile_type(&atile->loc);

if (!aie_part_check_clk_enable_loc(apart, &atile->loc)) {
mutex_unlock(&apart->mlock);
return aie_tile_print_event(atile, buffer, "clock_gated",
"clock_gated", "clock_gated");
}

if (ttype == AIE_TILE_TYPE_TILE) {
aie_read_event_status(apart, &atile->loc, AIE_CORE_MOD,
(u32 *)cs);
aie_read_event_status(apart, &atile->loc, AIE_MEM_MOD,
(u32 *)ms);
} else {
aie_read_event_status(apart, &atile->loc, AIE_PL_MOD,
(u32 *)ps);
}

for_each_set_bit(n, cs, 128) {
if (is_delimit_req) {
l += scnprintf(&core_buf[l],
max(0L, AIE_SYSFS_EVENT_STS_SIZE - l),
DELIMITER_LEVEL0);
}

l += scnprintf(&core_buf[l],
max(0L, AIE_SYSFS_EVENT_STS_SIZE - l), "%d", n);
is_delimit_req = true;
}

l = 0;
is_delimit_req = false;
for_each_set_bit(n, ms, 128) {
if (is_delimit_req) {
l += scnprintf(&mem_buf[l],
max(0L, AIE_SYSFS_EVENT_STS_SIZE - l),
DELIMITER_LEVEL0);
}

l += scnprintf(&mem_buf[l],
max(0L, AIE_SYSFS_EVENT_STS_SIZE - l), "%d", n);
is_delimit_req = true;
}

l = 0;
is_delimit_req = false;
for_each_set_bit(n, ps, 128) {
if (is_delimit_req) {
l += scnprintf(&pl_buf[l],
max(0L, AIE_SYSFS_EVENT_STS_SIZE - l),
DELIMITER_LEVEL0);
}

l += scnprintf(&pl_buf[l],
max(0L, AIE_SYSFS_EVENT_STS_SIZE - l), "%d", n);
is_delimit_req = true;
}

mutex_unlock(&apart->mlock);
return aie_tile_print_event(atile, buffer, core_buf, mem_buf, pl_buf);
}

0 comments on commit a93b6d8

Please sign in to comment.