diff options
Diffstat (limited to 'drivers/platform/x86/intel_ips.c')
-rw-r--r-- | drivers/platform/x86/intel_ips.c | 51 |
1 files changed, 47 insertions, 4 deletions
diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index c44a5e8b8b82..5ffe7c398148 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c | |||
@@ -75,6 +75,7 @@ | |||
75 | #include <drm/i915_drm.h> | 75 | #include <drm/i915_drm.h> |
76 | #include <asm/msr.h> | 76 | #include <asm/msr.h> |
77 | #include <asm/processor.h> | 77 | #include <asm/processor.h> |
78 | #include "intel_ips.h" | ||
78 | 79 | ||
79 | #define PCI_DEVICE_ID_INTEL_THERMAL_SENSOR 0x3b32 | 80 | #define PCI_DEVICE_ID_INTEL_THERMAL_SENSOR 0x3b32 |
80 | 81 | ||
@@ -245,6 +246,7 @@ | |||
245 | #define thm_writel(off, val) writel((val), ips->regmap + (off)) | 246 | #define thm_writel(off, val) writel((val), ips->regmap + (off)) |
246 | 247 | ||
247 | static const int IPS_ADJUST_PERIOD = 5000; /* ms */ | 248 | static const int IPS_ADJUST_PERIOD = 5000; /* ms */ |
249 | static bool late_i915_load = false; | ||
248 | 250 | ||
249 | /* For initial average collection */ | 251 | /* For initial average collection */ |
250 | static const int IPS_SAMPLE_PERIOD = 200; /* ms */ | 252 | static const int IPS_SAMPLE_PERIOD = 200; /* ms */ |
@@ -339,6 +341,22 @@ struct ips_driver { | |||
339 | u64 orig_turbo_ratios; | 341 | u64 orig_turbo_ratios; |
340 | }; | 342 | }; |
341 | 343 | ||
344 | static bool | ||
345 | ips_gpu_turbo_enabled(struct ips_driver *ips); | ||
346 | |||
347 | #ifndef readq | ||
348 | static inline __u64 readq(const volatile void __iomem *addr) | ||
349 | { | ||
350 | const volatile u32 __iomem *p = addr; | ||
351 | u32 low, high; | ||
352 | |||
353 | low = readl(p); | ||
354 | high = readl(p + 1); | ||
355 | |||
356 | return low + ((u64)high << 32); | ||
357 | } | ||
358 | #endif | ||
359 | |||
342 | /** | 360 | /** |
343 | * ips_cpu_busy - is CPU busy? | 361 | * ips_cpu_busy - is CPU busy? |
344 | * @ips: IPS driver struct | 362 | * @ips: IPS driver struct |
@@ -517,7 +535,7 @@ static void ips_disable_cpu_turbo(struct ips_driver *ips) | |||
517 | */ | 535 | */ |
518 | static bool ips_gpu_busy(struct ips_driver *ips) | 536 | static bool ips_gpu_busy(struct ips_driver *ips) |
519 | { | 537 | { |
520 | if (!ips->gpu_turbo_enabled) | 538 | if (!ips_gpu_turbo_enabled(ips)) |
521 | return false; | 539 | return false; |
522 | 540 | ||
523 | return ips->gpu_busy(); | 541 | return ips->gpu_busy(); |
@@ -532,7 +550,7 @@ static bool ips_gpu_busy(struct ips_driver *ips) | |||
532 | */ | 550 | */ |
533 | static void ips_gpu_raise(struct ips_driver *ips) | 551 | static void ips_gpu_raise(struct ips_driver *ips) |
534 | { | 552 | { |
535 | if (!ips->gpu_turbo_enabled) | 553 | if (!ips_gpu_turbo_enabled(ips)) |
536 | return; | 554 | return; |
537 | 555 | ||
538 | if (!ips->gpu_raise()) | 556 | if (!ips->gpu_raise()) |
@@ -549,7 +567,7 @@ static void ips_gpu_raise(struct ips_driver *ips) | |||
549 | */ | 567 | */ |
550 | static void ips_gpu_lower(struct ips_driver *ips) | 568 | static void ips_gpu_lower(struct ips_driver *ips) |
551 | { | 569 | { |
552 | if (!ips->gpu_turbo_enabled) | 570 | if (!ips_gpu_turbo_enabled(ips)) |
553 | return; | 571 | return; |
554 | 572 | ||
555 | if (!ips->gpu_lower()) | 573 | if (!ips->gpu_lower()) |
@@ -1106,7 +1124,7 @@ static int ips_monitor(void *data) | |||
1106 | last_msecs = jiffies_to_msecs(jiffies); | 1124 | last_msecs = jiffies_to_msecs(jiffies); |
1107 | expire = jiffies + msecs_to_jiffies(IPS_SAMPLE_PERIOD); | 1125 | expire = jiffies + msecs_to_jiffies(IPS_SAMPLE_PERIOD); |
1108 | 1126 | ||
1109 | __set_current_state(TASK_UNINTERRUPTIBLE); | 1127 | __set_current_state(TASK_INTERRUPTIBLE); |
1110 | mod_timer(&timer, expire); | 1128 | mod_timer(&timer, expire); |
1111 | schedule(); | 1129 | schedule(); |
1112 | 1130 | ||
@@ -1454,6 +1472,31 @@ out_err: | |||
1454 | return false; | 1472 | return false; |
1455 | } | 1473 | } |
1456 | 1474 | ||
1475 | static bool | ||
1476 | ips_gpu_turbo_enabled(struct ips_driver *ips) | ||
1477 | { | ||
1478 | if (!ips->gpu_busy && late_i915_load) { | ||
1479 | if (ips_get_i915_syms(ips)) { | ||
1480 | dev_info(&ips->dev->dev, | ||
1481 | "i915 driver attached, reenabling gpu turbo\n"); | ||
1482 | ips->gpu_turbo_enabled = !(thm_readl(THM_HTS) & HTS_GTD_DIS); | ||
1483 | } | ||
1484 | } | ||
1485 | |||
1486 | return ips->gpu_turbo_enabled; | ||
1487 | } | ||
1488 | |||
1489 | void | ||
1490 | ips_link_to_i915_driver(void) | ||
1491 | { | ||
1492 | /* We can't cleanly get at the various ips_driver structs from | ||
1493 | * this caller (the i915 driver), so just set a flag saying | ||
1494 | * that it's time to try getting the symbols again. | ||
1495 | */ | ||
1496 | late_i915_load = true; | ||
1497 | } | ||
1498 | EXPORT_SYMBOL_GPL(ips_link_to_i915_driver); | ||
1499 | |||
1457 | static DEFINE_PCI_DEVICE_TABLE(ips_id_table) = { | 1500 | static DEFINE_PCI_DEVICE_TABLE(ips_id_table) = { |
1458 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, | 1501 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, |
1459 | PCI_DEVICE_ID_INTEL_THERMAL_SENSOR), }, | 1502 | PCI_DEVICE_ID_INTEL_THERMAL_SENSOR), }, |