summaryrefslogtreecommitdiff
path: root/gxp-firmware-data.c
diff options
context:
space:
mode:
Diffstat (limited to 'gxp-firmware-data.c')
-rw-r--r--gxp-firmware-data.c98
1 files changed, 66 insertions, 32 deletions
diff --git a/gxp-firmware-data.c b/gxp-firmware-data.c
index d1def41..6f22f8d 100644
--- a/gxp-firmware-data.c
+++ b/gxp-firmware-data.c
@@ -70,7 +70,7 @@ struct gxp_fw_data_manager {
/* Doorbells allocator and reserved doorbell IDs */
struct range_alloc *doorbell_allocator;
- int core_wakeup_doorbells[GXP_NUM_CORES];
+ int core_wakeup_doorbells[GXP_NUM_WAKEUP_DOORBELLS];
int semaphore_doorbells[GXP_NUM_CORES];
/* Sync barriers allocator and reserved sync barrier IDs */
@@ -87,7 +87,7 @@ struct gxp_fw_data_manager {
struct fw_memory_allocator *allocator;
struct fw_memory sys_desc_mem;
struct fw_memory wdog_mem;
- struct fw_memory telemetry_mem;
+ struct fw_memory core_telemetry_mem;
struct fw_memory debug_dump_mem;
};
@@ -266,18 +266,18 @@ static struct fw_memory init_watchdog(struct gxp_fw_data_manager *mgr)
return mem;
}
-static struct fw_memory init_telemetry(struct gxp_fw_data_manager *mgr)
+static struct fw_memory init_core_telemetry(struct gxp_fw_data_manager *mgr)
{
- struct gxp_telemetry_descriptor *tel_region;
+ struct gxp_core_telemetry_descriptor *tel_region;
struct fw_memory mem;
mem_alloc_allocate(mgr->allocator, &mem, sizeof(*tel_region),
- __alignof__(struct gxp_telemetry_descriptor));
+ __alignof__(struct gxp_core_telemetry_descriptor));
tel_region = mem.host_addr;
/*
- * Telemetry is disabled for now.
+ * Core telemetry is disabled for now.
* Subsuequent calls to the FW data module can be used to populate or
* depopulate the descriptor pointers on demand.
*/
@@ -292,7 +292,7 @@ static struct fw_memory init_debug_dump(struct gxp_dev *gxp)
if (gxp->debug_dump_mgr) {
mem.host_addr = gxp->debug_dump_mgr->buf.vaddr;
- mem.device_addr = gxp->debug_dump_mgr->buf.daddr;
+ mem.device_addr = gxp->debug_dump_mgr->buf.dsp_addr;
mem.sz = gxp->debug_dump_mgr->buf.size;
} else {
mem.host_addr = 0;
@@ -510,7 +510,7 @@ int gxp_fw_data_init(struct gxp_dev *gxp)
/* Allocate doorbells */
/* Pinned: Cores wakeup doorbell */
- for (i = 0; i < GXP_NUM_CORES; i++) {
+ for (i = 0; i < GXP_NUM_WAKEUP_DOORBELLS; i++) {
mgr->core_wakeup_doorbells[i] = DOORBELL_ID_CORE_WAKEUP(i);
res = range_alloc_get(mgr->doorbell_allocator,
mgr->core_wakeup_doorbells[i]);
@@ -589,9 +589,10 @@ int gxp_fw_data_init(struct gxp_dev *gxp)
mgr->wdog_mem = init_watchdog(mgr);
mgr->system_desc->watchdog_dev_addr = mgr->wdog_mem.device_addr;
- /* Allocate the descriptor for device-side telemetry */
- mgr->telemetry_mem = init_telemetry(mgr);
- mgr->system_desc->telemetry_dev_addr = mgr->telemetry_mem.device_addr;
+ /* Allocate the descriptor for device-side core telemetry */
+ mgr->core_telemetry_mem = init_core_telemetry(mgr);
+ mgr->system_desc->core_telemetry_dev_addr =
+ mgr->core_telemetry_mem.device_addr;
/* Set the debug dump region parameters if available */
mgr->debug_dump_mem = init_debug_dump(gxp);
@@ -610,6 +611,7 @@ void *gxp_fw_data_create_app(struct gxp_dev *gxp, uint core_list)
{
struct gxp_fw_data_manager *mgr = gxp->data_mgr;
struct app_metadata *app;
+ void *err;
int i;
app = kzalloc(sizeof(struct app_metadata), GFP_KERNEL);
@@ -626,6 +628,11 @@ void *gxp_fw_data_create_app(struct gxp_dev *gxp, uint core_list)
app->user_doorbells_count = DEFAULT_APP_USER_DOORBELL_COUNT;
app->user_doorbells =
kcalloc(app->user_doorbells_count, sizeof(int), GFP_KERNEL);
+ if (!app->user_doorbells) {
+ err = ERR_PTR(-ENOMEM);
+ goto err_user_doorbells;
+ }
+
for (i = 0; i < app->user_doorbells_count; i++) {
range_alloc_get_any(mgr->doorbell_allocator,
&app->user_doorbells[i]);
@@ -635,6 +642,11 @@ void *gxp_fw_data_create_app(struct gxp_dev *gxp, uint core_list)
app->user_barriers_count = DEFAULT_APP_USER_BARRIER_COUNT;
app->user_barriers =
kcalloc(app->user_barriers_count, sizeof(int), GFP_KERNEL);
+ if (!app->user_barriers) {
+ err = ERR_PTR(-ENOMEM);
+ goto err_user_barriers;
+ }
+
for (i = 0; i < app->user_barriers_count; i++) {
range_alloc_get_any(mgr->sync_barrier_allocator,
&app->user_barriers[i]);
@@ -650,6 +662,16 @@ void *gxp_fw_data_create_app(struct gxp_dev *gxp, uint core_list)
}
return app;
+
+err_user_barriers:
+ for (i = 0; i < app->user_doorbells_count; i++)
+ range_alloc_put(mgr->doorbell_allocator,
+ app->user_doorbells[i]);
+ kfree(app->user_doorbells);
+err_user_doorbells:
+ kfree(app);
+
+ return err;
}
void gxp_fw_data_destroy_app(struct gxp_dev *gxp, void *application)
@@ -689,7 +711,7 @@ void gxp_fw_data_destroy(struct gxp_dev *gxp)
if (!mgr)
return;
- mem_alloc_free(mgr->allocator, &mgr->telemetry_mem);
+ mem_alloc_free(mgr->allocator, &mgr->core_telemetry_mem);
mem_alloc_free(mgr->allocator, &mgr->wdog_mem);
mem_alloc_free(mgr->allocator, &mgr->sys_desc_mem);
mem_alloc_destroy(mgr->allocator);
@@ -709,15 +731,16 @@ void gxp_fw_data_destroy(struct gxp_dev *gxp)
}
}
-int gxp_fw_data_set_telemetry_descriptors(struct gxp_dev *gxp, u8 type,
- u32 host_status,
- dma_addr_t *buffer_addrs,
- u32 per_buffer_size)
+int gxp_fw_data_set_core_telemetry_descriptors(struct gxp_dev *gxp, u8 type,
+ u32 host_status,
+ struct gxp_coherent_buf *buffers,
+ u32 per_buffer_size)
{
- struct gxp_telemetry_descriptor *descriptor =
- gxp->data_mgr->telemetry_mem.host_addr;
- struct telemetry_descriptor *core_descriptors;
+ struct gxp_core_telemetry_descriptor *descriptor =
+ gxp->data_mgr->core_telemetry_mem.host_addr;
+ struct core_telemetry_descriptor *core_descriptors;
uint core;
+ bool enable;
if (type == GXP_TELEMETRY_TYPE_LOGGING)
core_descriptors = descriptor->per_core_loggers;
@@ -726,26 +749,37 @@ int gxp_fw_data_set_telemetry_descriptors(struct gxp_dev *gxp, u8 type,
else
return -EINVAL;
- /* Validate that the provided IOVAs are addressable (i.e. 32-bit) */
- for (core = 0; core < GXP_NUM_CORES; core++) {
- if (buffer_addrs[core] > U32_MAX)
- return -EINVAL;
- }
+ enable = (host_status & GXP_CORE_TELEMETRY_HOST_STATUS_ENABLED);
- for (core = 0; core < GXP_NUM_CORES; core++) {
- core_descriptors[core].host_status = host_status;
- core_descriptors[core].buffer_addr = (u32)buffer_addrs[core];
- core_descriptors[core].buffer_size = per_buffer_size;
+ if (enable) {
+ /* Validate that the provided IOVAs are addressable (i.e. 32-bit) */
+ for (core = 0; core < GXP_NUM_CORES; core++) {
+ if (buffers && buffers[core].dsp_addr > U32_MAX &&
+ buffers[core].size == per_buffer_size)
+ return -EINVAL;
+ }
+
+ for (core = 0; core < GXP_NUM_CORES; core++) {
+ core_descriptors[core].host_status = host_status;
+ core_descriptors[core].buffer_addr = (u32)buffers[core].dsp_addr;
+ core_descriptors[core].buffer_size = per_buffer_size;
+ }
+ } else {
+ for (core = 0; core < GXP_NUM_CORES; core++) {
+ core_descriptors[core].host_status = host_status;
+ core_descriptors[core].buffer_addr = 0;
+ core_descriptors[core].buffer_size = 0;
+ }
}
return 0;
}
-u32 gxp_fw_data_get_telemetry_device_status(struct gxp_dev *gxp, uint core,
- u8 type)
+u32 gxp_fw_data_get_core_telemetry_device_status(struct gxp_dev *gxp, uint core,
+ u8 type)
{
- struct gxp_telemetry_descriptor *descriptor =
- gxp->data_mgr->telemetry_mem.host_addr;
+ struct gxp_core_telemetry_descriptor *descriptor =
+ gxp->data_mgr->core_telemetry_mem.host_addr;
if (core >= GXP_NUM_CORES)
return 0;