root/drivers/misc/habanalabs/goya/goya_hwmgr.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. goya_set_pll_profile
  2. mme_clk_show
  3. mme_clk_store
  4. tpc_clk_show
  5. tpc_clk_store
  6. ic_clk_show
  7. ic_clk_store
  8. mme_clk_curr_show
  9. tpc_clk_curr_show
  10. ic_clk_curr_show
  11. pm_mng_profile_show
  12. pm_mng_profile_store
  13. high_pll_show
  14. high_pll_store
  15. goya_add_device_attr

   1 // SPDX-License-Identifier: GPL-2.0
   2 
   3 /*
   4  * Copyright 2016-2019 HabanaLabs, Ltd.
   5  * All Rights Reserved.
   6  */
   7 
   8 #include "goyaP.h"
   9 
  10 void goya_set_pll_profile(struct hl_device *hdev, enum hl_pll_frequency freq)
  11 {
  12         struct goya_device *goya = hdev->asic_specific;
  13 
  14         switch (freq) {
  15         case PLL_HIGH:
  16                 hl_set_frequency(hdev, MME_PLL, hdev->high_pll);
  17                 hl_set_frequency(hdev, TPC_PLL, hdev->high_pll);
  18                 hl_set_frequency(hdev, IC_PLL, hdev->high_pll);
  19                 break;
  20         case PLL_LOW:
  21                 hl_set_frequency(hdev, MME_PLL, GOYA_PLL_FREQ_LOW);
  22                 hl_set_frequency(hdev, TPC_PLL, GOYA_PLL_FREQ_LOW);
  23                 hl_set_frequency(hdev, IC_PLL, GOYA_PLL_FREQ_LOW);
  24                 break;
  25         case PLL_LAST:
  26                 hl_set_frequency(hdev, MME_PLL, goya->mme_clk);
  27                 hl_set_frequency(hdev, TPC_PLL, goya->tpc_clk);
  28                 hl_set_frequency(hdev, IC_PLL, goya->ic_clk);
  29                 break;
  30         default:
  31                 dev_err(hdev->dev, "unknown frequency setting\n");
  32         }
  33 }
  34 
  35 static ssize_t mme_clk_show(struct device *dev, struct device_attribute *attr,
  36                                 char *buf)
  37 {
  38         struct hl_device *hdev = dev_get_drvdata(dev);
  39         long value;
  40 
  41         if (hl_device_disabled_or_in_reset(hdev))
  42                 return -ENODEV;
  43 
  44         value = hl_get_frequency(hdev, MME_PLL, false);
  45 
  46         if (value < 0)
  47                 return value;
  48 
  49         return sprintf(buf, "%lu\n", value);
  50 }
  51 
  52 static ssize_t mme_clk_store(struct device *dev, struct device_attribute *attr,
  53                                 const char *buf, size_t count)
  54 {
  55         struct hl_device *hdev = dev_get_drvdata(dev);
  56         struct goya_device *goya = hdev->asic_specific;
  57         int rc;
  58         long value;
  59 
  60         if (hl_device_disabled_or_in_reset(hdev)) {
  61                 count = -ENODEV;
  62                 goto fail;
  63         }
  64 
  65         if (hdev->pm_mng_profile == PM_AUTO) {
  66                 count = -EPERM;
  67                 goto fail;
  68         }
  69 
  70         rc = kstrtoul(buf, 0, &value);
  71 
  72         if (rc) {
  73                 count = -EINVAL;
  74                 goto fail;
  75         }
  76 
  77         hl_set_frequency(hdev, MME_PLL, value);
  78         goya->mme_clk = value;
  79 
  80 fail:
  81         return count;
  82 }
  83 
  84 static ssize_t tpc_clk_show(struct device *dev, struct device_attribute *attr,
  85                                 char *buf)
  86 {
  87         struct hl_device *hdev = dev_get_drvdata(dev);
  88         long value;
  89 
  90         if (hl_device_disabled_or_in_reset(hdev))
  91                 return -ENODEV;
  92 
  93         value = hl_get_frequency(hdev, TPC_PLL, false);
  94 
  95         if (value < 0)
  96                 return value;
  97 
  98         return sprintf(buf, "%lu\n", value);
  99 }
 100 
 101 static ssize_t tpc_clk_store(struct device *dev, struct device_attribute *attr,
 102                                 const char *buf, size_t count)
 103 {
 104         struct hl_device *hdev = dev_get_drvdata(dev);
 105         struct goya_device *goya = hdev->asic_specific;
 106         int rc;
 107         long value;
 108 
 109         if (hl_device_disabled_or_in_reset(hdev)) {
 110                 count = -ENODEV;
 111                 goto fail;
 112         }
 113 
 114         if (hdev->pm_mng_profile == PM_AUTO) {
 115                 count = -EPERM;
 116                 goto fail;
 117         }
 118 
 119         rc = kstrtoul(buf, 0, &value);
 120 
 121         if (rc) {
 122                 count = -EINVAL;
 123                 goto fail;
 124         }
 125 
 126         hl_set_frequency(hdev, TPC_PLL, value);
 127         goya->tpc_clk = value;
 128 
 129 fail:
 130         return count;
 131 }
 132 
 133 static ssize_t ic_clk_show(struct device *dev, struct device_attribute *attr,
 134                                 char *buf)
 135 {
 136         struct hl_device *hdev = dev_get_drvdata(dev);
 137         long value;
 138 
 139         if (hl_device_disabled_or_in_reset(hdev))
 140                 return -ENODEV;
 141 
 142         value = hl_get_frequency(hdev, IC_PLL, false);
 143 
 144         if (value < 0)
 145                 return value;
 146 
 147         return sprintf(buf, "%lu\n", value);
 148 }
 149 
 150 static ssize_t ic_clk_store(struct device *dev, struct device_attribute *attr,
 151                                 const char *buf, size_t count)
 152 {
 153         struct hl_device *hdev = dev_get_drvdata(dev);
 154         struct goya_device *goya = hdev->asic_specific;
 155         int rc;
 156         long value;
 157 
 158         if (hl_device_disabled_or_in_reset(hdev)) {
 159                 count = -ENODEV;
 160                 goto fail;
 161         }
 162 
 163         if (hdev->pm_mng_profile == PM_AUTO) {
 164                 count = -EPERM;
 165                 goto fail;
 166         }
 167 
 168         rc = kstrtoul(buf, 0, &value);
 169 
 170         if (rc) {
 171                 count = -EINVAL;
 172                 goto fail;
 173         }
 174 
 175         hl_set_frequency(hdev, IC_PLL, value);
 176         goya->ic_clk = value;
 177 
 178 fail:
 179         return count;
 180 }
 181 
 182 static ssize_t mme_clk_curr_show(struct device *dev,
 183                                 struct device_attribute *attr, char *buf)
 184 {
 185         struct hl_device *hdev = dev_get_drvdata(dev);
 186         long value;
 187 
 188         if (hl_device_disabled_or_in_reset(hdev))
 189                 return -ENODEV;
 190 
 191         value = hl_get_frequency(hdev, MME_PLL, true);
 192 
 193         if (value < 0)
 194                 return value;
 195 
 196         return sprintf(buf, "%lu\n", value);
 197 }
 198 
 199 static ssize_t tpc_clk_curr_show(struct device *dev,
 200                                 struct device_attribute *attr, char *buf)
 201 {
 202         struct hl_device *hdev = dev_get_drvdata(dev);
 203         long value;
 204 
 205         if (hl_device_disabled_or_in_reset(hdev))
 206                 return -ENODEV;
 207 
 208         value = hl_get_frequency(hdev, TPC_PLL, true);
 209 
 210         if (value < 0)
 211                 return value;
 212 
 213         return sprintf(buf, "%lu\n", value);
 214 }
 215 
 216 static ssize_t ic_clk_curr_show(struct device *dev,
 217                                 struct device_attribute *attr, char *buf)
 218 {
 219         struct hl_device *hdev = dev_get_drvdata(dev);
 220         long value;
 221 
 222         if (hl_device_disabled_or_in_reset(hdev))
 223                 return -ENODEV;
 224 
 225         value = hl_get_frequency(hdev, IC_PLL, true);
 226 
 227         if (value < 0)
 228                 return value;
 229 
 230         return sprintf(buf, "%lu\n", value);
 231 }
 232 
 233 static ssize_t pm_mng_profile_show(struct device *dev,
 234                                 struct device_attribute *attr, char *buf)
 235 {
 236         struct hl_device *hdev = dev_get_drvdata(dev);
 237 
 238         if (hl_device_disabled_or_in_reset(hdev))
 239                 return -ENODEV;
 240 
 241         return sprintf(buf, "%s\n",
 242                         (hdev->pm_mng_profile == PM_AUTO) ? "auto" :
 243                         (hdev->pm_mng_profile == PM_MANUAL) ? "manual" :
 244                         "unknown");
 245 }
 246 
 247 static ssize_t pm_mng_profile_store(struct device *dev,
 248                 struct device_attribute *attr, const char *buf, size_t count)
 249 {
 250         struct hl_device *hdev = dev_get_drvdata(dev);
 251 
 252         if (hl_device_disabled_or_in_reset(hdev)) {
 253                 count = -ENODEV;
 254                 goto out;
 255         }
 256 
 257         mutex_lock(&hdev->fpriv_list_lock);
 258 
 259         if (hdev->compute_ctx) {
 260                 dev_err(hdev->dev,
 261                         "Can't change PM profile while compute context is opened on the device\n");
 262                 count = -EPERM;
 263                 goto unlock_mutex;
 264         }
 265 
 266         if (strncmp("auto", buf, strlen("auto")) == 0) {
 267                 /* Make sure we are in LOW PLL when changing modes */
 268                 if (hdev->pm_mng_profile == PM_MANUAL) {
 269                         hdev->curr_pll_profile = PLL_HIGH;
 270                         hl_device_set_frequency(hdev, PLL_LOW);
 271                         hdev->pm_mng_profile = PM_AUTO;
 272                 }
 273         } else if (strncmp("manual", buf, strlen("manual")) == 0) {
 274                 if (hdev->pm_mng_profile == PM_AUTO) {
 275                         /* Must release the lock because the work thread also
 276                          * takes this lock. But before we release it, set
 277                          * the mode to manual so nothing will change if a user
 278                          * suddenly opens the device
 279                          */
 280                         hdev->pm_mng_profile = PM_MANUAL;
 281 
 282                         mutex_unlock(&hdev->fpriv_list_lock);
 283 
 284                         /* Flush the current work so we can return to the user
 285                          * knowing that he is the only one changing frequencies
 286                          */
 287                         flush_delayed_work(&hdev->work_freq);
 288 
 289                         return count;
 290                 }
 291         } else {
 292                 dev_err(hdev->dev, "value should be auto or manual\n");
 293                 count = -EINVAL;
 294         }
 295 
 296 unlock_mutex:
 297         mutex_unlock(&hdev->fpriv_list_lock);
 298 out:
 299         return count;
 300 }
 301 
 302 static ssize_t high_pll_show(struct device *dev, struct device_attribute *attr,
 303                                 char *buf)
 304 {
 305         struct hl_device *hdev = dev_get_drvdata(dev);
 306 
 307         if (hl_device_disabled_or_in_reset(hdev))
 308                 return -ENODEV;
 309 
 310         return sprintf(buf, "%u\n", hdev->high_pll);
 311 }
 312 
 313 static ssize_t high_pll_store(struct device *dev, struct device_attribute *attr,
 314                                 const char *buf, size_t count)
 315 {
 316         struct hl_device *hdev = dev_get_drvdata(dev);
 317         long value;
 318         int rc;
 319 
 320         if (hl_device_disabled_or_in_reset(hdev)) {
 321                 count = -ENODEV;
 322                 goto out;
 323         }
 324 
 325         rc = kstrtoul(buf, 0, &value);
 326 
 327         if (rc) {
 328                 count = -EINVAL;
 329                 goto out;
 330         }
 331 
 332         hdev->high_pll = value;
 333 
 334 out:
 335         return count;
 336 }
 337 
 338 static DEVICE_ATTR_RW(high_pll);
 339 static DEVICE_ATTR_RW(ic_clk);
 340 static DEVICE_ATTR_RO(ic_clk_curr);
 341 static DEVICE_ATTR_RW(mme_clk);
 342 static DEVICE_ATTR_RO(mme_clk_curr);
 343 static DEVICE_ATTR_RW(pm_mng_profile);
 344 static DEVICE_ATTR_RW(tpc_clk);
 345 static DEVICE_ATTR_RO(tpc_clk_curr);
 346 
 347 static struct attribute *goya_dev_attrs[] = {
 348         &dev_attr_high_pll.attr,
 349         &dev_attr_ic_clk.attr,
 350         &dev_attr_ic_clk_curr.attr,
 351         &dev_attr_mme_clk.attr,
 352         &dev_attr_mme_clk_curr.attr,
 353         &dev_attr_pm_mng_profile.attr,
 354         &dev_attr_tpc_clk.attr,
 355         &dev_attr_tpc_clk_curr.attr,
 356         NULL,
 357 };
 358 
 359 void goya_add_device_attr(struct hl_device *hdev,
 360                         struct attribute_group *dev_attr_grp)
 361 {
 362         dev_attr_grp->attrs = goya_dev_attrs;
 363 }

/* [<][>][^][v][top][bottom][index][help] */