Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/amd/pm: Add od_edit_dpm_table support

Add od_edit_dpm_table support for smu_v15_0_8

v2: Skip Gl2clk/Fclk (Lijo)

v3: sqaush in set_performance_support (Asad)

Signed-off-by: Asad Kamal <asad.kamal@amd.com>
Signed-off-by: Yang Wang <kevinyang.wang@amd.com>
Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Asad Kamal and committed by
Alex Deucher
422b399b c7de5a86

+306 -1
+295 -1
drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.c
··· 1391 1391 return 0; 1392 1392 } 1393 1393 1394 + static int smu_v15_0_8_set_gfx_soft_freq_limited_range(struct smu_context *smu, 1395 + uint32_t min, 1396 + uint32_t max) 1397 + { 1398 + int ret; 1399 + 1400 + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk, 1401 + max & 0xffff, NULL); 1402 + if (ret) 1403 + return ret; 1404 + 1405 + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMinGfxclk, 1406 + min & 0xffff, NULL); 1407 + 1408 + return ret; 1409 + } 1410 + 1411 + static int smu_v15_0_8_set_performance_level(struct smu_context *smu, 1412 + enum amd_dpm_forced_level level) 1413 + { 1414 + struct smu_dpm_context *smu_dpm = &smu->smu_dpm; 1415 + struct smu_15_0_dpm_context *dpm_context = smu_dpm->dpm_context; 1416 + struct smu_dpm_table *gfx_table = &dpm_context->dpm_tables.gfx_table; 1417 + struct smu_dpm_table *uclk_table = &dpm_context->dpm_tables.uclk_table; 1418 + struct smu_umd_pstate_table *pstate_table = &smu->pstate_table; 1419 + int ret; 1420 + 1421 + switch (level) { 1422 + case AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM: 1423 + /* Determinism not supported on SMU v15.0.8 */ 1424 + ret = -EOPNOTSUPP; 1425 + break; 1426 + 1427 + case AMD_DPM_FORCED_LEVEL_AUTO: 1428 + /* Restore GFXCLK to default range */ 1429 + if ((SMU_DPM_TABLE_MIN(gfx_table) != 1430 + pstate_table->gfxclk_pstate.curr.min) || 1431 + (SMU_DPM_TABLE_MAX(gfx_table) != 1432 + pstate_table->gfxclk_pstate.curr.max)) { 1433 + ret = smu_v15_0_8_set_gfx_soft_freq_limited_range( 1434 + smu, SMU_DPM_TABLE_MIN(gfx_table), 1435 + SMU_DPM_TABLE_MAX(gfx_table)); 1436 + if (ret) 1437 + goto out; 1438 + 1439 + pstate_table->gfxclk_pstate.curr.min = 1440 + SMU_DPM_TABLE_MIN(gfx_table); 1441 + pstate_table->gfxclk_pstate.curr.max = 1442 + SMU_DPM_TABLE_MAX(gfx_table); 1443 + } 1444 + 1445 + /* Restore UCLK to default max */ 1446 + if (SMU_DPM_TABLE_MAX(uclk_table) != 1447 + pstate_table->uclk_pstate.curr.max) { 1448 + /* Min UCLK is not expected to be changed */ 1449 + ret = smu_v15_0_set_soft_freq_limited_range(smu, 1450 + SMU_UCLK, 0, 1451 + SMU_DPM_TABLE_MAX(uclk_table), 1452 + false); 1453 + if (ret) 1454 + goto out; 1455 + 1456 + pstate_table->uclk_pstate.curr.max = 1457 + SMU_DPM_TABLE_MAX(uclk_table); 1458 + } 1459 + 1460 + if (ret) 1461 + goto out; 1462 + 1463 + smu_cmn_reset_custom_level(smu); 1464 + 1465 + break; 1466 + case AMD_DPM_FORCED_LEVEL_MANUAL: 1467 + ret = 0; 1468 + break; 1469 + default: 1470 + ret = -EOPNOTSUPP; 1471 + break; 1472 + } 1473 + 1474 + out: 1475 + return ret; 1476 + } 1477 + 1478 + static int smu_v15_0_8_set_soft_freq_limited_range(struct smu_context *smu, 1479 + enum smu_clk_type clk_type, 1480 + uint32_t min, uint32_t max, 1481 + bool automatic) 1482 + { 1483 + struct smu_dpm_context *smu_dpm = &smu->smu_dpm; 1484 + struct smu_umd_pstate_table *pstate_table = &smu->pstate_table; 1485 + int ret = 0; 1486 + 1487 + if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK && 1488 + clk_type != SMU_UCLK) 1489 + return -EINVAL; 1490 + 1491 + if (smu_dpm->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) 1492 + return -EINVAL; 1493 + 1494 + if (smu_dpm->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL) { 1495 + if (min >= max) { 1496 + dev_err(smu->adev->dev, 1497 + "Minimum clk should be less than the maximum allowed clock\n"); 1498 + return -EINVAL; 1499 + } 1500 + 1501 + if (clk_type == SMU_GFXCLK || clk_type == SMU_SCLK) { 1502 + if ((min == pstate_table->gfxclk_pstate.curr.min) && 1503 + (max == pstate_table->gfxclk_pstate.curr.max)) 1504 + return 0; 1505 + 1506 + ret = smu_v15_0_8_set_gfx_soft_freq_limited_range(smu, 1507 + min, max); 1508 + if (!ret) { 1509 + pstate_table->gfxclk_pstate.curr.min = min; 1510 + pstate_table->gfxclk_pstate.curr.max = max; 1511 + } 1512 + } 1513 + 1514 + if (clk_type == SMU_UCLK) { 1515 + if (max == pstate_table->uclk_pstate.curr.max) 1516 + return 0; 1517 + 1518 + ret = smu_v15_0_set_soft_freq_limited_range(smu, 1519 + SMU_UCLK, 1520 + 0, max, 1521 + false); 1522 + if (!ret) 1523 + pstate_table->uclk_pstate.curr.max = max; 1524 + } 1525 + 1526 + return ret; 1527 + } 1528 + 1529 + return 0; 1530 + } 1531 + 1532 + static int smu_v15_0_8_od_edit_dpm_table(struct smu_context *smu, 1533 + enum PP_OD_DPM_TABLE_COMMAND type, 1534 + long input[], uint32_t size) 1535 + { 1536 + struct smu_dpm_context *smu_dpm = &smu->smu_dpm; 1537 + struct smu_umd_pstate_table *pstate_table = &smu->pstate_table; 1538 + struct smu_15_0_dpm_context *dpm_context = smu_dpm->dpm_context; 1539 + uint32_t min_clk, max_clk; 1540 + int ret; 1541 + 1542 + /* Only allowed in manual mode */ 1543 + if (smu_dpm->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) 1544 + return -EINVAL; 1545 + 1546 + switch (type) { 1547 + case PP_OD_EDIT_SCLK_VDDC_TABLE: 1548 + if (size != 2) { 1549 + dev_err(smu->adev->dev, 1550 + "Input parameter number not correct\n"); 1551 + return -EINVAL; 1552 + } 1553 + min_clk = SMU_DPM_TABLE_MIN(&dpm_context->dpm_tables.gfx_table); 1554 + max_clk = SMU_DPM_TABLE_MAX(&dpm_context->dpm_tables.gfx_table); 1555 + if (input[0] == 0) { 1556 + if (input[1] < min_clk) { 1557 + dev_warn(smu->adev->dev, 1558 + "Minimum GFX clk (%ld) MHz specified is less than the minimum allowed (%d) MHz\n", 1559 + input[1], min_clk); 1560 + pstate_table->gfxclk_pstate.custom.min = 1561 + pstate_table->gfxclk_pstate.curr.min; 1562 + return -EINVAL; 1563 + } 1564 + 1565 + pstate_table->gfxclk_pstate.custom.min = input[1]; 1566 + } else if (input[0] == 1) { 1567 + if (input[1] > max_clk) { 1568 + dev_warn(smu->adev->dev, 1569 + "Maximum GFX clk (%ld) MHz specified is greater than the maximum allowed (%d) MHz\n", 1570 + input[1], max_clk); 1571 + pstate_table->gfxclk_pstate.custom.max = 1572 + pstate_table->gfxclk_pstate.curr.max; 1573 + return -EINVAL; 1574 + } 1575 + 1576 + pstate_table->gfxclk_pstate.custom.max = input[1]; 1577 + } else { 1578 + return -EINVAL; 1579 + } 1580 + break; 1581 + case PP_OD_EDIT_MCLK_VDDC_TABLE: 1582 + if (size != 2) { 1583 + dev_err(smu->adev->dev, 1584 + "Input parameter number not correct\n"); 1585 + return -EINVAL; 1586 + } 1587 + 1588 + if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) { 1589 + dev_warn(smu->adev->dev, 1590 + "UCLK_LIMITS setting not supported!\n"); 1591 + return -EOPNOTSUPP; 1592 + } 1593 + max_clk = SMU_DPM_TABLE_MAX(&dpm_context->dpm_tables.uclk_table); 1594 + if (input[0] == 0) { 1595 + dev_info(smu->adev->dev, 1596 + "Setting min UCLK level is not supported"); 1597 + return -EINVAL; 1598 + } else if (input[0] == 1) { 1599 + if (input[1] > max_clk) { 1600 + dev_warn(smu->adev->dev, 1601 + "Maximum UCLK (%ld) MHz specified is greater than the maximum allowed (%d) MHz\n", 1602 + input[1], max_clk); 1603 + pstate_table->uclk_pstate.custom.max = 1604 + pstate_table->uclk_pstate.curr.max; 1605 + 1606 + return -EINVAL; 1607 + } 1608 + 1609 + pstate_table->uclk_pstate.custom.max = input[1]; 1610 + } 1611 + break; 1612 + case PP_OD_RESTORE_DEFAULT_TABLE: 1613 + if (size != 0) { 1614 + dev_err(smu->adev->dev, 1615 + "Input parameter number not correct\n"); 1616 + return -EINVAL; 1617 + } 1618 + 1619 + /* Use the default frequencies for manual mode */ 1620 + min_clk = SMU_DPM_TABLE_MIN(&dpm_context->dpm_tables.gfx_table); 1621 + max_clk = SMU_DPM_TABLE_MAX(&dpm_context->dpm_tables.gfx_table); 1622 + 1623 + ret = smu_v15_0_8_set_soft_freq_limited_range(smu, 1624 + SMU_GFXCLK, 1625 + min_clk, max_clk, 1626 + false); 1627 + if (ret) 1628 + return ret; 1629 + 1630 + min_clk = SMU_DPM_TABLE_MIN(&dpm_context->dpm_tables.uclk_table); 1631 + max_clk = SMU_DPM_TABLE_MAX(&dpm_context->dpm_tables.uclk_table); 1632 + ret = smu_v15_0_8_set_soft_freq_limited_range(smu, 1633 + SMU_UCLK, 1634 + min_clk, max_clk, 1635 + false); 1636 + if (ret) 1637 + return ret; 1638 + 1639 + smu_cmn_reset_custom_level(smu); 1640 + break; 1641 + case PP_OD_COMMIT_DPM_TABLE: 1642 + if (size != 0) { 1643 + dev_err(smu->adev->dev, 1644 + "Input parameter number not correct\n"); 1645 + return -EINVAL; 1646 + } 1647 + 1648 + if (!pstate_table->gfxclk_pstate.custom.min) 1649 + pstate_table->gfxclk_pstate.custom.min = 1650 + pstate_table->gfxclk_pstate.curr.min; 1651 + 1652 + if (!pstate_table->gfxclk_pstate.custom.max) 1653 + pstate_table->gfxclk_pstate.custom.max = 1654 + pstate_table->gfxclk_pstate.curr.max; 1655 + 1656 + min_clk = pstate_table->gfxclk_pstate.custom.min; 1657 + max_clk = pstate_table->gfxclk_pstate.custom.max; 1658 + 1659 + ret = smu_v15_0_8_set_soft_freq_limited_range(smu, 1660 + SMU_GFXCLK, 1661 + min_clk, max_clk, 1662 + false); 1663 + if (ret) 1664 + return ret; 1665 + 1666 + /* Commit UCLK custom range (only max supported) */ 1667 + if (pstate_table->uclk_pstate.custom.max) { 1668 + min_clk = pstate_table->uclk_pstate.curr.min; 1669 + max_clk = pstate_table->uclk_pstate.custom.max; 1670 + ret = smu_v15_0_8_set_soft_freq_limited_range(smu, 1671 + SMU_UCLK, 1672 + min_clk, max_clk, 1673 + false); 1674 + if (ret) 1675 + return ret; 1676 + } 1677 + 1678 + break; 1679 + default: 1680 + return -ENOSYS; 1681 + } 1682 + 1683 + return 0; 1684 + } 1685 + 1394 1686 static const struct pptable_funcs smu_v15_0_8_ppt_funcs = { 1395 1687 .init_allowed_features = smu_v15_0_8_init_allowed_features, 1396 1688 .set_default_dpm_table = smu_v15_0_8_set_default_dpm_table, ··· 1712 1420 .set_power_limit = smu_v15_0_set_power_limit, 1713 1421 .emit_clk_levels = smu_v15_0_8_emit_clk_levels, 1714 1422 .populate_umd_state_clk = smu_v15_0_8_populate_umd_state_clk, 1715 - }; 1423 + .set_performance_level = smu_v15_0_8_set_performance_level, 1424 + .od_edit_dpm_table = smu_v15_0_8_od_edit_dpm_table, 1425 + }; 1716 1426 1717 1427 static void smu_v15_0_8_init_msg_ctl(struct smu_context *smu, 1718 1428 const struct cmn2asic_msg_mapping *message_map)
+10
drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
··· 1301 1301 } 1302 1302 } 1303 1303 1304 + void smu_cmn_reset_custom_level(struct smu_context *smu) 1305 + { 1306 + struct smu_umd_pstate_table *pstate_table = &smu->pstate_table; 1307 + 1308 + pstate_table->gfxclk_pstate.custom.min = 0; 1309 + pstate_table->gfxclk_pstate.custom.max = 0; 1310 + pstate_table->uclk_pstate.custom.min = 0; 1311 + pstate_table->uclk_pstate.custom.max = 0; 1312 + } 1313 + 1304 1314 static inline bool smu_cmn_freqs_match(uint32_t freq1, uint32_t freq2) 1305 1315 { 1306 1316 /* Frequencies within 25 MHz are considered equal */
+1
drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h
··· 204 204 struct smu_pcie_table *pcie_table, 205 205 uint32_t cur_gen, uint32_t cur_lane, 206 206 char *buf, int *offset); 207 + void smu_cmn_reset_custom_level(struct smu_context *smu); 207 208 208 209 int smu_cmn_dpm_pcie_gen_idx(int gen); 209 210 int smu_cmn_dpm_pcie_width_idx(int width);