diff options
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 23 | ||||
-rw-r--r-- | drivers/platform/x86/intel_ips.c | 36 | ||||
-rw-r--r-- | drivers/platform/x86/intel_ips.h | 21 |
3 files changed, 77 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index e6800819bca8..cb900dc83d95 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "i915_drm.h" | 34 | #include "i915_drm.h" |
35 | #include "i915_drv.h" | 35 | #include "i915_drv.h" |
36 | #include "i915_trace.h" | 36 | #include "i915_trace.h" |
37 | #include "../../../platform/x86/intel_ips.h" | ||
37 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
38 | #include <linux/vgaarb.h> | 39 | #include <linux/vgaarb.h> |
39 | #include <linux/acpi.h> | 40 | #include <linux/acpi.h> |
@@ -1871,6 +1872,26 @@ out_unlock: | |||
1871 | EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable); | 1872 | EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable); |
1872 | 1873 | ||
1873 | /** | 1874 | /** |
1875 | * Tells the intel_ips driver that the i915 driver is now loaded, if | ||
1876 | * IPS got loaded first. | ||
1877 | * | ||
1878 | * This awkward dance is so that neither module has to depend on the | ||
1879 | * other in order for IPS to do the appropriate communication of | ||
1880 | * GPU turbo limits to i915. | ||
1881 | */ | ||
1882 | static void | ||
1883 | ips_ping_for_i915_load(void) | ||
1884 | { | ||
1885 | void (*link)(void); | ||
1886 | |||
1887 | link = symbol_get(ips_link_to_i915_driver); | ||
1888 | if (link) { | ||
1889 | link(); | ||
1890 | symbol_put(ips_link_to_i915_driver); | ||
1891 | } | ||
1892 | } | ||
1893 | |||
1894 | /** | ||
1874 | * i915_driver_load - setup chip and create an initial config | 1895 | * i915_driver_load - setup chip and create an initial config |
1875 | * @dev: DRM device | 1896 | * @dev: DRM device |
1876 | * @flags: startup flags | 1897 | * @flags: startup flags |
@@ -2075,6 +2096,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2075 | dev_priv->mchdev_lock = &mchdev_lock; | 2096 | dev_priv->mchdev_lock = &mchdev_lock; |
2076 | spin_unlock(&mchdev_lock); | 2097 | spin_unlock(&mchdev_lock); |
2077 | 2098 | ||
2099 | ips_ping_for_i915_load(); | ||
2100 | |||
2078 | return 0; | 2101 | return 0; |
2079 | 2102 | ||
2080 | out_workqueue_free: | 2103 | out_workqueue_free: |
diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index c44a5e8b8b82..f0b3ad13c273 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,9 @@ 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 | |||
342 | /** | 347 | /** |
343 | * ips_cpu_busy - is CPU busy? | 348 | * ips_cpu_busy - is CPU busy? |
344 | * @ips: IPS driver struct | 349 | * @ips: IPS driver struct |
@@ -517,7 +522,7 @@ static void ips_disable_cpu_turbo(struct ips_driver *ips) | |||
517 | */ | 522 | */ |
518 | static bool ips_gpu_busy(struct ips_driver *ips) | 523 | static bool ips_gpu_busy(struct ips_driver *ips) |
519 | { | 524 | { |
520 | if (!ips->gpu_turbo_enabled) | 525 | if (!ips_gpu_turbo_enabled(ips)) |
521 | return false; | 526 | return false; |
522 | 527 | ||
523 | return ips->gpu_busy(); | 528 | return ips->gpu_busy(); |
@@ -532,7 +537,7 @@ static bool ips_gpu_busy(struct ips_driver *ips) | |||
532 | */ | 537 | */ |
533 | static void ips_gpu_raise(struct ips_driver *ips) | 538 | static void ips_gpu_raise(struct ips_driver *ips) |
534 | { | 539 | { |
535 | if (!ips->gpu_turbo_enabled) | 540 | if (!ips_gpu_turbo_enabled(ips)) |
536 | return; | 541 | return; |
537 | 542 | ||
538 | if (!ips->gpu_raise()) | 543 | if (!ips->gpu_raise()) |
@@ -549,7 +554,7 @@ static void ips_gpu_raise(struct ips_driver *ips) | |||
549 | */ | 554 | */ |
550 | static void ips_gpu_lower(struct ips_driver *ips) | 555 | static void ips_gpu_lower(struct ips_driver *ips) |
551 | { | 556 | { |
552 | if (!ips->gpu_turbo_enabled) | 557 | if (!ips_gpu_turbo_enabled(ips)) |
553 | return; | 558 | return; |
554 | 559 | ||
555 | if (!ips->gpu_lower()) | 560 | if (!ips->gpu_lower()) |
@@ -1454,6 +1459,31 @@ out_err: | |||
1454 | return false; | 1459 | return false; |
1455 | } | 1460 | } |
1456 | 1461 | ||
1462 | static bool | ||
1463 | ips_gpu_turbo_enabled(struct ips_driver *ips) | ||
1464 | { | ||
1465 | if (!ips->gpu_busy && late_i915_load) { | ||
1466 | if (ips_get_i915_syms(ips)) { | ||
1467 | dev_info(&ips->dev->dev, | ||
1468 | "i915 driver attached, reenabling gpu turbo\n"); | ||
1469 | ips->gpu_turbo_enabled = !(thm_readl(THM_HTS) & HTS_GTD_DIS); | ||
1470 | } | ||
1471 | } | ||
1472 | |||
1473 | return ips->gpu_turbo_enabled; | ||
1474 | } | ||
1475 | |||
1476 | void | ||
1477 | ips_link_to_i915_driver() | ||
1478 | { | ||
1479 | /* We can't cleanly get at the various ips_driver structs from | ||
1480 | * this caller (the i915 driver), so just set a flag saying | ||
1481 | * that it's time to try getting the symbols again. | ||
1482 | */ | ||
1483 | late_i915_load = true; | ||
1484 | } | ||
1485 | EXPORT_SYMBOL_GPL(ips_link_to_i915_driver); | ||
1486 | |||
1457 | static DEFINE_PCI_DEVICE_TABLE(ips_id_table) = { | 1487 | static DEFINE_PCI_DEVICE_TABLE(ips_id_table) = { |
1458 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, | 1488 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, |
1459 | PCI_DEVICE_ID_INTEL_THERMAL_SENSOR), }, | 1489 | PCI_DEVICE_ID_INTEL_THERMAL_SENSOR), }, |
diff --git a/drivers/platform/x86/intel_ips.h b/drivers/platform/x86/intel_ips.h new file mode 100644 index 000000000000..73299beff5b3 --- /dev/null +++ b/drivers/platform/x86/intel_ips.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010 Intel Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License along with | ||
14 | * this program; if not, write to the Free Software Foundation, Inc., | ||
15 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
16 | * | ||
17 | * The full GNU General Public License is included in this distribution in | ||
18 | * the file called "COPYING". | ||
19 | */ | ||
20 | |||
21 | void ips_link_to_i915_driver(void); | ||