drivers: neural_net: remove obsolete driver
This driver is not being used by anything and is not being built or tested, so remove it. Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit is contained in:
parent
c350c65be8
commit
1640d37189
7 changed files with 0 additions and 804 deletions
|
@ -9,13 +9,6 @@ Overview
|
|||
The GNA API provides access to Intel's Gaussian Mixture Model and Neural Network
|
||||
Accelerator (GNA).
|
||||
|
||||
Configuration Options
|
||||
*********************
|
||||
|
||||
Related configuration options:
|
||||
|
||||
* :kconfig:option:`CONFIG_INTEL_GNA`
|
||||
|
||||
API Reference
|
||||
*************
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_library()
|
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_INTEL_GNA intel_gna.c)
|
||||
|
|
|
@ -14,6 +14,4 @@ module = NEURAL_NET
|
|||
module-str = neural_net
|
||||
source "subsys/logging/Kconfig.template.log_config"
|
||||
|
||||
source "drivers/neural_net/Kconfig.*"
|
||||
|
||||
endif # NEURAL_NET
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
# Neural network accelerator driver configuration options
|
||||
|
||||
# Copyright (c) 2018 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
menuconfig INTEL_GNA
|
||||
bool "Intel GNA Inferencing Engine"
|
||||
help
|
||||
Enable support for Intel's GMM and Neural Network Accelerator
|
||||
|
||||
if INTEL_GNA
|
||||
|
||||
config INTEL_GNA_INIT_PRIORITY
|
||||
int "Init priority"
|
||||
default 99
|
||||
help
|
||||
Device driver initialization priority.
|
||||
|
||||
config INTEL_GNA_MAX_MODELS
|
||||
int "Max number of neural network models supported by driver"
|
||||
default 4
|
||||
help
|
||||
Max. number of unique neural network models required in the system
|
||||
|
||||
config INTEL_GNA_MAX_PENDING_REQUESTS
|
||||
int "Max number of pending inference requests"
|
||||
default 4
|
||||
help
|
||||
Maximum number of pending inference requests in the driver
|
||||
|
||||
config INTEL_GNA_POWER_MODE
|
||||
int "GNA operation mode"
|
||||
default 0
|
||||
range 0 3
|
||||
help
|
||||
Sets GNA operation mode for power saving
|
||||
Levels are:
|
||||
0 ALWAYS_ON, GNA is always on with very minimal power save
|
||||
1 CLOCK_GATED, GNA clock is gated when not active
|
||||
2 POWER_GATED, GNA clock and power are gated when not active
|
||||
3 ALWAYS_OFF, GNA is tuned off and never used in the system
|
||||
|
||||
endif # INTEL_GNA
|
|
@ -1,526 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Intel Corporation
|
||||
*
|
||||
* Author: Sathish Kuttan <sathish.k.kuttan@intel.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/** @file
|
||||
* @brief Intel GNA device driver
|
||||
*
|
||||
* Device driver implementation for Intel's
|
||||
* Gaussian Mixture Model and Neural Network Accelerator (GNA)
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT intel_gna
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <string.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/drivers/gna.h>
|
||||
|
||||
#include <memory.h>
|
||||
#include "intel_gna.h"
|
||||
|
||||
#define LOG_LEVEL CONFIG_NEURAL_NET_LOG_LEVEL
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/irq.h>
|
||||
LOG_MODULE_REGISTER(neural_net);
|
||||
|
||||
#if LOG_LEVEL >= LOG_LEVEL_DBG
|
||||
static void intel_gna_regs_dump(const struct device *dev);
|
||||
static void intel_gna_config_desc_dump(const struct device *dev);
|
||||
#define INTEL_GNA_REGS_DUMP(dev) intel_gna_regs_dump((dev))
|
||||
#define INTEL_GNA_CONFIG_DESC_DUMP(dev) intel_gna_config_desc_dump((dev))
|
||||
#else
|
||||
#define INTEL_GNA_REGS_DUMP(dev)
|
||||
#define INTEL_GNA_CONFIG_DESC_DUMP(dev)
|
||||
#endif
|
||||
|
||||
#define GNA_MODEL_VIRT_BASE_DEFAULT 0
|
||||
|
||||
DEVICE_DECLARE(gna);
|
||||
static struct intel_gna_config_desc __aligned(GNA_PG_SIZE_IN_BYTES)
|
||||
gna_config_desc;
|
||||
static struct intel_gna_page_table __aligned(GNA_PG_SIZE_IN_BYTES)
|
||||
gna_page_table[GNA_NUM_PG_TABLES_NEEDED];
|
||||
|
||||
static void intel_gna_interrupt_handler(const struct device *dev)
|
||||
{
|
||||
struct intel_gna_data *const gna = dev->data;
|
||||
|
||||
volatile struct intel_gna_regs *regs = gna->regs;
|
||||
struct intel_gna_pending_resp pending_resp;
|
||||
struct intel_gna_pending_req pending_req;
|
||||
|
||||
/* check for generic / virtual address out of range error */
|
||||
if (regs->gnasts & (GNA_STS_VIRT_ADDR_OOR | GNA_STS_ERROR)) {
|
||||
pending_resp.response.result = GNA_RESULT_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
/* check for parameter out of range error */
|
||||
if (regs->gnasts & GNA_STS_PARAM_OOR) {
|
||||
pending_resp.response.result =
|
||||
GNA_RESULT_PARAM_OUT_OF_RANGE_ERROR;
|
||||
}
|
||||
|
||||
/* check for output buffer full error */
|
||||
if (regs->gnasts & GNA_STS_BUFFER_FULL) {
|
||||
pending_resp.response.result =
|
||||
GNA_RESULT_OUTPUT_BUFFER_FULL_ERROR;
|
||||
}
|
||||
|
||||
/* check for scoring completion out of range error */
|
||||
if (regs->gnasts & GNA_STS_SCORE_COMPL) {
|
||||
pending_resp.response.result = GNA_RESULT_INFERENCE_COMPLETE;
|
||||
}
|
||||
|
||||
if (k_msgq_get(&gna->request_queue, &pending_req, K_NO_WAIT) != 0) {
|
||||
LOG_ERR("Pending request queue is empty");
|
||||
} else {
|
||||
sys_cache_data_invd_range(pending_req.model->output,
|
||||
pending_req.output_len);
|
||||
/* copy output from the model buffer to application buffer */
|
||||
memcpy(pending_req.output, pending_req.model->output,
|
||||
pending_req.output_len);
|
||||
pending_resp.response.output = pending_req.output;
|
||||
pending_resp.response.output_len = pending_req.output_len;
|
||||
pending_resp.callback = pending_req.callback;
|
||||
|
||||
pending_resp.response.stats.cycles_per_sec = 200000000U;
|
||||
if (regs->gnasts & GNA_STS_STATS_VALID) {
|
||||
pending_resp.response.stats.total_cycles = regs->gnaptc;
|
||||
pending_resp.response.stats.stall_cycles = regs->gnasc;
|
||||
} else {
|
||||
pending_resp.response.stats.total_cycles = 0U;
|
||||
pending_resp.response.stats.stall_cycles = 0U;
|
||||
}
|
||||
|
||||
k_msgq_put(&gna->response_queue, &pending_resp, K_NO_WAIT);
|
||||
|
||||
k_work_submit(&gna->gna_work);
|
||||
}
|
||||
|
||||
/* clear GNA operation and disable interrupt */
|
||||
regs->gnactrl |= GNA_CTRL_INTR_DISABLE | GNA_CTRL_ABORT_CLEAR;
|
||||
gna->state = GNA_STATE_IDLE;
|
||||
}
|
||||
|
||||
static void gna_work_handler(struct k_work *work)
|
||||
{
|
||||
struct intel_gna_data *gna = (struct intel_gna_data *)work;
|
||||
struct intel_gna_pending_resp resp;
|
||||
|
||||
while (k_msgq_get(&gna->response_queue, &resp, K_NO_WAIT) == 0) {
|
||||
resp.callback(&resp.response);
|
||||
}
|
||||
}
|
||||
|
||||
static int intel_gna_setup_page_table(void *physical, size_t size,
|
||||
void *virtual)
|
||||
{
|
||||
uint32_t page;
|
||||
uint32_t dir_index;
|
||||
uint32_t table_index;
|
||||
uint32_t virt_addr = (uint32_t)virtual;
|
||||
uint32_t phys_addr = (uint32_t)physical;
|
||||
|
||||
LOG_DBG("physical %p size %u virtual %p", physical, size, virtual);
|
||||
|
||||
if (((phys_addr + size - L2_SRAM_BASE) > L2_SRAM_SIZE) ||
|
||||
(phys_addr < L2_SRAM_BASE)) {
|
||||
LOG_ERR("model at %p of size %u exceeds L2 SRAM space",
|
||||
physical, size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dir_index = GNA_VA_PG_DIR(virtual);
|
||||
table_index = GNA_VA_PG_TABLE(virtual);
|
||||
|
||||
if (dir_index >= GNA_NUM_PG_TABLES_NEEDED) {
|
||||
LOG_ERR("virtual addr %p is in page dir %u (max %u)",
|
||||
virtual, dir_index,
|
||||
(uint32_t)GNA_NUM_PG_TABLES_NEEDED);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (page = 0U; page < GNA_NUM_PAGES(size); page++) {
|
||||
dir_index = GNA_VA_PG_DIR(virt_addr);
|
||||
table_index = GNA_VA_PG_TABLE(virt_addr);
|
||||
gna_page_table[dir_index].entry[table_index] =
|
||||
GNA_PG_TABLE_ENTRY(phys_addr);
|
||||
|
||||
LOG_DBG("di %u tb %u @ %p va %08x pa %08x ent %08x",
|
||||
dir_index, table_index,
|
||||
&gna_page_table[dir_index].entry[table_index],
|
||||
virt_addr, phys_addr,
|
||||
gna_page_table[dir_index].entry[table_index]);
|
||||
phys_addr += GNA_PG_SIZE_IN_BYTES;
|
||||
virt_addr += GNA_PG_SIZE_IN_BYTES;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int intel_gna_initialize(const struct device *dev)
|
||||
{
|
||||
struct intel_gna_data *const gna = dev->data;
|
||||
uint32_t page_dir_entry;
|
||||
|
||||
k_msgq_init(&gna->request_queue, (char *)gna->requests,
|
||||
sizeof(struct intel_gna_pending_req),
|
||||
GNA_REQUEST_QUEUE_LEN);
|
||||
|
||||
k_msgq_init(&gna->response_queue, (char *)gna->responses,
|
||||
sizeof(struct intel_gna_pending_resp),
|
||||
GNA_REQUEST_QUEUE_LEN);
|
||||
|
||||
k_mem_slab_init(&gna->model_slab, (char *)gna->models,
|
||||
sizeof(struct intel_gna_model), GNA_MAX_NUM_MODELS);
|
||||
|
||||
k_work_init(&gna->gna_work, gna_work_handler);
|
||||
|
||||
/* initialize the configuration descriptor's page directory table */
|
||||
for (int page = 0; page < GNA_CONFIG_DESC_PG_DIR_SIZE; page++) {
|
||||
page_dir_entry = (page < GNA_NUM_PG_TABLES_NEEDED) ?
|
||||
GNA_PG_DIR_ENTRY(&gna_page_table[page]) : (uint32_t)-1;
|
||||
gna_config_desc.pagedir[page] = page_dir_entry;
|
||||
LOG_DBG("%s: page %u pagetable %08x",
|
||||
dev->name, page, gna_config_desc.pagedir[page]);
|
||||
}
|
||||
gna_config_desc.vamaxaddr = GNA_ADDRESSABLE_MEM_SIZE;
|
||||
LOG_DBG("%s: max virtual address %08x",
|
||||
dev->name, gna_config_desc.vamaxaddr);
|
||||
|
||||
/* flush cache */
|
||||
sys_cache_data_flush_range((void *)&gna_config_desc, sizeof(gna_config_desc));
|
||||
|
||||
LOG_INF("%s: initialized (max %u models & max %u pending requests)",
|
||||
dev->name, GNA_MAX_NUM_MODELS,
|
||||
GNA_REQUEST_QUEUE_LEN);
|
||||
LOG_INF("%s: max addressable memory %u MB",
|
||||
dev->name, GNA_ADDRESSABLE_MEM_SIZE >> 20);
|
||||
LOG_INF("%s: %u page table(s) at %p and %u bytes",
|
||||
dev->name, (uint32_t)GNA_NUM_PG_TABLES_NEEDED,
|
||||
gna_page_table, sizeof(gna_page_table));
|
||||
LOG_INF("%s: configuration descriptor at %p",
|
||||
dev->name, &gna_config_desc);
|
||||
|
||||
/* register interrupt handler */
|
||||
IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority),
|
||||
intel_gna_interrupt_handler, DEVICE_GET(gna), 0);
|
||||
/* enable interrupt */
|
||||
irq_enable(INTEL_GNA_IRQ_ID);
|
||||
|
||||
gna->state = GNA_STATE_INITIALIZED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int intel_gna_configure(const struct device *dev,
|
||||
struct gna_config *cfg)
|
||||
{
|
||||
struct intel_gna_data *const gna = dev->data;
|
||||
volatile struct intel_gna_regs *regs = gna->regs;
|
||||
|
||||
if (gna->state != GNA_STATE_INITIALIZED) {
|
||||
LOG_ERR("Configuration attempt in invalid state (%u)",
|
||||
gna->state);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (cfg == NULL) {
|
||||
LOG_ERR("Config pointer is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
gna->config = *cfg;
|
||||
|
||||
regs->gnactrl |= GNA_CTRL_OPER_MODEL_XNN |
|
||||
GNA_CTRL_ERR_INTR_ENABLE | GNA_CTRL_COMPL_INTR_ENABLE;
|
||||
|
||||
switch (CONFIG_INTEL_GNA_POWER_MODE) {
|
||||
case GNA_POWER_MODE_ALWAYS_ON:
|
||||
regs->gnactrl |= GNA_CTRL_PM_OVRIDE_CLK_ON |
|
||||
GNA_CTRL_PM_OVRIDE_PWR_ON;
|
||||
break;
|
||||
|
||||
case GNA_POWER_MODE_CLOCK_GATED:
|
||||
regs->gnactrl |= GNA_CTRL_PM_OVRIDE_PWR_ON;
|
||||
break;
|
||||
|
||||
case GNA_POWER_MODE_POWER_GATED:
|
||||
case GNA_POWER_MODE_ALWAYS_OFF:
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_ERR("Invalid config CONFIG_INTEL_GNA_POWER_MODE (%u)",
|
||||
CONFIG_INTEL_GNA_POWER_MODE);
|
||||
break;
|
||||
}
|
||||
|
||||
/* assign the configuration descriptor address as the base */
|
||||
regs->gnadesbase = GNA_PHYS_ADDR_TO_PAGE(&gna_config_desc);
|
||||
|
||||
INTEL_GNA_CONFIG_DESC_DUMP(dev);
|
||||
|
||||
LOG_INF("Device %s (version %u.%u) configured with power mode %u",
|
||||
dev->name, regs->gnaversion >> 1,
|
||||
(uint32_t)(regs->gnaversion & BIT(0)),
|
||||
CONFIG_INTEL_GNA_POWER_MODE);
|
||||
|
||||
gna->state = GNA_STATE_IDLE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int intel_gna_register_model(const struct device *dev,
|
||||
struct gna_model_info *model,
|
||||
void **model_handle)
|
||||
{
|
||||
struct intel_gna_data *const gna = dev->data;
|
||||
struct intel_gna_model *gna_model;
|
||||
struct gna_model_header *header;
|
||||
uint32_t ro_size, rw_size = 0;
|
||||
void *virtual_base;
|
||||
void *ro_region;
|
||||
|
||||
if ((gna->state != GNA_STATE_IDLE) &&
|
||||
(gna->state != GNA_STATE_ACTIVE)) {
|
||||
LOG_ERR("Invalid state (%u)", gna->state);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((model_handle == NULL) || (model == NULL)) {
|
||||
LOG_ERR("model and/or model_handle is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((model->header == NULL) || (model->rw_region == NULL)) {
|
||||
LOG_ERR("model header / rw_region is/are NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* check for 64B alignment */
|
||||
if (((uint32_t)model->rw_region & BIT_MASK(6)) ||
|
||||
((uint32_t)model->ro_region & BIT_MASK(6))) {
|
||||
LOG_ERR("rw_region / ro_region not aligned to 64B");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (k_mem_slab_alloc(&gna->model_slab, (void **)&gna_model,
|
||||
K_NO_WAIT)) {
|
||||
LOG_ERR("No memory to register model");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
LOG_INF("model header: %p rw: %p ro: %p", model->header,
|
||||
model->rw_region, model->ro_region);
|
||||
|
||||
header = model->header;
|
||||
virtual_base = (void *)GNA_MODEL_VIRT_BASE_DEFAULT;
|
||||
|
||||
LOG_INF("model_size: %u rw_region_size: %u", header->model_size,
|
||||
header->rw_region_size);
|
||||
|
||||
/* setup page table entries for RW region */
|
||||
if (model->rw_region && header->rw_region_size) {
|
||||
/* calculate layer descriptor size */
|
||||
rw_size = header->layer_count *
|
||||
sizeof(struct intel_gna_layer_desc);
|
||||
/* round up to page boundary */
|
||||
rw_size = GNA_PAGES_TO_BYTES(GNA_NUM_PAGES(rw_size));
|
||||
/* add the input rw_region_size to get total rw_region_size */
|
||||
rw_size += header->rw_region_size;
|
||||
|
||||
intel_gna_setup_page_table(model->rw_region, rw_size,
|
||||
virtual_base);
|
||||
sys_cache_data_flush_range(model->rw_region, rw_size);
|
||||
}
|
||||
|
||||
if (model->ro_region == NULL) {
|
||||
ro_region = (void *)((uint32_t)model->rw_region + rw_size);
|
||||
} else {
|
||||
ro_region = model->ro_region;
|
||||
}
|
||||
|
||||
ro_size = header->model_size - rw_size;
|
||||
|
||||
LOG_INF("rw_region: %p (%u) ro_region: %p (%u)",
|
||||
model->rw_region, rw_size, ro_region, ro_size);
|
||||
|
||||
/* setup page table entries for RO region */
|
||||
intel_gna_setup_page_table(ro_region, ro_size,
|
||||
(void *)((uint32_t)virtual_base + rw_size));
|
||||
|
||||
sys_cache_data_flush_range(ro_region, ro_size);
|
||||
sys_cache_data_flush_range(gna_page_table, sizeof(gna_page_table));
|
||||
|
||||
/* copy the model pointers */
|
||||
gna_model->model = *model;
|
||||
gna_model->vabase = virtual_base;
|
||||
gna_model->input = (void *)((uint32_t)model->rw_region +
|
||||
*(uint32_t *)((uint32_t)model->rw_region +
|
||||
header->input_ptr_offset));
|
||||
gna_model->output = (void *)((uint32_t)model->rw_region +
|
||||
*(uint32_t *)((uint32_t)model->rw_region +
|
||||
header->output_ptr_offset));
|
||||
gna_model->registered = true;
|
||||
|
||||
LOG_INF("model->rw_region: %p", model->rw_region);
|
||||
LOG_INF("input offset: %u",
|
||||
*(uint32_t *)((uint32_t)model->rw_region + header->input_ptr_offset));
|
||||
LOG_INF("gna_model->input: %p", gna_model->input);
|
||||
LOG_INF("output offset: %u",
|
||||
*(uint32_t *)((uint32_t)model->rw_region +
|
||||
header->output_ptr_offset));
|
||||
LOG_INF("gna_model->output: %p", gna_model->output);
|
||||
LOG_DBG("returning model handle: %p", gna_model);
|
||||
*model_handle = (void *)gna_model;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int intel_gna_deregister_model(const struct device *dev,
|
||||
void *model_handle)
|
||||
{
|
||||
struct intel_gna_data *const gna = dev->data;
|
||||
struct intel_gna_model *gna_model;
|
||||
|
||||
if (model_handle == NULL) {
|
||||
LOG_ERR("model_handle is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
gna_model = (struct intel_gna_model *)model_handle;
|
||||
gna_model->registered = false;
|
||||
k_mem_slab_free(&gna->model_slab, model_handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int intel_gna_infer(const struct device *dev,
|
||||
struct gna_inference_req *req,
|
||||
gna_callback callback)
|
||||
{
|
||||
struct intel_gna_data *const gna = dev->data;
|
||||
volatile struct intel_gna_regs *regs = gna->regs;
|
||||
struct intel_gna_pending_req pending_req;
|
||||
struct gna_model_header *header;
|
||||
struct intel_gna_model *handle;
|
||||
struct gna_model_info *model;
|
||||
size_t input_size;
|
||||
int ret;
|
||||
|
||||
LOG_DBG("device %p", dev);
|
||||
if (req == NULL) {
|
||||
LOG_ERR("Invalid request pointer");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (callback == NULL) {
|
||||
LOG_ERR("Invalid callback function pointer");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
handle = (struct intel_gna_model *)req->model_handle;
|
||||
|
||||
if (handle->registered != true) {
|
||||
LOG_ERR("Model is not registered. Handle %p", handle);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (req->input == NULL) {
|
||||
LOG_ERR("Invalid input buffer");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (req->output == NULL) {
|
||||
LOG_ERR("Invalid output buffer");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
model = &handle->model;
|
||||
header = model->header;
|
||||
input_size = header->bytes_per_input * header->num_input_nodes;
|
||||
|
||||
pending_req.model = handle;
|
||||
pending_req.output = req->output;
|
||||
pending_req.output_len = header->bytes_per_output *
|
||||
header->num_output_nodes;
|
||||
pending_req.callback = callback;
|
||||
|
||||
ret = k_msgq_put(&gna->request_queue, &pending_req, K_NO_WAIT);
|
||||
if (ret) {
|
||||
LOG_ERR("Unable to queue request (code %d)", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (gna->state != GNA_STATE_IDLE) {
|
||||
/* multiple pending requests are not yet supported */
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* copy input */
|
||||
memcpy(handle->input, req->input, input_size);
|
||||
sys_cache_data_flush_range(handle->input, input_size);
|
||||
|
||||
/* assign layer descriptor base address to configuration descriptor */
|
||||
gna_config_desc.labase = (uint32_t)handle->vabase;
|
||||
gna_config_desc.lacnt = (uint16_t)header->layer_count;
|
||||
sys_cache_data_flush_range(&gna_config_desc, sizeof(gna_config_desc));
|
||||
|
||||
gna->state = GNA_STATE_ACTIVE;
|
||||
regs->gnactrl = (regs->gnactrl & ~GNA_CTRL_INTR_DISABLE) |
|
||||
GNA_CTRL_ACCEL_START | GNA_CTRL_STATS_ENABLE_STALL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if LOG_LEVEL >= LOG_LEVEL_DBG
|
||||
static void intel_gna_regs_dump(const struct device *dev)
|
||||
{
|
||||
struct intel_gna_data *const gna = dev->data;
|
||||
volatile struct intel_gna_regs *regs = gna->regs;
|
||||
|
||||
LOG_DBG("gnasts :%08x", regs->gnasts);
|
||||
LOG_DBG("gnactrl :%08x", regs->gnactrl);
|
||||
LOG_DBG("gnamctl :%08x", regs->gnamctl);
|
||||
LOG_DBG("gnaptc :%08x", regs->gnaptc);
|
||||
LOG_DBG("gnasc :%08x", regs->gnasc);
|
||||
LOG_DBG("gnaisi :%08x", regs->gnaisi);
|
||||
LOG_DBG("gnais_low :%08x", regs->gnais_low);
|
||||
LOG_DBG("gnais_high :%08x", regs->gnais_high);
|
||||
LOG_DBG("gnabp_low :%08x", regs->gnabp_low);
|
||||
LOG_DBG("gnabp_high :%08x", regs->gnabp_high);
|
||||
LOG_DBG("gnadesbase :%08x", regs->gnadesbase);
|
||||
LOG_DBG("gnaibuffs :%08x", regs->gnaibuffs);
|
||||
LOG_DBG("ovrcfgctl :%08x", regs->gnaibuffs);
|
||||
LOG_DBG("gnaversion :%08x", regs->gnaversion);
|
||||
}
|
||||
|
||||
static void intel_gna_config_desc_dump(const struct device *dev)
|
||||
{
|
||||
struct intel_gna_data *const gna = dev->data;
|
||||
volatile struct intel_gna_regs *regs = gna->regs;
|
||||
|
||||
LOG_DBG("gnadesbase :%08x", regs->gnadesbase);
|
||||
LOG_DBG("labase :%08x", gna_config_desc.labase);
|
||||
LOG_DBG("lacnt :%u", gna_config_desc.lacnt);
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct gna_driver_api gna_driver_api = {
|
||||
.configure = intel_gna_configure,
|
||||
.register_model = intel_gna_register_model,
|
||||
.deregister_model = intel_gna_deregister_model,
|
||||
.infer = intel_gna_infer,
|
||||
};
|
||||
|
||||
static struct intel_gna_data intel_gna_driver_data = {
|
||||
.regs = (volatile struct intel_gna_regs *)DT_INST_REG_ADDR(0),
|
||||
};
|
||||
|
||||
DEVICE_DT_INST_DEFINE(0, intel_gna_initialize,
|
||||
NULL,
|
||||
(void *)&intel_gna_driver_data, NULL,
|
||||
POST_KERNEL, CONFIG_INTEL_GNA_INIT_PRIORITY,
|
||||
&gna_driver_api);
|
|
@ -1,205 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Intel Corporation
|
||||
*
|
||||
* Author: Sathish Kuttan <sathish.k.kuttan@intel.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/** @file
|
||||
* @brief Intel GNA device driver
|
||||
*
|
||||
* Device driver implementation for Intel's
|
||||
* Gaussian Mixture Model and Neural Network Accelerator (GNA)
|
||||
*/
|
||||
|
||||
#ifndef __INTEL_GNA__
|
||||
#define __INTEL_GNA__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* number of requests that could be pending in driver */
|
||||
#define GNA_REQUEST_QUEUE_LEN CONFIG_INTEL_GNA_MAX_PENDING_REQUESTS
|
||||
#define GNA_MAX_NUM_MODELS CONFIG_INTEL_GNA_MAX_MODELS
|
||||
|
||||
/* values must match config values in Kconfig.intel_gna */
|
||||
#define GNA_POWER_MODE_ALWAYS_ON 0
|
||||
#define GNA_POWER_MODE_CLOCK_GATED 1
|
||||
#define GNA_POWER_MODE_POWER_GATED 2
|
||||
#define GNA_POWER_MODE_ALWAYS_OFF 3
|
||||
|
||||
#define INTEL_GNA_BASE_ADDR 0x0000E800
|
||||
|
||||
#define INTEL_GNA_IRQ_ID 0x00000506
|
||||
#define INTEL_GNA_IRQ_PRIORITY 3
|
||||
|
||||
#define GNA_STS_INTR_PENDING BIT(31)
|
||||
#define GNA_STS_SATURATION_OCCURRED BIT(17)
|
||||
#define GNA_STS_BUFFER_FULL BIT(16)
|
||||
#define GNA_STS_ERROR BIT(15)
|
||||
#define GNA_STS_PARAM_OOR BIT(8)
|
||||
#define GNA_STS_VIRT_ADDR_OOR BIT(7)
|
||||
#define GNA_STS_STATS_VALID BIT(3)
|
||||
#define GNA_STS_SUSP_PAUSE BIT(2)
|
||||
#define GNA_STS_SUSP_BREAKP BIT(1)
|
||||
#define GNA_STS_SCORE_COMPL BIT(0)
|
||||
|
||||
#define GNA_CTRL_INTR_DISABLE BIT(31)
|
||||
#define GNA_CTRL_PM_IDLE_DISABLE BIT(18)
|
||||
#define GNA_CTRL_PM_OVRIDE_CLK_ON BIT(17)
|
||||
#define GNA_CTRL_PM_OVRIDE_PWR_ON BIT(16)
|
||||
#define GNA_CTRL_STATS_ENABLE_STALL (1 << 12)
|
||||
#define GNA_CTRL_STATS_MASK (BIT_MASK(4) << 12)
|
||||
#define GNA_CTRL_ERR_INTR_ENABLE (1 << 10)
|
||||
#define GNA_CTRL_COMPL_INTR_ENABLE (1 << 8)
|
||||
#define GNA_CTRL_OPER_MODEL_XNN (1 << 5)
|
||||
#define GNA_CTRL_ABORT_CLEAR (1 << 2)
|
||||
#define GNA_CTRL_ACCEL_START (1 << 0)
|
||||
#define GNA_CTRL_ACCEL_BUSY GNA_CTRL_ACCEL_START
|
||||
|
||||
#define GNA_CONFIG_DESC_PG_DIR_SIZE 64
|
||||
|
||||
#define GNA_LAYER_DESC_ALIGN (128)
|
||||
|
||||
#define GNA_ADDRESSABLE_MEM_SIZE L2_SRAM_SIZE
|
||||
#define GNA_NUM_PG_TABLE_INDEX_BITS 10
|
||||
#define GNA_NUM_PG_TABLE_ENTRIES BIT(GNA_NUM_PG_TABLE_INDEX_BITS)
|
||||
#define GNA_PG_SIZE_IN_BITSHIFT 12
|
||||
#define GNA_PG_SIZE_IN_BYTES BIT(GNA_PG_SIZE_IN_BITSHIFT)
|
||||
|
||||
#define GNA_SHIFT_RNDUP(value, shift) (((value) + BIT_MASK(shift)) >> (shift))
|
||||
|
||||
#define GNA_NUM_PAGES(bytes) \
|
||||
GNA_SHIFT_RNDUP((bytes), GNA_PG_SIZE_IN_BITSHIFT)
|
||||
|
||||
#define GNA_PAGES_TO_BYTES(pages) ((pages) << GNA_PG_SIZE_IN_BITSHIFT)
|
||||
|
||||
#define GNA_MAX_NUM_PAGES GNA_NUM_PAGES(GNA_ADDRESSABLE_MEM_SIZE)
|
||||
|
||||
#define GNA_NUM_PG_TABLES_NEEDED \
|
||||
GNA_SHIFT_RNDUP(GNA_MAX_NUM_PAGES, GNA_NUM_PG_TABLE_INDEX_BITS)
|
||||
|
||||
#if GNA_NUM_PG_TABLES_NEEDED > GNA_CONFIG_DESC_PG_DIR_SIZE
|
||||
#error GNA_NUM_PG_TABLES_NEEDED exceeds GNA_CONFIG_DESC_PG_DIR_SIZE
|
||||
#endif
|
||||
|
||||
#define GNA_GET_BITS(val, b_hi, b_lo) ((((uint32_t)(val)) << (31 - (b_hi))) >> \
|
||||
(31 - (b_hi) + (b_lo)))
|
||||
|
||||
#define GNA_VA_PG_DIR(virt_addr) GNA_GET_BITS(virt_addr, 27, 22)
|
||||
#define GNA_VA_PG_TABLE(virt_addr) GNA_GET_BITS(virt_addr, 21, 12)
|
||||
|
||||
#define GNA_PHYS_ADDR_TO_PAGE(addr) ((uint32_t)(addr) >> \
|
||||
GNA_PG_SIZE_IN_BITSHIFT)
|
||||
#define GNA_PG_DIR_ENTRY(phys_addr) GNA_PHYS_ADDR_TO_PAGE(phys_addr)
|
||||
#define GNA_PG_BASE(addr) ((uint32_t)(addr) & \
|
||||
~BIT_MASK(GNA_PG_SIZE_IN_BITSHIFT))
|
||||
#define GNA_PG_OFFSET(addr) ((uint32_t)(addr) & \
|
||||
BIT_MASK(GNA_PG_SIZE_IN_BITSHIFT))
|
||||
#define GNA_PG_TABLE_ENTRY(phys_addr) GNA_PHYS_ADDR_TO_PAGE(phys_addr)
|
||||
|
||||
struct intel_gna_regs {
|
||||
uint32_t gnasts;
|
||||
uint32_t gnactrl;
|
||||
uint32_t gnamctl;
|
||||
uint32_t gnaptc;
|
||||
uint32_t gnasc;
|
||||
uint32_t gnaisi;
|
||||
uint32_t gnais_low;
|
||||
uint32_t gnais_high;
|
||||
uint32_t gnabp_low;
|
||||
uint32_t gnabp_high;
|
||||
uint32_t reserved1[2];
|
||||
uint32_t gnadesbase;
|
||||
uint32_t gnaibuffs;
|
||||
uint32_t reserved2[2];
|
||||
uint32_t ovrcfgctl;
|
||||
uint32_t reserved3[3];
|
||||
uint32_t gnaversion;
|
||||
};
|
||||
|
||||
struct intel_gna_config_desc {
|
||||
uint32_t reserved1[64];
|
||||
uint32_t labase; /* layer array base */
|
||||
uint16_t lacnt; /* layer array count */
|
||||
uint16_t reserved2;
|
||||
uint32_t reserved3[62];
|
||||
uint32_t vamaxaddr; /* virtual address max address */
|
||||
uint32_t reserved4[3];
|
||||
/* page directory entries */
|
||||
uint32_t pagedir[GNA_CONFIG_DESC_PG_DIR_SIZE];
|
||||
} __packed;
|
||||
|
||||
struct intel_gna_page_table {
|
||||
uint32_t entry[GNA_NUM_PG_TABLE_ENTRIES];
|
||||
} __aligned(GNA_PG_SIZE_IN_BYTES);
|
||||
|
||||
struct intel_gna_layer_desc {
|
||||
uint32_t gna_words[8];
|
||||
uint32_t inarrayptr;
|
||||
uint32_t outarrayactptr;
|
||||
uint32_t outarraysumptr;
|
||||
uint32_t outfbarrayactptr;
|
||||
uint32_t wtfltarrayptr;
|
||||
uint32_t constarrayptr;
|
||||
uint32_t actoutputslistptr;
|
||||
uint32_t actfuncsectdefptr;
|
||||
uint32_t reserved[16];
|
||||
} __packed __aligned(GNA_LAYER_DESC_ALIGN);
|
||||
|
||||
struct intel_gna_config {
|
||||
struct gna_config config;
|
||||
};
|
||||
|
||||
struct intel_gna_model {
|
||||
struct gna_model_info model;
|
||||
void *input;
|
||||
void *output;
|
||||
void *vabase;
|
||||
bool registered;
|
||||
};
|
||||
|
||||
struct intel_gna_pending_req {
|
||||
struct intel_gna_model *model;
|
||||
void *output;
|
||||
size_t output_len;
|
||||
gna_callback callback;
|
||||
};
|
||||
|
||||
struct intel_gna_pending_resp {
|
||||
struct gna_inference_resp response;
|
||||
gna_callback callback;
|
||||
};
|
||||
|
||||
enum gna_state {
|
||||
GNA_STATE_UNINITIALIZED,
|
||||
GNA_STATE_INITIALIZED,
|
||||
GNA_STATE_IDLE,
|
||||
GNA_STATE_ACTIVE,
|
||||
};
|
||||
|
||||
struct intel_gna_data {
|
||||
/*
|
||||
* gna_cb_work must be the first element in the structure
|
||||
* since it will be typecast as intel_gna_data in the work handler
|
||||
*/
|
||||
struct k_work gna_work;
|
||||
volatile struct intel_gna_regs *regs;
|
||||
struct k_mem_slab model_slab;
|
||||
struct intel_gna_model models[GNA_MAX_NUM_MODELS];
|
||||
struct k_msgq request_queue;
|
||||
struct intel_gna_pending_req requests[GNA_REQUEST_QUEUE_LEN];
|
||||
struct k_msgq response_queue;
|
||||
struct intel_gna_pending_resp responses[GNA_REQUEST_QUEUE_LEN];
|
||||
enum gna_state state;
|
||||
|
||||
struct gna_config config;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __INTEL_GNA__ */
|
|
@ -1,19 +0,0 @@
|
|||
# Copyright (c) 2021 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: Intel Gaussian Mixture Model and Neural Network Accelerator (GNA)
|
||||
|
||||
compatible: "intel,gna"
|
||||
|
||||
include: [base.yaml]
|
||||
|
||||
properties:
|
||||
reg:
|
||||
required: true
|
||||
|
||||
interrupts:
|
||||
required: true
|
||||
|
||||
interrupt-parent:
|
||||
required: true
|
Loading…
Add table
Add a link
Reference in a new issue