Loading drivers/media/platform/msm/npu/npu_common.h +4 −1 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ #define ROW_BYTES 16 #define GROUP_BYTES 4 #define NUM_MAX_CLK_NUM 24 #define NUM_MAX_CLK_NUM 48 #define NPU_MAX_REGULATOR_NUM 2 #define NPU_MAX_DT_NAME_LEN 21 #define NPU_MAX_PWRLEVELS 8 Loading Loading @@ -188,6 +188,7 @@ struct npu_irq { struct npu_io_data { size_t size; phys_addr_t phy_addr; void __iomem *base; }; Loading @@ -203,6 +204,8 @@ struct npu_device { struct npu_io_data core_io; struct npu_io_data tcm_io; struct npu_io_data qdsp_io; struct npu_io_data apss_shared_io; struct npu_io_data bwmon_io; struct npu_io_data qfprom_io; Loading drivers/media/platform/msm/npu/npu_dev.c +58 −86 Original line number Diff line number Diff line Loading @@ -59,8 +59,6 @@ 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 void npu_suspend_devbw(struct npu_device *npu_dev); static void npu_resume_devbw(struct npu_device *npu_dev); static bool npu_is_post_clock(const char *clk_name); static bool npu_is_exclude_rate_clock(const char *clk_name); static int npu_get_max_state(struct thermal_cooling_device *cdev, Loading Loading @@ -126,20 +124,21 @@ static const char * const npu_exclude_rate_clocks[] = { "npu_cpc_timer_clk", "qtimer_core_clk", "bwmon_clk", "bto_core_clk" }; static struct npu_reg npu_saved_bw_registers[] = { { BWMON2_SAMPLING_WINDOW, 0, false }, { BWMON2_BYTE_COUNT_THRESHOLD_HIGH, 0, false }, { BWMON2_BYTE_COUNT_THRESHOLD_MEDIUM, 0, false }, { BWMON2_BYTE_COUNT_THRESHOLD_LOW, 0, false }, { BWMON2_ZONE_ACTIONS, 0, false }, { BWMON2_ZONE_COUNT_THRESHOLD, 0, false }, "bto_core_clk", "llm_xo_clk", "dpm_xo_clk", "rsc_xo_clk", "dsp_bwmon_clk", "dl_dpm_clk", "dpm_temp_clk", "dsp_bwmon_ahb_clk", "cal_hm0_perf_cnt_clk", "cal_hm1_perf_cnt_clk", "dsp_ahbs_clk" }; static const struct npu_irq npu_irq_info[NPU_MAX_IRQ] = { {"ipc_irq", 0, IRQF_TRIGGER_HIGH}, {"ipc_irq", 0, IRQF_TRIGGER_RISING | IRQF_ONESHOT}, {"error_irq", 0, IRQF_TRIGGER_RISING | IRQF_ONESHOT}, {"wdg_bite_irq", 0, IRQF_TRIGGER_RISING | IRQF_ONESHOT}, }; Loading Loading @@ -314,7 +313,6 @@ int npu_enable_core_power(struct npu_device *npu_dev) pwr->pwr_vote_num = 0; return ret; } npu_resume_devbw(npu_dev); } pwr->pwr_vote_num++; Loading @@ -330,7 +328,6 @@ void npu_disable_core_power(struct npu_device *npu_dev) return; pwr->pwr_vote_num--; if (!pwr->pwr_vote_num) { npu_suspend_devbw(npu_dev); npu_disable_core_clocks(npu_dev); npu_disable_regulators(npu_dev); pwr->active_pwrlevel = thermalctrl->pwr_level; Loading Loading @@ -492,61 +489,6 @@ int npu_set_uc_power_level(struct npu_device *npu_dev, return npu_set_power_level(npu_dev, true); } /* ------------------------------------------------------------------------- * Bandwidth Related * ------------------------------------------------------------------------- */ static void npu_save_bw_registers(struct npu_device *npu_dev) { int i; if (!npu_dev->bwmon_io.base) return; for (i = 0; i < ARRAY_SIZE(npu_saved_bw_registers); i++) { npu_saved_bw_registers[i].val = npu_bwmon_reg_read(npu_dev, npu_saved_bw_registers[i].off); npu_saved_bw_registers[i].valid = true; } } static void npu_restore_bw_registers(struct npu_device *npu_dev) { int i; if (!npu_dev->bwmon_io.base) return; for (i = 0; i < ARRAY_SIZE(npu_saved_bw_registers); i++) { if (npu_saved_bw_registers[i].valid) { npu_bwmon_reg_write(npu_dev, npu_saved_bw_registers[i].off, npu_saved_bw_registers[i].val); npu_saved_bw_registers[i].valid = false; } } } static void npu_suspend_devbw(struct npu_device *npu_dev) { struct npu_pwrctrl *pwr = &npu_dev->pwrctrl; if (pwr->bwmon_enabled && pwr->devbw) { pwr->bwmon_enabled = 0; npu_save_bw_registers(npu_dev); } } static void npu_resume_devbw(struct npu_device *npu_dev) { struct npu_pwrctrl *pwr = &npu_dev->pwrctrl; if (!pwr->bwmon_enabled && pwr->devbw) { pwr->bwmon_enabled = 1; npu_restore_bw_registers(npu_dev); } } /* ------------------------------------------------------------------------- * Clocks Related * ------------------------------------------------------------------------- Loading Loading @@ -761,13 +703,6 @@ int npu_enable_irq(struct npu_device *npu_dev) { int i; /* clear pending irq state */ REGW(npu_dev, NPU_MASTERn_IPC_IRQ_OUT(0), 0x0); REGW(npu_dev, NPU_MASTERn_ERROR_IRQ_CLEAR(0), NPU_ERROR_IRQ_MASK); REGW(npu_dev, NPU_MASTERn_ERROR_IRQ_ENABLE(0), NPU_ERROR_IRQ_MASK); REGW(npu_dev, NPU_MASTERn_ERROR_IRQ_OWNER(0), NPU_ERROR_IRQ_MASK); REGW(npu_dev, NPU_MASTERn_WDOG_IRQ_OWNER(0), NPU_WDOG_IRQ_MASK); for (i = 0; i < NPU_MAX_IRQ; i++) { if (npu_dev->irq[i].irq != 0) { enable_irq(npu_dev->irq[i].irq); Loading @@ -788,11 +723,6 @@ void npu_disable_irq(struct npu_device *npu_dev) pr_debug("disable irq %d\n", npu_dev->irq[i].irq); } } REGW(npu_dev, NPU_MASTERn_ERROR_IRQ_ENABLE(0), 0); /* clear pending irq state */ REGW(npu_dev, NPU_MASTERn_IPC_IRQ_OUT(0), 0x0); REGW(npu_dev, NPU_MASTERn_ERROR_IRQ_CLEAR(0), NPU_ERROR_IRQ_MASK); } /* ------------------------------------------------------------------------- Loading Loading @@ -1656,6 +1586,7 @@ static int npu_probe(struct platform_device *pdev) goto error_get_dev_num; } npu_dev->core_io.size = resource_size(res); npu_dev->core_io.phy_addr = res->start; npu_dev->core_io.base = devm_ioremap(&pdev->dev, res->start, npu_dev->core_io.size); if (unlikely(!npu_dev->core_io.base)) { Loading @@ -1663,7 +1594,7 @@ static int npu_probe(struct platform_device *pdev) rc = -ENOMEM; goto error_get_dev_num; } pr_debug("core phy address=0x%x virt=%pK\n", pr_debug("core phy address=0x%llx virt=%pK\n", res->start, npu_dev->core_io.base); res = platform_get_resource_byname(pdev, Loading @@ -1674,6 +1605,7 @@ static int npu_probe(struct platform_device *pdev) goto error_get_dev_num; } npu_dev->tcm_io.size = resource_size(res); npu_dev->tcm_io.phy_addr = res->start; npu_dev->tcm_io.base = devm_ioremap(&pdev->dev, res->start, npu_dev->tcm_io.size); if (unlikely(!npu_dev->tcm_io.base)) { Loading @@ -1681,15 +1613,54 @@ static int npu_probe(struct platform_device *pdev) rc = -ENOMEM; goto error_get_dev_num; } pr_debug("core phy address=0x%x virt=%pK\n", pr_debug("tcm phy address=0x%llx virt=%pK\n", res->start, npu_dev->tcm_io.base); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qdsp"); if (!res) { pr_err("unable to get qdsp resource\n"); rc = -ENODEV; goto error_get_dev_num; } npu_dev->qdsp_io.size = resource_size(res); npu_dev->qdsp_io.phy_addr = res->start; npu_dev->qdsp_io.base = devm_ioremap(&pdev->dev, res->start, npu_dev->qdsp_io.size); if (unlikely(!npu_dev->qdsp_io.base)) { pr_err("unable to map qdsp\n"); rc = -ENOMEM; goto error_get_dev_num; } pr_debug("qdsp phy address=0x%x virt=%pK\n", res->start, npu_dev->qdsp_io.base); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "apss_shared"); if (!res) { pr_err("unable to get apss_shared resource\n"); rc = -ENODEV; goto error_get_dev_num; } npu_dev->apss_shared_io.size = resource_size(res); npu_dev->apss_shared_io.phy_addr = res->start; npu_dev->apss_shared_io.base = devm_ioremap(&pdev->dev, res->start, npu_dev->apss_shared_io.size); if (unlikely(!npu_dev->apss_shared_io.base)) { pr_err("unable to map apss_shared\n"); rc = -ENOMEM; goto error_get_dev_num; } pr_debug("apss_shared phy address=0x%x virt=%pK\n", res->start, npu_dev->apss_shared_io.base); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bwmon"); if (!res) { pr_info("unable to get bwmon resource\n"); } else { npu_dev->bwmon_io.size = resource_size(res); npu_dev->bwmon_io.phy_addr = res->start; npu_dev->bwmon_io.base = devm_ioremap(&pdev->dev, res->start, npu_dev->bwmon_io.size); if (unlikely(!npu_dev->bwmon_io.base)) { Loading @@ -1697,7 +1668,7 @@ static int npu_probe(struct platform_device *pdev) rc = -ENOMEM; goto error_get_dev_num; } pr_debug("bwmon phy address=0x%x virt=%pK\n", pr_debug("bwmon phy address=0x%llx virt=%pK\n", res->start, npu_dev->bwmon_io.base); } Loading @@ -1707,6 +1678,7 @@ static int npu_probe(struct platform_device *pdev) pr_info("unable to get qfprom_physical resource\n"); } else { npu_dev->qfprom_io.size = resource_size(res); npu_dev->qfprom_io.phy_addr = res->start; npu_dev->qfprom_io.base = devm_ioremap(&pdev->dev, res->start, npu_dev->qfprom_io.size); if (unlikely(!npu_dev->qfprom_io.base)) { Loading @@ -1714,7 +1686,7 @@ static int npu_probe(struct platform_device *pdev) rc = -ENOMEM; goto error_get_dev_num; } pr_debug("qfprom_physical phy address=0x%x virt=%pK\n", pr_debug("qfprom_physical phy address=0x%llx virt=%pK\n", res->start, npu_dev->qfprom_io.base); } Loading drivers/media/platform/msm/npu/npu_host_ipc.c +2 −1 Original line number Diff line number Diff line Loading @@ -136,7 +136,8 @@ static int npu_host_ipc_init_hfi(struct npu_device *npu_dev) kfree(q_tbl_addr); /* Write in the NPU's address for where IPC starts */ REGW(npu_dev, (uint32_t)REG_NPU_HOST_CTRL_VALUE, (uint32_t)IPC_MEM_OFFSET_FROM_SSTCM); (uint32_t)(npu_dev->tcm_io.phy_addr + IPC_MEM_OFFSET_FROM_SSTCM)); /* Set value bit */ reg_val = REGR(npu_dev, (uint32_t)REG_NPU_HOST_CTRL_STATUS); REGW(npu_dev, (uint32_t)REG_NPU_HOST_CTRL_STATUS, reg_val | Loading drivers/media/platform/msm/npu/npu_hw.h +7 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,8 @@ #define NPU_GPR2 (0x00000108) #define NPU_GPR3 (0x0000010C) #define NPU_GPR4 (0x00000110) #define NPU_GPR5 (0x00000114) #define NPU_GPR11 (0x0000012c) #define NPU_GPR13 (0x00000134) #define NPU_GPR14 (0x00000138) #define NPU_GPR15 (0x0000013C) Loading @@ -49,4 +51,9 @@ #define BWMON2_ZONE_ACTIONS (0x000003B8) #define BWMON2_ZONE_COUNT_THRESHOLD (0x000003BC) #define NPU_QDSP6SS_IPC 0x00088000 #define NPU_QDSP6SS_IPC1 0x00088004 #define APSS_SHARED_IPC_INTERRUPT_1 0x00000010 #endif /* NPU_HW_H */ drivers/media/platform/msm/npu/npu_hw_access.c +38 −30 Original line number Diff line number Diff line Loading @@ -37,6 +37,37 @@ void npu_core_reg_write(struct npu_device *npu_dev, uint32_t off, uint32_t val) __iowmb(); } uint32_t npu_qdsp_reg_read(struct npu_device *npu_dev, uint32_t off) { uint32_t ret = 0; ret = readl_relaxed(npu_dev->qdsp_io.base + off); __iormb(); return ret; } void npu_qdsp_reg_write(struct npu_device *npu_dev, uint32_t off, uint32_t val) { writel_relaxed(val, npu_dev->qdsp_io.base + off); __iowmb(); } uint32_t npu_apss_shared_reg_read(struct npu_device *npu_dev, uint32_t off) { uint32_t ret = 0; ret = readl_relaxed(npu_dev->apss_shared_io.base + off); __iormb(); return ret; } void npu_apss_shared_reg_write(struct npu_device *npu_dev, uint32_t off, uint32_t val) { writel_relaxed(val, npu_dev->apss_shared_io.base + off); __iowmb(); } uint32_t npu_bwmon_reg_read(struct npu_device *npu_dev, uint32_t off) { uint32_t ret = 0; Loading Loading @@ -78,6 +109,7 @@ void npu_mem_write(struct npu_device *npu_dev, void *dst, void *src, uint32_t i = 0; uint32_t num = 0; pr_debug("write dst_off %x size %x\n", dst_off, size); num = size/4; for (i = 0; i < num; i++) { writel_relaxed(src_ptr32[i], npu_dev->tcm_io.base + dst_off); Loading @@ -104,6 +136,8 @@ int32_t npu_mem_read(struct npu_device *npu_dev, void *src, void *dst, uint32_t i = 0; uint32_t num = 0; pr_debug("read src_off %x size %x\n", src_off, size); num = size/4; for (i = 0; i < num; i++) { out32[i] = readl_relaxed(npu_dev->tcm_io.base + src_off); Loading Loading @@ -132,44 +166,17 @@ void *npu_ipc_addr(void) */ void npu_interrupt_ack(struct npu_device *npu_dev, uint32_t intr_num) { struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; uint32_t wdg_irq_sts = 0, error_irq_sts = 0; /* Clear irq state */ REGW(npu_dev, NPU_MASTERn_IPC_IRQ_OUT(0), 0x0); wdg_irq_sts = REGR(npu_dev, NPU_MASTERn_WDOG_IRQ_STATUS(0)); if (wdg_irq_sts != 0) { pr_err("wdg irq %x\n", wdg_irq_sts); host_ctx->wdg_irq_sts |= wdg_irq_sts; host_ctx->fw_error = true; } error_irq_sts = REGR(npu_dev, NPU_MASTERn_ERROR_IRQ_STATUS(0)); error_irq_sts &= REGR(npu_dev, NPU_MASTERn_ERROR_IRQ_ENABLE(0)); if (error_irq_sts != 0) { REGW(npu_dev, NPU_MASTERn_ERROR_IRQ_CLEAR(0), error_irq_sts); pr_err("error irq %x\n", error_irq_sts); host_ctx->err_irq_sts |= error_irq_sts; host_ctx->fw_error = true; } } int32_t npu_interrupt_raise_m0(struct npu_device *npu_dev) { /* Bit 4 is setting IRQ_SOURCE_SELECT to local * and we're triggering a pulse to NPU_MASTER0_IPC_IN_IRQ0 */ npu_core_reg_write(npu_dev, NPU_MASTERn_IPC_IRQ_IN_CTRL(0), 0x1 << NPU_MASTER0_IPC_IRQ_IN_CTRL__IRQ_SOURCE_SELECT___S | 0x1); npu_apss_shared_reg_write(npu_dev, APSS_SHARED_IPC_INTERRUPT_1, 0x40); return 0; } int32_t npu_interrupt_raise_dsp(struct npu_device *npu_dev) { npu_core_reg_write(npu_dev, NPU_MASTERn_IPC_IRQ_OUT_CTRL(1), 0x8); return 0; } Loading @@ -194,7 +201,7 @@ static struct npu_ion_buf *npu_alloc_npu_ion_buffer(struct npu_client if (ret_val) { /* mapped already, treat as invalid request */ pr_err("ion buf %x has been mapped\n"); pr_err("ion buf has been mapped\n"); ret_val = NULL; } else { ret_val = kzalloc(sizeof(*ret_val), GFP_KERNEL); Loading Loading @@ -302,6 +309,7 @@ int npu_mem_map(struct npu_client *client, int buf_hdl, uint32_t size, *addr = ion_buf->iova; pr_debug("mapped mem addr:0x%llx size:0x%x\n", ion_buf->iova, ion_buf->size); pr_debug("physical address 0x%llx\n", sg_phys(ion_buf->table->sgl)); map_end: if (ret) npu_mem_unmap(client, buf_hdl, 0); Loading Loading @@ -354,7 +362,7 @@ void npu_mem_unmap(struct npu_client *client, int buf_hdl, uint64_t addr) } if (ion_buf->iova != addr) pr_warn("unmap address %lu doesn't match %lu\n", addr, pr_warn("unmap address %llu doesn't match %llu\n", addr, ion_buf->iova); if (ion_buf->table) Loading Loading
drivers/media/platform/msm/npu/npu_common.h +4 −1 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ #define ROW_BYTES 16 #define GROUP_BYTES 4 #define NUM_MAX_CLK_NUM 24 #define NUM_MAX_CLK_NUM 48 #define NPU_MAX_REGULATOR_NUM 2 #define NPU_MAX_DT_NAME_LEN 21 #define NPU_MAX_PWRLEVELS 8 Loading Loading @@ -188,6 +188,7 @@ struct npu_irq { struct npu_io_data { size_t size; phys_addr_t phy_addr; void __iomem *base; }; Loading @@ -203,6 +204,8 @@ struct npu_device { struct npu_io_data core_io; struct npu_io_data tcm_io; struct npu_io_data qdsp_io; struct npu_io_data apss_shared_io; struct npu_io_data bwmon_io; struct npu_io_data qfprom_io; Loading
drivers/media/platform/msm/npu/npu_dev.c +58 −86 Original line number Diff line number Diff line Loading @@ -59,8 +59,6 @@ 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 void npu_suspend_devbw(struct npu_device *npu_dev); static void npu_resume_devbw(struct npu_device *npu_dev); static bool npu_is_post_clock(const char *clk_name); static bool npu_is_exclude_rate_clock(const char *clk_name); static int npu_get_max_state(struct thermal_cooling_device *cdev, Loading Loading @@ -126,20 +124,21 @@ static const char * const npu_exclude_rate_clocks[] = { "npu_cpc_timer_clk", "qtimer_core_clk", "bwmon_clk", "bto_core_clk" }; static struct npu_reg npu_saved_bw_registers[] = { { BWMON2_SAMPLING_WINDOW, 0, false }, { BWMON2_BYTE_COUNT_THRESHOLD_HIGH, 0, false }, { BWMON2_BYTE_COUNT_THRESHOLD_MEDIUM, 0, false }, { BWMON2_BYTE_COUNT_THRESHOLD_LOW, 0, false }, { BWMON2_ZONE_ACTIONS, 0, false }, { BWMON2_ZONE_COUNT_THRESHOLD, 0, false }, "bto_core_clk", "llm_xo_clk", "dpm_xo_clk", "rsc_xo_clk", "dsp_bwmon_clk", "dl_dpm_clk", "dpm_temp_clk", "dsp_bwmon_ahb_clk", "cal_hm0_perf_cnt_clk", "cal_hm1_perf_cnt_clk", "dsp_ahbs_clk" }; static const struct npu_irq npu_irq_info[NPU_MAX_IRQ] = { {"ipc_irq", 0, IRQF_TRIGGER_HIGH}, {"ipc_irq", 0, IRQF_TRIGGER_RISING | IRQF_ONESHOT}, {"error_irq", 0, IRQF_TRIGGER_RISING | IRQF_ONESHOT}, {"wdg_bite_irq", 0, IRQF_TRIGGER_RISING | IRQF_ONESHOT}, }; Loading Loading @@ -314,7 +313,6 @@ int npu_enable_core_power(struct npu_device *npu_dev) pwr->pwr_vote_num = 0; return ret; } npu_resume_devbw(npu_dev); } pwr->pwr_vote_num++; Loading @@ -330,7 +328,6 @@ void npu_disable_core_power(struct npu_device *npu_dev) return; pwr->pwr_vote_num--; if (!pwr->pwr_vote_num) { npu_suspend_devbw(npu_dev); npu_disable_core_clocks(npu_dev); npu_disable_regulators(npu_dev); pwr->active_pwrlevel = thermalctrl->pwr_level; Loading Loading @@ -492,61 +489,6 @@ int npu_set_uc_power_level(struct npu_device *npu_dev, return npu_set_power_level(npu_dev, true); } /* ------------------------------------------------------------------------- * Bandwidth Related * ------------------------------------------------------------------------- */ static void npu_save_bw_registers(struct npu_device *npu_dev) { int i; if (!npu_dev->bwmon_io.base) return; for (i = 0; i < ARRAY_SIZE(npu_saved_bw_registers); i++) { npu_saved_bw_registers[i].val = npu_bwmon_reg_read(npu_dev, npu_saved_bw_registers[i].off); npu_saved_bw_registers[i].valid = true; } } static void npu_restore_bw_registers(struct npu_device *npu_dev) { int i; if (!npu_dev->bwmon_io.base) return; for (i = 0; i < ARRAY_SIZE(npu_saved_bw_registers); i++) { if (npu_saved_bw_registers[i].valid) { npu_bwmon_reg_write(npu_dev, npu_saved_bw_registers[i].off, npu_saved_bw_registers[i].val); npu_saved_bw_registers[i].valid = false; } } } static void npu_suspend_devbw(struct npu_device *npu_dev) { struct npu_pwrctrl *pwr = &npu_dev->pwrctrl; if (pwr->bwmon_enabled && pwr->devbw) { pwr->bwmon_enabled = 0; npu_save_bw_registers(npu_dev); } } static void npu_resume_devbw(struct npu_device *npu_dev) { struct npu_pwrctrl *pwr = &npu_dev->pwrctrl; if (!pwr->bwmon_enabled && pwr->devbw) { pwr->bwmon_enabled = 1; npu_restore_bw_registers(npu_dev); } } /* ------------------------------------------------------------------------- * Clocks Related * ------------------------------------------------------------------------- Loading Loading @@ -761,13 +703,6 @@ int npu_enable_irq(struct npu_device *npu_dev) { int i; /* clear pending irq state */ REGW(npu_dev, NPU_MASTERn_IPC_IRQ_OUT(0), 0x0); REGW(npu_dev, NPU_MASTERn_ERROR_IRQ_CLEAR(0), NPU_ERROR_IRQ_MASK); REGW(npu_dev, NPU_MASTERn_ERROR_IRQ_ENABLE(0), NPU_ERROR_IRQ_MASK); REGW(npu_dev, NPU_MASTERn_ERROR_IRQ_OWNER(0), NPU_ERROR_IRQ_MASK); REGW(npu_dev, NPU_MASTERn_WDOG_IRQ_OWNER(0), NPU_WDOG_IRQ_MASK); for (i = 0; i < NPU_MAX_IRQ; i++) { if (npu_dev->irq[i].irq != 0) { enable_irq(npu_dev->irq[i].irq); Loading @@ -788,11 +723,6 @@ void npu_disable_irq(struct npu_device *npu_dev) pr_debug("disable irq %d\n", npu_dev->irq[i].irq); } } REGW(npu_dev, NPU_MASTERn_ERROR_IRQ_ENABLE(0), 0); /* clear pending irq state */ REGW(npu_dev, NPU_MASTERn_IPC_IRQ_OUT(0), 0x0); REGW(npu_dev, NPU_MASTERn_ERROR_IRQ_CLEAR(0), NPU_ERROR_IRQ_MASK); } /* ------------------------------------------------------------------------- Loading Loading @@ -1656,6 +1586,7 @@ static int npu_probe(struct platform_device *pdev) goto error_get_dev_num; } npu_dev->core_io.size = resource_size(res); npu_dev->core_io.phy_addr = res->start; npu_dev->core_io.base = devm_ioremap(&pdev->dev, res->start, npu_dev->core_io.size); if (unlikely(!npu_dev->core_io.base)) { Loading @@ -1663,7 +1594,7 @@ static int npu_probe(struct platform_device *pdev) rc = -ENOMEM; goto error_get_dev_num; } pr_debug("core phy address=0x%x virt=%pK\n", pr_debug("core phy address=0x%llx virt=%pK\n", res->start, npu_dev->core_io.base); res = platform_get_resource_byname(pdev, Loading @@ -1674,6 +1605,7 @@ static int npu_probe(struct platform_device *pdev) goto error_get_dev_num; } npu_dev->tcm_io.size = resource_size(res); npu_dev->tcm_io.phy_addr = res->start; npu_dev->tcm_io.base = devm_ioremap(&pdev->dev, res->start, npu_dev->tcm_io.size); if (unlikely(!npu_dev->tcm_io.base)) { Loading @@ -1681,15 +1613,54 @@ static int npu_probe(struct platform_device *pdev) rc = -ENOMEM; goto error_get_dev_num; } pr_debug("core phy address=0x%x virt=%pK\n", pr_debug("tcm phy address=0x%llx virt=%pK\n", res->start, npu_dev->tcm_io.base); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qdsp"); if (!res) { pr_err("unable to get qdsp resource\n"); rc = -ENODEV; goto error_get_dev_num; } npu_dev->qdsp_io.size = resource_size(res); npu_dev->qdsp_io.phy_addr = res->start; npu_dev->qdsp_io.base = devm_ioremap(&pdev->dev, res->start, npu_dev->qdsp_io.size); if (unlikely(!npu_dev->qdsp_io.base)) { pr_err("unable to map qdsp\n"); rc = -ENOMEM; goto error_get_dev_num; } pr_debug("qdsp phy address=0x%x virt=%pK\n", res->start, npu_dev->qdsp_io.base); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "apss_shared"); if (!res) { pr_err("unable to get apss_shared resource\n"); rc = -ENODEV; goto error_get_dev_num; } npu_dev->apss_shared_io.size = resource_size(res); npu_dev->apss_shared_io.phy_addr = res->start; npu_dev->apss_shared_io.base = devm_ioremap(&pdev->dev, res->start, npu_dev->apss_shared_io.size); if (unlikely(!npu_dev->apss_shared_io.base)) { pr_err("unable to map apss_shared\n"); rc = -ENOMEM; goto error_get_dev_num; } pr_debug("apss_shared phy address=0x%x virt=%pK\n", res->start, npu_dev->apss_shared_io.base); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bwmon"); if (!res) { pr_info("unable to get bwmon resource\n"); } else { npu_dev->bwmon_io.size = resource_size(res); npu_dev->bwmon_io.phy_addr = res->start; npu_dev->bwmon_io.base = devm_ioremap(&pdev->dev, res->start, npu_dev->bwmon_io.size); if (unlikely(!npu_dev->bwmon_io.base)) { Loading @@ -1697,7 +1668,7 @@ static int npu_probe(struct platform_device *pdev) rc = -ENOMEM; goto error_get_dev_num; } pr_debug("bwmon phy address=0x%x virt=%pK\n", pr_debug("bwmon phy address=0x%llx virt=%pK\n", res->start, npu_dev->bwmon_io.base); } Loading @@ -1707,6 +1678,7 @@ static int npu_probe(struct platform_device *pdev) pr_info("unable to get qfprom_physical resource\n"); } else { npu_dev->qfprom_io.size = resource_size(res); npu_dev->qfprom_io.phy_addr = res->start; npu_dev->qfprom_io.base = devm_ioremap(&pdev->dev, res->start, npu_dev->qfprom_io.size); if (unlikely(!npu_dev->qfprom_io.base)) { Loading @@ -1714,7 +1686,7 @@ static int npu_probe(struct platform_device *pdev) rc = -ENOMEM; goto error_get_dev_num; } pr_debug("qfprom_physical phy address=0x%x virt=%pK\n", pr_debug("qfprom_physical phy address=0x%llx virt=%pK\n", res->start, npu_dev->qfprom_io.base); } Loading
drivers/media/platform/msm/npu/npu_host_ipc.c +2 −1 Original line number Diff line number Diff line Loading @@ -136,7 +136,8 @@ static int npu_host_ipc_init_hfi(struct npu_device *npu_dev) kfree(q_tbl_addr); /* Write in the NPU's address for where IPC starts */ REGW(npu_dev, (uint32_t)REG_NPU_HOST_CTRL_VALUE, (uint32_t)IPC_MEM_OFFSET_FROM_SSTCM); (uint32_t)(npu_dev->tcm_io.phy_addr + IPC_MEM_OFFSET_FROM_SSTCM)); /* Set value bit */ reg_val = REGR(npu_dev, (uint32_t)REG_NPU_HOST_CTRL_STATUS); REGW(npu_dev, (uint32_t)REG_NPU_HOST_CTRL_STATUS, reg_val | Loading
drivers/media/platform/msm/npu/npu_hw.h +7 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,8 @@ #define NPU_GPR2 (0x00000108) #define NPU_GPR3 (0x0000010C) #define NPU_GPR4 (0x00000110) #define NPU_GPR5 (0x00000114) #define NPU_GPR11 (0x0000012c) #define NPU_GPR13 (0x00000134) #define NPU_GPR14 (0x00000138) #define NPU_GPR15 (0x0000013C) Loading @@ -49,4 +51,9 @@ #define BWMON2_ZONE_ACTIONS (0x000003B8) #define BWMON2_ZONE_COUNT_THRESHOLD (0x000003BC) #define NPU_QDSP6SS_IPC 0x00088000 #define NPU_QDSP6SS_IPC1 0x00088004 #define APSS_SHARED_IPC_INTERRUPT_1 0x00000010 #endif /* NPU_HW_H */
drivers/media/platform/msm/npu/npu_hw_access.c +38 −30 Original line number Diff line number Diff line Loading @@ -37,6 +37,37 @@ void npu_core_reg_write(struct npu_device *npu_dev, uint32_t off, uint32_t val) __iowmb(); } uint32_t npu_qdsp_reg_read(struct npu_device *npu_dev, uint32_t off) { uint32_t ret = 0; ret = readl_relaxed(npu_dev->qdsp_io.base + off); __iormb(); return ret; } void npu_qdsp_reg_write(struct npu_device *npu_dev, uint32_t off, uint32_t val) { writel_relaxed(val, npu_dev->qdsp_io.base + off); __iowmb(); } uint32_t npu_apss_shared_reg_read(struct npu_device *npu_dev, uint32_t off) { uint32_t ret = 0; ret = readl_relaxed(npu_dev->apss_shared_io.base + off); __iormb(); return ret; } void npu_apss_shared_reg_write(struct npu_device *npu_dev, uint32_t off, uint32_t val) { writel_relaxed(val, npu_dev->apss_shared_io.base + off); __iowmb(); } uint32_t npu_bwmon_reg_read(struct npu_device *npu_dev, uint32_t off) { uint32_t ret = 0; Loading Loading @@ -78,6 +109,7 @@ void npu_mem_write(struct npu_device *npu_dev, void *dst, void *src, uint32_t i = 0; uint32_t num = 0; pr_debug("write dst_off %x size %x\n", dst_off, size); num = size/4; for (i = 0; i < num; i++) { writel_relaxed(src_ptr32[i], npu_dev->tcm_io.base + dst_off); Loading @@ -104,6 +136,8 @@ int32_t npu_mem_read(struct npu_device *npu_dev, void *src, void *dst, uint32_t i = 0; uint32_t num = 0; pr_debug("read src_off %x size %x\n", src_off, size); num = size/4; for (i = 0; i < num; i++) { out32[i] = readl_relaxed(npu_dev->tcm_io.base + src_off); Loading Loading @@ -132,44 +166,17 @@ void *npu_ipc_addr(void) */ void npu_interrupt_ack(struct npu_device *npu_dev, uint32_t intr_num) { struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; uint32_t wdg_irq_sts = 0, error_irq_sts = 0; /* Clear irq state */ REGW(npu_dev, NPU_MASTERn_IPC_IRQ_OUT(0), 0x0); wdg_irq_sts = REGR(npu_dev, NPU_MASTERn_WDOG_IRQ_STATUS(0)); if (wdg_irq_sts != 0) { pr_err("wdg irq %x\n", wdg_irq_sts); host_ctx->wdg_irq_sts |= wdg_irq_sts; host_ctx->fw_error = true; } error_irq_sts = REGR(npu_dev, NPU_MASTERn_ERROR_IRQ_STATUS(0)); error_irq_sts &= REGR(npu_dev, NPU_MASTERn_ERROR_IRQ_ENABLE(0)); if (error_irq_sts != 0) { REGW(npu_dev, NPU_MASTERn_ERROR_IRQ_CLEAR(0), error_irq_sts); pr_err("error irq %x\n", error_irq_sts); host_ctx->err_irq_sts |= error_irq_sts; host_ctx->fw_error = true; } } int32_t npu_interrupt_raise_m0(struct npu_device *npu_dev) { /* Bit 4 is setting IRQ_SOURCE_SELECT to local * and we're triggering a pulse to NPU_MASTER0_IPC_IN_IRQ0 */ npu_core_reg_write(npu_dev, NPU_MASTERn_IPC_IRQ_IN_CTRL(0), 0x1 << NPU_MASTER0_IPC_IRQ_IN_CTRL__IRQ_SOURCE_SELECT___S | 0x1); npu_apss_shared_reg_write(npu_dev, APSS_SHARED_IPC_INTERRUPT_1, 0x40); return 0; } int32_t npu_interrupt_raise_dsp(struct npu_device *npu_dev) { npu_core_reg_write(npu_dev, NPU_MASTERn_IPC_IRQ_OUT_CTRL(1), 0x8); return 0; } Loading @@ -194,7 +201,7 @@ static struct npu_ion_buf *npu_alloc_npu_ion_buffer(struct npu_client if (ret_val) { /* mapped already, treat as invalid request */ pr_err("ion buf %x has been mapped\n"); pr_err("ion buf has been mapped\n"); ret_val = NULL; } else { ret_val = kzalloc(sizeof(*ret_val), GFP_KERNEL); Loading Loading @@ -302,6 +309,7 @@ int npu_mem_map(struct npu_client *client, int buf_hdl, uint32_t size, *addr = ion_buf->iova; pr_debug("mapped mem addr:0x%llx size:0x%x\n", ion_buf->iova, ion_buf->size); pr_debug("physical address 0x%llx\n", sg_phys(ion_buf->table->sgl)); map_end: if (ret) npu_mem_unmap(client, buf_hdl, 0); Loading Loading @@ -354,7 +362,7 @@ void npu_mem_unmap(struct npu_client *client, int buf_hdl, uint64_t addr) } if (ion_buf->iova != addr) pr_warn("unmap address %lu doesn't match %lu\n", addr, pr_warn("unmap address %llu doesn't match %llu\n", addr, ion_buf->iova); if (ion_buf->table) Loading