Loading drivers/media/platform/msm/npu/npu_common.h +4 −1 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ #define NPU_MAX_DT_NAME_LEN 21 #define NPU_MAX_PWRLEVELS 8 #define NPU_MAX_STATS_BUF_SIZE 16384 #define NPU_MAX_BW_DEVS 4 enum npu_power_level { NPU_PWRLEVEL_MINSVS = 0, Loading Loading @@ -174,7 +175,9 @@ struct npu_pwrctrl { uint32_t min_pwrlevel; uint32_t num_pwrlevels; struct device *devbw; struct device *devbw[NPU_MAX_BW_DEVS]; uint32_t devbw_num; uint32_t bwmon_enabled; uint32_t uc_pwrlevel; uint32_t cdsprm_pwrlevel; uint32_t fmax_pwrlevel; Loading drivers/media/platform/msm/npu/npu_dev.c +87 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include <linux/regulator/consumer.h> #include <linux/thermal.h> #include <linux/soc/qcom/llcc-qcom.h> #include <soc/qcom/devfreq_devbw.h> #include "npu_common.h" #include "npu_hw.h" Loading Loading @@ -60,6 +61,8 @@ static ssize_t perf_mode_override_store(struct device *dev, static ssize_t boot_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 @@ -353,6 +356,7 @@ int npu_enable_core_power(struct npu_device *npu_dev) npu_disable_regulators(npu_dev); goto fail; } npu_resume_devbw(npu_dev); } pwr->pwr_vote_num++; fail: Loading @@ -373,6 +377,7 @@ void npu_disable_core_power(struct npu_device *npu_dev) pwr->pwr_vote_num--; if (!pwr->pwr_vote_num) { npu_suspend_devbw(npu_dev); npu_disable_core_clocks(npu_dev); npu_set_bw(npu_dev, 0, 0); npu_disable_regulators(npu_dev); Loading Loading @@ -565,6 +570,44 @@ int npu_set_uc_power_level(struct npu_device *npu_dev, return npu_set_power_level(npu_dev, true); } /* ------------------------------------------------------------------------- * Bandwidth Monitor Related * ------------------------------------------------------------------------- */ static void npu_suspend_devbw(struct npu_device *npu_dev) { struct npu_pwrctrl *pwr = &npu_dev->pwrctrl; int ret, i; if (pwr->bwmon_enabled && (pwr->devbw_num > 0)) { for (i = 0; i < pwr->devbw_num; i++) { NPU_DBG("Suspend devbw%d\n", i); ret = devfreq_suspend_devbw(pwr->devbw[i]); if (ret) NPU_ERR("devfreq_suspend_devbw failed rc:%d\n", ret); } pwr->bwmon_enabled = 0; } } static void npu_resume_devbw(struct npu_device *npu_dev) { struct npu_pwrctrl *pwr = &npu_dev->pwrctrl; int ret, i; if (!pwr->bwmon_enabled && (pwr->devbw_num > 0)) { for (i = 0; i < pwr->devbw_num; i++) { NPU_DBG("Resume devbw%d\n", i); ret = devfreq_resume_devbw(pwr->devbw[i]); if (ret) NPU_ERR("devfreq_resume_devbw failed rc:%d\n", ret); } pwr->bwmon_enabled = 1; } } /* ------------------------------------------------------------------------- * Clocks Related * ------------------------------------------------------------------------- Loading Loading @@ -1729,7 +1772,9 @@ static int npu_pwrctrl_init(struct npu_device *npu_dev) { struct platform_device *pdev = npu_dev->pdev; struct device_node *node; int ret = 0; int ret = 0, i; struct platform_device *p2dev; struct npu_pwrctrl *pwr = &npu_dev->pwrctrl; /* Power levels */ node = of_find_node_by_name(pdev->dev.of_node, "qcom,npu-pwrlevels"); Loading @@ -1743,6 +1788,47 @@ static int npu_pwrctrl_init(struct npu_device *npu_dev) if (ret) return ret; /* Parse Bandwidth Monitor */ pwr->devbw_num = of_property_count_strings(pdev->dev.of_node, "qcom,npubw-dev-names"); if (pwr->devbw_num <= 0) { NPU_INFO("npubw-dev-names are not defined\n"); return 0; } else if (pwr->devbw_num > NPU_MAX_BW_DEVS) { NPU_ERR("number of devbw %d exceeds limit\n", pwr->devbw_num); return -EINVAL; } for (i = 0; i < pwr->devbw_num; i++) { node = of_parse_phandle(pdev->dev.of_node, "qcom,npubw-devs", i); if (node) { p2dev = of_find_device_by_node(node); of_node_put(node); if (p2dev) { pwr->devbw[i] = &p2dev->dev; } else { NPU_ERR("can't find devbw%d\n", i); ret = -EINVAL; break; } } else { NPU_ERR("can't find devbw node\n"); ret = -EINVAL; break; } } if (ret) { /* Allow npu work without bwmon */ pwr->devbw_num = 0; ret = 0; } else { /* Set to 1 initially - we assume bwmon is on */ pwr->bwmon_enabled = 1; } return ret; } Loading drivers/media/platform/msm/npu/npu_mgr.c +9 −10 Original line number Diff line number Diff line Loading @@ -194,7 +194,6 @@ int load_fw(struct npu_device *npu_dev) int unload_fw(struct npu_device *npu_dev) { struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; int ret = 0; if (host_ctx->auto_pil_disable) { NPU_WARN("auto pil is disabled\n"); Loading @@ -212,16 +211,7 @@ int unload_fw(struct npu_device *npu_dev) return -EBUSY; } /* vote minimum bandwidth before unload npu fw via PIL */ ret = npu_set_bw(npu_dev, 100, 100); if (ret) { NPU_ERR("Can't update bandwidth\n"); mutex_unlock(&host_ctx->lock); return ret; } subsystem_put_local(host_ctx->subsystem_handle); npu_set_bw(npu_dev, 0, 0); host_ctx->fw_state = FW_UNLOADED; NPU_DBG("fw is unloaded\n"); mutex_unlock(&host_ctx->lock); Loading Loading @@ -531,9 +521,18 @@ static int npu_notifier_cb(struct notifier_block *this, unsigned long code, npu_disable_core_power(npu_dev); npu_notify_aop(npu_dev, false); } /* vote minimum bandwidth before unload npu fw via PIL */ ret = npu_set_bw(npu_dev, 100, 100); if (ret) NPU_WARN("Can't update bandwidth\n"); break; } case SUBSYS_AFTER_SHUTDOWN: ret = npu_set_bw(npu_dev, 0, 0); if (ret) NPU_WARN("Can't update bandwidth\n"); break; default: NPU_DBG("Ignoring event\n"); Loading Loading
drivers/media/platform/msm/npu/npu_common.h +4 −1 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ #define NPU_MAX_DT_NAME_LEN 21 #define NPU_MAX_PWRLEVELS 8 #define NPU_MAX_STATS_BUF_SIZE 16384 #define NPU_MAX_BW_DEVS 4 enum npu_power_level { NPU_PWRLEVEL_MINSVS = 0, Loading Loading @@ -174,7 +175,9 @@ struct npu_pwrctrl { uint32_t min_pwrlevel; uint32_t num_pwrlevels; struct device *devbw; struct device *devbw[NPU_MAX_BW_DEVS]; uint32_t devbw_num; uint32_t bwmon_enabled; uint32_t uc_pwrlevel; uint32_t cdsprm_pwrlevel; uint32_t fmax_pwrlevel; Loading
drivers/media/platform/msm/npu/npu_dev.c +87 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include <linux/regulator/consumer.h> #include <linux/thermal.h> #include <linux/soc/qcom/llcc-qcom.h> #include <soc/qcom/devfreq_devbw.h> #include "npu_common.h" #include "npu_hw.h" Loading Loading @@ -60,6 +61,8 @@ static ssize_t perf_mode_override_store(struct device *dev, static ssize_t boot_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 @@ -353,6 +356,7 @@ int npu_enable_core_power(struct npu_device *npu_dev) npu_disable_regulators(npu_dev); goto fail; } npu_resume_devbw(npu_dev); } pwr->pwr_vote_num++; fail: Loading @@ -373,6 +377,7 @@ void npu_disable_core_power(struct npu_device *npu_dev) pwr->pwr_vote_num--; if (!pwr->pwr_vote_num) { npu_suspend_devbw(npu_dev); npu_disable_core_clocks(npu_dev); npu_set_bw(npu_dev, 0, 0); npu_disable_regulators(npu_dev); Loading Loading @@ -565,6 +570,44 @@ int npu_set_uc_power_level(struct npu_device *npu_dev, return npu_set_power_level(npu_dev, true); } /* ------------------------------------------------------------------------- * Bandwidth Monitor Related * ------------------------------------------------------------------------- */ static void npu_suspend_devbw(struct npu_device *npu_dev) { struct npu_pwrctrl *pwr = &npu_dev->pwrctrl; int ret, i; if (pwr->bwmon_enabled && (pwr->devbw_num > 0)) { for (i = 0; i < pwr->devbw_num; i++) { NPU_DBG("Suspend devbw%d\n", i); ret = devfreq_suspend_devbw(pwr->devbw[i]); if (ret) NPU_ERR("devfreq_suspend_devbw failed rc:%d\n", ret); } pwr->bwmon_enabled = 0; } } static void npu_resume_devbw(struct npu_device *npu_dev) { struct npu_pwrctrl *pwr = &npu_dev->pwrctrl; int ret, i; if (!pwr->bwmon_enabled && (pwr->devbw_num > 0)) { for (i = 0; i < pwr->devbw_num; i++) { NPU_DBG("Resume devbw%d\n", i); ret = devfreq_resume_devbw(pwr->devbw[i]); if (ret) NPU_ERR("devfreq_resume_devbw failed rc:%d\n", ret); } pwr->bwmon_enabled = 1; } } /* ------------------------------------------------------------------------- * Clocks Related * ------------------------------------------------------------------------- Loading Loading @@ -1729,7 +1772,9 @@ static int npu_pwrctrl_init(struct npu_device *npu_dev) { struct platform_device *pdev = npu_dev->pdev; struct device_node *node; int ret = 0; int ret = 0, i; struct platform_device *p2dev; struct npu_pwrctrl *pwr = &npu_dev->pwrctrl; /* Power levels */ node = of_find_node_by_name(pdev->dev.of_node, "qcom,npu-pwrlevels"); Loading @@ -1743,6 +1788,47 @@ static int npu_pwrctrl_init(struct npu_device *npu_dev) if (ret) return ret; /* Parse Bandwidth Monitor */ pwr->devbw_num = of_property_count_strings(pdev->dev.of_node, "qcom,npubw-dev-names"); if (pwr->devbw_num <= 0) { NPU_INFO("npubw-dev-names are not defined\n"); return 0; } else if (pwr->devbw_num > NPU_MAX_BW_DEVS) { NPU_ERR("number of devbw %d exceeds limit\n", pwr->devbw_num); return -EINVAL; } for (i = 0; i < pwr->devbw_num; i++) { node = of_parse_phandle(pdev->dev.of_node, "qcom,npubw-devs", i); if (node) { p2dev = of_find_device_by_node(node); of_node_put(node); if (p2dev) { pwr->devbw[i] = &p2dev->dev; } else { NPU_ERR("can't find devbw%d\n", i); ret = -EINVAL; break; } } else { NPU_ERR("can't find devbw node\n"); ret = -EINVAL; break; } } if (ret) { /* Allow npu work without bwmon */ pwr->devbw_num = 0; ret = 0; } else { /* Set to 1 initially - we assume bwmon is on */ pwr->bwmon_enabled = 1; } return ret; } Loading
drivers/media/platform/msm/npu/npu_mgr.c +9 −10 Original line number Diff line number Diff line Loading @@ -194,7 +194,6 @@ int load_fw(struct npu_device *npu_dev) int unload_fw(struct npu_device *npu_dev) { struct npu_host_ctx *host_ctx = &npu_dev->host_ctx; int ret = 0; if (host_ctx->auto_pil_disable) { NPU_WARN("auto pil is disabled\n"); Loading @@ -212,16 +211,7 @@ int unload_fw(struct npu_device *npu_dev) return -EBUSY; } /* vote minimum bandwidth before unload npu fw via PIL */ ret = npu_set_bw(npu_dev, 100, 100); if (ret) { NPU_ERR("Can't update bandwidth\n"); mutex_unlock(&host_ctx->lock); return ret; } subsystem_put_local(host_ctx->subsystem_handle); npu_set_bw(npu_dev, 0, 0); host_ctx->fw_state = FW_UNLOADED; NPU_DBG("fw is unloaded\n"); mutex_unlock(&host_ctx->lock); Loading Loading @@ -531,9 +521,18 @@ static int npu_notifier_cb(struct notifier_block *this, unsigned long code, npu_disable_core_power(npu_dev); npu_notify_aop(npu_dev, false); } /* vote minimum bandwidth before unload npu fw via PIL */ ret = npu_set_bw(npu_dev, 100, 100); if (ret) NPU_WARN("Can't update bandwidth\n"); break; } case SUBSYS_AFTER_SHUTDOWN: ret = npu_set_bw(npu_dev, 0, 0); if (ret) NPU_WARN("Can't update bandwidth\n"); break; default: NPU_DBG("Ignoring event\n"); Loading