Author | Tokens | Token Proportion | Commits | Commit Proportion |
---|---|---|---|---|
Oded Gabbay | 1593 | 93.43% | 10 | 71.43% |
Ofir Bitton | 52 | 3.05% | 1 | 7.14% |
Rajaravi Krishna Katta | 38 | 2.23% | 1 | 7.14% |
Bharat Jauhari | 18 | 1.06% | 1 | 7.14% |
Dafna Hirschfeld | 4 | 0.23% | 1 | 7.14% |
Total | 1705 | 14 |
// SPDX-License-Identifier: GPL-2.0 /* * Copyright 2016-2022 HabanaLabs, Ltd. * All Rights Reserved. */ #include "goyaP.h" void goya_set_pll_profile(struct hl_device *hdev, enum hl_pll_frequency freq) { struct goya_device *goya = hdev->asic_specific; if (!hdev->pdev) return; switch (freq) { case PLL_HIGH: hl_fw_set_frequency(hdev, HL_GOYA_MME_PLL, hdev->high_pll); hl_fw_set_frequency(hdev, HL_GOYA_TPC_PLL, hdev->high_pll); hl_fw_set_frequency(hdev, HL_GOYA_IC_PLL, hdev->high_pll); break; case PLL_LOW: hl_fw_set_frequency(hdev, HL_GOYA_MME_PLL, GOYA_PLL_FREQ_LOW); hl_fw_set_frequency(hdev, HL_GOYA_TPC_PLL, GOYA_PLL_FREQ_LOW); hl_fw_set_frequency(hdev, HL_GOYA_IC_PLL, GOYA_PLL_FREQ_LOW); break; case PLL_LAST: hl_fw_set_frequency(hdev, HL_GOYA_MME_PLL, goya->mme_clk); hl_fw_set_frequency(hdev, HL_GOYA_TPC_PLL, goya->tpc_clk); hl_fw_set_frequency(hdev, HL_GOYA_IC_PLL, goya->ic_clk); break; default: dev_err(hdev->dev, "unknown frequency setting\n"); } } static ssize_t mme_clk_show(struct device *dev, struct device_attribute *attr, char *buf) { struct hl_device *hdev = dev_get_drvdata(dev); long value; if (!hl_device_operational(hdev, NULL)) return -ENODEV; value = hl_fw_get_frequency(hdev, HL_GOYA_MME_PLL, false); if (value < 0) return value; return sprintf(buf, "%lu\n", value); } static ssize_t mme_clk_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct hl_device *hdev = dev_get_drvdata(dev); struct goya_device *goya = hdev->asic_specific; int rc; long value; if (!hl_device_operational(hdev, NULL)) { count = -ENODEV; goto fail; } if (goya->pm_mng_profile == PM_AUTO) { count = -EPERM; goto fail; } rc = kstrtoul(buf, 0, &value); if (rc) { count = -EINVAL; goto fail; } hl_fw_set_frequency(hdev, HL_GOYA_MME_PLL, value); goya->mme_clk = value; fail: return count; } static ssize_t tpc_clk_show(struct device *dev, struct device_attribute *attr, char *buf) { struct hl_device *hdev = dev_get_drvdata(dev); long value; if (!hl_device_operational(hdev, NULL)) return -ENODEV; value = hl_fw_get_frequency(hdev, HL_GOYA_TPC_PLL, false); if (value < 0) return value; return sprintf(buf, "%lu\n", value); } static ssize_t tpc_clk_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct hl_device *hdev = dev_get_drvdata(dev); struct goya_device *goya = hdev->asic_specific; int rc; long value; if (!hl_device_operational(hdev, NULL)) { count = -ENODEV; goto fail; } if (goya->pm_mng_profile == PM_AUTO) { count = -EPERM; goto fail; } rc = kstrtoul(buf, 0, &value); if (rc) { count = -EINVAL; goto fail; } hl_fw_set_frequency(hdev, HL_GOYA_TPC_PLL, value); goya->tpc_clk = value; fail: return count; } static ssize_t ic_clk_show(struct device *dev, struct device_attribute *attr, char *buf) { struct hl_device *hdev = dev_get_drvdata(dev); long value; if (!hl_device_operational(hdev, NULL)) return -ENODEV; value = hl_fw_get_frequency(hdev, HL_GOYA_IC_PLL, false); if (value < 0) return value; return sprintf(buf, "%lu\n", value); } static ssize_t ic_clk_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct hl_device *hdev = dev_get_drvdata(dev); struct goya_device *goya = hdev->asic_specific; int rc; long value; if (!hl_device_operational(hdev, NULL)) { count = -ENODEV; goto fail; } if (goya->pm_mng_profile == PM_AUTO) { count = -EPERM; goto fail; } rc = kstrtoul(buf, 0, &value); if (rc) { count = -EINVAL; goto fail; } hl_fw_set_frequency(hdev, HL_GOYA_IC_PLL, value); goya->ic_clk = value; fail: return count; } static ssize_t mme_clk_curr_show(struct device *dev, struct device_attribute *attr, char *buf) { struct hl_device *hdev = dev_get_drvdata(dev); long value; if (!hl_device_operational(hdev, NULL)) return -ENODEV; value = hl_fw_get_frequency(hdev, HL_GOYA_MME_PLL, true); if (value < 0) return value; return sprintf(buf, "%lu\n", value); } static ssize_t tpc_clk_curr_show(struct device *dev, struct device_attribute *attr, char *buf) { struct hl_device *hdev = dev_get_drvdata(dev); long value; if (!hl_device_operational(hdev, NULL)) return -ENODEV; value = hl_fw_get_frequency(hdev, HL_GOYA_TPC_PLL, true); if (value < 0) return value; return sprintf(buf, "%lu\n", value); } static ssize_t ic_clk_curr_show(struct device *dev, struct device_attribute *attr, char *buf) { struct hl_device *hdev = dev_get_drvdata(dev); long value; if (!hl_device_operational(hdev, NULL)) return -ENODEV; value = hl_fw_get_frequency(hdev, HL_GOYA_IC_PLL, true); if (value < 0) return value; return sprintf(buf, "%lu\n", value); } static ssize_t pm_mng_profile_show(struct device *dev, struct device_attribute *attr, char *buf) { struct hl_device *hdev = dev_get_drvdata(dev); struct goya_device *goya = hdev->asic_specific; if (!hl_device_operational(hdev, NULL)) return -ENODEV; return sprintf(buf, "%s\n", (goya->pm_mng_profile == PM_AUTO) ? "auto" : (goya->pm_mng_profile == PM_MANUAL) ? "manual" : "unknown"); } static ssize_t pm_mng_profile_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct hl_device *hdev = dev_get_drvdata(dev); struct goya_device *goya = hdev->asic_specific; if (!hl_device_operational(hdev, NULL)) { count = -ENODEV; goto out; } mutex_lock(&hdev->fpriv_list_lock); if (hdev->is_compute_ctx_active) { dev_err(hdev->dev, "Can't change PM profile while compute context is opened on the device\n"); count = -EPERM; goto unlock_mutex; } if (strncmp("auto", buf, strlen("auto")) == 0) { /* Make sure we are in LOW PLL when changing modes */ if (goya->pm_mng_profile == PM_MANUAL) { goya->curr_pll_profile = PLL_HIGH; goya->pm_mng_profile = PM_AUTO; goya_set_frequency(hdev, PLL_LOW); } } else if (strncmp("manual", buf, strlen("manual")) == 0) { if (goya->pm_mng_profile == PM_AUTO) { /* Must release the lock because the work thread also * takes this lock. But before we release it, set * the mode to manual so nothing will change if a user * suddenly opens the device */ goya->pm_mng_profile = PM_MANUAL; mutex_unlock(&hdev->fpriv_list_lock); /* Flush the current work so we can return to the user * knowing that he is the only one changing frequencies */ if (goya->goya_work) flush_delayed_work(&goya->goya_work->work_freq); return count; } } else { dev_err(hdev->dev, "value should be auto or manual\n"); count = -EINVAL; } unlock_mutex: mutex_unlock(&hdev->fpriv_list_lock); out: return count; } static ssize_t high_pll_show(struct device *dev, struct device_attribute *attr, char *buf) { struct hl_device *hdev = dev_get_drvdata(dev); if (!hl_device_operational(hdev, NULL)) return -ENODEV; return sprintf(buf, "%u\n", hdev->high_pll); } static ssize_t high_pll_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct hl_device *hdev = dev_get_drvdata(dev); long value; int rc; if (!hl_device_operational(hdev, NULL)) { count = -ENODEV; goto out; } rc = kstrtoul(buf, 0, &value); if (rc) { count = -EINVAL; goto out; } hdev->high_pll = value; out: return count; } static DEVICE_ATTR_RW(high_pll); static DEVICE_ATTR_RW(ic_clk); static DEVICE_ATTR_RO(ic_clk_curr); static DEVICE_ATTR_RW(mme_clk); static DEVICE_ATTR_RO(mme_clk_curr); static DEVICE_ATTR_RW(pm_mng_profile); static DEVICE_ATTR_RW(tpc_clk); static DEVICE_ATTR_RO(tpc_clk_curr); static struct attribute *goya_clk_dev_attrs[] = { &dev_attr_high_pll.attr, &dev_attr_ic_clk.attr, &dev_attr_ic_clk_curr.attr, &dev_attr_mme_clk.attr, &dev_attr_mme_clk_curr.attr, &dev_attr_pm_mng_profile.attr, &dev_attr_tpc_clk.attr, &dev_attr_tpc_clk_curr.attr, NULL, }; static ssize_t infineon_ver_show(struct device *dev, struct device_attribute *attr, char *buf) { struct hl_device *hdev = dev_get_drvdata(dev); struct cpucp_info *cpucp_info; cpucp_info = &hdev->asic_prop.cpucp_info; return sprintf(buf, "%#04x\n", le32_to_cpu(cpucp_info->infineon_version)); } static DEVICE_ATTR_RO(infineon_ver); static struct attribute *goya_vrm_dev_attrs[] = { &dev_attr_infineon_ver.attr, NULL, }; void goya_add_device_attr(struct hl_device *hdev, struct attribute_group *dev_clk_attr_grp, struct attribute_group *dev_vrm_attr_grp) { dev_clk_attr_grp->attrs = goya_clk_dev_attrs; dev_vrm_attr_grp->attrs = goya_vrm_dev_attrs; }
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with Cregit http://github.com/cregit/cregit
Version 2.0-RC1