Hi AngeloGioacchino,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on pm/linux-next]
[also build test WARNING on robh/for-next linux/master linus/master v5.11-rc2 
next-20210108]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    
https://github.com/0day-ci/linux/commits/AngeloGioacchino-Del-Regno/Enable-CPRh-3-4-CPU-Scaling-on-various-QCOM-SoCs/20210110-021002
base:   https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git 
linux-next
config: arm64-allyesconfig (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
        chmod +x ~/bin/make.cross
        # 
https://github.com/0day-ci/linux/commit/f7b151e3b7c4b04b3333508e6ff13738de070041
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review 
AngeloGioacchino-Del-Regno/Enable-CPRh-3-4-CPU-Scaling-on-various-QCOM-SoCs/20210110-021002
        git checkout f7b151e3b7c4b04b3333508e6ff13738de070041
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross 
ARCH=arm64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <l...@intel.com>

All warnings (new ones prefixed by >>):

   drivers/soc/qcom/cpr3.c: In function 'cpr3_corner_init':
>> drivers/soc/qcom/cpr3.c:1673:17: warning: variable 'min_quot_val' set but 
>> not used [-Wunused-but-set-variable]
    1673 |   int ring_osc, min_quot_val;
         |                 ^~~~~~~~~~~~
>> drivers/soc/qcom/cpr3.c:1316:7: warning: variable 'apply_scaling' set but 
>> not used [-Wunused-but-set-variable]
    1316 |  bool apply_scaling;
         |       ^~~~~~~~~~~~~


vim +/min_quot_val +1673 drivers/soc/qcom/cpr3.c

  1284  
  1285  /**
  1286   * cpr3_corner_init - Calculate and set-up corners for the CPR HW
  1287   * @thread: Structure holding CPR thread-specific parameters
  1288   *
  1289   * This function calculates all the corner parameters by comparing
  1290   * and interpolating the values read from the various set-points
  1291   * read from the fuses (also called "fuse corners") to generate and
  1292   * program to the CPR a lookup table that describes each voltage
  1293   * step, mapped to a performance level (or corner number).
  1294   *
  1295   * It also programs other essential parameters on the CPR and - if
  1296   * we are dealing with CPR-Hardened, it will also enable the internal
  1297   * interface between the Operating State Manager (OSM) and the CPRh
  1298   * in order to achieve CPU DVFS.
  1299   *
  1300   * Returns: Zero for success, negative number on error
  1301   */
  1302  static int cpr3_corner_init(struct cpr_thread *thread)
  1303  {
  1304          struct cpr_drv *drv = thread->drv;
  1305          const struct cpr_desc *desc = drv->desc;
  1306          const struct cpr_thread_desc *tdesc = thread->desc;
  1307          const struct cpr_fuse *fuses = thread->cpr_fuses;
  1308          int i, ret, total_corners, extra_corners, level, scaling = 0;
  1309          unsigned int fnum, fc;
  1310          const char *quot_offset;
  1311          const struct fuse_corner_data *fdata;
  1312          struct fuse_corner *fuse, *prev_fuse;
  1313          struct corner *corner, *prev_corner, *end;
  1314          struct corner_data *cdata;
  1315          struct dev_pm_opp *opp;
  1316          bool apply_scaling;
  1317          unsigned long freq;
  1318          u32 ring_osc_mask = CPR3_RO_MASK, min_quotient = U32_MAX;
  1319  
  1320          corner = thread->corners;
  1321          prev_corner = &thread->corners[0];
  1322          end = &corner[thread->num_corners - 1];
  1323  
  1324          cdata = devm_kcalloc(drv->dev,
  1325                               thread->num_corners + drv->extra_corners,
  1326                               sizeof(struct corner_data),
  1327                               GFP_KERNEL);
  1328          if (!cdata)
  1329                  return -ENOMEM;
  1330  
  1331          for (level = 1; level <= thread->num_corners; level++) {
  1332                  opp = dev_pm_opp_find_level_exact(&thread->pd.dev, 
level);
  1333                  if (IS_ERR(opp))
  1334                          return -EINVAL;
  1335  
  1336                  /*
  1337                   * If there is only one specified qcom,opp-fuse-level, 
then
  1338                   * it is assumed that this only one is global and valid 
for
  1339                   * all IDs, so try to get the specific one but, on 
failure,
  1340                   * go for the global one.
  1341                   */
  1342                  fc = cpr_get_fuse_corner(opp, thread->id);
  1343                  if (fc == 0) {
  1344                          fc = cpr_get_fuse_corner(opp, 0);
  1345                          if (fc == 0) {
  1346                                  dev_err(drv->dev,
  1347                                          "qcom,opp-fuse-level is 
missing!\n");
  1348                                  dev_pm_opp_put(opp);
  1349                                  return -EINVAL;
  1350                          }
  1351                  }
  1352                  fnum = fc - 1;
  1353  
  1354                  freq = cpr_get_opp_hz_for_req(opp, 
thread->attached_cpu_dev);
  1355                  if (!freq) {
  1356                          thread->num_corners = max(level - 1, 0);
  1357                          end = &thread->corners[thread->num_corners - 1];
  1358                          break;
  1359                  }
  1360  
  1361                  /*
  1362                   * If any post-vadj (open/closed loop) is not 
specified, then
  1363                   * it's zero, meaning that it is not required for this 
corner.
  1364                   */
  1365                  cpr_get_corner_post_vadj(opp, thread->id,
  1366                                           &cdata[level - 1].oloop_vadj,
  1367                                           &cdata[level - 1].cloop_vadj);
  1368                  cdata[level - 1].fuse_corner = fnum;
  1369                  cdata[level - 1].freq = freq;
  1370  
  1371                  fuse = &thread->fuse_corners[fnum];
  1372                  dev_dbg(drv->dev, "freq: %lu level: %u fuse level: 
%u\n",
  1373                          freq, dev_pm_opp_get_level(opp) - 1, fnum);
  1374                  if (freq > fuse->max_freq)
  1375                          fuse->max_freq = freq;
  1376                  dev_pm_opp_put(opp);
  1377  
  1378                  /*
  1379                   * Make sure that the frequencies in the table are in 
ascending
  1380                   * order, as this is critical for the algorithm to work.
  1381                   */
  1382                  if (cdata[level - 2].freq > freq) {
  1383                          dev_err(drv->dev,
  1384                                  "Frequency table not in ascending 
order.\n");
  1385                          return -EINVAL;
  1386                  }
  1387          }
  1388  
  1389          if (thread->num_corners < 2) {
  1390                  dev_err(drv->dev, "need at least 2 OPPs to use CPR\n");
  1391                  return -EINVAL;
  1392          }
  1393  
  1394          /*
  1395           * Get the quotient adjustment scaling factor, according to:
  1396           *
  1397           * scaling = min(1000 * (QUOT(corner_N) - QUOT(corner_N-1))
  1398           *              / (freq(corner_N) - freq(corner_N-1)), 
max_factor)
  1399           *
  1400           * QUOT(corner_N):      quotient read from fuse for fuse corner 
N
  1401           * QUOT(corner_N-1):    quotient read from fuse for fuse corner 
(N - 1)
  1402           * freq(corner_N):      max frequency in MHz supported by fuse 
corner N
  1403           * freq(corner_N-1):    max frequency in MHz supported by fuse 
corner
  1404           *                       (N - 1)
  1405           *
  1406           * Then walk through the corners mapped to each fuse corner
  1407           * and calculate the quotient adjustment for each one using the
  1408           * following formula:
  1409           *
  1410           * quot_adjust = (freq_max - freq_corner) * scaling / 1000
  1411           *
  1412           * freq_max: max frequency in MHz supported by the fuse corner
  1413           * freq_corner: frequency in MHz corresponding to the corner
  1414           * scaling: calculated from above equation
  1415           *
  1416           *
  1417           *     +                           +
  1418           *     |                         v |
  1419           *   q |           f c           o |           f c
  1420           *   u |         c               l |         c
  1421           *   o |       f                 t |       f
  1422           *   t |     c                   a |     c
  1423           *     | c f                     g | c f
  1424           *     |                         e |
  1425           *     +---------------            +----------------
  1426           *       0 1 2 3 4 5 6               0 1 2 3 4 5 6
  1427           *          corner                      corner
  1428           *
  1429           *    c = corner
  1430           *    f = fuse corner
  1431           *
  1432           */
  1433          for (apply_scaling = false, i = 0; corner <= end; corner++, 
i++) {
  1434                  unsigned long freq_diff_mhz;
  1435                  int ro_fac, vadj, prev_quot;
  1436  
  1437                  fnum = cdata[i].fuse_corner;
  1438                  fdata = &tdesc->fuse_corner_data[fnum];
  1439                  quot_offset = fuses[fnum].quotient_offset;
  1440                  fuse = &thread->fuse_corners[fnum];
  1441                  ring_osc_mask &= (u16)(~BIT(fuse->ring_osc_idx));
  1442                  if (fnum)
  1443                          prev_fuse = &thread->fuse_corners[fnum - 1];
  1444                  else
  1445                          prev_fuse = NULL;
  1446  
  1447                  corner->fuse_corner = fuse;
  1448                  corner->freq = cdata[i].freq;
  1449                  corner->uV = fuse->uV;
  1450  
  1451                  if (prev_fuse) {
  1452                          if (prev_fuse->ring_osc_idx == 
fuse->ring_osc_idx)
  1453                                  quot_offset = NULL;
  1454  
  1455                          scaling = cpr_calculate_scaling(quot_offset, 
drv->dev,
  1456                                                          fdata, corner);
  1457                          if (scaling < 0)
  1458                                  return scaling;
  1459  
  1460                          freq_diff_mhz = fuse->max_freq - corner->freq;
  1461                          do_div(freq_diff_mhz, 1000000); /* now in MHz */
  1462  
  1463                          corner->quot_adjust = scaling * freq_diff_mhz;
  1464                          do_div(corner->quot_adjust, 1000);
  1465  
  1466                          /* Fine-tune QUOT (closed-loop) based on fixed 
values */
  1467                          ro_fac = cpr_get_ro_factor(tdesc, fnum, 
fuse->ring_osc_idx);
  1468                          vadj = cdata[i].cloop_vadj;
  1469                          corner->quot_adjust -= cpr3_adjust_quot(ro_fac, 
vadj);
  1470                          dev_vdbg(drv->dev,
  1471                                   "Quot fine-tuning to %d for 
post-vadj=%d\n",
  1472                                   corner->quot_adjust, vadj);
  1473  
  1474                          /*
  1475                           * Make sure that we scale (up) monotonically.
  1476                           * P.S.: Fuse quots can never be descending.
  1477                           */
  1478                          prev_quot = prev_corner->fuse_corner->quot;
  1479                          prev_quot -= prev_corner->quot_adjust;
  1480                          if (fuse->quot - corner->quot_adjust < 
prev_quot) {
  1481                                  int new_adj = 
prev_corner->fuse_corner->quot;
  1482                                  new_adj -= fuse->quot;
  1483                                  dev_vdbg(drv->dev,
  1484                                           "Monotonic increase forced: 
%d->%d\n",
  1485                                           corner->quot_adjust, new_adj);
  1486                                  corner->quot_adjust = new_adj;
  1487                          }
  1488  
  1489                          corner->uV = cpr_interpolate(corner,
  1490                                                       drv->vreg_step, 
fdata);
  1491                  } else if (corner->freq == fuse->max_freq) {
  1492                          /* This is a fuse corner; don't scale anything 
*/
  1493                          apply_scaling = false;
  1494                  }
  1495                  /* Negative fuse quotients are nonsense. */
  1496                  if (fuse->quot < corner->quot_adjust)
  1497                          return -EINVAL;
  1498  
  1499                  min_quotient = min(min_quotient,
  1500                                     (u32)(fuse->quot - 
corner->quot_adjust));
  1501  
  1502                  /* Fine-tune voltages (open-loop) based on fixed values 
*/
  1503                  corner->uV += cdata[i].oloop_vadj;
  1504                  dev_dbg(drv->dev,
  1505                           "Voltage fine-tuning to %d for post-vadj=%d\n",
  1506                           corner->uV, cdata[i].oloop_vadj);
  1507  
  1508                  corner->max_uV = fuse->max_uV;
  1509                  corner->min_uV = fuse->min_uV;
  1510                  corner->uV = clamp(corner->uV, corner->min_uV, 
corner->max_uV);
  1511                  dev_vdbg(drv->dev, "Clamped after interpolation: [%d %d 
%d]\n",
  1512                          corner->min_uV, corner->uV, corner->max_uV);
  1513  
  1514                  /* Make sure that we scale monotonically here, too. */
  1515                  if (corner->uV < prev_corner->uV)
  1516                          corner->uV = prev_corner->uV;
  1517  
  1518                  corner->last_uV = corner->uV;
  1519  
  1520                  /* Reduce the ceiling voltage if needed */
  1521                  if (desc->reduce_to_corner_uV && corner->uV < 
corner->max_uV)
  1522                          corner->max_uV = corner->uV;
  1523                  else if (desc->reduce_to_fuse_uV && fuse->uV < 
corner->max_uV)
  1524                          corner->max_uV = max(corner->min_uV, fuse->uV);
  1525  
  1526                  corner->min_uV = max(corner->max_uV - fdata->range_uV,
  1527                                       corner->min_uV);
  1528  
  1529                  /*
  1530                   * Adjust per-corner floor and ceiling voltages so that
  1531                   * they do not overlap the memory Array Power Mux (APM)
  1532                   * nor the Memory Accelerator (MEM-ACC) threshold 
voltages.
  1533                   */
  1534                  if (desc->apm_threshold)
  1535                          cpr3_restrict_corner(corner, 
desc->apm_threshold,
  1536                                               desc->apm_hysteresis,
  1537                                               drv->vreg_step);
  1538                  if (desc->mem_acc_threshold)
  1539                          cpr3_restrict_corner(corner, 
desc->mem_acc_threshold,
  1540                                               0, drv->vreg_step);
  1541  
  1542                  prev_corner = corner;
  1543                  dev_dbg(drv->dev, "corner %d: [%d %d %d] scaling %d 
quot %d\n", i,
  1544                          corner->min_uV, corner->uV, corner->max_uV, 
scaling,
  1545                          fuse->quot - corner->quot_adjust);
  1546          }
  1547  
  1548          /* Additional setup for CPRh only */
  1549          if (desc->cpr_type < CTRL_TYPE_CPRH)
  1550                  return 0;
  1551  
  1552          /* If the OPPs can't be adjusted, programming the CPRh is 
useless */
  1553          ret = cprh_corner_adjust_opps(thread);
  1554          if (ret) {
  1555                  dev_err(drv->dev, "Cannot adjust CPU OPP voltages: 
%d\n", ret);
  1556                  return ret;
  1557          }
  1558  
  1559          total_corners = thread->num_corners;
  1560          extra_corners = drv->extra_corners;
  1561  
  1562          /* If the APM extra corner exists, add it now. */
  1563          if (desc->apm_crossover && desc->apm_threshold && 
extra_corners) {
  1564                  /* Program the APM crossover corner on the CPR-Hardened 
*/
  1565                  thread->corners[total_corners].uV = desc->apm_crossover;
  1566                  thread->corners[total_corners].min_uV = 
desc->apm_crossover;
  1567                  thread->corners[total_corners].max_uV = 
desc->apm_crossover;
  1568                  thread->corners[total_corners].is_open_loop = true;
  1569  
  1570                  /*
  1571                   * Also add and disable an opp with zero frequency: 
other
  1572                   * drivers will need to know what is the APM *threshold*
  1573                   * voltage.
  1574                   */
  1575                  ret = dev_pm_opp_add(thread->attached_cpu_dev, 0,
  1576                                       desc->apm_threshold);
  1577                  if (ret)
  1578                          return ret;
  1579  
  1580                  ret = dev_pm_opp_disable(thread->attached_cpu_dev, 0);
  1581                  if (ret)
  1582                          return ret;
  1583  
  1584                  dev_dbg(drv->dev, "corner %d (APM): [%d %d %d] 
Open-Loop\n",
  1585                          total_corners, desc->apm_crossover,
  1586                          desc->apm_crossover, desc->apm_crossover);
  1587  
  1588                  total_corners++;
  1589                  extra_corners--;
  1590          }
  1591  
  1592          if (desc->mem_acc_threshold && extra_corners) {
  1593                  /* Program the Memory Accelerator threshold corner to 
CPRh */
  1594                  thread->corners[total_corners].uV = 
desc->mem_acc_threshold;
  1595                  thread->corners[total_corners].min_uV = 
desc->mem_acc_threshold;
  1596                  thread->corners[total_corners].max_uV = 
desc->mem_acc_threshold;
  1597                  thread->corners[total_corners].is_open_loop = true;
  1598  
  1599                  /*
  1600                   * Add and disable an opp with zero frequency: other
  1601                   * drivers will also need to know about any mem-acc
  1602                   * threshold to respect.
  1603                   */
  1604                  ret = dev_pm_opp_add(thread->attached_cpu_dev, 1,
  1605                                       desc->mem_acc_threshold);
  1606                  if (ret)
  1607                          return ret;
  1608  
  1609                  ret = dev_pm_opp_disable(thread->attached_cpu_dev, 1);
  1610                  if (ret)
  1611                          return ret;
  1612  
  1613                  dev_dbg(drv->dev, "corner %d (MEMACC): [%d %d %d] 
Open-Loop\n",
  1614                          total_corners, desc->mem_acc_threshold,
  1615                          desc->mem_acc_threshold, 
desc->mem_acc_threshold);
  1616  
  1617                  total_corners++;
  1618                  extra_corners--;
  1619          }
  1620  
  1621          /*
  1622           * If there are any extra corners left, it means that even 
though we
  1623           * expect to fill in both APM and MEM-ACC crossovers, one 
couldn't
  1624           * satisfy requirements, which means that the specified 
parameters
  1625           * are wrong: in this case, inform the user and bail out, 
otherwise
  1626           * if we go on writing the (invalid) table to the CPR-Hardened, 
the
  1627           * hardware (in this case, the CPU) will surely freeze and 
crash.
  1628           */
  1629          if (unlikely(extra_corners)) {
  1630                  dev_err(drv->dev, "APM/MEM-ACC corners: bad 
parameters.\n");
  1631                  return -EINVAL;
  1632          }
  1633          /* Reassign extra_corners, as we have to exclude delta_quot for 
them */
  1634          extra_corners = drv->extra_corners;
  1635  
  1636          /* Disable the interface between OSM and CPRh */
  1637          cpr_masked_write(thread, drv->reg_ctl,
  1638                           CPRH_CTL_OSM_ENABLED, 0);
  1639  
  1640          /* Program the GCNT before unmasking ring oscillator(s) */
  1641          for (i = 0; i < CPR3_RO_COUNT; i++) {
  1642                  if (!(ring_osc_mask & BIT(i))) {
  1643                          cpr_write(thread, CPR3_REG_GCNT(i), drv->gcnt);
  1644                          dev_vdbg(drv->dev, "RO%d gcnt=%d\n", i, 
drv->gcnt);
  1645                  }
  1646          }
  1647  
  1648          /*
  1649           * Unmask the ring oscillator(s) that we're going to use: it 
seems
  1650           * to be mandatory to do this *before* sending the rest of the
  1651           * CPRhardened specific configuration.
  1652           */
  1653          dev_dbg(drv->dev,
  1654                  "Unmasking ring oscillators with mask 0x%x\n", 
ring_osc_mask);
  1655          cpr_write(thread, CPR3_REG_RO_MASK(tdesc->hw_tid), 
ring_osc_mask);
  1656  
  1657          /* Setup minimum quotients for ring oscillators */
  1658          for (i = 0; i < CPR3_RO_COUNT; i++) {
  1659                  u32 tgt_quot_reg = CPR3_REG_TARGET_QUOT(tdesc->hw_tid, 
i);
  1660                  u32 tgt_quot_val = 0;
  1661  
  1662                  if (!(ring_osc_mask & BIT(i)))
  1663                          tgt_quot_val = min_quotient;
  1664  
  1665                  cpr_write(thread, tgt_quot_reg, tgt_quot_val);
  1666                  dev_vdbg(drv->dev,
  1667                           "Programmed min quotient %u for Ring 
Oscillator %d\n",
  1668                           tgt_quot_val, tgt_quot_reg);
  1669          }
  1670  
  1671          for (i = 0; i < total_corners; i++) {
  1672                  int volt_oloop_steps, volt_floor_steps, 
delta_quot_steps;
> 1673                  int ring_osc, min_quot_val;
  1674                  u32 val;
  1675  
  1676                  fnum = cdata[i].fuse_corner;
  1677                  fuse = &thread->fuse_corners[fnum];
  1678  
  1679                  val = thread->corners[i].uV - desc->cpr_base_voltage;
  1680                  volt_oloop_steps = DIV_ROUND_UP(val, drv->vreg_step);
  1681  
  1682                  val = thread->corners[i].min_uV - 
desc->cpr_base_voltage;
  1683                  volt_floor_steps = DIV_ROUND_UP(val, drv->vreg_step);
  1684  
  1685                  if (i >= (total_corners - extra_corners)) {
  1686                          delta_quot_steps = 0;
  1687                          min_quot_val = 0;
  1688                  } else {
  1689                          min_quot_val = min_quotient;
  1690                          val = fuse->quot - 
thread->corners[i].quot_adjust;
  1691                          val -= min_quotient;
  1692                          delta_quot_steps = DIV_ROUND_UP(val,
  1693                                                  
CPRH_DELTA_QUOT_STEP_FACTOR);
  1694                  }
  1695  
  1696                  /*
  1697                   * If we are accessing corners that are not used as
  1698                   * an active DCVS set-point, then always select RO 0
  1699                   * and zero out the delta quotient.
  1700                   */
  1701                  if (i >= thread->num_corners) {
  1702                          ring_osc = 0;
  1703                          delta_quot_steps = 0;
  1704                  } else {
  1705                          ring_osc = fuse->ring_osc_idx;
  1706                  }
  1707  
  1708                  if (volt_oloop_steps > 
CPRH_CORNER_INIT_VOLTAGE_MAX_VALUE  ||
  1709                      volt_floor_steps > 
CPRH_CORNER_FLOOR_VOLTAGE_MAX_VALUE ||
  1710                      delta_quot_steps > 
CPRH_CORNER_QUOT_DELTA_MAX_VALUE) {
  1711                          dev_err(drv->dev,
  1712                                  "Invalid cfg: oloop=%d, floor=%d, 
delta=%d\n",
  1713                                  volt_oloop_steps, volt_floor_steps,
  1714                                  delta_quot_steps);
  1715                          return -EINVAL;
  1716                  }
  1717                  /* Green light: Go, Go, Go! */
  1718  
  1719                  /* Set number of open-loop steps */
  1720                  val = volt_oloop_steps << 
CPRH_CORNER_INIT_VOLTAGE_SHIFT;
  1721                  val &= CPRH_CORNER_INIT_VOLTAGE_MASK;
  1722  
  1723                  /* Set number of floor voltage steps */
  1724                  val |= (volt_floor_steps << 
CPRH_CORNER_FLOOR_VOLTAGE_SHIFT) &
  1725                         CPRH_CORNER_FLOOR_VOLTAGE_MASK;
  1726  
  1727                  /* Set number of target quotient delta steps */
  1728                  val |= (delta_quot_steps << 
CPRH_CORNER_QUOT_DELTA_SHIFT) &
  1729                         CPRH_CORNER_QUOT_DELTA_MASK;
  1730  
  1731                  /* Select ring oscillator for this corner */
  1732                  val |= (ring_osc << CPRH_CORNER_RO_SEL_SHIFT) &
  1733                         CPRH_CORNER_RO_SEL_MASK;
  1734  
  1735                  /* Open loop corner is usually APM/ACC crossover */
  1736                  if (thread->corners[i].is_open_loop) {
  1737                          dev_dbg(drv->dev,
  1738                                  "Disabling Closed-Loop on corner %d\n", 
i);
  1739                          val |= CPRH_CORNER_CPR_CL_DISABLE;
  1740                  }
  1741                  cpr_write(thread, CPRH_REG_CORNER(drv, tdesc->hw_tid, 
i), val);
  1742  
  1743                  dev_dbg(drv->dev,
  1744                          "steps [%d]: open-loop %d, floor %d, delta_quot 
%d\n",
  1745                          i, volt_oloop_steps, volt_floor_steps,
  1746                          delta_quot_steps);
  1747          }
  1748  
  1749          /* YAY! Setup is done! Enable the internal loop to start CPR. */
  1750          cpr_masked_write(thread, CPR3_REG_CPR_CTL,
  1751                          CPR3_CPR_CTL_LOOP_EN_MASK,
  1752                          CPR3_CPR_CTL_LOOP_EN_MASK);
  1753  
  1754          /*
  1755           * Make sure that all the writes go through before enabling
  1756           * internal communication between the OSM and the CPRh
  1757           * controllers, otherwise there is a high risk of hardware
  1758           * lockups due to under-voltage for the selected CPU clock.
  1759           *
  1760           * Please note that the CPR-hardened gets set-up in Linux but
  1761           * then gets actually used in firmware (and only by the OSM);
  1762           * after handing it off we will have no more control on it,
  1763           * hence the only way to get things up properly for sure here
  1764           * is a write barrier.
  1765           */
  1766          wmb();
  1767  
  1768          /* Enable the interface between OSM and CPRh */
  1769          cpr_masked_write(thread, drv->reg_ctl,
  1770                           CPRH_CTL_OSM_ENABLED,
  1771                           CPRH_CTL_OSM_ENABLED);
  1772  
  1773          /* On success, free cdata manually */
  1774          devm_kfree(drv->dev, cdata);
  1775          return 0;
  1776  }
  1777  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org

Attachment: .config.gz
Description: application/gzip

Reply via email to