Loading arch/arm64/boot/dts/qcom/atoll-npu.dtsi +10 −9 Original line number Diff line number Diff line Loading @@ -17,8 +17,9 @@ reg = <0x9900000 0x20000>, <0x99f0000 0x10000>, <0x9980000 0x10000>, <0x17c00000 0x10000>; reg-names = "tcm", "core", "cc", "apss_shared"; <0x17c00000 0x10000>, <0x01f40000 0x40000>; reg-names = "tcm", "core", "cc", "apss_shared", "tcsr"; interrupts = <GIC_SPI 583 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 585 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 588 IRQ_TYPE_EDGE_RISING>, Loading Loading @@ -75,8 +76,8 @@ 100000000 200000000 200000000 120000000 40000000 150000000 30000000 200000000 19200000 50000000 Loading @@ -94,7 +95,7 @@ 400000000 400000000 200000000 40000000 37500000 300000000 19200000 50000000 Loading @@ -112,8 +113,8 @@ 515000000 515000000 300000000 75000000 400000000 37500000 403000000 19200000 50000000 19200000 Loading @@ -135,7 +136,7 @@ 19200000 100000000 19200000 515000000 650000000 19200000 660000000>; }; Loading @@ -153,7 +154,7 @@ 19200000 100000000 19200000 650000000 800000000 19200000 800000000>; }; Loading drivers/media/platform/msm/npu_v2/npu_common.h +10 −3 Original line number Diff line number Diff line Loading @@ -52,8 +52,11 @@ #define NPU_MAX_DT_NAME_LEN 21 #define NPU_MAX_PWRLEVELS 8 #define NPU_MAX_STATS_BUF_SIZE 16384 #define NPU_MAX_PATCH_NUM 160 #define NPU_MAX_BW_DEVS 4 #define PERF_MODE_DEFAULT 0 enum npu_power_level { NPU_PWRLEVEL_MINSVS = 0, NPU_PWRLEVEL_LOWSVS, Loading Loading @@ -170,6 +173,8 @@ struct npu_reg { * @uc_pwrlevel - power level from user driver setting * @perf_mode_override - perf mode from sysfs to override perf mode * settings from user driver * @dcvs_mode - dcvs mode from sysfs to turn on dcvs mode * settings from user driver * @devbw - bw device */ struct npu_pwrctrl { Loading @@ -189,6 +194,8 @@ struct npu_pwrctrl { uint32_t cdsprm_pwrlevel; uint32_t fmax_pwrlevel; uint32_t perf_mode_override; uint32_t dcvs_mode; uint32_t cur_dcvs_activity; }; /** Loading Loading @@ -252,7 +259,7 @@ struct npu_device { struct npu_io_data core_io; struct npu_io_data tcm_io; struct npu_io_data cc_io; struct npu_io_data qdsp_io; struct npu_io_data tcsr_io; struct npu_io_data apss_shared_io; struct npu_io_data qfprom_io; Loading drivers/media/platform/msm/npu_v2/npu_debugfs.c +23 −82 Original line number Diff line number Diff line Loading @@ -32,8 +32,7 @@ */ static int npu_debug_open(struct inode *inode, struct file *file); static int npu_debug_release(struct inode *inode, struct file *file); static ssize_t npu_debug_reg_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos); static int npu_debug_reg_release(struct inode *inode, struct file *file); static ssize_t npu_debug_reg_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos); static ssize_t npu_debug_off_write(struct file *file, Loading @@ -49,13 +48,12 @@ static ssize_t npu_debug_ctrl_write(struct file *file, * Variables * ------------------------------------------------------------------------- */ struct npu_device *g_npu_dev; static struct npu_device *g_npu_dev; static const struct file_operations npu_reg_fops = { .open = npu_debug_open, .release = npu_debug_release, .release = npu_debug_reg_release, .read = npu_debug_reg_read, .write = npu_debug_reg_write, }; static const struct file_operations npu_off_fops = { Loading Loading @@ -92,6 +90,11 @@ static int npu_debug_open(struct inode *inode, struct file *file) } static int npu_debug_release(struct inode *inode, struct file *file) { return 0; } static int npu_debug_reg_release(struct inode *inode, struct file *file) { struct npu_device *npu_dev = file->private_data; struct npu_debugfs_ctx *debugfs; Loading @@ -108,41 +111,6 @@ static int npu_debug_release(struct inode *inode, struct file *file) * Function Implementations - Reg Read/Write * ------------------------------------------------------------------------- */ static ssize_t npu_debug_reg_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { size_t off; uint32_t data, cnt; struct npu_device *npu_dev = file->private_data; char buf[24]; if (count >= sizeof(buf)) return -EINVAL; if (copy_from_user(buf, user_buf, count)) return -EFAULT; buf[count] = 0; /* end of string */ cnt = sscanf(buf, "%zx %x", &off, &data); NPU_DBG("%s 0x%zx, 0x%08x\n", buf, off, data); return count; if (cnt < 2) return -EINVAL; if (npu_enable_core_power(npu_dev)) return -EPERM; REGW(npu_dev, off, data); npu_disable_core_power(npu_dev); NPU_DBG("write: addr=%zx data=%x\n", off, data); return count; } static ssize_t npu_debug_reg_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { Loading Loading @@ -262,6 +230,7 @@ static ssize_t npu_debug_off_read(struct file *file, len = scnprintf(buf, sizeof(buf), "offset=0x%08x cnt=%d\n", debugfs->reg_off, debugfs->reg_cnt); len = min(len, count); if (copy_to_user(user_buf, buf, len)) { NPU_ERR("failed to copy to user\n"); Loading Loading @@ -291,49 +260,21 @@ static ssize_t npu_debug_log_read(struct file *file, mutex_lock(&debugfs->log_lock); if (debugfs->log_num_bytes_buffered != 0) { if ((debugfs->log_read_index + debugfs->log_num_bytes_buffered) > debugfs->log_buf_size) { /* Wrap around case */ uint32_t remaining_to_end = debugfs->log_buf_size - debugfs->log_read_index; uint8_t *src_addr = debugfs->log_buf + debugfs->log_read_index; void __user *dst_addr = (void __user *) user_buf; if (copy_to_user(dst_addr, src_addr, remaining_to_end)) { NPU_ERR("failed to copy to user\n"); mutex_unlock(&debugfs->log_lock); return -EFAULT; } src_addr = debugfs->log_buf; dst_addr = (void __user *)(user_buf + remaining_to_end); if (copy_to_user(dst_addr, src_addr, debugfs->log_num_bytes_buffered - remaining_to_end)) { NPU_ERR("failed to copy to user\n"); mutex_unlock(&debugfs->log_lock); return -EFAULT; } debugfs->log_read_index = debugfs->log_num_bytes_buffered - remaining_to_end; } else { len = min(debugfs->log_num_bytes_buffered, debugfs->log_buf_size - debugfs->log_read_index); len = min(count, len); if (copy_to_user(user_buf, (debugfs->log_buf + debugfs->log_read_index), debugfs->log_num_bytes_buffered)) { debugfs->log_read_index), len)) { NPU_ERR("failed to copy to user\n"); mutex_unlock(&debugfs->log_lock); return -EFAULT; } debugfs->log_read_index += debugfs->log_num_bytes_buffered; debugfs->log_read_index += len; if (debugfs->log_read_index == debugfs->log_buf_size) debugfs->log_read_index = 0; } len = debugfs->log_num_bytes_buffered; debugfs->log_num_bytes_buffered = 0; debugfs->log_num_bytes_buffered -= len; *ppos += len; } /* mutex log unlock */ Loading drivers/media/platform/msm/npu_v2/npu_dev.c +151 −31 Original line number Diff line number Diff line Loading @@ -37,7 +37,6 @@ #define DDR_MAPPED_START_ADDR 0x80000000 #define DDR_MAPPED_SIZE 0x60000000 #define PERF_MODE_DEFAULT 0 #define MBOX_OP_TIMEOUTMS 1000 /* ------------------------------------------------------------------------- Loading Loading @@ -65,6 +64,12 @@ static ssize_t perf_mode_override_show(struct device *dev, static ssize_t perf_mode_override_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); static ssize_t dcvs_mode_show(struct device *dev, struct device_attribute *attr, char *buf); static ssize_t dcvs_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); static ssize_t boot_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); Loading Loading @@ -92,6 +97,11 @@ static int npu_exec_network_v2(struct npu_client *client, unsigned long arg); static int npu_receive_event(struct npu_client *client, unsigned long arg); static int npu_set_fw_state(struct npu_client *client, uint32_t enable); static int npu_set_property(struct npu_client *client, unsigned long arg); static int npu_get_property(struct npu_client *client, unsigned long arg); static long npu_ioctl(struct file *file, unsigned int cmd, unsigned long arg); static unsigned int npu_poll(struct file *filp, struct poll_table_struct *p); Loading Loading @@ -162,11 +172,13 @@ static DEVICE_ATTR_RO(caps); static DEVICE_ATTR_RW(pwr); static DEVICE_ATTR_RW(perf_mode_override); static DEVICE_ATTR_WO(boot); static DEVICE_ATTR_RW(dcvs_mode); static struct attribute *npu_fs_attrs[] = { &dev_attr_caps.attr, &dev_attr_pwr.attr, &dev_attr_perf_mode_override.attr, &dev_attr_dcvs_mode.attr, &dev_attr_boot.attr, NULL }; Loading Loading @@ -285,8 +297,8 @@ static ssize_t perf_mode_override_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct npu_client client; struct npu_device *npu_dev = dev_get_drvdata(dev); struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; uint32_t val; int rc; Loading @@ -297,15 +309,56 @@ static ssize_t perf_mode_override_store(struct device *dev, } val = min(val, npu_dev->pwrctrl.num_pwrlevels); mutex_lock(&host_ctx->lock); npu_dev->pwrctrl.perf_mode_override = val; NPU_INFO("setting uc_pwrlevel_override to %d\n", val); npu_set_power_level(npu_dev, true); mutex_unlock(&host_ctx->lock); NPU_INFO("setting perf mode to %d\n", val); client.npu_dev = npu_dev; npu_host_set_perf_mode(&client, 0, val); return count; } static ssize_t dcvs_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { struct npu_device *npu_dev = dev_get_drvdata(dev); struct npu_pwrctrl *pwr = &npu_dev->pwrctrl; return scnprintf(buf, PAGE_SIZE, "%d\n", pwr->dcvs_mode); } static ssize_t dcvs_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct npu_device *npu_dev = dev_get_drvdata(dev); struct msm_npu_property prop; uint32_t val; int ret = 0; ret = kstrtou32(buf, 10, &val); if (ret) { NPU_ERR("Invalid input for dcvs mode setting\n"); return -EINVAL; } val = min(val, (uint32_t)(npu_dev->pwrctrl.num_pwrlevels - 1)); NPU_DBG("sysfs: setting dcvs_mode to %d\n", val); prop.prop_id = MSM_NPU_PROP_ID_DCVS_MODE; prop.num_of_params = 1; prop.network_hdl = 0; prop.prop_param[0] = val; ret = npu_host_set_fw_property(npu_dev, &prop); if (ret) { NPU_ERR("npu_host_set_fw_property failed %d\n", ret); return ret; } npu_dev->pwrctrl.dcvs_mode = val; return count; } /* ------------------------------------------------------------------------- * SysFS - npu_boot * ------------------------------------------------------------------------- Loading Loading @@ -393,6 +446,7 @@ void npu_disable_core_power(struct npu_device *npu_dev) pwr->active_pwrlevel = pwr->default_pwrlevel; pwr->uc_pwrlevel = pwr->max_pwrlevel; pwr->cdsprm_pwrlevel = pwr->max_pwrlevel; pwr->cur_dcvs_activity = pwr->num_pwrlevels; NPU_DBG("setting back to power level=%d\n", pwr->active_pwrlevel); } Loading Loading @@ -452,14 +506,6 @@ static uint32_t npu_calc_power_level(struct npu_device *npu_dev) uint32_t active_pwr_level = npu_dev->pwrctrl.active_pwrlevel; uint32_t uc_pwr_level = npu_dev->pwrctrl.uc_pwrlevel; /* * if perf_mode_override is not 0, use it to override * uc_pwrlevel */ if (npu_dev->pwrctrl.perf_mode_override > 0) uc_pwr_level = npu_power_level_from_index(npu_dev, npu_dev->pwrctrl.perf_mode_override - 1); /* * pick the lowese power level between thermal power and usecase power * settings Loading Loading @@ -566,9 +612,6 @@ int npu_set_uc_power_level(struct npu_device *npu_dev, struct npu_pwrctrl *pwr = &npu_dev->pwrctrl; uint32_t uc_pwrlevel_to_set; if (perf_mode == PERF_MODE_DEFAULT) uc_pwrlevel_to_set = pwr->default_pwrlevel; else uc_pwrlevel_to_set = npu_power_level_from_index(npu_dev, perf_mode - 1); Loading Loading @@ -853,6 +896,7 @@ static void npu_disable_regulators(struct npu_device *npu_dev) if (host_ctx->power_vote_num > 0) { for (i = 0; i < npu_dev->regulator_num; i++) regulator_disable(regulators[i].regulator); host_ctx->power_vote_num--; } } Loading Loading @@ -1148,9 +1192,10 @@ static int npu_load_network_v2(struct npu_client *client, return -EFAULT; } if (req.patch_info_num > MSM_NPU_MAX_PATCH_LAYER_NUM) { if ((req.patch_info_num > NPU_MAX_PATCH_NUM) || (req.patch_info_num == 0)) { NPU_ERR("Invalid patch info num %d[max:%d]\n", req.patch_info_num, MSM_NPU_MAX_PATCH_LAYER_NUM); req.patch_info_num, NPU_MAX_PATCH_NUM); return -EINVAL; } Loading Loading @@ -1235,9 +1280,10 @@ static int npu_exec_network_v2(struct npu_client *client, return -EFAULT; } if (req.patch_buf_info_num > MSM_NPU_MAX_PATCH_LAYER_NUM) { if ((req.patch_buf_info_num > NPU_MAX_PATCH_NUM) || (req.patch_buf_info_num == 0)) { NPU_ERR("Invalid patch buf info num %d[max:%d]\n", req.patch_buf_info_num, MSM_NPU_MAX_PATCH_LAYER_NUM); req.patch_buf_info_num, NPU_MAX_PATCH_NUM); return -EINVAL; } Loading Loading @@ -1331,6 +1377,43 @@ static int npu_receive_event(struct npu_client *client, return ret; } static int npu_set_fw_state(struct npu_client *client, uint32_t enable) { struct npu_device *npu_dev = client->npu_dev; struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; int rc = 0; if (host_ctx->network_num > 0) { NPU_ERR("Need to unload network first\n"); mutex_unlock(&npu_dev->dev_lock); return -EINVAL; } if (enable) { NPU_DBG("enable fw\n"); rc = enable_fw(npu_dev); if (rc) { NPU_ERR("enable fw failed\n"); } else { host_ctx->npu_init_cnt++; NPU_DBG("npu_init_cnt %d\n", host_ctx->npu_init_cnt); /* set npu to lowest power level */ if (npu_set_uc_power_level(npu_dev, 1)) NPU_WARN("Failed to set uc power level\n"); } } else if (host_ctx->npu_init_cnt > 0) { NPU_DBG("disable fw\n"); disable_fw(npu_dev); host_ctx->npu_init_cnt--; NPU_DBG("npu_init_cnt %d\n", host_ctx->npu_init_cnt); } else { NPU_ERR("can't disable fw %d\n", host_ctx->npu_init_cnt); } return rc; } static int npu_set_property(struct npu_client *client, unsigned long arg) { Loading @@ -1345,9 +1428,19 @@ static int npu_set_property(struct npu_client *client, } switch (prop.prop_id) { case MSM_NPU_PROP_ID_FW_STATE: ret = npu_set_fw_state(client, (uint32_t)prop.prop_param[0]); break; case MSM_NPU_PROP_ID_PERF_MODE: ret = npu_host_set_perf_mode(client, (uint32_t)prop.network_hdl, (uint32_t)prop.prop_param[0]); break; default: NPU_ERR("Not supported property %d\n", prop.prop_id); ret = -EINVAL; ret = npu_host_set_fw_property(client->npu_dev, &prop); if (ret) NPU_ERR("npu_host_set_fw_property failed\n"); break; } Loading @@ -1373,6 +1466,10 @@ static int npu_get_property(struct npu_client *client, case MSM_NPU_PROP_ID_FW_STATE: prop.prop_param[0] = host_ctx->fw_state; break; case MSM_NPU_PROP_ID_PERF_MODE: prop.prop_param[0] = npu_host_get_perf_mode(client, (uint32_t)prop.network_hdl); break; case MSM_NPU_PROP_ID_PERF_MODE_MAX: prop.prop_param[0] = npu_dev->pwrctrl.num_pwrlevels; break; Loading @@ -1383,13 +1480,17 @@ static int npu_get_property(struct npu_client *client, prop.prop_param[0] = npu_dev->hw_version; break; default: NPU_ERR("Not supported property %d\n", prop.prop_id); return -EINVAL; ret = npu_host_get_fw_property(client->npu_dev, &prop); if (ret) { NPU_ERR("npu_host_set_fw_property failed\n"); return ret; } break; } ret = copy_to_user(argp, &prop, sizeof(prop)); if (ret) { pr_err("fail to copy to user\n"); NPU_ERR("fail to copy to user\n"); return -EFAULT; } Loading Loading @@ -1749,6 +1850,7 @@ static int npu_of_parse_pwrlevels(struct npu_device *npu_dev, pwr->uc_pwrlevel = pwr->max_pwrlevel; pwr->perf_mode_override = 0; pwr->cdsprm_pwrlevel = pwr->max_pwrlevel; pwr->cur_dcvs_activity = pwr->num_pwrlevels; return 0; } Loading Loading @@ -2119,6 +2221,7 @@ static int npu_probe(struct platform_device *pdev) return -EFAULT; npu_dev->pdev = pdev; mutex_init(&npu_dev->dev_lock); platform_set_drvdata(pdev, npu_dev); res = platform_get_resource_byname(pdev, Loading Loading @@ -2178,6 +2281,25 @@ static int npu_probe(struct platform_device *pdev) NPU_DBG("cc_io phy address=0x%llx virt=%pK\n", res->start, npu_dev->cc_io.base); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tcsr"); if (!res) { NPU_ERR("unable to get tcsr_mutex resource\n"); rc = -ENODEV; goto error_get_dev_num; } npu_dev->tcsr_io.size = resource_size(res); npu_dev->tcsr_io.phy_addr = res->start; npu_dev->tcsr_io.base = devm_ioremap(&pdev->dev, res->start, npu_dev->tcsr_io.size); if (unlikely(!npu_dev->tcsr_io.base)) { NPU_ERR("unable to map tcsr\n"); rc = -ENOMEM; goto error_get_dev_num; } NPU_DBG("tcsr phy address=0x%llx virt=%pK\n", res->start, npu_dev->tcsr_io.base); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "apss_shared"); if (!res) { Loading Loading @@ -2288,8 +2410,6 @@ static int npu_probe(struct platform_device *pdev) goto error_driver_init; } mutex_init(&npu_dev->dev_lock); rc = npu_host_init(npu_dev); if (rc) { NPU_ERR("unable to init host\n"); Loading drivers/media/platform/msm/npu_v2/npu_host_ipc.c +7 −0 Original line number Diff line number Diff line Loading @@ -243,6 +243,13 @@ static int ipc_queue_read(struct npu_device *npu_dev, status = -EPERM; goto exit; } if (packet_size > NPU_IPC_BUF_LENGTH) { NPU_ERR("Invalid packet size %d\n", packet_size); status = -EINVAL; goto exit; } new_read_idx = queue.qhdr_read_idx + packet_size; if (new_read_idx < (queue.qhdr_q_size)) { Loading Loading
arch/arm64/boot/dts/qcom/atoll-npu.dtsi +10 −9 Original line number Diff line number Diff line Loading @@ -17,8 +17,9 @@ reg = <0x9900000 0x20000>, <0x99f0000 0x10000>, <0x9980000 0x10000>, <0x17c00000 0x10000>; reg-names = "tcm", "core", "cc", "apss_shared"; <0x17c00000 0x10000>, <0x01f40000 0x40000>; reg-names = "tcm", "core", "cc", "apss_shared", "tcsr"; interrupts = <GIC_SPI 583 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 585 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 588 IRQ_TYPE_EDGE_RISING>, Loading Loading @@ -75,8 +76,8 @@ 100000000 200000000 200000000 120000000 40000000 150000000 30000000 200000000 19200000 50000000 Loading @@ -94,7 +95,7 @@ 400000000 400000000 200000000 40000000 37500000 300000000 19200000 50000000 Loading @@ -112,8 +113,8 @@ 515000000 515000000 300000000 75000000 400000000 37500000 403000000 19200000 50000000 19200000 Loading @@ -135,7 +136,7 @@ 19200000 100000000 19200000 515000000 650000000 19200000 660000000>; }; Loading @@ -153,7 +154,7 @@ 19200000 100000000 19200000 650000000 800000000 19200000 800000000>; }; Loading
drivers/media/platform/msm/npu_v2/npu_common.h +10 −3 Original line number Diff line number Diff line Loading @@ -52,8 +52,11 @@ #define NPU_MAX_DT_NAME_LEN 21 #define NPU_MAX_PWRLEVELS 8 #define NPU_MAX_STATS_BUF_SIZE 16384 #define NPU_MAX_PATCH_NUM 160 #define NPU_MAX_BW_DEVS 4 #define PERF_MODE_DEFAULT 0 enum npu_power_level { NPU_PWRLEVEL_MINSVS = 0, NPU_PWRLEVEL_LOWSVS, Loading Loading @@ -170,6 +173,8 @@ struct npu_reg { * @uc_pwrlevel - power level from user driver setting * @perf_mode_override - perf mode from sysfs to override perf mode * settings from user driver * @dcvs_mode - dcvs mode from sysfs to turn on dcvs mode * settings from user driver * @devbw - bw device */ struct npu_pwrctrl { Loading @@ -189,6 +194,8 @@ struct npu_pwrctrl { uint32_t cdsprm_pwrlevel; uint32_t fmax_pwrlevel; uint32_t perf_mode_override; uint32_t dcvs_mode; uint32_t cur_dcvs_activity; }; /** Loading Loading @@ -252,7 +259,7 @@ struct npu_device { struct npu_io_data core_io; struct npu_io_data tcm_io; struct npu_io_data cc_io; struct npu_io_data qdsp_io; struct npu_io_data tcsr_io; struct npu_io_data apss_shared_io; struct npu_io_data qfprom_io; Loading
drivers/media/platform/msm/npu_v2/npu_debugfs.c +23 −82 Original line number Diff line number Diff line Loading @@ -32,8 +32,7 @@ */ static int npu_debug_open(struct inode *inode, struct file *file); static int npu_debug_release(struct inode *inode, struct file *file); static ssize_t npu_debug_reg_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos); static int npu_debug_reg_release(struct inode *inode, struct file *file); static ssize_t npu_debug_reg_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos); static ssize_t npu_debug_off_write(struct file *file, Loading @@ -49,13 +48,12 @@ static ssize_t npu_debug_ctrl_write(struct file *file, * Variables * ------------------------------------------------------------------------- */ struct npu_device *g_npu_dev; static struct npu_device *g_npu_dev; static const struct file_operations npu_reg_fops = { .open = npu_debug_open, .release = npu_debug_release, .release = npu_debug_reg_release, .read = npu_debug_reg_read, .write = npu_debug_reg_write, }; static const struct file_operations npu_off_fops = { Loading Loading @@ -92,6 +90,11 @@ static int npu_debug_open(struct inode *inode, struct file *file) } static int npu_debug_release(struct inode *inode, struct file *file) { return 0; } static int npu_debug_reg_release(struct inode *inode, struct file *file) { struct npu_device *npu_dev = file->private_data; struct npu_debugfs_ctx *debugfs; Loading @@ -108,41 +111,6 @@ static int npu_debug_release(struct inode *inode, struct file *file) * Function Implementations - Reg Read/Write * ------------------------------------------------------------------------- */ static ssize_t npu_debug_reg_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { size_t off; uint32_t data, cnt; struct npu_device *npu_dev = file->private_data; char buf[24]; if (count >= sizeof(buf)) return -EINVAL; if (copy_from_user(buf, user_buf, count)) return -EFAULT; buf[count] = 0; /* end of string */ cnt = sscanf(buf, "%zx %x", &off, &data); NPU_DBG("%s 0x%zx, 0x%08x\n", buf, off, data); return count; if (cnt < 2) return -EINVAL; if (npu_enable_core_power(npu_dev)) return -EPERM; REGW(npu_dev, off, data); npu_disable_core_power(npu_dev); NPU_DBG("write: addr=%zx data=%x\n", off, data); return count; } static ssize_t npu_debug_reg_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { Loading Loading @@ -262,6 +230,7 @@ static ssize_t npu_debug_off_read(struct file *file, len = scnprintf(buf, sizeof(buf), "offset=0x%08x cnt=%d\n", debugfs->reg_off, debugfs->reg_cnt); len = min(len, count); if (copy_to_user(user_buf, buf, len)) { NPU_ERR("failed to copy to user\n"); Loading Loading @@ -291,49 +260,21 @@ static ssize_t npu_debug_log_read(struct file *file, mutex_lock(&debugfs->log_lock); if (debugfs->log_num_bytes_buffered != 0) { if ((debugfs->log_read_index + debugfs->log_num_bytes_buffered) > debugfs->log_buf_size) { /* Wrap around case */ uint32_t remaining_to_end = debugfs->log_buf_size - debugfs->log_read_index; uint8_t *src_addr = debugfs->log_buf + debugfs->log_read_index; void __user *dst_addr = (void __user *) user_buf; if (copy_to_user(dst_addr, src_addr, remaining_to_end)) { NPU_ERR("failed to copy to user\n"); mutex_unlock(&debugfs->log_lock); return -EFAULT; } src_addr = debugfs->log_buf; dst_addr = (void __user *)(user_buf + remaining_to_end); if (copy_to_user(dst_addr, src_addr, debugfs->log_num_bytes_buffered - remaining_to_end)) { NPU_ERR("failed to copy to user\n"); mutex_unlock(&debugfs->log_lock); return -EFAULT; } debugfs->log_read_index = debugfs->log_num_bytes_buffered - remaining_to_end; } else { len = min(debugfs->log_num_bytes_buffered, debugfs->log_buf_size - debugfs->log_read_index); len = min(count, len); if (copy_to_user(user_buf, (debugfs->log_buf + debugfs->log_read_index), debugfs->log_num_bytes_buffered)) { debugfs->log_read_index), len)) { NPU_ERR("failed to copy to user\n"); mutex_unlock(&debugfs->log_lock); return -EFAULT; } debugfs->log_read_index += debugfs->log_num_bytes_buffered; debugfs->log_read_index += len; if (debugfs->log_read_index == debugfs->log_buf_size) debugfs->log_read_index = 0; } len = debugfs->log_num_bytes_buffered; debugfs->log_num_bytes_buffered = 0; debugfs->log_num_bytes_buffered -= len; *ppos += len; } /* mutex log unlock */ Loading
drivers/media/platform/msm/npu_v2/npu_dev.c +151 −31 Original line number Diff line number Diff line Loading @@ -37,7 +37,6 @@ #define DDR_MAPPED_START_ADDR 0x80000000 #define DDR_MAPPED_SIZE 0x60000000 #define PERF_MODE_DEFAULT 0 #define MBOX_OP_TIMEOUTMS 1000 /* ------------------------------------------------------------------------- Loading Loading @@ -65,6 +64,12 @@ static ssize_t perf_mode_override_show(struct device *dev, static ssize_t perf_mode_override_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); static ssize_t dcvs_mode_show(struct device *dev, struct device_attribute *attr, char *buf); static ssize_t dcvs_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); static ssize_t boot_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); Loading Loading @@ -92,6 +97,11 @@ static int npu_exec_network_v2(struct npu_client *client, unsigned long arg); static int npu_receive_event(struct npu_client *client, unsigned long arg); static int npu_set_fw_state(struct npu_client *client, uint32_t enable); static int npu_set_property(struct npu_client *client, unsigned long arg); static int npu_get_property(struct npu_client *client, unsigned long arg); static long npu_ioctl(struct file *file, unsigned int cmd, unsigned long arg); static unsigned int npu_poll(struct file *filp, struct poll_table_struct *p); Loading Loading @@ -162,11 +172,13 @@ static DEVICE_ATTR_RO(caps); static DEVICE_ATTR_RW(pwr); static DEVICE_ATTR_RW(perf_mode_override); static DEVICE_ATTR_WO(boot); static DEVICE_ATTR_RW(dcvs_mode); static struct attribute *npu_fs_attrs[] = { &dev_attr_caps.attr, &dev_attr_pwr.attr, &dev_attr_perf_mode_override.attr, &dev_attr_dcvs_mode.attr, &dev_attr_boot.attr, NULL }; Loading Loading @@ -285,8 +297,8 @@ static ssize_t perf_mode_override_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct npu_client client; struct npu_device *npu_dev = dev_get_drvdata(dev); struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; uint32_t val; int rc; Loading @@ -297,15 +309,56 @@ static ssize_t perf_mode_override_store(struct device *dev, } val = min(val, npu_dev->pwrctrl.num_pwrlevels); mutex_lock(&host_ctx->lock); npu_dev->pwrctrl.perf_mode_override = val; NPU_INFO("setting uc_pwrlevel_override to %d\n", val); npu_set_power_level(npu_dev, true); mutex_unlock(&host_ctx->lock); NPU_INFO("setting perf mode to %d\n", val); client.npu_dev = npu_dev; npu_host_set_perf_mode(&client, 0, val); return count; } static ssize_t dcvs_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { struct npu_device *npu_dev = dev_get_drvdata(dev); struct npu_pwrctrl *pwr = &npu_dev->pwrctrl; return scnprintf(buf, PAGE_SIZE, "%d\n", pwr->dcvs_mode); } static ssize_t dcvs_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct npu_device *npu_dev = dev_get_drvdata(dev); struct msm_npu_property prop; uint32_t val; int ret = 0; ret = kstrtou32(buf, 10, &val); if (ret) { NPU_ERR("Invalid input for dcvs mode setting\n"); return -EINVAL; } val = min(val, (uint32_t)(npu_dev->pwrctrl.num_pwrlevels - 1)); NPU_DBG("sysfs: setting dcvs_mode to %d\n", val); prop.prop_id = MSM_NPU_PROP_ID_DCVS_MODE; prop.num_of_params = 1; prop.network_hdl = 0; prop.prop_param[0] = val; ret = npu_host_set_fw_property(npu_dev, &prop); if (ret) { NPU_ERR("npu_host_set_fw_property failed %d\n", ret); return ret; } npu_dev->pwrctrl.dcvs_mode = val; return count; } /* ------------------------------------------------------------------------- * SysFS - npu_boot * ------------------------------------------------------------------------- Loading Loading @@ -393,6 +446,7 @@ void npu_disable_core_power(struct npu_device *npu_dev) pwr->active_pwrlevel = pwr->default_pwrlevel; pwr->uc_pwrlevel = pwr->max_pwrlevel; pwr->cdsprm_pwrlevel = pwr->max_pwrlevel; pwr->cur_dcvs_activity = pwr->num_pwrlevels; NPU_DBG("setting back to power level=%d\n", pwr->active_pwrlevel); } Loading Loading @@ -452,14 +506,6 @@ static uint32_t npu_calc_power_level(struct npu_device *npu_dev) uint32_t active_pwr_level = npu_dev->pwrctrl.active_pwrlevel; uint32_t uc_pwr_level = npu_dev->pwrctrl.uc_pwrlevel; /* * if perf_mode_override is not 0, use it to override * uc_pwrlevel */ if (npu_dev->pwrctrl.perf_mode_override > 0) uc_pwr_level = npu_power_level_from_index(npu_dev, npu_dev->pwrctrl.perf_mode_override - 1); /* * pick the lowese power level between thermal power and usecase power * settings Loading Loading @@ -566,9 +612,6 @@ int npu_set_uc_power_level(struct npu_device *npu_dev, struct npu_pwrctrl *pwr = &npu_dev->pwrctrl; uint32_t uc_pwrlevel_to_set; if (perf_mode == PERF_MODE_DEFAULT) uc_pwrlevel_to_set = pwr->default_pwrlevel; else uc_pwrlevel_to_set = npu_power_level_from_index(npu_dev, perf_mode - 1); Loading Loading @@ -853,6 +896,7 @@ static void npu_disable_regulators(struct npu_device *npu_dev) if (host_ctx->power_vote_num > 0) { for (i = 0; i < npu_dev->regulator_num; i++) regulator_disable(regulators[i].regulator); host_ctx->power_vote_num--; } } Loading Loading @@ -1148,9 +1192,10 @@ static int npu_load_network_v2(struct npu_client *client, return -EFAULT; } if (req.patch_info_num > MSM_NPU_MAX_PATCH_LAYER_NUM) { if ((req.patch_info_num > NPU_MAX_PATCH_NUM) || (req.patch_info_num == 0)) { NPU_ERR("Invalid patch info num %d[max:%d]\n", req.patch_info_num, MSM_NPU_MAX_PATCH_LAYER_NUM); req.patch_info_num, NPU_MAX_PATCH_NUM); return -EINVAL; } Loading Loading @@ -1235,9 +1280,10 @@ static int npu_exec_network_v2(struct npu_client *client, return -EFAULT; } if (req.patch_buf_info_num > MSM_NPU_MAX_PATCH_LAYER_NUM) { if ((req.patch_buf_info_num > NPU_MAX_PATCH_NUM) || (req.patch_buf_info_num == 0)) { NPU_ERR("Invalid patch buf info num %d[max:%d]\n", req.patch_buf_info_num, MSM_NPU_MAX_PATCH_LAYER_NUM); req.patch_buf_info_num, NPU_MAX_PATCH_NUM); return -EINVAL; } Loading Loading @@ -1331,6 +1377,43 @@ static int npu_receive_event(struct npu_client *client, return ret; } static int npu_set_fw_state(struct npu_client *client, uint32_t enable) { struct npu_device *npu_dev = client->npu_dev; struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; int rc = 0; if (host_ctx->network_num > 0) { NPU_ERR("Need to unload network first\n"); mutex_unlock(&npu_dev->dev_lock); return -EINVAL; } if (enable) { NPU_DBG("enable fw\n"); rc = enable_fw(npu_dev); if (rc) { NPU_ERR("enable fw failed\n"); } else { host_ctx->npu_init_cnt++; NPU_DBG("npu_init_cnt %d\n", host_ctx->npu_init_cnt); /* set npu to lowest power level */ if (npu_set_uc_power_level(npu_dev, 1)) NPU_WARN("Failed to set uc power level\n"); } } else if (host_ctx->npu_init_cnt > 0) { NPU_DBG("disable fw\n"); disable_fw(npu_dev); host_ctx->npu_init_cnt--; NPU_DBG("npu_init_cnt %d\n", host_ctx->npu_init_cnt); } else { NPU_ERR("can't disable fw %d\n", host_ctx->npu_init_cnt); } return rc; } static int npu_set_property(struct npu_client *client, unsigned long arg) { Loading @@ -1345,9 +1428,19 @@ static int npu_set_property(struct npu_client *client, } switch (prop.prop_id) { case MSM_NPU_PROP_ID_FW_STATE: ret = npu_set_fw_state(client, (uint32_t)prop.prop_param[0]); break; case MSM_NPU_PROP_ID_PERF_MODE: ret = npu_host_set_perf_mode(client, (uint32_t)prop.network_hdl, (uint32_t)prop.prop_param[0]); break; default: NPU_ERR("Not supported property %d\n", prop.prop_id); ret = -EINVAL; ret = npu_host_set_fw_property(client->npu_dev, &prop); if (ret) NPU_ERR("npu_host_set_fw_property failed\n"); break; } Loading @@ -1373,6 +1466,10 @@ static int npu_get_property(struct npu_client *client, case MSM_NPU_PROP_ID_FW_STATE: prop.prop_param[0] = host_ctx->fw_state; break; case MSM_NPU_PROP_ID_PERF_MODE: prop.prop_param[0] = npu_host_get_perf_mode(client, (uint32_t)prop.network_hdl); break; case MSM_NPU_PROP_ID_PERF_MODE_MAX: prop.prop_param[0] = npu_dev->pwrctrl.num_pwrlevels; break; Loading @@ -1383,13 +1480,17 @@ static int npu_get_property(struct npu_client *client, prop.prop_param[0] = npu_dev->hw_version; break; default: NPU_ERR("Not supported property %d\n", prop.prop_id); return -EINVAL; ret = npu_host_get_fw_property(client->npu_dev, &prop); if (ret) { NPU_ERR("npu_host_set_fw_property failed\n"); return ret; } break; } ret = copy_to_user(argp, &prop, sizeof(prop)); if (ret) { pr_err("fail to copy to user\n"); NPU_ERR("fail to copy to user\n"); return -EFAULT; } Loading Loading @@ -1749,6 +1850,7 @@ static int npu_of_parse_pwrlevels(struct npu_device *npu_dev, pwr->uc_pwrlevel = pwr->max_pwrlevel; pwr->perf_mode_override = 0; pwr->cdsprm_pwrlevel = pwr->max_pwrlevel; pwr->cur_dcvs_activity = pwr->num_pwrlevels; return 0; } Loading Loading @@ -2119,6 +2221,7 @@ static int npu_probe(struct platform_device *pdev) return -EFAULT; npu_dev->pdev = pdev; mutex_init(&npu_dev->dev_lock); platform_set_drvdata(pdev, npu_dev); res = platform_get_resource_byname(pdev, Loading Loading @@ -2178,6 +2281,25 @@ static int npu_probe(struct platform_device *pdev) NPU_DBG("cc_io phy address=0x%llx virt=%pK\n", res->start, npu_dev->cc_io.base); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tcsr"); if (!res) { NPU_ERR("unable to get tcsr_mutex resource\n"); rc = -ENODEV; goto error_get_dev_num; } npu_dev->tcsr_io.size = resource_size(res); npu_dev->tcsr_io.phy_addr = res->start; npu_dev->tcsr_io.base = devm_ioremap(&pdev->dev, res->start, npu_dev->tcsr_io.size); if (unlikely(!npu_dev->tcsr_io.base)) { NPU_ERR("unable to map tcsr\n"); rc = -ENOMEM; goto error_get_dev_num; } NPU_DBG("tcsr phy address=0x%llx virt=%pK\n", res->start, npu_dev->tcsr_io.base); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "apss_shared"); if (!res) { Loading Loading @@ -2288,8 +2410,6 @@ static int npu_probe(struct platform_device *pdev) goto error_driver_init; } mutex_init(&npu_dev->dev_lock); rc = npu_host_init(npu_dev); if (rc) { NPU_ERR("unable to init host\n"); Loading
drivers/media/platform/msm/npu_v2/npu_host_ipc.c +7 −0 Original line number Diff line number Diff line Loading @@ -243,6 +243,13 @@ static int ipc_queue_read(struct npu_device *npu_dev, status = -EPERM; goto exit; } if (packet_size > NPU_IPC_BUF_LENGTH) { NPU_ERR("Invalid packet size %d\n", packet_size); status = -EINVAL; goto exit; } new_read_idx = queue.qhdr_read_idx + packet_size; if (new_read_idx < (queue.qhdr_q_size)) { Loading