diff options
Diffstat (limited to 'gxp-firmware-data.c')
-rw-r--r-- | gxp-firmware-data.c | 98 |
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; |