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.

Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86

* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86:
IPS driver: Fix limit clamping when reducing CPU power
[PATCH 2/2] IPS driver: disable CPU turbo
IPS driver: apply BIOS provided CPU limit if different from default
intel_ips -- ensure we do not enable gpu turbo mode without driver linkage
intel_ips: Print MCP limit exceeded values.
IPS driver: verify BIOS provided limits
IPS driver: don't toggle CPU turbo on unsupported CPUs
NULL pointer might be used in ips_monitor()
Release symbol on error-handling path of ips_get_i915_syms()
old_cpu_power is wrongly divided by 65535 in ips_monitor()
seqno mask of THM_ITV register is 16bit

+93 -35
+93 -35
drivers/platform/x86/intel_ips.c
··· 51 51 * TODO: 52 52 * - handle CPU hotplug 53 53 * - provide turbo enable/disable api 54 - * - make sure we can write turbo enable/disable reg based on MISC_EN 55 54 * 56 55 * Related documents: 57 56 * - CDI 403777, 403778 - Auburndale EDS vol 1 & 2 ··· 229 230 #define THM_TC2 0xac 230 231 #define THM_DTV 0xb0 231 232 #define THM_ITV 0xd8 232 - #define ITV_ME_SEQNO_MASK 0x000f0000 /* ME should update every ~200ms */ 233 + #define ITV_ME_SEQNO_MASK 0x00ff0000 /* ME should update every ~200ms */ 233 234 #define ITV_ME_SEQNO_SHIFT (16) 234 235 #define ITV_MCH_TEMP_MASK 0x0000ff00 235 236 #define ITV_MCH_TEMP_SHIFT (8) ··· 324 325 bool gpu_preferred; 325 326 bool poll_turbo_status; 326 327 bool second_cpu; 328 + bool turbo_toggle_allowed; 327 329 struct ips_mcp_limits *limits; 328 330 329 331 /* Optional MCH interfaces for if i915 is in use */ ··· 415 415 new_limit = cur_limit - 8; /* 1W decrease */ 416 416 417 417 /* Clamp to SKU TDP limit */ 418 - if (((new_limit * 10) / 8) < (ips->orig_turbo_limit & TURBO_TDP_MASK)) 418 + if (new_limit < (ips->orig_turbo_limit & TURBO_TDP_MASK)) 419 419 new_limit = ips->orig_turbo_limit & TURBO_TDP_MASK; 420 420 421 421 thm_writew(THM_MPCPC, (new_limit * 10) / 8); ··· 461 461 if (ips->__cpu_turbo_on) 462 462 return; 463 463 464 - on_each_cpu(do_enable_cpu_turbo, ips, 1); 464 + if (ips->turbo_toggle_allowed) 465 + on_each_cpu(do_enable_cpu_turbo, ips, 1); 465 466 466 467 ips->__cpu_turbo_on = true; 467 468 } ··· 499 498 if (!ips->__cpu_turbo_on) 500 499 return; 501 500 502 - on_each_cpu(do_disable_cpu_turbo, ips, 1); 501 + if (ips->turbo_toggle_allowed) 502 + on_each_cpu(do_disable_cpu_turbo, ips, 1); 503 503 504 504 ips->__cpu_turbo_on = false; 505 505 } ··· 600 598 { 601 599 unsigned long flags; 602 600 bool ret = false; 601 + u32 temp_limit; 602 + u32 avg_power; 603 + const char *msg = "MCP limit exceeded: "; 603 604 604 605 spin_lock_irqsave(&ips->turbo_status_lock, flags); 605 - if (ips->mcp_avg_temp > (ips->mcp_temp_limit * 100)) 606 - ret = true; 607 - if (ips->cpu_avg_power + ips->mch_avg_power > ips->mcp_power_limit) 608 - ret = true; 609 - spin_unlock_irqrestore(&ips->turbo_status_lock, flags); 610 606 611 - if (ret) 607 + temp_limit = ips->mcp_temp_limit * 100; 608 + if (ips->mcp_avg_temp > temp_limit) { 612 609 dev_info(&ips->dev->dev, 613 - "MCP power or thermal limit exceeded\n"); 610 + "%sAvg temp %u, limit %u\n", msg, ips->mcp_avg_temp, 611 + temp_limit); 612 + ret = true; 613 + } 614 + 615 + avg_power = ips->cpu_avg_power + ips->mch_avg_power; 616 + if (avg_power > ips->mcp_power_limit) { 617 + dev_info(&ips->dev->dev, 618 + "%sAvg power %u, limit %u\n", msg, avg_power, 619 + ips->mcp_power_limit); 620 + ret = true; 621 + } 622 + 623 + spin_unlock_irqrestore(&ips->turbo_status_lock, flags); 614 624 615 625 return ret; 616 626 } ··· 677 663 } 678 664 679 665 /** 666 + * verify_limits - verify BIOS provided limits 667 + * @ips: IPS structure 668 + * 669 + * BIOS can optionally provide non-default limits for power and temp. Check 670 + * them here and use the defaults if the BIOS values are not provided or 671 + * are otherwise unusable. 672 + */ 673 + static void verify_limits(struct ips_driver *ips) 674 + { 675 + if (ips->mcp_power_limit < ips->limits->mcp_power_limit || 676 + ips->mcp_power_limit > 35000) 677 + ips->mcp_power_limit = ips->limits->mcp_power_limit; 678 + 679 + if (ips->mcp_temp_limit < ips->limits->core_temp_limit || 680 + ips->mcp_temp_limit < ips->limits->mch_temp_limit || 681 + ips->mcp_temp_limit > 150) 682 + ips->mcp_temp_limit = min(ips->limits->core_temp_limit, 683 + ips->limits->mch_temp_limit); 684 + } 685 + 686 + /** 680 687 * update_turbo_limits - get various limits & settings from regs 681 688 * @ips: IPS driver struct 682 689 * ··· 715 680 u32 hts = thm_readl(THM_HTS); 716 681 717 682 ips->cpu_turbo_enabled = !(hts & HTS_PCTD_DIS); 718 - ips->gpu_turbo_enabled = !(hts & HTS_GTD_DIS); 683 + /* 684 + * Disable turbo for now, until we can figure out why the power figures 685 + * are wrong 686 + */ 687 + ips->cpu_turbo_enabled = false; 688 + 689 + if (ips->gpu_busy) 690 + ips->gpu_turbo_enabled = !(hts & HTS_GTD_DIS); 691 + 719 692 ips->core_power_limit = thm_readw(THM_MPCPC); 720 693 ips->mch_power_limit = thm_readw(THM_MMGPC); 721 694 ips->mcp_temp_limit = thm_readw(THM_PTL); 722 695 ips->mcp_power_limit = thm_readw(THM_MPPC); 723 696 697 + verify_limits(ips); 724 698 /* Ignore BIOS CPU vs GPU pref */ 725 699 } 726 700 ··· 902 858 ret = (ret * 1000) / 65535; 903 859 *last = val; 904 860 905 - return ret; 861 + return 0; 906 862 } 907 863 908 864 static const u16 temp_decay_factor = 2; ··· 984 940 kfree(mch_samples); 985 941 kfree(cpu_samples); 986 942 kfree(mchp_samples); 987 - kthread_stop(ips->adjust); 988 943 return -ENOMEM; 989 944 } 990 945 ··· 991 948 ITV_ME_SEQNO_SHIFT; 992 949 seqno_timestamp = get_jiffies_64(); 993 950 994 - old_cpu_power = thm_readl(THM_CEC) / 65535; 951 + old_cpu_power = thm_readl(THM_CEC); 995 952 schedule_timeout_interruptible(msecs_to_jiffies(IPS_SAMPLE_PERIOD)); 996 953 997 954 /* Collect an initial average */ ··· 1193 1150 STS_GPL_SHIFT; 1194 1151 /* ignore EC CPU vs GPU pref */ 1195 1152 ips->cpu_turbo_enabled = !(sts & STS_PCTD_DIS); 1196 - ips->gpu_turbo_enabled = !(sts & STS_GTD_DIS); 1153 + /* 1154 + * Disable turbo for now, until we can figure 1155 + * out why the power figures are wrong 1156 + */ 1157 + ips->cpu_turbo_enabled = false; 1158 + if (ips->gpu_busy) 1159 + ips->gpu_turbo_enabled = !(sts & STS_GTD_DIS); 1197 1160 ips->mcp_temp_limit = (sts & STS_PTL_MASK) >> 1198 1161 STS_PTL_SHIFT; 1199 1162 ips->mcp_power_limit = (tc1 & STS_PPL_MASK) >> 1200 1163 STS_PPL_SHIFT; 1164 + verify_limits(ips); 1201 1165 spin_unlock(&ips->turbo_status_lock); 1202 1166 1203 1167 thm_writeb(THM_SEC, SEC_ACK); ··· 1383 1333 * turbo manually or we'll get an illegal MSR access, even though 1384 1334 * turbo will still be available. 1385 1335 */ 1386 - if (!(misc_en & IA32_MISC_TURBO_EN)) 1387 - ; /* add turbo MSR write allowed flag if necessary */ 1336 + if (misc_en & IA32_MISC_TURBO_EN) 1337 + ips->turbo_toggle_allowed = true; 1338 + else 1339 + ips->turbo_toggle_allowed = false; 1388 1340 1389 1341 if (strstr(boot_cpu_data.x86_model_id, "CPU M")) 1390 1342 limits = &ips_sv_limits; ··· 1403 1351 tdp = turbo_power & TURBO_TDP_MASK; 1404 1352 1405 1353 /* Sanity check TDP against CPU */ 1406 - if (limits->mcp_power_limit != (tdp / 8) * 1000) { 1407 - dev_warn(&ips->dev->dev, "Warning: CPU TDP doesn't match expected value (found %d, expected %d)\n", 1408 - tdp / 8, limits->mcp_power_limit / 1000); 1354 + if (limits->core_power_limit != (tdp / 8) * 1000) { 1355 + dev_info(&ips->dev->dev, "CPU TDP doesn't match expected value (found %d, expected %d)\n", 1356 + tdp / 8, limits->core_power_limit / 1000); 1357 + limits->core_power_limit = (tdp / 8) * 1000; 1409 1358 } 1410 1359 1411 1360 out: ··· 1443 1390 return true; 1444 1391 1445 1392 out_put_busy: 1446 - symbol_put(i915_gpu_turbo_disable); 1393 + symbol_put(i915_gpu_busy); 1447 1394 out_put_lower: 1448 1395 symbol_put(i915_gpu_lower); 1449 1396 out_put_raise: ··· 1585 1532 /* Save turbo limits & ratios */ 1586 1533 rdmsrl(TURBO_POWER_CURRENT_LIMIT, ips->orig_turbo_limit); 1587 1534 1588 - ips_enable_cpu_turbo(ips); 1589 - ips->cpu_turbo_enabled = true; 1535 + ips_disable_cpu_turbo(ips); 1536 + ips->cpu_turbo_enabled = false; 1590 1537 1591 - /* Set up the work queue and monitor/adjust threads */ 1592 - ips->monitor = kthread_run(ips_monitor, ips, "ips-monitor"); 1593 - if (IS_ERR(ips->monitor)) { 1594 - dev_err(&dev->dev, 1595 - "failed to create thermal monitor thread, aborting\n"); 1596 - ret = -ENOMEM; 1597 - goto error_free_irq; 1598 - } 1599 - 1538 + /* Create thermal adjust thread */ 1600 1539 ips->adjust = kthread_create(ips_adjust, ips, "ips-adjust"); 1601 1540 if (IS_ERR(ips->adjust)) { 1602 1541 dev_err(&dev->dev, 1603 1542 "failed to create thermal adjust thread, aborting\n"); 1543 + ret = -ENOMEM; 1544 + goto error_free_irq; 1545 + 1546 + } 1547 + 1548 + /* 1549 + * Set up the work queue and monitor thread. The monitor thread 1550 + * will wake up ips_adjust thread. 1551 + */ 1552 + ips->monitor = kthread_run(ips_monitor, ips, "ips-monitor"); 1553 + if (IS_ERR(ips->monitor)) { 1554 + dev_err(&dev->dev, 1555 + "failed to create thermal monitor thread, aborting\n"); 1604 1556 ret = -ENOMEM; 1605 1557 goto error_thread_cleanup; 1606 1558 } ··· 1624 1566 return ret; 1625 1567 1626 1568 error_thread_cleanup: 1627 - kthread_stop(ips->monitor); 1569 + kthread_stop(ips->adjust); 1628 1570 error_free_irq: 1629 1571 free_irq(ips->dev->irq, ips); 1630 1572 error_unmap: